Skip to content

Commit

Permalink
support oneofs in body
Browse files Browse the repository at this point in the history
  • Loading branch information
jhump committed Apr 30, 2018
1 parent 87a1b0c commit f2d5146
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 33 deletions.
63 changes: 32 additions & 31 deletions examples/proto/examplepb/echo_service.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

77 changes: 77 additions & 0 deletions examples/proto/examplepb/echo_service.pb.gw.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions examples/proto/examplepb/echo_service.proto
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ service EchoService {
option (google.api.http) = {
post: "/v1/example/echo_body"
body: "*"
additional_bindings {
put: "/v1/example/echo_body/{id}"
body: "no"
}
};
}
// EchoDelete method receives a simple message and returns it.
Expand Down
33 changes: 33 additions & 0 deletions examples/proto/examplepb/echo_service.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,39 @@
]
}
},
"/v1/example/echo_body/{id}": {
"put": {
"summary": "EchoBody method receives a simple message and returns it.",
"operationId": "EchoBody2",
"responses": {
"200": {
"description": "",
"schema": {
"$ref": "#/definitions/examplepbSimpleMessage"
}
}
},
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"type": "string"
},
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/examplepbEmbedded"
}
}
],
"tags": [
"EchoService"
]
}
},
"/v1/example/echo_delete": {
"delete": {
"summary": "EchoDelete method receives a simple message and returns it.",
Expand Down
42 changes: 40 additions & 2 deletions protoc-gen-grpc-gateway/descriptor/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,12 @@ func (b Body) AssignableExpr(msgExpr string) string {
return b.FieldPath.AssignableExpr(msgExpr)
}

// AssignableExprPrep returns prepatory statements for an assignable expression to initialize
// method request object.
func (b Body) AssignableExprPrep(msgExpr string) string {
return b.FieldPath.AssignableExprPrep(msgExpr)
}

// FieldPath is a path to a field from a request message.
type FieldPath []FieldPathComponent

Expand All @@ -261,13 +267,46 @@ func (p FieldPath) IsNestedProto3() bool {
}

// AssignableExpr is an assignable expression in Go to be used to assign a value to the target field.
// It starts with "msgExpr", which is the go expression of the method request object.
// It starts with "msgExpr", which is the go expression of the method request object. Before using
// such an expression the prep statements must be emitted first, in case the field path includes
// a oneof. See FieldPath.AssignableExprPrep.
func (p FieldPath) AssignableExpr(msgExpr string) string {
l := len(p)
if l == 0 {
return msgExpr
}

components := msgExpr
for i, c := range p {
// Check if it is a oneOf field.
if c.Target.OneofIndex != nil {
index := c.Target.OneofIndex
msg := c.Target.Message
oneOfName := gogen.CamelCase(msg.GetOneofDecl()[*index].GetName())
oneofFieldName := msg.GetName() + "_" + c.AssignableExpr()

components = components + "." + oneOfName + ".(*" + oneofFieldName + ")"
}

if i == l-1 {
components = components + "." + c.AssignableExpr()
continue
}
components = components + "." + c.ValueExpr()
}

return components
}

// AssignableExprPrep returns preparation statements for an assignable expression to assign a value
// to the target field. The go expression of the method request object is "msgExpr". This is only
// needed for field paths that contain oneofs. Otherwise, an empty string is returned.
func (p FieldPath) AssignableExprPrep(msgExpr string) string {
l := len(p)
if l == 0 {
return ""
}

var preparations []string
components := msgExpr
for i, c := range p {
Expand Down Expand Up @@ -296,7 +335,6 @@ func (p FieldPath) AssignableExpr(msgExpr string) string {
components = components + "." + c.ValueExpr()
}

preparations = append(preparations, components)
return strings.Join(preparations, "\n")
}

Expand Down
2 changes: 2 additions & 0 deletions protoc-gen-grpc-gateway/gengateway/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ var (
var protoReq {{.Method.RequestType.GoType .Method.Service.File.GoPkg.Path}}
var metadata runtime.ServerMetadata
{{if .Body}}
{{.Body.AssignableExprPrep "protoReq"}}
if err := marshaler.NewDecoder(req.Body).Decode(&{{.Body.AssignableExpr "protoReq"}}); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
Expand All @@ -226,6 +227,7 @@ var (
{{if $param.IsNestedProto3 }}
err = runtime.PopulateFieldFromPath(&protoReq, {{$param | printf "%q"}}, val)
{{else}}
{{$param.AssignableExprPrep "protoReq"}}
{{$param.AssignableExpr "protoReq"}}, err = {{$param.ConvertFuncExpr}}(val)
{{end}}
if err != nil {
Expand Down

0 comments on commit f2d5146

Please sign in to comment.