codec_message.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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. package impl
  5. import (
  6. "reflect"
  7. "sort"
  8. "google.golang.org/protobuf/internal/encoding/wire"
  9. pref "google.golang.org/protobuf/reflect/protoreflect"
  10. piface "google.golang.org/protobuf/runtime/protoiface"
  11. )
  12. // coderMessageInfo contains per-message information used by the fast-path functions.
  13. // This is a different type from MessageInfo to keep MessageInfo as general-purpose as
  14. // possible.
  15. type coderMessageInfo struct {
  16. orderedCoderFields []*coderFieldInfo
  17. denseCoderFields []*coderFieldInfo
  18. coderFields map[wire.Number]*coderFieldInfo
  19. sizecacheOffset offset
  20. unknownOffset offset
  21. extensionOffset offset
  22. needsInitCheck bool
  23. }
  24. type coderFieldInfo struct {
  25. funcs pointerCoderFuncs // fast-path per-field functions
  26. num pref.FieldNumber // field number
  27. offset offset // struct field offset
  28. wiretag uint64 // field tag (number + wire type)
  29. tagsize int // size of the varint-encoded tag
  30. isPointer bool // true if IsNil may be called on the struct field
  31. isRequired bool // true if field is required
  32. }
  33. func (mi *MessageInfo) makeMethods(t reflect.Type, si structInfo) {
  34. mi.sizecacheOffset = si.sizecacheOffset
  35. mi.unknownOffset = si.unknownOffset
  36. mi.extensionOffset = si.extensionOffset
  37. mi.coderFields = make(map[wire.Number]*coderFieldInfo)
  38. for i := 0; i < mi.PBType.Descriptor().Fields().Len(); i++ {
  39. fd := mi.PBType.Descriptor().Fields().Get(i)
  40. fs := si.fieldsByNumber[fd.Number()]
  41. if fd.ContainingOneof() != nil {
  42. fs = si.oneofsByName[fd.ContainingOneof().Name()]
  43. }
  44. ft := fs.Type
  45. var wiretag uint64
  46. if !fd.IsPacked() {
  47. wiretag = wire.EncodeTag(fd.Number(), wireTypes[fd.Kind()])
  48. } else {
  49. wiretag = wire.EncodeTag(fd.Number(), wire.BytesType)
  50. }
  51. var funcs pointerCoderFuncs
  52. if fd.ContainingOneof() != nil {
  53. funcs = makeOneofFieldCoder(si, fd)
  54. } else {
  55. funcs = fieldCoder(fd, ft)
  56. }
  57. cf := &coderFieldInfo{
  58. num: fd.Number(),
  59. offset: offsetOf(fs, mi.Exporter),
  60. wiretag: wiretag,
  61. tagsize: wire.SizeVarint(wiretag),
  62. funcs: funcs,
  63. isPointer: (fd.Cardinality() == pref.Repeated ||
  64. fd.Kind() == pref.MessageKind ||
  65. fd.Kind() == pref.GroupKind ||
  66. fd.Syntax() != pref.Proto3),
  67. isRequired: fd.Cardinality() == pref.Required,
  68. }
  69. mi.orderedCoderFields = append(mi.orderedCoderFields, cf)
  70. mi.coderFields[cf.num] = cf
  71. }
  72. sort.Slice(mi.orderedCoderFields, func(i, j int) bool {
  73. return mi.orderedCoderFields[i].num < mi.orderedCoderFields[j].num
  74. })
  75. var maxDense pref.FieldNumber
  76. for _, cf := range mi.orderedCoderFields {
  77. if cf.num >= 16 && cf.num >= 2*maxDense {
  78. break
  79. }
  80. maxDense = cf.num
  81. }
  82. mi.denseCoderFields = make([]*coderFieldInfo, maxDense+1)
  83. for _, cf := range mi.orderedCoderFields {
  84. if int(cf.num) > len(mi.denseCoderFields) {
  85. break
  86. }
  87. mi.denseCoderFields[cf.num] = cf
  88. }
  89. mi.needsInitCheck = needsInitCheck(mi.PBType)
  90. mi.methods = piface.Methods{
  91. Flags: piface.MethodFlagDeterministicMarshal,
  92. MarshalAppend: mi.marshalAppend,
  93. Unmarshal: mi.unmarshal,
  94. Size: mi.size,
  95. IsInitialized: mi.isInitialized,
  96. }
  97. }