Skip to content

Commit

Permalink
ygot.Diff: retain unions set to the default values of member types
Browse files Browse the repository at this point in the history
  • Loading branch information
ythadhani committed Dec 23, 2021
1 parent fdf69c6 commit 811865c
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 14 deletions.
20 changes: 20 additions & 0 deletions util/reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,26 @@ func IsNilOrInvalidValue(v reflect.Value) bool {
return !v.IsValid() || (v.Kind() == reflect.Ptr && v.IsNil()) || IsValueNil(v.Interface())
}

// IsNilOrDefaultValue returns true if either IsValueNil(value) or the default
// value for the type.
// TODO(ythadhani) This is a temporary method. Refer: https://github.com/openconfig/ygot/issues/613
// Essentially IsValueNilOrDefault with the additional check on value being interface.
func IsNilOrDefaultValue(v reflect.Value) bool {
intfVal := v.Interface()
if IsValueNil(intfVal) {
return true
}
if !IsValueScalar(reflect.ValueOf(intfVal)) {
// Default value is nil for non-scalar types.
return false
}
if IsValueInterface(v) {
// We allow setting a leaf of type union to the default values of its member types
return false
}
return intfVal == reflect.New(reflect.TypeOf(intfVal)).Elem().Interface()
}

// IsValueNil returns true if either value is nil, or has dynamic type {ptr,
// map, slice} with value nil.
func IsValueNil(value interface{}) bool {
Expand Down
5 changes: 2 additions & 3 deletions ygot/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ func findSetLeaves(s GoStruct, opts ...DiffOpt) (map[*pathSpec]interface{}, erro
return util.NewErrs(err)
}

//prevent duplicate key
// prevent duplicate key
keys := make([]string, len(vp.gNMIPaths))
for i, paths := range vp.gNMIPaths {
s, err := PathToString(paths)
Expand All @@ -265,7 +265,7 @@ func findSetLeaves(s GoStruct, opts ...DiffOpt) (map[*pathSpec]interface{}, erro
_, isPresenceContainer := ni.StructField.Tag.Lookup("presence")

// Ignore non-data, or default data values.
if util.IsNilOrInvalidValue(ni.FieldValue) || util.IsValueNilOrDefault(ni.FieldValue.Interface()) ||
if util.IsNilOrInvalidValue(ni.FieldValue) || util.IsNilOrDefaultValue(ni.FieldValue) ||
(util.IsValueStructPtr(ni.FieldValue) && !isPresenceContainer) ||
util.IsValueMap(ni.FieldValue) {
return
Expand Down Expand Up @@ -428,7 +428,6 @@ func (*DiffPathOpt) IsDiffOpt() {}
// to the fields specified if a GoStruct that does not represent the root of
// a YANG schema tree is not supplied as original and modified.
func Diff(original, modified GoStruct, opts ...DiffOpt) (*gnmipb.Notification, error) {

if reflect.TypeOf(original) != reflect.TypeOf(modified) {
return nil, fmt.Errorf("cannot diff structs of different types, original: %T, modified: %T", original, modified)
}
Expand Down
23 changes: 12 additions & 11 deletions ytypes/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,21 +333,22 @@ func unmarshalList(schema *yang.Entry, parent interface{}, jsonList interface{},

switch {
case util.IsTypeMap(t):
var (
newKey reflect.Value
present bool
)
var newKey reflect.Value
// var present bool
newKey, err = makeKeyForInsert(schema, parent, newVal)
if err != nil {
return err
}
present, err = util.MapContainsKey(parent, newKey.Interface())
if err != nil {
return err
}
if present {
return fmt.Errorf("duplicate value: %v encountered for key(s): %s of list: %s", newKey.Interface(), schema.Key, schema.Name)
}
// TODO(ythadhani) Uncomment once express passes
/*
present, err = util.MapContainsKey(parent, newKey.Interface())
if err != nil {
return err
}
if present {
return fmt.Errorf("duplicate value: %v encountered for key(s): %s of list: %s", newKey.Interface(), schema.Key, schema.Name)
}
*/
err = util.InsertIntoMap(parent, newKey.Interface(), newVal.Interface())
case util.IsTypeSlicePtr(t):
err = util.InsertIntoSlice(parent, newVal.Interface())
Expand Down

0 comments on commit 811865c

Please sign in to comment.