legacy_unknown.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. // Copyright 2018 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. "container/list"
  7. "reflect"
  8. "sort"
  9. papi "github.com/golang/protobuf/protoapi"
  10. "github.com/golang/protobuf/v2/internal/encoding/wire"
  11. pref "github.com/golang/protobuf/v2/reflect/protoreflect"
  12. )
  13. var bytesType = reflect.TypeOf([]byte(nil))
  14. func makeLegacyUnknownFieldsFunc(t reflect.Type) func(p *messageDataType) pref.UnknownFields {
  15. fu, ok := t.FieldByName("XXX_unrecognized")
  16. if !ok || fu.Type != bytesType {
  17. return nil
  18. }
  19. fieldOffset := offsetOf(fu)
  20. unkFunc := func(p *messageDataType) pref.UnknownFields {
  21. if p.p.IsNil() {
  22. return emptyUnknownFields{}
  23. }
  24. rv := p.p.Apply(fieldOffset).AsValueOf(bytesType)
  25. return (*legacyUnknownBytes)(rv.Interface().(*[]byte))
  26. }
  27. extFunc := makeLegacyExtensionMapFunc(t)
  28. if extFunc != nil {
  29. return func(p *messageDataType) pref.UnknownFields {
  30. if p.p.IsNil() {
  31. return emptyUnknownFields{}
  32. }
  33. return &legacyUnknownBytesAndExtensionMap{
  34. unkFunc(p), extFunc(p), p.mi.PBType.ExtensionRanges(),
  35. }
  36. }
  37. }
  38. return unkFunc
  39. }
  40. // legacyUnknownBytesAndExtensionMap is a wrapper around both XXX_unrecognized
  41. // and also the extension field map.
  42. type legacyUnknownBytesAndExtensionMap struct {
  43. u pref.UnknownFields
  44. x papi.ExtensionFields
  45. r pref.FieldRanges
  46. }
  47. func (fs *legacyUnknownBytesAndExtensionMap) Len() int {
  48. n := fs.u.Len()
  49. fs.x.Range(func(_ pref.FieldNumber, x papi.ExtensionField) bool {
  50. if len(x.Raw) > 0 {
  51. n++
  52. }
  53. return true
  54. })
  55. return n
  56. }
  57. func (fs *legacyUnknownBytesAndExtensionMap) Get(num pref.FieldNumber) (raw pref.RawFields) {
  58. if fs.r.Has(num) {
  59. return fs.x.Get(num).Raw
  60. }
  61. return fs.u.Get(num)
  62. }
  63. func (fs *legacyUnknownBytesAndExtensionMap) Set(num pref.FieldNumber, raw pref.RawFields) {
  64. if fs.r.Has(num) {
  65. x := fs.x.Get(num)
  66. x.Raw = raw
  67. fs.x.Set(num, x)
  68. return
  69. }
  70. fs.u.Set(num, raw)
  71. }
  72. func (fs *legacyUnknownBytesAndExtensionMap) Range(f func(pref.FieldNumber, pref.RawFields) bool) {
  73. // Range over unknown fields not in the extension range.
  74. // Create a closure around f to capture whether iteration terminated early.
  75. var stop bool
  76. fs.u.Range(func(n pref.FieldNumber, b pref.RawFields) bool {
  77. stop = stop || !f(n, b)
  78. return !stop
  79. })
  80. if stop {
  81. return
  82. }
  83. // Range over unknown fields in the extension range in ascending order
  84. // to ensure protoreflect.UnknownFields.Range remains deterministic.
  85. type entry struct {
  86. num pref.FieldNumber
  87. raw pref.RawFields
  88. }
  89. var xs []entry
  90. fs.x.Range(func(n pref.FieldNumber, x papi.ExtensionField) bool {
  91. if len(x.Raw) > 0 {
  92. xs = append(xs, entry{n, x.Raw})
  93. }
  94. return true
  95. })
  96. sort.Slice(xs, func(i, j int) bool { return xs[i].num < xs[j].num })
  97. for _, x := range xs {
  98. if !f(x.num, x.raw) {
  99. return
  100. }
  101. }
  102. }
  103. func (fs *legacyUnknownBytesAndExtensionMap) IsSupported() bool {
  104. return true
  105. }
  106. // legacyUnknownBytes is a wrapper around XXX_unrecognized that implements
  107. // the protoreflect.UnknownFields interface. This is challenging since we are
  108. // limited to a []byte, so we do not have much flexibility in the choice
  109. // of data structure that would have been ideal.
  110. type legacyUnknownBytes []byte
  111. func (fs *legacyUnknownBytes) Len() int {
  112. // Runtime complexity: O(n)
  113. b := *fs
  114. m := map[pref.FieldNumber]bool{}
  115. for len(b) > 0 {
  116. num, _, n := wire.ConsumeField(b)
  117. m[num] = true
  118. b = b[n:]
  119. }
  120. return len(m)
  121. }
  122. func (fs *legacyUnknownBytes) Get(num pref.FieldNumber) (raw pref.RawFields) {
  123. // Runtime complexity: O(n)
  124. b := *fs
  125. for len(b) > 0 {
  126. num2, _, n := wire.ConsumeField(b)
  127. if num == num2 {
  128. raw = append(raw, b[:n]...)
  129. }
  130. b = b[n:]
  131. }
  132. return raw
  133. }
  134. func (fs *legacyUnknownBytes) Set(num pref.FieldNumber, raw pref.RawFields) {
  135. num2, _, _ := wire.ConsumeTag(raw)
  136. if len(raw) > 0 && (!raw.IsValid() || num != num2) {
  137. panic("invalid raw fields")
  138. }
  139. // Remove all current fields of num.
  140. // Runtime complexity: O(n)
  141. b := *fs
  142. out := (*fs)[:0]
  143. for len(b) > 0 {
  144. num2, _, n := wire.ConsumeField(b)
  145. if num != num2 {
  146. out = append(out, b[:n]...)
  147. }
  148. b = b[n:]
  149. }
  150. *fs = out
  151. // Append new fields of num.
  152. *fs = append(*fs, raw...)
  153. }
  154. func (fs *legacyUnknownBytes) Range(f func(pref.FieldNumber, pref.RawFields) bool) {
  155. type entry struct {
  156. num pref.FieldNumber
  157. raw pref.RawFields
  158. }
  159. // Collect up a list of all the raw fields.
  160. // We preserve the order such that the latest encountered fields
  161. // are presented at the end.
  162. //
  163. // Runtime complexity: O(n)
  164. b := *fs
  165. l := list.New()
  166. m := map[pref.FieldNumber]*list.Element{}
  167. for len(b) > 0 {
  168. num, _, n := wire.ConsumeField(b)
  169. if e, ok := m[num]; ok {
  170. x := e.Value.(*entry)
  171. x.raw = append(x.raw, b[:n]...)
  172. l.MoveToBack(e)
  173. } else {
  174. x := &entry{num: num}
  175. x.raw = append(x.raw, b[:n]...)
  176. m[num] = l.PushBack(x)
  177. }
  178. b = b[n:]
  179. }
  180. // Iterate over all the raw fields.
  181. // This ranges over a snapshot of the current state such that mutations
  182. // while ranging are not observable.
  183. //
  184. // Runtime complexity: O(n)
  185. for e := l.Front(); e != nil; e = e.Next() {
  186. x := e.Value.(*entry)
  187. if !f(x.num, x.raw) {
  188. return
  189. }
  190. }
  191. }
  192. func (fs *legacyUnknownBytes) IsSupported() bool {
  193. return true
  194. }