Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 28 additions & 8 deletions pkg/yang/entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -683,18 +683,32 @@ func ToEntry(n Node) (e *Entry) {
}
// apply refinement according to https://datatracker.ietf.org/doc/html/rfc7950#section-7.13.2
// as best as we can

// o A leaf or choice node may get a default value, or a new default
// value if it already had one.
//
// o A leaf-list node may get a set of default values, or a new set of
// default values if it already had defaults; i.e., the set of
// refined default values replaces the defaults already given.
if refine.Default != nil {
// TODO: do it
_ = refine.Default
}
//
// o A leaf or choice node may get a default value, or a new default
// value if it already had one.
if len(refine.Defaults) != 0 {
switch refineTarget.Node.(type) {
case *Leaf, *LeafList, *Choice:
if refineTarget.ListAttr != nil {
refineTarget.Default = []string{}
for _, def := range refine.Defaults {
refineTarget.Default = append(refineTarget.Default, def.Name)
}
} else {
if len(refine.Defaults) > 1 {
return newError(refine, "only single default value allowed on leaf")
}
refineTarget.Default = []string{refine.Defaults[0].Name}
}
default:
return newError(refine, "refine default value only allowed on leaf, choice-node or leaf-list")
}

}
//
// o Any node may get a specialized "description" string.
if refine.Description != nil {
Expand All @@ -720,7 +734,13 @@ func ToEntry(n Node) (e *Entry) {
}

// o A container node may get a "presence" statement.
// TODO(): presence statement
if refine.Presence != nil {
if _, ok := refineTarget.Node.(*Container); !ok {
return newError(refine, "presence statement only allowed on container")
}
// We overwrite the current presence value and do not append
refineTarget.Extra["presence"] = []interface{}{&Value{Name: refine.Presence.Name}}
}

// o A leaf-list or list node may get a different "min-elements" or
// "max-elements" statement.
Expand Down
2 changes: 1 addition & 1 deletion pkg/yang/yang.go
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ type Refine struct {
Parent Node `yang:"Parent,nomerge"`
Extensions []*Statement `yang:"Ext"`

Default *Value `yang:"default"`
Defaults []*Value `yang:"default"`
Description *Value `yang:"description"`
IfFeature []*Value `yang:"if-feature"`
Reference *Value `yang:"reference"`
Expand Down
2 changes: 2 additions & 0 deletions testdata/base.yang
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ module base {
prefix "base";

include sub;
include refine-tests;
include presence-tests;
import other {
prefix bother;
}
Expand Down
22 changes: 22 additions & 0 deletions testdata/presence-tests.yang
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
submodule presence-tests {
belongs-to base { prefix "sbase"; }

// sample presence
container presence-example-container {
presence "the presence of this container means something";
}

grouping grouping-no-presence {
container container-no-presence {}
}

container container-with-presence {
uses grouping-no-presence {
refine container-no-presence {
presence "this presence was added with a refine";
}
}
}


}
48 changes: 48 additions & 0 deletions testdata/refine-tests.yang
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
submodule refine-tests {
belongs-to base { prefix "sbase"; }
grouping refine-sub-group {
leaf refine-sub-group-leaf {
type string;
default "initial-default";
}
}

// sample refine description
container refine-description {
uses refine-sub-group {
refine "refine-sub-group-leaf" {
description "new refined description";
}
}
}

// sample refine leaf default
container refine-default {
uses refine-sub-group {
refine refine-sub-group-leaf {
default "refined-default-string";
}
}
}

grouping fruit-bowl {
description
"A bowl with a few pieces of fruit by default.";
leaf-list fruit {
type string;
default "apple";
default "banana";
}
}

// sample refine leaf-list defaults
container exotic-bowl {
uses fruit-bowl {
refine fruit {
default "mango";
default "papaya";
}
}
}

}
15 changes: 15 additions & 0 deletions tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"fmt"
"io"
"sort"
"strings"

"github.com/openconfig/goyang/pkg/indent"
"github.com/openconfig/goyang/pkg/yang"
Expand Down Expand Up @@ -69,6 +70,9 @@ func Write(w io.Writer, e *yang.Entry) {
if e.Prefix != nil {
name = e.Prefix.Name + ":" + name
}
if e.Default != nil {
name = name + " default: " + strings.Join(e.Default, ",")
}
switch {
case e.Dir == nil && e.ListAttr != nil:
fmt.Fprintf(w, "[]%s\n", name)
Expand Down Expand Up @@ -97,6 +101,17 @@ func Write(w io.Writer, e *yang.Entry) {
for _, k := range names {
Write(indent.NewWriter(w, " "), e.Dir[k])
}
if e.Extra != nil {
val, ok := e.Extra["presence"]
if ok {
switch v := val[0].(type) {
case *yang.Value:
fmt.Fprintf(w, "presence: %s\n", v.Name)
default:
fmt.Fprintf(w, "presence: %s\n", val)
}
}
}
// { to match the brace below to keep brace matching working
fmt.Fprintln(w, "}")
}
Expand Down