github.com/muratcelep/terraform@v1.1.0-beta2-not-internal-4/not-internal/states/state_deepcopy.go (about) 1 package states 2 3 import ( 4 "github.com/muratcelep/terraform/not-internal/addrs" 5 "github.com/zclconf/go-cty/cty" 6 ) 7 8 // Taking deep copies of states is an important operation because state is 9 // otherwise a mutable data structure that is challenging to share across 10 // many separate callers. It is important that the DeepCopy implementations 11 // in this file comprehensively copy all parts of the state data structure 12 // that could be mutated via pointers. 13 14 // DeepCopy returns a new state that contains equivalent data to the reciever 15 // but shares no backing memory in common. 16 // 17 // As with all methods on State, this method is not safe to use concurrently 18 // with writing to any portion of the recieving data structure. It is the 19 // caller's responsibility to ensure mutual exclusion for the duration of the 20 // operation, but may then freely modify the receiver and the returned copy 21 // independently once this method returns. 22 func (s *State) DeepCopy() *State { 23 if s == nil { 24 return nil 25 } 26 27 modules := make(map[string]*Module, len(s.Modules)) 28 for k, m := range s.Modules { 29 modules[k] = m.DeepCopy() 30 } 31 return &State{ 32 Modules: modules, 33 } 34 } 35 36 // DeepCopy returns a new module state that contains equivalent data to the 37 // receiver but shares no backing memory in common. 38 // 39 // As with all methods on Module, this method is not safe to use concurrently 40 // with writing to any portion of the recieving data structure. It is the 41 // caller's responsibility to ensure mutual exclusion for the duration of the 42 // operation, but may then freely modify the receiver and the returned copy 43 // independently once this method returns. 44 func (ms *Module) DeepCopy() *Module { 45 if ms == nil { 46 return nil 47 } 48 49 resources := make(map[string]*Resource, len(ms.Resources)) 50 for k, r := range ms.Resources { 51 resources[k] = r.DeepCopy() 52 } 53 outputValues := make(map[string]*OutputValue, len(ms.OutputValues)) 54 for k, v := range ms.OutputValues { 55 outputValues[k] = v.DeepCopy() 56 } 57 localValues := make(map[string]cty.Value, len(ms.LocalValues)) 58 for k, v := range ms.LocalValues { 59 // cty.Value is immutable, so we don't need to copy these. 60 localValues[k] = v 61 } 62 63 return &Module{ 64 Addr: ms.Addr, // technically mutable, but immutable by convention 65 Resources: resources, 66 OutputValues: outputValues, 67 LocalValues: localValues, 68 } 69 } 70 71 // DeepCopy returns a new resource state that contains equivalent data to the 72 // receiver but shares no backing memory in common. 73 // 74 // As with all methods on Resource, this method is not safe to use concurrently 75 // with writing to any portion of the recieving data structure. It is the 76 // caller's responsibility to ensure mutual exclusion for the duration of the 77 // operation, but may then freely modify the receiver and the returned copy 78 // independently once this method returns. 79 func (rs *Resource) DeepCopy() *Resource { 80 if rs == nil { 81 return nil 82 } 83 84 instances := make(map[addrs.InstanceKey]*ResourceInstance, len(rs.Instances)) 85 for k, i := range rs.Instances { 86 instances[k] = i.DeepCopy() 87 } 88 89 return &Resource{ 90 Addr: rs.Addr, 91 Instances: instances, 92 ProviderConfig: rs.ProviderConfig, // technically mutable, but immutable by convention 93 } 94 } 95 96 // DeepCopy returns a new resource instance state that contains equivalent data 97 // to the receiver but shares no backing memory in common. 98 // 99 // As with all methods on ResourceInstance, this method is not safe to use 100 // concurrently with writing to any portion of the recieving data structure. It 101 // is the caller's responsibility to ensure mutual exclusion for the duration 102 // of the operation, but may then freely modify the receiver and the returned 103 // copy independently once this method returns. 104 func (i *ResourceInstance) DeepCopy() *ResourceInstance { 105 if i == nil { 106 return nil 107 } 108 109 deposed := make(map[DeposedKey]*ResourceInstanceObjectSrc, len(i.Deposed)) 110 for k, obj := range i.Deposed { 111 deposed[k] = obj.DeepCopy() 112 } 113 114 return &ResourceInstance{ 115 Current: i.Current.DeepCopy(), 116 Deposed: deposed, 117 } 118 } 119 120 // DeepCopy returns a new resource instance object that contains equivalent data 121 // to the receiver but shares no backing memory in common. 122 // 123 // As with all methods on ResourceInstanceObjectSrc, this method is not safe to 124 // use concurrently with writing to any portion of the recieving data structure. 125 // It is the caller's responsibility to ensure mutual exclusion for the duration 126 // of the operation, but may then freely modify the receiver and the returned 127 // copy independently once this method returns. 128 func (os *ResourceInstanceObjectSrc) DeepCopy() *ResourceInstanceObjectSrc { 129 if os == nil { 130 return nil 131 } 132 133 var attrsFlat map[string]string 134 if os.AttrsFlat != nil { 135 attrsFlat = make(map[string]string, len(os.AttrsFlat)) 136 for k, v := range os.AttrsFlat { 137 attrsFlat[k] = v 138 } 139 } 140 141 var attrsJSON []byte 142 if os.AttrsJSON != nil { 143 attrsJSON = make([]byte, len(os.AttrsJSON)) 144 copy(attrsJSON, os.AttrsJSON) 145 } 146 147 var attrPaths []cty.PathValueMarks 148 if os.AttrSensitivePaths != nil { 149 attrPaths = make([]cty.PathValueMarks, len(os.AttrSensitivePaths)) 150 copy(attrPaths, os.AttrSensitivePaths) 151 } 152 153 var private []byte 154 if os.Private != nil { 155 private = make([]byte, len(os.Private)) 156 copy(private, os.Private) 157 } 158 159 // Some addrs.Referencable implementations are technically mutable, but 160 // we treat them as immutable by convention and so we don't deep-copy here. 161 var dependencies []addrs.ConfigResource 162 if os.Dependencies != nil { 163 dependencies = make([]addrs.ConfigResource, len(os.Dependencies)) 164 copy(dependencies, os.Dependencies) 165 } 166 167 return &ResourceInstanceObjectSrc{ 168 Status: os.Status, 169 SchemaVersion: os.SchemaVersion, 170 Private: private, 171 AttrsFlat: attrsFlat, 172 AttrsJSON: attrsJSON, 173 AttrSensitivePaths: attrPaths, 174 Dependencies: dependencies, 175 CreateBeforeDestroy: os.CreateBeforeDestroy, 176 } 177 } 178 179 // DeepCopy returns a new resource instance object that contains equivalent data 180 // to the receiver but shares no backing memory in common. 181 // 182 // As with all methods on ResourceInstanceObject, this method is not safe to use 183 // concurrently with writing to any portion of the recieving data structure. It 184 // is the caller's responsibility to ensure mutual exclusion for the duration 185 // of the operation, but may then freely modify the receiver and the returned 186 // copy independently once this method returns. 187 func (o *ResourceInstanceObject) DeepCopy() *ResourceInstanceObject { 188 if o == nil { 189 return nil 190 } 191 192 var private []byte 193 if o.Private != nil { 194 private = make([]byte, len(o.Private)) 195 copy(private, o.Private) 196 } 197 198 // Some addrs.Referenceable implementations are technically mutable, but 199 // we treat them as immutable by convention and so we don't deep-copy here. 200 var dependencies []addrs.ConfigResource 201 if o.Dependencies != nil { 202 dependencies = make([]addrs.ConfigResource, len(o.Dependencies)) 203 copy(dependencies, o.Dependencies) 204 } 205 206 return &ResourceInstanceObject{ 207 Value: o.Value, 208 Status: o.Status, 209 Private: private, 210 Dependencies: dependencies, 211 CreateBeforeDestroy: o.CreateBeforeDestroy, 212 } 213 } 214 215 // DeepCopy returns a new output value state that contains equivalent data 216 // to the receiver but shares no backing memory in common. 217 // 218 // As with all methods on OutputValue, this method is not safe to use 219 // concurrently with writing to any portion of the recieving data structure. It 220 // is the caller's responsibility to ensure mutual exclusion for the duration 221 // of the operation, but may then freely modify the receiver and the returned 222 // copy independently once this method returns. 223 func (os *OutputValue) DeepCopy() *OutputValue { 224 if os == nil { 225 return nil 226 } 227 228 return &OutputValue{ 229 Addr: os.Addr, 230 Value: os.Value, 231 Sensitive: os.Sensitive, 232 } 233 }