github.com/graywolf-at-work-2/terraform-vendor@v1.4.5/internal/command/jsonformat/differ/object.go (about)

     1  package differ
     2  
     3  import (
     4  	"github.com/zclconf/go-cty/cty"
     5  
     6  	"github.com/hashicorp/terraform/internal/command/jsonformat/collections"
     7  	"github.com/hashicorp/terraform/internal/command/jsonformat/computed"
     8  	"github.com/hashicorp/terraform/internal/command/jsonformat/computed/renderers"
     9  	"github.com/hashicorp/terraform/internal/command/jsonprovider"
    10  	"github.com/hashicorp/terraform/internal/plans"
    11  )
    12  
    13  func (change Change) computeAttributeDiffAsObject(attributes map[string]cty.Type) computed.Diff {
    14  	attributeDiffs, action := processObject(change, attributes, func(value Change, ctype cty.Type) computed.Diff {
    15  		return value.ComputeDiffForType(ctype)
    16  	})
    17  	return computed.NewDiff(renderers.Object(attributeDiffs), action, change.ReplacePaths.Matches())
    18  }
    19  
    20  func (change Change) computeAttributeDiffAsNestedObject(attributes map[string]*jsonprovider.Attribute) computed.Diff {
    21  	attributeDiffs, action := processObject(change, attributes, func(value Change, attribute *jsonprovider.Attribute) computed.Diff {
    22  		return value.ComputeDiffForAttribute(attribute)
    23  	})
    24  	return computed.NewDiff(renderers.NestedObject(attributeDiffs), action, change.ReplacePaths.Matches())
    25  }
    26  
    27  // processObject steps through the children of value as if it is an object and
    28  // calls out to the provided computeDiff function once it has collated the
    29  // diffs for each child attribute.
    30  //
    31  // We have to make this generic as attributes and nested objects process either
    32  // cty.Type or jsonprovider.Attribute children respectively. And we want to
    33  // reuse as much code as possible.
    34  //
    35  // Also, as it generic we cannot make this function a method on Change as you
    36  // can't create generic methods on structs. Instead, we make this a generic
    37  // function that receives the value as an argument.
    38  func processObject[T any](v Change, attributes map[string]T, computeDiff func(Change, T) computed.Diff) (map[string]computed.Diff, plans.Action) {
    39  	attributeDiffs := make(map[string]computed.Diff)
    40  	mapValue := v.asMap()
    41  
    42  	currentAction := v.getDefaultActionForIteration()
    43  	for key, attribute := range attributes {
    44  		attributeValue := mapValue.getChild(key)
    45  
    46  		if !attributeValue.RelevantAttributes.MatchesPartial() {
    47  			// Mark non-relevant attributes as unchanged.
    48  			attributeValue = attributeValue.AsNoOp()
    49  		}
    50  
    51  		// We always assume changes to object are implicit.
    52  		attributeValue.BeforeExplicit = false
    53  		attributeValue.AfterExplicit = false
    54  
    55  		attributeDiff := computeDiff(attributeValue, attribute)
    56  		if attributeDiff.Action == plans.NoOp && attributeValue.Before == nil && attributeValue.After == nil {
    57  			// We skip attributes of objects that are null both before and
    58  			// after. We don't even count these as unchanged attributes.
    59  			continue
    60  		}
    61  		attributeDiffs[key] = attributeDiff
    62  		currentAction = collections.CompareActions(currentAction, attributeDiff.Action)
    63  	}
    64  
    65  	return attributeDiffs, currentAction
    66  }