Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add custom type handling for collection elements and object attribute types #9

Merged
merged 27 commits into from
Jun 21, 2023

Conversation

bendbennett
Copy link
Contributor

@bendbennett bendbennett commented Jun 6, 2023

Within the terraform-plugin-codegen-spec repository the JSON schema and the Go bindings for the schema define the intermediate representation.

The schema and Go bindings allow for the usage of custom types in conjunction with element types within collections (i.e., list, map, set) and attribute types within objects.

The changes in this PR include the following:

  • Handling of custom types for collection element types and object attribute types in the schema generation for data sources, provider and resources.
  • Handling of custom types for collection element types and object attribute types in the generation of import declarations for use in conjunction with the generated schema for data sources, provider and resources.

@bendbennett bendbennett marked this pull request as ready for review June 9, 2023 06:28
@bendbennett bendbennett requested a review from a team as a code owner June 9, 2023 06:28
@bendbennett bendbennett changed the title [WIP] Add custom type handling for elements and schema generation for provider and resources Add custom type handling for collection elements and object attribute types Jun 9, 2023
Copy link
Contributor

@bflad bflad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall I think this really looks good. Just a few little things to potentially followup on. 😄

return "types.Int64Type"
case e.List != nil:
if e.List.CustomType != nil {
return fmt.Sprintf("%s{\nElemType: %s,\n}", e.List.CustomType.Type, GetElementType(e.List.ElementType))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is okay as a placeholder for now, but we may need a way in the specification to ensure that developers can fully specify how this should be created as code since its not guaranteed that the custom type will be implemented with an ElemType field. Similarly with object types.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've created 2 issues for this:

}
return "types.NumberType"
case e.Object != nil:
return fmt.Sprintf("types.ObjectType{\nAttrTypes: map[string]attr.Type{\n%s\n},\n}", GetAttrTypes(e.Object))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this also be implementing e.Object.CustomType logic similar to the collection types?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

e.Object is a []ObjectAttributeType but there's no e.Object.CustomType available.

Perhaps this needs to be added to the spec?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ha, yes it would 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

switch {
case v.Bool != nil:
if v.Bool.CustomType != nil {
aTypes.WriteString(fmt.Sprintf("\"%s\": %s,", v.Name, v.Bool.CustomType.Type))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: These can use %q to remove the \"%s\" handling. It may also be worth moving the v.Name writing logic above the switch since branches require the logic.

aTypes.WriteString(fmt.Sprintf("%q: ", v.Name))

switch {
case v.Bool != nil:
	if v.Bool.CustomType != nil {
		aTypes.WriteString(v.Bool.CustomType.Type)
	} else {
		aTypes.WriteString("types.BoolType")
	}
	// ...
}

aTypes.WriteString(",")

Copy link
Contributor

@bflad bflad Jun 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(We could also consider making a "schema definition string" method on each of the types so calling logic doesn't need to handle the implementation details like the switch statement here 😄 )

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

)

type GeneratorListAttribute struct {
schema.ListAttribute

CustomType *specschema.CustomType
Validators []specschema.ListValidator
CustomType *specschema.CustomType
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: It might be good to throw a quick comment in these generator types about why we're preferring the "specschema" types here, rather than using the "real" schema types -- e.g. because we need to support extracting custom import information later. 👍

}

for a := range imports {
s.WriteString(fmt.Sprintf("\"%s\"\n", a))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: 😎

Suggested change
s.WriteString(fmt.Sprintf("\"%s\"\n", a))
s.WriteString(fmt.Sprintf("%q\n", a))

}

for a := range imports {
s.WriteString(fmt.Sprintf("\"%s\"\n", a))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: 😎

Suggested change
s.WriteString(fmt.Sprintf("\"%s\"\n", a))
s.WriteString(fmt.Sprintf("%q\n", a))

@@ -198,3 +230,93 @@ func customTypeEqual(x, y *specschema.CustomType) bool {

return true
}

func objectTypeEqual(x, y []specschema.ObjectAttributeType) bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind raising a feature request issue for consideration of this in terraform-plugin-codegen-spec? Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've created an issue for Consider adding equality functions in the terraform-plugin-codegen-spec repo.

Copy link
Contributor

@bflad bflad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me 🚀

@bendbennett bendbennett merged commit b404a8c into main Jun 21, 2023
@bendbennett bendbennett deleted the schema-provider-resources branch June 21, 2023 06:59
Copy link

I'm going to lock this pull request because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active contributions.
If you have found a problem that seems related to this change, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 23, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants