messageset.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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 proto
  5. import (
  6. "google.golang.org/protobuf/internal/encoding/messageset"
  7. "google.golang.org/protobuf/internal/encoding/wire"
  8. "google.golang.org/protobuf/internal/errors"
  9. "google.golang.org/protobuf/internal/flags"
  10. "google.golang.org/protobuf/reflect/protoreflect"
  11. "google.golang.org/protobuf/reflect/protoregistry"
  12. )
  13. func sizeMessageSet(m protoreflect.Message) (size int) {
  14. m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
  15. size += messageset.SizeField(fd.Number())
  16. size += wire.SizeTag(messageset.FieldMessage)
  17. size += wire.SizeBytes(sizeMessage(v.Message()))
  18. return true
  19. })
  20. size += len(m.GetUnknown())
  21. return size
  22. }
  23. func marshalMessageSet(b []byte, m protoreflect.Message, o MarshalOptions) ([]byte, error) {
  24. if !flags.ProtoLegacy {
  25. return b, errors.New("no support for message_set_wire_format")
  26. }
  27. var err error
  28. o.rangeFields(m, func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
  29. b, err = marshalMessageSetField(b, fd, v, o)
  30. return err == nil
  31. })
  32. if err != nil {
  33. return b, err
  34. }
  35. b = append(b, m.GetUnknown()...)
  36. return b, nil
  37. }
  38. func marshalMessageSetField(b []byte, fd protoreflect.FieldDescriptor, value protoreflect.Value, o MarshalOptions) ([]byte, error) {
  39. b = messageset.AppendFieldStart(b, fd.Number())
  40. b = wire.AppendTag(b, messageset.FieldMessage, wire.BytesType)
  41. b = wire.AppendVarint(b, uint64(o.Size(value.Message().Interface())))
  42. b, err := o.marshalMessage(b, value.Message())
  43. if err != nil {
  44. return b, err
  45. }
  46. b = messageset.AppendFieldEnd(b)
  47. return b, nil
  48. }
  49. func unmarshalMessageSet(b []byte, m protoreflect.Message, o UnmarshalOptions) error {
  50. if !flags.ProtoLegacy {
  51. return errors.New("no support for message_set_wire_format")
  52. }
  53. md := m.Descriptor()
  54. for len(b) > 0 {
  55. err := func() error {
  56. num, v, n, err := messageset.ConsumeField(b)
  57. if err != nil {
  58. // Not a message set field.
  59. //
  60. // Return errUnknown to try to add this to the unknown fields.
  61. // If the field is completely unparsable, we'll catch it
  62. // when trying to skip the field.
  63. return errUnknown
  64. }
  65. if !md.ExtensionRanges().Has(num) {
  66. return errUnknown
  67. }
  68. xt, err := o.Resolver.FindExtensionByNumber(md.FullName(), num)
  69. if err == protoregistry.NotFound {
  70. return errUnknown
  71. }
  72. if err != nil {
  73. return err
  74. }
  75. xd := xt.TypeDescriptor()
  76. if err := o.unmarshalMessage(v, m.Mutable(xd).Message()); err != nil {
  77. // Contents cannot be unmarshaled.
  78. return err
  79. }
  80. b = b[n:]
  81. return nil
  82. }()
  83. if err == errUnknown {
  84. _, _, n := wire.ConsumeField(b)
  85. if n < 0 {
  86. return wire.ParseError(n)
  87. }
  88. m.SetUnknown(append(m.GetUnknown(), b[:n]...))
  89. b = b[n:]
  90. continue
  91. }
  92. if err != nil {
  93. return err
  94. }
  95. }
  96. return nil
  97. }