Skip to content

Commit 0601f60

Browse files
author
Paddy Carver
committed
Let there be AttributePaths!
Finally connect the dots on AttributePaths. We move the type into tftypes, so it can be used throughout the tfprotov5 and the tftypes package without causing import cycles (tfprotov5 imports tftypes already). We get rid of our old tftypes.Path type, and just stick with one type of paths. And finally, msgpack unmarshaling gets upgraded to use the new tftypes.AttributePaths for enhanced errors. This does not add any helpers for extracting the AttributePath from an attributePathError, but we should do that, so we can bubble up attributePathErrors and get the AttributePath they're referring to for diagnostic purposes. Another day.
1 parent 95da7fb commit 0601f60

File tree

12 files changed

+182
-172
lines changed

12 files changed

+182
-172
lines changed

tfprotov5/diagnostic.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package tfprotov5
22

3+
import "github.com/hashicorp/terraform-plugin-go/tfprotov5/tftypes"
4+
35
const (
46
DiagnosticSeverityInvalid DiagnosticSeverity = 0
57
DiagnosticSeverityError DiagnosticSeverity = 1
@@ -10,7 +12,7 @@ type Diagnostic struct {
1012
Severity DiagnosticSeverity
1113
Summary string
1214
Detail string
13-
Attribute *AttributePath
15+
Attribute *tftypes.AttributePath
1416
}
1517

1618
type DiagnosticSeverity int32

tfprotov5/dynamic_value.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,12 @@ type DynamicValue struct {
5454
// Unmarshal.
5555
func (d DynamicValue) Unmarshal(typ tftypes.Type) (tftypes.Value, error) {
5656
if d.JSON != nil {
57-
return jsonUnmarshal(d.JSON, typ, nil)
57+
return jsonUnmarshal(d.JSON, typ, tftypes.AttributePath{})
5858
}
5959
if d.MsgPack != nil {
6060
r := bytes.NewReader(d.MsgPack)
6161
dec := msgpack.NewDecoder(r)
62-
return msgpackUnmarshal(dec, typ, nil)
62+
return msgpackUnmarshal(dec, typ, tftypes.AttributePath{})
6363
}
6464
return tftypes.Value{}, ErrUnknownDynamicValueType
6565
}

tfprotov5/dynamic_value_json.go

Lines changed: 25 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ func jsonByteDecoder(buf []byte) *json.Decoder {
1515
return dec
1616
}
1717

18-
func jsonUnmarshal(buf []byte, typ tftypes.Type, p tftypes.Path) (tftypes.Value, error) {
18+
func jsonUnmarshal(buf []byte, typ tftypes.Type, p tftypes.AttributePath) (tftypes.Value, error) {
1919
dec := jsonByteDecoder(buf)
2020

2121
tok, err := dec.Token()
@@ -51,7 +51,7 @@ func jsonUnmarshal(buf []byte, typ tftypes.Type, p tftypes.Path) (tftypes.Value,
5151
return tftypes.Value{}, p.NewErrorf("unknown type %s", typ)
5252
}
5353

54-
func jsonUnmarshalString(buf []byte, typ tftypes.Type, p tftypes.Path) (tftypes.Value, error) {
54+
func jsonUnmarshalString(buf []byte, typ tftypes.Type, p tftypes.AttributePath) (tftypes.Value, error) {
5555
dec := jsonByteDecoder(buf)
5656

5757
tok, err := dec.Token()
@@ -70,7 +70,7 @@ func jsonUnmarshalString(buf []byte, typ tftypes.Type, p tftypes.Path) (tftypes.
7070
return tftypes.Value{}, p.NewErrorf("unsupported type %T sent as %s", tok, tftypes.String)
7171
}
7272

73-
func jsonUnmarshalNumber(buf []byte, typ tftypes.Type, p tftypes.Path) (tftypes.Value, error) {
73+
func jsonUnmarshalNumber(buf []byte, typ tftypes.Type, p tftypes.AttributePath) (tftypes.Value, error) {
7474
dec := jsonByteDecoder(buf)
7575

7676
tok, err := dec.Token()
@@ -85,7 +85,7 @@ func jsonUnmarshalNumber(buf []byte, typ tftypes.Type, p tftypes.Path) (tftypes.
8585
return tftypes.NewValue(typ, numTok), nil
8686
}
8787

88-
func jsonUnmarshalBool(buf []byte, typ tftypes.Type, p tftypes.Path) (tftypes.Value, error) {
88+
func jsonUnmarshalBool(buf []byte, typ tftypes.Type, p tftypes.AttributePath) (tftypes.Value, error) {
8989
dec := jsonByteDecoder(buf)
9090
tok, err := dec.Token()
9191
if err != nil {
@@ -100,7 +100,7 @@ func jsonUnmarshalBool(buf []byte, typ tftypes.Type, p tftypes.Path) (tftypes.Va
100100
return tftypes.Value{}, p.NewErrorf("unsupported type %T sent as %s", tok, tftypes.Bool)
101101
}
102102

103-
func jsonUnmarshalDynamicPseudoType(buf []byte, typ tftypes.Type, p tftypes.Path) (tftypes.Value, error) {
103+
func jsonUnmarshalDynamicPseudoType(buf []byte, typ tftypes.Type, p tftypes.AttributePath) (tftypes.Value, error) {
104104
dec := jsonByteDecoder(buf)
105105
tok, err := dec.Token()
106106
if err != nil {
@@ -153,7 +153,7 @@ func jsonUnmarshalDynamicPseudoType(buf []byte, typ tftypes.Type, p tftypes.Path
153153
return jsonUnmarshal(valBody, t, p)
154154
}
155155

156-
func jsonUnmarshalList(buf []byte, elementType tftypes.Type, p tftypes.Path) (tftypes.Value, error) {
156+
func jsonUnmarshalList(buf []byte, elementType tftypes.Type, p tftypes.AttributePath) (tftypes.Value, error) {
157157
dec := jsonByteDecoder(buf)
158158

159159
tok, err := dec.Token()
@@ -176,15 +176,9 @@ func jsonUnmarshalList(buf []byte, elementType tftypes.Type, p tftypes.Path) (tf
176176
// distinction, so we'll allow it.
177177
vals := []tftypes.Value{}
178178

179-
// add a placeholder at the end of the path
180-
// we'll fix this in each part of the loop to have the right value
181-
// we can't just append in the loop, we need to replace, or we'll
182-
// be adding, not modifying, the last part of the path
183-
p = append(p, nil)
184179
var idx int64
185180
for dec.More() {
186-
// correct the last value in the path
187-
p[len(p)-1] = idx
181+
p.WithElementKeyInt(idx)
188182
// update the index
189183
idx++
190184

@@ -198,9 +192,8 @@ func jsonUnmarshalList(buf []byte, elementType tftypes.Type, p tftypes.Path) (tf
198192
return tftypes.Value{}, err
199193
}
200194
vals = append(vals, val)
195+
p.WithoutLastStep()
201196
}
202-
// drop the last value, we're out of the loop now
203-
p = p.RemoveLastStep()
204197

205198
tok, err = dec.Token()
206199
if err != nil {
@@ -214,7 +207,7 @@ func jsonUnmarshalList(buf []byte, elementType tftypes.Type, p tftypes.Path) (tf
214207
}, vals), nil
215208
}
216209

217-
func jsonUnmarshalSet(buf []byte, elementType tftypes.Type, p tftypes.Path) (tftypes.Value, error) {
210+
func jsonUnmarshalSet(buf []byte, elementType tftypes.Type, p tftypes.AttributePath) (tftypes.Value, error) {
218211
dec := jsonByteDecoder(buf)
219212

220213
tok, err := dec.Token()
@@ -237,8 +230,8 @@ func jsonUnmarshalSet(buf []byte, elementType tftypes.Type, p tftypes.Path) (tft
237230
// distinction, so we'll allow it.
238231
vals := []tftypes.Value{}
239232

240-
p = p.AddValueStep(tftypes.NewValue(elementType, tftypes.UnknownValue))
241233
for dec.More() {
234+
p.WithElementKeyValue(tftypes.NewValue(elementType, tftypes.UnknownValue))
242235
var rawVal json.RawMessage
243236
err = dec.Decode(&rawVal)
244237
if err != nil {
@@ -249,10 +242,8 @@ func jsonUnmarshalSet(buf []byte, elementType tftypes.Type, p tftypes.Path) (tft
249242
return tftypes.Value{}, err
250243
}
251244
vals = append(vals, val)
245+
p.WithoutLastStep()
252246
}
253-
// drop the last value, we're out of the loop now
254-
p = p.RemoveLastStep()
255-
256247
tok, err = dec.Token()
257248
if err != nil {
258249
return tftypes.Value{}, p.NewErrorf("error reading token: %w", err)
@@ -265,7 +256,7 @@ func jsonUnmarshalSet(buf []byte, elementType tftypes.Type, p tftypes.Path) (tft
265256
}, vals), nil
266257
}
267258

268-
func jsonUnmarshalMap(buf []byte, attrType tftypes.Type, p tftypes.Path) (tftypes.Value, error) {
259+
func jsonUnmarshalMap(buf []byte, attrType tftypes.Type, p tftypes.AttributePath) (tftypes.Value, error) {
269260
dec := jsonByteDecoder(buf)
270261

271262
tok, err := dec.Token()
@@ -277,8 +268,8 @@ func jsonUnmarshalMap(buf []byte, attrType tftypes.Type, p tftypes.Path) (tftype
277268
}
278269

279270
vals := map[string]tftypes.Value{}
280-
p = p.AddValueStep(tftypes.NewValue(attrType, tftypes.UnknownValue))
281271
for dec.More() {
272+
p.WithElementKeyValue(tftypes.NewValue(attrType, tftypes.UnknownValue))
282273
tok, err := dec.Token()
283274
if err != nil {
284275
return tftypes.Value{}, p.NewErrorf("error reading token: %w", err)
@@ -289,7 +280,8 @@ func jsonUnmarshalMap(buf []byte, attrType tftypes.Type, p tftypes.Path) (tftype
289280
}
290281

291282
//fix the path value, we have an actual key now
292-
p[len(p)-1] = key
283+
p.WithoutLastStep()
284+
p.WithElementKeyString(key)
293285

294286
var rawVal json.RawMessage
295287
err = dec.Decode(&rawVal)
@@ -301,10 +293,8 @@ func jsonUnmarshalMap(buf []byte, attrType tftypes.Type, p tftypes.Path) (tftype
301293
return tftypes.Value{}, err
302294
}
303295
vals[key] = val
296+
p.WithoutLastStep()
304297
}
305-
// drop the last value, we're out of the loop now
306-
p = p.RemoveLastStep()
307-
308298
tok, err = dec.Token()
309299
if err != nil {
310300
return tftypes.Value{}, p.NewErrorf("error reading token: %w", err)
@@ -318,7 +308,7 @@ func jsonUnmarshalMap(buf []byte, attrType tftypes.Type, p tftypes.Path) (tftype
318308
}, vals), nil
319309
}
320310

321-
func jsonUnmarshalTuple(buf []byte, elementTypes []tftypes.Type, p tftypes.Path) (tftypes.Value, error) {
311+
func jsonUnmarshalTuple(buf []byte, elementTypes []tftypes.Type, p tftypes.AttributePath) (tftypes.Value, error) {
322312
dec := jsonByteDecoder(buf)
323313

324314
tok, err := dec.Token()
@@ -341,18 +331,13 @@ func jsonUnmarshalTuple(buf []byte, elementTypes []tftypes.Type, p tftypes.Path)
341331
// distinction, so we'll allow it.
342332
vals := []tftypes.Value{}
343333

344-
// add a placeholder at the end of the path
345-
// we'll fix this in each part of the loop to have the right value
346-
// we can't just append in the loop, we need to replace, or we'll
347-
// be adding, not modifying, the last part of the path
348-
p = append(p, nil)
349334
var idx int64
350335
for dec.More() {
351336
if idx >= int64(len(elementTypes)) {
352-
return tftypes.Value{}, p[:len(p)-1].NewErrorf("too many tuple elements (only have types for %d)", len(elementTypes))
337+
return tftypes.Value{}, p.NewErrorf("too many tuple elements (only have types for %d)", len(elementTypes))
353338
}
354339

355-
p[len(p)-1] = idx
340+
p.WithElementKeyInt(idx)
356341
elementType := elementTypes[idx]
357342
idx++
358343

@@ -366,9 +351,8 @@ func jsonUnmarshalTuple(buf []byte, elementTypes []tftypes.Type, p tftypes.Path)
366351
return tftypes.Value{}, err
367352
}
368353
vals = append(vals, val)
354+
p.WithoutLastStep()
369355
}
370-
//drop the last value, we're out of the loop now
371-
p = p.RemoveLastStep()
372356

373357
tok, err = dec.Token()
374358
if err != nil {
@@ -387,7 +371,7 @@ func jsonUnmarshalTuple(buf []byte, elementTypes []tftypes.Type, p tftypes.Path)
387371
}, vals), nil
388372
}
389373

390-
func jsonUnmarshalObject(buf []byte, attrTypes map[string]tftypes.Type, p tftypes.Path) (tftypes.Value, error) {
374+
func jsonUnmarshalObject(buf []byte, attrTypes map[string]tftypes.Type, p tftypes.AttributePath) (tftypes.Value, error) {
391375
dec := jsonByteDecoder(buf)
392376

393377
tok, err := dec.Token()
@@ -399,10 +383,8 @@ func jsonUnmarshalObject(buf []byte, attrTypes map[string]tftypes.Type, p tftype
399383
}
400384

401385
vals := map[string]tftypes.Value{}
402-
// placeholder for the attributes we're about to loop through
403-
p = append(p, nil)
404-
405386
for dec.More() {
387+
p.WithElementKeyValue(tftypes.NewValue(tftypes.String, tftypes.UnknownValue))
406388
tok, err := dec.Token()
407389
if err != nil {
408390
return tftypes.Value{}, p.NewErrorf("error reading token: %w", err)
@@ -415,8 +397,8 @@ func jsonUnmarshalObject(buf []byte, attrTypes map[string]tftypes.Type, p tftype
415397
if !ok {
416398
return tftypes.Value{}, p.NewErrorf("unsupported attribute %q", key)
417399
}
418-
419-
p[len(p)-1] = key
400+
p.WithoutLastStep()
401+
p.WithAttributeName(key)
420402

421403
var rawVal json.RawMessage
422404
err = dec.Decode(&rawVal)
@@ -428,9 +410,8 @@ func jsonUnmarshalObject(buf []byte, attrTypes map[string]tftypes.Type, p tftype
428410
return tftypes.Value{}, err
429411
}
430412
vals[key] = val
413+
p.WithoutLastStep()
431414
}
432-
// we're out of the loop, drop the key from our path
433-
p = p.RemoveLastStep()
434415

435416
tok, err = dec.Token()
436417
if err != nil {

0 commit comments

Comments
 (0)