-
Notifications
You must be signed in to change notification settings - Fork 209
chore: Support dynamic json values which Map type #3860
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
Conversation
| AttrDynamicJSONString jsontypes.Normalized `tfsdk:"attr_dynamic_json_string"` | ||
| AttrDynamicJSONNumber jsontypes.Normalized `tfsdk:"attr_dynamic_json_number"` | ||
| AttrDynamicJSONArray jsontypes.Normalized `tfsdk:"attr_dynamic_json_array"` | ||
| AttrDynamicJSONObject jsontypes.Normalized `tfsdk:"attr_dynamic_json_object"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no changes to marshal/unmarshal logic needed, adding testing to ensure coverage
| nestedObject := NestedAttributeObject{Attributes: objectAttributes} | ||
| if len(nestedObject.Attributes) == 0 { | ||
| // objects without attributes use JSON custom type as element | ||
| result := s.buildRegularCollectionAttribute(name, tfModelName, computability, isSet, CustomTypeJSON) | ||
| return result, nil | ||
| } | ||
|
|
||
| result := s.buildNestedCollectionAttribute(name, tfModelName, fullName, computability, isSet, nestedObject) | ||
| return result, nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
change to list creation was purely refactoring, want to make clear when nested vs regular collection types are created, and when CustomTypeJSON is used (only within regular collection type).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR enhances the code generation tool to support OpenAPI object maps with dynamic JSON values, addressing a previous limitation that caused panics during code generation. The key change enables search_index_api to express definition.mappings.fields as a map of schemaless JSON values using MapValue[jsontypes.Normalized].
Key Changes:
- Code generation now recognizes OpenAPI objects without defined properties and generates appropriate
MapValue[jsontypes.Normalized]types - Error handling improved by replacing panics with proper error returns in code generation functions
- Added comprehensive test coverage for marshaling/unmarshaling dynamic JSON across map/list/set types
Reviewed Changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| tools/codegen/models/search_index_api.yaml | Adds fields map attribute to definition.mappings for search index API |
| tools/codegen/main.go | Updates to handle errors from code generation functions instead of ignoring them |
| tools/codegen/gofilegen/schema/schema_file.go | Changes GenerateGoCode to return errors instead of panicking |
| tools/codegen/gofilegen/resource/resource_file.go | Changes GenerateGoCode to return errors instead of panicking |
| tools/codegen/gofilegen/schema/schema_file_test.go | Updates tests to handle error returns from GenerateGoCode |
| tools/codegen/gofilegen/resource/resource_file_test.go | Updates tests to handle error returns from GenerateGoCode |
| tools/codegen/config.yml | Removes TODO comment and ignores for fields that are now supported |
| tools/codegen/codespec/testdata/config.yml | Adds test resource configuration for dynamic JSON properties |
| tools/codegen/codespec/testdata/api-spec.yml | Adds OpenAPI spec for testing dynamic JSON properties |
| tools/codegen/codespec/attribute.go | Refactors array/map attribute building to handle empty objects as dynamic JSON |
| tools/codegen/codespec/api_to_provider_spec_mapper_test.go | Adds test case for dynamic JSON properties conversion |
| internal/serviceapi/searchindexapi/resource_test.go | Adds acceptance test for mappings.fields functionality |
| internal/serviceapi/searchindexapi/resource_schema.go | Adds generated fields map attribute to mappings schema |
| internal/common/autogen/unmarshal_test.go | Expands tests to cover dynamic JSON in map/list/set types |
| internal/common/autogen/marshal_test.go | Expands tests to cover dynamic JSON in map/list/set types |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| }}, | ||
| }, | ||
| } | ||
| runTestCase(t, tc) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: i know it's not only from this PR but don't see the need to extract runTestCase logic instead of having it in each test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah agree runTestCase is very lightweight, don't see harm in having it unified
| if isSet { | ||
| attr.CustomType = NewCustomNestedSetType(nestedObjectName) | ||
| attr.SetNested = &SetNestedAttribute{NestedObject: nestedObject} | ||
| } else { | ||
| attr.CustomType = NewCustomNestedListType(nestedObjectName) | ||
| attr.ListNested = &ListNestedAttribute{NestedObject: nestedObject} | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if isSet { | |
| attr.CustomType = NewCustomNestedSetType(nestedObjectName) | |
| attr.SetNested = &SetNestedAttribute{NestedObject: nestedObject} | |
| } else { | |
| attr.CustomType = NewCustomNestedListType(nestedObjectName) | |
| attr.ListNested = &ListNestedAttribute{NestedObject: nestedObject} | |
| } | |
| attr.CustomType = NewCustomNestedListType(nestedObjectName) | |
| attr.ListNested = &ListNestedAttribute{NestedObject: nestedObject} | |
| if isSet { | |
| attr.CustomType = NewCustomNestedSetType(nestedObjectName) | |
| attr.SetNested = &SetNestedAttribute{NestedObject: nestedObject} | |
| } |
nit: don't know if it have side effect to update the values and then set again if set
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would go for the current implementation which does not allocate more than necessary (even if the compiler does optimize this, which I don't think it does).
| ) | ||
|
|
||
| func GenerateGoCode(input *codespec.Resource) []byte { | ||
| func GenerateGoCode(input *codespec.Resource) ([]byte, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice
Description
Link to any related issue(s): CLOUDP-352319
Before
search_index_apicouldn’t expressdefinition.mappings.fieldsas a map of schemaless JSON values.After
MapValue[jsontypes.Normalized]on the terraform side.search_index_apinow exposesdefinition.mappings.fieldsenablingjsonencode(...)per field.jsontypes.Normalized) across map/list/set.Type of change:
Required Checklist:
Further comments