codec_message.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  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. "google.golang.org/protobuf/encoding/protowire"
  10. "google.golang.org/protobuf/internal/encoding/messageset"
  11. "google.golang.org/protobuf/internal/order"
  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[protowire.Number]*coderFieldInfo
  23. sizecacheOffset offset
  24. unknownOffset offset
  25. unknownPtrKind bool
  26. extensionOffset offset
  27. needsInitCheck bool
  28. isMessageSet bool
  29. numRequiredFields uint8
  30. }
  31. type coderFieldInfo struct {
  32. funcs pointerCoderFuncs // fast-path per-field functions
  33. mi *MessageInfo // field's message
  34. ft reflect.Type
  35. validation validationInfo // information used by message validation
  36. num pref.FieldNumber // field number
  37. offset offset // struct field offset
  38. wiretag uint64 // field tag (number + wire type)
  39. tagsize int // size of the varint-encoded tag
  40. isPointer bool // true if IsNil may be called on the struct field
  41. isRequired bool // true if field is required
  42. }
  43. func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) {
  44. mi.sizecacheOffset = invalidOffset
  45. mi.unknownOffset = invalidOffset
  46. mi.extensionOffset = invalidOffset
  47. if si.sizecacheOffset.IsValid() && si.sizecacheType == sizecacheType {
  48. mi.sizecacheOffset = si.sizecacheOffset
  49. }
  50. if si.unknownOffset.IsValid() && (si.unknownType == unknownFieldsAType || si.unknownType == unknownFieldsBType) {
  51. mi.unknownOffset = si.unknownOffset
  52. mi.unknownPtrKind = si.unknownType.Kind() == reflect.Ptr
  53. }
  54. if si.extensionOffset.IsValid() && si.extensionType == extensionFieldsType {
  55. mi.extensionOffset = si.extensionOffset
  56. }
  57. mi.coderFields = make(map[protowire.Number]*coderFieldInfo)
  58. fields := mi.Desc.Fields()
  59. preallocFields := make([]coderFieldInfo, fields.Len())
  60. for i := 0; i < fields.Len(); i++ {
  61. fd := fields.Get(i)
  62. fs := si.fieldsByNumber[fd.Number()]
  63. isOneof := fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic()
  64. if isOneof {
  65. fs = si.oneofsByName[fd.ContainingOneof().Name()]
  66. }
  67. ft := fs.Type
  68. var wiretag uint64
  69. if !fd.IsPacked() {
  70. wiretag = protowire.EncodeTag(fd.Number(), wireTypes[fd.Kind()])
  71. } else {
  72. wiretag = protowire.EncodeTag(fd.Number(), protowire.BytesType)
  73. }
  74. var fieldOffset offset
  75. var funcs pointerCoderFuncs
  76. var childMessage *MessageInfo
  77. switch {
  78. case isOneof:
  79. fieldOffset = offsetOf(fs, mi.Exporter)
  80. case fd.IsWeak():
  81. fieldOffset = si.weakOffset
  82. funcs = makeWeakMessageFieldCoder(fd)
  83. default:
  84. fieldOffset = offsetOf(fs, mi.Exporter)
  85. childMessage, funcs = fieldCoder(fd, ft)
  86. }
  87. cf := &preallocFields[i]
  88. *cf = coderFieldInfo{
  89. num: fd.Number(),
  90. offset: fieldOffset,
  91. wiretag: wiretag,
  92. ft: ft,
  93. tagsize: protowire.SizeVarint(wiretag),
  94. funcs: funcs,
  95. mi: childMessage,
  96. validation: newFieldValidationInfo(mi, si, fd, ft),
  97. isPointer: fd.Cardinality() == pref.Repeated || fd.HasPresence(),
  98. isRequired: fd.Cardinality() == pref.Required,
  99. }
  100. mi.orderedCoderFields = append(mi.orderedCoderFields, cf)
  101. mi.coderFields[cf.num] = cf
  102. }
  103. for i, oneofs := 0, mi.Desc.Oneofs(); i < oneofs.Len(); i++ {
  104. if od := oneofs.Get(i); !od.IsSynthetic() {
  105. mi.initOneofFieldCoders(od, si)
  106. }
  107. }
  108. if messageset.IsMessageSet(mi.Desc) {
  109. if !mi.extensionOffset.IsValid() {
  110. panic(fmt.Sprintf("%v: MessageSet with no extensions field", mi.Desc.FullName()))
  111. }
  112. if !mi.unknownOffset.IsValid() {
  113. panic(fmt.Sprintf("%v: MessageSet with no unknown field", mi.Desc.FullName()))
  114. }
  115. mi.isMessageSet = true
  116. }
  117. sort.Slice(mi.orderedCoderFields, func(i, j int) bool {
  118. return mi.orderedCoderFields[i].num < mi.orderedCoderFields[j].num
  119. })
  120. var maxDense pref.FieldNumber
  121. for _, cf := range mi.orderedCoderFields {
  122. if cf.num >= 16 && cf.num >= 2*maxDense {
  123. break
  124. }
  125. maxDense = cf.num
  126. }
  127. mi.denseCoderFields = make([]*coderFieldInfo, maxDense+1)
  128. for _, cf := range mi.orderedCoderFields {
  129. if int(cf.num) >= len(mi.denseCoderFields) {
  130. break
  131. }
  132. mi.denseCoderFields[cf.num] = cf
  133. }
  134. // To preserve compatibility with historic wire output, marshal oneofs last.
  135. if mi.Desc.Oneofs().Len() > 0 {
  136. sort.Slice(mi.orderedCoderFields, func(i, j int) bool {
  137. fi := fields.ByNumber(mi.orderedCoderFields[i].num)
  138. fj := fields.ByNumber(mi.orderedCoderFields[j].num)
  139. return order.LegacyFieldOrder(fi, fj)
  140. })
  141. }
  142. mi.needsInitCheck = needsInitCheck(mi.Desc)
  143. if mi.methods.Marshal == nil && mi.methods.Size == nil {
  144. mi.methods.Flags |= piface.SupportMarshalDeterministic
  145. mi.methods.Marshal = mi.marshal
  146. mi.methods.Size = mi.size
  147. }
  148. if mi.methods.Unmarshal == nil {
  149. mi.methods.Flags |= piface.SupportUnmarshalDiscardUnknown
  150. mi.methods.Unmarshal = mi.unmarshal
  151. }
  152. if mi.methods.CheckInitialized == nil {
  153. mi.methods.CheckInitialized = mi.checkInitialized
  154. }
  155. if mi.methods.Merge == nil {
  156. mi.methods.Merge = mi.merge
  157. }
  158. }
  159. // getUnknownBytes returns a *[]byte for the unknown fields.
  160. // It is the caller's responsibility to check whether the pointer is nil.
  161. // This function is specially designed to be inlineable.
  162. func (mi *MessageInfo) getUnknownBytes(p pointer) *[]byte {
  163. if mi.unknownPtrKind {
  164. return *p.Apply(mi.unknownOffset).BytesPtr()
  165. } else {
  166. return p.Apply(mi.unknownOffset).Bytes()
  167. }
  168. }
  169. // mutableUnknownBytes returns a *[]byte for the unknown fields.
  170. // The returned pointer is guaranteed to not be nil.
  171. func (mi *MessageInfo) mutableUnknownBytes(p pointer) *[]byte {
  172. if mi.unknownPtrKind {
  173. bp := p.Apply(mi.unknownOffset).BytesPtr()
  174. if *bp == nil {
  175. *bp = new([]byte)
  176. }
  177. return *bp
  178. } else {
  179. return p.Apply(mi.unknownOffset).Bytes()
  180. }
  181. }