message.c 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329
  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 "message.h"
  31. #include "convert.h"
  32. #include "defs.h"
  33. #include "map.h"
  34. #include "protobuf.h"
  35. #include "repeated_field.h"
  36. static VALUE cParseError = Qnil;
  37. static ID descriptor_instancevar_interned;
  38. static VALUE initialize_rb_class_with_no_args(VALUE klass) {
  39. return rb_funcall(klass, rb_intern("new"), 0);
  40. }
  41. VALUE MessageOrEnum_GetDescriptor(VALUE klass) {
  42. return rb_ivar_get(klass, descriptor_instancevar_interned);
  43. }
  44. // -----------------------------------------------------------------------------
  45. // Class/module creation from msgdefs and enumdefs, respectively.
  46. // -----------------------------------------------------------------------------
  47. typedef struct {
  48. VALUE arena;
  49. const upb_msg* msg; // Can get as mutable when non-frozen.
  50. const upb_msgdef* msgdef; // kept alive by self.class.descriptor reference.
  51. } Message;
  52. static void Message_mark(void* _self) {
  53. Message* self = (Message *)_self;
  54. rb_gc_mark(self->arena);
  55. }
  56. static rb_data_type_t Message_type = {
  57. "Message",
  58. { Message_mark, RUBY_DEFAULT_FREE, NULL },
  59. .flags = RUBY_TYPED_FREE_IMMEDIATELY,
  60. };
  61. static Message* ruby_to_Message(VALUE msg_rb) {
  62. Message* msg;
  63. TypedData_Get_Struct(msg_rb, Message, &Message_type, msg);
  64. return msg;
  65. }
  66. static VALUE Message_alloc(VALUE klass) {
  67. VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
  68. Message* msg = ALLOC(Message);
  69. VALUE ret;
  70. msg->msgdef = Descriptor_GetMsgDef(descriptor);
  71. msg->arena = Qnil;
  72. msg->msg = NULL;
  73. ret = TypedData_Wrap_Struct(klass, &Message_type, msg);
  74. rb_ivar_set(ret, descriptor_instancevar_interned, descriptor);
  75. return ret;
  76. }
  77. const upb_msg *Message_Get(VALUE msg_rb, const upb_msgdef **m) {
  78. Message* msg = ruby_to_Message(msg_rb);
  79. if (m) *m = msg->msgdef;
  80. return msg->msg;
  81. }
  82. upb_msg *Message_GetMutable(VALUE msg_rb, const upb_msgdef **m) {
  83. rb_check_frozen(msg_rb);
  84. return (upb_msg*)Message_Get(msg_rb, m);
  85. }
  86. void Message_InitPtr(VALUE self_, upb_msg *msg, VALUE arena) {
  87. Message* self = ruby_to_Message(self_);
  88. self->msg = msg;
  89. self->arena = arena;
  90. ObjectCache_Add(msg, self_);
  91. }
  92. VALUE Message_GetArena(VALUE msg_rb) {
  93. Message* msg = ruby_to_Message(msg_rb);
  94. return msg->arena;
  95. }
  96. void Message_CheckClass(VALUE klass) {
  97. if (rb_get_alloc_func(klass) != &Message_alloc) {
  98. rb_raise(rb_eArgError,
  99. "Message class was not returned by the DescriptorPool.");
  100. }
  101. }
  102. VALUE Message_GetRubyWrapper(upb_msg* msg, const upb_msgdef* m, VALUE arena) {
  103. if (msg == NULL) return Qnil;
  104. VALUE val = ObjectCache_Get(msg);
  105. if (val == Qnil) {
  106. VALUE klass = Descriptor_DefToClass(m);
  107. val = Message_alloc(klass);
  108. Message_InitPtr(val, msg, arena);
  109. }
  110. return val;
  111. }
  112. void Message_PrintMessage(StringBuilder* b, const upb_msg* msg,
  113. const upb_msgdef* m) {
  114. bool first = true;
  115. int n = upb_msgdef_fieldcount(m);
  116. VALUE klass = Descriptor_DefToClass(m);
  117. StringBuilder_Printf(b, "<%s: ", rb_class2name(klass));
  118. for (int i = 0; i < n; i++) {
  119. const upb_fielddef* field = upb_msgdef_field(m, i);
  120. if (upb_fielddef_haspresence(field) && !upb_msg_has(msg, field)) {
  121. continue;
  122. }
  123. if (!first) {
  124. StringBuilder_Printf(b, ", ");
  125. } else {
  126. first = false;
  127. }
  128. upb_msgval msgval = upb_msg_get(msg, field);
  129. StringBuilder_Printf(b, "%s: ", upb_fielddef_name(field));
  130. if (upb_fielddef_ismap(field)) {
  131. const upb_msgdef* entry_m = upb_fielddef_msgsubdef(field);
  132. const upb_fielddef* key_f = upb_msgdef_itof(entry_m, 1);
  133. const upb_fielddef* val_f = upb_msgdef_itof(entry_m, 2);
  134. TypeInfo val_info = TypeInfo_get(val_f);
  135. Map_Inspect(b, msgval.map_val, upb_fielddef_type(key_f), val_info);
  136. } else if (upb_fielddef_isseq(field)) {
  137. RepeatedField_Inspect(b, msgval.array_val, TypeInfo_get(field));
  138. } else {
  139. StringBuilder_PrintMsgval(b, msgval, TypeInfo_get(field));
  140. }
  141. }
  142. StringBuilder_Printf(b, ">");
  143. }
  144. // Helper functions for #method_missing ////////////////////////////////////////
  145. enum {
  146. METHOD_UNKNOWN = 0,
  147. METHOD_GETTER = 1,
  148. METHOD_SETTER = 2,
  149. METHOD_CLEAR = 3,
  150. METHOD_PRESENCE = 4,
  151. METHOD_ENUM_GETTER = 5,
  152. METHOD_WRAPPER_GETTER = 6,
  153. METHOD_WRAPPER_SETTER = 7
  154. };
  155. // Check if the field is a well known wrapper type
  156. static bool IsWrapper(const upb_fielddef* f) {
  157. return upb_fielddef_issubmsg(f) &&
  158. upb_msgdef_iswrapper(upb_fielddef_msgsubdef(f));
  159. }
  160. static bool Match(const upb_msgdef* m, const char* name, const upb_fielddef** f,
  161. const upb_oneofdef** o, const char* prefix,
  162. const char* suffix) {
  163. size_t sp = strlen(prefix);
  164. size_t ss = strlen(suffix);
  165. size_t sn = strlen(name);
  166. if (sn <= sp + ss) return false;
  167. if (memcmp(name, prefix, sp) != 0 ||
  168. memcmp(name + sn - ss, suffix, ss) != 0) {
  169. return false;
  170. }
  171. return upb_msgdef_lookupname(m, name + sp, sn - sp - ss, f, o);
  172. }
  173. static int extract_method_call(VALUE method_name, Message* self,
  174. const upb_fielddef** f, const upb_oneofdef** o) {
  175. const upb_msgdef* m = self->msgdef;
  176. const char* name;
  177. Check_Type(method_name, T_SYMBOL);
  178. name = rb_id2name(SYM2ID(method_name));
  179. if (Match(m, name, f, o, "", "")) return METHOD_GETTER;
  180. if (Match(m, name, f, o, "", "=")) return METHOD_SETTER;
  181. if (Match(m, name, f, o, "clear_", "")) return METHOD_CLEAR;
  182. if (Match(m, name, f, o, "has_", "?") &&
  183. (*o || (*f && upb_fielddef_haspresence(*f)))) {
  184. // Disallow oneof hazzers for proto3.
  185. // TODO(haberman): remove this test when we are enabling oneof hazzers for
  186. // proto3.
  187. if (*f && !upb_fielddef_issubmsg(*f) &&
  188. upb_fielddef_realcontainingoneof(*f) &&
  189. upb_msgdef_syntax(upb_fielddef_containingtype(*f)) !=
  190. UPB_SYNTAX_PROTO2) {
  191. return METHOD_UNKNOWN;
  192. }
  193. return METHOD_PRESENCE;
  194. }
  195. if (Match(m, name, f, o, "", "_as_value") && *f && !upb_fielddef_isseq(*f) &&
  196. IsWrapper(*f)) {
  197. return METHOD_WRAPPER_GETTER;
  198. }
  199. if (Match(m, name, f, o, "", "_as_value=") && *f && !upb_fielddef_isseq(*f) &&
  200. IsWrapper(*f)) {
  201. return METHOD_WRAPPER_SETTER;
  202. }
  203. if (Match(m, name, f, o, "", "_const") && *f &&
  204. upb_fielddef_type(*f) == UPB_TYPE_ENUM) {
  205. return METHOD_ENUM_GETTER;
  206. }
  207. return METHOD_UNKNOWN;
  208. }
  209. static VALUE Message_oneof_accessor(VALUE _self, const upb_oneofdef* o,
  210. int accessor_type) {
  211. Message* self = ruby_to_Message(_self);
  212. const upb_fielddef* oneof_field = upb_msg_whichoneof(self->msg, o);
  213. switch (accessor_type) {
  214. case METHOD_PRESENCE:
  215. return oneof_field == NULL ? Qfalse : Qtrue;
  216. case METHOD_CLEAR:
  217. if (oneof_field != NULL) {
  218. upb_msg_clearfield(Message_GetMutable(_self, NULL), oneof_field);
  219. }
  220. return Qnil;
  221. case METHOD_GETTER:
  222. return oneof_field == NULL
  223. ? Qnil
  224. : ID2SYM(rb_intern(upb_fielddef_name(oneof_field)));
  225. case METHOD_SETTER:
  226. rb_raise(rb_eRuntimeError, "Oneof accessors are read-only.");
  227. }
  228. rb_raise(rb_eRuntimeError, "Invalid access of oneof field.");
  229. }
  230. static void Message_setfield(upb_msg* msg, const upb_fielddef* f, VALUE val,
  231. upb_arena* arena) {
  232. upb_msgval msgval;
  233. if (upb_fielddef_ismap(f)) {
  234. msgval.map_val = Map_GetUpbMap(val, f, arena);
  235. } else if (upb_fielddef_isseq(f)) {
  236. msgval.array_val = RepeatedField_GetUpbArray(val, f, arena);
  237. } else {
  238. if (val == Qnil &&
  239. (upb_fielddef_issubmsg(f) || upb_fielddef_realcontainingoneof(f))) {
  240. upb_msg_clearfield(msg, f);
  241. return;
  242. }
  243. msgval =
  244. Convert_RubyToUpb(val, upb_fielddef_name(f), TypeInfo_get(f), arena);
  245. }
  246. upb_msg_set(msg, f, msgval, arena);
  247. }
  248. VALUE Message_getfield(VALUE _self, const upb_fielddef* f) {
  249. Message* self = ruby_to_Message(_self);
  250. // This is a special-case: upb_msg_mutable() for map & array are logically
  251. // const (they will not change what is serialized) but physically
  252. // non-const, as they do allocate a repeated field or map. The logical
  253. // constness means it's ok to do even if the message is frozen.
  254. upb_msg *msg = (upb_msg*)self->msg;
  255. upb_arena *arena = Arena_get(self->arena);
  256. if (upb_fielddef_ismap(f)) {
  257. upb_map *map = upb_msg_mutable(msg, f, arena).map;
  258. const upb_fielddef *key_f = map_field_key(f);
  259. const upb_fielddef *val_f = map_field_value(f);
  260. upb_fieldtype_t key_type = upb_fielddef_type(key_f);
  261. TypeInfo value_type_info = TypeInfo_get(val_f);
  262. return Map_GetRubyWrapper(map, key_type, value_type_info, self->arena);
  263. } else if (upb_fielddef_isseq(f)) {
  264. upb_array *arr = upb_msg_mutable(msg, f, arena).array;
  265. return RepeatedField_GetRubyWrapper(arr, TypeInfo_get(f), self->arena);
  266. } else if (upb_fielddef_issubmsg(f)) {
  267. if (!upb_msg_has(self->msg, f)) return Qnil;
  268. upb_msg *submsg = upb_msg_mutable(msg, f, arena).msg;
  269. const upb_msgdef *m = upb_fielddef_msgsubdef(f);
  270. return Message_GetRubyWrapper(submsg, m, self->arena);
  271. } else {
  272. upb_msgval msgval = upb_msg_get(self->msg, f);
  273. return Convert_UpbToRuby(msgval, TypeInfo_get(f), self->arena);
  274. }
  275. }
  276. static VALUE Message_field_accessor(VALUE _self, const upb_fielddef* f,
  277. int accessor_type, int argc, VALUE* argv) {
  278. upb_arena *arena = Arena_get(Message_GetArena(_self));
  279. switch (accessor_type) {
  280. case METHOD_SETTER:
  281. Message_setfield(Message_GetMutable(_self, NULL), f, argv[1], arena);
  282. return Qnil;
  283. case METHOD_CLEAR:
  284. upb_msg_clearfield(Message_GetMutable(_self, NULL), f);
  285. return Qnil;
  286. case METHOD_PRESENCE:
  287. if (!upb_fielddef_haspresence(f)) {
  288. rb_raise(rb_eRuntimeError, "Field does not have presence.");
  289. }
  290. return upb_msg_has(Message_Get(_self, NULL), f);
  291. case METHOD_WRAPPER_GETTER: {
  292. Message* self = ruby_to_Message(_self);
  293. if (upb_msg_has(self->msg, f)) {
  294. PBRUBY_ASSERT(upb_fielddef_issubmsg(f) && !upb_fielddef_isseq(f));
  295. upb_msgval wrapper = upb_msg_get(self->msg, f);
  296. const upb_msgdef *wrapper_m = upb_fielddef_msgsubdef(f);
  297. const upb_fielddef *value_f = upb_msgdef_itof(wrapper_m, 1);
  298. upb_msgval value = upb_msg_get(wrapper.msg_val, value_f);
  299. return Convert_UpbToRuby(value, TypeInfo_get(value_f), self->arena);
  300. } else {
  301. return Qnil;
  302. }
  303. }
  304. case METHOD_WRAPPER_SETTER: {
  305. upb_msg *msg = Message_GetMutable(_self, NULL);
  306. if (argv[1] == Qnil) {
  307. upb_msg_clearfield(msg, f);
  308. } else {
  309. const upb_fielddef *val_f = upb_msgdef_itof(upb_fielddef_msgsubdef(f), 1);
  310. upb_msgval msgval = Convert_RubyToUpb(argv[1], upb_fielddef_name(f),
  311. TypeInfo_get(val_f), arena);
  312. upb_msg *wrapper = upb_msg_mutable(msg, f, arena).msg;
  313. upb_msg_set(wrapper, val_f, msgval, arena);
  314. }
  315. return Qnil;
  316. }
  317. case METHOD_ENUM_GETTER: {
  318. upb_msgval msgval = upb_msg_get(Message_Get(_self, NULL), f);
  319. if (upb_fielddef_label(f) == UPB_LABEL_REPEATED) {
  320. // Map repeated fields to a new type with ints
  321. VALUE arr = rb_ary_new();
  322. size_t i, n = upb_array_size(msgval.array_val);
  323. for (i = 0; i < n; i++) {
  324. upb_msgval elem = upb_array_get(msgval.array_val, i);
  325. rb_ary_push(arr, INT2NUM(elem.int32_val));
  326. }
  327. return arr;
  328. } else {
  329. return INT2NUM(msgval.int32_val);
  330. }
  331. }
  332. case METHOD_GETTER:
  333. return Message_getfield(_self, f);
  334. default:
  335. rb_raise(rb_eRuntimeError, "Internal error, no such accessor: %d",
  336. accessor_type);
  337. }
  338. }
  339. /*
  340. * call-seq:
  341. * Message.method_missing(*args)
  342. *
  343. * Provides accessors and setters and methods to clear and check for presence of
  344. * message fields according to their field names.
  345. *
  346. * For any field whose name does not conflict with a built-in method, an
  347. * accessor is provided with the same name as the field, and a setter is
  348. * provided with the name of the field plus the '=' suffix. Thus, given a
  349. * message instance 'msg' with field 'foo', the following code is valid:
  350. *
  351. * msg.foo = 42
  352. * puts msg.foo
  353. *
  354. * This method also provides read-only accessors for oneofs. If a oneof exists
  355. * with name 'my_oneof', then msg.my_oneof will return a Ruby symbol equal to
  356. * the name of the field in that oneof that is currently set, or nil if none.
  357. *
  358. * It also provides methods of the form 'clear_fieldname' to clear the value
  359. * of the field 'fieldname'. For basic data types, this will set the default
  360. * value of the field.
  361. *
  362. * Additionally, it provides methods of the form 'has_fieldname?', which returns
  363. * true if the field 'fieldname' is set in the message object, else false. For
  364. * 'proto3' syntax, calling this for a basic type field will result in an error.
  365. */
  366. static VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) {
  367. Message* self = ruby_to_Message(_self);
  368. const upb_oneofdef* o;
  369. const upb_fielddef* f;
  370. int accessor_type;
  371. if (argc < 1) {
  372. rb_raise(rb_eArgError, "Expected method name as first argument.");
  373. }
  374. accessor_type = extract_method_call(argv[0], self, &f, &o);
  375. if (accessor_type == METHOD_UNKNOWN) return rb_call_super(argc, argv);
  376. // Validate argument count.
  377. switch (accessor_type) {
  378. case METHOD_SETTER:
  379. case METHOD_WRAPPER_SETTER:
  380. if (argc != 2) {
  381. rb_raise(rb_eArgError, "Expected 2 arguments, received %d", argc);
  382. }
  383. rb_check_frozen(_self);
  384. break;
  385. default:
  386. if (argc != 1) {
  387. rb_raise(rb_eArgError, "Expected 1 argument, received %d", argc);
  388. }
  389. break;
  390. }
  391. // Dispatch accessor.
  392. if (o != NULL) {
  393. return Message_oneof_accessor(_self, o, accessor_type);
  394. } else {
  395. return Message_field_accessor(_self, f, accessor_type, argc, argv);
  396. }
  397. }
  398. static VALUE Message_respond_to_missing(int argc, VALUE* argv, VALUE _self) {
  399. Message* self = ruby_to_Message(_self);
  400. const upb_oneofdef* o;
  401. const upb_fielddef* f;
  402. int accessor_type;
  403. if (argc < 1) {
  404. rb_raise(rb_eArgError, "Expected method name as first argument.");
  405. }
  406. accessor_type = extract_method_call(argv[0], self, &f, &o);
  407. if (accessor_type == METHOD_UNKNOWN) {
  408. return rb_call_super(argc, argv);
  409. } else if (o != NULL) {
  410. return accessor_type == METHOD_SETTER ? Qfalse : Qtrue;
  411. } else {
  412. return Qtrue;
  413. }
  414. }
  415. void Message_InitFromValue(upb_msg* msg, const upb_msgdef* m, VALUE val,
  416. upb_arena* arena);
  417. typedef struct {
  418. upb_map *map;
  419. TypeInfo key_type;
  420. TypeInfo val_type;
  421. upb_arena *arena;
  422. } MapInit;
  423. static int Map_initialize_kwarg(VALUE key, VALUE val, VALUE _self) {
  424. MapInit *map_init = (MapInit*)_self;
  425. upb_msgval k, v;
  426. k = Convert_RubyToUpb(key, "", map_init->key_type, NULL);
  427. if (map_init->val_type.type == UPB_TYPE_MESSAGE && TYPE(val) == T_HASH) {
  428. upb_msg *msg = upb_msg_new(map_init->val_type.def.msgdef, map_init->arena);
  429. Message_InitFromValue(msg, map_init->val_type.def.msgdef, val,
  430. map_init->arena);
  431. v.msg_val = msg;
  432. } else {
  433. v = Convert_RubyToUpb(val, "", map_init->val_type, map_init->arena);
  434. }
  435. upb_map_set(map_init->map, k, v, map_init->arena);
  436. return ST_CONTINUE;
  437. }
  438. static void Map_InitFromValue(upb_map* map, const upb_fielddef* f, VALUE val,
  439. upb_arena* arena) {
  440. const upb_msgdef* entry_m = upb_fielddef_msgsubdef(f);
  441. const upb_fielddef* key_f = upb_msgdef_itof(entry_m, 1);
  442. const upb_fielddef* val_f = upb_msgdef_itof(entry_m, 2);
  443. if (TYPE(val) != T_HASH) {
  444. rb_raise(rb_eArgError,
  445. "Expected Hash object as initializer value for map field '%s' "
  446. "(given %s).",
  447. upb_fielddef_name(f), rb_class2name(CLASS_OF(val)));
  448. }
  449. MapInit map_init = {map, TypeInfo_get(key_f), TypeInfo_get(val_f), arena};
  450. rb_hash_foreach(val, Map_initialize_kwarg, (VALUE)&map_init);
  451. }
  452. static upb_msgval MessageValue_FromValue(VALUE val, TypeInfo info,
  453. upb_arena* arena) {
  454. if (info.type == UPB_TYPE_MESSAGE) {
  455. upb_msgval msgval;
  456. upb_msg* msg = upb_msg_new(info.def.msgdef, arena);
  457. Message_InitFromValue(msg, info.def.msgdef, val, arena);
  458. msgval.msg_val = msg;
  459. return msgval;
  460. } else {
  461. return Convert_RubyToUpb(val, "", info, arena);
  462. }
  463. }
  464. static void RepeatedField_InitFromValue(upb_array* arr, const upb_fielddef* f,
  465. VALUE val, upb_arena* arena) {
  466. TypeInfo type_info = TypeInfo_get(f);
  467. if (TYPE(val) != T_ARRAY) {
  468. rb_raise(rb_eArgError,
  469. "Expected array as initializer value for repeated field '%s' (given %s).",
  470. upb_fielddef_name(f), rb_class2name(CLASS_OF(val)));
  471. }
  472. for (int i = 0; i < RARRAY_LEN(val); i++) {
  473. VALUE entry = rb_ary_entry(val, i);
  474. upb_msgval msgval;
  475. if (upb_fielddef_issubmsg(f) && TYPE(entry) == T_HASH) {
  476. msgval = MessageValue_FromValue(entry, type_info, arena);
  477. } else {
  478. msgval = Convert_RubyToUpb(entry, upb_fielddef_name(f), type_info, arena);
  479. }
  480. upb_array_append(arr, msgval, arena);
  481. }
  482. }
  483. static void Message_InitFieldFromValue(upb_msg* msg, const upb_fielddef* f,
  484. VALUE val, upb_arena* arena) {
  485. if (TYPE(val) == T_NIL) return;
  486. if (upb_fielddef_ismap(f)) {
  487. upb_map *map = upb_msg_mutable(msg, f, arena).map;
  488. Map_InitFromValue(map, f, val, arena);
  489. } else if (upb_fielddef_label(f) == UPB_LABEL_REPEATED) {
  490. upb_array *arr = upb_msg_mutable(msg, f, arena).array;
  491. RepeatedField_InitFromValue(arr, f, val, arena);
  492. } else if (upb_fielddef_issubmsg(f)) {
  493. if (TYPE(val) == T_HASH) {
  494. upb_msg *submsg = upb_msg_mutable(msg, f, arena).msg;
  495. Message_InitFromValue(submsg, upb_fielddef_msgsubdef(f), val, arena);
  496. } else {
  497. Message_setfield(msg, f, val, arena);
  498. }
  499. } else {
  500. upb_msgval msgval =
  501. Convert_RubyToUpb(val, upb_fielddef_name(f), TypeInfo_get(f), arena);
  502. upb_msg_set(msg, f, msgval, arena);
  503. }
  504. }
  505. typedef struct {
  506. upb_msg *msg;
  507. const upb_msgdef *msgdef;
  508. upb_arena *arena;
  509. } MsgInit;
  510. static int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) {
  511. MsgInit *msg_init = (MsgInit*)_self;
  512. const char *name;
  513. if (TYPE(key) == T_STRING) {
  514. name = RSTRING_PTR(key);
  515. } else if (TYPE(key) == T_SYMBOL) {
  516. name = RSTRING_PTR(rb_id2str(SYM2ID(key)));
  517. } else {
  518. rb_raise(rb_eArgError,
  519. "Expected string or symbols as hash keys when initializing proto from hash.");
  520. }
  521. const upb_fielddef* f = upb_msgdef_ntofz(msg_init->msgdef, name);
  522. if (f == NULL) {
  523. rb_raise(rb_eArgError,
  524. "Unknown field name '%s' in initialization map entry.", name);
  525. }
  526. Message_InitFieldFromValue(msg_init->msg, f, val, msg_init->arena);
  527. return ST_CONTINUE;
  528. }
  529. void Message_InitFromValue(upb_msg* msg, const upb_msgdef* m, VALUE val,
  530. upb_arena* arena) {
  531. MsgInit msg_init = {msg, m, arena};
  532. if (TYPE(val) == T_HASH) {
  533. rb_hash_foreach(val, Message_initialize_kwarg, (VALUE)&msg_init);
  534. } else {
  535. rb_raise(rb_eArgError, "Expected hash arguments or message, not %s",
  536. rb_class2name(CLASS_OF(val)));
  537. }
  538. }
  539. /*
  540. * call-seq:
  541. * Message.new(kwargs) => new_message
  542. *
  543. * Creates a new instance of the given message class. Keyword arguments may be
  544. * provided with keywords corresponding to field names.
  545. *
  546. * Note that no literal Message class exists. Only concrete classes per message
  547. * type exist, as provided by the #msgclass method on Descriptors after they
  548. * have been added to a pool. The method definitions described here on the
  549. * Message class are provided on each concrete message class.
  550. */
  551. static VALUE Message_initialize(int argc, VALUE* argv, VALUE _self) {
  552. Message* self = ruby_to_Message(_self);
  553. VALUE arena_rb = Arena_new();
  554. upb_arena *arena = Arena_get(arena_rb);
  555. upb_msg *msg = upb_msg_new(self->msgdef, arena);
  556. Message_InitPtr(_self, msg, arena_rb);
  557. if (argc == 0) {
  558. return Qnil;
  559. }
  560. if (argc != 1) {
  561. rb_raise(rb_eArgError, "Expected 0 or 1 arguments.");
  562. }
  563. Message_InitFromValue((upb_msg*)self->msg, self->msgdef, argv[0], arena);
  564. return Qnil;
  565. }
  566. /*
  567. * call-seq:
  568. * Message.dup => new_message
  569. *
  570. * Performs a shallow copy of this message and returns the new copy.
  571. */
  572. static VALUE Message_dup(VALUE _self) {
  573. Message* self = ruby_to_Message(_self);
  574. VALUE new_msg = rb_class_new_instance(0, NULL, CLASS_OF(_self));
  575. Message* new_msg_self = ruby_to_Message(new_msg);
  576. size_t size = upb_msgdef_layout(self->msgdef)->size;
  577. // TODO(copy unknown fields?)
  578. // TODO(use official upb msg copy function)
  579. memcpy((upb_msg*)new_msg_self->msg, self->msg, size);
  580. Arena_fuse(self->arena, Arena_get(new_msg_self->arena));
  581. return new_msg;
  582. }
  583. // Support function for Message_eq, and also used by other #eq functions.
  584. bool Message_Equal(const upb_msg *m1, const upb_msg *m2, const upb_msgdef *m) {
  585. if (m1 == m2) return true;
  586. size_t size1, size2;
  587. int encode_opts = UPB_ENCODE_SKIPUNKNOWN | UPB_ENCODE_DETERMINISTIC;
  588. upb_arena *arena_tmp = upb_arena_new();
  589. const upb_msglayout *layout = upb_msgdef_layout(m);
  590. // Compare deterministically serialized payloads with no unknown fields.
  591. char *data1 = upb_encode_ex(m1, layout, encode_opts, arena_tmp, &size1);
  592. char *data2 = upb_encode_ex(m2, layout, encode_opts, arena_tmp, &size2);
  593. if (data1 && data2) {
  594. bool ret = (size1 == size2) && (memcmp(data1, data2, size1) == 0);
  595. upb_arena_free(arena_tmp);
  596. return ret;
  597. } else {
  598. upb_arena_free(arena_tmp);
  599. rb_raise(cParseError, "Error comparing messages");
  600. }
  601. }
  602. /*
  603. * call-seq:
  604. * Message.==(other) => boolean
  605. *
  606. * Performs a deep comparison of this message with another. Messages are equal
  607. * if they have the same type and if each field is equal according to the :==
  608. * method's semantics (a more efficient comparison may actually be done if the
  609. * field is of a primitive type).
  610. */
  611. static VALUE Message_eq(VALUE _self, VALUE _other) {
  612. if (CLASS_OF(_self) != CLASS_OF(_other)) return Qfalse;
  613. Message* self = ruby_to_Message(_self);
  614. Message* other = ruby_to_Message(_other);
  615. assert(self->msgdef == other->msgdef);
  616. return Message_Equal(self->msg, other->msg, self->msgdef) ? Qtrue : Qfalse;
  617. }
  618. uint64_t Message_Hash(const upb_msg* msg, const upb_msgdef* m, uint64_t seed) {
  619. upb_arena *arena = upb_arena_new();
  620. const char *data;
  621. size_t size;
  622. // Hash a deterministically serialized payloads with no unknown fields.
  623. data = upb_encode_ex(msg, upb_msgdef_layout(m),
  624. UPB_ENCODE_SKIPUNKNOWN | UPB_ENCODE_DETERMINISTIC, arena,
  625. &size);
  626. if (data) {
  627. uint64_t ret = Wyhash(data, size, seed, kWyhashSalt);
  628. upb_arena_free(arena);
  629. return ret;
  630. } else {
  631. upb_arena_free(arena);
  632. rb_raise(cParseError, "Error calculating hash");
  633. }
  634. }
  635. /*
  636. * call-seq:
  637. * Message.hash => hash_value
  638. *
  639. * Returns a hash value that represents this message's field values.
  640. */
  641. static VALUE Message_hash(VALUE _self) {
  642. Message* self = ruby_to_Message(_self);
  643. uint64_t hash_value = Message_Hash(self->msg, self->msgdef, 0);
  644. // RUBY_FIXNUM_MAX should be one less than a power of 2.
  645. assert((RUBY_FIXNUM_MAX & (RUBY_FIXNUM_MAX + 1)) == 0);
  646. return INT2FIX(hash_value & RUBY_FIXNUM_MAX);
  647. }
  648. /*
  649. * call-seq:
  650. * Message.inspect => string
  651. *
  652. * Returns a human-readable string representing this message. It will be
  653. * formatted as "<MessageType: field1: value1, field2: value2, ...>". Each
  654. * field's value is represented according to its own #inspect method.
  655. */
  656. static VALUE Message_inspect(VALUE _self) {
  657. Message* self = ruby_to_Message(_self);
  658. StringBuilder* builder = StringBuilder_New();
  659. Message_PrintMessage(builder, self->msg, self->msgdef);
  660. VALUE ret = StringBuilder_ToRubyString(builder);
  661. StringBuilder_Free(builder);
  662. return ret;
  663. }
  664. // Support functions for Message_to_h //////////////////////////////////////////
  665. static VALUE RepeatedField_CreateArray(const upb_array* arr,
  666. TypeInfo type_info) {
  667. int size = arr ? upb_array_size(arr) : 0;
  668. VALUE ary = rb_ary_new2(size);
  669. for (int i = 0; i < size; i++) {
  670. upb_msgval msgval = upb_array_get(arr, i);
  671. VALUE val = Scalar_CreateHash(msgval, type_info);
  672. rb_ary_push(ary, val);
  673. }
  674. return ary;
  675. }
  676. static VALUE Message_CreateHash(const upb_msg *msg, const upb_msgdef *m) {
  677. if (!msg) return Qnil;
  678. VALUE hash = rb_hash_new();
  679. int n = upb_msgdef_fieldcount(m);
  680. bool is_proto2;
  681. // We currently have a few behaviors that are specific to proto2.
  682. // This is unfortunate, we should key behaviors off field attributes (like
  683. // whether a field has presence), not proto2 vs. proto3. We should see if we
  684. // can change this without breaking users.
  685. is_proto2 = upb_msgdef_syntax(m) == UPB_SYNTAX_PROTO2;
  686. for (int i = 0; i < n; i++) {
  687. const upb_fielddef* field = upb_msgdef_field(m, i);
  688. TypeInfo type_info = TypeInfo_get(field);
  689. upb_msgval msgval;
  690. VALUE msg_value;
  691. VALUE msg_key;
  692. if (!is_proto2 && upb_fielddef_issubmsg(field) &&
  693. !upb_fielddef_isseq(field) && !upb_msg_has(msg, field)) {
  694. // TODO: Legacy behavior, remove when we fix the is_proto2 differences.
  695. msg_key = ID2SYM(rb_intern(upb_fielddef_name(field)));
  696. rb_hash_aset(hash, msg_key, Qnil);
  697. continue;
  698. }
  699. // Do not include fields that are not present (oneof or optional fields).
  700. if (is_proto2 && upb_fielddef_haspresence(field) &&
  701. !upb_msg_has(msg, field)) {
  702. continue;
  703. }
  704. msg_key = ID2SYM(rb_intern(upb_fielddef_name(field)));
  705. msgval = upb_msg_get(msg, field);
  706. // Proto2 omits empty map/repeated filds also.
  707. if (upb_fielddef_ismap(field)) {
  708. const upb_msgdef *entry_m = upb_fielddef_msgsubdef(field);
  709. const upb_fielddef *key_f = upb_msgdef_itof(entry_m, 1);
  710. const upb_fielddef *val_f = upb_msgdef_itof(entry_m, 2);
  711. upb_fieldtype_t key_type = upb_fielddef_type(key_f);
  712. msg_value = Map_CreateHash(msgval.map_val, key_type, TypeInfo_get(val_f));
  713. } else if (upb_fielddef_isseq(field)) {
  714. if (is_proto2 &&
  715. (!msgval.array_val || upb_array_size(msgval.array_val) == 0)) {
  716. continue;
  717. }
  718. msg_value = RepeatedField_CreateArray(msgval.array_val, type_info);
  719. } else {
  720. msg_value = Scalar_CreateHash(msgval, type_info);
  721. }
  722. rb_hash_aset(hash, msg_key, msg_value);
  723. }
  724. return hash;
  725. }
  726. VALUE Scalar_CreateHash(upb_msgval msgval, TypeInfo type_info) {
  727. if (type_info.type == UPB_TYPE_MESSAGE) {
  728. return Message_CreateHash(msgval.msg_val, type_info.def.msgdef);
  729. } else {
  730. return Convert_UpbToRuby(msgval, type_info, Qnil);
  731. }
  732. }
  733. /*
  734. * call-seq:
  735. * Message.to_h => {}
  736. *
  737. * Returns the message as a Ruby Hash object, with keys as symbols.
  738. */
  739. static VALUE Message_to_h(VALUE _self) {
  740. Message* self = ruby_to_Message(_self);
  741. return Message_CreateHash(self->msg, self->msgdef);
  742. }
  743. /*
  744. * call-seq:
  745. * Message.freeze => self
  746. *
  747. * Freezes the message object. We have to intercept this so we can pin the
  748. * Ruby object into memory so we don't forget it's frozen.
  749. */
  750. static VALUE Message_freeze(VALUE _self) {
  751. Message* self = ruby_to_Message(_self);
  752. if (!RB_OBJ_FROZEN(_self)) {
  753. Arena_Pin(self->arena, _self);
  754. RB_OBJ_FREEZE(_self);
  755. }
  756. return _self;
  757. }
  758. /*
  759. * call-seq:
  760. * Message.[](index) => value
  761. *
  762. * Accesses a field's value by field name. The provided field name should be a
  763. * string.
  764. */
  765. static VALUE Message_index(VALUE _self, VALUE field_name) {
  766. Message* self = ruby_to_Message(_self);
  767. const upb_fielddef* field;
  768. Check_Type(field_name, T_STRING);
  769. field = upb_msgdef_ntofz(self->msgdef, RSTRING_PTR(field_name));
  770. if (field == NULL) {
  771. return Qnil;
  772. }
  773. return Message_getfield(_self, field);
  774. }
  775. /*
  776. * call-seq:
  777. * Message.[]=(index, value)
  778. *
  779. * Sets a field's value by field name. The provided field name should be a
  780. * string.
  781. */
  782. static VALUE Message_index_set(VALUE _self, VALUE field_name, VALUE value) {
  783. Message* self = ruby_to_Message(_self);
  784. const upb_fielddef* f;
  785. upb_msgval val;
  786. upb_arena *arena = Arena_get(self->arena);
  787. Check_Type(field_name, T_STRING);
  788. f = upb_msgdef_ntofz(self->msgdef, RSTRING_PTR(field_name));
  789. if (f == NULL) {
  790. rb_raise(rb_eArgError, "Unknown field: %s", RSTRING_PTR(field_name));
  791. }
  792. val = Convert_RubyToUpb(value, upb_fielddef_name(f), TypeInfo_get(f), arena);
  793. upb_msg_set(Message_GetMutable(_self, NULL), f, val, arena);
  794. return Qnil;
  795. }
  796. /*
  797. * call-seq:
  798. * MessageClass.decode(data) => message
  799. *
  800. * Decodes the given data (as a string containing bytes in protocol buffers wire
  801. * format) under the interpretration given by this message class's definition
  802. * and returns a message object with the corresponding field values.
  803. */
  804. static VALUE Message_decode(VALUE klass, VALUE data) {
  805. if (TYPE(data) != T_STRING) {
  806. rb_raise(rb_eArgError, "Expected string for binary protobuf data.");
  807. }
  808. VALUE msg_rb = initialize_rb_class_with_no_args(klass);
  809. Message* msg = ruby_to_Message(msg_rb);
  810. if (!upb_decode(RSTRING_PTR(data), RSTRING_LEN(data), (upb_msg*)msg->msg,
  811. upb_msgdef_layout(msg->msgdef),
  812. Arena_get(msg->arena))) {
  813. rb_raise(cParseError, "Error occurred during parsing");
  814. }
  815. return msg_rb;
  816. }
  817. /*
  818. * call-seq:
  819. * MessageClass.decode_json(data, options = {}) => message
  820. *
  821. * Decodes the given data (as a string containing bytes in protocol buffers wire
  822. * format) under the interpretration given by this message class's definition
  823. * and returns a message object with the corresponding field values.
  824. *
  825. * @param options [Hash] options for the decoder
  826. * ignore_unknown_fields: set true to ignore unknown fields (default is to
  827. * raise an error)
  828. */
  829. static VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) {
  830. VALUE data = argv[0];
  831. int options = 0;
  832. upb_status status;
  833. // TODO(haberman): use this message's pool instead.
  834. const upb_symtab *symtab = DescriptorPool_GetSymtab(generated_pool);
  835. if (argc < 1 || argc > 2) {
  836. rb_raise(rb_eArgError, "Expected 1 or 2 arguments.");
  837. }
  838. if (argc == 2) {
  839. VALUE hash_args = argv[1];
  840. if (TYPE(hash_args) != T_HASH) {
  841. rb_raise(rb_eArgError, "Expected hash arguments.");
  842. }
  843. if (RTEST(rb_hash_lookup2( hash_args, ID2SYM(rb_intern("ignore_unknown_fields")), Qfalse))) {
  844. options |= UPB_JSONDEC_IGNOREUNKNOWN;
  845. }
  846. }
  847. if (TYPE(data) != T_STRING) {
  848. rb_raise(rb_eArgError, "Expected string for JSON data.");
  849. }
  850. // TODO(cfallin): Check and respect string encoding. If not UTF-8, we need to
  851. // convert, because string handlers pass data directly to message string
  852. // fields.
  853. VALUE msg_rb = initialize_rb_class_with_no_args(klass);
  854. Message* msg = ruby_to_Message(msg_rb);
  855. // We don't allow users to decode a wrapper type directly.
  856. if (upb_msgdef_iswrapper(msg->msgdef)) {
  857. rb_raise(rb_eRuntimeError, "Cannot parse a wrapper directly.");
  858. }
  859. upb_status_clear(&status);
  860. if (!upb_json_decode(RSTRING_PTR(data), RSTRING_LEN(data), (upb_msg*)msg->msg,
  861. msg->msgdef, symtab, options,
  862. Arena_get(msg->arena), &status)) {
  863. rb_raise(cParseError, "Error occurred during parsing: %s",
  864. upb_status_errmsg(&status));
  865. }
  866. return msg_rb;
  867. }
  868. /*
  869. * call-seq:
  870. * MessageClass.encode(msg) => bytes
  871. *
  872. * Encodes the given message object to its serialized form in protocol buffers
  873. * wire format.
  874. */
  875. static VALUE Message_encode(VALUE klass, VALUE msg_rb) {
  876. Message* msg = ruby_to_Message(msg_rb);
  877. const char *data;
  878. size_t size;
  879. if (CLASS_OF(msg_rb) != klass) {
  880. rb_raise(rb_eArgError, "Message of wrong type.");
  881. }
  882. upb_arena *arena = upb_arena_new();
  883. data = upb_encode(msg->msg, upb_msgdef_layout(msg->msgdef), arena,
  884. &size);
  885. if (data) {
  886. VALUE ret = rb_str_new(data, size);
  887. rb_enc_associate(ret, rb_ascii8bit_encoding());
  888. upb_arena_free(arena);
  889. return ret;
  890. } else {
  891. upb_arena_free(arena);
  892. rb_raise(rb_eRuntimeError, "Exceeded maximum depth (possibly cycle)");
  893. }
  894. }
  895. /*
  896. * call-seq:
  897. * MessageClass.encode_json(msg, options = {}) => json_string
  898. *
  899. * Encodes the given message object into its serialized JSON representation.
  900. * @param options [Hash] options for the decoder
  901. * preserve_proto_fieldnames: set true to use original fieldnames (default is to camelCase)
  902. * emit_defaults: set true to emit 0/false values (default is to omit them)
  903. */
  904. static VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
  905. Message* msg = ruby_to_Message(argv[0]);
  906. int options = 0;
  907. char buf[1024];
  908. size_t size;
  909. upb_status status;
  910. // TODO(haberman): use this message's pool instead.
  911. const upb_symtab *symtab = DescriptorPool_GetSymtab(generated_pool);
  912. if (argc < 1 || argc > 2) {
  913. rb_raise(rb_eArgError, "Expected 1 or 2 arguments.");
  914. }
  915. if (argc == 2) {
  916. VALUE hash_args = argv[1];
  917. if (TYPE(hash_args) != T_HASH) {
  918. rb_raise(rb_eArgError, "Expected hash arguments.");
  919. }
  920. if (RTEST(rb_hash_lookup2(hash_args,
  921. ID2SYM(rb_intern("preserve_proto_fieldnames")),
  922. Qfalse))) {
  923. options |= UPB_JSONENC_PROTONAMES;
  924. }
  925. if (RTEST(rb_hash_lookup2(hash_args, ID2SYM(rb_intern("emit_defaults")),
  926. Qfalse))) {
  927. options |= UPB_JSONENC_EMITDEFAULTS;
  928. }
  929. }
  930. upb_status_clear(&status);
  931. size = upb_json_encode(msg->msg, msg->msgdef, symtab, options, buf,
  932. sizeof(buf), &status);
  933. if (!upb_ok(&status)) {
  934. rb_raise(cParseError, "Error occurred during encoding: %s",
  935. upb_status_errmsg(&status));
  936. }
  937. VALUE ret;
  938. if (size >= sizeof(buf)) {
  939. char* buf2 = malloc(size + 1);
  940. upb_json_encode(msg->msg, msg->msgdef, symtab, options, buf2, size + 1,
  941. &status);
  942. ret = rb_str_new(buf2, size);
  943. free(buf2);
  944. } else {
  945. ret = rb_str_new(buf, size);
  946. }
  947. rb_enc_associate(ret, rb_utf8_encoding());
  948. return ret;
  949. }
  950. /*
  951. * call-seq:
  952. * Message.descriptor => descriptor
  953. *
  954. * Class method that returns the Descriptor instance corresponding to this
  955. * message class's type.
  956. */
  957. static VALUE Message_descriptor(VALUE klass) {
  958. return rb_ivar_get(klass, descriptor_instancevar_interned);
  959. }
  960. VALUE build_class_from_descriptor(VALUE descriptor) {
  961. const char *name;
  962. VALUE klass;
  963. name = upb_msgdef_fullname(Descriptor_GetMsgDef(descriptor));
  964. if (name == NULL) {
  965. rb_raise(rb_eRuntimeError, "Descriptor does not have assigned name.");
  966. }
  967. klass = rb_define_class_id(
  968. // Docs say this parameter is ignored. User will assign return value to
  969. // their own toplevel constant class name.
  970. rb_intern("Message"),
  971. rb_cObject);
  972. rb_ivar_set(klass, descriptor_instancevar_interned, descriptor);
  973. rb_define_alloc_func(klass, Message_alloc);
  974. rb_require("google/protobuf/message_exts");
  975. rb_include_module(klass, rb_eval_string("::Google::Protobuf::MessageExts"));
  976. rb_extend_object(
  977. klass, rb_eval_string("::Google::Protobuf::MessageExts::ClassMethods"));
  978. rb_define_method(klass, "method_missing",
  979. Message_method_missing, -1);
  980. rb_define_method(klass, "respond_to_missing?",
  981. Message_respond_to_missing, -1);
  982. rb_define_method(klass, "initialize", Message_initialize, -1);
  983. rb_define_method(klass, "dup", Message_dup, 0);
  984. // Also define #clone so that we don't inherit Object#clone.
  985. rb_define_method(klass, "clone", Message_dup, 0);
  986. rb_define_method(klass, "==", Message_eq, 1);
  987. rb_define_method(klass, "eql?", Message_eq, 1);
  988. rb_define_method(klass, "freeze", Message_freeze, 0);
  989. rb_define_method(klass, "hash", Message_hash, 0);
  990. rb_define_method(klass, "to_h", Message_to_h, 0);
  991. rb_define_method(klass, "inspect", Message_inspect, 0);
  992. rb_define_method(klass, "to_s", Message_inspect, 0);
  993. rb_define_method(klass, "[]", Message_index, 1);
  994. rb_define_method(klass, "[]=", Message_index_set, 2);
  995. rb_define_singleton_method(klass, "decode", Message_decode, 1);
  996. rb_define_singleton_method(klass, "encode", Message_encode, 1);
  997. rb_define_singleton_method(klass, "decode_json", Message_decode_json, -1);
  998. rb_define_singleton_method(klass, "encode_json", Message_encode_json, -1);
  999. rb_define_singleton_method(klass, "descriptor", Message_descriptor, 0);
  1000. return klass;
  1001. }
  1002. /*
  1003. * call-seq:
  1004. * Enum.lookup(number) => name
  1005. *
  1006. * This module method, provided on each generated enum module, looks up an enum
  1007. * value by number and returns its name as a Ruby symbol, or nil if not found.
  1008. */
  1009. static VALUE enum_lookup(VALUE self, VALUE number) {
  1010. int32_t num = NUM2INT(number);
  1011. VALUE desc = rb_ivar_get(self, descriptor_instancevar_interned);
  1012. const upb_enumdef *e = EnumDescriptor_GetEnumDef(desc);
  1013. const char* name = upb_enumdef_iton(e, num);
  1014. if (name == NULL) {
  1015. return Qnil;
  1016. } else {
  1017. return ID2SYM(rb_intern(name));
  1018. }
  1019. }
  1020. /*
  1021. * call-seq:
  1022. * Enum.resolve(name) => number
  1023. *
  1024. * This module method, provided on each generated enum module, looks up an enum
  1025. * value by name (as a Ruby symbol) and returns its name, or nil if not found.
  1026. */
  1027. static VALUE enum_resolve(VALUE self, VALUE sym) {
  1028. const char* name = rb_id2name(SYM2ID(sym));
  1029. VALUE desc = rb_ivar_get(self, descriptor_instancevar_interned);
  1030. const upb_enumdef *e = EnumDescriptor_GetEnumDef(desc);
  1031. int32_t num = 0;
  1032. bool found = upb_enumdef_ntoiz(e, name, &num);
  1033. if (!found) {
  1034. return Qnil;
  1035. } else {
  1036. return INT2NUM(num);
  1037. }
  1038. }
  1039. /*
  1040. * call-seq:
  1041. * Enum.descriptor
  1042. *
  1043. * This module method, provided on each generated enum module, returns the
  1044. * EnumDescriptor corresponding to this enum type.
  1045. */
  1046. static VALUE enum_descriptor(VALUE self) {
  1047. return rb_ivar_get(self, descriptor_instancevar_interned);
  1048. }
  1049. VALUE build_module_from_enumdesc(VALUE _enumdesc) {
  1050. const upb_enumdef *e = EnumDescriptor_GetEnumDef(_enumdesc);
  1051. VALUE mod = rb_define_module_id(rb_intern(upb_enumdef_fullname(e)));
  1052. upb_enum_iter it;
  1053. for (upb_enum_begin(&it, e);
  1054. !upb_enum_done(&it);
  1055. upb_enum_next(&it)) {
  1056. const char* name = upb_enum_iter_name(&it);
  1057. int32_t value = upb_enum_iter_number(&it);
  1058. if (name[0] < 'A' || name[0] > 'Z') {
  1059. rb_warn("Enum value '%s' does not start with an uppercase letter "
  1060. "as is required for Ruby constants.",
  1061. name);
  1062. }
  1063. rb_define_const(mod, name, INT2NUM(value));
  1064. }
  1065. rb_define_singleton_method(mod, "lookup", enum_lookup, 1);
  1066. rb_define_singleton_method(mod, "resolve", enum_resolve, 1);
  1067. rb_define_singleton_method(mod, "descriptor", enum_descriptor, 0);
  1068. rb_ivar_set(mod, descriptor_instancevar_interned, _enumdesc);
  1069. return mod;
  1070. }
  1071. // Internal only; used by Google::Protobuf.deep_copy.
  1072. upb_msg* Message_deep_copy(const upb_msg* msg, const upb_msgdef* m,
  1073. upb_arena *arena) {
  1074. // Serialize and parse.
  1075. upb_arena *tmp_arena = upb_arena_new();
  1076. const upb_msglayout *layout = upb_msgdef_layout(m);
  1077. size_t size;
  1078. char* data = upb_encode_ex(msg, layout, 0, tmp_arena, &size);
  1079. upb_msg* new_msg = upb_msg_new(m, arena);
  1080. if (!data || !upb_decode(data, size, new_msg, layout, arena)) {
  1081. upb_arena_free(tmp_arena);
  1082. rb_raise(cParseError, "Error occurred copying proto");
  1083. }
  1084. upb_arena_free(tmp_arena);
  1085. return new_msg;
  1086. }
  1087. const upb_msg* Message_GetUpbMessage(VALUE value, const upb_msgdef* m,
  1088. const char* name, upb_arena* arena) {
  1089. if (value == Qnil) {
  1090. rb_raise(cTypeError, "nil message not allowed here.");
  1091. }
  1092. VALUE klass = CLASS_OF(value);
  1093. VALUE desc_rb = rb_ivar_get(klass, descriptor_instancevar_interned);
  1094. const upb_msgdef* val_m =
  1095. desc_rb == Qnil ? NULL : Descriptor_GetMsgDef(desc_rb);
  1096. if (val_m != m) {
  1097. // Check for possible implicit conversions
  1098. // TODO: hash conversion?
  1099. switch (upb_msgdef_wellknowntype(m)) {
  1100. case UPB_WELLKNOWN_TIMESTAMP: {
  1101. // Time -> Google::Protobuf::Timestamp
  1102. upb_msg *msg = upb_msg_new(m, arena);
  1103. upb_msgval sec, nsec;
  1104. struct timespec time;
  1105. const upb_fielddef *sec_f = upb_msgdef_itof(m, 1);
  1106. const upb_fielddef *nsec_f = upb_msgdef_itof(m, 2);
  1107. if (!rb_obj_is_kind_of(value, rb_cTime)) goto badtype;
  1108. time = rb_time_timespec(value);
  1109. sec.int64_val = time.tv_sec;
  1110. nsec.int32_val = time.tv_nsec;
  1111. upb_msg_set(msg, sec_f, sec, arena);
  1112. upb_msg_set(msg, nsec_f, nsec, arena);
  1113. return msg;
  1114. }
  1115. case UPB_WELLKNOWN_DURATION: {
  1116. // Numeric -> Google::Protobuf::Duration
  1117. upb_msg *msg = upb_msg_new(m, arena);
  1118. upb_msgval sec, nsec;
  1119. const upb_fielddef *sec_f = upb_msgdef_itof(m, 1);
  1120. const upb_fielddef *nsec_f = upb_msgdef_itof(m, 2);
  1121. if (!rb_obj_is_kind_of(value, rb_cNumeric)) goto badtype;
  1122. sec.int64_val = NUM2LL(value);
  1123. nsec.int32_val = round((NUM2DBL(value) - NUM2LL(value)) * 1000000000);
  1124. upb_msg_set(msg, sec_f, sec, arena);
  1125. upb_msg_set(msg, nsec_f, nsec, arena);
  1126. return msg;
  1127. }
  1128. default:
  1129. badtype:
  1130. rb_raise(cTypeError,
  1131. "Invalid type %s to assign to submessage field '%s'.",
  1132. rb_class2name(CLASS_OF(value)), name);
  1133. }
  1134. }
  1135. Message* self = ruby_to_Message(value);
  1136. Arena_fuse(self->arena, arena);
  1137. return self->msg;
  1138. }
  1139. void Message_register(VALUE protobuf) {
  1140. cParseError = rb_const_get(protobuf, rb_intern("ParseError"));
  1141. // Ruby-interned string: "descriptor". We use this identifier to store an
  1142. // instance variable on message classes we create in order to link them back
  1143. // to their descriptors.
  1144. descriptor_instancevar_interned = rb_intern("descriptor");
  1145. }