google-protobuf 3.0.0 → 3.20.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of google-protobuf might be problematic. Click here for more details.

Files changed (46) hide show
  1. checksums.yaml +5 -5
  2. data/ext/google/protobuf_c/convert.c +361 -0
  3. data/ext/google/protobuf_c/convert.h +75 -0
  4. data/ext/google/protobuf_c/defs.c +760 -1243
  5. data/ext/google/protobuf_c/defs.h +107 -0
  6. data/ext/google/protobuf_c/extconf.rb +22 -4
  7. data/ext/google/protobuf_c/map.c +342 -450
  8. data/ext/google/protobuf_c/map.h +66 -0
  9. data/ext/google/protobuf_c/message.c +1108 -284
  10. data/ext/google/protobuf_c/message.h +104 -0
  11. data/ext/google/protobuf_c/protobuf.c +416 -51
  12. data/ext/google/protobuf_c/protobuf.h +53 -472
  13. data/ext/google/protobuf_c/repeated_field.c +318 -317
  14. data/ext/google/protobuf_c/repeated_field.h +63 -0
  15. data/ext/google/protobuf_c/ruby-upb.c +11115 -0
  16. data/ext/google/protobuf_c/ruby-upb.h +5612 -0
  17. data/ext/google/protobuf_c/third_party/utf8_range/LICENSE +21 -0
  18. data/ext/google/protobuf_c/third_party/utf8_range/naive.c +92 -0
  19. data/ext/google/protobuf_c/third_party/utf8_range/range2-neon.c +157 -0
  20. data/ext/google/protobuf_c/third_party/utf8_range/range2-sse.c +170 -0
  21. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +9 -0
  22. data/ext/google/protobuf_c/wrap_memcpy.c +52 -0
  23. data/lib/google/protobuf/any_pb.rb +6 -4
  24. data/lib/google/protobuf/api_pb.rb +27 -24
  25. data/lib/google/protobuf/descriptor_dsl.rb +465 -0
  26. data/lib/google/protobuf/descriptor_pb.rb +269 -0
  27. data/lib/google/protobuf/duration_pb.rb +6 -4
  28. data/lib/google/protobuf/empty_pb.rb +4 -2
  29. data/lib/google/protobuf/field_mask_pb.rb +5 -3
  30. data/lib/google/protobuf/message_exts.rb +4 -4
  31. data/lib/google/protobuf/repeated_field.rb +4 -4
  32. data/lib/google/protobuf/source_context_pb.rb +5 -3
  33. data/lib/google/protobuf/struct_pb.rb +23 -21
  34. data/lib/google/protobuf/timestamp_pb.rb +6 -4
  35. data/lib/google/protobuf/type_pb.rb +77 -74
  36. data/lib/google/protobuf/well_known_types.rb +240 -0
  37. data/lib/google/protobuf/wrappers_pb.rb +37 -35
  38. data/lib/google/protobuf.rb +12 -9
  39. data/tests/basic.rb +489 -1001
  40. data/tests/generated_code_test.rb +6 -2
  41. data/tests/stress.rb +1 -1
  42. metadata +39 -34
  43. data/ext/google/protobuf_c/encode_decode.c +0 -1264
  44. data/ext/google/protobuf_c/storage.c +0 -893
  45. data/ext/google/protobuf_c/upb.c +0 -12812
  46. data/ext/google/protobuf_c/upb.h +0 -8569
@@ -1,1264 +0,0 @@
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, xfree);
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, xfree);
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, xfree);
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_native(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_native(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
- static bool stringdata_end_handler(void* closure, const void* hd) {
186
- MessageHeader* msg = closure;
187
- const size_t *ofs = hd;
188
- VALUE rb_str = DEREF(msg, *ofs, VALUE);
189
- rb_obj_freeze(rb_str);
190
- return true;
191
- }
192
-
193
- static bool appendstring_end_handler(void* closure, const void* hd) {
194
- VALUE ary = (VALUE)closure;
195
- int size = RepeatedField_size(ary);
196
- VALUE* last = RepeatedField_index_native(ary, size - 1);
197
- VALUE rb_str = *last;
198
- rb_obj_freeze(rb_str);
199
- return true;
200
- }
201
-
202
- // Appends a submessage to a repeated field (a regular Ruby array for now).
203
- static void *appendsubmsg_handler(void *closure, const void *hd) {
204
- VALUE ary = (VALUE)closure;
205
- const submsg_handlerdata_t *submsgdata = hd;
206
- VALUE subdesc =
207
- get_def_obj((void*)submsgdata->md);
208
- VALUE subklass = Descriptor_msgclass(subdesc);
209
- MessageHeader* submsg;
210
-
211
- VALUE submsg_rb = rb_class_new_instance(0, NULL, subklass);
212
- RepeatedField_push(ary, submsg_rb);
213
-
214
- TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg);
215
- return submsg;
216
- }
217
-
218
- // Sets a non-repeated submessage field in a message.
219
- static void *submsg_handler(void *closure, const void *hd) {
220
- MessageHeader* msg = closure;
221
- const submsg_handlerdata_t* submsgdata = hd;
222
- VALUE subdesc =
223
- get_def_obj((void*)submsgdata->md);
224
- VALUE subklass = Descriptor_msgclass(subdesc);
225
- VALUE submsg_rb;
226
- MessageHeader* submsg;
227
-
228
- if (DEREF(msg, submsgdata->ofs, VALUE) == Qnil) {
229
- DEREF(msg, submsgdata->ofs, VALUE) =
230
- rb_class_new_instance(0, NULL, subklass);
231
- }
232
-
233
- submsg_rb = DEREF(msg, submsgdata->ofs, VALUE);
234
- TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg);
235
- return submsg;
236
- }
237
-
238
- // Handler data for startmap/endmap handlers.
239
- typedef struct {
240
- size_t ofs;
241
- upb_fieldtype_t key_field_type;
242
- upb_fieldtype_t value_field_type;
243
-
244
- // We know that we can hold this reference because the handlerdata has the
245
- // same lifetime as the upb_handlers struct, and the upb_handlers struct holds
246
- // a reference to the upb_msgdef, which in turn has references to its subdefs.
247
- const upb_def* value_field_subdef;
248
- } map_handlerdata_t;
249
-
250
- // Temporary frame for map parsing: at the beginning of a map entry message, a
251
- // submsg handler allocates a frame to hold (i) a reference to the Map object
252
- // into which this message will be inserted and (ii) storage slots to
253
- // temporarily hold the key and value for this map entry until the end of the
254
- // submessage. When the submessage ends, another handler is called to insert the
255
- // value into the map.
256
- typedef struct {
257
- VALUE map;
258
- char key_storage[NATIVE_SLOT_MAX_SIZE];
259
- char value_storage[NATIVE_SLOT_MAX_SIZE];
260
- } map_parse_frame_t;
261
-
262
- // Handler to begin a map entry: allocates a temporary frame. This is the
263
- // 'startsubmsg' handler on the msgdef that contains the map field.
264
- static void *startmapentry_handler(void *closure, const void *hd) {
265
- MessageHeader* msg = closure;
266
- const map_handlerdata_t* mapdata = hd;
267
- VALUE map_rb = DEREF(msg, mapdata->ofs, VALUE);
268
-
269
- map_parse_frame_t* frame = ALLOC(map_parse_frame_t);
270
- frame->map = map_rb;
271
-
272
- native_slot_init(mapdata->key_field_type, &frame->key_storage);
273
- native_slot_init(mapdata->value_field_type, &frame->value_storage);
274
-
275
- return frame;
276
- }
277
-
278
- // Handler to end a map entry: inserts the value defined during the message into
279
- // the map. This is the 'endmsg' handler on the map entry msgdef.
280
- static bool endmap_handler(void *closure, const void *hd, upb_status* s) {
281
- map_parse_frame_t* frame = closure;
282
- const map_handlerdata_t* mapdata = hd;
283
-
284
- VALUE key = native_slot_get(
285
- mapdata->key_field_type, Qnil,
286
- &frame->key_storage);
287
-
288
- VALUE value_field_typeclass = Qnil;
289
- VALUE value;
290
-
291
- if (mapdata->value_field_type == UPB_TYPE_MESSAGE ||
292
- mapdata->value_field_type == UPB_TYPE_ENUM) {
293
- value_field_typeclass = get_def_obj(mapdata->value_field_subdef);
294
- }
295
-
296
- value = native_slot_get(
297
- mapdata->value_field_type, value_field_typeclass,
298
- &frame->value_storage);
299
-
300
- Map_index_set(frame->map, key, value);
301
- xfree(frame);
302
-
303
- return true;
304
- }
305
-
306
- // Allocates a new map_handlerdata_t given the map entry message definition. If
307
- // the offset of the field within the parent message is also given, that is
308
- // added to the handler data as well. Note that this is called *twice* per map
309
- // field: once in the parent message handler setup when setting the startsubmsg
310
- // handler and once in the map entry message handler setup when setting the
311
- // key/value and endmsg handlers. The reason is that there is no easy way to
312
- // pass the handlerdata down to the sub-message handler setup.
313
- static map_handlerdata_t* new_map_handlerdata(
314
- size_t ofs,
315
- const upb_msgdef* mapentry_def,
316
- Descriptor* desc) {
317
- const upb_fielddef* key_field;
318
- const upb_fielddef* value_field;
319
- map_handlerdata_t* hd = ALLOC(map_handlerdata_t);
320
- hd->ofs = ofs;
321
- key_field = upb_msgdef_itof(mapentry_def, MAP_KEY_FIELD);
322
- assert(key_field != NULL);
323
- hd->key_field_type = upb_fielddef_type(key_field);
324
- value_field = upb_msgdef_itof(mapentry_def, MAP_VALUE_FIELD);
325
- assert(value_field != NULL);
326
- hd->value_field_type = upb_fielddef_type(value_field);
327
- hd->value_field_subdef = upb_fielddef_subdef(value_field);
328
-
329
- return hd;
330
- }
331
-
332
- // Handlers that set primitive values in oneofs.
333
- #define DEFINE_ONEOF_HANDLER(type, ctype) \
334
- static bool oneof##type##_handler(void *closure, const void *hd, \
335
- ctype val) { \
336
- const oneof_handlerdata_t *oneofdata = hd; \
337
- DEREF(closure, oneofdata->case_ofs, uint32_t) = \
338
- oneofdata->oneof_case_num; \
339
- DEREF(closure, oneofdata->ofs, ctype) = val; \
340
- return true; \
341
- }
342
-
343
- DEFINE_ONEOF_HANDLER(bool, bool)
344
- DEFINE_ONEOF_HANDLER(int32, int32_t)
345
- DEFINE_ONEOF_HANDLER(uint32, uint32_t)
346
- DEFINE_ONEOF_HANDLER(float, float)
347
- DEFINE_ONEOF_HANDLER(int64, int64_t)
348
- DEFINE_ONEOF_HANDLER(uint64, uint64_t)
349
- DEFINE_ONEOF_HANDLER(double, double)
350
-
351
- #undef DEFINE_ONEOF_HANDLER
352
-
353
- // Handlers for strings in a oneof.
354
- static void *oneofstr_handler(void *closure,
355
- const void *hd,
356
- size_t size_hint) {
357
- MessageHeader* msg = closure;
358
- const oneof_handlerdata_t *oneofdata = hd;
359
- VALUE str = rb_str_new2("");
360
- rb_enc_associate(str, kRubyStringUtf8Encoding);
361
- DEREF(msg, oneofdata->case_ofs, uint32_t) =
362
- oneofdata->oneof_case_num;
363
- DEREF(msg, oneofdata->ofs, VALUE) = str;
364
- return (void*)str;
365
- }
366
-
367
- static void *oneofbytes_handler(void *closure,
368
- const void *hd,
369
- size_t size_hint) {
370
- MessageHeader* msg = closure;
371
- const oneof_handlerdata_t *oneofdata = hd;
372
- VALUE str = rb_str_new2("");
373
- rb_enc_associate(str, kRubyString8bitEncoding);
374
- DEREF(msg, oneofdata->case_ofs, uint32_t) =
375
- oneofdata->oneof_case_num;
376
- DEREF(msg, oneofdata->ofs, VALUE) = str;
377
- return (void*)str;
378
- }
379
-
380
- static bool oneofstring_end_handler(void* closure, const void* hd) {
381
- MessageHeader* msg = closure;
382
- const oneof_handlerdata_t *oneofdata = hd;
383
- rb_obj_freeze(DEREF(msg, oneofdata->ofs, VALUE));
384
- return true;
385
- }
386
-
387
- // Handler for a submessage field in a oneof.
388
- static void *oneofsubmsg_handler(void *closure,
389
- const void *hd) {
390
- MessageHeader* msg = closure;
391
- const oneof_handlerdata_t *oneofdata = hd;
392
- uint32_t oldcase = DEREF(msg, oneofdata->case_ofs, uint32_t);
393
-
394
- VALUE subdesc =
395
- get_def_obj((void*)oneofdata->md);
396
- VALUE subklass = Descriptor_msgclass(subdesc);
397
- VALUE submsg_rb;
398
- MessageHeader* submsg;
399
-
400
- if (oldcase != oneofdata->oneof_case_num ||
401
- DEREF(msg, oneofdata->ofs, VALUE) == Qnil) {
402
- DEREF(msg, oneofdata->ofs, VALUE) =
403
- rb_class_new_instance(0, NULL, subklass);
404
- }
405
- // Set the oneof case *after* allocating the new class instance -- otherwise,
406
- // if the Ruby GC is invoked as part of a call into the VM, it might invoke
407
- // our mark routines, and our mark routines might see the case value
408
- // indicating a VALUE is present and expect a valid VALUE. See comment in
409
- // layout_set() for more detail: basically, the change to the value and the
410
- // case must be atomic w.r.t. the Ruby VM.
411
- DEREF(msg, oneofdata->case_ofs, uint32_t) =
412
- oneofdata->oneof_case_num;
413
-
414
- submsg_rb = DEREF(msg, oneofdata->ofs, VALUE);
415
- TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg);
416
- return submsg;
417
- }
418
-
419
- // Set up handlers for a repeated field.
420
- static void add_handlers_for_repeated_field(upb_handlers *h,
421
- const upb_fielddef *f,
422
- size_t offset) {
423
- upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
424
- upb_handlerattr_sethandlerdata(&attr, newhandlerdata(h, offset));
425
- upb_handlers_setstartseq(h, f, startseq_handler, &attr);
426
- upb_handlerattr_uninit(&attr);
427
-
428
- switch (upb_fielddef_type(f)) {
429
-
430
- #define SET_HANDLER(utype, ltype) \
431
- case utype: \
432
- upb_handlers_set##ltype(h, f, append##ltype##_handler, NULL); \
433
- break;
434
-
435
- SET_HANDLER(UPB_TYPE_BOOL, bool);
436
- SET_HANDLER(UPB_TYPE_INT32, int32);
437
- SET_HANDLER(UPB_TYPE_UINT32, uint32);
438
- SET_HANDLER(UPB_TYPE_ENUM, int32);
439
- SET_HANDLER(UPB_TYPE_FLOAT, float);
440
- SET_HANDLER(UPB_TYPE_INT64, int64);
441
- SET_HANDLER(UPB_TYPE_UINT64, uint64);
442
- SET_HANDLER(UPB_TYPE_DOUBLE, double);
443
-
444
- #undef SET_HANDLER
445
-
446
- case UPB_TYPE_STRING:
447
- case UPB_TYPE_BYTES: {
448
- bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES;
449
- upb_handlers_setstartstr(h, f, is_bytes ?
450
- appendbytes_handler : appendstr_handler,
451
- NULL);
452
- upb_handlers_setstring(h, f, stringdata_handler, NULL);
453
- upb_handlers_setendstr(h, f, appendstring_end_handler, NULL);
454
- break;
455
- }
456
- case UPB_TYPE_MESSAGE: {
457
- upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
458
- upb_handlerattr_sethandlerdata(&attr, newsubmsghandlerdata(h, 0, f));
459
- upb_handlers_setstartsubmsg(h, f, appendsubmsg_handler, &attr);
460
- upb_handlerattr_uninit(&attr);
461
- break;
462
- }
463
- }
464
- }
465
-
466
- // Set up handlers for a singular field.
467
- static void add_handlers_for_singular_field(upb_handlers *h,
468
- const upb_fielddef *f,
469
- size_t offset) {
470
- switch (upb_fielddef_type(f)) {
471
- case UPB_TYPE_BOOL:
472
- case UPB_TYPE_INT32:
473
- case UPB_TYPE_UINT32:
474
- case UPB_TYPE_ENUM:
475
- case UPB_TYPE_FLOAT:
476
- case UPB_TYPE_INT64:
477
- case UPB_TYPE_UINT64:
478
- case UPB_TYPE_DOUBLE:
479
- upb_shim_set(h, f, offset, -1);
480
- break;
481
- case UPB_TYPE_STRING:
482
- case UPB_TYPE_BYTES: {
483
- bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES;
484
- upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
485
- upb_handlerattr_sethandlerdata(&attr, newhandlerdata(h, offset));
486
- upb_handlers_setstartstr(h, f,
487
- is_bytes ? bytes_handler : str_handler,
488
- &attr);
489
- upb_handlers_setstring(h, f, stringdata_handler, &attr);
490
- upb_handlers_setendstr(h, f, stringdata_end_handler, &attr);
491
- upb_handlerattr_uninit(&attr);
492
- break;
493
- }
494
- case UPB_TYPE_MESSAGE: {
495
- upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
496
- upb_handlerattr_sethandlerdata(&attr, newsubmsghandlerdata(h, offset, f));
497
- upb_handlers_setstartsubmsg(h, f, submsg_handler, &attr);
498
- upb_handlerattr_uninit(&attr);
499
- break;
500
- }
501
- }
502
- }
503
-
504
- // Adds handlers to a map field.
505
- static void add_handlers_for_mapfield(upb_handlers* h,
506
- const upb_fielddef* fielddef,
507
- size_t offset,
508
- Descriptor* desc) {
509
- const upb_msgdef* map_msgdef = upb_fielddef_msgsubdef(fielddef);
510
- map_handlerdata_t* hd = new_map_handlerdata(offset, map_msgdef, desc);
511
- upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
512
-
513
- upb_handlers_addcleanup(h, hd, xfree);
514
- upb_handlerattr_sethandlerdata(&attr, hd);
515
- upb_handlers_setstartsubmsg(h, fielddef, startmapentry_handler, &attr);
516
- upb_handlerattr_uninit(&attr);
517
- }
518
-
519
- // Adds handlers to a map-entry msgdef.
520
- static void add_handlers_for_mapentry(const upb_msgdef* msgdef,
521
- upb_handlers* h,
522
- Descriptor* desc) {
523
- const upb_fielddef* key_field = map_entry_key(msgdef);
524
- const upb_fielddef* value_field = map_entry_value(msgdef);
525
- map_handlerdata_t* hd = new_map_handlerdata(0, msgdef, desc);
526
- upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
527
-
528
- upb_handlers_addcleanup(h, hd, xfree);
529
- upb_handlerattr_sethandlerdata(&attr, hd);
530
- upb_handlers_setendmsg(h, endmap_handler, &attr);
531
-
532
- add_handlers_for_singular_field(
533
- h, key_field,
534
- offsetof(map_parse_frame_t, key_storage));
535
- add_handlers_for_singular_field(
536
- h, value_field,
537
- offsetof(map_parse_frame_t, value_storage));
538
- }
539
-
540
- // Set up handlers for a oneof field.
541
- static void add_handlers_for_oneof_field(upb_handlers *h,
542
- const upb_fielddef *f,
543
- size_t offset,
544
- size_t oneof_case_offset) {
545
-
546
- upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
547
- upb_handlerattr_sethandlerdata(
548
- &attr, newoneofhandlerdata(h, offset, oneof_case_offset, f));
549
-
550
- switch (upb_fielddef_type(f)) {
551
-
552
- #define SET_HANDLER(utype, ltype) \
553
- case utype: \
554
- upb_handlers_set##ltype(h, f, oneof##ltype##_handler, &attr); \
555
- break;
556
-
557
- SET_HANDLER(UPB_TYPE_BOOL, bool);
558
- SET_HANDLER(UPB_TYPE_INT32, int32);
559
- SET_HANDLER(UPB_TYPE_UINT32, uint32);
560
- SET_HANDLER(UPB_TYPE_ENUM, int32);
561
- SET_HANDLER(UPB_TYPE_FLOAT, float);
562
- SET_HANDLER(UPB_TYPE_INT64, int64);
563
- SET_HANDLER(UPB_TYPE_UINT64, uint64);
564
- SET_HANDLER(UPB_TYPE_DOUBLE, double);
565
-
566
- #undef SET_HANDLER
567
-
568
- case UPB_TYPE_STRING:
569
- case UPB_TYPE_BYTES: {
570
- bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES;
571
- upb_handlers_setstartstr(h, f, is_bytes ?
572
- oneofbytes_handler : oneofstr_handler,
573
- &attr);
574
- upb_handlers_setstring(h, f, stringdata_handler, NULL);
575
- upb_handlers_setendstr(h, f, oneofstring_end_handler, &attr);
576
- break;
577
- }
578
- case UPB_TYPE_MESSAGE: {
579
- upb_handlers_setstartsubmsg(h, f, oneofsubmsg_handler, &attr);
580
- break;
581
- }
582
- }
583
-
584
- upb_handlerattr_uninit(&attr);
585
- }
586
-
587
-
588
- static void add_handlers_for_message(const void *closure, upb_handlers *h) {
589
- const upb_msgdef* msgdef = upb_handlers_msgdef(h);
590
- Descriptor* desc = ruby_to_Descriptor(get_def_obj((void*)msgdef));
591
- upb_msg_field_iter i;
592
-
593
- // If this is a mapentry message type, set up a special set of handlers and
594
- // bail out of the normal (user-defined) message type handling.
595
- if (upb_msgdef_mapentry(msgdef)) {
596
- add_handlers_for_mapentry(msgdef, h, desc);
597
- return;
598
- }
599
-
600
- // Ensure layout exists. We may be invoked to create handlers for a given
601
- // message if we are included as a submsg of another message type before our
602
- // class is actually built, so to work around this, we just create the layout
603
- // (and handlers, in the class-building function) on-demand.
604
- if (desc->layout == NULL) {
605
- desc->layout = create_layout(desc->msgdef);
606
- }
607
-
608
- for (upb_msg_field_begin(&i, desc->msgdef);
609
- !upb_msg_field_done(&i);
610
- upb_msg_field_next(&i)) {
611
- const upb_fielddef *f = upb_msg_iter_field(&i);
612
- size_t offset = desc->layout->fields[upb_fielddef_index(f)].offset +
613
- sizeof(MessageHeader);
614
-
615
- if (upb_fielddef_containingoneof(f)) {
616
- size_t oneof_case_offset =
617
- desc->layout->fields[upb_fielddef_index(f)].case_offset +
618
- sizeof(MessageHeader);
619
- add_handlers_for_oneof_field(h, f, offset, oneof_case_offset);
620
- } else if (is_map_field(f)) {
621
- add_handlers_for_mapfield(h, f, offset, desc);
622
- } else if (upb_fielddef_isseq(f)) {
623
- add_handlers_for_repeated_field(h, f, offset);
624
- } else {
625
- add_handlers_for_singular_field(h, f, offset);
626
- }
627
- }
628
- }
629
-
630
- // Creates upb handlers for populating a message.
631
- static const upb_handlers *new_fill_handlers(Descriptor* desc,
632
- const void* owner) {
633
- // TODO(cfallin, haberman): once upb gets a caching/memoization layer for
634
- // handlers, reuse subdef handlers so that e.g. if we already parse
635
- // B-with-field-of-type-C, we don't have to rebuild the whole hierarchy to
636
- // parse A-with-field-of-type-B-with-field-of-type-C.
637
- return upb_handlers_newfrozen(desc->msgdef, owner,
638
- add_handlers_for_message, NULL);
639
- }
640
-
641
- // Constructs the handlers for filling a message's data into an in-memory
642
- // object.
643
- const upb_handlers* get_fill_handlers(Descriptor* desc) {
644
- if (!desc->fill_handlers) {
645
- desc->fill_handlers =
646
- new_fill_handlers(desc, &desc->fill_handlers);
647
- }
648
- return desc->fill_handlers;
649
- }
650
-
651
- // Constructs the upb decoder method for parsing messages of this type.
652
- // This is called from the message class creation code.
653
- const upb_pbdecodermethod *new_fillmsg_decodermethod(Descriptor* desc,
654
- const void* owner) {
655
- const upb_handlers* handlers = get_fill_handlers(desc);
656
- upb_pbdecodermethodopts opts;
657
- upb_pbdecodermethodopts_init(&opts, handlers);
658
-
659
- return upb_pbdecodermethod_new(&opts, owner);
660
- }
661
-
662
- static const upb_pbdecodermethod *msgdef_decodermethod(Descriptor* desc) {
663
- if (desc->fill_method == NULL) {
664
- desc->fill_method = new_fillmsg_decodermethod(
665
- desc, &desc->fill_method);
666
- }
667
- return desc->fill_method;
668
- }
669
-
670
- static const upb_json_parsermethod *msgdef_jsonparsermethod(Descriptor* desc) {
671
- if (desc->json_fill_method == NULL) {
672
- desc->json_fill_method =
673
- upb_json_parsermethod_new(desc->msgdef, &desc->json_fill_method);
674
- }
675
- return desc->json_fill_method;
676
- }
677
-
678
-
679
- // Stack-allocated context during an encode/decode operation. Contains the upb
680
- // environment and its stack-based allocator, an initial buffer for allocations
681
- // to avoid malloc() when possible, and a template for Ruby exception messages
682
- // if any error occurs.
683
- #define STACK_ENV_STACKBYTES 4096
684
- typedef struct {
685
- upb_env env;
686
- const char* ruby_error_template;
687
- char allocbuf[STACK_ENV_STACKBYTES];
688
- } stackenv;
689
-
690
- static void stackenv_init(stackenv* se, const char* errmsg);
691
- static void stackenv_uninit(stackenv* se);
692
-
693
- // Callback invoked by upb if any error occurs during parsing or serialization.
694
- static bool env_error_func(void* ud, const upb_status* status) {
695
- stackenv* se = ud;
696
- // Free the env -- rb_raise will longjmp up the stack past the encode/decode
697
- // function so it would not otherwise have been freed.
698
- stackenv_uninit(se);
699
-
700
- // TODO(haberman): have a way to verify that this is actually a parse error,
701
- // instead of just throwing "parse error" unconditionally.
702
- rb_raise(cParseError, se->ruby_error_template, upb_status_errmsg(status));
703
- // Never reached: rb_raise() always longjmp()s up the stack, past all of our
704
- // code, back to Ruby.
705
- return false;
706
- }
707
-
708
- static void stackenv_init(stackenv* se, const char* errmsg) {
709
- se->ruby_error_template = errmsg;
710
- upb_env_init2(&se->env, se->allocbuf, sizeof(se->allocbuf), NULL);
711
- upb_env_seterrorfunc(&se->env, env_error_func, se);
712
- }
713
-
714
- static void stackenv_uninit(stackenv* se) {
715
- upb_env_uninit(&se->env);
716
- }
717
-
718
- /*
719
- * call-seq:
720
- * MessageClass.decode(data) => message
721
- *
722
- * Decodes the given data (as a string containing bytes in protocol buffers wire
723
- * format) under the interpretration given by this message class's definition
724
- * and returns a message object with the corresponding field values.
725
- */
726
- VALUE Message_decode(VALUE klass, VALUE data) {
727
- VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
728
- Descriptor* desc = ruby_to_Descriptor(descriptor);
729
- VALUE msgklass = Descriptor_msgclass(descriptor);
730
- VALUE msg_rb;
731
- MessageHeader* msg;
732
-
733
- if (TYPE(data) != T_STRING) {
734
- rb_raise(rb_eArgError, "Expected string for binary protobuf data.");
735
- }
736
-
737
- msg_rb = rb_class_new_instance(0, NULL, msgklass);
738
- TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
739
-
740
- {
741
- const upb_pbdecodermethod* method = msgdef_decodermethod(desc);
742
- const upb_handlers* h = upb_pbdecodermethod_desthandlers(method);
743
- stackenv se;
744
- upb_sink sink;
745
- upb_pbdecoder* decoder;
746
- stackenv_init(&se, "Error occurred during parsing: %s");
747
-
748
- upb_sink_reset(&sink, h, msg);
749
- decoder = upb_pbdecoder_create(&se.env, method, &sink);
750
- upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data),
751
- upb_pbdecoder_input(decoder));
752
-
753
- stackenv_uninit(&se);
754
- }
755
-
756
- return msg_rb;
757
- }
758
-
759
- /*
760
- * call-seq:
761
- * MessageClass.decode_json(data) => message
762
- *
763
- * Decodes the given data (as a string containing bytes in protocol buffers wire
764
- * format) under the interpretration given by this message class's definition
765
- * and returns a message object with the corresponding field values.
766
- */
767
- VALUE Message_decode_json(VALUE klass, VALUE data) {
768
- VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
769
- Descriptor* desc = ruby_to_Descriptor(descriptor);
770
- VALUE msgklass = Descriptor_msgclass(descriptor);
771
- VALUE msg_rb;
772
- MessageHeader* msg;
773
-
774
- if (TYPE(data) != T_STRING) {
775
- rb_raise(rb_eArgError, "Expected string for JSON data.");
776
- }
777
- // TODO(cfallin): Check and respect string encoding. If not UTF-8, we need to
778
- // convert, because string handlers pass data directly to message string
779
- // fields.
780
-
781
- msg_rb = rb_class_new_instance(0, NULL, msgklass);
782
- TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
783
-
784
- {
785
- const upb_json_parsermethod* method = msgdef_jsonparsermethod(desc);
786
- stackenv se;
787
- upb_sink sink;
788
- upb_json_parser* parser;
789
- stackenv_init(&se, "Error occurred during parsing: %s");
790
-
791
- upb_sink_reset(&sink, get_fill_handlers(desc), msg);
792
- parser = upb_json_parser_create(&se.env, method, &sink);
793
- upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data),
794
- upb_json_parser_input(parser));
795
-
796
- stackenv_uninit(&se);
797
- }
798
-
799
- return msg_rb;
800
- }
801
-
802
- // -----------------------------------------------------------------------------
803
- // Serializing.
804
- // -----------------------------------------------------------------------------
805
- //
806
- // The code below also comes from upb's prototype Ruby binding, developed by
807
- // haberman@.
808
-
809
- /* stringsink *****************************************************************/
810
-
811
- // This should probably be factored into a common upb component.
812
-
813
- typedef struct {
814
- upb_byteshandler handler;
815
- upb_bytessink sink;
816
- char *ptr;
817
- size_t len, size;
818
- } stringsink;
819
-
820
- static void *stringsink_start(void *_sink, const void *hd, size_t size_hint) {
821
- stringsink *sink = _sink;
822
- sink->len = 0;
823
- return sink;
824
- }
825
-
826
- static size_t stringsink_string(void *_sink, const void *hd, const char *ptr,
827
- size_t len, const upb_bufhandle *handle) {
828
- stringsink *sink = _sink;
829
- size_t new_size = sink->size;
830
-
831
- UPB_UNUSED(hd);
832
- UPB_UNUSED(handle);
833
-
834
- while (sink->len + len > new_size) {
835
- new_size *= 2;
836
- }
837
-
838
- if (new_size != sink->size) {
839
- sink->ptr = realloc(sink->ptr, new_size);
840
- sink->size = new_size;
841
- }
842
-
843
- memcpy(sink->ptr + sink->len, ptr, len);
844
- sink->len += len;
845
-
846
- return len;
847
- }
848
-
849
- void stringsink_init(stringsink *sink) {
850
- upb_byteshandler_init(&sink->handler);
851
- upb_byteshandler_setstartstr(&sink->handler, stringsink_start, NULL);
852
- upb_byteshandler_setstring(&sink->handler, stringsink_string, NULL);
853
-
854
- upb_bytessink_reset(&sink->sink, &sink->handler, sink);
855
-
856
- sink->size = 32;
857
- sink->ptr = malloc(sink->size);
858
- sink->len = 0;
859
- }
860
-
861
- void stringsink_uninit(stringsink *sink) {
862
- free(sink->ptr);
863
- }
864
-
865
- /* msgvisitor *****************************************************************/
866
-
867
- // TODO: If/when we support proto2 semantics in addition to the current proto3
868
- // semantics, which means that we have true field presence, we will want to
869
- // modify msgvisitor so that it emits all present fields rather than all
870
- // non-default-value fields.
871
- //
872
- // Likewise, when implementing JSON serialization, we may need to have a
873
- // 'verbose' mode that outputs all fields and a 'concise' mode that outputs only
874
- // those with non-default values.
875
-
876
- static void putmsg(VALUE msg, const Descriptor* desc,
877
- upb_sink *sink, int depth);
878
-
879
- static upb_selector_t getsel(const upb_fielddef *f, upb_handlertype_t type) {
880
- upb_selector_t ret;
881
- bool ok = upb_handlers_getselector(f, type, &ret);
882
- UPB_ASSERT_VAR(ok, ok);
883
- return ret;
884
- }
885
-
886
- static void putstr(VALUE str, const upb_fielddef *f, upb_sink *sink) {
887
- upb_sink subsink;
888
-
889
- if (str == Qnil) return;
890
-
891
- assert(BUILTIN_TYPE(str) == RUBY_T_STRING);
892
-
893
- // We should be guaranteed that the string has the correct encoding because
894
- // we ensured this at assignment time and then froze the string.
895
- if (upb_fielddef_type(f) == UPB_TYPE_STRING) {
896
- assert(rb_enc_from_index(ENCODING_GET(value)) == kRubyStringUtf8Encoding);
897
- } else {
898
- assert(rb_enc_from_index(ENCODING_GET(value)) == kRubyString8bitEncoding);
899
- }
900
-
901
- upb_sink_startstr(sink, getsel(f, UPB_HANDLER_STARTSTR), RSTRING_LEN(str),
902
- &subsink);
903
- upb_sink_putstring(&subsink, getsel(f, UPB_HANDLER_STRING), RSTRING_PTR(str),
904
- RSTRING_LEN(str), NULL);
905
- upb_sink_endstr(sink, getsel(f, UPB_HANDLER_ENDSTR));
906
- }
907
-
908
- static void putsubmsg(VALUE submsg, const upb_fielddef *f, upb_sink *sink,
909
- int depth) {
910
- upb_sink subsink;
911
- VALUE descriptor;
912
- Descriptor* subdesc;
913
-
914
- if (submsg == Qnil) return;
915
-
916
- descriptor = rb_ivar_get(submsg, descriptor_instancevar_interned);
917
- subdesc = ruby_to_Descriptor(descriptor);
918
-
919
- upb_sink_startsubmsg(sink, getsel(f, UPB_HANDLER_STARTSUBMSG), &subsink);
920
- putmsg(submsg, subdesc, &subsink, depth + 1);
921
- upb_sink_endsubmsg(sink, getsel(f, UPB_HANDLER_ENDSUBMSG));
922
- }
923
-
924
- static void putary(VALUE ary, const upb_fielddef *f, upb_sink *sink,
925
- int depth) {
926
- upb_sink subsink;
927
- upb_fieldtype_t type = upb_fielddef_type(f);
928
- upb_selector_t sel = 0;
929
- int size;
930
-
931
- if (ary == Qnil) return;
932
-
933
- upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);
934
-
935
- if (upb_fielddef_isprimitive(f)) {
936
- sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
937
- }
938
-
939
- size = NUM2INT(RepeatedField_length(ary));
940
- for (int i = 0; i < size; i++) {
941
- void* memory = RepeatedField_index_native(ary, i);
942
- switch (type) {
943
- #define T(upbtypeconst, upbtype, ctype) \
944
- case upbtypeconst: \
945
- upb_sink_put##upbtype(&subsink, sel, *((ctype *)memory)); \
946
- break;
947
-
948
- T(UPB_TYPE_FLOAT, float, float)
949
- T(UPB_TYPE_DOUBLE, double, double)
950
- T(UPB_TYPE_BOOL, bool, int8_t)
951
- case UPB_TYPE_ENUM:
952
- T(UPB_TYPE_INT32, int32, int32_t)
953
- T(UPB_TYPE_UINT32, uint32, uint32_t)
954
- T(UPB_TYPE_INT64, int64, int64_t)
955
- T(UPB_TYPE_UINT64, uint64, uint64_t)
956
-
957
- case UPB_TYPE_STRING:
958
- case UPB_TYPE_BYTES:
959
- putstr(*((VALUE *)memory), f, &subsink);
960
- break;
961
- case UPB_TYPE_MESSAGE:
962
- putsubmsg(*((VALUE *)memory), f, &subsink, depth);
963
- break;
964
-
965
- #undef T
966
-
967
- }
968
- }
969
- upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ));
970
- }
971
-
972
- static void put_ruby_value(VALUE value,
973
- const upb_fielddef *f,
974
- VALUE type_class,
975
- int depth,
976
- upb_sink *sink) {
977
- upb_selector_t sel = 0;
978
- if (upb_fielddef_isprimitive(f)) {
979
- sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
980
- }
981
-
982
- switch (upb_fielddef_type(f)) {
983
- case UPB_TYPE_INT32:
984
- upb_sink_putint32(sink, sel, NUM2INT(value));
985
- break;
986
- case UPB_TYPE_INT64:
987
- upb_sink_putint64(sink, sel, NUM2LL(value));
988
- break;
989
- case UPB_TYPE_UINT32:
990
- upb_sink_putuint32(sink, sel, NUM2UINT(value));
991
- break;
992
- case UPB_TYPE_UINT64:
993
- upb_sink_putuint64(sink, sel, NUM2ULL(value));
994
- break;
995
- case UPB_TYPE_FLOAT:
996
- upb_sink_putfloat(sink, sel, NUM2DBL(value));
997
- break;
998
- case UPB_TYPE_DOUBLE:
999
- upb_sink_putdouble(sink, sel, NUM2DBL(value));
1000
- break;
1001
- case UPB_TYPE_ENUM: {
1002
- if (TYPE(value) == T_SYMBOL) {
1003
- value = rb_funcall(type_class, rb_intern("resolve"), 1, value);
1004
- }
1005
- upb_sink_putint32(sink, sel, NUM2INT(value));
1006
- break;
1007
- }
1008
- case UPB_TYPE_BOOL:
1009
- upb_sink_putbool(sink, sel, value == Qtrue);
1010
- break;
1011
- case UPB_TYPE_STRING:
1012
- case UPB_TYPE_BYTES:
1013
- putstr(value, f, sink);
1014
- break;
1015
- case UPB_TYPE_MESSAGE:
1016
- putsubmsg(value, f, sink, depth);
1017
- }
1018
- }
1019
-
1020
- static void putmap(VALUE map, const upb_fielddef *f, upb_sink *sink,
1021
- int depth) {
1022
- Map* self;
1023
- upb_sink subsink;
1024
- const upb_fielddef* key_field;
1025
- const upb_fielddef* value_field;
1026
- Map_iter it;
1027
-
1028
- if (map == Qnil) return;
1029
- self = ruby_to_Map(map);
1030
-
1031
- upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);
1032
-
1033
- assert(upb_fielddef_type(f) == UPB_TYPE_MESSAGE);
1034
- key_field = map_field_key(f);
1035
- value_field = map_field_value(f);
1036
-
1037
- for (Map_begin(map, &it); !Map_done(&it); Map_next(&it)) {
1038
- VALUE key = Map_iter_key(&it);
1039
- VALUE value = Map_iter_value(&it);
1040
- upb_status status;
1041
-
1042
- upb_sink entry_sink;
1043
- upb_sink_startsubmsg(&subsink, getsel(f, UPB_HANDLER_STARTSUBMSG),
1044
- &entry_sink);
1045
- upb_sink_startmsg(&entry_sink);
1046
-
1047
- put_ruby_value(key, key_field, Qnil, depth + 1, &entry_sink);
1048
- put_ruby_value(value, value_field, self->value_type_class, depth + 1,
1049
- &entry_sink);
1050
-
1051
- upb_sink_endmsg(&entry_sink, &status);
1052
- upb_sink_endsubmsg(&subsink, getsel(f, UPB_HANDLER_ENDSUBMSG));
1053
- }
1054
-
1055
- upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ));
1056
- }
1057
-
1058
- static void putmsg(VALUE msg_rb, const Descriptor* desc,
1059
- upb_sink *sink, int depth) {
1060
- MessageHeader* msg;
1061
- upb_msg_field_iter i;
1062
- upb_status status;
1063
-
1064
- upb_sink_startmsg(sink);
1065
-
1066
- // Protect against cycles (possible because users may freely reassign message
1067
- // and repeated fields) by imposing a maximum recursion depth.
1068
- if (depth > ENCODE_MAX_NESTING) {
1069
- rb_raise(rb_eRuntimeError,
1070
- "Maximum recursion depth exceeded during encoding.");
1071
- }
1072
-
1073
- TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
1074
-
1075
- for (upb_msg_field_begin(&i, desc->msgdef);
1076
- !upb_msg_field_done(&i);
1077
- upb_msg_field_next(&i)) {
1078
- upb_fielddef *f = upb_msg_iter_field(&i);
1079
- bool is_matching_oneof = false;
1080
- uint32_t offset =
1081
- desc->layout->fields[upb_fielddef_index(f)].offset +
1082
- sizeof(MessageHeader);
1083
-
1084
- if (upb_fielddef_containingoneof(f)) {
1085
- uint32_t oneof_case_offset =
1086
- desc->layout->fields[upb_fielddef_index(f)].case_offset +
1087
- sizeof(MessageHeader);
1088
- // For a oneof, check that this field is actually present -- skip all the
1089
- // below if not.
1090
- if (DEREF(msg, oneof_case_offset, uint32_t) !=
1091
- upb_fielddef_number(f)) {
1092
- continue;
1093
- }
1094
- // Otherwise, fall through to the appropriate singular-field handler
1095
- // below.
1096
- is_matching_oneof = true;
1097
- }
1098
-
1099
- if (is_map_field(f)) {
1100
- VALUE map = DEREF(msg, offset, VALUE);
1101
- if (map != Qnil) {
1102
- putmap(map, f, sink, depth);
1103
- }
1104
- } else if (upb_fielddef_isseq(f)) {
1105
- VALUE ary = DEREF(msg, offset, VALUE);
1106
- if (ary != Qnil) {
1107
- putary(ary, f, sink, depth);
1108
- }
1109
- } else if (upb_fielddef_isstring(f)) {
1110
- VALUE str = DEREF(msg, offset, VALUE);
1111
- if (is_matching_oneof || RSTRING_LEN(str) > 0) {
1112
- putstr(str, f, sink);
1113
- }
1114
- } else if (upb_fielddef_issubmsg(f)) {
1115
- putsubmsg(DEREF(msg, offset, VALUE), f, sink, depth);
1116
- } else {
1117
- upb_selector_t sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
1118
-
1119
- #define T(upbtypeconst, upbtype, ctype, default_value) \
1120
- case upbtypeconst: { \
1121
- ctype value = DEREF(msg, offset, ctype); \
1122
- if (is_matching_oneof || value != default_value) { \
1123
- upb_sink_put##upbtype(sink, sel, value); \
1124
- } \
1125
- } \
1126
- break;
1127
-
1128
- switch (upb_fielddef_type(f)) {
1129
- T(UPB_TYPE_FLOAT, float, float, 0.0)
1130
- T(UPB_TYPE_DOUBLE, double, double, 0.0)
1131
- T(UPB_TYPE_BOOL, bool, uint8_t, 0)
1132
- case UPB_TYPE_ENUM:
1133
- T(UPB_TYPE_INT32, int32, int32_t, 0)
1134
- T(UPB_TYPE_UINT32, uint32, uint32_t, 0)
1135
- T(UPB_TYPE_INT64, int64, int64_t, 0)
1136
- T(UPB_TYPE_UINT64, uint64, uint64_t, 0)
1137
-
1138
- case UPB_TYPE_STRING:
1139
- case UPB_TYPE_BYTES:
1140
- case UPB_TYPE_MESSAGE: rb_raise(rb_eRuntimeError, "Internal error.");
1141
- }
1142
-
1143
- #undef T
1144
-
1145
- }
1146
- }
1147
-
1148
- upb_sink_endmsg(sink, &status);
1149
- }
1150
-
1151
- static const upb_handlers* msgdef_pb_serialize_handlers(Descriptor* desc) {
1152
- if (desc->pb_serialize_handlers == NULL) {
1153
- desc->pb_serialize_handlers =
1154
- upb_pb_encoder_newhandlers(desc->msgdef, &desc->pb_serialize_handlers);
1155
- }
1156
- return desc->pb_serialize_handlers;
1157
- }
1158
-
1159
- static const upb_handlers* msgdef_json_serialize_handlers(
1160
- Descriptor* desc, bool preserve_proto_fieldnames) {
1161
- if (preserve_proto_fieldnames) {
1162
- if (desc->json_serialize_handlers == NULL) {
1163
- desc->json_serialize_handlers =
1164
- upb_json_printer_newhandlers(
1165
- desc->msgdef, true, &desc->json_serialize_handlers);
1166
- }
1167
- return desc->json_serialize_handlers;
1168
- } else {
1169
- if (desc->json_serialize_handlers_preserve == NULL) {
1170
- desc->json_serialize_handlers_preserve =
1171
- upb_json_printer_newhandlers(
1172
- desc->msgdef, false, &desc->json_serialize_handlers_preserve);
1173
- }
1174
- return desc->json_serialize_handlers_preserve;
1175
- }
1176
- }
1177
-
1178
- /*
1179
- * call-seq:
1180
- * MessageClass.encode(msg) => bytes
1181
- *
1182
- * Encodes the given message object to its serialized form in protocol buffers
1183
- * wire format.
1184
- */
1185
- VALUE Message_encode(VALUE klass, VALUE msg_rb) {
1186
- VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
1187
- Descriptor* desc = ruby_to_Descriptor(descriptor);
1188
-
1189
- stringsink sink;
1190
- stringsink_init(&sink);
1191
-
1192
- {
1193
- const upb_handlers* serialize_handlers =
1194
- msgdef_pb_serialize_handlers(desc);
1195
-
1196
- stackenv se;
1197
- upb_pb_encoder* encoder;
1198
- VALUE ret;
1199
-
1200
- stackenv_init(&se, "Error occurred during encoding: %s");
1201
- encoder = upb_pb_encoder_create(&se.env, serialize_handlers, &sink.sink);
1202
-
1203
- putmsg(msg_rb, desc, upb_pb_encoder_input(encoder), 0);
1204
-
1205
- ret = rb_str_new(sink.ptr, sink.len);
1206
-
1207
- stackenv_uninit(&se);
1208
- stringsink_uninit(&sink);
1209
-
1210
- return ret;
1211
- }
1212
- }
1213
-
1214
- /*
1215
- * call-seq:
1216
- * MessageClass.encode_json(msg) => json_string
1217
- *
1218
- * Encodes the given message object into its serialized JSON representation.
1219
- */
1220
- VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
1221
- VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
1222
- Descriptor* desc = ruby_to_Descriptor(descriptor);
1223
- VALUE msg_rb;
1224
- VALUE preserve_proto_fieldnames = Qfalse;
1225
- stringsink sink;
1226
-
1227
- if (argc < 1 || argc > 2) {
1228
- rb_raise(rb_eArgError, "Expected 1 or 2 arguments.");
1229
- }
1230
-
1231
- msg_rb = argv[0];
1232
-
1233
- if (argc == 2) {
1234
- VALUE hash_args = argv[1];
1235
- if (TYPE(hash_args) != T_HASH) {
1236
- rb_raise(rb_eArgError, "Expected hash arguments.");
1237
- }
1238
- preserve_proto_fieldnames = rb_hash_lookup2(
1239
- hash_args, ID2SYM(rb_intern("preserve_proto_fieldnames")), Qfalse);
1240
- }
1241
-
1242
- stringsink_init(&sink);
1243
-
1244
- {
1245
- const upb_handlers* serialize_handlers =
1246
- msgdef_json_serialize_handlers(desc, RTEST(preserve_proto_fieldnames));
1247
- upb_json_printer* printer;
1248
- stackenv se;
1249
- VALUE ret;
1250
-
1251
- stackenv_init(&se, "Error occurred during encoding: %s");
1252
- printer = upb_json_printer_create(&se.env, serialize_handlers, &sink.sink);
1253
-
1254
- putmsg(msg_rb, desc, upb_json_printer_input(printer), 0);
1255
-
1256
- ret = rb_enc_str_new(sink.ptr, sink.len, rb_utf8_encoding());
1257
-
1258
- stackenv_uninit(&se);
1259
- stringsink_uninit(&sink);
1260
-
1261
- return ret;
1262
- }
1263
- }
1264
-