google-protobuf 3.9.2 → 3.10.0.rc.1
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 +851 -830
- data/ext/google/protobuf_c/encode_decode.c +219 -285
- data/ext/google/protobuf_c/extconf.rb +2 -4
- data/ext/google/protobuf_c/map.c +15 -9
- data/ext/google/protobuf_c/message.c +84 -91
- data/ext/google/protobuf_c/protobuf.c +30 -15
- data/ext/google/protobuf_c/protobuf.h +100 -54
- data/ext/google/protobuf_c/repeated_field.c +44 -19
- data/ext/google/protobuf_c/storage.c +219 -153
- data/ext/google/protobuf_c/upb.c +4516 -8706
- data/ext/google/protobuf_c/upb.h +4920 -8476
- data/lib/google/protobuf.rb +66 -0
- data/lib/google/protobuf/any_pb.rb +1 -1
- data/lib/google/protobuf/api_pb.rb +3 -3
- data/lib/google/protobuf/duration_pb.rb +1 -1
- data/lib/google/protobuf/empty_pb.rb +1 -1
- data/lib/google/protobuf/field_mask_pb.rb +1 -1
- data/lib/google/protobuf/source_context_pb.rb +1 -1
- data/lib/google/protobuf/struct_pb.rb +4 -4
- data/lib/google/protobuf/timestamp_pb.rb +1 -1
- data/lib/google/protobuf/type_pb.rb +8 -8
- data/lib/google/protobuf/well_known_types.rb +8 -2
- data/lib/google/protobuf/wrappers_pb.rb +9 -9
- data/tests/basic.rb +22 -6
- metadata +6 -5
@@ -117,18 +117,18 @@ static const void* newhandlerdata(upb_handlers* h, uint32_t ofs, int32_t hasbit)
|
|
117
117
|
typedef struct {
|
118
118
|
size_t ofs;
|
119
119
|
int32_t hasbit;
|
120
|
-
|
120
|
+
VALUE subklass;
|
121
121
|
} submsg_handlerdata_t;
|
122
122
|
|
123
123
|
// Creates a handlerdata that contains offset and submessage type information.
|
124
124
|
static const void *newsubmsghandlerdata(upb_handlers* h,
|
125
125
|
uint32_t ofs,
|
126
126
|
int32_t hasbit,
|
127
|
-
|
127
|
+
VALUE subklass) {
|
128
128
|
submsg_handlerdata_t *hd = ALLOC(submsg_handlerdata_t);
|
129
129
|
hd->ofs = ofs;
|
130
130
|
hd->hasbit = hasbit;
|
131
|
-
hd->
|
131
|
+
hd->subklass = subklass;
|
132
132
|
upb_handlers_addcleanup(h, hd, xfree);
|
133
133
|
return hd;
|
134
134
|
}
|
@@ -137,13 +137,14 @@ typedef struct {
|
|
137
137
|
size_t ofs; // union data slot
|
138
138
|
size_t case_ofs; // oneof_case field
|
139
139
|
uint32_t oneof_case_num; // oneof-case number to place in oneof_case field
|
140
|
-
|
140
|
+
VALUE subklass;
|
141
141
|
} oneof_handlerdata_t;
|
142
142
|
|
143
143
|
static const void *newoneofhandlerdata(upb_handlers *h,
|
144
144
|
uint32_t ofs,
|
145
145
|
uint32_t case_ofs,
|
146
|
-
const upb_fielddef *f
|
146
|
+
const upb_fielddef *f,
|
147
|
+
const Descriptor* desc) {
|
147
148
|
oneof_handlerdata_t *hd = ALLOC(oneof_handlerdata_t);
|
148
149
|
hd->ofs = ofs;
|
149
150
|
hd->case_ofs = case_ofs;
|
@@ -154,11 +155,10 @@ static const void *newoneofhandlerdata(upb_handlers *h,
|
|
154
155
|
// create a separate ID space. In addition, using the field tag number here
|
155
156
|
// lets us easily look up the field in the oneof accessor.
|
156
157
|
hd->oneof_case_num = upb_fielddef_number(f);
|
157
|
-
if (
|
158
|
-
hd->
|
159
|
-
} else {
|
160
|
-
hd->md = NULL;
|
158
|
+
if (is_value_field(f)) {
|
159
|
+
hd->oneof_case_num |= ONEOF_CASE_MASK;
|
161
160
|
}
|
161
|
+
hd->subklass = field_type_class(desc->layout, f);
|
162
162
|
upb_handlers_addcleanup(h, hd, xfree);
|
163
163
|
return hd;
|
164
164
|
}
|
@@ -254,13 +254,13 @@ static size_t stringdata_handler(void* closure, const void* hd,
|
|
254
254
|
}
|
255
255
|
|
256
256
|
static bool stringdata_end_handler(void* closure, const void* hd) {
|
257
|
-
VALUE rb_str = closure;
|
257
|
+
VALUE rb_str = (VALUE)closure;
|
258
258
|
rb_obj_freeze(rb_str);
|
259
259
|
return true;
|
260
260
|
}
|
261
261
|
|
262
262
|
static bool appendstring_end_handler(void* closure, const void* hd) {
|
263
|
-
VALUE rb_str = closure;
|
263
|
+
VALUE rb_str = (VALUE)closure;
|
264
264
|
rb_obj_freeze(rb_str);
|
265
265
|
return true;
|
266
266
|
}
|
@@ -269,12 +269,9 @@ static bool appendstring_end_handler(void* closure, const void* hd) {
|
|
269
269
|
static void *appendsubmsg_handler(void *closure, const void *hd) {
|
270
270
|
VALUE ary = (VALUE)closure;
|
271
271
|
const submsg_handlerdata_t *submsgdata = hd;
|
272
|
-
VALUE subdesc =
|
273
|
-
get_def_obj((void*)submsgdata->md);
|
274
|
-
VALUE subklass = Descriptor_msgclass(subdesc);
|
275
272
|
MessageHeader* submsg;
|
276
273
|
|
277
|
-
VALUE submsg_rb = rb_class_new_instance(0, NULL, subklass);
|
274
|
+
VALUE submsg_rb = rb_class_new_instance(0, NULL, submsgdata->subklass);
|
278
275
|
RepeatedField_push(ary, submsg_rb);
|
279
276
|
|
280
277
|
TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg);
|
@@ -285,15 +282,12 @@ static void *appendsubmsg_handler(void *closure, const void *hd) {
|
|
285
282
|
static void *submsg_handler(void *closure, const void *hd) {
|
286
283
|
MessageHeader* msg = closure;
|
287
284
|
const submsg_handlerdata_t* submsgdata = hd;
|
288
|
-
VALUE subdesc =
|
289
|
-
get_def_obj((void*)submsgdata->md);
|
290
|
-
VALUE subklass = Descriptor_msgclass(subdesc);
|
291
285
|
VALUE submsg_rb;
|
292
286
|
MessageHeader* submsg;
|
293
287
|
|
294
288
|
if (DEREF(msg, submsgdata->ofs, VALUE) == Qnil) {
|
295
289
|
DEREF(msg, submsgdata->ofs, VALUE) =
|
296
|
-
rb_class_new_instance(0, NULL, subklass);
|
290
|
+
rb_class_new_instance(0, NULL, submsgdata->subklass);
|
297
291
|
}
|
298
292
|
|
299
293
|
set_hasbit(closure, submsgdata->hasbit);
|
@@ -309,11 +303,7 @@ typedef struct {
|
|
309
303
|
size_t ofs;
|
310
304
|
upb_fieldtype_t key_field_type;
|
311
305
|
upb_fieldtype_t value_field_type;
|
312
|
-
|
313
|
-
// We know that we can hold this reference because the handlerdata has the
|
314
|
-
// same lifetime as the upb_handlers struct, and the upb_handlers struct holds
|
315
|
-
// a reference to the upb_msgdef, which in turn has references to its subdefs.
|
316
|
-
const upb_def* value_field_subdef;
|
306
|
+
VALUE subklass;
|
317
307
|
} map_handlerdata_t;
|
318
308
|
|
319
309
|
// Temporary frame for map parsing: at the beginning of a map entry message, a
|
@@ -349,33 +339,36 @@ rb_data_type_t MapParseFrame_type = {
|
|
349
339
|
{ MapParseFrame_mark, MapParseFrame_free, NULL },
|
350
340
|
};
|
351
341
|
|
352
|
-
|
353
|
-
|
342
|
+
// Handler to begin a map entry: allocates a temporary frame. This is the
|
343
|
+
// 'startsubmsg' handler on the msgdef that contains the map field.
|
344
|
+
static void *startmap_handler(void *closure, const void *hd) {
|
345
|
+
MessageHeader* msg = closure;
|
346
|
+
const map_handlerdata_t* mapdata = hd;
|
354
347
|
map_parse_frame_t* frame = ALLOC(map_parse_frame_t);
|
355
|
-
|
356
|
-
frame->map = map;
|
357
|
-
native_slot_init(handlerdata->key_field_type, &frame->key_storage);
|
358
|
-
native_slot_init(handlerdata->value_field_type, &frame->value_storage);
|
348
|
+
VALUE map_rb = DEREF(msg, mapdata->ofs, VALUE);
|
359
349
|
|
360
|
-
|
361
|
-
|
350
|
+
frame->handlerdata = mapdata;
|
351
|
+
frame->map = map_rb;
|
352
|
+
native_slot_init(mapdata->key_field_type, &frame->key_storage);
|
353
|
+
native_slot_init(mapdata->value_field_type, &frame->value_storage);
|
354
|
+
|
355
|
+
Map_set_frame(map_rb,
|
356
|
+
TypedData_Wrap_Struct(rb_cObject, &MapParseFrame_type, frame));
|
362
357
|
|
363
358
|
return frame;
|
364
359
|
}
|
365
360
|
|
366
|
-
|
367
|
-
// 'startsubmsg' handler on the msgdef that contains the map field.
|
368
|
-
static void *startmapentry_handler(void *closure, const void *hd) {
|
361
|
+
static bool endmap_handler(void *closure, const void *hd) {
|
369
362
|
MessageHeader* msg = closure;
|
370
363
|
const map_handlerdata_t* mapdata = hd;
|
371
364
|
VALUE map_rb = DEREF(msg, mapdata->ofs, VALUE);
|
372
|
-
|
373
|
-
return
|
365
|
+
Map_set_frame(map_rb, Qnil);
|
366
|
+
return true;
|
374
367
|
}
|
375
368
|
|
376
369
|
// Handler to end a map entry: inserts the value defined during the message into
|
377
370
|
// the map. This is the 'endmsg' handler on the map entry msgdef.
|
378
|
-
static bool
|
371
|
+
static bool endmapentry_handler(void* closure, const void* hd, upb_status* s) {
|
379
372
|
map_parse_frame_t* frame = closure;
|
380
373
|
const map_handlerdata_t* mapdata = hd;
|
381
374
|
|
@@ -383,23 +376,11 @@ static bool endmap_handler(void *closure, const void *hd, upb_status* s) {
|
|
383
376
|
mapdata->key_field_type, Qnil,
|
384
377
|
&frame->key_storage);
|
385
378
|
|
386
|
-
VALUE
|
387
|
-
|
388
|
-
|
389
|
-
if (mapdata->value_field_type == UPB_TYPE_MESSAGE ||
|
390
|
-
mapdata->value_field_type == UPB_TYPE_ENUM) {
|
391
|
-
value_field_typeclass = get_def_obj(mapdata->value_field_subdef);
|
392
|
-
if (mapdata->value_field_type == UPB_TYPE_ENUM) {
|
393
|
-
value_field_typeclass = EnumDescriptor_enummodule(value_field_typeclass);
|
394
|
-
}
|
395
|
-
}
|
396
|
-
|
397
|
-
value = native_slot_get(
|
398
|
-
mapdata->value_field_type, value_field_typeclass,
|
379
|
+
VALUE value = native_slot_get(
|
380
|
+
mapdata->value_field_type, mapdata->subklass,
|
399
381
|
&frame->value_storage);
|
400
382
|
|
401
383
|
Map_index_set(frame->map, key, value);
|
402
|
-
Map_set_frame(frame->map, Qnil);
|
403
384
|
|
404
385
|
return true;
|
405
386
|
}
|
@@ -414,7 +395,7 @@ static bool endmap_handler(void *closure, const void *hd, upb_status* s) {
|
|
414
395
|
static map_handlerdata_t* new_map_handlerdata(
|
415
396
|
size_t ofs,
|
416
397
|
const upb_msgdef* mapentry_def,
|
417
|
-
Descriptor* desc) {
|
398
|
+
const Descriptor* desc) {
|
418
399
|
const upb_fielddef* key_field;
|
419
400
|
const upb_fielddef* value_field;
|
420
401
|
map_handlerdata_t* hd = ALLOC(map_handlerdata_t);
|
@@ -425,7 +406,7 @@ static map_handlerdata_t* new_map_handlerdata(
|
|
425
406
|
value_field = upb_msgdef_itof(mapentry_def, MAP_VALUE_FIELD);
|
426
407
|
assert(value_field != NULL);
|
427
408
|
hd->value_field_type = upb_fielddef_type(value_field);
|
428
|
-
hd->
|
409
|
+
hd->subklass = field_type_class(desc->layout, value_field);
|
429
410
|
|
430
411
|
return hd;
|
431
412
|
}
|
@@ -491,16 +472,13 @@ static void *oneofsubmsg_handler(void *closure,
|
|
491
472
|
const oneof_handlerdata_t *oneofdata = hd;
|
492
473
|
uint32_t oldcase = DEREF(msg, oneofdata->case_ofs, uint32_t);
|
493
474
|
|
494
|
-
VALUE subdesc =
|
495
|
-
get_def_obj((void*)oneofdata->md);
|
496
|
-
VALUE subklass = Descriptor_msgclass(subdesc);
|
497
475
|
VALUE submsg_rb;
|
498
476
|
MessageHeader* submsg;
|
499
477
|
|
500
478
|
if (oldcase != oneofdata->oneof_case_num ||
|
501
479
|
DEREF(msg, oneofdata->ofs, VALUE) == Qnil) {
|
502
480
|
DEREF(msg, oneofdata->ofs, VALUE) =
|
503
|
-
rb_class_new_instance(0, NULL, subklass);
|
481
|
+
rb_class_new_instance(0, NULL, oneofdata->subklass);
|
504
482
|
}
|
505
483
|
// Set the oneof case *after* allocating the new class instance -- otherwise,
|
506
484
|
// if the Ruby GC is invoked as part of a call into the VM, it might invoke
|
@@ -518,12 +496,12 @@ static void *oneofsubmsg_handler(void *closure,
|
|
518
496
|
|
519
497
|
// Set up handlers for a repeated field.
|
520
498
|
static void add_handlers_for_repeated_field(upb_handlers *h,
|
499
|
+
const Descriptor* desc,
|
521
500
|
const upb_fielddef *f,
|
522
501
|
size_t offset) {
|
523
|
-
upb_handlerattr attr =
|
524
|
-
|
502
|
+
upb_handlerattr attr = UPB_HANDLERATTR_INIT;
|
503
|
+
attr.handler_data = newhandlerdata(h, offset, -1);
|
525
504
|
upb_handlers_setstartseq(h, f, startseq_handler, &attr);
|
526
|
-
upb_handlerattr_uninit(&attr);
|
527
505
|
|
528
506
|
switch (upb_fielddef_type(f)) {
|
529
507
|
|
@@ -554,20 +532,20 @@ static void add_handlers_for_repeated_field(upb_handlers *h,
|
|
554
532
|
break;
|
555
533
|
}
|
556
534
|
case UPB_TYPE_MESSAGE: {
|
557
|
-
|
558
|
-
|
535
|
+
VALUE subklass = field_type_class(desc->layout, f);
|
536
|
+
upb_handlerattr attr = UPB_HANDLERATTR_INIT;
|
537
|
+
attr.handler_data = newsubmsghandlerdata(h, 0, -1, subklass);
|
559
538
|
upb_handlers_setstartsubmsg(h, f, appendsubmsg_handler, &attr);
|
560
|
-
upb_handlerattr_uninit(&attr);
|
561
539
|
break;
|
562
540
|
}
|
563
541
|
}
|
564
542
|
}
|
565
543
|
|
566
544
|
// Set up handlers for a singular field.
|
567
|
-
static void add_handlers_for_singular_field(
|
568
|
-
|
569
|
-
|
570
|
-
size_t hasbit_off) {
|
545
|
+
static void add_handlers_for_singular_field(const Descriptor* desc,
|
546
|
+
upb_handlers* h,
|
547
|
+
const upb_fielddef* f,
|
548
|
+
size_t offset, size_t hasbit_off) {
|
571
549
|
// The offset we pass to UPB points to the start of the Message,
|
572
550
|
// rather than the start of where our data is stored.
|
573
551
|
int32_t hasbit = -1;
|
@@ -589,23 +567,20 @@ static void add_handlers_for_singular_field(upb_handlers *h,
|
|
589
567
|
case UPB_TYPE_STRING:
|
590
568
|
case UPB_TYPE_BYTES: {
|
591
569
|
bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES;
|
592
|
-
upb_handlerattr attr =
|
593
|
-
|
570
|
+
upb_handlerattr attr = UPB_HANDLERATTR_INIT;
|
571
|
+
attr.handler_data = newhandlerdata(h, offset, hasbit);
|
594
572
|
upb_handlers_setstartstr(h, f,
|
595
573
|
is_bytes ? bytes_handler : str_handler,
|
596
574
|
&attr);
|
597
575
|
upb_handlers_setstring(h, f, stringdata_handler, &attr);
|
598
576
|
upb_handlers_setendstr(h, f, stringdata_end_handler, &attr);
|
599
|
-
upb_handlerattr_uninit(&attr);
|
600
577
|
break;
|
601
578
|
}
|
602
579
|
case UPB_TYPE_MESSAGE: {
|
603
|
-
upb_handlerattr attr =
|
604
|
-
|
605
|
-
|
606
|
-
hasbit, f));
|
580
|
+
upb_handlerattr attr = UPB_HANDLERATTR_INIT;
|
581
|
+
attr.handler_data = newsubmsghandlerdata(
|
582
|
+
h, offset, hasbit, field_type_class(desc->layout, f));
|
607
583
|
upb_handlers_setstartsubmsg(h, f, submsg_handler, &attr);
|
608
|
-
upb_handlerattr_uninit(&attr);
|
609
584
|
break;
|
610
585
|
}
|
611
586
|
}
|
@@ -615,36 +590,35 @@ static void add_handlers_for_singular_field(upb_handlers *h,
|
|
615
590
|
static void add_handlers_for_mapfield(upb_handlers* h,
|
616
591
|
const upb_fielddef* fielddef,
|
617
592
|
size_t offset,
|
618
|
-
Descriptor* desc) {
|
593
|
+
const Descriptor* desc) {
|
619
594
|
const upb_msgdef* map_msgdef = upb_fielddef_msgsubdef(fielddef);
|
620
595
|
map_handlerdata_t* hd = new_map_handlerdata(offset, map_msgdef, desc);
|
621
|
-
upb_handlerattr attr =
|
596
|
+
upb_handlerattr attr = UPB_HANDLERATTR_INIT;
|
622
597
|
|
623
598
|
upb_handlers_addcleanup(h, hd, xfree);
|
624
|
-
|
625
|
-
upb_handlers_setstartsubmsg(h, fielddef,
|
626
|
-
|
599
|
+
attr.handler_data = hd;
|
600
|
+
upb_handlers_setstartsubmsg(h, fielddef, startmap_handler, &attr);
|
601
|
+
upb_handlers_setendsubmsg(h, fielddef, endmap_handler, &attr);
|
627
602
|
}
|
628
603
|
|
629
604
|
// Adds handlers to a map-entry msgdef.
|
630
|
-
static void add_handlers_for_mapentry(const upb_msgdef* msgdef,
|
631
|
-
|
632
|
-
Descriptor* desc) {
|
605
|
+
static void add_handlers_for_mapentry(const upb_msgdef* msgdef, upb_handlers* h,
|
606
|
+
const Descriptor* desc) {
|
633
607
|
const upb_fielddef* key_field = map_entry_key(msgdef);
|
634
608
|
const upb_fielddef* value_field = map_entry_value(msgdef);
|
635
609
|
map_handlerdata_t* hd = new_map_handlerdata(0, msgdef, desc);
|
636
|
-
upb_handlerattr attr =
|
610
|
+
upb_handlerattr attr = UPB_HANDLERATTR_INIT;
|
637
611
|
|
638
612
|
upb_handlers_addcleanup(h, hd, xfree);
|
639
|
-
|
640
|
-
upb_handlers_setendmsg(h,
|
613
|
+
attr.handler_data = hd;
|
614
|
+
upb_handlers_setendmsg(h, endmapentry_handler, &attr);
|
641
615
|
|
642
616
|
add_handlers_for_singular_field(
|
643
|
-
h, key_field,
|
617
|
+
desc, h, key_field,
|
644
618
|
offsetof(map_parse_frame_t, key_storage),
|
645
619
|
MESSAGE_FIELD_NO_HASBIT);
|
646
620
|
add_handlers_for_singular_field(
|
647
|
-
h, value_field,
|
621
|
+
desc, h, value_field,
|
648
622
|
offsetof(map_parse_frame_t, value_storage),
|
649
623
|
MESSAGE_FIELD_NO_HASBIT);
|
650
624
|
}
|
@@ -653,11 +627,11 @@ static void add_handlers_for_mapentry(const upb_msgdef* msgdef,
|
|
653
627
|
static void add_handlers_for_oneof_field(upb_handlers *h,
|
654
628
|
const upb_fielddef *f,
|
655
629
|
size_t offset,
|
656
|
-
size_t oneof_case_offset
|
657
|
-
|
658
|
-
upb_handlerattr attr =
|
659
|
-
|
660
|
-
|
630
|
+
size_t oneof_case_offset,
|
631
|
+
const Descriptor* desc) {
|
632
|
+
upb_handlerattr attr = UPB_HANDLERATTR_INIT;
|
633
|
+
attr.handler_data =
|
634
|
+
newoneofhandlerdata(h, offset, oneof_case_offset, f, desc);
|
661
635
|
|
662
636
|
switch (upb_fielddef_type(f)) {
|
663
637
|
|
@@ -692,15 +666,13 @@ static void add_handlers_for_oneof_field(upb_handlers *h,
|
|
692
666
|
break;
|
693
667
|
}
|
694
668
|
}
|
695
|
-
|
696
|
-
upb_handlerattr_uninit(&attr);
|
697
669
|
}
|
698
670
|
|
699
671
|
static bool unknown_field_handler(void* closure, const void* hd,
|
700
672
|
const char* buf, size_t size) {
|
673
|
+
MessageHeader* msg = (MessageHeader*)closure;
|
701
674
|
UPB_UNUSED(hd);
|
702
675
|
|
703
|
-
MessageHeader* msg = (MessageHeader*)closure;
|
704
676
|
if (msg->unknown_fields == NULL) {
|
705
677
|
msg->unknown_fields = malloc(sizeof(stringsink));
|
706
678
|
stringsink_init(msg->unknown_fields);
|
@@ -711,98 +683,88 @@ static bool unknown_field_handler(void* closure, const void* hd,
|
|
711
683
|
return true;
|
712
684
|
}
|
713
685
|
|
714
|
-
|
686
|
+
void add_handlers_for_message(const void *closure, upb_handlers *h) {
|
687
|
+
const VALUE descriptor_pool = (VALUE)closure;
|
715
688
|
const upb_msgdef* msgdef = upb_handlers_msgdef(h);
|
716
|
-
Descriptor* desc =
|
689
|
+
Descriptor* desc =
|
690
|
+
ruby_to_Descriptor(get_msgdef_obj(descriptor_pool, msgdef));
|
717
691
|
upb_msg_field_iter i;
|
718
|
-
|
719
|
-
// If this is a mapentry message type, set up a special set of handlers and
|
720
|
-
// bail out of the normal (user-defined) message type handling.
|
721
|
-
if (upb_msgdef_mapentry(msgdef)) {
|
722
|
-
add_handlers_for_mapentry(msgdef, h, desc);
|
723
|
-
return;
|
724
|
-
}
|
692
|
+
upb_handlerattr attr = UPB_HANDLERATTR_INIT;
|
725
693
|
|
726
694
|
// Ensure layout exists. We may be invoked to create handlers for a given
|
727
695
|
// message if we are included as a submsg of another message type before our
|
728
696
|
// class is actually built, so to work around this, we just create the layout
|
729
697
|
// (and handlers, in the class-building function) on-demand.
|
730
698
|
if (desc->layout == NULL) {
|
731
|
-
|
699
|
+
create_layout(desc);
|
700
|
+
}
|
701
|
+
|
702
|
+
// If this is a mapentry message type, set up a special set of handlers and
|
703
|
+
// bail out of the normal (user-defined) message type handling.
|
704
|
+
if (upb_msgdef_mapentry(msgdef)) {
|
705
|
+
add_handlers_for_mapentry(msgdef, h, desc);
|
706
|
+
return;
|
732
707
|
}
|
733
708
|
|
734
|
-
upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
|
735
709
|
upb_handlers_setunknown(h, unknown_field_handler, &attr);
|
736
710
|
|
737
711
|
for (upb_msg_field_begin(&i, desc->msgdef);
|
738
712
|
!upb_msg_field_done(&i);
|
739
713
|
upb_msg_field_next(&i)) {
|
740
714
|
const upb_fielddef *f = upb_msg_iter_field(&i);
|
715
|
+
const upb_oneofdef *oneof = upb_fielddef_containingoneof(f);
|
741
716
|
size_t offset = desc->layout->fields[upb_fielddef_index(f)].offset +
|
742
717
|
sizeof(MessageHeader);
|
743
718
|
|
744
|
-
if (
|
719
|
+
if (oneof) {
|
745
720
|
size_t oneof_case_offset =
|
746
|
-
desc->layout->
|
721
|
+
desc->layout->oneofs[upb_oneofdef_index(oneof)].case_offset +
|
747
722
|
sizeof(MessageHeader);
|
748
|
-
add_handlers_for_oneof_field(h, f, offset, oneof_case_offset);
|
723
|
+
add_handlers_for_oneof_field(h, f, offset, oneof_case_offset, desc);
|
749
724
|
} else if (is_map_field(f)) {
|
750
725
|
add_handlers_for_mapfield(h, f, offset, desc);
|
751
726
|
} else if (upb_fielddef_isseq(f)) {
|
752
|
-
add_handlers_for_repeated_field(h, f, offset);
|
727
|
+
add_handlers_for_repeated_field(h, desc, f, offset);
|
753
728
|
} else {
|
754
729
|
add_handlers_for_singular_field(
|
755
|
-
h, f, offset,
|
730
|
+
desc, h, f, offset,
|
731
|
+
desc->layout->fields[upb_fielddef_index(f)].hasbit);
|
756
732
|
}
|
757
733
|
}
|
758
734
|
}
|
759
735
|
|
760
|
-
// Creates upb handlers for populating a message.
|
761
|
-
static const upb_handlers *new_fill_handlers(Descriptor* desc,
|
762
|
-
const void* owner) {
|
763
|
-
// TODO(cfallin, haberman): once upb gets a caching/memoization layer for
|
764
|
-
// handlers, reuse subdef handlers so that e.g. if we already parse
|
765
|
-
// B-with-field-of-type-C, we don't have to rebuild the whole hierarchy to
|
766
|
-
// parse A-with-field-of-type-B-with-field-of-type-C.
|
767
|
-
return upb_handlers_newfrozen(desc->msgdef, owner,
|
768
|
-
add_handlers_for_message, NULL);
|
769
|
-
}
|
770
|
-
|
771
736
|
// Constructs the handlers for filling a message's data into an in-memory
|
772
737
|
// object.
|
773
738
|
const upb_handlers* get_fill_handlers(Descriptor* desc) {
|
774
|
-
|
775
|
-
|
776
|
-
new_fill_handlers(desc, &desc->fill_handlers);
|
777
|
-
}
|
778
|
-
return desc->fill_handlers;
|
739
|
+
DescriptorPool* pool = ruby_to_DescriptorPool(desc->descriptor_pool);
|
740
|
+
return upb_handlercache_get(pool->fill_handler_cache, desc->msgdef);
|
779
741
|
}
|
780
742
|
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
const upb_handlers* handlers = get_fill_handlers(desc);
|
786
|
-
upb_pbdecodermethodopts opts;
|
787
|
-
upb_pbdecodermethodopts_init(&opts, handlers);
|
743
|
+
static const upb_pbdecodermethod *msgdef_decodermethod(Descriptor* desc) {
|
744
|
+
DescriptorPool* pool = ruby_to_DescriptorPool(desc->descriptor_pool);
|
745
|
+
return upb_pbcodecache_get(pool->fill_method_cache, desc->msgdef);
|
746
|
+
}
|
788
747
|
|
789
|
-
|
748
|
+
static const upb_json_parsermethod *msgdef_jsonparsermethod(Descriptor* desc) {
|
749
|
+
DescriptorPool* pool = ruby_to_DescriptorPool(desc->descriptor_pool);
|
750
|
+
return upb_json_codecache_get(pool->json_fill_method_cache, desc->msgdef);
|
790
751
|
}
|
791
752
|
|
792
|
-
static const
|
793
|
-
|
794
|
-
|
795
|
-
desc, &desc->fill_method);
|
796
|
-
}
|
797
|
-
return desc->fill_method;
|
753
|
+
static const upb_handlers* msgdef_pb_serialize_handlers(Descriptor* desc) {
|
754
|
+
DescriptorPool* pool = ruby_to_DescriptorPool(desc->descriptor_pool);
|
755
|
+
return upb_handlercache_get(pool->pb_serialize_handler_cache, desc->msgdef);
|
798
756
|
}
|
799
757
|
|
800
|
-
static const
|
801
|
-
|
802
|
-
|
803
|
-
|
758
|
+
static const upb_handlers* msgdef_json_serialize_handlers(
|
759
|
+
Descriptor* desc, bool preserve_proto_fieldnames) {
|
760
|
+
DescriptorPool* pool = ruby_to_DescriptorPool(desc->descriptor_pool);
|
761
|
+
if (preserve_proto_fieldnames) {
|
762
|
+
return upb_handlercache_get(pool->json_serialize_handler_preserve_cache,
|
763
|
+
desc->msgdef);
|
764
|
+
} else {
|
765
|
+
return upb_handlercache_get(pool->json_serialize_handler_cache,
|
766
|
+
desc->msgdef);
|
804
767
|
}
|
805
|
-
return desc->json_fill_method;
|
806
768
|
}
|
807
769
|
|
808
770
|
|
@@ -812,7 +774,8 @@ static const upb_json_parsermethod *msgdef_jsonparsermethod(Descriptor* desc) {
|
|
812
774
|
// if any error occurs.
|
813
775
|
#define STACK_ENV_STACKBYTES 4096
|
814
776
|
typedef struct {
|
815
|
-
|
777
|
+
upb_arena *arena;
|
778
|
+
upb_status status;
|
816
779
|
const char* ruby_error_template;
|
817
780
|
char allocbuf[STACK_ENV_STACKBYTES];
|
818
781
|
} stackenv;
|
@@ -820,29 +783,22 @@ typedef struct {
|
|
820
783
|
static void stackenv_init(stackenv* se, const char* errmsg);
|
821
784
|
static void stackenv_uninit(stackenv* se);
|
822
785
|
|
823
|
-
// Callback invoked by upb if any error occurs during parsing or serialization.
|
824
|
-
static bool env_error_func(void* ud, const upb_status* status) {
|
825
|
-
stackenv* se = ud;
|
826
|
-
// Free the env -- rb_raise will longjmp up the stack past the encode/decode
|
827
|
-
// function so it would not otherwise have been freed.
|
828
|
-
stackenv_uninit(se);
|
829
|
-
|
830
|
-
// TODO(haberman): have a way to verify that this is actually a parse error,
|
831
|
-
// instead of just throwing "parse error" unconditionally.
|
832
|
-
rb_raise(cParseError, se->ruby_error_template, upb_status_errmsg(status));
|
833
|
-
// Never reached: rb_raise() always longjmp()s up the stack, past all of our
|
834
|
-
// code, back to Ruby.
|
835
|
-
return false;
|
836
|
-
}
|
837
|
-
|
838
786
|
static void stackenv_init(stackenv* se, const char* errmsg) {
|
839
787
|
se->ruby_error_template = errmsg;
|
840
|
-
|
841
|
-
|
788
|
+
se->arena =
|
789
|
+
upb_arena_init(se->allocbuf, sizeof(se->allocbuf), &upb_alloc_global);
|
790
|
+
upb_status_clear(&se->status);
|
842
791
|
}
|
843
792
|
|
844
793
|
static void stackenv_uninit(stackenv* se) {
|
845
|
-
|
794
|
+
upb_arena_free(se->arena);
|
795
|
+
|
796
|
+
if (!upb_ok(&se->status)) {
|
797
|
+
// TODO(haberman): have a way to verify that this is actually a parse error,
|
798
|
+
// instead of just throwing "parse error" unconditionally.
|
799
|
+
VALUE errmsg = rb_str_new2(upb_status_errmsg(&se->status));
|
800
|
+
rb_raise(cParseError, se->ruby_error_template, errmsg);
|
801
|
+
}
|
846
802
|
}
|
847
803
|
|
848
804
|
/*
|
@@ -873,10 +829,10 @@ VALUE Message_decode(VALUE klass, VALUE data) {
|
|
873
829
|
stackenv se;
|
874
830
|
upb_sink sink;
|
875
831
|
upb_pbdecoder* decoder;
|
876
|
-
stackenv_init(&se, "Error occurred during parsing: %
|
832
|
+
stackenv_init(&se, "Error occurred during parsing: %" PRIsVALUE);
|
877
833
|
|
878
834
|
upb_sink_reset(&sink, h, msg);
|
879
|
-
decoder = upb_pbdecoder_create(
|
835
|
+
decoder = upb_pbdecoder_create(se.arena, method, sink, &se.status);
|
880
836
|
upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data),
|
881
837
|
upb_pbdecoder_input(decoder));
|
882
838
|
|
@@ -894,8 +850,9 @@ VALUE Message_decode(VALUE klass, VALUE data) {
|
|
894
850
|
* format) under the interpretration given by this message class's definition
|
895
851
|
* and returns a message object with the corresponding field values.
|
896
852
|
*
|
897
|
-
*
|
898
|
-
* ignore_unknown_fields: set true to ignore unknown fields (default is to
|
853
|
+
* @param options [Hash] options for the decoder
|
854
|
+
* ignore_unknown_fields: set true to ignore unknown fields (default is to
|
855
|
+
* raise an error)
|
899
856
|
*/
|
900
857
|
VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) {
|
901
858
|
VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
|
@@ -923,6 +880,7 @@ VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) {
|
|
923
880
|
if (TYPE(data) != T_STRING) {
|
924
881
|
rb_raise(rb_eArgError, "Expected string for JSON data.");
|
925
882
|
}
|
883
|
+
|
926
884
|
// TODO(cfallin): Check and respect string encoding. If not UTF-8, we need to
|
927
885
|
// convert, because string handlers pass data directly to message string
|
928
886
|
// fields.
|
@@ -936,11 +894,11 @@ VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) {
|
|
936
894
|
upb_sink sink;
|
937
895
|
upb_json_parser* parser;
|
938
896
|
DescriptorPool* pool = ruby_to_DescriptorPool(generated_pool);
|
939
|
-
stackenv_init(&se, "Error occurred during parsing: %
|
897
|
+
stackenv_init(&se, "Error occurred during parsing: %" PRIsVALUE);
|
940
898
|
|
941
899
|
upb_sink_reset(&sink, get_fill_handlers(desc), msg);
|
942
|
-
parser = upb_json_parser_create(
|
943
|
-
&
|
900
|
+
parser = upb_json_parser_create(se.arena, method, pool->symtab, sink,
|
901
|
+
&se.status, RTEST(ignore_unknown_fields));
|
944
902
|
upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data),
|
945
903
|
upb_json_parser_input(parser));
|
946
904
|
|
@@ -956,9 +914,8 @@ VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) {
|
|
956
914
|
|
957
915
|
/* msgvisitor *****************************************************************/
|
958
916
|
|
959
|
-
static void putmsg(VALUE msg, const Descriptor* desc,
|
960
|
-
|
961
|
-
bool is_json, bool open_msg);
|
917
|
+
static void putmsg(VALUE msg, const Descriptor* desc, upb_sink sink, int depth,
|
918
|
+
bool emit_defaults, bool is_json, bool open_msg);
|
962
919
|
|
963
920
|
static upb_selector_t getsel(const upb_fielddef *f, upb_handlertype_t type) {
|
964
921
|
upb_selector_t ret;
|
@@ -967,7 +924,7 @@ static upb_selector_t getsel(const upb_fielddef *f, upb_handlertype_t type) {
|
|
967
924
|
return ret;
|
968
925
|
}
|
969
926
|
|
970
|
-
static void putstr(VALUE str, const upb_fielddef *f, upb_sink
|
927
|
+
static void putstr(VALUE str, const upb_fielddef *f, upb_sink sink) {
|
971
928
|
upb_sink subsink;
|
972
929
|
|
973
930
|
if (str == Qnil) return;
|
@@ -984,12 +941,12 @@ static void putstr(VALUE str, const upb_fielddef *f, upb_sink *sink) {
|
|
984
941
|
|
985
942
|
upb_sink_startstr(sink, getsel(f, UPB_HANDLER_STARTSTR), RSTRING_LEN(str),
|
986
943
|
&subsink);
|
987
|
-
upb_sink_putstring(
|
944
|
+
upb_sink_putstring(subsink, getsel(f, UPB_HANDLER_STRING), RSTRING_PTR(str),
|
988
945
|
RSTRING_LEN(str), NULL);
|
989
946
|
upb_sink_endstr(sink, getsel(f, UPB_HANDLER_ENDSTR));
|
990
947
|
}
|
991
948
|
|
992
|
-
static void putsubmsg(VALUE submsg, const upb_fielddef *f, upb_sink
|
949
|
+
static void putsubmsg(VALUE submsg, const upb_fielddef *f, upb_sink sink,
|
993
950
|
int depth, bool emit_defaults, bool is_json) {
|
994
951
|
upb_sink subsink;
|
995
952
|
VALUE descriptor;
|
@@ -1001,16 +958,17 @@ static void putsubmsg(VALUE submsg, const upb_fielddef *f, upb_sink *sink,
|
|
1001
958
|
subdesc = ruby_to_Descriptor(descriptor);
|
1002
959
|
|
1003
960
|
upb_sink_startsubmsg(sink, getsel(f, UPB_HANDLER_STARTSUBMSG), &subsink);
|
1004
|
-
putmsg(submsg, subdesc,
|
961
|
+
putmsg(submsg, subdesc, subsink, depth + 1, emit_defaults, is_json, true);
|
1005
962
|
upb_sink_endsubmsg(sink, getsel(f, UPB_HANDLER_ENDSUBMSG));
|
1006
963
|
}
|
1007
964
|
|
1008
|
-
static void putary(VALUE ary, const upb_fielddef
|
1009
|
-
|
965
|
+
static void putary(VALUE ary, const upb_fielddef* f, upb_sink sink, int depth,
|
966
|
+
bool emit_defaults, bool is_json) {
|
1010
967
|
upb_sink subsink;
|
1011
968
|
upb_fieldtype_t type = upb_fielddef_type(f);
|
1012
969
|
upb_selector_t sel = 0;
|
1013
970
|
int size;
|
971
|
+
int i;
|
1014
972
|
|
1015
973
|
if (ary == Qnil) return;
|
1016
974
|
if (!emit_defaults && NUM2INT(RepeatedField_length(ary)) == 0) return;
|
@@ -1024,12 +982,12 @@ static void putary(VALUE ary, const upb_fielddef *f, upb_sink *sink,
|
|
1024
982
|
sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
|
1025
983
|
}
|
1026
984
|
|
1027
|
-
for (
|
985
|
+
for (i = 0; i < size; i++) {
|
1028
986
|
void* memory = RepeatedField_index_native(ary, i);
|
1029
987
|
switch (type) {
|
1030
|
-
#define T(upbtypeconst, upbtype, ctype)
|
1031
|
-
case upbtypeconst:
|
1032
|
-
upb_sink_put##upbtype(
|
988
|
+
#define T(upbtypeconst, upbtype, ctype) \
|
989
|
+
case upbtypeconst: \
|
990
|
+
upb_sink_put##upbtype(subsink, sel, *((ctype*)memory)); \
|
1033
991
|
break;
|
1034
992
|
|
1035
993
|
T(UPB_TYPE_FLOAT, float, float)
|
@@ -1043,11 +1001,10 @@ static void putary(VALUE ary, const upb_fielddef *f, upb_sink *sink,
|
|
1043
1001
|
|
1044
1002
|
case UPB_TYPE_STRING:
|
1045
1003
|
case UPB_TYPE_BYTES:
|
1046
|
-
putstr(*((VALUE *)memory), f,
|
1004
|
+
putstr(*((VALUE *)memory), f, subsink);
|
1047
1005
|
break;
|
1048
1006
|
case UPB_TYPE_MESSAGE:
|
1049
|
-
putsubmsg(*((VALUE
|
1050
|
-
emit_defaults, is_json);
|
1007
|
+
putsubmsg(*((VALUE*)memory), f, subsink, depth, emit_defaults, is_json);
|
1051
1008
|
break;
|
1052
1009
|
|
1053
1010
|
#undef T
|
@@ -1057,19 +1014,16 @@ static void putary(VALUE ary, const upb_fielddef *f, upb_sink *sink,
|
|
1057
1014
|
upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ));
|
1058
1015
|
}
|
1059
1016
|
|
1060
|
-
static void put_ruby_value(VALUE value,
|
1061
|
-
|
1062
|
-
VALUE type_class,
|
1063
|
-
int depth,
|
1064
|
-
upb_sink *sink,
|
1065
|
-
bool emit_defaults,
|
1017
|
+
static void put_ruby_value(VALUE value, const upb_fielddef* f, VALUE type_class,
|
1018
|
+
int depth, upb_sink sink, bool emit_defaults,
|
1066
1019
|
bool is_json) {
|
1020
|
+
upb_selector_t sel = 0;
|
1021
|
+
|
1067
1022
|
if (depth > ENCODE_MAX_NESTING) {
|
1068
1023
|
rb_raise(rb_eRuntimeError,
|
1069
1024
|
"Maximum recursion depth exceeded during encoding.");
|
1070
1025
|
}
|
1071
1026
|
|
1072
|
-
upb_selector_t sel = 0;
|
1073
1027
|
if (upb_fielddef_isprimitive(f)) {
|
1074
1028
|
sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
|
1075
1029
|
}
|
@@ -1112,8 +1066,8 @@ static void put_ruby_value(VALUE value,
|
|
1112
1066
|
}
|
1113
1067
|
}
|
1114
1068
|
|
1115
|
-
static void putmap(VALUE map, const upb_fielddef
|
1116
|
-
|
1069
|
+
static void putmap(VALUE map, const upb_fielddef* f, upb_sink sink, int depth,
|
1070
|
+
bool emit_defaults, bool is_json) {
|
1117
1071
|
Map* self;
|
1118
1072
|
upb_sink subsink;
|
1119
1073
|
const upb_fielddef* key_field;
|
@@ -1137,17 +1091,17 @@ static void putmap(VALUE map, const upb_fielddef *f, upb_sink *sink,
|
|
1137
1091
|
upb_status status;
|
1138
1092
|
|
1139
1093
|
upb_sink entry_sink;
|
1140
|
-
upb_sink_startsubmsg(
|
1094
|
+
upb_sink_startsubmsg(subsink, getsel(f, UPB_HANDLER_STARTSUBMSG),
|
1141
1095
|
&entry_sink);
|
1142
|
-
upb_sink_startmsg(
|
1096
|
+
upb_sink_startmsg(entry_sink);
|
1143
1097
|
|
1144
|
-
put_ruby_value(key, key_field, Qnil, depth + 1,
|
1145
|
-
|
1098
|
+
put_ruby_value(key, key_field, Qnil, depth + 1, entry_sink, emit_defaults,
|
1099
|
+
is_json);
|
1146
1100
|
put_ruby_value(value, value_field, self->value_type_class, depth + 1,
|
1147
|
-
|
1101
|
+
entry_sink, emit_defaults, is_json);
|
1148
1102
|
|
1149
|
-
upb_sink_endmsg(
|
1150
|
-
upb_sink_endsubmsg(
|
1103
|
+
upb_sink_endmsg(entry_sink, &status);
|
1104
|
+
upb_sink_endsubmsg(subsink, getsel(f, UPB_HANDLER_ENDSUBMSG));
|
1151
1105
|
}
|
1152
1106
|
|
1153
1107
|
upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ));
|
@@ -1156,8 +1110,8 @@ static void putmap(VALUE map, const upb_fielddef *f, upb_sink *sink,
|
|
1156
1110
|
static const upb_handlers* msgdef_json_serialize_handlers(
|
1157
1111
|
Descriptor* desc, bool preserve_proto_fieldnames);
|
1158
1112
|
|
1159
|
-
static void putjsonany(VALUE msg_rb, const Descriptor* desc,
|
1160
|
-
|
1113
|
+
static void putjsonany(VALUE msg_rb, const Descriptor* desc, upb_sink sink,
|
1114
|
+
int depth, bool emit_defaults) {
|
1161
1115
|
upb_status status;
|
1162
1116
|
MessageHeader* msg = NULL;
|
1163
1117
|
const upb_fielddef* type_field = upb_msgdef_itof(desc->msgdef, UPB_ANY_TYPE);
|
@@ -1204,16 +1158,14 @@ static void putjsonany(VALUE msg_rb, const Descriptor* desc,
|
|
1204
1158
|
{
|
1205
1159
|
uint32_t value_offset;
|
1206
1160
|
VALUE value_str_rb;
|
1207
|
-
const char* value_str;
|
1208
1161
|
size_t value_len;
|
1209
1162
|
|
1210
1163
|
value_offset = desc->layout->fields[upb_fielddef_index(value_field)].offset;
|
1211
1164
|
value_str_rb = DEREF(Message_data(msg), value_offset, VALUE);
|
1212
|
-
value_str = RSTRING_PTR(value_str_rb);
|
1213
1165
|
value_len = RSTRING_LEN(value_str_rb);
|
1214
1166
|
|
1215
1167
|
if (value_len > 0) {
|
1216
|
-
VALUE payload_desc_rb =
|
1168
|
+
VALUE payload_desc_rb = get_msgdef_obj(generated_pool, payload_type);
|
1217
1169
|
Descriptor* payload_desc = ruby_to_Descriptor(payload_desc_rb);
|
1218
1170
|
VALUE payload_class = Descriptor_msgclass(payload_desc_rb);
|
1219
1171
|
upb_sink subsink;
|
@@ -1231,8 +1183,8 @@ static void putjsonany(VALUE msg_rb, const Descriptor* desc,
|
|
1231
1183
|
|
1232
1184
|
subsink.handlers =
|
1233
1185
|
msgdef_json_serialize_handlers(payload_desc, true);
|
1234
|
-
subsink.closure = sink
|
1235
|
-
putmsg(payload_msg_rb, payload_desc,
|
1186
|
+
subsink.closure = sink.closure;
|
1187
|
+
putmsg(payload_msg_rb, payload_desc, subsink, depth, emit_defaults, true,
|
1236
1188
|
is_wellknown);
|
1237
1189
|
}
|
1238
1190
|
}
|
@@ -1242,7 +1194,7 @@ static void putjsonany(VALUE msg_rb, const Descriptor* desc,
|
|
1242
1194
|
|
1243
1195
|
static void putjsonlistvalue(
|
1244
1196
|
VALUE msg_rb, const Descriptor* desc,
|
1245
|
-
upb_sink
|
1197
|
+
upb_sink sink, int depth, bool emit_defaults) {
|
1246
1198
|
upb_status status;
|
1247
1199
|
upb_sink subsink;
|
1248
1200
|
MessageHeader* msg = NULL;
|
@@ -1269,7 +1221,7 @@ static void putjsonlistvalue(
|
|
1269
1221
|
}
|
1270
1222
|
|
1271
1223
|
static void putmsg(VALUE msg_rb, const Descriptor* desc,
|
1272
|
-
upb_sink
|
1224
|
+
upb_sink sink, int depth, bool emit_defaults,
|
1273
1225
|
bool is_json, bool open_msg) {
|
1274
1226
|
MessageHeader* msg;
|
1275
1227
|
upb_msg_field_iter i;
|
@@ -1311,19 +1263,18 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
|
|
1311
1263
|
!upb_msg_field_done(&i);
|
1312
1264
|
upb_msg_field_next(&i)) {
|
1313
1265
|
upb_fielddef *f = upb_msg_iter_field(&i);
|
1266
|
+
const upb_oneofdef *oneof = upb_fielddef_containingoneof(f);
|
1314
1267
|
bool is_matching_oneof = false;
|
1315
1268
|
uint32_t offset =
|
1316
1269
|
desc->layout->fields[upb_fielddef_index(f)].offset +
|
1317
1270
|
sizeof(MessageHeader);
|
1318
1271
|
|
1319
|
-
if (
|
1320
|
-
uint32_t
|
1321
|
-
desc->layout
|
1322
|
-
sizeof(MessageHeader);
|
1272
|
+
if (oneof) {
|
1273
|
+
uint32_t oneof_case =
|
1274
|
+
slot_read_oneof_case(desc->layout, Message_data(msg), oneof);
|
1323
1275
|
// For a oneof, check that this field is actually present -- skip all the
|
1324
1276
|
// below if not.
|
1325
|
-
if (
|
1326
|
-
upb_fielddef_number(f)) {
|
1277
|
+
if (oneof_case != upb_fielddef_number(f)) {
|
1327
1278
|
continue;
|
1328
1279
|
}
|
1329
1280
|
// Otherwise, fall through to the appropriate singular-field handler
|
@@ -1360,20 +1311,19 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
|
|
1360
1311
|
} else {
|
1361
1312
|
upb_selector_t sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
|
1362
1313
|
|
1363
|
-
#define T(upbtypeconst, upbtype, ctype, default_value)
|
1364
|
-
case upbtypeconst: {
|
1365
|
-
|
1366
|
-
|
1367
|
-
|
1368
|
-
|
1369
|
-
|
1370
|
-
|
1371
|
-
|
1372
|
-
|
1373
|
-
|
1374
|
-
|
1375
|
-
|
1376
|
-
break;
|
1314
|
+
#define T(upbtypeconst, upbtype, ctype, default_value) \
|
1315
|
+
case upbtypeconst: { \
|
1316
|
+
ctype value = DEREF(msg, offset, ctype); \
|
1317
|
+
bool is_default = false; \
|
1318
|
+
if (upb_fielddef_haspresence(f)) { \
|
1319
|
+
is_default = layout_has(desc->layout, Message_data(msg), f) == Qfalse; \
|
1320
|
+
} else if (upb_msgdef_syntax(desc->msgdef) == UPB_SYNTAX_PROTO3) { \
|
1321
|
+
is_default = default_value == value; \
|
1322
|
+
} \
|
1323
|
+
if (is_matching_oneof || emit_defaults || !is_default) { \
|
1324
|
+
upb_sink_put##upbtype(sink, sel, value); \
|
1325
|
+
} \
|
1326
|
+
} break;
|
1377
1327
|
|
1378
1328
|
switch (upb_fielddef_type(f)) {
|
1379
1329
|
T(UPB_TYPE_FLOAT, float, float, 0.0)
|
@@ -1395,9 +1345,11 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
|
|
1395
1345
|
}
|
1396
1346
|
}
|
1397
1347
|
|
1398
|
-
|
1399
|
-
|
1400
|
-
|
1348
|
+
{
|
1349
|
+
stringsink* unknown = msg->unknown_fields;
|
1350
|
+
if (unknown != NULL) {
|
1351
|
+
upb_sink_putunknown(sink, unknown->ptr, unknown->len);
|
1352
|
+
}
|
1401
1353
|
}
|
1402
1354
|
|
1403
1355
|
if (open_msg) {
|
@@ -1405,33 +1357,6 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
|
|
1405
1357
|
}
|
1406
1358
|
}
|
1407
1359
|
|
1408
|
-
static const upb_handlers* msgdef_pb_serialize_handlers(Descriptor* desc) {
|
1409
|
-
if (desc->pb_serialize_handlers == NULL) {
|
1410
|
-
desc->pb_serialize_handlers =
|
1411
|
-
upb_pb_encoder_newhandlers(desc->msgdef, &desc->pb_serialize_handlers);
|
1412
|
-
}
|
1413
|
-
return desc->pb_serialize_handlers;
|
1414
|
-
}
|
1415
|
-
|
1416
|
-
static const upb_handlers* msgdef_json_serialize_handlers(
|
1417
|
-
Descriptor* desc, bool preserve_proto_fieldnames) {
|
1418
|
-
if (preserve_proto_fieldnames) {
|
1419
|
-
if (desc->json_serialize_handlers == NULL) {
|
1420
|
-
desc->json_serialize_handlers =
|
1421
|
-
upb_json_printer_newhandlers(
|
1422
|
-
desc->msgdef, true, &desc->json_serialize_handlers);
|
1423
|
-
}
|
1424
|
-
return desc->json_serialize_handlers;
|
1425
|
-
} else {
|
1426
|
-
if (desc->json_serialize_handlers_preserve == NULL) {
|
1427
|
-
desc->json_serialize_handlers_preserve =
|
1428
|
-
upb_json_printer_newhandlers(
|
1429
|
-
desc->msgdef, false, &desc->json_serialize_handlers_preserve);
|
1430
|
-
}
|
1431
|
-
return desc->json_serialize_handlers_preserve;
|
1432
|
-
}
|
1433
|
-
}
|
1434
|
-
|
1435
1360
|
/*
|
1436
1361
|
* call-seq:
|
1437
1362
|
* MessageClass.encode(msg) => bytes
|
@@ -1454,8 +1379,8 @@ VALUE Message_encode(VALUE klass, VALUE msg_rb) {
|
|
1454
1379
|
upb_pb_encoder* encoder;
|
1455
1380
|
VALUE ret;
|
1456
1381
|
|
1457
|
-
stackenv_init(&se, "Error occurred during encoding: %
|
1458
|
-
encoder = upb_pb_encoder_create(
|
1382
|
+
stackenv_init(&se, "Error occurred during encoding: %" PRIsVALUE);
|
1383
|
+
encoder = upb_pb_encoder_create(se.arena, serialize_handlers, sink.sink);
|
1459
1384
|
|
1460
1385
|
putmsg(msg_rb, desc, upb_pb_encoder_input(encoder), 0, false, false, true);
|
1461
1386
|
|
@@ -1512,8 +1437,8 @@ VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
|
|
1512
1437
|
stackenv se;
|
1513
1438
|
VALUE ret;
|
1514
1439
|
|
1515
|
-
stackenv_init(&se, "Error occurred during encoding: %
|
1516
|
-
printer = upb_json_printer_create(
|
1440
|
+
stackenv_init(&se, "Error occurred during encoding: %" PRIsVALUE);
|
1441
|
+
printer = upb_json_printer_create(se.arena, serialize_handlers, sink.sink);
|
1517
1442
|
|
1518
1443
|
putmsg(msg_rb, desc, upb_json_printer_input(printer), 0,
|
1519
1444
|
RTEST(emit_defaults), true, true);
|
@@ -1533,28 +1458,29 @@ static void discard_unknown(VALUE msg_rb, const Descriptor* desc) {
|
|
1533
1458
|
|
1534
1459
|
TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
|
1535
1460
|
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1461
|
+
{
|
1462
|
+
stringsink* unknown = msg->unknown_fields;
|
1463
|
+
if (unknown != NULL) {
|
1464
|
+
stringsink_uninit(unknown);
|
1465
|
+
msg->unknown_fields = NULL;
|
1466
|
+
}
|
1540
1467
|
}
|
1541
1468
|
|
1542
1469
|
for (upb_msg_field_begin(&it, desc->msgdef);
|
1543
1470
|
!upb_msg_field_done(&it);
|
1544
1471
|
upb_msg_field_next(&it)) {
|
1545
1472
|
upb_fielddef *f = upb_msg_iter_field(&it);
|
1473
|
+
const upb_oneofdef *oneof = upb_fielddef_containingoneof(f);
|
1546
1474
|
uint32_t offset =
|
1547
1475
|
desc->layout->fields[upb_fielddef_index(f)].offset +
|
1548
1476
|
sizeof(MessageHeader);
|
1549
1477
|
|
1550
|
-
if (
|
1551
|
-
uint32_t
|
1552
|
-
desc->layout
|
1553
|
-
sizeof(MessageHeader);
|
1478
|
+
if (oneof) {
|
1479
|
+
uint32_t oneof_case =
|
1480
|
+
slot_read_oneof_case(desc->layout, Message_data(msg), oneof);
|
1554
1481
|
// For a oneof, check that this field is actually present -- skip all the
|
1555
1482
|
// below if not.
|
1556
|
-
if (
|
1557
|
-
upb_fielddef_number(f)) {
|
1483
|
+
if (oneof_case != upb_fielddef_number(f)) {
|
1558
1484
|
continue;
|
1559
1485
|
}
|
1560
1486
|
// Otherwise, fall through to the appropriate singular-field handler
|
@@ -1566,10 +1492,12 @@ static void discard_unknown(VALUE msg_rb, const Descriptor* desc) {
|
|
1566
1492
|
}
|
1567
1493
|
|
1568
1494
|
if (is_map_field(f)) {
|
1495
|
+
VALUE map;
|
1496
|
+
Map_iter map_it;
|
1497
|
+
|
1569
1498
|
if (!upb_fielddef_issubmsg(map_field_value(f))) continue;
|
1570
|
-
|
1499
|
+
map = DEREF(msg, offset, VALUE);
|
1571
1500
|
if (map == Qnil) continue;
|
1572
|
-
Map_iter map_it;
|
1573
1501
|
for (Map_begin(map, &map_it); !Map_done(&map_it); Map_next(&map_it)) {
|
1574
1502
|
VALUE submsg = Map_iter_value(&map_it);
|
1575
1503
|
VALUE descriptor = rb_ivar_get(submsg, descriptor_instancevar_interned);
|
@@ -1578,9 +1506,12 @@ static void discard_unknown(VALUE msg_rb, const Descriptor* desc) {
|
|
1578
1506
|
}
|
1579
1507
|
} else if (upb_fielddef_isseq(f)) {
|
1580
1508
|
VALUE ary = DEREF(msg, offset, VALUE);
|
1509
|
+
int size;
|
1510
|
+
int i;
|
1511
|
+
|
1581
1512
|
if (ary == Qnil) continue;
|
1582
|
-
|
1583
|
-
for (
|
1513
|
+
size = NUM2INT(RepeatedField_length(ary));
|
1514
|
+
for (i = 0; i < size; i++) {
|
1584
1515
|
void* memory = RepeatedField_index_native(ary, i);
|
1585
1516
|
VALUE submsg = *((VALUE *)memory);
|
1586
1517
|
VALUE descriptor = rb_ivar_get(submsg, descriptor_instancevar_interned);
|
@@ -1589,9 +1520,12 @@ static void discard_unknown(VALUE msg_rb, const Descriptor* desc) {
|
|
1589
1520
|
}
|
1590
1521
|
} else {
|
1591
1522
|
VALUE submsg = DEREF(msg, offset, VALUE);
|
1523
|
+
VALUE descriptor;
|
1524
|
+
const Descriptor* subdesc;
|
1525
|
+
|
1592
1526
|
if (submsg == Qnil) continue;
|
1593
|
-
|
1594
|
-
|
1527
|
+
descriptor = rb_ivar_get(submsg, descriptor_instancevar_interned);
|
1528
|
+
subdesc = ruby_to_Descriptor(descriptor);
|
1595
1529
|
discard_unknown(submsg, subdesc);
|
1596
1530
|
}
|
1597
1531
|
}
|