Skip to content

Commit 79b9578

Browse files
Anthony TODISCOAnthony TODISCO
authored andcommitted
fix: Fix issue on enum extraction
Fix issue linked to enum in array when there is inheritance or discriminator
1 parent 2498607 commit 79b9578

2 files changed

Lines changed: 45 additions & 11 deletions

File tree

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

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,10 @@ public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> objs)
830830

831831
// Extract enum properties to separate files if enabled
832832
if (this.extractEnumsToSeparateFiles) {
833+
// Recompute allModels after managing children properties
834+
// This ensures inherited properties are included in the vars
835+
allModels = this.getAllModels(objs);
836+
833837
// First, update property data types for referenced enum models
834838
this.updateReferencedEnumPropertyDataTypes(objs, allModels);
835839

@@ -890,6 +894,7 @@ private void updateReferencedEnumPropertyDataTypes(Map<String, ModelsMap> objs,
890894
String dataTypeToCheck = null;
891895
CodegenProperty itemToCheck = property;
892896

897+
// Determine what data type to check
893898
if (property.isArray && property.items != null) {
894899
dataTypeToCheck = property.items.dataType;
895900
itemToCheck = property.items;
@@ -906,21 +911,49 @@ private void updateReferencedEnumPropertyDataTypes(Map<String, ModelsMap> objs,
906911
}
907912

908913
// Look for an enum model that matches this dataType
909-
CodegenModel referencedModel = allModels.get(dataTypeToCheck);
914+
// Note: Need to apply toModelName to ensure correct key lookup since getAllModels() uses this
915+
String modelNameKey = toModelName(dataTypeToCheck);
916+
917+
// If the dataType already ends with .Enum, it's already been wrapped
918+
// Strip the .Enum suffix to find the underlying enum model
919+
if (dataTypeToCheck.endsWith("." + ENUM_WRAPPER_INNER_NAME)) {
920+
// Strip the .Enum suffix for lookup
921+
modelNameKey = toModelName(dataTypeToCheck.substring(0, dataTypeToCheck.length() - ("." + ENUM_WRAPPER_INNER_NAME).length()));
922+
}
923+
924+
CodegenModel referencedModel = allModels.get(modelNameKey);
910925
if (referencedModel != null && referencedModel.isEnum) {
926+
927+
// Use the actual classname from the enum model for consistency with how it's used in templates
928+
String enumWrapperName = referencedModel.getClassname();
929+
930+
// For referenced enums, the wrapper name is just the enum model's classname
931+
// (not a composite like "ModelName_PropertyName" which is for inline enums)
932+
933+
// Check if already properly wrapped with .Enum suffix
934+
String expectedWrappedType = enumWrapperName + "." + ENUM_WRAPPER_INNER_NAME;
935+
911936
// This property references an enum model, update its data type to include .Enum suffix
912937
// Also mark it as a referenced extracted enum and add import
913938
property.vendorExtensions.put(VENDOR_EXT_ENUM_EXTRACTED, true);
914939
property.vendorExtensions.put("x-protobuf-enum-reference-import", true);
915-
String enumWrapperName = dataTypeToCheck; // The message wrapper name is the enum model name
916940
property.vendorExtensions.put(VENDOR_EXT_ENUM_WRAPPER_MESSAGE, enumWrapperName);
917941

918942
// Update the data type of the item to include .Enum suffix
919-
String wrappedEnumType = enumWrapperName + "." + ENUM_WRAPPER_INNER_NAME;
920-
itemToCheck.dataType = wrappedEnumType;
943+
itemToCheck.dataType = expectedWrappedType;
921944

922-
// Also update the x-protobuf-data-type for protobuf rendering
923-
property.vendorExtensions.put("x-protobuf-data-type", wrappedEnumType);
945+
// Update the vendor extension for protobuf rendering
946+
// This is critical for arrays, as the template uses x-protobuf-data-type
947+
// For arrays: x-protobuf-data-type must reference the wrapped enum type
948+
// For direct properties: the dataType in the template is used
949+
if (property.isArray) {
950+
// For array properties, the template uses x-protobuf-data-type which comes from items.dataType
951+
// Make sure it's updated there
952+
property.vendorExtensions.put("x-protobuf-data-type", expectedWrappedType);
953+
} else {
954+
// For non-array properties, also update vendor extension for consistency
955+
property.vendorExtensions.put("x-protobuf-data-type", expectedWrappedType);
956+
}
924957

925958
// Add import for the referenced enum to the current model
926959
this.addImport(objs, model, enumWrapperName);

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,6 @@ public void testExtractEnumsToSeparateFiles() throws IOException {
484484
System.setProperty("line.separator", "\n");
485485

486486
File output = Files.createTempDirectory("test").toFile();
487-
System.out.println("ExtractEnums Temporary output directory: " + output.getAbsolutePath());
488487

489488
final CodegenConfigurator configurator = new CodegenConfigurator()
490489
.setGeneratorName("protobuf-schema")
@@ -572,15 +571,15 @@ public void testExtractEnumsToSeparateFilesWithOtherEnumOptions() throws IOExcep
572571
System.setProperty("line.separator", "\n");
573572

574573
File output = Files.createTempDirectory("test").toFile();
575-
System.out.println("With combined options Temporary output directory: " + output.getAbsolutePath());
576574

577575
final CodegenConfigurator configurator = new CodegenConfigurator()
578576
.setGeneratorName("protobuf-schema")
579577
.setInputSpec("src/test/resources/3_0/protobuf-schema/extracted_enum.yaml")
580578
.setOutputDir(output.getAbsolutePath().replace("\\", "/"))
581-
.addAdditionalProperty(EXTRACT_ENUMS_TO_SEPARATE_FILES, true)
579+
.addAdditionalProperty("removeEnumValuePrefix", false)
580+
.addAdditionalProperty(START_ENUMS_WITH_UNSPECIFIED, true)
582581
.addAdditionalProperty(USE_SIMPLIFIED_ENUM_NAMES, true)
583-
.addAdditionalProperty(START_ENUMS_WITH_UNSPECIFIED, true);
582+
.addAdditionalProperty(EXTRACT_ENUMS_TO_SEPARATE_FILES, true);
584583

585584

586585
final ClientOptInput clientOptInput = configurator.toClientOptInput();
@@ -829,7 +828,6 @@ public void testEnumsRemainsInlineWithoutExtraction() throws IOException {
829828
System.setProperty("line.separator", "\n");
830829

831830
File output = Files.createTempDirectory("test").toFile();
832-
System.out.println("InlineEnums Temporary output directory: " + output.getAbsolutePath());
833831

834832
final CodegenConfigurator configurator = new CodegenConfigurator()
835833
.setGeneratorName("protobuf-schema")
@@ -915,6 +913,9 @@ public void testEnumsInArraysWithExtraction() throws IOException {
915913
.setGeneratorName("protobuf-schema")
916914
.setInputSpec("src/test/resources/3_0/protobuf-schema/extracted_enum.yaml")
917915
.setOutputDir(output.getAbsolutePath().replace("\\", "/"))
916+
.addAdditionalProperty("removeEnumValuePrefix", false)
917+
.addAdditionalProperty(START_ENUMS_WITH_UNSPECIFIED, true)
918+
.addAdditionalProperty(USE_SIMPLIFIED_ENUM_NAMES, true)
918919
.addAdditionalProperty(EXTRACT_ENUMS_TO_SEPARATE_FILES, true);
919920

920921
final ClientOptInput clientOptInput = configurator.toClientOptInput();

0 commit comments

Comments
 (0)