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#include <math.h>
34
35#include <ruby/encoding.h>
36
37// -----------------------------------------------------------------------------
38// Ruby <-> native slot management.
39// -----------------------------------------------------------------------------
40
41#define CHARPTR_AT(msg, ofs) ((char*)msg + ofs)
42#define DEREF_OFFSET(msg, ofs, type) *(type*)CHARPTR_AT(msg, ofs)
43#define DEREF(memory, type) *(type*)(memory)
44
45size_t native_slot_size(upb_fieldtype_t type) {
46  switch (type) {
47    case UPB_TYPE_FLOAT:   return 4;
48    case UPB_TYPE_DOUBLE:  return 8;
49    case UPB_TYPE_BOOL:    return 1;
50    case UPB_TYPE_STRING:  return sizeof(VALUE);
51    case UPB_TYPE_BYTES:   return sizeof(VALUE);
52    case UPB_TYPE_MESSAGE: return sizeof(VALUE);
53    case UPB_TYPE_ENUM:    return 4;
54    case UPB_TYPE_INT32:   return 4;
55    case UPB_TYPE_INT64:   return 8;
56    case UPB_TYPE_UINT32:  return 4;
57    case UPB_TYPE_UINT64:  return 8;
58    default: return 0;
59  }
60}
61
62static bool is_ruby_num(VALUE value) {
63  return (TYPE(value) == T_FLOAT ||
64          TYPE(value) == T_FIXNUM ||
65          TYPE(value) == T_BIGNUM);
66}
67
68void native_slot_check_int_range_precision(const char* name, upb_fieldtype_t type, VALUE val) {
69  if (!is_ruby_num(val)) {
70    rb_raise(cTypeError, "Expected number type for integral field '%s' (given %s).",
71             name, rb_class2name(CLASS_OF(val)));
72  }
73
74  // NUM2{INT,UINT,LL,ULL} macros do the appropriate range checks on upper
75  // bound; we just need to do precision checks (i.e., disallow rounding) and
76  // check for < 0 on unsigned types.
77  if (TYPE(val) == T_FLOAT) {
78    double dbl_val = NUM2DBL(val);
79    if (floor(dbl_val) != dbl_val) {
80      rb_raise(rb_eRangeError,
81               "Non-integral floating point value assigned to integer field '%s' (given %s).",
82               name, rb_class2name(CLASS_OF(val)));
83    }
84  }
85  if (type == UPB_TYPE_UINT32 || type == UPB_TYPE_UINT64) {
86    if (NUM2DBL(val) < 0) {
87      rb_raise(rb_eRangeError,
88               "Assigning negative value to unsigned integer field '%s' (given %s).",
89               name, rb_class2name(CLASS_OF(val)));
90    }
91  }
92}
93
94VALUE native_slot_encode_and_freeze_string(upb_fieldtype_t type, VALUE value) {
95  rb_encoding* desired_encoding = (type == UPB_TYPE_STRING) ?
96      kRubyStringUtf8Encoding : kRubyString8bitEncoding;
97  VALUE desired_encoding_value = rb_enc_from_encoding(desired_encoding);
98
99  if (rb_obj_encoding(value) != desired_encoding_value || !OBJ_FROZEN(value)) {
100    // Note: this will not duplicate underlying string data unless necessary.
101    value = rb_str_encode(value, desired_encoding_value, 0, Qnil);
102
103    if (type == UPB_TYPE_STRING &&
104        rb_enc_str_coderange(value) == ENC_CODERANGE_BROKEN) {
105      rb_raise(rb_eEncodingError, "String is invalid UTF-8");
106    }
107
108    // Ensure the data remains valid.  Since we called #encode a moment ago,
109    // this does not freeze the string the user assigned.
110    rb_obj_freeze(value);
111  }
112
113  return value;
114}
115
116void native_slot_set(const char* name,
117                     upb_fieldtype_t type, VALUE type_class,
118                     void* memory, VALUE value) {
119  native_slot_set_value_and_case(name, type, type_class, memory, value, NULL, 0);
120}
121
122void native_slot_set_value_and_case(const char* name,
123                                    upb_fieldtype_t type, VALUE type_class,
124                                    void* memory, VALUE value,
125                                    uint32_t* case_memory,
126                                    uint32_t case_number) {
127  // Note that in order to atomically change the value in memory and the case
128  // value (w.r.t. Ruby VM calls), we must set the value at |memory| only after
129  // all Ruby VM calls are complete. The case is then set at the bottom of this
130  // function.
131  switch (type) {
132    case UPB_TYPE_FLOAT:
133      if (!is_ruby_num(value)) {
134        rb_raise(cTypeError, "Expected number type for float field '%s' (given %s).",
135                 name, rb_class2name(CLASS_OF(value)));
136      }
137      DEREF(memory, float) = NUM2DBL(value);
138      break;
139    case UPB_TYPE_DOUBLE:
140      if (!is_ruby_num(value)) {
141        rb_raise(cTypeError, "Expected number type for double field '%s' (given %s).",
142                 name, rb_class2name(CLASS_OF(value)));
143      }
144      DEREF(memory, double) = NUM2DBL(value);
145      break;
146    case UPB_TYPE_BOOL: {
147      int8_t val = -1;
148      if (value == Qtrue) {
149        val = 1;
150      } else if (value == Qfalse) {
151        val = 0;
152      } else {
153        rb_raise(cTypeError, "Invalid argument for boolean field '%s' (given %s).",
154                 name, rb_class2name(CLASS_OF(value)));
155      }
156      DEREF(memory, int8_t) = val;
157      break;
158    }
159    case UPB_TYPE_STRING:
160      if (CLASS_OF(value) == rb_cSymbol) {
161        value = rb_funcall(value, rb_intern("to_s"), 0);
162      } else if (CLASS_OF(value) != rb_cString) {
163        rb_raise(cTypeError, "Invalid argument for string field '%s' (given %s).",
164                 name, rb_class2name(CLASS_OF(value)));
165      }
166
167      DEREF(memory, VALUE) = native_slot_encode_and_freeze_string(type, value);
168      break;
169
170    case UPB_TYPE_BYTES: {
171      if (CLASS_OF(value) != rb_cString) {
172        rb_raise(cTypeError, "Invalid argument for bytes field '%s' (given %s).",
173                 name, rb_class2name(CLASS_OF(value)));
174      }
175
176      DEREF(memory, VALUE) = native_slot_encode_and_freeze_string(type, value);
177      break;
178    }
179    case UPB_TYPE_MESSAGE: {
180      if (CLASS_OF(value) == CLASS_OF(Qnil)) {
181        value = Qnil;
182      } else if (CLASS_OF(value) != type_class) {
183        // check for possible implicit conversions
184        VALUE converted_value = Qnil;
185        const char* field_type_name = rb_class2name(type_class);
186
187        if (strcmp(field_type_name, "Google::Protobuf::Timestamp") == 0 &&
188            rb_obj_is_kind_of(value, rb_cTime)) {
189          // Time -> Google::Protobuf::Timestamp
190          VALUE hash = rb_hash_new();
191          rb_hash_aset(hash, rb_str_new2("seconds"),
192                       rb_funcall(value, rb_intern("to_i"), 0));
193          rb_hash_aset(hash, rb_str_new2("nanos"),
194                       rb_funcall(value, rb_intern("nsec"), 0));
195          {
196            VALUE args[1] = {hash};
197            converted_value = rb_class_new_instance(1, args, type_class);
198          }
199        } else if (strcmp(field_type_name, "Google::Protobuf::Duration") == 0 &&
200                   rb_obj_is_kind_of(value, rb_cNumeric)) {
201          // Numeric -> Google::Protobuf::Duration
202          VALUE hash = rb_hash_new();
203          rb_hash_aset(hash, rb_str_new2("seconds"),
204                       rb_funcall(value, rb_intern("to_i"), 0));
205          {
206            VALUE n_value =
207                rb_funcall(value, rb_intern("remainder"), 1, INT2NUM(1));
208            n_value =
209                rb_funcall(n_value, rb_intern("*"), 1, INT2NUM(1000000000));
210            n_value = rb_funcall(n_value, rb_intern("round"), 0);
211            rb_hash_aset(hash, rb_str_new2("nanos"), n_value);
212          }
213          {
214            VALUE args[1] = { hash };
215            converted_value = rb_class_new_instance(1, args, type_class);
216          }
217        }
218
219        // raise if no suitable conversaion could be found
220        if (converted_value == Qnil) {
221          rb_raise(cTypeError,
222                   "Invalid type %s to assign to submessage field '%s'.",
223                  rb_class2name(CLASS_OF(value)), name);
224        } else {
225          value = converted_value;
226        }
227      }
228      DEREF(memory, VALUE) = value;
229      break;
230    }
231    case UPB_TYPE_ENUM: {
232      int32_t int_val = 0;
233      if (TYPE(value) == T_STRING) {
234        value = rb_funcall(value, rb_intern("to_sym"), 0);
235      } else if (!is_ruby_num(value) && TYPE(value) != T_SYMBOL) {
236        rb_raise(cTypeError,
237                 "Expected number or symbol type for enum field '%s'.", name);
238      }
239      if (TYPE(value) == T_SYMBOL) {
240        // Ensure that the given symbol exists in the enum module.
241        VALUE lookup = rb_funcall(type_class, rb_intern("resolve"), 1, value);
242        if (lookup == Qnil) {
243          rb_raise(rb_eRangeError, "Unknown symbol value for enum field '%s'.", name);
244        } else {
245          int_val = NUM2INT(lookup);
246        }
247      } else {
248        native_slot_check_int_range_precision(name, UPB_TYPE_INT32, value);
249        int_val = NUM2INT(value);
250      }
251      DEREF(memory, int32_t) = int_val;
252      break;
253    }
254    case UPB_TYPE_INT32:
255    case UPB_TYPE_INT64:
256    case UPB_TYPE_UINT32:
257    case UPB_TYPE_UINT64:
258      native_slot_check_int_range_precision(name, type, value);
259      switch (type) {
260      case UPB_TYPE_INT32:
261        DEREF(memory, int32_t) = NUM2INT(value);
262        break;
263      case UPB_TYPE_INT64:
264        DEREF(memory, int64_t) = NUM2LL(value);
265        break;
266      case UPB_TYPE_UINT32:
267        DEREF(memory, uint32_t) = NUM2UINT(value);
268        break;
269      case UPB_TYPE_UINT64:
270        DEREF(memory, uint64_t) = NUM2ULL(value);
271        break;
272      default:
273        break;
274      }
275      break;
276    default:
277      break;
278  }
279
280  if (case_memory != NULL) {
281    *case_memory = case_number;
282  }
283}
284
285VALUE native_slot_get(upb_fieldtype_t type,
286                      VALUE type_class,
287                      const void* memory) {
288  switch (type) {
289    case UPB_TYPE_FLOAT:
290      return DBL2NUM(DEREF(memory, float));
291    case UPB_TYPE_DOUBLE:
292      return DBL2NUM(DEREF(memory, double));
293    case UPB_TYPE_BOOL:
294      return DEREF(memory, int8_t) ? Qtrue : Qfalse;
295    case UPB_TYPE_STRING:
296    case UPB_TYPE_BYTES:
297      return DEREF(memory, VALUE);
298    case UPB_TYPE_MESSAGE: {
299      VALUE val = DEREF(memory, VALUE);
300
301      // Lazily expand wrapper type if necessary.
302      int type = TYPE(val);
303      if (type != T_DATA && type != T_NIL) {
304        // This must be a wrapper type.
305        val = ruby_wrapper_type(type_class, val);
306        DEREF(memory, VALUE) = val;
307      }
308
309      return val;
310    }
311    case UPB_TYPE_ENUM: {
312      int32_t val = DEREF(memory, int32_t);
313      VALUE symbol = enum_lookup(type_class, INT2NUM(val));
314      if (symbol == Qnil) {
315        return INT2NUM(val);
316      } else {
317        return symbol;
318      }
319    }
320    case UPB_TYPE_INT32:
321      return INT2NUM(DEREF(memory, int32_t));
322    case UPB_TYPE_INT64:
323      return LL2NUM(DEREF(memory, int64_t));
324    case UPB_TYPE_UINT32:
325      return UINT2NUM(DEREF(memory, uint32_t));
326    case UPB_TYPE_UINT64:
327      return ULL2NUM(DEREF(memory, uint64_t));
328    default:
329      return Qnil;
330  }
331}
332
333void native_slot_init(upb_fieldtype_t type, void* memory) {
334  switch (type) {
335    case UPB_TYPE_FLOAT:
336      DEREF(memory, float) = 0.0;
337      break;
338    case UPB_TYPE_DOUBLE:
339      DEREF(memory, double) = 0.0;
340      break;
341    case UPB_TYPE_BOOL:
342      DEREF(memory, int8_t) = 0;
343      break;
344    case UPB_TYPE_STRING:
345    case UPB_TYPE_BYTES:
346      DEREF(memory, VALUE) = rb_str_new2("");
347      rb_enc_associate(DEREF(memory, VALUE), (type == UPB_TYPE_BYTES) ?
348                       kRubyString8bitEncoding : kRubyStringUtf8Encoding);
349      break;
350    case UPB_TYPE_MESSAGE:
351      DEREF(memory, VALUE) = Qnil;
352      break;
353    case UPB_TYPE_ENUM:
354    case UPB_TYPE_INT32:
355      DEREF(memory, int32_t) = 0;
356      break;
357    case UPB_TYPE_INT64:
358      DEREF(memory, int64_t) = 0;
359      break;
360    case UPB_TYPE_UINT32:
361      DEREF(memory, uint32_t) = 0;
362      break;
363    case UPB_TYPE_UINT64:
364      DEREF(memory, uint64_t) = 0;
365      break;
366    default:
367      break;
368  }
369}
370
371void native_slot_mark(upb_fieldtype_t type, void* memory) {
372  switch (type) {
373    case UPB_TYPE_STRING:
374    case UPB_TYPE_BYTES:
375    case UPB_TYPE_MESSAGE:
376      rb_gc_mark(DEREF(memory, VALUE));
377      break;
378    default:
379      break;
380  }
381}
382
383void native_slot_dup(upb_fieldtype_t type, void* to, void* from) {
384  memcpy(to, from, native_slot_size(type));
385}
386
387void native_slot_deep_copy(upb_fieldtype_t type, VALUE type_class, void* to,
388                           void* from) {
389  switch (type) {
390    case UPB_TYPE_STRING:
391    case UPB_TYPE_BYTES: {
392      VALUE from_val = DEREF(from, VALUE);
393      DEREF(to, VALUE) = (from_val != Qnil) ?
394          rb_funcall(from_val, rb_intern("dup"), 0) : Qnil;
395      break;
396    }
397    case UPB_TYPE_MESSAGE: {
398      VALUE from_val = native_slot_get(type, type_class, from);
399      DEREF(to, VALUE) = (from_val != Qnil) ?
400          Message_deep_copy(from_val) : Qnil;
401      break;
402    }
403    default:
404      memcpy(to, from, native_slot_size(type));
405  }
406}
407
408bool native_slot_eq(upb_fieldtype_t type, VALUE type_class, void* mem1,
409                    void* mem2) {
410  switch (type) {
411    case UPB_TYPE_STRING:
412    case UPB_TYPE_BYTES:
413    case UPB_TYPE_MESSAGE: {
414      VALUE val1 = native_slot_get(type, type_class, mem1);
415      VALUE val2 = native_slot_get(type, type_class, mem2);
416      VALUE ret = rb_funcall(val1, rb_intern("=="), 1, val2);
417      return ret == Qtrue;
418    }
419    default:
420      return !memcmp(mem1, mem2, native_slot_size(type));
421  }
422}
423
424// -----------------------------------------------------------------------------
425// Map field utilities.
426// -----------------------------------------------------------------------------
427
428const upb_msgdef* tryget_map_entry_msgdef(const upb_fielddef* field) {
429  const upb_msgdef* subdef;
430  if (upb_fielddef_label(field) != UPB_LABEL_REPEATED ||
431      upb_fielddef_type(field) != UPB_TYPE_MESSAGE) {
432    return NULL;
433  }
434  subdef = upb_fielddef_msgsubdef(field);
435  return upb_msgdef_mapentry(subdef) ? subdef : NULL;
436}
437
438const upb_msgdef *map_entry_msgdef(const upb_fielddef* field) {
439  const upb_msgdef* subdef = tryget_map_entry_msgdef(field);
440  assert(subdef);
441  return subdef;
442}
443
444bool is_map_field(const upb_fielddef *field) {
445  const upb_msgdef* subdef = tryget_map_entry_msgdef(field);
446  if (subdef == NULL) return false;
447
448  // Map fields are a proto3 feature.
449  // If we're using proto2 syntax we need to fallback to the repeated field.
450  return upb_msgdef_syntax(subdef) == UPB_SYNTAX_PROTO3;
451}
452
453const upb_fielddef* map_field_key(const upb_fielddef* field) {
454  const upb_msgdef* subdef = map_entry_msgdef(field);
455  return map_entry_key(subdef);
456}
457
458const upb_fielddef* map_field_value(const upb_fielddef* field) {
459  const upb_msgdef* subdef = map_entry_msgdef(field);
460  return map_entry_value(subdef);
461}
462
463const upb_fielddef* map_entry_key(const upb_msgdef* msgdef) {
464  const upb_fielddef* key_field = upb_msgdef_itof(msgdef, MAP_KEY_FIELD);
465  assert(key_field != NULL);
466  return key_field;
467}
468
469const upb_fielddef* map_entry_value(const upb_msgdef* msgdef) {
470  const upb_fielddef* value_field = upb_msgdef_itof(msgdef, MAP_VALUE_FIELD);
471  assert(value_field != NULL);
472  return value_field;
473}
474
475// -----------------------------------------------------------------------------
476// Memory layout management.
477// -----------------------------------------------------------------------------
478
479bool field_contains_hasbit(MessageLayout* layout,
480                            const upb_fielddef* field) {
481  return layout->fields[upb_fielddef_index(field)].hasbit !=
482      MESSAGE_FIELD_NO_HASBIT;
483}
484
485static size_t align_up_to(size_t offset, size_t granularity) {
486  // Granularity must be a power of two.
487  return (offset + granularity - 1) & ~(granularity - 1);
488}
489
490bool is_value_field(const upb_fielddef* f) {
491  return upb_fielddef_isseq(f) || upb_fielddef_issubmsg(f) ||
492         upb_fielddef_isstring(f);
493}
494
495void create_layout(Descriptor* desc) {
496  const upb_msgdef *msgdef = desc->msgdef;
497  MessageLayout* layout = ALLOC(MessageLayout);
498  int nfields = upb_msgdef_numfields(msgdef);
499  int noneofs = upb_msgdef_numrealoneofs(msgdef);
500  upb_msg_field_iter it;
501  upb_msg_oneof_iter oit;
502  size_t off = 0;
503  size_t hasbit = 0;
504  int i;
505
506  (void)i;
507
508  layout->empty_template = NULL;
509  layout->desc = desc;
510  desc->layout = layout;
511
512  layout->fields = ALLOC_N(MessageField, nfields);
513  layout->oneofs = NULL;
514
515  if (noneofs > 0) {
516    layout->oneofs = ALLOC_N(MessageOneof, noneofs);
517  }
518
519#ifndef NDEBUG
520  for (i = 0; i < nfields; i++) {
521    layout->fields[i].offset = -1;
522  }
523
524  for (i = 0; i < noneofs; i++) {
525    layout->oneofs[i].offset = -1;
526  }
527#endif
528
529  for (upb_msg_field_begin(&it, msgdef);
530       !upb_msg_field_done(&it);
531       upb_msg_field_next(&it)) {
532    const upb_fielddef* field = upb_msg_iter_field(&it);
533    if (upb_fielddef_haspresence(field) &&
534        !upb_fielddef_realcontainingoneof(field)) {
535      layout->fields[upb_fielddef_index(field)].hasbit = hasbit++;
536    } else {
537      layout->fields[upb_fielddef_index(field)].hasbit =
538          MESSAGE_FIELD_NO_HASBIT;
539    }
540  }
541
542  if (hasbit != 0) {
543    off += (hasbit + 8 - 1) / 8;
544  }
545
546  off = align_up_to(off, sizeof(VALUE));
547  layout->value_offset = off;
548  layout->repeated_count = 0;
549  layout->map_count = 0;
550  layout->value_count = 0;
551
552  // Place all VALUE fields for repeated fields.
553  for (upb_msg_field_begin(&it, msgdef);
554       !upb_msg_field_done(&it);
555       upb_msg_field_next(&it)) {
556    const upb_fielddef* field = upb_msg_iter_field(&it);
557    if (upb_fielddef_realcontainingoneof(field) || !upb_fielddef_isseq(field) ||
558        upb_fielddef_ismap(field)) {
559      continue;
560    }
561
562    layout->fields[upb_fielddef_index(field)].offset = off;
563    off += sizeof(VALUE);
564    layout->repeated_count++;
565  }
566
567  // Place all VALUE fields for map fields.
568  for (upb_msg_field_begin(&it, msgdef);
569       !upb_msg_field_done(&it);
570       upb_msg_field_next(&it)) {
571    const upb_fielddef* field = upb_msg_iter_field(&it);
572    if (upb_fielddef_realcontainingoneof(field) || !upb_fielddef_isseq(field) ||
573        !upb_fielddef_ismap(field)) {
574      continue;
575    }
576
577    layout->fields[upb_fielddef_index(field)].offset = off;
578    off += sizeof(VALUE);
579    layout->map_count++;
580  }
581
582  layout->value_count = layout->repeated_count + layout->map_count;
583
584  // Next place all other (non-oneof) VALUE fields.
585  for (upb_msg_field_begin(&it, msgdef);
586       !upb_msg_field_done(&it);
587       upb_msg_field_next(&it)) {
588    const upb_fielddef* field = upb_msg_iter_field(&it);
589    if (upb_fielddef_realcontainingoneof(field) || !is_value_field(field) ||
590        upb_fielddef_isseq(field)) {
591      continue;
592    }
593
594    layout->fields[upb_fielddef_index(field)].offset = off;
595    off += sizeof(VALUE);
596    layout->value_count++;
597  }
598
599  // Now place all other (non-oneof) fields.
600  for (upb_msg_field_begin(&it, msgdef);
601       !upb_msg_field_done(&it);
602       upb_msg_field_next(&it)) {
603    const upb_fielddef* field = upb_msg_iter_field(&it);
604    size_t field_size;
605
606    if (upb_fielddef_realcontainingoneof(field) || is_value_field(field)) {
607      continue;
608    }
609
610    // Allocate |field_size| bytes for this field in the layout.
611    field_size = native_slot_size(upb_fielddef_type(field));
612
613    // Align current offset up to |size| granularity.
614    off = align_up_to(off, field_size);
615    layout->fields[upb_fielddef_index(field)].offset = off;
616    off += field_size;
617  }
618
619  // Handle oneofs now -- we iterate over oneofs specifically and allocate only
620  // one slot per oneof.
621  //
622  // We assign all value slots first, then pack the 'case' fields at the end,
623  // since in the common case (modern 64-bit platform) these are 8 bytes and 4
624  // bytes respectively and we want to avoid alignment overhead.
625  //
626  // Note that we reserve 4 bytes (a uint32) per 'case' slot because the value
627  // space for oneof cases is conceptually as wide as field tag numbers. In
628  // practice, it's unlikely that a oneof would have more than e.g. 256 or 64K
629  // members (8 or 16 bits respectively), so conceivably we could assign
630  // consecutive case numbers and then pick a smaller oneof case slot size, but
631  // the complexity to implement this indirection is probably not worthwhile.
632  for (upb_msg_oneof_begin(&oit, msgdef);
633       !upb_msg_oneof_done(&oit);
634       upb_msg_oneof_next(&oit)) {
635    const upb_oneofdef* oneof = upb_msg_iter_oneof(&oit);
636    upb_oneof_iter fit;
637
638    // Always allocate NATIVE_SLOT_MAX_SIZE bytes, but share the slot between
639    // all fields.
640    size_t field_size = NATIVE_SLOT_MAX_SIZE;
641
642    if (upb_oneofdef_issynthetic(oneof)) continue;
643    assert(upb_oneofdef_index(oneof) < noneofs);
644
645    // Align the offset.
646    off = align_up_to(off, field_size);
647    // Assign all fields in the oneof this same offset.
648    for (upb_oneof_begin(&fit, oneof);
649         !upb_oneof_done(&fit);
650         upb_oneof_next(&fit)) {
651      const upb_fielddef* field = upb_oneof_iter_field(&fit);
652      layout->fields[upb_fielddef_index(field)].offset = off;
653      layout->oneofs[upb_oneofdef_index(oneof)].offset = off;
654    }
655    off += field_size;
656  }
657
658  // Now the case fields.
659  for (upb_msg_oneof_begin(&oit, msgdef);
660       !upb_msg_oneof_done(&oit);
661       upb_msg_oneof_next(&oit)) {
662    const upb_oneofdef* oneof = upb_msg_iter_oneof(&oit);
663    size_t field_size = sizeof(uint32_t);
664    if (upb_oneofdef_issynthetic(oneof)) continue;
665    assert(upb_oneofdef_index(oneof) < noneofs);
666    // Align the offset.
667    off = (off + field_size - 1) & ~(field_size - 1);
668    layout->oneofs[upb_oneofdef_index(oneof)].case_offset = off;
669    off += field_size;
670  }
671
672  layout->size = off;
673  layout->msgdef = msgdef;
674
675#ifndef NDEBUG
676  for (i = 0; i < nfields; i++) {
677    assert(layout->fields[i].offset != -1);
678  }
679
680  for (i = 0; i < noneofs; i++) {
681    assert(layout->oneofs[i].offset != -1);
682  }
683#endif
684
685  // Create the empty message template.
686  layout->empty_template = ALLOC_N(char, layout->size);
687  memset(layout->empty_template, 0, layout->size);
688
689  for (upb_msg_field_begin(&it, layout->msgdef);
690       !upb_msg_field_done(&it);
691       upb_msg_field_next(&it)) {
692    layout_clear(layout, layout->empty_template, upb_msg_iter_field(&it));
693  }
694}
695
696void free_layout(MessageLayout* layout) {
697  xfree(layout->empty_template);
698  xfree(layout->fields);
699  xfree(layout->oneofs);
700  xfree(layout);
701}
702
703VALUE field_type_class(const MessageLayout* layout, const upb_fielddef* field) {
704  VALUE type_class = Qnil;
705  if (upb_fielddef_type(field) == UPB_TYPE_MESSAGE) {
706    VALUE submsgdesc = get_msgdef_obj(layout->desc->descriptor_pool,
707                                      upb_fielddef_msgsubdef(field));
708    type_class = Descriptor_msgclass(submsgdesc);
709  } else if (upb_fielddef_type(field) == UPB_TYPE_ENUM) {
710    VALUE subenumdesc = get_enumdef_obj(layout->desc->descriptor_pool,
711                                        upb_fielddef_enumsubdef(field));
712    type_class = EnumDescriptor_enummodule(subenumdesc);
713  }
714  return type_class;
715}
716
717static void* slot_memory(MessageLayout* layout,
718                         const void* storage,
719                         const upb_fielddef* field) {
720  return ((uint8_t *)storage) +
721      layout->fields[upb_fielddef_index(field)].offset;
722}
723
724static uint32_t* slot_oneof_case(MessageLayout* layout,
725                                 const void* storage,
726                                 const upb_oneofdef* oneof) {
727  return (uint32_t*)(((uint8_t*)storage) +
728                     layout->oneofs[upb_oneofdef_index(oneof)].case_offset);
729}
730
731uint32_t slot_read_oneof_case(MessageLayout* layout, const void* storage,
732                              const upb_oneofdef* oneof) {
733  uint32_t* ptr = slot_oneof_case(layout, storage, oneof);
734  return *ptr & ~ONEOF_CASE_MASK;
735}
736
737static void slot_set_hasbit(MessageLayout* layout,
738                            const void* storage,
739                            const upb_fielddef* field) {
740  size_t hasbit = layout->fields[upb_fielddef_index(field)].hasbit;
741  assert(hasbit != MESSAGE_FIELD_NO_HASBIT);
742
743  ((uint8_t*)storage)[hasbit / 8] |= 1 << (hasbit % 8);
744}
745
746static void slot_clear_hasbit(MessageLayout* layout,
747                              const void* storage,
748                              const upb_fielddef* field) {
749  size_t hasbit = layout->fields[upb_fielddef_index(field)].hasbit;
750  assert(hasbit != MESSAGE_FIELD_NO_HASBIT);
751  ((uint8_t*)storage)[hasbit / 8] &= ~(1 << (hasbit % 8));
752}
753
754static bool slot_is_hasbit_set(MessageLayout* layout,
755                            const void* storage,
756                            const upb_fielddef* field) {
757  size_t hasbit = layout->fields[upb_fielddef_index(field)].hasbit;
758  assert(field_contains_hasbit(layout, field));
759  return DEREF_OFFSET(
760      (uint8_t*)storage, hasbit / 8, char) & (1 << (hasbit % 8));
761}
762
763VALUE layout_has(MessageLayout* layout,
764                 const void* storage,
765                 const upb_fielddef* field) {
766  const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(field);
767  assert(upb_fielddef_haspresence(field));
768  if (oneof) {
769    uint32_t oneof_case = slot_read_oneof_case(layout, storage, oneof);
770    return oneof_case == upb_fielddef_number(field) ? Qtrue : Qfalse;
771  } else {
772    return slot_is_hasbit_set(layout, storage, field) ? Qtrue : Qfalse;
773  }
774}
775
776void layout_clear(MessageLayout* layout,
777                 const void* storage,
778                 const upb_fielddef* field) {
779  void* memory = slot_memory(layout, storage, field);
780  const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(field);
781
782  if (field_contains_hasbit(layout, field)) {
783    slot_clear_hasbit(layout, storage, field);
784  }
785
786  if (oneof) {
787    uint32_t* oneof_case = slot_oneof_case(layout, storage, oneof);
788    memset(memory, 0, NATIVE_SLOT_MAX_SIZE);
789    *oneof_case = ONEOF_CASE_NONE;
790  } else if (is_map_field(field)) {
791    VALUE map = Qnil;
792
793    const upb_fielddef* key_field = map_field_key(field);
794    const upb_fielddef* value_field = map_field_value(field);
795    VALUE type_class = field_type_class(layout, value_field);
796
797    if (type_class != Qnil) {
798      VALUE args[3] = {
799        fieldtype_to_ruby(upb_fielddef_type(key_field)),
800        fieldtype_to_ruby(upb_fielddef_type(value_field)),
801        type_class,
802      };
803      map = rb_class_new_instance(3, args, cMap);
804    } else {
805      VALUE args[2] = {
806        fieldtype_to_ruby(upb_fielddef_type(key_field)),
807        fieldtype_to_ruby(upb_fielddef_type(value_field)),
808      };
809      map = rb_class_new_instance(2, args, cMap);
810    }
811
812    DEREF(memory, VALUE) = map;
813  } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
814    VALUE ary = Qnil;
815
816    VALUE type_class = field_type_class(layout, field);
817
818    if (type_class != Qnil) {
819      VALUE args[2] = {
820        fieldtype_to_ruby(upb_fielddef_type(field)),
821        type_class,
822      };
823      ary = rb_class_new_instance(2, args, cRepeatedField);
824    } else {
825      VALUE args[1] = { fieldtype_to_ruby(upb_fielddef_type(field)) };
826      ary = rb_class_new_instance(1, args, cRepeatedField);
827    }
828
829    DEREF(memory, VALUE) = ary;
830  } else {
831    native_slot_set(upb_fielddef_name(field), upb_fielddef_type(field),
832                    field_type_class(layout, field), memory,
833                    layout_get_default(field));
834  }
835}
836
837VALUE layout_get_default(const upb_fielddef *field) {
838  switch (upb_fielddef_type(field)) {
839    case UPB_TYPE_FLOAT:   return DBL2NUM(upb_fielddef_defaultfloat(field));
840    case UPB_TYPE_DOUBLE:  return DBL2NUM(upb_fielddef_defaultdouble(field));
841    case UPB_TYPE_BOOL:
842      return upb_fielddef_defaultbool(field) ? Qtrue : Qfalse;
843    case UPB_TYPE_MESSAGE: return Qnil;
844    case UPB_TYPE_ENUM: {
845      const upb_enumdef *enumdef = upb_fielddef_enumsubdef(field);
846      int32_t num = upb_fielddef_defaultint32(field);
847      const char *label = upb_enumdef_iton(enumdef, num);
848      if (label) {
849        return ID2SYM(rb_intern(label));
850      } else {
851        return INT2NUM(num);
852      }
853    }
854    case UPB_TYPE_INT32:   return INT2NUM(upb_fielddef_defaultint32(field));
855    case UPB_TYPE_INT64:   return LL2NUM(upb_fielddef_defaultint64(field));;
856    case UPB_TYPE_UINT32:  return UINT2NUM(upb_fielddef_defaultuint32(field));
857    case UPB_TYPE_UINT64:  return ULL2NUM(upb_fielddef_defaultuint64(field));
858    case UPB_TYPE_STRING:
859    case UPB_TYPE_BYTES: {
860      size_t size;
861      const char *str = upb_fielddef_defaultstr(field, &size);
862      return get_frozen_string(str, size,
863                               upb_fielddef_type(field) == UPB_TYPE_BYTES);
864    }
865    default: return Qnil;
866  }
867}
868
869VALUE layout_get(MessageLayout* layout,
870                 const void* storage,
871                 const upb_fielddef* field) {
872  void* memory = slot_memory(layout, storage, field);
873  const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(field);
874  bool field_set;
875  if (field_contains_hasbit(layout, field)) {
876    field_set = slot_is_hasbit_set(layout, storage, field);
877  } else {
878    field_set = true;
879  }
880
881  if (oneof) {
882    uint32_t oneof_case = slot_read_oneof_case(layout, storage, oneof);
883    if (oneof_case != upb_fielddef_number(field)) {
884      return layout_get_default(field);
885    }
886    return native_slot_get(upb_fielddef_type(field),
887                           field_type_class(layout, field), memory);
888  } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
889    return *((VALUE *)memory);
890  } else if (!field_set) {
891    return layout_get_default(field);
892  } else {
893    return native_slot_get(upb_fielddef_type(field),
894                           field_type_class(layout, field), memory);
895  }
896}
897
898static void check_repeated_field_type(const MessageLayout* layout, VALUE val,
899                                      const upb_fielddef* field) {
900  RepeatedField* self;
901  assert(upb_fielddef_label(field) == UPB_LABEL_REPEATED);
902
903  if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) ||
904      RTYPEDDATA_TYPE(val) != &RepeatedField_type) {
905    rb_raise(cTypeError, "Expected repeated field array");
906  }
907
908  self = ruby_to_RepeatedField(val);
909  if (self->field_type != upb_fielddef_type(field)) {
910    rb_raise(cTypeError, "Repeated field array has wrong element type");
911  }
912
913  if (self->field_type_class != field_type_class(layout, field)) {
914    rb_raise(cTypeError, "Repeated field array has wrong message/enum class");
915  }
916}
917
918static void check_map_field_type(const MessageLayout* layout, VALUE val,
919                                 const upb_fielddef* field) {
920  const upb_fielddef* key_field = map_field_key(field);
921  const upb_fielddef* value_field = map_field_value(field);
922  Map* self;
923
924  if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) ||
925      RTYPEDDATA_TYPE(val) != &Map_type) {
926    rb_raise(cTypeError, "Expected Map instance");
927  }
928
929  self = ruby_to_Map(val);
930  if (self->key_type != upb_fielddef_type(key_field)) {
931    rb_raise(cTypeError, "Map key type does not match field's key type");
932  }
933  if (self->value_type != upb_fielddef_type(value_field)) {
934    rb_raise(cTypeError, "Map value type does not match field's value type");
935  }
936  if (self->value_type_class != field_type_class(layout, value_field)) {
937    rb_raise(cTypeError, "Map value type has wrong message/enum class");
938  }
939}
940
941void layout_set(MessageLayout* layout,
942                void* storage,
943                const upb_fielddef* field,
944                VALUE val) {
945  void* memory = slot_memory(layout, storage, field);
946  const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(field);
947
948  if (oneof) {
949    uint32_t* oneof_case = slot_oneof_case(layout, storage, oneof);
950    if (val == Qnil) {
951      // Assigning nil to a oneof field clears the oneof completely.
952      *oneof_case = ONEOF_CASE_NONE;
953      memset(memory, 0, NATIVE_SLOT_MAX_SIZE);
954    } else {
955      // The transition between field types for a single oneof (union) slot is
956      // somewhat complex because we need to ensure that a GC triggered at any
957      // point by a call into the Ruby VM sees a valid state for this field and
958      // does not either go off into the weeds (following what it thinks is a
959      // VALUE but is actually a different field type) or miss an object (seeing
960      // what it thinks is a primitive field but is actually a VALUE for the new
961      // field type).
962      //
963      // In order for the transition to be safe, the oneof case slot must be in
964      // sync with the value slot whenever the Ruby VM has been called. Thus, we
965      // use native_slot_set_value_and_case(), which ensures that both the value
966      // and case number are altered atomically (w.r.t. the Ruby VM).
967      uint32_t case_value = upb_fielddef_number(field);
968      if (upb_fielddef_issubmsg(field) || upb_fielddef_isstring(field)) {
969        case_value |= ONEOF_CASE_MASK;
970      }
971
972      native_slot_set_value_and_case(
973          upb_fielddef_name(field), upb_fielddef_type(field),
974          field_type_class(layout, field), memory, val, oneof_case, case_value);
975    }
976  } else if (is_map_field(field)) {
977    check_map_field_type(layout, val, field);
978    DEREF(memory, VALUE) = val;
979  } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
980    check_repeated_field_type(layout, val, field);
981    DEREF(memory, VALUE) = val;
982  } else {
983    native_slot_set(upb_fielddef_name(field), upb_fielddef_type(field),
984                    field_type_class(layout, field), memory, val);
985  }
986
987  if (layout->fields[upb_fielddef_index(field)].hasbit !=
988      MESSAGE_FIELD_NO_HASBIT) {
989    if (val == Qnil) {
990      // No other field type has a hasbit and allows nil assignment.
991      if (upb_fielddef_type(field) != UPB_TYPE_MESSAGE) {
992        fprintf(stderr, "field: %s\n", upb_fielddef_fullname(field));
993      }
994      assert(upb_fielddef_type(field) == UPB_TYPE_MESSAGE);
995      slot_clear_hasbit(layout, storage, field);
996    } else {
997      slot_set_hasbit(layout, storage, field);
998    }
999  }
1000}
1001
1002void layout_init(MessageLayout* layout, void* storage) {
1003  VALUE* value = (VALUE*)CHARPTR_AT(storage, layout->value_offset);
1004  int i;
1005
1006  for (i = 0; i < layout->repeated_count; i++, value++) {
1007    *value = RepeatedField_new_this_type(*value);
1008  }
1009
1010  for (i = 0; i < layout->map_count; i++, value++) {
1011    *value = Map_new_this_type(*value);
1012  }
1013}
1014
1015void layout_mark(MessageLayout* layout, void* storage) {
1016  VALUE* values = (VALUE*)CHARPTR_AT(storage, layout->value_offset);
1017  int noneofs = upb_msgdef_numrealoneofs(layout->msgdef);
1018  int i;
1019
1020  for (i = 0; i < layout->value_count; i++) {
1021    rb_gc_mark(values[i]);
1022  }
1023
1024  for (i = 0; i < noneofs; i++) {
1025    MessageOneof* oneof = &layout->oneofs[i];
1026    uint32_t* case_ptr = (uint32_t*)CHARPTR_AT(storage, oneof->case_offset);
1027    if (*case_ptr & ONEOF_CASE_MASK) {
1028      rb_gc_mark(DEREF_OFFSET(storage, oneof->offset, VALUE));
1029    }
1030  }
1031}
1032
1033void layout_dup(MessageLayout* layout, void* to, void* from) {
1034  upb_msg_field_iter it;
1035  for (upb_msg_field_begin(&it, layout->msgdef);
1036       !upb_msg_field_done(&it);
1037       upb_msg_field_next(&it)) {
1038    const upb_fielddef* field = upb_msg_iter_field(&it);
1039    const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(field);
1040
1041    void* to_memory = slot_memory(layout, to, field);
1042    void* from_memory = slot_memory(layout, from, field);
1043
1044    if (oneof) {
1045      uint32_t* to_oneof_case = slot_oneof_case(layout, to, oneof);
1046      uint32_t* from_oneof_case = slot_oneof_case(layout, from, oneof);
1047      if (slot_read_oneof_case(layout, from, oneof) ==
1048          upb_fielddef_number(field)) {
1049        *to_oneof_case = *from_oneof_case;
1050        native_slot_dup(upb_fielddef_type(field), to_memory, from_memory);
1051      }
1052    } else if (is_map_field(field)) {
1053      DEREF(to_memory, VALUE) = Map_dup(DEREF(from_memory, VALUE));
1054    } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
1055      DEREF(to_memory, VALUE) = RepeatedField_dup(DEREF(from_memory, VALUE));
1056    } else {
1057      if (field_contains_hasbit(layout, field)) {
1058        if (!slot_is_hasbit_set(layout, from, field)) continue;
1059        slot_set_hasbit(layout, to, field);
1060      }
1061
1062      native_slot_dup(upb_fielddef_type(field), to_memory, from_memory);
1063    }
1064  }
1065}
1066
1067void layout_deep_copy(MessageLayout* layout, void* to, void* from) {
1068  upb_msg_field_iter it;
1069  for (upb_msg_field_begin(&it, layout->msgdef);
1070       !upb_msg_field_done(&it);
1071       upb_msg_field_next(&it)) {
1072    const upb_fielddef* field = upb_msg_iter_field(&it);
1073    const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(field);
1074
1075    void* to_memory = slot_memory(layout, to, field);
1076    void* from_memory = slot_memory(layout, from, field);
1077
1078    if (oneof) {
1079      uint32_t* to_oneof_case = slot_oneof_case(layout, to, oneof);
1080      uint32_t* from_oneof_case = slot_oneof_case(layout, from, oneof);
1081      if (slot_read_oneof_case(layout, from, oneof) ==
1082          upb_fielddef_number(field)) {
1083        *to_oneof_case = *from_oneof_case;
1084        native_slot_deep_copy(upb_fielddef_type(field),
1085                              field_type_class(layout, field), to_memory,
1086                              from_memory);
1087      }
1088    } else if (is_map_field(field)) {
1089      DEREF(to_memory, VALUE) =
1090          Map_deep_copy(DEREF(from_memory, VALUE));
1091    } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
1092      DEREF(to_memory, VALUE) =
1093          RepeatedField_deep_copy(DEREF(from_memory, VALUE));
1094    } else {
1095      if (field_contains_hasbit(layout, field)) {
1096        if (!slot_is_hasbit_set(layout, from, field)) continue;
1097        slot_set_hasbit(layout, to, field);
1098      }
1099
1100      native_slot_deep_copy(upb_fielddef_type(field),
1101                            field_type_class(layout, field), to_memory,
1102                            from_memory);
1103    }
1104  }
1105}
1106
1107VALUE layout_eq(MessageLayout* layout, void* msg1, void* msg2) {
1108  upb_msg_field_iter it;
1109  for (upb_msg_field_begin(&it, layout->msgdef);
1110       !upb_msg_field_done(&it);
1111       upb_msg_field_next(&it)) {
1112    const upb_fielddef* field = upb_msg_iter_field(&it);
1113    const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(field);
1114
1115    void* msg1_memory = slot_memory(layout, msg1, field);
1116    void* msg2_memory = slot_memory(layout, msg2, field);
1117
1118    if (oneof) {
1119      uint32_t* msg1_oneof_case = slot_oneof_case(layout, msg1, oneof);
1120      uint32_t* msg2_oneof_case = slot_oneof_case(layout, msg2, oneof);
1121      if (*msg1_oneof_case != *msg2_oneof_case ||
1122          (slot_read_oneof_case(layout, msg1, oneof) ==
1123               upb_fielddef_number(field) &&
1124           !native_slot_eq(upb_fielddef_type(field),
1125                           field_type_class(layout, field), msg1_memory,
1126                           msg2_memory))) {
1127        return Qfalse;
1128      }
1129    } else if (is_map_field(field)) {
1130      if (!Map_eq(DEREF(msg1_memory, VALUE),
1131                  DEREF(msg2_memory, VALUE))) {
1132        return Qfalse;
1133      }
1134    } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
1135      if (!RepeatedField_eq(DEREF(msg1_memory, VALUE),
1136                            DEREF(msg2_memory, VALUE))) {
1137        return Qfalse;
1138      }
1139    } else {
1140      if (field_contains_hasbit(layout, field) &&
1141          slot_is_hasbit_set(layout, msg1, field) !=
1142              slot_is_hasbit_set(layout, msg2, field)) {
1143        // TODO(haberman): I don't think we should actually care about hasbits
1144        // here: an unset default should be able to equal a set default. But we
1145        // can address this later (will also have to make sure defaults are
1146        // being properly set when hasbit is clear).
1147        return Qfalse;
1148      }
1149      if (!native_slot_eq(upb_fielddef_type(field),
1150                          field_type_class(layout, field), msg1_memory,
1151                          msg2_memory)) {
1152        return Qfalse;
1153      }
1154    }
1155  }
1156  return Qtrue;
1157}
1158
1159VALUE layout_hash(MessageLayout* layout, void* storage) {
1160  upb_msg_field_iter it;
1161  st_index_t h = rb_hash_start(0);
1162  VALUE hash_sym = rb_intern("hash");
1163  for (upb_msg_field_begin(&it, layout->msgdef);
1164       !upb_msg_field_done(&it);
1165       upb_msg_field_next(&it)) {
1166    const upb_fielddef* field = upb_msg_iter_field(&it);
1167    VALUE field_val = layout_get(layout, storage, field);
1168    h = rb_hash_uint(h, NUM2LONG(rb_funcall(field_val, hash_sym, 0)));
1169  }
1170  h = rb_hash_end(h);
1171
1172  return INT2FIX(h);
1173}
1174
1175VALUE layout_inspect(MessageLayout* layout, void* storage) {
1176  VALUE str = rb_str_new2("");
1177
1178  upb_msg_field_iter it;
1179  bool first = true;
1180  for (upb_msg_field_begin(&it, layout->msgdef);
1181       !upb_msg_field_done(&it);
1182       upb_msg_field_next(&it)) {
1183    const upb_fielddef* field = upb_msg_iter_field(&it);
1184    VALUE field_val = layout_get(layout, storage, field);
1185
1186    if (!first) {
1187      str = rb_str_cat2(str, ", ");
1188    } else {
1189      first = false;
1190    }
1191    str = rb_str_cat2(str, upb_fielddef_name(field));
1192    str = rb_str_cat2(str, ": ");
1193
1194    str = rb_str_append(str, rb_funcall(field_val, rb_intern("inspect"), 0));
1195  }
1196
1197  return str;
1198}
1199