You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

218 lines
7.1 KiB

  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. "google.golang.org/protobuf/reflect/protoreflect"
  13. "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 protoiface.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 protoreflect.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 ft == nil:
  79. // This never occurs for generated message types.
  80. // It implies that a hand-crafted type has missing Go fields
  81. // for specific protobuf message fields.
  82. funcs = pointerCoderFuncs{
  83. size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
  84. return 0
  85. },
  86. marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
  87. return nil, nil
  88. },
  89. unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
  90. panic("missing Go struct field for " + string(fd.FullName()))
  91. },
  92. isInit: func(p pointer, f *coderFieldInfo) error {
  93. panic("missing Go struct field for " + string(fd.FullName()))
  94. },
  95. merge: func(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
  96. panic("missing Go struct field for " + string(fd.FullName()))
  97. },
  98. }
  99. case isOneof:
  100. fieldOffset = offsetOf(fs, mi.Exporter)
  101. case fd.IsWeak():
  102. fieldOffset = si.weakOffset
  103. funcs = makeWeakMessageFieldCoder(fd)
  104. default:
  105. fieldOffset = offsetOf(fs, mi.Exporter)
  106. childMessage, funcs = fieldCoder(fd, ft)
  107. }
  108. cf := &preallocFields[i]
  109. *cf = coderFieldInfo{
  110. num: fd.Number(),
  111. offset: fieldOffset,
  112. wiretag: wiretag,
  113. ft: ft,
  114. tagsize: protowire.SizeVarint(wiretag),
  115. funcs: funcs,
  116. mi: childMessage,
  117. validation: newFieldValidationInfo(mi, si, fd, ft),
  118. isPointer: fd.Cardinality() == protoreflect.Repeated || fd.HasPresence(),
  119. isRequired: fd.Cardinality() == protoreflect.Required,
  120. }
  121. mi.orderedCoderFields = append(mi.orderedCoderFields, cf)
  122. mi.coderFields[cf.num] = cf
  123. }
  124. for i, oneofs := 0, mi.Desc.Oneofs(); i < oneofs.Len(); i++ {
  125. if od := oneofs.Get(i); !od.IsSynthetic() {
  126. mi.initOneofFieldCoders(od, si)
  127. }
  128. }
  129. if messageset.IsMessageSet(mi.Desc) {
  130. if !mi.extensionOffset.IsValid() {
  131. panic(fmt.Sprintf("%v: MessageSet with no extensions field", mi.Desc.FullName()))
  132. }
  133. if !mi.unknownOffset.IsValid() {
  134. panic(fmt.Sprintf("%v: MessageSet with no unknown field", mi.Desc.FullName()))
  135. }
  136. mi.isMessageSet = true
  137. }
  138. sort.Slice(mi.orderedCoderFields, func(i, j int) bool {
  139. return mi.orderedCoderFields[i].num < mi.orderedCoderFields[j].num
  140. })
  141. var maxDense protoreflect.FieldNumber
  142. for _, cf := range mi.orderedCoderFields {
  143. if cf.num >= 16 && cf.num >= 2*maxDense {
  144. break
  145. }
  146. maxDense = cf.num
  147. }
  148. mi.denseCoderFields = make([]*coderFieldInfo, maxDense+1)
  149. for _, cf := range mi.orderedCoderFields {
  150. if int(cf.num) >= len(mi.denseCoderFields) {
  151. break
  152. }
  153. mi.denseCoderFields[cf.num] = cf
  154. }
  155. // To preserve compatibility with historic wire output, marshal oneofs last.
  156. if mi.Desc.Oneofs().Len() > 0 {
  157. sort.Slice(mi.orderedCoderFields, func(i, j int) bool {
  158. fi := fields.ByNumber(mi.orderedCoderFields[i].num)
  159. fj := fields.ByNumber(mi.orderedCoderFields[j].num)
  160. return order.LegacyFieldOrder(fi, fj)
  161. })
  162. }
  163. mi.needsInitCheck = needsInitCheck(mi.Desc)
  164. if mi.methods.Marshal == nil && mi.methods.Size == nil {
  165. mi.methods.Flags |= protoiface.SupportMarshalDeterministic
  166. mi.methods.Marshal = mi.marshal
  167. mi.methods.Size = mi.size
  168. }
  169. if mi.methods.Unmarshal == nil {
  170. mi.methods.Flags |= protoiface.SupportUnmarshalDiscardUnknown
  171. mi.methods.Unmarshal = mi.unmarshal
  172. }
  173. if mi.methods.CheckInitialized == nil {
  174. mi.methods.CheckInitialized = mi.checkInitialized
  175. }
  176. if mi.methods.Merge == nil {
  177. mi.methods.Merge = mi.merge
  178. }
  179. }
  180. // getUnknownBytes returns a *[]byte for the unknown fields.
  181. // It is the caller's responsibility to check whether the pointer is nil.
  182. // This function is specially designed to be inlineable.
  183. func (mi *MessageInfo) getUnknownBytes(p pointer) *[]byte {
  184. if mi.unknownPtrKind {
  185. return *p.Apply(mi.unknownOffset).BytesPtr()
  186. } else {
  187. return p.Apply(mi.unknownOffset).Bytes()
  188. }
  189. }
  190. // mutableUnknownBytes returns a *[]byte for the unknown fields.
  191. // The returned pointer is guaranteed to not be nil.
  192. func (mi *MessageInfo) mutableUnknownBytes(p pointer) *[]byte {
  193. if mi.unknownPtrKind {
  194. bp := p.Apply(mi.unknownOffset).BytesPtr()
  195. if *bp == nil {
  196. *bp = new([]byte)
  197. }
  198. return *bp
  199. } else {
  200. return p.Apply(mi.unknownOffset).Bytes()
  201. }
  202. }