decode.go 4.6 KB

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