desc_init.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  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/encoding/protowire"
  8. "google.golang.org/protobuf/internal/genid"
  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 := protowire.ConsumeTag(b)
  92. b = b[n:]
  93. switch typ {
  94. case protowire.BytesType:
  95. v, m := protowire.ConsumeBytes(b)
  96. b = b[m:]
  97. switch num {
  98. case genid.FileDescriptorProto_Syntax_field_number:
  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 genid.FileDescriptorProto_Name_field_number:
  108. fd.L1.Path = sb.MakeString(v)
  109. case genid.FileDescriptorProto_Package_field_number:
  110. fd.L1.Package = pref.FullName(sb.MakeString(v))
  111. case genid.FileDescriptorProto_EnumType_field_number:
  112. if prevField != genid.FileDescriptorProto_EnumType_field_number {
  113. if numEnums > 0 {
  114. panic("non-contiguous repeated field")
  115. }
  116. posEnums = len(b0) - len(b) - n - m
  117. }
  118. numEnums++
  119. case genid.FileDescriptorProto_MessageType_field_number:
  120. if prevField != genid.FileDescriptorProto_MessageType_field_number {
  121. if numMessages > 0 {
  122. panic("non-contiguous repeated field")
  123. }
  124. posMessages = len(b0) - len(b) - n - m
  125. }
  126. numMessages++
  127. case genid.FileDescriptorProto_Extension_field_number:
  128. if prevField != genid.FileDescriptorProto_Extension_field_number {
  129. if numExtensions > 0 {
  130. panic("non-contiguous repeated field")
  131. }
  132. posExtensions = len(b0) - len(b) - n - m
  133. }
  134. numExtensions++
  135. case genid.FileDescriptorProto_Service_field_number:
  136. if prevField != genid.FileDescriptorProto_Service_field_number {
  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 := protowire.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 := protowire.ConsumeVarint(b)
  173. v, m := protowire.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 := protowire.ConsumeVarint(b)
  182. v, m := protowire.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 := protowire.ConsumeVarint(b)
  191. v, m := protowire.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 := protowire.ConsumeVarint(b)
  200. v, m := protowire.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 := protowire.ConsumeTag(b)
  213. b = b[n:]
  214. switch typ {
  215. case protowire.BytesType:
  216. v, m := protowire.ConsumeBytes(b)
  217. b = b[m:]
  218. switch num {
  219. case genid.EnumDescriptorProto_Name_field_number:
  220. ed.L0.FullName = appendFullName(sb, pd.FullName(), v)
  221. case genid.EnumDescriptorProto_Value_field_number:
  222. numValues++
  223. }
  224. default:
  225. m := protowire.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 := protowire.ConsumeTag(b)
  239. b = b[n:]
  240. switch typ {
  241. case protowire.BytesType:
  242. v, m := protowire.ConsumeBytes(b)
  243. b = b[m:]
  244. switch num {
  245. case genid.EnumDescriptorProto_Value_field_number:
  246. ed.L2.Values.List[i].unmarshalFull(v, sb, pf, ed, i)
  247. i++
  248. }
  249. default:
  250. m := protowire.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 := protowire.ConsumeTag(b)
  265. b = b[n:]
  266. switch typ {
  267. case protowire.BytesType:
  268. v, m := protowire.ConsumeBytes(b)
  269. b = b[m:]
  270. switch num {
  271. case genid.DescriptorProto_Name_field_number:
  272. md.L0.FullName = appendFullName(sb, pd.FullName(), v)
  273. case genid.DescriptorProto_EnumType_field_number:
  274. if prevField != genid.DescriptorProto_EnumType_field_number {
  275. if numEnums > 0 {
  276. panic("non-contiguous repeated field")
  277. }
  278. posEnums = len(b0) - len(b) - n - m
  279. }
  280. numEnums++
  281. case genid.DescriptorProto_NestedType_field_number:
  282. if prevField != genid.DescriptorProto_NestedType_field_number {
  283. if numMessages > 0 {
  284. panic("non-contiguous repeated field")
  285. }
  286. posMessages = len(b0) - len(b) - n - m
  287. }
  288. numMessages++
  289. case genid.DescriptorProto_Extension_field_number:
  290. if prevField != genid.DescriptorProto_Extension_field_number {
  291. if numExtensions > 0 {
  292. panic("non-contiguous repeated field")
  293. }
  294. posExtensions = len(b0) - len(b) - n - m
  295. }
  296. numExtensions++
  297. case genid.DescriptorProto_Options_field_number:
  298. md.unmarshalSeedOptions(v)
  299. }
  300. prevField = num
  301. default:
  302. m := protowire.ConsumeFieldValue(num, typ, b)
  303. b = b[m:]
  304. prevField = -1 // ignore known field numbers of unknown wire type
  305. }
  306. }
  307. // Must allocate all declarations before parsing each descriptor type
  308. // to ensure we handled all descriptors in "flattened ordering".
  309. if numEnums > 0 {
  310. md.L1.Enums.List = pf.allocEnums(numEnums)
  311. }
  312. if numMessages > 0 {
  313. md.L1.Messages.List = pf.allocMessages(numMessages)
  314. }
  315. if numExtensions > 0 {
  316. md.L1.Extensions.List = pf.allocExtensions(numExtensions)
  317. }
  318. if numEnums > 0 {
  319. b := b0[posEnums:]
  320. for i := range md.L1.Enums.List {
  321. _, n := protowire.ConsumeVarint(b)
  322. v, m := protowire.ConsumeBytes(b[n:])
  323. md.L1.Enums.List[i].unmarshalSeed(v, sb, pf, md, i)
  324. b = b[n+m:]
  325. }
  326. }
  327. if numMessages > 0 {
  328. b := b0[posMessages:]
  329. for i := range md.L1.Messages.List {
  330. _, n := protowire.ConsumeVarint(b)
  331. v, m := protowire.ConsumeBytes(b[n:])
  332. md.L1.Messages.List[i].unmarshalSeed(v, sb, pf, md, i)
  333. b = b[n+m:]
  334. }
  335. }
  336. if numExtensions > 0 {
  337. b := b0[posExtensions:]
  338. for i := range md.L1.Extensions.List {
  339. _, n := protowire.ConsumeVarint(b)
  340. v, m := protowire.ConsumeBytes(b[n:])
  341. md.L1.Extensions.List[i].unmarshalSeed(v, sb, pf, md, i)
  342. b = b[n+m:]
  343. }
  344. }
  345. }
  346. func (md *Message) unmarshalSeedOptions(b []byte) {
  347. for len(b) > 0 {
  348. num, typ, n := protowire.ConsumeTag(b)
  349. b = b[n:]
  350. switch typ {
  351. case protowire.VarintType:
  352. v, m := protowire.ConsumeVarint(b)
  353. b = b[m:]
  354. switch num {
  355. case genid.MessageOptions_MapEntry_field_number:
  356. md.L1.IsMapEntry = protowire.DecodeBool(v)
  357. case genid.MessageOptions_MessageSetWireFormat_field_number:
  358. md.L1.IsMessageSet = protowire.DecodeBool(v)
  359. }
  360. default:
  361. m := protowire.ConsumeFieldValue(num, typ, b)
  362. b = b[m:]
  363. }
  364. }
  365. }
  366. func (xd *Extension) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
  367. xd.L0.ParentFile = pf
  368. xd.L0.Parent = pd
  369. xd.L0.Index = i
  370. for len(b) > 0 {
  371. num, typ, n := protowire.ConsumeTag(b)
  372. b = b[n:]
  373. switch typ {
  374. case protowire.VarintType:
  375. v, m := protowire.ConsumeVarint(b)
  376. b = b[m:]
  377. switch num {
  378. case genid.FieldDescriptorProto_Number_field_number:
  379. xd.L1.Number = pref.FieldNumber(v)
  380. case genid.FieldDescriptorProto_Label_field_number:
  381. xd.L1.Cardinality = pref.Cardinality(v)
  382. case genid.FieldDescriptorProto_Type_field_number:
  383. xd.L1.Kind = pref.Kind(v)
  384. }
  385. case protowire.BytesType:
  386. v, m := protowire.ConsumeBytes(b)
  387. b = b[m:]
  388. switch num {
  389. case genid.FieldDescriptorProto_Name_field_number:
  390. xd.L0.FullName = appendFullName(sb, pd.FullName(), v)
  391. case genid.FieldDescriptorProto_Extendee_field_number:
  392. xd.L1.Extendee = PlaceholderMessage(makeFullName(sb, v))
  393. }
  394. default:
  395. m := protowire.ConsumeFieldValue(num, typ, b)
  396. b = b[m:]
  397. }
  398. }
  399. }
  400. func (sd *Service) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) {
  401. sd.L0.ParentFile = pf
  402. sd.L0.Parent = pd
  403. sd.L0.Index = i
  404. for len(b) > 0 {
  405. num, typ, n := protowire.ConsumeTag(b)
  406. b = b[n:]
  407. switch typ {
  408. case protowire.BytesType:
  409. v, m := protowire.ConsumeBytes(b)
  410. b = b[m:]
  411. switch num {
  412. case genid.ServiceDescriptorProto_Name_field_number:
  413. sd.L0.FullName = appendFullName(sb, pd.FullName(), v)
  414. }
  415. default:
  416. m := protowire.ConsumeFieldValue(num, typ, b)
  417. b = b[m:]
  418. }
  419. }
  420. }
  421. var nameBuilderPool = sync.Pool{
  422. New: func() interface{} { return new(strs.Builder) },
  423. }
  424. func getBuilder() *strs.Builder {
  425. return nameBuilderPool.Get().(*strs.Builder)
  426. }
  427. func putBuilder(b *strs.Builder) {
  428. nameBuilderPool.Put(b)
  429. }
  430. // makeFullName converts b to a protoreflect.FullName,
  431. // where b must start with a leading dot.
  432. func makeFullName(sb *strs.Builder, b []byte) pref.FullName {
  433. if len(b) == 0 || b[0] != '.' {
  434. panic("name reference must be fully qualified")
  435. }
  436. return pref.FullName(sb.MakeString(b[1:]))
  437. }
  438. func appendFullName(sb *strs.Builder, prefix pref.FullName, suffix []byte) pref.FullName {
  439. return sb.AppendFullName(prefix, pref.Name(strs.UnsafeString(suffix)))
  440. }