Skip to content

Commit 7adb44d

Browse files
committed
attr: Add attribute path parameter to (TypeWithValidate).Validate() method
Reference: #127
1 parent 7055f97 commit 7adb44d

22 files changed

+105
-83
lines changed

attr/type.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,9 @@ type TypeWithValidate interface {
8080
// being used to populate the Type. It is generally used to check the
8181
// data format and ensure that it complies with the requirements of the
8282
// Type.
83-
Validate(context.Context, tftypes.Value) diag.Diagnostics
83+
//
84+
// TODO: don't use tfprotov6.Diagnostic, use our type
85+
Validate(context.Context, tftypes.Value, *tftypes.AttributePath) diag.Diagnostics
8486
}
8587

8688
// TypeWithPlaintextDescription extends the Type interface to include a

internal/reflect/interfaces.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func FromUnknownable(ctx context.Context, typ attr.Type, val Unknownable, path *
7070
tfVal := tftypes.NewValue(typ.TerraformType(ctx), tftypes.UnknownValue)
7171

7272
if typeWithValidate, ok := typ.(attr.TypeWithValidate); ok {
73-
diags.Append(typeWithValidate.Validate(ctx, tfVal)...)
73+
diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...)
7474

7575
if diags.HasError() {
7676
return nil, diags
@@ -91,7 +91,7 @@ func FromUnknownable(ctx context.Context, typ attr.Type, val Unknownable, path *
9191
tfVal := tftypes.NewValue(typ.TerraformType(ctx), val.GetValue(ctx))
9292

9393
if typeWithValidate, ok := typ.(attr.TypeWithValidate); ok {
94-
diags.Append(typeWithValidate.Validate(ctx, tfVal)...)
94+
diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...)
9595

9696
if diags.HasError() {
9797
return nil, diags
@@ -164,7 +164,7 @@ func FromNullable(ctx context.Context, typ attr.Type, val Nullable, path *tftype
164164
tfVal := tftypes.NewValue(typ.TerraformType(ctx), nil)
165165

166166
if typeWithValidate, ok := typ.(attr.TypeWithValidate); ok {
167-
diags.Append(typeWithValidate.Validate(ctx, tfVal)...)
167+
diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...)
168168

169169
if diags.HasError() {
170170
return nil, diags
@@ -185,7 +185,7 @@ func FromNullable(ctx context.Context, typ attr.Type, val Nullable, path *tftype
185185
tfVal := tftypes.NewValue(typ.TerraformType(ctx), val.GetValue(ctx))
186186

187187
if typeWithValidate, ok := typ.(attr.TypeWithValidate); ok {
188-
diags.Append(typeWithValidate.Validate(ctx, tfVal)...)
188+
diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...)
189189

190190
if diags.HasError() {
191191
return nil, diags
@@ -256,7 +256,7 @@ func FromValueCreator(ctx context.Context, typ attr.Type, val tftypes.ValueCreat
256256
tfVal := tftypes.NewValue(typ.TerraformType(ctx), raw)
257257

258258
if typeWithValidate, ok := typ.(attr.TypeWithValidate); ok {
259-
diags.Append(typeWithValidate.Validate(ctx, tfVal)...)
259+
diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...)
260260

261261
if diags.HasError() {
262262
return nil, diags
@@ -279,7 +279,7 @@ func NewAttributeValue(ctx context.Context, typ attr.Type, val tftypes.Value, ta
279279
var diags diag.Diagnostics
280280

281281
if typeWithValidate, ok := typ.(attr.TypeWithValidate); ok {
282-
diags.Append(typeWithValidate.Validate(ctx, val)...)
282+
diags.Append(typeWithValidate.Validate(ctx, val, path)...)
283283

284284
if diags.HasError() {
285285
return target, diags
@@ -319,7 +319,7 @@ func FromAttributeValue(ctx context.Context, typ attr.Type, val attr.Value, path
319319
return val, append(diags, toTerraformValueErrorDiag(err, path))
320320
}
321321

322-
diags.Append(typeWithValidate.Validate(ctx, tftypes.NewValue(tfType, tfVal))...)
322+
diags.Append(typeWithValidate.Validate(ctx, tftypes.NewValue(tfType, tfVal), path)...)
323323

324324
if diags.HasError() {
325325
return val, diags

internal/reflect/map.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ func FromMap(ctx context.Context, typ attr.TypeWithElementType, val reflect.Valu
102102
tfVal := tftypes.NewValue(tfType, nil)
103103

104104
if typeWithValidate, ok := typ.(attr.TypeWithValidate); ok {
105-
diags.Append(typeWithValidate.Validate(ctx, tfVal)...)
105+
diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...)
106106

107107
if diags.HasError() {
108108
return nil, diags
@@ -156,7 +156,7 @@ func FromMap(ctx context.Context, typ attr.TypeWithElementType, val reflect.Valu
156156
tfElemVal := tftypes.NewValue(tfElemType, tfVal)
157157

158158
if typeWithValidate, ok := typ.(attr.TypeWithValidate); ok {
159-
diags.Append(typeWithValidate.Validate(ctx, tfElemVal)...)
159+
diags.Append(typeWithValidate.Validate(ctx, tfElemVal, path.WithElementKeyString(key.String()))...)
160160

161161
if diags.HasError() {
162162
return nil, diags
@@ -174,7 +174,7 @@ func FromMap(ctx context.Context, typ attr.TypeWithElementType, val reflect.Valu
174174
tfVal := tftypes.NewValue(tfType, tfElems)
175175

176176
if typeWithValidate, ok := typ.(attr.TypeWithValidate); ok {
177-
diags.Append(typeWithValidate.Validate(ctx, tfVal)...)
177+
diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...)
178178

179179
if diags.HasError() {
180180
return nil, diags

internal/reflect/number.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ func FromInt(ctx context.Context, typ attr.Type, val int64, path *tftypes.Attrib
245245
tfNum := tftypes.NewValue(tftypes.Number, val)
246246

247247
if typeWithValidate, ok := typ.(attr.TypeWithValidate); ok {
248-
diags.Append(typeWithValidate.Validate(ctx, tfNum)...)
248+
diags.Append(typeWithValidate.Validate(ctx, tfNum, path)...)
249249

250250
if diags.HasError() {
251251
return nil, diags
@@ -272,7 +272,7 @@ func FromUint(ctx context.Context, typ attr.Type, val uint64, path *tftypes.Attr
272272
tfNum := tftypes.NewValue(tftypes.Number, val)
273273

274274
if typeWithValidate, ok := typ.(attr.TypeWithValidate); ok {
275-
diags.Append(typeWithValidate.Validate(ctx, tfNum)...)
275+
diags.Append(typeWithValidate.Validate(ctx, tfNum, path)...)
276276

277277
if diags.HasError() {
278278
return nil, diags
@@ -299,7 +299,7 @@ func FromFloat(ctx context.Context, typ attr.Type, val float64, path *tftypes.At
299299
tfNum := tftypes.NewValue(tftypes.Number, val)
300300

301301
if typeWithValidate, ok := typ.(attr.TypeWithValidate); ok {
302-
diags.Append(typeWithValidate.Validate(ctx, tfNum)...)
302+
diags.Append(typeWithValidate.Validate(ctx, tfNum, path)...)
303303

304304
if diags.HasError() {
305305
return nil, diags
@@ -326,7 +326,7 @@ func FromBigFloat(ctx context.Context, typ attr.Type, val *big.Float, path *tfty
326326
tfNum := tftypes.NewValue(tftypes.Number, val)
327327

328328
if typeWithValidate, ok := typ.(attr.TypeWithValidate); ok {
329-
diags.Append(typeWithValidate.Validate(ctx, tfNum)...)
329+
diags.Append(typeWithValidate.Validate(ctx, tfNum, path)...)
330330

331331
if diags.HasError() {
332332
return nil, diags
@@ -354,7 +354,7 @@ func FromBigInt(ctx context.Context, typ attr.Type, val *big.Int, path *tftypes.
354354
tfNum := tftypes.NewValue(tftypes.Number, fl)
355355

356356
if typeWithValidate, ok := typ.(attr.TypeWithValidate); ok {
357-
diags.Append(typeWithValidate.Validate(ctx, tfNum)...)
357+
diags.Append(typeWithValidate.Validate(ctx, tfNum, path)...)
358358

359359
if diags.HasError() {
360360
return nil, diags

internal/reflect/number_test.go

+10-10
Original file line numberDiff line numberDiff line change
@@ -1202,14 +1202,14 @@ func TestFromInt(t *testing.T) {
12021202
Value: big.NewFloat(1),
12031203
},
12041204
expectedDiags: diag.Diagnostics{
1205-
testtypes.TestWarningDiagnostic,
1205+
testtypes.TestWarningDiagnostic(tftypes.NewAttributePath()),
12061206
},
12071207
},
12081208
"WithValidateError": {
12091209
val: 1,
12101210
typ: testtypes.NumberTypeWithValidateError{},
12111211
expectedDiags: diag.Diagnostics{
1212-
testtypes.TestErrorDiagnostic,
1212+
testtypes.TestErrorDiagnostic(tftypes.NewAttributePath()),
12131213
},
12141214
},
12151215
}
@@ -1261,14 +1261,14 @@ func TestFromUint(t *testing.T) {
12611261
Value: big.NewFloat(1),
12621262
},
12631263
expectedDiags: diag.Diagnostics{
1264-
testtypes.TestWarningDiagnostic,
1264+
testtypes.TestWarningDiagnostic(tftypes.NewAttributePath()),
12651265
},
12661266
},
12671267
"WithValidateError": {
12681268
val: 1,
12691269
typ: testtypes.NumberTypeWithValidateError{},
12701270
expectedDiags: diag.Diagnostics{
1271-
testtypes.TestErrorDiagnostic,
1271+
testtypes.TestErrorDiagnostic(tftypes.NewAttributePath()),
12721272
},
12731273
},
12741274
}
@@ -1327,14 +1327,14 @@ func TestFromFloat(t *testing.T) {
13271327
Value: big.NewFloat(1),
13281328
},
13291329
expectedDiags: diag.Diagnostics{
1330-
testtypes.TestWarningDiagnostic,
1330+
testtypes.TestWarningDiagnostic(tftypes.NewAttributePath()),
13311331
},
13321332
},
13331333
"WithValidateError": {
13341334
val: 1,
13351335
typ: testtypes.NumberTypeWithValidateError{},
13361336
expectedDiags: diag.Diagnostics{
1337-
testtypes.TestErrorDiagnostic,
1337+
testtypes.TestErrorDiagnostic(tftypes.NewAttributePath()),
13381338
},
13391339
},
13401340
}
@@ -1393,14 +1393,14 @@ func TestFromBigFloat(t *testing.T) {
13931393
Value: big.NewFloat(1),
13941394
},
13951395
expectedDiags: diag.Diagnostics{
1396-
testtypes.TestWarningDiagnostic,
1396+
testtypes.TestWarningDiagnostic(tftypes.NewAttributePath()),
13971397
},
13981398
},
13991399
"WithValidateError": {
14001400
val: big.NewFloat(1),
14011401
typ: testtypes.NumberTypeWithValidateError{},
14021402
expectedDiags: diag.Diagnostics{
1403-
testtypes.TestErrorDiagnostic,
1403+
testtypes.TestErrorDiagnostic(tftypes.NewAttributePath()),
14041404
},
14051405
},
14061406
}
@@ -1452,14 +1452,14 @@ func TestFromBigInt(t *testing.T) {
14521452
Value: big.NewFloat(1),
14531453
},
14541454
expectedDiags: diag.Diagnostics{
1455-
testtypes.TestWarningDiagnostic,
1455+
testtypes.TestWarningDiagnostic(tftypes.NewAttributePath()),
14561456
},
14571457
},
14581458
"WithValidateError": {
14591459
val: big.NewInt(1),
14601460
typ: testtypes.NumberTypeWithValidateError{},
14611461
expectedDiags: diag.Diagnostics{
1462-
testtypes.TestErrorDiagnostic,
1462+
testtypes.TestErrorDiagnostic(tftypes.NewAttributePath()),
14631463
},
14641464
},
14651465
}

internal/reflect/pointer.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ func FromPointer(ctx context.Context, typ attr.Type, value reflect.Value, path *
9090
tfVal := tftypes.NewValue(typ.TerraformType(ctx), nil)
9191

9292
if typeWithValidate, ok := typ.(attr.TypeWithValidate); ok {
93-
diags.Append(typeWithValidate.Validate(ctx, tfVal)...)
93+
diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...)
9494

9595
if diags.HasError() {
9696
return nil, diags

internal/reflect/pointer_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ func TestFromPointer(t *testing.T) {
109109
typ: testtypes.StringTypeWithValidateError{},
110110
val: reflect.ValueOf(strPtr("hello, world")),
111111
expectedDiags: diag.Diagnostics{
112-
testtypes.TestErrorDiagnostic,
112+
testtypes.TestErrorDiagnostic(tftypes.NewAttributePath()),
113113
},
114114
},
115115
"WithValidateWarning": {
@@ -119,7 +119,7 @@ func TestFromPointer(t *testing.T) {
119119
Value: "hello, world",
120120
},
121121
expectedDiags: diag.Diagnostics{
122-
testtypes.TestWarningDiagnostic,
122+
testtypes.TestWarningDiagnostic(tftypes.NewAttributePath()),
123123
},
124124
},
125125
}

internal/reflect/primitive.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func FromString(ctx context.Context, typ attr.Type, val string, path *tftypes.At
6565
tfStr := tftypes.NewValue(tftypes.String, val)
6666

6767
if typeWithValidate, ok := typ.(attr.TypeWithValidate); ok {
68-
diags.Append(typeWithValidate.Validate(ctx, tfStr)...)
68+
diags.Append(typeWithValidate.Validate(ctx, tfStr, path)...)
6969

7070
if diags.HasError() {
7171
return nil, diags
@@ -92,7 +92,7 @@ func FromBool(ctx context.Context, typ attr.Type, val bool, path *tftypes.Attrib
9292
tfBool := tftypes.NewValue(tftypes.Bool, val)
9393

9494
if typeWithValidate, ok := typ.(attr.TypeWithValidate); ok {
95-
diags.Append(typeWithValidate.Validate(ctx, tfBool)...)
95+
diags.Append(typeWithValidate.Validate(ctx, tfBool, path)...)
9696

9797
if diags.HasError() {
9898
return nil, diags

internal/reflect/primitive_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,14 @@ func TestFromString(t *testing.T) {
9999
Value: "mystring",
100100
},
101101
expectedDiags: diag.Diagnostics{
102-
testtypes.TestWarningDiagnostic,
102+
testtypes.TestWarningDiagnostic(tftypes.NewAttributePath()),
103103
},
104104
},
105105
"WithValidateError": {
106106
val: "mystring",
107107
typ: testtypes.StringTypeWithValidateError{},
108108
expectedDiags: diag.Diagnostics{
109-
testtypes.TestErrorDiagnostic,
109+
testtypes.TestErrorDiagnostic(tftypes.NewAttributePath()),
110110
},
111111
},
112112
}
@@ -159,14 +159,14 @@ func TestFromBool(t *testing.T) {
159159
Value: true,
160160
},
161161
expectedDiags: diag.Diagnostics{
162-
testtypes.TestWarningDiagnostic,
162+
testtypes.TestWarningDiagnostic(tftypes.NewAttributePath()),
163163
},
164164
},
165165
"WithValidateError": {
166166
val: true,
167167
typ: testtypes.BoolTypeWithValidateError{},
168168
expectedDiags: diag.Diagnostics{
169-
testtypes.TestErrorDiagnostic,
169+
testtypes.TestErrorDiagnostic(tftypes.NewAttributePath()),
170170
},
171171
},
172172
}

internal/reflect/slice.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ func FromSlice(ctx context.Context, typ attr.Type, val reflect.Value, path *tfty
9999
tfVal := tftypes.NewValue(tfType, nil)
100100

101101
if typeWithValidate, ok := typ.(attr.TypeWithValidate); ok {
102-
diags.Append(typeWithValidate.Validate(ctx, tfVal)...)
102+
diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...)
103103

104104
if diags.HasError() {
105105
return nil, diags
@@ -152,7 +152,7 @@ func FromSlice(ctx context.Context, typ attr.Type, val reflect.Value, path *tfty
152152
tfElemVal := tftypes.NewValue(elemType.TerraformType(ctx), tfVal)
153153

154154
if typeWithValidate, ok := typ.(attr.TypeWithValidate); ok {
155-
diags.Append(typeWithValidate.Validate(ctx, tfElemVal)...)
155+
diags.Append(typeWithValidate.Validate(ctx, tfElemVal, path.WithElementKeyInt(int64(i)))...)
156156

157157
if diags.HasError() {
158158
return nil, diags
@@ -170,7 +170,7 @@ func FromSlice(ctx context.Context, typ attr.Type, val reflect.Value, path *tfty
170170
tfVal := tftypes.NewValue(tfType, tfElems)
171171

172172
if typeWithValidate, ok := typ.(attr.TypeWithValidate); ok {
173-
diags.Append(typeWithValidate.Validate(ctx, tfVal)...)
173+
diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...)
174174

175175
if diags.HasError() {
176176
return nil, diags

internal/reflect/struct.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ func FromStruct(ctx context.Context, typ attr.TypeWithAttributeTypes, val reflec
204204
tfObjVal := tftypes.NewValue(objTypes[name], tfVal)
205205

206206
if typeWithValidate, ok := typ.(attr.TypeWithValidate); ok {
207-
diags.Append(typeWithValidate.Validate(ctx, tfObjVal)...)
207+
diags.Append(typeWithValidate.Validate(ctx, tfObjVal, path)...)
208208

209209
if diags.HasError() {
210210
return nil, diags
@@ -219,7 +219,7 @@ func FromStruct(ctx context.Context, typ attr.TypeWithAttributeTypes, val reflec
219219
}, objValues)
220220

221221
if typeWithValidate, ok := typ.(attr.TypeWithValidate); ok {
222-
diags.Append(typeWithValidate.Validate(ctx, tfVal)...)
222+
diags.Append(typeWithValidate.Validate(ctx, tfVal, path)...)
223223

224224
if diags.HasError() {
225225
return nil, diags

internal/testing/types/boolwithvalidate.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ type BoolTypeWithValidateWarning struct {
2121
BoolType
2222
}
2323

24-
func (t BoolTypeWithValidateError) Validate(ctx context.Context, in tftypes.Value) diag.Diagnostics {
25-
return diag.Diagnostics{TestErrorDiagnostic}
24+
func (t BoolTypeWithValidateError) Validate(ctx context.Context, in tftypes.Value, path *tftypes.AttributePath) diag.Diagnostics {
25+
return diag.Diagnostics{TestErrorDiagnostic(path)}
2626
}
2727

28-
func (t BoolTypeWithValidateWarning) Validate(ctx context.Context, in tftypes.Value) diag.Diagnostics {
29-
return diag.Diagnostics{TestWarningDiagnostic}
28+
func (t BoolTypeWithValidateWarning) Validate(ctx context.Context, in tftypes.Value, path *tftypes.AttributePath) diag.Diagnostics {
29+
return diag.Diagnostics{TestWarningDiagnostic(path)}
3030
}

internal/testing/types/diags.go

+10-4
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,21 @@ package types
22

33
import (
44
"github.com/hashicorp/terraform-plugin-framework/diag"
5+
"github.com/hashicorp/terraform-plugin-go/tftypes"
56
)
67

7-
var (
8-
TestErrorDiagnostic = diag.NewErrorDiagnostic(
8+
func TestErrorDiagnostic(path *tftypes.AttributePath) diag.AttributeErrorDiagnostic {
9+
return diag.NewAttributeErrorDiagnostic(
10+
path,
911
"Error Diagnostic",
1012
"This is an error.",
1113
)
12-
TestWarningDiagnostic = diag.NewWarningDiagnostic(
14+
}
15+
16+
func TestWarningDiagnostic(path *tftypes.AttributePath) diag.AttributeWarningDiagnostic {
17+
return diag.NewAttributeWarningDiagnostic(
18+
path,
1319
"Warning Diagnostic",
1420
"This is a warning.",
1521
)
16-
)
22+
}

0 commit comments

Comments
 (0)