message.c 42 KB

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