ruby/ext/google/protobuf_c/encode_decode.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 // This function is equivalent to rb_str_cat(), but unlike the real
34 // rb_str_cat(), it doesn't leak memory in some versions of Ruby.
35 // For more information, see:
36 // https://bugs.ruby-lang.org/issues/11328
37 VALUE noleak_rb_str_cat(VALUE rb_str, const char *str, long len) {
38  char *p;
39  size_t oldlen = RSTRING_LEN(rb_str);
40  rb_str_modify_expand(rb_str, len);
41  p = RSTRING_PTR(rb_str);
42  memcpy(p + oldlen, str, len);
43  rb_str_set_len(rb_str, oldlen + len);
44  return rb_str;
45 }
46 
47 // The code below also comes from upb's prototype Ruby binding, developed by
48 // haberman@.
49 
50 /* stringsink *****************************************************************/
51 
52 static void *stringsink_start(void *_sink, const void *hd, size_t size_hint) {
53  stringsink *sink = _sink;
54  sink->len = 0;
55  return sink;
56 }
57 
58 static size_t stringsink_string(void *_sink, const void *hd, const char *ptr,
59  size_t len, const upb_bufhandle *handle) {
60  stringsink *sink = _sink;
61  size_t new_size = sink->size;
62 
63  UPB_UNUSED(hd);
65 
66  while (sink->len + len > new_size) {
67  new_size *= 2;
68  }
69 
70  if (new_size != sink->size) {
71  sink->ptr = realloc(sink->ptr, new_size);
72  sink->size = new_size;
73  }
74 
75  memcpy(sink->ptr + sink->len, ptr, len);
76  sink->len += len;
77 
78  return len;
79 }
80 
82  upb_byteshandler_init(&sink->handler);
85 
86  upb_bytessink_reset(&sink->sink, &sink->handler, sink);
87 
88  sink->size = 32;
89  sink->ptr = malloc(sink->size);
90  sink->len = 0;
91 }
92 
94  free(sink->ptr);
95 }
96 
97 // -----------------------------------------------------------------------------
98 // Parsing.
99 // -----------------------------------------------------------------------------
100 
101 #define DEREF(msg, ofs, type) *(type*)(((uint8_t *)msg) + ofs)
102 
103 typedef struct {
104  size_t ofs;
107 
108 // Creates a handlerdata that contains the offset and the hasbit for the field
109 static const void* newhandlerdata(upb_handlers* h, uint32_t ofs, int32_t hasbit) {
111  hd->ofs = ofs;
112  hd->hasbit = hasbit;
113  upb_handlers_addcleanup(h, hd, xfree);
114  return hd;
115 }
116 
117 typedef struct {
118  size_t ofs;
120  VALUE subklass;
122 
123 // Creates a handlerdata that contains offset and submessage type information.
124 static const void *newsubmsghandlerdata(upb_handlers* h,
125  uint32_t ofs,
126  int32_t hasbit,
127  VALUE subklass) {
129  hd->ofs = ofs;
130  hd->hasbit = hasbit;
131  hd->subklass = subklass;
132  upb_handlers_addcleanup(h, hd, xfree);
133  return hd;
134 }
135 
136 typedef struct {
137  size_t ofs; // union data slot
138  size_t case_ofs; // oneof_case field
139  uint32_t oneof_case_num; // oneof-case number to place in oneof_case field
140  VALUE subklass;
142 
143 static const void *newoneofhandlerdata(upb_handlers *h,
144  uint32_t ofs,
145  uint32_t case_ofs,
146  const upb_fielddef *f,
147  const Descriptor* desc) {
149  hd->ofs = ofs;
150  hd->case_ofs = case_ofs;
151  // We reuse the field tag number as a oneof union discriminant tag. Note that
152  // we don't expose these numbers to the user, so the only requirement is that
153  // we have some unique ID for each union case/possibility. The field tag
154  // numbers are already present and are easy to use so there's no reason to
155  // create a separate ID space. In addition, using the field tag number here
156  // lets us easily look up the field in the oneof accessor.
158  if (is_value_field(f)) {
160  }
161  hd->subklass = field_type_class(desc->layout, f);
162  upb_handlers_addcleanup(h, hd, xfree);
163  return hd;
164 }
165 
166 // A handler that starts a repeated field. Gets the Repeated*Field instance for
167 // this field (such an instance always exists even in an empty message).
168 static void *startseq_handler(void* closure, const void* hd) {
170  const size_t *ofs = hd;
171  return (void*)DEREF(msg, *ofs, VALUE);
172 }
173 
174 // Handlers that append primitive values to a repeated field.
175 #define DEFINE_APPEND_HANDLER(type, ctype) \
176  static bool append##type##_handler(void *closure, const void *hd, \
177  ctype val) { \
178  VALUE ary = (VALUE)closure; \
179  RepeatedField_push_native(ary, &val); \
180  return true; \
181  }
182 
183 DEFINE_APPEND_HANDLER(bool, bool)
186 DEFINE_APPEND_HANDLER(float, float)
189 DEFINE_APPEND_HANDLER(double, double)
190 
191 // Appends a string to a repeated field.
192 static void* appendstr_handler(void *closure,
193  const void *hd,
194  size_t size_hint) {
195  VALUE ary = (VALUE)closure;
196  VALUE str = rb_str_new2("");
197  rb_enc_associate(str, kRubyStringUtf8Encoding);
199  return (void*)str;
200 }
201 
202 static void set_hasbit(void *closure, int32_t hasbit) {
203  if (hasbit > 0) {
205  storage[hasbit/8] |= 1 << (hasbit % 8);
206  }
207 }
208 
209 // Appends a 'bytes' string to a repeated field.
210 static void* appendbytes_handler(void *closure,
211  const void *hd,
212  size_t size_hint) {
213  VALUE ary = (VALUE)closure;
214  VALUE str = rb_str_new2("");
215  rb_enc_associate(str, kRubyString8bitEncoding);
217  return (void*)str;
218 }
219 
220 // Sets a non-repeated string field in a message.
221 static void* str_handler(void *closure,
222  const void *hd,
223  size_t size_hint) {
225  const field_handlerdata_t *fieldhandler = hd;
226 
227  VALUE str = rb_str_new2("");
228  rb_enc_associate(str, kRubyStringUtf8Encoding);
229  DEREF(msg, fieldhandler->ofs, VALUE) = str;
230  set_hasbit(closure, fieldhandler->hasbit);
231  return (void*)str;
232 }
233 
234 // Sets a non-repeated 'bytes' field in a message.
235 static void* bytes_handler(void *closure,
236  const void *hd,
237  size_t size_hint) {
239  const field_handlerdata_t *fieldhandler = hd;
240 
241  VALUE str = rb_str_new2("");
242  rb_enc_associate(str, kRubyString8bitEncoding);
243  DEREF(msg, fieldhandler->ofs, VALUE) = str;
244  set_hasbit(closure, fieldhandler->hasbit);
245  return (void*)str;
246 }
247 
248 static size_t stringdata_handler(void* closure, const void* hd,
249  const char* str, size_t len,
250  const upb_bufhandle* handle) {
251  VALUE rb_str = (VALUE)closure;
252  noleak_rb_str_cat(rb_str, str, len);
253  return len;
254 }
255 
256 static bool stringdata_end_handler(void* closure, const void* hd) {
257  VALUE rb_str = (VALUE)closure;
258  rb_obj_freeze(rb_str);
259  return true;
260 }
261 
262 static bool appendstring_end_handler(void* closure, const void* hd) {
263  VALUE rb_str = (VALUE)closure;
264  rb_obj_freeze(rb_str);
265  return true;
266 }
267 
268 // Appends a submessage to a repeated field (a regular Ruby array for now).
269 static void *appendsubmsg_handler(void *closure, const void *hd) {
270  VALUE ary = (VALUE)closure;
271  const submsg_handlerdata_t *submsgdata = hd;
272  MessageHeader* submsg;
273 
274  VALUE submsg_rb = rb_class_new_instance(0, NULL, submsgdata->subklass);
275  RepeatedField_push(ary, submsg_rb);
276 
277  TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg);
278  return submsg;
279 }
280 
281 // Sets a non-repeated submessage field in a message.
282 static void *submsg_handler(void *closure, const void *hd) {
284  const submsg_handlerdata_t* submsgdata = hd;
285  VALUE submsg_rb;
286  MessageHeader* submsg;
287 
288  if (DEREF(msg, submsgdata->ofs, VALUE) == Qnil) {
289  DEREF(msg, submsgdata->ofs, VALUE) =
290  rb_class_new_instance(0, NULL, submsgdata->subklass);
291  }
292 
293  set_hasbit(closure, submsgdata->hasbit);
294 
295  submsg_rb = DEREF(msg, submsgdata->ofs, VALUE);
296  TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg);
297 
298  return submsg;
299 }
300 
301 // Handler data for startmap/endmap handlers.
302 typedef struct {
303  size_t ofs;
304  upb_fieldtype_t key_field_type;
305  upb_fieldtype_t value_field_type;
306  VALUE subklass;
308 
309 // Temporary frame for map parsing: at the beginning of a map entry message, a
310 // submsg handler allocates a frame to hold (i) a reference to the Map object
311 // into which this message will be inserted and (ii) storage slots to
312 // temporarily hold the key and value for this map entry until the end of the
313 // submessage. When the submessage ends, another handler is called to insert the
314 // value into the map.
315 typedef struct {
316  VALUE map;
318  char key_storage[NATIVE_SLOT_MAX_SIZE];
319  char value_storage[NATIVE_SLOT_MAX_SIZE];
321 
322 static void MapParseFrame_mark(void* _self) {
323  map_parse_frame_t* frame = _self;
324 
325  // This shouldn't strictly be necessary since this should be rooted by the
326  // message itself, but it can't hurt.
327  rb_gc_mark(frame->map);
328 
329  native_slot_mark(frame->handlerdata->key_field_type, &frame->key_storage);
330  native_slot_mark(frame->handlerdata->value_field_type, &frame->value_storage);
331 }
332 
333 void MapParseFrame_free(void* self) {
334  xfree(self);
335 }
336 
337 rb_data_type_t MapParseFrame_type = {
338  "MapParseFrame",
340 };
341 
342 // Handler to begin a map entry: allocates a temporary frame. This is the
343 // 'startsubmsg' handler on the msgdef that contains the map field.
344 static void *startmap_handler(void *closure, const void *hd) {
346  const map_handlerdata_t* mapdata = hd;
348  VALUE map_rb = DEREF(msg, mapdata->ofs, VALUE);
349 
350  frame->handlerdata = mapdata;
351  frame->map = map_rb;
352  native_slot_init(mapdata->key_field_type, &frame->key_storage);
353  native_slot_init(mapdata->value_field_type, &frame->value_storage);
354 
355  Map_set_frame(map_rb,
356  TypedData_Wrap_Struct(rb_cObject, &MapParseFrame_type, frame));
357 
358  return frame;
359 }
360 
361 static bool endmap_handler(void *closure, const void *hd) {
363  const map_handlerdata_t* mapdata = hd;
364  VALUE map_rb = DEREF(msg, mapdata->ofs, VALUE);
365  Map_set_frame(map_rb, Qnil);
366  return true;
367 }
368 
369 // Handler to end a map entry: inserts the value defined during the message into
370 // the map. This is the 'endmsg' handler on the map entry msgdef.
371 static bool endmapentry_handler(void* closure, const void* hd, upb_status* s) {
373  const map_handlerdata_t* mapdata = hd;
374 
375  VALUE key = native_slot_get(
376  mapdata->key_field_type, Qnil,
377  &frame->key_storage);
378 
379  VALUE value = native_slot_get(
380  mapdata->value_field_type, mapdata->subklass,
381  &frame->value_storage);
382 
383  Map_index_set(frame->map, key, value);
384 
385  return true;
386 }
387 
388 // Allocates a new map_handlerdata_t given the map entry message definition. If
389 // the offset of the field within the parent message is also given, that is
390 // added to the handler data as well. Note that this is called *twice* per map
391 // field: once in the parent message handler setup when setting the startsubmsg
392 // handler and once in the map entry message handler setup when setting the
393 // key/value and endmsg handlers. The reason is that there is no easy way to
394 // pass the handlerdata down to the sub-message handler setup.
396  size_t ofs,
397  const upb_msgdef* mapentry_def,
398  const Descriptor* desc) {
399  const upb_fielddef* key_field;
400  const upb_fielddef* value_field;
402  hd->ofs = ofs;
403  key_field = upb_msgdef_itof(mapentry_def, MAP_KEY_FIELD);
404  assert(key_field != NULL);
405  hd->key_field_type = upb_fielddef_type(key_field);
406  value_field = upb_msgdef_itof(mapentry_def, MAP_VALUE_FIELD);
407  assert(value_field != NULL);
408  hd->value_field_type = upb_fielddef_type(value_field);
409  hd->subklass = field_type_class(desc->layout, value_field);
410 
411  return hd;
412 }
413 
414 // Handlers that set primitive values in oneofs.
415 #define DEFINE_ONEOF_HANDLER(type, ctype) \
416  static bool oneof##type##_handler(void *closure, const void *hd, \
417  ctype val) { \
418  const oneof_handlerdata_t *oneofdata = hd; \
419  DEREF(closure, oneofdata->case_ofs, uint32_t) = \
420  oneofdata->oneof_case_num; \
421  DEREF(closure, oneofdata->ofs, ctype) = val; \
422  return true; \
423  }
424 
425 DEFINE_ONEOF_HANDLER(bool, bool)
428 DEFINE_ONEOF_HANDLER(float, float)
431 DEFINE_ONEOF_HANDLER(double, double)
432 
433 #undef DEFINE_ONEOF_HANDLER
434 
435 // Handlers for strings in a oneof.
436 static void *oneofstr_handler(void *closure,
437  const void *hd,
438  size_t size_hint) {
440  const oneof_handlerdata_t *oneofdata = hd;
441  VALUE str = rb_str_new2("");
442  rb_enc_associate(str, kRubyStringUtf8Encoding);
443  DEREF(msg, oneofdata->case_ofs, uint32_t) =
444  oneofdata->oneof_case_num;
445  DEREF(msg, oneofdata->ofs, VALUE) = str;
446  return (void*)str;
447 }
448 
449 static void *oneofbytes_handler(void *closure,
450  const void *hd,
451  size_t size_hint) {
453  const oneof_handlerdata_t *oneofdata = hd;
454  VALUE str = rb_str_new2("");
455  rb_enc_associate(str, kRubyString8bitEncoding);
456  DEREF(msg, oneofdata->case_ofs, uint32_t) =
457  oneofdata->oneof_case_num;
458  DEREF(msg, oneofdata->ofs, VALUE) = str;
459  return (void*)str;
460 }
461 
462 static bool oneofstring_end_handler(void* closure, const void* hd) {
463  VALUE rb_str = rb_str_new2("");
464  rb_obj_freeze(rb_str);
465  return true;
466 }
467 
468 // Handler for a submessage field in a oneof.
469 static void *oneofsubmsg_handler(void *closure,
470  const void *hd) {
472  const oneof_handlerdata_t *oneofdata = hd;
473  uint32_t oldcase = DEREF(msg, oneofdata->case_ofs, uint32_t);
474 
475  VALUE submsg_rb;
476  MessageHeader* submsg;
477 
478  if (oldcase != oneofdata->oneof_case_num ||
479  DEREF(msg, oneofdata->ofs, VALUE) == Qnil) {
480  DEREF(msg, oneofdata->ofs, VALUE) =
481  rb_class_new_instance(0, NULL, oneofdata->subklass);
482  }
483  // Set the oneof case *after* allocating the new class instance -- otherwise,
484  // if the Ruby GC is invoked as part of a call into the VM, it might invoke
485  // our mark routines, and our mark routines might see the case value
486  // indicating a VALUE is present and expect a valid VALUE. See comment in
487  // layout_set() for more detail: basically, the change to the value and the
488  // case must be atomic w.r.t. the Ruby VM.
489  DEREF(msg, oneofdata->case_ofs, uint32_t) =
490  oneofdata->oneof_case_num;
491 
492  submsg_rb = DEREF(msg, oneofdata->ofs, VALUE);
493  TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg);
494  return submsg;
495 }
496 
497 // Set up handlers for a repeated field.
499  const Descriptor* desc,
500  const upb_fielddef *f,
501  size_t offset) {
503  attr.handler_data = newhandlerdata(h, offset, -1);
505 
506  switch (upb_fielddef_type(f)) {
507 
508 #define SET_HANDLER(utype, ltype) \
509  case utype: \
510  upb_handlers_set##ltype(h, f, append##ltype##_handler, NULL); \
511  break;
512 
513  SET_HANDLER(UPB_TYPE_BOOL, bool);
517  SET_HANDLER(UPB_TYPE_FLOAT, float);
520  SET_HANDLER(UPB_TYPE_DOUBLE, double);
521 
522 #undef SET_HANDLER
523 
524  case UPB_TYPE_STRING:
525  case UPB_TYPE_BYTES: {
526  bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES;
527  upb_handlers_setstartstr(h, f, is_bytes ?
529  NULL);
532  break;
533  }
534  case UPB_TYPE_MESSAGE: {
535  VALUE subklass = field_type_class(desc->layout, f);
537  attr.handler_data = newsubmsghandlerdata(h, 0, -1, subklass);
539  break;
540  }
541  }
542 }
543 
544 // Set up handlers for a singular field.
546  upb_handlers* h,
547  const upb_fielddef* f,
548  size_t offset, size_t hasbit_off) {
549  // The offset we pass to UPB points to the start of the Message,
550  // rather than the start of where our data is stored.
551  int32_t hasbit = -1;
552  if (hasbit_off != MESSAGE_FIELD_NO_HASBIT) {
553  hasbit = hasbit_off + sizeof(MessageHeader) * 8;
554  }
555 
556  switch (upb_fielddef_type(f)) {
557  case UPB_TYPE_BOOL:
558  case UPB_TYPE_INT32:
559  case UPB_TYPE_UINT32:
560  case UPB_TYPE_ENUM:
561  case UPB_TYPE_FLOAT:
562  case UPB_TYPE_INT64:
563  case UPB_TYPE_UINT64:
564  case UPB_TYPE_DOUBLE:
565  upb_msg_setscalarhandler(h, f, offset, hasbit);
566  break;
567  case UPB_TYPE_STRING:
568  case UPB_TYPE_BYTES: {
569  bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES;
571  attr.handler_data = newhandlerdata(h, offset, hasbit);
573  is_bytes ? bytes_handler : str_handler,
574  &attr);
577  break;
578  }
579  case UPB_TYPE_MESSAGE: {
581  attr.handler_data = newsubmsghandlerdata(
582  h, offset, hasbit, field_type_class(desc->layout, f));
584  break;
585  }
586  }
587 }
588 
589 // Adds handlers to a map field.
591  const upb_fielddef* fielddef,
592  size_t offset,
593  const Descriptor* desc) {
594  const upb_msgdef* map_msgdef = upb_fielddef_msgsubdef(fielddef);
595  map_handlerdata_t* hd = new_map_handlerdata(offset, map_msgdef, desc);
597 
598  upb_handlers_addcleanup(h, hd, xfree);
599  attr.handler_data = hd;
602 }
603 
604 // Adds handlers to a map-entry msgdef.
606  const Descriptor* desc) {
607  const upb_fielddef* key_field = map_entry_key(msgdef);
608  const upb_fielddef* value_field = map_entry_value(msgdef);
611 
612  upb_handlers_addcleanup(h, hd, xfree);
613  attr.handler_data = hd;
615 
617  desc, h, key_field,
618  offsetof(map_parse_frame_t, key_storage),
621  desc, h, value_field,
622  offsetof(map_parse_frame_t, value_storage),
624 }
625 
626 // Set up handlers for a oneof field.
628  const upb_fielddef *f,
629  size_t offset,
630  size_t oneof_case_offset,
631  const Descriptor* desc) {
633  attr.handler_data =
634  newoneofhandlerdata(h, offset, oneof_case_offset, f, desc);
635 
636  switch (upb_fielddef_type(f)) {
637 
638 #define SET_HANDLER(utype, ltype) \
639  case utype: \
640  upb_handlers_set##ltype(h, f, oneof##ltype##_handler, &attr); \
641  break;
642 
643  SET_HANDLER(UPB_TYPE_BOOL, bool);
647  SET_HANDLER(UPB_TYPE_FLOAT, float);
650  SET_HANDLER(UPB_TYPE_DOUBLE, double);
651 
652 #undef SET_HANDLER
653 
654  case UPB_TYPE_STRING:
655  case UPB_TYPE_BYTES: {
656  bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES;
657  upb_handlers_setstartstr(h, f, is_bytes ?
659  &attr);
662  break;
663  }
664  case UPB_TYPE_MESSAGE: {
666  break;
667  }
668  }
669 }
670 
671 static bool unknown_field_handler(void* closure, const void* hd,
672  const char* buf, size_t size) {
674  UPB_UNUSED(hd);
675 
676  if (msg->unknown_fields == NULL) {
677  msg->unknown_fields = malloc(sizeof(stringsink));
678  stringsink_init(msg->unknown_fields);
679  }
680 
681  stringsink_string(msg->unknown_fields, NULL, buf, size, NULL);
682 
683  return true;
684 }
685 
687  const VALUE descriptor_pool = (VALUE)closure;
689  Descriptor* desc =
690  ruby_to_Descriptor(get_msgdef_obj(descriptor_pool, msgdef));
693 
694  // Ensure layout exists. We may be invoked to create handlers for a given
695  // message if we are included as a submsg of another message type before our
696  // class is actually built, so to work around this, we just create the layout
697  // (and handlers, in the class-building function) on-demand.
698  if (desc->layout == NULL) {
700  }
701 
702  // If this is a mapentry message type, set up a special set of handlers and
703  // bail out of the normal (user-defined) message type handling.
706  return;
707  }
708 
710 
711  for (upb_msg_field_begin(&i, desc->msgdef);
713  upb_msg_field_next(&i)) {
714  const upb_fielddef *f = upb_msg_iter_field(&i);
716  size_t offset = desc->layout->fields[upb_fielddef_index(f)].offset +
717  sizeof(MessageHeader);
718 
719  if (oneof) {
720  size_t oneof_case_offset =
721  desc->layout->oneofs[upb_oneofdef_index(oneof)].case_offset +
722  sizeof(MessageHeader);
723  add_handlers_for_oneof_field(h, f, offset, oneof_case_offset, desc);
724  } else if (is_map_field(f)) {
726  } else if (upb_fielddef_isseq(f)) {
728  } else {
730  desc, h, f, offset,
731  desc->layout->fields[upb_fielddef_index(f)].hasbit);
732  }
733  }
734 }
735 
736 // Constructs the handlers for filling a message's data into an in-memory
737 // object.
739  DescriptorPool* pool = ruby_to_DescriptorPool(desc->descriptor_pool);
740  return upb_handlercache_get(pool->fill_handler_cache, desc->msgdef);
741 }
742 
744  DescriptorPool* pool = ruby_to_DescriptorPool(desc->descriptor_pool);
745  return upb_pbcodecache_get(pool->fill_method_cache, desc->msgdef);
746 }
747 
749  DescriptorPool* pool = ruby_to_DescriptorPool(desc->descriptor_pool);
750  return upb_json_codecache_get(pool->json_fill_method_cache, desc->msgdef);
751 }
752 
754  DescriptorPool* pool = ruby_to_DescriptorPool(desc->descriptor_pool);
755  return upb_handlercache_get(pool->pb_serialize_handler_cache, desc->msgdef);
756 }
757 
759  Descriptor* desc, bool preserve_proto_fieldnames) {
760  DescriptorPool* pool = ruby_to_DescriptorPool(desc->descriptor_pool);
761  if (preserve_proto_fieldnames) {
762  return upb_handlercache_get(pool->json_serialize_handler_preserve_cache,
763  desc->msgdef);
764  } else {
765  return upb_handlercache_get(pool->json_serialize_handler_cache,
766  desc->msgdef);
767  }
768 }
769 
770 
771 // Stack-allocated context during an encode/decode operation. Contains the upb
772 // environment and its stack-based allocator, an initial buffer for allocations
773 // to avoid malloc() when possible, and a template for Ruby exception messages
774 // if any error occurs.
775 #define STACK_ENV_STACKBYTES 4096
776 typedef struct {
777  upb_arena *arena;
779  const char* ruby_error_template;
780  char allocbuf[STACK_ENV_STACKBYTES];
781 } stackenv;
782 
783 static void stackenv_init(stackenv* se, const char* errmsg);
784 static void stackenv_uninit(stackenv* se);
785 
786 static void stackenv_init(stackenv* se, const char* errmsg) {
787  se->ruby_error_template = errmsg;
788  se->arena =
789  upb_arena_init(se->allocbuf, sizeof(se->allocbuf), &upb_alloc_global);
790  upb_status_clear(&se->status);
791 }
792 
793 static void stackenv_uninit(stackenv* se) {
794  upb_arena_free(se->arena);
795 
796  if (!upb_ok(&se->status)) {
797  // TODO(haberman): have a way to verify that this is actually a parse error,
798  // instead of just throwing "parse error" unconditionally.
799  VALUE errmsg = rb_str_new2(upb_status_errmsg(&se->status));
800  rb_raise(cParseError, se->ruby_error_template, errmsg);
801  }
802 }
803 
804 /*
805  * call-seq:
806  * MessageClass.decode(data) => message
807  *
808  * Decodes the given data (as a string containing bytes in protocol buffers wire
809  * format) under the interpretration given by this message class's definition
810  * and returns a message object with the corresponding field values.
811  */
812 VALUE Message_decode(VALUE klass, VALUE data) {
813  VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
815  VALUE msgklass = Descriptor_msgclass(descriptor);
816  VALUE msg_rb;
818 
819  if (TYPE(data) != T_STRING) {
820  rb_raise(rb_eArgError, "Expected string for binary protobuf data.");
821  }
822 
823  msg_rb = rb_class_new_instance(0, NULL, msgklass);
824  TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
825 
826  {
829  stackenv se;
830  upb_sink sink;
831  upb_pbdecoder* decoder;
832  stackenv_init(&se, "Error occurred during parsing: %" PRIsVALUE);
833 
834  upb_sink_reset(&sink, h, msg);
835  decoder = upb_pbdecoder_create(se.arena, method, sink, &se.status);
836  upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data),
837  upb_pbdecoder_input(decoder));
838 
839  stackenv_uninit(&se);
840  }
841 
842  return msg_rb;
843 }
844 
845 /*
846  * call-seq:
847  * MessageClass.decode_json(data, options = {}) => message
848  *
849  * Decodes the given data (as a string containing bytes in protocol buffers wire
850  * format) under the interpretration given by this message class's definition
851  * and returns a message object with the corresponding field values.
852  *
853  * @param options [Hash] options for the decoder
854  * ignore_unknown_fields: set true to ignore unknown fields (default is to
855  * raise an error)
856  */
857 VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) {
858  VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
860  VALUE msgklass = Descriptor_msgclass(descriptor);
861  VALUE msg_rb;
862  VALUE data = argv[0];
863  VALUE ignore_unknown_fields = Qfalse;
865 
866  if (argc < 1 || argc > 2) {
867  rb_raise(rb_eArgError, "Expected 1 or 2 arguments.");
868  }
869 
870  if (argc == 2) {
871  VALUE hash_args = argv[1];
872  if (TYPE(hash_args) != T_HASH) {
873  rb_raise(rb_eArgError, "Expected hash arguments.");
874  }
875 
876  ignore_unknown_fields = rb_hash_lookup2(
877  hash_args, ID2SYM(rb_intern("ignore_unknown_fields")), Qfalse);
878  }
879 
880  if (TYPE(data) != T_STRING) {
881  rb_raise(rb_eArgError, "Expected string for JSON data.");
882  }
883 
884  // TODO(cfallin): Check and respect string encoding. If not UTF-8, we need to
885  // convert, because string handlers pass data directly to message string
886  // fields.
887 
888  msg_rb = rb_class_new_instance(0, NULL, msgklass);
889  TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
890 
891  {
893  stackenv se;
894  upb_sink sink;
897  stackenv_init(&se, "Error occurred during parsing: %" PRIsVALUE);
898 
901  &se.status, RTEST(ignore_unknown_fields));
902  upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data),
904 
905  stackenv_uninit(&se);
906  }
907 
908  return msg_rb;
909 }
910 
911 // -----------------------------------------------------------------------------
912 // Serializing.
913 // -----------------------------------------------------------------------------
914 
915 /* msgvisitor *****************************************************************/
916 
917 static void putmsg(VALUE msg, const Descriptor* desc, upb_sink sink, int depth,
918  bool emit_defaults, bool is_json, bool open_msg);
919 
922  bool ok = upb_handlers_getselector(f, type, &ret);
923  UPB_ASSERT(ok);
924  return ret;
925 }
926 
927 static void putstr(VALUE str, const upb_fielddef *f, upb_sink sink) {
928  upb_sink subsink;
929 
930  if (str == Qnil) return;
931 
932  assert(BUILTIN_TYPE(str) == RUBY_T_STRING);
933 
934  // We should be guaranteed that the string has the correct encoding because
935  // we ensured this at assignment time and then froze the string.
937  assert(rb_enc_from_index(ENCODING_GET(str)) == kRubyStringUtf8Encoding);
938  } else {
939  assert(rb_enc_from_index(ENCODING_GET(str)) == kRubyString8bitEncoding);
940  }
941 
943  &subsink);
944  upb_sink_putstring(subsink, getsel(f, UPB_HANDLER_STRING), RSTRING_PTR(str),
945  RSTRING_LEN(str), NULL);
947 }
948 
949 static void putsubmsg(VALUE submsg, const upb_fielddef *f, upb_sink sink,
950  int depth, bool emit_defaults, bool is_json) {
951  upb_sink subsink;
952  VALUE descriptor;
953  Descriptor* subdesc;
954 
955  if (submsg == Qnil) return;
956 
957  descriptor = rb_ivar_get(submsg, descriptor_instancevar_interned);
958  subdesc = ruby_to_Descriptor(descriptor);
959 
961  putmsg(submsg, subdesc, subsink, depth + 1, emit_defaults, is_json, true);
963 }
964 
965 static void putary(VALUE ary, const upb_fielddef* f, upb_sink sink, int depth,
966  bool emit_defaults, bool is_json) {
967  upb_sink subsink;
969  upb_selector_t sel = 0;
970  int size;
971  int i;
972 
973  if (ary == Qnil) return;
974  if (!emit_defaults && NUM2INT(RepeatedField_length(ary)) == 0) return;
975 
976  size = NUM2INT(RepeatedField_length(ary));
977  if (size == 0 && !emit_defaults) return;
978 
980 
983  }
984 
985  for (i = 0; i < size; i++) {
986  void* memory = RepeatedField_index_native(ary, i);
987  switch (type) {
988 #define T(upbtypeconst, upbtype, ctype) \
989  case upbtypeconst: \
990  upb_sink_put##upbtype(subsink, sel, *((ctype*)memory)); \
991  break;
992 
993  T(UPB_TYPE_FLOAT, float, float)
994  T(UPB_TYPE_DOUBLE, double, double)
995  T(UPB_TYPE_BOOL, bool, int8_t)
996  case UPB_TYPE_ENUM:
1001 
1002  case UPB_TYPE_STRING:
1003  case UPB_TYPE_BYTES:
1004  putstr(*((VALUE *)memory), f, subsink);
1005  break;
1006  case UPB_TYPE_MESSAGE:
1007  putsubmsg(*((VALUE*)memory), f, subsink, depth, emit_defaults, is_json);
1008  break;
1009 
1010 #undef T
1011 
1012  }
1013  }
1015 }
1016 
1017 static void put_ruby_value(VALUE value, const upb_fielddef* f, VALUE type_class,
1018  int depth, upb_sink sink, bool emit_defaults,
1019  bool is_json) {
1020  upb_selector_t sel = 0;
1021 
1022  if (depth > ENCODE_MAX_NESTING) {
1023  rb_raise(rb_eRuntimeError,
1024  "Maximum recursion depth exceeded during encoding.");
1025  }
1026 
1027  if (upb_fielddef_isprimitive(f)) {
1029  }
1030 
1031  switch (upb_fielddef_type(f)) {
1032  case UPB_TYPE_INT32:
1033  upb_sink_putint32(sink, sel, NUM2INT(value));
1034  break;
1035  case UPB_TYPE_INT64:
1036  upb_sink_putint64(sink, sel, NUM2LL(value));
1037  break;
1038  case UPB_TYPE_UINT32:
1039  upb_sink_putuint32(sink, sel, NUM2UINT(value));
1040  break;
1041  case UPB_TYPE_UINT64:
1042  upb_sink_putuint64(sink, sel, NUM2ULL(value));
1043  break;
1044  case UPB_TYPE_FLOAT:
1045  upb_sink_putfloat(sink, sel, NUM2DBL(value));
1046  break;
1047  case UPB_TYPE_DOUBLE:
1048  upb_sink_putdouble(sink, sel, NUM2DBL(value));
1049  break;
1050  case UPB_TYPE_ENUM: {
1051  if (TYPE(value) == T_SYMBOL) {
1052  value = rb_funcall(type_class, rb_intern("resolve"), 1, value);
1053  }
1054  upb_sink_putint32(sink, sel, NUM2INT(value));
1055  break;
1056  }
1057  case UPB_TYPE_BOOL:
1058  upb_sink_putbool(sink, sel, value == Qtrue);
1059  break;
1060  case UPB_TYPE_STRING:
1061  case UPB_TYPE_BYTES:
1062  putstr(value, f, sink);
1063  break;
1064  case UPB_TYPE_MESSAGE:
1065  putsubmsg(value, f, sink, depth, emit_defaults, is_json);
1066  }
1067 }
1068 
1069 static void putmap(VALUE map, const upb_fielddef* f, upb_sink sink, int depth,
1070  bool emit_defaults, bool is_json) {
1071  Map* self;
1072  upb_sink subsink;
1073  const upb_fielddef* key_field;
1074  const upb_fielddef* value_field;
1075  Map_iter it;
1076 
1077  if (map == Qnil) return;
1078  if (!emit_defaults && Map_length(map) == 0) return;
1079 
1080  self = ruby_to_Map(map);
1081 
1083 
1084  assert(upb_fielddef_type(f) == UPB_TYPE_MESSAGE);
1085  key_field = map_field_key(f);
1086  value_field = map_field_value(f);
1087 
1088  for (Map_begin(map, &it); !Map_done(&it); Map_next(&it)) {
1089  VALUE key = Map_iter_key(&it);
1090  VALUE value = Map_iter_value(&it);
1092 
1093  upb_sink entry_sink;
1095  &entry_sink);
1096  upb_sink_startmsg(entry_sink);
1097 
1098  put_ruby_value(key, key_field, Qnil, depth + 1, entry_sink, emit_defaults,
1099  is_json);
1100  put_ruby_value(value, value_field, self->value_type_class, depth + 1,
1101  entry_sink, emit_defaults, is_json);
1102 
1103  upb_sink_endmsg(entry_sink, &status);
1105  }
1106 
1108 }
1109 
1111  Descriptor* desc, bool preserve_proto_fieldnames);
1112 
1113 static void putjsonany(VALUE msg_rb, const Descriptor* desc, upb_sink sink,
1114  int depth, bool emit_defaults) {
1116  MessageHeader* msg = NULL;
1117  const upb_fielddef* type_field = upb_msgdef_itof(desc->msgdef, UPB_ANY_TYPE);
1118  const upb_fielddef* value_field = upb_msgdef_itof(desc->msgdef, UPB_ANY_VALUE);
1119 
1120  size_t type_url_offset;
1121  VALUE type_url_str_rb;
1122  const upb_msgdef *payload_type = NULL;
1123 
1124  TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
1125 
1127 
1128  /* Handle type url */
1129  type_url_offset = desc->layout->fields[upb_fielddef_index(type_field)].offset;
1130  type_url_str_rb = DEREF(Message_data(msg), type_url_offset, VALUE);
1131  if (RSTRING_LEN(type_url_str_rb) > 0) {
1132  putstr(type_url_str_rb, type_field, sink);
1133  }
1134 
1135  {
1136  const char* type_url_str = RSTRING_PTR(type_url_str_rb);
1137  size_t type_url_len = RSTRING_LEN(type_url_str_rb);
1139 
1140  if (type_url_len <= 20 ||
1141  strncmp(type_url_str, "type.googleapis.com/", 20) != 0) {
1142  rb_raise(rb_eRuntimeError, "Invalid type url: %s", type_url_str);
1143  return;
1144  }
1145 
1146  /* Resolve type url */
1147  type_url_str += 20;
1148  type_url_len -= 20;
1149 
1150  payload_type = upb_symtab_lookupmsg2(
1151  pool->symtab, type_url_str, type_url_len);
1152  if (payload_type == NULL) {
1153  rb_raise(rb_eRuntimeError, "Unknown type: %s", type_url_str);
1154  return;
1155  }
1156  }
1157 
1158  {
1159  uint32_t value_offset;
1160  VALUE value_str_rb;
1161  size_t value_len;
1162 
1163  value_offset = desc->layout->fields[upb_fielddef_index(value_field)].offset;
1164  value_str_rb = DEREF(Message_data(msg), value_offset, VALUE);
1165  value_len = RSTRING_LEN(value_str_rb);
1166 
1167  if (value_len > 0) {
1168  VALUE payload_desc_rb = get_msgdef_obj(generated_pool, payload_type);
1169  Descriptor* payload_desc = ruby_to_Descriptor(payload_desc_rb);
1170  VALUE payload_class = Descriptor_msgclass(payload_desc_rb);
1171  upb_sink subsink;
1172  bool is_wellknown;
1173 
1174  VALUE payload_msg_rb = Message_decode(payload_class, value_str_rb);
1175 
1176  is_wellknown =
1177  upb_msgdef_wellknowntype(payload_desc->msgdef) !=
1179  if (is_wellknown) {
1181  &subsink);
1182  }
1183 
1184  subsink.handlers =
1185  msgdef_json_serialize_handlers(payload_desc, true);
1186  subsink.closure = sink.closure;
1187  putmsg(payload_msg_rb, payload_desc, subsink, depth, emit_defaults, true,
1188  is_wellknown);
1189  }
1190  }
1191 
1193 }
1194 
1195 static void putjsonlistvalue(
1196  VALUE msg_rb, const Descriptor* desc,
1197  upb_sink sink, int depth, bool emit_defaults) {
1199  upb_sink subsink;
1200  MessageHeader* msg = NULL;
1201  const upb_fielddef* f = upb_msgdef_itof(desc->msgdef, 1);
1202  uint32_t offset =
1203  desc->layout->fields[upb_fielddef_index(f)].offset +
1204  sizeof(MessageHeader);
1205  VALUE ary;
1206 
1207  TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
1208 
1210 
1211  ary = DEREF(msg, offset, VALUE);
1212 
1213  if (ary == Qnil || RepeatedField_size(ary) == 0) {
1216  } else {
1217  putary(ary, f, sink, depth, emit_defaults, true);
1218  }
1219 
1221 }
1222 
1223 static void putmsg(VALUE msg_rb, const Descriptor* desc,
1224  upb_sink sink, int depth, bool emit_defaults,
1225  bool is_json, bool open_msg) {
1226  MessageHeader* msg;
1229 
1230  if (is_json &&
1232  putjsonany(msg_rb, desc, sink, depth, emit_defaults);
1233  return;
1234  }
1235 
1236  if (is_json &&
1238  putjsonlistvalue(msg_rb, desc, sink, depth, emit_defaults);
1239  return;
1240  }
1241 
1242  if (open_msg) {
1244  }
1245 
1246  // Protect against cycles (possible because users may freely reassign message
1247  // and repeated fields) by imposing a maximum recursion depth.
1248  if (depth > ENCODE_MAX_NESTING) {
1249  rb_raise(rb_eRuntimeError,
1250  "Maximum recursion depth exceeded during encoding.");
1251  }
1252 
1253  TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
1254 
1255  if (desc != msg->descriptor) {
1256  rb_raise(rb_eArgError,
1257  "The type of given msg is '%s', expect '%s'.",
1258  upb_msgdef_fullname(msg->descriptor->msgdef),
1259  upb_msgdef_fullname(desc->msgdef));
1260  }
1261 
1262  for (upb_msg_field_begin(&i, desc->msgdef);
1263  !upb_msg_field_done(&i);
1264  upb_msg_field_next(&i)) {
1267  bool is_matching_oneof = false;
1268  uint32_t offset =
1269  desc->layout->fields[upb_fielddef_index(f)].offset +
1270  sizeof(MessageHeader);
1271 
1272  if (oneof) {
1273  uint32_t oneof_case =
1274  slot_read_oneof_case(desc->layout, Message_data(msg), oneof);
1275  // For a oneof, check that this field is actually present -- skip all the
1276  // below if not.
1277  if (oneof_case != upb_fielddef_number(f)) {
1278  continue;
1279  }
1280  // Otherwise, fall through to the appropriate singular-field handler
1281  // below.
1282  is_matching_oneof = true;
1283  }
1284 
1285  if (is_map_field(f)) {
1286  VALUE map = DEREF(msg, offset, VALUE);
1287  if (map != Qnil || emit_defaults) {
1288  putmap(map, f, sink, depth, emit_defaults, is_json);
1289  }
1290  } else if (upb_fielddef_isseq(f)) {
1291  VALUE ary = DEREF(msg, offset, VALUE);
1292  if (ary != Qnil) {
1293  putary(ary, f, sink, depth, emit_defaults, is_json);
1294  }
1295  } else if (upb_fielddef_isstring(f)) {
1296  VALUE str = DEREF(msg, offset, VALUE);
1297  bool is_default = false;
1298 
1299  if (upb_msgdef_syntax(desc->msgdef) == UPB_SYNTAX_PROTO2) {
1300  is_default = layout_has(desc->layout, Message_data(msg), f) == Qfalse;
1301  } else if (upb_msgdef_syntax(desc->msgdef) == UPB_SYNTAX_PROTO3) {
1302  is_default = RSTRING_LEN(str) == 0;
1303  }
1304 
1305  if (is_matching_oneof || emit_defaults || !is_default) {
1306  putstr(str, f, sink);
1307  }
1308  } else if (upb_fielddef_issubmsg(f)) {
1309  putsubmsg(DEREF(msg, offset, VALUE), f, sink, depth,
1310  emit_defaults, is_json);
1311  } else {
1313 
1314 #define T(upbtypeconst, upbtype, ctype, default_value) \
1315  case upbtypeconst: { \
1316  ctype value = DEREF(msg, offset, ctype); \
1317  bool is_default = false; \
1318  if (upb_fielddef_haspresence(f)) { \
1319  is_default = layout_has(desc->layout, Message_data(msg), f) == Qfalse; \
1320  } else if (upb_msgdef_syntax(desc->msgdef) == UPB_SYNTAX_PROTO3) { \
1321  is_default = default_value == value; \
1322  } \
1323  if (is_matching_oneof || emit_defaults || !is_default) { \
1324  upb_sink_put##upbtype(sink, sel, value); \
1325  } \
1326  } break;
1327 
1328  switch (upb_fielddef_type(f)) {
1329  T(UPB_TYPE_FLOAT, float, float, 0.0)
1330  T(UPB_TYPE_DOUBLE, double, double, 0.0)
1331  T(UPB_TYPE_BOOL, bool, uint8_t, 0)
1332  case UPB_TYPE_ENUM:
1337 
1338  case UPB_TYPE_STRING:
1339  case UPB_TYPE_BYTES:
1340  case UPB_TYPE_MESSAGE: rb_raise(rb_eRuntimeError, "Internal error.");
1341  }
1342 
1343 #undef T
1344 
1345  }
1346  }
1347 
1348  {
1349  stringsink* unknown = msg->unknown_fields;
1350  if (unknown != NULL) {
1351  upb_sink_putunknown(sink, unknown->ptr, unknown->len);
1352  }
1353  }
1354 
1355  if (open_msg) {
1357  }
1358 }
1359 
1360 /*
1361  * call-seq:
1362  * MessageClass.encode(msg) => bytes
1363  *
1364  * Encodes the given message object to its serialized form in protocol buffers
1365  * wire format.
1366  */
1367 VALUE Message_encode(VALUE klass, VALUE msg_rb) {
1368  VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
1370 
1371  stringsink sink;
1373 
1374  {
1375  const upb_handlers* serialize_handlers =
1377 
1378  stackenv se;
1379  upb_pb_encoder* encoder;
1380  VALUE ret;
1381 
1382  stackenv_init(&se, "Error occurred during encoding: %" PRIsVALUE);
1383  encoder = upb_pb_encoder_create(se.arena, serialize_handlers, sink.sink);
1384 
1385  putmsg(msg_rb, desc, upb_pb_encoder_input(encoder), 0, false, false, true);
1386 
1387  ret = rb_str_new(sink.ptr, sink.len);
1388 
1389  stackenv_uninit(&se);
1391 
1392  return ret;
1393  }
1394 }
1395 
1396 /*
1397  * call-seq:
1398  * MessageClass.encode_json(msg, options = {}) => json_string
1399  *
1400  * Encodes the given message object into its serialized JSON representation.
1401  * @param options [Hash] options for the decoder
1402  * preserve_proto_fieldnames: set true to use original fieldnames (default is to camelCase)
1403  * emit_defaults: set true to emit 0/false values (default is to omit them)
1404  */
1405 VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
1406  VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
1408  VALUE msg_rb;
1409  VALUE preserve_proto_fieldnames = Qfalse;
1410  VALUE emit_defaults = Qfalse;
1411  stringsink sink;
1412 
1413  if (argc < 1 || argc > 2) {
1414  rb_raise(rb_eArgError, "Expected 1 or 2 arguments.");
1415  }
1416 
1417  msg_rb = argv[0];
1418 
1419  if (argc == 2) {
1420  VALUE hash_args = argv[1];
1421  if (TYPE(hash_args) != T_HASH) {
1422  rb_raise(rb_eArgError, "Expected hash arguments.");
1423  }
1424  preserve_proto_fieldnames = rb_hash_lookup2(
1425  hash_args, ID2SYM(rb_intern("preserve_proto_fieldnames")), Qfalse);
1426 
1427  emit_defaults = rb_hash_lookup2(
1428  hash_args, ID2SYM(rb_intern("emit_defaults")), Qfalse);
1429  }
1430 
1432 
1433  {
1434  const upb_handlers* serialize_handlers =
1435  msgdef_json_serialize_handlers(desc, RTEST(preserve_proto_fieldnames));
1436  upb_json_printer* printer;
1437  stackenv se;
1438  VALUE ret;
1439 
1440  stackenv_init(&se, "Error occurred during encoding: %" PRIsVALUE);
1441  printer = upb_json_printer_create(se.arena, serialize_handlers, sink.sink);
1442 
1443  putmsg(msg_rb, desc, upb_json_printer_input(printer), 0,
1444  RTEST(emit_defaults), true, true);
1445 
1446  ret = rb_enc_str_new(sink.ptr, sink.len, rb_utf8_encoding());
1447 
1448  stackenv_uninit(&se);
1450 
1451  return ret;
1452  }
1453 }
1454 
1455 static void discard_unknown(VALUE msg_rb, const Descriptor* desc) {
1456  MessageHeader* msg;
1458 
1459  TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
1460 
1461  {
1462  stringsink* unknown = msg->unknown_fields;
1463  if (unknown != NULL) {
1464  stringsink_uninit(unknown);
1465  msg->unknown_fields = NULL;
1466  }
1467  }
1468 
1469  for (upb_msg_field_begin(&it, desc->msgdef);
1471  upb_msg_field_next(&it)) {
1474  uint32_t offset =
1475  desc->layout->fields[upb_fielddef_index(f)].offset +
1476  sizeof(MessageHeader);
1477 
1478  if (oneof) {
1479  uint32_t oneof_case =
1480  slot_read_oneof_case(desc->layout, Message_data(msg), oneof);
1481  // For a oneof, check that this field is actually present -- skip all the
1482  // below if not.
1483  if (oneof_case != upb_fielddef_number(f)) {
1484  continue;
1485  }
1486  // Otherwise, fall through to the appropriate singular-field handler
1487  // below.
1488  }
1489 
1490  if (!upb_fielddef_issubmsg(f)) {
1491  continue;
1492  }
1493 
1494  if (is_map_field(f)) {
1495  VALUE map;
1496  Map_iter map_it;
1497 
1498  if (!upb_fielddef_issubmsg(map_field_value(f))) continue;
1499  map = DEREF(msg, offset, VALUE);
1500  if (map == Qnil) continue;
1501  for (Map_begin(map, &map_it); !Map_done(&map_it); Map_next(&map_it)) {
1502  VALUE submsg = Map_iter_value(&map_it);
1503  VALUE descriptor = rb_ivar_get(submsg, descriptor_instancevar_interned);
1504  const Descriptor* subdesc = ruby_to_Descriptor(descriptor);
1505  discard_unknown(submsg, subdesc);
1506  }
1507  } else if (upb_fielddef_isseq(f)) {
1508  VALUE ary = DEREF(msg, offset, VALUE);
1509  int size;
1510  int i;
1511 
1512  if (ary == Qnil) continue;
1513  size = NUM2INT(RepeatedField_length(ary));
1514  for (i = 0; i < size; i++) {
1515  void* memory = RepeatedField_index_native(ary, i);
1516  VALUE submsg = *((VALUE *)memory);
1517  VALUE descriptor = rb_ivar_get(submsg, descriptor_instancevar_interned);
1518  const Descriptor* subdesc = ruby_to_Descriptor(descriptor);
1519  discard_unknown(submsg, subdesc);
1520  }
1521  } else {
1522  VALUE submsg = DEREF(msg, offset, VALUE);
1523  VALUE descriptor;
1524  const Descriptor* subdesc;
1525 
1526  if (submsg == Qnil) continue;
1527  descriptor = rb_ivar_get(submsg, descriptor_instancevar_interned);
1528  subdesc = ruby_to_Descriptor(descriptor);
1529  discard_unknown(submsg, subdesc);
1530  }
1531  }
1532 }
1533 
1534 /*
1535  * call-seq:
1536  * Google::Protobuf.discard_unknown(msg)
1537  *
1538  * Discard unknown fields in the given message object and recursively discard
1539  * unknown fields in submessages.
1540  */
1541 VALUE Google_Protobuf_discard_unknown(VALUE self, VALUE msg_rb) {
1542  VALUE klass = CLASS_OF(msg_rb);
1543  VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
1545  if (klass == cRepeatedField || klass == cMap) {
1546  rb_raise(rb_eArgError, "Expected proto msg for discard unknown.");
1547  } else {
1548  discard_unknown(msg_rb, desc);
1549  }
1550  return Qnil;
1551 }
STACK_ENV_STACKBYTES
#define STACK_ENV_STACKBYTES
Definition: ruby/ext/google/protobuf_c/encode_decode.c:775
xds_interop_client.str
str
Definition: xds_interop_client.py:487
ptr
char * ptr
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:45
upb_handlers_setendstr
bool upb_handlers_setendstr(upb_handlers *h, const upb_fielddef *f, upb_endfield_handlerfunc *func, const upb_handlerattr *attr)
upb_sink_putstring
UPB_INLINE size_t upb_sink_putstring(upb_sink s, upb_selector_t sel, const char *buf, size_t n, const upb_bufhandle *handle)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:5584
upb_sink_startmsg
UPB_INLINE bool upb_sink_startmsg(upb_sink s)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:5609
appendstr_handler
static void * appendstr_handler(void *closure, const void *hd, size_t size_hint)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:192
UPB_SYNTAX_PROTO2
@ UPB_SYNTAX_PROTO2
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:2972
upb_json_printer_input
upb_sink upb_json_printer_input(upb_json_printer *p)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:13312
stackenv::status
upb_status status
Definition: php/ext/google/protobuf/encode_decode.c:94
UPB_TYPE_UINT64
@ UPB_TYPE_UINT64
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:487
Map_set_frame
VALUE Map_set_frame(VALUE map, VALUE val)
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/map.c:181
newoneofhandlerdata
static const void * newoneofhandlerdata(upb_handlers *h, uint32_t ofs, uint32_t case_ofs, const upb_fielddef *f, const Descriptor *desc)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:143
upb_arena
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2252
regen-readme.it
it
Definition: regen-readme.py:15
kRubyStringUtf8Encoding
rb_encoding * kRubyStringUtf8Encoding
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.c:77
upb_status_clear
void upb_status_clear(upb_status *status)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2196
upb_oneofdef_index
uint32_t upb_oneofdef_index(const upb_oneofdef *o)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3693
upb_msg_field_next
void upb_msg_field_next(upb_msg_field_iter *iter)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3626
discard_unknown
static void discard_unknown(VALUE msg_rb, const Descriptor *desc)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:1455
const
#define const
Definition: bloaty/third_party/zlib/zconf.h:230
Map
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:451
UPB_TYPE_FLOAT
@ UPB_TYPE_FLOAT
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:476
upb_json_parsermethod
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:8761
startmap_handler
static void * startmap_handler(void *closure, const void *hd)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:344
RepeatedField_size
int RepeatedField_size(VALUE _self)
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/repeated_field.c:258
upb_status
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:197
putmap
static void putmap(VALUE map, const upb_fielddef *f, upb_sink sink, int depth, bool emit_defaults, bool is_json)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:1069
map_handlerdata_t::value_field_type
upb_fieldtype_t value_field_type
Definition: php/ext/google/protobuf/encode_decode.c:463
upb_json_printer
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:11933
Message_decode
VALUE Message_decode(VALUE klass, VALUE data)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:812
google::protobuf::int64
int64_t int64
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/stubs/port.h:151
upb_fielddef_issubmsg
bool upb_fielddef_issubmsg(const upb_fielddef *f)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3486
map_field_key
const upb_fielddef * map_field_key(const upb_fielddef *field)
Definition: php/ext/google/protobuf/storage.c:530
field_handlerdata_t::hasbit
int32_t hasbit
Definition: ruby/ext/google/protobuf_c/encode_decode.c:105
upb_handlers_getprimitivehandlertype
upb_handlertype_t upb_handlers_getprimitivehandlertype(const upb_fielddef *f)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:5201
UPB_ANY_TYPE
#define UPB_ANY_TYPE
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:3313
putmsg
static void putmsg(VALUE msg, const Descriptor *desc, upb_sink sink, int depth, bool emit_defaults, bool is_json, bool open_msg)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:1223
UPB_HANDLER_STARTSTR
@ UPB_HANDLER_STARTSTR
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:3923
UPB_HANDLER_ENDSEQ
@ UPB_HANDLER_ENDSEQ
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:3929
upb_pbdecoder
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:6436
MessageHeader
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:574
msgdef_jsonparsermethod
static const upb_json_parsermethod * msgdef_jsonparsermethod(Descriptor *desc)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:748
upb_fieldtype_t
upb_fieldtype_t
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:472
stringsink_start
static void * stringsink_start(void *_sink, const void *hd, size_t size_hint)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:52
upb_arena_free
void upb_arena_free(upb_arena *a)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2391
Map_iter
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:490
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
unknown_field_handler
static bool unknown_field_handler(void *closure, const void *hd, const char *buf, size_t size)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:671
putsubmsg
static void putsubmsg(VALUE submsg, const upb_fielddef *f, upb_sink sink, int depth, bool emit_defaults, bool is_json)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:949
upb_handlers_setstring
bool upb_handlers_setstring(upb_handlers *h, const upb_fielddef *f, upb_string_handlerfunc *func, const upb_handlerattr *attr)
UPB_WELLKNOWN_UNSPECIFIED
@ UPB_WELLKNOWN_UNSPECIFIED
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:2981
binary_size.new_size
def new_size
Definition: binary_size.py:124
Descriptor::msgdef
const upb_msgdef * msgdef
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:122
upb_handlers_setstartsubmsg
bool upb_handlers_setstartsubmsg(upb_handlers *h, const upb_fielddef *f, upb_startfield_handlerfunc *func, const upb_handlerattr *attr)
upb_msg_iter_field
upb_fielddef * upb_msg_iter_field(const upb_msg_field_iter *iter)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3632
google::protobuf::uint32
uint32_t uint32
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/stubs/port.h:155
RepeatedField_push
VALUE RepeatedField_push(VALUE _self, VALUE val)
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/repeated_field.c:216
native_slot_get
void native_slot_get(upb_fieldtype_t type, const void *memory, CACHED_VALUE *cache TSRMLS_DC)
Definition: php/ext/google/protobuf/storage.c:311
DEFINE_APPEND_HANDLER
#define DEFINE_APPEND_HANDLER(type, ctype)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:175
upb_byteshandler_setstartstr
bool upb_byteshandler_setstartstr(upb_byteshandler *h, upb_startstr_handlerfunc *func, void *d)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:5360
Message_data
void * Message_data(void *msg)
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/message.c:37
ENCODE_MAX_NESTING
#define ENCODE_MAX_NESTING
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:978
status
absl::Status status
Definition: rls.cc:251
UPB_TYPE_UINT32
@ UPB_TYPE_UINT32
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:478
startseq_handler
static void * startseq_handler(void *closure, const void *hd)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:168
upb_pbdecoder_create
upb_pbdecoder * upb_pbdecoder_create(upb_arena *a, const upb_pbdecodermethod *m, upb_sink sink, upb_status *status)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:7408
add_handlers_for_repeated_field
static void add_handlers_for_repeated_field(upb_handlers *h, const Descriptor *desc, const upb_fielddef *f, size_t offset)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:498
upb_bufsrc_putbuf
bool upb_bufsrc_putbuf(const char *buf, size_t len, upb_bytessink sink)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:5477
xds_manager.p
p
Definition: xds_manager.py:60
str_handler
static void * str_handler(void *closure, const void *hd, size_t size_hint)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:221
DEREF
#define DEREF(msg, ofs, type)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:101
NATIVE_SLOT_MAX_SIZE
#define NATIVE_SLOT_MAX_SIZE
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:1030
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
upb_fielddef_isprimitive
bool upb_fielddef_isprimitive(const upb_fielddef *f)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3499
DEFINE_ONEOF_HANDLER
#define DEFINE_ONEOF_HANDLER(type, ctype)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:415
map
zval * map
Definition: php/ext/google/protobuf/encode_decode.c:480
upb_sink_startseq
UPB_INLINE bool upb_sink_startseq(upb_sink s, upb_selector_t sel, upb_sink *sub)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:5633
upb_handlers_setunknown
bool upb_handlers_setunknown(upb_handlers *h, upb_unknown_handlerfunc *func, const upb_handlerattr *attr)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:5136
MapParseFrame_type
rb_data_type_t MapParseFrame_type
Definition: ruby/ext/google/protobuf_c/encode_decode.c:337
upb_sink::handlers
const upb_handlers * handlers
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:5554
add_handlers_for_mapentry
static void add_handlers_for_mapentry(const upb_msgdef *msgdef, upb_handlers *h, const Descriptor *desc)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:605
stringdata_end_handler
static bool stringdata_end_handler(void *closure, const void *hd)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:256
map_parse_frame_t
Definition: ruby/ext/google/protobuf_c/encode_decode.c:315
Descriptor
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:121
ruby_to_Descriptor
Descriptor * ruby_to_Descriptor(VALUE value)
arena
grpc_core::ScopedArenaPtr arena
Definition: binder_transport_test.cc:237
upb_fielddef_msgsubdef
const upb_msgdef * upb_fielddef_msgsubdef(const upb_fielddef *f)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3476
upb_alloc_global
upb_alloc upb_alloc_global
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2241
get_fill_handlers
const upb_handlers * get_fill_handlers(Descriptor *desc)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:738
upb_handlercache_get
const upb_handlers * upb_handlercache_get(upb_handlercache *c, const upb_msgdef *md)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:5288
upb_handlertype_t
upb_handlertype_t
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:3915
upb_symtab_lookupmsg2
const upb_msgdef * upb_symtab_lookupmsg2(const upb_symtab *s, const char *sym, size_t len)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:4571
upb_bytessink_reset
UPB_INLINE void upb_bytessink_reset(upb_bytessink *s, const upb_byteshandler *h, void *closure)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:5916
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
UPB_TYPE_BYTES
@ UPB_TYPE_BYTES
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:482
upb_msg_field_done
bool upb_msg_field_done(const upb_msg_field_iter *iter)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3628
upb_oneofdef
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2992
upb_handlers_getselector
bool upb_handlers_getselector(const upb_fielddef *f, upb_handlertype_t type, upb_selector_t *s)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:5215
bytes_handler
static void * bytes_handler(void *closure, const void *hd, size_t size_hint)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:235
UPB_TYPE_ENUM
@ UPB_TYPE_ENUM
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:479
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
stackenv_uninit
static void stackenv_uninit(stackenv *se)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:793
oneof_handlerdata_t
Definition: php/ext/google/protobuf/encode_decode.c:182
layout_has
VALUE layout_has(MessageLayout *layout, const void *storage, const upb_fielddef *field)
Definition: ruby/ext/google/protobuf_c/storage.c:722
google::protobuf::int32
int32_t int32
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/stubs/port.h:150
field_handlerdata_t
Definition: ruby/ext/google/protobuf_c/encode_decode.c:103
putstr
static void putstr(VALUE str, const upb_fielddef *f, upb_sink sink)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:927
new_map_handlerdata
static map_handlerdata_t * new_map_handlerdata(size_t ofs, const upb_msgdef *mapentry_def, const Descriptor *desc)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:395
upb_selector_t
int32_t upb_selector_t
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:3942
autogen_x86imm.f
f
Definition: autogen_x86imm.py:9
asyncio_get_stats.parser
parser
Definition: asyncio_get_stats.py:34
upb_msgdef_fullname
const char * upb_msgdef_fullname(const upb_msgdef *m)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3532
upb_sink_endsubmsg
UPB_INLINE bool upb_sink_endsubmsg(upb_sink s, upb_selector_t sel)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:5703
getsel
static upb_selector_t getsel(const upb_fielddef *f, upb_handlertype_t type)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:920
MapParseFrame_mark
static void MapParseFrame_mark(void *_self)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:322
upb_bufhandle
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:3975
Map_done
bool Map_done(Map_iter *iter)
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/map.c:818
int64_t
signed __int64 int64_t
Definition: stdint-msvc2008.h:89
native_slot_mark
void native_slot_mark(upb_fieldtype_t type, void *memory)
Definition: ruby/ext/google/protobuf_c/storage.c:359
Map_next
void Map_next(Map_iter *iter)
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/map.c:814
upb_status_errmsg
const char * upb_status_errmsg(const upb_status *status)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2204
stringdata_handler
static size_t stringdata_handler(void *closure, const void *hd, const char *str, size_t len, const upb_bufhandle *handle)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:248
upb_arena_init
upb_arena * upb_arena_init(void *mem, size_t n, upb_alloc *alloc)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2354
map_handlerdata_t::key_field_type
upb_fieldtype_t key_field_type
Definition: php/ext/google/protobuf/encode_decode.c:462
cParseError
VALUE cParseError
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.c:34
map_handlerdata_t::subklass
VALUE subklass
Definition: ruby/ext/google/protobuf_c/encode_decode.c:306
newsubmsghandlerdata
static const void * newsubmsghandlerdata(upb_handlers *h, uint32_t ofs, int32_t hasbit, VALUE subklass)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:124
Map_iter_value
VALUE Map_iter_value(Map_iter *iter)
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/map.c:829
upb_inttable_iter
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:1113
UPB_HANDLER_ENDSTR
@ UPB_HANDLER_ENDSTR
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:3925
Map_index_set
VALUE Map_index_set(VALUE _self, VALUE key, VALUE value)
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/map.c:391
add_handlers_for_message
void add_handlers_for_message(const void *closure, upb_handlers *h)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:686
submsg_handlerdata_t::hasbit
int32_t hasbit
Definition: ruby/ext/google/protobuf_c/encode_decode.c:119
oneofstr_handler
static void * oneofstr_handler(void *closure, const void *hd, size_t size_hint)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:436
stringsink::len
size_t len
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:1473
msgdef_pb_serialize_handlers
static const upb_handlers * msgdef_pb_serialize_handlers(Descriptor *desc)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:753
upb_pbdecoder_input
upb_bytessink upb_pbdecoder_input(upb_pbdecoder *d)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:7453
closure
grpc_closure closure
Definition: src/core/lib/surface/server.cc:466
Google_Protobuf_discard_unknown
VALUE Google_Protobuf_discard_unknown(VALUE self, VALUE msg_rb)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:1541
uint64_t
unsigned __int64 uint64_t
Definition: stdint-msvc2008.h:90
upb_fielddef_number
uint32_t upb_fielddef_number(const upb_fielddef *f)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3351
upb_sink_endmsg
UPB_INLINE bool upb_sink_endmsg(upb_sink s, upb_status *status)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:5621
upb_handlers_addcleanup
bool upb_handlers_addcleanup(upb_handlers *h, void *p, upb_handlerfree *func)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:5197
upb_fielddef_isstring
bool upb_fielddef_isstring(const upb_fielddef *f)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3490
msgdef_json_serialize_handlers
static const upb_handlers * msgdef_json_serialize_handlers(Descriptor *desc, bool preserve_proto_fieldnames)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:758
set_hasbit
static void set_hasbit(void *closure, int32_t hasbit)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:202
T
#define T(upbtypeconst, upbtype, ctype)
is_value_field
bool is_value_field(const upb_fielddef *f)
Definition: ruby/ext/google/protobuf_c/storage.c:476
UPB_ANY_VALUE
#define UPB_ANY_VALUE
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:3314
slot_read_oneof_case
uint32_t slot_read_oneof_case(MessageLayout *layout, const void *storage, const upb_oneofdef *oneof)
Definition: ruby/ext/google/protobuf_c/storage.c:687
google::protobuf::uint64
uint64_t uint64
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/stubs/port.h:156
generated_pool
InternalDescriptorPool * generated_pool
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/def.c:582
oneof_handlerdata_t::subklass
VALUE subklass
Definition: ruby/ext/google/protobuf_c/encode_decode.c:140
MessageHeader
struct MessageHeader MessageHeader
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:659
MESSAGE_FIELD_NO_HASBIT
#define MESSAGE_FIELD_NO_HASBIT
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:505
UPB_ASSERT
#define UPB_ASSERT(expr)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:135
oneof_handlerdata_t::oneof_case_num
uint32_t oneof_case_num
Definition: php/ext/google/protobuf/encode_decode.c:186
upb_pbcodecache_get
const upb_pbdecodermethod * upb_pbcodecache_get(upb_pbcodecache *c, const upb_msgdef *md)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:6400
data
char data[kBufferLength]
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1006
cRepeatedField
VALUE cRepeatedField
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/repeated_field.c:42
stackenv
Definition: php/ext/google/protobuf/encode_decode.c:92
upb_fielddef
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2934
Map_iter_key
VALUE Map_iter_key(Map_iter *iter)
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/map.c:822
submsg_handler
static void * submsg_handler(void *closure, const void *hd)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:282
map_field_value
const upb_fielddef * map_field_value(const upb_fielddef *field)
Definition: php/ext/google/protobuf/storage.c:535
upb_pb_encoder
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:7583
map_handlerdata_t::ofs
size_t ofs
Definition: php/ext/google/protobuf/encode_decode.c:461
UPB_TYPE_INT32
@ UPB_TYPE_INT32
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:477
submsg_handlerdata_t::subklass
VALUE subklass
Definition: ruby/ext/google/protobuf_c/encode_decode.c:120
Message_encode_json
VALUE Message_encode_json(int argc, VALUE *argv, VALUE klass)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:1405
RepeatedField_length
VALUE RepeatedField_length(VALUE _self)
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/repeated_field.c:321
upb_msgdef_itof
const upb_fielddef * upb_msgdef_itof(const upb_msgdef *m, uint32_t i)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3556
protobuf.h
upb_ok
bool upb_ok(const upb_status *status)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2202
UPB_HANDLER_STRING
@ UPB_HANDLER_STRING
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:3924
msg
std::string msg
Definition: client_interceptors_end2end_test.cc:372
UPB_HANDLER_STARTSUBMSG
@ UPB_HANDLER_STARTSUBMSG
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:3926
stringsink::ptr
char * ptr
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:1472
map_parse_frame_t
typedefPHP_PROTO_WRAP_OBJECT_END struct map_parse_frame_t map_parse_frame_t
Definition: php/ext/google/protobuf/encode_decode.c:486
MapParseFrame_free
void MapParseFrame_free(void *self)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:333
MAP_VALUE_FIELD
#define MAP_VALUE_FIELD
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:1103
put_ruby_value
static void put_ruby_value(VALUE value, const upb_fielddef *f, VALUE type_class, int depth, upb_sink sink, bool emit_defaults, bool is_json)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:1017
Message_encode
VALUE Message_encode(VALUE klass, VALUE msg_rb)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:1367
Message_type
rb_data_type_t Message_type
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/message.c:55
value
const char * value
Definition: hpack_parser_table.cc:165
upb_fielddef_index
uint32_t upb_fielddef_index(const upb_fielddef *f)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3343
stringsink_init
void stringsink_init(stringsink *sink)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:81
upb_pb_encoder_input
upb_sink upb_pb_encoder_input(upb_pb_encoder *e)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:8059
upb_json_parser
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:8702
upb_sink
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:5553
oneofstring_end_handler
static bool oneofstring_end_handler(void *closure, const void *hd)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:462
attr
OPENSSL_EXPORT X509_ATTRIBUTE * attr
Definition: x509.h:1666
putjsonany
static void putjsonany(VALUE msg_rb, const Descriptor *desc, upb_sink sink, int depth, bool emit_defaults)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:1113
upb_sink_endstr
UPB_INLINE bool upb_sink_endstr(upb_sink s, upb_selector_t sel)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:5674
map_parse_frame_t::handlerdata
const map_handlerdata_t * handlerdata
Definition: ruby/ext/google/protobuf_c/encode_decode.c:317
upb_sink_putunknown
UPB_INLINE bool upb_sink_putunknown(upb_sink s, const char *buf, size_t n)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:5597
key
const char * key
Definition: hpack_parser_table.cc:164
UPB_TYPE_STRING
@ UPB_TYPE_STRING
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:481
stringsink_uninit
void stringsink_uninit(stringsink *sink)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:93
upb_sink_startstr
UPB_INLINE bool upb_sink_startstr(upb_sink s, upb_selector_t sel, size_t size_hint, upb_sink *sub)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:5659
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
sink
FormatSinkImpl * sink
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:450
RepeatedField_push_native
void RepeatedField_push_native(VALUE _self, void *data)
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/repeated_field.c:239
ALLOC
#define ALLOC(class_name)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:1486
upb_msg_field_begin
void upb_msg_field_begin(upb_msg_field_iter *iter, const upb_msgdef *m)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3622
UPB_UNUSED
#define UPB_UNUSED(var)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:128
map_entry_value
const upb_fielddef * map_entry_value(const upb_msgdef *msgdef)
Definition: php/ext/google/protobuf/storage.c:546
upb_byteshandler_init
UPB_INLINE void upb_byteshandler_init(upb_byteshandler *handler)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:4535
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
Map_begin
void Map_begin(VALUE _self, Map_iter *iter)
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/map.c:808
map_handlerdata_t
Definition: php/ext/google/protobuf/encode_decode.c:460
stackenv::ruby_error_template
const char * ruby_error_template
Definition: ruby/ext/google/protobuf_c/encode_decode.c:779
oneofbytes_handler
static void * oneofbytes_handler(void *closure, const void *hd, size_t size_hint)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:449
MAP_KEY_FIELD
#define MAP_KEY_FIELD
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:1102
upb_json_printer_create
upb_json_printer * upb_json_printer_create(upb_arena *a, const upb_handlers *h, upb_bytessink output)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:13291
msgdef
const upb_msgdef * msgdef
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:808
upb_msgdef_syntax
upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3544
ruby_to_Map
Map * ruby_to_Map(VALUE _self)
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/map.c:142
oneof_handlerdata_t::case_ofs
size_t case_ofs
Definition: php/ext/google/protobuf/encode_decode.c:184
UPB_HANDLERATTR_INIT
#define UPB_HANDLERATTR_INIT
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:3972
kRubyString8bitEncoding
rb_encoding * kRubyString8bitEncoding
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.c:79
appendbytes_handler
static void * appendbytes_handler(void *closure, const void *hd, size_t size_hint)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:210
native_slot_init
void native_slot_init(upb_fieldtype_t type, void *memory, CACHED_VALUE *cache)
Definition: php/ext/google/protobuf/storage.c:276
msgdef_decodermethod
static const upb_pbdecodermethod * msgdef_decodermethod(Descriptor *desc)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:743
upb_json_parser_input
upb_bytessink upb_json_parser_input(upb_json_parser *p)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:11858
upb_sink_reset
UPB_INLINE void upb_sink_reset(upb_sink *s, const upb_handlers *h, void *c)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:5579
ok
bool ok
Definition: async_end2end_test.cc:197
UPB_SYNTAX_PROTO3
@ UPB_SYNTAX_PROTO3
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:2973
frame
static void frame(frame_handler *handler, unsigned char *payload, size_t payload_length, size_t write_length)
Definition: frame_handler_test.cc:65
appendstring_end_handler
static bool appendstring_end_handler(void *closure, const void *hd)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:262
newhandlerdata
static const void * newhandlerdata(upb_handlers *h, uint32_t ofs, int32_t hasbit)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:109
desc
#define desc
Definition: bloaty/third_party/protobuf/src/google/protobuf/extension_set.h:338
UPB_HANDLER_ENDSUBMSG
@ UPB_HANDLER_ENDSUBMSG
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:3927
Message_decode_json
VALUE Message_decode_json(int argc, VALUE *argv, VALUE klass)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:857
closure
Definition: proxy.cc:59
Descriptor_msgclass
VALUE Descriptor_msgclass(VALUE _self)
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/defs.c:664
UPB_TYPE_MESSAGE
@ UPB_TYPE_MESSAGE
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:483
upb_msgdef_wellknowntype
upb_wellknowntype_t upb_msgdef_wellknowntype(const upb_msgdef *m)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3612
upb_msg_setscalarhandler
bool upb_msg_setscalarhandler(upb_handlers *h, const upb_fielddef *f, size_t offset, int32_t hasbit)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:5407
cMap
VALUE cMap
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/map.c:140
pool
InternalDescriptorPool * pool
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:807
upb_pb_encoder_create
upb_pb_encoder * upb_pb_encoder_create(upb_arena *arena, const upb_handlers *h, upb_bytessink output)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:8020
TYPE
#define TYPE(u, l)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:8202
upb_handlerattr
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:3965
upb_fielddef_containingoneof
const upb_oneofdef * upb_fielddef_containingoneof(const upb_fielddef *f)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3418
oneofsubmsg_handler
static void * oneofsubmsg_handler(void *closure, const void *hd)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:469
upb_sink_endseq
UPB_INLINE bool upb_sink_endseq(upb_sink s, upb_selector_t sel)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:5648
stackenv::arena
upb_arena * arena
Definition: php/ext/google/protobuf/encode_decode.c:93
upb_msgdef_mapentry
bool upb_msgdef_mapentry(const upb_msgdef *m)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3608
handle
static csh handle
Definition: test_arm_regression.c:16
submsg_handlerdata_t::ofs
size_t ofs
Definition: php/ext/google/protobuf/encode_decode.c:166
appendsubmsg_handler
static void * appendsubmsg_handler(void *closure, const void *hd)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:269
noleak_rb_str_cat
VALUE noleak_rb_str_cat(VALUE rb_str, const char *str, long len)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:37
endmapentry_handler
static bool endmapentry_handler(void *closure, const void *hd, upb_status *s)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:371
UPB_HANDLER_STARTSEQ
@ UPB_HANDLER_STARTSEQ
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:3928
add_handlers_for_mapfield
static void add_handlers_for_mapfield(upb_handlers *h, const upb_fielddef *fielddef, size_t offset, const Descriptor *desc)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:590
upb_handlers_setendmsg
bool upb_handlers_setendmsg(upb_handlers *h, upb_endmsg_handlerfunc *func, const upb_handlerattr *attr)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:5148
int8_t
signed char int8_t
Definition: stdint-msvc2008.h:75
upb_handlers_msgdef
const upb_msgdef * upb_handlers_msgdef(const upb_handlers *h)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:5195
asyncio_get_stats.type
type
Definition: asyncio_get_stats.py:37
map_entry_key
const upb_fielddef * map_entry_key(const upb_msgdef *msgdef)
Definition: php/ext/google/protobuf/storage.c:540
upb_handlers_setendsubmsg
bool upb_handlers_setendsubmsg(upb_handlers *h, const upb_fielddef *f, upb_endfield_handlerfunc *func, const upb_handlerattr *attr)
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
add_handlers_for_oneof_field
static void add_handlers_for_oneof_field(upb_handlers *h, const upb_fielddef *f, size_t offset, size_t oneof_case_offset, const Descriptor *desc)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:627
Map_length
VALUE Map_length(VALUE _self)
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/map.c:493
upb_handlers_setstartseq
bool upb_handlers_setstartseq(upb_handlers *h, const upb_fielddef *f, upb_startfield_handlerfunc *func, const upb_handlerattr *attr)
upb_sink::closure
void * closure
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:5555
stackenv::allocbuf
char allocbuf[STACK_ENV_STACKBYTES]
Definition: php/ext/google/protobuf/encode_decode.c:96
size
voidpf void uLong size
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
fielddef
const upb_fielddef * fielddef
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:825
putjsonlistvalue
static void putjsonlistvalue(VALUE msg_rb, const Descriptor *desc, upb_sink sink, int depth, bool emit_defaults)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:1195
self
PHP_PROTO_OBJECT_FREE_END PHP_PROTO_OBJECT_DTOR_END intern self
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/map.c:543
mkowners.depth
depth
Definition: mkowners.py:114
descriptor_instancevar_interned
ID descriptor_instancevar_interned
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.c:88
method
NSString * method
Definition: ProtoMethod.h:28
int32_t
signed int int32_t
Definition: stdint-msvc2008.h:77
upb_fielddef_isseq
bool upb_fielddef_isseq(const upb_fielddef *f)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3495
upb_json_parser_create
upb_json_parser * upb_json_parser_create(upb_arena *arena, const upb_json_parsermethod *method, const upb_symtab *symtab, upb_sink output, upb_status *status, bool ignore_json_unknown)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:11816
DescriptorPool
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:110
endmap_handler
static bool endmap_handler(void *closure, const void *hd)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:361
upb_handlers_setstartstr
bool upb_handlers_setstartstr(upb_handlers *h, const upb_fielddef *f, upb_startstr_handlerfunc *func, const upb_handlerattr *attr)
klass
zend_class_entry * klass
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:810
putary
static void putary(VALUE ary, const upb_fielddef *f, upb_sink sink, int depth, bool emit_defaults, bool is_json)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:965
upb_handlers
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:4921
descriptor
static const char descriptor[1336]
Definition: certs.upbdefs.c:16
map_parse_frame_t::map
VALUE map
Definition: ruby/ext/google/protobuf_c/encode_decode.c:316
submsg_handlerdata_t
Definition: php/ext/google/protobuf/encode_decode.c:165
UPB_TYPE_DOUBLE
@ UPB_TYPE_DOUBLE
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:485
absl::status_internal::storage
static ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES absl::base_internal::AtomicHook< StatusPayloadPrinter > storage
Definition: abseil-cpp/absl/status/status_payload_printer.cc:26
upb_json_codecache_get
const upb_json_parsermethod * upb_json_codecache_get(upb_json_codecache *c, const upb_msgdef *md)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:11886
create_layout
PHP_PROTO_WRAP_OBJECT_END MessageLayout * create_layout(const upb_msgdef *msgdef)
Definition: php/ext/google/protobuf/storage.c:591
UPB_TYPE_BOOL
@ UPB_TYPE_BOOL
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:474
is_map_field
bool is_map_field(const upb_fielddef *field)
Definition: php/ext/google/protobuf/storage.c:526
UPB_TYPE_INT64
@ UPB_TYPE_INT64
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:486
stackenv_init
static void stackenv_init(stackenv *se, const char *errmsg)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:786
get_msgdef_obj
VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_msgdef *def)
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/defs.c:2260
add_handlers_for_singular_field
static void add_handlers_for_singular_field(const Descriptor *desc, upb_handlers *h, const upb_fielddef *f, size_t offset, size_t hasbit_off)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:545
upb_pbdecodermethod_desthandlers
const upb_handlers * upb_pbdecodermethod_desthandlers(const upb_pbdecodermethod *m)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:5529
stringsink_string
static size_t stringsink_string(void *_sink, const void *hd, const char *ptr, size_t len, const upb_bufhandle *handle)
Definition: ruby/ext/google/protobuf_c/encode_decode.c:58
ONEOF_CASE_MASK
#define ONEOF_CASE_MASK
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:531
upb_msgdef
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:2962
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
UPB_WELLKNOWN_LISTVALUE
@ UPB_WELLKNOWN_LISTVALUE
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:2998
offset
voidpf uLong offset
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:142
upb_fielddef_type
upb_fieldtype_t upb_fielddef_type(const upb_fielddef *f)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:3304
UPB_WELLKNOWN_ANY
@ UPB_WELLKNOWN_ANY
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:2982
upb_sink_startsubmsg
UPB_INLINE bool upb_sink_startsubmsg(upb_sink s, upb_selector_t sel, upb_sink *sub)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:5685
RepeatedField_index_native
void * RepeatedField_index_native(VALUE _self, int index)
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/repeated_field.c:251
stringsink
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:1469
field_handlerdata_t::ofs
size_t ofs
Definition: ruby/ext/google/protobuf_c/encode_decode.c:104
oneof_handlerdata_t::ofs
size_t ofs
Definition: php/ext/google/protobuf/encode_decode.c:183
SET_HANDLER
#define SET_HANDLER(utype, ltype)
ruby_to_DescriptorPool
DescriptorPool * ruby_to_DescriptorPool(VALUE value)
upb_pbdecodermethod
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:6410
upb_byteshandler_setstring
bool upb_byteshandler_setstring(upb_byteshandler *h, upb_string_handlerfunc *func, void *d)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:5367


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:18