Skip to content

Commit 1136872

Browse files
author
Andrew Wilson
authored
[feat] [protobuf] Improve protobuf generator with switch useSimplifiedEnumNames (#21052)
* improving with simple enum names * adding test case * fixing docs * fixing param name * fix docs
1 parent ffefebd commit 1136872

5 files changed

Lines changed: 103 additions & 21 deletions

File tree

bin/configs/protobuf-schema-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ additionalProperties:
1010
wrapComplexType: false
1111
supportMultipleResponses: false
1212
aggregateModelsName: data
13+
useSimplifiedEnumNames: true
1314
typeMappings:
1415
object: "google.protobuf.Struct"
1516
importMappings:

docs/generators/protobuf-schema.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
2323
|numberedFieldNumberList|Field numbers in order.| |false|
2424
|startEnumsWithUnspecified|Introduces "UNSPECIFIED" as the first element of enumerations.| |false|
2525
|supportMultipleResponses|Support multiple responses| |true|
26+
|useSimplifiedEnumNames|Use a simple name for enums| |false|
2627
|wrapComplexType|Generate Additional message for complex type| |true|
2728

2829
## IMPORT MAPPING

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

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ public class ProtobufSchemaCodegen extends DefaultCodegen implements CodegenConf
6666

6767
public static final String WRAP_COMPLEX_TYPE = "wrapComplexType";
6868

69+
public static final String USE_SIMPLIFIED_ENUM_NAMES = "useSimplifiedEnumNames";
70+
6971
public static final String AGGREGATE_MODELS_NAME = "aggregateModelsName";
7072

7173
public static final String SUPPORT_MULTIPLE_RESPONSES = "supportMultipleResponses";
@@ -84,6 +86,8 @@ public class ProtobufSchemaCodegen extends DefaultCodegen implements CodegenConf
8486

8587
private boolean wrapComplexType = true;
8688

89+
private boolean useSimplifiedEnumNames = false;
90+
8791
private boolean supportMultipleResponses = true;
8892

8993
@Override
@@ -196,6 +200,7 @@ public ProtobufSchemaCodegen() {
196200
addSwitch(START_ENUMS_WITH_UNSPECIFIED, "Introduces \"UNSPECIFIED\" as the first element of enumerations.", startEnumsWithUnspecified);
197201
addSwitch(ADD_JSON_NAME_ANNOTATION, "Append \"json_name\" annotation to message field when the specification name differs from the protobuf field name", addJsonNameAnnotation);
198202
addSwitch(WRAP_COMPLEX_TYPE, "Generate Additional message for complex type", wrapComplexType);
203+
addSwitch(USE_SIMPLIFIED_ENUM_NAMES, "Use a simple name for enums", useSimplifiedEnumNames);
199204
addSwitch(SUPPORT_MULTIPLE_RESPONSES, "Support multiple responses", supportMultipleResponses);
200205
addOption(AGGREGATE_MODELS_NAME, "Aggregated model filename. If set, all generated models will be combined into this single file.", null);
201206
}
@@ -224,22 +229,26 @@ public void processOpts() {
224229
additionalProperties.put(CodegenConstants.MODEL_PACKAGE, modelPackage);
225230
}
226231

227-
if (additionalProperties.containsKey(this.NUMBERED_FIELD_NUMBER_LIST)) {
232+
if (additionalProperties.containsKey(NUMBERED_FIELD_NUMBER_LIST)) {
228233
this.numberedFieldNumberList = convertPropertyToBooleanAndWriteBack(NUMBERED_FIELD_NUMBER_LIST);
229234
}
230235

231-
if (additionalProperties.containsKey(this.START_ENUMS_WITH_UNSPECIFIED)) {
236+
if (additionalProperties.containsKey(START_ENUMS_WITH_UNSPECIFIED)) {
232237
this.startEnumsWithUnspecified = convertPropertyToBooleanAndWriteBack(START_ENUMS_WITH_UNSPECIFIED);
233238
}
234239

235-
if (additionalProperties.containsKey(this.ADD_JSON_NAME_ANNOTATION)) {
240+
if (additionalProperties.containsKey(ADD_JSON_NAME_ANNOTATION)) {
236241
this.addJsonNameAnnotation = convertPropertyToBooleanAndWriteBack(ADD_JSON_NAME_ANNOTATION);
237242
}
238243

239-
if (additionalProperties.containsKey(this.WRAP_COMPLEX_TYPE)) {
244+
if (additionalProperties.containsKey(WRAP_COMPLEX_TYPE)) {
240245
this.wrapComplexType = convertPropertyToBooleanAndWriteBack(WRAP_COMPLEX_TYPE);
241246
}
242247

248+
if (additionalProperties.containsKey(USE_SIMPLIFIED_ENUM_NAMES)) {
249+
this.useSimplifiedEnumNames = convertPropertyToBooleanAndWriteBack(USE_SIMPLIFIED_ENUM_NAMES);
250+
}
251+
243252
if (additionalProperties.containsKey(AGGREGATE_MODELS_NAME)) {
244253
this.setAggregateModelsName((String) additionalProperties.get(AGGREGATE_MODELS_NAME));
245254
}
@@ -498,16 +507,15 @@ public void addEnumValuesPrefix(Map<String, Object> allowableValues, String pref
498507
prefix = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, prefix);
499508
for (Map<String, Object> value : enumVars) {
500509
String name = (String) value.get("name");
501-
value.put("name", prefix + "_" + name);
502-
value.put("value", "\"" + prefix + "_" + name + "\"");
503-
510+
value.put("name", useSimplifiedEnumNames ? name : prefix + "_" + name);
511+
value.put("value", useSimplifiedEnumNames ? name : "\"" + prefix + "_" + name + "\"");
504512
}
505513
}
506514

507515
if (allowableValues.containsKey("values")) {
508516
List<Object> values = (List<Object>) allowableValues.get("values");
509517
for (Object value : values) {
510-
value = prefix + "_" + String.valueOf(value);
518+
value = useSimplifiedEnumNames ? value : prefix + "_" + value;
511519
}
512520
}
513521
}

modules/openapi-generator/src/test/java/org/openapitools/codegen/protobuf/ProtobufSchemaCodegenTest.java

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@
1717
package org.openapitools.codegen.protobuf;
1818

1919
import io.swagger.v3.oas.models.OpenAPI;
20+
import io.swagger.v3.oas.models.media.IntegerSchema;
21+
import io.swagger.v3.oas.models.media.Schema;
22+
import io.swagger.v3.oas.models.media.StringSchema;
2023
import org.openapitools.codegen.ClientOptInput;
2124
import org.openapitools.codegen.CodegenModel;
25+
import org.openapitools.codegen.CodegenProperty;
2226
import org.openapitools.codegen.DefaultGenerator;
2327
import org.openapitools.codegen.TestUtils;
2428
import org.openapitools.codegen.config.CodegenConfigurator;
@@ -34,8 +38,12 @@
3438
import java.nio.file.Files;
3539
import java.nio.file.Path;
3640
import java.nio.file.Paths;
41+
import java.util.Arrays;
3742
import java.util.List;
43+
import java.util.Map;
3844

45+
import static org.openapitools.codegen.TestUtils.createCodegenModelWrapper;
46+
import static org.openapitools.codegen.languages.ProtobufSchemaCodegen.USE_SIMPLIFIED_ENUM_NAMES;
3947
import static org.testng.Assert.assertEquals;
4048

4149
public class ProtobufSchemaCodegenTest {
@@ -141,4 +149,68 @@ public void modelTest() {
141149
Assert.assertEquals(simpleName.classname, "DollarModel");
142150
Assert.assertEquals(simpleName.classVarName, "dollar_model");
143151
}
152+
153+
@Test(description = "support complex enum values")
154+
public void supportComplexEnumValues() {
155+
testEnumValues(false);
156+
}
157+
158+
@Test(description = "support simple enum values")
159+
public void supportSimpleEnumValues() {
160+
testEnumValues(true);
161+
}
162+
163+
private void testEnumValues(boolean simpleEnumValue) {
164+
final Schema model = new Schema()
165+
.description("a sample model")
166+
.addProperties("testStringEnum", new StringSchema()._enum(Arrays.asList("foo", "bar")))
167+
.addProperties("testIntEnum", new IntegerSchema().addEnumItem(1).addEnumItem(2));
168+
final ProtobufSchemaCodegen codegen = new ProtobufSchemaCodegen();
169+
OpenAPI openAPI = TestUtils.createOpenAPIWithOneSchema("sample", model);
170+
codegen.setOpenAPI(openAPI);
171+
final CodegenModel cm = codegen.fromModel("sample", model);
172+
codegen.additionalProperties().put(USE_SIMPLIFIED_ENUM_NAMES, simpleEnumValue);
173+
codegen.processOpts();
174+
codegen.postProcessModels(createCodegenModelWrapper(cm));
175+
176+
final CodegenProperty property1 = cm.vars.get(0);
177+
Assert.assertEquals(property1.baseName, "testStringEnum");
178+
Assert.assertEquals(property1.dataType, "string");
179+
Assert.assertEquals(property1.baseType, "string");
180+
Assert.assertEquals(property1.datatypeWithEnum, "Test_string_enum");
181+
Assert.assertEquals(property1.name, "test_string_enum");
182+
Assert.assertTrue(property1.isEnum);
183+
Assert.assertEquals(property1.allowableValues.size(), 2);
184+
Assert.assertEquals(((List<String>) property1.allowableValues.get("values")).size(), 2);
185+
List<Map<String, Object>> enumVars1 = (List<Map<String, Object>>) property1.allowableValues.get("enumVars");
186+
Assert.assertEquals(enumVars1.size(), 2);
187+
188+
Assert.assertEquals(enumVars1.get(0).get("name"), simpleEnumValue ? "FOO" : "TEST_STRING_ENUM_FOO");
189+
Assert.assertEquals(enumVars1.get(0).get("value"), simpleEnumValue ? "FOO" : "\"TEST_STRING_ENUM_FOO\"");
190+
Assert.assertEquals(enumVars1.get(0).get("isString"), false);
191+
192+
Assert.assertEquals(enumVars1.get(1).get("name"), simpleEnumValue ? "BAR" : "TEST_STRING_ENUM_BAR");
193+
Assert.assertEquals(enumVars1.get(1).get("value"), simpleEnumValue ? "BAR" : "\"TEST_STRING_ENUM_BAR\"");
194+
Assert.assertEquals(enumVars1.get(1).get("isString"), false);
195+
196+
final CodegenProperty property2 = cm.vars.get(1);
197+
Assert.assertEquals(property2.baseName, "testIntEnum");
198+
Assert.assertEquals(property2.dataType, "int32");
199+
Assert.assertEquals(property2.baseType, "int32");
200+
Assert.assertEquals(property2.datatypeWithEnum, "Test_int_enum");
201+
Assert.assertEquals(property2.name, "test_int_enum");
202+
Assert.assertTrue(property2.isEnum);
203+
Assert.assertEquals(property2.allowableValues.size(), 2);
204+
Assert.assertEquals(((List<String>) property2.allowableValues.get("values")).size(), 2);
205+
List<Map<String, Object>> enumVars2 = (List<Map<String, Object>>) property2.allowableValues.get("enumVars");
206+
Assert.assertEquals(enumVars2.size(), 2);
207+
208+
Assert.assertEquals(enumVars2.get(0).get("name"), simpleEnumValue ? "_1" : "TEST_INT_ENUM__1");
209+
Assert.assertEquals(enumVars2.get(0).get("value"), simpleEnumValue ? "_1" : "\"TEST_INT_ENUM__1\"");
210+
Assert.assertEquals(enumVars2.get(0).get("isString"), false);
211+
212+
Assert.assertEquals(enumVars2.get(1).get("name"), simpleEnumValue ? "_2" : "TEST_INT_ENUM__2");
213+
Assert.assertEquals(enumVars2.get(1).get("value"), simpleEnumValue ? "_2" : "\"TEST_INT_ENUM__2\"");
214+
Assert.assertEquals(enumVars2.get(1).get("isString"), false);
215+
}
144216
}

samples/config/petstore/protobuf-schema-config/models/data.proto

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ message Dog {
4545
bool bark = 1;
4646

4747
enum Breed {
48-
BREED_UNSPECIFIED = 0;
49-
BREED_DINGO = 1;
50-
BREED_HUSKY = 2;
51-
BREED_RETRIEVER = 3;
52-
BREED_SHEPHERD = 4;
48+
UNSPECIFIED = 0;
49+
DINGO = 1;
50+
HUSKY = 2;
51+
RETRIEVER = 3;
52+
SHEPHERD = 4;
5353
}
5454

5555
Breed breed = 2;
@@ -78,10 +78,10 @@ message Order {
7878

7979
// Order Status
8080
enum Status {
81-
STATUS_UNSPECIFIED = 0;
82-
STATUS_PLACED = 1;
83-
STATUS_APPROVED = 2;
84-
STATUS_DELIVERED = 3;
81+
UNSPECIFIED = 0;
82+
PLACED = 1;
83+
APPROVED = 2;
84+
DELIVERED = 3;
8585
}
8686

8787
Status status = 5;
@@ -112,10 +112,10 @@ message Pet {
112112

113113
// pet status in the store
114114
enum Status {
115-
STATUS_UNSPECIFIED = 0;
116-
STATUS_AVAILABLE = 1;
117-
STATUS_PENDING = 2;
118-
STATUS_SOLD = 3;
115+
UNSPECIFIED = 0;
116+
AVAILABLE = 1;
117+
PENDING = 2;
118+
SOLD = 3;
119119
}
120120

121121
Status status = 6;

0 commit comments

Comments
 (0)