ruby/ext/google/protobuf_c/message.c
Go to the documentation of this file.
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 
31 #include "protobuf.h"
32 
33 // -----------------------------------------------------------------------------
34 // Class/module creation from msgdefs and enumdefs, respectively.
35 // -----------------------------------------------------------------------------
36 
37 void* Message_data(void* msg) {
38  return ((uint8_t *)msg) + sizeof(MessageHeader);
39 }
40 
41 void Message_mark(void* _self) {
42  MessageHeader* self = (MessageHeader *)_self;
43  layout_mark(self->descriptor->layout, Message_data(self));
44 }
45 
46 void Message_free(void* self) {
47  stringsink* unknown = ((MessageHeader *)self)->unknown_fields;
48  if (unknown != NULL) {
49  stringsink_uninit(unknown);
50  free(unknown);
51  }
52  xfree(self);
53 }
54 
55 rb_data_type_t Message_type = {
56  "Message",
58 };
59 
60 VALUE Message_alloc(VALUE klass) {
61  VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
64  uint8_t, sizeof(MessageHeader) + desc->layout->size);
65  VALUE ret;
66 
67  memset(Message_data(msg), 0, desc->layout->size);
68 
69  // We wrap first so that everything in the message object is GC-rooted in case
70  // a collection happens during object creation in layout_init().
71  ret = TypedData_Wrap_Struct(klass, &Message_type, msg);
72  msg->descriptor = desc;
74 
75  msg->unknown_fields = NULL;
76 
77  layout_init(desc->layout, Message_data(msg));
78 
79  return ret;
80 }
81 
82 static const upb_fielddef* which_oneof_field(MessageHeader* self, const upb_oneofdef* o) {
84  size_t case_ofs;
85  uint32_t oneof_case;
86  const upb_fielddef* first_field;
87  const upb_fielddef* f;
88 
89  // If no fields in the oneof, always nil.
90  if (upb_oneofdef_numfields(o) == 0) {
91  return NULL;
92  }
93  // Grab the first field in the oneof so we can get its layout info to find the
94  // oneof_case field.
95  upb_oneof_begin(&it, o);
96  assert(!upb_oneof_done(&it));
97  first_field = upb_oneof_iter_field(&it);
98  assert(upb_fielddef_containingoneof(first_field) != NULL);
99 
100  case_ofs =
101  self->descriptor->layout->
102  fields[upb_fielddef_index(first_field)].case_offset;
103  oneof_case = *((uint32_t*)((char*)Message_data(self) + case_ofs));
104 
105  if (oneof_case == ONEOF_CASE_NONE) {
106  return NULL;
107  }
108 
109  // oneof_case is a field index, so find that field.
110  f = upb_oneofdef_itof(o, oneof_case);
111  assert(f != NULL);
112 
113  return f;
114 }
115 
116 enum {
125 };
126 
127 // Check if the field is a well known wrapper type
129  char* field_type_name = rb_class2name(field_type_class(field));
130 
131  return strcmp(field_type_name, "Google::Protobuf::DoubleValue") == 0 ||
132  strcmp(field_type_name, "Google::Protobuf::FloatValue") == 0 ||
133  strcmp(field_type_name, "Google::Protobuf::Int32Value") == 0 ||
134  strcmp(field_type_name, "Google::Protobuf::Int64Value") == 0 ||
135  strcmp(field_type_name, "Google::Protobuf::UInt32Value") == 0 ||
136  strcmp(field_type_name, "Google::Protobuf::UInt64Value") == 0 ||
137  strcmp(field_type_name, "Google::Protobuf::BoolValue") == 0 ||
138  strcmp(field_type_name, "Google::Protobuf::StringValue") == 0 ||
139  strcmp(field_type_name, "Google::Protobuf::BytesValue") == 0;
140 }
141 
142 // Get a new Ruby wrapper type and set the initial value
143 static VALUE ruby_wrapper_type(const upb_fielddef* field, const VALUE* value) {
144  if (is_wrapper_type_field(field) && value != Qnil) {
145  VALUE hash = rb_hash_new();
146  rb_hash_aset(hash, rb_str_new2("value"), value);
147  VALUE args[1] = { hash };
148  return rb_class_new_instance(1, args, field_type_class(field));
149  }
150  return Qnil;
151 }
152 
153 static int extract_method_call(VALUE method_name, MessageHeader* self,
154  const upb_fielddef **f, const upb_oneofdef **o) {
155  Check_Type(method_name, T_SYMBOL);
156 
157  VALUE method_str = rb_id2str(SYM2ID(method_name));
158  char* name = RSTRING_PTR(method_str);
159  size_t name_len = RSTRING_LEN(method_str);
160  int accessor_type;
161  const upb_oneofdef* test_o;
162  const upb_fielddef* test_f;
163 
164  if (name[name_len - 1] == '=') {
165  accessor_type = METHOD_SETTER;
166  name_len--;
167  // We want to ensure if the proto has something named clear_foo or has_foo?,
168  // we don't strip the prefix.
169  } else if (strncmp("clear_", name, 6) == 0 &&
170  !upb_msgdef_lookupname(self->descriptor->msgdef, name, name_len,
171  &test_f, &test_o)) {
172  accessor_type = METHOD_CLEAR;
173  name = name + 6;
174  name_len = name_len - 6;
175  } else if (strncmp("has_", name, 4) == 0 && name[name_len - 1] == '?' &&
176  !upb_msgdef_lookupname(self->descriptor->msgdef, name, name_len,
177  &test_f, &test_o)) {
178  accessor_type = METHOD_PRESENCE;
179  name = name + 4;
180  name_len = name_len - 5;
181  } else {
182  accessor_type = METHOD_GETTER;
183  }
184 
185  bool has_field = upb_msgdef_lookupname(self->descriptor->msgdef, name, name_len,
186  &test_f, &test_o);
187 
188  // Look for wrapper type accessor of the form <field_name>_as_value
189  if (!has_field &&
190  (accessor_type == METHOD_GETTER || accessor_type == METHOD_SETTER) &&
191  name_len > 9 && strncmp(name + name_len - 9, "_as_value", 9) == 0) {
192  // Find the field name
193  char wrapper_field_name[name_len - 8];
194  strncpy(wrapper_field_name, name, name_len - 9);
195  wrapper_field_name[name_len - 7] = '\0';
196 
197  // Check if field exists and is a wrapper type
198  const upb_oneofdef* test_o_wrapper;
199  const upb_fielddef* test_f_wrapper;
200  if (upb_msgdef_lookupname(self->descriptor->msgdef, wrapper_field_name, name_len - 9,
201  &test_f_wrapper, &test_o_wrapper) &&
202  upb_fielddef_type(test_f_wrapper) == UPB_TYPE_MESSAGE &&
203  is_wrapper_type_field(test_f_wrapper)) {
204  // It does exist!
205  has_field = true;
206  if (accessor_type == METHOD_SETTER) {
207  accessor_type = METHOD_WRAPPER_SETTER;
208  } else {
209  accessor_type = METHOD_WRAPPER_GETTER;
210  }
211  test_o = test_o_wrapper;
212  test_f = test_f_wrapper;
213  }
214  }
215 
216  // Look for enum accessor of the form <enum_name>_const
217  if (!has_field && accessor_type == METHOD_GETTER &&
218  name_len > 6 && strncmp(name + name_len - 6, "_const", 6) == 0) {
219 
220  // Find enum field name
221  char enum_name[name_len - 5];
222  strncpy(enum_name, name, name_len - 6);
223  enum_name[name_len - 4] = '\0';
224 
225  // Check if enum field exists
226  const upb_oneofdef* test_o_enum;
227  const upb_fielddef* test_f_enum;
228  if (upb_msgdef_lookupname(self->descriptor->msgdef, enum_name, name_len - 6,
229  &test_f_enum, &test_o_enum) &&
230  upb_fielddef_type(test_f_enum) == UPB_TYPE_ENUM) {
231  // It does exist!
232  has_field = true;
233  accessor_type = METHOD_ENUM_GETTER;
234  test_o = test_o_enum;
235  test_f = test_f_enum;
236  }
237  }
238 
239  // Verify the name corresponds to a oneof or field in this message.
240  if (!has_field) {
241  return METHOD_UNKNOWN;
242  }
243 
244  // Method calls like 'has_foo?' are not allowed if field "foo" does not have
245  // a hasbit (e.g. repeated fields or non-message type fields for proto3
246  // syntax).
247  if (accessor_type == METHOD_PRESENCE && test_f != NULL &&
248  !upb_fielddef_haspresence(test_f)) {
249  return METHOD_UNKNOWN;
250  }
251 
252  *o = test_o;
253  *f = test_f;
254  return accessor_type;
255 }
256 
257 /*
258  * call-seq:
259  * Message.method_missing(*args)
260  *
261  * Provides accessors and setters and methods to clear and check for presence of
262  * message fields according to their field names.
263  *
264  * For any field whose name does not conflict with a built-in method, an
265  * accessor is provided with the same name as the field, and a setter is
266  * provided with the name of the field plus the '=' suffix. Thus, given a
267  * message instance 'msg' with field 'foo', the following code is valid:
268  *
269  * msg.foo = 42
270  * puts msg.foo
271  *
272  * This method also provides read-only accessors for oneofs. If a oneof exists
273  * with name 'my_oneof', then msg.my_oneof will return a Ruby symbol equal to
274  * the name of the field in that oneof that is currently set, or nil if none.
275  *
276  * It also provides methods of the form 'clear_fieldname' to clear the value
277  * of the field 'fieldname'. For basic data types, this will set the default
278  * value of the field.
279  *
280  * Additionally, it provides methods of the form 'has_fieldname?', which returns
281  * true if the field 'fieldname' is set in the message object, else false. For
282  * 'proto3' syntax, calling this for a basic type field will result in an error.
283  */
284 VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) {
285  MessageHeader* self;
286  const upb_oneofdef* o;
287  const upb_fielddef* f;
288 
289  TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
290  if (argc < 1) {
291  rb_raise(rb_eArgError, "Expected method name as first argument.");
292  }
293 
294  int accessor_type = extract_method_call(argv[0], self, &f, &o);
295  if (accessor_type == METHOD_UNKNOWN || (o == NULL && f == NULL) ) {
296  return rb_call_super(argc, argv);
297  } else if (accessor_type == METHOD_SETTER || accessor_type == METHOD_WRAPPER_SETTER) {
298  if (argc != 2) {
299  rb_raise(rb_eArgError, "Expected 2 arguments, received %d", argc);
300  }
301  rb_check_frozen(_self);
302  } else if (argc != 1) {
303  rb_raise(rb_eArgError, "Expected 1 argument, received %d", argc);
304  }
305 
306  // Return which of the oneof fields are set
307  if (o != NULL) {
308  if (accessor_type == METHOD_SETTER) {
309  rb_raise(rb_eRuntimeError, "Oneof accessors are read-only.");
310  }
311 
312  const upb_fielddef* oneof_field = which_oneof_field(self, o);
313  if (accessor_type == METHOD_PRESENCE) {
314  return oneof_field == NULL ? Qfalse : Qtrue;
315  } else if (accessor_type == METHOD_CLEAR) {
316  if (oneof_field != NULL) {
317  layout_clear(self->descriptor->layout, Message_data(self), oneof_field);
318  }
319  return Qnil;
320  } else {
321  // METHOD_ACCESSOR
322  return oneof_field == NULL ? Qnil :
323  ID2SYM(rb_intern(upb_fielddef_name(oneof_field)));
324  }
325  // Otherwise we're operating on a single proto field
326  } else if (accessor_type == METHOD_SETTER) {
327  layout_set(self->descriptor->layout, Message_data(self), f, argv[1]);
328  return Qnil;
329  } else if (accessor_type == METHOD_CLEAR) {
330  layout_clear(self->descriptor->layout, Message_data(self), f);
331  return Qnil;
332  } else if (accessor_type == METHOD_PRESENCE) {
333  return layout_has(self->descriptor->layout, Message_data(self), f);
334  } else if (accessor_type == METHOD_WRAPPER_GETTER) {
335  VALUE value = layout_get(self->descriptor->layout, Message_data(self), f);
336  if (value != Qnil) {
337  value = rb_funcall(value, rb_intern("value"), 0);
338  }
339  return value;
340  } else if (accessor_type == METHOD_WRAPPER_SETTER) {
341  VALUE wrapper = ruby_wrapper_type(f, argv[1]);
342  layout_set(self->descriptor->layout, Message_data(self), f, wrapper);
343  return Qnil;
344  } else if (accessor_type == METHOD_ENUM_GETTER) {
345  VALUE enum_type = field_type_class(f);
346  VALUE method = rb_intern("const_get");
347  VALUE raw_value = layout_get(self->descriptor->layout, Message_data(self), f);
348 
349  // Map repeated fields to a new type with ints
351  int array_size = FIX2INT(rb_funcall(raw_value, rb_intern("length"), 0));
352  VALUE array_args[1] = { ID2SYM(rb_intern("int64")) };
353  VALUE array = rb_class_new_instance(1, array_args, CLASS_OF(raw_value));
354  for (int i = 0; i < array_size; i++) {
355  VALUE entry = rb_funcall(enum_type, method, 1, rb_funcall(raw_value,
356  rb_intern("at"), 1, INT2NUM(i)));
357  rb_funcall(array, rb_intern("push"), 1, entry);
358  }
359  return array;
360  }
361  // Convert the value for singular fields
362  return rb_funcall(enum_type, method, 1, raw_value);
363  } else {
364  return layout_get(self->descriptor->layout, Message_data(self), f);
365  }
366 }
367 
368 
369 VALUE Message_respond_to_missing(int argc, VALUE* argv, VALUE _self) {
370  MessageHeader* self;
371  const upb_oneofdef* o;
372  const upb_fielddef* f;
373 
374  TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
375  if (argc < 1) {
376  rb_raise(rb_eArgError, "Expected method name as first argument.");
377  }
378 
379  int accessor_type = extract_method_call(argv[0], self, &f, &o);
380  if (accessor_type == METHOD_UNKNOWN) {
381  return rb_call_super(argc, argv);
382  } else if (o != NULL) {
383  return accessor_type == METHOD_SETTER ? Qfalse : Qtrue;
384  } else {
385  return Qtrue;
386  }
387 }
388 
389 VALUE create_submsg_from_hash(const upb_fielddef *f, VALUE hash) {
390  const upb_def *d = upb_fielddef_subdef(f);
391  assert(d != NULL);
392 
393  VALUE descriptor = get_def_obj(d);
394  VALUE msgclass = rb_funcall(descriptor, rb_intern("msgclass"), 0, NULL);
395 
396  VALUE args[1] = { hash };
397  return rb_class_new_instance(1, args, msgclass);
398 }
399 
400 int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) {
401  MessageHeader* self;
402  char *name;
403  const upb_fielddef* f;
404  TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
405 
406  if (TYPE(key) == T_STRING) {
407  name = RSTRING_PTR(key);
408  } else if (TYPE(key) == T_SYMBOL) {
409  name = RSTRING_PTR(rb_id2str(SYM2ID(key)));
410  } else {
411  rb_raise(rb_eArgError,
412  "Expected string or symbols as hash keys when initializing proto from hash.");
413  }
414 
415  f = upb_msgdef_ntofz(self->descriptor->msgdef, name);
416  if (f == NULL) {
417  rb_raise(rb_eArgError,
418  "Unknown field name '%s' in initialization map entry.", name);
419  }
420 
421  if (TYPE(val) == T_NIL) {
422  return 0;
423  }
424 
425  if (is_map_field(f)) {
426  VALUE map;
427 
428  if (TYPE(val) != T_HASH) {
429  rb_raise(rb_eArgError,
430  "Expected Hash object as initializer value for map field '%s' (given %s).",
431  name, rb_class2name(CLASS_OF(val)));
432  }
433  map = layout_get(self->descriptor->layout, Message_data(self), f);
435  } else if (upb_fielddef_label(f) == UPB_LABEL_REPEATED) {
436  VALUE ary;
437 
438  if (TYPE(val) != T_ARRAY) {
439  rb_raise(rb_eArgError,
440  "Expected array as initializer value for repeated field '%s' (given %s).",
441  name, rb_class2name(CLASS_OF(val)));
442  }
443  ary = layout_get(self->descriptor->layout, Message_data(self), f);
444  for (int i = 0; i < RARRAY_LEN(val); i++) {
445  VALUE entry = rb_ary_entry(val, i);
446  if (TYPE(entry) == T_HASH && upb_fielddef_issubmsg(f)) {
447  entry = create_submsg_from_hash(f, entry);
448  }
449 
450  RepeatedField_push(ary, entry);
451  }
452  } else {
453  if (TYPE(val) == T_HASH && upb_fielddef_issubmsg(f)) {
455  }
456 
457  layout_set(self->descriptor->layout, Message_data(self), f, val);
458  }
459  return 0;
460 }
461 
462 /*
463  * call-seq:
464  * Message.new(kwargs) => new_message
465  *
466  * Creates a new instance of the given message class. Keyword arguments may be
467  * provided with keywords corresponding to field names.
468  *
469  * Note that no literal Message class exists. Only concrete classes per message
470  * type exist, as provided by the #msgclass method on Descriptors after they
471  * have been added to a pool. The method definitions described here on the
472  * Message class are provided on each concrete message class.
473  */
474 VALUE Message_initialize(int argc, VALUE* argv, VALUE _self) {
475  VALUE hash_args;
476 
477  if (argc == 0) {
478  return Qnil;
479  }
480  if (argc != 1) {
481  rb_raise(rb_eArgError, "Expected 0 or 1 arguments.");
482  }
483  hash_args = argv[0];
484  if (TYPE(hash_args) != T_HASH) {
485  rb_raise(rb_eArgError, "Expected hash arguments.");
486  }
487 
488  rb_hash_foreach(hash_args, Message_initialize_kwarg, _self);
489  return Qnil;
490 }
491 
492 /*
493  * call-seq:
494  * Message.dup => new_message
495  *
496  * Performs a shallow copy of this message and returns the new copy.
497  */
498 VALUE Message_dup(VALUE _self) {
499  MessageHeader* self;
500  VALUE new_msg;
501  MessageHeader* new_msg_self;
502  TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
503 
504  new_msg = rb_class_new_instance(0, NULL, CLASS_OF(_self));
505  TypedData_Get_Struct(new_msg, MessageHeader, &Message_type, new_msg_self);
506 
507  layout_dup(self->descriptor->layout,
508  Message_data(new_msg_self),
509  Message_data(self));
510 
511  return new_msg;
512 }
513 
514 // Internal only; used by Google::Protobuf.deep_copy.
515 VALUE Message_deep_copy(VALUE _self) {
516  MessageHeader* self;
517  MessageHeader* new_msg_self;
518  VALUE new_msg;
519  TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
520 
521  new_msg = rb_class_new_instance(0, NULL, CLASS_OF(_self));
522  TypedData_Get_Struct(new_msg, MessageHeader, &Message_type, new_msg_self);
523 
524  layout_deep_copy(self->descriptor->layout,
525  Message_data(new_msg_self),
526  Message_data(self));
527 
528  return new_msg;
529 }
530 
531 /*
532  * call-seq:
533  * Message.==(other) => boolean
534  *
535  * Performs a deep comparison of this message with another. Messages are equal
536  * if they have the same type and if each field is equal according to the :==
537  * method's semantics (a more efficient comparison may actually be done if the
538  * field is of a primitive type).
539  */
540 VALUE Message_eq(VALUE _self, VALUE _other) {
541  MessageHeader* self;
542  MessageHeader* other;
543  if (TYPE(_self) != TYPE(_other)) {
544  return Qfalse;
545  }
546  TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
547  TypedData_Get_Struct(_other, MessageHeader, &Message_type, other);
548 
549  if (self->descriptor != other->descriptor) {
550  return Qfalse;
551  }
552 
553  return layout_eq(self->descriptor->layout,
554  Message_data(self),
555  Message_data(other));
556 }
557 
558 /*
559  * call-seq:
560  * Message.hash => hash_value
561  *
562  * Returns a hash value that represents this message's field values.
563  */
564 VALUE Message_hash(VALUE _self) {
565  MessageHeader* self;
566  TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
567 
568  return layout_hash(self->descriptor->layout, Message_data(self));
569 }
570 
571 /*
572  * call-seq:
573  * Message.inspect => string
574  *
575  * Returns a human-readable string representing this message. It will be
576  * formatted as "<MessageType: field1: value1, field2: value2, ...>". Each
577  * field's value is represented according to its own #inspect method.
578  */
579 VALUE Message_inspect(VALUE _self) {
580  MessageHeader* self;
581  VALUE str;
582  TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
583 
584  str = rb_str_new2("<");
585  str = rb_str_append(str, rb_str_new2(rb_class2name(CLASS_OF(_self))));
586  str = rb_str_cat2(str, ": ");
587  str = rb_str_append(str, layout_inspect(
588  self->descriptor->layout, Message_data(self)));
589  str = rb_str_cat2(str, ">");
590  return str;
591 }
592 
593 /*
594  * call-seq:
595  * Message.to_h => {}
596  *
597  * Returns the message as a Ruby Hash object, with keys as symbols.
598  */
599 VALUE Message_to_h(VALUE _self) {
600  MessageHeader* self;
601  VALUE hash;
603  TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
604 
605  hash = rb_hash_new();
606 
607  for (upb_msg_field_begin(&it, self->descriptor->msgdef);
611 
612  // For proto2, do not include fields which are not set.
613  if (upb_msgdef_syntax(self->descriptor->msgdef) == UPB_SYNTAX_PROTO2 &&
614  field_contains_hasbit(self->descriptor->layout, field) &&
615  !layout_has(self->descriptor->layout, Message_data(self), field)) {
616  continue;
617  }
618 
619  VALUE msg_value = layout_get(self->descriptor->layout, Message_data(self),
620  field);
621  VALUE msg_key = ID2SYM(rb_intern(upb_fielddef_name(field)));
622  if (is_map_field(field)) {
623  msg_value = Map_to_h(msg_value);
625  msg_value = RepeatedField_to_ary(msg_value);
626  if (upb_msgdef_syntax(self->descriptor->msgdef) == UPB_SYNTAX_PROTO2 &&
627  RARRAY_LEN(msg_value) == 0) {
628  continue;
629  }
630 
632  for (int i = 0; i < RARRAY_LEN(msg_value); i++) {
633  VALUE elem = rb_ary_entry(msg_value, i);
634  rb_ary_store(msg_value, i, Message_to_h(elem));
635  }
636  }
637 
638  } else if (msg_value != Qnil &&
640  msg_value = Message_to_h(msg_value);
641  }
642  rb_hash_aset(hash, msg_key, msg_value);
643  }
644  return hash;
645 }
646 
647 
648 
649 /*
650  * call-seq:
651  * Message.[](index) => value
652  *
653  * Accesses a field's value by field name. The provided field name should be a
654  * string.
655  */
656 VALUE Message_index(VALUE _self, VALUE field_name) {
657  MessageHeader* self;
658  const upb_fielddef* field;
659  TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
660  Check_Type(field_name, T_STRING);
661  field = upb_msgdef_ntofz(self->descriptor->msgdef, RSTRING_PTR(field_name));
662  if (field == NULL) {
663  return Qnil;
664  }
665  return layout_get(self->descriptor->layout, Message_data(self), field);
666 }
667 
668 /*
669  * call-seq:
670  * Message.[]=(index, value)
671  *
672  * Sets a field's value by field name. The provided field name should be a
673  * string.
674  */
675 VALUE Message_index_set(VALUE _self, VALUE field_name, VALUE value) {
676  MessageHeader* self;
677  const upb_fielddef* field;
678  TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
679  Check_Type(field_name, T_STRING);
680  field = upb_msgdef_ntofz(self->descriptor->msgdef, RSTRING_PTR(field_name));
681  if (field == NULL) {
682  rb_raise(rb_eArgError, "Unknown field: %s", RSTRING_PTR(field_name));
683  }
684  layout_set(self->descriptor->layout, Message_data(self), field, value);
685  return Qnil;
686 }
687 
688 /*
689  * call-seq:
690  * Message.descriptor => descriptor
691  *
692  * Class method that returns the Descriptor instance corresponding to this
693  * message class's type.
694  */
695 VALUE Message_descriptor(VALUE klass) {
696  return rb_ivar_get(klass, descriptor_instancevar_interned);
697 }
698 
700  const char *name;
701  VALUE klass;
702 
703  if (desc->layout == NULL) {
704  desc->layout = create_layout(desc->msgdef);
705  }
706  if (desc->fill_method == NULL) {
707  desc->fill_method = new_fillmsg_decodermethod(desc, &desc->fill_method);
708  }
709 
710  name = upb_msgdef_fullname(desc->msgdef);
711  if (name == NULL) {
712  rb_raise(rb_eRuntimeError, "Descriptor does not have assigned name.");
713  }
714 
715  klass = rb_define_class_id(
716  // Docs say this parameter is ignored. User will assign return value to
717  // their own toplevel constant class name.
718  rb_intern("Message"),
719  rb_cObject);
721  get_def_obj(desc->msgdef));
722  rb_define_alloc_func(klass, Message_alloc);
723  rb_require("google/protobuf/message_exts");
724  rb_include_module(klass, rb_eval_string("::Google::Protobuf::MessageExts"));
725  rb_extend_object(
726  klass, rb_eval_string("::Google::Protobuf::MessageExts::ClassMethods"));
727 
728  rb_define_method(klass, "method_missing",
730  rb_define_method(klass, "respond_to_missing?",
732  rb_define_method(klass, "initialize", Message_initialize, -1);
733  rb_define_method(klass, "dup", Message_dup, 0);
734  // Also define #clone so that we don't inherit Object#clone.
735  rb_define_method(klass, "clone", Message_dup, 0);
736  rb_define_method(klass, "==", Message_eq, 1);
737  rb_define_method(klass, "eql?", Message_eq, 1);
738  rb_define_method(klass, "hash", Message_hash, 0);
739  rb_define_method(klass, "to_h", Message_to_h, 0);
740  rb_define_method(klass, "inspect", Message_inspect, 0);
741  rb_define_method(klass, "to_s", Message_inspect, 0);
742  rb_define_method(klass, "[]", Message_index, 1);
743  rb_define_method(klass, "[]=", Message_index_set, 2);
744  rb_define_singleton_method(klass, "decode", Message_decode, 1);
745  rb_define_singleton_method(klass, "encode", Message_encode, 1);
746  rb_define_singleton_method(klass, "decode_json", Message_decode_json, -1);
747  rb_define_singleton_method(klass, "encode_json", Message_encode_json, -1);
748  rb_define_singleton_method(klass, "descriptor", Message_descriptor, 0);
749 
750  return klass;
751 }
752 
753 /*
754  * call-seq:
755  * Enum.lookup(number) => name
756  *
757  * This module method, provided on each generated enum module, looks up an enum
758  * value by number and returns its name as a Ruby symbol, or nil if not found.
759  */
760 VALUE enum_lookup(VALUE self, VALUE number) {
761  int32_t num = NUM2INT(number);
762  VALUE desc = rb_ivar_get(self, descriptor_instancevar_interned);
764 
765  const char* name = upb_enumdef_iton(enumdesc->enumdef, num);
766  if (name == NULL) {
767  return Qnil;
768  } else {
769  return ID2SYM(rb_intern(name));
770  }
771 }
772 
773 /*
774  * call-seq:
775  * Enum.resolve(name) => number
776  *
777  * This module method, provided on each generated enum module, looks up an enum
778  * value by name (as a Ruby symbol) and returns its name, or nil if not found.
779  */
780 VALUE enum_resolve(VALUE self, VALUE sym) {
781  const char* name = rb_id2name(SYM2ID(sym));
782  VALUE desc = rb_ivar_get(self, descriptor_instancevar_interned);
784 
785  int32_t num = 0;
786  bool found = upb_enumdef_ntoiz(enumdesc->enumdef, name, &num);
787  if (!found) {
788  return Qnil;
789  } else {
790  return INT2NUM(num);
791  }
792 }
793 
794 /*
795  * call-seq:
796  * Enum.descriptor
797  *
798  * This module method, provided on each generated enum module, returns the
799  * EnumDescriptor corresponding to this enum type.
800  */
801 VALUE enum_descriptor(VALUE self) {
802  return rb_ivar_get(self, descriptor_instancevar_interned);
803 }
804 
806  VALUE mod = rb_define_module_id(
807  rb_intern(upb_enumdef_fullname(enumdesc->enumdef)));
808 
810  for (upb_enum_begin(&it, enumdesc->enumdef);
811  !upb_enum_done(&it);
812  upb_enum_next(&it)) {
813  const char* name = upb_enum_iter_name(&it);
814  int32_t value = upb_enum_iter_number(&it);
815  if (name[0] < 'A' || name[0] > 'Z') {
816  rb_warn("Enum value '%s' does not start with an uppercase letter "
817  "as is required for Ruby constants.",
818  name);
819  }
820  rb_define_const(mod, name, INT2NUM(value));
821  }
822 
823  rb_define_singleton_method(mod, "lookup", enum_lookup, 1);
824  rb_define_singleton_method(mod, "resolve", enum_resolve, 1);
825  rb_define_singleton_method(mod, "descriptor", enum_descriptor, 0);
826  rb_ivar_set(mod, descriptor_instancevar_interned,
827  get_def_obj(enumdesc->enumdef));
828 
829  return mod;
830 }
831 
832 /*
833  * call-seq:
834  * Google::Protobuf.deep_copy(obj) => copy_of_obj
835  *
836  * Performs a deep copy of a RepeatedField instance, a Map instance, or a
837  * message object, recursively copying its members.
838  */
839 VALUE Google_Protobuf_deep_copy(VALUE self, VALUE obj) {
840  VALUE klass = CLASS_OF(obj);
841  if (klass == cRepeatedField) {
843  } else if (klass == cMap) {
844  return Map_deep_copy(obj);
845  } else {
846  return Message_deep_copy(obj);
847  }
848 }
upb_enum_iter_number
int32_t upb_enum_iter_number(upb_enum_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1494
layout_init
void layout_init(MessageLayout *layout, void *storage, zend_object *object PHP_PROTO_TSRMLS_DC)
Definition: php/ext/google/protobuf/storage.c:755
UPB_SYNTAX_PROTO2
@ UPB_SYNTAX_PROTO2
Definition: php/ext/google/protobuf/upb.h:3140
upb_enum_next
void upb_enum_next(upb_enum_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1471
name
GLuint const GLchar * name
Definition: glcorearb.h:3055
cMap
VALUE cMap
Definition: ruby/ext/google/protobuf_c/map.c:137
Message_initialize
VALUE Message_initialize(int argc, VALUE *argv, VALUE _self)
Definition: ruby/ext/google/protobuf_c/message.c:474
layout_hash
VALUE layout_hash(MessageLayout *layout, void *storage)
Definition: ruby/ext/google/protobuf_c/storage.c:1023
cRepeatedField
VALUE cRepeatedField
Definition: repeated_field.c:42
MessageHeader::unknown_fields
stringsink * unknown_fields
Definition: ruby/ext/google/protobuf_c/protobuf.h:553
NULL
NULL
Definition: test_security_zap.cpp:405
layout_get
zval * layout_get(MessageLayout *layout, const void *storage, const upb_fielddef *field, CACHED_VALUE *cache TSRMLS_DC)
Definition: php/ext/google/protobuf/storage.c:812
Message_decode
VALUE Message_decode(VALUE klass, VALUE data)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:856
Google_Protobuf_deep_copy
VALUE Google_Protobuf_deep_copy(VALUE self, VALUE obj)
Definition: ruby/ext/google/protobuf_c/message.c:839
MessageHeader::descriptor
Descriptor * descriptor
Definition: ruby/ext/google/protobuf_c/protobuf.h:552
Message_to_h
VALUE Message_to_h(VALUE _self)
Definition: ruby/ext/google/protobuf_c/message.c:599
upb_enumdef_iton
const char * upb_enumdef_iton(const upb_enumdef *def, int32_t num)
Definition: php/ext/google/protobuf/upb.c:1484
upb_oneofdef_itof
const upb_fielddef * upb_oneofdef_itof(const upb_oneofdef *o, uint32_t num)
Definition: php/ext/google/protobuf/upb.c:1905
MessageHeader
Definition: ruby/ext/google/protobuf_c/protobuf.h:551
upb_msg_field_begin
void upb_msg_field_begin(upb_msg_field_iter *iter, const upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:1823
Map_merge_into_self
VALUE Map_merge_into_self(VALUE _self, VALUE hashmap)
Definition: ruby/ext/google/protobuf_c/map.c:761
EnumDescriptor::enumdef
const upb_enumdef * enumdef
Definition: ruby/ext/google/protobuf_c/protobuf.h:138
Message_method_missing
VALUE Message_method_missing(int argc, VALUE *argv, VALUE _self)
Definition: ruby/ext/google/protobuf_c/message.c:284
descriptor_instancevar_interned
ID descriptor_instancevar_interned
Definition: ruby/ext/google/protobuf_c/protobuf.c:78
upb_fielddef_issubmsg
bool upb_fielddef_issubmsg(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1687
layout_set
void layout_set(MessageLayout *layout, MessageHeader *header, const upb_fielddef *field, zval *val TSRMLS_DC)
Definition: php/ext/google/protobuf/storage.c:834
self
PHP_PROTO_OBJECT_FREE_END PHP_PROTO_OBJECT_DTOR_END intern self
Definition: php/ext/google/protobuf/map.c:543
RepeatedField_to_ary
VALUE RepeatedField_to_ary(VALUE _self)
Definition: repeated_field.c:384
protobuf.h
Message_dup
VALUE Message_dup(VALUE _self)
Definition: ruby/ext/google/protobuf_c/message.c:498
RepeatedField_push
VALUE RepeatedField_push(VALUE _self, VALUE val)
Definition: repeated_field.c:212
is_map_field
bool is_map_field(const upb_fielddef *field)
Definition: php/ext/google/protobuf/storage.c:526
desc
#define desc
Definition: extension_set.h:342
METHOD_WRAPPER_SETTER
@ METHOD_WRAPPER_SETTER
Definition: ruby/ext/google/protobuf_c/message.c:124
upb_fielddef_subdef
const upb_def * upb_fielddef_subdef(const upb_fielddef *f)
Definition: ruby/ext/google/protobuf_c/upb.c:2081
ruby_to_Descriptor
Descriptor * ruby_to_Descriptor(VALUE value)
METHOD_WRAPPER_GETTER
@ METHOD_WRAPPER_GETTER
Definition: ruby/ext/google/protobuf_c/message.c:123
enum_resolve
VALUE enum_resolve(VALUE self, VALUE sym)
Definition: ruby/ext/google/protobuf_c/message.c:780
layout_inspect
VALUE layout_inspect(MessageLayout *layout, void *storage)
Definition: ruby/ext/google/protobuf_c/storage.c:1039
Message_data
void * Message_data(void *msg)
Definition: ruby/ext/google/protobuf_c/message.c:37
METHOD_PRESENCE
@ METHOD_PRESENCE
Definition: ruby/ext/google/protobuf_c/message.c:121
upb_oneofdef_numfields
int upb_oneofdef_numfields(const upb_oneofdef *o)
Definition: php/ext/google/protobuf/upb.c:1890
Message_type
rb_data_type_t Message_type
Definition: ruby/ext/google/protobuf_c/message.c:55
enum_type
zend_class_entry * enum_type
Definition: php/ext/google/protobuf/message.c:1904
descriptor
Descriptor * descriptor
Definition: php/ext/google/protobuf/protobuf.h:936
Message_descriptor
VALUE Message_descriptor(VALUE klass)
Definition: ruby/ext/google/protobuf_c/message.c:695
map
zval * map
Definition: php/ext/google/protobuf/encode_decode.c:473
found
return found
Definition: socket_poller.cpp:456
METHOD_SETTER
@ METHOD_SETTER
Definition: ruby/ext/google/protobuf_c/message.c:119
layout_eq
VALUE layout_eq(MessageLayout *layout, void *msg1, void *msg2)
Definition: ruby/ext/google/protobuf_c/storage.c:981
Message_alloc
VALUE Message_alloc(VALUE klass)
Definition: ruby/ext/google/protobuf_c/message.c:60
Descriptor
Definition: ruby/ext/google/protobuf_c/protobuf.h:113
is_wrapper_type_field
static bool is_wrapper_type_field(const upb_fielddef *field)
Definition: ruby/ext/google/protobuf_c/message.c:128
upb_msgdef_ntofz
const UPB_INLINE upb_fielddef * upb_msgdef_ntofz(const upb_msgdef *m, const char *name)
Definition: php/ext/google/protobuf/upb.h:3518
create_submsg_from_hash
VALUE create_submsg_from_hash(const upb_fielddef *f, VALUE hash)
Definition: ruby/ext/google/protobuf_c/message.c:389
upb_oneofdef
Definition: php/ext/google/protobuf/upb.c:1176
ONEOF_CASE_NONE
#define ONEOF_CASE_NONE
Definition: php/ext/google/protobuf/protobuf.h:1188
obj
GLsizei GLsizei GLuint * obj
Definition: glcorearb.h:3066
ruby_wrapper_type
static VALUE ruby_wrapper_type(const upb_fielddef *field, const VALUE *value)
Definition: ruby/ext/google/protobuf_c/message.c:143
ALLOC_N
#define ALLOC_N(class_name, n)
Definition: php/ext/google/protobuf/protobuf.h:1479
upb_inttable_iter
Definition: php/ext/google/protobuf/upb.h:3088
Message_index
VALUE Message_index(VALUE _self, VALUE field_name)
Definition: ruby/ext/google/protobuf_c/message.c:656
update_failure_list.str
str
Definition: update_failure_list.py:41
upb_fielddef_containingoneof
const upb_oneofdef * upb_fielddef_containingoneof(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1619
Message_initialize_kwarg
int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self)
Definition: ruby/ext/google/protobuf_c/message.c:400
build_module_from_enumdesc
VALUE build_module_from_enumdesc(EnumDescriptor *enumdesc)
Definition: ruby/ext/google/protobuf_c/message.c:805
field_type_class
const zend_class_entry * field_type_class(const upb_fielddef *field PHP_PROTO_TSRMLS_DC)
Definition: php/ext/google/protobuf/storage.c:552
upb_enumdef_fullname
const char * upb_enumdef_fullname(const upb_enumdef *e)
Definition: php/ext/google/protobuf/upb.c:1445
layout_clear
void layout_clear(MessageLayout *layout, const void *storage, const upb_fielddef *field)
Definition: ruby/ext/google/protobuf_c/storage.c:647
layout_deep_copy
void layout_deep_copy(MessageLayout *layout, void *to, void *from)
Definition: ruby/ext/google/protobuf_c/storage.c:947
Message_inspect
VALUE Message_inspect(VALUE _self)
Definition: ruby/ext/google/protobuf_c/message.c:579
Message_free
void Message_free(void *self)
Definition: ruby/ext/google/protobuf_c/message.c:46
upb_fielddef_name
const char * upb_fielddef_name(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1568
upb_fielddef
Definition: php/ext/google/protobuf/upb.c:1118
build_class_from_descriptor
VALUE build_class_from_descriptor(Descriptor *desc)
Definition: ruby/ext/google/protobuf_c/message.c:699
layout_has
VALUE layout_has(MessageLayout *layout, const void *storage, const upb_fielddef *field)
Definition: ruby/ext/google/protobuf_c/storage.c:640
d
d
EnumDescriptor
Definition: ruby/ext/google/protobuf_c/protobuf.h:137
Message_encode_json
VALUE Message_encode_json(int argc, VALUE *argv, VALUE klass)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:1480
UPB_TYPE_MESSAGE
@ UPB_TYPE_MESSAGE
Definition: php/ext/google/protobuf/upb.h:421
field
const FieldDescriptor * field
Definition: parser_unittest.cc:2694
UPB_TYPE_ENUM
@ UPB_TYPE_ENUM
Definition: php/ext/google/protobuf/upb.h:417
key
const SETUP_TEARDOWN_TESTCONTEXT char * key
Definition: test_wss_transport.cpp:10
extract_method_call
static int extract_method_call(VALUE method_name, MessageHeader *self, const upb_fielddef **f, const upb_oneofdef **o)
Definition: ruby/ext/google/protobuf_c/message.c:153
upb_enumdef_ntoiz
UPB_INLINE bool upb_enumdef_ntoiz(const upb_enumdef *e, const char *name, int32_t *num)
Definition: php/ext/google/protobuf/upb.h:3775
stringsink_uninit
void stringsink_uninit(stringsink *sink)
Definition: php/ext/google/protobuf/encode_decode.c:80
layout_dup
void layout_dup(MessageLayout *layout, void *to, void *from)
Definition: ruby/ext/google/protobuf_c/storage.c:915
Message_encode
VALUE Message_encode(VALUE klass, VALUE msg_rb)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:1442
i
int i
Definition: gmock-matchers_test.cc:764
upb_msg_iter_field
upb_fielddef * upb_msg_iter_field(const upb_msg_field_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1833
upb_fielddef_type
upb_fieldtype_t upb_fielddef_type(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1505
upb_msgdef_lookupname
bool upb_msgdef_lookupname(const upb_msgdef *m, const char *name, size_t len, const upb_fielddef **f, const upb_oneofdef **o)
Definition: php/ext/google/protobuf/upb.c:1785
upb_enum_done
bool upb_enum_done(upb_enum_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1472
fields
static const upb_fielddef fields[107]
Definition: ruby/ext/google/protobuf_c/upb.c:7671
upb_oneof_iter_field
upb_fielddef * upb_oneof_iter_field(const upb_oneof_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1923
upb_oneof_begin
void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o)
Definition: php/ext/google/protobuf/upb.c:1911
MessageHeader
struct MessageHeader MessageHeader
Definition: php/ext/google/protobuf/protobuf.h:650
create_layout
PHP_PROTO_WRAP_OBJECT_END MessageLayout * create_layout(const upb_msgdef *msgdef)
Definition: php/ext/google/protobuf/storage.c:591
upb_msg_field_next
void upb_msg_field_next(upb_msg_field_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1827
UPB_LABEL_REPEATED
@ UPB_LABEL_REPEATED
Definition: php/ext/google/protobuf/upb.h:432
get_def_obj
PHP_PROTO_HASHTABLE_VALUE get_def_obj(const void *def)
Definition: php/ext/google/protobuf/protobuf.c:112
ruby_to_EnumDescriptor
EnumDescriptor * ruby_to_EnumDescriptor(VALUE value)
layout_mark
void layout_mark(MessageLayout *layout, void *storage)
Definition: ruby/ext/google/protobuf_c/storage.c:894
enum_descriptor
VALUE enum_descriptor(VALUE self)
Definition: ruby/ext/google/protobuf_c/message.c:801
upb_enum_iter_name
const char * upb_enum_iter_name(upb_enum_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1490
upb_msg_field_done
bool upb_msg_field_done(const upb_msg_field_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1829
METHOD_UNKNOWN
@ METHOD_UNKNOWN
Definition: ruby/ext/google/protobuf_c/message.c:117
name_len
static size_t name_len(const char *name_)
Definition: mechanism.cpp:104
Message_mark
void Message_mark(void *_self)
Definition: ruby/ext/google/protobuf_c/message.c:41
Message_deep_copy
VALUE Message_deep_copy(VALUE _self)
Definition: ruby/ext/google/protobuf_c/message.c:515
upb_enum_begin
void upb_enum_begin(upb_enum_iter *i, const upb_enumdef *e)
Definition: php/ext/google/protobuf/upb.c:1466
Map_to_h
VALUE Map_to_h(VALUE _self)
Definition: ruby/ext/google/protobuf_c/map.c:675
field_contains_hasbit
bool field_contains_hasbit(MessageLayout *layout, const upb_fielddef *field)
Definition: ruby/ext/google/protobuf_c/storage.c:452
METHOD_ENUM_GETTER
@ METHOD_ENUM_GETTER
Definition: ruby/ext/google/protobuf_c/message.c:122
Message_eq
VALUE Message_eq(VALUE _self, VALUE _other)
Definition: ruby/ext/google/protobuf_c/message.c:540
Message_decode_json
VALUE Message_decode_json(int argc, VALUE *argv, VALUE klass)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:900
upb_fielddef_label
upb_label_t upb_fielddef_label(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1548
TYPE
#define TYPE(u, l)
Definition: php/ext/google/protobuf/upb.c:8510
upb_oneof_done
bool upb_oneof_done(upb_oneof_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1919
METHOD_GETTER
@ METHOD_GETTER
Definition: ruby/ext/google/protobuf_c/message.c:118
upb_def
Definition: ruby/ext/google/protobuf_c/upb.h:1844
val
GLuint GLfloat * val
Definition: glcorearb.h:3604
Message_index_set
VALUE Message_index_set(VALUE _self, VALUE field_name, VALUE value)
Definition: ruby/ext/google/protobuf_c/message.c:675
METHOD_CLEAR
@ METHOD_CLEAR
Definition: ruby/ext/google/protobuf_c/message.c:120
f
GLfloat f
Definition: glcorearb.h:3964
value
GLsizei const GLfloat * value
Definition: glcorearb.h:3093
which_oneof_field
static const upb_fielddef * which_oneof_field(MessageHeader *self, const upb_oneofdef *o)
Definition: ruby/ext/google/protobuf_c/message.c:82
new_fillmsg_decodermethod
const upb_pbdecodermethod * new_fillmsg_decodermethod(Descriptor *desc, const void *owner)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:783
RepeatedField_deep_copy
VALUE RepeatedField_deep_copy(VALUE _self)
Definition: repeated_field.c:359
upb_strtable_iter
Definition: php/ext/google/protobuf/upb.h:3061
enum_lookup
VALUE enum_lookup(VALUE self, VALUE number)
Definition: ruby/ext/google/protobuf_c/message.c:760
upb_msgdef_syntax
upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:1745
raw_value
static const char * raw_value(void *memory, const upb_fielddef *f)
Definition: php/ext/google/protobuf/encode_decode.c:1147
upb_msgdef_fullname
const char * upb_msgdef_fullname(const upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:1733
upb_fielddef_index
uint32_t upb_fielddef_index(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1544
Message_hash
VALUE Message_hash(VALUE _self)
Definition: ruby/ext/google/protobuf_c/message.c:564
klass
zend_class_entry * klass
Definition: php/ext/google/protobuf/protobuf.h:801
number
double number
Definition: cJSON.h:326
it
MapIter it
Definition: php/ext/google/protobuf/map.c:205
upb_fielddef_haspresence
bool upb_fielddef_haspresence(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1713
Message_respond_to_missing
VALUE Message_respond_to_missing(int argc, VALUE *argv, VALUE _self)
Definition: ruby/ext/google/protobuf_c/message.c:369
google::protobuf::method
const Descriptor::ReservedRange const EnumValueDescriptor method
Definition: src/google/protobuf/descriptor.h:1973
benchmarks.python.py_benchmark.args
args
Definition: py_benchmark.py:24
stringsink
Definition: php/ext/google/protobuf/protobuf.h:1460
array
PHP_PROTO_OBJECT_FREE_END PHP_PROTO_OBJECT_DTOR_END intern array
Definition: array.c:111
Map_deep_copy
VALUE Map_deep_copy(VALUE _self)
Definition: ruby/ext/google/protobuf_c/map.c:542


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:56