diff --git a/cmd/protoc-gen-openapi/generator/generator.go b/cmd/protoc-gen-openapi/generator/generator.go index e548ab21..744e295a 100644 --- a/cmd/protoc-gen-openapi/generator/generator.go +++ b/cmd/protoc-gen-openapi/generator/generator.go @@ -35,15 +35,16 @@ import ( ) type Configuration struct { - Version *string - Title *string - Description *string - Naming *string - FQSchemaNaming *bool - EnumType *string - CircularDepth *int - DefaultResponse *bool - OutputMode *string + Version *string + Title *string + Description *string + Naming *string + FQSchemaNaming *bool + NoRecursiveSchemaNaming *bool + EnumType *string + CircularDepth *int + DefaultResponse *bool + OutputMode *string } const ( diff --git a/cmd/protoc-gen-openapi/generator/reflector.go b/cmd/protoc-gen-openapi/generator/reflector.go index 31a0f930..c0fdc6a2 100644 --- a/cmd/protoc-gen-openapi/generator/reflector.go +++ b/cmd/protoc-gen-openapi/generator/reflector.go @@ -46,14 +46,23 @@ func NewOpenAPIv3Reflector(conf Configuration) *OpenAPIv3Reflector { } func (r *OpenAPIv3Reflector) getMessageName(message protoreflect.MessageDescriptor) string { - prefix := "" + name := string(message.Name()) parent := message.Parent() - - if _, ok := parent.(protoreflect.MessageDescriptor); ok { - prefix = string(parent.Name()) + "_" + prefix + if *r.conf.NoRecursiveSchemaNaming { + if msg, ok := parent.(protoreflect.MessageDescriptor); ok { + name = string(msg.Name()) + "_" + name + } + return name } - - return prefix + string(message.Name()) + for { + msg, ok := parent.(protoreflect.MessageDescriptor) + if !ok { + break + } + name = string(msg.Name()) + "_" + name + parent = msg.Parent() + } + return name } func (r *OpenAPIv3Reflector) formatMessageName(message protoreflect.MessageDescriptor) string { diff --git a/cmd/protoc-gen-openapi/main.go b/cmd/protoc-gen-openapi/main.go index 75405aed..a1cd2275 100644 --- a/cmd/protoc-gen-openapi/main.go +++ b/cmd/protoc-gen-openapi/main.go @@ -33,7 +33,8 @@ func main() { Title: flags.String("title", "", "name of the API"), Description: flags.String("description", "", "description of the API"), Naming: flags.String("naming", "json", `naming convention. Use "proto" for passing names directly from the proto files`), - FQSchemaNaming: flags.Bool("fq_schema_naming", false, `schema naming convention. If "true", generates fully-qualified schema names by prefixing them with the proto message package name`), + FQSchemaNaming: flags.Bool("fq_schema_naming", false, `schema naming convention. If "true", generates fully-qualified schema names by prefixing them with the proto message package name`), + NoRecursiveSchemaNaming: flags.Bool("no_recursive_schema_naming", false, `if "true", only include the immediate parent message name in schema names instead of the full message hierarchy. This restores the legacy naming behavior where e.g. A.B.C.Request becomes C_Request instead of A_B_C_Request`), EnumType: flags.String("enum_type", "integer", `type for enum serialization. Use "string" for string-based serialization`), CircularDepth: flags.Int("depth", 2, "depth of recursion for circular messages"), DefaultResponse: flags.Bool("default_response", true, `add default response. If "true", automatically adds a default response to operations which use the google.rpc.Status message. Useful if you use envoy or grpc-gateway to transcode as they use this type for their default error responses.`),