diff --git a/pluginframework/tfschema/attribute_builder.go b/pluginframework/tfschema/attribute_builder.go new file mode 100644 index 0000000000..47d6a756af --- /dev/null +++ b/pluginframework/tfschema/attribute_builder.go @@ -0,0 +1,42 @@ +package tfschema + +import ( + dataschema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" +) + +// AttributeBuilder is the common interface for all attributes, it can be used to build data source attribute and resource attribute. +// We need this because in terraform plugin framework, the datasource schema and resource schema are in two separate packages. +// This common interface prevents us from keeping two copies of StructToSchema and CustomizableSchema. +type AttributeBuilder interface { + BuildDataSourceAttribute() dataschema.Attribute + BuildResourceAttribute() schema.Attribute + SetOptional() AttributeBuilder + SetRequired() AttributeBuilder + SetSensitive() AttributeBuilder + SetComputed() AttributeBuilder + SetReadOnly() AttributeBuilder + SetDeprecated(string) AttributeBuilder +} + +// BuildDataSourceAttributeMap takes a map from string to AttributeBuilder and returns a map from string to datasource.schema.Attribute +func BuildDataSourceAttributeMap(attributes map[string]AttributeBuilder) map[string]dataschema.Attribute { + dataSourceAttributes := make(map[string]dataschema.Attribute) + + for key, attribute := range attributes { + dataSourceAttributes[key] = attribute.BuildDataSourceAttribute() + } + + return dataSourceAttributes +} + +// BuildResourceAttributeMap takes a map from string to AttributeBuilder and returns a map from string to resource.schema.Attribute +func BuildResourceAttributeMap(attributes map[string]AttributeBuilder) map[string]schema.Attribute { + resourceAttributes := make(map[string]schema.Attribute) + + for key, attribute := range attributes { + resourceAttributes[key] = attribute.BuildResourceAttribute() + } + + return resourceAttributes +} diff --git a/pluginframework/tfschema/bool_attribute.go b/pluginframework/tfschema/bool_attribute.go new file mode 100644 index 0000000000..4e96dce28f --- /dev/null +++ b/pluginframework/tfschema/bool_attribute.go @@ -0,0 +1,78 @@ +package tfschema + +import ( + dataschema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +type BoolAttributeBuilder struct { + Optional bool + Required bool + Sensitive bool + Computed bool + DeprecationMessage string + Validators []validator.Bool +} + +func (a BoolAttributeBuilder) BuildDataSourceAttribute() dataschema.Attribute { + return dataschema.BoolAttribute{Optional: a.Optional, Required: a.Required, Sensitive: a.Sensitive, DeprecationMessage: a.DeprecationMessage, Computed: a.Computed, Validators: a.Validators} +} + +func (a BoolAttributeBuilder) BuildResourceAttribute() schema.Attribute { + return schema.BoolAttribute{Optional: a.Optional, Required: a.Required, Sensitive: a.Sensitive, DeprecationMessage: a.DeprecationMessage, Computed: a.Computed, Validators: a.Validators} +} + +func (a BoolAttributeBuilder) SetOptional() AttributeBuilder { + if a.Optional && !a.Required { + panic("attribute is already optional") + } + a.Optional = true + a.Required = false + return a +} + +func (a BoolAttributeBuilder) SetRequired() AttributeBuilder { + if !a.Optional && a.Required { + panic("attribute is already required") + } + a.Optional = false + a.Required = true + return a +} + +func (a BoolAttributeBuilder) SetSensitive() AttributeBuilder { + if a.Sensitive { + panic("attribute is already sensitive") + } + a.Sensitive = true + return a +} + +func (a BoolAttributeBuilder) SetComputed() AttributeBuilder { + if a.Computed { + panic("attribute is already computed") + } + a.Computed = true + return a +} + +func (a BoolAttributeBuilder) SetReadOnly() AttributeBuilder { + if a.Computed && !a.Optional && !a.Required { + panic("attribute is already read only") + } + a.Computed = true + a.Optional = false + a.Required = false + return a +} + +func (a BoolAttributeBuilder) SetDeprecated(msg string) AttributeBuilder { + a.DeprecationMessage = msg + return a +} + +func (a BoolAttributeBuilder) AddValidator(v validator.Bool) AttributeBuilder { + a.Validators = append(a.Validators, v) + return a +} diff --git a/pluginframework/tfschema/float64_attribute.go b/pluginframework/tfschema/float64_attribute.go new file mode 100644 index 0000000000..47923ea70e --- /dev/null +++ b/pluginframework/tfschema/float64_attribute.go @@ -0,0 +1,78 @@ +package tfschema + +import ( + dataschema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +type Float64Attribute struct { + Optional bool + Required bool + Sensitive bool + Computed bool + DeprecationMessage string + Validators []validator.Float64 +} + +func (a Float64Attribute) BuildDataSourceAttribute() dataschema.Attribute { + return dataschema.Float64Attribute{Optional: a.Optional, Required: a.Required, Sensitive: a.Sensitive, DeprecationMessage: a.DeprecationMessage, Computed: a.Computed, Validators: a.Validators} +} + +func (a Float64Attribute) BuildResourceAttribute() schema.Attribute { + return schema.Float64Attribute{Optional: a.Optional, Required: a.Required, Sensitive: a.Sensitive, DeprecationMessage: a.DeprecationMessage, Computed: a.Computed, Validators: a.Validators} +} + +func (a Float64Attribute) SetOptional() AttributeBuilder { + if a.Optional && !a.Required { + panic("attribute is already optional") + } + a.Optional = true + a.Required = false + return a +} + +func (a Float64Attribute) SetRequired() AttributeBuilder { + if !a.Optional && a.Required { + panic("attribute is already required") + } + a.Optional = false + a.Required = true + return a +} + +func (a Float64Attribute) SetSensitive() AttributeBuilder { + if a.Sensitive { + panic("attribute is already sensitive") + } + a.Sensitive = true + return a +} + +func (a Float64Attribute) SetComputed() AttributeBuilder { + if a.Computed { + panic("attribute is already computed") + } + a.Computed = true + return a +} + +func (a Float64Attribute) SetReadOnly() AttributeBuilder { + if a.Computed && !a.Optional && !a.Required { + panic("attribute is already read only") + } + a.Computed = true + a.Optional = false + a.Required = false + return a +} + +func (a Float64Attribute) SetDeprecated(msg string) AttributeBuilder { + a.DeprecationMessage = msg + return a +} + +func (a Float64Attribute) AddValidator(v validator.Float64) AttributeBuilder { + a.Validators = append(a.Validators, v) + return a +} diff --git a/pluginframework/tfschema/int64_attribute.go b/pluginframework/tfschema/int64_attribute.go new file mode 100644 index 0000000000..0fac4251ac --- /dev/null +++ b/pluginframework/tfschema/int64_attribute.go @@ -0,0 +1,78 @@ +package tfschema + +import ( + dataschema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +type Int64Attribute struct { + Optional bool + Required bool + Sensitive bool + Computed bool + DeprecationMessage string + Validators []validator.Int64 +} + +func (a Int64Attribute) BuildDataSourceAttribute() dataschema.Attribute { + return dataschema.Int64Attribute{Optional: a.Optional, Required: a.Required, Sensitive: a.Sensitive, DeprecationMessage: a.DeprecationMessage, Computed: a.Computed, Validators: a.Validators} +} + +func (a Int64Attribute) BuildResourceAttribute() schema.Attribute { + return schema.Int64Attribute{Optional: a.Optional, Required: a.Required, Sensitive: a.Sensitive, DeprecationMessage: a.DeprecationMessage, Computed: a.Computed, Validators: a.Validators} +} + +func (a Int64Attribute) SetOptional() AttributeBuilder { + if a.Optional && !a.Required { + panic("attribute is already optional") + } + a.Optional = true + a.Required = false + return a +} + +func (a Int64Attribute) SetRequired() AttributeBuilder { + if !a.Optional && a.Required { + panic("attribute is already required") + } + a.Optional = false + a.Required = true + return a +} + +func (a Int64Attribute) SetSensitive() AttributeBuilder { + if a.Sensitive { + panic("attribute is already sensitive") + } + a.Sensitive = true + return a +} + +func (a Int64Attribute) SetComputed() AttributeBuilder { + if a.Computed { + panic("attribute is already computed") + } + a.Computed = true + return a +} + +func (a Int64Attribute) SetReadOnly() AttributeBuilder { + if a.Computed && !a.Optional && !a.Required { + panic("attribute is already read only") + } + a.Computed = true + a.Optional = false + a.Required = false + return a +} + +func (a Int64Attribute) SetDeprecated(msg string) AttributeBuilder { + a.DeprecationMessage = msg + return a +} + +func (a Int64Attribute) AddValidator(v validator.Int64) AttributeBuilder { + a.Validators = append(a.Validators, v) + return a +} diff --git a/pluginframework/tfschema/list_attribute.go b/pluginframework/tfschema/list_attribute.go new file mode 100644 index 0000000000..60e44e6eb5 --- /dev/null +++ b/pluginframework/tfschema/list_attribute.go @@ -0,0 +1,81 @@ +package tfschema + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + dataschema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +// ListAttributte represents a list of primitive types. +type ListAttribute struct { + ElementType attr.Type + Optional bool + Required bool + Sensitive bool + Computed bool + DeprecationMessage string + Validators []validator.List +} + +func (a ListAttribute) BuildDataSourceAttribute() dataschema.Attribute { + return dataschema.ListAttribute{ElementType: a.ElementType, Optional: a.Optional, Required: a.Required, Sensitive: a.Sensitive, DeprecationMessage: a.DeprecationMessage, Computed: a.Computed, Validators: a.Validators} +} + +func (a ListAttribute) BuildResourceAttribute() schema.Attribute { + return schema.ListAttribute{ElementType: a.ElementType, Optional: a.Optional, Required: a.Required, Sensitive: a.Sensitive, DeprecationMessage: a.DeprecationMessage, Computed: a.Computed, Validators: a.Validators} +} + +func (a ListAttribute) SetOptional() AttributeBuilder { + if a.Optional && !a.Required { + panic("attribute is already optional") + } + a.Optional = true + a.Required = false + return a +} + +func (a ListAttribute) SetRequired() AttributeBuilder { + if !a.Optional && a.Required { + panic("attribute is already required") + } + a.Optional = false + a.Required = true + return a +} + +func (a ListAttribute) SetSensitive() AttributeBuilder { + if a.Sensitive { + panic("attribute is already sensitive") + } + a.Sensitive = true + return a +} + +func (a ListAttribute) SetComputed() AttributeBuilder { + if a.Computed { + panic("attribute is already computed") + } + a.Computed = true + return a +} + +func (a ListAttribute) SetReadOnly() AttributeBuilder { + if a.Computed && !a.Optional && !a.Required { + panic("attribute is already read only") + } + a.Computed = true + a.Optional = false + a.Required = false + return a +} + +func (a ListAttribute) SetDeprecated(msg string) AttributeBuilder { + a.DeprecationMessage = msg + return a +} + +func (a ListAttribute) AddValidator(v validator.List) AttributeBuilder { + a.Validators = append(a.Validators, v) + return a +} diff --git a/pluginframework/tfschema/list_nested_attribute.go b/pluginframework/tfschema/list_nested_attribute.go new file mode 100644 index 0000000000..53105e6fc5 --- /dev/null +++ b/pluginframework/tfschema/list_nested_attribute.go @@ -0,0 +1,80 @@ +package tfschema + +import ( + dataschema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +// ListNestedAttributte represents a list of complex (non-primitive) types. +type ListNestedAttribute struct { + NestedObject NestedAttributeObject + Optional bool + Required bool + Sensitive bool + Computed bool + DeprecationMessage string + Validators []validator.List +} + +func (a ListNestedAttribute) BuildDataSourceAttribute() dataschema.Attribute { + return dataschema.ListNestedAttribute{NestedObject: a.NestedObject.BuildDataSourceAttribute(), Optional: a.Optional, Required: a.Required, Sensitive: a.Sensitive, DeprecationMessage: a.DeprecationMessage, Computed: a.Computed, Validators: a.Validators} +} + +func (a ListNestedAttribute) BuildResourceAttribute() schema.Attribute { + return schema.ListNestedAttribute{NestedObject: a.NestedObject.BuildResourceAttribute(), Optional: a.Optional, Required: a.Required, Sensitive: a.Sensitive, DeprecationMessage: a.DeprecationMessage, Computed: a.Computed, Validators: a.Validators} +} + +func (a ListNestedAttribute) SetOptional() AttributeBuilder { + if a.Optional && !a.Required { + panic("attribute is already optional") + } + a.Optional = true + a.Required = false + return a +} + +func (a ListNestedAttribute) SetRequired() AttributeBuilder { + if !a.Optional && a.Required { + panic("attribute is already required") + } + a.Optional = false + a.Required = true + return a +} + +func (a ListNestedAttribute) SetSensitive() AttributeBuilder { + if a.Sensitive { + panic("attribute is already sensitive") + } + a.Sensitive = true + return a +} + +func (a ListNestedAttribute) SetComputed() AttributeBuilder { + if a.Computed { + panic("attribute is already computed") + } + a.Computed = true + return a +} + +func (a ListNestedAttribute) SetReadOnly() AttributeBuilder { + if a.Computed && !a.Optional && !a.Required { + panic("attribute is already read only") + } + a.Computed = true + a.Optional = false + a.Required = false + return a +} + +func (a ListNestedAttribute) SetDeprecated(msg string) AttributeBuilder { + a.DeprecationMessage = msg + return a +} + +func (a ListNestedAttribute) AddValidator(v validator.List) AttributeBuilder { + a.Validators = append(a.Validators, v) + return a +} diff --git a/pluginframework/tfschema/map_attribute.go b/pluginframework/tfschema/map_attribute.go new file mode 100644 index 0000000000..29c60bbf6e --- /dev/null +++ b/pluginframework/tfschema/map_attribute.go @@ -0,0 +1,81 @@ +package tfschema + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + dataschema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +// MapAttributte represents a map of primitive types. +type MapAttribute struct { + ElementType attr.Type + Optional bool + Required bool + Sensitive bool + Computed bool + DeprecationMessage string + Validators []validator.Map +} + +func (a MapAttribute) BuildDataSourceAttribute() dataschema.Attribute { + return dataschema.MapAttribute{ElementType: a.ElementType, Optional: a.Optional, Required: a.Required, Sensitive: a.Sensitive, DeprecationMessage: a.DeprecationMessage, Computed: a.Computed, Validators: a.Validators} +} + +func (a MapAttribute) BuildResourceAttribute() schema.Attribute { + return schema.MapAttribute{ElementType: a.ElementType, Optional: a.Optional, Required: a.Required, Sensitive: a.Sensitive, DeprecationMessage: a.DeprecationMessage, Computed: a.Computed, Validators: a.Validators} +} + +func (a MapAttribute) SetOptional() AttributeBuilder { + if a.Optional && !a.Required { + panic("attribute is already optional") + } + a.Optional = true + a.Required = false + return a +} + +func (a MapAttribute) SetRequired() AttributeBuilder { + if !a.Optional && a.Required { + panic("attribute is already required") + } + a.Optional = false + a.Required = true + return a +} + +func (a MapAttribute) SetSensitive() AttributeBuilder { + if a.Sensitive { + panic("attribute is already sensitive") + } + a.Sensitive = true + return a +} + +func (a MapAttribute) SetComputed() AttributeBuilder { + if a.Computed { + panic("attribute is already computed") + } + a.Computed = true + return a +} + +func (a MapAttribute) SetReadOnly() AttributeBuilder { + if a.Computed && !a.Optional && !a.Required { + panic("attribute is already read only") + } + a.Computed = true + a.Optional = false + a.Required = false + return a +} + +func (a MapAttribute) SetDeprecated(msg string) AttributeBuilder { + a.DeprecationMessage = msg + return a +} + +func (a MapAttribute) AddValidator(v validator.Map) AttributeBuilder { + a.Validators = append(a.Validators, v) + return a +} diff --git a/pluginframework/tfschema/map_nested_attribute.go b/pluginframework/tfschema/map_nested_attribute.go new file mode 100644 index 0000000000..16f537b90e --- /dev/null +++ b/pluginframework/tfschema/map_nested_attribute.go @@ -0,0 +1,80 @@ +package tfschema + +import ( + dataschema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +// MapNestedAttributte represents a map of complex (non-primitive) types. +type MapNestedAttribute struct { + NestedObject NestedAttributeObject + Optional bool + Required bool + Sensitive bool + Computed bool + DeprecationMessage string + Validators []validator.Map +} + +func (a MapNestedAttribute) BuildDataSourceAttribute() dataschema.Attribute { + return dataschema.MapNestedAttribute{NestedObject: a.NestedObject.BuildDataSourceAttribute(), Optional: a.Optional, Required: a.Required, Sensitive: a.Sensitive, DeprecationMessage: a.DeprecationMessage, Computed: a.Computed, Validators: a.Validators} +} + +func (a MapNestedAttribute) BuildResourceAttribute() schema.Attribute { + return schema.MapNestedAttribute{NestedObject: a.NestedObject.BuildResourceAttribute(), Optional: a.Optional, Required: a.Required, Sensitive: a.Sensitive, DeprecationMessage: a.DeprecationMessage, Computed: a.Computed, Validators: a.Validators} +} + +func (a MapNestedAttribute) SetOptional() AttributeBuilder { + if a.Optional && !a.Required { + panic("attribute is already optional") + } + a.Optional = true + a.Required = false + return a +} + +func (a MapNestedAttribute) SetRequired() AttributeBuilder { + if !a.Optional && a.Required { + panic("attribute is already required") + } + a.Optional = false + a.Required = true + return a +} + +func (a MapNestedAttribute) SetSensitive() AttributeBuilder { + if a.Sensitive { + panic("attribute is already sensitive") + } + a.Sensitive = true + return a +} + +func (a MapNestedAttribute) SetComputed() AttributeBuilder { + if a.Computed { + panic("attribute is already computed") + } + a.Computed = true + return a +} + +func (a MapNestedAttribute) SetReadOnly() AttributeBuilder { + if a.Computed && !a.Optional && !a.Required { + panic("attribute is already read only") + } + a.Computed = true + a.Optional = false + a.Required = false + return a +} + +func (a MapNestedAttribute) SetDeprecated(msg string) AttributeBuilder { + a.DeprecationMessage = msg + return a +} + +func (a MapNestedAttribute) AddValidator(v validator.Map) AttributeBuilder { + a.Validators = append(a.Validators, v) + return a +} diff --git a/pluginframework/tfschema/nested_attribute_object.go b/pluginframework/tfschema/nested_attribute_object.go new file mode 100644 index 0000000000..bf9f639231 --- /dev/null +++ b/pluginframework/tfschema/nested_attribute_object.go @@ -0,0 +1,27 @@ +package tfschema + +import ( + dataschema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" +) + +// NestedAttributteObject is the intermediate type for nested complex (non-primitive) types. +type NestedAttributeObject struct { + Attributes map[string]AttributeBuilder +} + +func (a NestedAttributeObject) BuildDataSourceAttribute() dataschema.NestedAttributeObject { + dataSourceAttributes := BuildDataSourceAttributeMap(a.Attributes) + + return dataschema.NestedAttributeObject{ + Attributes: dataSourceAttributes, + } +} + +func (a NestedAttributeObject) BuildResourceAttribute() schema.NestedAttributeObject { + resourceAttributes := BuildResourceAttributeMap(a.Attributes) + + return schema.NestedAttributeObject{ + Attributes: resourceAttributes, + } +} diff --git a/pluginframework/tfschema/single_nested_attribute.go b/pluginframework/tfschema/single_nested_attribute.go new file mode 100644 index 0000000000..005df73883 --- /dev/null +++ b/pluginframework/tfschema/single_nested_attribute.go @@ -0,0 +1,80 @@ +package tfschema + +import ( + dataschema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +// SingleNestedAttributte represents single complex (struct) types. +type SingleNestedAttribute struct { + Attributes map[string]AttributeBuilder + Optional bool + Required bool + Sensitive bool + Computed bool + DeprecationMessage string + Validators []validator.Object +} + +func (a SingleNestedAttribute) BuildDataSourceAttribute() dataschema.Attribute { + return dataschema.SingleNestedAttribute{Attributes: BuildDataSourceAttributeMap(a.Attributes), Optional: a.Optional, Required: a.Required, Sensitive: a.Sensitive, DeprecationMessage: a.DeprecationMessage, Computed: a.Computed, Validators: a.Validators} +} + +func (a SingleNestedAttribute) BuildResourceAttribute() schema.Attribute { + return schema.SingleNestedAttribute{Attributes: BuildResourceAttributeMap(a.Attributes), Optional: a.Optional, Required: a.Required, Sensitive: a.Sensitive, DeprecationMessage: a.DeprecationMessage, Computed: a.Computed, Validators: a.Validators} +} + +func (a SingleNestedAttribute) SetOptional() AttributeBuilder { + if a.Optional && !a.Required { + panic("attribute is already optional") + } + a.Optional = true + a.Required = false + return a +} + +func (a SingleNestedAttribute) SetRequired() AttributeBuilder { + if !a.Optional && a.Required { + panic("attribute is already required") + } + a.Optional = false + a.Required = true + return a +} + +func (a SingleNestedAttribute) SetSensitive() AttributeBuilder { + if a.Sensitive { + panic("attribute is already sensitive") + } + a.Sensitive = true + return a +} + +func (a SingleNestedAttribute) SetComputed() AttributeBuilder { + if a.Computed { + panic("attribute is already computed") + } + a.Computed = true + return a +} + +func (a SingleNestedAttribute) SetReadOnly() AttributeBuilder { + if a.Computed && !a.Optional && !a.Required { + panic("attribute is already read only") + } + a.Computed = true + a.Optional = false + a.Required = false + return a +} + +func (a SingleNestedAttribute) SetDeprecated(msg string) AttributeBuilder { + a.DeprecationMessage = msg + return a +} + +func (a SingleNestedAttribute) AddValidator(v validator.Object) AttributeBuilder { + a.Validators = append(a.Validators, v) + return a +} diff --git a/pluginframework/tfschema/string_attribute.go b/pluginframework/tfschema/string_attribute.go new file mode 100644 index 0000000000..4258b53665 --- /dev/null +++ b/pluginframework/tfschema/string_attribute.go @@ -0,0 +1,78 @@ +package tfschema + +import ( + dataschema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +type StringAttribute struct { + Optional bool + Required bool + Sensitive bool + Computed bool + DeprecationMessage string + Validators []validator.String +} + +func (a StringAttribute) BuildDataSourceAttribute() dataschema.Attribute { + return dataschema.StringAttribute{Optional: a.Optional, Required: a.Required, Sensitive: a.Sensitive, DeprecationMessage: a.DeprecationMessage, Computed: a.Computed, Validators: a.Validators} +} + +func (a StringAttribute) BuildResourceAttribute() schema.Attribute { + return schema.StringAttribute{Optional: a.Optional, Required: a.Required, Sensitive: a.Sensitive, DeprecationMessage: a.DeprecationMessage, Computed: a.Computed, Validators: a.Validators} +} + +func (a StringAttribute) SetOptional() AttributeBuilder { + if a.Optional && !a.Required { + panic("attribute is already optional") + } + a.Optional = true + a.Required = false + return a +} + +func (a StringAttribute) SetRequired() AttributeBuilder { + if !a.Optional && a.Required { + panic("attribute is already required") + } + a.Optional = false + a.Required = true + return a +} + +func (a StringAttribute) SetSensitive() AttributeBuilder { + if a.Sensitive { + panic("attribute is already sensitive") + } + a.Sensitive = true + return a +} + +func (a StringAttribute) SetComputed() AttributeBuilder { + if a.Computed { + panic("attribute is already computed") + } + a.Computed = true + return a +} + +func (a StringAttribute) SetReadOnly() AttributeBuilder { + if a.Computed && !a.Optional && !a.Required { + panic("attribute is already read only") + } + a.Computed = true + a.Optional = false + a.Required = false + return a +} + +func (a StringAttribute) SetDeprecated(msg string) AttributeBuilder { + a.DeprecationMessage = msg + return a +} + +func (a StringAttribute) AddValidator(v validator.String) AttributeBuilder { + a.Validators = append(a.Validators, v) + return a +}