codec_tables.go raw

   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.HasPresence() && 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  }
 558