-
Notifications
You must be signed in to change notification settings - Fork 13
/
message_types.go
56 lines (49 loc) · 1.7 KB
/
message_types.go
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package csproto
import (
"reflect"
"sync"
gogo "github.com/gogo/protobuf/proto"
google "google.golang.org/protobuf/proto"
)
// MessageType defines the types of Protobuf message implementations this API supports.
type MessageType int
const (
// MessageTypeUnknown indicates that we don't know which type of Protobuf message a type is.
MessageTypeUnknown MessageType = iota
// MessageTypeGogo indicates that a type was generated using Gogo Protobuf.
MessageTypeGogo
// MessageTypeGoogleV1 indicates that a type was generated using v1 of Google's Protobuf tools.
MessageTypeGoogleV1
// MessageTypeGoogle indicates that a type was generated using v2 of Google's Protobuf tools.
MessageTypeGoogle
)
var unmarshalMap sync.Map // in-memory cache of the mapping of Go types to MessageType
// MsgType accepts a protobuf message and returns the corresponding MessageType value.
func MsgType(msg interface{}) MessageType {
typ := reflect.TypeOf(msg)
val, found := unmarshalMap.Load(typ)
if found {
return val.(MessageType)
}
mt := deduceMsgType(msg, typ)
unmarshalMap.Store(typ, mt)
return mt
}
func deduceMsgType(msg interface{}, typ reflect.Type) MessageType {
// does the message satisfy Google's v2 csproto.Message interface?
if _, ok := msg.(google.Message); ok {
return MessageTypeGoogle
}
if typ.Kind() != reflect.Ptr {
return MessageTypeUnknown
}
// does the message satisfy Gogo's csproto.Message interface
if gogoMsg, ok := msg.(gogo.Message); ok {
// secondary check that the message type is registered with the Gogo runtime b/c
// Gogo's csproto.Message and Google's v1 csproto.Message are the same
if gogo.MessageName(gogoMsg) != "" {
return MessageTypeGogo
}
}
return MessageTypeGoogleV1
}