github.com/openconfig/goyang@v1.4.5/types.go (about) 1 // Copyright 2015 Google Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package main 16 17 import ( 18 "fmt" 19 "io" 20 "strings" 21 22 "github.com/openconfig/goyang/pkg/indent" 23 "github.com/openconfig/goyang/pkg/yang" 24 "github.com/pborman/getopt" 25 ) 26 27 var ( 28 typesDebug bool 29 typesVerbose bool 30 ) 31 32 func init() { 33 flags := getopt.New() 34 register(&formatter{ 35 name: "types", 36 f: doTypes, 37 help: "display found types", 38 flags: flags, 39 }) 40 flags.BoolVarLong(&typesDebug, "types_debug", 0, "display debug information") 41 flags.BoolVarLong(&typesVerbose, "types_verbose", 0, "include base information") 42 } 43 44 func doTypes(w io.Writer, entries []*yang.Entry) { 45 types := Types{} 46 for _, e := range entries { 47 types.AddEntry(e) 48 } 49 50 for t := range types { 51 printType(w, t, typesVerbose) 52 } 53 if typesDebug { 54 for _, e := range entries { 55 showall(w, e) 56 } 57 } 58 } 59 60 // Types keeps track of all the YangTypes defined. 61 type Types map[*yang.YangType]struct{} 62 63 // AddEntry adds all types defined in e and its descendants to t. 64 func (t Types) AddEntry(e *yang.Entry) { 65 if e == nil { 66 return 67 } 68 if e.Type != nil { 69 t[e.Type.Root] = struct{}{} 70 } 71 for _, d := range e.Dir { 72 t.AddEntry(d) 73 } 74 } 75 76 // printType prints type t in a moderately human readable format to w. 77 func printType(w io.Writer, t *yang.YangType, verbose bool) { 78 if verbose && t.Base != nil { 79 base := yang.Source(t.Base) 80 if base == "unknown" { 81 base = "unnamed type" 82 } 83 fmt.Fprintf(w, "%s: ", base) 84 } 85 fmt.Fprintf(w, "%s", t.Root.Name) 86 if t.Kind.String() != t.Root.Name { 87 fmt.Fprintf(w, "(%s)", t.Kind) 88 } 89 if t.Units != "" { 90 fmt.Fprintf(w, " units=%s", t.Units) 91 } 92 if t.Default != "" { 93 fmt.Fprintf(w, " default=%q", t.Default) 94 } 95 if t.FractionDigits != 0 { 96 fmt.Fprintf(w, " fraction-digits=%d", t.FractionDigits) 97 } 98 if len(t.Length) > 0 { 99 fmt.Fprintf(w, " length=%s", t.Length) 100 } 101 if t.Kind == yang.YinstanceIdentifier && !t.OptionalInstance { 102 fmt.Fprintf(w, " required") 103 } 104 if t.Kind == yang.Yleafref && t.Path != "" { 105 fmt.Fprintf(w, " path=%q", t.Path) 106 } 107 if len(t.Pattern) > 0 { 108 fmt.Fprintf(w, " pattern=%s", strings.Join(t.Pattern, "|")) 109 } 110 b := yang.BaseTypedefs[t.Kind.String()].YangType 111 if len(t.Range) > 0 && !t.Range.Equal(b.Range) { 112 fmt.Fprintf(w, " range=%s", t.Range) 113 } 114 if len(t.Type) > 0 { 115 fmt.Fprintf(w, "{\n") 116 for _, t := range t.Type { 117 printType(indent.NewWriter(w, " "), t, verbose) 118 } 119 fmt.Fprintf(w, "}") 120 } 121 fmt.Fprintf(w, ";\n") 122 } 123 124 func showall(w io.Writer, e *yang.Entry) { 125 if e == nil { 126 return 127 } 128 if e.Type != nil { 129 fmt.Fprintf(w, "\n%s\n ", e.Node.Statement().Location()) 130 printType(w, e.Type.Root, false) 131 } 132 for _, d := range e.Dir { 133 showall(w, d) 134 } 135 }