Skip to content

Commit 0b971a1

Browse files
author
Paddy Carver
committed
Add type parsing to fromproto.
Use the same type parsing we use when unmarshalling DynamicPseudoTypes to unmarshal type information in fromproto.
1 parent a5966a7 commit 0b971a1

File tree

5 files changed

+80
-37
lines changed

5 files changed

+80
-37
lines changed

tfprotov5/internal/fromproto/provider.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,17 @@ func GetProviderSchemaRequest(in tfplugin5.GetProviderSchema_Request) (tfprotov5
1414
func GetProviderSchemaResponse(in tfplugin5.GetProviderSchema_Response) (tfprotov5.GetProviderSchemaResponse, error) {
1515
var resp tfprotov5.GetProviderSchemaResponse
1616
if in.Provider != nil {
17-
schema := Schema(*in.Provider)
17+
schema, err := Schema(*in.Provider)
18+
if err != nil {
19+
return resp, err
20+
}
1821
resp.Provider = &schema
1922
}
2023
if in.ProviderMeta != nil {
21-
schema := Schema(*in.ProviderMeta)
24+
schema, err := Schema(*in.ProviderMeta)
25+
if err != nil {
26+
return resp, err
27+
}
2228
resp.ProviderMeta = &schema
2329
}
2430
resp.ResourceSchemas = make(map[string]*tfprotov5.Schema, len(in.ResourceSchemas))
@@ -27,7 +33,10 @@ func GetProviderSchemaResponse(in tfplugin5.GetProviderSchema_Response) (tfproto
2733
resp.ResourceSchemas[k] = nil
2834
continue
2935
}
30-
schema := Schema(*v)
36+
schema, err := Schema(*v)
37+
if err != nil {
38+
return resp, err
39+
}
3140
resp.ResourceSchemas[k] = &schema
3241
}
3342
resp.DataSourceSchemas = make(map[string]*tfprotov5.Schema, len(in.DataSourceSchemas))
@@ -36,7 +45,10 @@ func GetProviderSchemaResponse(in tfplugin5.GetProviderSchema_Response) (tfproto
3645
resp.DataSourceSchemas[k] = nil
3746
continue
3847
}
39-
schema := Schema(*v)
48+
schema, err := Schema(*v)
49+
if err != nil {
50+
return resp, err
51+
}
4052
resp.DataSourceSchemas[k] = &schema
4153
}
4254
diags, err := Diagnostics(in.Diagnostics)

tfprotov5/internal/fromproto/schema.go

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,48 @@
11
package fromproto
22

33
import (
4+
"fmt"
5+
46
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
57
"github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5"
68
)
79

8-
func Schema(in tfplugin5.Schema) tfprotov5.Schema {
10+
func Schema(in tfplugin5.Schema) (tfprotov5.Schema, error) {
911
var resp tfprotov5.Schema
1012
resp.Version = in.Version
1113
if in.Block != nil {
12-
block := SchemaBlock(*in.Block)
14+
block, err := SchemaBlock(*in.Block)
15+
if err != nil {
16+
return resp, err
17+
}
1318
resp.Block = &block
1419
}
15-
return resp
20+
return resp, nil
1621
}
1722

18-
func SchemaBlock(in tfplugin5.Schema_Block) tfprotov5.SchemaBlock {
19-
return tfprotov5.SchemaBlock{
23+
func SchemaBlock(in tfplugin5.Schema_Block) (tfprotov5.SchemaBlock, error) {
24+
resp := tfprotov5.SchemaBlock{
2025
Version: in.Version,
21-
Attributes: SchemaAttributes(in.Attributes),
22-
BlockTypes: SchemaNestedBlocks(in.BlockTypes),
2326
Description: in.Description,
2427
DescriptionKind: StringKind(in.DescriptionKind),
2528
Deprecated: in.Deprecated,
2629
}
30+
attrs, err := SchemaAttributes(in.Attributes)
31+
if err != nil {
32+
return resp, err
33+
}
34+
resp.Attributes = attrs
35+
blocks, err := SchemaNestedBlocks(in.BlockTypes)
36+
if err != nil {
37+
return resp, err
38+
}
39+
resp.BlockTypes = blocks
40+
return resp, nil
2741
}
2842

29-
func SchemaAttribute(in tfplugin5.Schema_Attribute) tfprotov5.SchemaAttribute {
30-
return tfprotov5.SchemaAttribute{
43+
func SchemaAttribute(in tfplugin5.Schema_Attribute) (tfprotov5.SchemaAttribute, error) {
44+
resp := tfprotov5.SchemaAttribute{
3145
Name: in.Name,
32-
Type: TerraformTypesType(in.Type),
3346
Description: in.Description,
3447
Required: in.Required,
3548
Optional: in.Optional,
@@ -38,46 +51,61 @@ func SchemaAttribute(in tfplugin5.Schema_Attribute) tfprotov5.SchemaAttribute {
3851
DescriptionKind: StringKind(in.DescriptionKind),
3952
Deprecated: in.Deprecated,
4053
}
54+
typ, err := TerraformTypesType(in.Type)
55+
if err != nil {
56+
return resp, err
57+
}
58+
resp.Type = typ
59+
return resp, nil
4160
}
4261

43-
func SchemaAttributes(in []*tfplugin5.Schema_Attribute) []*tfprotov5.SchemaAttribute {
62+
func SchemaAttributes(in []*tfplugin5.Schema_Attribute) ([]*tfprotov5.SchemaAttribute, error) {
4463
resp := make([]*tfprotov5.SchemaAttribute, 0, len(in))
45-
for _, a := range in {
64+
for pos, a := range in {
4665
if a == nil {
4766
resp = append(resp, nil)
4867
continue
4968
}
50-
attr := SchemaAttribute(*a)
69+
attr, err := SchemaAttribute(*a)
70+
if err != nil {
71+
return resp, fmt.Errorf("error converting schema attribute %d: %w", pos, err)
72+
}
5173
resp = append(resp, &attr)
5274
}
53-
return resp
75+
return resp, nil
5476
}
5577

56-
func SchemaNestedBlock(in tfplugin5.Schema_NestedBlock) tfprotov5.SchemaNestedBlock {
78+
func SchemaNestedBlock(in tfplugin5.Schema_NestedBlock) (tfprotov5.SchemaNestedBlock, error) {
5779
resp := tfprotov5.SchemaNestedBlock{
5880
TypeName: in.TypeName,
5981
Nesting: SchemaNestedBlockNestingMode(in.Nesting),
6082
MinItems: in.MinItems,
6183
MaxItems: in.MaxItems,
6284
}
6385
if in.Block != nil {
64-
block := SchemaBlock(*in.Block)
86+
block, err := SchemaBlock(*in.Block)
87+
if err != nil {
88+
return resp, err
89+
}
6590
resp.Block = &block
6691
}
67-
return resp
92+
return resp, nil
6893
}
6994

70-
func SchemaNestedBlocks(in []*tfplugin5.Schema_NestedBlock) []*tfprotov5.SchemaNestedBlock {
95+
func SchemaNestedBlocks(in []*tfplugin5.Schema_NestedBlock) ([]*tfprotov5.SchemaNestedBlock, error) {
7196
resp := make([]*tfprotov5.SchemaNestedBlock, 0, len(in))
72-
for _, b := range in {
97+
for pos, b := range in {
7398
if b == nil {
7499
resp = append(resp, nil)
75100
continue
76101
}
77-
block := SchemaNestedBlock(*b)
102+
block, err := SchemaNestedBlock(*b)
103+
if err != nil {
104+
return resp, fmt.Errorf("error converting nested block %d: %w", pos, err)
105+
}
78106
resp = append(resp, &block)
79107
}
80-
return resp
108+
return resp, nil
81109
}
82110

83111
func SchemaNestedBlockNestingMode(in tfplugin5.Schema_NestedBlock_NestingMode) tfprotov5.SchemaNestedBlockNestingMode {

tfprotov5/internal/fromproto/types.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,11 @@ func typeFromValue(in interface{}) (tftypes.Type, error) {
140140
return tftypes.UnknownType, fmt.Errorf("Go type %T has no default tftypes.Type", in)
141141
}
142142

143-
func TerraformTypesType(in []byte) tftypes.Type {
144-
// TODO: figure out how to unmarshal a cty []byte to tftypes.Type
145-
var resp tftypes.Type
146-
return resp
143+
func TerraformTypesType(in []byte) (tftypes.Type, error) {
144+
var raw interface{}
145+
err := json.Unmarshal(in, &raw)
146+
if err != nil {
147+
return nil, fmt.Errorf("error parsing type, not valid JSON: %w", err)
148+
}
149+
return tftypes.ParseType(raw)
147150
}

tfprotov5/tftypes/raw_value.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ func (r RawValue) Unmarshal(dst interface{}) error {
184184
if err != nil {
185185
return fmt.Errorf("can't unmarshal into tftypes.RawValue; invalid type information. First value %q isn't valid JSON: %w", str, err)
186186
}
187-
parsedType, err := parseType(typ)
187+
parsedType, err := ParseType(typ)
188188
if err != nil {
189189
return fmt.Errorf("error parsing type: %w", err)
190190
}
@@ -234,7 +234,7 @@ func (r RawValue) Unmarshal(dst interface{}) error {
234234
if err != nil {
235235
return fmt.Errorf("can't unmarshal into tftypes.RawValue; invalid type information. \"type\" key's value %q isn't valid JSON: %w", typeStr, err)
236236
}
237-
parsedType, err := parseType(typ)
237+
parsedType, err := ParseType(typ)
238238
if err != nil {
239239
return fmt.Errorf("error parsing type: %w", err)
240240
}

tfprotov5/tftypes/type.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ type Type interface {
88
private()
99
}
1010

11-
func parseType(in interface{}) (Type, error) {
11+
func ParseType(in interface{}) (Type, error) {
1212
switch v := in.(type) {
1313
// primitive types are represented just as strings,
1414
// with the type name in the string itself
@@ -35,7 +35,7 @@ func parseType(in interface{}) (Type, error) {
3535
if len(v) != 2 {
3636
return nil, fmt.Errorf("improperly formatted type information; need %d elements, got %d", 2, len(v))
3737
}
38-
subType, err := parseType(v[1])
38+
subType, err := ParseType(v[1])
3939
if err != nil {
4040
return nil, fmt.Errorf("error parsing element type for tftypes.Set: %w", err)
4141
}
@@ -46,7 +46,7 @@ func parseType(in interface{}) (Type, error) {
4646
if len(v) != 2 {
4747
return nil, fmt.Errorf("improperly formatted type information; need %d elements, got %d", 2, len(v))
4848
}
49-
subType, err := parseType(v[1])
49+
subType, err := ParseType(v[1])
5050
if err != nil {
5151
return nil, fmt.Errorf("error parsing element type for tftypes.List: %w", err)
5252
}
@@ -59,7 +59,7 @@ func parseType(in interface{}) (Type, error) {
5959
}
6060
var types []Type
6161
for pos, typ := range v {
62-
subType, err := parseType(typ)
62+
subType, err := ParseType(typ)
6363
if err != nil {
6464
return nil, fmt.Errorf("error parsing type of element %d for tftypes.Tuple: %w", pos, err)
6565
}
@@ -72,7 +72,7 @@ func parseType(in interface{}) (Type, error) {
7272
if len(v) != 2 {
7373
return nil, fmt.Errorf("improperly formatted type information; need %d elements, got %d", 2, len(v))
7474
}
75-
subType, err := parseType(v[1])
75+
subType, err := ParseType(v[1])
7676
if err != nil {
7777
return nil, fmt.Errorf("error parsing attribute type for tftypes.Map: %w", err)
7878
}
@@ -86,7 +86,7 @@ func parseType(in interface{}) (Type, error) {
8686
types := map[string]Type{}
8787
valTypes := v[1].(map[string]interface{})
8888
for key, typ := range valTypes {
89-
subType, err := parseType(typ)
89+
subType, err := ParseType(typ)
9090
if err != nil {
9191
return nil, fmt.Errorf("error parsing type of attribute %q for tftypes.Object: %w", key, err)
9292
}

0 commit comments

Comments
 (0)