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

Sign up to get free protection for your applications and to get access to all the features.

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);