Skip to content

Commit

Permalink
Add ParseOption/DeviateOption to ignore not-supported statements (#238)
Browse files Browse the repository at this point in the history
  • Loading branch information
wenovus authored Dec 2, 2022
1 parent 03fa68f commit fc70dac
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 3 deletions.
6 changes: 4 additions & 2 deletions pkg/yang/entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -1098,7 +1098,7 @@ func (e *Entry) Augment(addErrors bool) (processed, skipped int) {

// ApplyDeviate walks the deviations within the supplied entry, and applies them to the
// schema.
func (e *Entry) ApplyDeviate() []error {
func (e *Entry) ApplyDeviate(deviateOpts ...DeviateOpt) []error {
var errs []error
appendErr := func(err error) { errs = append(errs, err) }
for _, d := range e.Deviations {
Expand Down Expand Up @@ -1168,7 +1168,9 @@ func (e *Entry) ApplyDeviate() []error {
appendErr(fmt.Errorf("%s: node %s does not have a valid parent, but deviate not-supported references one", Source(e.Node), e.Name))
continue
}
dp.delete(deviatedNode.Name)
if !hasIgnoreDeviateNotSupported(deviateOpts) {
dp.delete(deviatedNode.Name)
}
case DeviationDelete:
if devSpec.Config != TSUnset {
deviatedNode.Config = TSUnset
Expand Down
28 changes: 28 additions & 0 deletions pkg/yang/entry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2957,6 +2957,7 @@ func TestDeviation(t *testing.T) {
tests := []struct {
desc string
inFiles map[string]string
inParseOptions Options
wants map[string][]deviationTest
wantParseErrSubstring string
wantProcessErrSubstring string
Expand Down Expand Up @@ -3161,6 +3162,32 @@ func TestDeviation(t *testing.T) {
entry: &Entry{Name: "survivor"},
}},
},
}, {
desc: "deviation - not supported but ignored by option",
inFiles: map[string]string{"deviate": mustReadFile(filepath.Join("testdata", "deviate-notsupported.yang"))},
inParseOptions: Options{
DeviateOptions: DeviateOptions{
IgnoreDeviateNotSupported: true,
},
},
wants: map[string][]deviationTest{
"deviate": {{
path: "/target",
entry: &Entry{Name: "target"},
}, {
path: "/target-list",
entry: &Entry{Name: "target-list"},
}, {
path: "/a-leaf",
entry: &Entry{Name: "a-leaf"},
}, {
path: "/a-leaflist",
entry: &Entry{Name: "a-leaflist"},
}, {
path: "survivor",
entry: &Entry{Name: "survivor"},
}},
},
}, {
desc: "deviation removing non-existent node",
inFiles: map[string]string{
Expand Down Expand Up @@ -3527,6 +3554,7 @@ func TestDeviation(t *testing.T) {
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
ms := NewModules()
ms.ParseOptions = tt.inParseOptions

for name, mod := range tt.inFiles {
if err := ms.Parse(mod, name); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion pkg/yang/modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ func (ms *Modules) Process() []error {
for _, m := range devmods {
e := ToEntry(m)
if !dvP[e.Name] {
errs = append(errs, e.ApplyDeviate()...)
errs = append(errs, e.ApplyDeviate(ms.ParseOptions.DeviateOptions)...)
dvP[e.Name] = true
}
}
Expand Down
29 changes: 29 additions & 0 deletions pkg/yang/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,33 @@ type Options struct {
// generated within the schema to store the logical grouping from which it
// is derived.
StoreUses bool
// DeviateOptions contains options for how deviations are handled.
DeviateOptions DeviateOptions
}

// DeviateOptions contains options for how deviations are handled.
type DeviateOptions struct {
// IgnoreDeviateNotSupported indicates to the parser to retain nodes
// that are marked with "deviate not-supported". An example use case is
// where the user wants to interact with different targets that have
// different support for a leaf without having to use a second instance
// of an AST.
IgnoreDeviateNotSupported bool
}

// IsDeviateOpt ensures that DeviateOptions satisfies the DeviateOpt interface.
func (DeviateOptions) IsDeviateOpt() {}

// DeviateOpt is an interface that can be used in function arguments.
type DeviateOpt interface {
IsDeviateOpt()
}

func hasIgnoreDeviateNotSupported(opts []DeviateOpt) bool {
for _, o := range opts {
if opt, ok := o.(DeviateOptions); ok {
return opt.IgnoreDeviateNotSupported
}
}
return false
}

0 comments on commit fc70dac

Please sign in to comment.