Skip to content

Commit 90edc51

Browse files
committed
feat(go): add enumUnknownDefaultCase config option
1 parent a8003fb commit 90edc51

File tree

19 files changed

+81
-6
lines changed

19 files changed

+81
-6
lines changed

bin/configs/go-petstore.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ additionalProperties:
1616
disallowAdditionalPropertiesIfNotPresent: false
1717
generateInterfaces: true
1818
useDefaultValuesForRequiredVars: "true"
19+
enumUnknownDefaultCase: true
1920
enumNameMappings:
2021
delivered: SHIPPED
2122

docs/generators/go.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
2020
| ------ | ----------- | ------ | ------- |
2121
|disallowAdditionalPropertiesIfNotPresent|If false, the 'additionalProperties' implementation (set to true by default) is compliant with the OAS and JSON schema specifications. If true (default), keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.|<dl><dt>**false**</dt><dd>The 'additionalProperties' implementation is compliant with the OAS and JSON schema specifications.</dd><dt>**true**</dt><dd>Keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.</dd></dl>|true|
2222
|enumClassPrefix|Prefix enum with class name| |false|
23+
|enumUnknownDefaultCase|If the server adds new enum cases, that are unknown by an old spec/client, the client will fail to parse the network response.With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the server sends an enum case that is not known by the client/spec, they can safely fallback to this case.|<dl><dt>**false**</dt><dd>No changes to the enum's are made, this is the default option.</dd><dt>**true**</dt><dd>With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the enum case sent by the server is not known by the client/spec, can safely be decoded to this case.</dd></dl>|false|
2324
|generateInterfaces|Generate interfaces for api classes| |false|
2425
|generateMarshalJSON|Generate MarshalJSON method| |true|
2526
|generateUnmarshalJSON|Generate UnmarshalJSON method| |true|

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractGoCodegen.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -892,6 +892,18 @@ public String escapeQuotationMark(String input) {
892892
return input.replace("\"", "");
893893
}
894894

895+
/**
896+
* checks if the data should be classified as "string" in enum
897+
* In the future, we may rename this function to "isEnumString"
898+
*
899+
* @param dataType data type
900+
* @return true if it's a enum string
901+
*/
902+
@Override
903+
public boolean isDataTypeString(String dataType) {
904+
return "string".equalsIgnoreCase(dataType);
905+
}
906+
895907
@Override
896908
public String escapeUnsafeCharacters(String input) {
897909
return input.replace("*/", "*_/").replace("/*", "/_*");
@@ -908,6 +920,8 @@ public Map<String, String> createMapping(String key, String value) {
908920
public String toEnumValue(String value, String datatype) {
909921
if (isNumberType(datatype) || "bool".equals(datatype)) {
910922
return value;
923+
} else if (isDataTypeString(datatype) && value.indexOf("\"") == 0 && value.lastIndexOf("\"") == value.length() - 1) {
924+
return value;
911925
} else {
912926
return "\"" + escapeText(value) + "\"";
913927
}

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/GoClientCodegen.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,19 @@ public GoClientCodegen() {
153153
cliOptions.add(CliOption.newBoolean(WITH_GO_MOD, "Generate go.mod and go.sum", true));
154154
cliOptions.add(CliOption.newBoolean(CodegenConstants.GENERATE_MARSHAL_JSON, CodegenConstants.GENERATE_MARSHAL_JSON_DESC, true));
155155
cliOptions.add(CliOption.newBoolean(CodegenConstants.GENERATE_UNMARSHAL_JSON, CodegenConstants.GENERATE_UNMARSHAL_JSON_DESC, true));
156+
157+
CliOption enumUnknownDefaultCaseOpt = CliOption.newBoolean(
158+
CodegenConstants.ENUM_UNKNOWN_DEFAULT_CASE,
159+
CodegenConstants.ENUM_UNKNOWN_DEFAULT_CASE_DESC).defaultValue(Boolean.FALSE.toString());
160+
Map<String, String> enumUnknownDefaultCaseOpts = new HashMap<>();
161+
enumUnknownDefaultCaseOpts.put("false",
162+
"No changes to the enum's are made, this is the default option.");
163+
enumUnknownDefaultCaseOpts.put("true",
164+
"With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the enum case sent by the server is not known by the client/spec, can safely be decoded to this case.");
165+
enumUnknownDefaultCaseOpt.setEnum(enumUnknownDefaultCaseOpts);
166+
cliOptions.add(enumUnknownDefaultCaseOpt);
167+
this.setEnumUnknownDefaultCase(false);
168+
156169
this.setWithGoMod(true);
157170
}
158171

@@ -411,6 +424,7 @@ public void updateCodegenPropertyEnum(CodegenProperty var) {
411424
}
412425
}
413426

427+
414428
/**
415429
* Determines if at least one of the allOf pieces of a schema are of type string
416430
*

modules/openapi-generator/src/main/resources/go/model_enum.mustache

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,19 @@ func (v *{{{classname}}}) UnmarshalJSON(src []byte) error {
3535
}
3636
}
3737

38+
{{#enumUnknownDefaultCase}}
39+
{{#allowableValues}}
40+
{{#enumVars}}
41+
{{#-last}}
42+
*v = {{#enumClassPrefix}}{{{classname.toUpperCase}}}_{{/enumClassPrefix}}{{{name}}}
43+
return nil
44+
{{/-last}}
45+
{{/enumVars}}
46+
{{/allowableValues}}
47+
{{/enumUnknownDefaultCase}}
48+
{{^enumUnknownDefaultCase}}
3849
return fmt.Errorf("%+v is not a valid {{classname}}", value)
50+
{{/enumUnknownDefaultCase}}
3951
}
4052

4153
// New{{{classname}}}FromValue returns a pointer to a valid {{{classname}}}

modules/openapi-generator/src/test/java/org/openapitools/codegen/go/GoClientOptionsTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,6 @@ protected void verifyOptions() {
5555
verify(clientCodegen).setGenerateMarshalJSON(GoClientOptionsProvider.GENERATE_MARSHAL_JSON_VALUE);
5656
verify(clientCodegen).setGenerateUnmarshalJSON(GoClientOptionsProvider.GENERATE_UNMARSHAL_JSON_VALUE);
5757
verify(clientCodegen).setUseDefaultValuesForRequiredVars(GoClientOptionsProvider.USE_DEFAULT_VALUES_FOR_REQUIRED_VARS_VALUE);
58+
verify(clientCodegen).setEnumUnknownDefaultCase(Boolean.parseBoolean(GoClientOptionsProvider.ENUM_UNKNOWN_DEFAULT_CASE_VALUE));
5859
}
5960
}

modules/openapi-generator/src/test/java/org/openapitools/codegen/options/GoClientOptionsProvider.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public class GoClientOptionsProvider implements OptionsProvider {
4040
public static final boolean GENERATE_MARSHAL_JSON_VALUE = true;
4141
public static final boolean GENERATE_UNMARSHAL_JSON_VALUE = true;
4242
public static final boolean USE_DEFAULT_VALUES_FOR_REQUIRED_VARS_VALUE = true;
43+
public static final String ENUM_UNKNOWN_DEFAULT_CASE_VALUE = "false";
4344

4445
@Override
4546
public String getLanguage() {
@@ -66,6 +67,7 @@ public Map<String, String> createOptions() {
6667
.put("generateInterfaces", "true")
6768
.put("structPrefix", "true")
6869
.put(CodegenConstants.USE_DEFAULT_VALUES_FOR_REQUIRED_VARS, "true")
70+
.put(CodegenConstants.ENUM_UNKNOWN_DEFAULT_CASE, ENUM_UNKNOWN_DEFAULT_CASE_VALUE)
6971
.build();
7072
}
7173

samples/openapi3/client/petstore/go/go-petstore/docs/EnumClass.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
* `XYZ` (value: `"(xyz)"`)
1111

12+
* `UNKNOWN_DEFAULT_OPEN_API` (value: `"unknown_default_open_api"`)
13+
1214

1315
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
1416

samples/openapi3/client/petstore/go/go-petstore/docs/ExampleEnum.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
* `EXAMPLE2` (value: `"example2"`)
99

10+
* `UNKNOWN_DEFAULT_OPEN_API` (value: `"unknown_default_open_api"`)
11+
1012

1113
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
1214

samples/openapi3/client/petstore/go/go-petstore/docs/OuterEnum.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
* `SHIPPED` (value: `"delivered"`)
1111

12+
* `UNKNOWN_DEFAULT_OPEN_API` (value: `"unknown_default_open_api"`)
13+
1214

1315
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
1416

0 commit comments

Comments
 (0)