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