defs.c 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2014 Google Inc. All rights reserved.
  3. // https://developers.google.com/protocol-buffers/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. #include <ctype.h>
  31. #include <errno.h>
  32. #include <ruby/version.h>
  33. #include "convert.h"
  34. #include "message.h"
  35. #include "protobuf.h"
  36. // -----------------------------------------------------------------------------
  37. // Global map from upb {msg,enum}defs to wrapper Descriptor/EnumDescriptor
  38. // instances.
  39. // -----------------------------------------------------------------------------
  40. static VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_msgdef* def);
  41. static VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_enumdef* def);
  42. static VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_fielddef* def);
  43. static VALUE get_filedef_obj(VALUE descriptor_pool, const upb_filedef* def);
  44. static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_oneofdef* def);
  45. // A distinct object that is not accessible from Ruby. We use this as a
  46. // constructor argument to enforce that certain objects cannot be created from
  47. // Ruby.
  48. VALUE c_only_cookie = Qnil;
  49. // -----------------------------------------------------------------------------
  50. // Common utilities.
  51. // -----------------------------------------------------------------------------
  52. static const char* get_str(VALUE str) {
  53. Check_Type(str, T_STRING);
  54. return RSTRING_PTR(str);
  55. }
  56. static VALUE rb_str_maybe_null(const char* s) {
  57. if (s == NULL) {
  58. s = "";
  59. }
  60. return rb_str_new2(s);
  61. }
  62. // -----------------------------------------------------------------------------
  63. // DescriptorPool.
  64. // -----------------------------------------------------------------------------
  65. typedef struct {
  66. VALUE def_to_descriptor; // Hash table of def* -> Ruby descriptor.
  67. upb_symtab* symtab;
  68. } DescriptorPool;
  69. VALUE cDescriptorPool = Qnil;
  70. // Global singleton DescriptorPool. The user is free to create others, but this
  71. // is used by generated code.
  72. VALUE generated_pool = Qnil;
  73. static void DescriptorPool_mark(void* _self) {
  74. DescriptorPool* self = _self;
  75. rb_gc_mark(self->def_to_descriptor);
  76. }
  77. static void DescriptorPool_free(void* _self) {
  78. DescriptorPool* self = _self;
  79. upb_symtab_free(self->symtab);
  80. xfree(self);
  81. }
  82. static const rb_data_type_t DescriptorPool_type = {
  83. "Google::Protobuf::DescriptorPool",
  84. {DescriptorPool_mark, DescriptorPool_free, NULL},
  85. .flags = RUBY_TYPED_FREE_IMMEDIATELY,
  86. };
  87. static DescriptorPool* ruby_to_DescriptorPool(VALUE val) {
  88. DescriptorPool* ret;
  89. TypedData_Get_Struct(val, DescriptorPool, &DescriptorPool_type, ret);
  90. return ret;
  91. }
  92. // Exposed to other modules in defs.h.
  93. const upb_symtab *DescriptorPool_GetSymtab(VALUE desc_pool_rb) {
  94. DescriptorPool *pool = ruby_to_DescriptorPool(desc_pool_rb);
  95. return pool->symtab;
  96. }
  97. /*
  98. * call-seq:
  99. * DescriptorPool.new => pool
  100. *
  101. * Creates a new, empty, descriptor pool.
  102. */
  103. static VALUE DescriptorPool_alloc(VALUE klass) {
  104. DescriptorPool* self = ALLOC(DescriptorPool);
  105. VALUE ret;
  106. self->def_to_descriptor = Qnil;
  107. ret = TypedData_Wrap_Struct(klass, &DescriptorPool_type, self);
  108. self->def_to_descriptor = rb_hash_new();
  109. self->symtab = upb_symtab_new();
  110. ObjectCache_Add(self->symtab, ret);
  111. return ret;
  112. }
  113. /*
  114. * call-seq:
  115. * DescriptorPool.add_serialized_file(serialized_file_proto)
  116. *
  117. * Adds the given serialized FileDescriptorProto to the pool.
  118. */
  119. VALUE DescriptorPool_add_serialized_file(VALUE _self,
  120. VALUE serialized_file_proto) {
  121. DescriptorPool* self = ruby_to_DescriptorPool(_self);
  122. Check_Type(serialized_file_proto, T_STRING);
  123. VALUE arena_rb = Arena_new();
  124. upb_arena *arena = Arena_get(arena_rb);
  125. google_protobuf_FileDescriptorProto* file_proto =
  126. google_protobuf_FileDescriptorProto_parse(
  127. RSTRING_PTR(serialized_file_proto),
  128. RSTRING_LEN(serialized_file_proto), arena);
  129. if (!file_proto) {
  130. rb_raise(rb_eArgError, "Unable to parse FileDescriptorProto");
  131. }
  132. upb_status status;
  133. upb_status_clear(&status);
  134. const upb_filedef* filedef =
  135. upb_symtab_addfile(self->symtab, file_proto, &status);
  136. if (!filedef) {
  137. rb_raise(cTypeError, "Unable to build file to DescriptorPool: %s",
  138. upb_status_errmsg(&status));
  139. }
  140. return get_filedef_obj(_self, filedef);
  141. }
  142. /*
  143. * call-seq:
  144. * DescriptorPool.lookup(name) => descriptor
  145. *
  146. * Finds a Descriptor or EnumDescriptor by name and returns it, or nil if none
  147. * exists with the given name.
  148. */
  149. static VALUE DescriptorPool_lookup(VALUE _self, VALUE name) {
  150. DescriptorPool* self = ruby_to_DescriptorPool(_self);
  151. const char* name_str = get_str(name);
  152. const upb_msgdef* msgdef;
  153. const upb_enumdef* enumdef;
  154. msgdef = upb_symtab_lookupmsg(self->symtab, name_str);
  155. if (msgdef) {
  156. return get_msgdef_obj(_self, msgdef);
  157. }
  158. enumdef = upb_symtab_lookupenum(self->symtab, name_str);
  159. if (enumdef) {
  160. return get_enumdef_obj(_self, enumdef);
  161. }
  162. return Qnil;
  163. }
  164. /*
  165. * call-seq:
  166. * DescriptorPool.generated_pool => descriptor_pool
  167. *
  168. * Class method that returns the global DescriptorPool. This is a singleton into
  169. * which generated-code message and enum types are registered. The user may also
  170. * register types in this pool for convenience so that they do not have to hold
  171. * a reference to a private pool instance.
  172. */
  173. static VALUE DescriptorPool_generated_pool(VALUE _self) {
  174. return generated_pool;
  175. }
  176. static void DescriptorPool_register(VALUE module) {
  177. VALUE klass = rb_define_class_under(
  178. module, "DescriptorPool", rb_cObject);
  179. rb_define_alloc_func(klass, DescriptorPool_alloc);
  180. rb_define_method(klass, "add_serialized_file",
  181. DescriptorPool_add_serialized_file, 1);
  182. rb_define_method(klass, "lookup", DescriptorPool_lookup, 1);
  183. rb_define_singleton_method(klass, "generated_pool",
  184. DescriptorPool_generated_pool, 0);
  185. rb_gc_register_address(&cDescriptorPool);
  186. cDescriptorPool = klass;
  187. rb_gc_register_address(&generated_pool);
  188. generated_pool = rb_class_new_instance(0, NULL, klass);
  189. }
  190. // -----------------------------------------------------------------------------
  191. // Descriptor.
  192. // -----------------------------------------------------------------------------
  193. typedef struct {
  194. const upb_msgdef* msgdef;
  195. VALUE klass;
  196. VALUE descriptor_pool;
  197. } Descriptor;
  198. VALUE cDescriptor = Qnil;
  199. static void Descriptor_mark(void* _self) {
  200. Descriptor* self = _self;
  201. rb_gc_mark(self->klass);
  202. rb_gc_mark(self->descriptor_pool);
  203. }
  204. static const rb_data_type_t Descriptor_type = {
  205. "Google::Protobuf::Descriptor",
  206. {Descriptor_mark, RUBY_DEFAULT_FREE, NULL},
  207. .flags = RUBY_TYPED_FREE_IMMEDIATELY,
  208. };
  209. static Descriptor* ruby_to_Descriptor(VALUE val) {
  210. Descriptor* ret;
  211. TypedData_Get_Struct(val, Descriptor, &Descriptor_type, ret);
  212. return ret;
  213. }
  214. /*
  215. * call-seq:
  216. * Descriptor.new => descriptor
  217. *
  218. * Creates a new, empty, message type descriptor. At a minimum, its name must be
  219. * set before it is added to a pool. It cannot be used to create messages until
  220. * it is added to a pool, after which it becomes immutable (as part of a
  221. * finalization process).
  222. */
  223. static VALUE Descriptor_alloc(VALUE klass) {
  224. Descriptor* self = ALLOC(Descriptor);
  225. VALUE ret = TypedData_Wrap_Struct(klass, &Descriptor_type, self);
  226. self->msgdef = NULL;
  227. self->klass = Qnil;
  228. self->descriptor_pool = Qnil;
  229. return ret;
  230. }
  231. /*
  232. * call-seq:
  233. * Descriptor.new(c_only_cookie, ptr) => Descriptor
  234. *
  235. * Creates a descriptor wrapper object. May only be called from C.
  236. */
  237. static VALUE Descriptor_initialize(VALUE _self, VALUE cookie,
  238. VALUE descriptor_pool, VALUE ptr) {
  239. Descriptor* self = ruby_to_Descriptor(_self);
  240. if (cookie != c_only_cookie) {
  241. rb_raise(rb_eRuntimeError,
  242. "Descriptor objects may not be created from Ruby.");
  243. }
  244. self->descriptor_pool = descriptor_pool;
  245. self->msgdef = (const upb_msgdef*)NUM2ULL(ptr);
  246. return Qnil;
  247. }
  248. /*
  249. * call-seq:
  250. * Descriptor.file_descriptor
  251. *
  252. * Returns the FileDescriptor object this message belongs to.
  253. */
  254. static VALUE Descriptor_file_descriptor(VALUE _self) {
  255. Descriptor* self = ruby_to_Descriptor(_self);
  256. return get_filedef_obj(self->descriptor_pool, upb_msgdef_file(self->msgdef));
  257. }
  258. /*
  259. * call-seq:
  260. * Descriptor.name => name
  261. *
  262. * Returns the name of this message type as a fully-qualified string (e.g.,
  263. * My.Package.MessageType).
  264. */
  265. static VALUE Descriptor_name(VALUE _self) {
  266. Descriptor* self = ruby_to_Descriptor(_self);
  267. return rb_str_maybe_null(upb_msgdef_fullname(self->msgdef));
  268. }
  269. /*
  270. * call-seq:
  271. * Descriptor.each(&block)
  272. *
  273. * Iterates over fields in this message type, yielding to the block on each one.
  274. */
  275. static VALUE Descriptor_each(VALUE _self) {
  276. Descriptor* self = ruby_to_Descriptor(_self);
  277. upb_msg_field_iter it;
  278. for (upb_msg_field_begin(&it, self->msgdef);
  279. !upb_msg_field_done(&it);
  280. upb_msg_field_next(&it)) {
  281. const upb_fielddef* field = upb_msg_iter_field(&it);
  282. VALUE obj = get_fielddef_obj(self->descriptor_pool, field);
  283. rb_yield(obj);
  284. }
  285. return Qnil;
  286. }
  287. /*
  288. * call-seq:
  289. * Descriptor.lookup(name) => FieldDescriptor
  290. *
  291. * Returns the field descriptor for the field with the given name, if present,
  292. * or nil if none.
  293. */
  294. static VALUE Descriptor_lookup(VALUE _self, VALUE name) {
  295. Descriptor* self = ruby_to_Descriptor(_self);
  296. const char* s = get_str(name);
  297. const upb_fielddef* field = upb_msgdef_ntofz(self->msgdef, s);
  298. if (field == NULL) {
  299. return Qnil;
  300. }
  301. return get_fielddef_obj(self->descriptor_pool, field);
  302. }
  303. /*
  304. * call-seq:
  305. * Descriptor.each_oneof(&block) => nil
  306. *
  307. * Invokes the given block for each oneof in this message type, passing the
  308. * corresponding OneofDescriptor.
  309. */
  310. static VALUE Descriptor_each_oneof(VALUE _self) {
  311. Descriptor* self = ruby_to_Descriptor(_self);
  312. upb_msg_oneof_iter it;
  313. for (upb_msg_oneof_begin(&it, self->msgdef);
  314. !upb_msg_oneof_done(&it);
  315. upb_msg_oneof_next(&it)) {
  316. const upb_oneofdef* oneof = upb_msg_iter_oneof(&it);
  317. VALUE obj = get_oneofdef_obj(self->descriptor_pool, oneof);
  318. rb_yield(obj);
  319. }
  320. return Qnil;
  321. }
  322. /*
  323. * call-seq:
  324. * Descriptor.lookup_oneof(name) => OneofDescriptor
  325. *
  326. * Returns the oneof descriptor for the oneof with the given name, if present,
  327. * or nil if none.
  328. */
  329. static VALUE Descriptor_lookup_oneof(VALUE _self, VALUE name) {
  330. Descriptor* self = ruby_to_Descriptor(_self);
  331. const char* s = get_str(name);
  332. const upb_oneofdef* oneof = upb_msgdef_ntooz(self->msgdef, s);
  333. if (oneof == NULL) {
  334. return Qnil;
  335. }
  336. return get_oneofdef_obj(self->descriptor_pool, oneof);
  337. }
  338. /*
  339. * call-seq:
  340. * Descriptor.msgclass => message_klass
  341. *
  342. * Returns the Ruby class created for this message type.
  343. */
  344. static VALUE Descriptor_msgclass(VALUE _self) {
  345. Descriptor* self = ruby_to_Descriptor(_self);
  346. if (self->klass == Qnil) {
  347. self->klass = build_class_from_descriptor(_self);
  348. }
  349. return self->klass;
  350. }
  351. static void Descriptor_register(VALUE module) {
  352. VALUE klass = rb_define_class_under(
  353. module, "Descriptor", rb_cObject);
  354. rb_define_alloc_func(klass, Descriptor_alloc);
  355. rb_define_method(klass, "initialize", Descriptor_initialize, 3);
  356. rb_define_method(klass, "each", Descriptor_each, 0);
  357. rb_define_method(klass, "lookup", Descriptor_lookup, 1);
  358. rb_define_method(klass, "each_oneof", Descriptor_each_oneof, 0);
  359. rb_define_method(klass, "lookup_oneof", Descriptor_lookup_oneof, 1);
  360. rb_define_method(klass, "msgclass", Descriptor_msgclass, 0);
  361. rb_define_method(klass, "name", Descriptor_name, 0);
  362. rb_define_method(klass, "file_descriptor", Descriptor_file_descriptor, 0);
  363. rb_include_module(klass, rb_mEnumerable);
  364. rb_gc_register_address(&cDescriptor);
  365. cDescriptor = klass;
  366. }
  367. // -----------------------------------------------------------------------------
  368. // FileDescriptor.
  369. // -----------------------------------------------------------------------------
  370. typedef struct {
  371. const upb_filedef* filedef;
  372. VALUE descriptor_pool; // Owns the upb_filedef.
  373. } FileDescriptor;
  374. static VALUE cFileDescriptor = Qnil;
  375. static void FileDescriptor_mark(void* _self) {
  376. FileDescriptor* self = _self;
  377. rb_gc_mark(self->descriptor_pool);
  378. }
  379. static const rb_data_type_t FileDescriptor_type = {
  380. "Google::Protobuf::FileDescriptor",
  381. {FileDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
  382. .flags = RUBY_TYPED_FREE_IMMEDIATELY,
  383. };
  384. static FileDescriptor* ruby_to_FileDescriptor(VALUE val) {
  385. FileDescriptor* ret;
  386. TypedData_Get_Struct(val, FileDescriptor, &FileDescriptor_type, ret);
  387. return ret;
  388. }
  389. static VALUE FileDescriptor_alloc(VALUE klass) {
  390. FileDescriptor* self = ALLOC(FileDescriptor);
  391. VALUE ret = TypedData_Wrap_Struct(klass, &FileDescriptor_type, self);
  392. self->descriptor_pool = Qnil;
  393. self->filedef = NULL;
  394. return ret;
  395. }
  396. /*
  397. * call-seq:
  398. * FileDescriptor.new => file
  399. *
  400. * Returns a new file descriptor. The syntax must be set before it's passed
  401. * to a builder.
  402. */
  403. static VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie,
  404. VALUE descriptor_pool, VALUE ptr) {
  405. FileDescriptor* self = ruby_to_FileDescriptor(_self);
  406. if (cookie != c_only_cookie) {
  407. rb_raise(rb_eRuntimeError,
  408. "Descriptor objects may not be created from Ruby.");
  409. }
  410. self->descriptor_pool = descriptor_pool;
  411. self->filedef = (const upb_filedef*)NUM2ULL(ptr);
  412. return Qnil;
  413. }
  414. /*
  415. * call-seq:
  416. * FileDescriptor.name => name
  417. *
  418. * Returns the name of the file.
  419. */
  420. static VALUE FileDescriptor_name(VALUE _self) {
  421. FileDescriptor* self = ruby_to_FileDescriptor(_self);
  422. const char* name = upb_filedef_name(self->filedef);
  423. return name == NULL ? Qnil : rb_str_new2(name);
  424. }
  425. /*
  426. * call-seq:
  427. * FileDescriptor.syntax => syntax
  428. *
  429. * Returns this file descriptors syntax.
  430. *
  431. * Valid syntax versions are:
  432. * :proto2 or :proto3.
  433. */
  434. static VALUE FileDescriptor_syntax(VALUE _self) {
  435. FileDescriptor* self = ruby_to_FileDescriptor(_self);
  436. switch (upb_filedef_syntax(self->filedef)) {
  437. case UPB_SYNTAX_PROTO3: return ID2SYM(rb_intern("proto3"));
  438. case UPB_SYNTAX_PROTO2: return ID2SYM(rb_intern("proto2"));
  439. default: return Qnil;
  440. }
  441. }
  442. static void FileDescriptor_register(VALUE module) {
  443. VALUE klass = rb_define_class_under(
  444. module, "FileDescriptor", rb_cObject);
  445. rb_define_alloc_func(klass, FileDescriptor_alloc);
  446. rb_define_method(klass, "initialize", FileDescriptor_initialize, 3);
  447. rb_define_method(klass, "name", FileDescriptor_name, 0);
  448. rb_define_method(klass, "syntax", FileDescriptor_syntax, 0);
  449. rb_gc_register_address(&cFileDescriptor);
  450. cFileDescriptor = klass;
  451. }
  452. // -----------------------------------------------------------------------------
  453. // FieldDescriptor.
  454. // -----------------------------------------------------------------------------
  455. typedef struct {
  456. const upb_fielddef* fielddef;
  457. VALUE descriptor_pool; // Owns the upb_fielddef.
  458. } FieldDescriptor;
  459. static VALUE cFieldDescriptor = Qnil;
  460. static void FieldDescriptor_mark(void* _self) {
  461. FieldDescriptor* self = _self;
  462. rb_gc_mark(self->descriptor_pool);
  463. }
  464. static const rb_data_type_t FieldDescriptor_type = {
  465. "Google::Protobuf::FieldDescriptor",
  466. {FieldDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
  467. .flags = RUBY_TYPED_FREE_IMMEDIATELY,
  468. };
  469. static FieldDescriptor* ruby_to_FieldDescriptor(VALUE val) {
  470. FieldDescriptor* ret;
  471. TypedData_Get_Struct(val, FieldDescriptor, &FieldDescriptor_type, ret);
  472. return ret;
  473. }
  474. /*
  475. * call-seq:
  476. * FieldDescriptor.new => field
  477. *
  478. * Returns a new field descriptor. Its name, type, etc. must be set before it is
  479. * added to a message type.
  480. */
  481. static VALUE FieldDescriptor_alloc(VALUE klass) {
  482. FieldDescriptor* self = ALLOC(FieldDescriptor);
  483. VALUE ret = TypedData_Wrap_Struct(klass, &FieldDescriptor_type, self);
  484. self->fielddef = NULL;
  485. return ret;
  486. }
  487. /*
  488. * call-seq:
  489. * EnumDescriptor.new(c_only_cookie, pool, ptr) => EnumDescriptor
  490. *
  491. * Creates a descriptor wrapper object. May only be called from C.
  492. */
  493. static VALUE FieldDescriptor_initialize(VALUE _self, VALUE cookie,
  494. VALUE descriptor_pool, VALUE ptr) {
  495. FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
  496. if (cookie != c_only_cookie) {
  497. rb_raise(rb_eRuntimeError,
  498. "Descriptor objects may not be created from Ruby.");
  499. }
  500. self->descriptor_pool = descriptor_pool;
  501. self->fielddef = (const upb_fielddef*)NUM2ULL(ptr);
  502. return Qnil;
  503. }
  504. /*
  505. * call-seq:
  506. * FieldDescriptor.name => name
  507. *
  508. * Returns the name of this field.
  509. */
  510. static VALUE FieldDescriptor_name(VALUE _self) {
  511. FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
  512. return rb_str_maybe_null(upb_fielddef_name(self->fielddef));
  513. }
  514. // Non-static, exposed to other .c files.
  515. upb_fieldtype_t ruby_to_fieldtype(VALUE type) {
  516. if (TYPE(type) != T_SYMBOL) {
  517. rb_raise(rb_eArgError, "Expected symbol for field type.");
  518. }
  519. #define CONVERT(upb, ruby) \
  520. if (SYM2ID(type) == rb_intern( # ruby )) { \
  521. return UPB_TYPE_ ## upb; \
  522. }
  523. CONVERT(FLOAT, float);
  524. CONVERT(DOUBLE, double);
  525. CONVERT(BOOL, bool);
  526. CONVERT(STRING, string);
  527. CONVERT(BYTES, bytes);
  528. CONVERT(MESSAGE, message);
  529. CONVERT(ENUM, enum);
  530. CONVERT(INT32, int32);
  531. CONVERT(INT64, int64);
  532. CONVERT(UINT32, uint32);
  533. CONVERT(UINT64, uint64);
  534. #undef CONVERT
  535. rb_raise(rb_eArgError, "Unknown field type.");
  536. return 0;
  537. }
  538. static VALUE descriptortype_to_ruby(upb_descriptortype_t type) {
  539. switch (type) {
  540. #define CONVERT(upb, ruby) \
  541. case UPB_DESCRIPTOR_TYPE_ ## upb : return ID2SYM(rb_intern( # ruby ));
  542. CONVERT(FLOAT, float);
  543. CONVERT(DOUBLE, double);
  544. CONVERT(BOOL, bool);
  545. CONVERT(STRING, string);
  546. CONVERT(BYTES, bytes);
  547. CONVERT(MESSAGE, message);
  548. CONVERT(GROUP, group);
  549. CONVERT(ENUM, enum);
  550. CONVERT(INT32, int32);
  551. CONVERT(INT64, int64);
  552. CONVERT(UINT32, uint32);
  553. CONVERT(UINT64, uint64);
  554. CONVERT(SINT32, sint32);
  555. CONVERT(SINT64, sint64);
  556. CONVERT(FIXED32, fixed32);
  557. CONVERT(FIXED64, fixed64);
  558. CONVERT(SFIXED32, sfixed32);
  559. CONVERT(SFIXED64, sfixed64);
  560. #undef CONVERT
  561. }
  562. return Qnil;
  563. }
  564. /*
  565. * call-seq:
  566. * FieldDescriptor.type => type
  567. *
  568. * Returns this field's type, as a Ruby symbol, or nil if not yet set.
  569. *
  570. * Valid field types are:
  571. * :int32, :int64, :uint32, :uint64, :float, :double, :bool, :string,
  572. * :bytes, :message.
  573. */
  574. static VALUE FieldDescriptor__type(VALUE _self) {
  575. FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
  576. return descriptortype_to_ruby(upb_fielddef_descriptortype(self->fielddef));
  577. }
  578. /*
  579. * call-seq:
  580. * FieldDescriptor.default => default
  581. *
  582. * Returns this field's default, as a Ruby object, or nil if not yet set.
  583. */
  584. static VALUE FieldDescriptor_default(VALUE _self) {
  585. FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
  586. const upb_fielddef *f = self->fielddef;
  587. upb_msgval default_val = {0};
  588. if (upb_fielddef_issubmsg(f)) {
  589. return Qnil;
  590. } else if (!upb_fielddef_isseq(f)) {
  591. default_val = upb_fielddef_default(f);
  592. }
  593. return Convert_UpbToRuby(default_val, TypeInfo_get(self->fielddef), Qnil);
  594. }
  595. /*
  596. * call-seq:
  597. * FieldDescriptor.json_name => json_name
  598. *
  599. * Returns this field's json_name, as a Ruby string, or nil if not yet set.
  600. */
  601. static VALUE FieldDescriptor_json_name(VALUE _self) {
  602. FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
  603. const upb_fielddef *f = self->fielddef;
  604. const char *json_name = upb_fielddef_jsonname(f);
  605. return rb_str_new2(json_name);
  606. }
  607. /*
  608. * call-seq:
  609. * FieldDescriptor.label => label
  610. *
  611. * Returns this field's label (i.e., plurality), as a Ruby symbol.
  612. *
  613. * Valid field labels are:
  614. * :optional, :repeated
  615. */
  616. static VALUE FieldDescriptor_label(VALUE _self) {
  617. FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
  618. switch (upb_fielddef_label(self->fielddef)) {
  619. #define CONVERT(upb, ruby) \
  620. case UPB_LABEL_ ## upb : return ID2SYM(rb_intern( # ruby ));
  621. CONVERT(OPTIONAL, optional);
  622. CONVERT(REQUIRED, required);
  623. CONVERT(REPEATED, repeated);
  624. #undef CONVERT
  625. }
  626. return Qnil;
  627. }
  628. /*
  629. * call-seq:
  630. * FieldDescriptor.number => number
  631. *
  632. * Returns the tag number for this field.
  633. */
  634. static VALUE FieldDescriptor_number(VALUE _self) {
  635. FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
  636. return INT2NUM(upb_fielddef_number(self->fielddef));
  637. }
  638. /*
  639. * call-seq:
  640. * FieldDescriptor.submsg_name => submsg_name
  641. *
  642. * Returns the name of the message or enum type corresponding to this field, if
  643. * it is a message or enum field (respectively), or nil otherwise. This type
  644. * name will be resolved within the context of the pool to which the containing
  645. * message type is added.
  646. */
  647. static VALUE FieldDescriptor_submsg_name(VALUE _self) {
  648. FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
  649. switch (upb_fielddef_type(self->fielddef)) {
  650. case UPB_TYPE_ENUM:
  651. return rb_str_new2(
  652. upb_enumdef_fullname(upb_fielddef_enumsubdef(self->fielddef)));
  653. case UPB_TYPE_MESSAGE:
  654. return rb_str_new2(
  655. upb_msgdef_fullname(upb_fielddef_msgsubdef(self->fielddef)));
  656. default:
  657. return Qnil;
  658. }
  659. }
  660. /*
  661. * call-seq:
  662. * FieldDescriptor.subtype => message_or_enum_descriptor
  663. *
  664. * Returns the message or enum descriptor corresponding to this field's type if
  665. * it is a message or enum field, respectively, or nil otherwise. Cannot be
  666. * called *until* the containing message type is added to a pool (and thus
  667. * resolved).
  668. */
  669. static VALUE FieldDescriptor_subtype(VALUE _self) {
  670. FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
  671. switch (upb_fielddef_type(self->fielddef)) {
  672. case UPB_TYPE_ENUM:
  673. return get_enumdef_obj(self->descriptor_pool,
  674. upb_fielddef_enumsubdef(self->fielddef));
  675. case UPB_TYPE_MESSAGE:
  676. return get_msgdef_obj(self->descriptor_pool,
  677. upb_fielddef_msgsubdef(self->fielddef));
  678. default:
  679. return Qnil;
  680. }
  681. }
  682. /*
  683. * call-seq:
  684. * FieldDescriptor.get(message) => value
  685. *
  686. * Returns the value set for this field on the given message. Raises an
  687. * exception if message is of the wrong type.
  688. */
  689. static VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) {
  690. FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
  691. const upb_msgdef *m;
  692. Message_Get(msg_rb, &m);
  693. if (m != upb_fielddef_containingtype(self->fielddef)) {
  694. rb_raise(cTypeError, "get method called on wrong message type");
  695. }
  696. return Message_getfield(msg_rb, self->fielddef);
  697. }
  698. /*
  699. * call-seq:
  700. * FieldDescriptor.has?(message) => boolean
  701. *
  702. * Returns whether the value is set on the given message. Raises an
  703. * exception when calling for fields that do not have presence.
  704. */
  705. static VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) {
  706. FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
  707. const upb_msgdef *m;
  708. const upb_msgdef *msg = Message_Get(msg_rb, &m);
  709. if (m != upb_fielddef_containingtype(self->fielddef)) {
  710. rb_raise(cTypeError, "has method called on wrong message type");
  711. } else if (!upb_fielddef_haspresence(self->fielddef)) {
  712. rb_raise(rb_eArgError, "does not track presence");
  713. }
  714. return upb_msg_has(msg, self->fielddef) ? Qtrue : Qfalse;
  715. }
  716. /*
  717. * call-seq:
  718. * FieldDescriptor.clear(message)
  719. *
  720. * Clears the field from the message if it's set.
  721. */
  722. static VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb) {
  723. FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
  724. const upb_msgdef *m;
  725. upb_msgdef *msg = Message_GetMutable(msg_rb, &m);
  726. if (m != upb_fielddef_containingtype(self->fielddef)) {
  727. rb_raise(cTypeError, "has method called on wrong message type");
  728. }
  729. upb_msg_clearfield(msg, self->fielddef);
  730. return Qnil;
  731. }
  732. /*
  733. * call-seq:
  734. * FieldDescriptor.set(message, value)
  735. *
  736. * Sets the value corresponding to this field to the given value on the given
  737. * message. Raises an exception if message is of the wrong type. Performs the
  738. * ordinary type-checks for field setting.
  739. */
  740. static VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) {
  741. FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
  742. const upb_msgdef *m;
  743. upb_msgdef *msg = Message_GetMutable(msg_rb, &m);
  744. upb_arena *arena = Arena_get(Message_GetArena(msg_rb));
  745. upb_msgval msgval;
  746. if (m != upb_fielddef_containingtype(self->fielddef)) {
  747. rb_raise(cTypeError, "set method called on wrong message type");
  748. }
  749. msgval = Convert_RubyToUpb(value, upb_fielddef_name(self->fielddef),
  750. TypeInfo_get(self->fielddef), arena);
  751. upb_msg_set(msg, self->fielddef, msgval, arena);
  752. return Qnil;
  753. }
  754. static void FieldDescriptor_register(VALUE module) {
  755. VALUE klass = rb_define_class_under(
  756. module, "FieldDescriptor", rb_cObject);
  757. rb_define_alloc_func(klass, FieldDescriptor_alloc);
  758. rb_define_method(klass, "initialize", FieldDescriptor_initialize, 3);
  759. rb_define_method(klass, "name", FieldDescriptor_name, 0);
  760. rb_define_method(klass, "type", FieldDescriptor__type, 0);
  761. rb_define_method(klass, "default", FieldDescriptor_default, 0);
  762. rb_define_method(klass, "json_name", FieldDescriptor_json_name, 0);
  763. rb_define_method(klass, "label", FieldDescriptor_label, 0);
  764. rb_define_method(klass, "number", FieldDescriptor_number, 0);
  765. rb_define_method(klass, "submsg_name", FieldDescriptor_submsg_name, 0);
  766. rb_define_method(klass, "subtype", FieldDescriptor_subtype, 0);
  767. rb_define_method(klass, "has?", FieldDescriptor_has, 1);
  768. rb_define_method(klass, "clear", FieldDescriptor_clear, 1);
  769. rb_define_method(klass, "get", FieldDescriptor_get, 1);
  770. rb_define_method(klass, "set", FieldDescriptor_set, 2);
  771. rb_gc_register_address(&cFieldDescriptor);
  772. cFieldDescriptor = klass;
  773. }
  774. // -----------------------------------------------------------------------------
  775. // OneofDescriptor.
  776. // -----------------------------------------------------------------------------
  777. typedef struct {
  778. const upb_oneofdef* oneofdef;
  779. VALUE descriptor_pool; // Owns the upb_oneofdef.
  780. } OneofDescriptor;
  781. static VALUE cOneofDescriptor = Qnil;
  782. static void OneofDescriptor_mark(void* _self) {
  783. OneofDescriptor* self = _self;
  784. rb_gc_mark(self->descriptor_pool);
  785. }
  786. static const rb_data_type_t OneofDescriptor_type = {
  787. "Google::Protobuf::OneofDescriptor",
  788. {OneofDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
  789. .flags = RUBY_TYPED_FREE_IMMEDIATELY,
  790. };
  791. static OneofDescriptor* ruby_to_OneofDescriptor(VALUE val) {
  792. OneofDescriptor* ret;
  793. TypedData_Get_Struct(val, OneofDescriptor, &OneofDescriptor_type, ret);
  794. return ret;
  795. }
  796. /*
  797. * call-seq:
  798. * OneofDescriptor.new => oneof_descriptor
  799. *
  800. * Creates a new, empty, oneof descriptor. The oneof may only be modified prior
  801. * to being added to a message descriptor which is subsequently added to a pool.
  802. */
  803. static VALUE OneofDescriptor_alloc(VALUE klass) {
  804. OneofDescriptor* self = ALLOC(OneofDescriptor);
  805. VALUE ret = TypedData_Wrap_Struct(klass, &OneofDescriptor_type, self);
  806. self->oneofdef = NULL;
  807. self->descriptor_pool = Qnil;
  808. return ret;
  809. }
  810. /*
  811. * call-seq:
  812. * OneofDescriptor.new(c_only_cookie, pool, ptr) => OneofDescriptor
  813. *
  814. * Creates a descriptor wrapper object. May only be called from C.
  815. */
  816. static VALUE OneofDescriptor_initialize(VALUE _self, VALUE cookie,
  817. VALUE descriptor_pool, VALUE ptr) {
  818. OneofDescriptor* self = ruby_to_OneofDescriptor(_self);
  819. if (cookie != c_only_cookie) {
  820. rb_raise(rb_eRuntimeError,
  821. "Descriptor objects may not be created from Ruby.");
  822. }
  823. self->descriptor_pool = descriptor_pool;
  824. self->oneofdef = (const upb_oneofdef*)NUM2ULL(ptr);
  825. return Qnil;
  826. }
  827. /*
  828. * call-seq:
  829. * OneofDescriptor.name => name
  830. *
  831. * Returns the name of this oneof.
  832. */
  833. static VALUE OneofDescriptor_name(VALUE _self) {
  834. OneofDescriptor* self = ruby_to_OneofDescriptor(_self);
  835. return rb_str_maybe_null(upb_oneofdef_name(self->oneofdef));
  836. }
  837. /*
  838. * call-seq:
  839. * OneofDescriptor.each(&block) => nil
  840. *
  841. * Iterates through fields in this oneof, yielding to the block on each one.
  842. */
  843. static VALUE OneofDescriptor_each(VALUE _self) {
  844. OneofDescriptor* self = ruby_to_OneofDescriptor(_self);
  845. upb_oneof_iter it;
  846. for (upb_oneof_begin(&it, self->oneofdef);
  847. !upb_oneof_done(&it);
  848. upb_oneof_next(&it)) {
  849. const upb_fielddef* f = upb_oneof_iter_field(&it);
  850. VALUE obj = get_fielddef_obj(self->descriptor_pool, f);
  851. rb_yield(obj);
  852. }
  853. return Qnil;
  854. }
  855. static void OneofDescriptor_register(VALUE module) {
  856. VALUE klass = rb_define_class_under(
  857. module, "OneofDescriptor", rb_cObject);
  858. rb_define_alloc_func(klass, OneofDescriptor_alloc);
  859. rb_define_method(klass, "initialize", OneofDescriptor_initialize, 3);
  860. rb_define_method(klass, "name", OneofDescriptor_name, 0);
  861. rb_define_method(klass, "each", OneofDescriptor_each, 0);
  862. rb_include_module(klass, rb_mEnumerable);
  863. rb_gc_register_address(&cOneofDescriptor);
  864. cOneofDescriptor = klass;
  865. }
  866. // -----------------------------------------------------------------------------
  867. // EnumDescriptor.
  868. // -----------------------------------------------------------------------------
  869. typedef struct {
  870. const upb_enumdef* enumdef;
  871. VALUE module; // begins as nil
  872. VALUE descriptor_pool; // Owns the upb_enumdef.
  873. } EnumDescriptor;
  874. static VALUE cEnumDescriptor = Qnil;
  875. static void EnumDescriptor_mark(void* _self) {
  876. EnumDescriptor* self = _self;
  877. rb_gc_mark(self->module);
  878. rb_gc_mark(self->descriptor_pool);
  879. }
  880. static const rb_data_type_t EnumDescriptor_type = {
  881. "Google::Protobuf::EnumDescriptor",
  882. {EnumDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
  883. .flags = RUBY_TYPED_FREE_IMMEDIATELY,
  884. };
  885. static EnumDescriptor* ruby_to_EnumDescriptor(VALUE val) {
  886. EnumDescriptor* ret;
  887. TypedData_Get_Struct(val, EnumDescriptor, &EnumDescriptor_type, ret);
  888. return ret;
  889. }
  890. static VALUE EnumDescriptor_alloc(VALUE klass) {
  891. EnumDescriptor* self = ALLOC(EnumDescriptor);
  892. VALUE ret = TypedData_Wrap_Struct(klass, &EnumDescriptor_type, self);
  893. self->enumdef = NULL;
  894. self->module = Qnil;
  895. self->descriptor_pool = Qnil;
  896. return ret;
  897. }
  898. // Exposed to other modules in defs.h.
  899. const upb_enumdef *EnumDescriptor_GetEnumDef(VALUE enum_desc_rb) {
  900. EnumDescriptor *desc = ruby_to_EnumDescriptor(enum_desc_rb);
  901. return desc->enumdef;
  902. }
  903. /*
  904. * call-seq:
  905. * EnumDescriptor.new(c_only_cookie, ptr) => EnumDescriptor
  906. *
  907. * Creates a descriptor wrapper object. May only be called from C.
  908. */
  909. static VALUE EnumDescriptor_initialize(VALUE _self, VALUE cookie,
  910. VALUE descriptor_pool, VALUE ptr) {
  911. EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
  912. if (cookie != c_only_cookie) {
  913. rb_raise(rb_eRuntimeError,
  914. "Descriptor objects may not be created from Ruby.");
  915. }
  916. self->descriptor_pool = descriptor_pool;
  917. self->enumdef = (const upb_enumdef*)NUM2ULL(ptr);
  918. return Qnil;
  919. }
  920. /*
  921. * call-seq:
  922. * EnumDescriptor.file_descriptor
  923. *
  924. * Returns the FileDescriptor object this enum belongs to.
  925. */
  926. static VALUE EnumDescriptor_file_descriptor(VALUE _self) {
  927. EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
  928. return get_filedef_obj(self->descriptor_pool,
  929. upb_enumdef_file(self->enumdef));
  930. }
  931. /*
  932. * call-seq:
  933. * EnumDescriptor.name => name
  934. *
  935. * Returns the name of this enum type.
  936. */
  937. static VALUE EnumDescriptor_name(VALUE _self) {
  938. EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
  939. return rb_str_maybe_null(upb_enumdef_fullname(self->enumdef));
  940. }
  941. /*
  942. * call-seq:
  943. * EnumDescriptor.lookup_name(name) => value
  944. *
  945. * Returns the numeric value corresponding to the given key name (as a Ruby
  946. * symbol), or nil if none.
  947. */
  948. static VALUE EnumDescriptor_lookup_name(VALUE _self, VALUE name) {
  949. EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
  950. const char* name_str= rb_id2name(SYM2ID(name));
  951. int32_t val = 0;
  952. if (upb_enumdef_ntoiz(self->enumdef, name_str, &val)) {
  953. return INT2NUM(val);
  954. } else {
  955. return Qnil;
  956. }
  957. }
  958. /*
  959. * call-seq:
  960. * EnumDescriptor.lookup_value(name) => value
  961. *
  962. * Returns the key name (as a Ruby symbol) corresponding to the integer value,
  963. * or nil if none.
  964. */
  965. static VALUE EnumDescriptor_lookup_value(VALUE _self, VALUE number) {
  966. EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
  967. int32_t val = NUM2INT(number);
  968. const char* name = upb_enumdef_iton(self->enumdef, val);
  969. if (name != NULL) {
  970. return ID2SYM(rb_intern(name));
  971. } else {
  972. return Qnil;
  973. }
  974. }
  975. /*
  976. * call-seq:
  977. * EnumDescriptor.each(&block)
  978. *
  979. * Iterates over key => value mappings in this enum's definition, yielding to
  980. * the block with (key, value) arguments for each one.
  981. */
  982. static VALUE EnumDescriptor_each(VALUE _self) {
  983. EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
  984. upb_enum_iter it;
  985. for (upb_enum_begin(&it, self->enumdef);
  986. !upb_enum_done(&it);
  987. upb_enum_next(&it)) {
  988. VALUE key = ID2SYM(rb_intern(upb_enum_iter_name(&it)));
  989. VALUE number = INT2NUM(upb_enum_iter_number(&it));
  990. rb_yield_values(2, key, number);
  991. }
  992. return Qnil;
  993. }
  994. /*
  995. * call-seq:
  996. * EnumDescriptor.enummodule => module
  997. *
  998. * Returns the Ruby module corresponding to this enum type.
  999. */
  1000. static VALUE EnumDescriptor_enummodule(VALUE _self) {
  1001. EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
  1002. if (self->module == Qnil) {
  1003. self->module = build_module_from_enumdesc(_self);
  1004. }
  1005. return self->module;
  1006. }
  1007. static void EnumDescriptor_register(VALUE module) {
  1008. VALUE klass = rb_define_class_under(
  1009. module, "EnumDescriptor", rb_cObject);
  1010. rb_define_alloc_func(klass, EnumDescriptor_alloc);
  1011. rb_define_method(klass, "initialize", EnumDescriptor_initialize, 3);
  1012. rb_define_method(klass, "name", EnumDescriptor_name, 0);
  1013. rb_define_method(klass, "lookup_name", EnumDescriptor_lookup_name, 1);
  1014. rb_define_method(klass, "lookup_value", EnumDescriptor_lookup_value, 1);
  1015. rb_define_method(klass, "each", EnumDescriptor_each, 0);
  1016. rb_define_method(klass, "enummodule", EnumDescriptor_enummodule, 0);
  1017. rb_define_method(klass, "file_descriptor", EnumDescriptor_file_descriptor, 0);
  1018. rb_include_module(klass, rb_mEnumerable);
  1019. rb_gc_register_address(&cEnumDescriptor);
  1020. cEnumDescriptor = klass;
  1021. }
  1022. static VALUE get_def_obj(VALUE _descriptor_pool, const void* ptr, VALUE klass) {
  1023. DescriptorPool* descriptor_pool = ruby_to_DescriptorPool(_descriptor_pool);
  1024. VALUE key = ULL2NUM((intptr_t)ptr);
  1025. VALUE def;
  1026. def = rb_hash_aref(descriptor_pool->def_to_descriptor, key);
  1027. if (ptr == NULL) {
  1028. return Qnil;
  1029. }
  1030. if (def == Qnil) {
  1031. // Lazily create wrapper object.
  1032. VALUE args[3] = { c_only_cookie, _descriptor_pool, key };
  1033. def = rb_class_new_instance(3, args, klass);
  1034. rb_hash_aset(descriptor_pool->def_to_descriptor, key, def);
  1035. }
  1036. return def;
  1037. }
  1038. static VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_msgdef* def) {
  1039. return get_def_obj(descriptor_pool, def, cDescriptor);
  1040. }
  1041. static VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_enumdef* def) {
  1042. return get_def_obj(descriptor_pool, def, cEnumDescriptor);
  1043. }
  1044. static VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_fielddef* def) {
  1045. return get_def_obj(descriptor_pool, def, cFieldDescriptor);
  1046. }
  1047. static VALUE get_filedef_obj(VALUE descriptor_pool, const upb_filedef* def) {
  1048. return get_def_obj(descriptor_pool, def, cFileDescriptor);
  1049. }
  1050. static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_oneofdef* def) {
  1051. return get_def_obj(descriptor_pool, def, cOneofDescriptor);
  1052. }
  1053. // -----------------------------------------------------------------------------
  1054. // Shared functions
  1055. // -----------------------------------------------------------------------------
  1056. // Functions exposed to other modules in defs.h.
  1057. VALUE Descriptor_DefToClass(const upb_msgdef *m) {
  1058. const upb_symtab *symtab = upb_filedef_symtab(upb_msgdef_file(m));
  1059. VALUE pool = ObjectCache_Get(symtab);
  1060. PBRUBY_ASSERT(pool != Qnil);
  1061. VALUE desc_rb = get_msgdef_obj(pool, m);
  1062. const Descriptor* desc = ruby_to_Descriptor(desc_rb);
  1063. return desc->klass;
  1064. }
  1065. const upb_msgdef *Descriptor_GetMsgDef(VALUE desc_rb) {
  1066. const Descriptor* desc = ruby_to_Descriptor(desc_rb);
  1067. return desc->msgdef;
  1068. }
  1069. VALUE TypeInfo_InitArg(int argc, VALUE *argv, int skip_arg) {
  1070. if (argc > skip_arg) {
  1071. if (argc > 1 + skip_arg) {
  1072. rb_raise(rb_eArgError, "Expected a maximum of %d arguments.", skip_arg + 1);
  1073. }
  1074. return argv[skip_arg];
  1075. } else {
  1076. return Qnil;
  1077. }
  1078. }
  1079. TypeInfo TypeInfo_FromClass(int argc, VALUE* argv, int skip_arg,
  1080. VALUE* type_class, VALUE* init_arg) {
  1081. TypeInfo ret = {ruby_to_fieldtype(argv[skip_arg])};
  1082. if (ret.type == UPB_TYPE_MESSAGE || ret.type == UPB_TYPE_ENUM) {
  1083. *init_arg = TypeInfo_InitArg(argc, argv, skip_arg + 2);
  1084. if (argc < 2 + skip_arg) {
  1085. rb_raise(rb_eArgError, "Expected at least %d arguments for message/enum.",
  1086. 2 + skip_arg);
  1087. }
  1088. VALUE klass = argv[1 + skip_arg];
  1089. VALUE desc = MessageOrEnum_GetDescriptor(klass);
  1090. *type_class = klass;
  1091. if (desc == Qnil) {
  1092. rb_raise(rb_eArgError,
  1093. "Type class has no descriptor. Please pass a "
  1094. "class or enum as returned by the DescriptorPool.");
  1095. }
  1096. if (ret.type == UPB_TYPE_MESSAGE) {
  1097. ret.def.msgdef = ruby_to_Descriptor(desc)->msgdef;
  1098. Message_CheckClass(klass);
  1099. } else {
  1100. PBRUBY_ASSERT(ret.type == UPB_TYPE_ENUM);
  1101. ret.def.enumdef = ruby_to_EnumDescriptor(desc)->enumdef;
  1102. }
  1103. } else {
  1104. *init_arg = TypeInfo_InitArg(argc, argv, skip_arg + 1);
  1105. }
  1106. return ret;
  1107. }
  1108. void Defs_register(VALUE module) {
  1109. DescriptorPool_register(module);
  1110. Descriptor_register(module);
  1111. FileDescriptor_register(module);
  1112. FieldDescriptor_register(module);
  1113. OneofDescriptor_register(module);
  1114. EnumDescriptor_register(module);
  1115. rb_gc_register_address(&c_only_cookie);
  1116. c_only_cookie = rb_class_new_instance(0, NULL, rb_cObject);
  1117. }