Skip to content

Commit

Permalink
[Go] fix oneOf naming (#11863)
Browse files Browse the repository at this point in the history
* update samples

* add lambda to handle oneof/anyof naming in go
  • Loading branch information
wing328 authored Mar 15, 2022
1 parent 266de25 commit 7ea5d15
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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"));
Expand Down
Original file line number Diff line number Diff line change
@@ -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,
}
}

Expand Down Expand Up @@ -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}})")
Expand All @@ -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}})")
Expand All @@ -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}}
Expand All @@ -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}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 7ea5d15

Please sign in to comment.