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  }