google-protobuf 3.0.0.alpha.1.0 → 3.0.0.alpha.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of google-protobuf might be problematic. Click here for more details.

@@ -139,7 +139,14 @@ int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) {
139
139
  "Unknown field name in initialization map entry.");
140
140
  }
141
141
 
142
- if (upb_fielddef_label(f) == UPB_LABEL_REPEATED) {
142
+ if (is_map_field(f)) {
143
+ if (TYPE(val) != T_HASH) {
144
+ rb_raise(rb_eArgError,
145
+ "Expected Hash object as initializer value for map field.");
146
+ }
147
+ VALUE map = layout_get(self->descriptor->layout, Message_data(self), f);
148
+ Map_merge_into_self(map, val);
149
+ } else if (upb_fielddef_label(f) == UPB_LABEL_REPEATED) {
143
150
  if (TYPE(val) != T_ARRAY) {
144
151
  rb_raise(rb_eArgError,
145
152
  "Expected array as initializer value for repeated field.");
@@ -450,13 +457,15 @@ VALUE build_module_from_enumdesc(EnumDescriptor* enumdesc) {
450
457
  * call-seq:
451
458
  * Google::Protobuf.deep_copy(obj) => copy_of_obj
452
459
  *
453
- * Performs a deep copy of either a RepeatedField instance or a message object,
454
- * recursively copying its members.
460
+ * Performs a deep copy of a RepeatedField instance, a Map instance, or a
461
+ * message object, recursively copying its members.
455
462
  */
456
463
  VALUE Google_Protobuf_deep_copy(VALUE self, VALUE obj) {
457
464
  VALUE klass = CLASS_OF(obj);
458
465
  if (klass == cRepeatedField) {
459
466
  return RepeatedField_deep_copy(obj);
467
+ } else if (klass == cMap) {
468
+ return Map_deep_copy(obj);
460
469
  } else {
461
470
  return Message_deep_copy(obj);
462
471
  }
@@ -82,6 +82,7 @@ void Init_protobuf_c() {
82
82
  EnumBuilderContext_register(internal);
83
83
  Builder_register(internal);
84
84
  RepeatedField_register(protobuf);
85
+ Map_register(protobuf);
85
86
 
86
87
  rb_define_singleton_method(protobuf, "encode", Google_Protobuf_encode, 1);
87
88
  rb_define_singleton_method(protobuf, "decode", Google_Protobuf_decode, 2);
@@ -110,6 +110,10 @@ struct Descriptor {
110
110
  const upb_pbdecodermethod* fill_method;
111
111
  const upb_handlers* pb_serialize_handlers;
112
112
  const upb_handlers* json_serialize_handlers;
113
+ // Handlers hold type class references for sub-message fields directly in some
114
+ // cases. We need to keep these rooted because they might otherwise be
115
+ // collected.
116
+ VALUE typeclass_references;
113
117
  };
114
118
 
115
119
  struct FieldDescriptor {
@@ -123,6 +127,7 @@ struct EnumDescriptor {
123
127
 
124
128
  struct MessageBuilderContext {
125
129
  VALUE descriptor;
130
+ VALUE builder;
126
131
  };
127
132
 
128
133
  struct EnumBuilderContext {
@@ -213,10 +218,13 @@ void MessageBuilderContext_free(void* _self);
213
218
  VALUE MessageBuilderContext_alloc(VALUE klass);
214
219
  void MessageBuilderContext_register(VALUE module);
215
220
  MessageBuilderContext* ruby_to_MessageBuilderContext(VALUE value);
216
- VALUE MessageBuilderContext_initialize(VALUE _self, VALUE descriptor);
221
+ VALUE MessageBuilderContext_initialize(VALUE _self,
222
+ VALUE descriptor,
223
+ VALUE builder);
217
224
  VALUE MessageBuilderContext_optional(int argc, VALUE* argv, VALUE _self);
218
225
  VALUE MessageBuilderContext_required(int argc, VALUE* argv, VALUE _self);
219
226
  VALUE MessageBuilderContext_repeated(int argc, VALUE* argv, VALUE _self);
227
+ VALUE MessageBuilderContext_map(int argc, VALUE* argv, VALUE _self);
220
228
 
221
229
  void EnumBuilderContext_mark(void* _self);
222
230
  void EnumBuilderContext_free(void* _self);
@@ -239,6 +247,8 @@ VALUE Builder_finalize_to_pool(VALUE _self, VALUE pool_rb);
239
247
  // Native slot storage abstraction.
240
248
  // -----------------------------------------------------------------------------
241
249
 
250
+ #define NATIVE_SLOT_MAX_SIZE sizeof(void*)
251
+
242
252
  size_t native_slot_size(upb_fieldtype_t type);
243
253
  void native_slot_set(upb_fieldtype_t type,
244
254
  VALUE type_class,
@@ -246,7 +256,7 @@ void native_slot_set(upb_fieldtype_t type,
246
256
  VALUE value);
247
257
  VALUE native_slot_get(upb_fieldtype_t type,
248
258
  VALUE type_class,
249
- void* memory);
259
+ const void* memory);
250
260
  void native_slot_init(upb_fieldtype_t type, void* memory);
251
261
  void native_slot_mark(upb_fieldtype_t type, void* memory);
252
262
  void native_slot_dup(upb_fieldtype_t type, void* to, void* from);
@@ -254,11 +264,27 @@ void native_slot_deep_copy(upb_fieldtype_t type, void* to, void* from);
254
264
  bool native_slot_eq(upb_fieldtype_t type, void* mem1, void* mem2);
255
265
 
256
266
  void native_slot_validate_string_encoding(upb_fieldtype_t type, VALUE value);
267
+ void native_slot_check_int_range_precision(upb_fieldtype_t type, VALUE value);
257
268
 
258
269
  extern rb_encoding* kRubyStringUtf8Encoding;
259
270
  extern rb_encoding* kRubyStringASCIIEncoding;
260
271
  extern rb_encoding* kRubyString8bitEncoding;
261
272
 
273
+ VALUE field_type_class(const upb_fielddef* field);
274
+
275
+ #define MAP_KEY_FIELD 1
276
+ #define MAP_VALUE_FIELD 2
277
+
278
+ // These operate on a map field (i.e., a repeated field of submessages whose
279
+ // submessage type is a map-entry msgdef).
280
+ bool is_map_field(const upb_fielddef* field);
281
+ const upb_fielddef* map_field_key(const upb_fielddef* field);
282
+ const upb_fielddef* map_field_value(const upb_fielddef* field);
283
+
284
+ // These operate on a map-entry msgdef.
285
+ const upb_fielddef* map_entry_key(const upb_msgdef* msgdef);
286
+ const upb_fielddef* map_entry_value(const upb_msgdef* msgdef);
287
+
262
288
  // -----------------------------------------------------------------------------
263
289
  // Repeated field container type.
264
290
  // -----------------------------------------------------------------------------
@@ -282,7 +308,6 @@ extern VALUE cRepeatedField;
282
308
 
283
309
  RepeatedField* ruby_to_RepeatedField(VALUE value);
284
310
 
285
- void RepeatedField_register(VALUE module);
286
311
  VALUE RepeatedField_each(VALUE _self);
287
312
  VALUE RepeatedField_index(VALUE _self, VALUE _index);
288
313
  void* RepeatedField_index_native(VALUE _self, int index);
@@ -302,6 +327,59 @@ VALUE RepeatedField_hash(VALUE _self);
302
327
  VALUE RepeatedField_inspect(VALUE _self);
303
328
  VALUE RepeatedField_plus(VALUE _self, VALUE list);
304
329
 
330
+ // Defined in repeated_field.c; also used by Map.
331
+ void validate_type_class(upb_fieldtype_t type, VALUE klass);
332
+
333
+ // -----------------------------------------------------------------------------
334
+ // Map container type.
335
+ // -----------------------------------------------------------------------------
336
+
337
+ typedef struct {
338
+ upb_fieldtype_t key_type;
339
+ upb_fieldtype_t value_type;
340
+ VALUE value_type_class;
341
+ upb_strtable table;
342
+ } Map;
343
+
344
+ void Map_mark(void* self);
345
+ void Map_free(void* self);
346
+ VALUE Map_alloc(VALUE klass);
347
+ VALUE Map_init(int argc, VALUE* argv, VALUE self);
348
+ void Map_register(VALUE module);
349
+
350
+ extern const rb_data_type_t Map_type;
351
+ extern VALUE cMap;
352
+
353
+ Map* ruby_to_Map(VALUE value);
354
+
355
+ VALUE Map_each(VALUE _self);
356
+ VALUE Map_keys(VALUE _self);
357
+ VALUE Map_values(VALUE _self);
358
+ VALUE Map_index(VALUE _self, VALUE key);
359
+ VALUE Map_index_set(VALUE _self, VALUE key, VALUE value);
360
+ VALUE Map_has_key(VALUE _self, VALUE key);
361
+ VALUE Map_delete(VALUE _self, VALUE key);
362
+ VALUE Map_clear(VALUE _self);
363
+ VALUE Map_length(VALUE _self);
364
+ VALUE Map_dup(VALUE _self);
365
+ VALUE Map_deep_copy(VALUE _self);
366
+ VALUE Map_eq(VALUE _self, VALUE _other);
367
+ VALUE Map_hash(VALUE _self);
368
+ VALUE Map_inspect(VALUE _self);
369
+ VALUE Map_merge(VALUE _self, VALUE hashmap);
370
+ VALUE Map_merge_into_self(VALUE _self, VALUE hashmap);
371
+
372
+ typedef struct {
373
+ Map* self;
374
+ upb_strtable_iter it;
375
+ } Map_iter;
376
+
377
+ void Map_begin(VALUE _self, Map_iter* iter);
378
+ void Map_next(Map_iter* iter);
379
+ bool Map_done(Map_iter* iter);
380
+ VALUE Map_iter_key(Map_iter* iter);
381
+ VALUE Map_iter_value(Map_iter* iter);
382
+
305
383
  // -----------------------------------------------------------------------------
306
384
  // Message layout / storage.
307
385
  // -----------------------------------------------------------------------------
@@ -315,7 +393,7 @@ struct MessageLayout {
315
393
  MessageLayout* create_layout(const upb_msgdef* msgdef);
316
394
  void free_layout(MessageLayout* layout);
317
395
  VALUE layout_get(MessageLayout* layout,
318
- void* storage,
396
+ const void* storage,
319
397
  const upb_fielddef* field);
320
398
  void layout_set(MessageLayout* layout,
321
399
  void* storage,
@@ -324,6 +324,10 @@ VALUE RepeatedField_deep_copy(VALUE _self) {
324
324
  * element types are equal, their lengths are equal, and each element is equal.
325
325
  * Elements are compared as per normal Ruby semantics, by calling their :==
326
326
  * methods (or performing a more efficient comparison for primitive types).
327
+ *
328
+ * Repeated fields with dissimilar element types are never equal, even if value
329
+ * comparison (for example, between integers and floats) would have otherwise
330
+ * indicated that every element has equal value.
327
331
  */
328
332
  VALUE RepeatedField_eq(VALUE _self, VALUE _other) {
329
333
  if (_self == _other) {
@@ -458,7 +462,7 @@ VALUE RepeatedField_plus(VALUE _self, VALUE list) {
458
462
  return dupped;
459
463
  }
460
464
 
461
- static void validate_type_class(upb_fieldtype_t type, VALUE klass) {
465
+ void validate_type_class(upb_fieldtype_t type, VALUE klass) {
462
466
  if (rb_iv_get(klass, kDescriptorInstanceVar) == Qnil) {
463
467
  rb_raise(rb_eArgError,
464
468
  "Type class has no descriptor. Please pass a "
@@ -57,7 +57,17 @@ size_t native_slot_size(upb_fieldtype_t type) {
57
57
  }
58
58
  }
59
59
 
60
- static void check_int_range_precision(upb_fieldtype_t type, VALUE val) {
60
+ static bool is_ruby_num(VALUE value) {
61
+ return (TYPE(value) == T_FLOAT ||
62
+ TYPE(value) == T_FIXNUM ||
63
+ TYPE(value) == T_BIGNUM);
64
+ }
65
+
66
+ void native_slot_check_int_range_precision(upb_fieldtype_t type, VALUE val) {
67
+ if (!is_ruby_num(val)) {
68
+ rb_raise(rb_eTypeError, "Expected number type for integral field.");
69
+ }
70
+
61
71
  // NUM2{INT,UINT,LL,ULL} macros do the appropriate range checks on upper
62
72
  // bound; we just need to do precision checks (i.e., disallow rounding) and
63
73
  // check for < 0 on unsigned types.
@@ -76,12 +86,6 @@ static void check_int_range_precision(upb_fieldtype_t type, VALUE val) {
76
86
  }
77
87
  }
78
88
 
79
- static bool is_ruby_num(VALUE value) {
80
- return (TYPE(value) == T_FLOAT ||
81
- TYPE(value) == T_FIXNUM ||
82
- TYPE(value) == T_BIGNUM);
83
- }
84
-
85
89
  void native_slot_validate_string_encoding(upb_fieldtype_t type, VALUE value) {
86
90
  bool bad_encoding = false;
87
91
  rb_encoding* string_encoding = rb_enc_from_index(ENCODING_GET(value));
@@ -156,14 +160,14 @@ void native_slot_set(upb_fieldtype_t type, VALUE type_class,
156
160
  int32_t int_val = 0;
157
161
  if (TYPE(value) == T_SYMBOL) {
158
162
  // Ensure that the given symbol exists in the enum module.
159
- VALUE lookup = rb_const_get(type_class, SYM2ID(value));
163
+ VALUE lookup = rb_funcall(type_class, rb_intern("resolve"), 1, value);
160
164
  if (lookup == Qnil) {
161
165
  rb_raise(rb_eRangeError, "Unknown symbol value for enum field.");
162
166
  } else {
163
167
  int_val = NUM2INT(lookup);
164
168
  }
165
169
  } else {
166
- check_int_range_precision(UPB_TYPE_INT32, value);
170
+ native_slot_check_int_range_precision(UPB_TYPE_INT32, value);
167
171
  int_val = NUM2INT(value);
168
172
  }
169
173
  DEREF(memory, int32_t) = int_val;
@@ -173,10 +177,7 @@ void native_slot_set(upb_fieldtype_t type, VALUE type_class,
173
177
  case UPB_TYPE_INT64:
174
178
  case UPB_TYPE_UINT32:
175
179
  case UPB_TYPE_UINT64:
176
- if (!is_ruby_num(value)) {
177
- rb_raise(rb_eTypeError, "Expected number type for integral field.");
178
- }
179
- check_int_range_precision(type, value);
180
+ native_slot_check_int_range_precision(type, value);
180
181
  switch (type) {
181
182
  case UPB_TYPE_INT32:
182
183
  DEREF(memory, int32_t) = NUM2INT(value);
@@ -199,7 +200,9 @@ void native_slot_set(upb_fieldtype_t type, VALUE type_class,
199
200
  }
200
201
  }
201
202
 
202
- VALUE native_slot_get(upb_fieldtype_t type, VALUE type_class, void* memory) {
203
+ VALUE native_slot_get(upb_fieldtype_t type,
204
+ VALUE type_class,
205
+ const void* memory) {
203
206
  switch (type) {
204
207
  case UPB_TYPE_FLOAT:
205
208
  return DBL2NUM(DEREF(memory, float));
@@ -210,7 +213,7 @@ VALUE native_slot_get(upb_fieldtype_t type, VALUE type_class, void* memory) {
210
213
  case UPB_TYPE_STRING:
211
214
  case UPB_TYPE_BYTES:
212
215
  case UPB_TYPE_MESSAGE:
213
- return *((VALUE *)memory);
216
+ return DEREF(memory, VALUE);
214
217
  case UPB_TYPE_ENUM: {
215
218
  int32_t val = DEREF(memory, int32_t);
216
219
  VALUE symbol = enum_lookup(type_class, INT2NUM(val));
@@ -246,8 +249,9 @@ void native_slot_init(upb_fieldtype_t type, void* memory) {
246
249
  break;
247
250
  case UPB_TYPE_STRING:
248
251
  case UPB_TYPE_BYTES:
249
- // TODO(cfallin): set encoding appropriately
250
252
  DEREF(memory, VALUE) = rb_str_new2("");
253
+ rb_enc_associate(DEREF(memory, VALUE), (type == UPB_TYPE_BYTES) ?
254
+ kRubyString8bitEncoding : kRubyStringUtf8Encoding);
251
255
  break;
252
256
  case UPB_TYPE_MESSAGE:
253
257
  DEREF(memory, VALUE) = Qnil;
@@ -321,6 +325,43 @@ bool native_slot_eq(upb_fieldtype_t type, void* mem1, void* mem2) {
321
325
  }
322
326
  }
323
327
 
328
+ // -----------------------------------------------------------------------------
329
+ // Map field utilities.
330
+ // -----------------------------------------------------------------------------
331
+
332
+ bool is_map_field(const upb_fielddef* field) {
333
+ if (upb_fielddef_label(field) != UPB_LABEL_REPEATED ||
334
+ upb_fielddef_type(field) != UPB_TYPE_MESSAGE) {
335
+ return false;
336
+ }
337
+ const upb_msgdef* subdef = upb_fielddef_msgsubdef(field);
338
+ return upb_msgdef_mapentry(subdef);
339
+ }
340
+
341
+ const upb_fielddef* map_field_key(const upb_fielddef* field) {
342
+ assert(is_map_field(field));
343
+ const upb_msgdef* subdef = upb_fielddef_msgsubdef(field);
344
+ return map_entry_key(subdef);
345
+ }
346
+
347
+ const upb_fielddef* map_field_value(const upb_fielddef* field) {
348
+ assert(is_map_field(field));
349
+ const upb_msgdef* subdef = upb_fielddef_msgsubdef(field);
350
+ return map_entry_value(subdef);
351
+ }
352
+
353
+ const upb_fielddef* map_entry_key(const upb_msgdef* msgdef) {
354
+ const upb_fielddef* key_field = upb_msgdef_itof(msgdef, MAP_KEY_FIELD);
355
+ assert(key_field != NULL);
356
+ return key_field;
357
+ }
358
+
359
+ const upb_fielddef* map_entry_value(const upb_msgdef* msgdef) {
360
+ const upb_fielddef* value_field = upb_msgdef_itof(msgdef, MAP_VALUE_FIELD);
361
+ assert(value_field != NULL);
362
+ return value_field;
363
+ }
364
+
324
365
  // -----------------------------------------------------------------------------
325
366
  // Memory layout management.
326
367
  // -----------------------------------------------------------------------------
@@ -334,9 +375,12 @@ MessageLayout* create_layout(const upb_msgdef* msgdef) {
334
375
  size_t off = 0;
335
376
  for (upb_msg_begin(&it, msgdef); !upb_msg_done(&it); upb_msg_next(&it)) {
336
377
  const upb_fielddef* field = upb_msg_iter_field(&it);
337
- size_t field_size =
338
- (upb_fielddef_label(field) == UPB_LABEL_REPEATED) ?
339
- sizeof(VALUE) : native_slot_size(upb_fielddef_type(field));
378
+ size_t field_size = 0;
379
+ if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
380
+ field_size = sizeof(VALUE);
381
+ } else {
382
+ field_size = native_slot_size(upb_fielddef_type(field));
383
+ }
340
384
  // align current offset
341
385
  off = (off + field_size - 1) & ~(field_size - 1);
342
386
  layout->offsets[upb_fielddef_index(field)] = off;
@@ -357,7 +401,7 @@ void free_layout(MessageLayout* layout) {
357
401
  xfree(layout);
358
402
  }
359
403
 
360
- static VALUE get_type_class(const upb_fielddef* field) {
404
+ VALUE field_type_class(const upb_fielddef* field) {
361
405
  VALUE type_class = Qnil;
362
406
  if (upb_fielddef_type(field) == UPB_TYPE_MESSAGE) {
363
407
  VALUE submsgdesc =
@@ -372,7 +416,7 @@ static VALUE get_type_class(const upb_fielddef* field) {
372
416
  }
373
417
 
374
418
  VALUE layout_get(MessageLayout* layout,
375
- void* storage,
419
+ const void* storage,
376
420
  const upb_fielddef* field) {
377
421
  void* memory = ((uint8_t *)storage) +
378
422
  layout->offsets[upb_fielddef_index(field)];
@@ -380,7 +424,7 @@ VALUE layout_get(MessageLayout* layout,
380
424
  return *((VALUE *)memory);
381
425
  } else {
382
426
  return native_slot_get(upb_fielddef_type(field),
383
- get_type_class(field),
427
+ field_type_class(field),
384
428
  memory);
385
429
  }
386
430
  }
@@ -398,9 +442,8 @@ static void check_repeated_field_type(VALUE val, const upb_fielddef* field) {
398
442
  rb_raise(rb_eTypeError, "Repeated field array has wrong element type");
399
443
  }
400
444
 
401
- if (upb_fielddef_type(field) == UPB_TYPE_MESSAGE ||
402
- upb_fielddef_type(field) == UPB_TYPE_ENUM) {
403
- RepeatedField* self = ruby_to_RepeatedField(val);
445
+ if (self->field_type == UPB_TYPE_MESSAGE ||
446
+ self->field_type == UPB_TYPE_ENUM) {
404
447
  if (self->field_type_class !=
405
448
  get_def_obj(upb_fielddef_subdef(field))) {
406
449
  rb_raise(rb_eTypeError,
@@ -409,17 +452,48 @@ static void check_repeated_field_type(VALUE val, const upb_fielddef* field) {
409
452
  }
410
453
  }
411
454
 
455
+ static void check_map_field_type(VALUE val, const upb_fielddef* field) {
456
+ assert(is_map_field(field));
457
+ const upb_fielddef* key_field = map_field_key(field);
458
+ const upb_fielddef* value_field = map_field_value(field);
459
+
460
+ if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) ||
461
+ RTYPEDDATA_TYPE(val) != &Map_type) {
462
+ rb_raise(rb_eTypeError, "Expected Map instance");
463
+ }
464
+
465
+ Map* self = ruby_to_Map(val);
466
+ if (self->key_type != upb_fielddef_type(key_field)) {
467
+ rb_raise(rb_eTypeError, "Map key type does not match field's key type");
468
+ }
469
+ if (self->value_type != upb_fielddef_type(value_field)) {
470
+ rb_raise(rb_eTypeError, "Map value type does not match field's value type");
471
+ }
472
+ if (upb_fielddef_type(value_field) == UPB_TYPE_MESSAGE ||
473
+ upb_fielddef_type(value_field) == UPB_TYPE_ENUM) {
474
+ if (self->value_type_class !=
475
+ get_def_obj(upb_fielddef_subdef(value_field))) {
476
+ rb_raise(rb_eTypeError,
477
+ "Map value type has wrong message/enum class");
478
+ }
479
+ }
480
+ }
481
+
482
+
412
483
  void layout_set(MessageLayout* layout,
413
484
  void* storage,
414
485
  const upb_fielddef* field,
415
486
  VALUE val) {
416
487
  void* memory = ((uint8_t *)storage) +
417
488
  layout->offsets[upb_fielddef_index(field)];
418
- if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
489
+ if (is_map_field(field)) {
490
+ check_map_field_type(val, field);
491
+ DEREF(memory, VALUE) = val;
492
+ } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
419
493
  check_repeated_field_type(val, field);
420
- *((VALUE *)memory) = val;
494
+ DEREF(memory, VALUE) = val;
421
495
  } else {
422
- native_slot_set(upb_fielddef_type(field), get_type_class(field),
496
+ native_slot_set(upb_fielddef_type(field), field_type_class(field),
423
497
  memory, val);
424
498
  }
425
499
  }
@@ -434,9 +508,34 @@ void layout_init(MessageLayout* layout,
434
508
  void* memory = ((uint8_t *)storage) +
435
509
  layout->offsets[upb_fielddef_index(field)];
436
510
 
437
- if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
511
+ if (is_map_field(field)) {
512
+ VALUE map = Qnil;
513
+
514
+ const upb_fielddef* key_field = map_field_key(field);
515
+ const upb_fielddef* value_field = map_field_value(field);
516
+ VALUE type_class = field_type_class(value_field);
517
+
518
+ if (type_class != Qnil) {
519
+ VALUE args[3] = {
520
+ fieldtype_to_ruby(upb_fielddef_type(key_field)),
521
+ fieldtype_to_ruby(upb_fielddef_type(value_field)),
522
+ type_class,
523
+ };
524
+ map = rb_class_new_instance(3, args, cMap);
525
+ } else {
526
+ VALUE args[2] = {
527
+ fieldtype_to_ruby(upb_fielddef_type(key_field)),
528
+ fieldtype_to_ruby(upb_fielddef_type(value_field)),
529
+ };
530
+ map = rb_class_new_instance(2, args, cMap);
531
+ }
532
+
533
+ DEREF(memory, VALUE) = map;
534
+ } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
438
535
  VALUE ary = Qnil;
439
- VALUE type_class = get_type_class(field);
536
+
537
+ VALUE type_class = field_type_class(field);
538
+
440
539
  if (type_class != Qnil) {
441
540
  VALUE args[2] = {
442
541
  fieldtype_to_ruby(upb_fielddef_type(field)),
@@ -447,7 +546,8 @@ void layout_init(MessageLayout* layout,
447
546
  VALUE args[1] = { fieldtype_to_ruby(upb_fielddef_type(field)) };
448
547
  ary = rb_class_new_instance(1, args, cRepeatedField);
449
548
  }
450
- *((VALUE *)memory) = ary;
549
+
550
+ DEREF(memory, VALUE) = ary;
451
551
  } else {
452
552
  native_slot_init(upb_fielddef_type(field), memory);
453
553
  }
@@ -464,7 +564,7 @@ void layout_mark(MessageLayout* layout, void* storage) {
464
564
  layout->offsets[upb_fielddef_index(field)];
465
565
 
466
566
  if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
467
- rb_gc_mark(*((VALUE *)memory));
567
+ rb_gc_mark(DEREF(memory, VALUE));
468
568
  } else {
469
569
  native_slot_mark(upb_fielddef_type(field), memory);
470
570
  }
@@ -482,8 +582,10 @@ void layout_dup(MessageLayout* layout, void* to, void* from) {
482
582
  void* from_memory = ((uint8_t *)from) +
483
583
  layout->offsets[upb_fielddef_index(field)];
484
584
 
485
- if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
486
- *((VALUE *)to_memory) = RepeatedField_dup(*((VALUE *)from_memory));
585
+ if (is_map_field(field)) {
586
+ DEREF(to_memory, VALUE) = Map_dup(DEREF(from_memory, VALUE));
587
+ } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
588
+ DEREF(to_memory, VALUE) = RepeatedField_dup(DEREF(from_memory, VALUE));
487
589
  } else {
488
590
  native_slot_dup(upb_fielddef_type(field), to_memory, from_memory);
489
591
  }
@@ -501,8 +603,12 @@ void layout_deep_copy(MessageLayout* layout, void* to, void* from) {
501
603
  void* from_memory = ((uint8_t *)from) +
502
604
  layout->offsets[upb_fielddef_index(field)];
503
605
 
504
- if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
505
- *((VALUE *)to_memory) = RepeatedField_deep_copy(*((VALUE *)from_memory));
606
+ if (is_map_field(field)) {
607
+ DEREF(to_memory, VALUE) =
608
+ Map_deep_copy(DEREF(from_memory, VALUE));
609
+ } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
610
+ DEREF(to_memory, VALUE) =
611
+ RepeatedField_deep_copy(DEREF(from_memory, VALUE));
506
612
  } else {
507
613
  native_slot_deep_copy(upb_fielddef_type(field), to_memory, from_memory);
508
614
  }
@@ -520,11 +626,12 @@ VALUE layout_eq(MessageLayout* layout, void* msg1, void* msg2) {
520
626
  void* msg2_memory = ((uint8_t *)msg2) +
521
627
  layout->offsets[upb_fielddef_index(field)];
522
628
 
523
- if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
524
- if (RepeatedField_eq(*((VALUE *)msg1_memory),
525
- *((VALUE *)msg2_memory)) == Qfalse) {
526
- return Qfalse;
527
- }
629
+ if (is_map_field(field)) {
630
+ return Map_eq(DEREF(msg1_memory, VALUE),
631
+ DEREF(msg2_memory, VALUE));
632
+ } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
633
+ return RepeatedField_eq(DEREF(msg1_memory, VALUE),
634
+ DEREF(msg2_memory, VALUE));
528
635
  } else {
529
636
  if (!native_slot_eq(upb_fielddef_type(field),
530
637
  msg1_memory, msg2_memory)) {