Skip to content

Commit 4717692

Browse files
gen-grpc-gateway, gen-openapiv2: add support for proto3 optional
1 parent a996d7a commit 4717692

File tree

14 files changed

+121
-1
lines changed

14 files changed

+121
-1
lines changed

examples/internal/clients/abe/api/swagger.yaml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,12 @@ paths:
403403
type: "string"
404404
x-exportParamName: "OutputOnlyStringViaFieldBehaviorAnnotation"
405405
x-optionalDataType: "String"
406+
- name: "optionalString"
407+
in: "query"
408+
required: false
409+
type: "string"
410+
x-exportParamName: "OptionalString"
411+
x-optionalDataType: "String"
406412
responses:
407413
200:
408414
description: "A successful response."
@@ -714,6 +720,12 @@ paths:
714720
type: "string"
715721
x-exportParamName: "OutputOnlyStringViaFieldBehaviorAnnotation"
716722
x-optionalDataType: "String"
723+
- name: "optionalString"
724+
in: "query"
725+
required: false
726+
type: "string"
727+
x-exportParamName: "OptionalString"
728+
x-optionalDataType: "String"
717729
responses:
718730
200:
719731
description: "A successful response."
@@ -1012,6 +1024,12 @@ paths:
10121024
type: "string"
10131025
x-exportParamName: "OutputOnlyStringViaFieldBehaviorAnnotation"
10141026
x-optionalDataType: "String"
1027+
- name: "optionalString"
1028+
in: "query"
1029+
required: false
1030+
type: "string"
1031+
x-exportParamName: "OptionalString"
1032+
x-optionalDataType: "String"
10151033
responses:
10161034
200:
10171035
description: "A successful response."
@@ -1330,6 +1348,12 @@ paths:
13301348
type: "string"
13311349
x-exportParamName: "OutputOnlyStringViaFieldBehaviorAnnotation"
13321350
x-optionalDataType: "String"
1351+
- name: "optionalString"
1352+
in: "query"
1353+
required: false
1354+
type: "string"
1355+
x-exportParamName: "OptionalString"
1356+
x-optionalDataType: "String"
13331357
responses:
13341358
200:
13351359
description: "A successful response."
@@ -2698,6 +2722,8 @@ definitions:
26982722
type: "string"
26992723
title: "mark a field as readonly in Open API definition"
27002724
readOnly: true
2725+
optionalString:
2726+
type: "string"
27012727
externalDocs:
27022728
description: "Find out more about ABitOfEverything"
27032729
url: "https://github.com/grpc-ecosystem/grpc-gateway"

examples/internal/clients/abe/api_a_bit_of_everything_service.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ ABitOfEverythingServiceApiService
222222
* @param "NestedAnnotationOk" (optional.String) - DeepEnum description. - FALSE: FALSE is false. - TRUE: TRUE is true.
223223
* @param "Int64OverrideType" (optional.Int64) -
224224
* @param "OutputOnlyStringViaFieldBehaviorAnnotation" (optional.String) - mark a field as readonly in Open API definition.
225+
* @param "OptionalString" (optional.String) -
225226
226227
@return ExamplepbABitOfEverything
227228
*/
@@ -259,6 +260,7 @@ type ABitOfEverythingServiceCheckGetQueryParamsOpts struct {
259260
NestedAnnotationOk optional.String
260261
Int64OverrideType optional.Int64
261262
OutputOnlyStringViaFieldBehaviorAnnotation optional.String
263+
OptionalString optional.String
262264
}
263265

264266
func (a *ABitOfEverythingServiceApiService) ABitOfEverythingServiceCheckGetQueryParams(ctx context.Context, singleNestedName string, floatValue float32, requiredStringViaFieldBehaviorAnnotation string, localVarOptionals *ABitOfEverythingServiceCheckGetQueryParamsOpts) (ExamplepbABitOfEverything, *http.Response, error) {
@@ -376,6 +378,9 @@ func (a *ABitOfEverythingServiceApiService) ABitOfEverythingServiceCheckGetQuery
376378
if localVarOptionals != nil && localVarOptionals.OutputOnlyStringViaFieldBehaviorAnnotation.IsSet() {
377379
localVarQueryParams.Add("outputOnlyStringViaFieldBehaviorAnnotation", parameterToString(localVarOptionals.OutputOnlyStringViaFieldBehaviorAnnotation.Value(), ""))
378380
}
381+
if localVarOptionals != nil && localVarOptionals.OptionalString.IsSet() {
382+
localVarQueryParams.Add("optionalString", parameterToString(localVarOptionals.OptionalString.Value(), ""))
383+
}
379384
// to determine the Content-Type header
380385
localVarHttpContentTypes := []string{"application/json", "application/x-foo-mime"}
381386

@@ -547,6 +552,7 @@ ABitOfEverythingServiceApiService
547552
* @param "NestedAnnotationAmount" (optional.Int64) -
548553
* @param "Int64OverrideType" (optional.Int64) -
549554
* @param "OutputOnlyStringViaFieldBehaviorAnnotation" (optional.String) - mark a field as readonly in Open API definition.
555+
* @param "OptionalString" (optional.String) -
550556
551557
@return ExamplepbABitOfEverything
552558
*/
@@ -584,6 +590,7 @@ type ABitOfEverythingServiceCheckNestedEnumGetQueryParamsOpts struct {
584590
NestedAnnotationAmount optional.Int64
585591
Int64OverrideType optional.Int64
586592
OutputOnlyStringViaFieldBehaviorAnnotation optional.String
593+
OptionalString optional.String
587594
}
588595

589596
func (a *ABitOfEverythingServiceApiService) ABitOfEverythingServiceCheckNestedEnumGetQueryParams(ctx context.Context, singleNestedOk string, floatValue float32, requiredStringViaFieldBehaviorAnnotation string, localVarOptionals *ABitOfEverythingServiceCheckNestedEnumGetQueryParamsOpts) (ExamplepbABitOfEverything, *http.Response, error) {
@@ -701,6 +708,9 @@ func (a *ABitOfEverythingServiceApiService) ABitOfEverythingServiceCheckNestedEn
701708
if localVarOptionals != nil && localVarOptionals.OutputOnlyStringViaFieldBehaviorAnnotation.IsSet() {
702709
localVarQueryParams.Add("outputOnlyStringViaFieldBehaviorAnnotation", parameterToString(localVarOptionals.OutputOnlyStringViaFieldBehaviorAnnotation.Value(), ""))
703710
}
711+
if localVarOptionals != nil && localVarOptionals.OptionalString.IsSet() {
712+
localVarQueryParams.Add("optionalString", parameterToString(localVarOptionals.OptionalString.Value(), ""))
713+
}
704714
// to determine the Content-Type header
705715
localVarHttpContentTypes := []string{"application/json", "application/x-foo-mime"}
706716

@@ -871,6 +881,7 @@ ABitOfEverythingServiceApiService
871881
* @param "NestedAnnotationOk" (optional.String) - DeepEnum description. - FALSE: FALSE is false. - TRUE: TRUE is true.
872882
* @param "Int64OverrideType" (optional.Int64) -
873883
* @param "OutputOnlyStringViaFieldBehaviorAnnotation" (optional.String) - mark a field as readonly in Open API definition.
884+
* @param "OptionalString" (optional.String) -
874885
875886
@return ExamplepbABitOfEverything
876887
*/
@@ -906,6 +917,7 @@ type ABitOfEverythingServiceCheckPostQueryParamsOpts struct {
906917
NestedAnnotationOk optional.String
907918
Int64OverrideType optional.Int64
908919
OutputOnlyStringViaFieldBehaviorAnnotation optional.String
920+
OptionalString optional.String
909921
}
910922

911923
func (a *ABitOfEverythingServiceApiService) ABitOfEverythingServiceCheckPostQueryParams(ctx context.Context, stringValue string, body ABitOfEverythingNested, floatValue float32, requiredStringViaFieldBehaviorAnnotation string, localVarOptionals *ABitOfEverythingServiceCheckPostQueryParamsOpts) (ExamplepbABitOfEverything, *http.Response, error) {
@@ -1017,6 +1029,9 @@ func (a *ABitOfEverythingServiceApiService) ABitOfEverythingServiceCheckPostQuer
10171029
if localVarOptionals != nil && localVarOptionals.OutputOnlyStringViaFieldBehaviorAnnotation.IsSet() {
10181030
localVarQueryParams.Add("outputOnlyStringViaFieldBehaviorAnnotation", parameterToString(localVarOptionals.OutputOnlyStringViaFieldBehaviorAnnotation.Value(), ""))
10191031
}
1032+
if localVarOptionals != nil && localVarOptionals.OptionalString.IsSet() {
1033+
localVarQueryParams.Add("optionalString", parameterToString(localVarOptionals.OptionalString.Value(), ""))
1034+
}
10201035
// to determine the Content-Type header
10211036
localVarHttpContentTypes := []string{"application/json", "application/x-foo-mime"}
10221037

@@ -2492,6 +2507,7 @@ ABitOfEverythingServiceApiService
24922507
* @param "NestedAnnotationOk" (optional.String) - DeepEnum description. - FALSE: FALSE is false. - TRUE: TRUE is true.
24932508
* @param "Int64OverrideType" (optional.Int64) -
24942509
* @param "OutputOnlyStringViaFieldBehaviorAnnotation" (optional.String) - mark a field as readonly in Open API definition.
2510+
* @param "OptionalString" (optional.String) -
24952511
24962512
@return interface{}
24972513
*/
@@ -2530,6 +2546,7 @@ type ABitOfEverythingServiceGetQueryOpts struct {
25302546
NestedAnnotationOk optional.String
25312547
Int64OverrideType optional.Int64
25322548
OutputOnlyStringViaFieldBehaviorAnnotation optional.String
2549+
OptionalString optional.String
25332550
}
25342551

25352552
func (a *ABitOfEverythingServiceApiService) ABitOfEverythingServiceGetQuery(ctx context.Context, uuid string, floatValue float32, requiredStringViaFieldBehaviorAnnotation string, localVarOptionals *ABitOfEverythingServiceGetQueryOpts) (interface{}, *http.Response, error) {
@@ -2650,6 +2667,9 @@ func (a *ABitOfEverythingServiceApiService) ABitOfEverythingServiceGetQuery(ctx
26502667
if localVarOptionals != nil && localVarOptionals.OutputOnlyStringViaFieldBehaviorAnnotation.IsSet() {
26512668
localVarQueryParams.Add("outputOnlyStringViaFieldBehaviorAnnotation", parameterToString(localVarOptionals.OutputOnlyStringViaFieldBehaviorAnnotation.Value(), ""))
26522669
}
2670+
if localVarOptionals != nil && localVarOptionals.OptionalString.IsSet() {
2671+
localVarQueryParams.Add("optionalString", parameterToString(localVarOptionals.OptionalString.Value(), ""))
2672+
}
26532673
// to determine the Content-Type header
26542674
localVarHttpContentTypes := []string{"application/json", "application/x-foo-mime"}
26552675

examples/internal/clients/abe/model_examplepb_a_bit_of_everything.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,5 @@ type ExamplepbABitOfEverything struct {
6060
Int64OverrideType int64 `json:"int64OverrideType,omitempty"`
6161
RequiredStringViaFieldBehaviorAnnotation string `json:"requiredStringViaFieldBehaviorAnnotation"`
6262
OutputOnlyStringViaFieldBehaviorAnnotation string `json:"outputOnlyStringViaFieldBehaviorAnnotation,omitempty"`
63+
OptionalString string `json:"optionalString,omitempty"`
6364
}

examples/internal/proto/examplepb/a_bit_of_everything.proto

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,8 @@ message ABitOfEverything {
325325

326326
// mark a field as readonly in Open API definition
327327
string output_only_string_via_field_behavior_annotation = 39 [(google.api.field_behavior) = OUTPUT_ONLY];
328+
329+
optional string optional_string = 40;
328330
}
329331

330332
// ABitOfEverythingRepeated is used to validate repeated path parameter functionality

examples/internal/proto/examplepb/a_bit_of_everything.swagger.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,12 @@
495495
"in": "query",
496496
"required": false,
497497
"type": "string"
498+
},
499+
{
500+
"name": "optionalString",
501+
"in": "query",
502+
"required": false,
503+
"type": "string"
498504
}
499505
],
500506
"tags": [
@@ -835,6 +841,12 @@
835841
"in": "query",
836842
"required": false,
837843
"type": "string"
844+
},
845+
{
846+
"name": "optionalString",
847+
"in": "query",
848+
"required": false,
849+
"type": "string"
838850
}
839851
],
840852
"tags": [
@@ -1164,6 +1176,12 @@
11641176
"in": "query",
11651177
"required": false,
11661178
"type": "string"
1179+
},
1180+
{
1181+
"name": "optionalString",
1182+
"in": "query",
1183+
"required": false,
1184+
"type": "string"
11671185
}
11681186
],
11691187
"tags": [
@@ -1511,6 +1529,12 @@
15111529
"in": "query",
15121530
"required": false,
15131531
"type": "string"
1532+
},
1533+
{
1534+
"name": "optionalString",
1535+
"in": "query",
1536+
"required": false,
1537+
"type": "string"
15141538
}
15151539
],
15161540
"tags": [
@@ -3307,6 +3331,9 @@
33073331
"type": "string",
33083332
"title": "mark a field as readonly in Open API definition",
33093333
"readOnly": true
3334+
},
3335+
"optionalString": {
3336+
"type": "string"
33103337
}
33113338
},
33123339
"description": "Intentionaly complicated message type to cover many features of Protobuf.",

examples/internal/proto/examplepb/generated_input.swagger.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,9 @@
273273
"type": "string",
274274
"title": "mark a field as readonly in Open API definition",
275275
"readOnly": true
276+
},
277+
"optionalString": {
278+
"type": "string"
276279
}
277280
},
278281
"description": "Intentionaly complicated message type to cover many features of Protobuf.",

examples/internal/proto/examplepb/stream.swagger.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,9 @@
400400
"type": "string",
401401
"title": "mark a field as readonly in Open API definition",
402402
"readOnly": true
403+
},
404+
"optionalString": {
405+
"type": "string"
403406
}
404407
},
405408
"description": "Intentionaly complicated message type to cover many features of Protobuf.",

internal/codegenerator/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ go_library(
77
srcs = [
88
"doc.go",
99
"parse_req.go",
10+
"supported_features.go",
1011
],
1112
importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/internal/codegenerator",
1213
deps = [
14+
"@org_golang_google_protobuf//compiler/protogen:go_default_library",
1315
"@org_golang_google_protobuf//proto:go_default_library",
1416
"@org_golang_google_protobuf//types/pluginpb:go_default_library",
1517
],
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package codegenerator
2+
3+
import (
4+
"google.golang.org/protobuf/compiler/protogen"
5+
"google.golang.org/protobuf/types/pluginpb"
6+
)
7+
8+
func supportedCodeGeneratorFeatures() uint64 {
9+
// Enable support for optional keyword in proto3.
10+
return uint64(pluginpb.CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL)
11+
}
12+
13+
// SetSupportedFeaturesOnPluginGen sets supported proto3 features
14+
// on protogen.Plugin.
15+
func SetSupportedFeaturesOnPluginGen(gen *protogen.Plugin) {
16+
gen.SupportedFeatures = supportedCodeGeneratorFeatures()
17+
}
18+
19+
// SetSupportedFeaturesOnCodeGeneratorResponse sets supported proto3 features
20+
// on pluginpb.CodeGeneratorResponse.
21+
func SetSupportedFeaturesOnCodeGeneratorResponse(resp *pluginpb.CodeGeneratorResponse) {
22+
sf := supportedCodeGeneratorFeatures()
23+
resp.SupportedFeatures = &sf
24+
}

internal/descriptor/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ go_library(
1414
importpath = "github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor",
1515
deps = [
1616
"//internal/casing:go_default_library",
17+
"//internal/codegenerator:go_default_library",
1718
"//internal/descriptor/apiconfig:go_default_library",
1819
"//internal/descriptor/openapiconfig:go_default_library",
1920
"//internal/httprule:go_default_library",

0 commit comments

Comments
 (0)