blob: 2c62bda71ed25a97fe9d1cec23fb7e36b514db34 [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"
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)
21 unmarshal func(b []byte, p pointer, wtyp wire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error)
22 isInit func(p pointer, f *coderFieldInfo) error
Damien Neilc37adef2019-04-01 13:49:56 -070023}
24
Damien Neil68b81c32019-08-22 11:41:32 -070025// valueCoderFuncs is a set of protoreflect.Value encoding functions.
26type valueCoderFuncs struct {
27 size func(v pref.Value, tagsize int, opts marshalOptions) int
28 marshal func(b []byte, v pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error)
Damien Neilf0831e82020-01-21 14:25:12 -080029 unmarshal func(b []byte, v pref.Value, num wire.Number, wtyp wire.Type, opts unmarshalOptions) (pref.Value, unmarshalOutput, error)
Damien Neil68b81c32019-08-22 11:41:32 -070030 isInit func(v pref.Value) error
Damien Neilc37adef2019-04-01 13:49:56 -070031}
32
33// fieldCoder returns pointer functions for a field, used for operating on
34// struct fields.
Damien Neil316febd2020-02-09 12:26:50 -080035func fieldCoder(fd pref.FieldDescriptor, ft reflect.Type) (*MessageInfo, pointerCoderFuncs) {
Damien Neilc37adef2019-04-01 13:49:56 -070036 switch {
Damien Neil4ae30bb2019-06-20 10:12:23 -070037 case fd.IsMap():
38 return encoderFuncsForMap(fd, ft)
Damien Neilc37adef2019-04-01 13:49:56 -070039 case fd.Cardinality() == pref.Repeated && !fd.IsPacked():
40 // Repeated fields (not packed).
41 if ft.Kind() != reflect.Slice {
42 break
43 }
44 ft := ft.Elem()
45 switch fd.Kind() {
46 case pref.BoolKind:
47 if ft.Kind() == reflect.Bool {
Damien Neil316febd2020-02-09 12:26:50 -080048 return nil, coderBoolSlice
Damien Neilc37adef2019-04-01 13:49:56 -070049 }
50 case pref.EnumKind:
51 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -080052 return nil, coderEnumSlice
Damien Neilc37adef2019-04-01 13:49:56 -070053 }
54 case pref.Int32Kind:
55 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -080056 return nil, coderInt32Slice
Damien Neilc37adef2019-04-01 13:49:56 -070057 }
58 case pref.Sint32Kind:
59 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -080060 return nil, coderSint32Slice
Damien Neilc37adef2019-04-01 13:49:56 -070061 }
62 case pref.Uint32Kind:
63 if ft.Kind() == reflect.Uint32 {
Damien Neil316febd2020-02-09 12:26:50 -080064 return nil, coderUint32Slice
Damien Neilc37adef2019-04-01 13:49:56 -070065 }
66 case pref.Int64Kind:
67 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -080068 return nil, coderInt64Slice
Damien Neilc37adef2019-04-01 13:49:56 -070069 }
70 case pref.Sint64Kind:
71 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -080072 return nil, coderSint64Slice
Damien Neilc37adef2019-04-01 13:49:56 -070073 }
74 case pref.Uint64Kind:
75 if ft.Kind() == reflect.Uint64 {
Damien Neil316febd2020-02-09 12:26:50 -080076 return nil, coderUint64Slice
Damien Neilc37adef2019-04-01 13:49:56 -070077 }
78 case pref.Sfixed32Kind:
79 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -080080 return nil, coderSfixed32Slice
Damien Neilc37adef2019-04-01 13:49:56 -070081 }
82 case pref.Fixed32Kind:
83 if ft.Kind() == reflect.Uint32 {
Damien Neil316febd2020-02-09 12:26:50 -080084 return nil, coderFixed32Slice
Damien Neilc37adef2019-04-01 13:49:56 -070085 }
86 case pref.FloatKind:
87 if ft.Kind() == reflect.Float32 {
Damien Neil316febd2020-02-09 12:26:50 -080088 return nil, coderFloatSlice
Damien Neilc37adef2019-04-01 13:49:56 -070089 }
90 case pref.Sfixed64Kind:
91 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -080092 return nil, coderSfixed64Slice
Damien Neilc37adef2019-04-01 13:49:56 -070093 }
94 case pref.Fixed64Kind:
95 if ft.Kind() == reflect.Uint64 {
Damien Neil316febd2020-02-09 12:26:50 -080096 return nil, coderFixed64Slice
Damien Neilc37adef2019-04-01 13:49:56 -070097 }
98 case pref.DoubleKind:
99 if ft.Kind() == reflect.Float64 {
Damien Neil316febd2020-02-09 12:26:50 -0800100 return nil, coderDoubleSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700101 }
102 case pref.StringKind:
Joe Tsaic51e2e02019-07-13 00:44:41 -0700103 if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) {
Damien Neil316febd2020-02-09 12:26:50 -0800104 return nil, coderStringSliceValidateUTF8
Damien Neilc37adef2019-04-01 13:49:56 -0700105 }
106 if ft.Kind() == reflect.String {
Damien Neil316febd2020-02-09 12:26:50 -0800107 return nil, coderStringSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700108 }
Joe Tsaic51e2e02019-07-13 00:44:41 -0700109 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 && strs.EnforceUTF8(fd) {
Damien Neil316febd2020-02-09 12:26:50 -0800110 return nil, coderBytesSliceValidateUTF8
Joe Tsaic51e2e02019-07-13 00:44:41 -0700111 }
Damien Neilc37adef2019-04-01 13:49:56 -0700112 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
Damien Neil316febd2020-02-09 12:26:50 -0800113 return nil, coderBytesSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700114 }
115 case pref.BytesKind:
116 if ft.Kind() == reflect.String {
Damien Neil316febd2020-02-09 12:26:50 -0800117 return nil, coderStringSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700118 }
119 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
Damien Neil316febd2020-02-09 12:26:50 -0800120 return nil, coderBytesSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700121 }
122 case pref.MessageKind:
Damien Neil316febd2020-02-09 12:26:50 -0800123 return getMessageInfo(ft), makeMessageSliceFieldCoder(fd, ft)
Damien Neilc37adef2019-04-01 13:49:56 -0700124 case pref.GroupKind:
Damien Neil316febd2020-02-09 12:26:50 -0800125 return getMessageInfo(ft), makeGroupSliceFieldCoder(fd, ft)
Damien Neilc37adef2019-04-01 13:49:56 -0700126 }
127 case fd.Cardinality() == pref.Repeated && fd.IsPacked():
128 // Packed repeated fields.
129 //
130 // Only repeated fields of primitive numeric types
131 // (Varint, Fixed32, or Fixed64 wire type) can be packed.
132 if ft.Kind() != reflect.Slice {
133 break
134 }
135 ft := ft.Elem()
136 switch fd.Kind() {
137 case pref.BoolKind:
138 if ft.Kind() == reflect.Bool {
Damien Neil316febd2020-02-09 12:26:50 -0800139 return nil, coderBoolPackedSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700140 }
141 case pref.EnumKind:
142 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800143 return nil, coderEnumPackedSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700144 }
145 case pref.Int32Kind:
146 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800147 return nil, coderInt32PackedSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700148 }
149 case pref.Sint32Kind:
150 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800151 return nil, coderSint32PackedSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700152 }
153 case pref.Uint32Kind:
154 if ft.Kind() == reflect.Uint32 {
Damien Neil316febd2020-02-09 12:26:50 -0800155 return nil, coderUint32PackedSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700156 }
157 case pref.Int64Kind:
158 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -0800159 return nil, coderInt64PackedSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700160 }
161 case pref.Sint64Kind:
162 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -0800163 return nil, coderSint64PackedSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700164 }
165 case pref.Uint64Kind:
166 if ft.Kind() == reflect.Uint64 {
Damien Neil316febd2020-02-09 12:26:50 -0800167 return nil, coderUint64PackedSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700168 }
169 case pref.Sfixed32Kind:
170 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800171 return nil, coderSfixed32PackedSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700172 }
173 case pref.Fixed32Kind:
174 if ft.Kind() == reflect.Uint32 {
Damien Neil316febd2020-02-09 12:26:50 -0800175 return nil, coderFixed32PackedSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700176 }
177 case pref.FloatKind:
178 if ft.Kind() == reflect.Float32 {
Damien Neil316febd2020-02-09 12:26:50 -0800179 return nil, coderFloatPackedSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700180 }
181 case pref.Sfixed64Kind:
182 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -0800183 return nil, coderSfixed64PackedSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700184 }
185 case pref.Fixed64Kind:
186 if ft.Kind() == reflect.Uint64 {
Damien Neil316febd2020-02-09 12:26:50 -0800187 return nil, coderFixed64PackedSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700188 }
189 case pref.DoubleKind:
190 if ft.Kind() == reflect.Float64 {
Damien Neil316febd2020-02-09 12:26:50 -0800191 return nil, coderDoublePackedSlice
Damien Neilc37adef2019-04-01 13:49:56 -0700192 }
193 }
194 case fd.Kind() == pref.MessageKind:
Damien Neil316febd2020-02-09 12:26:50 -0800195 return getMessageInfo(ft), makeMessageFieldCoder(fd, ft)
Damien Neilc37adef2019-04-01 13:49:56 -0700196 case fd.Kind() == pref.GroupKind:
Damien Neil316febd2020-02-09 12:26:50 -0800197 return getMessageInfo(ft), makeGroupFieldCoder(fd, ft)
Damien Neilc37adef2019-04-01 13:49:56 -0700198 case fd.Syntax() == pref.Proto3 && fd.ContainingOneof() == nil:
199 // Populated oneof fields always encode even if set to the zero value,
200 // which normally are not encoded in proto3.
201 switch fd.Kind() {
202 case pref.BoolKind:
203 if ft.Kind() == reflect.Bool {
Damien Neil316febd2020-02-09 12:26:50 -0800204 return nil, coderBoolNoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700205 }
206 case pref.EnumKind:
207 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800208 return nil, coderEnumNoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700209 }
210 case pref.Int32Kind:
211 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800212 return nil, coderInt32NoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700213 }
214 case pref.Sint32Kind:
215 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800216 return nil, coderSint32NoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700217 }
218 case pref.Uint32Kind:
219 if ft.Kind() == reflect.Uint32 {
Damien Neil316febd2020-02-09 12:26:50 -0800220 return nil, coderUint32NoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700221 }
222 case pref.Int64Kind:
223 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -0800224 return nil, coderInt64NoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700225 }
226 case pref.Sint64Kind:
227 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -0800228 return nil, coderSint64NoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700229 }
230 case pref.Uint64Kind:
231 if ft.Kind() == reflect.Uint64 {
Damien Neil316febd2020-02-09 12:26:50 -0800232 return nil, coderUint64NoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700233 }
234 case pref.Sfixed32Kind:
235 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800236 return nil, coderSfixed32NoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700237 }
238 case pref.Fixed32Kind:
239 if ft.Kind() == reflect.Uint32 {
Damien Neil316febd2020-02-09 12:26:50 -0800240 return nil, coderFixed32NoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700241 }
242 case pref.FloatKind:
243 if ft.Kind() == reflect.Float32 {
Damien Neil316febd2020-02-09 12:26:50 -0800244 return nil, coderFloatNoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700245 }
246 case pref.Sfixed64Kind:
247 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -0800248 return nil, coderSfixed64NoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700249 }
250 case pref.Fixed64Kind:
251 if ft.Kind() == reflect.Uint64 {
Damien Neil316febd2020-02-09 12:26:50 -0800252 return nil, coderFixed64NoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700253 }
254 case pref.DoubleKind:
255 if ft.Kind() == reflect.Float64 {
Damien Neil316febd2020-02-09 12:26:50 -0800256 return nil, coderDoubleNoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700257 }
258 case pref.StringKind:
Joe Tsaic51e2e02019-07-13 00:44:41 -0700259 if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) {
Damien Neil316febd2020-02-09 12:26:50 -0800260 return nil, coderStringNoZeroValidateUTF8
Damien Neilc37adef2019-04-01 13:49:56 -0700261 }
Joe Tsaic51e2e02019-07-13 00:44:41 -0700262 if ft.Kind() == reflect.String {
Damien Neil316febd2020-02-09 12:26:50 -0800263 return nil, coderStringNoZero
Joe Tsaic51e2e02019-07-13 00:44:41 -0700264 }
265 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 && strs.EnforceUTF8(fd) {
Damien Neil316febd2020-02-09 12:26:50 -0800266 return nil, coderBytesNoZeroValidateUTF8
Joe Tsaic51e2e02019-07-13 00:44:41 -0700267 }
Damien Neilc37adef2019-04-01 13:49:56 -0700268 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
Damien Neil316febd2020-02-09 12:26:50 -0800269 return nil, coderBytesNoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700270 }
271 case pref.BytesKind:
272 if ft.Kind() == reflect.String {
Damien Neil316febd2020-02-09 12:26:50 -0800273 return nil, coderStringNoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700274 }
275 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
Damien Neil316febd2020-02-09 12:26:50 -0800276 return nil, coderBytesNoZero
Damien Neilc37adef2019-04-01 13:49:56 -0700277 }
278 }
279 case ft.Kind() == reflect.Ptr:
280 ft := ft.Elem()
281 switch fd.Kind() {
282 case pref.BoolKind:
283 if ft.Kind() == reflect.Bool {
Damien Neil316febd2020-02-09 12:26:50 -0800284 return nil, coderBoolPtr
Damien Neilc37adef2019-04-01 13:49:56 -0700285 }
286 case pref.EnumKind:
287 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800288 return nil, coderEnumPtr
Damien Neilc37adef2019-04-01 13:49:56 -0700289 }
290 case pref.Int32Kind:
291 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800292 return nil, coderInt32Ptr
Damien Neilc37adef2019-04-01 13:49:56 -0700293 }
294 case pref.Sint32Kind:
295 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800296 return nil, coderSint32Ptr
Damien Neilc37adef2019-04-01 13:49:56 -0700297 }
298 case pref.Uint32Kind:
299 if ft.Kind() == reflect.Uint32 {
Damien Neil316febd2020-02-09 12:26:50 -0800300 return nil, coderUint32Ptr
Damien Neilc37adef2019-04-01 13:49:56 -0700301 }
302 case pref.Int64Kind:
303 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -0800304 return nil, coderInt64Ptr
Damien Neilc37adef2019-04-01 13:49:56 -0700305 }
306 case pref.Sint64Kind:
307 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -0800308 return nil, coderSint64Ptr
Damien Neilc37adef2019-04-01 13:49:56 -0700309 }
310 case pref.Uint64Kind:
311 if ft.Kind() == reflect.Uint64 {
Damien Neil316febd2020-02-09 12:26:50 -0800312 return nil, coderUint64Ptr
Damien Neilc37adef2019-04-01 13:49:56 -0700313 }
314 case pref.Sfixed32Kind:
315 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800316 return nil, coderSfixed32Ptr
Damien Neilc37adef2019-04-01 13:49:56 -0700317 }
318 case pref.Fixed32Kind:
319 if ft.Kind() == reflect.Uint32 {
Damien Neil316febd2020-02-09 12:26:50 -0800320 return nil, coderFixed32Ptr
Damien Neilc37adef2019-04-01 13:49:56 -0700321 }
322 case pref.FloatKind:
323 if ft.Kind() == reflect.Float32 {
Damien Neil316febd2020-02-09 12:26:50 -0800324 return nil, coderFloatPtr
Damien Neilc37adef2019-04-01 13:49:56 -0700325 }
326 case pref.Sfixed64Kind:
327 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -0800328 return nil, coderSfixed64Ptr
Damien Neilc37adef2019-04-01 13:49:56 -0700329 }
330 case pref.Fixed64Kind:
331 if ft.Kind() == reflect.Uint64 {
Damien Neil316febd2020-02-09 12:26:50 -0800332 return nil, coderFixed64Ptr
Damien Neilc37adef2019-04-01 13:49:56 -0700333 }
334 case pref.DoubleKind:
335 if ft.Kind() == reflect.Float64 {
Damien Neil316febd2020-02-09 12:26:50 -0800336 return nil, coderDoublePtr
Damien Neilc37adef2019-04-01 13:49:56 -0700337 }
338 case pref.StringKind:
339 if ft.Kind() == reflect.String {
Damien Neil316febd2020-02-09 12:26:50 -0800340 return nil, coderStringPtr
Damien Neilc37adef2019-04-01 13:49:56 -0700341 }
342 case pref.BytesKind:
343 if ft.Kind() == reflect.String {
Damien Neil316febd2020-02-09 12:26:50 -0800344 return nil, coderStringPtr
Damien Neilc37adef2019-04-01 13:49:56 -0700345 }
346 }
347 default:
348 switch fd.Kind() {
349 case pref.BoolKind:
350 if ft.Kind() == reflect.Bool {
Damien Neil316febd2020-02-09 12:26:50 -0800351 return nil, coderBool
Damien Neilc37adef2019-04-01 13:49:56 -0700352 }
353 case pref.EnumKind:
354 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800355 return nil, coderEnum
Damien Neilc37adef2019-04-01 13:49:56 -0700356 }
357 case pref.Int32Kind:
358 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800359 return nil, coderInt32
Damien Neilc37adef2019-04-01 13:49:56 -0700360 }
361 case pref.Sint32Kind:
362 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800363 return nil, coderSint32
Damien Neilc37adef2019-04-01 13:49:56 -0700364 }
365 case pref.Uint32Kind:
366 if ft.Kind() == reflect.Uint32 {
Damien Neil316febd2020-02-09 12:26:50 -0800367 return nil, coderUint32
Damien Neilc37adef2019-04-01 13:49:56 -0700368 }
369 case pref.Int64Kind:
370 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -0800371 return nil, coderInt64
Damien Neilc37adef2019-04-01 13:49:56 -0700372 }
373 case pref.Sint64Kind:
374 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -0800375 return nil, coderSint64
Damien Neilc37adef2019-04-01 13:49:56 -0700376 }
377 case pref.Uint64Kind:
378 if ft.Kind() == reflect.Uint64 {
Damien Neil316febd2020-02-09 12:26:50 -0800379 return nil, coderUint64
Damien Neilc37adef2019-04-01 13:49:56 -0700380 }
381 case pref.Sfixed32Kind:
382 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800383 return nil, coderSfixed32
Damien Neilc37adef2019-04-01 13:49:56 -0700384 }
385 case pref.Fixed32Kind:
386 if ft.Kind() == reflect.Uint32 {
Damien Neil316febd2020-02-09 12:26:50 -0800387 return nil, coderFixed32
Damien Neilc37adef2019-04-01 13:49:56 -0700388 }
389 case pref.FloatKind:
390 if ft.Kind() == reflect.Float32 {
Damien Neil316febd2020-02-09 12:26:50 -0800391 return nil, coderFloat
Damien Neilc37adef2019-04-01 13:49:56 -0700392 }
393 case pref.Sfixed64Kind:
394 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -0800395 return nil, coderSfixed64
Damien Neilc37adef2019-04-01 13:49:56 -0700396 }
397 case pref.Fixed64Kind:
398 if ft.Kind() == reflect.Uint64 {
Damien Neil316febd2020-02-09 12:26:50 -0800399 return nil, coderFixed64
Damien Neilc37adef2019-04-01 13:49:56 -0700400 }
401 case pref.DoubleKind:
402 if ft.Kind() == reflect.Float64 {
Damien Neil316febd2020-02-09 12:26:50 -0800403 return nil, coderDouble
Damien Neilc37adef2019-04-01 13:49:56 -0700404 }
405 case pref.StringKind:
Joe Tsaic51e2e02019-07-13 00:44:41 -0700406 if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) {
Damien Neil316febd2020-02-09 12:26:50 -0800407 return nil, coderStringValidateUTF8
Damien Neilc37adef2019-04-01 13:49:56 -0700408 }
409 if ft.Kind() == reflect.String {
Damien Neil316febd2020-02-09 12:26:50 -0800410 return nil, coderString
Damien Neilc37adef2019-04-01 13:49:56 -0700411 }
Joe Tsaic51e2e02019-07-13 00:44:41 -0700412 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 && strs.EnforceUTF8(fd) {
Damien Neil316febd2020-02-09 12:26:50 -0800413 return nil, coderBytesValidateUTF8
Joe Tsaic51e2e02019-07-13 00:44:41 -0700414 }
Damien Neilc37adef2019-04-01 13:49:56 -0700415 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
Damien Neil316febd2020-02-09 12:26:50 -0800416 return nil, coderBytes
Damien Neilc37adef2019-04-01 13:49:56 -0700417 }
418 case pref.BytesKind:
419 if ft.Kind() == reflect.String {
Damien Neil316febd2020-02-09 12:26:50 -0800420 return nil, coderString
Damien Neilc37adef2019-04-01 13:49:56 -0700421 }
422 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
Damien Neil316febd2020-02-09 12:26:50 -0800423 return nil, coderBytes
Damien Neilc37adef2019-04-01 13:49:56 -0700424 }
425 }
426 }
Joe Tsai09217f02019-09-06 16:57:46 -0700427 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 -0700428}
429
Damien Neil4b3a82f2019-09-04 19:07:00 -0700430// encoderFuncsForValue returns value functions for a field, used for
Damien Neilc37adef2019-04-01 13:49:56 -0700431// extension values and map encoding.
Damien Neil4b3a82f2019-09-04 19:07:00 -0700432func encoderFuncsForValue(fd pref.FieldDescriptor) valueCoderFuncs {
Damien Neilc37adef2019-04-01 13:49:56 -0700433 switch {
434 case fd.Cardinality() == pref.Repeated && !fd.IsPacked():
Damien Neilc37adef2019-04-01 13:49:56 -0700435 switch fd.Kind() {
436 case pref.BoolKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700437 return coderBoolSliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700438 case pref.EnumKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700439 return coderEnumSliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700440 case pref.Int32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700441 return coderInt32SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700442 case pref.Sint32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700443 return coderSint32SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700444 case pref.Uint32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700445 return coderUint32SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700446 case pref.Int64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700447 return coderInt64SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700448 case pref.Sint64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700449 return coderSint64SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700450 case pref.Uint64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700451 return coderUint64SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700452 case pref.Sfixed32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700453 return coderSfixed32SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700454 case pref.Fixed32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700455 return coderFixed32SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700456 case pref.FloatKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700457 return coderFloatSliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700458 case pref.Sfixed64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700459 return coderSfixed64SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700460 case pref.Fixed64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700461 return coderFixed64SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700462 case pref.DoubleKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700463 return coderDoubleSliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700464 case pref.StringKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700465 // We don't have a UTF-8 validating coder for repeated string fields.
466 // Value coders are used for extensions and maps.
467 // Extensions are never proto3, and maps never contain lists.
468 return coderStringSliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700469 case pref.BytesKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700470 return coderBytesSliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700471 case pref.MessageKind:
Damien Neil68b81c32019-08-22 11:41:32 -0700472 return coderMessageSliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700473 case pref.GroupKind:
Damien Neil68b81c32019-08-22 11:41:32 -0700474 return coderGroupSliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700475 }
476 case fd.Cardinality() == pref.Repeated && fd.IsPacked():
Damien Neil7492a092019-07-10 15:23:29 -0700477 switch fd.Kind() {
478 case pref.BoolKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700479 return coderBoolPackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700480 case pref.EnumKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700481 return coderEnumPackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700482 case pref.Int32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700483 return coderInt32PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700484 case pref.Sint32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700485 return coderSint32PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700486 case pref.Uint32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700487 return coderUint32PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700488 case pref.Int64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700489 return coderInt64PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700490 case pref.Sint64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700491 return coderSint64PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700492 case pref.Uint64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700493 return coderUint64PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700494 case pref.Sfixed32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700495 return coderSfixed32PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700496 case pref.Fixed32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700497 return coderFixed32PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700498 case pref.FloatKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700499 return coderFloatPackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700500 case pref.Sfixed64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700501 return coderSfixed64PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700502 case pref.Fixed64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700503 return coderFixed64PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700504 case pref.DoubleKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700505 return coderDoublePackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700506 }
Damien Neilc37adef2019-04-01 13:49:56 -0700507 default:
508 switch fd.Kind() {
Damien Neil68b81c32019-08-22 11:41:32 -0700509 default:
Damien Neilc37adef2019-04-01 13:49:56 -0700510 case pref.BoolKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700511 return coderBoolValue
Damien Neilc37adef2019-04-01 13:49:56 -0700512 case pref.EnumKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700513 return coderEnumValue
Damien Neilc37adef2019-04-01 13:49:56 -0700514 case pref.Int32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700515 return coderInt32Value
Damien Neilc37adef2019-04-01 13:49:56 -0700516 case pref.Sint32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700517 return coderSint32Value
Damien Neilc37adef2019-04-01 13:49:56 -0700518 case pref.Uint32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700519 return coderUint32Value
Damien Neilc37adef2019-04-01 13:49:56 -0700520 case pref.Int64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700521 return coderInt64Value
Damien Neilc37adef2019-04-01 13:49:56 -0700522 case pref.Sint64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700523 return coderSint64Value
Damien Neilc37adef2019-04-01 13:49:56 -0700524 case pref.Uint64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700525 return coderUint64Value
Damien Neilc37adef2019-04-01 13:49:56 -0700526 case pref.Sfixed32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700527 return coderSfixed32Value
Damien Neilc37adef2019-04-01 13:49:56 -0700528 case pref.Fixed32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700529 return coderFixed32Value
Damien Neilc37adef2019-04-01 13:49:56 -0700530 case pref.FloatKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700531 return coderFloatValue
Damien Neilc37adef2019-04-01 13:49:56 -0700532 case pref.Sfixed64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700533 return coderSfixed64Value
Damien Neilc37adef2019-04-01 13:49:56 -0700534 case pref.Fixed64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700535 return coderFixed64Value
Damien Neilc37adef2019-04-01 13:49:56 -0700536 case pref.DoubleKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700537 return coderDoubleValue
Damien Neilc37adef2019-04-01 13:49:56 -0700538 case pref.StringKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700539 if strs.EnforceUTF8(fd) {
Damien Neil68b81c32019-08-22 11:41:32 -0700540 return coderStringValueValidateUTF8
Damien Neilc37adef2019-04-01 13:49:56 -0700541 }
Damien Neil4b3a82f2019-09-04 19:07:00 -0700542 return coderStringValue
Damien Neilc37adef2019-04-01 13:49:56 -0700543 case pref.BytesKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700544 return coderBytesValue
Damien Neilc37adef2019-04-01 13:49:56 -0700545 case pref.MessageKind:
Damien Neil68b81c32019-08-22 11:41:32 -0700546 return coderMessageValue
Damien Neilc37adef2019-04-01 13:49:56 -0700547 case pref.GroupKind:
Damien Neil68b81c32019-08-22 11:41:32 -0700548 return coderGroupValue
Damien Neilc37adef2019-04-01 13:49:56 -0700549 }
550 }
Joe Tsai09217f02019-09-06 16:57:46 -0700551 panic(fmt.Sprintf("invalid field: no encoder for %v %v %v", fd.FullName(), fd.Cardinality(), fd.Kind()))
Damien Neilc37adef2019-04-01 13:49:56 -0700552}