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 @@ -832,6 +832,27 @@ public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> objs)
}
}

// A oneOf interface declares the inline enum of its own discriminator (oneof_interface.mustache) and the
// implementors inherit it. A property in an implementor's allVars is its own and keeps its enum.
if (useOneOfInterfaces && !(this instanceof GroovyClientCodegen)) {
for (CodegenModel cm : allModels.values()) {
for (CodegenProperty disc : cm.vars) {
boolean fromImplementors = cm.interfaceModels != null && cm.interfaceModels.stream()
.flatMap(m -> m.allVars.stream())
.anyMatch(v -> disc.baseName.equals(v.baseName));
if (cm.oneOf.isEmpty() || !disc.isDiscriminator || !disc.isEnum) continue;
if (fromImplementors) {
disc.isEnum = false;
continue;
}
cm.oneOf.stream().map(allModels::get).filter(Objects::nonNull)
.flatMap(impl -> impl.vars.stream())
.filter(v -> disc.baseName.equals(v.baseName))
.forEach(v -> v.isEnum = false);
}
}
}

if (isGenerateConstructorWithAllArgs()) {
// conditionally force the generation of all args constructor.
for (CodegenModel cm : allModels.values()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
{{{.}}}
{{/vendorExtensions.x-class-extra-annotation}}
public {{>sealed}}interface {{classname}} {{#vendorExtensions.x-implements}}{{#-first}}extends {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{#-last}} {{/-last}}{{/vendorExtensions.x-implements}}{{>permits}}{
{{#vars}}

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: Property-level oneOf interfaces still omit inline discriminator enums because this template only renders enums from vars, while addOneOfInterfaceModel creates those synthetic interfaces without populating vars. Populate the synthetic interface's discriminator property or render the enum from discriminator metadata, then cover this form with a regression test.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At modules/openapi-generator/src/main/resources/Java/oneof_interface.mustache, line 6:

<comment>Property-level oneOf interfaces still omit inline discriminator enums because this template only renders enums from `vars`, while `addOneOfInterfaceModel` creates those synthetic interfaces without populating `vars`. Populate the synthetic interface's discriminator property or render the enum from discriminator metadata, then cover this form with a regression test.</comment>

<file context>
@@ -3,6 +3,13 @@
 {{{.}}}
 {{/vendorExtensions.x-class-extra-annotation}}
 public {{>sealed}}interface {{classname}} {{#vendorExtensions.x-implements}}{{#-first}}extends {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{#-last}} {{/-last}}{{/vendorExtensions.x-implements}}{{>permits}}{
+    {{#vars}}
+    {{#isEnum}}
+    {{#isDiscriminator}}
</file context>

{{#isEnum}}
{{#isDiscriminator}}
{{>modelInnerEnum}}

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: The discriminator enum rendered here uses @JsonCreator, but the oneOf interface model may not import com.fasterxml.jackson.annotation.JsonCreator. Confirm the generated interface compiles with jackson, or add the import explicitly as the JAX-RS template does.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At modules/openapi-generator/src/main/resources/Java/oneof_interface.mustache, line 9:

<comment>The discriminator enum rendered here uses `@JsonCreator`, but the oneOf interface model may not import `com.fasterxml.jackson.annotation.JsonCreator`. Confirm the generated interface compiles with jackson, or add the import explicitly as the JAX-RS template does.</comment>

<file context>
@@ -3,6 +3,13 @@
+    {{#vars}}
+    {{#isEnum}}
+    {{#isDiscriminator}}
+{{>modelInnerEnum}}
+    {{/isDiscriminator}}
+    {{/isEnum}}
</file context>

{{/isDiscriminator}}
{{/isEnum}}
{{/vars}}
{{#discriminator}}
public {{propertyType}} {{propertyGetter}}();
{{/discriminator}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@

| Name | Type | Description | Notes |
|------------ | ------------- | ------------- | -------------|
{{#vars}}|**{{name}}** | {{#isEnum}}[**{{datatypeWithEnum}}**](#{{datatypeWithEnum}}){{/isEnum}}{{^isEnum}}{{#isContainer}}{{#isArray}}{{#items}}{{#isModel}}[{{/isModel}}{{/items}}**{{baseType}}{{#items}}&lt;{{dataType}}&gt;**{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isModel}}{{/items}}{{/isArray}}{{#isMap}}{{#items}}{{#isModel}}[{{/isModel}}**Map&lt;String, {{dataType}}&gt;**{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isModel}}{{/items}}{{/isMap}}{{/isContainer}}{{^isContainer}}{{#isModel}}[{{/isModel}}**{{dataType}}**{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isModel}}{{/isContainer}}{{/isEnum}} | {{description}} | {{^required}} [optional]{{/required}}{{#isReadOnly}} [readonly]{{/isReadOnly}} |
{{#vars}}|**{{name}}** | {{#isInnerEnum}}[**{{datatypeWithEnum}}**](#{{datatypeWithEnum}}){{/isInnerEnum}}{{^isInnerEnum}}{{#isContainer}}{{#isArray}}{{#items}}{{#isModel}}[{{/isModel}}{{/items}}**{{baseType}}{{#items}}&lt;{{dataType}}&gt;**{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isModel}}{{/items}}{{/isArray}}{{#isMap}}{{#items}}{{#isModel}}[{{/isModel}}**Map&lt;String, {{dataType}}&gt;**{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isModel}}{{/items}}{{/isMap}}{{/isContainer}}{{^isContainer}}{{#isModel}}[{{/isModel}}**{{dataType}}**{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isModel}}{{/isContainer}}{{/isInnerEnum}} | {{description}} | {{^required}} [optional]{{/required}}{{#isReadOnly}} [readonly]{{/isReadOnly}} |
{{/vars}}
{{#vars}}{{#isEnum}}
{{#vars}}{{#isInnerEnum}}


## Enum: {{datatypeWithEnum}}

| Name | Value |
|---- | -----|{{#allowableValues}}{{#enumVars}}
| {{name}} | {{value}} |{{/enumVars}}{{/allowableValues}}
{{/isEnum}}{{/vars}}
{{/isInnerEnum}}{{/vars}}
{{#vendorExtensions.x-implements.0}}

## Implemented Interfaces
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
{{#vars}}
{{#isEnum}}
{{#isDiscriminator}}
{{#jackson}}
import com.fasterxml.jackson.annotation.*;
{{/jackson}}
{{#jsonb}}
import {{javaxPackage}}.json.bind.annotation.*;
import {{javaxPackage}}.json.bind.serializer.*;
import {{javaxPackage}}.json.stream.*;
{{/jsonb}}
{{#withXml}}
import {{javaxPackage}}.xml.bind.annotation.*;
{{/withXml}}
{{/isDiscriminator}}
{{/isEnum}}
{{/vars}}

{{>additionalOneOfTypeAnnotations}}
{{#discriminator}}
{{>typeInfoAnnotation}}
Expand All @@ -15,6 +33,13 @@
{{>generatedAnnotation}}

public {{>sealed}}interface {{classname}}{{#vendorExtensions.x-implements}}{{#-first}} extends {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.x-implements}} {{>permits}}{
{{#vars}}
{{#isEnum}}
{{#isDiscriminator}}
{{>enumClass}}
{{/isDiscriminator}}
{{/isEnum}}
{{/vars}}
{{#discriminator}}
{{propertyType}} {{propertyGetter}}();
{{/discriminator}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@
{{>generatedAnnotation}}

public {{>sealed}}interface {{classname}}{{#vendorExtensions.x-implements}}{{#-first}} extends {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.x-implements}} {{>permits}}{
{{#vars}}
{{#isEnum}}
{{#isDiscriminator}}
{{>enumClass}}
{{/isDiscriminator}}
{{/isEnum}}
{{/vars}}
{{#discriminator}}
public {{propertyType}} {{propertyGetter}}();
{{/discriminator}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
{{>additionalOneOfTypeAnnotations}}{{>generatedAnnotation}}{{>typeInfoAnnotation}}{{>xmlAnnotation}}
public interface {{classname}} {{#vendorExtensions.x-implements}}{{#-first}}extends {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.x-implements}} {
{{#vars}}
{{#isEnum}}
{{#isDiscriminator}}
{{>enumClass}}
{{/isDiscriminator}}
{{/isEnum}}
{{/vars}}
{{#discriminator}}
public {{propertyType}} {{propertyGetter}}();
{{/discriminator}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@

| Name | Type | Description | Notes |
|------------ | ------------- | ------------- | -------------|
{{#vars}}|**{{name}}** | {{#isEnum}}[**{{datatypeWithEnum}}**](#{{datatypeWithEnum}}){{/isEnum}}{{^isEnum}}{{#isContainer}}{{#isArray}}{{#items}}{{#isModel}}[{{/isModel}}{{/items}}**{{baseType}}{{#items}}&lt;{{dataType}}&gt;**{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isModel}}{{/items}}{{/isArray}}{{#isMap}}{{#items}}{{#isModel}}[{{/isModel}}**Map&lt;String, {{dataType}}&gt;**{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isModel}}{{/items}}{{/isMap}}{{/isContainer}}{{^isContainer}}{{#isModel}}[{{/isModel}}**{{dataType}}**{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isModel}}{{/isContainer}}{{/isEnum}} | {{description}} | {{^required}} [optional]{{/required}}{{#isReadOnly}} [readonly]{{/isReadOnly}} |
{{#vars}}|**{{name}}** | {{#isInnerEnum}}[**{{datatypeWithEnum}}**](#{{datatypeWithEnum}}){{/isInnerEnum}}{{^isInnerEnum}}{{#isContainer}}{{#isArray}}{{#items}}{{#isModel}}[{{/isModel}}{{/items}}**{{baseType}}{{#items}}&lt;{{dataType}}&gt;**{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isModel}}{{/items}}{{/isArray}}{{#isMap}}{{#items}}{{#isModel}}[{{/isModel}}**Map&lt;String, {{dataType}}&gt;**{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isModel}}{{/items}}{{/isMap}}{{/isContainer}}{{^isContainer}}{{#isModel}}[{{/isModel}}**{{dataType}}**{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isModel}}{{/isContainer}}{{/isInnerEnum}} | {{description}} | {{^required}} [optional]{{/required}}{{#isReadOnly}} [readonly]{{/isReadOnly}} |
{{/vars}}
{{#vars}}{{#isEnum}}
{{#vars}}{{#isInnerEnum}}


## Enum: {{datatypeWithEnum}}

| Name | Value |
|---- | -----|{{#allowableValues}}{{#enumVars}}
| {{name}} | {{value}} |{{/enumVars}}{{/allowableValues}}
{{/isEnum}}{{/vars}}
{{/isInnerEnum}}{{/vars}}
{{#vendorExtensions.x-implements.0}}

## Implemented Interfaces
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
{{>additionalOneOfTypeAnnotations}}{{>generatedAnnotation}}{{>typeInfoAnnotation}}{{>xmlAnnotation}}
public interface {{classname}} {{#vendorExtensions.x-implements}}{{#-first}}extends {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.x-implements}} {
{{#vars}}
{{#isEnum}}
{{#isDiscriminator}}
{{>enumClass}}
{{/isDiscriminator}}
{{/isEnum}}
{{/vars}}
{{#discriminator}}
public {{propertyType}} {{propertyGetter}}();
{{/discriminator}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@

| Name | Type | Description | Notes |
|------------ | ------------- | ------------- | -------------|
{{#vars}}|**{{name}}** | {{#isEnum}}[**{{datatypeWithEnum}}**](#{{datatypeWithEnum}}){{/isEnum}}{{^isEnum}}{{#isContainer}}{{#isArray}}{{#items}}{{#isModel}}[{{/isModel}}{{/items}}**{{baseType}}{{#items}}&lt;{{dataType}}&gt;**{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isModel}}{{/items}}{{/isArray}}{{#isMap}}{{#items}}{{#isModel}}[{{/isModel}}**Map&lt;String, {{dataType}}&gt;**{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isModel}}{{/items}}{{/isMap}}{{/isContainer}}{{^isContainer}}{{#isModel}}[{{/isModel}}**{{dataType}}**{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isModel}}{{/isContainer}}{{/isEnum}} | {{description}} | {{^required}} [optional]{{/required}}{{#isReadOnly}} [readonly]{{/isReadOnly}} |
{{#vars}}|**{{name}}** | {{#isInnerEnum}}[**{{datatypeWithEnum}}**](#{{datatypeWithEnum}}){{/isInnerEnum}}{{^isInnerEnum}}{{#isContainer}}{{#isArray}}{{#items}}{{#isModel}}[{{/isModel}}{{/items}}**{{baseType}}{{#items}}&lt;{{dataType}}&gt;**{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isModel}}{{/items}}{{/isArray}}{{#isMap}}{{#items}}{{#isModel}}[{{/isModel}}**Map&lt;String, {{dataType}}&gt;**{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isModel}}{{/items}}{{/isMap}}{{/isContainer}}{{^isContainer}}{{#isModel}}[{{/isModel}}**{{dataType}}**{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isModel}}{{/isContainer}}{{/isInnerEnum}} | {{description}} | {{^required}} [optional]{{/required}}{{#isReadOnly}} [readonly]{{/isReadOnly}} |
{{/vars}}
{{#vars}}{{#isEnum}}
{{#vars}}{{#isInnerEnum}}


## Enum: {{datatypeWithEnum}}

| Name | Value |
|---- | -----|{{#allowableValues}}{{#enumVars}}
| {{name}} | {{value}} |{{/enumVars}}{{/allowableValues}}
{{/isEnum}}{{/vars}}
{{/isInnerEnum}}{{/vars}}
{{#vendorExtensions.x-implements.0}}

## Implemented Interfaces
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@

| Name | Type | Description | Notes |
|------------ | ------------- | ------------- | -------------|
{{#vars}}|**{{name}}** | {{#isEnum}}[**{{datatypeWithEnum}}**](#{{datatypeWithEnum}}){{/isEnum}}{{^isEnum}}{{#isContainer}}{{#isArray}}{{#items}}{{#isModel}}[{{/isModel}}{{/items}}**{{baseType}}{{#items}}&lt;{{dataType}}&gt;**{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isModel}}{{/items}}{{/isArray}}{{#isMap}}{{#items}}{{#isModel}}[{{/isModel}}**Map&lt;String, {{dataType}}&gt;**{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isModel}}{{/items}}{{/isMap}}{{/isContainer}}{{^isContainer}}{{#isModel}}[{{/isModel}}**{{dataType}}**{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isModel}}{{/isContainer}}{{/isEnum}} | {{description}} | {{^required}} [optional]{{/required}}{{#isReadOnly}} [readonly]{{/isReadOnly}} |
{{#vars}}|**{{name}}** | {{#isInnerEnum}}[**{{datatypeWithEnum}}**](#{{datatypeWithEnum}}){{/isInnerEnum}}{{^isInnerEnum}}{{#isContainer}}{{#isArray}}{{#items}}{{#isModel}}[{{/isModel}}{{/items}}**{{baseType}}{{#items}}&lt;{{dataType}}&gt;**{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isModel}}{{/items}}{{/isArray}}{{#isMap}}{{#items}}{{#isModel}}[{{/isModel}}**Map&lt;String, {{dataType}}&gt;**{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isModel}}{{/items}}{{/isMap}}{{/isContainer}}{{^isContainer}}{{#isModel}}[{{/isModel}}**{{dataType}}**{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isModel}}{{/isContainer}}{{/isInnerEnum}} | {{description}} | {{^required}} [optional]{{/required}}{{#isReadOnly}} [readonly]{{/isReadOnly}} |
{{/vars}}
{{#vars}}{{#isEnum}}
{{#vars}}{{#isInnerEnum}}


## Enum: {{datatypeWithEnum}}

| Name | Value |
|---- | -----|{{#allowableValues}}{{#enumVars}}
| {{name}} | {{value}} |{{/enumVars}}{{/allowableValues}}
{{/isEnum}}{{/vars}}
{{/isInnerEnum}}{{/vars}}
{{#vendorExtensions.x-implements.0}}

## Implemented Interfaces
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ The class is defined in **[{{classname}}.java](../../{{{modelFolder}}}/{{classna

Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
{{#vars}}**{{name}}** | {{#isEnum}}[**{{datatypeWithEnum}}**](#{{datatypeWithEnum}}){{/isEnum}}{{^isEnum}}{{#isContainer}}{{#isArray}}{{#items}}{{#isModel}}[{{/isModel}}{{/items}}`{{baseType}}{{#items}}&lt;{{dataType}}&gt;`{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{#baseType}}{{baseType}}{{/baseType}}.md){{/isModel}}{{/items}}{{/isArray}}{{#isMap}}{{#items}}{{#isModel}}[{{/isModel}}`Map&lt;String, {{dataType}}&gt;`{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{#baseType}}{{baseType}}{{/baseType}}.md){{/isModel}}{{/items}}{{/isMap}}{{/isContainer}}{{^isContainer}}{{#isModel}}[{{/isModel}}`{{dataType}}`{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{#baseType}}{{baseType}}{{/baseType}}.md){{/isModel}}{{/isContainer}}{{/isEnum}} | {{description}} | {{^required}} [optional property]{{/required}}{{#isReadOnly}} [readonly property]{{/isReadOnly}}
{{#vars}}**{{name}}** | {{#isInnerEnum}}[**{{datatypeWithEnum}}**](#{{datatypeWithEnum}}){{/isInnerEnum}}{{^isInnerEnum}}{{#isContainer}}{{#isArray}}{{#items}}{{#isModel}}[{{/isModel}}{{/items}}`{{baseType}}{{#items}}&lt;{{dataType}}&gt;`{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{#baseType}}{{baseType}}{{/baseType}}.md){{/isModel}}{{/items}}{{/isArray}}{{#isMap}}{{#items}}{{#isModel}}[{{/isModel}}`Map&lt;String, {{dataType}}&gt;`{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{#baseType}}{{baseType}}{{/baseType}}.md){{/isModel}}{{/items}}{{/isMap}}{{/isContainer}}{{^isContainer}}{{#isModel}}[{{/isModel}}`{{dataType}}`{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{#baseType}}{{baseType}}{{/baseType}}.md){{/isModel}}{{/isContainer}}{{/isInnerEnum}} | {{description}} | {{^required}} [optional property]{{/required}}{{#isReadOnly}} [readonly property]{{/isReadOnly}}
{{/vars}}
{{#vars}}

{{#isEnum}}
{{#isInnerEnum}}
## {{datatypeWithEnum}}

Name | Value
Expand All @@ -25,7 +25,7 @@ Name | Value
{{name}} | `{{{value}}}`
{{/enumVars}}
{{/allowableValues}}
{{/isEnum}}
{{/isInnerEnum}}
{{/vars}}
{{#vendorExtensions.x-implements.0}}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
{{/additionalOneOfTypeAnnotations}}
{{>common/generatedAnnotation}}{{>common/model/typeInfoAnnotation}}{{>common/model/xmlAnnotation}}
public interface {{classname}} {{#vendorExtensions.x-implements}}{{#-first}}extends {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.x-implements}} {
{{#vars}}
{{#isEnum}}
{{#isDiscriminator}}
{{>common/model/modelInnerEnum}}
{{/isDiscriminator}}
{{/isEnum}}
{{/vars}}
{{#discriminator}}
public {{propertyType}} {{propertyGetter}}();
{{/discriminator}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2481,6 +2481,41 @@ public void testOneOfInterfaceGeneration() throws Exception {
assertFileNotContains(Paths.get(modelDir + "DogRequest.java"), "@JsonTypeName(\"DogRequest\")");
}

@Test
public void testOneOfInterfaceInlineDiscriminatorEnum() throws Exception {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();
OpenAPI openAPI = new OpenAPIParser()
.readLocation("src/test/resources/bugs/issue_25398.yaml", null, new ParseOptions()).getOpenAPI();
codegen.setOutputDir(output.getAbsolutePath());
codegen.setUseOneOfInterfaces(true);
new DefaultGenerator().opts(new ClientOptInput().openAPI(openAPI).config(codegen)).generate();

Path pet = output.toPath().resolve("src/gen/java/org/openapitools/model/Pet.java");
assertFileContains(pet, "public enum PetTypeEnum {", "import com.fasterxml.jackson.annotation.*;",
"PetTypeEnum getPetType();");
Path dog = output.toPath().resolve("src/gen/java/org/openapitools/model/Dog.java");
assertFileContains(dog, "implements Pet", "public PetTypeEnum getPetType()");
assertFileNotContains(dog, "public enum PetTypeEnum {");
}

@Test
public void testPropertyLevelOneOfInterfaceInlineDiscriminatorEnum() throws Exception {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();
OpenAPI openAPI = new OpenAPIParser()
.readLocation("src/test/resources/bugs/issue_25398_property_level.yaml", null, new ParseOptions()).getOpenAPI();
codegen.setOutputDir(output.getAbsolutePath());
codegen.setUseOneOfInterfaces(true);
new DefaultGenerator().opts(new ClientOptInput().openAPI(openAPI).config(codegen)).generate();

Path ownerPet = output.toPath().resolve("src/gen/java/org/openapitools/model/OwnerPet.java");
assertFileContains(ownerPet, "public enum PetTypeEnum {", "PetTypeEnum getPetType();");
Path dog = output.toPath().resolve("src/gen/java/org/openapitools/model/Dog.java");
assertFileContains(dog, "implements OwnerPet", "public PetTypeEnum getPetType()");
assertFileNotContains(dog, "public enum PetTypeEnum {");
}

@Test
public void generatesEmailAnnotationWhenBeanValidationEnabled() throws IOException {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2565,6 +2565,17 @@ void testOneOfWithEnumDiscriminator() throws IOException {
);
}

@Test
public void testOneOfInterfaceDeclaresInlineDiscriminatorEnum() throws IOException {
Map<String, File> files = generateFromContract("src/test/resources/bugs/issue_25398.yaml", SPRING_BOOT);

assertThat(files.get("Pet.java").toPath()).content()
.contains("public enum PetTypeEnum {", "public PetTypeEnum getPetType();");
assertThat(files.get("Dog.java").toPath()).content()
.contains("private PetTypeEnum petType;")
.doesNotContain("enum PetTypeEnum");
}

@Test
public void testTypeMappings() {
final SpringCodegen codegen = new SpringCodegen();
Expand Down
35 changes: 35 additions & 0 deletions modules/openapi-generator/src/test/resources/bugs/issue_25398.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
openapi: 3.0.1
info:
title: oneOf interface with an inline enum discriminator
version: 0.0.1
paths: {}
components:
schemas:
Pet:
type: object
required:
- petType
properties:
petType:
type: string
enum:
- dog
- cat
oneOf:
- $ref: '#/components/schemas/Dog'
- $ref: '#/components/schemas/Cat'
discriminator:
propertyName: petType
mapping:
dog: Dog
cat: Cat
Dog:
type: object
properties:
breed:
type: string
Cat:
type: object
properties:
declawed:
type: boolean
Loading
Loading