From 2e9f9d65d9224a1f3a864af6a7714e022524b700 Mon Sep 17 00:00:00 2001 From: Andrew Jorgensen Date: Tue, 28 Oct 2025 20:30:55 -0400 Subject: [PATCH] fix: handle int64 as string context: - https://github.com/grpc-ecosystem/grpc-gateway/issues/438 - https://github.com/golang/protobuf/issues/1414 - https://github.com/OpenAPITools/openapi-generator-cli Originally, this was changed so that int64 fields would be written to the openapi spec as integer types which is supported by the OpenAPI spec. However, jsonpb and other related projects have chosen to enforce that int64 fields are written as strings. This is because JavaScript represents integers as 32 bit numbers and if you pass it a value that is outside of that range it will overflow. Since we are using jsonpb to transform the protos to json, we need to make sure that the generated schema is consistent with the jsonpb behavior. --- examples/tests/mapfields/openapi.yaml | 6 ++---- .../tests/mapfields/openapi_default_response.yaml | 6 ++---- .../tests/mapfields/openapi_fq_schema_naming.yaml | 6 ++---- examples/tests/mapfields/openapi_json.yaml | 6 ++---- examples/tests/mapfields/openapi_string_enum.yaml | 6 ++---- examples/tests/noannotations/openapi.yaml | 3 +-- .../noannotations/openapi_default_response.yaml | 3 +-- .../noannotations/openapi_fq_schema_naming.yaml | 3 +-- examples/tests/noannotations/openapi_json.yaml | 3 +-- .../tests/noannotations/openapi_string_enum.yaml | 3 +-- examples/tests/openapiv3annotations/openapi.yaml | 3 +-- .../openapi_default_response.yaml | 3 +-- .../openapi_fq_schema_naming.yaml | 3 +-- .../tests/openapiv3annotations/openapi_json.yaml | 3 +-- .../openapiv3annotations/openapi_string_enum.yaml | 3 +-- examples/tests/pathparams/openapi.yaml | 9 +++------ .../tests/pathparams/openapi_default_response.yaml | 9 +++------ .../tests/pathparams/openapi_fq_schema_naming.yaml | 9 +++------ examples/tests/pathparams/openapi_json.yaml | 9 +++------ examples/tests/pathparams/openapi_string_enum.yaml | 9 +++------ examples/tests/protobuftypes/openapi.yaml | 12 ++++-------- .../protobuftypes/openapi_default_response.yaml | 12 ++++-------- .../protobuftypes/openapi_fq_schema_naming.yaml | 12 ++++-------- examples/tests/protobuftypes/openapi_json.yaml | 12 ++++-------- .../tests/protobuftypes/openapi_string_enum.yaml | 12 ++++-------- generator/reflector.go | 8 +++++--- 26 files changed, 60 insertions(+), 113 deletions(-) diff --git a/examples/tests/mapfields/openapi.yaml b/examples/tests/mapfields/openapi.yaml index 73ac59e..b689b49 100644 --- a/examples/tests/mapfields/openapi.yaml +++ b/examples/tests/mapfields/openapi.yaml @@ -42,8 +42,7 @@ components: type: object properties: id: - type: integer - format: int64 + type: string label: type: string GoogleProtobufAny: @@ -91,8 +90,7 @@ components: type: object properties: id: - type: integer - format: int64 + type: string label: type: string Status: diff --git a/examples/tests/mapfields/openapi_default_response.yaml b/examples/tests/mapfields/openapi_default_response.yaml index b09f9c2..307185f 100644 --- a/examples/tests/mapfields/openapi_default_response.yaml +++ b/examples/tests/mapfields/openapi_default_response.yaml @@ -42,8 +42,7 @@ components: type: object properties: id: - type: integer - format: int64 + type: string label: type: string GoogleProtobufAny: @@ -91,8 +90,7 @@ components: type: object properties: id: - type: integer - format: int64 + type: string label: type: string Status: diff --git a/examples/tests/mapfields/openapi_fq_schema_naming.yaml b/examples/tests/mapfields/openapi_fq_schema_naming.yaml index 5798961..a03494a 100644 --- a/examples/tests/mapfields/openapi_fq_schema_naming.yaml +++ b/examples/tests/mapfields/openapi_fq_schema_naming.yaml @@ -66,8 +66,7 @@ components: type: object properties: id: - type: integer - format: int64 + type: string label: type: string tests.mapfields.message.v1.Message: @@ -107,8 +106,7 @@ components: type: object properties: id: - type: integer - format: int64 + type: string label: type: string tags: diff --git a/examples/tests/mapfields/openapi_json.yaml b/examples/tests/mapfields/openapi_json.yaml index 773a2d7..8f899b1 100644 --- a/examples/tests/mapfields/openapi_json.yaml +++ b/examples/tests/mapfields/openapi_json.yaml @@ -42,8 +42,7 @@ components: type: object properties: id: - type: integer - format: int64 + type: string label: type: string GoogleProtobufAny: @@ -91,8 +90,7 @@ components: type: object properties: id: - type: integer - format: int64 + type: string label: type: string Status: diff --git a/examples/tests/mapfields/openapi_string_enum.yaml b/examples/tests/mapfields/openapi_string_enum.yaml index b09f9c2..307185f 100644 --- a/examples/tests/mapfields/openapi_string_enum.yaml +++ b/examples/tests/mapfields/openapi_string_enum.yaml @@ -42,8 +42,7 @@ components: type: object properties: id: - type: integer - format: int64 + type: string label: type: string GoogleProtobufAny: @@ -91,8 +90,7 @@ components: type: object properties: id: - type: integer - format: int64 + type: string label: type: string Status: diff --git a/examples/tests/noannotations/openapi.yaml b/examples/tests/noannotations/openapi.yaml index 0049103..8c0888f 100644 --- a/examples/tests/noannotations/openapi.yaml +++ b/examples/tests/noannotations/openapi.yaml @@ -50,8 +50,7 @@ components: type: object properties: id: - type: integer - format: int64 + type: string label: type: string Status: diff --git a/examples/tests/noannotations/openapi_default_response.yaml b/examples/tests/noannotations/openapi_default_response.yaml index 0049103..8c0888f 100644 --- a/examples/tests/noannotations/openapi_default_response.yaml +++ b/examples/tests/noannotations/openapi_default_response.yaml @@ -50,8 +50,7 @@ components: type: object properties: id: - type: integer - format: int64 + type: string label: type: string Status: diff --git a/examples/tests/noannotations/openapi_fq_schema_naming.yaml b/examples/tests/noannotations/openapi_fq_schema_naming.yaml index e672453..a311c13 100644 --- a/examples/tests/noannotations/openapi_fq_schema_naming.yaml +++ b/examples/tests/noannotations/openapi_fq_schema_naming.yaml @@ -66,8 +66,7 @@ components: type: object properties: id: - type: integer - format: int64 + type: string label: type: string tags: diff --git a/examples/tests/noannotations/openapi_json.yaml b/examples/tests/noannotations/openapi_json.yaml index 6f29b3c..37ced69 100644 --- a/examples/tests/noannotations/openapi_json.yaml +++ b/examples/tests/noannotations/openapi_json.yaml @@ -50,8 +50,7 @@ components: type: object properties: id: - type: integer - format: int64 + type: string label: type: string Status: diff --git a/examples/tests/noannotations/openapi_string_enum.yaml b/examples/tests/noannotations/openapi_string_enum.yaml index 0049103..8c0888f 100644 --- a/examples/tests/noannotations/openapi_string_enum.yaml +++ b/examples/tests/noannotations/openapi_string_enum.yaml @@ -50,8 +50,7 @@ components: type: object properties: id: - type: integer - format: int64 + type: string label: type: string Status: diff --git a/examples/tests/openapiv3annotations/openapi.yaml b/examples/tests/openapiv3annotations/openapi.yaml index d296478..9d5df6b 100644 --- a/examples/tests/openapiv3annotations/openapi.yaml +++ b/examples/tests/openapiv3annotations/openapi.yaml @@ -61,8 +61,7 @@ components: type: object properties: id: - type: integer - format: int64 + type: string label: title: this is an overriden field schema title maxLength: 255 diff --git a/examples/tests/openapiv3annotations/openapi_default_response.yaml b/examples/tests/openapiv3annotations/openapi_default_response.yaml index d296478..9d5df6b 100644 --- a/examples/tests/openapiv3annotations/openapi_default_response.yaml +++ b/examples/tests/openapiv3annotations/openapi_default_response.yaml @@ -61,8 +61,7 @@ components: type: object properties: id: - type: integer - format: int64 + type: string label: title: this is an overriden field schema title maxLength: 255 diff --git a/examples/tests/openapiv3annotations/openapi_fq_schema_naming.yaml b/examples/tests/openapiv3annotations/openapi_fq_schema_naming.yaml index f1ddd18..957b8d4 100644 --- a/examples/tests/openapiv3annotations/openapi_fq_schema_naming.yaml +++ b/examples/tests/openapiv3annotations/openapi_fq_schema_naming.yaml @@ -77,8 +77,7 @@ components: type: object properties: id: - type: integer - format: int64 + type: string label: title: this is an overriden field schema title maxLength: 255 diff --git a/examples/tests/openapiv3annotations/openapi_json.yaml b/examples/tests/openapiv3annotations/openapi_json.yaml index d296478..9d5df6b 100644 --- a/examples/tests/openapiv3annotations/openapi_json.yaml +++ b/examples/tests/openapiv3annotations/openapi_json.yaml @@ -61,8 +61,7 @@ components: type: object properties: id: - type: integer - format: int64 + type: string label: title: this is an overriden field schema title maxLength: 255 diff --git a/examples/tests/openapiv3annotations/openapi_string_enum.yaml b/examples/tests/openapiv3annotations/openapi_string_enum.yaml index d296478..9d5df6b 100644 --- a/examples/tests/openapiv3annotations/openapi_string_enum.yaml +++ b/examples/tests/openapiv3annotations/openapi_string_enum.yaml @@ -61,8 +61,7 @@ components: type: object properties: id: - type: integer - format: int64 + type: string label: title: this is an overriden field schema title maxLength: 255 diff --git a/examples/tests/pathparams/openapi.yaml b/examples/tests/pathparams/openapi.yaml index 17beccc..033b0a5 100644 --- a/examples/tests/pathparams/openapi.yaml +++ b/examples/tests/pathparams/openapi.yaml @@ -20,8 +20,7 @@ paths: - name: user_id in: query schema: - type: integer - format: uint64 + type: string responses: "200": description: OK @@ -74,8 +73,7 @@ paths: in: path required: true schema: - type: integer - format: uint64 + type: string - name: message_id in: path required: true @@ -110,8 +108,7 @@ components: message_id: type: string user_id: - type: integer - format: uint64 + type: string content: type: string maybe: diff --git a/examples/tests/pathparams/openapi_default_response.yaml b/examples/tests/pathparams/openapi_default_response.yaml index 8520bbd..2f5b38d 100644 --- a/examples/tests/pathparams/openapi_default_response.yaml +++ b/examples/tests/pathparams/openapi_default_response.yaml @@ -20,8 +20,7 @@ paths: - name: userId in: query schema: - type: integer - format: uint64 + type: string responses: "200": description: OK @@ -74,8 +73,7 @@ paths: in: path required: true schema: - type: integer - format: uint64 + type: string - name: messageId in: path required: true @@ -110,8 +108,7 @@ components: messageId: type: string userId: - type: integer - format: uint64 + type: string content: type: string maybe: diff --git a/examples/tests/pathparams/openapi_fq_schema_naming.yaml b/examples/tests/pathparams/openapi_fq_schema_naming.yaml index 38c1a1f..9e7e3de 100644 --- a/examples/tests/pathparams/openapi_fq_schema_naming.yaml +++ b/examples/tests/pathparams/openapi_fq_schema_naming.yaml @@ -20,8 +20,7 @@ paths: - name: userId in: query schema: - type: integer - format: uint64 + type: string responses: "200": description: OK @@ -74,8 +73,7 @@ paths: in: path required: true schema: - type: integer - format: uint64 + type: string - name: messageId in: path required: true @@ -126,8 +124,7 @@ components: messageId: type: string userId: - type: integer - format: uint64 + type: string content: type: string maybe: diff --git a/examples/tests/pathparams/openapi_json.yaml b/examples/tests/pathparams/openapi_json.yaml index 6643069..0fbc577 100644 --- a/examples/tests/pathparams/openapi_json.yaml +++ b/examples/tests/pathparams/openapi_json.yaml @@ -20,8 +20,7 @@ paths: - name: userId in: query schema: - type: integer - format: uint64 + type: string responses: "200": description: OK @@ -74,8 +73,7 @@ paths: in: path required: true schema: - type: integer - format: uint64 + type: string - name: messageId in: path required: true @@ -110,8 +108,7 @@ components: messageId: type: string userId: - type: integer - format: uint64 + type: string content: type: string maybe: diff --git a/examples/tests/pathparams/openapi_string_enum.yaml b/examples/tests/pathparams/openapi_string_enum.yaml index 8520bbd..2f5b38d 100644 --- a/examples/tests/pathparams/openapi_string_enum.yaml +++ b/examples/tests/pathparams/openapi_string_enum.yaml @@ -20,8 +20,7 @@ paths: - name: userId in: query schema: - type: integer - format: uint64 + type: string responses: "200": description: OK @@ -74,8 +73,7 @@ paths: in: path required: true schema: - type: integer - format: uint64 + type: string - name: messageId in: path required: true @@ -110,8 +108,7 @@ components: messageId: type: string userId: - type: integer - format: uint64 + type: string content: type: string maybe: diff --git a/examples/tests/protobuftypes/openapi.yaml b/examples/tests/protobuftypes/openapi.yaml index c3d4505..b0aa84e 100644 --- a/examples/tests/protobuftypes/openapi.yaml +++ b/examples/tests/protobuftypes/openapi.yaml @@ -124,13 +124,11 @@ paths: - name: int64_value_type in: query schema: - type: integer - format: int64 + type: string - name: uint64_value_type in: query schema: - type: integer - format: uint64 + type: string - name: float_value_type in: query schema: @@ -291,13 +289,11 @@ paths: - name: int64_value_type in: query schema: - type: integer - format: int64 + type: string - name: uint64_value_type in: query schema: - type: integer - format: uint64 + type: string - name: float_value_type in: query schema: diff --git a/examples/tests/protobuftypes/openapi_default_response.yaml b/examples/tests/protobuftypes/openapi_default_response.yaml index f3edb4a..d99c914 100644 --- a/examples/tests/protobuftypes/openapi_default_response.yaml +++ b/examples/tests/protobuftypes/openapi_default_response.yaml @@ -124,13 +124,11 @@ paths: - name: int64ValueType in: query schema: - type: integer - format: int64 + type: string - name: uint64ValueType in: query schema: - type: integer - format: uint64 + type: string - name: floatValueType in: query schema: @@ -291,13 +289,11 @@ paths: - name: int64ValueType in: query schema: - type: integer - format: int64 + type: string - name: uint64ValueType in: query schema: - type: integer - format: uint64 + type: string - name: floatValueType in: query schema: diff --git a/examples/tests/protobuftypes/openapi_fq_schema_naming.yaml b/examples/tests/protobuftypes/openapi_fq_schema_naming.yaml index ecc81dc..9843987 100644 --- a/examples/tests/protobuftypes/openapi_fq_schema_naming.yaml +++ b/examples/tests/protobuftypes/openapi_fq_schema_naming.yaml @@ -124,13 +124,11 @@ paths: - name: int64ValueType in: query schema: - type: integer - format: int64 + type: string - name: uint64ValueType in: query schema: - type: integer - format: uint64 + type: string - name: floatValueType in: query schema: @@ -291,13 +289,11 @@ paths: - name: int64ValueType in: query schema: - type: integer - format: int64 + type: string - name: uint64ValueType in: query schema: - type: integer - format: uint64 + type: string - name: floatValueType in: query schema: diff --git a/examples/tests/protobuftypes/openapi_json.yaml b/examples/tests/protobuftypes/openapi_json.yaml index c699355..dfb954c 100644 --- a/examples/tests/protobuftypes/openapi_json.yaml +++ b/examples/tests/protobuftypes/openapi_json.yaml @@ -124,13 +124,11 @@ paths: - name: int64ValueType in: query schema: - type: integer - format: int64 + type: string - name: uint64ValueType in: query schema: - type: integer - format: uint64 + type: string - name: floatValueType in: query schema: @@ -291,13 +289,11 @@ paths: - name: int64ValueType in: query schema: - type: integer - format: int64 + type: string - name: uint64ValueType in: query schema: - type: integer - format: uint64 + type: string - name: floatValueType in: query schema: diff --git a/examples/tests/protobuftypes/openapi_string_enum.yaml b/examples/tests/protobuftypes/openapi_string_enum.yaml index f3edb4a..d99c914 100644 --- a/examples/tests/protobuftypes/openapi_string_enum.yaml +++ b/examples/tests/protobuftypes/openapi_string_enum.yaml @@ -124,13 +124,11 @@ paths: - name: int64ValueType in: query schema: - type: integer - format: int64 + type: string - name: uint64ValueType in: query schema: - type: integer - format: uint64 + type: string - name: floatValueType in: query schema: @@ -291,13 +289,11 @@ paths: - name: int64ValueType in: query schema: - type: integer - format: int64 + type: string - name: uint64ValueType in: query schema: - type: integer - format: uint64 + type: string - name: floatValueType in: query schema: diff --git a/generator/reflector.go b/generator/reflector.go index f638ca8..a1fe057 100644 --- a/generator/reflector.go +++ b/generator/reflector.go @@ -233,11 +233,13 @@ func (r *OpenAPIv3Reflector) schemaOrReferenceForField(field protoreflect.FieldD kindSchema = wk.NewStringSchema() case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Uint32Kind, - protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Uint64Kind, - protoreflect.Sfixed32Kind, protoreflect.Fixed32Kind, protoreflect.Sfixed64Kind, - protoreflect.Fixed64Kind: + protoreflect.Sfixed32Kind, protoreflect.Fixed32Kind: kindSchema = wk.NewIntegerSchema(kind.String()) + case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Uint64Kind, + protoreflect.Sfixed64Kind, protoreflect.Fixed64Kind: + kindSchema = wk.NewStringSchema() + case protoreflect.EnumKind: kindSchema = wk.NewEnumSchema(*&r.conf.EnumType, field)