fix: allow x-go-type and x-go-type-skip-optional-pointer for allOf#1610
fix: allow x-go-type and x-go-type-skip-optional-pointer for allOf#1610turip wants to merge 5 commits intooapi-codegen:mainfrom
Conversation
This patch ensures that if a schema is defined using allOf the main schema entry's x-go-type and x-go-type-skip-optional-pointer values are considered instead of a random allOf member's.
Greptile SummaryThis PR fixes a bug where Key changes:
Issues found:
Confidence Score: 3/5
|
| Filename | Overview |
|---|---|
| pkg/codegen/schema.go | Adds allOf-level handling for x-go-type and x-go-type-skip-optional-pointer extensions. The x-go-type path has a bug where SkipOptionalPointer (from the global default or a co-located x-go-type-skip-optional-pointer extension) is not propagated to the returned mergedSchema. |
| pkg/codegen/codegen_test.go | Adds TestGoAllofTypeOverride to verify that top-level x-go-type on an allOf schema produces the correct type aliases and imports. Coverage is straightforward and correct, though it doesn't cover the x-go-type-skip-optional-pointer + allOf interaction. |
| pkg/codegen/test_specs/x-go-type-pet-allof.yaml | New test fixture for the allOf + x-go-type scenario using a Pet/Dog/Cat discriminator pattern. Minor: missing a trailing newline at EOF. |
Last reviewed commit: 0c9b5b0
| if extension, ok := schema.Extensions[extPropGoType]; ok { | ||
| typeName, err := extTypeName(extension) | ||
| if err != nil { | ||
| return outSchema, fmt.Errorf("invalid value for %q: %w", extPropGoType, err) | ||
| } | ||
| mergedSchema.GoType = typeName | ||
| mergedSchema.DefineViaAlias = true | ||
|
|
||
| return mergedSchema, nil | ||
| } |
There was a problem hiding this comment.
SkipOptionalPointer not propagated to mergedSchema in the allOf + x-go-type path
At the top of GenerateGoSchema, skipOptionalPointer is computed by combining the global PreferSkipOptionalPointer default with any top-level x-go-type-skip-optional-pointer extension:
skipOptionalPointer := globalState.options.OutputOptions.PreferSkipOptionalPointer
if extension, ok := schema.Extensions[extPropGoTypeSkipOptionalPointer]; ok {
skipOptionalPointer, err = extParsePropGoTypeSkipOptionalPointer(extension)
...
}This value is applied to outSchema.SkipOptionalPointer, but in the new allOf + x-go-type early-return block, mergedSchema is returned without that value. This means:
- If the global
PreferSkipOptionalPointer: trueoutput option is set, it won't be respected for allOf schemas that also usex-go-type. - If a schema uses all three —
allOf+x-go-type+x-go-type-skip-optional-pointer— the early return skips the second block entirely, so thex-go-type-skip-optional-pointerextension is silently ignored.
The non-allOf x-go-type path doesn't have this issue because it returns outSchema which already has SkipOptionalPointer set from initialization.
The fix is to apply skipOptionalPointer to mergedSchema before the early return:
| if extension, ok := schema.Extensions[extPropGoType]; ok { | |
| typeName, err := extTypeName(extension) | |
| if err != nil { | |
| return outSchema, fmt.Errorf("invalid value for %q: %w", extPropGoType, err) | |
| } | |
| mergedSchema.GoType = typeName | |
| mergedSchema.DefineViaAlias = true | |
| return mergedSchema, nil | |
| } | |
| if extension, ok := schema.Extensions[extPropGoType]; ok { | |
| typeName, err := extTypeName(extension) | |
| if err != nil { | |
| return outSchema, fmt.Errorf("invalid value for %q: %w", extPropGoType, err) | |
| } | |
| mergedSchema.GoType = typeName | |
| mergedSchema.DefineViaAlias = true | |
| mergedSchema.SkipOptionalPointer = skipOptionalPointer | |
| return mergedSchema, nil | |
| } |
Right now if a schema contains
x-go-type, for example:old behavior
The generated code will still take the pet as the
x-go-type:new behavior
This patch makes sure that we are generating the expected output:
This is a corner case, as in most cases the same type is used (e.g. splitting the ID from the CreateRequest but using the same underlying object), but in case we would want to compose the objects it would make sense to make this overridable on the parent level.
This patch doesn't introduce a breaking change, as if the x-go-* values are not set, the same inheritance will hapen.