@@ -68,6 +68,8 @@ public class ProtobufSchemaCodegen extends DefaultCodegen implements CodegenConf
6868
6969 public static final String AGGREGATE_MODELS_NAME = "aggregateModelsName" ;
7070
71+ public static final String SUPPORT_MULTIPLE_RESPONSES = "supportMultipleResponses" ;
72+
7173 private final Logger LOGGER = LoggerFactory .getLogger (ProtobufSchemaCodegen .class );
7274
7375 @ Setter protected String packageName = "openapitools" ;
@@ -82,6 +84,8 @@ public class ProtobufSchemaCodegen extends DefaultCodegen implements CodegenConf
8284
8385 private boolean wrapComplexType = true ;
8486
87+ private boolean supportMultipleResponses = true ;
88+
8589 @ Override
8690 public CodegenType getTag () {
8791 return CodegenType .SCHEMA ;
@@ -192,6 +196,7 @@ public ProtobufSchemaCodegen() {
192196 addSwitch (START_ENUMS_WITH_UNSPECIFIED , "Introduces \" UNSPECIFIED\" as the first element of enumerations." , startEnumsWithUnspecified );
193197 addSwitch (ADD_JSON_NAME_ANNOTATION , "Append \" json_name\" annotation to message field when the specification name differs from the protobuf field name" , addJsonNameAnnotation );
194198 addSwitch (WRAP_COMPLEX_TYPE , "Generate Additional message for complex type" , wrapComplexType );
199+ addSwitch (SUPPORT_MULTIPLE_RESPONSES , "Support multiple responses" , supportMultipleResponses );
195200 addOption (AGGREGATE_MODELS_NAME , "Aggregated model filename. If set, all generated models will be combined into this single file." , null );
196201 }
197202
@@ -239,6 +244,12 @@ public void processOpts() {
239244 this .setAggregateModelsName ((String ) additionalProperties .get (AGGREGATE_MODELS_NAME ));
240245 }
241246
247+ if (additionalProperties .containsKey (this .SUPPORT_MULTIPLE_RESPONSES )) {
248+ this .supportMultipleResponses = convertPropertyToBooleanAndWriteBack (SUPPORT_MULTIPLE_RESPONSES );
249+ } else {
250+ additionalProperties .put (this .SUPPORT_MULTIPLE_RESPONSES , this .supportMultipleResponses );
251+ }
252+
242253 supportingFiles .add (new SupportingFile ("README.mustache" , "" , "README.md" ));
243254 }
244255
@@ -442,7 +453,6 @@ private void wrapModels() {
442453 } else if (ModelUtils .isAnyOf (schema )) {
443454 wrapComposedChildren (schema .getAnyOf (), visitedSchema );
444455 }
445-
446456 }
447457 }
448458
@@ -475,7 +485,6 @@ public void preprocessOpenAPI(OpenAPI openAPI) {
475485 }
476486 }
477487
478-
479488 /**
480489 * Adds prefix to the enum allowable values
481490 * NOTE: Enum values use C++ scoping rules, meaning that enum values are siblings of their type, not children of it. Therefore, enum value must be unique
@@ -522,7 +531,9 @@ public void addUnspecifiedToAllowableValues(Map<String, Object> allowableValues)
522531
523532 if (allowableValues .containsKey ("values" )) {
524533 List <String > values = (List <String >) allowableValues .get ("values" );
525- values .add (0 , "UNSPECIFIED" );
534+ List <String > modifiableValues = new ArrayList <>(values );
535+ modifiableValues .add (0 , "UNSPECIFIED" );
536+ allowableValues .put ("values" , modifiableValues );
526537 }
527538 }
528539 }
@@ -542,24 +553,28 @@ public void addEnumIndexes(List<Map<String, Object>> enumVars) {
542553
543554 public List <CodegenProperty > processOneOfAnyOfItems (List <CodegenProperty > composedSchemasProperty ) {
544555 for (CodegenProperty cd : composedSchemasProperty ) {
545- if (cd .getTitle () != null ) {
546- cd .name = cd .getTitle ();
547- cd .baseName = cd .getTitle ();
548- } else {
549- cd .name = getNameFromDataType (cd );
550- cd .baseName = getNameFromDataType (cd );
551- }
556+ cd .name = resolveVarName (cd );
557+ cd .baseName = resolveVarName (cd );
552558 }
553559 return composedSchemasProperty ;
554560 }
555561
562+
563+ private String resolveVarName (CodegenProperty property ) {
564+ if (property .getTitle () != null ) {
565+ return toVarName (property .getTitle ());
566+ } else {
567+ return getNameFromDataType (property );
568+ }
569+ }
570+
556571 public String getNameFromDataType (CodegenProperty property ) {
557572 if (Boolean .TRUE .equals (property .getIsArray ())){
558- return underscore (property .mostInnerItems .dataType + ARRAY_SUFFIX );
573+ return toVarName (property .mostInnerItems .dataType + ARRAY_SUFFIX );
559574 } else if (Boolean .TRUE .equals (property .getIsMap ())) {
560- return underscore (property .mostInnerItems .dataType + MAP_SUFFIX );
575+ return toVarName (property .mostInnerItems .dataType + MAP_SUFFIX );
561576 } else {
562- return underscore (property .dataType );
577+ return toVarName (property .dataType );
563578 }
564579 }
565580
@@ -944,12 +959,41 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
944959 }
945960 }
946961 }
962+
963+ if (this .supportMultipleResponses ) {
964+ int responseIdx = 1 ;
965+ op .vendorExtensions .put ("x-grpc-response" , op .operationId +"Response" );
966+ for (CodegenResponse r : op .responses ) {
967+ if (r .returnProperty == null ) {
968+ r .vendorExtensions .put ("x-oneOf-response-type" , "google.protobuf.Empty" );
969+ r .vendorExtensions .put ("x-oneOf-response-name" , "empty" );
970+ } else if (r .isMap && r .additionalProperties != null ) {
971+ r .vendorExtensions .put ("x-oneOf-response-type" , r .returnProperty .additionalProperties .dataType );
972+ r .vendorExtensions .put ("x-oneOf-response-name" , resolveVarName (r .returnProperty .additionalProperties ));
973+ LOGGER .warn ("Mapping responses for operations with supportMultipleResponses flag (operation ID: {}) is not currently supported." , op .operationId );
974+ } else if (r .isArray && r .items != null ) {
975+ r .vendorExtensions .put ("x-oneOf-response-type" , r .returnProperty .items .dataType );
976+ r .vendorExtensions .put ("x-oneOf-response-name" , resolveVarName (r .returnProperty .items ));
977+ LOGGER .warn ("Array responses for operations with supportMultipleResponses flag (operation ID: {}) is not currently supported." , op .operationId );
978+ }
979+ else {
980+ r .vendorExtensions .put ("x-oneOf-response-type" , r .returnProperty .dataType );
981+ r .vendorExtensions .put ("x-oneOf-response-name" , resolveVarName (r .returnProperty ));
982+ }
983+ r .vendorExtensions .put ("x-oneOf-response-index" , responseIdx ++);
984+ }
985+ }
947986 }
948987
949988 if (this .aggregateModelsName != null ) {
989+ List <Map <String , String >> imports = objs .getImports ().stream ()
990+ .filter (importMap -> !importMap .get ("import" ).startsWith ("models/" ))
991+ .collect (Collectors .toList ());
992+
950993 List <Map <String , String >> aggregate_imports = Collections .singletonList (Collections
951994 .singletonMap (IMPORT , toModelImport (this .aggregateModelsName )));
952- objs .setImports (aggregate_imports );
995+ imports .addAll (aggregate_imports );
996+ objs .setImports (imports );
953997 }
954998 return objs ;
955999 }
0 commit comments