google-protobuf 3.8.0 → 3.13.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 +942 -833
- data/ext/google/protobuf_c/encode_decode.c +482 -301
- data/ext/google/protobuf_c/extconf.rb +2 -4
- data/ext/google/protobuf_c/map.c +39 -58
- data/ext/google/protobuf_c/message.c +124 -114
- data/ext/google/protobuf_c/protobuf.c +30 -15
- data/ext/google/protobuf_c/protobuf.h +109 -57
- data/ext/google/protobuf_c/repeated_field.c +47 -21
- data/ext/google/protobuf_c/storage.c +305 -169
- data/ext/google/protobuf_c/upb.c +5335 -8998
- data/ext/google/protobuf_c/upb.h +4634 -8498
- data/lib/google/protobuf.rb +70 -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 +229 -67
- data/tests/generated_code_test.rb +0 -0
- data/tests/stress.rb +0 -0
- metadata +17 -10
@@ -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;
|
120
|
-
|
141
|
+
upb_fieldtype_t wrapped_type; // Only for wrappers.
|
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
|
-
hd->
|
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
|
|
@@ -137,13 +165,14 @@ typedef struct {
|
|
137
165
|
size_t ofs; // union data slot
|
138
166
|
size_t case_ofs; // oneof_case field
|
139
167
|
uint32_t oneof_case_num; // oneof-case number to place in oneof_case field
|
140
|
-
|
168
|
+
VALUE subklass;
|
141
169
|
} oneof_handlerdata_t;
|
142
170
|
|
143
171
|
static const void *newoneofhandlerdata(upb_handlers *h,
|
144
172
|
uint32_t ofs,
|
145
173
|
uint32_t case_ofs,
|
146
|
-
const upb_fielddef *f
|
174
|
+
const upb_fielddef *f,
|
175
|
+
const Descriptor* desc) {
|
147
176
|
oneof_handlerdata_t *hd = ALLOC(oneof_handlerdata_t);
|
148
177
|
hd->ofs = ofs;
|
149
178
|
hd->case_ofs = case_ofs;
|
@@ -154,11 +183,10 @@ static const void *newoneofhandlerdata(upb_handlers *h,
|
|
154
183
|
// create a separate ID space. In addition, using the field tag number here
|
155
184
|
// lets us easily look up the field in the oneof accessor.
|
156
185
|
hd->oneof_case_num = upb_fielddef_number(f);
|
157
|
-
if (
|
158
|
-
hd->
|
159
|
-
} else {
|
160
|
-
hd->md = NULL;
|
186
|
+
if (is_value_field(f)) {
|
187
|
+
hd->oneof_case_num |= ONEOF_CASE_MASK;
|
161
188
|
}
|
189
|
+
hd->subklass = field_type_class(desc->layout, f);
|
162
190
|
upb_handlers_addcleanup(h, hd, xfree);
|
163
191
|
return hd;
|
164
192
|
}
|
@@ -254,13 +282,13 @@ static size_t stringdata_handler(void* closure, const void* hd,
|
|
254
282
|
}
|
255
283
|
|
256
284
|
static bool stringdata_end_handler(void* closure, const void* hd) {
|
257
|
-
VALUE rb_str = closure;
|
285
|
+
VALUE rb_str = (VALUE)closure;
|
258
286
|
rb_obj_freeze(rb_str);
|
259
287
|
return true;
|
260
288
|
}
|
261
289
|
|
262
290
|
static bool appendstring_end_handler(void* closure, const void* hd) {
|
263
|
-
VALUE rb_str = closure;
|
291
|
+
VALUE rb_str = (VALUE)closure;
|
264
292
|
rb_obj_freeze(rb_str);
|
265
293
|
return true;
|
266
294
|
}
|
@@ -269,31 +297,36 @@ static bool appendstring_end_handler(void* closure, const void* hd) {
|
|
269
297
|
static void *appendsubmsg_handler(void *closure, const void *hd) {
|
270
298
|
VALUE ary = (VALUE)closure;
|
271
299
|
const submsg_handlerdata_t *submsgdata = hd;
|
272
|
-
VALUE subdesc =
|
273
|
-
get_def_obj((void*)submsgdata->md);
|
274
|
-
VALUE subklass = Descriptor_msgclass(subdesc);
|
275
300
|
MessageHeader* submsg;
|
276
301
|
|
277
|
-
VALUE submsg_rb =
|
302
|
+
VALUE submsg_rb = initialize_rb_class_with_no_args(submsgdata->subklass);
|
278
303
|
RepeatedField_push(ary, submsg_rb);
|
279
304
|
|
280
305
|
TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg);
|
281
306
|
return submsg;
|
282
307
|
}
|
283
308
|
|
309
|
+
// Appends a wrapper to a repeated field (a regular Ruby array for now).
|
310
|
+
static void *appendwrapper_handler(void *closure, const void *hd) {
|
311
|
+
VALUE ary = (VALUE)closure;
|
312
|
+
int size = RepeatedField_size(ary);
|
313
|
+
(void)hd;
|
314
|
+
|
315
|
+
RepeatedField_push(ary, Qnil);
|
316
|
+
|
317
|
+
return RepeatedField_index_native(ary, size);
|
318
|
+
}
|
319
|
+
|
284
320
|
// Sets a non-repeated submessage field in a message.
|
285
321
|
static void *submsg_handler(void *closure, const void *hd) {
|
286
322
|
MessageHeader* msg = closure;
|
287
323
|
const submsg_handlerdata_t* submsgdata = hd;
|
288
|
-
VALUE subdesc =
|
289
|
-
get_def_obj((void*)submsgdata->md);
|
290
|
-
VALUE subklass = Descriptor_msgclass(subdesc);
|
291
324
|
VALUE submsg_rb;
|
292
325
|
MessageHeader* submsg;
|
293
326
|
|
294
327
|
if (DEREF(msg, submsgdata->ofs, VALUE) == Qnil) {
|
295
328
|
DEREF(msg, submsgdata->ofs, VALUE) =
|
296
|
-
|
329
|
+
initialize_rb_class_with_no_args(submsgdata->subklass);
|
297
330
|
}
|
298
331
|
|
299
332
|
set_hasbit(closure, submsgdata->hasbit);
|
@@ -304,16 +337,48 @@ static void *submsg_handler(void *closure, const void *hd) {
|
|
304
337
|
return submsg;
|
305
338
|
}
|
306
339
|
|
340
|
+
static void* startwrapper(void* closure, const void* hd) {
|
341
|
+
const submsg_handlerdata_t* submsgdata = hd;
|
342
|
+
char* msg = closure;
|
343
|
+
VALUE* field = (VALUE*)(msg + submsgdata->ofs);
|
344
|
+
|
345
|
+
set_hasbit(closure, submsgdata->hasbit);
|
346
|
+
|
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;
|
374
|
+
}
|
375
|
+
|
307
376
|
// Handler data for startmap/endmap handlers.
|
308
377
|
typedef struct {
|
309
378
|
size_t ofs;
|
310
379
|
upb_fieldtype_t key_field_type;
|
311
380
|
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;
|
381
|
+
VALUE subklass;
|
317
382
|
} map_handlerdata_t;
|
318
383
|
|
319
384
|
// Temporary frame for map parsing: at the beginning of a map entry message, a
|
@@ -349,33 +414,34 @@ rb_data_type_t MapParseFrame_type = {
|
|
349
414
|
{ MapParseFrame_mark, MapParseFrame_free, NULL },
|
350
415
|
};
|
351
416
|
|
352
|
-
static map_parse_frame_t* map_push_frame(VALUE map,
|
353
|
-
const map_handlerdata_t* handlerdata) {
|
354
|
-
map_parse_frame_t* frame = ALLOC(map_parse_frame_t);
|
355
|
-
frame->handlerdata = handlerdata;
|
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);
|
359
|
-
|
360
|
-
Map_set_frame(map,
|
361
|
-
TypedData_Wrap_Struct(rb_cObject, &MapParseFrame_type, frame));
|
362
|
-
|
363
|
-
return frame;
|
364
|
-
}
|
365
|
-
|
366
417
|
// Handler to begin a map entry: allocates a temporary frame. This is the
|
367
418
|
// 'startsubmsg' handler on the msgdef that contains the map field.
|
368
|
-
static void *
|
419
|
+
static void *startmap_handler(void *closure, const void *hd) {
|
369
420
|
MessageHeader* msg = closure;
|
370
421
|
const map_handlerdata_t* mapdata = hd;
|
422
|
+
map_parse_frame_t* frame = ALLOC(map_parse_frame_t);
|
371
423
|
VALUE map_rb = DEREF(msg, mapdata->ofs, VALUE);
|
372
424
|
|
373
|
-
|
425
|
+
frame->handlerdata = mapdata;
|
426
|
+
frame->map = map_rb;
|
427
|
+
native_slot_init(mapdata->key_field_type, &frame->key_storage);
|
428
|
+
native_slot_init(mapdata->value_field_type, &frame->value_storage);
|
429
|
+
|
430
|
+
Map_set_frame(map_rb,
|
431
|
+
TypedData_Wrap_Struct(rb_cObject, &MapParseFrame_type, frame));
|
432
|
+
|
433
|
+
return frame;
|
434
|
+
}
|
435
|
+
|
436
|
+
static bool endmap_handler(void *closure, const void *hd) {
|
437
|
+
map_parse_frame_t* frame = closure;
|
438
|
+
Map_set_frame(frame->map, Qnil);
|
439
|
+
return true;
|
374
440
|
}
|
375
441
|
|
376
442
|
// Handler to end a map entry: inserts the value defined during the message into
|
377
443
|
// the map. This is the 'endmsg' handler on the map entry msgdef.
|
378
|
-
static bool
|
444
|
+
static bool endmapentry_handler(void* closure, const void* hd, upb_status* s) {
|
379
445
|
map_parse_frame_t* frame = closure;
|
380
446
|
const map_handlerdata_t* mapdata = hd;
|
381
447
|
|
@@ -383,20 +449,11 @@ static bool endmap_handler(void *closure, const void *hd, upb_status* s) {
|
|
383
449
|
mapdata->key_field_type, Qnil,
|
384
450
|
&frame->key_storage);
|
385
451
|
|
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
|
-
}
|
393
|
-
|
394
|
-
value = native_slot_get(
|
395
|
-
mapdata->value_field_type, value_field_typeclass,
|
452
|
+
VALUE value = native_slot_get(
|
453
|
+
mapdata->value_field_type, mapdata->subklass,
|
396
454
|
&frame->value_storage);
|
397
455
|
|
398
456
|
Map_index_set(frame->map, key, value);
|
399
|
-
Map_set_frame(frame->map, Qnil);
|
400
457
|
|
401
458
|
return true;
|
402
459
|
}
|
@@ -411,7 +468,7 @@ static bool endmap_handler(void *closure, const void *hd, upb_status* s) {
|
|
411
468
|
static map_handlerdata_t* new_map_handlerdata(
|
412
469
|
size_t ofs,
|
413
470
|
const upb_msgdef* mapentry_def,
|
414
|
-
Descriptor* desc) {
|
471
|
+
const Descriptor* desc) {
|
415
472
|
const upb_fielddef* key_field;
|
416
473
|
const upb_fielddef* value_field;
|
417
474
|
map_handlerdata_t* hd = ALLOC(map_handlerdata_t);
|
@@ -422,7 +479,7 @@ static map_handlerdata_t* new_map_handlerdata(
|
|
422
479
|
value_field = upb_msgdef_itof(mapentry_def, MAP_VALUE_FIELD);
|
423
480
|
assert(value_field != NULL);
|
424
481
|
hd->value_field_type = upb_fielddef_type(value_field);
|
425
|
-
hd->
|
482
|
+
hd->subklass = field_type_class(desc->layout, value_field);
|
426
483
|
|
427
484
|
return hd;
|
428
485
|
}
|
@@ -488,16 +545,13 @@ static void *oneofsubmsg_handler(void *closure,
|
|
488
545
|
const oneof_handlerdata_t *oneofdata = hd;
|
489
546
|
uint32_t oldcase = DEREF(msg, oneofdata->case_ofs, uint32_t);
|
490
547
|
|
491
|
-
VALUE subdesc =
|
492
|
-
get_def_obj((void*)oneofdata->md);
|
493
|
-
VALUE subklass = Descriptor_msgclass(subdesc);
|
494
548
|
VALUE submsg_rb;
|
495
549
|
MessageHeader* submsg;
|
496
550
|
|
497
551
|
if (oldcase != oneofdata->oneof_case_num ||
|
498
552
|
DEREF(msg, oneofdata->ofs, VALUE) == Qnil) {
|
499
553
|
DEREF(msg, oneofdata->ofs, VALUE) =
|
500
|
-
|
554
|
+
initialize_rb_class_with_no_args(oneofdata->subklass);
|
501
555
|
}
|
502
556
|
// Set the oneof case *after* allocating the new class instance -- otherwise,
|
503
557
|
// if the Ruby GC is invoked as part of a call into the VM, it might invoke
|
@@ -505,22 +559,30 @@ static void *oneofsubmsg_handler(void *closure,
|
|
505
559
|
// indicating a VALUE is present and expect a valid VALUE. See comment in
|
506
560
|
// layout_set() for more detail: basically, the change to the value and the
|
507
561
|
// case must be atomic w.r.t. the Ruby VM.
|
508
|
-
DEREF(msg, oneofdata->case_ofs, uint32_t) =
|
509
|
-
oneofdata->oneof_case_num;
|
562
|
+
DEREF(msg, oneofdata->case_ofs, uint32_t) = oneofdata->oneof_case_num;
|
510
563
|
|
511
564
|
submsg_rb = DEREF(msg, oneofdata->ofs, VALUE);
|
512
565
|
TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg);
|
513
566
|
return submsg;
|
514
567
|
}
|
515
568
|
|
569
|
+
static void* oneof_startwrapper(void* closure, const void* hd) {
|
570
|
+
char* msg = closure;
|
571
|
+
const oneof_handlerdata_t *oneofdata = hd;
|
572
|
+
|
573
|
+
DEREF(msg, oneofdata->case_ofs, uint32_t) = oneofdata->oneof_case_num;
|
574
|
+
|
575
|
+
return msg + oneofdata->ofs;
|
576
|
+
}
|
577
|
+
|
516
578
|
// Set up handlers for a repeated field.
|
517
579
|
static void add_handlers_for_repeated_field(upb_handlers *h,
|
580
|
+
const Descriptor* desc,
|
518
581
|
const upb_fielddef *f,
|
519
582
|
size_t offset) {
|
520
|
-
upb_handlerattr attr =
|
521
|
-
|
583
|
+
upb_handlerattr attr = UPB_HANDLERATTR_INIT;
|
584
|
+
attr.handler_data = newhandlerdata(h, offset, -1);
|
522
585
|
upb_handlers_setstartseq(h, f, startseq_handler, &attr);
|
523
|
-
upb_handlerattr_uninit(&attr);
|
524
586
|
|
525
587
|
switch (upb_fielddef_type(f)) {
|
526
588
|
|
@@ -551,20 +613,104 @@ static void add_handlers_for_repeated_field(upb_handlers *h,
|
|
551
613
|
break;
|
552
614
|
}
|
553
615
|
case UPB_TYPE_MESSAGE: {
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
616
|
+
VALUE subklass = field_type_class(desc->layout, f);
|
617
|
+
upb_handlerattr attr = UPB_HANDLERATTR_INIT;
|
618
|
+
attr.handler_data = newsubmsghandlerdata(h, f, 0, -1, subklass);
|
619
|
+
if (is_wrapper(upb_fielddef_msgsubdef(f))) {
|
620
|
+
upb_handlers_setstartsubmsg(h, f, appendwrapper_handler, &attr);
|
621
|
+
} else {
|
622
|
+
upb_handlers_setstartsubmsg(h, f, appendsubmsg_handler, &attr);
|
623
|
+
}
|
558
624
|
break;
|
559
625
|
}
|
560
626
|
}
|
561
627
|
}
|
562
628
|
|
629
|
+
static bool doublewrapper_handler(void* closure, const void* hd, double val) {
|
630
|
+
VALUE* rbval = closure;
|
631
|
+
*rbval = DBL2NUM(val);
|
632
|
+
return true;
|
633
|
+
}
|
634
|
+
|
635
|
+
static bool floatwrapper_handler(void* closure, const void* hd, float val) {
|
636
|
+
VALUE* rbval = closure;
|
637
|
+
*rbval = DBL2NUM(val);
|
638
|
+
return true;
|
639
|
+
}
|
640
|
+
|
641
|
+
static bool int64wrapper_handler(void* closure, const void* hd, int64_t val) {
|
642
|
+
VALUE* rbval = closure;
|
643
|
+
*rbval = LL2NUM(val);
|
644
|
+
return true;
|
645
|
+
}
|
646
|
+
|
647
|
+
static bool uint64wrapper_handler(void* closure, const void* hd, uint64_t val) {
|
648
|
+
VALUE* rbval = closure;
|
649
|
+
*rbval = ULL2NUM(val);
|
650
|
+
return true;
|
651
|
+
}
|
652
|
+
|
653
|
+
static bool int32wrapper_handler(void* closure, const void* hd, int32_t val) {
|
654
|
+
VALUE* rbval = closure;
|
655
|
+
*rbval = INT2NUM(val);
|
656
|
+
return true;
|
657
|
+
}
|
658
|
+
|
659
|
+
static bool uint32wrapper_handler(void* closure, const void* hd, uint32_t val) {
|
660
|
+
VALUE* rbval = closure;
|
661
|
+
*rbval = UINT2NUM(val);
|
662
|
+
return true;
|
663
|
+
}
|
664
|
+
|
665
|
+
static void* startstringwrapper_handler(void* closure, const void* hd,
|
666
|
+
size_t size_hint) {
|
667
|
+
VALUE* rbval = closure;
|
668
|
+
(void)size_hint;
|
669
|
+
*rbval = rb_str_new(NULL, 0);
|
670
|
+
rb_enc_associate(*rbval, kRubyStringUtf8Encoding);
|
671
|
+
return closure;
|
672
|
+
}
|
673
|
+
|
674
|
+
static size_t stringwrapper_handler(void* closure, const void* hd,
|
675
|
+
const char* ptr, size_t len,
|
676
|
+
const upb_bufhandle* handle) {
|
677
|
+
VALUE* rbval = closure;
|
678
|
+
*rbval = noleak_rb_str_cat(*rbval, ptr, len);
|
679
|
+
return len;
|
680
|
+
}
|
681
|
+
|
682
|
+
static void* startbyteswrapper_handler(void* closure, const void* hd,
|
683
|
+
size_t size_hint) {
|
684
|
+
VALUE* rbval = closure;
|
685
|
+
(void)size_hint;
|
686
|
+
*rbval = rb_str_new(NULL, 0);
|
687
|
+
rb_enc_associate(*rbval, kRubyString8bitEncoding);
|
688
|
+
return closure;
|
689
|
+
}
|
690
|
+
|
691
|
+
static size_t byteswrapper_handler(void* closure, const void* hd,
|
692
|
+
const char* ptr, size_t len,
|
693
|
+
const upb_bufhandle* handle) {
|
694
|
+
VALUE* rbval = closure;
|
695
|
+
*rbval = noleak_rb_str_cat(*rbval, ptr, len);
|
696
|
+
return len;
|
697
|
+
}
|
698
|
+
|
699
|
+
static bool boolwrapper_handler(void* closure, const void* hd, bool val) {
|
700
|
+
VALUE* rbval = closure;
|
701
|
+
if (val) {
|
702
|
+
*rbval = Qtrue;
|
703
|
+
} else {
|
704
|
+
*rbval = Qfalse;
|
705
|
+
}
|
706
|
+
return true;
|
707
|
+
}
|
708
|
+
|
563
709
|
// Set up handlers for a singular field.
|
564
|
-
static void add_handlers_for_singular_field(
|
565
|
-
|
566
|
-
|
567
|
-
size_t hasbit_off) {
|
710
|
+
static void add_handlers_for_singular_field(const Descriptor* desc,
|
711
|
+
upb_handlers* h,
|
712
|
+
const upb_fielddef* f,
|
713
|
+
size_t offset, size_t hasbit_off) {
|
568
714
|
// The offset we pass to UPB points to the start of the Message,
|
569
715
|
// rather than the start of where our data is stored.
|
570
716
|
int32_t hasbit = -1;
|
@@ -586,24 +732,24 @@ static void add_handlers_for_singular_field(upb_handlers *h,
|
|
586
732
|
case UPB_TYPE_STRING:
|
587
733
|
case UPB_TYPE_BYTES: {
|
588
734
|
bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES;
|
589
|
-
upb_handlerattr attr =
|
590
|
-
|
735
|
+
upb_handlerattr attr = UPB_HANDLERATTR_INIT;
|
736
|
+
attr.handler_data = newhandlerdata(h, offset, hasbit);
|
591
737
|
upb_handlers_setstartstr(h, f,
|
592
738
|
is_bytes ? bytes_handler : str_handler,
|
593
739
|
&attr);
|
594
740
|
upb_handlers_setstring(h, f, stringdata_handler, &attr);
|
595
741
|
upb_handlers_setendstr(h, f, stringdata_end_handler, &attr);
|
596
|
-
upb_handlerattr_uninit(&attr);
|
597
742
|
break;
|
598
743
|
}
|
599
744
|
case UPB_TYPE_MESSAGE: {
|
600
|
-
upb_handlerattr attr =
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
745
|
+
upb_handlerattr attr = UPB_HANDLERATTR_INIT;
|
746
|
+
attr.handler_data = newsubmsghandlerdata(
|
747
|
+
h, f, offset, hasbit, field_type_class(desc->layout, f));
|
748
|
+
if (is_wrapper(upb_fielddef_msgsubdef(f))) {
|
749
|
+
upb_handlers_setstartsubmsg(h, f, startwrapper, &attr);
|
750
|
+
} else {
|
751
|
+
upb_handlers_setstartsubmsg(h, f, submsg_handler, &attr);
|
752
|
+
}
|
607
753
|
}
|
608
754
|
}
|
609
755
|
}
|
@@ -612,49 +758,87 @@ static void add_handlers_for_singular_field(upb_handlers *h,
|
|
612
758
|
static void add_handlers_for_mapfield(upb_handlers* h,
|
613
759
|
const upb_fielddef* fielddef,
|
614
760
|
size_t offset,
|
615
|
-
Descriptor* desc) {
|
761
|
+
const Descriptor* desc) {
|
616
762
|
const upb_msgdef* map_msgdef = upb_fielddef_msgsubdef(fielddef);
|
617
763
|
map_handlerdata_t* hd = new_map_handlerdata(offset, map_msgdef, desc);
|
618
|
-
upb_handlerattr attr =
|
764
|
+
upb_handlerattr attr = UPB_HANDLERATTR_INIT;
|
619
765
|
|
620
766
|
upb_handlers_addcleanup(h, hd, xfree);
|
621
|
-
|
622
|
-
upb_handlers_setstartsubmsg(h, fielddef,
|
623
|
-
|
767
|
+
attr.handler_data = hd;
|
768
|
+
upb_handlers_setstartsubmsg(h, fielddef, startmap_handler, &attr);
|
769
|
+
upb_handlers_setendsubmsg(h, fielddef, endmap_handler, &attr);
|
624
770
|
}
|
625
771
|
|
626
772
|
// Adds handlers to a map-entry msgdef.
|
627
|
-
static void add_handlers_for_mapentry(const upb_msgdef* msgdef,
|
628
|
-
|
629
|
-
Descriptor* desc) {
|
773
|
+
static void add_handlers_for_mapentry(const upb_msgdef* msgdef, upb_handlers* h,
|
774
|
+
const Descriptor* desc) {
|
630
775
|
const upb_fielddef* key_field = map_entry_key(msgdef);
|
631
776
|
const upb_fielddef* value_field = map_entry_value(msgdef);
|
632
777
|
map_handlerdata_t* hd = new_map_handlerdata(0, msgdef, desc);
|
633
|
-
upb_handlerattr attr =
|
778
|
+
upb_handlerattr attr = UPB_HANDLERATTR_INIT;
|
634
779
|
|
635
780
|
upb_handlers_addcleanup(h, hd, xfree);
|
636
|
-
|
637
|
-
upb_handlers_setendmsg(h,
|
781
|
+
attr.handler_data = hd;
|
782
|
+
upb_handlers_setendmsg(h, endmapentry_handler, &attr);
|
638
783
|
|
639
784
|
add_handlers_for_singular_field(
|
640
|
-
h, key_field,
|
785
|
+
desc, h, key_field,
|
641
786
|
offsetof(map_parse_frame_t, key_storage),
|
642
787
|
MESSAGE_FIELD_NO_HASBIT);
|
643
788
|
add_handlers_for_singular_field(
|
644
|
-
h, value_field,
|
789
|
+
desc, h, value_field,
|
645
790
|
offsetof(map_parse_frame_t, value_storage),
|
646
791
|
MESSAGE_FIELD_NO_HASBIT);
|
647
792
|
}
|
648
793
|
|
794
|
+
static void add_handlers_for_wrapper(const upb_msgdef* msgdef,
|
795
|
+
upb_handlers* h) {
|
796
|
+
const upb_fielddef* f = upb_msgdef_itof(msgdef, 1);
|
797
|
+
switch (upb_msgdef_wellknowntype(msgdef)) {
|
798
|
+
case UPB_WELLKNOWN_DOUBLEVALUE:
|
799
|
+
upb_handlers_setdouble(h, f, doublewrapper_handler, NULL);
|
800
|
+
break;
|
801
|
+
case UPB_WELLKNOWN_FLOATVALUE:
|
802
|
+
upb_handlers_setfloat(h, f, floatwrapper_handler, NULL);
|
803
|
+
break;
|
804
|
+
case UPB_WELLKNOWN_INT64VALUE:
|
805
|
+
upb_handlers_setint64(h, f, int64wrapper_handler, NULL);
|
806
|
+
break;
|
807
|
+
case UPB_WELLKNOWN_UINT64VALUE:
|
808
|
+
upb_handlers_setuint64(h, f, uint64wrapper_handler, NULL);
|
809
|
+
break;
|
810
|
+
case UPB_WELLKNOWN_INT32VALUE:
|
811
|
+
upb_handlers_setint32(h, f, int32wrapper_handler, NULL);
|
812
|
+
break;
|
813
|
+
case UPB_WELLKNOWN_UINT32VALUE:
|
814
|
+
upb_handlers_setuint32(h, f, uint32wrapper_handler, NULL);
|
815
|
+
break;
|
816
|
+
case UPB_WELLKNOWN_STRINGVALUE:
|
817
|
+
upb_handlers_setstartstr(h, f, startstringwrapper_handler, NULL);
|
818
|
+
upb_handlers_setstring(h, f, stringwrapper_handler, NULL);
|
819
|
+
break;
|
820
|
+
case UPB_WELLKNOWN_BYTESVALUE:
|
821
|
+
upb_handlers_setstartstr(h, f, startbyteswrapper_handler, NULL);
|
822
|
+
upb_handlers_setstring(h, f, byteswrapper_handler, NULL);
|
823
|
+
break;
|
824
|
+
case UPB_WELLKNOWN_BOOLVALUE:
|
825
|
+
upb_handlers_setbool(h, f, boolwrapper_handler, NULL);
|
826
|
+
return;
|
827
|
+
default:
|
828
|
+
rb_raise(rb_eRuntimeError,
|
829
|
+
"Internal logic error with well-known types.");
|
830
|
+
}
|
831
|
+
}
|
832
|
+
|
649
833
|
// Set up handlers for a oneof field.
|
650
834
|
static void add_handlers_for_oneof_field(upb_handlers *h,
|
651
835
|
const upb_fielddef *f,
|
652
836
|
size_t offset,
|
653
|
-
size_t oneof_case_offset
|
654
|
-
|
655
|
-
upb_handlerattr attr =
|
656
|
-
|
657
|
-
|
837
|
+
size_t oneof_case_offset,
|
838
|
+
const Descriptor* desc) {
|
839
|
+
upb_handlerattr attr = UPB_HANDLERATTR_INIT;
|
840
|
+
attr.handler_data =
|
841
|
+
newoneofhandlerdata(h, offset, oneof_case_offset, f, desc);
|
658
842
|
|
659
843
|
switch (upb_fielddef_type(f)) {
|
660
844
|
|
@@ -685,19 +869,21 @@ static void add_handlers_for_oneof_field(upb_handlers *h,
|
|
685
869
|
break;
|
686
870
|
}
|
687
871
|
case UPB_TYPE_MESSAGE: {
|
688
|
-
|
872
|
+
if (is_wrapper(upb_fielddef_msgsubdef(f))) {
|
873
|
+
upb_handlers_setstartsubmsg(h, f, oneof_startwrapper, &attr);
|
874
|
+
} else {
|
875
|
+
upb_handlers_setstartsubmsg(h, f, oneofsubmsg_handler, &attr);
|
876
|
+
}
|
689
877
|
break;
|
690
878
|
}
|
691
879
|
}
|
692
|
-
|
693
|
-
upb_handlerattr_uninit(&attr);
|
694
880
|
}
|
695
881
|
|
696
882
|
static bool unknown_field_handler(void* closure, const void* hd,
|
697
883
|
const char* buf, size_t size) {
|
884
|
+
MessageHeader* msg = (MessageHeader*)closure;
|
698
885
|
UPB_UNUSED(hd);
|
699
886
|
|
700
|
-
MessageHeader* msg = (MessageHeader*)closure;
|
701
887
|
if (msg->unknown_fields == NULL) {
|
702
888
|
msg->unknown_fields = malloc(sizeof(stringsink));
|
703
889
|
stringsink_init(msg->unknown_fields);
|
@@ -708,10 +894,25 @@ static bool unknown_field_handler(void* closure, const void* hd,
|
|
708
894
|
return true;
|
709
895
|
}
|
710
896
|
|
711
|
-
|
897
|
+
size_t get_field_offset(MessageLayout* layout, const upb_fielddef* f) {
|
898
|
+
return layout->fields[upb_fielddef_index(f)].offset + sizeof(MessageHeader);
|
899
|
+
}
|
900
|
+
|
901
|
+
void add_handlers_for_message(const void *closure, upb_handlers *h) {
|
902
|
+
const VALUE descriptor_pool = (VALUE)closure;
|
712
903
|
const upb_msgdef* msgdef = upb_handlers_msgdef(h);
|
713
|
-
Descriptor* desc =
|
904
|
+
Descriptor* desc =
|
905
|
+
ruby_to_Descriptor(get_msgdef_obj(descriptor_pool, msgdef));
|
714
906
|
upb_msg_field_iter i;
|
907
|
+
upb_handlerattr attr = UPB_HANDLERATTR_INIT;
|
908
|
+
|
909
|
+
// Ensure layout exists. We may be invoked to create handlers for a given
|
910
|
+
// message if we are included as a submsg of another message type before our
|
911
|
+
// class is actually built, so to work around this, we just create the layout
|
912
|
+
// (and handlers, in the class-building function) on-demand.
|
913
|
+
if (desc->layout == NULL) {
|
914
|
+
create_layout(desc);
|
915
|
+
}
|
715
916
|
|
716
917
|
// If this is a mapentry message type, set up a special set of handlers and
|
717
918
|
// bail out of the normal (user-defined) message type handling.
|
@@ -720,86 +921,70 @@ static void add_handlers_for_message(const void *closure, upb_handlers *h) {
|
|
720
921
|
return;
|
721
922
|
}
|
722
923
|
|
723
|
-
//
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
if (desc->layout == NULL) {
|
728
|
-
desc->layout = create_layout(desc->msgdef);
|
924
|
+
// If this is a wrapper type, use special handlers and bail.
|
925
|
+
if (is_wrapper(msgdef)) {
|
926
|
+
add_handlers_for_wrapper(msgdef, h);
|
927
|
+
return;
|
729
928
|
}
|
730
929
|
|
731
|
-
upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
|
732
930
|
upb_handlers_setunknown(h, unknown_field_handler, &attr);
|
733
931
|
|
734
932
|
for (upb_msg_field_begin(&i, desc->msgdef);
|
735
933
|
!upb_msg_field_done(&i);
|
736
934
|
upb_msg_field_next(&i)) {
|
737
935
|
const upb_fielddef *f = upb_msg_iter_field(&i);
|
738
|
-
|
739
|
-
|
936
|
+
const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(f);
|
937
|
+
size_t offset = get_field_offset(desc->layout, f);
|
740
938
|
|
741
|
-
if (
|
939
|
+
if (oneof) {
|
742
940
|
size_t oneof_case_offset =
|
743
|
-
desc->layout->
|
941
|
+
desc->layout->oneofs[upb_oneofdef_index(oneof)].case_offset +
|
744
942
|
sizeof(MessageHeader);
|
745
|
-
add_handlers_for_oneof_field(h, f, offset, oneof_case_offset);
|
943
|
+
add_handlers_for_oneof_field(h, f, offset, oneof_case_offset, desc);
|
746
944
|
} else if (is_map_field(f)) {
|
747
945
|
add_handlers_for_mapfield(h, f, offset, desc);
|
748
946
|
} else if (upb_fielddef_isseq(f)) {
|
749
|
-
add_handlers_for_repeated_field(h, f, offset);
|
947
|
+
add_handlers_for_repeated_field(h, desc, f, offset);
|
750
948
|
} else {
|
751
949
|
add_handlers_for_singular_field(
|
752
|
-
h, f, offset,
|
950
|
+
desc, h, f, offset,
|
951
|
+
desc->layout->fields[upb_fielddef_index(f)].hasbit);
|
753
952
|
}
|
754
953
|
}
|
755
954
|
}
|
756
955
|
|
757
|
-
// Creates upb handlers for populating a message.
|
758
|
-
static const upb_handlers *new_fill_handlers(Descriptor* desc,
|
759
|
-
const void* owner) {
|
760
|
-
// TODO(cfallin, haberman): once upb gets a caching/memoization layer for
|
761
|
-
// handlers, reuse subdef handlers so that e.g. if we already parse
|
762
|
-
// B-with-field-of-type-C, we don't have to rebuild the whole hierarchy to
|
763
|
-
// parse A-with-field-of-type-B-with-field-of-type-C.
|
764
|
-
return upb_handlers_newfrozen(desc->msgdef, owner,
|
765
|
-
add_handlers_for_message, NULL);
|
766
|
-
}
|
767
|
-
|
768
956
|
// Constructs the handlers for filling a message's data into an in-memory
|
769
957
|
// object.
|
770
958
|
const upb_handlers* get_fill_handlers(Descriptor* desc) {
|
771
|
-
|
772
|
-
|
773
|
-
new_fill_handlers(desc, &desc->fill_handlers);
|
774
|
-
}
|
775
|
-
return desc->fill_handlers;
|
959
|
+
DescriptorPool* pool = ruby_to_DescriptorPool(desc->descriptor_pool);
|
960
|
+
return upb_handlercache_get(pool->fill_handler_cache, desc->msgdef);
|
776
961
|
}
|
777
962
|
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
const upb_handlers* handlers = get_fill_handlers(desc);
|
783
|
-
upb_pbdecodermethodopts opts;
|
784
|
-
upb_pbdecodermethodopts_init(&opts, handlers);
|
963
|
+
static const upb_pbdecodermethod *msgdef_decodermethod(Descriptor* desc) {
|
964
|
+
DescriptorPool* pool = ruby_to_DescriptorPool(desc->descriptor_pool);
|
965
|
+
return upb_pbcodecache_get(pool->fill_method_cache, desc->msgdef);
|
966
|
+
}
|
785
967
|
|
786
|
-
|
968
|
+
static const upb_json_parsermethod *msgdef_jsonparsermethod(Descriptor* desc) {
|
969
|
+
DescriptorPool* pool = ruby_to_DescriptorPool(desc->descriptor_pool);
|
970
|
+
return upb_json_codecache_get(pool->json_fill_method_cache, desc->msgdef);
|
787
971
|
}
|
788
972
|
|
789
|
-
static const
|
790
|
-
|
791
|
-
|
792
|
-
desc, &desc->fill_method);
|
793
|
-
}
|
794
|
-
return desc->fill_method;
|
973
|
+
static const upb_handlers* msgdef_pb_serialize_handlers(Descriptor* desc) {
|
974
|
+
DescriptorPool* pool = ruby_to_DescriptorPool(desc->descriptor_pool);
|
975
|
+
return upb_handlercache_get(pool->pb_serialize_handler_cache, desc->msgdef);
|
795
976
|
}
|
796
977
|
|
797
|
-
static const
|
798
|
-
|
799
|
-
|
800
|
-
|
978
|
+
static const upb_handlers* msgdef_json_serialize_handlers(
|
979
|
+
Descriptor* desc, bool preserve_proto_fieldnames) {
|
980
|
+
DescriptorPool* pool = ruby_to_DescriptorPool(desc->descriptor_pool);
|
981
|
+
if (preserve_proto_fieldnames) {
|
982
|
+
return upb_handlercache_get(pool->json_serialize_handler_preserve_cache,
|
983
|
+
desc->msgdef);
|
984
|
+
} else {
|
985
|
+
return upb_handlercache_get(pool->json_serialize_handler_cache,
|
986
|
+
desc->msgdef);
|
801
987
|
}
|
802
|
-
return desc->json_fill_method;
|
803
988
|
}
|
804
989
|
|
805
990
|
|
@@ -809,7 +994,8 @@ static const upb_json_parsermethod *msgdef_jsonparsermethod(Descriptor* desc) {
|
|
809
994
|
// if any error occurs.
|
810
995
|
#define STACK_ENV_STACKBYTES 4096
|
811
996
|
typedef struct {
|
812
|
-
|
997
|
+
upb_arena *arena;
|
998
|
+
upb_status status;
|
813
999
|
const char* ruby_error_template;
|
814
1000
|
char allocbuf[STACK_ENV_STACKBYTES];
|
815
1001
|
} stackenv;
|
@@ -817,29 +1003,22 @@ typedef struct {
|
|
817
1003
|
static void stackenv_init(stackenv* se, const char* errmsg);
|
818
1004
|
static void stackenv_uninit(stackenv* se);
|
819
1005
|
|
820
|
-
// Callback invoked by upb if any error occurs during parsing or serialization.
|
821
|
-
static bool env_error_func(void* ud, const upb_status* status) {
|
822
|
-
stackenv* se = ud;
|
823
|
-
// Free the env -- rb_raise will longjmp up the stack past the encode/decode
|
824
|
-
// function so it would not otherwise have been freed.
|
825
|
-
stackenv_uninit(se);
|
826
|
-
|
827
|
-
// TODO(haberman): have a way to verify that this is actually a parse error,
|
828
|
-
// instead of just throwing "parse error" unconditionally.
|
829
|
-
rb_raise(cParseError, se->ruby_error_template, upb_status_errmsg(status));
|
830
|
-
// Never reached: rb_raise() always longjmp()s up the stack, past all of our
|
831
|
-
// code, back to Ruby.
|
832
|
-
return false;
|
833
|
-
}
|
834
|
-
|
835
1006
|
static void stackenv_init(stackenv* se, const char* errmsg) {
|
836
1007
|
se->ruby_error_template = errmsg;
|
837
|
-
|
838
|
-
|
1008
|
+
se->arena =
|
1009
|
+
upb_arena_init(se->allocbuf, sizeof(se->allocbuf), &upb_alloc_global);
|
1010
|
+
upb_status_clear(&se->status);
|
839
1011
|
}
|
840
1012
|
|
841
1013
|
static void stackenv_uninit(stackenv* se) {
|
842
|
-
|
1014
|
+
upb_arena_free(se->arena);
|
1015
|
+
|
1016
|
+
if (!upb_ok(&se->status)) {
|
1017
|
+
// TODO(haberman): have a way to verify that this is actually a parse error,
|
1018
|
+
// instead of just throwing "parse error" unconditionally.
|
1019
|
+
VALUE errmsg = rb_str_new2(upb_status_errmsg(&se->status));
|
1020
|
+
rb_raise(cParseError, se->ruby_error_template, errmsg);
|
1021
|
+
}
|
843
1022
|
}
|
844
1023
|
|
845
1024
|
/*
|
@@ -861,23 +1040,34 @@ VALUE Message_decode(VALUE klass, VALUE data) {
|
|
861
1040
|
rb_raise(rb_eArgError, "Expected string for binary protobuf data.");
|
862
1041
|
}
|
863
1042
|
|
864
|
-
msg_rb =
|
1043
|
+
msg_rb = initialize_rb_class_with_no_args(msgklass);
|
865
1044
|
TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
|
866
1045
|
|
867
1046
|
{
|
868
1047
|
const upb_pbdecodermethod* method = msgdef_decodermethod(desc);
|
869
1048
|
const upb_handlers* h = upb_pbdecodermethod_desthandlers(method);
|
1049
|
+
const upb_msgdef* m = upb_handlers_msgdef(h);
|
1050
|
+
VALUE wrapper = Qnil;
|
1051
|
+
void* ptr = msg;
|
870
1052
|
stackenv se;
|
871
1053
|
upb_sink sink;
|
872
1054
|
upb_pbdecoder* decoder;
|
873
|
-
stackenv_init(&se, "Error occurred during parsing: %
|
1055
|
+
stackenv_init(&se, "Error occurred during parsing: %" PRIsVALUE);
|
874
1056
|
|
875
|
-
|
876
|
-
|
1057
|
+
if (is_wrapper(m)) {
|
1058
|
+
ptr = &wrapper;
|
1059
|
+
}
|
1060
|
+
|
1061
|
+
upb_sink_reset(&sink, h, ptr);
|
1062
|
+
decoder = upb_pbdecoder_create(se.arena, method, sink, &se.status);
|
877
1063
|
upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data),
|
878
1064
|
upb_pbdecoder_input(decoder));
|
879
1065
|
|
880
1066
|
stackenv_uninit(&se);
|
1067
|
+
|
1068
|
+
if (is_wrapper(m)) {
|
1069
|
+
msg_rb = ruby_wrapper_type(msgklass, wrapper);
|
1070
|
+
}
|
881
1071
|
}
|
882
1072
|
|
883
1073
|
return msg_rb;
|
@@ -891,8 +1081,9 @@ VALUE Message_decode(VALUE klass, VALUE data) {
|
|
891
1081
|
* format) under the interpretration given by this message class's definition
|
892
1082
|
* and returns a message object with the corresponding field values.
|
893
1083
|
*
|
894
|
-
*
|
895
|
-
* ignore_unknown_fields: set true to ignore unknown fields (default is to
|
1084
|
+
* @param options [Hash] options for the decoder
|
1085
|
+
* ignore_unknown_fields: set true to ignore unknown fields (default is to
|
1086
|
+
* raise an error)
|
896
1087
|
*/
|
897
1088
|
VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) {
|
898
1089
|
VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
|
@@ -920,24 +1111,33 @@ VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) {
|
|
920
1111
|
if (TYPE(data) != T_STRING) {
|
921
1112
|
rb_raise(rb_eArgError, "Expected string for JSON data.");
|
922
1113
|
}
|
1114
|
+
|
923
1115
|
// TODO(cfallin): Check and respect string encoding. If not UTF-8, we need to
|
924
1116
|
// convert, because string handlers pass data directly to message string
|
925
1117
|
// fields.
|
926
1118
|
|
927
|
-
msg_rb =
|
1119
|
+
msg_rb = initialize_rb_class_with_no_args(msgklass);
|
928
1120
|
TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
|
929
1121
|
|
930
1122
|
{
|
931
1123
|
const upb_json_parsermethod* method = msgdef_jsonparsermethod(desc);
|
1124
|
+
const upb_handlers* h = get_fill_handlers(desc);
|
1125
|
+
const upb_msgdef* m = upb_handlers_msgdef(h);
|
932
1126
|
stackenv se;
|
933
1127
|
upb_sink sink;
|
934
1128
|
upb_json_parser* parser;
|
935
1129
|
DescriptorPool* pool = ruby_to_DescriptorPool(generated_pool);
|
936
|
-
stackenv_init(&se, "Error occurred during parsing: %
|
1130
|
+
stackenv_init(&se, "Error occurred during parsing: %" PRIsVALUE);
|
1131
|
+
|
1132
|
+
if (is_wrapper(m)) {
|
1133
|
+
rb_raise(
|
1134
|
+
rb_eRuntimeError,
|
1135
|
+
"Parsing a wrapper type from JSON at the top level does not work.");
|
1136
|
+
}
|
937
1137
|
|
938
|
-
upb_sink_reset(&sink,
|
939
|
-
parser = upb_json_parser_create(
|
940
|
-
&
|
1138
|
+
upb_sink_reset(&sink, h, msg);
|
1139
|
+
parser = upb_json_parser_create(se.arena, method, pool->symtab, sink,
|
1140
|
+
&se.status, RTEST(ignore_unknown_fields));
|
941
1141
|
upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data),
|
942
1142
|
upb_json_parser_input(parser));
|
943
1143
|
|
@@ -953,9 +1153,8 @@ VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) {
|
|
953
1153
|
|
954
1154
|
/* msgvisitor *****************************************************************/
|
955
1155
|
|
956
|
-
static void putmsg(VALUE msg, const Descriptor* desc,
|
957
|
-
|
958
|
-
bool is_json, bool open_msg);
|
1156
|
+
static void putmsg(VALUE msg, const Descriptor* desc, upb_sink sink, int depth,
|
1157
|
+
bool emit_defaults, bool is_json, bool open_msg);
|
959
1158
|
|
960
1159
|
static upb_selector_t getsel(const upb_fielddef *f, upb_handlertype_t type) {
|
961
1160
|
upb_selector_t ret;
|
@@ -964,7 +1163,7 @@ static upb_selector_t getsel(const upb_fielddef *f, upb_handlertype_t type) {
|
|
964
1163
|
return ret;
|
965
1164
|
}
|
966
1165
|
|
967
|
-
static void putstr(VALUE str, const upb_fielddef *f, upb_sink
|
1166
|
+
static void putstr(VALUE str, const upb_fielddef *f, upb_sink sink) {
|
968
1167
|
upb_sink subsink;
|
969
1168
|
|
970
1169
|
if (str == Qnil) return;
|
@@ -981,12 +1180,12 @@ static void putstr(VALUE str, const upb_fielddef *f, upb_sink *sink) {
|
|
981
1180
|
|
982
1181
|
upb_sink_startstr(sink, getsel(f, UPB_HANDLER_STARTSTR), RSTRING_LEN(str),
|
983
1182
|
&subsink);
|
984
|
-
upb_sink_putstring(
|
1183
|
+
upb_sink_putstring(subsink, getsel(f, UPB_HANDLER_STRING), RSTRING_PTR(str),
|
985
1184
|
RSTRING_LEN(str), NULL);
|
986
1185
|
upb_sink_endstr(sink, getsel(f, UPB_HANDLER_ENDSTR));
|
987
1186
|
}
|
988
1187
|
|
989
|
-
static void putsubmsg(VALUE submsg, const upb_fielddef *f, upb_sink
|
1188
|
+
static void putsubmsg(VALUE submsg, const upb_fielddef *f, upb_sink sink,
|
990
1189
|
int depth, bool emit_defaults, bool is_json) {
|
991
1190
|
upb_sink subsink;
|
992
1191
|
VALUE descriptor;
|
@@ -998,16 +1197,18 @@ static void putsubmsg(VALUE submsg, const upb_fielddef *f, upb_sink *sink,
|
|
998
1197
|
subdesc = ruby_to_Descriptor(descriptor);
|
999
1198
|
|
1000
1199
|
upb_sink_startsubmsg(sink, getsel(f, UPB_HANDLER_STARTSUBMSG), &subsink);
|
1001
|
-
putmsg(submsg, subdesc,
|
1002
|
-
upb_sink_endsubmsg(sink, getsel(f, UPB_HANDLER_ENDSUBMSG));
|
1200
|
+
putmsg(submsg, subdesc, subsink, depth + 1, emit_defaults, is_json, true);
|
1201
|
+
upb_sink_endsubmsg(sink, subsink, getsel(f, UPB_HANDLER_ENDSUBMSG));
|
1003
1202
|
}
|
1004
1203
|
|
1005
|
-
static void putary(VALUE ary, const upb_fielddef
|
1006
|
-
|
1204
|
+
static void putary(VALUE ary, const upb_fielddef* f, upb_sink sink, int depth,
|
1205
|
+
bool emit_defaults, bool is_json) {
|
1007
1206
|
upb_sink subsink;
|
1008
1207
|
upb_fieldtype_t type = upb_fielddef_type(f);
|
1009
1208
|
upb_selector_t sel = 0;
|
1010
1209
|
int size;
|
1210
|
+
int i;
|
1211
|
+
VALUE type_class = ruby_to_RepeatedField(ary)->field_type_class;
|
1011
1212
|
|
1012
1213
|
if (ary == Qnil) return;
|
1013
1214
|
if (!emit_defaults && NUM2INT(RepeatedField_length(ary)) == 0) return;
|
@@ -1021,12 +1222,12 @@ static void putary(VALUE ary, const upb_fielddef *f, upb_sink *sink,
|
|
1021
1222
|
sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
|
1022
1223
|
}
|
1023
1224
|
|
1024
|
-
for (
|
1225
|
+
for (i = 0; i < size; i++) {
|
1025
1226
|
void* memory = RepeatedField_index_native(ary, i);
|
1026
1227
|
switch (type) {
|
1027
|
-
#define T(upbtypeconst, upbtype, ctype)
|
1028
|
-
case upbtypeconst:
|
1029
|
-
upb_sink_put##upbtype(
|
1228
|
+
#define T(upbtypeconst, upbtype, ctype) \
|
1229
|
+
case upbtypeconst: \
|
1230
|
+
upb_sink_put##upbtype(subsink, sel, *((ctype*)memory)); \
|
1030
1231
|
break;
|
1031
1232
|
|
1032
1233
|
T(UPB_TYPE_FLOAT, float, float)
|
@@ -1040,12 +1241,13 @@ static void putary(VALUE ary, const upb_fielddef *f, upb_sink *sink,
|
|
1040
1241
|
|
1041
1242
|
case UPB_TYPE_STRING:
|
1042
1243
|
case UPB_TYPE_BYTES:
|
1043
|
-
putstr(*((VALUE *)memory), f,
|
1244
|
+
putstr(*((VALUE *)memory), f, subsink);
|
1044
1245
|
break;
|
1045
|
-
case UPB_TYPE_MESSAGE:
|
1046
|
-
|
1047
|
-
|
1246
|
+
case UPB_TYPE_MESSAGE: {
|
1247
|
+
VALUE val = native_slot_get(UPB_TYPE_MESSAGE, type_class, memory);
|
1248
|
+
putsubmsg(val, f, subsink, depth, emit_defaults, is_json);
|
1048
1249
|
break;
|
1250
|
+
}
|
1049
1251
|
|
1050
1252
|
#undef T
|
1051
1253
|
|
@@ -1054,19 +1256,16 @@ static void putary(VALUE ary, const upb_fielddef *f, upb_sink *sink,
|
|
1054
1256
|
upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ));
|
1055
1257
|
}
|
1056
1258
|
|
1057
|
-
static void put_ruby_value(VALUE value,
|
1058
|
-
|
1059
|
-
VALUE type_class,
|
1060
|
-
int depth,
|
1061
|
-
upb_sink *sink,
|
1062
|
-
bool emit_defaults,
|
1259
|
+
static void put_ruby_value(VALUE value, const upb_fielddef* f, VALUE type_class,
|
1260
|
+
int depth, upb_sink sink, bool emit_defaults,
|
1063
1261
|
bool is_json) {
|
1262
|
+
upb_selector_t sel = 0;
|
1263
|
+
|
1064
1264
|
if (depth > ENCODE_MAX_NESTING) {
|
1065
1265
|
rb_raise(rb_eRuntimeError,
|
1066
1266
|
"Maximum recursion depth exceeded during encoding.");
|
1067
1267
|
}
|
1068
1268
|
|
1069
|
-
upb_selector_t sel = 0;
|
1070
1269
|
if (upb_fielddef_isprimitive(f)) {
|
1071
1270
|
sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
|
1072
1271
|
}
|
@@ -1109,8 +1308,8 @@ static void put_ruby_value(VALUE value,
|
|
1109
1308
|
}
|
1110
1309
|
}
|
1111
1310
|
|
1112
|
-
static void putmap(VALUE map, const upb_fielddef
|
1113
|
-
|
1311
|
+
static void putmap(VALUE map, const upb_fielddef* f, upb_sink sink, int depth,
|
1312
|
+
bool emit_defaults, bool is_json) {
|
1114
1313
|
Map* self;
|
1115
1314
|
upb_sink subsink;
|
1116
1315
|
const upb_fielddef* key_field;
|
@@ -1134,17 +1333,17 @@ static void putmap(VALUE map, const upb_fielddef *f, upb_sink *sink,
|
|
1134
1333
|
upb_status status;
|
1135
1334
|
|
1136
1335
|
upb_sink entry_sink;
|
1137
|
-
upb_sink_startsubmsg(
|
1336
|
+
upb_sink_startsubmsg(subsink, getsel(f, UPB_HANDLER_STARTSUBMSG),
|
1138
1337
|
&entry_sink);
|
1139
|
-
upb_sink_startmsg(
|
1338
|
+
upb_sink_startmsg(entry_sink);
|
1140
1339
|
|
1141
|
-
put_ruby_value(key, key_field, Qnil, depth + 1,
|
1142
|
-
|
1340
|
+
put_ruby_value(key, key_field, Qnil, depth + 1, entry_sink, emit_defaults,
|
1341
|
+
is_json);
|
1143
1342
|
put_ruby_value(value, value_field, self->value_type_class, depth + 1,
|
1144
|
-
|
1343
|
+
entry_sink, emit_defaults, is_json);
|
1145
1344
|
|
1146
|
-
upb_sink_endmsg(
|
1147
|
-
upb_sink_endsubmsg(
|
1345
|
+
upb_sink_endmsg(entry_sink, &status);
|
1346
|
+
upb_sink_endsubmsg(subsink, entry_sink, getsel(f, UPB_HANDLER_ENDSUBMSG));
|
1148
1347
|
}
|
1149
1348
|
|
1150
1349
|
upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ));
|
@@ -1153,8 +1352,8 @@ static void putmap(VALUE map, const upb_fielddef *f, upb_sink *sink,
|
|
1153
1352
|
static const upb_handlers* msgdef_json_serialize_handlers(
|
1154
1353
|
Descriptor* desc, bool preserve_proto_fieldnames);
|
1155
1354
|
|
1156
|
-
static void putjsonany(VALUE msg_rb, const Descriptor* desc,
|
1157
|
-
|
1355
|
+
static void putjsonany(VALUE msg_rb, const Descriptor* desc, upb_sink sink,
|
1356
|
+
int depth, bool emit_defaults) {
|
1158
1357
|
upb_status status;
|
1159
1358
|
MessageHeader* msg = NULL;
|
1160
1359
|
const upb_fielddef* type_field = upb_msgdef_itof(desc->msgdef, UPB_ANY_TYPE);
|
@@ -1201,16 +1400,14 @@ static void putjsonany(VALUE msg_rb, const Descriptor* desc,
|
|
1201
1400
|
{
|
1202
1401
|
uint32_t value_offset;
|
1203
1402
|
VALUE value_str_rb;
|
1204
|
-
const char* value_str;
|
1205
1403
|
size_t value_len;
|
1206
1404
|
|
1207
1405
|
value_offset = desc->layout->fields[upb_fielddef_index(value_field)].offset;
|
1208
1406
|
value_str_rb = DEREF(Message_data(msg), value_offset, VALUE);
|
1209
|
-
value_str = RSTRING_PTR(value_str_rb);
|
1210
1407
|
value_len = RSTRING_LEN(value_str_rb);
|
1211
1408
|
|
1212
1409
|
if (value_len > 0) {
|
1213
|
-
VALUE payload_desc_rb =
|
1410
|
+
VALUE payload_desc_rb = get_msgdef_obj(generated_pool, payload_type);
|
1214
1411
|
Descriptor* payload_desc = ruby_to_Descriptor(payload_desc_rb);
|
1215
1412
|
VALUE payload_class = Descriptor_msgclass(payload_desc_rb);
|
1216
1413
|
upb_sink subsink;
|
@@ -1228,8 +1425,8 @@ static void putjsonany(VALUE msg_rb, const Descriptor* desc,
|
|
1228
1425
|
|
1229
1426
|
subsink.handlers =
|
1230
1427
|
msgdef_json_serialize_handlers(payload_desc, true);
|
1231
|
-
subsink.closure = sink
|
1232
|
-
putmsg(payload_msg_rb, payload_desc,
|
1428
|
+
subsink.closure = sink.closure;
|
1429
|
+
putmsg(payload_msg_rb, payload_desc, subsink, depth, emit_defaults, true,
|
1233
1430
|
is_wellknown);
|
1234
1431
|
}
|
1235
1432
|
}
|
@@ -1239,7 +1436,7 @@ static void putjsonany(VALUE msg_rb, const Descriptor* desc,
|
|
1239
1436
|
|
1240
1437
|
static void putjsonlistvalue(
|
1241
1438
|
VALUE msg_rb, const Descriptor* desc,
|
1242
|
-
upb_sink
|
1439
|
+
upb_sink sink, int depth, bool emit_defaults) {
|
1243
1440
|
upb_status status;
|
1244
1441
|
upb_sink subsink;
|
1245
1442
|
MessageHeader* msg = NULL;
|
@@ -1266,11 +1463,12 @@ static void putjsonlistvalue(
|
|
1266
1463
|
}
|
1267
1464
|
|
1268
1465
|
static void putmsg(VALUE msg_rb, const Descriptor* desc,
|
1269
|
-
upb_sink
|
1466
|
+
upb_sink sink, int depth, bool emit_defaults,
|
1270
1467
|
bool is_json, bool open_msg) {
|
1271
1468
|
MessageHeader* msg;
|
1272
1469
|
upb_msg_field_iter i;
|
1273
1470
|
upb_status status;
|
1471
|
+
bool json_wrapper = is_wrapper(desc->msgdef) && is_json;
|
1274
1472
|
|
1275
1473
|
if (is_json &&
|
1276
1474
|
upb_msgdef_wellknowntype(desc->msgdef) == UPB_WELLKNOWN_ANY) {
|
@@ -1308,19 +1506,18 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
|
|
1308
1506
|
!upb_msg_field_done(&i);
|
1309
1507
|
upb_msg_field_next(&i)) {
|
1310
1508
|
upb_fielddef *f = upb_msg_iter_field(&i);
|
1509
|
+
const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(f);
|
1311
1510
|
bool is_matching_oneof = false;
|
1312
1511
|
uint32_t offset =
|
1313
1512
|
desc->layout->fields[upb_fielddef_index(f)].offset +
|
1314
1513
|
sizeof(MessageHeader);
|
1315
1514
|
|
1316
|
-
if (
|
1317
|
-
uint32_t
|
1318
|
-
desc->layout
|
1319
|
-
sizeof(MessageHeader);
|
1515
|
+
if (oneof) {
|
1516
|
+
uint32_t oneof_case =
|
1517
|
+
slot_read_oneof_case(desc->layout, Message_data(msg), oneof);
|
1320
1518
|
// For a oneof, check that this field is actually present -- skip all the
|
1321
1519
|
// below if not.
|
1322
|
-
if (
|
1323
|
-
upb_fielddef_number(f)) {
|
1520
|
+
if (oneof_case != upb_fielddef_number(f)) {
|
1324
1521
|
continue;
|
1325
1522
|
}
|
1326
1523
|
// Otherwise, fall through to the appropriate singular-field handler
|
@@ -1348,29 +1545,30 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
|
|
1348
1545
|
is_default = RSTRING_LEN(str) == 0;
|
1349
1546
|
}
|
1350
1547
|
|
1351
|
-
if (is_matching_oneof || emit_defaults || !is_default) {
|
1548
|
+
if (is_matching_oneof || emit_defaults || !is_default || json_wrapper) {
|
1352
1549
|
putstr(str, f, sink);
|
1353
1550
|
}
|
1354
1551
|
} else if (upb_fielddef_issubmsg(f)) {
|
1355
|
-
|
1356
|
-
|
1552
|
+
// OPT: could try to avoid the layout_get() (which will expand lazy
|
1553
|
+
// wrappers).
|
1554
|
+
VALUE val = layout_get(desc->layout, Message_data(msg), f);
|
1555
|
+
putsubmsg(val, f, sink, depth, emit_defaults, is_json);
|
1357
1556
|
} else {
|
1358
1557
|
upb_selector_t sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
|
1359
1558
|
|
1360
|
-
#define T(upbtypeconst, upbtype, ctype, default_value)
|
1361
|
-
case upbtypeconst: {
|
1362
|
-
|
1363
|
-
|
1364
|
-
|
1365
|
-
|
1366
|
-
|
1367
|
-
|
1368
|
-
|
1369
|
-
|
1370
|
-
|
1371
|
-
|
1372
|
-
|
1373
|
-
break;
|
1559
|
+
#define T(upbtypeconst, upbtype, ctype, default_value) \
|
1560
|
+
case upbtypeconst: { \
|
1561
|
+
ctype value = DEREF(msg, offset, ctype); \
|
1562
|
+
bool is_default = false; \
|
1563
|
+
if (upb_fielddef_haspresence(f)) { \
|
1564
|
+
is_default = layout_has(desc->layout, Message_data(msg), f) == Qfalse; \
|
1565
|
+
} else if (upb_msgdef_syntax(desc->msgdef) == UPB_SYNTAX_PROTO3) { \
|
1566
|
+
is_default = default_value == value; \
|
1567
|
+
} \
|
1568
|
+
if (is_matching_oneof || emit_defaults || !is_default || json_wrapper) { \
|
1569
|
+
upb_sink_put##upbtype(sink, sel, value); \
|
1570
|
+
} \
|
1571
|
+
} break;
|
1374
1572
|
|
1375
1573
|
switch (upb_fielddef_type(f)) {
|
1376
1574
|
T(UPB_TYPE_FLOAT, float, float, 0.0)
|
@@ -1388,13 +1586,14 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
|
|
1388
1586
|
}
|
1389
1587
|
|
1390
1588
|
#undef T
|
1391
|
-
|
1392
1589
|
}
|
1393
1590
|
}
|
1394
1591
|
|
1395
|
-
|
1396
|
-
|
1397
|
-
|
1592
|
+
{
|
1593
|
+
stringsink* unknown = msg->unknown_fields;
|
1594
|
+
if (unknown != NULL) {
|
1595
|
+
upb_sink_putunknown(sink, unknown->ptr, unknown->len);
|
1596
|
+
}
|
1398
1597
|
}
|
1399
1598
|
|
1400
1599
|
if (open_msg) {
|
@@ -1402,33 +1601,6 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
|
|
1402
1601
|
}
|
1403
1602
|
}
|
1404
1603
|
|
1405
|
-
static const upb_handlers* msgdef_pb_serialize_handlers(Descriptor* desc) {
|
1406
|
-
if (desc->pb_serialize_handlers == NULL) {
|
1407
|
-
desc->pb_serialize_handlers =
|
1408
|
-
upb_pb_encoder_newhandlers(desc->msgdef, &desc->pb_serialize_handlers);
|
1409
|
-
}
|
1410
|
-
return desc->pb_serialize_handlers;
|
1411
|
-
}
|
1412
|
-
|
1413
|
-
static const upb_handlers* msgdef_json_serialize_handlers(
|
1414
|
-
Descriptor* desc, bool preserve_proto_fieldnames) {
|
1415
|
-
if (preserve_proto_fieldnames) {
|
1416
|
-
if (desc->json_serialize_handlers == NULL) {
|
1417
|
-
desc->json_serialize_handlers =
|
1418
|
-
upb_json_printer_newhandlers(
|
1419
|
-
desc->msgdef, true, &desc->json_serialize_handlers);
|
1420
|
-
}
|
1421
|
-
return desc->json_serialize_handlers;
|
1422
|
-
} else {
|
1423
|
-
if (desc->json_serialize_handlers_preserve == NULL) {
|
1424
|
-
desc->json_serialize_handlers_preserve =
|
1425
|
-
upb_json_printer_newhandlers(
|
1426
|
-
desc->msgdef, false, &desc->json_serialize_handlers_preserve);
|
1427
|
-
}
|
1428
|
-
return desc->json_serialize_handlers_preserve;
|
1429
|
-
}
|
1430
|
-
}
|
1431
|
-
|
1432
1604
|
/*
|
1433
1605
|
* call-seq:
|
1434
1606
|
* MessageClass.encode(msg) => bytes
|
@@ -1451,8 +1623,8 @@ VALUE Message_encode(VALUE klass, VALUE msg_rb) {
|
|
1451
1623
|
upb_pb_encoder* encoder;
|
1452
1624
|
VALUE ret;
|
1453
1625
|
|
1454
|
-
stackenv_init(&se, "Error occurred during encoding: %
|
1455
|
-
encoder = upb_pb_encoder_create(
|
1626
|
+
stackenv_init(&se, "Error occurred during encoding: %" PRIsVALUE);
|
1627
|
+
encoder = upb_pb_encoder_create(se.arena, serialize_handlers, sink.sink);
|
1456
1628
|
|
1457
1629
|
putmsg(msg_rb, desc, upb_pb_encoder_input(encoder), 0, false, false, true);
|
1458
1630
|
|
@@ -1509,8 +1681,8 @@ VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
|
|
1509
1681
|
stackenv se;
|
1510
1682
|
VALUE ret;
|
1511
1683
|
|
1512
|
-
stackenv_init(&se, "Error occurred during encoding: %
|
1513
|
-
printer = upb_json_printer_create(
|
1684
|
+
stackenv_init(&se, "Error occurred during encoding: %" PRIsVALUE);
|
1685
|
+
printer = upb_json_printer_create(se.arena, serialize_handlers, sink.sink);
|
1514
1686
|
|
1515
1687
|
putmsg(msg_rb, desc, upb_json_printer_input(printer), 0,
|
1516
1688
|
RTEST(emit_defaults), true, true);
|
@@ -1530,28 +1702,29 @@ static void discard_unknown(VALUE msg_rb, const Descriptor* desc) {
|
|
1530
1702
|
|
1531
1703
|
TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
|
1532
1704
|
|
1533
|
-
|
1534
|
-
|
1535
|
-
|
1536
|
-
|
1705
|
+
{
|
1706
|
+
stringsink* unknown = msg->unknown_fields;
|
1707
|
+
if (unknown != NULL) {
|
1708
|
+
stringsink_uninit(unknown);
|
1709
|
+
msg->unknown_fields = NULL;
|
1710
|
+
}
|
1537
1711
|
}
|
1538
1712
|
|
1539
1713
|
for (upb_msg_field_begin(&it, desc->msgdef);
|
1540
1714
|
!upb_msg_field_done(&it);
|
1541
1715
|
upb_msg_field_next(&it)) {
|
1542
1716
|
upb_fielddef *f = upb_msg_iter_field(&it);
|
1717
|
+
const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(f);
|
1543
1718
|
uint32_t offset =
|
1544
1719
|
desc->layout->fields[upb_fielddef_index(f)].offset +
|
1545
1720
|
sizeof(MessageHeader);
|
1546
1721
|
|
1547
|
-
if (
|
1548
|
-
uint32_t
|
1549
|
-
desc->layout
|
1550
|
-
sizeof(MessageHeader);
|
1722
|
+
if (oneof) {
|
1723
|
+
uint32_t oneof_case =
|
1724
|
+
slot_read_oneof_case(desc->layout, Message_data(msg), oneof);
|
1551
1725
|
// For a oneof, check that this field is actually present -- skip all the
|
1552
1726
|
// below if not.
|
1553
|
-
if (
|
1554
|
-
upb_fielddef_number(f)) {
|
1727
|
+
if (oneof_case != upb_fielddef_number(f)) {
|
1555
1728
|
continue;
|
1556
1729
|
}
|
1557
1730
|
// Otherwise, fall through to the appropriate singular-field handler
|
@@ -1563,10 +1736,12 @@ static void discard_unknown(VALUE msg_rb, const Descriptor* desc) {
|
|
1563
1736
|
}
|
1564
1737
|
|
1565
1738
|
if (is_map_field(f)) {
|
1739
|
+
VALUE map;
|
1740
|
+
Map_iter map_it;
|
1741
|
+
|
1566
1742
|
if (!upb_fielddef_issubmsg(map_field_value(f))) continue;
|
1567
|
-
|
1743
|
+
map = DEREF(msg, offset, VALUE);
|
1568
1744
|
if (map == Qnil) continue;
|
1569
|
-
Map_iter map_it;
|
1570
1745
|
for (Map_begin(map, &map_it); !Map_done(&map_it); Map_next(&map_it)) {
|
1571
1746
|
VALUE submsg = Map_iter_value(&map_it);
|
1572
1747
|
VALUE descriptor = rb_ivar_get(submsg, descriptor_instancevar_interned);
|
@@ -1575,9 +1750,12 @@ static void discard_unknown(VALUE msg_rb, const Descriptor* desc) {
|
|
1575
1750
|
}
|
1576
1751
|
} else if (upb_fielddef_isseq(f)) {
|
1577
1752
|
VALUE ary = DEREF(msg, offset, VALUE);
|
1753
|
+
int size;
|
1754
|
+
int i;
|
1755
|
+
|
1578
1756
|
if (ary == Qnil) continue;
|
1579
|
-
|
1580
|
-
for (
|
1757
|
+
size = NUM2INT(RepeatedField_length(ary));
|
1758
|
+
for (i = 0; i < size; i++) {
|
1581
1759
|
void* memory = RepeatedField_index_native(ary, i);
|
1582
1760
|
VALUE submsg = *((VALUE *)memory);
|
1583
1761
|
VALUE descriptor = rb_ivar_get(submsg, descriptor_instancevar_interned);
|
@@ -1586,9 +1764,12 @@ static void discard_unknown(VALUE msg_rb, const Descriptor* desc) {
|
|
1586
1764
|
}
|
1587
1765
|
} else {
|
1588
1766
|
VALUE submsg = DEREF(msg, offset, VALUE);
|
1767
|
+
VALUE descriptor;
|
1768
|
+
const Descriptor* subdesc;
|
1769
|
+
|
1589
1770
|
if (submsg == Qnil) continue;
|
1590
|
-
|
1591
|
-
|
1771
|
+
descriptor = rb_ivar_get(submsg, descriptor_instancevar_interned);
|
1772
|
+
subdesc = ruby_to_Descriptor(descriptor);
|
1592
1773
|
discard_unknown(submsg, subdesc);
|
1593
1774
|
}
|
1594
1775
|
}
|