fix(java): don't emit unqualified enum default for discriminator ref-to-property - #24934
Open
seonwooj0810 wants to merge 1 commit into
Conversation
…to-property A discriminator property that is a `$ref` to another schema's inline enum property (rather than a ref to a named enum schema, or an inline enum itself) still has its allowableValues/default resolved by updateCodegenPropertyEnum, but there is no enum type at this property's own use site to qualify the value with. toEnumDefaultValue was called regardless, falling back to the raw (non-enum) datatype, producing uninitializable code such as `this.category = String.ARCHIVE;` in the okhttp-gson library's generated subtype constructor. Only call toEnumDefaultValue when the property is actually an inline enum (var.isEnum) or resolves to a named enum schema (referencedSchema); otherwise drop the default rather than emit an unqualified token. Verified the full java-* sample set (bin/configs/java-*.yaml, 136 generators) regenerates with zero model/pojo diffs, so no existing sample exercises this edge case. Fixes OpenAPITools#24874
Contributor
There was a problem hiding this comment.
1 issue found across 3 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java">
<violation number="1" location="modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java:7168">
P3: The else branch sets `var.defaultValue = null` for every non-enum, non-ref property with an enum constraint and matching default, not just the discriminator case it targets (#24874). For a non-discriminator String property that `$ref`s another schema's inline enum with a default, the field's default is silently dropped instead of emitting the still-valid raw literal (e.g. `this.category = "ARCHIVE";`), leaving the field uninitialized. Consider restoring the raw literal for `var.isString` when the intention is solely to avoid the bare `String.X` token.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| // allowableValues/enum matching still ran, but there's no enum constant to | ||
| // qualify the value with. Drop the default rather than emit a bare, | ||
| // unqualified token that would not compile (see #24874). | ||
| var.defaultValue = null; |
Contributor
There was a problem hiding this comment.
P3: The else branch sets var.defaultValue = null for every non-enum, non-ref property with an enum constraint and matching default, not just the discriminator case it targets (#24874). For a non-discriminator String property that $refs another schema's inline enum with a default, the field's default is silently dropped instead of emitting the still-valid raw literal (e.g. this.category = "ARCHIVE";), leaving the field uninitialized. Consider restoring the raw literal for var.isString when the intention is solely to avoid the bare String.X token.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java, line 7168:
<comment>The else branch sets `var.defaultValue = null` for every non-enum, non-ref property with an enum constraint and matching default, not just the discriminator case it targets (#24874). For a non-discriminator String property that `$ref`s another schema's inline enum with a default, the field's default is silently dropped instead of emitting the still-valid raw literal (e.g. `this.category = "ARCHIVE";`), leaving the field uninitialized. Consider restoring the raw literal for `var.isString` when the intention is solely to avoid the bare `String.X` token.</comment>
<file context>
@@ -7155,7 +7155,18 @@ public void updateCodegenPropertyEnum(CodegenProperty var) {
+ // allowableValues/enum matching still ran, but there's no enum constant to
+ // qualify the value with. Drop the default rather than emit a bare,
+ // unqualified token that would not compile (see #24874).
+ var.defaultValue = null;
+ }
}
</file context>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #24874
Bug
The Java client generator (default library: okhttp-gson) produced non-compiling code when a discriminator property is a
$refdirectly into another schema's inline enum property, rather than a$refto a named enum schema:String.ARCHIVEdoes not exist, so the generated client fails to compile.Root cause
DefaultCodegen#updateCodegenPropertyEnumresolves the enum default value and, whenever a matching enum entry is found, unconditionally callstoEnumDefaultValue(var, enumName)to qualify it with the property's datatype. That qualification is only meaningful when the property is itself an inline enum (var.isEnum) or resolves to a named enum schema (referencedSchema). For a discriminator property that is a$refinto another schema's property (not the enum schema itself), neither is true —var.datatypeWithEnumis just the raw scalar type (String) — yet the enum-matching logic still ran and produced a bogus qualified token.This is exercised by okhttp-gson's
pojo.mustache, which assigns the discriminator's default value in the generated subtype's constructor (other Java libraries don't emit this constructor-level assignment, which is why @jpfinne's comment on the issue pinned it to okhttp-gson specifically — the underlying bad value is computed generically inDefaultCodegen, okhttp-gson is just the template that surfaces it as a compile error).Fix
Only call
toEnumDefaultValuewhenvar.isEnum || referencedSchema.isPresent(). Otherwise, drop the default (null) rather than emit an unqualified token that won't compile. The field is simply left unset in this edge case, which is the same as any other discriminator property whose caller must set it explicitly — no compile error, no incorrect value.Test evidence
modules/openapi-generator/src/test/resources/bugs/issue_24874.yaml(the exact spec from the issue).JavaClientCodegenTest#testDiscriminatorPropertyRefToEnumDoesNotEmitInvalidDefault_issue24874, which fails on current master (reproducesthis.category = String.ARCHIVE;viafileDoesNotContainassertion) and passes with this fix.java-*sample set (bin/configs/java-*.yaml, 136 generators viabin/generate-samples.sh) — zero model/pojo diffs, confirming no existing committed sample exercises this narrow edge case and this change is safe.Verification done
gh issue view/gh api .../timeline).upstream/masterbefore the fix, and is resolved after.Verification done: reproduced the exact compile failure from the issue on latest master using the issue's own minimal spec, confirmed root cause in
DefaultCodegen#updateCodegenPropertyEnum, added a regression test that is red before / green after the fix, and confirmed zero sample diffs across the full java-* config set.Summary by cubic
Fixes #24874. Stops the Java generator from emitting uncompilable defaults like
this.category = String.ARCHIVE;when a discriminator property is a$refto another schema's inline enum property — the default is now left unset instead of qualified with the raw scalar type.Bug Fixes
toEnumDefaultValueis now only called when the property is an inline enum or resolves to a named enum schema; otherwise the default isnull.java-*sample set (136 generators) regenerates with zero diffs, so no existing sample is affected.Written for commit 72f54fe. Summary will update on new commits.