decode.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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. "google.golang.org/protobuf/internal/encoding/wire"
  7. "google.golang.org/protobuf/internal/errors"
  8. "google.golang.org/protobuf/proto"
  9. pref "google.golang.org/protobuf/reflect/protoreflect"
  10. preg "google.golang.org/protobuf/reflect/protoregistry"
  11. piface "google.golang.org/protobuf/runtime/protoiface"
  12. )
  13. // unmarshalOptions is a more efficient representation of UnmarshalOptions.
  14. //
  15. // We don't preserve the AllowPartial flag, because fast-path (un)marshal
  16. // operations always allow partial messages.
  17. type unmarshalOptions struct {
  18. flags unmarshalOptionFlags
  19. resolver preg.ExtensionTypeResolver
  20. }
  21. type unmarshalOptionFlags uint8
  22. const (
  23. unmarshalDiscardUnknown unmarshalOptionFlags = 1 << iota
  24. )
  25. func newUnmarshalOptions(opts piface.UnmarshalOptions) unmarshalOptions {
  26. o := unmarshalOptions{
  27. resolver: opts.Resolver,
  28. }
  29. if opts.DiscardUnknown {
  30. o.flags |= unmarshalDiscardUnknown
  31. }
  32. return o
  33. }
  34. func (o unmarshalOptions) Options() proto.UnmarshalOptions {
  35. return proto.UnmarshalOptions{
  36. AllowPartial: true,
  37. DiscardUnknown: o.DiscardUnknown(),
  38. Resolver: o.Resolver(),
  39. }
  40. }
  41. func (o unmarshalOptions) DiscardUnknown() bool { return o.flags&unmarshalDiscardUnknown != 0 }
  42. func (o unmarshalOptions) Resolver() preg.ExtensionTypeResolver { return o.resolver }
  43. // unmarshal is protoreflect.Methods.Unmarshal.
  44. func (mi *MessageInfo) unmarshal(b []byte, m pref.ProtoMessage, opts piface.UnmarshalOptions) error {
  45. _, err := mi.unmarshalPointer(b, pointerOfIface(m), 0, newUnmarshalOptions(opts))
  46. return err
  47. }
  48. // errUnknown is returned during unmarshaling to indicate a parse error that
  49. // should result in a field being placed in the unknown fields section (for example,
  50. // when the wire type doesn't match) as opposed to the entire unmarshal operation
  51. // failing (for example, when a field extends past the available input).
  52. //
  53. // This is a sentinel error which should never be visible to the user.
  54. var errUnknown = errors.New("unknown")
  55. func (mi *MessageInfo) unmarshalPointer(b []byte, p pointer, groupTag wire.Number, opts unmarshalOptions) (int, error) {
  56. mi.init()
  57. var exts *map[int32]ExtensionField
  58. start := len(b)
  59. for len(b) > 0 {
  60. // Parse the tag (field number and wire type).
  61. // TODO: inline 1 and 2 byte variants?
  62. num, wtyp, n := wire.ConsumeTag(b)
  63. if n < 0 {
  64. return 0, wire.ParseError(n)
  65. }
  66. b = b[n:]
  67. var f *coderFieldInfo
  68. if int(num) < len(mi.denseCoderFields) {
  69. f = mi.denseCoderFields[num]
  70. } else {
  71. f = mi.coderFields[num]
  72. }
  73. err := errUnknown
  74. switch {
  75. case f != nil:
  76. if f.funcs.unmarshal == nil {
  77. break
  78. }
  79. n, err = f.funcs.unmarshal(b, p.Apply(f.offset), wtyp, opts)
  80. case num == groupTag && wtyp == wire.EndGroupType:
  81. // End of group.
  82. return start - len(b), nil
  83. default:
  84. // Possible extension.
  85. if exts == nil && mi.extensionOffset.IsValid() {
  86. exts = p.Apply(mi.extensionOffset).Extensions()
  87. if *exts == nil {
  88. *exts = make(map[int32]ExtensionField)
  89. }
  90. }
  91. if exts == nil {
  92. break
  93. }
  94. n, err = mi.unmarshalExtension(b, num, wtyp, *exts, opts)
  95. }
  96. if err != nil {
  97. if err != errUnknown {
  98. return 0, err
  99. }
  100. n = wire.ConsumeFieldValue(num, wtyp, b)
  101. if n < 0 {
  102. return 0, wire.ParseError(n)
  103. }
  104. if mi.unknownOffset.IsValid() {
  105. u := p.Apply(mi.unknownOffset).Bytes()
  106. *u = wire.AppendTag(*u, num, wtyp)
  107. *u = append(*u, b[:n]...)
  108. }
  109. }
  110. b = b[n:]
  111. }
  112. if groupTag != 0 {
  113. return 0, errors.New("missing end group marker")
  114. }
  115. return start, nil
  116. }
  117. func (mi *MessageInfo) unmarshalExtension(b []byte, num wire.Number, wtyp wire.Type, exts map[int32]ExtensionField, opts unmarshalOptions) (n int, err error) {
  118. x := exts[int32(num)]
  119. xt := x.GetType()
  120. if xt == nil {
  121. var err error
  122. xt, err = opts.Resolver().FindExtensionByNumber(mi.PBType.FullName(), num)
  123. if err != nil {
  124. if err == preg.NotFound {
  125. return 0, errUnknown
  126. }
  127. return 0, err
  128. }
  129. x.SetType(xt)
  130. }
  131. xi := mi.extensionFieldInfo(xt)
  132. if xi.funcs.unmarshal == nil {
  133. return 0, errUnknown
  134. }
  135. ival := x.GetValue()
  136. if ival == nil && xi.unmarshalNeedsValue {
  137. // Create a new message, list, or map value to fill in.
  138. // For enums, create a prototype value to let the unmarshal func know the
  139. // concrete type.
  140. ival = xt.InterfaceOf(xt.New())
  141. }
  142. v, n, err := xi.funcs.unmarshal(b, ival, num, wtyp, opts)
  143. if err != nil {
  144. return 0, err
  145. }
  146. x.SetEagerValue(v)
  147. exts[int32(num)] = x
  148. return n, nil
  149. }