@@ -254,6 +254,8 @@ func findSetLeaves(s GoStruct, orderedMapAsLeaf bool, opts ...DiffOpt) (map[*pat
254254 return
255255 }
256256
257+ isYangPresence := hasRespectPresenceContainers (opts ) != nil && util .IsYangPresence (ni .StructField )
258+
257259 var sp [][]string
258260 if pathOpt != nil && pathOpt .PreferShadowPath {
259261 // Try the shadow-path tag first to see if it exists.
@@ -313,9 +315,10 @@ func findSetLeaves(s GoStruct, orderedMapAsLeaf bool, opts ...DiffOpt) (map[*pat
313315 // Ignore structs unless it is an ordered map and we're
314316 // treating it as a leaf (since it is assumed to be
315317 // telemetry-atomic in order to preserve ordering of entries).
316- if ( ! isOrderedMap || ! orderedMapAsLeaf ) && util . IsValueStructPtr ( ni . FieldValue ) {
318+ if util . IsValueStructPtr ( ni . FieldValue ) && ( ! isOrderedMap || ! orderedMapAsLeaf ) && ! isYangPresence {
317319 return
318320 }
321+
319322 if isOrderedMap && orderedMap .Len () == 0 {
320323 return
321324 }
@@ -335,7 +338,15 @@ func findSetLeaves(s GoStruct, orderedMapAsLeaf bool, opts ...DiffOpt) (map[*pat
335338 }
336339
337340 outs := out .(map [* pathSpec ]interface {})
338- outs [vp ] = ival
341+ if isYangPresence {
342+ // If the current field is tagged as a presence container,
343+ // we set it's value to `nil` instead of returning earlier.
344+ // This is because empty presence containers has a meaning,
345+ // unlike a normal container.
346+ outs [vp ] = nil
347+ } else {
348+ outs [vp ] = ival
349+ }
339350
340351 if isOrderedMap && orderedMapAsLeaf {
341352 // We treat the ordered map as a leaf, so don't
@@ -426,6 +437,24 @@ func hasIgnoreAdditions(opts []DiffOpt) *IgnoreAdditions {
426437 return nil
427438}
428439
440+ // The RespectPresenceContainers DiffOpt indicates that presence containers
441+ // should be respected in the diff output.
442+ // This option was added to ensure we do not break backward compatibility.
443+ type WithRespectPresenceContainers struct {}
444+
445+ func (* WithRespectPresenceContainers ) IsDiffOpt () {}
446+
447+ // hasIgnoreAdditions returns the first IgnoreAdditions from an opts slice, or
448+ // nil if there isn't one.
449+ func hasRespectPresenceContainers (opts []DiffOpt ) * WithRespectPresenceContainers {
450+ for _ , o := range opts {
451+ if rp , ok := o .(* WithRespectPresenceContainers ); ok {
452+ return rp
453+ }
454+ }
455+ return nil
456+ }
457+
429458// DiffPathOpt is a DiffOpt that allows control of the path behaviour of the
430459// Diff function.
431460type DiffPathOpt struct {
0 commit comments