github.com/openconfig/goyang@v1.4.5/tree.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  	"sort"
    21  
    22  	"github.com/openconfig/goyang/pkg/indent"
    23  	"github.com/openconfig/goyang/pkg/yang"
    24  )
    25  
    26  func init() {
    27  	register(&formatter{
    28  		name: "tree",
    29  		f:    doTree,
    30  		help: "display in a tree format",
    31  	})
    32  }
    33  
    34  func doTree(w io.Writer, entries []*yang.Entry) {
    35  	for _, e := range entries {
    36  		Write(w, e)
    37  	}
    38  }
    39  
    40  // Write writes e, formatted, and all of its children, to w.
    41  func Write(w io.Writer, e *yang.Entry) {
    42  	if e.Description != "" {
    43  		fmt.Fprintln(w)
    44  		fmt.Fprintln(indent.NewWriter(w, "// "), e.Description)
    45  	}
    46  	if len(e.Exts) > 0 {
    47  		fmt.Fprintf(w, "extensions: {\n")
    48  		for _, ext := range e.Exts {
    49  			if n := ext.NName(); n != "" {
    50  				fmt.Fprintf(w, "  %s %s;\n", ext.Kind(), n)
    51  			} else {
    52  				fmt.Fprintf(w, "  %s;\n", ext.Kind())
    53  			}
    54  		}
    55  		fmt.Fprintln(w, "}")
    56  	}
    57  	switch {
    58  	case e.RPC != nil:
    59  		fmt.Fprintf(w, "RPC: ")
    60  	case e.ReadOnly():
    61  		fmt.Fprintf(w, "RO: ")
    62  	default:
    63  		fmt.Fprintf(w, "rw: ")
    64  	}
    65  	if e.Type != nil {
    66  		fmt.Fprintf(w, "%s ", getTypeName(e))
    67  	}
    68  	name := e.Name
    69  	if e.Prefix != nil {
    70  		name = e.Prefix.Name + ":" + name
    71  	}
    72  	switch {
    73  	case e.Dir == nil && e.ListAttr != nil:
    74  		fmt.Fprintf(w, "[]%s\n", name)
    75  		return
    76  	case e.Dir == nil:
    77  		fmt.Fprintf(w, "%s\n", name)
    78  		return
    79  	case e.ListAttr != nil:
    80  		fmt.Fprintf(w, "[%s]%s {\n", e.Key, name) //}
    81  	default:
    82  		fmt.Fprintf(w, "%s {\n", name) //}
    83  	}
    84  	if r := e.RPC; r != nil {
    85  		if r.Input != nil {
    86  			Write(indent.NewWriter(w, "  "), r.Input)
    87  		}
    88  		if r.Output != nil {
    89  			Write(indent.NewWriter(w, "  "), r.Output)
    90  		}
    91  	}
    92  	var names []string
    93  	for k := range e.Dir {
    94  		names = append(names, k)
    95  	}
    96  	sort.Strings(names)
    97  	for _, k := range names {
    98  		Write(indent.NewWriter(w, "  "), e.Dir[k])
    99  	}
   100  	// { to match the brace below to keep brace matching working
   101  	fmt.Fprintln(w, "}")
   102  }
   103  
   104  func getTypeName(e *yang.Entry) string {
   105  	if e == nil || e.Type == nil {
   106  		return ""
   107  	}
   108  	// Return our root's type name.
   109  	// This is should be the builtin type-name
   110  	// for this entry.
   111  	return e.Type.Root.Name
   112  }