diff --git a/ygen/directory.go b/ygen/directory.go index 483ce5594..fc838fa68 100644 --- a/ygen/directory.go +++ b/ygen/directory.go @@ -202,6 +202,7 @@ func getOrderedDirDetails(langMapper LangMapper, directory map[string]*Directory pd.Fields = make(map[string]*NodeDetails, len(dir.Fields)) for _, fn := range GetOrderedFieldNames(dir) { field := dir.Fields[fn] + shadowField, hasShadowField := dir.ShadowedFields[fn] mp, mm, err := findMapPaths(dir, fn, opts.TransformationOptions.CompressBehaviour.CompressEnabled(), false, opts.AbsoluteMapPaths) if err != nil { @@ -252,6 +253,9 @@ func getOrderedDirDetails(langMapper LangMapper, directory map[string]*Directory ShadowMappedPaths: smp, ShadowMappedPathModules: smm, } + if hasShadowField { + nd.YANGDetails.ShadowSchemaPath = util.SchemaTreePathNoModule(shadowField) + } switch { case field.IsLeaf(), field.IsLeafList(): diff --git a/ygen/genir_test.go b/ygen/genir_test.go index e46727560..6cbddbf47 100644 --- a/ygen/genir_test.go +++ b/ygen/genir_test.go @@ -174,6 +174,7 @@ func TestGenerateIR(t *testing.T) { DefiningModule: "openconfig-simple", Path: "/openconfig-simple/parent/child/config/one", SchemaPath: "/parent/child/config/one", + ShadowSchemaPath: "/parent/child/state/one", LeafrefTargetPath: "", Description: "", Type: &YANGType{Name: "string"}, @@ -228,6 +229,7 @@ func TestGenerateIR(t *testing.T) { DefiningModule: "openconfig-simple", Path: "/openconfig-simple/parent/child/config/three", SchemaPath: "/parent/child/config/three", + ShadowSchemaPath: "/parent/child/state/three", LeafrefTargetPath: "", Description: "", Type: &YANGType{Name: "enumeration"}, @@ -255,6 +257,7 @@ func TestGenerateIR(t *testing.T) { DefiningModule: "openconfig-simple", Path: "/openconfig-simple/parent/child/config/four", SchemaPath: "/parent/child/config/four", + ShadowSchemaPath: "/parent/child/state/four", LeafrefTargetPath: "", Description: "", Type: &YANGType{Name: "binary"}, @@ -292,6 +295,7 @@ func TestGenerateIR(t *testing.T) { DefiningModule: "openconfig-remote", Path: "/openconfig-simple/remote-container/config/a-leaf", SchemaPath: "/remote-container/config/a-leaf", + ShadowSchemaPath: "/remote-container/state/a-leaf", LeafrefTargetPath: "", Description: "", Type: &YANGType{Name: "string"}, @@ -463,6 +467,7 @@ func TestGenerateIR(t *testing.T) { DefiningModule: "openconfig-simple", Path: "/openconfig-simple/parent/child/state/one", SchemaPath: "/parent/child/state/one", + ShadowSchemaPath: "/parent/child/config/one", LeafrefTargetPath: "", Description: "", Type: &YANGType{Name: "string"}, @@ -517,6 +522,7 @@ func TestGenerateIR(t *testing.T) { DefiningModule: "openconfig-simple", Path: "/openconfig-simple/parent/child/state/three", SchemaPath: "/parent/child/state/three", + ShadowSchemaPath: "/parent/child/config/three", LeafrefTargetPath: "", Description: "", Type: &YANGType{Name: "enumeration"}, @@ -544,6 +550,7 @@ func TestGenerateIR(t *testing.T) { DefiningModule: "openconfig-simple", Path: "/openconfig-simple/parent/child/state/four", SchemaPath: "/parent/child/state/four", + ShadowSchemaPath: "/parent/child/config/four", LeafrefTargetPath: "", Description: "", Type: &YANGType{Name: "binary"}, @@ -581,6 +588,7 @@ func TestGenerateIR(t *testing.T) { DefiningModule: "openconfig-remote", Path: "/openconfig-simple/remote-container/state/a-leaf", SchemaPath: "/remote-container/state/a-leaf", + ShadowSchemaPath: "/remote-container/config/a-leaf", LeafrefTargetPath: "", Description: "", Type: &YANGType{Name: "string"}, @@ -1387,6 +1395,7 @@ func TestGenerateIR(t *testing.T) { DefiningModule: "openconfig-complex", Path: "/openconfig-complex/model/a/single-key/config/dates", SchemaPath: "/model/a/single-key/config/dates", + ShadowSchemaPath: "/model/a/single-key/state/dates", LeafrefTargetPath: "", Description: "", Type: &YANGType{Name: "weekday"}, @@ -1408,6 +1417,7 @@ func TestGenerateIR(t *testing.T) { DefiningModule: "openconfig-complex", Path: "/openconfig-complex/model/a/single-key/config/dates-with-defaults", SchemaPath: "/model/a/single-key/config/dates-with-defaults", + ShadowSchemaPath: "/model/a/single-key/state/dates-with-defaults", LeafrefTargetPath: "", Description: "", Type: &YANGType{Name: "weekday"}, @@ -1429,6 +1439,7 @@ func TestGenerateIR(t *testing.T) { DefiningModule: "openconfig-complex", Path: "/openconfig-complex/model/a/single-key/config/iref", SchemaPath: "/model/a/single-key/config/iref", + ShadowSchemaPath: "/model/a/single-key/state/iref", LeafrefTargetPath: "", Description: "", Type: &YANGType{Name: "identityref"}, @@ -1450,6 +1461,7 @@ func TestGenerateIR(t *testing.T) { DefiningModule: "openconfig-complex", Path: "/openconfig-complex/model/a/single-key/config/key", SchemaPath: "/model/a/single-key/config/key", + ShadowSchemaPath: "/model/a/single-key/state/key", LeafrefTargetPath: "", Description: "", Type: &YANGType{Name: "days-of-week"}, @@ -1475,6 +1487,7 @@ func TestGenerateIR(t *testing.T) { DefiningModule: "openconfig-complex", Path: "/openconfig-complex/model/a/single-key/config/leaf-default-override", SchemaPath: "/model/a/single-key/config/leaf-default-override", + ShadowSchemaPath: "/model/a/single-key/state/leaf-default-override", LeafrefTargetPath: "", Description: "", Type: &YANGType{Name: "cyclone-scales"}, @@ -1501,6 +1514,7 @@ func TestGenerateIR(t *testing.T) { DefiningModule: "openconfig-complex", Path: "/openconfig-complex/model/a/single-key/config/simple-union-enum", SchemaPath: "/model/a/single-key/config/simple-union-enum", + ShadowSchemaPath: "/model/a/single-key/state/simple-union-enum", LeafrefTargetPath: "", Description: "", Type: &YANGType{Name: "union"}, @@ -1527,6 +1541,7 @@ func TestGenerateIR(t *testing.T) { DefiningModule: "openconfig-complex", Path: "/openconfig-complex/model/a/single-key/config/singleton-union-enum", SchemaPath: "/model/a/single-key/config/singleton-union-enum", + ShadowSchemaPath: "/model/a/single-key/state/singleton-union-enum", LeafrefTargetPath: "", Description: "", Type: &YANGType{Name: "union"}, @@ -1554,6 +1569,7 @@ func TestGenerateIR(t *testing.T) { DefiningModule: "openconfig-complex", Path: "/openconfig-complex/model/a/single-key/config/typedef-enum", SchemaPath: "/model/a/single-key/config/typedef-enum", + ShadowSchemaPath: "/model/a/single-key/state/typedef-enum", LeafrefTargetPath: "", Description: "", Type: &YANGType{Name: "weekend-days"}, @@ -1580,6 +1596,7 @@ func TestGenerateIR(t *testing.T) { DefiningModule: "openconfig-complex", Path: "/openconfig-complex/model/a/single-key/config/typedef-union-enum", SchemaPath: "/model/a/single-key/config/typedef-union-enum", + ShadowSchemaPath: "/model/a/single-key/state/typedef-union-enum", LeafrefTargetPath: "", Description: "", Type: &YANGType{Name: "cyclone-scales"}, @@ -1629,6 +1646,7 @@ func TestGenerateIR(t *testing.T) { DefiningModule: "openconfig-complex", Path: "/openconfig-complex/model/b/multi-key/config/key1", SchemaPath: "/model/b/multi-key/config/key1", + ShadowSchemaPath: "/model/b/multi-key/state/key1", LeafrefTargetPath: "", Description: "", Type: &YANGType{Name: "uint32"}, @@ -1650,6 +1668,7 @@ func TestGenerateIR(t *testing.T) { DefiningModule: "openconfig-complex", Path: "/openconfig-complex/model/b/multi-key/config/key2", SchemaPath: "/model/b/multi-key/config/key2", + ShadowSchemaPath: "/model/b/multi-key/state/key2", LeafrefTargetPath: "", Description: "", Type: &YANGType{Name: "uint64"}, diff --git a/ygen/ir.go b/ygen/ir.go index 7e8c3ec27..6a00e9218 100644 --- a/ygen/ir.go +++ b/ygen/ir.go @@ -441,6 +441,18 @@ type YANGNodeDetails struct { // SchemaPath specifies the absolute YANG schema node path. It does not // include the module name nor choice/case elements in the YANG file. SchemaPath string + // ShadowSchemaPath, which specifies the absolute YANG schema node path + // of the "shadowed" sibling node, is included when a leaf exists in + // both 'intended' and 'applied' state of an OpenConfig schema (see + // https://datatracker.ietf.org/doc/html/draft-openconfig-netmod-opstate-01) + // and hence is within the 'config' and 'state' containers of the + // schema. ShadowSchemaPath is populated only when the -compress + // generator flag is used, and indicates the path of the node not + // represented in the generated IR based on the preference to prefer + // intended or applied leaves. + // Similar to SchemaPath, it does not include the module name nor + // choice/case elements. + ShadowSchemaPath string // LeafrefTargetPath is the absolute YANG schema node path of the // target node to which the leafref points via its path statement. Note // that this is *not* the recursively-resolved path.