func clearNonOverlayFields(ctx *visitorContext, val reflect.Value, typ reflect.Type) (retainAncestors bool) {
	for i := 0; i < typ.NumField(); i++ {
		structField := typ.Field(i)

		// Skip non-exportable and empty fields
		v := val.Field(i)
		if !v.CanInterface() || isZero(v) {
			continue
		}

		// If this is an overlay field we need to preserve it and all
		// its ancestor fields up to the root. However, we still need
		// to visit its descendants in case we need to clear additional
		// non-overlay fields further down the tree.
		isOverlayField := isOverlayField(structField)
		if isOverlayField {
			retainAncestors = true
		}

		target := v.Interface()
		if retain := visitField(ctx, target); !isOverlayField && !retain {
			v.Set(reflect.Zero(v.Type()))
			continue
		}

		retainAncestors = true
	}
	return retainAncestors
}
// clearNonOverlayFields is an implementation of structVisitor. It recursively
// visits all fields in the val struct and sets any field that does not contain
// any overlay-only descendants to the zero value for its particular type.
clearNonOverlayFields is an implementation of structVisitor. It recursively
visits all fields in the val struct and sets any field that does not contain
any overlay-only descendants to the zero value for its particular type.
// clearNonOverlayFields is an implementation of structVisitor . It recursively // visits all fields in the val struct and sets any field that does not contain // any overlay - only descendants to the zero value for its particular type .
func clearNonOverlayFields(ctx *visitorContext, val reflect.Value, typ reflect.Type) (retainAncestors bool) {
	for i := 0; i < typ.NumField(); i++ {
		structField := typ.Field(i)
		v := val.Field(i)
		if !v.CanInterface() || isZero(v) {
			continue
		}
		isOverlayField := isOverlayField(structField)
		if isOverlayField {
			retainAncestors = true
		}
		target := v.Interface()
		if retain := visitField(ctx, target); !isOverlayField && !retain {
			v.Set(reflect.Zero(v.Type()))
			continue
		}
		retainAncestors = true
	}
	return retainAncestors
}
func clearNonOverlayFields ( ctx * visitorContext , val reflect . Value , typ reflect . Type ) ( retainAncestors bool ) { for i := 0 ; i < typ . NumField ( ) ; i ++ { structField := typ . Field ( i ) v := val . Field ( i ) if ! v . CanInterface ( ) || isZero ( v ) { continue } isOverlayField := isOverlayField ( structField ) if isOverlayField { retainAncestors = true } target := v . Interface ( ) if retain := visitField ( ctx , target ) ; ! isOverlayField && ! retain { v . Set ( reflect . Zero ( v . Type ( ) ) ) continue } retainAncestors = true } return retainAncestors }
clearNonOverlayFields is an implementation of structVisitor.
clearNonOverlayFields is an implementation of structVisitor .
// Skip non-exportable and empty fields // If this is an overlay field we need to preserve it and all // its ancestor fields up to the root. However, we still need // to visit its descendants in case we need to clear additional // non-overlay fields further down the tree.