[feature] Add option to disable stripping of common prefix enum (#5166)

This commit is contained in:
John Flanigan 2020-02-08 15:29:50 -05:00 committed by GitHub
parent 4208f3da82
commit c6ad35cac8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 162 additions and 79 deletions

View File

@ -288,4 +288,8 @@ public interface CodegenConfig {
FeatureSet getFeatureSet();
void setFeatureSet(FeatureSet featureSet);
boolean isRemoveEnumValuePrefix();
void setRemoveEnumValuePrefix(boolean removeEnumValuePrefix);
}

View File

@ -342,4 +342,7 @@ public class CodegenConstants {
public static final String PACKAGE_TAGS = "packageTags";
public static final String PACKAGE_TAGS_DESC = "Tags to identify the package";
public static final String REMOVE_ENUM_VALUE_PREFIX = "removeEnumValuePrefix";
public static final String REMOVE_ENUM_VALUE_PREFIX_DESC = "Remove the common prefix of enum values";
}

View File

@ -193,6 +193,8 @@ public class DefaultCodegen implements CodegenConfig {
// acts strictly upon a spec, potentially modifying it to have consistent behavior across generators.
protected boolean strictSpecBehavior = true;
// flag to indicate whether enum value prefixes are removed
protected boolean removeEnumValuePrefix = true;
// make openapi available to all methods
protected OpenAPI openAPI;
@ -276,6 +278,11 @@ public class DefaultCodegen implements CodegenConfig {
ModelUtils.setGenerateAliasAsModel(Boolean.valueOf(additionalProperties
.get(CodegenConstants.GENERATE_ALIAS_AS_MODEL).toString()));
}
if (additionalProperties.containsKey(CodegenConstants.REMOVE_ENUM_VALUE_PREFIX)) {
this.setRemoveEnumValuePrefix(Boolean.valueOf(additionalProperties
.get(CodegenConstants.REMOVE_ENUM_VALUE_PREFIX).toString()));
}
}
/***
@ -480,25 +487,7 @@ public class DefaultCodegen implements CodegenConfig {
if (Boolean.TRUE.equals(cm.isEnum) && cm.allowableValues != null) {
Map<String, Object> allowableValues = cm.allowableValues;
List<Object> values = (List<Object>) allowableValues.get("values");
List<Map<String, Object>> enumVars = new ArrayList<Map<String, Object>>();
String commonPrefix = findCommonPrefixOfVars(values);
int truncateIdx = commonPrefix.length();
for (Object value : values) {
Map<String, Object> enumVar = new HashMap<String, Object>();
String enumName;
if (truncateIdx == 0) {
enumName = value.toString();
} else {
enumName = value.toString().substring(truncateIdx);
if ("".equals(enumName)) {
enumName = value.toString();
}
}
enumVar.put("name", toEnumVarName(enumName, cm.dataType));
enumVar.put("value", toEnumValue(value.toString(), cm.dataType));
enumVar.put("isString", isDataTypeString(cm.dataType));
enumVars.add(enumVar);
}
List<Map<String, Object>> enumVars = buildEnumVars(values, cm.dataType);
// if "x-enum-varnames" or "x-enum-descriptions" defined, update varnames
updateEnumVarsWithExtensions(enumVars, cm.getVendorExtensions());
cm.allowableValues.put("enumVars", enumVars);
@ -4572,28 +4561,8 @@ public class DefaultCodegen implements CodegenConfig {
.map(Map.Entry::getValue)
.findFirst();
String dataType = (referencedSchema.isPresent()) ? getTypeDeclaration(referencedSchema.get()) : varDataType;
List<Map<String, Object>> enumVars = buildEnumVars(values, dataType);
// put "enumVars" map into `allowableValues", including `name` and `value`
List<Map<String, Object>> enumVars = new ArrayList<>();
String commonPrefix = findCommonPrefixOfVars(values);
int truncateIdx = commonPrefix.length();
for (Object value : values) {
Map<String, Object> enumVar = new HashMap<>();
String enumName;
if (truncateIdx == 0) {
enumName = value.toString();
} else {
enumName = value.toString().substring(truncateIdx);
if ("".equals(enumName)) {
enumName = value.toString();
}
}
enumVar.put("name", toEnumVarName(enumName, dataType));
enumVar.put("value", toEnumValue(value.toString(), dataType));
enumVar.put("isString", isDataTypeString(dataType));
enumVars.add(enumVar);
}
// if "x-enum-varnames" or "x-enum-descriptions" defined, update varnames
Map<String, Object> extensions = var.mostInnerItems != null ? var.mostInnerItems.getVendorExtensions() : var.getVendorExtensions();
if (referencedSchema.isPresent()) {
@ -4623,6 +4592,34 @@ public class DefaultCodegen implements CodegenConfig {
}
}
protected List<Map<String, Object>> buildEnumVars(List<Object> values, String dataType) {
List<Map<String, Object>> enumVars = new ArrayList<>();
int truncateIdx = 0;
if (isRemoveEnumValuePrefix()) {
String commonPrefix = findCommonPrefixOfVars(values);
truncateIdx = commonPrefix.length();
}
for (Object value : values) {
Map<String, Object> enumVar = new HashMap<>();
String enumName;
if (truncateIdx == 0) {
enumName = value.toString();
}
else {
enumName = value.toString().substring(truncateIdx);
if ("".equals(enumName)) {
enumName = value.toString();
}
}
enumVar.put("name", toEnumVarName(enumName, dataType));
enumVar.put("value", toEnumValue(value.toString(), dataType));
enumVar.put("isString", isDataTypeString(dataType));
enumVars.add(enumVar);
}
return enumVars;
}
protected void updateEnumVarsWithExtensions(List<Map<String, Object>> enumVars, Map<String, Object> vendorExtensions) {
if (vendorExtensions != null) {
updateEnumVarsWithExtensions(enumVars, vendorExtensions, "x-enum-varnames", "name");
@ -5519,4 +5516,22 @@ public class DefaultCodegen implements CodegenConfig {
public void setFeatureSet(final FeatureSet featureSet) {
this.featureSet = featureSet == null ? DefaultFeatureSet : featureSet;
}
}
/**
* Get the boolean value indicating whether to remove enum value prefixes
*/
@Override
public boolean isRemoveEnumValuePrefix() {
return this.removeEnumValuePrefix;
}
/**
* Set the boolean value indicating whether to remove enum value prefixes
*
* @param removeEnumValuePrefix true to enable enum value prefix removal
*/
@Override
public void setRemoveEnumValuePrefix(final boolean removeEnumValuePrefix) {
this.removeEnumValuePrefix = removeEnumValuePrefix;
}
}

View File

@ -469,25 +469,7 @@ public class DartClientCodegen extends DefaultCodegen implements CodegenConfig {
}
Map<String, Object> allowableValues = cm.allowableValues;
List<Object> values = (List<Object>) allowableValues.get("values");
List<Map<String, String>> enumVars =
new ArrayList<Map<String, String>>();
String commonPrefix = findCommonPrefixOfVars(values);
int truncateIdx = commonPrefix.length();
for (Object value : values) {
Map<String, String> enumVar = new HashMap<String, String>();
String enumName;
if (truncateIdx == 0) {
enumName = value.toString();
} else {
enumName = value.toString().substring(truncateIdx);
if ("".equals(enumName)) {
enumName = value.toString();
}
}
enumVar.put("name", toEnumVarName(enumName, cm.dataType));
enumVar.put("value", toEnumValue(value.toString(), cm.dataType));
enumVars.add(enumVar);
}
List<Map<String, Object>> enumVars = buildEnumVars(values, cm.dataType);
cm.allowableValues.put("enumVars", enumVars);
return true;
}

View File

@ -463,26 +463,8 @@ public class PythonClientExperimentalCodegen extends PythonClientCodegen {
String dataType = (referencedSchema.isPresent()) ? getTypeDeclaration(referencedSchema.get()) : varDataType;
// put "enumVars" map into `allowableValues", including `name` and `value`
List<Map<String, Object>> enumVars = new ArrayList<>();
String commonPrefix = findCommonPrefixOfVars(values);
int truncateIdx = commonPrefix.length();
for (Object value : values) {
Map<String, Object> enumVar = new HashMap<>();
String enumName;
if (truncateIdx == 0) {
enumName = value.toString();
} else {
enumName = value.toString().substring(truncateIdx);
if ("".equals(enumName)) {
enumName = value.toString();
}
}
List<Map<String, Object>> enumVars = buildEnumVars(values, dataType);
enumVar.put("name", toEnumVarName(enumName, dataType));
enumVar.put("value", toEnumValue(value.toString(), dataType));
enumVar.put("isString", isDataTypeString(dataType));
enumVars.add(enumVar);
}
// if "x-enum-varnames" or "x-enum-descriptions" defined, update varnames
Map<String, Object> extensions = var.mostInnerItems != null ? var.mostInnerItems.getVendorExtensions() : var.getVendorExtensions();
if (referencedSchema.isPresent()) {

View File

@ -388,6 +388,79 @@ public class DefaultCodegenTest {
}
}
@Test
public void updateCodegenPropertyEnumWithPrefixRemoved() {
final DefaultCodegen codegen = new DefaultCodegen();
CodegenProperty enumProperty = codegenProperty(Arrays.asList("animal_dog", "animal_cat"));
codegen.updateCodegenPropertyEnum(enumProperty);
List<Map<String, Object>> enumVars = (List<Map<String, Object>>) enumProperty.getItems().getAllowableValues().get("enumVars");
Assert.assertNotNull(enumVars);
Assert.assertNotNull(enumVars.get(0));
Assert.assertEquals(enumVars.get(0).getOrDefault("name", ""), "DOG");
Assert.assertEquals(enumVars.get(0).getOrDefault("value", ""), "\"animal_dog\"");
Assert.assertNotNull(enumVars.get(1));
Assert.assertEquals(enumVars.get(1).getOrDefault("name", ""), "CAT");
Assert.assertEquals(enumVars.get(1).getOrDefault("value", ""), "\"animal_cat\"");
}
@Test
public void updateCodegenPropertyEnumWithoutPrefixRemoved() {
final DefaultCodegen codegen = new DefaultCodegen();
codegen.setRemoveEnumValuePrefix(false);
CodegenProperty enumProperty = codegenProperty(Arrays.asList("animal_dog", "animal_cat"));
codegen.updateCodegenPropertyEnum(enumProperty);
List<Map<String, Object>> enumVars = (List<Map<String, Object>>) enumProperty.getItems().getAllowableValues().get("enumVars");
Assert.assertNotNull(enumVars);
Assert.assertNotNull(enumVars.get(0));
Assert.assertEquals(enumVars.get(0).getOrDefault("name", ""), "ANIMAL_DOG");
Assert.assertEquals(enumVars.get(0).getOrDefault("value", ""), "\"animal_dog\"");
Assert.assertNotNull(enumVars.get(1));
Assert.assertEquals(enumVars.get(1).getOrDefault("name", ""), "ANIMAL_CAT");
Assert.assertEquals(enumVars.get(1).getOrDefault("value", ""), "\"animal_cat\"");
}
@Test
public void postProcessModelsEnumWithPrefixRemoved() {
final DefaultCodegen codegen = new DefaultCodegen();
Map<String, Object> objs = codegenModel(Arrays.asList("animal_dog", "animal_cat"));
CodegenModel cm = (CodegenModel) ((Map<String, Object>) ((List<Object>) objs.get("models")).get(0)).get("model");
codegen.postProcessModelsEnum(objs);
List<Map<String, Object>> enumVars = (List<Map<String, Object>>) cm.getAllowableValues().get("enumVars");
Assert.assertNotNull(enumVars);
Assert.assertNotNull(enumVars.get(0));
Assert.assertEquals(enumVars.get(0).getOrDefault("name", ""), "DOG");
Assert.assertEquals(enumVars.get(0).getOrDefault("value", ""), "\"animal_dog\"");
Assert.assertNotNull(enumVars.get(1));
Assert.assertEquals(enumVars.get(1).getOrDefault("name", ""), "CAT");
Assert.assertEquals(enumVars.get(1).getOrDefault("value", ""), "\"animal_cat\"");
}
@Test
public void postProcessModelsEnumWithoutPrefixRemoved() {
final DefaultCodegen codegen = new DefaultCodegen();
codegen.setRemoveEnumValuePrefix(false);
Map<String, Object> objs = codegenModel(Arrays.asList("animal_dog", "animal_cat"));
CodegenModel cm = (CodegenModel) ((Map<String, Object>) ((List<Object>) objs.get("models")).get(0)).get("model");
codegen.postProcessModelsEnum(objs);
List<Map<String, Object>> enumVars = (List<Map<String, Object>>) cm.getAllowableValues().get("enumVars");
Assert.assertNotNull(enumVars);
Assert.assertNotNull(enumVars.get(0));
Assert.assertEquals(enumVars.get(0).getOrDefault("name", ""), "ANIMAL_DOG");
Assert.assertEquals(enumVars.get(0).getOrDefault("value", ""), "\"animal_dog\"");
Assert.assertNotNull(enumVars.get(1));
Assert.assertEquals(enumVars.get(1).getOrDefault("name", ""), "ANIMAL_CAT");
Assert.assertEquals(enumVars.get(1).getOrDefault("value", ""), "\"animal_cat\"");
}
@Test
public void postProcessModelsEnumWithExtention() {
final DefaultCodegen codegen = new DefaultCodegen();
@ -902,6 +975,19 @@ public class DefaultCodegenTest {
return array;
}
private CodegenProperty codegenProperty(List<String> values) {
CodegenProperty array = new CodegenProperty();
final CodegenProperty items = new CodegenProperty();
final HashMap<String, Object> allowableValues = new HashMap<>();
allowableValues.put("values", values);
items.setAllowableValues(allowableValues);
items.dataType = "String";
array.items = items;
array.mostInnerItems = items;
array.dataType = "Array";
return array;
}
private CodegenProperty codegenPropertyWithXEnumVarName(List<String> values, List<String> aliases) {
final CodegenProperty var = new CodegenProperty();
final HashMap<String, Object> allowableValues = new HashMap<>();
@ -913,6 +999,17 @@ public class DefaultCodegenTest {
return var;
}
private Map<String, Object> codegenModel(List<String> values) {
final CodegenModel cm = new CodegenModel();
cm.isEnum = true;
final HashMap<String, Object> allowableValues = new HashMap<>();
allowableValues.put("values", values);
cm.setAllowableValues(allowableValues);
cm.dataType = "String";
Map<String, Object> objs = Collections.singletonMap("models", Collections.singletonList(Collections.singletonMap("model", cm)));
return objs;
}
private Map<String, Object> codegenModelWithXEnumVarName() {
final CodegenModel cm = new CodegenModel();
cm.isEnum = true;