diff --git a/cmd/protoc-gen-openapi/README.md b/cmd/protoc-gen-openapi/README.md index 80efa37b..20b16922 100644 --- a/cmd/protoc-gen-openapi/README.md +++ b/cmd/protoc-gen-openapi/README.md @@ -63,3 +63,17 @@ refers to additional .proto files in the same directory as schema: $ref: '#/components/schemas/google.rpc.Status' ``` +9. `int64_as_string`: use string for 64-bit integer serialization. + Using "false" generates a scheme incompatible with official proto JSON serialization, but maybe more accurately represent the types used in some cases. + - **default**: true + - `false`: output all 64-bit integer fields as type `integer` and the specific type under format + ```yaml + schema: + type: integer + format: int64 + ``` + - `true`: setting type to `string` + ```yaml + schema: + type: string + ``` diff --git a/cmd/protoc-gen-openapi/generator/generator.go b/cmd/protoc-gen-openapi/generator/generator.go index 1c79f970..5211a1fb 100644 --- a/cmd/protoc-gen-openapi/generator/generator.go +++ b/cmd/protoc-gen-openapi/generator/generator.go @@ -44,6 +44,7 @@ type Configuration struct { CircularDepth *int DefaultResponse *bool OutputMode *string + Int64AsString *bool } const ( diff --git a/cmd/protoc-gen-openapi/generator/reflector.go b/cmd/protoc-gen-openapi/generator/reflector.go index 31a0f930..b210c7d9 100644 --- a/cmd/protoc-gen-openapi/generator/reflector.go +++ b/cmd/protoc-gen-openapi/generator/reflector.go @@ -163,7 +163,14 @@ func (r *OpenAPIv3Reflector) schemaOrReferenceForMessage(message protoreflect.Me case ".google.protobuf.Int32Value", ".google.protobuf.UInt32Value": return wk.NewIntegerSchema(getValueKind(message)) - case ".google.protobuf.StringValue", ".google.protobuf.Int64Value", ".google.protobuf.UInt64Value": + case ".google.protobuf.Int64Value", ".google.protobuf.UInt64Value": + if *r.conf.Int64AsString { + return wk.NewStringSchema() + } else { + return wk.NewIntegerSchema(getValueKind(message)) + } + + case ".google.protobuf.StringValue": return wk.NewStringSchema() case ".google.protobuf.FloatValue", ".google.protobuf.DoubleValue": @@ -213,7 +220,11 @@ func (r *OpenAPIv3Reflector) schemaOrReferenceForField(field protoreflect.FieldD case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Uint64Kind, protoreflect.Sfixed64Kind, protoreflect.Fixed64Kind: - kindSchema = wk.NewStringSchema() + if *r.conf.Int64AsString { + kindSchema = wk.NewStringSchema() + } else { + kindSchema = wk.NewIntegerSchema(kind.String()) + } case protoreflect.EnumKind: kindSchema = wk.NewEnumSchema(*&r.conf.EnumType, field) diff --git a/cmd/protoc-gen-openapi/main.go b/cmd/protoc-gen-openapi/main.go index 75405aed..c553b5d5 100644 --- a/cmd/protoc-gen-openapi/main.go +++ b/cmd/protoc-gen-openapi/main.go @@ -38,6 +38,7 @@ func main() { 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.`), OutputMode: flags.String("output_mode", "merged", `output generation mode. By default, a single openapi.yaml is generated at the out folder. Use "source_relative' to generate a separate '[inputfile].openapi.yaml' next to each '[inputfile].proto'.`), + Int64AsString: flags.Bool("int64_as_string", true, `serialize 64-bit integer types as string. If false, will serialize as integer which is incompatible with the official proto JSON serialization.`), } opts := protogen.Options{