google-protobuf 3.0.0.alpha.5.0.3-x86-mingw32

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.

@@ -0,0 +1,1200 @@
1
+ // Protocol Buffers - Google's data interchange format
2
+ // Copyright 2014 Google Inc. All rights reserved.
3
+ // https://developers.google.com/protocol-buffers/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are
7
+ // met:
8
+ //
9
+ // * Redistributions of source code must retain the above copyright
10
+ // notice, this list of conditions and the following disclaimer.
11
+ // * Redistributions in binary form must reproduce the above
12
+ // copyright notice, this list of conditions and the following disclaimer
13
+ // in the documentation and/or other materials provided with the
14
+ // distribution.
15
+ // * Neither the name of Google Inc. nor the names of its
16
+ // contributors may be used to endorse or promote products derived from
17
+ // this software without specific prior written permission.
18
+ //
19
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+ // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+ // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
+ // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
+ // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+ // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
+ // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
+ // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
+ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+ #include "protobuf.h"
32
+
33
+ // This function is equivalent to rb_str_cat(), but unlike the real
34
+ // rb_str_cat(), it doesn't leak memory in some versions of Ruby.
35
+ // For more information, see:
36
+ // https://bugs.ruby-lang.org/issues/11328
37
+ VALUE noleak_rb_str_cat(VALUE rb_str, const char *str, long len) {
38
+ char *p;
39
+ size_t oldlen = RSTRING_LEN(rb_str);
40
+ rb_str_modify_expand(rb_str, len);
41
+ p = RSTRING_PTR(rb_str);
42
+ memcpy(p + oldlen, str, len);
43
+ rb_str_set_len(rb_str, oldlen + len);
44
+ return rb_str;
45
+ }
46
+
47
+ // -----------------------------------------------------------------------------
48
+ // Parsing.
49
+ // -----------------------------------------------------------------------------
50
+
51
+ #define DEREF(msg, ofs, type) *(type*)(((uint8_t *)msg) + ofs)
52
+
53
+ // Creates a handlerdata that simply contains the offset for this field.
54
+ static const void* newhandlerdata(upb_handlers* h, uint32_t ofs) {
55
+ size_t* hd_ofs = ALLOC(size_t);
56
+ *hd_ofs = ofs;
57
+ upb_handlers_addcleanup(h, hd_ofs, free);
58
+ return hd_ofs;
59
+ }
60
+
61
+ typedef struct {
62
+ size_t ofs;
63
+ const upb_msgdef *md;
64
+ } submsg_handlerdata_t;
65
+
66
+ // Creates a handlerdata that contains offset and submessage type information.
67
+ static const void *newsubmsghandlerdata(upb_handlers* h, uint32_t ofs,
68
+ const upb_fielddef* f) {
69
+ submsg_handlerdata_t *hd = ALLOC(submsg_handlerdata_t);
70
+ hd->ofs = ofs;
71
+ hd->md = upb_fielddef_msgsubdef(f);
72
+ upb_handlers_addcleanup(h, hd, free);
73
+ return hd;
74
+ }
75
+
76
+ typedef struct {
77
+ size_t ofs; // union data slot
78
+ size_t case_ofs; // oneof_case field
79
+ uint32_t oneof_case_num; // oneof-case number to place in oneof_case field
80
+ const upb_msgdef *md; // msgdef, for oneof submessage handler
81
+ } oneof_handlerdata_t;
82
+
83
+ static const void *newoneofhandlerdata(upb_handlers *h,
84
+ uint32_t ofs,
85
+ uint32_t case_ofs,
86
+ const upb_fielddef *f) {
87
+ oneof_handlerdata_t *hd = ALLOC(oneof_handlerdata_t);
88
+ hd->ofs = ofs;
89
+ hd->case_ofs = case_ofs;
90
+ // We reuse the field tag number as a oneof union discriminant tag. Note that
91
+ // we don't expose these numbers to the user, so the only requirement is that
92
+ // we have some unique ID for each union case/possibility. The field tag
93
+ // numbers are already present and are easy to use so there's no reason to
94
+ // create a separate ID space. In addition, using the field tag number here
95
+ // lets us easily look up the field in the oneof accessor.
96
+ hd->oneof_case_num = upb_fielddef_number(f);
97
+ if (upb_fielddef_type(f) == UPB_TYPE_MESSAGE) {
98
+ hd->md = upb_fielddef_msgsubdef(f);
99
+ } else {
100
+ hd->md = NULL;
101
+ }
102
+ upb_handlers_addcleanup(h, hd, free);
103
+ return hd;
104
+ }
105
+
106
+ // A handler that starts a repeated field. Gets the Repeated*Field instance for
107
+ // this field (such an instance always exists even in an empty message).
108
+ static void *startseq_handler(void* closure, const void* hd) {
109
+ MessageHeader* msg = closure;
110
+ const size_t *ofs = hd;
111
+ return (void*)DEREF(msg, *ofs, VALUE);
112
+ }
113
+
114
+ // Handlers that append primitive values to a repeated field.
115
+ #define DEFINE_APPEND_HANDLER(type, ctype) \
116
+ static bool append##type##_handler(void *closure, const void *hd, \
117
+ ctype val) { \
118
+ VALUE ary = (VALUE)closure; \
119
+ RepeatedField_push_native(ary, &val); \
120
+ return true; \
121
+ }
122
+
123
+ DEFINE_APPEND_HANDLER(bool, bool)
124
+ DEFINE_APPEND_HANDLER(int32, int32_t)
125
+ DEFINE_APPEND_HANDLER(uint32, uint32_t)
126
+ DEFINE_APPEND_HANDLER(float, float)
127
+ DEFINE_APPEND_HANDLER(int64, int64_t)
128
+ DEFINE_APPEND_HANDLER(uint64, uint64_t)
129
+ DEFINE_APPEND_HANDLER(double, double)
130
+
131
+ // Appends a string to a repeated field.
132
+ static void* appendstr_handler(void *closure,
133
+ const void *hd,
134
+ size_t size_hint) {
135
+ VALUE ary = (VALUE)closure;
136
+ VALUE str = rb_str_new2("");
137
+ rb_enc_associate(str, kRubyStringUtf8Encoding);
138
+ RepeatedField_push(ary, str);
139
+ return (void*)str;
140
+ }
141
+
142
+ // Appends a 'bytes' string to a repeated field.
143
+ static void* appendbytes_handler(void *closure,
144
+ const void *hd,
145
+ size_t size_hint) {
146
+ VALUE ary = (VALUE)closure;
147
+ VALUE str = rb_str_new2("");
148
+ rb_enc_associate(str, kRubyString8bitEncoding);
149
+ RepeatedField_push(ary, str);
150
+ return (void*)str;
151
+ }
152
+
153
+ // Sets a non-repeated string field in a message.
154
+ static void* str_handler(void *closure,
155
+ const void *hd,
156
+ size_t size_hint) {
157
+ MessageHeader* msg = closure;
158
+ const size_t *ofs = hd;
159
+ VALUE str = rb_str_new2("");
160
+ rb_enc_associate(str, kRubyStringUtf8Encoding);
161
+ DEREF(msg, *ofs, VALUE) = str;
162
+ return (void*)str;
163
+ }
164
+
165
+ // Sets a non-repeated 'bytes' field in a message.
166
+ static void* bytes_handler(void *closure,
167
+ const void *hd,
168
+ size_t size_hint) {
169
+ MessageHeader* msg = closure;
170
+ const size_t *ofs = hd;
171
+ VALUE str = rb_str_new2("");
172
+ rb_enc_associate(str, kRubyString8bitEncoding);
173
+ DEREF(msg, *ofs, VALUE) = str;
174
+ return (void*)str;
175
+ }
176
+
177
+ static size_t stringdata_handler(void* closure, const void* hd,
178
+ const char* str, size_t len,
179
+ const upb_bufhandle* handle) {
180
+ VALUE rb_str = (VALUE)closure;
181
+ noleak_rb_str_cat(rb_str, str, len);
182
+ return len;
183
+ }
184
+
185
+ // Appends a submessage to a repeated field (a regular Ruby array for now).
186
+ static void *appendsubmsg_handler(void *closure, const void *hd) {
187
+ VALUE ary = (VALUE)closure;
188
+ const submsg_handlerdata_t *submsgdata = hd;
189
+ VALUE subdesc =
190
+ get_def_obj((void*)submsgdata->md);
191
+ VALUE subklass = Descriptor_msgclass(subdesc);
192
+ MessageHeader* submsg;
193
+
194
+ VALUE submsg_rb = rb_class_new_instance(0, NULL, subklass);
195
+ RepeatedField_push(ary, submsg_rb);
196
+
197
+ TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg);
198
+ return submsg;
199
+ }
200
+
201
+ // Sets a non-repeated submessage field in a message.
202
+ static void *submsg_handler(void *closure, const void *hd) {
203
+ MessageHeader* msg = closure;
204
+ const submsg_handlerdata_t* submsgdata = hd;
205
+ VALUE subdesc =
206
+ get_def_obj((void*)submsgdata->md);
207
+ VALUE subklass = Descriptor_msgclass(subdesc);
208
+ VALUE submsg_rb;
209
+ MessageHeader* submsg;
210
+
211
+ if (DEREF(msg, submsgdata->ofs, VALUE) == Qnil) {
212
+ DEREF(msg, submsgdata->ofs, VALUE) =
213
+ rb_class_new_instance(0, NULL, subklass);
214
+ }
215
+
216
+ submsg_rb = DEREF(msg, submsgdata->ofs, VALUE);
217
+ TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg);
218
+ return submsg;
219
+ }
220
+
221
+ // Handler data for startmap/endmap handlers.
222
+ typedef struct {
223
+ size_t ofs;
224
+ upb_fieldtype_t key_field_type;
225
+ upb_fieldtype_t value_field_type;
226
+
227
+ // We know that we can hold this reference because the handlerdata has the
228
+ // same lifetime as the upb_handlers struct, and the upb_handlers struct holds
229
+ // a reference to the upb_msgdef, which in turn has references to its subdefs.
230
+ const upb_def* value_field_subdef;
231
+ } map_handlerdata_t;
232
+
233
+ // Temporary frame for map parsing: at the beginning of a map entry message, a
234
+ // submsg handler allocates a frame to hold (i) a reference to the Map object
235
+ // into which this message will be inserted and (ii) storage slots to
236
+ // temporarily hold the key and value for this map entry until the end of the
237
+ // submessage. When the submessage ends, another handler is called to insert the
238
+ // value into the map.
239
+ typedef struct {
240
+ VALUE map;
241
+ char key_storage[NATIVE_SLOT_MAX_SIZE];
242
+ char value_storage[NATIVE_SLOT_MAX_SIZE];
243
+ } map_parse_frame_t;
244
+
245
+ // Handler to begin a map entry: allocates a temporary frame. This is the
246
+ // 'startsubmsg' handler on the msgdef that contains the map field.
247
+ static void *startmapentry_handler(void *closure, const void *hd) {
248
+ MessageHeader* msg = closure;
249
+ const map_handlerdata_t* mapdata = hd;
250
+ VALUE map_rb = DEREF(msg, mapdata->ofs, VALUE);
251
+
252
+ map_parse_frame_t* frame = ALLOC(map_parse_frame_t);
253
+ frame->map = map_rb;
254
+
255
+ native_slot_init(mapdata->key_field_type, &frame->key_storage);
256
+ native_slot_init(mapdata->value_field_type, &frame->value_storage);
257
+
258
+ return frame;
259
+ }
260
+
261
+ // Handler to end a map entry: inserts the value defined during the message into
262
+ // the map. This is the 'endmsg' handler on the map entry msgdef.
263
+ static bool endmap_handler(void *closure, const void *hd, upb_status* s) {
264
+ map_parse_frame_t* frame = closure;
265
+ const map_handlerdata_t* mapdata = hd;
266
+
267
+ VALUE key = native_slot_get(
268
+ mapdata->key_field_type, Qnil,
269
+ &frame->key_storage);
270
+
271
+ VALUE value_field_typeclass = Qnil;
272
+ VALUE value;
273
+
274
+ if (mapdata->value_field_type == UPB_TYPE_MESSAGE ||
275
+ mapdata->value_field_type == UPB_TYPE_ENUM) {
276
+ value_field_typeclass = get_def_obj(mapdata->value_field_subdef);
277
+ }
278
+
279
+ value = native_slot_get(
280
+ mapdata->value_field_type, value_field_typeclass,
281
+ &frame->value_storage);
282
+
283
+ Map_index_set(frame->map, key, value);
284
+ free(frame);
285
+
286
+ return true;
287
+ }
288
+
289
+ // Allocates a new map_handlerdata_t given the map entry message definition. If
290
+ // the offset of the field within the parent message is also given, that is
291
+ // added to the handler data as well. Note that this is called *twice* per map
292
+ // field: once in the parent message handler setup when setting the startsubmsg
293
+ // handler and once in the map entry message handler setup when setting the
294
+ // key/value and endmsg handlers. The reason is that there is no easy way to
295
+ // pass the handlerdata down to the sub-message handler setup.
296
+ static map_handlerdata_t* new_map_handlerdata(
297
+ size_t ofs,
298
+ const upb_msgdef* mapentry_def,
299
+ Descriptor* desc) {
300
+ const upb_fielddef* key_field;
301
+ const upb_fielddef* value_field;
302
+ map_handlerdata_t* hd = ALLOC(map_handlerdata_t);
303
+ hd->ofs = ofs;
304
+ key_field = upb_msgdef_itof(mapentry_def, MAP_KEY_FIELD);
305
+ assert(key_field != NULL);
306
+ hd->key_field_type = upb_fielddef_type(key_field);
307
+ value_field = upb_msgdef_itof(mapentry_def, MAP_VALUE_FIELD);
308
+ assert(value_field != NULL);
309
+ hd->value_field_type = upb_fielddef_type(value_field);
310
+ hd->value_field_subdef = upb_fielddef_subdef(value_field);
311
+
312
+ return hd;
313
+ }
314
+
315
+ // Handlers that set primitive values in oneofs.
316
+ #define DEFINE_ONEOF_HANDLER(type, ctype) \
317
+ static bool oneof##type##_handler(void *closure, const void *hd, \
318
+ ctype val) { \
319
+ const oneof_handlerdata_t *oneofdata = hd; \
320
+ DEREF(closure, oneofdata->case_ofs, uint32_t) = \
321
+ oneofdata->oneof_case_num; \
322
+ DEREF(closure, oneofdata->ofs, ctype) = val; \
323
+ return true; \
324
+ }
325
+
326
+ DEFINE_ONEOF_HANDLER(bool, bool)
327
+ DEFINE_ONEOF_HANDLER(int32, int32_t)
328
+ DEFINE_ONEOF_HANDLER(uint32, uint32_t)
329
+ DEFINE_ONEOF_HANDLER(float, float)
330
+ DEFINE_ONEOF_HANDLER(int64, int64_t)
331
+ DEFINE_ONEOF_HANDLER(uint64, uint64_t)
332
+ DEFINE_ONEOF_HANDLER(double, double)
333
+
334
+ #undef DEFINE_ONEOF_HANDLER
335
+
336
+ // Handlers for strings in a oneof.
337
+ static void *oneofstr_handler(void *closure,
338
+ const void *hd,
339
+ size_t size_hint) {
340
+ MessageHeader* msg = closure;
341
+ const oneof_handlerdata_t *oneofdata = hd;
342
+ VALUE str = rb_str_new2("");
343
+ rb_enc_associate(str, kRubyStringUtf8Encoding);
344
+ DEREF(msg, oneofdata->case_ofs, uint32_t) =
345
+ oneofdata->oneof_case_num;
346
+ DEREF(msg, oneofdata->ofs, VALUE) = str;
347
+ return (void*)str;
348
+ }
349
+
350
+ static void *oneofbytes_handler(void *closure,
351
+ const void *hd,
352
+ size_t size_hint) {
353
+ MessageHeader* msg = closure;
354
+ const oneof_handlerdata_t *oneofdata = hd;
355
+ VALUE str = rb_str_new2("");
356
+ rb_enc_associate(str, kRubyString8bitEncoding);
357
+ DEREF(msg, oneofdata->case_ofs, uint32_t) =
358
+ oneofdata->oneof_case_num;
359
+ DEREF(msg, oneofdata->ofs, VALUE) = str;
360
+ return (void*)str;
361
+ }
362
+
363
+ // Handler for a submessage field in a oneof.
364
+ static void *oneofsubmsg_handler(void *closure,
365
+ const void *hd) {
366
+ MessageHeader* msg = closure;
367
+ const oneof_handlerdata_t *oneofdata = hd;
368
+ uint32_t oldcase = DEREF(msg, oneofdata->case_ofs, uint32_t);
369
+
370
+ VALUE subdesc =
371
+ get_def_obj((void*)oneofdata->md);
372
+ VALUE subklass = Descriptor_msgclass(subdesc);
373
+ VALUE submsg_rb;
374
+ MessageHeader* submsg;
375
+
376
+ if (oldcase != oneofdata->oneof_case_num ||
377
+ DEREF(msg, oneofdata->ofs, VALUE) == Qnil) {
378
+ DEREF(msg, oneofdata->ofs, VALUE) =
379
+ rb_class_new_instance(0, NULL, subklass);
380
+ }
381
+ // Set the oneof case *after* allocating the new class instance -- otherwise,
382
+ // if the Ruby GC is invoked as part of a call into the VM, it might invoke
383
+ // our mark routines, and our mark routines might see the case value
384
+ // indicating a VALUE is present and expect a valid VALUE. See comment in
385
+ // layout_set() for more detail: basically, the change to the value and the
386
+ // case must be atomic w.r.t. the Ruby VM.
387
+ DEREF(msg, oneofdata->case_ofs, uint32_t) =
388
+ oneofdata->oneof_case_num;
389
+
390
+ submsg_rb = DEREF(msg, oneofdata->ofs, VALUE);
391
+ TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg);
392
+ return submsg;
393
+ }
394
+
395
+ // Set up handlers for a repeated field.
396
+ static void add_handlers_for_repeated_field(upb_handlers *h,
397
+ const upb_fielddef *f,
398
+ size_t offset) {
399
+ upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
400
+ upb_handlerattr_sethandlerdata(&attr, newhandlerdata(h, offset));
401
+ upb_handlers_setstartseq(h, f, startseq_handler, &attr);
402
+ upb_handlerattr_uninit(&attr);
403
+
404
+ switch (upb_fielddef_type(f)) {
405
+
406
+ #define SET_HANDLER(utype, ltype) \
407
+ case utype: \
408
+ upb_handlers_set##ltype(h, f, append##ltype##_handler, NULL); \
409
+ break;
410
+
411
+ SET_HANDLER(UPB_TYPE_BOOL, bool);
412
+ SET_HANDLER(UPB_TYPE_INT32, int32);
413
+ SET_HANDLER(UPB_TYPE_UINT32, uint32);
414
+ SET_HANDLER(UPB_TYPE_ENUM, int32);
415
+ SET_HANDLER(UPB_TYPE_FLOAT, float);
416
+ SET_HANDLER(UPB_TYPE_INT64, int64);
417
+ SET_HANDLER(UPB_TYPE_UINT64, uint64);
418
+ SET_HANDLER(UPB_TYPE_DOUBLE, double);
419
+
420
+ #undef SET_HANDLER
421
+
422
+ case UPB_TYPE_STRING:
423
+ case UPB_TYPE_BYTES: {
424
+ bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES;
425
+ upb_handlers_setstartstr(h, f, is_bytes ?
426
+ appendbytes_handler : appendstr_handler,
427
+ NULL);
428
+ upb_handlers_setstring(h, f, stringdata_handler, NULL);
429
+ break;
430
+ }
431
+ case UPB_TYPE_MESSAGE: {
432
+ upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
433
+ upb_handlerattr_sethandlerdata(&attr, newsubmsghandlerdata(h, 0, f));
434
+ upb_handlers_setstartsubmsg(h, f, appendsubmsg_handler, &attr);
435
+ upb_handlerattr_uninit(&attr);
436
+ break;
437
+ }
438
+ }
439
+ }
440
+
441
+ // Set up handlers for a singular field.
442
+ static void add_handlers_for_singular_field(upb_handlers *h,
443
+ const upb_fielddef *f,
444
+ size_t offset) {
445
+ switch (upb_fielddef_type(f)) {
446
+ case UPB_TYPE_BOOL:
447
+ case UPB_TYPE_INT32:
448
+ case UPB_TYPE_UINT32:
449
+ case UPB_TYPE_ENUM:
450
+ case UPB_TYPE_FLOAT:
451
+ case UPB_TYPE_INT64:
452
+ case UPB_TYPE_UINT64:
453
+ case UPB_TYPE_DOUBLE:
454
+ upb_shim_set(h, f, offset, -1);
455
+ break;
456
+ case UPB_TYPE_STRING:
457
+ case UPB_TYPE_BYTES: {
458
+ bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES;
459
+ upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
460
+ upb_handlerattr_sethandlerdata(&attr, newhandlerdata(h, offset));
461
+ upb_handlers_setstartstr(h, f,
462
+ is_bytes ? bytes_handler : str_handler,
463
+ &attr);
464
+ upb_handlers_setstring(h, f, stringdata_handler, &attr);
465
+ upb_handlerattr_uninit(&attr);
466
+ break;
467
+ }
468
+ case UPB_TYPE_MESSAGE: {
469
+ upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
470
+ upb_handlerattr_sethandlerdata(&attr, newsubmsghandlerdata(h, offset, f));
471
+ upb_handlers_setstartsubmsg(h, f, submsg_handler, &attr);
472
+ upb_handlerattr_uninit(&attr);
473
+ break;
474
+ }
475
+ }
476
+ }
477
+
478
+ // Adds handlers to a map field.
479
+ static void add_handlers_for_mapfield(upb_handlers* h,
480
+ const upb_fielddef* fielddef,
481
+ size_t offset,
482
+ Descriptor* desc) {
483
+ const upb_msgdef* map_msgdef = upb_fielddef_msgsubdef(fielddef);
484
+ map_handlerdata_t* hd = new_map_handlerdata(offset, map_msgdef, desc);
485
+ upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
486
+
487
+ upb_handlers_addcleanup(h, hd, free);
488
+ upb_handlerattr_sethandlerdata(&attr, hd);
489
+ upb_handlers_setstartsubmsg(h, fielddef, startmapentry_handler, &attr);
490
+ upb_handlerattr_uninit(&attr);
491
+ }
492
+
493
+ // Adds handlers to a map-entry msgdef.
494
+ static void add_handlers_for_mapentry(const upb_msgdef* msgdef,
495
+ upb_handlers* h,
496
+ Descriptor* desc) {
497
+ const upb_fielddef* key_field = map_entry_key(msgdef);
498
+ const upb_fielddef* value_field = map_entry_value(msgdef);
499
+ map_handlerdata_t* hd = new_map_handlerdata(0, msgdef, desc);
500
+ upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
501
+
502
+ upb_handlers_addcleanup(h, hd, free);
503
+ upb_handlerattr_sethandlerdata(&attr, hd);
504
+ upb_handlers_setendmsg(h, endmap_handler, &attr);
505
+
506
+ add_handlers_for_singular_field(
507
+ h, key_field,
508
+ offsetof(map_parse_frame_t, key_storage));
509
+ add_handlers_for_singular_field(
510
+ h, value_field,
511
+ offsetof(map_parse_frame_t, value_storage));
512
+ }
513
+
514
+ // Set up handlers for a oneof field.
515
+ static void add_handlers_for_oneof_field(upb_handlers *h,
516
+ const upb_fielddef *f,
517
+ size_t offset,
518
+ size_t oneof_case_offset) {
519
+
520
+ upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
521
+ upb_handlerattr_sethandlerdata(
522
+ &attr, newoneofhandlerdata(h, offset, oneof_case_offset, f));
523
+
524
+ switch (upb_fielddef_type(f)) {
525
+
526
+ #define SET_HANDLER(utype, ltype) \
527
+ case utype: \
528
+ upb_handlers_set##ltype(h, f, oneof##ltype##_handler, &attr); \
529
+ break;
530
+
531
+ SET_HANDLER(UPB_TYPE_BOOL, bool);
532
+ SET_HANDLER(UPB_TYPE_INT32, int32);
533
+ SET_HANDLER(UPB_TYPE_UINT32, uint32);
534
+ SET_HANDLER(UPB_TYPE_ENUM, int32);
535
+ SET_HANDLER(UPB_TYPE_FLOAT, float);
536
+ SET_HANDLER(UPB_TYPE_INT64, int64);
537
+ SET_HANDLER(UPB_TYPE_UINT64, uint64);
538
+ SET_HANDLER(UPB_TYPE_DOUBLE, double);
539
+
540
+ #undef SET_HANDLER
541
+
542
+ case UPB_TYPE_STRING:
543
+ case UPB_TYPE_BYTES: {
544
+ bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES;
545
+ upb_handlers_setstartstr(h, f, is_bytes ?
546
+ oneofbytes_handler : oneofstr_handler,
547
+ &attr);
548
+ upb_handlers_setstring(h, f, stringdata_handler, NULL);
549
+ break;
550
+ }
551
+ case UPB_TYPE_MESSAGE: {
552
+ upb_handlers_setstartsubmsg(h, f, oneofsubmsg_handler, &attr);
553
+ break;
554
+ }
555
+ }
556
+
557
+ upb_handlerattr_uninit(&attr);
558
+ }
559
+
560
+
561
+ static void add_handlers_for_message(const void *closure, upb_handlers *h) {
562
+ const upb_msgdef* msgdef = upb_handlers_msgdef(h);
563
+ Descriptor* desc = ruby_to_Descriptor(get_def_obj((void*)msgdef));
564
+ upb_msg_field_iter i;
565
+
566
+ // If this is a mapentry message type, set up a special set of handlers and
567
+ // bail out of the normal (user-defined) message type handling.
568
+ if (upb_msgdef_mapentry(msgdef)) {
569
+ add_handlers_for_mapentry(msgdef, h, desc);
570
+ return;
571
+ }
572
+
573
+ // Ensure layout exists. We may be invoked to create handlers for a given
574
+ // message if we are included as a submsg of another message type before our
575
+ // class is actually built, so to work around this, we just create the layout
576
+ // (and handlers, in the class-building function) on-demand.
577
+ if (desc->layout == NULL) {
578
+ desc->layout = create_layout(desc->msgdef);
579
+ }
580
+
581
+ for (upb_msg_field_begin(&i, desc->msgdef);
582
+ !upb_msg_field_done(&i);
583
+ upb_msg_field_next(&i)) {
584
+ const upb_fielddef *f = upb_msg_iter_field(&i);
585
+ size_t offset = desc->layout->fields[upb_fielddef_index(f)].offset +
586
+ sizeof(MessageHeader);
587
+
588
+ if (upb_fielddef_containingoneof(f)) {
589
+ size_t oneof_case_offset =
590
+ desc->layout->fields[upb_fielddef_index(f)].case_offset +
591
+ sizeof(MessageHeader);
592
+ add_handlers_for_oneof_field(h, f, offset, oneof_case_offset);
593
+ } else if (is_map_field(f)) {
594
+ add_handlers_for_mapfield(h, f, offset, desc);
595
+ } else if (upb_fielddef_isseq(f)) {
596
+ add_handlers_for_repeated_field(h, f, offset);
597
+ } else {
598
+ add_handlers_for_singular_field(h, f, offset);
599
+ }
600
+ }
601
+ }
602
+
603
+ // Creates upb handlers for populating a message.
604
+ static const upb_handlers *new_fill_handlers(Descriptor* desc,
605
+ const void* owner) {
606
+ // TODO(cfallin, haberman): once upb gets a caching/memoization layer for
607
+ // handlers, reuse subdef handlers so that e.g. if we already parse
608
+ // B-with-field-of-type-C, we don't have to rebuild the whole hierarchy to
609
+ // parse A-with-field-of-type-B-with-field-of-type-C.
610
+ return upb_handlers_newfrozen(desc->msgdef, owner,
611
+ add_handlers_for_message, NULL);
612
+ }
613
+
614
+ // Constructs the handlers for filling a message's data into an in-memory
615
+ // object.
616
+ const upb_handlers* get_fill_handlers(Descriptor* desc) {
617
+ if (!desc->fill_handlers) {
618
+ desc->fill_handlers =
619
+ new_fill_handlers(desc, &desc->fill_handlers);
620
+ }
621
+ return desc->fill_handlers;
622
+ }
623
+
624
+ // Constructs the upb decoder method for parsing messages of this type.
625
+ // This is called from the message class creation code.
626
+ const upb_pbdecodermethod *new_fillmsg_decodermethod(Descriptor* desc,
627
+ const void* owner) {
628
+ const upb_handlers* handlers = get_fill_handlers(desc);
629
+ upb_pbdecodermethodopts opts;
630
+ upb_pbdecodermethodopts_init(&opts, handlers);
631
+
632
+ return upb_pbdecodermethod_new(&opts, owner);
633
+ }
634
+
635
+ static const upb_pbdecodermethod *msgdef_decodermethod(Descriptor* desc) {
636
+ if (desc->fill_method == NULL) {
637
+ desc->fill_method = new_fillmsg_decodermethod(
638
+ desc, &desc->fill_method);
639
+ }
640
+ return desc->fill_method;
641
+ }
642
+
643
+
644
+ // Stack-allocated context during an encode/decode operation. Contains the upb
645
+ // environment and its stack-based allocator, an initial buffer for allocations
646
+ // to avoid malloc() when possible, and a template for Ruby exception messages
647
+ // if any error occurs.
648
+ #define STACK_ENV_STACKBYTES 4096
649
+ typedef struct {
650
+ upb_env env;
651
+ upb_seededalloc alloc;
652
+ const char* ruby_error_template;
653
+ char allocbuf[STACK_ENV_STACKBYTES];
654
+ } stackenv;
655
+
656
+ static void stackenv_init(stackenv* se, const char* errmsg);
657
+ static void stackenv_uninit(stackenv* se);
658
+
659
+ // Callback invoked by upb if any error occurs during parsing or serialization.
660
+ static bool env_error_func(void* ud, const upb_status* status) {
661
+ stackenv* se = ud;
662
+ // Free the env -- rb_raise will longjmp up the stack past the encode/decode
663
+ // function so it would not otherwise have been freed.
664
+ stackenv_uninit(se);
665
+
666
+ // TODO(haberman): have a way to verify that this is actually a parse error,
667
+ // instead of just throwing "parse error" unconditionally.
668
+ rb_raise(cParseError, se->ruby_error_template, upb_status_errmsg(status));
669
+ // Never reached: rb_raise() always longjmp()s up the stack, past all of our
670
+ // code, back to Ruby.
671
+ return false;
672
+ }
673
+
674
+ static void stackenv_init(stackenv* se, const char* errmsg) {
675
+ se->ruby_error_template = errmsg;
676
+ upb_env_init(&se->env);
677
+ upb_seededalloc_init(&se->alloc, &se->allocbuf, STACK_ENV_STACKBYTES);
678
+ upb_env_setallocfunc(
679
+ &se->env, upb_seededalloc_getallocfunc(&se->alloc), &se->alloc);
680
+ upb_env_seterrorfunc(&se->env, env_error_func, se);
681
+ }
682
+
683
+ static void stackenv_uninit(stackenv* se) {
684
+ upb_env_uninit(&se->env);
685
+ upb_seededalloc_uninit(&se->alloc);
686
+ }
687
+
688
+ /*
689
+ * call-seq:
690
+ * MessageClass.decode(data) => message
691
+ *
692
+ * Decodes the given data (as a string containing bytes in protocol buffers wire
693
+ * format) under the interpretration given by this message class's definition
694
+ * and returns a message object with the corresponding field values.
695
+ */
696
+ VALUE Message_decode(VALUE klass, VALUE data) {
697
+ VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
698
+ Descriptor* desc = ruby_to_Descriptor(descriptor);
699
+ VALUE msgklass = Descriptor_msgclass(descriptor);
700
+ VALUE msg_rb;
701
+ MessageHeader* msg;
702
+
703
+ if (TYPE(data) != T_STRING) {
704
+ rb_raise(rb_eArgError, "Expected string for binary protobuf data.");
705
+ }
706
+
707
+ msg_rb = rb_class_new_instance(0, NULL, msgklass);
708
+ TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
709
+
710
+ {
711
+ const upb_pbdecodermethod* method = msgdef_decodermethod(desc);
712
+ const upb_handlers* h = upb_pbdecodermethod_desthandlers(method);
713
+ stackenv se;
714
+ upb_sink sink;
715
+ upb_pbdecoder* decoder;
716
+ stackenv_init(&se, "Error occurred during parsing: %s");
717
+
718
+ upb_sink_reset(&sink, h, msg);
719
+ decoder = upb_pbdecoder_create(&se.env, method, &sink);
720
+ upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data),
721
+ upb_pbdecoder_input(decoder));
722
+
723
+ stackenv_uninit(&se);
724
+ }
725
+
726
+ return msg_rb;
727
+ }
728
+
729
+ /*
730
+ * call-seq:
731
+ * MessageClass.decode_json(data) => message
732
+ *
733
+ * Decodes the given data (as a string containing bytes in protocol buffers wire
734
+ * format) under the interpretration given by this message class's definition
735
+ * and returns a message object with the corresponding field values.
736
+ */
737
+ VALUE Message_decode_json(VALUE klass, VALUE data) {
738
+ VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
739
+ Descriptor* desc = ruby_to_Descriptor(descriptor);
740
+ VALUE msgklass = Descriptor_msgclass(descriptor);
741
+ VALUE msg_rb;
742
+ MessageHeader* msg;
743
+
744
+ if (TYPE(data) != T_STRING) {
745
+ rb_raise(rb_eArgError, "Expected string for JSON data.");
746
+ }
747
+ // TODO(cfallin): Check and respect string encoding. If not UTF-8, we need to
748
+ // convert, because string handlers pass data directly to message string
749
+ // fields.
750
+
751
+ msg_rb = rb_class_new_instance(0, NULL, msgklass);
752
+ TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
753
+
754
+ {
755
+ stackenv se;
756
+ upb_sink sink;
757
+ upb_json_parser* parser;
758
+ stackenv_init(&se, "Error occurred during parsing: %s");
759
+
760
+ upb_sink_reset(&sink, get_fill_handlers(desc), msg);
761
+ parser = upb_json_parser_create(&se.env, &sink);
762
+ upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data),
763
+ upb_json_parser_input(parser));
764
+
765
+ stackenv_uninit(&se);
766
+ }
767
+
768
+ return msg_rb;
769
+ }
770
+
771
+ // -----------------------------------------------------------------------------
772
+ // Serializing.
773
+ // -----------------------------------------------------------------------------
774
+ //
775
+ // The code below also comes from upb's prototype Ruby binding, developed by
776
+ // haberman@.
777
+
778
+ /* stringsink *****************************************************************/
779
+
780
+ // This should probably be factored into a common upb component.
781
+
782
+ typedef struct {
783
+ upb_byteshandler handler;
784
+ upb_bytessink sink;
785
+ char *ptr;
786
+ size_t len, size;
787
+ } stringsink;
788
+
789
+ static void *stringsink_start(void *_sink, const void *hd, size_t size_hint) {
790
+ stringsink *sink = _sink;
791
+ sink->len = 0;
792
+ return sink;
793
+ }
794
+
795
+ static size_t stringsink_string(void *_sink, const void *hd, const char *ptr,
796
+ size_t len, const upb_bufhandle *handle) {
797
+ stringsink *sink = _sink;
798
+ size_t new_size = sink->size;
799
+
800
+ UPB_UNUSED(hd);
801
+ UPB_UNUSED(handle);
802
+
803
+ while (sink->len + len > new_size) {
804
+ new_size *= 2;
805
+ }
806
+
807
+ if (new_size != sink->size) {
808
+ sink->ptr = realloc(sink->ptr, new_size);
809
+ sink->size = new_size;
810
+ }
811
+
812
+ memcpy(sink->ptr + sink->len, ptr, len);
813
+ sink->len += len;
814
+
815
+ return len;
816
+ }
817
+
818
+ void stringsink_init(stringsink *sink) {
819
+ upb_byteshandler_init(&sink->handler);
820
+ upb_byteshandler_setstartstr(&sink->handler, stringsink_start, NULL);
821
+ upb_byteshandler_setstring(&sink->handler, stringsink_string, NULL);
822
+
823
+ upb_bytessink_reset(&sink->sink, &sink->handler, sink);
824
+
825
+ sink->size = 32;
826
+ sink->ptr = malloc(sink->size);
827
+ sink->len = 0;
828
+ }
829
+
830
+ void stringsink_uninit(stringsink *sink) {
831
+ free(sink->ptr);
832
+ }
833
+
834
+ /* msgvisitor *****************************************************************/
835
+
836
+ // TODO: If/when we support proto2 semantics in addition to the current proto3
837
+ // semantics, which means that we have true field presence, we will want to
838
+ // modify msgvisitor so that it emits all present fields rather than all
839
+ // non-default-value fields.
840
+ //
841
+ // Likewise, when implementing JSON serialization, we may need to have a
842
+ // 'verbose' mode that outputs all fields and a 'concise' mode that outputs only
843
+ // those with non-default values.
844
+
845
+ static void putmsg(VALUE msg, const Descriptor* desc,
846
+ upb_sink *sink, int depth);
847
+
848
+ static upb_selector_t getsel(const upb_fielddef *f, upb_handlertype_t type) {
849
+ upb_selector_t ret;
850
+ bool ok = upb_handlers_getselector(f, type, &ret);
851
+ UPB_ASSERT_VAR(ok, ok);
852
+ return ret;
853
+ }
854
+
855
+ static void putstr(VALUE str, const upb_fielddef *f, upb_sink *sink) {
856
+ upb_sink subsink;
857
+
858
+ if (str == Qnil) return;
859
+
860
+ assert(BUILTIN_TYPE(str) == RUBY_T_STRING);
861
+
862
+ // Ensure that the string has the correct encoding. We also check at field-set
863
+ // time, but the user may have mutated the string object since then.
864
+ native_slot_validate_string_encoding(upb_fielddef_type(f), str);
865
+
866
+ upb_sink_startstr(sink, getsel(f, UPB_HANDLER_STARTSTR), RSTRING_LEN(str),
867
+ &subsink);
868
+ upb_sink_putstring(&subsink, getsel(f, UPB_HANDLER_STRING), RSTRING_PTR(str),
869
+ RSTRING_LEN(str), NULL);
870
+ upb_sink_endstr(sink, getsel(f, UPB_HANDLER_ENDSTR));
871
+ }
872
+
873
+ static void putsubmsg(VALUE submsg, const upb_fielddef *f, upb_sink *sink,
874
+ int depth) {
875
+ upb_sink subsink;
876
+ VALUE descriptor;
877
+ Descriptor* subdesc;
878
+
879
+ if (submsg == Qnil) return;
880
+
881
+ descriptor = rb_ivar_get(submsg, descriptor_instancevar_interned);
882
+ subdesc = ruby_to_Descriptor(descriptor);
883
+
884
+ upb_sink_startsubmsg(sink, getsel(f, UPB_HANDLER_STARTSUBMSG), &subsink);
885
+ putmsg(submsg, subdesc, &subsink, depth + 1);
886
+ upb_sink_endsubmsg(sink, getsel(f, UPB_HANDLER_ENDSUBMSG));
887
+ }
888
+
889
+ static void putary(VALUE ary, const upb_fielddef *f, upb_sink *sink,
890
+ int depth) {
891
+ upb_sink subsink;
892
+ upb_fieldtype_t type = upb_fielddef_type(f);
893
+ upb_selector_t sel = 0;
894
+ int size;
895
+
896
+ if (ary == Qnil) return;
897
+
898
+ upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);
899
+
900
+ if (upb_fielddef_isprimitive(f)) {
901
+ sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
902
+ }
903
+
904
+ size = NUM2INT(RepeatedField_length(ary));
905
+ for (int i = 0; i < size; i++) {
906
+ void* memory = RepeatedField_index_native(ary, i);
907
+ switch (type) {
908
+ #define T(upbtypeconst, upbtype, ctype) \
909
+ case upbtypeconst: \
910
+ upb_sink_put##upbtype(&subsink, sel, *((ctype *)memory)); \
911
+ break;
912
+
913
+ T(UPB_TYPE_FLOAT, float, float)
914
+ T(UPB_TYPE_DOUBLE, double, double)
915
+ T(UPB_TYPE_BOOL, bool, int8_t)
916
+ case UPB_TYPE_ENUM:
917
+ T(UPB_TYPE_INT32, int32, int32_t)
918
+ T(UPB_TYPE_UINT32, uint32, uint32_t)
919
+ T(UPB_TYPE_INT64, int64, int64_t)
920
+ T(UPB_TYPE_UINT64, uint64, uint64_t)
921
+
922
+ case UPB_TYPE_STRING:
923
+ case UPB_TYPE_BYTES:
924
+ putstr(*((VALUE *)memory), f, &subsink);
925
+ break;
926
+ case UPB_TYPE_MESSAGE:
927
+ putsubmsg(*((VALUE *)memory), f, &subsink, depth);
928
+ break;
929
+
930
+ #undef T
931
+
932
+ }
933
+ }
934
+ upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ));
935
+ }
936
+
937
+ static void put_ruby_value(VALUE value,
938
+ const upb_fielddef *f,
939
+ VALUE type_class,
940
+ int depth,
941
+ upb_sink *sink) {
942
+ upb_selector_t sel = 0;
943
+ if (upb_fielddef_isprimitive(f)) {
944
+ sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
945
+ }
946
+
947
+ switch (upb_fielddef_type(f)) {
948
+ case UPB_TYPE_INT32:
949
+ upb_sink_putint32(sink, sel, NUM2INT(value));
950
+ break;
951
+ case UPB_TYPE_INT64:
952
+ upb_sink_putint64(sink, sel, NUM2LL(value));
953
+ break;
954
+ case UPB_TYPE_UINT32:
955
+ upb_sink_putuint32(sink, sel, NUM2UINT(value));
956
+ break;
957
+ case UPB_TYPE_UINT64:
958
+ upb_sink_putuint64(sink, sel, NUM2ULL(value));
959
+ break;
960
+ case UPB_TYPE_FLOAT:
961
+ upb_sink_putfloat(sink, sel, NUM2DBL(value));
962
+ break;
963
+ case UPB_TYPE_DOUBLE:
964
+ upb_sink_putdouble(sink, sel, NUM2DBL(value));
965
+ break;
966
+ case UPB_TYPE_ENUM: {
967
+ if (TYPE(value) == T_SYMBOL) {
968
+ value = rb_funcall(type_class, rb_intern("resolve"), 1, value);
969
+ }
970
+ upb_sink_putint32(sink, sel, NUM2INT(value));
971
+ break;
972
+ }
973
+ case UPB_TYPE_BOOL:
974
+ upb_sink_putbool(sink, sel, value == Qtrue);
975
+ break;
976
+ case UPB_TYPE_STRING:
977
+ case UPB_TYPE_BYTES:
978
+ putstr(value, f, sink);
979
+ break;
980
+ case UPB_TYPE_MESSAGE:
981
+ putsubmsg(value, f, sink, depth);
982
+ }
983
+ }
984
+
985
+ static void putmap(VALUE map, const upb_fielddef *f, upb_sink *sink,
986
+ int depth) {
987
+ Map* self;
988
+ upb_sink subsink;
989
+ const upb_fielddef* key_field;
990
+ const upb_fielddef* value_field;
991
+ Map_iter it;
992
+
993
+ if (map == Qnil) return;
994
+ self = ruby_to_Map(map);
995
+
996
+ upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);
997
+
998
+ assert(upb_fielddef_type(f) == UPB_TYPE_MESSAGE);
999
+ key_field = map_field_key(f);
1000
+ value_field = map_field_value(f);
1001
+
1002
+ for (Map_begin(map, &it); !Map_done(&it); Map_next(&it)) {
1003
+ VALUE key = Map_iter_key(&it);
1004
+ VALUE value = Map_iter_value(&it);
1005
+ upb_status status;
1006
+
1007
+ upb_sink entry_sink;
1008
+ upb_sink_startsubmsg(&subsink, getsel(f, UPB_HANDLER_STARTSUBMSG),
1009
+ &entry_sink);
1010
+ upb_sink_startmsg(&entry_sink);
1011
+
1012
+ put_ruby_value(key, key_field, Qnil, depth + 1, &entry_sink);
1013
+ put_ruby_value(value, value_field, self->value_type_class, depth + 1,
1014
+ &entry_sink);
1015
+
1016
+ upb_sink_endmsg(&entry_sink, &status);
1017
+ upb_sink_endsubmsg(&subsink, getsel(f, UPB_HANDLER_ENDSUBMSG));
1018
+ }
1019
+
1020
+ upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ));
1021
+ }
1022
+
1023
+ static void putmsg(VALUE msg_rb, const Descriptor* desc,
1024
+ upb_sink *sink, int depth) {
1025
+ MessageHeader* msg;
1026
+ upb_msg_field_iter i;
1027
+ upb_status status;
1028
+
1029
+ upb_sink_startmsg(sink);
1030
+
1031
+ // Protect against cycles (possible because users may freely reassign message
1032
+ // and repeated fields) by imposing a maximum recursion depth.
1033
+ if (depth > ENCODE_MAX_NESTING) {
1034
+ rb_raise(rb_eRuntimeError,
1035
+ "Maximum recursion depth exceeded during encoding.");
1036
+ }
1037
+
1038
+ TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
1039
+
1040
+ for (upb_msg_field_begin(&i, desc->msgdef);
1041
+ !upb_msg_field_done(&i);
1042
+ upb_msg_field_next(&i)) {
1043
+ upb_fielddef *f = upb_msg_iter_field(&i);
1044
+ uint32_t offset =
1045
+ desc->layout->fields[upb_fielddef_index(f)].offset +
1046
+ sizeof(MessageHeader);
1047
+
1048
+ if (upb_fielddef_containingoneof(f)) {
1049
+ uint32_t oneof_case_offset =
1050
+ desc->layout->fields[upb_fielddef_index(f)].case_offset +
1051
+ sizeof(MessageHeader);
1052
+ // For a oneof, check that this field is actually present -- skip all the
1053
+ // below if not.
1054
+ if (DEREF(msg, oneof_case_offset, uint32_t) !=
1055
+ upb_fielddef_number(f)) {
1056
+ continue;
1057
+ }
1058
+ // Otherwise, fall through to the appropriate singular-field handler
1059
+ // below.
1060
+ }
1061
+
1062
+ if (is_map_field(f)) {
1063
+ VALUE map = DEREF(msg, offset, VALUE);
1064
+ if (map != Qnil) {
1065
+ putmap(map, f, sink, depth);
1066
+ }
1067
+ } else if (upb_fielddef_isseq(f)) {
1068
+ VALUE ary = DEREF(msg, offset, VALUE);
1069
+ if (ary != Qnil) {
1070
+ putary(ary, f, sink, depth);
1071
+ }
1072
+ } else if (upb_fielddef_isstring(f)) {
1073
+ VALUE str = DEREF(msg, offset, VALUE);
1074
+ if (RSTRING_LEN(str) > 0) {
1075
+ putstr(str, f, sink);
1076
+ }
1077
+ } else if (upb_fielddef_issubmsg(f)) {
1078
+ putsubmsg(DEREF(msg, offset, VALUE), f, sink, depth);
1079
+ } else {
1080
+ upb_selector_t sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
1081
+
1082
+ #define T(upbtypeconst, upbtype, ctype, default_value) \
1083
+ case upbtypeconst: { \
1084
+ ctype value = DEREF(msg, offset, ctype); \
1085
+ if (value != default_value) { \
1086
+ upb_sink_put##upbtype(sink, sel, value); \
1087
+ } \
1088
+ } \
1089
+ break;
1090
+
1091
+ switch (upb_fielddef_type(f)) {
1092
+ T(UPB_TYPE_FLOAT, float, float, 0.0)
1093
+ T(UPB_TYPE_DOUBLE, double, double, 0.0)
1094
+ T(UPB_TYPE_BOOL, bool, uint8_t, 0)
1095
+ case UPB_TYPE_ENUM:
1096
+ T(UPB_TYPE_INT32, int32, int32_t, 0)
1097
+ T(UPB_TYPE_UINT32, uint32, uint32_t, 0)
1098
+ T(UPB_TYPE_INT64, int64, int64_t, 0)
1099
+ T(UPB_TYPE_UINT64, uint64, uint64_t, 0)
1100
+
1101
+ case UPB_TYPE_STRING:
1102
+ case UPB_TYPE_BYTES:
1103
+ case UPB_TYPE_MESSAGE: rb_raise(rb_eRuntimeError, "Internal error.");
1104
+ }
1105
+
1106
+ #undef T
1107
+
1108
+ }
1109
+ }
1110
+
1111
+ upb_sink_endmsg(sink, &status);
1112
+ }
1113
+
1114
+ static const upb_handlers* msgdef_pb_serialize_handlers(Descriptor* desc) {
1115
+ if (desc->pb_serialize_handlers == NULL) {
1116
+ desc->pb_serialize_handlers =
1117
+ upb_pb_encoder_newhandlers(desc->msgdef, &desc->pb_serialize_handlers);
1118
+ }
1119
+ return desc->pb_serialize_handlers;
1120
+ }
1121
+
1122
+ static const upb_handlers* msgdef_json_serialize_handlers(Descriptor* desc) {
1123
+ if (desc->json_serialize_handlers == NULL) {
1124
+ desc->json_serialize_handlers =
1125
+ upb_json_printer_newhandlers(
1126
+ desc->msgdef, &desc->json_serialize_handlers);
1127
+ }
1128
+ return desc->json_serialize_handlers;
1129
+ }
1130
+
1131
+ /*
1132
+ * call-seq:
1133
+ * MessageClass.encode(msg) => bytes
1134
+ *
1135
+ * Encodes the given message object to its serialized form in protocol buffers
1136
+ * wire format.
1137
+ */
1138
+ VALUE Message_encode(VALUE klass, VALUE msg_rb) {
1139
+ VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
1140
+ Descriptor* desc = ruby_to_Descriptor(descriptor);
1141
+
1142
+ stringsink sink;
1143
+ stringsink_init(&sink);
1144
+
1145
+ {
1146
+ const upb_handlers* serialize_handlers =
1147
+ msgdef_pb_serialize_handlers(desc);
1148
+
1149
+ stackenv se;
1150
+ upb_pb_encoder* encoder;
1151
+ VALUE ret;
1152
+
1153
+ stackenv_init(&se, "Error occurred during encoding: %s");
1154
+ encoder = upb_pb_encoder_create(&se.env, serialize_handlers, &sink.sink);
1155
+
1156
+ putmsg(msg_rb, desc, upb_pb_encoder_input(encoder), 0);
1157
+
1158
+ ret = rb_str_new(sink.ptr, sink.len);
1159
+
1160
+ stackenv_uninit(&se);
1161
+ stringsink_uninit(&sink);
1162
+
1163
+ return ret;
1164
+ }
1165
+ }
1166
+
1167
+ /*
1168
+ * call-seq:
1169
+ * MessageClass.encode_json(msg) => json_string
1170
+ *
1171
+ * Encodes the given message object into its serialized JSON representation.
1172
+ */
1173
+ VALUE Message_encode_json(VALUE klass, VALUE msg_rb) {
1174
+ VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
1175
+ Descriptor* desc = ruby_to_Descriptor(descriptor);
1176
+
1177
+ stringsink sink;
1178
+ stringsink_init(&sink);
1179
+
1180
+ {
1181
+ const upb_handlers* serialize_handlers =
1182
+ msgdef_json_serialize_handlers(desc);
1183
+ upb_json_printer* printer;
1184
+ stackenv se;
1185
+ VALUE ret;
1186
+
1187
+ stackenv_init(&se, "Error occurred during encoding: %s");
1188
+ printer = upb_json_printer_create(&se.env, serialize_handlers, &sink.sink);
1189
+
1190
+ putmsg(msg_rb, desc, upb_json_printer_input(printer), 0);
1191
+
1192
+ ret = rb_str_new(sink.ptr, sink.len);
1193
+
1194
+ stackenv_uninit(&se);
1195
+ stringsink_uninit(&sink);
1196
+
1197
+ return ret;
1198
+ }
1199
+ }
1200
+