Skip to content

Commit

Permalink
use a model's ToSchema function if it has one
Browse files Browse the repository at this point in the history
  • Loading branch information
rauchy committed Dec 30, 2024
1 parent 151ed6d commit 9711e91
Showing 1 changed file with 27 additions and 11 deletions.
38 changes: 27 additions & 11 deletions internal/providers/pluginfw/tfschema/struct_to_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ import (
"github.com/hashicorp/terraform-plugin-framework/types"
)

type CustomizableSchemaProvider interface {
ToSchema(cs CustomizableSchema, path ...string) CustomizableSchema
}

type structTag struct {
optional bool
computed bool
Expand All @@ -26,6 +30,7 @@ type structTag struct {
func typeToSchema(ctx context.Context, v reflect.Value) NestedBlockObject {
scmAttr := map[string]AttributeBuilder{}
rk := v.Kind()
typeProvidesSchemaCustomization := v.Type().Implements(reflect.TypeOf((*CustomizableSchemaProvider)(nil)).Elem())
if rk == reflect.Ptr {
v = v.Elem()
rk = v.Kind()
Expand Down Expand Up @@ -139,21 +144,28 @@ func typeToSchema(ctx context.Context, v reflect.Value) NestedBlockObject {
}
panic(fmt.Errorf("unexpected type %T in tfsdk structs, expected a plugin framework value type. %s", value, common.TerraformBugErrorMessage))
}

attr := scmAttr[fieldName]
if structTag.computed {
// Computed attributes are always computed and may be optional.
attr = attr.SetComputed()
if structTag.optional {
attr = attr.SetOptional()
}

if typeProvidesSchemaCustomization {
attr = attr.SetOptional() // default to optional, ToSchema may override this
} else {
// Non-computed attributes must be either optional or required.
if structTag.optional {
attr = attr.SetOptional()
if structTag.computed {
// Computed attributes are always computed and may be optional.
attr = attr.SetComputed()
if structTag.optional {
attr = attr.SetOptional()
}
} else {
attr = attr.SetRequired()
// Non-computed attributes must be either optional or required.
if structTag.optional {
attr = attr.SetOptional()
} else {
attr = attr.SetRequired()
}
}
}

scmAttr[fieldName] = attr
}
return NestedBlockObject{Attributes: scmAttr}
Expand Down Expand Up @@ -185,7 +197,11 @@ func ResourceStructToSchemaMap(ctx context.Context, v any, customizeSchema func(
nestedBlockObj := typeToSchema(ctx, reflect.ValueOf(v))

if customizeSchema != nil {
cs := customizeSchema(*ConstructCustomizableSchema(nestedBlockObj))
cs := *ConstructCustomizableSchema(nestedBlockObj)
if schemaProvider, ok := v.(CustomizableSchemaProvider); ok {
cs = schemaProvider.ToSchema(cs)
}
cs = customizeSchema(cs)
return BuildResourceAttributeMap(cs.ToNestedBlockObject().Attributes), BuildResourceBlockMap(cs.ToNestedBlockObject().Blocks)
} else {
return BuildResourceAttributeMap(nestedBlockObj.Attributes), BuildResourceBlockMap(nestedBlockObj.Blocks)
Expand Down

0 comments on commit 9711e91

Please sign in to comment.