diff --git a/docs/generators/go-experimental.md b/docs/generators/go-experimental.md index d5298fd44f16..5866c95004ef 100644 --- a/docs/generators/go-experimental.md +++ b/docs/generators/go-experimental.md @@ -12,6 +12,7 @@ sidebar_label: go-experimental |packageVersion|Go package version.| |1.0.0| |prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false| |structPrefix|whether to prefix struct with the class name. e.g. DeletePetOpts => PetApiDeletePetOpts| |false| +|useOneOfDiscriminatorLookup|Use the discriminator's mapping in oneOf to speed up the model lookup. IMPORTANT: Validation (e.g. one and onlye one match in oneOf's schemas) will be skipped.| |false| |withAWSV4Signature|whether to include AWS v4 signature support| |false| |withGoCodegenComment|whether to include Go codegen comment to disable Go Lint and collapse by default in GitHub PRs and diffs| |false| |withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false| diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/GoClientExperimentalCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/GoClientExperimentalCodegen.java index a72d18959b18..ddb10684f2a0 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/GoClientExperimentalCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/GoClientExperimentalCodegen.java @@ -35,6 +35,7 @@ public class GoClientExperimentalCodegen extends GoClientCodegen { private static final Logger LOGGER = LoggerFactory.getLogger(GoClientExperimentalCodegen.class); protected String goImportAlias = "openapiclient"; + protected boolean useOneOfDiscriminatorLookup = false; // use oneOf discriminator's mapping for model lookup public GoClientExperimentalCodegen() { super(); @@ -44,6 +45,8 @@ public GoClientExperimentalCodegen() { usesOptionals = false; generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata).stability(Stability.EXPERIMENTAL).build(); + + cliOptions.add(new CliOption(CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP, CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP_DESC).defaultValue("false")); } /** @@ -93,6 +96,20 @@ public void processOpts() { additionalProperties.put("goImportAlias", goImportAlias); } + if (additionalProperties.containsKey(CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP)) { + setUseOneOfDiscriminatorLookup(convertPropertyToBooleanAndWriteBack(CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP)); + } else { + additionalProperties.put(CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP, useOneOfDiscriminatorLookup); + } + + } + + public void setUseOneOfDiscriminatorLookup(boolean useOneOfDiscriminatorLookup) { + this.useOneOfDiscriminatorLookup = useOneOfDiscriminatorLookup; + } + + public boolean getUseOneOfDiscriminatorLookup() { + return this.useOneOfDiscriminatorLookup; } public void setGoImportAlias(String goImportAlias) { diff --git a/modules/openapi-generator/src/main/resources/go-experimental/model_oneof.mustache b/modules/openapi-generator/src/main/resources/go-experimental/model_oneof.mustache index 20cb13d541b1..bbd9aeecccee 100644 --- a/modules/openapi-generator/src/main/resources/go-experimental/model_oneof.mustache +++ b/modules/openapi-generator/src/main/resources/go-experimental/model_oneof.mustache @@ -24,6 +24,37 @@ func (dst *{{classname}}) UnmarshalJSON(data []byte) error { } {{/isNullable}} + {{#useOneOfDiscriminatorLookup}} + {{#discriminator}} + {{#mappedModels}} + {{#-first}} + // use discriminator value to speed up the lookup + var jsonDict map[string]interface{} + err := json.Unmarshal(data, &jsonDict) + if err != nil { + return fmt.Errorf("Failed to unmarshal JSON into map for the discrimintor lookup.") + } + + {{/-first}} + // check if the discriminator value is '{{{mappingName}}}' + if jsonDict["{{{propertyBaseName}}}"] == "{{{mappingName}}}" { + // try to unmarshal JSON data into {{{modelName}}} + err = json.Unmarshal(data, &dst.{{{modelName}}}); + if err == nil { + json{{{modelName}}}, _ := json.Marshal(dst.{{{modelName}}}) + if string(json{{{modelName}}}) == "{}" { // empty struct + dst.{{{modelName}}} = nil + } else { + return nil // data stored in dst.{{{modelName}}}, return on the first match + } + } else { + dst.{{{modelName}}} = nil + } + } + + {{/mappedModels}} + {{/discriminator}} + {{/useOneOfDiscriminatorLookup}} {{#oneOf}} // try to unmarshal data into {{{.}}} err = json.Unmarshal(data, &dst.{{{.}}}); @@ -76,4 +107,4 @@ func (obj *{{classname}}) GetActualInstance() (interface{}) { return nil } -{{>nullable_model}} \ No newline at end of file +{{>nullable_model}} diff --git a/samples/openapi3/client/petstore/go-experimental/go-petstore/model_fruit.go b/samples/openapi3/client/petstore/go-experimental/go-petstore/model_fruit.go index ec7e137f352e..416ae81c7188 100644 --- a/samples/openapi3/client/petstore/go-experimental/go-petstore/model_fruit.go +++ b/samples/openapi3/client/petstore/go-experimental/go-petstore/model_fruit.go @@ -137,3 +137,4 @@ func (v *NullableFruit) UnmarshalJSON(src []byte) error { return json.Unmarshal(src, &v.value) } + diff --git a/samples/openapi3/client/petstore/go-experimental/go-petstore/model_fruit_req.go b/samples/openapi3/client/petstore/go-experimental/go-petstore/model_fruit_req.go index b70da598b420..dce03284f0f0 100644 --- a/samples/openapi3/client/petstore/go-experimental/go-petstore/model_fruit_req.go +++ b/samples/openapi3/client/petstore/go-experimental/go-petstore/model_fruit_req.go @@ -137,3 +137,4 @@ func (v *NullableFruitReq) UnmarshalJSON(src []byte) error { return json.Unmarshal(src, &v.value) } + diff --git a/samples/openapi3/client/petstore/go-experimental/go-petstore/model_mammal.go b/samples/openapi3/client/petstore/go-experimental/go-petstore/model_mammal.go index a3af711d6f39..e9731f1d550d 100644 --- a/samples/openapi3/client/petstore/go-experimental/go-petstore/model_mammal.go +++ b/samples/openapi3/client/petstore/go-experimental/go-petstore/model_mammal.go @@ -137,3 +137,4 @@ func (v *NullableMammal) UnmarshalJSON(src []byte) error { return json.Unmarshal(src, &v.value) } +