diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/GoClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/GoClientCodegen.java index 4dd0b8cbba23..5a59c3f6fef9 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/GoClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/GoClientCodegen.java @@ -18,6 +18,8 @@ package org.openapitools.codegen.languages; import com.google.common.collect.Iterables; +import com.samskivert.mustache.Mustache; +import com.samskivert.mustache.Template; import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.security.SecurityScheme; import org.apache.commons.lang3.StringUtils; @@ -31,6 +33,8 @@ import org.slf4j.LoggerFactory; import java.io.File; +import java.io.IOException; +import java.io.Writer; import java.util.*; import static org.openapitools.codegen.utils.StringUtils.camelize; @@ -245,6 +249,19 @@ public void processOpts() { .get(CodegenConstants.DISALLOW_ADDITIONAL_PROPERTIES_IF_NOT_PRESENT).toString())); } + // add lambda for mustache templates to handle oneOf/anyOf naming + // e.g. []string => ArrayOfString + additionalProperties.put("lambda.type-to-name", new Mustache.Lambda() { + @Override + public void execute(Template.Fragment fragment, Writer writer) throws IOException { + String content = fragment.execute(); + content = content.trim().replace("[]", "array_of_"); + content = content.trim().replace("[", "map_of_"); + content = content.trim().replace("]", ""); + writer.write(camelize(content)); + } + }); + supportingFiles.add(new SupportingFile("openapi.mustache", "api", "openapi.yaml")); supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh")); diff --git a/modules/openapi-generator/src/main/resources/go/model_oneof.mustache b/modules/openapi-generator/src/main/resources/go/model_oneof.mustache index 6722492abda5..14bc3ada757e 100644 --- a/modules/openapi-generator/src/main/resources/go/model_oneof.mustache +++ b/modules/openapi-generator/src/main/resources/go/model_oneof.mustache @@ -1,15 +1,15 @@ // {{classname}} - {{{description}}}{{^description}}struct for {{{classname}}}{{/description}} type {{classname}} struct { {{#oneOf}} - {{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}} *{{{.}}} + {{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}} *{{{.}}} {{/oneOf}} } {{#oneOf}} // {{{.}}}As{{classname}} is a convenience function that returns {{{.}}} wrapped in {{classname}} -func {{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}}As{{classname}}(v *{{{.}}}) {{classname}} { +func {{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}}As{{classname}}(v *{{{.}}}) {{classname}} { return {{classname}}{ - {{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}}: v, + {{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}}: v, } } @@ -55,24 +55,24 @@ func (dst *{{classname}}) UnmarshalJSON(data []byte) error { {{^discriminator}} match := 0 {{#oneOf}} - // try to unmarshal data into {{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}} - err = json.Unmarshal(data, &dst.{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}}) + // try to unmarshal data into {{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}} + err = json.Unmarshal(data, &dst.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}}) if err == nil { - json{{{.}}}, _ := json.Marshal(dst.{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}}) + json{{{.}}}, _ := json.Marshal(dst.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}}) if string(json{{{.}}}) == "{}" { // empty struct - dst.{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}} = nil + dst.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}} = nil } else { match++ } } else { - dst.{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}} = nil + dst.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}} = nil } {{/oneOf}} if match > 1 { // more than 1 match // reset to nil {{#oneOf}} - dst.{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}} = nil + dst.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}} = nil {{/oneOf}} return fmt.Errorf("Data matches more than one schema in oneOf({{classname}})") @@ -86,24 +86,24 @@ func (dst *{{classname}}) UnmarshalJSON(data []byte) error { {{^useOneOfDiscriminatorLookup}} match := 0 {{#oneOf}} - // try to unmarshal data into {{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}} - err = newStrictDecoder(data).Decode(&dst.{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}}) + // try to unmarshal data into {{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}} + err = newStrictDecoder(data).Decode(&dst.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}}) if err == nil { - json{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}}, _ := json.Marshal(dst.{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}}) - if string(json{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}}) == "{}" { // empty struct - dst.{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}} = nil + json{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}}, _ := json.Marshal(dst.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}}) + if string(json{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}}) == "{}" { // empty struct + dst.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}} = nil } else { match++ } } else { - dst.{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}} = nil + dst.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}} = nil } {{/oneOf}} if match > 1 { // more than 1 match // reset to nil {{#oneOf}} - dst.{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}} = nil + dst.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}} = nil {{/oneOf}} return fmt.Errorf("Data matches more than one schema in oneOf({{classname}})") @@ -118,8 +118,8 @@ func (dst *{{classname}}) UnmarshalJSON(data []byte) error { // Marshal data from the first non-nil pointers in the struct to JSON func (src {{classname}}) MarshalJSON() ([]byte, error) { {{#oneOf}} - if src.{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}} != nil { - return json.Marshal(&src.{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}}) + if src.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}} != nil { + return json.Marshal(&src.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}}) } {{/oneOf}} @@ -132,8 +132,8 @@ func (obj *{{classname}}) GetActualInstance() (interface{}) { return nil } {{#oneOf}} - if obj.{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}} != nil { - return obj.{{#lambda.titlecase}}{{{.}}}{{/lambda.titlecase}} + if obj.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}} != nil { + return obj.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}} } {{/oneOf}} diff --git a/modules/openapi-generator/src/test/resources/3_0/go/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml b/modules/openapi-generator/src/test/resources/3_0/go/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml index abc9e37573e0..674afde01d57 100644 --- a/modules/openapi-generator/src/test/resources/3_0/go/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml +++ b/modules/openapi-generator/src/test/resources/3_0/go/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml @@ -1976,13 +1976,13 @@ components: - $ref: '#/components/schemas/OneOfPrimitiveTypeChild' - type: integer format: int32 - #- $ref: '#/components/schemas/OneOfArrayOfString' + - $ref: '#/components/schemas/OneOfArrayOfString' OneOfPrimitiveTypeChild: type: object properties: name: type: string - #OneOfArrayOfString: - # type: array - # items: - # type: string + OneOfArrayOfString: + type: array + items: + type: string diff --git a/samples/openapi3/client/petstore/go/go-petstore/api/openapi.yaml b/samples/openapi3/client/petstore/go/go-petstore/api/openapi.yaml index 946f8c4ed956..4790eaddd3cc 100644 --- a/samples/openapi3/client/petstore/go/go-petstore/api/openapi.yaml +++ b/samples/openapi3/client/petstore/go/go-petstore/api/openapi.yaml @@ -2104,11 +2104,16 @@ components: - $ref: '#/components/schemas/OneOfPrimitiveTypeChild' - format: int32 type: integer + - $ref: '#/components/schemas/OneOfArrayOfString' OneOfPrimitiveTypeChild: properties: name: type: string type: object + OneOfArrayOfString: + items: + type: string + type: array inline_response_default: example: string: diff --git a/samples/openapi3/client/petstore/go/go-petstore/model_one_of_primitive_type.go b/samples/openapi3/client/petstore/go/go-petstore/model_one_of_primitive_type.go index 837c04a41b3b..dd008dfc1502 100644 --- a/samples/openapi3/client/petstore/go/go-petstore/model_one_of_primitive_type.go +++ b/samples/openapi3/client/petstore/go/go-petstore/model_one_of_primitive_type.go @@ -18,6 +18,7 @@ import ( // OneOfPrimitiveType - struct for OneOfPrimitiveType type OneOfPrimitiveType struct { OneOfPrimitiveTypeChild *OneOfPrimitiveTypeChild + ArrayOfString *[]string Int32 *int32 } @@ -28,6 +29,13 @@ func OneOfPrimitiveTypeChildAsOneOfPrimitiveType(v *OneOfPrimitiveTypeChild) One } } +// []stringAsOneOfPrimitiveType is a convenience function that returns []string wrapped in OneOfPrimitiveType +func ArrayOfStringAsOneOfPrimitiveType(v *[]string) OneOfPrimitiveType { + return OneOfPrimitiveType{ + ArrayOfString: v, + } +} + // int32AsOneOfPrimitiveType is a convenience function that returns int32 wrapped in OneOfPrimitiveType func Int32AsOneOfPrimitiveType(v *int32) OneOfPrimitiveType { return OneOfPrimitiveType{ @@ -53,6 +61,19 @@ func (dst *OneOfPrimitiveType) UnmarshalJSON(data []byte) error { dst.OneOfPrimitiveTypeChild = nil } + // try to unmarshal data into ArrayOfString + err = newStrictDecoder(data).Decode(&dst.ArrayOfString) + if err == nil { + jsonArrayOfString, _ := json.Marshal(dst.ArrayOfString) + if string(jsonArrayOfString) == "{}" { // empty struct + dst.ArrayOfString = nil + } else { + match++ + } + } else { + dst.ArrayOfString = nil + } + // try to unmarshal data into Int32 err = newStrictDecoder(data).Decode(&dst.Int32) if err == nil { @@ -69,6 +90,7 @@ func (dst *OneOfPrimitiveType) UnmarshalJSON(data []byte) error { if match > 1 { // more than 1 match // reset to nil dst.OneOfPrimitiveTypeChild = nil + dst.ArrayOfString = nil dst.Int32 = nil return fmt.Errorf("Data matches more than one schema in oneOf(OneOfPrimitiveType)") @@ -85,6 +107,10 @@ func (src OneOfPrimitiveType) MarshalJSON() ([]byte, error) { return json.Marshal(&src.OneOfPrimitiveTypeChild) } + if src.ArrayOfString != nil { + return json.Marshal(&src.ArrayOfString) + } + if src.Int32 != nil { return json.Marshal(&src.Int32) } @@ -101,6 +127,10 @@ func (obj *OneOfPrimitiveType) GetActualInstance() (interface{}) { return obj.OneOfPrimitiveTypeChild } + if obj.ArrayOfString != nil { + return obj.ArrayOfString + } + if obj.Int32 != nil { return obj.Int32 }