message.c 42 KB

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