blob: e89971238879f2bfb7e6229257b065c4737912ed [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:
Joe Tsaid0a499b2020-04-30 17:45:48 -0700341 if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) {
342 return nil, coderStringPtrValidateUTF8
343 }
Damien Neilc37adef2019-04-01 13:49:56 -0700344 if ft.Kind() == reflect.String {
Damien Neil316febd2020-02-09 12:26:50 -0800345 return nil, coderStringPtr
Damien Neilc37adef2019-04-01 13:49:56 -0700346 }
347 case pref.BytesKind:
348 if ft.Kind() == reflect.String {
Damien Neil316febd2020-02-09 12:26:50 -0800349 return nil, coderStringPtr
Damien Neilc37adef2019-04-01 13:49:56 -0700350 }
351 }
352 default:
353 switch fd.Kind() {
354 case pref.BoolKind:
355 if ft.Kind() == reflect.Bool {
Damien Neil316febd2020-02-09 12:26:50 -0800356 return nil, coderBool
Damien Neilc37adef2019-04-01 13:49:56 -0700357 }
358 case pref.EnumKind:
359 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800360 return nil, coderEnum
Damien Neilc37adef2019-04-01 13:49:56 -0700361 }
362 case pref.Int32Kind:
363 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800364 return nil, coderInt32
Damien Neilc37adef2019-04-01 13:49:56 -0700365 }
366 case pref.Sint32Kind:
367 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800368 return nil, coderSint32
Damien Neilc37adef2019-04-01 13:49:56 -0700369 }
370 case pref.Uint32Kind:
371 if ft.Kind() == reflect.Uint32 {
Damien Neil316febd2020-02-09 12:26:50 -0800372 return nil, coderUint32
Damien Neilc37adef2019-04-01 13:49:56 -0700373 }
374 case pref.Int64Kind:
375 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -0800376 return nil, coderInt64
Damien Neilc37adef2019-04-01 13:49:56 -0700377 }
378 case pref.Sint64Kind:
379 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -0800380 return nil, coderSint64
Damien Neilc37adef2019-04-01 13:49:56 -0700381 }
382 case pref.Uint64Kind:
383 if ft.Kind() == reflect.Uint64 {
Damien Neil316febd2020-02-09 12:26:50 -0800384 return nil, coderUint64
Damien Neilc37adef2019-04-01 13:49:56 -0700385 }
386 case pref.Sfixed32Kind:
387 if ft.Kind() == reflect.Int32 {
Damien Neil316febd2020-02-09 12:26:50 -0800388 return nil, coderSfixed32
Damien Neilc37adef2019-04-01 13:49:56 -0700389 }
390 case pref.Fixed32Kind:
391 if ft.Kind() == reflect.Uint32 {
Damien Neil316febd2020-02-09 12:26:50 -0800392 return nil, coderFixed32
Damien Neilc37adef2019-04-01 13:49:56 -0700393 }
394 case pref.FloatKind:
395 if ft.Kind() == reflect.Float32 {
Damien Neil316febd2020-02-09 12:26:50 -0800396 return nil, coderFloat
Damien Neilc37adef2019-04-01 13:49:56 -0700397 }
398 case pref.Sfixed64Kind:
399 if ft.Kind() == reflect.Int64 {
Damien Neil316febd2020-02-09 12:26:50 -0800400 return nil, coderSfixed64
Damien Neilc37adef2019-04-01 13:49:56 -0700401 }
402 case pref.Fixed64Kind:
403 if ft.Kind() == reflect.Uint64 {
Damien Neil316febd2020-02-09 12:26:50 -0800404 return nil, coderFixed64
Damien Neilc37adef2019-04-01 13:49:56 -0700405 }
406 case pref.DoubleKind:
407 if ft.Kind() == reflect.Float64 {
Damien Neil316febd2020-02-09 12:26:50 -0800408 return nil, coderDouble
Damien Neilc37adef2019-04-01 13:49:56 -0700409 }
410 case pref.StringKind:
Joe Tsaic51e2e02019-07-13 00:44:41 -0700411 if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) {
Damien Neil316febd2020-02-09 12:26:50 -0800412 return nil, coderStringValidateUTF8
Damien Neilc37adef2019-04-01 13:49:56 -0700413 }
414 if ft.Kind() == reflect.String {
Damien Neil316febd2020-02-09 12:26:50 -0800415 return nil, coderString
Damien Neilc37adef2019-04-01 13:49:56 -0700416 }
Joe Tsaic51e2e02019-07-13 00:44:41 -0700417 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 && strs.EnforceUTF8(fd) {
Damien Neil316febd2020-02-09 12:26:50 -0800418 return nil, coderBytesValidateUTF8
Joe Tsaic51e2e02019-07-13 00:44:41 -0700419 }
Damien Neilc37adef2019-04-01 13:49:56 -0700420 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
Damien Neil316febd2020-02-09 12:26:50 -0800421 return nil, coderBytes
Damien Neilc37adef2019-04-01 13:49:56 -0700422 }
423 case pref.BytesKind:
424 if ft.Kind() == reflect.String {
Damien Neil316febd2020-02-09 12:26:50 -0800425 return nil, coderString
Damien Neilc37adef2019-04-01 13:49:56 -0700426 }
427 if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
Damien Neil316febd2020-02-09 12:26:50 -0800428 return nil, coderBytes
Damien Neilc37adef2019-04-01 13:49:56 -0700429 }
430 }
431 }
Joe Tsai09217f02019-09-06 16:57:46 -0700432 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 -0700433}
434
Damien Neil4b3a82f2019-09-04 19:07:00 -0700435// encoderFuncsForValue returns value functions for a field, used for
Damien Neilc37adef2019-04-01 13:49:56 -0700436// extension values and map encoding.
Damien Neil4b3a82f2019-09-04 19:07:00 -0700437func encoderFuncsForValue(fd pref.FieldDescriptor) valueCoderFuncs {
Damien Neilc37adef2019-04-01 13:49:56 -0700438 switch {
439 case fd.Cardinality() == pref.Repeated && !fd.IsPacked():
Damien Neilc37adef2019-04-01 13:49:56 -0700440 switch fd.Kind() {
441 case pref.BoolKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700442 return coderBoolSliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700443 case pref.EnumKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700444 return coderEnumSliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700445 case pref.Int32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700446 return coderInt32SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700447 case pref.Sint32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700448 return coderSint32SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700449 case pref.Uint32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700450 return coderUint32SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700451 case pref.Int64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700452 return coderInt64SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700453 case pref.Sint64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700454 return coderSint64SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700455 case pref.Uint64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700456 return coderUint64SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700457 case pref.Sfixed32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700458 return coderSfixed32SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700459 case pref.Fixed32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700460 return coderFixed32SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700461 case pref.FloatKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700462 return coderFloatSliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700463 case pref.Sfixed64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700464 return coderSfixed64SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700465 case pref.Fixed64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700466 return coderFixed64SliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700467 case pref.DoubleKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700468 return coderDoubleSliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700469 case pref.StringKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700470 // We don't have a UTF-8 validating coder for repeated string fields.
471 // Value coders are used for extensions and maps.
472 // Extensions are never proto3, and maps never contain lists.
473 return coderStringSliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700474 case pref.BytesKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700475 return coderBytesSliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700476 case pref.MessageKind:
Damien Neil68b81c32019-08-22 11:41:32 -0700477 return coderMessageSliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700478 case pref.GroupKind:
Damien Neil68b81c32019-08-22 11:41:32 -0700479 return coderGroupSliceValue
Damien Neilc37adef2019-04-01 13:49:56 -0700480 }
481 case fd.Cardinality() == pref.Repeated && fd.IsPacked():
Damien Neil7492a092019-07-10 15:23:29 -0700482 switch fd.Kind() {
483 case pref.BoolKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700484 return coderBoolPackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700485 case pref.EnumKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700486 return coderEnumPackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700487 case pref.Int32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700488 return coderInt32PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700489 case pref.Sint32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700490 return coderSint32PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700491 case pref.Uint32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700492 return coderUint32PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700493 case pref.Int64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700494 return coderInt64PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700495 case pref.Sint64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700496 return coderSint64PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700497 case pref.Uint64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700498 return coderUint64PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700499 case pref.Sfixed32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700500 return coderSfixed32PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700501 case pref.Fixed32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700502 return coderFixed32PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700503 case pref.FloatKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700504 return coderFloatPackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700505 case pref.Sfixed64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700506 return coderSfixed64PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700507 case pref.Fixed64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700508 return coderFixed64PackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700509 case pref.DoubleKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700510 return coderDoublePackedSliceValue
Damien Neil7492a092019-07-10 15:23:29 -0700511 }
Damien Neilc37adef2019-04-01 13:49:56 -0700512 default:
513 switch fd.Kind() {
Damien Neil68b81c32019-08-22 11:41:32 -0700514 default:
Damien Neilc37adef2019-04-01 13:49:56 -0700515 case pref.BoolKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700516 return coderBoolValue
Damien Neilc37adef2019-04-01 13:49:56 -0700517 case pref.EnumKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700518 return coderEnumValue
Damien Neilc37adef2019-04-01 13:49:56 -0700519 case pref.Int32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700520 return coderInt32Value
Damien Neilc37adef2019-04-01 13:49:56 -0700521 case pref.Sint32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700522 return coderSint32Value
Damien Neilc37adef2019-04-01 13:49:56 -0700523 case pref.Uint32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700524 return coderUint32Value
Damien Neilc37adef2019-04-01 13:49:56 -0700525 case pref.Int64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700526 return coderInt64Value
Damien Neilc37adef2019-04-01 13:49:56 -0700527 case pref.Sint64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700528 return coderSint64Value
Damien Neilc37adef2019-04-01 13:49:56 -0700529 case pref.Uint64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700530 return coderUint64Value
Damien Neilc37adef2019-04-01 13:49:56 -0700531 case pref.Sfixed32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700532 return coderSfixed32Value
Damien Neilc37adef2019-04-01 13:49:56 -0700533 case pref.Fixed32Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700534 return coderFixed32Value
Damien Neilc37adef2019-04-01 13:49:56 -0700535 case pref.FloatKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700536 return coderFloatValue
Damien Neilc37adef2019-04-01 13:49:56 -0700537 case pref.Sfixed64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700538 return coderSfixed64Value
Damien Neilc37adef2019-04-01 13:49:56 -0700539 case pref.Fixed64Kind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700540 return coderFixed64Value
Damien Neilc37adef2019-04-01 13:49:56 -0700541 case pref.DoubleKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700542 return coderDoubleValue
Damien Neilc37adef2019-04-01 13:49:56 -0700543 case pref.StringKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700544 if strs.EnforceUTF8(fd) {
Damien Neil68b81c32019-08-22 11:41:32 -0700545 return coderStringValueValidateUTF8
Damien Neilc37adef2019-04-01 13:49:56 -0700546 }
Damien Neil4b3a82f2019-09-04 19:07:00 -0700547 return coderStringValue
Damien Neilc37adef2019-04-01 13:49:56 -0700548 case pref.BytesKind:
Damien Neil4b3a82f2019-09-04 19:07:00 -0700549 return coderBytesValue
Damien Neilc37adef2019-04-01 13:49:56 -0700550 case pref.MessageKind:
Damien Neil68b81c32019-08-22 11:41:32 -0700551 return coderMessageValue
Damien Neilc37adef2019-04-01 13:49:56 -0700552 case pref.GroupKind:
Damien Neil68b81c32019-08-22 11:41:32 -0700553 return coderGroupValue
Damien Neilc37adef2019-04-01 13:49:56 -0700554 }
555 }
Joe Tsai09217f02019-09-06 16:57:46 -0700556 panic(fmt.Sprintf("invalid field: no encoder for %v %v %v", fd.FullName(), fd.Cardinality(), fd.Kind()))
Damien Neilc37adef2019-04-01 13:49:56 -0700557}