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 +5 -13
- data/ext/google/protobuf_c/defs.c +298 -9
- data/ext/google/protobuf_c/encode_decode.c +204 -29
- data/ext/google/protobuf_c/map.c +1 -1
- data/ext/google/protobuf_c/message.c +44 -0
- data/ext/google/protobuf_c/protobuf.c +2 -0
- data/ext/google/protobuf_c/protobuf.h +61 -2
- data/ext/google/protobuf_c/repeated_field.c +28 -31
- data/ext/google/protobuf_c/storage.c +230 -66
- data/ext/google/protobuf_c/upb.c +938 -153
- data/ext/google/protobuf_c/upb.h +607 -55
- data/tests/basic.rb +114 -2
- data/tests/generated_code_test.rb +17 -0
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
YzJhNmY2MjZkNDQzN2E2MTk4MGNjYzIxODAwMTQ1ZThkNjMwZTg3Mg==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 63730161da9f93c004fac333b54735b3d4ab2bb0
|
4
|
+
data.tar.gz: f5f01388a467ba1d0c92679563debbe2f2f24760
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
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 (
|
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 (
|
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
|
-
|
332
|
-
for (
|
333
|
-
!
|
334
|
-
|
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.
|
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
|
-
|
1326
|
-
for (
|
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
|
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
|
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
|
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
|
-
|
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,
|
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->
|
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
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
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->
|
566
|
+
size_t offset = desc->layout->fields[upb_fielddef_index(f)].offset +
|
412
567
|
sizeof(MessageHeader);
|
413
568
|
|
414
|
-
if (
|
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
|
-
|
808
|
-
for (
|
809
|
-
!
|
810
|
-
|
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->
|
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);
|