I have a gRPC service which takes Request and Response with specific formats.
message Response {
string ID = 1;
ScorerA ScrA = 2;
ScorerB ScrB = 3;
}
// Any one of ScorerA and ScorerB needs to populated in Response and will be decided at runtime
message ScorerA {
string Name = 1;
}
message ScorerB {
string Section = 1;
}
I have created map of Scorer Name to Scorer Type:
var scrA *pb.ScorerA = &pb.ScorerA{}
var scrAType protoreflect.MessageType = scrA.ProtoReflect().Type()
var scrB *pb.ScorerB = &pb.ScorerB{}
var scrBType protoreflect.MessageType = scrB.ProtoReflect().Type()
ScorerTypes := map[string]protoreflect.MessageType {
"ScorerA": scrAType
"ScorerB": scrBType
}
In my gRPC server I am getting the Scorer Name at runtime based on some condition.
scorerName := "ScorerA" // Let's say
Now I create an empty structure (not to be confused with go struct) of type scrAType and set values for fields:
var recType protoreflect.MessageType = ScorerTypes[scorerName]
var rec protoreflect.Message = recType.New()
.
.
.
rec.Set(_, _) // Setting values for fields
Finally converted to protoreflect.ProtoMessage using:
var finalScorer protoreflect.ProtoMessage = rec.Interface()
Reference: https://pkg.go.dev/google.golang.org/protobuf/reflect/protoreflect#hdr-Go_Type_Descriptors
Now my gRPC server has return type of *pb.Response, So:
resp := &pb.Response{ID: "1", ScrA: finalScorer}
This gives the following error:
cannot use finalScorer (variable of type protoreflect.ProtoMessage) as *"proto".ScorerA value in struct literal
How can I convert protoreflect.ProtoMessage to actual pb (lets say pb.ScorerA)?
If there’s any better way to handle this usecase please let me know.