Add options to aggregate protos to one file (#20962)

This commit is contained in:
lucy66hw 2025-03-25 07:35:48 -07:00 committed by GitHub
parent 16552755bf
commit c8cfa16a48
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
40 changed files with 231 additions and 322 deletions

View File

@ -8,6 +8,7 @@ additionalProperties:
numberedFieldNumberList: true
startEnumsWithUnspecified: true
wrapComplexType: false
aggregateModelsName: data
typeMappings:
object: "google.protobuf.Struct"
importMappings:

View File

@ -19,6 +19,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
| Option | Description | Values | Default |
| ------ | ----------- | ------ | ------- |
|addJsonNameAnnotation|Append "json_name" annotation to message field when the specification name differs from the protobuf field name| |false|
|aggregateModelsName|Aggregated model filename. If set, all generated models will be combined into this single file.| |null|
|numberedFieldNumberList|Field numbers in order.| |false|
|startEnumsWithUnspecified|Introduces "UNSPECIFIED" as the first element of enumerations.| |false|
|wrapComplexType|Generate Additional message for complex type| |true|

View File

@ -42,6 +42,8 @@ import java.io.File;
import java.util.*;
import java.util.Map.Entry;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import com.google.common.base.CaseFormat;
import static org.openapitools.codegen.utils.StringUtils.*;
@ -64,10 +66,14 @@ public class ProtobufSchemaCodegen extends DefaultCodegen implements CodegenConf
public static final String WRAP_COMPLEX_TYPE = "wrapComplexType";
public static final String AGGREGATE_MODELS_NAME = "aggregateModelsName";
private final Logger LOGGER = LoggerFactory.getLogger(ProtobufSchemaCodegen.class);
@Setter protected String packageName = "openapitools";
@Setter protected String aggregateModelsName = null;
private boolean numberedFieldNumberList = false;
private boolean startEnumsWithUnspecified = false;
@ -186,6 +192,7 @@ public class ProtobufSchemaCodegen extends DefaultCodegen implements CodegenConf
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);
addOption(AGGREGATE_MODELS_NAME, "Aggregated model filename. If set, all generated models will be combined into this single file.", null);
}
@Override
@ -228,6 +235,10 @@ public class ProtobufSchemaCodegen extends DefaultCodegen implements CodegenConf
this.wrapComplexType = convertPropertyToBooleanAndWriteBack(WRAP_COMPLEX_TYPE);
}
if (additionalProperties.containsKey(AGGREGATE_MODELS_NAME)) {
this.setAggregateModelsName((String) additionalProperties.get(AGGREGATE_MODELS_NAME));
}
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
}
@ -650,7 +661,35 @@ public class ProtobufSchemaCodegen extends DefaultCodegen implements CodegenConf
.forEach(importFromList -> this.addImport(objs, parentCM, importFromList));
}
}
return objs;
return aggregateModelsName == null ? objs : aggregateModels(objs);
}
/**
* Aggregates all individual model definitions into a single entry.
*
* @param objs the original map of model names to their respective entries
* @return a new {@link Map} containing a single entry keyed by {@code aggregateModelsName} with
* combined models and imports from all provided entries
*/
public Map<String, ModelsMap> aggregateModels(Map<String, ModelsMap> objs) {
Map<String, ModelsMap> objects = new HashMap<>();
ModelsMap aggregateObj = objs.values().stream()
.findFirst()
.orElse(new ModelsMap());
List<ModelMap> models = objs.values().stream()
.flatMap(modelsMap -> modelsMap.getModels().stream())
.collect(Collectors.toList());
Set<Map<String, String>> imports = objs.values().stream()
.flatMap(modelsMap -> modelsMap.getImports().stream())
.filter(importMap -> !importMap.get("import").startsWith("models/"))
.collect(Collectors.toSet());
aggregateObj.setModels(models);
aggregateObj.setImports(new ArrayList<>(imports));
objects.put(this.aggregateModelsName, aggregateObj);
return objects;
}
public void addImport(Map<String, ModelsMap> objs, CodegenModel cm, String importValue) {
@ -907,6 +946,11 @@ public class ProtobufSchemaCodegen extends DefaultCodegen implements CodegenConf
}
}
if (this.aggregateModelsName != null) {
List<Map<String, String>> aggregate_imports = Collections.singletonList(Collections
.singletonMap(IMPORT, toModelImport(this.aggregateModelsName)));
objs.setImports(aggregate_imports);
}
return objs;
}

View File

@ -50,4 +50,5 @@ import public "{{{.}}}.proto";
}
{{/isEnum}}
{{/model}}
{{/models}}

View File

@ -20,3 +20,4 @@ message Cat {
int32 age = 2;
}

View File

@ -23,3 +23,4 @@ message Category {
map<string, StringArray> document = 3;
}

View File

@ -28,3 +28,4 @@ message Dog {
Breed breed = 2;
}

View File

@ -21,3 +21,4 @@ message Pet {
Category category = 2;
}

View File

@ -18,3 +18,4 @@ message StringArray {
repeated string string_array = 1;
}

View File

@ -18,3 +18,4 @@ message StringMap {
map<string, string> string_map = 1;
}

View File

@ -21,3 +21,4 @@ message Tag {
TagName name = 2;
}

View File

@ -23,3 +23,4 @@ message TagName {
StringMap map = 3;
}
}

View File

@ -1,15 +1,5 @@
README.md
models/api_response.proto
models/cat.proto
models/category.proto
models/dog.proto
models/order.proto
models/other_test.proto
models/pet.proto
models/pets_get_request.proto
models/pets_post_request.proto
models/tag.proto
models/user.proto
models/data.proto
services/default_service.proto
services/pet_service.proto
services/store_service.proto

View File

@ -1,24 +0,0 @@
/*
OpenAPI Petstore
This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator: https://openapi-generator.tech
*/
syntax = "proto3";
package petstore;
message ApiResponse {
int32 code = 1;
string type = 2;
string message = 3;
}

View File

@ -1,22 +0,0 @@
/*
OpenAPI Petstore
This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator: https://openapi-generator.tech
*/
syntax = "proto3";
package petstore;
message Cat {
bool hunts = 1;
int32 age = 2;
}

View File

@ -1,22 +0,0 @@
/*
OpenAPI Petstore
This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator: https://openapi-generator.tech
*/
syntax = "proto3";
package petstore;
message Category {
int64 id = 1;
string name = 2;
}

View File

@ -0,0 +1,159 @@
/*
OpenAPI Petstore
This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator: https://openapi-generator.tech
*/
syntax = "proto3";
package petstore;
import public "google/protobuf/struct.proto";
message ApiResponse {
int32 code = 1;
string type = 2;
string message = 3;
}
message Cat {
bool hunts = 1;
int32 age = 2;
}
message Category {
int64 id = 1;
string name = 2;
}
message Dog {
bool bark = 1;
enum Breed {
BREED_UNSPECIFIED = 0;
BREED_DINGO = 1;
BREED_HUSKY = 2;
BREED_RETRIEVER = 3;
BREED_SHEPHERD = 4;
}
Breed breed = 2;
}
message Order {
int64 id = 1;
int64 pet_id = 2 [json_name="petId"];
int32 quantity = 3;
string ship_date = 4 [json_name="shipDate"];
// Order Status
enum Status {
STATUS_UNSPECIFIED = 0;
STATUS_PLACED = 1;
STATUS_APPROVED = 2;
STATUS_DELIVERED = 3;
}
Status status = 5;
bool complete = 6;
google.protobuf.Struct meta = 7;
}
message OtherTest {
repeated string set_test = 1;
}
message Pet {
int64 id = 1;
Category category = 2;
string name = 3;
repeated string photo_urls = 4 [json_name="photoUrls"];
repeated Tag tags = 5;
// pet status in the store
enum Status {
STATUS_UNSPECIFIED = 0;
STATUS_AVAILABLE = 1;
STATUS_PENDING = 2;
STATUS_SOLD = 3;
}
Status status = 6;
}
message PetsGetRequest {
oneof pets_get_request {
Cat cat = 1;
Dog dog = 2;
}
}
message PetsPostRequest {
Cat cat = 1;
Dog dog = 2;
}
message Tag {
int64 id = 1;
string name = 2;
}
message User {
int64 id = 1;
string username = 2;
string first_name = 3 [json_name="firstName"];
string last_name = 4 [json_name="lastName"];
string email = 5;
string password = 6;
string phone = 7;
// User Status
int32 user_status = 8 [json_name="userStatus"];
}

View File

@ -1,30 +0,0 @@
/*
OpenAPI Petstore
This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator: https://openapi-generator.tech
*/
syntax = "proto3";
package petstore;
message Dog {
bool bark = 1;
enum Breed {
BREED_UNSPECIFIED = 0;
BREED_DINGO = 1;
BREED_HUSKY = 2;
BREED_RETRIEVER = 3;
BREED_SHEPHERD = 4;
}
Breed breed = 2;
}

View File

@ -1,41 +0,0 @@
/*
OpenAPI Petstore
This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator: https://openapi-generator.tech
*/
syntax = "proto3";
package petstore;
import public "google/protobuf/struct.proto";
message Order {
int64 id = 1;
int64 pet_id = 2 [json_name="petId"];
int32 quantity = 3;
string ship_date = 4 [json_name="shipDate"];
// Order Status
enum Status {
STATUS_UNSPECIFIED = 0;
STATUS_PLACED = 1;
STATUS_APPROVED = 2;
STATUS_DELIVERED = 3;
}
Status status = 5;
bool complete = 6;
google.protobuf.Struct meta = 7;
}

View File

@ -1,20 +0,0 @@
/*
OpenAPI Petstore
This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator: https://openapi-generator.tech
*/
syntax = "proto3";
package petstore;
message OtherTest {
repeated string set_test = 1;
}

View File

@ -1,40 +0,0 @@
/*
OpenAPI Petstore
This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator: https://openapi-generator.tech
*/
syntax = "proto3";
package petstore;
import public "models/category.proto";
import public "models/tag.proto";
message Pet {
int64 id = 1;
Category category = 2;
string name = 3;
repeated string photo_urls = 4 [json_name="photoUrls"];
repeated Tag tags = 5;
// pet status in the store
enum Status {
STATUS_UNSPECIFIED = 0;
STATUS_AVAILABLE = 1;
STATUS_PENDING = 2;
STATUS_SOLD = 3;
}
Status status = 6;
}

View File

@ -1,24 +0,0 @@
/*
OpenAPI Petstore
This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator: https://openapi-generator.tech
*/
syntax = "proto3";
package petstore;
import public "models/cat.proto";
import public "models/dog.proto";
message PetsGetRequest {
oneof pets_get_request {
Cat cat = 1;
Dog dog = 2;
}
}

View File

@ -1,24 +0,0 @@
/*
OpenAPI Petstore
This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator: https://openapi-generator.tech
*/
syntax = "proto3";
package petstore;
import public "models/cat.proto";
import public "models/dog.proto";
message PetsPostRequest {
Cat cat = 1;
Dog dog = 2;
}

View File

@ -1,22 +0,0 @@
/*
OpenAPI Petstore
This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator: https://openapi-generator.tech
*/
syntax = "proto3";
package petstore;
message Tag {
int64 id = 1;
string name = 2;
}

View File

@ -1,35 +0,0 @@
/*
OpenAPI Petstore
This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator: https://openapi-generator.tech
*/
syntax = "proto3";
package petstore;
message User {
int64 id = 1;
string username = 2;
string first_name = 3 [json_name="firstName"];
string last_name = 4 [json_name="lastName"];
string email = 5;
string password = 6;
string phone = 7;
// User Status
int32 user_status = 8 [json_name="userStatus"];
}

View File

@ -13,8 +13,7 @@ syntax = "proto3";
package petstore.services.defaultservice;
import "google/protobuf/empty.proto";
import public "models/pets_get_request.proto";
import public "models/pets_post_request.proto";
import public "models/data.proto";
service DefaultService {
rpc PetsGet (PetsGetRequest) returns (google.protobuf.Empty);

View File

@ -13,8 +13,7 @@ syntax = "proto3";
package petstore.services.petservice;
import "google/protobuf/empty.proto";
import public "models/api_response.proto";
import public "models/pet.proto";
import public "models/data.proto";
service PetService {
rpc AddPet (AddPetRequest) returns (Pet);

View File

@ -13,7 +13,7 @@ syntax = "proto3";
package petstore.services.storeservice;
import "google/protobuf/empty.proto";
import public "models/order.proto";
import public "models/data.proto";
service StoreService {
rpc DeleteOrder (DeleteOrderRequest) returns (google.protobuf.Empty);

View File

@ -13,7 +13,7 @@ syntax = "proto3";
package petstore.services.userservice;
import "google/protobuf/empty.proto";
import public "models/user.proto";
import public "models/data.proto";
service UserService {
rpc CreateUser (CreateUserRequest) returns (google.protobuf.Empty);

View File

@ -22,3 +22,4 @@ message ApiResponse {
string message = 418054152;
}

View File

@ -20,3 +20,4 @@ message Cat {
int32 age = 96511;
}

View File

@ -20,3 +20,4 @@ message Category {
string name = 3373707;
}

View File

@ -27,3 +27,4 @@ message Dog {
Breed breed = 94001524;
}

View File

@ -38,3 +38,4 @@ message Order {
google.protobuf.Struct meta = 3347973;
}

View File

@ -18,3 +18,4 @@ message OtherTest {
repeated string set_test = 341814865;
}

View File

@ -37,3 +37,4 @@ message Pet {
Status status = 355610639;
}

View File

@ -22,3 +22,4 @@ message PetsGetRequest {
Dog dog = 99644;
}
}

View File

@ -22,3 +22,4 @@ message PetsPostRequest {
Dog dog = 99644;
}

View File

@ -20,3 +20,4 @@ message Tag {
string name = 3373707;
}

View File

@ -33,3 +33,4 @@ message User {
int32 user_status = 150530330;
}