decode.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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.Message, opts piface.UnmarshalOptions) error {
  45. var p pointer
  46. if ms, ok := m.(*messageState); ok {
  47. p = ms.pointer()
  48. } else {
  49. p = m.(*messageReflectWrapper).pointer()
  50. }
  51. _, err := mi.unmarshalPointer(b, p, 0, newUnmarshalOptions(opts))
  52. return err
  53. }
  54. // errUnknown is returned during unmarshaling to indicate a parse error that
  55. // should result in a field being placed in the unknown fields section (for example,
  56. // when the wire type doesn't match) as opposed to the entire unmarshal operation
  57. // failing (for example, when a field extends past the available input).
  58. //
  59. // This is a sentinel error which should never be visible to the user.
  60. var errUnknown = errors.New("unknown")
  61. func (mi *MessageInfo) unmarshalPointer(b []byte, p pointer, groupTag wire.Number, opts unmarshalOptions) (int, error) {
  62. mi.init()
  63. var exts *map[int32]ExtensionField
  64. start := len(b)
  65. for len(b) > 0 {
  66. // Parse the tag (field number and wire type).
  67. // TODO: inline 1 and 2 byte variants?
  68. num, wtyp, n := wire.ConsumeTag(b)
  69. if n < 0 {
  70. return 0, wire.ParseError(n)
  71. }
  72. b = b[n:]
  73. var f *coderFieldInfo
  74. if int(num) < len(mi.denseCoderFields) {
  75. f = mi.denseCoderFields[num]
  76. } else {
  77. f = mi.coderFields[num]
  78. }
  79. err := errUnknown
  80. switch {
  81. case f != nil:
  82. if f.funcs.unmarshal == nil {
  83. break
  84. }
  85. n, err = f.funcs.unmarshal(b, p.Apply(f.offset), wtyp, opts)
  86. case num == groupTag && wtyp == wire.EndGroupType:
  87. // End of group.
  88. return start - len(b), nil
  89. default:
  90. // Possible extension.
  91. if exts == nil && mi.extensionOffset.IsValid() {
  92. exts = p.Apply(mi.extensionOffset).Extensions()
  93. if *exts == nil {
  94. *exts = make(map[int32]ExtensionField)
  95. }
  96. }
  97. if exts == nil {
  98. break
  99. }
  100. n, err = mi.unmarshalExtension(b, num, wtyp, *exts, opts)
  101. }
  102. if err != nil {
  103. if err != errUnknown {
  104. return 0, err
  105. }
  106. n = wire.ConsumeFieldValue(num, wtyp, b)
  107. if n < 0 {
  108. return 0, wire.ParseError(n)
  109. }
  110. if mi.unknownOffset.IsValid() {
  111. u := p.Apply(mi.unknownOffset).Bytes()
  112. *u = wire.AppendTag(*u, num, wtyp)
  113. *u = append(*u, b[:n]...)
  114. }
  115. }
  116. b = b[n:]
  117. }
  118. if groupTag != 0 {
  119. return 0, errors.New("missing end group marker")
  120. }
  121. return start, nil
  122. }
  123. func (mi *MessageInfo) unmarshalExtension(b []byte, num wire.Number, wtyp wire.Type, exts map[int32]ExtensionField, opts unmarshalOptions) (n int, err error) {
  124. x := exts[int32(num)]
  125. xt := x.GetType()
  126. if xt == nil {
  127. var err error
  128. xt, err = opts.Resolver().FindExtensionByNumber(mi.Desc.FullName(), num)
  129. if err != nil {
  130. if err == preg.NotFound {
  131. return 0, errUnknown
  132. }
  133. return 0, err
  134. }
  135. }
  136. xi := mi.extensionFieldInfo(xt)
  137. if xi.funcs.unmarshal == nil {
  138. return 0, errUnknown
  139. }
  140. ival := x.Value()
  141. if !ival.IsValid() && xi.unmarshalNeedsValue {
  142. // Create a new message, list, or map value to fill in.
  143. // For enums, create a prototype value to let the unmarshal func know the
  144. // concrete type.
  145. ival = xt.New()
  146. }
  147. v, n, err := xi.funcs.unmarshal(b, ival, num, wtyp, opts)
  148. if err != nil {
  149. return 0, err
  150. }
  151. x.Set(xt, v)
  152. exts[int32(num)] = x
  153. return n, nil
  154. }