blob: c934c8d3ca8d2d883c366e2bec0e82bfe9e71435 [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
Joe Tsaicd108d02020-02-14 18:08:02 -080011 "google.golang.org/protobuf/encoding/protowire"
Joe Tsaic51e2e02019-07-13 00:44:41 -070012 "google.golang.org/protobuf/internal/strs"
Damien Neilc37adef2019-04-01 13:49:56 -070013 pref "google.golang.org/protobuf/reflect/protoreflect"
14)
15
16// pointerCoderFuncs is a set of pointer encoding functions.
17type pointerCoderFuncs struct {
Damien Neil316febd2020-02-09 12:26:50 -080018 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)
Joe Tsaicd108d02020-02-14 18:08:02 -080021 unmarshal func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error)
Damien Neil316febd2020-02-09 12:26:50 -080022 isInit func(p pointer, f *coderFieldInfo) error
Damien Neile8e88752020-02-11 11:25:16 -080023 merge func(dst, src pointer, f *coderFieldInfo, opts mergeOptions)
Damien Neilc37adef2019-04-01 13:49:56 -070024}
25
Damien Neil68b81c32019-08-22 11:41:32 -070026// 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)
Joe Tsaicd108d02020-02-14 18:08:02 -080030 unmarshal func(b []byte, v pref.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (pref.Value, unmarshalOutput, error)
Damien Neil68b81c32019-08-22 11:41:32 -070031 isInit func(v pref.Value) error
Damien Neile8e88752020-02-11 11:25:16 -080032 merge func(dst, src pref.Value, opts mergeOptions) pref.Value
Damien Neilc37adef2019-04-01 13:49:56 -070033}
34
35// fieldCoder returns pointer functions for a field, used for operating on
36// struct fields.
Damien Neil316febd2020-02-09 12:26:50 -080037func fieldCoder(fd pref.FieldDescriptor, ft reflect.Type) (*MessageInfo, pointerCoderFuncs) {
Damien Neilc37adef2019-04-01 13:49:56 -070038 switch {
Damien Neil4ae30bb2019-06-20 10:12:23 -070039 case fd.IsMap():
40 return encoderFuncsForMap(fd, ft)
Damien Neilc37adef2019-04-01 13:49:56 -070041 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 {
Damien Neil316febd2020-02-09 12:26:50 -080050 return nil, coderBoolSlice
Damien Neilc37adef2019-04-01 13:49:56 -070051 }
52 case pref.EnumKind:
53 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -080054 return nil, coderEnumSlice
Damien Neilc37adef2019-04-01 13:49:56 -070055 }
56 case pref.Int32Kind:
57 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -080058 return nil, coderInt32Slice
Damien Neilc37adef2019-04-01 13:49:56 -070059 }
60 case pref.Sint32Kind:
61 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -080062 return nil, coderSint32Slice
Damien Neilc37adef2019-04-01 13:49:56 -070063 }
64 case pref.Uint32Kind:
65 if ft.Kind() == reflect.Uint32 {
Damien Neil316febd2020-02-09 12:26:50 -080066 return nil, coderUint32Slice
Damien Neilc37adef2019-04-01 13:49:56 -070067 }
68 case pref.Int64Kind:
69 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -080070 return nil, coderInt64Slice
Damien Neilc37adef2019-04-01 13:49:56 -070071 }
72 case pref.Sint64Kind:
73 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -080074 return nil, coderSint64Slice
Damien Neilc37adef2019-04-01 13:49:56 -070075 }
76 case pref.Uint64Kind:
77 if ft.Kind() == reflect.Uint64 {
Damien Neil316febd2020-02-09 12:26:50 -080078 return nil, coderUint64Slice
Damien Neilc37adef2019-04-01 13:49:56 -070079 }
80 case pref.Sfixed32Kind:
81 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -080082 return nil, coderSfixed32Slice
Damien Neilc37adef2019-04-01 13:49:56 -070083 }
84 case pref.Fixed32Kind:
85 if ft.Kind() == reflect.Uint32 {
Damien Neil316febd2020-02-09 12:26:50 -080086 return nil, coderFixed32Slice
Damien Neilc37adef2019-04-01 13:49:56 -070087 }
88 case pref.FloatKind:
89 if ft.Kind() == reflect.Float32 {
Damien Neil316febd2020-02-09 12:26:50 -080090 return nil, coderFloatSlice
Damien Neilc37adef2019-04-01 13:49:56 -070091 }
92 case pref.Sfixed64Kind:
93 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -080094 return nil, coderSfixed64Slice
Damien Neilc37adef2019-04-01 13:49:56 -070095 }
96 case pref.Fixed64Kind:
97 if ft.Kind() == reflect.Uint64 {
Damien Neil316febd2020-02-09 12:26:50 -080098 return nil, coderFixed64Slice
Damien Neilc37adef2019-04-01 13:49:56 -070099 }
100 case pref.DoubleKind:
101 if ft.Kind() == reflect.Float64 {
Damien Neil316febd2020-02-09 12:26:50 -0800102 return nil, coderDoubleSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700103 }
104 case pref.StringKind:
Joe Tsaic51e2e02019-07-13 00:44:41 -0700105 if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) {
Damien Neil316febd2020-02-09 12:26:50 -0800106 return nil, coderStringSliceValidateUTF8
Damien Neilc37adef2019-04-01 13:49:56 -0700107 }
108 if ft.Kind() == reflect.String {
Damien Neil316febd2020-02-09 12:26:50 -0800109 return nil, coderStringSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700110 }
Joe Tsaic51e2e02019-07-13 00:44:41 -0700111 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 && strs.EnforceUTF8(fd) {
Damien Neil316febd2020-02-09 12:26:50 -0800112 return nil, coderBytesSliceValidateUTF8
Joe Tsaic51e2e02019-07-13 00:44:41 -0700113 }
Damien Neilc37adef2019-04-01 13:49:56 -0700114 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
Damien Neil316febd2020-02-09 12:26:50 -0800115 return nil, coderBytesSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700116 }
117 case pref.BytesKind:
118 if ft.Kind() == reflect.String {
Damien Neil316febd2020-02-09 12:26:50 -0800119 return nil, coderStringSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700120 }
121 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
Damien Neil316febd2020-02-09 12:26:50 -0800122 return nil, coderBytesSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700123 }
124 case pref.MessageKind:
Damien Neil316febd2020-02-09 12:26:50 -0800125 return getMessageInfo(ft), makeMessageSliceFieldCoder(fd, ft)
Damien Neilc37adef2019-04-01 13:49:56 -0700126 case pref.GroupKind:
Damien Neil316febd2020-02-09 12:26:50 -0800127 return getMessageInfo(ft), makeGroupSliceFieldCoder(fd, ft)
Damien Neilc37adef2019-04-01 13:49:56 -0700128 }
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 {
Damien Neil316febd2020-02-09 12:26:50 -0800141 return nil, coderBoolPackedSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700142 }
143 case pref.EnumKind:
144 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800145 return nil, coderEnumPackedSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700146 }
147 case pref.Int32Kind:
148 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800149 return nil, coderInt32PackedSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700150 }
151 case pref.Sint32Kind:
152 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800153 return nil, coderSint32PackedSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700154 }
155 case pref.Uint32Kind:
156 if ft.Kind() == reflect.Uint32 {
Damien Neil316febd2020-02-09 12:26:50 -0800157 return nil, coderUint32PackedSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700158 }
159 case pref.Int64Kind:
160 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -0800161 return nil, coderInt64PackedSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700162 }
163 case pref.Sint64Kind:
164 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -0800165 return nil, coderSint64PackedSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700166 }
167 case pref.Uint64Kind:
168 if ft.Kind() == reflect.Uint64 {
Damien Neil316febd2020-02-09 12:26:50 -0800169 return nil, coderUint64PackedSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700170 }
171 case pref.Sfixed32Kind:
172 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800173 return nil, coderSfixed32PackedSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700174 }
175 case pref.Fixed32Kind:
176 if ft.Kind() == reflect.Uint32 {
Damien Neil316febd2020-02-09 12:26:50 -0800177 return nil, coderFixed32PackedSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700178 }
179 case pref.FloatKind:
180 if ft.Kind() == reflect.Float32 {
Damien Neil316febd2020-02-09 12:26:50 -0800181 return nil, coderFloatPackedSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700182 }
183 case pref.Sfixed64Kind:
184 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -0800185 return nil, coderSfixed64PackedSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700186 }
187 case pref.Fixed64Kind:
188 if ft.Kind() == reflect.Uint64 {
Damien Neil316febd2020-02-09 12:26:50 -0800189 return nil, coderFixed64PackedSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700190 }
191 case pref.DoubleKind:
192 if ft.Kind() == reflect.Float64 {
Damien Neil316febd2020-02-09 12:26:50 -0800193 return nil, coderDoublePackedSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700194 }
195 }
196 case fd.Kind() == pref.MessageKind:
Damien Neil316febd2020-02-09 12:26:50 -0800197 return getMessageInfo(ft), makeMessageFieldCoder(fd, ft)
Damien Neilc37adef2019-04-01 13:49:56 -0700198 case fd.Kind() == pref.GroupKind:
Damien Neil316febd2020-02-09 12:26:50 -0800199 return getMessageInfo(ft), makeGroupFieldCoder(fd, ft)
Damien Neilc37adef2019-04-01 13:49:56 -0700200 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 {
Damien Neil316febd2020-02-09 12:26:50 -0800206 return nil, coderBoolNoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700207 }
208 case pref.EnumKind:
209 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800210 return nil, coderEnumNoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700211 }
212 case pref.Int32Kind:
213 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800214 return nil, coderInt32NoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700215 }
216 case pref.Sint32Kind:
217 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800218 return nil, coderSint32NoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700219 }
220 case pref.Uint32Kind:
221 if ft.Kind() == reflect.Uint32 {
Damien Neil316febd2020-02-09 12:26:50 -0800222 return nil, coderUint32NoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700223 }
224 case pref.Int64Kind:
225 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -0800226 return nil, coderInt64NoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700227 }
228 case pref.Sint64Kind:
229 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -0800230 return nil, coderSint64NoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700231 }
232 case pref.Uint64Kind:
233 if ft.Kind() == reflect.Uint64 {
Damien Neil316febd2020-02-09 12:26:50 -0800234 return nil, coderUint64NoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700235 }
236 case pref.Sfixed32Kind:
237 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800238 return nil, coderSfixed32NoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700239 }
240 case pref.Fixed32Kind:
241 if ft.Kind() == reflect.Uint32 {
Damien Neil316febd2020-02-09 12:26:50 -0800242 return nil, coderFixed32NoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700243 }
244 case pref.FloatKind:
245 if ft.Kind() == reflect.Float32 {
Damien Neil316febd2020-02-09 12:26:50 -0800246 return nil, coderFloatNoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700247 }
248 case pref.Sfixed64Kind:
249 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -0800250 return nil, coderSfixed64NoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700251 }
252 case pref.Fixed64Kind:
253 if ft.Kind() == reflect.Uint64 {
Damien Neil316febd2020-02-09 12:26:50 -0800254 return nil, coderFixed64NoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700255 }
256 case pref.DoubleKind:
257 if ft.Kind() == reflect.Float64 {
Damien Neil316febd2020-02-09 12:26:50 -0800258 return nil, coderDoubleNoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700259 }
260 case pref.StringKind:
Joe Tsaic51e2e02019-07-13 00:44:41 -0700261 if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) {
Damien Neil316febd2020-02-09 12:26:50 -0800262 return nil, coderStringNoZeroValidateUTF8
Damien Neilc37adef2019-04-01 13:49:56 -0700263 }
Joe Tsaic51e2e02019-07-13 00:44:41 -0700264 if ft.Kind() == reflect.String {
Damien Neil316febd2020-02-09 12:26:50 -0800265 return nil, coderStringNoZero
Joe Tsaic51e2e02019-07-13 00:44:41 -0700266 }
267 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 && strs.EnforceUTF8(fd) {
Damien Neil316febd2020-02-09 12:26:50 -0800268 return nil, coderBytesNoZeroValidateUTF8
Joe Tsaic51e2e02019-07-13 00:44:41 -0700269 }
Damien Neilc37adef2019-04-01 13:49:56 -0700270 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
Damien Neil316febd2020-02-09 12:26:50 -0800271 return nil, coderBytesNoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700272 }
273 case pref.BytesKind:
274 if ft.Kind() == reflect.String {
Damien Neil316febd2020-02-09 12:26:50 -0800275 return nil, coderStringNoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700276 }
277 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
Damien Neil316febd2020-02-09 12:26:50 -0800278 return nil, coderBytesNoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700279 }
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 {
Damien Neil316febd2020-02-09 12:26:50 -0800286 return nil, coderBoolPtr
Damien Neilc37adef2019-04-01 13:49:56 -0700287 }
288 case pref.EnumKind:
289 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800290 return nil, coderEnumPtr
Damien Neilc37adef2019-04-01 13:49:56 -0700291 }
292 case pref.Int32Kind:
293 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800294 return nil, coderInt32Ptr
Damien Neilc37adef2019-04-01 13:49:56 -0700295 }
296 case pref.Sint32Kind:
297 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800298 return nil, coderSint32Ptr
Damien Neilc37adef2019-04-01 13:49:56 -0700299 }
300 case pref.Uint32Kind:
301 if ft.Kind() == reflect.Uint32 {
Damien Neil316febd2020-02-09 12:26:50 -0800302 return nil, coderUint32Ptr
Damien Neilc37adef2019-04-01 13:49:56 -0700303 }
304 case pref.Int64Kind:
305 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -0800306 return nil, coderInt64Ptr
Damien Neilc37adef2019-04-01 13:49:56 -0700307 }
308 case pref.Sint64Kind:
309 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -0800310 return nil, coderSint64Ptr
Damien Neilc37adef2019-04-01 13:49:56 -0700311 }
312 case pref.Uint64Kind:
313 if ft.Kind() == reflect.Uint64 {
Damien Neil316febd2020-02-09 12:26:50 -0800314 return nil, coderUint64Ptr
Damien Neilc37adef2019-04-01 13:49:56 -0700315 }
316 case pref.Sfixed32Kind:
317 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800318 return nil, coderSfixed32Ptr
Damien Neilc37adef2019-04-01 13:49:56 -0700319 }
320 case pref.Fixed32Kind:
321 if ft.Kind() == reflect.Uint32 {
Damien Neil316febd2020-02-09 12:26:50 -0800322 return nil, coderFixed32Ptr
Damien Neilc37adef2019-04-01 13:49:56 -0700323 }
324 case pref.FloatKind:
325 if ft.Kind() == reflect.Float32 {
Damien Neil316febd2020-02-09 12:26:50 -0800326 return nil, coderFloatPtr
Damien Neilc37adef2019-04-01 13:49:56 -0700327 }
328 case pref.Sfixed64Kind:
329 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -0800330 return nil, coderSfixed64Ptr
Damien Neilc37adef2019-04-01 13:49:56 -0700331 }
332 case pref.Fixed64Kind:
333 if ft.Kind() == reflect.Uint64 {
Damien Neil316febd2020-02-09 12:26:50 -0800334 return nil, coderFixed64Ptr
Damien Neilc37adef2019-04-01 13:49:56 -0700335 }
336 case pref.DoubleKind:
337 if ft.Kind() == reflect.Float64 {
Damien Neil316febd2020-02-09 12:26:50 -0800338 return nil, coderDoublePtr
Damien Neilc37adef2019-04-01 13:49:56 -0700339 }
340 case pref.StringKind:
341 if ft.Kind() == reflect.String {
Damien Neil316febd2020-02-09 12:26:50 -0800342 return nil, coderStringPtr
Damien Neilc37adef2019-04-01 13:49:56 -0700343 }
344 case pref.BytesKind:
345 if ft.Kind() == reflect.String {
Damien Neil316febd2020-02-09 12:26:50 -0800346 return nil, coderStringPtr
Damien Neilc37adef2019-04-01 13:49:56 -0700347 }
348 }
349 default:
350 switch fd.Kind() {
351 case pref.BoolKind:
352 if ft.Kind() == reflect.Bool {
Damien Neil316febd2020-02-09 12:26:50 -0800353 return nil, coderBool
Damien Neilc37adef2019-04-01 13:49:56 -0700354 }
355 case pref.EnumKind:
356 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800357 return nil, coderEnum
Damien Neilc37adef2019-04-01 13:49:56 -0700358 }
359 case pref.Int32Kind:
360 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800361 return nil, coderInt32
Damien Neilc37adef2019-04-01 13:49:56 -0700362 }
363 case pref.Sint32Kind:
364 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800365 return nil, coderSint32
Damien Neilc37adef2019-04-01 13:49:56 -0700366 }
367 case pref.Uint32Kind:
368 if ft.Kind() == reflect.Uint32 {
Damien Neil316febd2020-02-09 12:26:50 -0800369 return nil, coderUint32
Damien Neilc37adef2019-04-01 13:49:56 -0700370 }
371 case pref.Int64Kind:
372 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -0800373 return nil, coderInt64
Damien Neilc37adef2019-04-01 13:49:56 -0700374 }
375 case pref.Sint64Kind:
376 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -0800377 return nil, coderSint64
Damien Neilc37adef2019-04-01 13:49:56 -0700378 }
379 case pref.Uint64Kind:
380 if ft.Kind() == reflect.Uint64 {
Damien Neil316febd2020-02-09 12:26:50 -0800381 return nil, coderUint64
Damien Neilc37adef2019-04-01 13:49:56 -0700382 }
383 case pref.Sfixed32Kind:
384 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800385 return nil, coderSfixed32
Damien Neilc37adef2019-04-01 13:49:56 -0700386 }
387 case pref.Fixed32Kind:
388 if ft.Kind() == reflect.Uint32 {
Damien Neil316febd2020-02-09 12:26:50 -0800389 return nil, coderFixed32
Damien Neilc37adef2019-04-01 13:49:56 -0700390 }
391 case pref.FloatKind:
392 if ft.Kind() == reflect.Float32 {
Damien Neil316febd2020-02-09 12:26:50 -0800393 return nil, coderFloat
Damien Neilc37adef2019-04-01 13:49:56 -0700394 }
395 case pref.Sfixed64Kind:
396 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -0800397 return nil, coderSfixed64
Damien Neilc37adef2019-04-01 13:49:56 -0700398 }
399 case pref.Fixed64Kind:
400 if ft.Kind() == reflect.Uint64 {
Damien Neil316febd2020-02-09 12:26:50 -0800401 return nil, coderFixed64
Damien Neilc37adef2019-04-01 13:49:56 -0700402 }
403 case pref.DoubleKind:
404 if ft.Kind() == reflect.Float64 {
Damien Neil316febd2020-02-09 12:26:50 -0800405 return nil, coderDouble
Damien Neilc37adef2019-04-01 13:49:56 -0700406 }
407 case pref.StringKind:
Joe Tsaic51e2e02019-07-13 00:44:41 -0700408 if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) {
Damien Neil316febd2020-02-09 12:26:50 -0800409 return nil, coderStringValidateUTF8
Damien Neilc37adef2019-04-01 13:49:56 -0700410 }
411 if ft.Kind() == reflect.String {
Damien Neil316febd2020-02-09 12:26:50 -0800412 return nil, coderString
Damien Neilc37adef2019-04-01 13:49:56 -0700413 }
Joe Tsaic51e2e02019-07-13 00:44:41 -0700414 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 && strs.EnforceUTF8(fd) {
Damien Neil316febd2020-02-09 12:26:50 -0800415 return nil, coderBytesValidateUTF8
Joe Tsaic51e2e02019-07-13 00:44:41 -0700416 }
Damien Neilc37adef2019-04-01 13:49:56 -0700417 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
Damien Neil316febd2020-02-09 12:26:50 -0800418 return nil, coderBytes
Damien Neilc37adef2019-04-01 13:49:56 -0700419 }
420 case pref.BytesKind:
421 if ft.Kind() == reflect.String {
Damien Neil316febd2020-02-09 12:26:50 -0800422 return nil, coderString
Damien Neilc37adef2019-04-01 13:49:56 -0700423 }
424 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
Damien Neil316febd2020-02-09 12:26:50 -0800425 return nil, coderBytes
Damien Neilc37adef2019-04-01 13:49:56 -0700426 }
427 }
428 }
Joe Tsai09217f02019-09-06 16:57:46 -0700429 panic(fmt.Sprintf("invalid type: no encoder for %v %v %v/%v", fd.FullName(), fd.Cardinality(), fd.Kind(), ft))
Damien Neilc37adef2019-04-01 13:49:56 -0700430}
431
Damien Neil4b3a82f2019-09-04 19:07:00 -0700432// encoderFuncsForValue returns value functions for a field, used for
Damien Neilc37adef2019-04-01 13:49:56 -0700433// extension values and map encoding.
Damien Neil4b3a82f2019-09-04 19:07:00 -0700434func encoderFuncsForValue(fd pref.FieldDescriptor) valueCoderFuncs {
Damien Neilc37adef2019-04-01 13:49:56 -0700435 switch {
436 case fd.Cardinality() == pref.Repeated && !fd.IsPacked():
Damien Neilc37adef2019-04-01 13:49:56 -0700437 switch fd.Kind() {
438 case pref.BoolKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700439 return coderBoolSliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700440 case pref.EnumKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700441 return coderEnumSliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700442 case pref.Int32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700443 return coderInt32SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700444 case pref.Sint32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700445 return coderSint32SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700446 case pref.Uint32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700447 return coderUint32SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700448 case pref.Int64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700449 return coderInt64SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700450 case pref.Sint64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700451 return coderSint64SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700452 case pref.Uint64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700453 return coderUint64SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700454 case pref.Sfixed32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700455 return coderSfixed32SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700456 case pref.Fixed32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700457 return coderFixed32SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700458 case pref.FloatKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700459 return coderFloatSliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700460 case pref.Sfixed64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700461 return coderSfixed64SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700462 case pref.Fixed64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700463 return coderFixed64SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700464 case pref.DoubleKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700465 return coderDoubleSliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700466 case pref.StringKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700467 // 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
Damien Neilc37adef2019-04-01 13:49:56 -0700471 case pref.BytesKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700472 return coderBytesSliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700473 case pref.MessageKind:
Damien Neil68b81c32019-08-22 11:41:32 -0700474 return coderMessageSliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700475 case pref.GroupKind:
Damien Neil68b81c32019-08-22 11:41:32 -0700476 return coderGroupSliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700477 }
478 case fd.Cardinality() == pref.Repeated && fd.IsPacked():
Damien Neil7492a092019-07-10 15:23:29 -0700479 switch fd.Kind() {
480 case pref.BoolKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700481 return coderBoolPackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700482 case pref.EnumKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700483 return coderEnumPackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700484 case pref.Int32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700485 return coderInt32PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700486 case pref.Sint32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700487 return coderSint32PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700488 case pref.Uint32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700489 return coderUint32PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700490 case pref.Int64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700491 return coderInt64PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700492 case pref.Sint64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700493 return coderSint64PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700494 case pref.Uint64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700495 return coderUint64PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700496 case pref.Sfixed32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700497 return coderSfixed32PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700498 case pref.Fixed32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700499 return coderFixed32PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700500 case pref.FloatKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700501 return coderFloatPackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700502 case pref.Sfixed64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700503 return coderSfixed64PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700504 case pref.Fixed64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700505 return coderFixed64PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700506 case pref.DoubleKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700507 return coderDoublePackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700508 }
Damien Neilc37adef2019-04-01 13:49:56 -0700509 default:
510 switch fd.Kind() {
Damien Neil68b81c32019-08-22 11:41:32 -0700511 default:
Damien Neilc37adef2019-04-01 13:49:56 -0700512 case pref.BoolKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700513 return coderBoolValue
Damien Neilc37adef2019-04-01 13:49:56 -0700514 case pref.EnumKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700515 return coderEnumValue
Damien Neilc37adef2019-04-01 13:49:56 -0700516 case pref.Int32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700517 return coderInt32Value
Damien Neilc37adef2019-04-01 13:49:56 -0700518 case pref.Sint32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700519 return coderSint32Value
Damien Neilc37adef2019-04-01 13:49:56 -0700520 case pref.Uint32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700521 return coderUint32Value
Damien Neilc37adef2019-04-01 13:49:56 -0700522 case pref.Int64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700523 return coderInt64Value
Damien Neilc37adef2019-04-01 13:49:56 -0700524 case pref.Sint64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700525 return coderSint64Value
Damien Neilc37adef2019-04-01 13:49:56 -0700526 case pref.Uint64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700527 return coderUint64Value
Damien Neilc37adef2019-04-01 13:49:56 -0700528 case pref.Sfixed32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700529 return coderSfixed32Value
Damien Neilc37adef2019-04-01 13:49:56 -0700530 case pref.Fixed32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700531 return coderFixed32Value
Damien Neilc37adef2019-04-01 13:49:56 -0700532 case pref.FloatKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700533 return coderFloatValue
Damien Neilc37adef2019-04-01 13:49:56 -0700534 case pref.Sfixed64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700535 return coderSfixed64Value
Damien Neilc37adef2019-04-01 13:49:56 -0700536 case pref.Fixed64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700537 return coderFixed64Value
Damien Neilc37adef2019-04-01 13:49:56 -0700538 case pref.DoubleKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700539 return coderDoubleValue
Damien Neilc37adef2019-04-01 13:49:56 -0700540 case pref.StringKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700541 if strs.EnforceUTF8(fd) {
Damien Neil68b81c32019-08-22 11:41:32 -0700542 return coderStringValueValidateUTF8
Damien Neilc37adef2019-04-01 13:49:56 -0700543 }
Damien Neil4b3a82f2019-09-04 19:07:00 -0700544 return coderStringValue
Damien Neilc37adef2019-04-01 13:49:56 -0700545 case pref.BytesKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700546 return coderBytesValue
Damien Neilc37adef2019-04-01 13:49:56 -0700547 case pref.MessageKind:
Damien Neil68b81c32019-08-22 11:41:32 -0700548 return coderMessageValue
Damien Neilc37adef2019-04-01 13:49:56 -0700549 case pref.GroupKind:
Damien Neil68b81c32019-08-22 11:41:32 -0700550 return coderGroupValue
Damien Neilc37adef2019-04-01 13:49:56 -0700551 }
552 }
Joe Tsai09217f02019-09-06 16:57:46 -0700553 panic(fmt.Sprintf("invalid field: no encoder for %v %v %v", fd.FullName(), fd.Cardinality(), fd.Kind()))
Damien Neilc37adef2019-04-01 13:49:56 -0700554}