codec_message.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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. sizecacheOffset offset
  18. extensionOffset offset
  19. unknownOffset offset
  20. needsInitCheck bool
  21. }
  22. type coderFieldInfo struct {
  23. funcs pointerCoderFuncs // fast-path per-field functions
  24. num pref.FieldNumber // field number
  25. offset offset // struct field offset
  26. wiretag uint64 // field tag (number + wire type)
  27. tagsize int // size of the varint-encoded tag
  28. isPointer bool // true if IsNil may be called on the struct field
  29. isRequired bool // true if field is required
  30. }
  31. func (mi *MessageInfo) makeMethods(t reflect.Type, si structInfo) {
  32. mi.sizecacheOffset = invalidOffset
  33. if fx, _ := t.FieldByName("XXX_sizecache"); fx.Type == sizecacheType {
  34. mi.sizecacheOffset = offsetOf(fx)
  35. }
  36. mi.unknownOffset = invalidOffset
  37. if fx, _ := t.FieldByName("XXX_unrecognized"); fx.Type == unknownFieldsType {
  38. mi.unknownOffset = offsetOf(fx)
  39. }
  40. mi.extensionOffset = invalidOffset
  41. if fx, _ := t.FieldByName("XXX_InternalExtensions"); fx.Type == extensionFieldsType {
  42. mi.extensionOffset = offsetOf(fx)
  43. } else if fx, _ = t.FieldByName("XXX_extensions"); fx.Type == extensionFieldsType {
  44. mi.extensionOffset = offsetOf(fx)
  45. }
  46. for i := 0; i < mi.PBType.Descriptor().Fields().Len(); i++ {
  47. fd := mi.PBType.Descriptor().Fields().Get(i)
  48. if fd.ContainingOneof() != nil {
  49. continue
  50. }
  51. fs := si.fieldsByNumber[fd.Number()]
  52. ft := fs.Type
  53. var wiretag uint64
  54. if !fd.IsPacked() {
  55. wiretag = wire.EncodeTag(fd.Number(), wireTypes[fd.Kind()])
  56. } else {
  57. wiretag = wire.EncodeTag(fd.Number(), wire.BytesType)
  58. }
  59. mi.orderedCoderFields = append(mi.orderedCoderFields, &coderFieldInfo{
  60. num: fd.Number(),
  61. offset: offsetOf(fs),
  62. wiretag: wiretag,
  63. tagsize: wire.SizeVarint(wiretag),
  64. funcs: fieldCoder(fd, ft),
  65. isPointer: (fd.Cardinality() == pref.Repeated ||
  66. fd.Kind() == pref.MessageKind ||
  67. fd.Kind() == pref.GroupKind ||
  68. fd.Syntax() != pref.Proto3),
  69. isRequired: fd.Cardinality() == pref.Required,
  70. })
  71. }
  72. for i := 0; i < mi.PBType.Descriptor().Oneofs().Len(); i++ {
  73. od := mi.PBType.Descriptor().Oneofs().Get(i)
  74. fs := si.oneofsByName[od.Name()]
  75. mi.orderedCoderFields = append(mi.orderedCoderFields, &coderFieldInfo{
  76. num: od.Fields().Get(0).Number(),
  77. offset: offsetOf(fs),
  78. funcs: makeOneofFieldCoder(fs, od, si.fieldsByNumber, si.oneofWrappersByNumber),
  79. isPointer: true,
  80. })
  81. }
  82. sort.Slice(mi.orderedCoderFields, func(i, j int) bool {
  83. return mi.orderedCoderFields[i].num < mi.orderedCoderFields[j].num
  84. })
  85. mi.needsInitCheck = needsInitCheck(mi.PBType)
  86. mi.methods = piface.Methods{
  87. Flags: piface.MethodFlagDeterministicMarshal,
  88. MarshalAppend: mi.marshalAppend,
  89. Size: mi.size,
  90. IsInitialized: mi.isInitialized,
  91. }
  92. }