desc_init.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  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. "sync"
  7. "google.golang.org/protobuf/internal/encoding/wire"
  8. "google.golang.org/protobuf/internal/fieldnum"
  9. "google.golang.org/protobuf/internal/strs"
  10. pref "google.golang.org/protobuf/reflect/protoreflect"
  11. )
  12. // fileRaw is a data struct used when initializing a file descriptor from
  13. // a raw FileDescriptorProto.
  14. type fileRaw struct {
  15. builder Builder
  16. allEnums []Enum
  17. allMessages []Message
  18. allExtensions []Extension
  19. allServices []Service
  20. }
  21. func newRawFile(db Builder) *File {
  22. fd := &File{fileRaw: fileRaw{builder: db}}
  23. fd.initDecls(db.NumEnums, db.NumMessages, db.NumExtensions, db.NumServices)
  24. fd.unmarshalSeed(db.RawDescriptor)
  25. // Extended message targets are eagerly resolved since registration
  26. // needs this information at program init time.
  27. for i := range fd.allExtensions {
  28. xd := &fd.allExtensions[i]
  29. xd.L1.Extendee = fd.resolveMessageDependency(xd.L1.Extendee, listExtTargets, int32(i))
  30. }
  31. fd.checkDecls()
  32. return fd
  33. }
  34. // initDecls pre-allocates slices for the exact number of enums, messages
  35. // (including map entries), extensions, and services declared in the proto file.
  36. // This is done to avoid regrowing the slice, which would change the address
  37. // for any previously seen declaration.
  38. //
  39. // The alloc methods "allocates" slices by pulling from the capacity.
  40. func (fd *File) initDecls(numEnums, numMessages, numExtensions, numServices int32) {
  41. fd.allEnums = make([]Enum, 0, numEnums)
  42. fd.allMessages = make([]Message, 0, numMessages)
  43. fd.allExtensions = make([]Extension, 0, numExtensions)
  44. fd.allServices = make([]Service, 0, numServices)
  45. }
  46. func (fd *File) allocEnums(n int) []Enum {
  47. total := len(fd.allEnums)
  48. es := fd.allEnums[total : total+n]
  49. fd.allEnums = fd.allEnums[:total+n]
  50. return es
  51. }
  52. func (fd *File) allocMessages(n int) []Message {
  53. total := len(fd.allMessages)
  54. ms := fd.allMessages[total : total+n]
  55. fd.allMessages = fd.allMessages[:total+n]
  56. return ms
  57. }
  58. func (fd *File) allocExtensions(n int) []Extension {
  59. total := len(fd.allExtensions)
  60. xs := fd.allExtensions[total : total+n]
  61. fd.allExtensions = fd.allExtensions[:total+n]
  62. return xs
  63. }
  64. func (fd *File) allocServices(n int) []Service {
  65. total := len(fd.allServices)
  66. xs := fd.allServices[total : total+n]
  67. fd.allServices = fd.allServices[:total+n]
  68. return xs
  69. }
  70. // checkDecls performs a sanity check that the expected number of expected
  71. // declarations matches the number that were found in the descriptor proto.
  72. func (fd *File) checkDecls() {
  73. switch {
  74. case len(fd.allEnums) != cap(fd.allEnums):
  75. case len(fd.allMessages) != cap(fd.allMessages):
  76. case len(fd.allExtensions) != cap(fd.allExtensions):
  77. case len(fd.allServices) != cap(fd.allServices):
  78. default:
  79. return
  80. }
  81. panic("mismatching cardinality")
  82. }
  83. func (fd *File) unmarshalSeed(b []byte) {
  84. sb := getBuilder()
  85. defer putBuilder(sb)
  86. var prevField pref.FieldNumber
  87. var numEnums, numMessages, numExtensions, numServices int
  88. var posEnums, posMessages, posExtensions, posServices int
  89. b0 := b
  90. for len(b) > 0 {
  91. num, typ, n := wire.ConsumeTag(b)
  92. b = b[n:]
  93. switch typ {
  94. case wire.BytesType:
  95. v, m := wire.ConsumeBytes(b)
  96. b = b[m:]
  97. switch num {
  98. case fieldnum.FileDescriptorProto_Syntax:
  99. switch string(v) {
  100. case "proto2":
  101. fd.L1.Syntax = pref.Proto2
  102. case "proto3":
  103. fd.L1.Syntax = pref.Proto3
  104. default:
  105. panic("invalid syntax")
  106. }
  107. case fieldnum.FileDescriptorProto_Name:
  108. fd.L1.Path = sb.MakeString(v)
  109. case fieldnum.FileDescriptorProto_Package:
  110. fd.L1.Package = pref.FullName(sb.MakeString(v))
  111. case fieldnum.FileDescriptorProto_EnumType:
  112. if prevField != fieldnum.FileDescriptorProto_EnumType {
  113. if numEnums > 0 {
  114. panic("non-contiguous repeated field")
  115. }
  116. posEnums = len(b0) - len(b) - n - m
  117. }
  118. numEnums++
  119. case fieldnum.FileDescriptorProto_MessageType:
  120. if prevField != fieldnum.FileDescriptorProto_MessageType {
  121. if numMessages > 0 {
  122. panic("non-contiguous repeated field")
  123. }
  124. posMessages = len(b0) - len(b) - n - m
  125. }
  126. numMessages++
  127. case fieldnum.FileDescriptorProto_Extension:
  128. if prevField != fieldnum.FileDescriptorProto_Extension {
  129. if numExtensions > 0 {
  130. panic("non-contiguous repeated field")
  131. }
  132. posExtensions = len(b0) - len(b) - n - m
  133. }
  134. numExtensions++
  135. case fieldnum.FileDescriptorProto_Service:
  136. if prevField != fieldnum.FileDescriptorProto_Service {
  137. if numServices > 0 {
  138. panic("non-contiguous repeated field")
  139. }
  140. posServices = len(b0) - len(b) - n - m
  141. }
  142. numServices++
  143. }
  144. prevField = num
  145. default:
  146. m := wire.ConsumeFieldValue(num, typ, b)
  147. b = b[m:]
  148. prevField = -1 // ignore known field numbers of unknown wire type
  149. }
  150. }
  151. // If syntax is missing, it is assumed to be proto2.
  152. if fd.L1.Syntax == 0 {
  153. fd.L1.Syntax = pref.Proto2
  154. }
  155. // Must allocate all declarations before parsing each descriptor type
  156. // to ensure we handled all descriptors in "flattened ordering".
  157. if numEnums > 0 {
  158. fd.L1.Enums.List = fd.allocEnums(numEnums)
  159. }
  160. if numMessages > 0 {
  161. fd.L1.Messages.List = fd.allocMessages(numMessages)
  162. }
  163. if numExtensions > 0 {
  164. fd.L1.Extensions.List = fd.allocExtensions(numExtensions)
  165. }
  166. if numServices > 0 {
  167. fd.L1.Services.List = fd.allocServices(numServices)
  168. }
  169. if numEnums > 0 {
  170. b := b0[posEnums:]
  171. for i := range fd.L1.Enums.List {
  172. _, n := wire.ConsumeVarint(b)
  173. v, m := wire.ConsumeBytes(b[n:])
  174. fd.L1.Enums.List[i].unmarshalSeed(v, sb, fd, fd, i)
  175. b = b[n+m:]
  176. }
  177. }
  178. if numMessages > 0 {
  179. b := b0[posMessages:]
  180. for i := range fd.L1.Messages.List {
  181. _, n := wire.ConsumeVarint(b)
  182. v, m := wire.ConsumeBytes(b[n:])
  183. fd.L1.Messages.List[i].unmarshalSeed(v, sb, fd, fd, i)
  184. b = b[n+m:]
  185. }
  186. }
  187. if numExtensions > 0 {
  188. b := b0[posExtensions:]
  189. for i := range fd.L1.Extensions.List {
  190. _, n := wire.ConsumeVarint(b)
  191. v, m := wire.ConsumeBytes(b[n:])
  192. fd.L1.Extensions.List[i].unmarshalSeed(v, sb, fd, fd, i)
  193. b = b[n+m:]
  194. }
  195. }
  196. if numServices > 0 {
  197. b := b0[posServices:]
  198. for i := range fd.L1.Services.List {
  199. _, n := wire.ConsumeVarint(b)
  200. v, m := wire.ConsumeBytes(b[n:])
  201. fd.L1.Services.List[i].unmarshalSeed(v, sb, fd, fd, i)
  202. b = b[n+m:]
  203. }
  204. }
  205. }
  206. func (ed *Enum) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
  207. ed.L0.ParentFile = pf
  208. ed.L0.Parent = pd
  209. ed.L0.Index = i
  210. var numValues int
  211. for b := b; len(b) > 0; {
  212. num, typ, n := wire.ConsumeTag(b)
  213. b = b[n:]
  214. switch typ {
  215. case wire.BytesType:
  216. v, m := wire.ConsumeBytes(b)
  217. b = b[m:]
  218. switch num {
  219. case fieldnum.EnumDescriptorProto_Name:
  220. ed.L0.FullName = appendFullName(sb, pd.FullName(), v)
  221. case fieldnum.EnumDescriptorProto_Value:
  222. numValues++
  223. }
  224. default:
  225. m := wire.ConsumeFieldValue(num, typ, b)
  226. b = b[m:]
  227. }
  228. }
  229. // Only construct enum value descriptors for top-level enums since
  230. // they are needed for registration.
  231. if pd != pf {
  232. return
  233. }
  234. ed.L1.eagerValues = true
  235. ed.L2 = new(EnumL2)
  236. ed.L2.Values.List = make([]EnumValue, numValues)
  237. for i := 0; len(b) > 0; {
  238. num, typ, n := wire.ConsumeTag(b)
  239. b = b[n:]
  240. switch typ {
  241. case wire.BytesType:
  242. v, m := wire.ConsumeBytes(b)
  243. b = b[m:]
  244. switch num {
  245. case fieldnum.EnumDescriptorProto_Value:
  246. ed.L2.Values.List[i].unmarshalFull(v, sb, pf, ed, i)
  247. i++
  248. }
  249. default:
  250. m := wire.ConsumeFieldValue(num, typ, b)
  251. b = b[m:]
  252. }
  253. }
  254. }
  255. func (md *Message) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
  256. md.L0.ParentFile = pf
  257. md.L0.Parent = pd
  258. md.L0.Index = i
  259. var prevField pref.FieldNumber
  260. var numEnums, numMessages, numExtensions int
  261. var posEnums, posMessages, posExtensions int
  262. b0 := b
  263. for len(b) > 0 {
  264. num, typ, n := wire.ConsumeTag(b)
  265. b = b[n:]
  266. switch typ {
  267. case wire.BytesType:
  268. v, m := wire.ConsumeBytes(b)
  269. b = b[m:]
  270. switch num {
  271. case fieldnum.DescriptorProto_Name:
  272. md.L0.FullName = appendFullName(sb, pd.FullName(), v)
  273. case fieldnum.DescriptorProto_EnumType:
  274. if prevField != fieldnum.DescriptorProto_EnumType {
  275. if numEnums > 0 {
  276. panic("non-contiguous repeated field")
  277. }
  278. posEnums = len(b0) - len(b) - n - m
  279. }
  280. numEnums++
  281. case fieldnum.DescriptorProto_NestedType:
  282. if prevField != fieldnum.DescriptorProto_NestedType {
  283. if numMessages > 0 {
  284. panic("non-contiguous repeated field")
  285. }
  286. posMessages = len(b0) - len(b) - n - m
  287. }
  288. numMessages++
  289. case fieldnum.DescriptorProto_Extension:
  290. if prevField != fieldnum.DescriptorProto_Extension {
  291. if numExtensions > 0 {
  292. panic("non-contiguous repeated field")
  293. }
  294. posExtensions = len(b0) - len(b) - n - m
  295. }
  296. numExtensions++
  297. }
  298. prevField = num
  299. default:
  300. m := wire.ConsumeFieldValue(num, typ, b)
  301. b = b[m:]
  302. prevField = -1 // ignore known field numbers of unknown wire type
  303. }
  304. }
  305. // Must allocate all declarations before parsing each descriptor type
  306. // to ensure we handled all descriptors in "flattened ordering".
  307. if numEnums > 0 {
  308. md.L1.Enums.List = pf.allocEnums(numEnums)
  309. }
  310. if numMessages > 0 {
  311. md.L1.Messages.List = pf.allocMessages(numMessages)
  312. }
  313. if numExtensions > 0 {
  314. md.L1.Extensions.List = pf.allocExtensions(numExtensions)
  315. }
  316. if numEnums > 0 {
  317. b := b0[posEnums:]
  318. for i := range md.L1.Enums.List {
  319. _, n := wire.ConsumeVarint(b)
  320. v, m := wire.ConsumeBytes(b[n:])
  321. md.L1.Enums.List[i].unmarshalSeed(v, sb, pf, md, i)
  322. b = b[n+m:]
  323. }
  324. }
  325. if numMessages > 0 {
  326. b := b0[posMessages:]
  327. for i := range md.L1.Messages.List {
  328. _, n := wire.ConsumeVarint(b)
  329. v, m := wire.ConsumeBytes(b[n:])
  330. md.L1.Messages.List[i].unmarshalSeed(v, sb, pf, md, i)
  331. b = b[n+m:]
  332. }
  333. }
  334. if numExtensions > 0 {
  335. b := b0[posExtensions:]
  336. for i := range md.L1.Extensions.List {
  337. _, n := wire.ConsumeVarint(b)
  338. v, m := wire.ConsumeBytes(b[n:])
  339. md.L1.Extensions.List[i].unmarshalSeed(v, sb, pf, md, i)
  340. b = b[n+m:]
  341. }
  342. }
  343. }
  344. func (xd *Extension) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
  345. xd.L0.ParentFile = pf
  346. xd.L0.Parent = pd
  347. xd.L0.Index = i
  348. for len(b) > 0 {
  349. num, typ, n := wire.ConsumeTag(b)
  350. b = b[n:]
  351. switch typ {
  352. case wire.VarintType:
  353. v, m := wire.ConsumeVarint(b)
  354. b = b[m:]
  355. switch num {
  356. case fieldnum.FieldDescriptorProto_Number:
  357. xd.L1.Number = pref.FieldNumber(v)
  358. case fieldnum.FieldDescriptorProto_Label:
  359. xd.L1.Cardinality = pref.Cardinality(v)
  360. case fieldnum.FieldDescriptorProto_Type:
  361. xd.L1.Kind = pref.Kind(v)
  362. }
  363. case wire.BytesType:
  364. v, m := wire.ConsumeBytes(b)
  365. b = b[m:]
  366. switch num {
  367. case fieldnum.FieldDescriptorProto_Name:
  368. xd.L0.FullName = appendFullName(sb, pd.FullName(), v)
  369. case fieldnum.FieldDescriptorProto_Extendee:
  370. xd.L1.Extendee = PlaceholderMessage(makeFullName(sb, v))
  371. }
  372. default:
  373. m := wire.ConsumeFieldValue(num, typ, b)
  374. b = b[m:]
  375. }
  376. }
  377. }
  378. func (sd *Service) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
  379. sd.L0.ParentFile = pf
  380. sd.L0.Parent = pd
  381. sd.L0.Index = i
  382. for len(b) > 0 {
  383. num, typ, n := wire.ConsumeTag(b)
  384. b = b[n:]
  385. switch typ {
  386. case wire.BytesType:
  387. v, m := wire.ConsumeBytes(b)
  388. b = b[m:]
  389. switch num {
  390. case fieldnum.ServiceDescriptorProto_Name:
  391. sd.L0.FullName = appendFullName(sb, pd.FullName(), v)
  392. }
  393. default:
  394. m := wire.ConsumeFieldValue(num, typ, b)
  395. b = b[m:]
  396. }
  397. }
  398. }
  399. var nameBuilderPool = sync.Pool{
  400. New: func() interface{} { return new(strs.Builder) },
  401. }
  402. func getBuilder() *strs.Builder {
  403. return nameBuilderPool.Get().(*strs.Builder)
  404. }
  405. func putBuilder(b *strs.Builder) {
  406. nameBuilderPool.Put(b)
  407. }
  408. // makeFullName converts b to a protoreflect.FullName,
  409. // where b must start with a leading dot.
  410. func makeFullName(sb *strs.Builder, b []byte) pref.FullName {
  411. if len(b) == 0 || b[0] != '.' {
  412. panic("name reference must be fully qualified")
  413. }
  414. return pref.FullName(sb.MakeString(b[1:]))
  415. }
  416. func appendFullName(sb *strs.Builder, prefix pref.FullName, suffix []byte) pref.FullName {
  417. return sb.AppendFullName(prefix, pref.Name(strs.UnsafeString(suffix)))
  418. }