From 876ed03da993acc78280d11f6d5b564d4709093e Mon Sep 17 00:00:00 2001 From: Kunal8954 Date: Thu, 10 Sep 2026 14:00:25 +0530 Subject: [PATCH] fix(go): preserve json tags for properties with oneOf Fixes #24916. The Go generator could omit json struct tags when a schema contained both normal properties and a schema-level oneOf/anyOf. The issue occurs because model property processing could select inherited properties from composed schemas instead of the model's own properties. For validation-only oneOf constraints, those inherited properties can be empty, causing generated fields to lose their JSON tags. This change ensures that existing model properties retain their generated JSON tags even when schema-level composition is present, while preserving the behavior of pure oneOf models. --- .../codegen/languages/AbstractGoCodegen.java | 6 +-- .../codegen/go/GoClientCodegenTest.java | 30 +++++++++++++ .../3_0/go/oneof-with-properties.yaml | 43 +++++++++++++++++++ 3 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 modules/openapi-generator/src/test/resources/3_0/go/oneof-with-properties.yaml diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractGoCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractGoCodegen.java index 0e56b31cf6f0..ff2bcf1e44ee 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractGoCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractGoCodegen.java @@ -787,13 +787,9 @@ public ModelsMap postProcessModels(ModelsMap objs) { } List codegenProperties = new ArrayList<>(); - if (model.getComposedSchemas() == null || (model.getComposedSchemas() != null && model.getComposedSchemas().getAllOf() != null)) { - // If the model is an allOf or does not have any composed schemas, then we can use the model's properties. + if (model.vars != null && !model.vars.isEmpty()) { codegenProperties.addAll(model.vars); } else { - // If the model is no model, but is a - // anyOf or oneOf, add all first level options - // from anyOf or oneOf. codegenProperties.addAll(inheritedProperties); } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/go/GoClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/go/GoClientCodegenTest.java index 6b04bf8e8703..665880d1fe42 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/go/GoClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/go/GoClientCodegenTest.java @@ -562,4 +562,34 @@ public void testOneOfUnmarshalJSONGeneratedByDefault() throws IOException { "validator.Validate", "gopkg.in/validator.v2"); } + + @Test(description = "schema with both properties and oneOf must emit json tags on properties (#24916)") + public void testOneOfWithPropertiesEmitsJsonTags() throws IOException { + File output = Files.createTempDirectory("test").toFile(); + output.deleteOnExit(); + + final CodegenConfigurator configurator = new CodegenConfigurator() + .setGeneratorName("go") + .setInputSpec("src/test/resources/3_0/go/oneof-with-properties.yaml") + .setOutputDir(output.getAbsolutePath().replace("\\", "/")); + + DefaultGenerator generator = new DefaultGenerator(); + List files = generator.opts(configurator.toClientOptInput()).generate(); + files.forEach(File::deleteOnExit); + + Path modelFile = Paths.get(output + "/model_thing.go"); + TestUtils.assertFileExists(modelFile); + + // Properties must have json tags even though oneOf is present + TestUtils.assertFileContains(modelFile, + "Kind string `json:\"kind\"`"); + TestUtils.assertFileContains(modelFile, + "FirstValue []float32 `json:\"first_value,omitempty\"`"); + TestUtils.assertFileContains(modelFile, + "SecondValue []float32 `json:\"second_value,omitempty\"`"); + + // Must not be rendered as a oneOf union struct + TestUtils.assertFileNotContains(modelFile, + "GetActualInstance"); + } } diff --git a/modules/openapi-generator/src/test/resources/3_0/go/oneof-with-properties.yaml b/modules/openapi-generator/src/test/resources/3_0/go/oneof-with-properties.yaml new file mode 100644 index 000000000000..9c020b37fbe8 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/go/oneof-with-properties.yaml @@ -0,0 +1,43 @@ +openapi: 3.0.3 +info: + title: oneOf with properties regression test + version: 1.0.0 +paths: + /thing: + get: + operationId: getThing + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Thing' +components: + schemas: + Thing: + type: object + required: + - kind + properties: + kind: + type: string + first_value: + type: array + items: + type: number + second_value: + type: array + items: + type: number + oneOf: + - required: + - first_value + not: + required: + - second_value + - required: + - second_value + not: + required: + - first_value