github.com/opentofu/opentofu@v1.7.1/internal/command/jsonformat/differ/attribute.go (about) 1 // Copyright (c) The OpenTofu Authors 2 // SPDX-License-Identifier: MPL-2.0 3 // Copyright (c) 2023 HashiCorp, Inc. 4 // SPDX-License-Identifier: MPL-2.0 5 6 package differ 7 8 import ( 9 "github.com/opentofu/opentofu/internal/command/jsonformat/structured" 10 "github.com/zclconf/go-cty/cty" 11 ctyjson "github.com/zclconf/go-cty/cty/json" 12 13 "github.com/opentofu/opentofu/internal/command/jsonformat/computed" 14 15 "github.com/opentofu/opentofu/internal/command/jsonprovider" 16 ) 17 18 func ComputeDiffForAttribute(change structured.Change, attribute *jsonprovider.Attribute) computed.Diff { 19 if attribute.AttributeNestedType != nil { 20 return computeDiffForNestedAttribute(change, attribute.AttributeNestedType) 21 } 22 return ComputeDiffForType(change, unmarshalAttribute(attribute)) 23 } 24 25 func computeDiffForNestedAttribute(change structured.Change, nested *jsonprovider.NestedType) computed.Diff { 26 if sensitive, ok := checkForSensitiveNestedAttribute(change, nested); ok { 27 return sensitive 28 } 29 30 if computed, ok := checkForUnknownNestedAttribute(change, nested); ok { 31 return computed 32 } 33 34 switch NestingMode(nested.NestingMode) { 35 case nestingModeSingle, nestingModeGroup: 36 return computeAttributeDiffAsNestedObject(change, nested.Attributes) 37 case nestingModeMap: 38 return computeAttributeDiffAsNestedMap(change, nested.Attributes) 39 case nestingModeList: 40 return computeAttributeDiffAsNestedList(change, nested.Attributes) 41 case nestingModeSet: 42 return computeAttributeDiffAsNestedSet(change, nested.Attributes) 43 default: 44 panic("unrecognized nesting mode: " + nested.NestingMode) 45 } 46 } 47 48 func ComputeDiffForType(change structured.Change, ctype cty.Type) computed.Diff { 49 if sensitive, ok := checkForSensitiveType(change, ctype); ok { 50 return sensitive 51 } 52 53 if computed, ok := checkForUnknownType(change, ctype); ok { 54 return computed 55 } 56 57 switch { 58 case ctype == cty.NilType, ctype == cty.DynamicPseudoType: 59 // Forward nil or dynamic types over to be processed as outputs. 60 // There is nothing particularly special about the way outputs are 61 // processed that make this unsafe, we could just as easily call this 62 // function computeChangeForDynamicValues(), but external callers will 63 // only be in this situation when processing outputs so this function 64 // is named for their benefit. 65 return ComputeDiffForOutput(change) 66 case ctype.IsPrimitiveType(): 67 return computeAttributeDiffAsPrimitive(change, ctype) 68 case ctype.IsObjectType(): 69 return computeAttributeDiffAsObject(change, ctype.AttributeTypes()) 70 case ctype.IsMapType(): 71 return computeAttributeDiffAsMap(change, ctype.ElementType()) 72 case ctype.IsListType(): 73 return computeAttributeDiffAsList(change, ctype.ElementType()) 74 case ctype.IsTupleType(): 75 return computeAttributeDiffAsTuple(change, ctype.TupleElementTypes()) 76 case ctype.IsSetType(): 77 return computeAttributeDiffAsSet(change, ctype.ElementType()) 78 default: 79 panic("unrecognized type: " + ctype.FriendlyName()) 80 } 81 } 82 83 func unmarshalAttribute(attribute *jsonprovider.Attribute) cty.Type { 84 ctyType, err := ctyjson.UnmarshalType(attribute.AttributeType) 85 if err != nil { 86 panic("could not unmarshal attribute type: " + err.Error()) 87 } 88 return ctyType 89 }