google-protobuf 3.11.0 → 3.12.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 +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);
|