Skip to content

Commit 816a0f6

Browse files
authored
Support JSON Marshalling augments to compressed schemas (#572)
* Correctly marshal JSON for augments in compressed containers. * Extend `findSchemaPath` and `findMapPaths` to return a path of module names that correspond with the paths. e.g. "(shadow-)path:config/name|name" -> "(shadow-)module:modA/modB|modA" * Removed a small existing hack whereby error from `InstantiatingModule` was being ignored. * Change `structJSON` to use the corresponding modules when determining whether to prefix node names with corresponding module names. * Added helper `structTagToLibModules` sister to existing `structTagToLibPaths` to extract modules tag. Testing: * Added compressed augment unit test for `findMapPaths` and JSON marshalling. * Added integration test for generating a compressed augment. * Other integration tests updated to test `module` and `shadow-module` generation. Other Testing Changes: * Changed tests for `findSchemaPath` and `findMapPaths` to create `yang.Entry` objects using `Modules.Process` instead of manually creating them. * Populated `.Modules` field for other tests in order to avoid errors due to above-mentioned hack being removed. * Move function to util and refactor structJSON. * Update goyang to v0.2.9
1 parent 47eb900 commit 816a0f6

File tree

49 files changed

+121473
-120910
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+121473
-120910
lines changed

exampleoc/oc.go

Lines changed: 40078 additions & 40052 deletions
Large diffs are not rendered by default.

exampleoc/opstateoc/oc.go

Lines changed: 40143 additions & 40129 deletions
Large diffs are not rendered by default.

exampleoc/wrapperunionoc/oc.go

Lines changed: 40101 additions & 40084 deletions
Large diffs are not rendered by default.

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ require (
88
github.com/google/go-cmp v0.5.5
99
github.com/kylelemons/godebug v1.1.0
1010
github.com/openconfig/gnmi v0.0.0-20200508230933-d19cebf5e7be
11-
github.com/openconfig/goyang v0.2.8
11+
github.com/openconfig/goyang v0.2.9
1212
github.com/openconfig/gribi v0.1.1-0.20210423184541-ce37eb4ba92f
1313
github.com/pmezard/go-difflib v1.0.0
1414
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ github.com/openconfig/gnmi v0.0.0-20200508230933-d19cebf5e7be h1:VEK8utxoyZu/hkp
4444
github.com/openconfig/gnmi v0.0.0-20200508230933-d19cebf5e7be/go.mod h1:M/EcuapNQgvzxo1DDXHK4tx3QpYM/uG4l591v33jG2A=
4545
github.com/openconfig/goyang v0.0.0-20200115183954-d0a48929f0ea/go.mod h1:dhXaV0JgHJzdrHi2l+w0fZrwArtXL7jEFoiqLEdmkvU=
4646
github.com/openconfig/goyang v0.2.2/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8=
47-
github.com/openconfig/goyang v0.2.8 h1:TAdUM9k+MP3GccppsrvJhDEnOA7zpp7hpakKI7qczPU=
48-
github.com/openconfig/goyang v0.2.8/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8=
47+
github.com/openconfig/goyang v0.2.9 h1:Z95LskKYk6nBYOxHtmJCu3YEKlr3pJLWG1tYAaNh3yU=
48+
github.com/openconfig/goyang v0.2.9/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8=
4949
github.com/openconfig/gribi v0.1.1-0.20210423184541-ce37eb4ba92f h1:8vRtC+y0xh9BYPrEGf/jG/paYXiDUJ6P8iYt5rCVols=
5050
github.com/openconfig/gribi v0.1.1-0.20210423184541-ce37eb4ba92f/go.mod h1:OoH46A2kV42cIXGyviYmAlGmn6cHjGduyC2+I9d/iVs=
5151
github.com/openconfig/ygot v0.6.0/go.mod h1:o30svNf7O0xK+R35tlx95odkDmZWS9JyWWQSmIhqwAs=

testdata/modules/openconfig-simple-augment.yang

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,9 @@ module openconfig-simple-augment {
1515
}
1616
}
1717
}
18+
19+
augment "/t:native/state" {
20+
leaf b { type string; }
21+
}
1822
}
1923

ygen/directory.go

Lines changed: 49 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -137,67 +137,92 @@ func GetOrderedDirectories(directory map[string]*Directory) ([]string, map[strin
137137
// of a Directory. The Field is specified as a name in order to guarantee its
138138
// existence before processing.
139139
func FindSchemaPath(parent *Directory, fieldName string, absolutePaths bool) ([]string, error) {
140-
return findSchemaPath(parent, fieldName, false, absolutePaths)
140+
schemaPaths, _, err := findSchemaPath(parent, fieldName, false, absolutePaths)
141+
return schemaPaths, err
141142
}
142143

143144
// findSchemaPath finds the relative or absolute schema path of a given field
144-
// of a Directory, or the shadowed field path (field duplicated and
145-
// deprioritized via compression) of a Directory. The Field is specified as a
146-
// name in order to guarantee its existence before processing.
145+
// of a Directory, or the shadowed field path (i.e. field duplicated and
146+
// deprioritized via compression) of a Directory. The first returned slice
147+
// contains the names of the path elements, and the second contains the
148+
// corresponding module names for each path element's resident namespace. The
149+
// Field is specified as a name in order to guarantee its existence before
150+
// processing.
147151
// NOTE: If shadowSchemaPaths is true, no error is returned if fieldName is not found.
148-
func findSchemaPath(parent *Directory, fieldName string, shadowSchemaPaths, absolutePaths bool) ([]string, error) {
152+
func findSchemaPath(parent *Directory, fieldName string, shadowSchemaPaths, absolutePaths bool) ([]string, []string, error) {
149153
field, ok := parent.Fields[fieldName]
150154
if shadowSchemaPaths {
151155
if field, ok = parent.ShadowedFields[fieldName]; !ok {
152-
return nil, nil
156+
return nil, nil, nil
153157
}
154158
}
155159
if !ok {
156-
return nil, fmt.Errorf("FindSchemaPath(shadowSchemaPaths:%v): field name %q does not exist in Directory %s", shadowSchemaPaths, fieldName, parent.Path)
160+
return nil, nil, fmt.Errorf("FindSchemaPath(shadowSchemaPaths:%v): field name %q does not exist in Directory %s", shadowSchemaPaths, fieldName, parent.Path)
157161
}
158162
fieldSlicePath := util.SchemaPathNoChoiceCase(field)
163+
var fieldSliceModules []string
164+
for _, e := range util.SchemaEntryPathNoChoiceCase(field) {
165+
im, err := e.InstantiatingModule()
166+
if err != nil {
167+
return nil, nil, fmt.Errorf("FindSchemaPath(shadowSchemaPaths:%v): cannot find instantiating module for field %q in Directory %s: %v", shadowSchemaPaths, fieldName, parent.Path, err)
168+
}
169+
fieldSliceModules = append(fieldSliceModules, im)
170+
}
159171

160172
if absolutePaths {
161-
return append([]string{""}, fieldSlicePath[1:]...), nil
173+
return append([]string{""}, fieldSlicePath[1:]...), append([]string{""}, fieldSliceModules[1:]...), nil
162174
}
163175
// Return the elements that are not common between the two paths.
164176
// Since the field is necessarily a child of the parent, then to
165177
// determine those elements of the field's path that are not contained
166178
// in the parent's, we walk from index X of the field's path (where X
167179
// is the number of elements in the path of the parent).
168180
if len(fieldSlicePath) < len(parent.Path) {
169-
return nil, fmt.Errorf("FindSchemaPath(shadowSchemaPaths:%v): field %v is not a valid child of %v", shadowSchemaPaths, fieldSlicePath, parent.Path)
181+
return nil, nil, fmt.Errorf("FindSchemaPath(shadowSchemaPaths:%v): field %v is not a valid child of %v", shadowSchemaPaths, fieldSlicePath, parent.Path)
170182
}
171-
return fieldSlicePath[len(parent.Path)-1:], nil
183+
return fieldSlicePath[len(parent.Path)-1:], fieldSliceModules[len(parent.Path)-1:], nil
172184
}
173185

174-
// findMapPaths takes an input field name for a parent Directory and calculates the set of schemapaths that it represents.
175-
// If absolutePaths is set, the paths are absolute otherwise they are relative to the parent. If
186+
// findMapPaths takes an input field name for a parent Directory and calculates
187+
// the set of schema paths it represents, as well as the corresponding module
188+
// names for each schema path element's resident namespace.
189+
// If absolutePaths is set, the paths are absolute; otherwise, they are relative to the parent. If
176190
// the input entry is a key to a list, and is of type leafref, then the corresponding target leaf's
177191
// path is also returned. If shadowSchemaPaths is set, then the path of the
178192
// field deprioritized via compression is returned instead of the prioritized paths.
179193
// The first returned path is the path of the direct child, with the shadow
180194
// child's path afterwards, and the key leafref, if any, last.
181-
func findMapPaths(parent *Directory, fieldName string, compressPaths, shadowSchemaPaths, absolutePaths bool) ([][]string, error) {
182-
childPath, err := findSchemaPath(parent, fieldName, shadowSchemaPaths, absolutePaths)
195+
func findMapPaths(parent *Directory, fieldName string, compressPaths, shadowSchemaPaths, absolutePaths bool) ([][]string, [][]string, error) {
196+
childPath, childModulePath, err := findSchemaPath(parent, fieldName, shadowSchemaPaths, absolutePaths)
183197
if err != nil {
184-
return nil, err
198+
return nil, nil, err
185199
}
186-
var mapPaths [][]string
200+
var mapPaths, mapModulePaths [][]string
187201
if childPath != nil {
188202
mapPaths = append(mapPaths, childPath)
189203
}
204+
if childModulePath != nil {
205+
mapModulePaths = append(mapModulePaths, childModulePath)
206+
}
190207
// Only for compressed data schema paths for list fields do we have the
191208
// possibility for a direct leafref path as a second path for the field.
192209
if !compressPaths || parent.ListAttr == nil {
193-
return mapPaths, nil
210+
return mapPaths, mapModulePaths, nil
194211
}
195212

196213
field, ok := parent.Fields[fieldName]
197214
if !ok {
198-
return nil, fmt.Errorf("field name %s does not exist in Directory %s", fieldName, parent.Path)
215+
return nil, nil, fmt.Errorf("field name %s does not exist in Directory %s", fieldName, parent.Path)
199216
}
200217
fieldSlicePath := util.SchemaPathNoChoiceCase(field)
218+
var fieldSliceModules []string
219+
for _, e := range util.SchemaEntryPathNoChoiceCase(field) {
220+
im, err := e.InstantiatingModule()
221+
if err != nil {
222+
return nil, nil, fmt.Errorf("FindSchemaPath(shadowSchemaPaths:%v): cannot find instantiating module for field %q in Directory %s: %v", shadowSchemaPaths, fieldName, parent.Path, err)
223+
}
224+
fieldSliceModules = append(fieldSliceModules, im)
225+
}
201226

202227
// Handle specific issue of compressed path schemas, where a key of the
203228
// parent list is a leafref to this leaf.
@@ -210,7 +235,7 @@ func findMapPaths(parent *Directory, fieldName string, compressPaths, shadowSche
210235
// leafref leaf within the schema as well as the target of the
211236
// leafref.
212237
if k.Parent == nil || k.Parent.Parent == nil || k.Parent.Parent.Dir[k.Name] == nil || k.Parent.Parent.Dir[k.Name].Type == nil {
213-
return nil, fmt.Errorf("invalid compressed schema, could not find the key %s or the grandparent of %s", k.Name, k.Path())
238+
return nil, nil, fmt.Errorf("invalid compressed schema, could not find the key %s or the grandparent of %s", k.Name, k.Path())
214239
}
215240

216241
// If a key of the list is a leafref that points to the field,
@@ -223,15 +248,19 @@ func findMapPaths(parent *Directory, fieldName string, compressPaths, shadowSche
223248
// list, since the YANG specification enforces that keys are direct
224249
// children of the list.
225250
keyPath := []string{fieldSlicePath[len(fieldSlicePath)-1]}
251+
keyModulePath := []string{fieldSliceModules[len(fieldSliceModules)-1]}
226252
if absolutePaths {
227253
// If absolute paths are required, then the 'config' or 'state' container needs to be omitted from
228254
// the complete path for the secondary mapping.
229255
keyPath = append([]string{""}, fieldSlicePath[1:len(fieldSlicePath)-2]...)
230256
keyPath = append(keyPath, fieldSlicePath[len(fieldSlicePath)-1])
257+
keyModulePath = append([]string{""}, fieldSliceModules[1:len(fieldSliceModules)-2]...)
258+
keyModulePath = append(keyModulePath, fieldSliceModules[len(fieldSliceModules)-1])
231259
}
232260
mapPaths = append(mapPaths, keyPath)
261+
mapModulePaths = append(mapModulePaths, keyModulePath)
233262
break
234263
}
235264
}
236-
return mapPaths, nil
265+
return mapPaths, mapModulePaths, nil
237266
}

0 commit comments

Comments
 (0)