hashicorp / hashicorp/terraform-plugin-codegen-framework

Consider only generating one custom type per associated external type

Open
#86 0 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
Go
Stars
57
Forks
29
Avg merge
2d 13h
Merged PRs (30d)
1

Description

Currently, the code generator iterates over the spec and generates custom type and value types for each attribute that has an `associated_external_type`. This could result in the generation of many custom types that provide the same functionality.

For example, given the following spec:

```json
{
"version": "0.1",
"datasources": [
{
"name": "example",
"schema": {
"attributes": [
{
"name": "bool_attribute",
"bool": {
"associated_external_type": {
"import": {
"path": "github.com/hashicorp/api"
},
"type": "*api.ExternalBool"
},
"computed_optional_required": "required"
}
},
{
"name": "another_bool_attribute",
"bool": {
"associated_external_type": {
"import": {
"path": "github.com/hashicorp/api"
},
"type": "*api.ExternalBool"
},
"computed_optional_required": "required"
}
}
]
}
}
],
"provider": {
"name": "provider"
}
}
```

The code generator will produce the following:

```go
return schema.Schema{
Attributes: map[string]schema.Attribute{
"another_bool_attribute": schema.BoolAttribute{
CustomType: AnotherBoolAttributeType{},
Required: true,
},
"bool_attribute": schema.BoolAttribute{
CustomType: BoolAttributeType{},
Required: true,
},
},
}
}

type ExampleModel struct {
AnotherBoolAttribute AnotherBoolAttributeValue `tfsdk:"another_bool_attribute"`
BoolAttribute BoolAttributeValue `tfsdk:"bool_attribute"`
}

func (v AnotherBoolAttributeValue) ToApiExternalBool(ctx context.Context) (*api.ExternalBool, diag.Diagnostics) {
var diags diag.Diagnostics

if v.IsNull() {
return nil, diags
}

if v.IsUnknown() {
diags.Append(diag.NewErrorDiagnostic(
"AnotherBoolAttributeValue Value Is Unknown",
`"AnotherBoolAttributeValue" is unknown.`,
))

return nil, diags
}

a := api.ExternalBool(v.ValueBoolPointer())

return &a, diags
}

func (v BoolAttributeValue) ToApiExternalBool(ctx context.Context) (*api.ExternalBool, diag.Diagnostics) {
var diags diag.Diagnostics

if v.IsNull() {
return nil, diags
}

if v.IsUnknown() {
diags.Append(diag.NewErrorDiagnostic(
"BoolAttributeValue Value Is Unknown",
`"BoolAttributeValue" is unknown.`,
))

return nil, diags
}

a := api.ExternalBool(v.ValueBoolPointer())

return &a, diags
}
```

Consideration should be given to consolidating the generation of custom type and value types in instances where the code contained in the generated functions is essentially identical. For example:

```go
func ExampleDataSourceSchema(ctx context.Context) schema.Schema {
return schema.Schema{
Attributes: map[string]schema.Attribute{
"another_bool_attribute": schema.BoolAttribute{
CustomType: BoolAttributeType{},
Required: true,
},
"bool_attribute": schema.BoolAttribute{
CustomType: BoolAttributeType{},
Required: true,
},
},
}
}

type ExampleModel struct {
AnotherBoolAttribute BoolAttributeValue `tfsdk:"another_bool_attribute"`
BoolAttribute BoolAttributeValue `tfsdk:"bool_attribute"`
}

func (v BoolAttributeValue) ToApiExternalBool(ctx context.Context) (*api.ExternalBool, diag.Diagnostics) {
var diags diag.Diagnostics

if v.IsNull() {
return nil, diags
}

if v.IsUnknown() {
diags.Append(diag.NewErrorDiagnostic(
"BoolAttributeValue Value Is Unknown",
`"BoolAttributeValue" is unknown.`,
))

return nil, diags
}

a := api.ExternalBool(v.ValueBoolPointer())

return &a, diags
}
```

Handling of the generation of attribute-specific diagnostics would require further consideration under these circumstances, for example:

```go
if v.IsUnknown() {
diags.Append(diag.NewErrorDiagnostic(
"BoolAttributeValue Value Is Unknown",
`"BoolAttributeValue" is unknown.`,
))

return nil, diags
}
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.