1
|
|
|
// Copyright 2018 The Go Authors. All rights reserved. |
2
|
|
|
// Use of this source code is governed by a BSD-style |
3
|
|
|
// license that can be found in the LICENSE file. |
4
|
|
|
|
5
|
|
|
package impl |
6
|
|
|
|
7
|
|
|
import ( |
8
|
|
|
"fmt" |
9
|
|
|
"reflect" |
10
|
|
|
|
11
|
|
|
pref "google.golang.org/protobuf/reflect/protoreflect" |
12
|
|
|
) |
13
|
|
|
|
14
|
|
|
// unwrapper unwraps the value to the underlying value. |
15
|
|
|
// This is implemented by List and Map. |
16
|
|
|
type unwrapper interface { |
17
|
|
|
protoUnwrap() interface{} |
18
|
|
|
} |
19
|
|
|
|
20
|
|
|
// A Converter coverts to/from Go reflect.Value types and protobuf protoreflect.Value types. |
21
|
|
|
type Converter interface { |
22
|
|
|
// PBValueOf converts a reflect.Value to a protoreflect.Value. |
23
|
|
|
PBValueOf(reflect.Value) pref.Value |
24
|
|
|
|
25
|
|
|
// GoValueOf converts a protoreflect.Value to a reflect.Value. |
26
|
|
|
GoValueOf(pref.Value) reflect.Value |
27
|
|
|
|
28
|
|
|
// IsValidPB returns whether a protoreflect.Value is compatible with this type. |
29
|
|
|
IsValidPB(pref.Value) bool |
30
|
|
|
|
31
|
|
|
// IsValidGo returns whether a reflect.Value is compatible with this type. |
32
|
|
|
IsValidGo(reflect.Value) bool |
33
|
|
|
|
34
|
|
|
// New returns a new field value. |
35
|
|
|
// For scalars, it returns the default value of the field. |
36
|
|
|
// For composite types, it returns a new mutable value. |
37
|
|
|
New() pref.Value |
38
|
|
|
|
39
|
|
|
// Zero returns a new field value. |
40
|
|
|
// For scalars, it returns the default value of the field. |
41
|
|
|
// For composite types, it returns an immutable, empty value. |
42
|
|
|
Zero() pref.Value |
43
|
|
|
} |
44
|
|
|
|
45
|
|
|
// NewConverter matches a Go type with a protobuf field and returns a Converter |
46
|
|
|
// that converts between the two. Enums must be a named int32 kind that |
47
|
|
|
// implements protoreflect.Enum, and messages must be pointer to a named |
48
|
|
|
// struct type that implements protoreflect.ProtoMessage. |
49
|
|
|
// |
50
|
|
|
// This matcher deliberately supports a wider range of Go types than what |
51
|
|
|
// protoc-gen-go historically generated to be able to automatically wrap some |
52
|
|
|
// v1 messages generated by other forks of protoc-gen-go. |
53
|
|
|
func NewConverter(t reflect.Type, fd pref.FieldDescriptor) Converter { |
54
|
|
|
switch { |
55
|
|
|
case fd.IsList(): |
56
|
|
|
return newListConverter(t, fd) |
57
|
|
|
case fd.IsMap(): |
58
|
|
|
return newMapConverter(t, fd) |
59
|
|
|
default: |
60
|
|
|
return newSingularConverter(t, fd) |
61
|
|
|
} |
62
|
|
|
panic(fmt.Sprintf("invalid Go type %v for field %v", t, fd.FullName())) |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
var ( |
66
|
|
|
boolType = reflect.TypeOf(bool(false)) |
67
|
|
|
int32Type = reflect.TypeOf(int32(0)) |
68
|
|
|
int64Type = reflect.TypeOf(int64(0)) |
69
|
|
|
uint32Type = reflect.TypeOf(uint32(0)) |
70
|
|
|
uint64Type = reflect.TypeOf(uint64(0)) |
71
|
|
|
float32Type = reflect.TypeOf(float32(0)) |
72
|
|
|
float64Type = reflect.TypeOf(float64(0)) |
73
|
|
|
stringType = reflect.TypeOf(string("")) |
74
|
|
|
bytesType = reflect.TypeOf([]byte(nil)) |
75
|
|
|
byteType = reflect.TypeOf(byte(0)) |
76
|
|
|
) |
77
|
|
|
|
78
|
|
|
var ( |
79
|
|
|
boolZero = pref.ValueOfBool(false) |
80
|
|
|
int32Zero = pref.ValueOfInt32(0) |
81
|
|
|
int64Zero = pref.ValueOfInt64(0) |
82
|
|
|
uint32Zero = pref.ValueOfUint32(0) |
83
|
|
|
uint64Zero = pref.ValueOfUint64(0) |
84
|
|
|
float32Zero = pref.ValueOfFloat32(0) |
85
|
|
|
float64Zero = pref.ValueOfFloat64(0) |
86
|
|
|
stringZero = pref.ValueOfString("") |
87
|
|
|
bytesZero = pref.ValueOfBytes(nil) |
88
|
|
|
) |
89
|
|
|
|
90
|
|
|
func newSingularConverter(t reflect.Type, fd pref.FieldDescriptor) Converter { |
91
|
|
|
defVal := func(fd pref.FieldDescriptor, zero pref.Value) pref.Value { |
92
|
|
|
if fd.Cardinality() == pref.Repeated { |
93
|
|
|
// Default isn't defined for repeated fields. |
94
|
|
|
return zero |
95
|
|
|
} |
96
|
|
|
return fd.Default() |
97
|
|
|
} |
98
|
|
|
switch fd.Kind() { |
99
|
|
|
case pref.BoolKind: |
100
|
|
|
if t.Kind() == reflect.Bool { |
101
|
|
|
return &boolConverter{t, defVal(fd, boolZero)} |
102
|
|
|
} |
103
|
|
|
case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind: |
104
|
|
|
if t.Kind() == reflect.Int32 { |
105
|
|
|
return &int32Converter{t, defVal(fd, int32Zero)} |
106
|
|
|
} |
107
|
|
|
case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind: |
108
|
|
|
if t.Kind() == reflect.Int64 { |
109
|
|
|
return &int64Converter{t, defVal(fd, int64Zero)} |
110
|
|
|
} |
111
|
|
|
case pref.Uint32Kind, pref.Fixed32Kind: |
112
|
|
|
if t.Kind() == reflect.Uint32 { |
113
|
|
|
return &uint32Converter{t, defVal(fd, uint32Zero)} |
114
|
|
|
} |
115
|
|
|
case pref.Uint64Kind, pref.Fixed64Kind: |
116
|
|
|
if t.Kind() == reflect.Uint64 { |
117
|
|
|
return &uint64Converter{t, defVal(fd, uint64Zero)} |
118
|
|
|
} |
119
|
|
|
case pref.FloatKind: |
120
|
|
|
if t.Kind() == reflect.Float32 { |
121
|
|
|
return &float32Converter{t, defVal(fd, float32Zero)} |
122
|
|
|
} |
123
|
|
|
case pref.DoubleKind: |
124
|
|
|
if t.Kind() == reflect.Float64 { |
125
|
|
|
return &float64Converter{t, defVal(fd, float64Zero)} |
126
|
|
|
} |
127
|
|
|
case pref.StringKind: |
128
|
|
|
if t.Kind() == reflect.String || (t.Kind() == reflect.Slice && t.Elem() == byteType) { |
129
|
|
|
return &stringConverter{t, defVal(fd, stringZero)} |
130
|
|
|
} |
131
|
|
|
case pref.BytesKind: |
132
|
|
|
if t.Kind() == reflect.String || (t.Kind() == reflect.Slice && t.Elem() == byteType) { |
133
|
|
|
return &bytesConverter{t, defVal(fd, bytesZero)} |
134
|
|
|
} |
135
|
|
|
case pref.EnumKind: |
136
|
|
|
// Handle enums, which must be a named int32 type. |
137
|
|
|
if t.Kind() == reflect.Int32 { |
138
|
|
|
return newEnumConverter(t, fd) |
139
|
|
|
} |
140
|
|
|
case pref.MessageKind, pref.GroupKind: |
141
|
|
|
return newMessageConverter(t) |
142
|
|
|
} |
143
|
|
|
panic(fmt.Sprintf("invalid Go type %v for field %v", t, fd.FullName())) |
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
type boolConverter struct { |
147
|
|
|
goType reflect.Type |
148
|
|
|
def pref.Value |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
func (c *boolConverter) PBValueOf(v reflect.Value) pref.Value { |
152
|
|
|
if v.Type() != c.goType { |
153
|
|
|
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) |
154
|
|
|
} |
155
|
|
|
return pref.ValueOfBool(v.Bool()) |
156
|
|
|
} |
157
|
|
|
func (c *boolConverter) GoValueOf(v pref.Value) reflect.Value { |
158
|
|
|
return reflect.ValueOf(v.Bool()).Convert(c.goType) |
159
|
|
|
} |
160
|
|
|
func (c *boolConverter) IsValidPB(v pref.Value) bool { |
161
|
|
|
_, ok := v.Interface().(bool) |
162
|
|
|
return ok |
163
|
|
|
} |
164
|
|
|
func (c *boolConverter) IsValidGo(v reflect.Value) bool { |
165
|
|
|
return v.IsValid() && v.Type() == c.goType |
166
|
|
|
} |
167
|
|
|
func (c *boolConverter) New() pref.Value { return c.def } |
168
|
|
|
func (c *boolConverter) Zero() pref.Value { return c.def } |
169
|
|
|
|
170
|
|
|
type int32Converter struct { |
171
|
|
|
goType reflect.Type |
172
|
|
|
def pref.Value |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
func (c *int32Converter) PBValueOf(v reflect.Value) pref.Value { |
176
|
|
|
if v.Type() != c.goType { |
177
|
|
|
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) |
178
|
|
|
} |
179
|
|
|
return pref.ValueOfInt32(int32(v.Int())) |
180
|
|
|
} |
181
|
|
|
func (c *int32Converter) GoValueOf(v pref.Value) reflect.Value { |
182
|
|
|
return reflect.ValueOf(int32(v.Int())).Convert(c.goType) |
183
|
|
|
} |
184
|
|
|
func (c *int32Converter) IsValidPB(v pref.Value) bool { |
185
|
|
|
_, ok := v.Interface().(int32) |
186
|
|
|
return ok |
187
|
|
|
} |
188
|
|
|
func (c *int32Converter) IsValidGo(v reflect.Value) bool { |
189
|
|
|
return v.IsValid() && v.Type() == c.goType |
190
|
|
|
} |
191
|
|
|
func (c *int32Converter) New() pref.Value { return c.def } |
192
|
|
|
func (c *int32Converter) Zero() pref.Value { return c.def } |
193
|
|
|
|
194
|
|
|
type int64Converter struct { |
195
|
|
|
goType reflect.Type |
196
|
|
|
def pref.Value |
197
|
|
|
} |
198
|
|
|
|
199
|
|
|
func (c *int64Converter) PBValueOf(v reflect.Value) pref.Value { |
200
|
|
|
if v.Type() != c.goType { |
201
|
|
|
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) |
202
|
|
|
} |
203
|
|
|
return pref.ValueOfInt64(int64(v.Int())) |
204
|
|
|
} |
205
|
|
|
func (c *int64Converter) GoValueOf(v pref.Value) reflect.Value { |
206
|
|
|
return reflect.ValueOf(int64(v.Int())).Convert(c.goType) |
207
|
|
|
} |
208
|
|
|
func (c *int64Converter) IsValidPB(v pref.Value) bool { |
209
|
|
|
_, ok := v.Interface().(int64) |
210
|
|
|
return ok |
211
|
|
|
} |
212
|
|
|
func (c *int64Converter) IsValidGo(v reflect.Value) bool { |
213
|
|
|
return v.IsValid() && v.Type() == c.goType |
214
|
|
|
} |
215
|
|
|
func (c *int64Converter) New() pref.Value { return c.def } |
216
|
|
|
func (c *int64Converter) Zero() pref.Value { return c.def } |
217
|
|
|
|
218
|
|
|
type uint32Converter struct { |
219
|
|
|
goType reflect.Type |
220
|
|
|
def pref.Value |
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
func (c *uint32Converter) PBValueOf(v reflect.Value) pref.Value { |
224
|
|
|
if v.Type() != c.goType { |
225
|
|
|
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) |
226
|
|
|
} |
227
|
|
|
return pref.ValueOfUint32(uint32(v.Uint())) |
228
|
|
|
} |
229
|
|
|
func (c *uint32Converter) GoValueOf(v pref.Value) reflect.Value { |
230
|
|
|
return reflect.ValueOf(uint32(v.Uint())).Convert(c.goType) |
231
|
|
|
} |
232
|
|
|
func (c *uint32Converter) IsValidPB(v pref.Value) bool { |
233
|
|
|
_, ok := v.Interface().(uint32) |
234
|
|
|
return ok |
235
|
|
|
} |
236
|
|
|
func (c *uint32Converter) IsValidGo(v reflect.Value) bool { |
237
|
|
|
return v.IsValid() && v.Type() == c.goType |
238
|
|
|
} |
239
|
|
|
func (c *uint32Converter) New() pref.Value { return c.def } |
240
|
|
|
func (c *uint32Converter) Zero() pref.Value { return c.def } |
241
|
|
|
|
242
|
|
|
type uint64Converter struct { |
243
|
|
|
goType reflect.Type |
244
|
|
|
def pref.Value |
245
|
|
|
} |
246
|
|
|
|
247
|
|
|
func (c *uint64Converter) PBValueOf(v reflect.Value) pref.Value { |
248
|
|
|
if v.Type() != c.goType { |
249
|
|
|
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) |
250
|
|
|
} |
251
|
|
|
return pref.ValueOfUint64(uint64(v.Uint())) |
252
|
|
|
} |
253
|
|
|
func (c *uint64Converter) GoValueOf(v pref.Value) reflect.Value { |
254
|
|
|
return reflect.ValueOf(uint64(v.Uint())).Convert(c.goType) |
255
|
|
|
} |
256
|
|
|
func (c *uint64Converter) IsValidPB(v pref.Value) bool { |
257
|
|
|
_, ok := v.Interface().(uint64) |
258
|
|
|
return ok |
259
|
|
|
} |
260
|
|
|
func (c *uint64Converter) IsValidGo(v reflect.Value) bool { |
261
|
|
|
return v.IsValid() && v.Type() == c.goType |
262
|
|
|
} |
263
|
|
|
func (c *uint64Converter) New() pref.Value { return c.def } |
264
|
|
|
func (c *uint64Converter) Zero() pref.Value { return c.def } |
265
|
|
|
|
266
|
|
|
type float32Converter struct { |
267
|
|
|
goType reflect.Type |
268
|
|
|
def pref.Value |
269
|
|
|
} |
270
|
|
|
|
271
|
|
|
func (c *float32Converter) PBValueOf(v reflect.Value) pref.Value { |
272
|
|
|
if v.Type() != c.goType { |
273
|
|
|
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) |
274
|
|
|
} |
275
|
|
|
return pref.ValueOfFloat32(float32(v.Float())) |
276
|
|
|
} |
277
|
|
|
func (c *float32Converter) GoValueOf(v pref.Value) reflect.Value { |
278
|
|
|
return reflect.ValueOf(float32(v.Float())).Convert(c.goType) |
279
|
|
|
} |
280
|
|
|
func (c *float32Converter) IsValidPB(v pref.Value) bool { |
281
|
|
|
_, ok := v.Interface().(float32) |
282
|
|
|
return ok |
283
|
|
|
} |
284
|
|
|
func (c *float32Converter) IsValidGo(v reflect.Value) bool { |
285
|
|
|
return v.IsValid() && v.Type() == c.goType |
286
|
|
|
} |
287
|
|
|
func (c *float32Converter) New() pref.Value { return c.def } |
288
|
|
|
func (c *float32Converter) Zero() pref.Value { return c.def } |
289
|
|
|
|
290
|
|
|
type float64Converter struct { |
291
|
|
|
goType reflect.Type |
292
|
|
|
def pref.Value |
293
|
|
|
} |
294
|
|
|
|
295
|
|
|
func (c *float64Converter) PBValueOf(v reflect.Value) pref.Value { |
296
|
|
|
if v.Type() != c.goType { |
297
|
|
|
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) |
298
|
|
|
} |
299
|
|
|
return pref.ValueOfFloat64(float64(v.Float())) |
300
|
|
|
} |
301
|
|
|
func (c *float64Converter) GoValueOf(v pref.Value) reflect.Value { |
302
|
|
|
return reflect.ValueOf(float64(v.Float())).Convert(c.goType) |
303
|
|
|
} |
304
|
|
|
func (c *float64Converter) IsValidPB(v pref.Value) bool { |
305
|
|
|
_, ok := v.Interface().(float64) |
306
|
|
|
return ok |
307
|
|
|
} |
308
|
|
|
func (c *float64Converter) IsValidGo(v reflect.Value) bool { |
309
|
|
|
return v.IsValid() && v.Type() == c.goType |
310
|
|
|
} |
311
|
|
|
func (c *float64Converter) New() pref.Value { return c.def } |
312
|
|
|
func (c *float64Converter) Zero() pref.Value { return c.def } |
313
|
|
|
|
314
|
|
|
type stringConverter struct { |
315
|
|
|
goType reflect.Type |
316
|
|
|
def pref.Value |
317
|
|
|
} |
318
|
|
|
|
319
|
|
|
func (c *stringConverter) PBValueOf(v reflect.Value) pref.Value { |
320
|
|
|
if v.Type() != c.goType { |
321
|
|
|
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) |
322
|
|
|
} |
323
|
|
|
return pref.ValueOfString(v.Convert(stringType).String()) |
324
|
|
|
} |
325
|
|
|
func (c *stringConverter) GoValueOf(v pref.Value) reflect.Value { |
326
|
|
|
// pref.Value.String never panics, so we go through an interface |
327
|
|
|
// conversion here to check the type. |
328
|
|
|
s := v.Interface().(string) |
329
|
|
|
if c.goType.Kind() == reflect.Slice && s == "" { |
330
|
|
|
return reflect.Zero(c.goType) // ensure empty string is []byte(nil) |
331
|
|
|
} |
332
|
|
|
return reflect.ValueOf(s).Convert(c.goType) |
333
|
|
|
} |
334
|
|
|
func (c *stringConverter) IsValidPB(v pref.Value) bool { |
335
|
|
|
_, ok := v.Interface().(string) |
336
|
|
|
return ok |
337
|
|
|
} |
338
|
|
|
func (c *stringConverter) IsValidGo(v reflect.Value) bool { |
339
|
|
|
return v.IsValid() && v.Type() == c.goType |
340
|
|
|
} |
341
|
|
|
func (c *stringConverter) New() pref.Value { return c.def } |
342
|
|
|
func (c *stringConverter) Zero() pref.Value { return c.def } |
343
|
|
|
|
344
|
|
|
type bytesConverter struct { |
345
|
|
|
goType reflect.Type |
346
|
|
|
def pref.Value |
347
|
|
|
} |
348
|
|
|
|
349
|
|
|
func (c *bytesConverter) PBValueOf(v reflect.Value) pref.Value { |
350
|
|
|
if v.Type() != c.goType { |
351
|
|
|
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) |
352
|
|
|
} |
353
|
|
|
if c.goType.Kind() == reflect.String && v.Len() == 0 { |
354
|
|
|
return pref.ValueOfBytes(nil) // ensure empty string is []byte(nil) |
355
|
|
|
} |
356
|
|
|
return pref.ValueOfBytes(v.Convert(bytesType).Bytes()) |
357
|
|
|
} |
358
|
|
|
func (c *bytesConverter) GoValueOf(v pref.Value) reflect.Value { |
359
|
|
|
return reflect.ValueOf(v.Bytes()).Convert(c.goType) |
360
|
|
|
} |
361
|
|
|
func (c *bytesConverter) IsValidPB(v pref.Value) bool { |
362
|
|
|
_, ok := v.Interface().([]byte) |
363
|
|
|
return ok |
364
|
|
|
} |
365
|
|
|
func (c *bytesConverter) IsValidGo(v reflect.Value) bool { |
366
|
|
|
return v.IsValid() && v.Type() == c.goType |
367
|
|
|
} |
368
|
|
|
func (c *bytesConverter) New() pref.Value { return c.def } |
369
|
|
|
func (c *bytesConverter) Zero() pref.Value { return c.def } |
370
|
|
|
|
371
|
|
|
type enumConverter struct { |
372
|
|
|
goType reflect.Type |
373
|
|
|
def pref.Value |
374
|
|
|
} |
375
|
|
|
|
376
|
|
|
func newEnumConverter(goType reflect.Type, fd pref.FieldDescriptor) Converter { |
377
|
|
|
var def pref.Value |
378
|
|
|
if fd.Cardinality() == pref.Repeated { |
379
|
|
|
def = pref.ValueOfEnum(fd.Enum().Values().Get(0).Number()) |
380
|
|
|
} else { |
381
|
|
|
def = fd.Default() |
382
|
|
|
} |
383
|
|
|
return &enumConverter{goType, def} |
384
|
|
|
} |
385
|
|
|
|
386
|
|
|
func (c *enumConverter) PBValueOf(v reflect.Value) pref.Value { |
387
|
|
|
if v.Type() != c.goType { |
388
|
|
|
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) |
389
|
|
|
} |
390
|
|
|
return pref.ValueOfEnum(pref.EnumNumber(v.Int())) |
391
|
|
|
} |
392
|
|
|
|
393
|
|
|
func (c *enumConverter) GoValueOf(v pref.Value) reflect.Value { |
394
|
|
|
return reflect.ValueOf(v.Enum()).Convert(c.goType) |
395
|
|
|
} |
396
|
|
|
|
397
|
|
|
func (c *enumConverter) IsValidPB(v pref.Value) bool { |
398
|
|
|
_, ok := v.Interface().(pref.EnumNumber) |
399
|
|
|
return ok |
400
|
|
|
} |
401
|
|
|
|
402
|
|
|
func (c *enumConverter) IsValidGo(v reflect.Value) bool { |
403
|
|
|
return v.IsValid() && v.Type() == c.goType |
404
|
|
|
} |
405
|
|
|
|
406
|
|
|
func (c *enumConverter) New() pref.Value { |
407
|
|
|
return c.def |
408
|
|
|
} |
409
|
|
|
|
410
|
|
|
func (c *enumConverter) Zero() pref.Value { |
411
|
|
|
return c.def |
412
|
|
|
} |
413
|
|
|
|
414
|
|
|
type messageConverter struct { |
415
|
|
|
goType reflect.Type |
416
|
|
|
} |
417
|
|
|
|
418
|
|
|
func newMessageConverter(goType reflect.Type) Converter { |
419
|
|
|
return &messageConverter{goType} |
420
|
|
|
} |
421
|
|
|
|
422
|
|
|
func (c *messageConverter) PBValueOf(v reflect.Value) pref.Value { |
423
|
|
|
if v.Type() != c.goType { |
424
|
|
|
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) |
425
|
|
|
} |
426
|
|
|
if c.isNonPointer() { |
427
|
|
|
if v.CanAddr() { |
428
|
|
|
v = v.Addr() // T => *T |
429
|
|
|
} else { |
430
|
|
|
v = reflect.Zero(reflect.PtrTo(v.Type())) |
431
|
|
|
} |
432
|
|
|
} |
433
|
|
|
if m, ok := v.Interface().(pref.ProtoMessage); ok { |
434
|
|
|
return pref.ValueOfMessage(m.ProtoReflect()) |
435
|
|
|
} |
436
|
|
|
return pref.ValueOfMessage(legacyWrapMessage(v)) |
437
|
|
|
} |
438
|
|
|
|
439
|
|
|
func (c *messageConverter) GoValueOf(v pref.Value) reflect.Value { |
440
|
|
|
m := v.Message() |
441
|
|
|
var rv reflect.Value |
442
|
|
|
if u, ok := m.(unwrapper); ok { |
443
|
|
|
rv = reflect.ValueOf(u.protoUnwrap()) |
444
|
|
|
} else { |
445
|
|
|
rv = reflect.ValueOf(m.Interface()) |
446
|
|
|
} |
447
|
|
|
if c.isNonPointer() { |
448
|
|
|
if rv.Type() != reflect.PtrTo(c.goType) { |
449
|
|
|
panic(fmt.Sprintf("invalid type: got %v, want %v", rv.Type(), reflect.PtrTo(c.goType))) |
450
|
|
|
} |
451
|
|
|
if !rv.IsNil() { |
452
|
|
|
rv = rv.Elem() // *T => T |
453
|
|
|
} else { |
454
|
|
|
rv = reflect.Zero(rv.Type().Elem()) |
455
|
|
|
} |
456
|
|
|
} |
457
|
|
|
if rv.Type() != c.goType { |
458
|
|
|
panic(fmt.Sprintf("invalid type: got %v, want %v", rv.Type(), c.goType)) |
459
|
|
|
} |
460
|
|
|
return rv |
461
|
|
|
} |
462
|
|
|
|
463
|
|
|
func (c *messageConverter) IsValidPB(v pref.Value) bool { |
464
|
|
|
m := v.Message() |
465
|
|
|
var rv reflect.Value |
466
|
|
|
if u, ok := m.(unwrapper); ok { |
467
|
|
|
rv = reflect.ValueOf(u.protoUnwrap()) |
468
|
|
|
} else { |
469
|
|
|
rv = reflect.ValueOf(m.Interface()) |
470
|
|
|
} |
471
|
|
|
if c.isNonPointer() { |
472
|
|
|
return rv.Type() == reflect.PtrTo(c.goType) |
473
|
|
|
} |
474
|
|
|
return rv.Type() == c.goType |
475
|
|
|
} |
476
|
|
|
|
477
|
|
|
func (c *messageConverter) IsValidGo(v reflect.Value) bool { |
478
|
|
|
return v.IsValid() && v.Type() == c.goType |
479
|
|
|
} |
480
|
|
|
|
481
|
|
|
func (c *messageConverter) New() pref.Value { |
482
|
|
|
if c.isNonPointer() { |
483
|
|
|
return c.PBValueOf(reflect.New(c.goType).Elem()) |
484
|
|
|
} |
485
|
|
|
return c.PBValueOf(reflect.New(c.goType.Elem())) |
486
|
|
|
} |
487
|
|
|
|
488
|
|
|
func (c *messageConverter) Zero() pref.Value { |
489
|
|
|
return c.PBValueOf(reflect.Zero(c.goType)) |
490
|
|
|
} |
491
|
|
|
|
492
|
|
|
// isNonPointer reports whether the type is a non-pointer type. |
493
|
|
|
// This never occurs for generated message types. |
494
|
|
|
func (c *messageConverter) isNonPointer() bool { |
495
|
|
|
return c.goType.Kind() != reflect.Ptr |
496
|
|
|
} |
497
|
|
|
|