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