1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
package protoregistry
import (
"fmt"
"reflect"
"strings"
"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/protoc-gen-go/descriptor"
)
// requestFactory returns a function to allocate a new instance of the request
// message type for an RPC method. This is useful in gRPC components that treat
// messages generically, like a stream interceptor.
func requestFactory(mdp *descriptor.MethodDescriptorProto) (func() (proto.Message, error), error) {
// not sure why this has a leading dot
reqTypeName := strings.TrimPrefix(mdp.GetInputType(), ".")
reqType := proto.MessageType(reqTypeName)
if reqType == nil {
return nil, fmt.Errorf("unable to retrieve protobuf message type for %s", reqTypeName)
}
factory := func() (proto.Message, error) {
newReq := reflect.New(reqType.Elem())
val, ok := newReq.Interface().(proto.Message)
if !ok {
return nil, fmt.Errorf("method request factory does not return proto message: %#v", newReq)
}
return val, nil
}
// does the factory actually work? kick the tires...
if _, err := factory(); err != nil {
return nil, fmt.Errorf("defective factory function: %q", err)
}
return factory, nil
}
|