blob: 564187e4d863ed222d2bfc30c74016a4b0f26d11 [file] [log] [blame]
Damien Neilc37adef2019-04-01 13:49:56 -07001// Copyright 2019 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
5package impl
6
7import (
8 "fmt"
9 "reflect"
10
Damien Neile91877d2019-06-27 10:54:42 -070011 "google.golang.org/protobuf/internal/encoding/wire"
Damien Neilc37adef2019-04-01 13:49:56 -070012 pref "google.golang.org/protobuf/reflect/protoreflect"
13)
14
15// pointerCoderFuncs is a set of pointer encoding functions.
16type pointerCoderFuncs struct {
Damien Neile91877d2019-06-27 10:54:42 -070017 size func(p pointer, tagsize int, opts marshalOptions) int
18 marshal func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error)
19 unmarshal func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (int, error)
20 isInit func(p pointer) error
Damien Neilc37adef2019-04-01 13:49:56 -070021}
22
23// ifaceCoderFuncs is a set of interface{} encoding functions.
24type ifaceCoderFuncs struct {
Damien Neile91877d2019-06-27 10:54:42 -070025 size func(ival interface{}, tagsize int, opts marshalOptions) int
26 marshal func(b []byte, ival interface{}, wiretag uint64, opts marshalOptions) ([]byte, error)
27 unmarshal func(b []byte, ival interface{}, num wire.Number, wtyp wire.Type, opts unmarshalOptions) (interface{}, int, error)
28 isInit func(ival interface{}) error
Damien Neilc37adef2019-04-01 13:49:56 -070029}
30
31// fieldCoder returns pointer functions for a field, used for operating on
32// struct fields.
33func fieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
34 switch {
Damien Neil4ae30bb2019-06-20 10:12:23 -070035 case fd.IsMap():
36 return encoderFuncsForMap(fd, ft)
Damien Neilc37adef2019-04-01 13:49:56 -070037 case fd.Cardinality() == pref.Repeated && !fd.IsPacked():
38 // Repeated fields (not packed).
39 if ft.Kind() != reflect.Slice {
40 break
41 }
42 ft := ft.Elem()
43 switch fd.Kind() {
44 case pref.BoolKind:
45 if ft.Kind() == reflect.Bool {
46 return coderBoolSlice
47 }
48 case pref.EnumKind:
49 if ft.Kind() == reflect.Int32 {
50 return coderEnumSlice
51 }
52 case pref.Int32Kind:
53 if ft.Kind() == reflect.Int32 {
54 return coderInt32Slice
55 }
56 case pref.Sint32Kind:
57 if ft.Kind() == reflect.Int32 {
58 return coderSint32Slice
59 }
60 case pref.Uint32Kind:
61 if ft.Kind() == reflect.Uint32 {
62 return coderUint32Slice
63 }
64 case pref.Int64Kind:
65 if ft.Kind() == reflect.Int64 {
66 return coderInt64Slice
67 }
68 case pref.Sint64Kind:
69 if ft.Kind() == reflect.Int64 {
70 return coderSint64Slice
71 }
72 case pref.Uint64Kind:
73 if ft.Kind() == reflect.Uint64 {
74 return coderUint64Slice
75 }
76 case pref.Sfixed32Kind:
77 if ft.Kind() == reflect.Int32 {
78 return coderSfixed32Slice
79 }
80 case pref.Fixed32Kind:
81 if ft.Kind() == reflect.Uint32 {
82 return coderFixed32Slice
83 }
84 case pref.FloatKind:
85 if ft.Kind() == reflect.Float32 {
86 return coderFloatSlice
87 }
88 case pref.Sfixed64Kind:
89 if ft.Kind() == reflect.Int64 {
90 return coderSfixed64Slice
91 }
92 case pref.Fixed64Kind:
93 if ft.Kind() == reflect.Uint64 {
94 return coderFixed64Slice
95 }
96 case pref.DoubleKind:
97 if ft.Kind() == reflect.Float64 {
98 return coderDoubleSlice
99 }
100 case pref.StringKind:
101 if ft.Kind() == reflect.String && fd.Syntax() == pref.Proto3 {
102 return coderStringSliceValidateUTF8
103 }
104 if ft.Kind() == reflect.String {
105 return coderStringSlice
106 }
107 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
108 return coderBytesSlice
109 }
110 case pref.BytesKind:
111 if ft.Kind() == reflect.String {
112 return coderStringSlice
113 }
114 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
115 return coderBytesSlice
116 }
117 case pref.MessageKind:
118 return makeMessageSliceFieldCoder(fd, ft)
119 case pref.GroupKind:
120 return makeGroupSliceFieldCoder(fd, ft)
121 }
122 case fd.Cardinality() == pref.Repeated && fd.IsPacked():
123 // Packed repeated fields.
124 //
125 // Only repeated fields of primitive numeric types
126 // (Varint, Fixed32, or Fixed64 wire type) can be packed.
127 if ft.Kind() != reflect.Slice {
128 break
129 }
130 ft := ft.Elem()
131 switch fd.Kind() {
132 case pref.BoolKind:
133 if ft.Kind() == reflect.Bool {
134 return coderBoolPackedSlice
135 }
136 case pref.EnumKind:
137 if ft.Kind() == reflect.Int32 {
138 return coderEnumPackedSlice
139 }
140 case pref.Int32Kind:
141 if ft.Kind() == reflect.Int32 {
142 return coderInt32PackedSlice
143 }
144 case pref.Sint32Kind:
145 if ft.Kind() == reflect.Int32 {
146 return coderSint32PackedSlice
147 }
148 case pref.Uint32Kind:
149 if ft.Kind() == reflect.Uint32 {
150 return coderUint32PackedSlice
151 }
152 case pref.Int64Kind:
153 if ft.Kind() == reflect.Int64 {
154 return coderInt64PackedSlice
155 }
156 case pref.Sint64Kind:
157 if ft.Kind() == reflect.Int64 {
158 return coderSint64PackedSlice
159 }
160 case pref.Uint64Kind:
161 if ft.Kind() == reflect.Uint64 {
162 return coderUint64PackedSlice
163 }
164 case pref.Sfixed32Kind:
165 if ft.Kind() == reflect.Int32 {
166 return coderSfixed32PackedSlice
167 }
168 case pref.Fixed32Kind:
169 if ft.Kind() == reflect.Uint32 {
170 return coderFixed32PackedSlice
171 }
172 case pref.FloatKind:
173 if ft.Kind() == reflect.Float32 {
174 return coderFloatPackedSlice
175 }
176 case pref.Sfixed64Kind:
177 if ft.Kind() == reflect.Int64 {
178 return coderSfixed64PackedSlice
179 }
180 case pref.Fixed64Kind:
181 if ft.Kind() == reflect.Uint64 {
182 return coderFixed64PackedSlice
183 }
184 case pref.DoubleKind:
185 if ft.Kind() == reflect.Float64 {
186 return coderDoublePackedSlice
187 }
188 }
189 case fd.Kind() == pref.MessageKind:
190 return makeMessageFieldCoder(fd, ft)
191 case fd.Kind() == pref.GroupKind:
192 return makeGroupFieldCoder(fd, ft)
193 case fd.Syntax() == pref.Proto3 && fd.ContainingOneof() == nil:
194 // Populated oneof fields always encode even if set to the zero value,
195 // which normally are not encoded in proto3.
196 switch fd.Kind() {
197 case pref.BoolKind:
198 if ft.Kind() == reflect.Bool {
199 return coderBoolNoZero
200 }
201 case pref.EnumKind:
202 if ft.Kind() == reflect.Int32 {
203 return coderEnumNoZero
204 }
205 case pref.Int32Kind:
206 if ft.Kind() == reflect.Int32 {
207 return coderInt32NoZero
208 }
209 case pref.Sint32Kind:
210 if ft.Kind() == reflect.Int32 {
211 return coderSint32NoZero
212 }
213 case pref.Uint32Kind:
214 if ft.Kind() == reflect.Uint32 {
215 return coderUint32NoZero
216 }
217 case pref.Int64Kind:
218 if ft.Kind() == reflect.Int64 {
219 return coderInt64NoZero
220 }
221 case pref.Sint64Kind:
222 if ft.Kind() == reflect.Int64 {
223 return coderSint64NoZero
224 }
225 case pref.Uint64Kind:
226 if ft.Kind() == reflect.Uint64 {
227 return coderUint64NoZero
228 }
229 case pref.Sfixed32Kind:
230 if ft.Kind() == reflect.Int32 {
231 return coderSfixed32NoZero
232 }
233 case pref.Fixed32Kind:
234 if ft.Kind() == reflect.Uint32 {
235 return coderFixed32NoZero
236 }
237 case pref.FloatKind:
238 if ft.Kind() == reflect.Float32 {
239 return coderFloatNoZero
240 }
241 case pref.Sfixed64Kind:
242 if ft.Kind() == reflect.Int64 {
243 return coderSfixed64NoZero
244 }
245 case pref.Fixed64Kind:
246 if ft.Kind() == reflect.Uint64 {
247 return coderFixed64NoZero
248 }
249 case pref.DoubleKind:
250 if ft.Kind() == reflect.Float64 {
251 return coderDoubleNoZero
252 }
253 case pref.StringKind:
254 if ft.Kind() == reflect.String {
255 return coderStringNoZeroValidateUTF8
256 }
257 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
258 return coderBytesNoZero
259 }
260 case pref.BytesKind:
261 if ft.Kind() == reflect.String {
262 return coderStringNoZero
263 }
264 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
265 return coderBytesNoZero
266 }
267 }
268 case ft.Kind() == reflect.Ptr:
269 ft := ft.Elem()
270 switch fd.Kind() {
271 case pref.BoolKind:
272 if ft.Kind() == reflect.Bool {
273 return coderBoolPtr
274 }
275 case pref.EnumKind:
276 if ft.Kind() == reflect.Int32 {
277 return coderEnumPtr
278 }
279 case pref.Int32Kind:
280 if ft.Kind() == reflect.Int32 {
281 return coderInt32Ptr
282 }
283 case pref.Sint32Kind:
284 if ft.Kind() == reflect.Int32 {
285 return coderSint32Ptr
286 }
287 case pref.Uint32Kind:
288 if ft.Kind() == reflect.Uint32 {
289 return coderUint32Ptr
290 }
291 case pref.Int64Kind:
292 if ft.Kind() == reflect.Int64 {
293 return coderInt64Ptr
294 }
295 case pref.Sint64Kind:
296 if ft.Kind() == reflect.Int64 {
297 return coderSint64Ptr
298 }
299 case pref.Uint64Kind:
300 if ft.Kind() == reflect.Uint64 {
301 return coderUint64Ptr
302 }
303 case pref.Sfixed32Kind:
304 if ft.Kind() == reflect.Int32 {
305 return coderSfixed32Ptr
306 }
307 case pref.Fixed32Kind:
308 if ft.Kind() == reflect.Uint32 {
309 return coderFixed32Ptr
310 }
311 case pref.FloatKind:
312 if ft.Kind() == reflect.Float32 {
313 return coderFloatPtr
314 }
315 case pref.Sfixed64Kind:
316 if ft.Kind() == reflect.Int64 {
317 return coderSfixed64Ptr
318 }
319 case pref.Fixed64Kind:
320 if ft.Kind() == reflect.Uint64 {
321 return coderFixed64Ptr
322 }
323 case pref.DoubleKind:
324 if ft.Kind() == reflect.Float64 {
325 return coderDoublePtr
326 }
327 case pref.StringKind:
328 if ft.Kind() == reflect.String {
329 return coderStringPtr
330 }
331 case pref.BytesKind:
332 if ft.Kind() == reflect.String {
333 return coderStringPtr
334 }
335 }
336 default:
337 switch fd.Kind() {
338 case pref.BoolKind:
339 if ft.Kind() == reflect.Bool {
340 return coderBool
341 }
342 case pref.EnumKind:
343 if ft.Kind() == reflect.Int32 {
344 return coderEnum
345 }
346 case pref.Int32Kind:
347 if ft.Kind() == reflect.Int32 {
348 return coderInt32
349 }
350 case pref.Sint32Kind:
351 if ft.Kind() == reflect.Int32 {
352 return coderSint32
353 }
354 case pref.Uint32Kind:
355 if ft.Kind() == reflect.Uint32 {
356 return coderUint32
357 }
358 case pref.Int64Kind:
359 if ft.Kind() == reflect.Int64 {
360 return coderInt64
361 }
362 case pref.Sint64Kind:
363 if ft.Kind() == reflect.Int64 {
364 return coderSint64
365 }
366 case pref.Uint64Kind:
367 if ft.Kind() == reflect.Uint64 {
368 return coderUint64
369 }
370 case pref.Sfixed32Kind:
371 if ft.Kind() == reflect.Int32 {
372 return coderSfixed32
373 }
374 case pref.Fixed32Kind:
375 if ft.Kind() == reflect.Uint32 {
376 return coderFixed32
377 }
378 case pref.FloatKind:
379 if ft.Kind() == reflect.Float32 {
380 return coderFloat
381 }
382 case pref.Sfixed64Kind:
383 if ft.Kind() == reflect.Int64 {
384 return coderSfixed64
385 }
386 case pref.Fixed64Kind:
387 if ft.Kind() == reflect.Uint64 {
388 return coderFixed64
389 }
390 case pref.DoubleKind:
391 if ft.Kind() == reflect.Float64 {
392 return coderDouble
393 }
394 case pref.StringKind:
395 if fd.Syntax() == pref.Proto3 && ft.Kind() == reflect.String {
396 return coderStringValidateUTF8
397 }
398 if ft.Kind() == reflect.String {
399 return coderString
400 }
401 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
402 return coderBytes
403 }
404 case pref.BytesKind:
405 if ft.Kind() == reflect.String {
406 return coderString
407 }
408 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
409 return coderBytes
410 }
411 }
412 }
413 panic(fmt.Errorf("invalid type: no encoder for %v %v %v/%v", fd.FullName(), fd.Cardinality(), fd.Kind(), ft))
414}
415
416// encoderFuncsForValue returns interface{} value functions for a field, used for
417// extension values and map encoding.
418func encoderFuncsForValue(fd pref.FieldDescriptor, ft reflect.Type) ifaceCoderFuncs {
419 switch {
420 case fd.Cardinality() == pref.Repeated && !fd.IsPacked():
421 if ft.Kind() != reflect.Ptr || ft.Elem().Kind() != reflect.Slice {
422 break
423 }
424 ft := ft.Elem().Elem()
425 switch fd.Kind() {
426 case pref.BoolKind:
427 if ft.Kind() == reflect.Bool {
428 return coderBoolSliceIface
429 }
430 case pref.EnumKind:
431 if ft.Kind() == reflect.Int32 {
432 return coderEnumSliceIface
433 }
434 case pref.Int32Kind:
435 if ft.Kind() == reflect.Int32 {
436 return coderInt32SliceIface
437 }
438 case pref.Sint32Kind:
439 if ft.Kind() == reflect.Int32 {
440 return coderSint32SliceIface
441 }
442 case pref.Uint32Kind:
443 if ft.Kind() == reflect.Uint32 {
444 return coderUint32SliceIface
445 }
446 case pref.Int64Kind:
447 if ft.Kind() == reflect.Int64 {
448 return coderInt64SliceIface
449 }
450 case pref.Sint64Kind:
451 if ft.Kind() == reflect.Int64 {
452 return coderSint64SliceIface
453 }
454 case pref.Uint64Kind:
455 if ft.Kind() == reflect.Uint64 {
456 return coderUint64SliceIface
457 }
458 case pref.Sfixed32Kind:
459 if ft.Kind() == reflect.Int32 {
460 return coderSfixed32SliceIface
461 }
462 case pref.Fixed32Kind:
463 if ft.Kind() == reflect.Uint32 {
464 return coderFixed32SliceIface
465 }
466 case pref.FloatKind:
467 if ft.Kind() == reflect.Float32 {
468 return coderFloatSliceIface
469 }
470 case pref.Sfixed64Kind:
471 if ft.Kind() == reflect.Int64 {
472 return coderSfixed64SliceIface
473 }
474 case pref.Fixed64Kind:
475 if ft.Kind() == reflect.Uint64 {
476 return coderFixed64SliceIface
477 }
478 case pref.DoubleKind:
479 if ft.Kind() == reflect.Float64 {
480 return coderDoubleSliceIface
481 }
482 case pref.StringKind:
483 if ft.Kind() == reflect.String {
484 return coderStringSliceIface
485 }
486 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
487 return coderBytesSliceIface
488 }
489 case pref.BytesKind:
490 if ft.Kind() == reflect.String {
491 return coderStringSliceIface
492 }
493 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
494 return coderBytesSliceIface
495 }
496 case pref.MessageKind:
497 return coderMessageSliceIface
498 case pref.GroupKind:
499 return coderGroupSliceIface
500 }
501 case fd.Cardinality() == pref.Repeated && fd.IsPacked():
Damien Neil7492a092019-07-10 15:23:29 -0700502 if ft.Kind() != reflect.Ptr || ft.Elem().Kind() != reflect.Slice {
503 break
504 }
505 ft := ft.Elem().Elem()
506 switch fd.Kind() {
507 case pref.BoolKind:
508 if ft.Kind() == reflect.Bool {
509 return coderBoolPackedSliceIface
510 }
511 case pref.EnumKind:
512 if ft.Kind() == reflect.Int32 {
513 return coderEnumPackedSliceIface
514 }
515 case pref.Int32Kind:
516 if ft.Kind() == reflect.Int32 {
517 return coderInt32PackedSliceIface
518 }
519 case pref.Sint32Kind:
520 if ft.Kind() == reflect.Int32 {
521 return coderSint32PackedSliceIface
522 }
523 case pref.Uint32Kind:
524 if ft.Kind() == reflect.Uint32 {
525 return coderUint32PackedSliceIface
526 }
527 case pref.Int64Kind:
528 if ft.Kind() == reflect.Int64 {
529 return coderInt64PackedSliceIface
530 }
531 case pref.Sint64Kind:
532 if ft.Kind() == reflect.Int64 {
533 return coderSint64PackedSliceIface
534 }
535 case pref.Uint64Kind:
536 if ft.Kind() == reflect.Uint64 {
537 return coderUint64PackedSliceIface
538 }
539 case pref.Sfixed32Kind:
540 if ft.Kind() == reflect.Int32 {
541 return coderSfixed32PackedSliceIface
542 }
543 case pref.Fixed32Kind:
544 if ft.Kind() == reflect.Uint32 {
545 return coderFixed32PackedSliceIface
546 }
547 case pref.FloatKind:
548 if ft.Kind() == reflect.Float32 {
549 return coderFloatPackedSliceIface
550 }
551 case pref.Sfixed64Kind:
552 if ft.Kind() == reflect.Int64 {
553 return coderSfixed64PackedSliceIface
554 }
555 case pref.Fixed64Kind:
556 if ft.Kind() == reflect.Uint64 {
557 return coderFixed64PackedSliceIface
558 }
559 case pref.DoubleKind:
560 if ft.Kind() == reflect.Float64 {
561 return coderDoublePackedSliceIface
562 }
563 }
Damien Neilc37adef2019-04-01 13:49:56 -0700564 default:
565 switch fd.Kind() {
566 case pref.BoolKind:
567 if ft.Kind() == reflect.Bool {
568 return coderBoolIface
569 }
570 case pref.EnumKind:
571 if ft.Kind() == reflect.Int32 {
572 return coderEnumIface
573 }
574 case pref.Int32Kind:
575 if ft.Kind() == reflect.Int32 {
576 return coderInt32Iface
577 }
578 case pref.Sint32Kind:
579 if ft.Kind() == reflect.Int32 {
580 return coderSint32Iface
581 }
582 case pref.Uint32Kind:
583 if ft.Kind() == reflect.Uint32 {
584 return coderUint32Iface
585 }
586 case pref.Int64Kind:
587 if ft.Kind() == reflect.Int64 {
588 return coderInt64Iface
589 }
590 case pref.Sint64Kind:
591 if ft.Kind() == reflect.Int64 {
592 return coderSint64Iface
593 }
594 case pref.Uint64Kind:
595 if ft.Kind() == reflect.Uint64 {
596 return coderUint64Iface
597 }
598 case pref.Sfixed32Kind:
599 if ft.Kind() == reflect.Int32 {
600 return coderSfixed32Iface
601 }
602 case pref.Fixed32Kind:
603 if ft.Kind() == reflect.Uint32 {
604 return coderFixed32Iface
605 }
606 case pref.FloatKind:
607 if ft.Kind() == reflect.Float32 {
608 return coderFloatIface
609 }
610 case pref.Sfixed64Kind:
611 if ft.Kind() == reflect.Int64 {
612 return coderSfixed64Iface
613 }
614 case pref.Fixed64Kind:
615 if ft.Kind() == reflect.Uint64 {
616 return coderFixed64Iface
617 }
618 case pref.DoubleKind:
619 if ft.Kind() == reflect.Float64 {
620 return coderDoubleIface
621 }
622 case pref.StringKind:
623 if fd.Syntax() == pref.Proto3 && ft.Kind() == reflect.String {
624 return coderStringIfaceValidateUTF8
625 }
626 if ft.Kind() == reflect.String {
627 return coderStringIface
628 }
629 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
630 return coderBytesIface
631 }
632 case pref.BytesKind:
633 if ft.Kind() == reflect.String {
634 return coderStringIface
635 }
636 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
637 return coderBytesIface
638 }
639 case pref.MessageKind:
640 return coderMessageIface
641 case pref.GroupKind:
Damien Neile91877d2019-06-27 10:54:42 -0700642 return makeGroupValueCoder(fd, ft)
Damien Neilc37adef2019-04-01 13:49:56 -0700643 }
644 }
645 panic(fmt.Errorf("invalid type: no encoder for %v %v %v/%v", fd.FullName(), fd.Cardinality(), fd.Kind(), ft))
646}