Skip to content

Commit

Permalink
Fix bug with nested proto3 messages in URL parameters, by reusing the…
Browse files Browse the repository at this point in the history
… reflection code.
  • Loading branch information
Michal Witkowski committed Jul 27, 2015
1 parent edd2e79 commit 583755b
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 2 deletions.
8 changes: 8 additions & 0 deletions protoc-gen-grpc-gateway/descriptor/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,14 @@ func (p FieldPath) String() string {
return strings.Join(components, ".")
}

// IsNestedProto3 indicates whether the FieldPath is a nested Proto3 path.
func (p FieldPath) IsNestedProto3() bool {
if len(p) > 1 && !p[0].Target.Message.File.proto2() {
return true
}
return false
}

// RHS is a right-hand-side 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.
func (p FieldPath) RHS(msgExpr string) string {
Expand Down
4 changes: 4 additions & 0 deletions protoc-gen-grpc-gateway/gengateway/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,11 @@ var (
if !ok {
return nil, grpc.Errorf(codes.InvalidArgument, "missing parameter %s", {{$param | printf "%q"}})
}
{{if $param.IsNestedProto3 }}
err = runtime.PopulateFieldFromPath(&protoReq, {{$param | printf "%q"}}, val)
{{else}}
{{$param.RHS "protoReq"}}, err = {{$param.ConvertFuncExpr}}(val)
{{end}}
if err != nil {
return nil, err
}
Expand Down
11 changes: 9 additions & 2 deletions runtime/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,21 @@ func PopulateQueryParameters(msg proto.Message, values url.Values, filter *inter
if filter.HasCommonPrefix(fieldPath) {
continue
}
if err := populateQueryParameter(msg, fieldPath, values); err != nil {
if err := populateFieldValueFromPath(msg, fieldPath, values); err != nil {
return err
}
}
return nil
}

func populateQueryParameter(msg proto.Message, fieldPath []string, values []string) error {
// PopulateFieldFromPath sets a value in a nested Protobuf structure.
// It instantiates missing protobuf fields as it goes.
func PopulateFieldFromPath(msg proto.Message, fieldPathString string, value string) error {
fieldPath := strings.Split(fieldPathString, ".")
return populateFieldValueFromPath(msg, fieldPath, []string{value})
}

func populateFieldValueFromPath(msg proto.Message, fieldPath []string, values []string) error {
m := reflect.ValueOf(msg)
if m.Kind() != reflect.Ptr {
return fmt.Errorf("unexpected type %T: %v", msg, msg)
Expand Down

0 comments on commit 583755b

Please sign in to comment.