Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

458 строки
15 KiB

  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. )
  17. type FileImports []protoreflect.FileImport
  18. func (p *FileImports) Len() int { return len(*p) }
  19. func (p *FileImports) Get(i int) protoreflect.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 []protoreflect.Name
  24. once sync.Once
  25. has map[protoreflect.Name]int // protected by once
  26. }
  27. func (p *Names) Len() int { return len(p.List) }
  28. func (p *Names) Get(i int) protoreflect.Name { return p.List[i] }
  29. func (p *Names) Has(s protoreflect.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[protoreflect.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]protoreflect.EnumNumber // start inclusive; end inclusive
  60. once sync.Once
  61. sorted [][2]protoreflect.EnumNumber // protected by once
  62. }
  63. func (p *EnumRanges) Len() int { return len(p.List) }
  64. func (p *EnumRanges) Get(i int) [2]protoreflect.EnumNumber { return p.List[i] }
  65. func (p *EnumRanges) Has(n protoreflect.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]protoreflect.FieldNumber // start inclusive; end exclusive
  117. once sync.Once
  118. sorted [][2]protoreflect.FieldNumber // protected by once
  119. }
  120. func (p *FieldRanges) Len() int { return len(p.List) }
  121. func (p *FieldRanges) Get(i int) [2]protoreflect.FieldNumber { return p.List[i] }
  122. func (p *FieldRanges) Has(n protoreflect.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. return protowire.MinValidNumber <= n && (n <= protowire.MaxValidNumber || isMessageSet)
  172. }
  173. // CheckOverlap reports an error if p and q overlap.
  174. func (p *FieldRanges) CheckOverlap(q *FieldRanges) error {
  175. rps := p.lazyInit().sorted
  176. rqs := q.lazyInit().sorted
  177. for pi, qi := 0, 0; pi < len(rps) && qi < len(rqs); {
  178. rp := fieldRange(rps[pi])
  179. rq := fieldRange(rqs[qi])
  180. if !(rp.End() < rq.Start() || rq.End() < rp.Start()) {
  181. return errors.New("overlapping ranges: %v with %v", rp, rq)
  182. }
  183. if rp.Start() < rq.Start() {
  184. pi++
  185. } else {
  186. qi++
  187. }
  188. }
  189. return nil
  190. }
  191. type fieldRange [2]protoreflect.FieldNumber
  192. func (r fieldRange) Start() protoreflect.FieldNumber { return r[0] } // inclusive
  193. func (r fieldRange) End() protoreflect.FieldNumber { return r[1] - 1 } // inclusive
  194. func (r fieldRange) String() string {
  195. if r.Start() == r.End() {
  196. return fmt.Sprintf("%d", r.Start())
  197. }
  198. return fmt.Sprintf("%d to %d", r.Start(), r.End())
  199. }
  200. type FieldNumbers struct {
  201. List []protoreflect.FieldNumber
  202. once sync.Once
  203. has map[protoreflect.FieldNumber]struct{} // protected by once
  204. }
  205. func (p *FieldNumbers) Len() int { return len(p.List) }
  206. func (p *FieldNumbers) Get(i int) protoreflect.FieldNumber { return p.List[i] }
  207. func (p *FieldNumbers) Has(n protoreflect.FieldNumber) bool {
  208. p.once.Do(func() {
  209. if len(p.List) > 0 {
  210. p.has = make(map[protoreflect.FieldNumber]struct{}, len(p.List))
  211. for _, n := range p.List {
  212. p.has[n] = struct{}{}
  213. }
  214. }
  215. })
  216. _, ok := p.has[n]
  217. return ok
  218. }
  219. func (p *FieldNumbers) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) }
  220. func (p *FieldNumbers) ProtoInternal(pragma.DoNotImplement) {}
  221. type OneofFields struct {
  222. List []protoreflect.FieldDescriptor
  223. once sync.Once
  224. byName map[protoreflect.Name]protoreflect.FieldDescriptor // protected by once
  225. byJSON map[string]protoreflect.FieldDescriptor // protected by once
  226. byText map[string]protoreflect.FieldDescriptor // protected by once
  227. byNum map[protoreflect.FieldNumber]protoreflect.FieldDescriptor // protected by once
  228. }
  229. func (p *OneofFields) Len() int { return len(p.List) }
  230. func (p *OneofFields) Get(i int) protoreflect.FieldDescriptor { return p.List[i] }
  231. func (p *OneofFields) ByName(s protoreflect.Name) protoreflect.FieldDescriptor {
  232. return p.lazyInit().byName[s]
  233. }
  234. func (p *OneofFields) ByJSONName(s string) protoreflect.FieldDescriptor {
  235. return p.lazyInit().byJSON[s]
  236. }
  237. func (p *OneofFields) ByTextName(s string) protoreflect.FieldDescriptor {
  238. return p.lazyInit().byText[s]
  239. }
  240. func (p *OneofFields) ByNumber(n protoreflect.FieldNumber) protoreflect.FieldDescriptor {
  241. return p.lazyInit().byNum[n]
  242. }
  243. func (p *OneofFields) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) }
  244. func (p *OneofFields) ProtoInternal(pragma.DoNotImplement) {}
  245. func (p *OneofFields) lazyInit() *OneofFields {
  246. p.once.Do(func() {
  247. if len(p.List) > 0 {
  248. p.byName = make(map[protoreflect.Name]protoreflect.FieldDescriptor, len(p.List))
  249. p.byJSON = make(map[string]protoreflect.FieldDescriptor, len(p.List))
  250. p.byText = make(map[string]protoreflect.FieldDescriptor, len(p.List))
  251. p.byNum = make(map[protoreflect.FieldNumber]protoreflect.FieldDescriptor, len(p.List))
  252. for _, f := range p.List {
  253. // Field names and numbers are guaranteed to be unique.
  254. p.byName[f.Name()] = f
  255. p.byJSON[f.JSONName()] = f
  256. p.byText[f.TextName()] = f
  257. p.byNum[f.Number()] = f
  258. }
  259. }
  260. })
  261. return p
  262. }
  263. type SourceLocations struct {
  264. // List is a list of SourceLocations.
  265. // The SourceLocation.Next field does not need to be populated
  266. // as it will be lazily populated upon first need.
  267. List []protoreflect.SourceLocation
  268. // File is the parent file descriptor that these locations are relative to.
  269. // If non-nil, ByDescriptor verifies that the provided descriptor
  270. // is a child of this file descriptor.
  271. File protoreflect.FileDescriptor
  272. once sync.Once
  273. byPath map[pathKey]int
  274. }
  275. func (p *SourceLocations) Len() int { return len(p.List) }
  276. func (p *SourceLocations) Get(i int) protoreflect.SourceLocation { return p.lazyInit().List[i] }
  277. func (p *SourceLocations) byKey(k pathKey) protoreflect.SourceLocation {
  278. if i, ok := p.lazyInit().byPath[k]; ok {
  279. return p.List[i]
  280. }
  281. return protoreflect.SourceLocation{}
  282. }
  283. func (p *SourceLocations) ByPath(path protoreflect.SourcePath) protoreflect.SourceLocation {
  284. return p.byKey(newPathKey(path))
  285. }
  286. func (p *SourceLocations) ByDescriptor(desc protoreflect.Descriptor) protoreflect.SourceLocation {
  287. if p.File != nil && desc != nil && p.File != desc.ParentFile() {
  288. return protoreflect.SourceLocation{} // mismatching parent files
  289. }
  290. var pathArr [16]int32
  291. path := pathArr[:0]
  292. for {
  293. switch desc.(type) {
  294. case protoreflect.FileDescriptor:
  295. // Reverse the path since it was constructed in reverse.
  296. for i, j := 0, len(path)-1; i < j; i, j = i+1, j-1 {
  297. path[i], path[j] = path[j], path[i]
  298. }
  299. return p.byKey(newPathKey(path))
  300. case protoreflect.MessageDescriptor:
  301. path = append(path, int32(desc.Index()))
  302. desc = desc.Parent()
  303. switch desc.(type) {
  304. case protoreflect.FileDescriptor:
  305. path = append(path, int32(genid.FileDescriptorProto_MessageType_field_number))
  306. case protoreflect.MessageDescriptor:
  307. path = append(path, int32(genid.DescriptorProto_NestedType_field_number))
  308. default:
  309. return protoreflect.SourceLocation{}
  310. }
  311. case protoreflect.FieldDescriptor:
  312. isExtension := desc.(protoreflect.FieldDescriptor).IsExtension()
  313. path = append(path, int32(desc.Index()))
  314. desc = desc.Parent()
  315. if isExtension {
  316. switch desc.(type) {
  317. case protoreflect.FileDescriptor:
  318. path = append(path, int32(genid.FileDescriptorProto_Extension_field_number))
  319. case protoreflect.MessageDescriptor:
  320. path = append(path, int32(genid.DescriptorProto_Extension_field_number))
  321. default:
  322. return protoreflect.SourceLocation{}
  323. }
  324. } else {
  325. switch desc.(type) {
  326. case protoreflect.MessageDescriptor:
  327. path = append(path, int32(genid.DescriptorProto_Field_field_number))
  328. default:
  329. return protoreflect.SourceLocation{}
  330. }
  331. }
  332. case protoreflect.OneofDescriptor:
  333. path = append(path, int32(desc.Index()))
  334. desc = desc.Parent()
  335. switch desc.(type) {
  336. case protoreflect.MessageDescriptor:
  337. path = append(path, int32(genid.DescriptorProto_OneofDecl_field_number))
  338. default:
  339. return protoreflect.SourceLocation{}
  340. }
  341. case protoreflect.EnumDescriptor:
  342. path = append(path, int32(desc.Index()))
  343. desc = desc.Parent()
  344. switch desc.(type) {
  345. case protoreflect.FileDescriptor:
  346. path = append(path, int32(genid.FileDescriptorProto_EnumType_field_number))
  347. case protoreflect.MessageDescriptor:
  348. path = append(path, int32(genid.DescriptorProto_EnumType_field_number))
  349. default:
  350. return protoreflect.SourceLocation{}
  351. }
  352. case protoreflect.EnumValueDescriptor:
  353. path = append(path, int32(desc.Index()))
  354. desc = desc.Parent()
  355. switch desc.(type) {
  356. case protoreflect.EnumDescriptor:
  357. path = append(path, int32(genid.EnumDescriptorProto_Value_field_number))
  358. default:
  359. return protoreflect.SourceLocation{}
  360. }
  361. case protoreflect.ServiceDescriptor:
  362. path = append(path, int32(desc.Index()))
  363. desc = desc.Parent()
  364. switch desc.(type) {
  365. case protoreflect.FileDescriptor:
  366. path = append(path, int32(genid.FileDescriptorProto_Service_field_number))
  367. default:
  368. return protoreflect.SourceLocation{}
  369. }
  370. case protoreflect.MethodDescriptor:
  371. path = append(path, int32(desc.Index()))
  372. desc = desc.Parent()
  373. switch desc.(type) {
  374. case protoreflect.ServiceDescriptor:
  375. path = append(path, int32(genid.ServiceDescriptorProto_Method_field_number))
  376. default:
  377. return protoreflect.SourceLocation{}
  378. }
  379. default:
  380. return protoreflect.SourceLocation{}
  381. }
  382. }
  383. }
  384. func (p *SourceLocations) lazyInit() *SourceLocations {
  385. p.once.Do(func() {
  386. if len(p.List) > 0 {
  387. // Collect all the indexes for a given path.
  388. pathIdxs := make(map[pathKey][]int, len(p.List))
  389. for i, l := range p.List {
  390. k := newPathKey(l.Path)
  391. pathIdxs[k] = append(pathIdxs[k], i)
  392. }
  393. // Update the next index for all locations.
  394. p.byPath = make(map[pathKey]int, len(p.List))
  395. for k, idxs := range pathIdxs {
  396. for i := 0; i < len(idxs)-1; i++ {
  397. p.List[idxs[i]].Next = idxs[i+1]
  398. }
  399. p.List[idxs[len(idxs)-1]].Next = 0
  400. p.byPath[k] = idxs[0] // record the first location for this path
  401. }
  402. }
  403. })
  404. return p
  405. }
  406. func (p *SourceLocations) ProtoInternal(pragma.DoNotImplement) {}
  407. // pathKey is a comparable representation of protoreflect.SourcePath.
  408. type pathKey struct {
  409. arr [16]uint8 // first n-1 path segments; last element is the length
  410. str string // used if the path does not fit in arr
  411. }
  412. func newPathKey(p protoreflect.SourcePath) (k pathKey) {
  413. if len(p) < len(k.arr) {
  414. for i, ps := range p {
  415. if ps < 0 || math.MaxUint8 <= ps {
  416. return pathKey{str: p.String()}
  417. }
  418. k.arr[i] = uint8(ps)
  419. }
  420. k.arr[len(k.arr)-1] = uint8(len(p))
  421. return k
  422. }
  423. return pathKey{str: p.String()}
  424. }