codec_message.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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. "fmt"
  7. "reflect"
  8. "sort"
  9. "sync"
  10. "google.golang.org/protobuf/internal/encoding/messageset"
  11. "google.golang.org/protobuf/internal/encoding/wire"
  12. pref "google.golang.org/protobuf/reflect/protoreflect"
  13. piface "google.golang.org/protobuf/runtime/protoiface"
  14. )
  15. // coderMessageInfo contains per-message information used by the fast-path functions.
  16. // This is a different type from MessageInfo to keep MessageInfo as general-purpose as
  17. // possible.
  18. type coderMessageInfo struct {
  19. methods piface.Methods
  20. orderedCoderFields []*coderFieldInfo
  21. denseCoderFields []*coderFieldInfo
  22. coderFields map[wire.Number]*coderFieldInfo
  23. sizecacheOffset offset
  24. unknownOffset offset
  25. extensionOffset offset
  26. needsInitCheck bool
  27. extensionFieldInfosMu sync.RWMutex
  28. extensionFieldInfos map[pref.ExtensionType]*extensionFieldInfo
  29. }
  30. type coderFieldInfo struct {
  31. funcs pointerCoderFuncs // fast-path per-field functions
  32. num pref.FieldNumber // field number
  33. offset offset // struct field offset
  34. wiretag uint64 // field tag (number + wire type)
  35. tagsize int // size of the varint-encoded tag
  36. isPointer bool // true if IsNil may be called on the struct field
  37. isRequired bool // true if field is required
  38. }
  39. func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) {
  40. mi.sizecacheOffset = si.sizecacheOffset
  41. mi.unknownOffset = si.unknownOffset
  42. mi.extensionOffset = si.extensionOffset
  43. mi.coderFields = make(map[wire.Number]*coderFieldInfo)
  44. fields := mi.Desc.Fields()
  45. for i := 0; i < fields.Len(); i++ {
  46. fd := fields.Get(i)
  47. fs := si.fieldsByNumber[fd.Number()]
  48. if fd.ContainingOneof() != nil {
  49. fs = si.oneofsByName[fd.ContainingOneof().Name()]
  50. }
  51. ft := fs.Type
  52. var wiretag uint64
  53. if !fd.IsPacked() {
  54. wiretag = wire.EncodeTag(fd.Number(), wireTypes[fd.Kind()])
  55. } else {
  56. wiretag = wire.EncodeTag(fd.Number(), wire.BytesType)
  57. }
  58. var fieldOffset offset
  59. var funcs pointerCoderFuncs
  60. switch {
  61. case fd.ContainingOneof() != nil:
  62. fieldOffset = offsetOf(fs, mi.Exporter)
  63. funcs = makeOneofFieldCoder(fd, si)
  64. case fd.IsWeak():
  65. fieldOffset = si.weakOffset
  66. funcs = makeWeakMessageFieldCoder(fd)
  67. default:
  68. fieldOffset = offsetOf(fs, mi.Exporter)
  69. funcs = fieldCoder(fd, ft)
  70. }
  71. cf := &coderFieldInfo{
  72. num: fd.Number(),
  73. offset: fieldOffset,
  74. wiretag: wiretag,
  75. tagsize: wire.SizeVarint(wiretag),
  76. funcs: funcs,
  77. isPointer: (fd.Cardinality() == pref.Repeated ||
  78. fd.Kind() == pref.MessageKind ||
  79. fd.Kind() == pref.GroupKind ||
  80. fd.Syntax() != pref.Proto3),
  81. isRequired: fd.Cardinality() == pref.Required,
  82. }
  83. mi.orderedCoderFields = append(mi.orderedCoderFields, cf)
  84. mi.coderFields[cf.num] = cf
  85. }
  86. if messageset.IsMessageSet(mi.Desc) {
  87. if !mi.extensionOffset.IsValid() {
  88. panic(fmt.Sprintf("%v: MessageSet with no extensions field", mi.Desc.FullName()))
  89. }
  90. cf := &coderFieldInfo{
  91. num: messageset.FieldItem,
  92. offset: si.extensionOffset,
  93. isPointer: true,
  94. funcs: makeMessageSetFieldCoder(mi),
  95. }
  96. mi.orderedCoderFields = append(mi.orderedCoderFields, cf)
  97. mi.coderFields[cf.num] = cf
  98. // Invalidate the extension offset, since the field codec handles extensions.
  99. mi.extensionOffset = invalidOffset
  100. }
  101. sort.Slice(mi.orderedCoderFields, func(i, j int) bool {
  102. return mi.orderedCoderFields[i].num < mi.orderedCoderFields[j].num
  103. })
  104. var maxDense pref.FieldNumber
  105. for _, cf := range mi.orderedCoderFields {
  106. if cf.num >= 16 && cf.num >= 2*maxDense {
  107. break
  108. }
  109. maxDense = cf.num
  110. }
  111. mi.denseCoderFields = make([]*coderFieldInfo, maxDense+1)
  112. for _, cf := range mi.orderedCoderFields {
  113. if int(cf.num) > len(mi.denseCoderFields) {
  114. break
  115. }
  116. mi.denseCoderFields[cf.num] = cf
  117. }
  118. mi.needsInitCheck = needsInitCheck(mi.Desc)
  119. if mi.methods.MarshalAppend == nil && mi.methods.Size == nil {
  120. mi.methods.Flags |= piface.SupportMarshalDeterministic
  121. mi.methods.MarshalAppend = mi.marshalAppend
  122. mi.methods.Size = mi.size
  123. }
  124. if mi.methods.Unmarshal == nil {
  125. mi.methods.Flags |= piface.SupportUnmarshalDiscardUnknown
  126. mi.methods.Unmarshal = mi.unmarshal
  127. }
  128. if mi.methods.IsInitialized == nil {
  129. mi.methods.IsInitialized = mi.isInitialized
  130. }
  131. }