/
object.go
118 lines (101 loc) · 4.02 KB
/
object.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package apitypes
import (
"github.com/swaggest/openapi-go/openapi3"
"golang.org/x/exp/maps"
)
// Object represents an object with known property types.
type Object struct {
Schema *openapi3.Schema
// We store the object properties in structs generated by schemas.go. We
// need to reference those structs in the code generated here
TFModelStructName string
TFSchemaAttrTypeMapName string
TFSchemaAttributesMapName string
JSONClientModelStructName string
// We also generate functions in schemas.go that iterate over the object
// properties in order to convert between model types
TFModelToJSONClientFuncName string
JSONClientModelToTFFuncName string
}
// TFModelType returns the type that should be used to represent this type in a Terraform model.
func (t *Object) TFModelType() string {
return "types.Object"
}
// TFSchemaAttributeType returns an attr.Type, which is a struct representing the type of this
// object in the Terraform schema.
func (t *Object) TFSchemaAttributeType() string {
return `types.ObjectType{
AttrTypes: ` + t.TFSchemaAttrTypeMapName + `,
}`
}
// TFSchemaAttributeText returns the text of the code for instantiating this type as a Terraform
// schema attribute.
func (t *Object) TFSchemaAttributeText(extraFields map[string]string) string {
fields := makeCommonFields(t.Schema)
maps.Copy(fields, extraFields)
return `schema.SingleNestedAttribute{
Attributes: ` + t.TFSchemaAttributesMapName + `,
` + fieldsToString(fields) + `
}`
}
// JSONClientModelType returns the type that should be used to represent this type in a jsonclient
// request/response struct.
func (t *Object) JSONClientModelType() string {
return t.JSONClientModelStructName
}
// TFModelToJSONClientFunc returns the text of a function for converting a Terraform model struct to
// a jsonclient model struct.
func (t *Object) TFModelToJSONClientFunc() string {
return `func (val *` + t.TFModelType() + `) (*` + t.JSONClientModelType() + `, error) {
if val == nil || val.IsNull() || val.IsUnknown() {
return nil, nil
}
attrs := val.Attributes()
tfModel := ` + t.TFModelStructName + `{}
reflected := reflect.ValueOf(&tfModel)
tfsdkNamesToFieldNames := map[string]string{}
for i := 0; i < reflect.Indirect(reflected).NumField(); i++ {
tfsdkNamesToFieldNames[reflect.Indirect(reflected).Type().Field(i).Tag.Get("tfsdk")] = reflect.Indirect(reflected).Type().Field(i).Name
}
for k, v := range attrs {
reflect.Indirect(reflected).FieldByName(tfsdkNamesToFieldNames[k]).Set(reflect.ValueOf(v))
}
return ` + t.TFModelToJSONClientFuncName + `(&tfModel)
}`
}
// JSONClientModelToTFFunc returns the text of a function for converting a jsonclient model struct
// to a Terraform model struct.
func (t *Object) JSONClientModelToTFFunc() string {
return `func (val *` + t.JSONClientModelType() + `) (` + t.TFModelType() + `, error) {
attrTypes := ` + t.TFSchemaAttrTypeMapName + `
if val == nil {
return types.ObjectNull(attrTypes), nil
}
tfModel, err := ` + t.JSONClientModelToTFFuncName + `(val)
if err != nil {
return types.ObjectNull(attrTypes), ucerr.Wrap(err)
}
v := reflect.ValueOf(tfModel)
attrVals := map[string]attr.Value{}
for i := 0; i < v.NumField(); i++ {
attrVals[v.Type().Field(i).Tag.Get("tfsdk")] = v.Field(i).Interface().(attr.Value)
}
objVal, diag := types.ObjectValue(attrTypes, attrVals)
if diag.ErrorsCount() > 0 {
return types.ObjectNull(attrTypes), ucerr.Errorf("failed to convert ` + t.TFModelStructName + ` to terraform basetypes.Object: %s", diag.Errors()[0].Detail())
}
return objVal, nil
}`
}
// GetTFPlanModifierType returns the name of the
// terraform-plugin-framework/resource/schema/planmodifier type for this API
// type (e.g. String, Int64, etc.)
func (t *Object) GetTFPlanModifierType() string {
return "Object"
}
// GetTFPlanModifierPackageName returns the name of the package
// (terraform-plugin-framework/resource/schema/RETURNVALUE) containing the plan
// modifiers for this type
func (t *Object) GetTFPlanModifierPackageName() string {
return "objectplanmodifier"
}