xref: /aosp_15_r20/external/golang-protobuf/internal/impl/codec_tables.go (revision 1c12ee1efe575feb122dbf939ff15148a3b3e8f2)
1*1c12ee1eSDan Willemsen// Copyright 2019 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/encoding/protowire"
12*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/internal/strs"
13*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/reflect/protoreflect"
14*1c12ee1eSDan Willemsen)
15*1c12ee1eSDan Willemsen
16*1c12ee1eSDan Willemsen// pointerCoderFuncs is a set of pointer encoding functions.
17*1c12ee1eSDan Willemsentype pointerCoderFuncs struct {
18*1c12ee1eSDan Willemsen	mi        *MessageInfo
19*1c12ee1eSDan Willemsen	size      func(p pointer, f *coderFieldInfo, opts marshalOptions) int
20*1c12ee1eSDan Willemsen	marshal   func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error)
21*1c12ee1eSDan Willemsen	unmarshal func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error)
22*1c12ee1eSDan Willemsen	isInit    func(p pointer, f *coderFieldInfo) error
23*1c12ee1eSDan Willemsen	merge     func(dst, src pointer, f *coderFieldInfo, opts mergeOptions)
24*1c12ee1eSDan Willemsen}
25*1c12ee1eSDan Willemsen
26*1c12ee1eSDan Willemsen// valueCoderFuncs is a set of protoreflect.Value encoding functions.
27*1c12ee1eSDan Willemsentype valueCoderFuncs struct {
28*1c12ee1eSDan Willemsen	size      func(v protoreflect.Value, tagsize int, opts marshalOptions) int
29*1c12ee1eSDan Willemsen	marshal   func(b []byte, v protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error)
30*1c12ee1eSDan Willemsen	unmarshal func(b []byte, v protoreflect.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (protoreflect.Value, unmarshalOutput, error)
31*1c12ee1eSDan Willemsen	isInit    func(v protoreflect.Value) error
32*1c12ee1eSDan Willemsen	merge     func(dst, src protoreflect.Value, opts mergeOptions) protoreflect.Value
33*1c12ee1eSDan Willemsen}
34*1c12ee1eSDan Willemsen
35*1c12ee1eSDan Willemsen// fieldCoder returns pointer functions for a field, used for operating on
36*1c12ee1eSDan Willemsen// struct fields.
37*1c12ee1eSDan Willemsenfunc fieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) (*MessageInfo, pointerCoderFuncs) {
38*1c12ee1eSDan Willemsen	switch {
39*1c12ee1eSDan Willemsen	case fd.IsMap():
40*1c12ee1eSDan Willemsen		return encoderFuncsForMap(fd, ft)
41*1c12ee1eSDan Willemsen	case fd.Cardinality() == protoreflect.Repeated && !fd.IsPacked():
42*1c12ee1eSDan Willemsen		// Repeated fields (not packed).
43*1c12ee1eSDan Willemsen		if ft.Kind() != reflect.Slice {
44*1c12ee1eSDan Willemsen			break
45*1c12ee1eSDan Willemsen		}
46*1c12ee1eSDan Willemsen		ft := ft.Elem()
47*1c12ee1eSDan Willemsen		switch fd.Kind() {
48*1c12ee1eSDan Willemsen		case protoreflect.BoolKind:
49*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Bool {
50*1c12ee1eSDan Willemsen				return nil, coderBoolSlice
51*1c12ee1eSDan Willemsen			}
52*1c12ee1eSDan Willemsen		case protoreflect.EnumKind:
53*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int32 {
54*1c12ee1eSDan Willemsen				return nil, coderEnumSlice
55*1c12ee1eSDan Willemsen			}
56*1c12ee1eSDan Willemsen		case protoreflect.Int32Kind:
57*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int32 {
58*1c12ee1eSDan Willemsen				return nil, coderInt32Slice
59*1c12ee1eSDan Willemsen			}
60*1c12ee1eSDan Willemsen		case protoreflect.Sint32Kind:
61*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int32 {
62*1c12ee1eSDan Willemsen				return nil, coderSint32Slice
63*1c12ee1eSDan Willemsen			}
64*1c12ee1eSDan Willemsen		case protoreflect.Uint32Kind:
65*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Uint32 {
66*1c12ee1eSDan Willemsen				return nil, coderUint32Slice
67*1c12ee1eSDan Willemsen			}
68*1c12ee1eSDan Willemsen		case protoreflect.Int64Kind:
69*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int64 {
70*1c12ee1eSDan Willemsen				return nil, coderInt64Slice
71*1c12ee1eSDan Willemsen			}
72*1c12ee1eSDan Willemsen		case protoreflect.Sint64Kind:
73*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int64 {
74*1c12ee1eSDan Willemsen				return nil, coderSint64Slice
75*1c12ee1eSDan Willemsen			}
76*1c12ee1eSDan Willemsen		case protoreflect.Uint64Kind:
77*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Uint64 {
78*1c12ee1eSDan Willemsen				return nil, coderUint64Slice
79*1c12ee1eSDan Willemsen			}
80*1c12ee1eSDan Willemsen		case protoreflect.Sfixed32Kind:
81*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int32 {
82*1c12ee1eSDan Willemsen				return nil, coderSfixed32Slice
83*1c12ee1eSDan Willemsen			}
84*1c12ee1eSDan Willemsen		case protoreflect.Fixed32Kind:
85*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Uint32 {
86*1c12ee1eSDan Willemsen				return nil, coderFixed32Slice
87*1c12ee1eSDan Willemsen			}
88*1c12ee1eSDan Willemsen		case protoreflect.FloatKind:
89*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Float32 {
90*1c12ee1eSDan Willemsen				return nil, coderFloatSlice
91*1c12ee1eSDan Willemsen			}
92*1c12ee1eSDan Willemsen		case protoreflect.Sfixed64Kind:
93*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int64 {
94*1c12ee1eSDan Willemsen				return nil, coderSfixed64Slice
95*1c12ee1eSDan Willemsen			}
96*1c12ee1eSDan Willemsen		case protoreflect.Fixed64Kind:
97*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Uint64 {
98*1c12ee1eSDan Willemsen				return nil, coderFixed64Slice
99*1c12ee1eSDan Willemsen			}
100*1c12ee1eSDan Willemsen		case protoreflect.DoubleKind:
101*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Float64 {
102*1c12ee1eSDan Willemsen				return nil, coderDoubleSlice
103*1c12ee1eSDan Willemsen			}
104*1c12ee1eSDan Willemsen		case protoreflect.StringKind:
105*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) {
106*1c12ee1eSDan Willemsen				return nil, coderStringSliceValidateUTF8
107*1c12ee1eSDan Willemsen			}
108*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.String {
109*1c12ee1eSDan Willemsen				return nil, coderStringSlice
110*1c12ee1eSDan Willemsen			}
111*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 && strs.EnforceUTF8(fd) {
112*1c12ee1eSDan Willemsen				return nil, coderBytesSliceValidateUTF8
113*1c12ee1eSDan Willemsen			}
114*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
115*1c12ee1eSDan Willemsen				return nil, coderBytesSlice
116*1c12ee1eSDan Willemsen			}
117*1c12ee1eSDan Willemsen		case protoreflect.BytesKind:
118*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.String {
119*1c12ee1eSDan Willemsen				return nil, coderStringSlice
120*1c12ee1eSDan Willemsen			}
121*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
122*1c12ee1eSDan Willemsen				return nil, coderBytesSlice
123*1c12ee1eSDan Willemsen			}
124*1c12ee1eSDan Willemsen		case protoreflect.MessageKind:
125*1c12ee1eSDan Willemsen			return getMessageInfo(ft), makeMessageSliceFieldCoder(fd, ft)
126*1c12ee1eSDan Willemsen		case protoreflect.GroupKind:
127*1c12ee1eSDan Willemsen			return getMessageInfo(ft), makeGroupSliceFieldCoder(fd, ft)
128*1c12ee1eSDan Willemsen		}
129*1c12ee1eSDan Willemsen	case fd.Cardinality() == protoreflect.Repeated && fd.IsPacked():
130*1c12ee1eSDan Willemsen		// Packed repeated fields.
131*1c12ee1eSDan Willemsen		//
132*1c12ee1eSDan Willemsen		// Only repeated fields of primitive numeric types
133*1c12ee1eSDan Willemsen		// (Varint, Fixed32, or Fixed64 wire type) can be packed.
134*1c12ee1eSDan Willemsen		if ft.Kind() != reflect.Slice {
135*1c12ee1eSDan Willemsen			break
136*1c12ee1eSDan Willemsen		}
137*1c12ee1eSDan Willemsen		ft := ft.Elem()
138*1c12ee1eSDan Willemsen		switch fd.Kind() {
139*1c12ee1eSDan Willemsen		case protoreflect.BoolKind:
140*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Bool {
141*1c12ee1eSDan Willemsen				return nil, coderBoolPackedSlice
142*1c12ee1eSDan Willemsen			}
143*1c12ee1eSDan Willemsen		case protoreflect.EnumKind:
144*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int32 {
145*1c12ee1eSDan Willemsen				return nil, coderEnumPackedSlice
146*1c12ee1eSDan Willemsen			}
147*1c12ee1eSDan Willemsen		case protoreflect.Int32Kind:
148*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int32 {
149*1c12ee1eSDan Willemsen				return nil, coderInt32PackedSlice
150*1c12ee1eSDan Willemsen			}
151*1c12ee1eSDan Willemsen		case protoreflect.Sint32Kind:
152*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int32 {
153*1c12ee1eSDan Willemsen				return nil, coderSint32PackedSlice
154*1c12ee1eSDan Willemsen			}
155*1c12ee1eSDan Willemsen		case protoreflect.Uint32Kind:
156*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Uint32 {
157*1c12ee1eSDan Willemsen				return nil, coderUint32PackedSlice
158*1c12ee1eSDan Willemsen			}
159*1c12ee1eSDan Willemsen		case protoreflect.Int64Kind:
160*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int64 {
161*1c12ee1eSDan Willemsen				return nil, coderInt64PackedSlice
162*1c12ee1eSDan Willemsen			}
163*1c12ee1eSDan Willemsen		case protoreflect.Sint64Kind:
164*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int64 {
165*1c12ee1eSDan Willemsen				return nil, coderSint64PackedSlice
166*1c12ee1eSDan Willemsen			}
167*1c12ee1eSDan Willemsen		case protoreflect.Uint64Kind:
168*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Uint64 {
169*1c12ee1eSDan Willemsen				return nil, coderUint64PackedSlice
170*1c12ee1eSDan Willemsen			}
171*1c12ee1eSDan Willemsen		case protoreflect.Sfixed32Kind:
172*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int32 {
173*1c12ee1eSDan Willemsen				return nil, coderSfixed32PackedSlice
174*1c12ee1eSDan Willemsen			}
175*1c12ee1eSDan Willemsen		case protoreflect.Fixed32Kind:
176*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Uint32 {
177*1c12ee1eSDan Willemsen				return nil, coderFixed32PackedSlice
178*1c12ee1eSDan Willemsen			}
179*1c12ee1eSDan Willemsen		case protoreflect.FloatKind:
180*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Float32 {
181*1c12ee1eSDan Willemsen				return nil, coderFloatPackedSlice
182*1c12ee1eSDan Willemsen			}
183*1c12ee1eSDan Willemsen		case protoreflect.Sfixed64Kind:
184*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int64 {
185*1c12ee1eSDan Willemsen				return nil, coderSfixed64PackedSlice
186*1c12ee1eSDan Willemsen			}
187*1c12ee1eSDan Willemsen		case protoreflect.Fixed64Kind:
188*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Uint64 {
189*1c12ee1eSDan Willemsen				return nil, coderFixed64PackedSlice
190*1c12ee1eSDan Willemsen			}
191*1c12ee1eSDan Willemsen		case protoreflect.DoubleKind:
192*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Float64 {
193*1c12ee1eSDan Willemsen				return nil, coderDoublePackedSlice
194*1c12ee1eSDan Willemsen			}
195*1c12ee1eSDan Willemsen		}
196*1c12ee1eSDan Willemsen	case fd.Kind() == protoreflect.MessageKind:
197*1c12ee1eSDan Willemsen		return getMessageInfo(ft), makeMessageFieldCoder(fd, ft)
198*1c12ee1eSDan Willemsen	case fd.Kind() == protoreflect.GroupKind:
199*1c12ee1eSDan Willemsen		return getMessageInfo(ft), makeGroupFieldCoder(fd, ft)
200*1c12ee1eSDan Willemsen	case fd.Syntax() == protoreflect.Proto3 && fd.ContainingOneof() == nil:
201*1c12ee1eSDan Willemsen		// Populated oneof fields always encode even if set to the zero value,
202*1c12ee1eSDan Willemsen		// which normally are not encoded in proto3.
203*1c12ee1eSDan Willemsen		switch fd.Kind() {
204*1c12ee1eSDan Willemsen		case protoreflect.BoolKind:
205*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Bool {
206*1c12ee1eSDan Willemsen				return nil, coderBoolNoZero
207*1c12ee1eSDan Willemsen			}
208*1c12ee1eSDan Willemsen		case protoreflect.EnumKind:
209*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int32 {
210*1c12ee1eSDan Willemsen				return nil, coderEnumNoZero
211*1c12ee1eSDan Willemsen			}
212*1c12ee1eSDan Willemsen		case protoreflect.Int32Kind:
213*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int32 {
214*1c12ee1eSDan Willemsen				return nil, coderInt32NoZero
215*1c12ee1eSDan Willemsen			}
216*1c12ee1eSDan Willemsen		case protoreflect.Sint32Kind:
217*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int32 {
218*1c12ee1eSDan Willemsen				return nil, coderSint32NoZero
219*1c12ee1eSDan Willemsen			}
220*1c12ee1eSDan Willemsen		case protoreflect.Uint32Kind:
221*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Uint32 {
222*1c12ee1eSDan Willemsen				return nil, coderUint32NoZero
223*1c12ee1eSDan Willemsen			}
224*1c12ee1eSDan Willemsen		case protoreflect.Int64Kind:
225*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int64 {
226*1c12ee1eSDan Willemsen				return nil, coderInt64NoZero
227*1c12ee1eSDan Willemsen			}
228*1c12ee1eSDan Willemsen		case protoreflect.Sint64Kind:
229*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int64 {
230*1c12ee1eSDan Willemsen				return nil, coderSint64NoZero
231*1c12ee1eSDan Willemsen			}
232*1c12ee1eSDan Willemsen		case protoreflect.Uint64Kind:
233*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Uint64 {
234*1c12ee1eSDan Willemsen				return nil, coderUint64NoZero
235*1c12ee1eSDan Willemsen			}
236*1c12ee1eSDan Willemsen		case protoreflect.Sfixed32Kind:
237*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int32 {
238*1c12ee1eSDan Willemsen				return nil, coderSfixed32NoZero
239*1c12ee1eSDan Willemsen			}
240*1c12ee1eSDan Willemsen		case protoreflect.Fixed32Kind:
241*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Uint32 {
242*1c12ee1eSDan Willemsen				return nil, coderFixed32NoZero
243*1c12ee1eSDan Willemsen			}
244*1c12ee1eSDan Willemsen		case protoreflect.FloatKind:
245*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Float32 {
246*1c12ee1eSDan Willemsen				return nil, coderFloatNoZero
247*1c12ee1eSDan Willemsen			}
248*1c12ee1eSDan Willemsen		case protoreflect.Sfixed64Kind:
249*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int64 {
250*1c12ee1eSDan Willemsen				return nil, coderSfixed64NoZero
251*1c12ee1eSDan Willemsen			}
252*1c12ee1eSDan Willemsen		case protoreflect.Fixed64Kind:
253*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Uint64 {
254*1c12ee1eSDan Willemsen				return nil, coderFixed64NoZero
255*1c12ee1eSDan Willemsen			}
256*1c12ee1eSDan Willemsen		case protoreflect.DoubleKind:
257*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Float64 {
258*1c12ee1eSDan Willemsen				return nil, coderDoubleNoZero
259*1c12ee1eSDan Willemsen			}
260*1c12ee1eSDan Willemsen		case protoreflect.StringKind:
261*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) {
262*1c12ee1eSDan Willemsen				return nil, coderStringNoZeroValidateUTF8
263*1c12ee1eSDan Willemsen			}
264*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.String {
265*1c12ee1eSDan Willemsen				return nil, coderStringNoZero
266*1c12ee1eSDan Willemsen			}
267*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 && strs.EnforceUTF8(fd) {
268*1c12ee1eSDan Willemsen				return nil, coderBytesNoZeroValidateUTF8
269*1c12ee1eSDan Willemsen			}
270*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
271*1c12ee1eSDan Willemsen				return nil, coderBytesNoZero
272*1c12ee1eSDan Willemsen			}
273*1c12ee1eSDan Willemsen		case protoreflect.BytesKind:
274*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.String {
275*1c12ee1eSDan Willemsen				return nil, coderStringNoZero
276*1c12ee1eSDan Willemsen			}
277*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
278*1c12ee1eSDan Willemsen				return nil, coderBytesNoZero
279*1c12ee1eSDan Willemsen			}
280*1c12ee1eSDan Willemsen		}
281*1c12ee1eSDan Willemsen	case ft.Kind() == reflect.Ptr:
282*1c12ee1eSDan Willemsen		ft := ft.Elem()
283*1c12ee1eSDan Willemsen		switch fd.Kind() {
284*1c12ee1eSDan Willemsen		case protoreflect.BoolKind:
285*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Bool {
286*1c12ee1eSDan Willemsen				return nil, coderBoolPtr
287*1c12ee1eSDan Willemsen			}
288*1c12ee1eSDan Willemsen		case protoreflect.EnumKind:
289*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int32 {
290*1c12ee1eSDan Willemsen				return nil, coderEnumPtr
291*1c12ee1eSDan Willemsen			}
292*1c12ee1eSDan Willemsen		case protoreflect.Int32Kind:
293*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int32 {
294*1c12ee1eSDan Willemsen				return nil, coderInt32Ptr
295*1c12ee1eSDan Willemsen			}
296*1c12ee1eSDan Willemsen		case protoreflect.Sint32Kind:
297*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int32 {
298*1c12ee1eSDan Willemsen				return nil, coderSint32Ptr
299*1c12ee1eSDan Willemsen			}
300*1c12ee1eSDan Willemsen		case protoreflect.Uint32Kind:
301*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Uint32 {
302*1c12ee1eSDan Willemsen				return nil, coderUint32Ptr
303*1c12ee1eSDan Willemsen			}
304*1c12ee1eSDan Willemsen		case protoreflect.Int64Kind:
305*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int64 {
306*1c12ee1eSDan Willemsen				return nil, coderInt64Ptr
307*1c12ee1eSDan Willemsen			}
308*1c12ee1eSDan Willemsen		case protoreflect.Sint64Kind:
309*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int64 {
310*1c12ee1eSDan Willemsen				return nil, coderSint64Ptr
311*1c12ee1eSDan Willemsen			}
312*1c12ee1eSDan Willemsen		case protoreflect.Uint64Kind:
313*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Uint64 {
314*1c12ee1eSDan Willemsen				return nil, coderUint64Ptr
315*1c12ee1eSDan Willemsen			}
316*1c12ee1eSDan Willemsen		case protoreflect.Sfixed32Kind:
317*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int32 {
318*1c12ee1eSDan Willemsen				return nil, coderSfixed32Ptr
319*1c12ee1eSDan Willemsen			}
320*1c12ee1eSDan Willemsen		case protoreflect.Fixed32Kind:
321*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Uint32 {
322*1c12ee1eSDan Willemsen				return nil, coderFixed32Ptr
323*1c12ee1eSDan Willemsen			}
324*1c12ee1eSDan Willemsen		case protoreflect.FloatKind:
325*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Float32 {
326*1c12ee1eSDan Willemsen				return nil, coderFloatPtr
327*1c12ee1eSDan Willemsen			}
328*1c12ee1eSDan Willemsen		case protoreflect.Sfixed64Kind:
329*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int64 {
330*1c12ee1eSDan Willemsen				return nil, coderSfixed64Ptr
331*1c12ee1eSDan Willemsen			}
332*1c12ee1eSDan Willemsen		case protoreflect.Fixed64Kind:
333*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Uint64 {
334*1c12ee1eSDan Willemsen				return nil, coderFixed64Ptr
335*1c12ee1eSDan Willemsen			}
336*1c12ee1eSDan Willemsen		case protoreflect.DoubleKind:
337*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Float64 {
338*1c12ee1eSDan Willemsen				return nil, coderDoublePtr
339*1c12ee1eSDan Willemsen			}
340*1c12ee1eSDan Willemsen		case protoreflect.StringKind:
341*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) {
342*1c12ee1eSDan Willemsen				return nil, coderStringPtrValidateUTF8
343*1c12ee1eSDan Willemsen			}
344*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.String {
345*1c12ee1eSDan Willemsen				return nil, coderStringPtr
346*1c12ee1eSDan Willemsen			}
347*1c12ee1eSDan Willemsen		case protoreflect.BytesKind:
348*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.String {
349*1c12ee1eSDan Willemsen				return nil, coderStringPtr
350*1c12ee1eSDan Willemsen			}
351*1c12ee1eSDan Willemsen		}
352*1c12ee1eSDan Willemsen	default:
353*1c12ee1eSDan Willemsen		switch fd.Kind() {
354*1c12ee1eSDan Willemsen		case protoreflect.BoolKind:
355*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Bool {
356*1c12ee1eSDan Willemsen				return nil, coderBool
357*1c12ee1eSDan Willemsen			}
358*1c12ee1eSDan Willemsen		case protoreflect.EnumKind:
359*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int32 {
360*1c12ee1eSDan Willemsen				return nil, coderEnum
361*1c12ee1eSDan Willemsen			}
362*1c12ee1eSDan Willemsen		case protoreflect.Int32Kind:
363*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int32 {
364*1c12ee1eSDan Willemsen				return nil, coderInt32
365*1c12ee1eSDan Willemsen			}
366*1c12ee1eSDan Willemsen		case protoreflect.Sint32Kind:
367*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int32 {
368*1c12ee1eSDan Willemsen				return nil, coderSint32
369*1c12ee1eSDan Willemsen			}
370*1c12ee1eSDan Willemsen		case protoreflect.Uint32Kind:
371*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Uint32 {
372*1c12ee1eSDan Willemsen				return nil, coderUint32
373*1c12ee1eSDan Willemsen			}
374*1c12ee1eSDan Willemsen		case protoreflect.Int64Kind:
375*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int64 {
376*1c12ee1eSDan Willemsen				return nil, coderInt64
377*1c12ee1eSDan Willemsen			}
378*1c12ee1eSDan Willemsen		case protoreflect.Sint64Kind:
379*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int64 {
380*1c12ee1eSDan Willemsen				return nil, coderSint64
381*1c12ee1eSDan Willemsen			}
382*1c12ee1eSDan Willemsen		case protoreflect.Uint64Kind:
383*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Uint64 {
384*1c12ee1eSDan Willemsen				return nil, coderUint64
385*1c12ee1eSDan Willemsen			}
386*1c12ee1eSDan Willemsen		case protoreflect.Sfixed32Kind:
387*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int32 {
388*1c12ee1eSDan Willemsen				return nil, coderSfixed32
389*1c12ee1eSDan Willemsen			}
390*1c12ee1eSDan Willemsen		case protoreflect.Fixed32Kind:
391*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Uint32 {
392*1c12ee1eSDan Willemsen				return nil, coderFixed32
393*1c12ee1eSDan Willemsen			}
394*1c12ee1eSDan Willemsen		case protoreflect.FloatKind:
395*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Float32 {
396*1c12ee1eSDan Willemsen				return nil, coderFloat
397*1c12ee1eSDan Willemsen			}
398*1c12ee1eSDan Willemsen		case protoreflect.Sfixed64Kind:
399*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Int64 {
400*1c12ee1eSDan Willemsen				return nil, coderSfixed64
401*1c12ee1eSDan Willemsen			}
402*1c12ee1eSDan Willemsen		case protoreflect.Fixed64Kind:
403*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Uint64 {
404*1c12ee1eSDan Willemsen				return nil, coderFixed64
405*1c12ee1eSDan Willemsen			}
406*1c12ee1eSDan Willemsen		case protoreflect.DoubleKind:
407*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Float64 {
408*1c12ee1eSDan Willemsen				return nil, coderDouble
409*1c12ee1eSDan Willemsen			}
410*1c12ee1eSDan Willemsen		case protoreflect.StringKind:
411*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) {
412*1c12ee1eSDan Willemsen				return nil, coderStringValidateUTF8
413*1c12ee1eSDan Willemsen			}
414*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.String {
415*1c12ee1eSDan Willemsen				return nil, coderString
416*1c12ee1eSDan Willemsen			}
417*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 && strs.EnforceUTF8(fd) {
418*1c12ee1eSDan Willemsen				return nil, coderBytesValidateUTF8
419*1c12ee1eSDan Willemsen			}
420*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
421*1c12ee1eSDan Willemsen				return nil, coderBytes
422*1c12ee1eSDan Willemsen			}
423*1c12ee1eSDan Willemsen		case protoreflect.BytesKind:
424*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.String {
425*1c12ee1eSDan Willemsen				return nil, coderString
426*1c12ee1eSDan Willemsen			}
427*1c12ee1eSDan Willemsen			if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
428*1c12ee1eSDan Willemsen				return nil, coderBytes
429*1c12ee1eSDan Willemsen			}
430*1c12ee1eSDan Willemsen		}
431*1c12ee1eSDan Willemsen	}
432*1c12ee1eSDan Willemsen	panic(fmt.Sprintf("invalid type: no encoder for %v %v %v/%v", fd.FullName(), fd.Cardinality(), fd.Kind(), ft))
433*1c12ee1eSDan Willemsen}
434*1c12ee1eSDan Willemsen
435*1c12ee1eSDan Willemsen// encoderFuncsForValue returns value functions for a field, used for
436*1c12ee1eSDan Willemsen// extension values and map encoding.
437*1c12ee1eSDan Willemsenfunc encoderFuncsForValue(fd protoreflect.FieldDescriptor) valueCoderFuncs {
438*1c12ee1eSDan Willemsen	switch {
439*1c12ee1eSDan Willemsen	case fd.Cardinality() == protoreflect.Repeated && !fd.IsPacked():
440*1c12ee1eSDan Willemsen		switch fd.Kind() {
441*1c12ee1eSDan Willemsen		case protoreflect.BoolKind:
442*1c12ee1eSDan Willemsen			return coderBoolSliceValue
443*1c12ee1eSDan Willemsen		case protoreflect.EnumKind:
444*1c12ee1eSDan Willemsen			return coderEnumSliceValue
445*1c12ee1eSDan Willemsen		case protoreflect.Int32Kind:
446*1c12ee1eSDan Willemsen			return coderInt32SliceValue
447*1c12ee1eSDan Willemsen		case protoreflect.Sint32Kind:
448*1c12ee1eSDan Willemsen			return coderSint32SliceValue
449*1c12ee1eSDan Willemsen		case protoreflect.Uint32Kind:
450*1c12ee1eSDan Willemsen			return coderUint32SliceValue
451*1c12ee1eSDan Willemsen		case protoreflect.Int64Kind:
452*1c12ee1eSDan Willemsen			return coderInt64SliceValue
453*1c12ee1eSDan Willemsen		case protoreflect.Sint64Kind:
454*1c12ee1eSDan Willemsen			return coderSint64SliceValue
455*1c12ee1eSDan Willemsen		case protoreflect.Uint64Kind:
456*1c12ee1eSDan Willemsen			return coderUint64SliceValue
457*1c12ee1eSDan Willemsen		case protoreflect.Sfixed32Kind:
458*1c12ee1eSDan Willemsen			return coderSfixed32SliceValue
459*1c12ee1eSDan Willemsen		case protoreflect.Fixed32Kind:
460*1c12ee1eSDan Willemsen			return coderFixed32SliceValue
461*1c12ee1eSDan Willemsen		case protoreflect.FloatKind:
462*1c12ee1eSDan Willemsen			return coderFloatSliceValue
463*1c12ee1eSDan Willemsen		case protoreflect.Sfixed64Kind:
464*1c12ee1eSDan Willemsen			return coderSfixed64SliceValue
465*1c12ee1eSDan Willemsen		case protoreflect.Fixed64Kind:
466*1c12ee1eSDan Willemsen			return coderFixed64SliceValue
467*1c12ee1eSDan Willemsen		case protoreflect.DoubleKind:
468*1c12ee1eSDan Willemsen			return coderDoubleSliceValue
469*1c12ee1eSDan Willemsen		case protoreflect.StringKind:
470*1c12ee1eSDan Willemsen			// We don't have a UTF-8 validating coder for repeated string fields.
471*1c12ee1eSDan Willemsen			// Value coders are used for extensions and maps.
472*1c12ee1eSDan Willemsen			// Extensions are never proto3, and maps never contain lists.
473*1c12ee1eSDan Willemsen			return coderStringSliceValue
474*1c12ee1eSDan Willemsen		case protoreflect.BytesKind:
475*1c12ee1eSDan Willemsen			return coderBytesSliceValue
476*1c12ee1eSDan Willemsen		case protoreflect.MessageKind:
477*1c12ee1eSDan Willemsen			return coderMessageSliceValue
478*1c12ee1eSDan Willemsen		case protoreflect.GroupKind:
479*1c12ee1eSDan Willemsen			return coderGroupSliceValue
480*1c12ee1eSDan Willemsen		}
481*1c12ee1eSDan Willemsen	case fd.Cardinality() == protoreflect.Repeated && fd.IsPacked():
482*1c12ee1eSDan Willemsen		switch fd.Kind() {
483*1c12ee1eSDan Willemsen		case protoreflect.BoolKind:
484*1c12ee1eSDan Willemsen			return coderBoolPackedSliceValue
485*1c12ee1eSDan Willemsen		case protoreflect.EnumKind:
486*1c12ee1eSDan Willemsen			return coderEnumPackedSliceValue
487*1c12ee1eSDan Willemsen		case protoreflect.Int32Kind:
488*1c12ee1eSDan Willemsen			return coderInt32PackedSliceValue
489*1c12ee1eSDan Willemsen		case protoreflect.Sint32Kind:
490*1c12ee1eSDan Willemsen			return coderSint32PackedSliceValue
491*1c12ee1eSDan Willemsen		case protoreflect.Uint32Kind:
492*1c12ee1eSDan Willemsen			return coderUint32PackedSliceValue
493*1c12ee1eSDan Willemsen		case protoreflect.Int64Kind:
494*1c12ee1eSDan Willemsen			return coderInt64PackedSliceValue
495*1c12ee1eSDan Willemsen		case protoreflect.Sint64Kind:
496*1c12ee1eSDan Willemsen			return coderSint64PackedSliceValue
497*1c12ee1eSDan Willemsen		case protoreflect.Uint64Kind:
498*1c12ee1eSDan Willemsen			return coderUint64PackedSliceValue
499*1c12ee1eSDan Willemsen		case protoreflect.Sfixed32Kind:
500*1c12ee1eSDan Willemsen			return coderSfixed32PackedSliceValue
501*1c12ee1eSDan Willemsen		case protoreflect.Fixed32Kind:
502*1c12ee1eSDan Willemsen			return coderFixed32PackedSliceValue
503*1c12ee1eSDan Willemsen		case protoreflect.FloatKind:
504*1c12ee1eSDan Willemsen			return coderFloatPackedSliceValue
505*1c12ee1eSDan Willemsen		case protoreflect.Sfixed64Kind:
506*1c12ee1eSDan Willemsen			return coderSfixed64PackedSliceValue
507*1c12ee1eSDan Willemsen		case protoreflect.Fixed64Kind:
508*1c12ee1eSDan Willemsen			return coderFixed64PackedSliceValue
509*1c12ee1eSDan Willemsen		case protoreflect.DoubleKind:
510*1c12ee1eSDan Willemsen			return coderDoublePackedSliceValue
511*1c12ee1eSDan Willemsen		}
512*1c12ee1eSDan Willemsen	default:
513*1c12ee1eSDan Willemsen		switch fd.Kind() {
514*1c12ee1eSDan Willemsen		default:
515*1c12ee1eSDan Willemsen		case protoreflect.BoolKind:
516*1c12ee1eSDan Willemsen			return coderBoolValue
517*1c12ee1eSDan Willemsen		case protoreflect.EnumKind:
518*1c12ee1eSDan Willemsen			return coderEnumValue
519*1c12ee1eSDan Willemsen		case protoreflect.Int32Kind:
520*1c12ee1eSDan Willemsen			return coderInt32Value
521*1c12ee1eSDan Willemsen		case protoreflect.Sint32Kind:
522*1c12ee1eSDan Willemsen			return coderSint32Value
523*1c12ee1eSDan Willemsen		case protoreflect.Uint32Kind:
524*1c12ee1eSDan Willemsen			return coderUint32Value
525*1c12ee1eSDan Willemsen		case protoreflect.Int64Kind:
526*1c12ee1eSDan Willemsen			return coderInt64Value
527*1c12ee1eSDan Willemsen		case protoreflect.Sint64Kind:
528*1c12ee1eSDan Willemsen			return coderSint64Value
529*1c12ee1eSDan Willemsen		case protoreflect.Uint64Kind:
530*1c12ee1eSDan Willemsen			return coderUint64Value
531*1c12ee1eSDan Willemsen		case protoreflect.Sfixed32Kind:
532*1c12ee1eSDan Willemsen			return coderSfixed32Value
533*1c12ee1eSDan Willemsen		case protoreflect.Fixed32Kind:
534*1c12ee1eSDan Willemsen			return coderFixed32Value
535*1c12ee1eSDan Willemsen		case protoreflect.FloatKind:
536*1c12ee1eSDan Willemsen			return coderFloatValue
537*1c12ee1eSDan Willemsen		case protoreflect.Sfixed64Kind:
538*1c12ee1eSDan Willemsen			return coderSfixed64Value
539*1c12ee1eSDan Willemsen		case protoreflect.Fixed64Kind:
540*1c12ee1eSDan Willemsen			return coderFixed64Value
541*1c12ee1eSDan Willemsen		case protoreflect.DoubleKind:
542*1c12ee1eSDan Willemsen			return coderDoubleValue
543*1c12ee1eSDan Willemsen		case protoreflect.StringKind:
544*1c12ee1eSDan Willemsen			if strs.EnforceUTF8(fd) {
545*1c12ee1eSDan Willemsen				return coderStringValueValidateUTF8
546*1c12ee1eSDan Willemsen			}
547*1c12ee1eSDan Willemsen			return coderStringValue
548*1c12ee1eSDan Willemsen		case protoreflect.BytesKind:
549*1c12ee1eSDan Willemsen			return coderBytesValue
550*1c12ee1eSDan Willemsen		case protoreflect.MessageKind:
551*1c12ee1eSDan Willemsen			return coderMessageValue
552*1c12ee1eSDan Willemsen		case protoreflect.GroupKind:
553*1c12ee1eSDan Willemsen			return coderGroupValue
554*1c12ee1eSDan Willemsen		}
555*1c12ee1eSDan Willemsen	}
556*1c12ee1eSDan Willemsen	panic(fmt.Sprintf("invalid field: no encoder for %v %v %v", fd.FullName(), fd.Cardinality(), fd.Kind()))
557*1c12ee1eSDan Willemsen}
558