google-protobuf 3.11.0 → 3.12.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 +4 -4
- data/ext/google/protobuf_c/defs.c +96 -8
- data/ext/google/protobuf_c/encode_decode.c +74 -37
- data/ext/google/protobuf_c/extconf.rb +0 -0
- data/ext/google/protobuf_c/map.c +20 -46
- data/ext/google/protobuf_c/message.c +20 -11
- data/ext/google/protobuf_c/protobuf.h +1 -0
- data/ext/google/protobuf_c/storage.c +72 -23
- data/ext/google/protobuf_c/upb.c +1810 -1282
- data/ext/google/protobuf_c/upb.h +1031 -1339
- data/lib/google/protobuf/well_known_types.rb +0 -0
- data/tests/basic.rb +146 -48
- data/tests/generated_code_test.rb +0 -0
- data/tests/stress.rb +0 -0
- metadata +16 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 350de56c66a16de213635709b4d4e295bf4ea6404b487aaed6d42b3ce069067e
|
4
|
+
data.tar.gz: c9cdd0880d273e47fe4dcb70797fb3068174f7f3c2b4f3f2945f05782878e0fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6b0fecc0c6fc1ef76a9ccd232e1f94c5334500d498ea5a8ee7f5be724827f83b4f4518ea4881d28d797f239be252d6f1d7a3fb6d630fd572cd1999d6095a35c8
|
7
|
+
data.tar.gz: ba9ba2cf25c2bbf5d4959926e4ead989b5dbcf886a91b9940c11217fdf4c476c6a6e2cfd372e1593b253ed1efdb8ff2711e45b3c2f68434ccc1c326acde0dca8
|
@@ -136,7 +136,7 @@ static void rewrite_enum_default(const upb_symtab* symtab,
|
|
136
136
|
* same number.
|
137
137
|
*
|
138
138
|
* Here we do a pass over all enum defaults and rewrite numeric defaults by
|
139
|
-
* looking up their labels. This is
|
139
|
+
* looking up their labels. This is complicated by the fact that the enum
|
140
140
|
* definition can live in either the symtab or the file_proto.
|
141
141
|
* */
|
142
142
|
static void rewrite_enum_defaults(
|
@@ -572,7 +572,7 @@ VALUE Descriptor_file_descriptor(VALUE _self) {
|
|
572
572
|
* call-seq:
|
573
573
|
* Descriptor.name => name
|
574
574
|
*
|
575
|
-
* Returns the name of this message type as a fully-
|
575
|
+
* Returns the name of this message type as a fully-qualified string (e.g.,
|
576
576
|
* My.Package.MessageType).
|
577
577
|
*/
|
578
578
|
VALUE Descriptor_name(VALUE _self) {
|
@@ -1100,7 +1100,7 @@ VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) {
|
|
1100
1100
|
* FieldDescriptor.has?(message) => boolean
|
1101
1101
|
*
|
1102
1102
|
* Returns whether the value is set on the given message. Raises an
|
1103
|
-
* exception when calling
|
1103
|
+
* exception when calling for fields that do not have presence.
|
1104
1104
|
*/
|
1105
1105
|
VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) {
|
1106
1106
|
DEFINE_SELF(FieldDescriptor, self, _self);
|
@@ -1434,6 +1434,7 @@ void MessageBuilderContext_register(VALUE module) {
|
|
1434
1434
|
rb_define_method(klass, "initialize",
|
1435
1435
|
MessageBuilderContext_initialize, 2);
|
1436
1436
|
rb_define_method(klass, "optional", MessageBuilderContext_optional, -1);
|
1437
|
+
rb_define_method(klass, "proto3_optional", MessageBuilderContext_proto3_optional, -1);
|
1437
1438
|
rb_define_method(klass, "required", MessageBuilderContext_required, -1);
|
1438
1439
|
rb_define_method(klass, "repeated", MessageBuilderContext_repeated, -1);
|
1439
1440
|
rb_define_method(klass, "map", MessageBuilderContext_map, -1);
|
@@ -1469,7 +1470,8 @@ VALUE MessageBuilderContext_initialize(VALUE _self,
|
|
1469
1470
|
|
1470
1471
|
static void msgdef_add_field(VALUE msgbuilder_rb, upb_label_t label, VALUE name,
|
1471
1472
|
VALUE type, VALUE number, VALUE type_class,
|
1472
|
-
VALUE options, int oneof_index
|
1473
|
+
VALUE options, int oneof_index,
|
1474
|
+
bool proto3_optional) {
|
1473
1475
|
DEFINE_SELF(MessageBuilderContext, self, msgbuilder_rb);
|
1474
1476
|
FileBuilderContext* file_context =
|
1475
1477
|
ruby_to_FileBuilderContext(self->file_builder);
|
@@ -1489,6 +1491,10 @@ static void msgdef_add_field(VALUE msgbuilder_rb, upb_label_t label, VALUE name,
|
|
1489
1491
|
google_protobuf_FieldDescriptorProto_set_type(
|
1490
1492
|
field_proto, (int)ruby_to_descriptortype(type));
|
1491
1493
|
|
1494
|
+
if (proto3_optional) {
|
1495
|
+
google_protobuf_FieldDescriptorProto_set_proto3_optional(field_proto, true);
|
1496
|
+
}
|
1497
|
+
|
1492
1498
|
if (type_class != Qnil) {
|
1493
1499
|
Check_Type(type_class, T_STRING);
|
1494
1500
|
|
@@ -1574,7 +1580,38 @@ VALUE MessageBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
|
|
1574
1580
|
}
|
1575
1581
|
|
1576
1582
|
msgdef_add_field(_self, UPB_LABEL_OPTIONAL, name, type, number, type_class,
|
1577
|
-
options, -1);
|
1583
|
+
options, -1, false);
|
1584
|
+
|
1585
|
+
return Qnil;
|
1586
|
+
}
|
1587
|
+
|
1588
|
+
/*
|
1589
|
+
* call-seq:
|
1590
|
+
* MessageBuilderContext.proto3_optional(name, type, number,
|
1591
|
+
* type_class = nil, options = nil)
|
1592
|
+
*
|
1593
|
+
* Defines a true proto3 optional field (that tracks presence) on this message
|
1594
|
+
* type with the given type, tag number, and type class (for message and enum
|
1595
|
+
* fields). The type must be a Ruby symbol (as accepted by
|
1596
|
+
* FieldDescriptor#type=) and the type_class must be a string, if present (as
|
1597
|
+
* accepted by FieldDescriptor#submsg_name=).
|
1598
|
+
*/
|
1599
|
+
VALUE MessageBuilderContext_proto3_optional(int argc, VALUE* argv,
|
1600
|
+
VALUE _self) {
|
1601
|
+
VALUE name, type, number;
|
1602
|
+
VALUE type_class, options = Qnil;
|
1603
|
+
|
1604
|
+
rb_scan_args(argc, argv, "32", &name, &type, &number, &type_class, &options);
|
1605
|
+
|
1606
|
+
// Allow passing (name, type, number, options) or
|
1607
|
+
// (name, type, number, type_class, options)
|
1608
|
+
if (argc == 4 && RB_TYPE_P(type_class, T_HASH)) {
|
1609
|
+
options = type_class;
|
1610
|
+
type_class = Qnil;
|
1611
|
+
}
|
1612
|
+
|
1613
|
+
msgdef_add_field(_self, UPB_LABEL_OPTIONAL, name, type, number, type_class,
|
1614
|
+
options, -1, true);
|
1578
1615
|
|
1579
1616
|
return Qnil;
|
1580
1617
|
}
|
@@ -1607,7 +1644,7 @@ VALUE MessageBuilderContext_required(int argc, VALUE* argv, VALUE _self) {
|
|
1607
1644
|
}
|
1608
1645
|
|
1609
1646
|
msgdef_add_field(_self, UPB_LABEL_REQUIRED, name, type, number, type_class,
|
1610
|
-
options, -1);
|
1647
|
+
options, -1, false);
|
1611
1648
|
|
1612
1649
|
return Qnil;
|
1613
1650
|
}
|
@@ -1633,7 +1670,7 @@ VALUE MessageBuilderContext_repeated(int argc, VALUE* argv, VALUE _self) {
|
|
1633
1670
|
type_class = (argc > 3) ? argv[3] : Qnil;
|
1634
1671
|
|
1635
1672
|
msgdef_add_field(_self, UPB_LABEL_REPEATED, name, type, number, type_class,
|
1636
|
-
Qnil, -1);
|
1673
|
+
Qnil, -1, false);
|
1637
1674
|
|
1638
1675
|
return Qnil;
|
1639
1676
|
}
|
@@ -1758,6 +1795,56 @@ VALUE MessageBuilderContext_oneof(VALUE _self, VALUE name) {
|
|
1758
1795
|
return Qnil;
|
1759
1796
|
}
|
1760
1797
|
|
1798
|
+
void MessageBuilderContext_add_synthetic_oneofs(VALUE _self) {
|
1799
|
+
DEFINE_SELF(MessageBuilderContext, self, _self);
|
1800
|
+
FileBuilderContext* file_context =
|
1801
|
+
ruby_to_FileBuilderContext(self->file_builder);
|
1802
|
+
size_t field_count, oneof_count;
|
1803
|
+
google_protobuf_FieldDescriptorProto** fields =
|
1804
|
+
google_protobuf_DescriptorProto_mutable_field(self->msg_proto, &field_count);
|
1805
|
+
const google_protobuf_OneofDescriptorProto*const* oneofs =
|
1806
|
+
google_protobuf_DescriptorProto_oneof_decl(self->msg_proto, &oneof_count);
|
1807
|
+
VALUE names = rb_hash_new();
|
1808
|
+
VALUE underscore = rb_str_new2("_");
|
1809
|
+
size_t i;
|
1810
|
+
|
1811
|
+
// We have to build a set of all names, to ensure that synthetic oneofs are
|
1812
|
+
// not creating conflicts.
|
1813
|
+
for (i = 0; i < field_count; i++) {
|
1814
|
+
upb_strview name = google_protobuf_FieldDescriptorProto_name(fields[i]);
|
1815
|
+
rb_hash_aset(names, rb_str_new(name.data, name.size), Qtrue);
|
1816
|
+
}
|
1817
|
+
for (i = 0; i < oneof_count; i++) {
|
1818
|
+
upb_strview name = google_protobuf_OneofDescriptorProto_name(oneofs[i]);
|
1819
|
+
rb_hash_aset(names, rb_str_new(name.data, name.size), Qtrue);
|
1820
|
+
}
|
1821
|
+
|
1822
|
+
for (i = 0; i < field_count; i++) {
|
1823
|
+
google_protobuf_OneofDescriptorProto* oneof_proto;
|
1824
|
+
VALUE oneof_name;
|
1825
|
+
upb_strview field_name;
|
1826
|
+
|
1827
|
+
if (!google_protobuf_FieldDescriptorProto_proto3_optional(fields[i])) {
|
1828
|
+
continue;
|
1829
|
+
}
|
1830
|
+
|
1831
|
+
// Prepend '_' until we are no longer conflicting.
|
1832
|
+
field_name = google_protobuf_FieldDescriptorProto_name(fields[i]);
|
1833
|
+
oneof_name = rb_str_new(field_name.data, field_name.size);
|
1834
|
+
while (rb_hash_lookup(names, oneof_name) != Qnil) {
|
1835
|
+
oneof_name = rb_str_plus(underscore, oneof_name);
|
1836
|
+
}
|
1837
|
+
|
1838
|
+
rb_hash_aset(names, oneof_name, Qtrue);
|
1839
|
+
google_protobuf_FieldDescriptorProto_set_oneof_index(fields[i],
|
1840
|
+
oneof_count++);
|
1841
|
+
oneof_proto = google_protobuf_DescriptorProto_add_oneof_decl(
|
1842
|
+
self->msg_proto, file_context->arena);
|
1843
|
+
google_protobuf_OneofDescriptorProto_set_name(
|
1844
|
+
oneof_proto, FileBuilderContext_strdup(self->file_builder, oneof_name));
|
1845
|
+
}
|
1846
|
+
}
|
1847
|
+
|
1761
1848
|
// -----------------------------------------------------------------------------
|
1762
1849
|
// OneofBuilderContext.
|
1763
1850
|
// -----------------------------------------------------------------------------
|
@@ -1829,7 +1916,7 @@ VALUE OneofBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
|
|
1829
1916
|
rb_scan_args(argc, argv, "32", &name, &type, &number, &type_class, &options);
|
1830
1917
|
|
1831
1918
|
msgdef_add_field(self->message_builder, UPB_LABEL_OPTIONAL, name, type,
|
1832
|
-
number, type_class, options, self->oneof_index);
|
1919
|
+
number, type_class, options, self->oneof_index, false);
|
1833
1920
|
|
1834
1921
|
return Qnil;
|
1835
1922
|
}
|
@@ -2033,6 +2120,7 @@ VALUE FileBuilderContext_add_message(VALUE _self, VALUE name) {
|
|
2033
2120
|
VALUE ctx = rb_class_new_instance(2, args, cMessageBuilderContext);
|
2034
2121
|
VALUE block = rb_block_proc();
|
2035
2122
|
rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
|
2123
|
+
MessageBuilderContext_add_synthetic_oneofs(ctx);
|
2036
2124
|
return Qnil;
|
2037
2125
|
}
|
2038
2126
|
|
@@ -30,6 +30,10 @@
|
|
30
30
|
|
31
31
|
#include "protobuf.h"
|
32
32
|
|
33
|
+
VALUE initialize_rb_class_with_no_args(VALUE klass) {
|
34
|
+
return rb_funcall(klass, rb_intern("new"), 0);
|
35
|
+
}
|
36
|
+
|
33
37
|
// This function is equivalent to rb_str_cat(), but unlike the real
|
34
38
|
// rb_str_cat(), it doesn't leak memory in some versions of Ruby.
|
35
39
|
// For more information, see:
|
@@ -44,6 +48,23 @@ VALUE noleak_rb_str_cat(VALUE rb_str, const char *str, long len) {
|
|
44
48
|
return rb_str;
|
45
49
|
}
|
46
50
|
|
51
|
+
bool is_wrapper(const upb_msgdef* m) {
|
52
|
+
switch (upb_msgdef_wellknowntype(m)) {
|
53
|
+
case UPB_WELLKNOWN_DOUBLEVALUE:
|
54
|
+
case UPB_WELLKNOWN_FLOATVALUE:
|
55
|
+
case UPB_WELLKNOWN_INT64VALUE:
|
56
|
+
case UPB_WELLKNOWN_UINT64VALUE:
|
57
|
+
case UPB_WELLKNOWN_INT32VALUE:
|
58
|
+
case UPB_WELLKNOWN_UINT32VALUE:
|
59
|
+
case UPB_WELLKNOWN_STRINGVALUE:
|
60
|
+
case UPB_WELLKNOWN_BYTESVALUE:
|
61
|
+
case UPB_WELLKNOWN_BOOLVALUE:
|
62
|
+
return true;
|
63
|
+
default:
|
64
|
+
return false;
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
47
68
|
// The code below also comes from upb's prototype Ruby binding, developed by
|
48
69
|
// haberman@.
|
49
70
|
|
@@ -117,19 +138,26 @@ static const void* newhandlerdata(upb_handlers* h, uint32_t ofs, int32_t hasbit)
|
|
117
138
|
typedef struct {
|
118
139
|
size_t ofs;
|
119
140
|
int32_t hasbit;
|
141
|
+
upb_fieldtype_t wrapped_type; // Only for wrappers.
|
120
142
|
VALUE subklass;
|
121
143
|
} submsg_handlerdata_t;
|
122
144
|
|
123
145
|
// Creates a handlerdata that contains offset and submessage type information.
|
124
146
|
static const void *newsubmsghandlerdata(upb_handlers* h,
|
147
|
+
const upb_fielddef *f,
|
125
148
|
uint32_t ofs,
|
126
149
|
int32_t hasbit,
|
127
150
|
VALUE subklass) {
|
128
151
|
submsg_handlerdata_t *hd = ALLOC(submsg_handlerdata_t);
|
152
|
+
const upb_msgdef *subm = upb_fielddef_msgsubdef(f);
|
129
153
|
hd->ofs = ofs;
|
130
154
|
hd->hasbit = hasbit;
|
131
155
|
hd->subklass = subklass;
|
132
156
|
upb_handlers_addcleanup(h, hd, xfree);
|
157
|
+
if (is_wrapper(subm)) {
|
158
|
+
const upb_fielddef *value_f = upb_msgdef_itof(subm, 1);
|
159
|
+
hd->wrapped_type = upb_fielddef_type(value_f);
|
160
|
+
}
|
133
161
|
return hd;
|
134
162
|
}
|
135
163
|
|
@@ -271,7 +299,7 @@ static void *appendsubmsg_handler(void *closure, const void *hd) {
|
|
271
299
|
const submsg_handlerdata_t *submsgdata = hd;
|
272
300
|
MessageHeader* submsg;
|
273
301
|
|
274
|
-
VALUE submsg_rb =
|
302
|
+
VALUE submsg_rb = initialize_rb_class_with_no_args(submsgdata->subklass);
|
275
303
|
RepeatedField_push(ary, submsg_rb);
|
276
304
|
|
277
305
|
TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg);
|
@@ -298,7 +326,7 @@ static void *submsg_handler(void *closure, const void *hd) {
|
|
298
326
|
|
299
327
|
if (DEREF(msg, submsgdata->ofs, VALUE) == Qnil) {
|
300
328
|
DEREF(msg, submsgdata->ofs, VALUE) =
|
301
|
-
|
329
|
+
initialize_rb_class_with_no_args(submsgdata->subklass);
|
302
330
|
}
|
303
331
|
|
304
332
|
set_hasbit(closure, submsgdata->hasbit);
|
@@ -310,12 +338,39 @@ static void *submsg_handler(void *closure, const void *hd) {
|
|
310
338
|
}
|
311
339
|
|
312
340
|
static void* startwrapper(void* closure, const void* hd) {
|
313
|
-
char* msg = closure;
|
314
341
|
const submsg_handlerdata_t* submsgdata = hd;
|
342
|
+
char* msg = closure;
|
343
|
+
VALUE* field = (VALUE*)(msg + submsgdata->ofs);
|
315
344
|
|
316
345
|
set_hasbit(closure, submsgdata->hasbit);
|
317
346
|
|
318
|
-
|
347
|
+
switch (submsgdata->wrapped_type) {
|
348
|
+
case UPB_TYPE_FLOAT:
|
349
|
+
case UPB_TYPE_DOUBLE:
|
350
|
+
*field = DBL2NUM(0);
|
351
|
+
break;
|
352
|
+
case UPB_TYPE_BOOL:
|
353
|
+
*field = Qfalse;
|
354
|
+
break;
|
355
|
+
case UPB_TYPE_STRING:
|
356
|
+
*field = get_frozen_string(NULL, 0, false);
|
357
|
+
break;
|
358
|
+
case UPB_TYPE_BYTES:
|
359
|
+
*field = get_frozen_string(NULL, 0, true);
|
360
|
+
break;
|
361
|
+
case UPB_TYPE_ENUM:
|
362
|
+
case UPB_TYPE_INT32:
|
363
|
+
case UPB_TYPE_INT64:
|
364
|
+
case UPB_TYPE_UINT32:
|
365
|
+
case UPB_TYPE_UINT64:
|
366
|
+
*field = INT2NUM(0);
|
367
|
+
break;
|
368
|
+
case UPB_TYPE_MESSAGE:
|
369
|
+
rb_raise(rb_eRuntimeError,
|
370
|
+
"Internal logic error with well-known types.");
|
371
|
+
}
|
372
|
+
|
373
|
+
return field;
|
319
374
|
}
|
320
375
|
|
321
376
|
// Handler data for startmap/endmap handlers.
|
@@ -379,10 +434,8 @@ static void *startmap_handler(void *closure, const void *hd) {
|
|
379
434
|
}
|
380
435
|
|
381
436
|
static bool endmap_handler(void *closure, const void *hd) {
|
382
|
-
|
383
|
-
|
384
|
-
VALUE map_rb = DEREF(msg, mapdata->ofs, VALUE);
|
385
|
-
Map_set_frame(map_rb, Qnil);
|
437
|
+
map_parse_frame_t* frame = closure;
|
438
|
+
Map_set_frame(frame->map, Qnil);
|
386
439
|
return true;
|
387
440
|
}
|
388
441
|
|
@@ -498,7 +551,7 @@ static void *oneofsubmsg_handler(void *closure,
|
|
498
551
|
if (oldcase != oneofdata->oneof_case_num ||
|
499
552
|
DEREF(msg, oneofdata->ofs, VALUE) == Qnil) {
|
500
553
|
DEREF(msg, oneofdata->ofs, VALUE) =
|
501
|
-
|
554
|
+
initialize_rb_class_with_no_args(oneofdata->subklass);
|
502
555
|
}
|
503
556
|
// Set the oneof case *after* allocating the new class instance -- otherwise,
|
504
557
|
// if the Ruby GC is invoked as part of a call into the VM, it might invoke
|
@@ -522,23 +575,6 @@ static void* oneof_startwrapper(void* closure, const void* hd) {
|
|
522
575
|
return msg + oneofdata->ofs;
|
523
576
|
}
|
524
577
|
|
525
|
-
bool is_wrapper(const upb_msgdef* m) {
|
526
|
-
switch (upb_msgdef_wellknowntype(m)) {
|
527
|
-
case UPB_WELLKNOWN_DOUBLEVALUE:
|
528
|
-
case UPB_WELLKNOWN_FLOATVALUE:
|
529
|
-
case UPB_WELLKNOWN_INT64VALUE:
|
530
|
-
case UPB_WELLKNOWN_UINT64VALUE:
|
531
|
-
case UPB_WELLKNOWN_INT32VALUE:
|
532
|
-
case UPB_WELLKNOWN_UINT32VALUE:
|
533
|
-
case UPB_WELLKNOWN_STRINGVALUE:
|
534
|
-
case UPB_WELLKNOWN_BYTESVALUE:
|
535
|
-
case UPB_WELLKNOWN_BOOLVALUE:
|
536
|
-
return true;
|
537
|
-
default:
|
538
|
-
return false;
|
539
|
-
}
|
540
|
-
}
|
541
|
-
|
542
578
|
// Set up handlers for a repeated field.
|
543
579
|
static void add_handlers_for_repeated_field(upb_handlers *h,
|
544
580
|
const Descriptor* desc,
|
@@ -579,7 +615,7 @@ static void add_handlers_for_repeated_field(upb_handlers *h,
|
|
579
615
|
case UPB_TYPE_MESSAGE: {
|
580
616
|
VALUE subklass = field_type_class(desc->layout, f);
|
581
617
|
upb_handlerattr attr = UPB_HANDLERATTR_INIT;
|
582
|
-
attr.handler_data = newsubmsghandlerdata(h, 0, -1, subklass);
|
618
|
+
attr.handler_data = newsubmsghandlerdata(h, f, 0, -1, subklass);
|
583
619
|
if (is_wrapper(upb_fielddef_msgsubdef(f))) {
|
584
620
|
upb_handlers_setstartsubmsg(h, f, appendwrapper_handler, &attr);
|
585
621
|
} else {
|
@@ -708,7 +744,7 @@ static void add_handlers_for_singular_field(const Descriptor* desc,
|
|
708
744
|
case UPB_TYPE_MESSAGE: {
|
709
745
|
upb_handlerattr attr = UPB_HANDLERATTR_INIT;
|
710
746
|
attr.handler_data = newsubmsghandlerdata(
|
711
|
-
h, offset, hasbit, field_type_class(desc->layout, f));
|
747
|
+
h, f, offset, hasbit, field_type_class(desc->layout, f));
|
712
748
|
if (is_wrapper(upb_fielddef_msgsubdef(f))) {
|
713
749
|
upb_handlers_setstartsubmsg(h, f, startwrapper, &attr);
|
714
750
|
} else {
|
@@ -897,7 +933,7 @@ void add_handlers_for_message(const void *closure, upb_handlers *h) {
|
|
897
933
|
!upb_msg_field_done(&i);
|
898
934
|
upb_msg_field_next(&i)) {
|
899
935
|
const upb_fielddef *f = upb_msg_iter_field(&i);
|
900
|
-
const upb_oneofdef
|
936
|
+
const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(f);
|
901
937
|
size_t offset = get_field_offset(desc->layout, f);
|
902
938
|
|
903
939
|
if (oneof) {
|
@@ -1004,7 +1040,7 @@ VALUE Message_decode(VALUE klass, VALUE data) {
|
|
1004
1040
|
rb_raise(rb_eArgError, "Expected string for binary protobuf data.");
|
1005
1041
|
}
|
1006
1042
|
|
1007
|
-
msg_rb =
|
1043
|
+
msg_rb = initialize_rb_class_with_no_args(msgklass);
|
1008
1044
|
TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
|
1009
1045
|
|
1010
1046
|
{
|
@@ -1080,7 +1116,7 @@ VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) {
|
|
1080
1116
|
// convert, because string handlers pass data directly to message string
|
1081
1117
|
// fields.
|
1082
1118
|
|
1083
|
-
msg_rb =
|
1119
|
+
msg_rb = initialize_rb_class_with_no_args(msgklass);
|
1084
1120
|
TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
|
1085
1121
|
|
1086
1122
|
{
|
@@ -1162,7 +1198,7 @@ static void putsubmsg(VALUE submsg, const upb_fielddef *f, upb_sink sink,
|
|
1162
1198
|
|
1163
1199
|
upb_sink_startsubmsg(sink, getsel(f, UPB_HANDLER_STARTSUBMSG), &subsink);
|
1164
1200
|
putmsg(submsg, subdesc, subsink, depth + 1, emit_defaults, is_json, true);
|
1165
|
-
upb_sink_endsubmsg(sink, getsel(f, UPB_HANDLER_ENDSUBMSG));
|
1201
|
+
upb_sink_endsubmsg(sink, subsink, getsel(f, UPB_HANDLER_ENDSUBMSG));
|
1166
1202
|
}
|
1167
1203
|
|
1168
1204
|
static void putary(VALUE ary, const upb_fielddef* f, upb_sink sink, int depth,
|
@@ -1307,7 +1343,7 @@ static void putmap(VALUE map, const upb_fielddef* f, upb_sink sink, int depth,
|
|
1307
1343
|
entry_sink, emit_defaults, is_json);
|
1308
1344
|
|
1309
1345
|
upb_sink_endmsg(entry_sink, &status);
|
1310
|
-
upb_sink_endsubmsg(subsink, getsel(f, UPB_HANDLER_ENDSUBMSG));
|
1346
|
+
upb_sink_endsubmsg(subsink, entry_sink, getsel(f, UPB_HANDLER_ENDSUBMSG));
|
1311
1347
|
}
|
1312
1348
|
|
1313
1349
|
upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ));
|
@@ -1432,6 +1468,7 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
|
|
1432
1468
|
MessageHeader* msg;
|
1433
1469
|
upb_msg_field_iter i;
|
1434
1470
|
upb_status status;
|
1471
|
+
bool json_wrapper = is_wrapper(desc->msgdef) && is_json;
|
1435
1472
|
|
1436
1473
|
if (is_json &&
|
1437
1474
|
upb_msgdef_wellknowntype(desc->msgdef) == UPB_WELLKNOWN_ANY) {
|
@@ -1469,7 +1506,7 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
|
|
1469
1506
|
!upb_msg_field_done(&i);
|
1470
1507
|
upb_msg_field_next(&i)) {
|
1471
1508
|
upb_fielddef *f = upb_msg_iter_field(&i);
|
1472
|
-
const upb_oneofdef
|
1509
|
+
const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(f);
|
1473
1510
|
bool is_matching_oneof = false;
|
1474
1511
|
uint32_t offset =
|
1475
1512
|
desc->layout->fields[upb_fielddef_index(f)].offset +
|
@@ -1508,7 +1545,7 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
|
|
1508
1545
|
is_default = RSTRING_LEN(str) == 0;
|
1509
1546
|
}
|
1510
1547
|
|
1511
|
-
if (is_matching_oneof || emit_defaults || !is_default) {
|
1548
|
+
if (is_matching_oneof || emit_defaults || !is_default || json_wrapper) {
|
1512
1549
|
putstr(str, f, sink);
|
1513
1550
|
}
|
1514
1551
|
} else if (upb_fielddef_issubmsg(f)) {
|
@@ -1528,7 +1565,7 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
|
|
1528
1565
|
} else if (upb_msgdef_syntax(desc->msgdef) == UPB_SYNTAX_PROTO3) { \
|
1529
1566
|
is_default = default_value == value; \
|
1530
1567
|
} \
|
1531
|
-
if (is_matching_oneof || emit_defaults || !is_default) {
|
1568
|
+
if (is_matching_oneof || emit_defaults || !is_default || json_wrapper) { \
|
1532
1569
|
upb_sink_put##upbtype(sink, sel, value); \
|
1533
1570
|
} \
|
1534
1571
|
} break;
|
@@ -1677,7 +1714,7 @@ static void discard_unknown(VALUE msg_rb, const Descriptor* desc) {
|
|
1677
1714
|
!upb_msg_field_done(&it);
|
1678
1715
|
upb_msg_field_next(&it)) {
|
1679
1716
|
upb_fielddef *f = upb_msg_iter_field(&it);
|
1680
|
-
const upb_oneofdef
|
1717
|
+
const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(f);
|
1681
1718
|
uint32_t offset =
|
1682
1719
|
desc->layout->fields[upb_fielddef_index(f)].offset +
|
1683
1720
|
sizeof(MessageHeader);
|