Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7155,7 +7155,25 @@ public void updateCodegenPropertyEnum(CodegenProperty var) {
}
}
if (enumName != null) {
var.defaultValue = toEnumDefaultValue(var, enumName);
if (var.isEnum || !languageSpecificPrimitives.contains(varDataType)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2: When a referenced inline enum resolves to a mapped scalar such as Java Date, UUID, or BigDecimal, this condition treats it as a named enum and emits invalid defaults like Date.CASE. Determine named-enum status from the resolved schema/reference rather than primitive-set membership.

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 7158:

<comment>When a referenced inline enum resolves to a mapped scalar such as Java `Date`, `UUID`, or `BigDecimal`, this condition treats it as a named enum and emits invalid defaults like `Date.CASE`. Determine named-enum status from the resolved schema/reference rather than primitive-set membership.</comment>

<file context>
@@ -7155,16 +7155,23 @@ public void updateCodegenPropertyEnum(CodegenProperty var) {
             }
             if (enumName != null) {
-                if (var.isEnum || referencedSchema.isPresent()) {
+                if (var.isEnum || !languageSpecificPrimitives.contains(varDataType)) {
                     var.defaultValue = toEnumDefaultValue(var, enumName);
                 } else {
</file context>

var.defaultValue = toEnumDefaultValue(var, enumName);
} else {
// Not an inline nested enum (var.isEnum) and varDataType is a raw
// language-specific primitive (e.g. "String"): there's no enum class at
// this use site to qualify the value with (e.g. a discriminator property
// that is a `$ref` into another schema's property rather than a ref to the
// enum schema itself). allowableValues/enum matching still ran, but
// emitting a bare, unqualified token like `String.ARCHIVE` would not
// compile. Drop the default instead (see #24874).
//
// Note: this check is intentionally based on languageSpecificPrimitives
// rather than referencedSchema.isPresent() — referencedSchema's name match
// against the raw dataType string is brittle for codegens whose dataType is
// namespace/package-qualified (e.g. PHP's `OpenAPI\Server\Model\Foo`), which
// would never match `toModelName(...)` and incorrectly drop valid enum
// defaults for genuine named-enum refs.
var.defaultValue = null;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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>

}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1869,6 +1869,27 @@ public void testObjectDefaultWithEnumProperty_issue24298() {
.contains("new OutputFormat().order(OutputFormat.OrderEnum.SIMILARITY).limit(10)");
}

@Test
public void testDiscriminatorPropertyRefToEnumDoesNotEmitInvalidDefault_issue24874() {
final Path output = newTempFolder();
final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName(JAVA_GENERATOR)
.setInputSpec("src/test/resources/bugs/issue_24874.yaml")
.setAdditionalProperties(Map.of(MODEL_NAME_PREFIX, "Stock"))
.setOutputDir(output.toString().replace("\\", "/"));

Map<String, File> files = new DefaultGenerator().opts(configurator.toClientOptInput()).generate().stream()
.collect(Collectors.toMap(File::getName, Function.identity()));

// CategoryEvent.category is a discriminator property that is a `$ref` to another schema's
// (CategorySource) inline enum property, not to a named enum schema and not an inline enum
// itself. There is no enum type at this use site to qualify the discriminator mapping value
// with, so no default must be emitted here; previously this rendered the uncompilable
// `this.category = String.ARCHIVE;` (see #24874).
JavaFileAssert.assertThat(files.get("StockArchiveCategoryEvent.java"))
.fileDoesNotContain("String.ARCHIVE");
}

@Test
public void testWebClientJsonCreatorWithNullable_issue12790() {
final Path output = newTempFolder();
Expand Down
35 changes: 35 additions & 0 deletions modules/openapi-generator/src/test/resources/bugs/issue_24874.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
openapi: "3.1.0"
info:
title: Shared category discriminator
version: 1.0.0
paths: {}
components:
schemas:
CategorySource:
type: object
required:
- category
properties:
category:
type: string
enum:
- ARCHIVE
CategoryEvent:
type: object
required:
- category
properties:
category:
description: Event category
$ref: "#/components/schemas/CategorySource/properties/category"
discriminator:
propertyName: category
mapping:
ARCHIVE: "#/components/schemas/ArchiveCategoryEvent"
ArchiveCategoryEvent:
allOf:
- $ref: "#/components/schemas/CategoryEvent"
- type: object
properties:
value:
type: string
Loading