diff options
author | Alex Pilon <apilon@hashicorp.com> | 2019-02-22 18:24:37 -0500 |
---|---|---|
committer | Alex Pilon <apilon@hashicorp.com> | 2019-02-22 18:24:37 -0500 |
commit | 15c0b25d011f37e7c20aeca9eaf461f78285b8d9 (patch) | |
tree | 255c250a5c9d4801c74092d33b7337d8c14438ff /vendor/github.com/hashicorp/terraform/helper/schema/field_writer_map.go | |
parent | 07971ca38143c5faf951d152fba370ddcbe26ad5 (diff) | |
download | terraform-provider-statuscake-15c0b25d011f37e7c20aeca9eaf461f78285b8d9.tar.gz terraform-provider-statuscake-15c0b25d011f37e7c20aeca9eaf461f78285b8d9.tar.zst terraform-provider-statuscake-15c0b25d011f37e7c20aeca9eaf461f78285b8d9.zip |
deps: github.com/hashicorp/terraform@sdk-v0.11-with-go-modules
Updated via: go get github.com/hashicorp/terraform@sdk-v0.11-with-go-modules and go mod tidy
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/helper/schema/field_writer_map.go')
-rw-r--r-- | vendor/github.com/hashicorp/terraform/helper/schema/field_writer_map.go | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/helper/schema/field_writer_map.go b/vendor/github.com/hashicorp/terraform/helper/schema/field_writer_map.go index 689ed8d..814c7ba 100644 --- a/vendor/github.com/hashicorp/terraform/helper/schema/field_writer_map.go +++ b/vendor/github.com/hashicorp/terraform/helper/schema/field_writer_map.go | |||
@@ -39,6 +39,19 @@ func (w *MapFieldWriter) unsafeWriteField(addr string, value string) { | |||
39 | w.result[addr] = value | 39 | w.result[addr] = value |
40 | } | 40 | } |
41 | 41 | ||
42 | // clearTree clears a field and any sub-fields of the given address out of the | ||
43 | // map. This should be used to reset some kind of complex structures (namely | ||
44 | // sets) before writing to make sure that any conflicting data is removed (for | ||
45 | // example, if the set was previously written to the writer's layer). | ||
46 | func (w *MapFieldWriter) clearTree(addr []string) { | ||
47 | prefix := strings.Join(addr, ".") + "." | ||
48 | for k := range w.result { | ||
49 | if strings.HasPrefix(k, prefix) { | ||
50 | delete(w.result, k) | ||
51 | } | ||
52 | } | ||
53 | } | ||
54 | |||
42 | func (w *MapFieldWriter) WriteField(addr []string, value interface{}) error { | 55 | func (w *MapFieldWriter) WriteField(addr []string, value interface{}) error { |
43 | w.lock.Lock() | 56 | w.lock.Lock() |
44 | defer w.lock.Unlock() | 57 | defer w.lock.Unlock() |
@@ -115,6 +128,14 @@ func (w *MapFieldWriter) setList( | |||
115 | return fmt.Errorf("%s: %s", k, err) | 128 | return fmt.Errorf("%s: %s", k, err) |
116 | } | 129 | } |
117 | 130 | ||
131 | // Wipe the set from the current writer prior to writing if it exists. | ||
132 | // Multiple writes to the same layer is a lot safer for lists than sets due | ||
133 | // to the fact that indexes are always deterministic and the length will | ||
134 | // always be updated with the current length on the last write, but making | ||
135 | // sure we have a clean namespace removes any chance for edge cases to pop up | ||
136 | // and ensures that the last write to the set is the correct value. | ||
137 | w.clearTree(addr) | ||
138 | |||
118 | // Set the entire list. | 139 | // Set the entire list. |
119 | var err error | 140 | var err error |
120 | for i, elem := range vs { | 141 | for i, elem := range vs { |
@@ -162,6 +183,10 @@ func (w *MapFieldWriter) setMap( | |||
162 | vs[mk.String()] = mv.Interface() | 183 | vs[mk.String()] = mv.Interface() |
163 | } | 184 | } |
164 | 185 | ||
186 | // Wipe this address tree. The contents of the map should always reflect the | ||
187 | // last write made to it. | ||
188 | w.clearTree(addr) | ||
189 | |||
165 | // Remove the pure key since we're setting the full map value | 190 | // Remove the pure key since we're setting the full map value |
166 | delete(w.result, k) | 191 | delete(w.result, k) |
167 | 192 | ||
@@ -308,6 +333,13 @@ func (w *MapFieldWriter) setSet( | |||
308 | value = s | 333 | value = s |
309 | } | 334 | } |
310 | 335 | ||
336 | // Clear any keys that match the set address first. This is necessary because | ||
337 | // it's always possible and sometimes may be necessary to write to a certain | ||
338 | // writer layer more than once with different set data each time, which will | ||
339 | // lead to different keys being inserted, which can lead to determinism | ||
340 | // problems when the old data isn't wiped first. | ||
341 | w.clearTree(addr) | ||
342 | |||
311 | for code, elem := range value.(*Set).m { | 343 | for code, elem := range value.(*Set).m { |
312 | if err := w.set(append(addrCopy, code), elem); err != nil { | 344 | if err := w.set(append(addrCopy, code), elem); err != nil { |
313 | return err | 345 | return err |