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