Skip to content

Commit 05b3a58

Browse files
committed
attr: Add ValueType method to Type interface
Reference: #496 This will allow the internal reflection package to return better error diagnostics.
1 parent 19568f0 commit 05b3a58

File tree

12 files changed

+85
-0
lines changed

12 files changed

+85
-0
lines changed

.changelog/pending.txt

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
```release-note:breaking-change
2+
attr: The `Type` interface now requires the `ValueType` method, which is used for enhancing error diagnostics from the framework
3+
```
4+
5+
```release-note:enhancement
6+
internal/reflect: Added `attr.Value` type suggestions to error diagnostics
7+
```

attr/type.go

+6
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ type Type interface {
2525
// for the provider to consume the data with.
2626
ValueFromTerraform(context.Context, tftypes.Value) (Value, error)
2727

28+
// ValueType should return the attr.Value type returned by
29+
// ValueFromTerraform. The returned attr.Value can be any null, unknown,
30+
// or known value for the type, as this is intended for type detection
31+
// and improving error diagnostics.
32+
ValueType(context.Context) Value
33+
2834
// Equal must return true if the Type is considered semantically equal
2935
// to the Type passed as an argument.
3036
Equal(Type) bool

internal/testing/types/bool.go

+5
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ func (t BoolType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (att
5959
return Bool{Bool: types.Bool{Value: b}, CreatedBy: t}, nil
6060
}
6161

62+
// ValueType returns the Value type.
63+
func (t BoolType) ValueType(_ context.Context) attr.Value {
64+
return Bool{}
65+
}
66+
6267
type Bool struct {
6368
types.Bool
6469

internal/testing/types/invalid.go

+5
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ func (t InvalidType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (
3838
return nil, fmt.Errorf("intentional ValueFromTerraform error")
3939
}
4040

41+
// ValueType returns the Value type.
42+
func (t InvalidType) ValueType(_ context.Context) attr.Value {
43+
return Invalid{}
44+
}
45+
4146
// Invalid is an attr.Value that returns errors for methods than can return errors.
4247
type Invalid struct{}
4348

internal/testing/types/number.go

+5
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ func (t NumberType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (a
6363
}, nil
6464
}
6565

66+
// ValueType returns the Value type.
67+
func (t NumberType) ValueType(_ context.Context) attr.Value {
68+
return Number{}
69+
}
70+
6671
type Number struct {
6772
types.Number
6873

internal/testing/types/string.go

+5
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ func (t StringType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (a
6262
}, nil
6363
}
6464

65+
// ValueType returns the Value type.
66+
func (t StringType) ValueType(_ context.Context) attr.Value {
67+
return String{}
68+
}
69+
6570
type String struct {
6671
InternalString types.String
6772

types/list.go

+7
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,13 @@ func (l ListType) Validate(ctx context.Context, in tftypes.Value, path path.Path
162162
return diags
163163
}
164164

165+
// ValueType returns the Value type.
166+
func (t ListType) ValueType(_ context.Context) attr.Value {
167+
return List{
168+
ElemType: t.ElemType,
169+
}
170+
}
171+
165172
// List represents a list of attr.Values, all of the same type, indicated
166173
// by ElemType.
167174
type List struct {

types/map.go

+7
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,13 @@ func (m MapType) Validate(ctx context.Context, in tftypes.Value, path path.Path)
166166
return diags
167167
}
168168

169+
// ValueType returns the Value type.
170+
func (t MapType) ValueType(_ context.Context) attr.Value {
171+
return Map{
172+
ElemType: t.ElemType,
173+
}
174+
}
175+
169176
// Map represents a map of attr.Values, all of the same type, indicated by
170177
// ElemType. Keys for the map will always be strings.
171178
type Map struct {

types/object.go

+7
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,13 @@ func (o ObjectType) String() string {
143143
return res.String()
144144
}
145145

146+
// ValueType returns the Value type.
147+
func (t ObjectType) ValueType(_ context.Context) attr.Value {
148+
return Object{
149+
AttrTypes: t.AttrTypes,
150+
}
151+
}
152+
146153
// Object represents an object
147154
type Object struct {
148155
// Unknown will be set to true if the entire object is an unknown value.

types/primitive.go

+19
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,25 @@ func (p primitive) ValueFromTerraform(ctx context.Context, in tftypes.Value) (at
9292
}
9393
}
9494

95+
// ValueType returns the Value type.
96+
func (p primitive) ValueType(_ context.Context) attr.Value {
97+
// These Value do not need to be valid.
98+
switch p {
99+
case BoolType:
100+
return Bool{}
101+
case Float64Type:
102+
return Float64{}
103+
case Int64Type:
104+
return Int64{}
105+
case NumberType:
106+
return Number{}
107+
case StringType:
108+
return String{}
109+
default:
110+
panic(fmt.Sprintf("unknown primitive %d", p))
111+
}
112+
}
113+
95114
// Equal returns true if `o` is also a primitive, and is the same type of
96115
// primitive as `p`.
97116
func (p primitive) Equal(o attr.Type) bool {

types/primitive_test.go

+5
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ func (t testAttributeType) String() string {
9090
panic("not implemented")
9191
}
9292

93+
// ValueType returns the Value type.
94+
func (t testAttributeType) ValueType(_ context.Context) attr.Value {
95+
panic("not implemented")
96+
}
97+
9398
func TestPrimitiveEqual(t *testing.T) {
9499
t.Parallel()
95100

types/set.go

+7
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,13 @@ func (st SetType) Validate(ctx context.Context, in tftypes.Value, path path.Path
194194
return diags
195195
}
196196

197+
// ValueType returns the Value type.
198+
func (t SetType) ValueType(_ context.Context) attr.Value {
199+
return Set{
200+
ElemType: t.ElemType,
201+
}
202+
}
203+
197204
// Set represents a set of attr.Value, all of the same type,
198205
// indicated by ElemType.
199206
type Set struct {

0 commit comments

Comments
 (0)