desc_list.go 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  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 filedesc
  5. import (
  6. "fmt"
  7. "math"
  8. "sort"
  9. "sync"
  10. "google.golang.org/protobuf/internal/descfmt"
  11. "google.golang.org/protobuf/internal/encoding/wire"
  12. "google.golang.org/protobuf/internal/errors"
  13. "google.golang.org/protobuf/internal/pragma"
  14. "google.golang.org/protobuf/reflect/protoreflect"
  15. pref "google.golang.org/protobuf/reflect/protoreflect"
  16. )
  17. type FileImports []pref.FileImport
  18. func (p *FileImports) Len() int { return len(*p) }
  19. func (p *FileImports) Get(i int) pref.FileImport { return (*p)[i] }
  20. func (p *FileImports) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) }
  21. func (p *FileImports) ProtoInternal(pragma.DoNotImplement) {}
  22. type Names struct {
  23. List []pref.Name
  24. once sync.Once
  25. has map[pref.Name]int // protected by once
  26. }
  27. func (p *Names) Len() int { return len(p.List) }
  28. func (p *Names) Get(i int) pref.Name { return p.List[i] }
  29. func (p *Names) Has(s pref.Name) bool { return p.lazyInit().has[s] > 0 }
  30. func (p *Names) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) }
  31. func (p *Names) ProtoInternal(pragma.DoNotImplement) {}
  32. func (p *Names) lazyInit() *Names {
  33. p.once.Do(func() {
  34. if len(p.List) > 0 {
  35. p.has = make(map[pref.Name]int, len(p.List))
  36. for _, s := range p.List {
  37. p.has[s] = p.has[s] + 1
  38. }
  39. }
  40. })
  41. return p
  42. }
  43. // CheckValid reports any errors with the set of names with an error message
  44. // that completes the sentence: "ranges is invalid because it has ..."
  45. func (p *Names) CheckValid() error {
  46. for s, n := range p.lazyInit().has {
  47. switch {
  48. case n > 1:
  49. return errors.New("duplicate name: %q", s)
  50. case false && !s.IsValid():
  51. // NOTE: The C++ implementation does not validate the identifier.
  52. // See https://github.com/protocolbuffers/protobuf/issues/6335.
  53. return errors.New("invalid name: %q", s)
  54. }
  55. }
  56. return nil
  57. }
  58. type EnumRanges struct {
  59. List [][2]pref.EnumNumber // start inclusive; end inclusive
  60. once sync.Once
  61. sorted [][2]pref.EnumNumber // protected by once
  62. }
  63. func (p *EnumRanges) Len() int { return len(p.List) }
  64. func (p *EnumRanges) Get(i int) [2]pref.EnumNumber { return p.List[i] }
  65. func (p *EnumRanges) Has(n pref.EnumNumber) bool {
  66. for ls := p.lazyInit().sorted; len(ls) > 0; {
  67. i := len(ls) / 2
  68. switch r := enumRange(ls[i]); {
  69. case n < r.Start():
  70. ls = ls[:i] // search lower
  71. case n > r.End():
  72. ls = ls[i+1:] // search upper
  73. default:
  74. return true
  75. }
  76. }
  77. return false
  78. }
  79. func (p *EnumRanges) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) }
  80. func (p *EnumRanges) ProtoInternal(pragma.DoNotImplement) {}
  81. func (p *EnumRanges) lazyInit() *EnumRanges {
  82. p.once.Do(func() {
  83. p.sorted = append(p.sorted, p.List...)
  84. sort.Slice(p.sorted, func(i, j int) bool {
  85. return p.sorted[i][0] < p.sorted[j][0]
  86. })
  87. })
  88. return p
  89. }
  90. // CheckValid reports any errors with the set of names with an error message
  91. // that completes the sentence: "ranges is invalid because it has ..."
  92. func (p *EnumRanges) CheckValid() error {
  93. var rp enumRange
  94. for i, r := range p.lazyInit().sorted {
  95. r := enumRange(r)
  96. switch {
  97. case !(r.Start() <= r.End()):
  98. return errors.New("invalid range: %v", r)
  99. case !(rp.End() < r.Start()) && i > 0:
  100. return errors.New("overlapping ranges: %v with %v", rp, r)
  101. }
  102. rp = r
  103. }
  104. return nil
  105. }
  106. type enumRange [2]protoreflect.EnumNumber
  107. func (r enumRange) Start() protoreflect.EnumNumber { return r[0] } // inclusive
  108. func (r enumRange) End() protoreflect.EnumNumber { return r[1] } // inclusive
  109. func (r enumRange) String() string {
  110. if r.Start() == r.End() {
  111. return fmt.Sprintf("%d", r.Start())
  112. }
  113. return fmt.Sprintf("%d to %d", r.Start(), r.End())
  114. }
  115. type FieldRanges struct {
  116. List [][2]pref.FieldNumber // start inclusive; end exclusive
  117. once sync.Once
  118. sorted [][2]pref.FieldNumber // protected by once
  119. }
  120. func (p *FieldRanges) Len() int { return len(p.List) }
  121. func (p *FieldRanges) Get(i int) [2]pref.FieldNumber { return p.List[i] }
  122. func (p *FieldRanges) Has(n pref.FieldNumber) bool {
  123. for ls := p.lazyInit().sorted; len(ls) > 0; {
  124. i := len(ls) / 2
  125. switch r := fieldRange(ls[i]); {
  126. case n < r.Start():
  127. ls = ls[:i] // search lower
  128. case n > r.End():
  129. ls = ls[i+1:] // search upper
  130. default:
  131. return true
  132. }
  133. }
  134. return false
  135. }
  136. func (p *FieldRanges) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) }
  137. func (p *FieldRanges) ProtoInternal(pragma.DoNotImplement) {}
  138. func (p *FieldRanges) lazyInit() *FieldRanges {
  139. p.once.Do(func() {
  140. p.sorted = append(p.sorted, p.List...)
  141. sort.Slice(p.sorted, func(i, j int) bool {
  142. return p.sorted[i][0] < p.sorted[j][0]
  143. })
  144. })
  145. return p
  146. }
  147. // CheckValid reports any errors with the set of ranges with an error message
  148. // that completes the sentence: "ranges is invalid because it has ..."
  149. func (p *FieldRanges) CheckValid(isMessageSet bool) error {
  150. var rp fieldRange
  151. for i, r := range p.lazyInit().sorted {
  152. r := fieldRange(r)
  153. switch {
  154. case !isValidFieldNumber(r.Start(), isMessageSet):
  155. return errors.New("invalid field number: %d", r.Start())
  156. case !isValidFieldNumber(r.End(), isMessageSet):
  157. return errors.New("invalid field number: %d", r.End())
  158. case !(r.Start() <= r.End()):
  159. return errors.New("invalid range: %v", r)
  160. case !(rp.End() < r.Start()) && i > 0:
  161. return errors.New("overlapping ranges: %v with %v", rp, r)
  162. }
  163. rp = r
  164. }
  165. return nil
  166. }
  167. // isValidFieldNumber reports whether the field number is valid.
  168. // Unlike the FieldNumber.IsValid method, it allows ranges that cover the
  169. // reserved number range.
  170. func isValidFieldNumber(n protoreflect.FieldNumber, isMessageSet bool) bool {
  171. if isMessageSet {
  172. return wire.MinValidNumber <= n && n <= math.MaxInt32
  173. }
  174. return wire.MinValidNumber <= n && n <= wire.MaxValidNumber
  175. }
  176. // CheckOverlap reports an error if p and q overlap.
  177. func (p *FieldRanges) CheckOverlap(q *FieldRanges) error {
  178. rps := p.lazyInit().sorted
  179. rqs := q.lazyInit().sorted
  180. for pi, qi := 0, 0; pi < len(rps) && qi < len(rqs); {
  181. rp := fieldRange(rps[pi])
  182. rq := fieldRange(rqs[qi])
  183. if !(rp.End() < rq.Start() || rq.End() < rp.Start()) {
  184. return errors.New("overlapping ranges: %v with %v", rp, rq)
  185. }
  186. if rp.Start() < rq.Start() {
  187. pi++
  188. } else {
  189. qi++
  190. }
  191. }
  192. return nil
  193. }
  194. type fieldRange [2]protoreflect.FieldNumber
  195. func (r fieldRange) Start() protoreflect.FieldNumber { return r[0] } // inclusive
  196. func (r fieldRange) End() protoreflect.FieldNumber { return r[1] - 1 } // inclusive
  197. func (r fieldRange) String() string {
  198. if r.Start() == r.End() {
  199. return fmt.Sprintf("%d", r.Start())
  200. }
  201. return fmt.Sprintf("%d to %d", r.Start(), r.End())
  202. }
  203. type FieldNumbers struct {
  204. List []pref.FieldNumber
  205. once sync.Once
  206. has map[pref.FieldNumber]struct{} // protected by once
  207. }
  208. func (p *FieldNumbers) Len() int { return len(p.List) }
  209. func (p *FieldNumbers) Get(i int) pref.FieldNumber { return p.List[i] }
  210. func (p *FieldNumbers) Has(n pref.FieldNumber) bool {
  211. p.once.Do(func() {
  212. if len(p.List) > 0 {
  213. p.has = make(map[pref.FieldNumber]struct{}, len(p.List))
  214. for _, n := range p.List {
  215. p.has[n] = struct{}{}
  216. }
  217. }
  218. })
  219. _, ok := p.has[n]
  220. return ok
  221. }
  222. func (p *FieldNumbers) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) }
  223. func (p *FieldNumbers) ProtoInternal(pragma.DoNotImplement) {}
  224. type OneofFields struct {
  225. List []pref.FieldDescriptor
  226. once sync.Once
  227. byName map[pref.Name]pref.FieldDescriptor // protected by once
  228. byJSON map[string]pref.FieldDescriptor // protected by once
  229. byNum map[pref.FieldNumber]pref.FieldDescriptor // protected by once
  230. }
  231. func (p *OneofFields) Len() int { return len(p.List) }
  232. func (p *OneofFields) Get(i int) pref.FieldDescriptor { return p.List[i] }
  233. func (p *OneofFields) ByName(s pref.Name) pref.FieldDescriptor { return p.lazyInit().byName[s] }
  234. func (p *OneofFields) ByJSONName(s string) pref.FieldDescriptor { return p.lazyInit().byJSON[s] }
  235. func (p *OneofFields) ByNumber(n pref.FieldNumber) pref.FieldDescriptor { return p.lazyInit().byNum[n] }
  236. func (p *OneofFields) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) }
  237. func (p *OneofFields) ProtoInternal(pragma.DoNotImplement) {}
  238. func (p *OneofFields) lazyInit() *OneofFields {
  239. p.once.Do(func() {
  240. if len(p.List) > 0 {
  241. p.byName = make(map[pref.Name]pref.FieldDescriptor, len(p.List))
  242. p.byJSON = make(map[string]pref.FieldDescriptor, len(p.List))
  243. p.byNum = make(map[pref.FieldNumber]pref.FieldDescriptor, len(p.List))
  244. for _, f := range p.List {
  245. // Field names and numbers are guaranteed to be unique.
  246. p.byName[f.Name()] = f
  247. p.byJSON[f.JSONName()] = f
  248. p.byNum[f.Number()] = f
  249. }
  250. }
  251. })
  252. return p
  253. }
  254. type SourceLocations struct {
  255. List []pref.SourceLocation
  256. }
  257. func (p *SourceLocations) Len() int { return len(p.List) }
  258. func (p *SourceLocations) Get(i int) pref.SourceLocation { return p.List[i] }
  259. func (p *SourceLocations) ProtoInternal(pragma.DoNotImplement) {}