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