Embedded struct / message is not correctly populated, causing panic #2901
Open
Description
🐛 Bug Report
Embedded struct / message is not correctly populated, causing panic
To Reproduce
Use this particular proto file:
syntax = "proto3";
package test;
import "google/api/annotations.proto";
import "protoc-gen-openapiv2/options/annotations.proto";
option go_package = "github.com/alexadhy/protos-gen-go/test;test";
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
responses: {
key: "200";
}
responses: {
key: "404";
value: {
description: "Returned when the resource does not exist.";
}
}
responses: {
key: "500";
value: {
description: "Returned when the service is temporarily unavailable.";
}
}
responses: {
key: "503";
value: {
description: "Returned when the resource is temporarily unavailable.";
}
}
};
service XService {
rpc UpdateX (UpdateXRequest) returns (X) {
option (google.api.http) = {
put: "/v1/exes/{x.type=*}"
body: "x"
};
}
}
message UpdateXRequest {
// The parent resource
string parent = 1;
// The X to set.
X x = 2;
}
enum XType {
TYPE_UNDEFINED = 0;
TYPE_A = 1;
TYPE_B = 2;
}
message X {
XType type = 1;
string name = 2;
}
on generated code, it generates (snippet):
// Suppress "imported and not used" errors
var _ codes.Code
var _ io.Reader
var _ status.Status
var _ = runtime.String
var _ = utilities.NewDoubleArray
var _ = metadata.Join
var (
filter_XService_UpdateX_0 = &utilities.DoubleArray{Encoding: map[string]int{"x": 0, "type": 1}, Base: []int{1, 2, 1, 0, 0}, Check: []int{0, 1, 2, 3, 2}}
)
func request_XService_UpdateX_0(ctx context.Context, marshaler runtime.Marshaler, client XServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq UpdateXRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.X); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
var (
val string
e int32
ok bool
err error
_ = err
)
val, ok = pathParams["x.type"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "x.type")
}
err = runtime.PopulateFieldFromPath(&protoReq, "x.type", val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "x.type", err)
}
e, err = runtime.Enum(val, XType_value)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "could not parse path as enum value, parameter: %s, error: %v", "x.type", err)
}
protoReq.X.Type = XType(e) // this line is causing issue
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_XService_UpdateX_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.UpdateX(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
I added a comment where the generated code creates an issue, because the X
object is not yet initialized, access / assignment to X
via protoreq.X.type = XType(e)
will panic
Expected behavior
I expect that it should be populated correctly before assigning something, perhaps something like protoreq.X = &X{}
Actual Behavior
Panic
Your Environment
OS: Mac
Generated via buf with the following buf.lock:
Generated by buf. DO NOT EDIT.
version: v1
deps:
- remote: buf.build
owner: googleapis
repository: googleapis
commit: 8d7204855ec14631a499bd7393ce1970 - remote: buf.build
owner: grpc-ecosystem
repository: grpc-gateway
commit: bc28b723cd774c32b6fbc77621518765