Skip to content

Commit f7f4091

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 123c67f commit f7f4091

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
@@ -163,6 +163,13 @@ func (l ListType) Validate(ctx context.Context, in tftypes.Value, path path.Path
163163
return diags
164164
}
165165

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

types/map.go

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

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

types/object.go

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

148+
// ValueType returns the Value type.
149+
func (t ObjectType) ValueType(_ context.Context) attr.Value {
150+
return Object{
151+
AttrTypes: t.AttrTypes,
152+
}
153+
}
154+
148155
// Object represents an object
149156
type Object struct {
150157
// 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
@@ -195,6 +195,13 @@ func (st SetType) Validate(ctx context.Context, in tftypes.Value, path path.Path
195195
return diags
196196
}
197197

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

0 commit comments

Comments
 (0)