Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bin/configs/protobuf-schema-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ additionalProperties:
wrapComplexType: false
supportMultipleResponses: false
aggregateModelsName: data
useSimplifiedEnumNames: true
typeMappings:
object: "google.protobuf.Struct"
importMappings:
Expand Down
1 change: 1 addition & 0 deletions docs/generators/protobuf-schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|numberedFieldNumberList|Field numbers in order.| |false|
|startEnumsWithUnspecified|Introduces "UNSPECIFIED" as the first element of enumerations.| |false|
|supportMultipleResponses|Support multiple responses| |true|
|useSimplifiedEnumNames|Use a simple name for enums| |false|
|wrapComplexType|Generate Additional message for complex type| |true|

## IMPORT MAPPING
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ public class ProtobufSchemaCodegen extends DefaultCodegen implements CodegenConf

public static final String WRAP_COMPLEX_TYPE = "wrapComplexType";

public static final String USE_SIMPLIFIED_ENUM_NAMES = "useSimplifiedEnumNames";

public static final String AGGREGATE_MODELS_NAME = "aggregateModelsName";

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

private boolean wrapComplexType = true;

private boolean useSimplifiedEnumNames = false;

private boolean supportMultipleResponses = true;

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

if (additionalProperties.containsKey(this.NUMBERED_FIELD_NUMBER_LIST)) {
if (additionalProperties.containsKey(NUMBERED_FIELD_NUMBER_LIST)) {
this.numberedFieldNumberList = convertPropertyToBooleanAndWriteBack(NUMBERED_FIELD_NUMBER_LIST);
}

if (additionalProperties.containsKey(this.START_ENUMS_WITH_UNSPECIFIED)) {
if (additionalProperties.containsKey(START_ENUMS_WITH_UNSPECIFIED)) {
this.startEnumsWithUnspecified = convertPropertyToBooleanAndWriteBack(START_ENUMS_WITH_UNSPECIFIED);
}

if (additionalProperties.containsKey(this.ADD_JSON_NAME_ANNOTATION)) {
if (additionalProperties.containsKey(ADD_JSON_NAME_ANNOTATION)) {
this.addJsonNameAnnotation = convertPropertyToBooleanAndWriteBack(ADD_JSON_NAME_ANNOTATION);
}

if (additionalProperties.containsKey(this.WRAP_COMPLEX_TYPE)) {
if (additionalProperties.containsKey(WRAP_COMPLEX_TYPE)) {
this.wrapComplexType = convertPropertyToBooleanAndWriteBack(WRAP_COMPLEX_TYPE);
}

if (additionalProperties.containsKey(USE_SIMPLIFIED_ENUM_NAMES)) {
this.useSimplifiedEnumNames = convertPropertyToBooleanAndWriteBack(USE_SIMPLIFIED_ENUM_NAMES);
}

if (additionalProperties.containsKey(AGGREGATE_MODELS_NAME)) {
this.setAggregateModelsName((String) additionalProperties.get(AGGREGATE_MODELS_NAME));
}
Expand Down Expand Up @@ -498,16 +507,15 @@ public void addEnumValuesPrefix(Map<String, Object> allowableValues, String pref
prefix = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, prefix);
for (Map<String, Object> value : enumVars) {
String name = (String) value.get("name");
value.put("name", prefix + "_" + name);
value.put("value", "\"" + prefix + "_" + name + "\"");

value.put("name", useSimplifiedEnumNames ? name : prefix + "_" + name);
value.put("value", useSimplifiedEnumNames ? name : "\"" + prefix + "_" + name + "\"");
}
}

if (allowableValues.containsKey("values")) {
List<Object> values = (List<Object>) allowableValues.get("values");
for (Object value : values) {
value = prefix + "_" + String.valueOf(value);
value = useSimplifiedEnumNames ? value : prefix + "_" + value;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@
package org.openapitools.codegen.protobuf;

import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.media.IntegerSchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.media.StringSchema;
import org.openapitools.codegen.ClientOptInput;
import org.openapitools.codegen.CodegenModel;
import org.openapitools.codegen.CodegenProperty;
import org.openapitools.codegen.DefaultGenerator;
import org.openapitools.codegen.TestUtils;
import org.openapitools.codegen.config.CodegenConfigurator;
Expand All @@ -34,8 +38,12 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import static org.openapitools.codegen.TestUtils.createCodegenModelWrapper;
import static org.openapitools.codegen.languages.ProtobufSchemaCodegen.USE_SIMPLIFIED_ENUM_NAMES;
import static org.testng.Assert.assertEquals;

public class ProtobufSchemaCodegenTest {
Expand Down Expand Up @@ -141,4 +149,68 @@ public void modelTest() {
Assert.assertEquals(simpleName.classname, "DollarModel");
Assert.assertEquals(simpleName.classVarName, "dollar_model");
}

@Test(description = "support complex enum values")
public void supportComplexEnumValues() {
testEnumValues(false);
}

@Test(description = "support simple enum values")
public void supportSimpleEnumValues() {
testEnumValues(true);
}

private void testEnumValues(boolean simpleEnumValue) {
final Schema model = new Schema()
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modelled this test on this one

.description("a sample model")
.addProperties("testStringEnum", new StringSchema()._enum(Arrays.asList("foo", "bar")))
.addProperties("testIntEnum", new IntegerSchema().addEnumItem(1).addEnumItem(2));
final ProtobufSchemaCodegen codegen = new ProtobufSchemaCodegen();
OpenAPI openAPI = TestUtils.createOpenAPIWithOneSchema("sample", model);
codegen.setOpenAPI(openAPI);
final CodegenModel cm = codegen.fromModel("sample", model);
codegen.additionalProperties().put(USE_SIMPLIFIED_ENUM_NAMES, simpleEnumValue);
codegen.processOpts();
codegen.postProcessModels(createCodegenModelWrapper(cm));

final CodegenProperty property1 = cm.vars.get(0);
Assert.assertEquals(property1.baseName, "testStringEnum");
Assert.assertEquals(property1.dataType, "string");
Assert.assertEquals(property1.baseType, "string");
Assert.assertEquals(property1.datatypeWithEnum, "Test_string_enum");
Assert.assertEquals(property1.name, "test_string_enum");
Assert.assertTrue(property1.isEnum);
Assert.assertEquals(property1.allowableValues.size(), 2);
Assert.assertEquals(((List<String>) property1.allowableValues.get("values")).size(), 2);
List<Map<String, Object>> enumVars1 = (List<Map<String, Object>>) property1.allowableValues.get("enumVars");
Assert.assertEquals(enumVars1.size(), 2);

Assert.assertEquals(enumVars1.get(0).get("name"), simpleEnumValue ? "FOO" : "TEST_STRING_ENUM_FOO");
Assert.assertEquals(enumVars1.get(0).get("value"), simpleEnumValue ? "FOO" : "\"TEST_STRING_ENUM_FOO\"");
Assert.assertEquals(enumVars1.get(0).get("isString"), false);

Assert.assertEquals(enumVars1.get(1).get("name"), simpleEnumValue ? "BAR" : "TEST_STRING_ENUM_BAR");
Assert.assertEquals(enumVars1.get(1).get("value"), simpleEnumValue ? "BAR" : "\"TEST_STRING_ENUM_BAR\"");
Assert.assertEquals(enumVars1.get(1).get("isString"), false);

final CodegenProperty property2 = cm.vars.get(1);
Assert.assertEquals(property2.baseName, "testIntEnum");
Assert.assertEquals(property2.dataType, "int32");
Assert.assertEquals(property2.baseType, "int32");
Assert.assertEquals(property2.datatypeWithEnum, "Test_int_enum");
Assert.assertEquals(property2.name, "test_int_enum");
Assert.assertTrue(property2.isEnum);
Assert.assertEquals(property2.allowableValues.size(), 2);
Assert.assertEquals(((List<String>) property2.allowableValues.get("values")).size(), 2);
List<Map<String, Object>> enumVars2 = (List<Map<String, Object>>) property2.allowableValues.get("enumVars");
Assert.assertEquals(enumVars2.size(), 2);

Assert.assertEquals(enumVars2.get(0).get("name"), simpleEnumValue ? "_1" : "TEST_INT_ENUM__1");
Assert.assertEquals(enumVars2.get(0).get("value"), simpleEnumValue ? "_1" : "\"TEST_INT_ENUM__1\"");
Assert.assertEquals(enumVars2.get(0).get("isString"), false);

Assert.assertEquals(enumVars2.get(1).get("name"), simpleEnumValue ? "_2" : "TEST_INT_ENUM__2");
Assert.assertEquals(enumVars2.get(1).get("value"), simpleEnumValue ? "_2" : "\"TEST_INT_ENUM__2\"");
Assert.assertEquals(enumVars2.get(1).get("isString"), false);
}
}
26 changes: 13 additions & 13 deletions samples/config/petstore/protobuf-schema-config/models/data.proto
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ message Dog {
bool bark = 1;

enum Breed {
BREED_UNSPECIFIED = 0;
BREED_DINGO = 1;
BREED_HUSKY = 2;
BREED_RETRIEVER = 3;
BREED_SHEPHERD = 4;
UNSPECIFIED = 0;
DINGO = 1;
HUSKY = 2;
RETRIEVER = 3;
SHEPHERD = 4;
}

Breed breed = 2;
Expand Down Expand Up @@ -78,10 +78,10 @@ message Order {

// Order Status
enum Status {
STATUS_UNSPECIFIED = 0;
STATUS_PLACED = 1;
STATUS_APPROVED = 2;
STATUS_DELIVERED = 3;
UNSPECIFIED = 0;
PLACED = 1;
APPROVED = 2;
DELIVERED = 3;
}

Status status = 5;
Expand Down Expand Up @@ -112,10 +112,10 @@ message Pet {

// pet status in the store
enum Status {
STATUS_UNSPECIFIED = 0;
STATUS_AVAILABLE = 1;
STATUS_PENDING = 2;
STATUS_SOLD = 3;
UNSPECIFIED = 0;
AVAILABLE = 1;
PENDING = 2;
SOLD = 3;
}

Status status = 6;
Expand Down
Loading