|
| 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/yang" |
| 23 | +) |
| 24 | + |
| 25 | +var allimports = make(map[string]string) |
| 26 | +var modules = make(map[string]*yang.Module) |
| 27 | + |
| 28 | +func init() { |
| 29 | + register(&formatter{ |
| 30 | + name: "annotate", |
| 31 | + f: genAnnotate, |
| 32 | + utilf: getFile, |
| 33 | + help: "generate template file for yang annotations", |
| 34 | + }) |
| 35 | +} |
| 36 | + |
| 37 | +// Get the modules for which annotation file needs to be generated |
| 38 | +func getFile(files []string, mods map[string]*yang.Module) { |
| 39 | + for _, name := range files { |
| 40 | + slash := strings.Split(name, "/") |
| 41 | + if strings.HasSuffix(name, ".yang") { |
| 42 | + modname := slash[len(slash)-1] |
| 43 | + modname = strings.TrimSuffix(modname, ".yang"); |
| 44 | + /* Save the yang.Module entries we are interested in */ |
| 45 | + modules[modname] = mods[modname] |
| 46 | + } |
| 47 | + } |
| 48 | +} |
| 49 | + |
| 50 | +func genAnnotate(w io.Writer, entries []*yang.Entry) { |
| 51 | + /* Get all the imported modules in the entries */ |
| 52 | + GetAllImports(entries) |
| 53 | + for _, e := range entries { |
| 54 | + if _, ok := modules[e.Name]; ok { |
| 55 | + var path string = "" |
| 56 | + generate(w, e, path) |
| 57 | + // { Add closing brace for each module |
| 58 | + fmt.Fprintln(w, "}") |
| 59 | + fmt.Fprintln(w) |
| 60 | + } |
| 61 | + } |
| 62 | +} |
| 63 | + |
| 64 | +// generate writes to stdoutput a template annotation file entry for the selected modules. |
| 65 | +func generate(w io.Writer, e *yang.Entry, path string) { |
| 66 | + if e.Parent == nil { |
| 67 | + if e.Name != "" { |
| 68 | + fmt.Fprintf(w, "module %s-annot {\n", e.Name) //} |
| 69 | + fmt.Fprintln(w) |
| 70 | + fmt.Fprintf(w, " yang-version \"%s\"\n", getYangVersion(e.Name, modules)) |
| 71 | + fmt.Fprintln(w) |
| 72 | + fmt.Fprintf(w, " namespace \"http://openconfig.net/yang/annotation\";\n") |
| 73 | + if e.Prefix != nil { |
| 74 | + fmt.Fprintf(w, " prefix \"%s-annot\" \n", e.Prefix.Name) |
| 75 | + } |
| 76 | + fmt.Fprintln(w) |
| 77 | + |
| 78 | + var imports = make(map[string]string) |
| 79 | + imports = getImportModules(e.Name, modules) |
| 80 | + for k := range imports { |
| 81 | + if e.Name != k { |
| 82 | + fmt.Fprintf(w, " import %s { prefix %s }\n", k, allimports[k]) |
| 83 | + } |
| 84 | + } |
| 85 | + |
| 86 | + fmt.Fprintln(w) |
| 87 | + } |
| 88 | + } |
| 89 | + |
| 90 | + name := e.Name |
| 91 | + if e.Prefix != nil { |
| 92 | + name = e.Prefix.Name + ":" + name |
| 93 | + } |
| 94 | + |
| 95 | + delim := "" |
| 96 | + if path != "" { |
| 97 | + delim = "/" |
| 98 | + } |
| 99 | + path = path + delim + name |
| 100 | + |
| 101 | + fmt.Fprintf(w, " deviation %s {\n", path) |
| 102 | + fmt.Fprintf(w, " deviate add {\n") |
| 103 | + fmt.Fprintf(w, " }\n") |
| 104 | + fmt.Fprintf(w, " }\n") |
| 105 | + fmt.Fprintln(w) |
| 106 | + |
| 107 | + var names []string |
| 108 | + for k := range e.Dir { |
| 109 | + names = append(names, k) |
| 110 | + } |
| 111 | + |
| 112 | + for _, k := range names { |
| 113 | + generate(w, e.Dir[k], path) |
| 114 | + } |
| 115 | + |
| 116 | +} |
| 117 | + |
| 118 | +// Save to map all imported modules |
| 119 | +func GetAllImports(entries []*yang.Entry) { |
| 120 | + for _, e := range entries { |
| 121 | + allimports[e.Name] = e.Prefix.Name |
| 122 | + } |
| 123 | +} |
| 124 | + |
| 125 | +//Get Yang version from the yang.Modules |
| 126 | +func getYangVersion(modname string, mods map[string]*yang.Module) string { |
| 127 | + if (mods[modname].YangVersion != nil) { |
| 128 | + return mods[modname].YangVersion.Name |
| 129 | + } |
| 130 | + return "" |
| 131 | + |
| 132 | +} |
| 133 | + |
| 134 | +// Get imported modules for a given module from yang.Module |
| 135 | +func getImportModules(modname string, mods map[string]*yang.Module) map[string]string { |
| 136 | + imports := map[string]string{} |
| 137 | + if (mods[modname].Import != nil) { |
| 138 | + for _, imp := range mods[modname].Import { |
| 139 | + imports[imp.Name] = imp.Prefix.Name |
| 140 | + } |
| 141 | + } |
| 142 | + return imports |
| 143 | +} |
0 commit comments