legacy_unknown.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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. "github.com/golang/protobuf/v2/internal/encoding/wire"
  9. pref "github.com/golang/protobuf/v2/reflect/protoreflect"
  10. )
  11. var bytesType = reflect.TypeOf([]byte(nil))
  12. func makeLegacyUnknownFieldsFunc(t reflect.Type) func(p *messageDataType) pref.UnknownFields {
  13. fu, ok := t.FieldByName("XXX_unrecognized")
  14. if !ok || fu.Type != bytesType {
  15. return nil
  16. }
  17. fieldOffset := offsetOf(fu)
  18. return func(p *messageDataType) pref.UnknownFields {
  19. if p.p.IsNil() {
  20. return emptyUnknownFields{}
  21. }
  22. rv := p.p.Apply(fieldOffset).AsValueOf(bytesType)
  23. return (*legacyUnknownBytes)(rv.Interface().(*[]byte))
  24. }
  25. }
  26. // legacyUnknownBytes is a wrapper around XXX_unrecognized that implements
  27. // the protoreflect.UnknownFields interface. This is challenging since we are
  28. // limited to a []byte, so we do not have much flexibility in the choice
  29. // of data structure that would have been ideal.
  30. type legacyUnknownBytes []byte
  31. func (fs *legacyUnknownBytes) Len() int {
  32. // Runtime complexity: O(n)
  33. b := *fs
  34. m := map[pref.FieldNumber]bool{}
  35. for len(b) > 0 {
  36. num, _, n := wire.ConsumeField(b)
  37. m[num] = true
  38. b = b[n:]
  39. }
  40. return len(m)
  41. }
  42. func (fs *legacyUnknownBytes) Get(num pref.FieldNumber) (raw pref.RawFields) {
  43. // Runtime complexity: O(n)
  44. b := *fs
  45. for len(b) > 0 {
  46. num2, _, n := wire.ConsumeField(b)
  47. if num == num2 {
  48. raw = append(raw, b[:n]...)
  49. }
  50. b = b[n:]
  51. }
  52. return raw
  53. }
  54. func (fs *legacyUnknownBytes) Set(num pref.FieldNumber, raw pref.RawFields) {
  55. num2, _, _ := wire.ConsumeTag(raw)
  56. if len(raw) > 0 && (!raw.IsValid() || num != num2) {
  57. panic("invalid raw fields")
  58. }
  59. // Remove all current fields of num.
  60. // Runtime complexity: O(n)
  61. b := *fs
  62. out := (*fs)[:0]
  63. for len(b) > 0 {
  64. num2, _, n := wire.ConsumeField(b)
  65. if num != num2 {
  66. out = append(out, b[:n]...)
  67. }
  68. b = b[n:]
  69. }
  70. *fs = out
  71. // Append new fields of num.
  72. *fs = append(*fs, raw...)
  73. }
  74. func (fs *legacyUnknownBytes) Range(f func(pref.FieldNumber, pref.RawFields) bool) {
  75. type entry struct {
  76. num pref.FieldNumber
  77. raw pref.RawFields
  78. }
  79. // Collect up a list of all the raw fields.
  80. // We preserve the order such that the latest encountered fields
  81. // are presented at the end.
  82. //
  83. // Runtime complexity: O(n)
  84. b := *fs
  85. l := list.New()
  86. m := map[pref.FieldNumber]*list.Element{}
  87. for len(b) > 0 {
  88. num, _, n := wire.ConsumeField(b)
  89. if e, ok := m[num]; ok {
  90. x := e.Value.(*entry)
  91. x.raw = append(x.raw, b[:n]...)
  92. l.MoveToBack(e)
  93. } else {
  94. x := &entry{num: num}
  95. x.raw = append(x.raw, b[:n]...)
  96. m[num] = l.PushBack(x)
  97. }
  98. b = b[n:]
  99. }
  100. // Iterate over all the raw fields.
  101. // This ranges over a snapshot of the current state such that mutations
  102. // while ranging are not observable.
  103. //
  104. // Runtime complexity: O(n)
  105. for e := l.Front(); e != nil; e = e.Next() {
  106. x := e.Value.(*entry)
  107. if !f(x.num, x.raw) {
  108. return
  109. }
  110. }
  111. }
  112. func (fs *legacyUnknownBytes) IsSupported() bool {
  113. return true
  114. }