desc_list.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  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/genid"
  11. "google.golang.org/protobuf/encoding/protowire"
  12. "google.golang.org/protobuf/internal/descfmt"
  13. "google.golang.org/protobuf/internal/errors"
  14. "google.golang.org/protobuf/internal/pragma"
  15. "google.golang.org/protobuf/reflect/protoreflect"
  16. pref "google.golang.org/protobuf/reflect/protoreflect"
  17. )
  18. type FileImports []pref.FileImport
  19. func (p *FileImports) Len() int { return len(*p) }
  20. func (p *FileImports) Get(i int) pref.FileImport { return (*p)[i] }
  21. func (p *FileImports) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) }
  22. func (p *FileImports) ProtoInternal(pragma.DoNotImplement) {}
  23. type Names struct {
  24. List []pref.Name
  25. once sync.Once
  26. has map[pref.Name]int // protected by once
  27. }
  28. func (p *Names) Len() int { return len(p.List) }
  29. func (p *Names) Get(i int) pref.Name { return p.List[i] }
  30. func (p *Names) Has(s pref.Name) bool { return p.lazyInit().has[s] > 0 }
  31. func (p *Names) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) }
  32. func (p *Names) ProtoInternal(pragma.DoNotImplement) {}
  33. func (p *Names) lazyInit() *Names {
  34. p.once.Do(func() {
  35. if len(p.List) > 0 {
  36. p.has = make(map[pref.Name]int, len(p.List))
  37. for _, s := range p.List {
  38. p.has[s] = p.has[s] + 1
  39. }
  40. }
  41. })
  42. return p
  43. }
  44. // CheckValid reports any errors with the set of names with an error message
  45. // that completes the sentence: "ranges is invalid because it has ..."
  46. func (p *Names) CheckValid() error {
  47. for s, n := range p.lazyInit().has {
  48. switch {
  49. case n > 1:
  50. return errors.New("duplicate name: %q", s)
  51. case false && !s.IsValid():
  52. // NOTE: The C++ implementation does not validate the identifier.
  53. // See https://github.com/protocolbuffers/protobuf/issues/6335.
  54. return errors.New("invalid name: %q", s)
  55. }
  56. }
  57. return nil
  58. }
  59. type EnumRanges struct {
  60. List [][2]pref.EnumNumber // start inclusive; end inclusive
  61. once sync.Once
  62. sorted [][2]pref.EnumNumber // protected by once
  63. }
  64. func (p *EnumRanges) Len() int { return len(p.List) }
  65. func (p *EnumRanges) Get(i int) [2]pref.EnumNumber { return p.List[i] }
  66. func (p *EnumRanges) Has(n pref.EnumNumber) bool {
  67. for ls := p.lazyInit().sorted; len(ls) > 0; {
  68. i := len(ls) / 2
  69. switch r := enumRange(ls[i]); {
  70. case n < r.Start():
  71. ls = ls[:i] // search lower
  72. case n > r.End():
  73. ls = ls[i+1:] // search upper
  74. default:
  75. return true
  76. }
  77. }
  78. return false
  79. }
  80. func (p *EnumRanges) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) }
  81. func (p *EnumRanges) ProtoInternal(pragma.DoNotImplement) {}
  82. func (p *EnumRanges) lazyInit() *EnumRanges {
  83. p.once.Do(func() {
  84. p.sorted = append(p.sorted, p.List...)
  85. sort.Slice(p.sorted, func(i, j int) bool {
  86. return p.sorted[i][0] < p.sorted[j][0]
  87. })
  88. })
  89. return p
  90. }
  91. // CheckValid reports any errors with the set of names with an error message
  92. // that completes the sentence: "ranges is invalid because it has ..."
  93. func (p *EnumRanges) CheckValid() error {
  94. var rp enumRange
  95. for i, r := range p.lazyInit().sorted {
  96. r := enumRange(r)
  97. switch {
  98. case !(r.Start() <= r.End()):
  99. return errors.New("invalid range: %v", r)
  100. case !(rp.End() < r.Start()) && i > 0:
  101. return errors.New("overlapping ranges: %v with %v", rp, r)
  102. }
  103. rp = r
  104. }
  105. return nil
  106. }
  107. type enumRange [2]protoreflect.EnumNumber
  108. func (r enumRange) Start() protoreflect.EnumNumber { return r[0] } // inclusive
  109. func (r enumRange) End() protoreflect.EnumNumber { return r[1] } // inclusive
  110. func (r enumRange) String() string {
  111. if r.Start() == r.End() {
  112. return fmt.Sprintf("%d", r.Start())
  113. }
  114. return fmt.Sprintf("%d to %d", r.Start(), r.End())
  115. }
  116. type FieldRanges struct {
  117. List [][2]pref.FieldNumber // start inclusive; end exclusive
  118. once sync.Once
  119. sorted [][2]pref.FieldNumber // protected by once
  120. }
  121. func (p *FieldRanges) Len() int { return len(p.List) }
  122. func (p *FieldRanges) Get(i int) [2]pref.FieldNumber { return p.List[i] }
  123. func (p *FieldRanges) Has(n pref.FieldNumber) bool {
  124. for ls := p.lazyInit().sorted; len(ls) > 0; {
  125. i := len(ls) / 2
  126. switch r := fieldRange(ls[i]); {
  127. case n < r.Start():
  128. ls = ls[:i] // search lower
  129. case n > r.End():
  130. ls = ls[i+1:] // search upper
  131. default:
  132. return true
  133. }
  134. }
  135. return false
  136. }
  137. func (p *FieldRanges) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) }
  138. func (p *FieldRanges) ProtoInternal(pragma.DoNotImplement) {}
  139. func (p *FieldRanges) lazyInit() *FieldRanges {
  140. p.once.Do(func() {
  141. p.sorted = append(p.sorted, p.List...)
  142. sort.Slice(p.sorted, func(i, j int) bool {
  143. return p.sorted[i][0] < p.sorted[j][0]
  144. })
  145. })
  146. return p
  147. }
  148. // CheckValid reports any errors with the set of ranges with an error message
  149. // that completes the sentence: "ranges is invalid because it has ..."
  150. func (p *FieldRanges) CheckValid(isMessageSet bool) error {
  151. var rp fieldRange
  152. for i, r := range p.lazyInit().sorted {
  153. r := fieldRange(r)
  154. switch {
  155. case !isValidFieldNumber(r.Start(), isMessageSet):
  156. return errors.New("invalid field number: %d", r.Start())
  157. case !isValidFieldNumber(r.End(), isMessageSet):
  158. return errors.New("invalid field number: %d", r.End())
  159. case !(r.Start() <= r.End()):
  160. return errors.New("invalid range: %v", r)
  161. case !(rp.End() < r.Start()) && i > 0:
  162. return errors.New("overlapping ranges: %v with %v", rp, r)
  163. }
  164. rp = r
  165. }
  166. return nil
  167. }
  168. // isValidFieldNumber reports whether the field number is valid.
  169. // Unlike the FieldNumber.IsValid method, it allows ranges that cover the
  170. // reserved number range.
  171. func isValidFieldNumber(n protoreflect.FieldNumber, isMessageSet bool) bool {
  172. return protowire.MinValidNumber <= n && (n <= protowire.MaxValidNumber || isMessageSet)
  173. }
  174. // CheckOverlap reports an error if p and q overlap.
  175. func (p *FieldRanges) CheckOverlap(q *FieldRanges) error {
  176. rps := p.lazyInit().sorted
  177. rqs := q.lazyInit().sorted
  178. for pi, qi := 0, 0; pi < len(rps) && qi < len(rqs); {
  179. rp := fieldRange(rps[pi])
  180. rq := fieldRange(rqs[qi])
  181. if !(rp.End() < rq.Start() || rq.End() < rp.Start()) {
  182. return errors.New("overlapping ranges: %v with %v", rp, rq)
  183. }
  184. if rp.Start() < rq.Start() {
  185. pi++
  186. } else {
  187. qi++
  188. }
  189. }
  190. return nil
  191. }
  192. type fieldRange [2]protoreflect.FieldNumber
  193. func (r fieldRange) Start() protoreflect.FieldNumber { return r[0] } // inclusive
  194. func (r fieldRange) End() protoreflect.FieldNumber { return r[1] - 1 } // inclusive
  195. func (r fieldRange) String() string {
  196. if r.Start() == r.End() {
  197. return fmt.Sprintf("%d", r.Start())
  198. }
  199. return fmt.Sprintf("%d to %d", r.Start(), r.End())
  200. }
  201. type FieldNumbers struct {
  202. List []pref.FieldNumber
  203. once sync.Once
  204. has map[pref.FieldNumber]struct{} // protected by once
  205. }
  206. func (p *FieldNumbers) Len() int { return len(p.List) }
  207. func (p *FieldNumbers) Get(i int) pref.FieldNumber { return p.List[i] }
  208. func (p *FieldNumbers) Has(n pref.FieldNumber) bool {
  209. p.once.Do(func() {
  210. if len(p.List) > 0 {
  211. p.has = make(map[pref.FieldNumber]struct{}, len(p.List))
  212. for _, n := range p.List {
  213. p.has[n] = struct{}{}
  214. }
  215. }
  216. })
  217. _, ok := p.has[n]
  218. return ok
  219. }
  220. func (p *FieldNumbers) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) }
  221. func (p *FieldNumbers) ProtoInternal(pragma.DoNotImplement) {}
  222. type OneofFields struct {
  223. List []pref.FieldDescriptor
  224. once sync.Once
  225. byName map[pref.Name]pref.FieldDescriptor // protected by once
  226. byJSON map[string]pref.FieldDescriptor // protected by once
  227. byText map[string]pref.FieldDescriptor // protected by once
  228. byNum map[pref.FieldNumber]pref.FieldDescriptor // protected by once
  229. }
  230. func (p *OneofFields) Len() int { return len(p.List) }
  231. func (p *OneofFields) Get(i int) pref.FieldDescriptor { return p.List[i] }
  232. func (p *OneofFields) ByName(s pref.Name) pref.FieldDescriptor { return p.lazyInit().byName[s] }
  233. func (p *OneofFields) ByJSONName(s string) pref.FieldDescriptor { return p.lazyInit().byJSON[s] }
  234. func (p *OneofFields) ByTextName(s string) pref.FieldDescriptor { return p.lazyInit().byText[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.byText = make(map[string]pref.FieldDescriptor, len(p.List))
  244. p.byNum = make(map[pref.FieldNumber]pref.FieldDescriptor, len(p.List))
  245. for _, f := range p.List {
  246. // Field names and numbers are guaranteed to be unique.
  247. p.byName[f.Name()] = f
  248. p.byJSON[f.JSONName()] = f
  249. p.byText[f.TextName()] = f
  250. p.byNum[f.Number()] = f
  251. }
  252. }
  253. })
  254. return p
  255. }
  256. type SourceLocations struct {
  257. // List is a list of SourceLocations.
  258. // The SourceLocation.Next field does not need to be populated
  259. // as it will be lazily populated upon first need.
  260. List []pref.SourceLocation
  261. // File is the parent file descriptor that these locations are relative to.
  262. // If non-nil, ByDescriptor verifies that the provided descriptor
  263. // is a child of this file descriptor.
  264. File pref.FileDescriptor
  265. once sync.Once
  266. byPath map[pathKey]int
  267. }
  268. func (p *SourceLocations) Len() int { return len(p.List) }
  269. func (p *SourceLocations) Get(i int) pref.SourceLocation { return p.lazyInit().List[i] }
  270. func (p *SourceLocations) byKey(k pathKey) pref.SourceLocation {
  271. if i, ok := p.lazyInit().byPath[k]; ok {
  272. return p.List[i]
  273. }
  274. return pref.SourceLocation{}
  275. }
  276. func (p *SourceLocations) ByPath(path pref.SourcePath) pref.SourceLocation {
  277. return p.byKey(newPathKey(path))
  278. }
  279. func (p *SourceLocations) ByDescriptor(desc pref.Descriptor) pref.SourceLocation {
  280. if p.File != nil && desc != nil && p.File != desc.ParentFile() {
  281. return pref.SourceLocation{} // mismatching parent files
  282. }
  283. var pathArr [16]int32
  284. path := pathArr[:0]
  285. for {
  286. switch desc.(type) {
  287. case pref.FileDescriptor:
  288. // Reverse the path since it was constructed in reverse.
  289. for i, j := 0, len(path)-1; i < j; i, j = i+1, j-1 {
  290. path[i], path[j] = path[j], path[i]
  291. }
  292. return p.byKey(newPathKey(path))
  293. case pref.MessageDescriptor:
  294. path = append(path, int32(desc.Index()))
  295. desc = desc.Parent()
  296. switch desc.(type) {
  297. case pref.FileDescriptor:
  298. path = append(path, int32(genid.FileDescriptorProto_MessageType_field_number))
  299. case pref.MessageDescriptor:
  300. path = append(path, int32(genid.DescriptorProto_NestedType_field_number))
  301. default:
  302. return pref.SourceLocation{}
  303. }
  304. case pref.FieldDescriptor:
  305. isExtension := desc.(pref.FieldDescriptor).IsExtension()
  306. path = append(path, int32(desc.Index()))
  307. desc = desc.Parent()
  308. if isExtension {
  309. switch desc.(type) {
  310. case pref.FileDescriptor:
  311. path = append(path, int32(genid.FileDescriptorProto_Extension_field_number))
  312. case pref.MessageDescriptor:
  313. path = append(path, int32(genid.DescriptorProto_Extension_field_number))
  314. default:
  315. return pref.SourceLocation{}
  316. }
  317. } else {
  318. switch desc.(type) {
  319. case pref.MessageDescriptor:
  320. path = append(path, int32(genid.DescriptorProto_Field_field_number))
  321. default:
  322. return pref.SourceLocation{}
  323. }
  324. }
  325. case pref.OneofDescriptor:
  326. path = append(path, int32(desc.Index()))
  327. desc = desc.Parent()
  328. switch desc.(type) {
  329. case pref.MessageDescriptor:
  330. path = append(path, int32(genid.DescriptorProto_OneofDecl_field_number))
  331. default:
  332. return pref.SourceLocation{}
  333. }
  334. case pref.EnumDescriptor:
  335. path = append(path, int32(desc.Index()))
  336. desc = desc.Parent()
  337. switch desc.(type) {
  338. case pref.FileDescriptor:
  339. path = append(path, int32(genid.FileDescriptorProto_EnumType_field_number))
  340. case pref.MessageDescriptor:
  341. path = append(path, int32(genid.DescriptorProto_EnumType_field_number))
  342. default:
  343. return pref.SourceLocation{}
  344. }
  345. case pref.EnumValueDescriptor:
  346. path = append(path, int32(desc.Index()))
  347. desc = desc.Parent()
  348. switch desc.(type) {
  349. case pref.EnumDescriptor:
  350. path = append(path, int32(genid.EnumDescriptorProto_Value_field_number))
  351. default:
  352. return pref.SourceLocation{}
  353. }
  354. case pref.ServiceDescriptor:
  355. path = append(path, int32(desc.Index()))
  356. desc = desc.Parent()
  357. switch desc.(type) {
  358. case pref.FileDescriptor:
  359. path = append(path, int32(genid.FileDescriptorProto_Service_field_number))
  360. default:
  361. return pref.SourceLocation{}
  362. }
  363. case pref.MethodDescriptor:
  364. path = append(path, int32(desc.Index()))
  365. desc = desc.Parent()
  366. switch desc.(type) {
  367. case pref.ServiceDescriptor:
  368. path = append(path, int32(genid.ServiceDescriptorProto_Method_field_number))
  369. default:
  370. return pref.SourceLocation{}
  371. }
  372. default:
  373. return pref.SourceLocation{}
  374. }
  375. }
  376. }
  377. func (p *SourceLocations) lazyInit() *SourceLocations {
  378. p.once.Do(func() {
  379. if len(p.List) > 0 {
  380. // Collect all the indexes for a given path.
  381. pathIdxs := make(map[pathKey][]int, len(p.List))
  382. for i, l := range p.List {
  383. k := newPathKey(l.Path)
  384. pathIdxs[k] = append(pathIdxs[k], i)
  385. }
  386. // Update the next index for all locations.
  387. p.byPath = make(map[pathKey]int, len(p.List))
  388. for k, idxs := range pathIdxs {
  389. for i := 0; i < len(idxs)-1; i++ {
  390. p.List[idxs[i]].Next = idxs[i+1]
  391. }
  392. p.List[idxs[len(idxs)-1]].Next = 0
  393. p.byPath[k] = idxs[0] // record the first location for this path
  394. }
  395. }
  396. })
  397. return p
  398. }
  399. func (p *SourceLocations) ProtoInternal(pragma.DoNotImplement) {}
  400. // pathKey is a comparable representation of protoreflect.SourcePath.
  401. type pathKey struct {
  402. arr [16]uint8 // first n-1 path segments; last element is the length
  403. str string // used if the path does not fit in arr
  404. }
  405. func newPathKey(p pref.SourcePath) (k pathKey) {
  406. if len(p) < len(k.arr) {
  407. for i, ps := range p {
  408. if ps < 0 || math.MaxUint8 <= ps {
  409. return pathKey{str: p.String()}
  410. }
  411. k.arr[i] = uint8(ps)
  412. }
  413. k.arr[len(k.arr)-1] = uint8(len(p))
  414. return k
  415. }
  416. return pathKey{str: p.String()}
  417. }