/
any.go
130 lines (115 loc) · 3.15 KB
/
any.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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package protoutil
import (
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/anypb"
"google.golang.org/protobuf/types/known/wrapperspb"
)
// ToAny converts any type into an any value.
func ToAny(value interface{}) *anypb.Any {
switch v := value.(type) {
case bool:
return NewAnyBool(v)
case []byte:
return NewAnyBytes(v)
case float32:
return NewAnyFloat(v)
case float64:
return NewAnyDouble(v)
case int:
return NewAnyInt64(int64(v))
case int8:
return NewAnyInt32(int32(v))
case int16:
return NewAnyInt32(int32(v))
case int32:
return NewAnyInt32(v)
case int64:
return NewAnyInt64(v)
case string:
return NewAnyString(v)
case uint:
return NewAnyUInt64(uint64(v))
case uint8:
return NewAnyUInt32(uint32(v))
case uint16:
return NewAnyUInt32(uint32(v))
case uint32:
return NewAnyUInt32(v)
case uint64:
return NewAnyUInt64(v)
default:
return NewAny(ToStruct(value))
}
}
// NewAny creates a new Any using deterministic serialization.
func NewAny(msg proto.Message) *anypb.Any {
a := new(anypb.Any)
err := anypb.MarshalFrom(a, msg, proto.MarshalOptions{
AllowPartial: true,
Deterministic: true,
})
if err != nil {
// on error, which doesn't really happen in practice, return null
return NewAnyNull()
}
return a
}
// UnmarshalAnyJSON unmarshals JSON data into Any
func UnmarshalAnyJSON(data []byte) (*anypb.Any, error) {
opts := protojson.UnmarshalOptions{
AllowPartial: true,
DiscardUnknown: true,
}
var val anypb.Any
if err := opts.Unmarshal(data, &val); err != nil {
return nil, err
}
return &val, nil
}
// NewAnyBool creates a new any type from a bool.
func NewAnyBool(v bool) *anypb.Any {
return NewAny(wrapperspb.Bool(v))
}
// NewAnyBytes creates a new any type from bytes.
func NewAnyBytes(v []byte) *anypb.Any {
return NewAny(wrapperspb.Bytes(v))
}
// NewAnyDouble creates a new any type from a float64.
func NewAnyDouble(v float64) *anypb.Any {
return NewAny(wrapperspb.Double(v))
}
// NewAnyFloat creates a new any type from a float32.
func NewAnyFloat(v float32) *anypb.Any {
return NewAny(wrapperspb.Float(v))
}
// NewAnyInt64 creates a new any type from an int64.
func NewAnyInt64(v int64) *anypb.Any {
return NewAny(wrapperspb.Int64(v))
}
// NewAnyInt32 creates a new any type from an int32.
func NewAnyInt32(v int32) *anypb.Any {
return NewAny(wrapperspb.Int32(v))
}
// NewAnyNull creates a new any type from a null struct.
func NewAnyNull() *anypb.Any {
return NewAny(NewStructNull())
}
// NewAnyString creates a new any type from a string.
func NewAnyString(v string) *anypb.Any {
return NewAny(wrapperspb.String(v))
}
// NewAnyUInt64 creates a new any type from an uint64.
func NewAnyUInt64(v uint64) *anypb.Any {
return NewAny(wrapperspb.UInt64(v))
}
// NewAnyUInt32 creates a new any type from an uint32.
func NewAnyUInt32(v uint32) *anypb.Any {
return NewAny(wrapperspb.UInt32(v))
}
// GetTypeURL gets the TypeURL for a protobuf message.
func GetTypeURL(msg proto.Message) string {
// taken from the anypb package
const urlPrefix = "type.googleapis.com/"
return urlPrefix + string(msg.ProtoReflect().Descriptor().FullName())
}