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

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.

checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ZGYwNjhlZGZjOTE1ZjM4YmE2ZTAzYTZlOTZiZmZmMDFjMmQ4MjJiMw==
5
- data.tar.gz: !binary |-
6
- YzJhNmY2MjZkNDQzN2E2MTk4MGNjYzIxODAwMTQ1ZThkNjMwZTg3Mg==
2
+ SHA1:
3
+ metadata.gz: 63730161da9f93c004fac333b54735b3d4ab2bb0
4
+ data.tar.gz: f5f01388a467ba1d0c92679563debbe2f2f24760
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- MzMwMzVhNjkzNzA0NTc3NTJhNDVlOTNlMTgzZjJkNzA3NGE4ZDk2NjRlYmNi
10
- OTBhMmQ4M2Y1YWZiYzc0Njc5OThmODliYzQ4YTA5YWM0MTk3MGQyZTA4YWYy
11
- MjZiNDJmNjA4N2I4MDgzZjM5Y2IwMGViM2U4MjM5ZWE4NDBhZjI=
12
- data.tar.gz: !binary |-
13
- NDhhZmI5M2IxN2Q5OTc2MWQ5YzY5Mzk3MzU2ODZjYzJiMTA4OTFlYTA3MzBj
14
- MGE4YTg1NmVlMmViNTUzZDI5ZjQ4ZTE2ZDkxZDI5OGQxMDlmMTgzN2E2M2Qw
15
- MWY4NGQ3YWVjZTIxY2Y3Y2FlNjMyODFjNDc0NDgyOTljN2E0NWY=
6
+ metadata.gz: 17c66e414b0317d5f7afad344cf4c45f830856bc60c4cb78bf775934a26472a65bd6b539ddb0412d8ba409c951d8c6b3dd0d97d06cb9a50cbf2fbba43e70ca60
7
+ data.tar.gz: 6c381c080addcc25725e8102497456cdf8a74df582d6f5f9efc43bd77d0fc0cbcffd407c2861f7aa2b9866c7dd575ce17e158df7e0bf3cfc6cd15f9047e882d8
@@ -58,11 +58,15 @@ static upb_def* check_notfrozen(const upb_def* def) {
58
58
  }
59
59
 
60
60
  static upb_msgdef* check_msg_notfrozen(const upb_msgdef* def) {
61
- return (upb_msgdef*)check_notfrozen((const upb_def*)def);
61
+ return upb_downcast_msgdef_mutable(check_notfrozen((const upb_def*)def));
62
62
  }
63
63
 
64
64
  static upb_fielddef* check_field_notfrozen(const upb_fielddef* def) {
65
- return (upb_fielddef*)check_notfrozen((const upb_def*)def);
65
+ return upb_downcast_fielddef_mutable(check_notfrozen((const upb_def*)def));
66
+ }
67
+
68
+ static upb_oneofdef* check_oneof_notfrozen(const upb_oneofdef* def) {
69
+ return (upb_oneofdef*)check_notfrozen((const upb_def*)def);
66
70
  }
67
71
 
68
72
  static upb_enumdef* check_enum_notfrozen(const upb_enumdef* def) {
@@ -282,6 +286,9 @@ void Descriptor_register(VALUE module) {
282
286
  rb_define_method(klass, "each", Descriptor_each, 0);
283
287
  rb_define_method(klass, "lookup", Descriptor_lookup, 1);
284
288
  rb_define_method(klass, "add_field", Descriptor_add_field, 1);
289
+ rb_define_method(klass, "add_oneof", Descriptor_add_oneof, 1);
290
+ rb_define_method(klass, "each_oneof", Descriptor_each_oneof, 0);
291
+ rb_define_method(klass, "lookup_oneof", Descriptor_lookup_oneof, 1);
285
292
  rb_define_method(klass, "msgclass", Descriptor_msgclass, 0);
286
293
  rb_define_method(klass, "name", Descriptor_name, 0);
287
294
  rb_define_method(klass, "name=", Descriptor_name_set, 1);
@@ -328,10 +335,10 @@ VALUE Descriptor_name_set(VALUE _self, VALUE str) {
328
335
  VALUE Descriptor_each(VALUE _self) {
329
336
  DEFINE_SELF(Descriptor, self, _self);
330
337
 
331
- upb_msg_iter it;
332
- for (upb_msg_begin(&it, self->msgdef);
333
- !upb_msg_done(&it);
334
- upb_msg_next(&it)) {
338
+ upb_msg_field_iter it;
339
+ for (upb_msg_field_begin(&it, self->msgdef);
340
+ !upb_msg_field_done(&it);
341
+ upb_msg_field_next(&it)) {
335
342
  const upb_fielddef* field = upb_msg_iter_field(&it);
336
343
  VALUE obj = get_def_obj(field);
337
344
  rb_yield(obj);
@@ -360,7 +367,7 @@ VALUE Descriptor_lookup(VALUE _self, VALUE name) {
360
367
  * call-seq:
361
368
  * Descriptor.add_field(field) => nil
362
369
  *
363
- * Adds the given FieldDescriptor to this message type. The descriptor must not
370
+ * Adds the given FieldDescriptor to this message type. This descriptor must not
364
371
  * have been added to a pool yet. Raises an exception if a field with the same
365
372
  * name or number already exists. Sub-type references (e.g. for fields of type
366
373
  * message) are not resolved at this point.
@@ -377,6 +384,67 @@ VALUE Descriptor_add_field(VALUE _self, VALUE obj) {
377
384
  return Qnil;
378
385
  }
379
386
 
387
+ /*
388
+ * call-seq:
389
+ * Descriptor.add_oneof(oneof) => nil
390
+ *
391
+ * Adds the given OneofDescriptor to this message type. This descriptor must not
392
+ * have been added to a pool yet. Raises an exception if a oneof with the same
393
+ * name already exists, or if any of the oneof's fields' names or numbers
394
+ * conflict with an existing field in this message type. All fields in the oneof
395
+ * are added to the message descriptor. Sub-type references (e.g. for fields of
396
+ * type message) are not resolved at this point.
397
+ */
398
+ VALUE Descriptor_add_oneof(VALUE _self, VALUE obj) {
399
+ DEFINE_SELF(Descriptor, self, _self);
400
+ upb_msgdef* mut_def = check_msg_notfrozen(self->msgdef);
401
+ OneofDescriptor* def = ruby_to_OneofDescriptor(obj);
402
+ upb_oneofdef* mut_oneof_def = check_oneof_notfrozen(def->oneofdef);
403
+ CHECK_UPB(
404
+ upb_msgdef_addoneof(mut_def, mut_oneof_def, NULL, &status),
405
+ "Adding oneof to Descriptor failed");
406
+ add_def_obj(def->oneofdef, obj);
407
+ return Qnil;
408
+ }
409
+
410
+ /*
411
+ * call-seq:
412
+ * Descriptor.each_oneof(&block) => nil
413
+ *
414
+ * Invokes the given block for each oneof in this message type, passing the
415
+ * corresponding OneofDescriptor.
416
+ */
417
+ VALUE Descriptor_each_oneof(VALUE _self) {
418
+ DEFINE_SELF(Descriptor, self, _self);
419
+
420
+ upb_msg_oneof_iter it;
421
+ for (upb_msg_oneof_begin(&it, self->msgdef);
422
+ !upb_msg_oneof_done(&it);
423
+ upb_msg_oneof_next(&it)) {
424
+ const upb_oneofdef* oneof = upb_msg_iter_oneof(&it);
425
+ VALUE obj = get_def_obj(oneof);
426
+ rb_yield(obj);
427
+ }
428
+ return Qnil;
429
+ }
430
+
431
+ /*
432
+ * call-seq:
433
+ * Descriptor.lookup_oneof(name) => OneofDescriptor
434
+ *
435
+ * Returns the oneof descriptor for the oneof with the given name, if present,
436
+ * or nil if none.
437
+ */
438
+ VALUE Descriptor_lookup_oneof(VALUE _self, VALUE name) {
439
+ DEFINE_SELF(Descriptor, self, _self);
440
+ const char* s = get_str(name);
441
+ const upb_oneofdef* oneof = upb_msgdef_ntooz(self->msgdef, s);
442
+ if (oneof == NULL) {
443
+ return Qnil;
444
+ }
445
+ return get_def_obj(oneof);
446
+ }
447
+
380
448
  /*
381
449
  * call-seq:
382
450
  * Descriptor.msgclass => message_klass
@@ -743,6 +811,120 @@ VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) {
743
811
  return Qnil;
744
812
  }
745
813
 
814
+ // -----------------------------------------------------------------------------
815
+ // OneofDescriptor.
816
+ // -----------------------------------------------------------------------------
817
+
818
+ DEFINE_CLASS(OneofDescriptor, "Google::Protobuf::OneofDescriptor");
819
+
820
+ void OneofDescriptor_mark(void* _self) {
821
+ }
822
+
823
+ void OneofDescriptor_free(void* _self) {
824
+ OneofDescriptor* self = _self;
825
+ upb_oneofdef_unref(self->oneofdef, &self->oneofdef);
826
+ xfree(self);
827
+ }
828
+
829
+ /*
830
+ * call-seq:
831
+ * OneofDescriptor.new => oneof_descriptor
832
+ *
833
+ * Creates a new, empty, oneof descriptor. The oneof may only be modified prior
834
+ * to being added to a message descriptor which is subsequently added to a pool.
835
+ */
836
+ VALUE OneofDescriptor_alloc(VALUE klass) {
837
+ OneofDescriptor* self = ALLOC(OneofDescriptor);
838
+ VALUE ret = TypedData_Wrap_Struct(klass, &_OneofDescriptor_type, self);
839
+ self->oneofdef = upb_oneofdef_new(&self->oneofdef);
840
+ return ret;
841
+ }
842
+
843
+ void OneofDescriptor_register(VALUE module) {
844
+ VALUE klass = rb_define_class_under(
845
+ module, "OneofDescriptor", rb_cObject);
846
+ rb_define_alloc_func(klass, OneofDescriptor_alloc);
847
+ rb_define_method(klass, "name", OneofDescriptor_name, 0);
848
+ rb_define_method(klass, "name=", OneofDescriptor_name_set, 1);
849
+ rb_define_method(klass, "add_field", OneofDescriptor_add_field, 1);
850
+ rb_define_method(klass, "each", OneofDescriptor_each, 0);
851
+ rb_include_module(klass, rb_mEnumerable);
852
+ cOneofDescriptor = klass;
853
+ rb_gc_register_address(&cOneofDescriptor);
854
+ }
855
+
856
+ /*
857
+ * call-seq:
858
+ * OneofDescriptor.name => name
859
+ *
860
+ * Returns the name of this oneof.
861
+ */
862
+ VALUE OneofDescriptor_name(VALUE _self) {
863
+ DEFINE_SELF(OneofDescriptor, self, _self);
864
+ return rb_str_maybe_null(upb_oneofdef_name(self->oneofdef));
865
+ }
866
+
867
+ /*
868
+ * call-seq:
869
+ * OneofDescriptor.name = name
870
+ *
871
+ * Sets a new name for this oneof. The oneof must not have been added to a
872
+ * message descriptor yet.
873
+ */
874
+ VALUE OneofDescriptor_name_set(VALUE _self, VALUE value) {
875
+ DEFINE_SELF(OneofDescriptor, self, _self);
876
+ upb_oneofdef* mut_def = check_oneof_notfrozen(self->oneofdef);
877
+ const char* str = get_str(value);
878
+ CHECK_UPB(upb_oneofdef_setname(mut_def, str, &status),
879
+ "Error setting oneof name");
880
+ return Qnil;
881
+ }
882
+
883
+ /*
884
+ * call-seq:
885
+ * OneofDescriptor.add_field(field) => nil
886
+ *
887
+ * Adds a field to this oneof. The field may have been added to this oneof in
888
+ * the past, or the message to which this oneof belongs (if any), but may not
889
+ * have already been added to any other oneof or message. Otherwise, an
890
+ * exception is raised.
891
+ *
892
+ * All fields added to the oneof via this method will be automatically added to
893
+ * the message to which this oneof belongs, if it belongs to one currently, or
894
+ * else will be added to any message to which the oneof is later added at the
895
+ * time that it is added.
896
+ */
897
+ VALUE OneofDescriptor_add_field(VALUE _self, VALUE obj) {
898
+ DEFINE_SELF(OneofDescriptor, self, _self);
899
+ upb_oneofdef* mut_def = check_oneof_notfrozen(self->oneofdef);
900
+ FieldDescriptor* def = ruby_to_FieldDescriptor(obj);
901
+ upb_fielddef* mut_field_def = check_field_notfrozen(def->fielddef);
902
+ CHECK_UPB(
903
+ upb_oneofdef_addfield(mut_def, mut_field_def, NULL, &status),
904
+ "Adding field to OneofDescriptor failed");
905
+ add_def_obj(def->fielddef, obj);
906
+ return Qnil;
907
+ }
908
+
909
+ /*
910
+ * call-seq:
911
+ * OneofDescriptor.each(&block) => nil
912
+ *
913
+ * Iterates through fields in this oneof, yielding to the block on each one.
914
+ */
915
+ VALUE OneofDescriptor_each(VALUE _self, VALUE field) {
916
+ DEFINE_SELF(OneofDescriptor, self, _self);
917
+ upb_oneof_iter it;
918
+ for (upb_oneof_begin(&it, self->oneofdef);
919
+ !upb_oneof_done(&it);
920
+ upb_oneof_next(&it)) {
921
+ const upb_fielddef* f = upb_oneof_iter_field(&it);
922
+ VALUE obj = get_def_obj(f);
923
+ rb_yield(obj);
924
+ }
925
+ return Qnil;
926
+ }
927
+
746
928
  // -----------------------------------------------------------------------------
747
929
  // EnumDescriptor.
748
930
  // -----------------------------------------------------------------------------
@@ -952,6 +1134,7 @@ void MessageBuilderContext_register(VALUE module) {
952
1134
  rb_define_method(klass, "required", MessageBuilderContext_required, -1);
953
1135
  rb_define_method(klass, "repeated", MessageBuilderContext_repeated, -1);
954
1136
  rb_define_method(klass, "map", MessageBuilderContext_map, -1);
1137
+ rb_define_method(klass, "oneof", MessageBuilderContext_oneof, 1);
955
1138
  cMessageBuilderContext = klass;
956
1139
  rb_gc_register_address(&cMessageBuilderContext);
957
1140
  }
@@ -1165,6 +1348,110 @@ VALUE MessageBuilderContext_map(int argc, VALUE* argv, VALUE _self) {
1165
1348
  return Qnil;
1166
1349
  }
1167
1350
 
1351
+ /*
1352
+ * call-seq:
1353
+ * MessageBuilderContext.oneof(name, &block) => nil
1354
+ *
1355
+ * Creates a new OneofDescriptor with the given name, creates a
1356
+ * OneofBuilderContext attached to that OneofDescriptor, evaluates the given
1357
+ * block in the context of that OneofBuilderContext with #instance_eval, and
1358
+ * then adds the oneof to the message.
1359
+ *
1360
+ * This is the recommended, idiomatic way to build oneof definitions.
1361
+ */
1362
+ VALUE MessageBuilderContext_oneof(VALUE _self, VALUE name) {
1363
+ DEFINE_SELF(MessageBuilderContext, self, _self);
1364
+ VALUE oneofdef = rb_class_new_instance(0, NULL, cOneofDescriptor);
1365
+ VALUE args[2] = { oneofdef, self->builder };
1366
+ VALUE ctx = rb_class_new_instance(2, args, cOneofBuilderContext);
1367
+ VALUE block = rb_block_proc();
1368
+ VALUE name_str = rb_str_new2(rb_id2name(SYM2ID(name)));
1369
+ rb_funcall(oneofdef, rb_intern("name="), 1, name_str);
1370
+ rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
1371
+ Descriptor_add_oneof(self->descriptor, oneofdef);
1372
+
1373
+ return Qnil;
1374
+ }
1375
+
1376
+ // -----------------------------------------------------------------------------
1377
+ // OneofBuilderContext.
1378
+ // -----------------------------------------------------------------------------
1379
+
1380
+ DEFINE_CLASS(OneofBuilderContext,
1381
+ "Google::Protobuf::Internal::OneofBuilderContext");
1382
+
1383
+ void OneofBuilderContext_mark(void* _self) {
1384
+ OneofBuilderContext* self = _self;
1385
+ rb_gc_mark(self->descriptor);
1386
+ rb_gc_mark(self->builder);
1387
+ }
1388
+
1389
+ void OneofBuilderContext_free(void* _self) {
1390
+ OneofBuilderContext* self = _self;
1391
+ xfree(self);
1392
+ }
1393
+
1394
+ VALUE OneofBuilderContext_alloc(VALUE klass) {
1395
+ OneofBuilderContext* self = ALLOC(OneofBuilderContext);
1396
+ VALUE ret = TypedData_Wrap_Struct(
1397
+ klass, &_OneofBuilderContext_type, self);
1398
+ self->descriptor = Qnil;
1399
+ self->builder = Qnil;
1400
+ return ret;
1401
+ }
1402
+
1403
+ void OneofBuilderContext_register(VALUE module) {
1404
+ VALUE klass = rb_define_class_under(
1405
+ module, "OneofBuilderContext", rb_cObject);
1406
+ rb_define_alloc_func(klass, OneofBuilderContext_alloc);
1407
+ rb_define_method(klass, "initialize",
1408
+ OneofBuilderContext_initialize, 2);
1409
+ rb_define_method(klass, "optional", OneofBuilderContext_optional, -1);
1410
+ cOneofBuilderContext = klass;
1411
+ rb_gc_register_address(&cOneofBuilderContext);
1412
+ }
1413
+
1414
+ /*
1415
+ * call-seq:
1416
+ * OneofBuilderContext.new(desc, builder) => context
1417
+ *
1418
+ * Create a new oneof builder context around the given oneof descriptor and
1419
+ * builder context. This class is intended to serve as a DSL context to be used
1420
+ * with #instance_eval.
1421
+ */
1422
+ VALUE OneofBuilderContext_initialize(VALUE _self,
1423
+ VALUE oneofdef,
1424
+ VALUE builder) {
1425
+ DEFINE_SELF(OneofBuilderContext, self, _self);
1426
+ self->descriptor = oneofdef;
1427
+ self->builder = builder;
1428
+ return Qnil;
1429
+ }
1430
+
1431
+ /*
1432
+ * call-seq:
1433
+ * OneofBuilderContext.optional(name, type, number, type_class = nil)
1434
+ *
1435
+ * Defines a new optional field in this oneof with the given type, tag number,
1436
+ * and type class (for message and enum fields). The type must be a Ruby symbol
1437
+ * (as accepted by FieldDescriptor#type=) and the type_class must be a string,
1438
+ * if present (as accepted by FieldDescriptor#submsg_name=).
1439
+ */
1440
+ VALUE OneofBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
1441
+ DEFINE_SELF(OneofBuilderContext, self, _self);
1442
+
1443
+ if (argc < 3) {
1444
+ rb_raise(rb_eArgError, "Expected at least 3 arguments.");
1445
+ }
1446
+ VALUE name = argv[0];
1447
+ VALUE type = argv[1];
1448
+ VALUE number = argv[2];
1449
+ VALUE type_class = (argc > 3) ? argv[3] : Qnil;
1450
+
1451
+ return msgdef_add_field(self->descriptor, "optional",
1452
+ name, type, number, type_class);
1453
+ }
1454
+
1168
1455
  // -----------------------------------------------------------------------------
1169
1456
  // EnumBuilderContext.
1170
1457
  // -----------------------------------------------------------------------------
@@ -1322,8 +1609,10 @@ VALUE Builder_add_enum(VALUE _self, VALUE name) {
1322
1609
 
1323
1610
  static void validate_msgdef(const upb_msgdef* msgdef) {
1324
1611
  // Verify that no required fields exist. proto3 does not support these.
1325
- upb_msg_iter it;
1326
- for (upb_msg_begin(&it, msgdef); !upb_msg_done(&it); upb_msg_next(&it)) {
1612
+ upb_msg_field_iter it;
1613
+ for (upb_msg_field_begin(&it, msgdef);
1614
+ !upb_msg_field_done(&it);
1615
+ upb_msg_field_next(&it)) {
1327
1616
  const upb_fielddef* field = upb_msg_iter_field(&it);
1328
1617
  if (upb_fielddef_label(field) == UPB_LABEL_REQUIRED) {
1329
1618
  rb_raise(rb_eTypeError, "Required fields are unsupported in proto3.");
@@ -59,6 +59,36 @@ static const void *newsubmsghandlerdata(upb_handlers* h, uint32_t ofs,
59
59
  return hd;
60
60
  }
61
61
 
62
+ typedef struct {
63
+ size_t ofs; // union data slot
64
+ size_t case_ofs; // oneof_case field
65
+ uint32_t oneof_case_num; // oneof-case number to place in oneof_case field
66
+ const upb_msgdef *md; // msgdef, for oneof submessage handler
67
+ } oneof_handlerdata_t;
68
+
69
+ static const void *newoneofhandlerdata(upb_handlers *h,
70
+ uint32_t ofs,
71
+ uint32_t case_ofs,
72
+ const upb_fielddef *f) {
73
+ oneof_handlerdata_t *hd = ALLOC(oneof_handlerdata_t);
74
+ hd->ofs = ofs;
75
+ hd->case_ofs = case_ofs;
76
+ // We reuse the field tag number as a oneof union discriminant tag. Note that
77
+ // we don't expose these numbers to the user, so the only requirement is that
78
+ // we have some unique ID for each union case/possibility. The field tag
79
+ // numbers are already present and are easy to use so there's no reason to
80
+ // create a separate ID space. In addition, using the field tag number here
81
+ // lets us easily look up the field in the oneof accessor.
82
+ hd->oneof_case_num = upb_fielddef_number(f);
83
+ if (upb_fielddef_type(f) == UPB_TYPE_MESSAGE) {
84
+ hd->md = upb_fielddef_msgsubdef(f);
85
+ } else {
86
+ hd->md = NULL;
87
+ }
88
+ upb_handlers_addcleanup(h, hd, free);
89
+ return hd;
90
+ }
91
+
62
92
  // A handler that starts a repeated field. Gets the Repeated*Field instance for
63
93
  // this field (such an instance always exists even in an empty message).
64
94
  static void *startseq_handler(void* closure, const void* hd) {
@@ -67,8 +97,7 @@ static void *startseq_handler(void* closure, const void* hd) {
67
97
  return (void*)DEREF(msg, *ofs, VALUE);
68
98
  }
69
99
 
70
- // Handlers that append primitive values to a repeated field (a regular Ruby
71
- // array for now).
100
+ // Handlers that append primitive values to a repeated field.
72
101
  #define DEFINE_APPEND_HANDLER(type, ctype) \
73
102
  static bool append##type##_handler(void *closure, const void *hd, \
74
103
  ctype val) { \
@@ -85,7 +114,7 @@ DEFINE_APPEND_HANDLER(int64, int64_t)
85
114
  DEFINE_APPEND_HANDLER(uint64, uint64_t)
86
115
  DEFINE_APPEND_HANDLER(double, double)
87
116
 
88
- // Appends a string to a repeated field (a regular Ruby array for now).
117
+ // Appends a string to a repeated field.
89
118
  static void* appendstr_handler(void *closure,
90
119
  const void *hd,
91
120
  size_t size_hint) {
@@ -96,7 +125,7 @@ static void* appendstr_handler(void *closure,
96
125
  return (void*)str;
97
126
  }
98
127
 
99
- // Appends a 'bytes' string to a repeated field (a regular Ruby array for now).
128
+ // Appends a 'bytes' string to a repeated field.
100
129
  static void* appendbytes_handler(void *closure,
101
130
  const void *hd,
102
131
  size_t size_hint) {
@@ -179,7 +208,11 @@ typedef struct {
179
208
  size_t ofs;
180
209
  upb_fieldtype_t key_field_type;
181
210
  upb_fieldtype_t value_field_type;
182
- VALUE value_field_typeclass;
211
+
212
+ // We know that we can hold this reference because the handlerdata has the
213
+ // same lifetime as the upb_handlers struct, and the upb_handlers struct holds
214
+ // a reference to the upb_msgdef, which in turn has references to its subdefs.
215
+ const upb_def* value_field_subdef;
183
216
  } map_handlerdata_t;
184
217
 
185
218
  // Temporary frame for map parsing: at the beginning of a map entry message, a
@@ -219,8 +252,15 @@ static bool endmap_handler(void *closure, const void *hd, upb_status* s) {
219
252
  VALUE key = native_slot_get(
220
253
  mapdata->key_field_type, Qnil,
221
254
  &frame->key_storage);
255
+
256
+ VALUE value_field_typeclass = Qnil;
257
+ if (mapdata->value_field_type == UPB_TYPE_MESSAGE ||
258
+ mapdata->value_field_type == UPB_TYPE_ENUM) {
259
+ value_field_typeclass = get_def_obj(mapdata->value_field_subdef);
260
+ }
261
+
222
262
  VALUE value = native_slot_get(
223
- mapdata->value_field_type, mapdata->value_field_typeclass,
263
+ mapdata->value_field_type, value_field_typeclass,
224
264
  &frame->value_storage);
225
265
 
226
266
  Map_index_set(frame->map, key, value);
@@ -251,21 +291,90 @@ static map_handlerdata_t* new_map_handlerdata(
251
291
  MAP_VALUE_FIELD);
252
292
  assert(value_field != NULL);
253
293
  hd->value_field_type = upb_fielddef_type(value_field);
254
- hd->value_field_typeclass = field_type_class(value_field);
255
-
256
- // Ensure that value_field_typeclass is properly GC-rooted. We must do this
257
- // because we hold a reference to the Ruby class in the handlerdata, which is
258
- // owned by the handlers. The handlers are owned by *this* message's Ruby
259
- // object, but each Ruby object is rooted independently at the def -> Ruby
260
- // object map. So we have to ensure that the Ruby objects we depend on will
261
- // stick around as long as we're around.
262
- if (hd->value_field_typeclass != Qnil) {
263
- rb_ary_push(desc->typeclass_references, hd->value_field_typeclass);
264
- }
294
+ hd->value_field_subdef = upb_fielddef_subdef(value_field);
265
295
 
266
296
  return hd;
267
297
  }
268
298
 
299
+ // Handlers that set primitive values in oneofs.
300
+ #define DEFINE_ONEOF_HANDLER(type, ctype) \
301
+ static bool oneof##type##_handler(void *closure, const void *hd, \
302
+ ctype val) { \
303
+ const oneof_handlerdata_t *oneofdata = hd; \
304
+ DEREF(closure, oneofdata->case_ofs, uint32_t) = \
305
+ oneofdata->oneof_case_num; \
306
+ DEREF(closure, oneofdata->ofs, ctype) = val; \
307
+ return true; \
308
+ }
309
+
310
+ DEFINE_ONEOF_HANDLER(bool, bool)
311
+ DEFINE_ONEOF_HANDLER(int32, int32_t)
312
+ DEFINE_ONEOF_HANDLER(uint32, uint32_t)
313
+ DEFINE_ONEOF_HANDLER(float, float)
314
+ DEFINE_ONEOF_HANDLER(int64, int64_t)
315
+ DEFINE_ONEOF_HANDLER(uint64, uint64_t)
316
+ DEFINE_ONEOF_HANDLER(double, double)
317
+
318
+ #undef DEFINE_ONEOF_HANDLER
319
+
320
+ // Handlers for strings in a oneof.
321
+ static void *oneofstr_handler(void *closure,
322
+ const void *hd,
323
+ size_t size_hint) {
324
+ MessageHeader* msg = closure;
325
+ const oneof_handlerdata_t *oneofdata = hd;
326
+ VALUE str = rb_str_new2("");
327
+ rb_enc_associate(str, kRubyStringUtf8Encoding);
328
+ DEREF(msg, oneofdata->case_ofs, uint32_t) =
329
+ oneofdata->oneof_case_num;
330
+ DEREF(msg, oneofdata->ofs, VALUE) = str;
331
+ return (void*)str;
332
+ }
333
+
334
+ static void *oneofbytes_handler(void *closure,
335
+ const void *hd,
336
+ size_t size_hint) {
337
+ MessageHeader* msg = closure;
338
+ const oneof_handlerdata_t *oneofdata = hd;
339
+ VALUE str = rb_str_new2("");
340
+ rb_enc_associate(str, kRubyString8bitEncoding);
341
+ DEREF(msg, oneofdata->case_ofs, uint32_t) =
342
+ oneofdata->oneof_case_num;
343
+ DEREF(msg, oneofdata->ofs, VALUE) = str;
344
+ return (void*)str;
345
+ }
346
+
347
+ // Handler for a submessage field in a oneof.
348
+ static void *oneofsubmsg_handler(void *closure,
349
+ const void *hd) {
350
+ MessageHeader* msg = closure;
351
+ const oneof_handlerdata_t *oneofdata = hd;
352
+ uint32_t oldcase = DEREF(msg, oneofdata->case_ofs, uint32_t);
353
+
354
+ VALUE subdesc =
355
+ get_def_obj((void*)oneofdata->md);
356
+ VALUE subklass = Descriptor_msgclass(subdesc);
357
+
358
+ if (oldcase != oneofdata->oneof_case_num ||
359
+ DEREF(msg, oneofdata->ofs, VALUE) == Qnil) {
360
+ DEREF(msg, oneofdata->ofs, VALUE) =
361
+ rb_class_new_instance(0, NULL, subklass);
362
+ }
363
+ // Set the oneof case *after* allocating the new class instance -- otherwise,
364
+ // if the Ruby GC is invoked as part of a call into the VM, it might invoke
365
+ // our mark routines, and our mark routines might see the case value
366
+ // indicating a VALUE is present and expect a valid VALUE. See comment in
367
+ // layout_set() for more detail: basically, the change to the value and the
368
+ // case must be atomic w.r.t. the Ruby VM.
369
+ DEREF(msg, oneofdata->case_ofs, uint32_t) =
370
+ oneofdata->oneof_case_num;
371
+
372
+ VALUE submsg_rb = DEREF(msg, oneofdata->ofs, VALUE);
373
+ MessageHeader* submsg;
374
+ TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg);
375
+ return submsg;
376
+ }
377
+
269
378
  // Set up handlers for a repeated field.
270
379
  static void add_handlers_for_repeated_field(upb_handlers *h,
271
380
  const upb_fielddef *f,
@@ -383,6 +492,53 @@ static void add_handlers_for_mapentry(const upb_msgdef* msgdef,
383
492
  offsetof(map_parse_frame_t, value_storage));
384
493
  }
385
494
 
495
+ // Set up handlers for a oneof field.
496
+ static void add_handlers_for_oneof_field(upb_handlers *h,
497
+ const upb_fielddef *f,
498
+ size_t offset,
499
+ size_t oneof_case_offset) {
500
+
501
+ upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
502
+ upb_handlerattr_sethandlerdata(
503
+ &attr, newoneofhandlerdata(h, offset, oneof_case_offset, f));
504
+
505
+ switch (upb_fielddef_type(f)) {
506
+
507
+ #define SET_HANDLER(utype, ltype) \
508
+ case utype: \
509
+ upb_handlers_set##ltype(h, f, oneof##ltype##_handler, &attr); \
510
+ break;
511
+
512
+ SET_HANDLER(UPB_TYPE_BOOL, bool);
513
+ SET_HANDLER(UPB_TYPE_INT32, int32);
514
+ SET_HANDLER(UPB_TYPE_UINT32, uint32);
515
+ SET_HANDLER(UPB_TYPE_ENUM, int32);
516
+ SET_HANDLER(UPB_TYPE_FLOAT, float);
517
+ SET_HANDLER(UPB_TYPE_INT64, int64);
518
+ SET_HANDLER(UPB_TYPE_UINT64, uint64);
519
+ SET_HANDLER(UPB_TYPE_DOUBLE, double);
520
+
521
+ #undef SET_HANDLER
522
+
523
+ case UPB_TYPE_STRING:
524
+ case UPB_TYPE_BYTES: {
525
+ bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES;
526
+ upb_handlers_setstartstr(h, f, is_bytes ?
527
+ oneofbytes_handler : oneofstr_handler,
528
+ &attr);
529
+ upb_handlers_setstring(h, f, stringdata_handler, NULL);
530
+ break;
531
+ }
532
+ case UPB_TYPE_MESSAGE: {
533
+ upb_handlers_setstartsubmsg(h, f, oneofsubmsg_handler, &attr);
534
+ break;
535
+ }
536
+ }
537
+
538
+ upb_handlerattr_uninit(&attr);
539
+ }
540
+
541
+
386
542
  static void add_handlers_for_message(const void *closure, upb_handlers *h) {
387
543
  const upb_msgdef* msgdef = upb_handlers_msgdef(h);
388
544
  Descriptor* desc = ruby_to_Descriptor(get_def_obj((void*)msgdef));
@@ -402,16 +558,20 @@ static void add_handlers_for_message(const void *closure, upb_handlers *h) {
402
558
  desc->layout = create_layout(desc->msgdef);
403
559
  }
404
560
 
405
- upb_msg_iter i;
406
-
407
- for (upb_msg_begin(&i, desc->msgdef);
408
- !upb_msg_done(&i);
409
- upb_msg_next(&i)) {
561
+ upb_msg_field_iter i;
562
+ for (upb_msg_field_begin(&i, desc->msgdef);
563
+ !upb_msg_field_done(&i);
564
+ upb_msg_field_next(&i)) {
410
565
  const upb_fielddef *f = upb_msg_iter_field(&i);
411
- size_t offset = desc->layout->offsets[upb_fielddef_index(f)] +
566
+ size_t offset = desc->layout->fields[upb_fielddef_index(f)].offset +
412
567
  sizeof(MessageHeader);
413
568
 
414
- if (is_map_field(f)) {
569
+ if (upb_fielddef_containingoneof(f)) {
570
+ size_t oneof_case_offset =
571
+ desc->layout->fields[upb_fielddef_index(f)].case_offset +
572
+ sizeof(MessageHeader);
573
+ add_handlers_for_oneof_field(h, f, offset, oneof_case_offset);
574
+ } else if (is_map_field(f)) {
415
575
  add_handlers_for_mapfield(h, f, offset, desc);
416
576
  } else if (upb_fielddef_isseq(f)) {
417
577
  add_handlers_for_repeated_field(h, f, offset);
@@ -804,13 +964,28 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
804
964
  MessageHeader* msg;
805
965
  TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
806
966
 
807
- upb_msg_iter i;
808
- for (upb_msg_begin(&i, desc->msgdef);
809
- !upb_msg_done(&i);
810
- upb_msg_next(&i)) {
967
+ upb_msg_field_iter i;
968
+ for (upb_msg_field_begin(&i, desc->msgdef);
969
+ !upb_msg_field_done(&i);
970
+ upb_msg_field_next(&i)) {
811
971
  upb_fielddef *f = upb_msg_iter_field(&i);
812
972
  uint32_t offset =
813
- desc->layout->offsets[upb_fielddef_index(f)] + sizeof(MessageHeader);
973
+ desc->layout->fields[upb_fielddef_index(f)].offset +
974
+ sizeof(MessageHeader);
975
+
976
+ if (upb_fielddef_containingoneof(f)) {
977
+ uint32_t oneof_case_offset =
978
+ desc->layout->fields[upb_fielddef_index(f)].case_offset +
979
+ sizeof(MessageHeader);
980
+ // For a oneof, check that this field is actually present -- skip all the
981
+ // below if not.
982
+ if (DEREF(msg, oneof_case_offset, uint32_t) !=
983
+ upb_fielddef_number(f)) {
984
+ continue;
985
+ }
986
+ // Otherwise, fall through to the appropriate singular-field handler
987
+ // below.
988
+ }
814
989
 
815
990
  if (is_map_field(f)) {
816
991
  VALUE map = DEREF(msg, offset, VALUE);