google-protobuf-z 3.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,1019 @@
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
+ #include <math.h>
34
+
35
+ #include <ruby/encoding.h>
36
+
37
+ // -----------------------------------------------------------------------------
38
+ // Ruby <-> native slot management.
39
+ // -----------------------------------------------------------------------------
40
+
41
+ #define CHARPTR_AT(msg, ofs) ((char*)msg + ofs)
42
+ #define DEREF_OFFSET(msg, ofs, type) *(type*)CHARPTR_AT(msg, ofs)
43
+ #define DEREF(memory, type) *(type*)(memory)
44
+
45
+ size_t native_slot_size(upb_fieldtype_t type) {
46
+ switch (type) {
47
+ case UPB_TYPE_FLOAT: return 4;
48
+ case UPB_TYPE_DOUBLE: return 8;
49
+ case UPB_TYPE_BOOL: return 1;
50
+ case UPB_TYPE_STRING: return sizeof(VALUE);
51
+ case UPB_TYPE_BYTES: return sizeof(VALUE);
52
+ case UPB_TYPE_MESSAGE: return sizeof(VALUE);
53
+ case UPB_TYPE_ENUM: return 4;
54
+ case UPB_TYPE_INT32: return 4;
55
+ case UPB_TYPE_INT64: return 8;
56
+ case UPB_TYPE_UINT32: return 4;
57
+ case UPB_TYPE_UINT64: return 8;
58
+ default: return 0;
59
+ }
60
+ }
61
+
62
+ static bool is_ruby_num(VALUE value) {
63
+ return (TYPE(value) == T_FLOAT ||
64
+ TYPE(value) == T_FIXNUM ||
65
+ TYPE(value) == T_BIGNUM);
66
+ }
67
+
68
+ void native_slot_check_int_range_precision(upb_fieldtype_t type, VALUE val) {
69
+ if (!is_ruby_num(val)) {
70
+ rb_raise(cTypeError, "Expected number type for integral field.");
71
+ }
72
+
73
+ // NUM2{INT,UINT,LL,ULL} macros do the appropriate range checks on upper
74
+ // bound; we just need to do precision checks (i.e., disallow rounding) and
75
+ // check for < 0 on unsigned types.
76
+ if (TYPE(val) == T_FLOAT) {
77
+ double dbl_val = NUM2DBL(val);
78
+ if (floor(dbl_val) != dbl_val) {
79
+ rb_raise(rb_eRangeError,
80
+ "Non-integral floating point value assigned to integer field.");
81
+ }
82
+ }
83
+ if (type == UPB_TYPE_UINT32 || type == UPB_TYPE_UINT64) {
84
+ if (NUM2DBL(val) < 0) {
85
+ rb_raise(rb_eRangeError,
86
+ "Assigning negative value to unsigned integer field.");
87
+ }
88
+ }
89
+ }
90
+
91
+ VALUE native_slot_encode_and_freeze_string(upb_fieldtype_t type, VALUE value) {
92
+ rb_encoding* desired_encoding = (type == UPB_TYPE_STRING) ?
93
+ kRubyStringUtf8Encoding : kRubyString8bitEncoding;
94
+ VALUE desired_encoding_value = rb_enc_from_encoding(desired_encoding);
95
+
96
+ // Note: this will not duplicate underlying string data unless necessary.
97
+ value = rb_str_encode(value, desired_encoding_value, 0, Qnil);
98
+
99
+ if (type == UPB_TYPE_STRING &&
100
+ rb_enc_str_coderange(value) == ENC_CODERANGE_BROKEN) {
101
+ rb_raise(rb_eEncodingError, "String is invalid UTF-8");
102
+ }
103
+
104
+ // Ensure the data remains valid. Since we called #encode a moment ago,
105
+ // this does not freeze the string the user assigned.
106
+ rb_obj_freeze(value);
107
+
108
+ return value;
109
+ }
110
+
111
+ void native_slot_set(upb_fieldtype_t type, VALUE type_class,
112
+ void* memory, VALUE value) {
113
+ native_slot_set_value_and_case(type, type_class, memory, value, NULL, 0);
114
+ }
115
+
116
+ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
117
+ void* memory, VALUE value,
118
+ uint32_t* case_memory,
119
+ uint32_t case_number) {
120
+ // Note that in order to atomically change the value in memory and the case
121
+ // value (w.r.t. Ruby VM calls), we must set the value at |memory| only after
122
+ // all Ruby VM calls are complete. The case is then set at the bottom of this
123
+ // function.
124
+ switch (type) {
125
+ case UPB_TYPE_FLOAT:
126
+ if (!is_ruby_num(value)) {
127
+ rb_raise(cTypeError, "Expected number type for float field.");
128
+ }
129
+ DEREF(memory, float) = NUM2DBL(value);
130
+ break;
131
+ case UPB_TYPE_DOUBLE:
132
+ if (!is_ruby_num(value)) {
133
+ rb_raise(cTypeError, "Expected number type for double field.");
134
+ }
135
+ DEREF(memory, double) = NUM2DBL(value);
136
+ break;
137
+ case UPB_TYPE_BOOL: {
138
+ int8_t val = -1;
139
+ if (value == Qtrue) {
140
+ val = 1;
141
+ } else if (value == Qfalse) {
142
+ val = 0;
143
+ } else {
144
+ rb_raise(cTypeError, "Invalid argument for boolean field.");
145
+ }
146
+ DEREF(memory, int8_t) = val;
147
+ break;
148
+ }
149
+ case UPB_TYPE_STRING:
150
+ if (CLASS_OF(value) == rb_cSymbol) {
151
+ value = rb_funcall(value, rb_intern("to_s"), 0);
152
+ } else if (CLASS_OF(value) != rb_cString) {
153
+ rb_raise(cTypeError, "Invalid argument for string field.");
154
+ }
155
+
156
+ DEREF(memory, VALUE) = native_slot_encode_and_freeze_string(type, value);
157
+ break;
158
+
159
+ case UPB_TYPE_BYTES: {
160
+ if (CLASS_OF(value) != rb_cString) {
161
+ rb_raise(cTypeError, "Invalid argument for string field.");
162
+ }
163
+
164
+ DEREF(memory, VALUE) = native_slot_encode_and_freeze_string(type, value);
165
+ break;
166
+ }
167
+ case UPB_TYPE_MESSAGE: {
168
+ if (CLASS_OF(value) == CLASS_OF(Qnil)) {
169
+ value = Qnil;
170
+ } else if (CLASS_OF(value) != type_class) {
171
+ rb_raise(cTypeError,
172
+ "Invalid type %s to assign to submessage field.",
173
+ rb_class2name(CLASS_OF(value)));
174
+ }
175
+ DEREF(memory, VALUE) = value;
176
+ break;
177
+ }
178
+ case UPB_TYPE_ENUM: {
179
+ int32_t int_val = 0;
180
+ if (TYPE(value) == T_STRING) {
181
+ value = rb_funcall(value, rb_intern("to_sym"), 0);
182
+ } else if (!is_ruby_num(value) && TYPE(value) != T_SYMBOL) {
183
+ rb_raise(cTypeError,
184
+ "Expected number or symbol type for enum field.");
185
+ }
186
+ if (TYPE(value) == T_SYMBOL) {
187
+ // Ensure that the given symbol exists in the enum module.
188
+ VALUE lookup = rb_funcall(type_class, rb_intern("resolve"), 1, value);
189
+ if (lookup == Qnil) {
190
+ rb_raise(rb_eRangeError, "Unknown symbol value for enum field.");
191
+ } else {
192
+ int_val = NUM2INT(lookup);
193
+ }
194
+ } else {
195
+ native_slot_check_int_range_precision(UPB_TYPE_INT32, value);
196
+ int_val = NUM2INT(value);
197
+ }
198
+ DEREF(memory, int32_t) = int_val;
199
+ break;
200
+ }
201
+ case UPB_TYPE_INT32:
202
+ case UPB_TYPE_INT64:
203
+ case UPB_TYPE_UINT32:
204
+ case UPB_TYPE_UINT64:
205
+ native_slot_check_int_range_precision(type, value);
206
+ switch (type) {
207
+ case UPB_TYPE_INT32:
208
+ DEREF(memory, int32_t) = NUM2INT(value);
209
+ break;
210
+ case UPB_TYPE_INT64:
211
+ DEREF(memory, int64_t) = NUM2LL(value);
212
+ break;
213
+ case UPB_TYPE_UINT32:
214
+ DEREF(memory, uint32_t) = NUM2UINT(value);
215
+ break;
216
+ case UPB_TYPE_UINT64:
217
+ DEREF(memory, uint64_t) = NUM2ULL(value);
218
+ break;
219
+ default:
220
+ break;
221
+ }
222
+ break;
223
+ default:
224
+ break;
225
+ }
226
+
227
+ if (case_memory != NULL) {
228
+ *case_memory = case_number;
229
+ }
230
+ }
231
+
232
+ VALUE native_slot_get(upb_fieldtype_t type,
233
+ VALUE type_class,
234
+ const void* memory) {
235
+ switch (type) {
236
+ case UPB_TYPE_FLOAT:
237
+ return DBL2NUM(DEREF(memory, float));
238
+ case UPB_TYPE_DOUBLE:
239
+ return DBL2NUM(DEREF(memory, double));
240
+ case UPB_TYPE_BOOL:
241
+ return DEREF(memory, int8_t) ? Qtrue : Qfalse;
242
+ case UPB_TYPE_STRING:
243
+ case UPB_TYPE_BYTES:
244
+ case UPB_TYPE_MESSAGE:
245
+ return DEREF(memory, VALUE);
246
+ case UPB_TYPE_ENUM: {
247
+ int32_t val = DEREF(memory, int32_t);
248
+ VALUE symbol = enum_lookup(type_class, INT2NUM(val));
249
+ if (symbol == Qnil) {
250
+ return INT2NUM(val);
251
+ } else {
252
+ return symbol;
253
+ }
254
+ }
255
+ case UPB_TYPE_INT32:
256
+ return INT2NUM(DEREF(memory, int32_t));
257
+ case UPB_TYPE_INT64:
258
+ return LL2NUM(DEREF(memory, int64_t));
259
+ case UPB_TYPE_UINT32:
260
+ return UINT2NUM(DEREF(memory, uint32_t));
261
+ case UPB_TYPE_UINT64:
262
+ return ULL2NUM(DEREF(memory, uint64_t));
263
+ default:
264
+ return Qnil;
265
+ }
266
+ }
267
+
268
+ void native_slot_init(upb_fieldtype_t type, void* memory) {
269
+ switch (type) {
270
+ case UPB_TYPE_FLOAT:
271
+ DEREF(memory, float) = 0.0;
272
+ break;
273
+ case UPB_TYPE_DOUBLE:
274
+ DEREF(memory, double) = 0.0;
275
+ break;
276
+ case UPB_TYPE_BOOL:
277
+ DEREF(memory, int8_t) = 0;
278
+ break;
279
+ case UPB_TYPE_STRING:
280
+ case UPB_TYPE_BYTES:
281
+ DEREF(memory, VALUE) = rb_str_new2("");
282
+ rb_enc_associate(DEREF(memory, VALUE), (type == UPB_TYPE_BYTES) ?
283
+ kRubyString8bitEncoding : kRubyStringUtf8Encoding);
284
+ break;
285
+ case UPB_TYPE_MESSAGE:
286
+ DEREF(memory, VALUE) = Qnil;
287
+ break;
288
+ case UPB_TYPE_ENUM:
289
+ case UPB_TYPE_INT32:
290
+ DEREF(memory, int32_t) = 0;
291
+ break;
292
+ case UPB_TYPE_INT64:
293
+ DEREF(memory, int64_t) = 0;
294
+ break;
295
+ case UPB_TYPE_UINT32:
296
+ DEREF(memory, uint32_t) = 0;
297
+ break;
298
+ case UPB_TYPE_UINT64:
299
+ DEREF(memory, uint64_t) = 0;
300
+ break;
301
+ default:
302
+ break;
303
+ }
304
+ }
305
+
306
+ void native_slot_mark(upb_fieldtype_t type, void* memory) {
307
+ switch (type) {
308
+ case UPB_TYPE_STRING:
309
+ case UPB_TYPE_BYTES:
310
+ case UPB_TYPE_MESSAGE:
311
+ rb_gc_mark(DEREF(memory, VALUE));
312
+ break;
313
+ default:
314
+ break;
315
+ }
316
+ }
317
+
318
+ void native_slot_dup(upb_fieldtype_t type, void* to, void* from) {
319
+ memcpy(to, from, native_slot_size(type));
320
+ }
321
+
322
+ void native_slot_deep_copy(upb_fieldtype_t type, void* to, void* from) {
323
+ switch (type) {
324
+ case UPB_TYPE_STRING:
325
+ case UPB_TYPE_BYTES: {
326
+ VALUE from_val = DEREF(from, VALUE);
327
+ DEREF(to, VALUE) = (from_val != Qnil) ?
328
+ rb_funcall(from_val, rb_intern("dup"), 0) : Qnil;
329
+ break;
330
+ }
331
+ case UPB_TYPE_MESSAGE: {
332
+ VALUE from_val = DEREF(from, VALUE);
333
+ DEREF(to, VALUE) = (from_val != Qnil) ?
334
+ Message_deep_copy(from_val) : Qnil;
335
+ break;
336
+ }
337
+ default:
338
+ memcpy(to, from, native_slot_size(type));
339
+ }
340
+ }
341
+
342
+ bool native_slot_eq(upb_fieldtype_t type, void* mem1, void* mem2) {
343
+ switch (type) {
344
+ case UPB_TYPE_STRING:
345
+ case UPB_TYPE_BYTES:
346
+ case UPB_TYPE_MESSAGE: {
347
+ VALUE val1 = DEREF(mem1, VALUE);
348
+ VALUE val2 = DEREF(mem2, VALUE);
349
+ VALUE ret = rb_funcall(val1, rb_intern("=="), 1, val2);
350
+ return ret == Qtrue;
351
+ }
352
+ default:
353
+ return !memcmp(mem1, mem2, native_slot_size(type));
354
+ }
355
+ }
356
+
357
+ // -----------------------------------------------------------------------------
358
+ // Map field utilities.
359
+ // -----------------------------------------------------------------------------
360
+
361
+ const upb_msgdef* tryget_map_entry_msgdef(const upb_fielddef* field) {
362
+ const upb_msgdef* subdef;
363
+ if (upb_fielddef_label(field) != UPB_LABEL_REPEATED ||
364
+ upb_fielddef_type(field) != UPB_TYPE_MESSAGE) {
365
+ return NULL;
366
+ }
367
+ subdef = upb_fielddef_msgsubdef(field);
368
+ return upb_msgdef_mapentry(subdef) ? subdef : NULL;
369
+ }
370
+
371
+ const upb_msgdef *map_entry_msgdef(const upb_fielddef* field) {
372
+ const upb_msgdef* subdef = tryget_map_entry_msgdef(field);
373
+ assert(subdef);
374
+ return subdef;
375
+ }
376
+
377
+ bool is_map_field(const upb_fielddef *field) {
378
+ const upb_msgdef* subdef = tryget_map_entry_msgdef(field);
379
+ if (subdef == NULL) return false;
380
+
381
+ // Map fields are a proto3 feature.
382
+ // If we're using proto2 syntax we need to fallback to the repeated field.
383
+ return upb_msgdef_syntax(subdef) == UPB_SYNTAX_PROTO3;
384
+ }
385
+
386
+ const upb_fielddef* map_field_key(const upb_fielddef* field) {
387
+ const upb_msgdef* subdef = map_entry_msgdef(field);
388
+ return map_entry_key(subdef);
389
+ }
390
+
391
+ const upb_fielddef* map_field_value(const upb_fielddef* field) {
392
+ const upb_msgdef* subdef = map_entry_msgdef(field);
393
+ return map_entry_value(subdef);
394
+ }
395
+
396
+ const upb_fielddef* map_entry_key(const upb_msgdef* msgdef) {
397
+ const upb_fielddef* key_field = upb_msgdef_itof(msgdef, MAP_KEY_FIELD);
398
+ assert(key_field != NULL);
399
+ return key_field;
400
+ }
401
+
402
+ const upb_fielddef* map_entry_value(const upb_msgdef* msgdef) {
403
+ const upb_fielddef* value_field = upb_msgdef_itof(msgdef, MAP_VALUE_FIELD);
404
+ assert(value_field != NULL);
405
+ return value_field;
406
+ }
407
+
408
+ // -----------------------------------------------------------------------------
409
+ // Memory layout management.
410
+ // -----------------------------------------------------------------------------
411
+
412
+ bool field_contains_hasbit(MessageLayout* layout,
413
+ const upb_fielddef* field) {
414
+ return layout->fields[upb_fielddef_index(field)].hasbit !=
415
+ MESSAGE_FIELD_NO_HASBIT;
416
+ }
417
+
418
+ static size_t align_up_to(size_t offset, size_t granularity) {
419
+ // Granularity must be a power of two.
420
+ return (offset + granularity - 1) & ~(granularity - 1);
421
+ }
422
+
423
+ MessageLayout* create_layout(const upb_msgdef* msgdef) {
424
+ MessageLayout* layout = ALLOC(MessageLayout);
425
+ int nfields = upb_msgdef_numfields(msgdef);
426
+ upb_msg_field_iter it;
427
+ upb_msg_oneof_iter oit;
428
+ size_t off = 0;
429
+
430
+ layout->fields = ALLOC_N(MessageField, nfields);
431
+
432
+ size_t hasbit = 0;
433
+ for (upb_msg_field_begin(&it, msgdef);
434
+ !upb_msg_field_done(&it);
435
+ upb_msg_field_next(&it)) {
436
+ const upb_fielddef* field = upb_msg_iter_field(&it);
437
+ if (upb_fielddef_haspresence(field)) {
438
+ layout->fields[upb_fielddef_index(field)].hasbit = hasbit++;
439
+ } else {
440
+ layout->fields[upb_fielddef_index(field)].hasbit =
441
+ MESSAGE_FIELD_NO_HASBIT;
442
+ }
443
+ }
444
+
445
+ if (hasbit != 0) {
446
+ off += (hasbit + 8 - 1) / 8;
447
+ }
448
+
449
+ for (upb_msg_field_begin(&it, msgdef);
450
+ !upb_msg_field_done(&it);
451
+ upb_msg_field_next(&it)) {
452
+ const upb_fielddef* field = upb_msg_iter_field(&it);
453
+ size_t field_size;
454
+
455
+ if (upb_fielddef_containingoneof(field)) {
456
+ // Oneofs are handled separately below.
457
+ continue;
458
+ }
459
+
460
+ // Allocate |field_size| bytes for this field in the layout.
461
+ field_size = 0;
462
+ if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
463
+ field_size = sizeof(VALUE);
464
+ } else {
465
+ field_size = native_slot_size(upb_fielddef_type(field));
466
+ }
467
+ // Align current offset up to |size| granularity.
468
+ off = align_up_to(off, field_size);
469
+ layout->fields[upb_fielddef_index(field)].offset = off;
470
+ layout->fields[upb_fielddef_index(field)].case_offset =
471
+ MESSAGE_FIELD_NO_CASE;
472
+ off += field_size;
473
+ }
474
+
475
+ // Handle oneofs now -- we iterate over oneofs specifically and allocate only
476
+ // one slot per oneof.
477
+ //
478
+ // We assign all value slots first, then pack the 'case' fields at the end,
479
+ // since in the common case (modern 64-bit platform) these are 8 bytes and 4
480
+ // bytes respectively and we want to avoid alignment overhead.
481
+ //
482
+ // Note that we reserve 4 bytes (a uint32) per 'case' slot because the value
483
+ // space for oneof cases is conceptually as wide as field tag numbers. In
484
+ // practice, it's unlikely that a oneof would have more than e.g. 256 or 64K
485
+ // members (8 or 16 bits respectively), so conceivably we could assign
486
+ // consecutive case numbers and then pick a smaller oneof case slot size, but
487
+ // the complexity to implement this indirection is probably not worthwhile.
488
+ for (upb_msg_oneof_begin(&oit, msgdef);
489
+ !upb_msg_oneof_done(&oit);
490
+ upb_msg_oneof_next(&oit)) {
491
+ const upb_oneofdef* oneof = upb_msg_iter_oneof(&oit);
492
+ upb_oneof_iter fit;
493
+
494
+ // Always allocate NATIVE_SLOT_MAX_SIZE bytes, but share the slot between
495
+ // all fields.
496
+ size_t field_size = NATIVE_SLOT_MAX_SIZE;
497
+ // Align the offset.
498
+ off = align_up_to(off, field_size);
499
+ // Assign all fields in the oneof this same offset.
500
+ for (upb_oneof_begin(&fit, oneof);
501
+ !upb_oneof_done(&fit);
502
+ upb_oneof_next(&fit)) {
503
+ const upb_fielddef* field = upb_oneof_iter_field(&fit);
504
+ layout->fields[upb_fielddef_index(field)].offset = off;
505
+ }
506
+ off += field_size;
507
+ }
508
+
509
+ // Now the case fields.
510
+ for (upb_msg_oneof_begin(&oit, msgdef);
511
+ !upb_msg_oneof_done(&oit);
512
+ upb_msg_oneof_next(&oit)) {
513
+ const upb_oneofdef* oneof = upb_msg_iter_oneof(&oit);
514
+ upb_oneof_iter fit;
515
+
516
+ size_t field_size = sizeof(uint32_t);
517
+ // Align the offset.
518
+ off = (off + field_size - 1) & ~(field_size - 1);
519
+ // Assign all fields in the oneof this same offset.
520
+ for (upb_oneof_begin(&fit, oneof);
521
+ !upb_oneof_done(&fit);
522
+ upb_oneof_next(&fit)) {
523
+ const upb_fielddef* field = upb_oneof_iter_field(&fit);
524
+ layout->fields[upb_fielddef_index(field)].case_offset = off;
525
+ }
526
+ off += field_size;
527
+ }
528
+
529
+ layout->size = off;
530
+
531
+ layout->msgdef = msgdef;
532
+ upb_msgdef_ref(layout->msgdef, &layout->msgdef);
533
+
534
+ return layout;
535
+ }
536
+
537
+ void free_layout(MessageLayout* layout) {
538
+ xfree(layout->fields);
539
+ upb_msgdef_unref(layout->msgdef, &layout->msgdef);
540
+ xfree(layout);
541
+ }
542
+
543
+ VALUE field_type_class(const upb_fielddef* field) {
544
+ VALUE type_class = Qnil;
545
+ if (upb_fielddef_type(field) == UPB_TYPE_MESSAGE) {
546
+ VALUE submsgdesc =
547
+ get_def_obj(upb_fielddef_subdef(field));
548
+ type_class = Descriptor_msgclass(submsgdesc);
549
+ } else if (upb_fielddef_type(field) == UPB_TYPE_ENUM) {
550
+ VALUE subenumdesc =
551
+ get_def_obj(upb_fielddef_subdef(field));
552
+ type_class = EnumDescriptor_enummodule(subenumdesc);
553
+ }
554
+ return type_class;
555
+ }
556
+
557
+ static void* slot_memory(MessageLayout* layout,
558
+ const void* storage,
559
+ const upb_fielddef* field) {
560
+ return ((uint8_t *)storage) +
561
+ layout->fields[upb_fielddef_index(field)].offset;
562
+ }
563
+
564
+ static uint32_t* slot_oneof_case(MessageLayout* layout,
565
+ const void* storage,
566
+ const upb_fielddef* field) {
567
+ return (uint32_t *)(((uint8_t *)storage) +
568
+ layout->fields[upb_fielddef_index(field)].case_offset);
569
+ }
570
+
571
+ static void slot_set_hasbit(MessageLayout* layout,
572
+ const void* storage,
573
+ const upb_fielddef* field) {
574
+ size_t hasbit = layout->fields[upb_fielddef_index(field)].hasbit;
575
+ assert(hasbit != MESSAGE_FIELD_NO_HASBIT);
576
+
577
+ ((uint8_t*)storage)[hasbit / 8] |= 1 << (hasbit % 8);
578
+ }
579
+
580
+ static void slot_clear_hasbit(MessageLayout* layout,
581
+ const void* storage,
582
+ const upb_fielddef* field) {
583
+ size_t hasbit = layout->fields[upb_fielddef_index(field)].hasbit;
584
+ assert(hasbit != MESSAGE_FIELD_NO_HASBIT);
585
+ ((uint8_t*)storage)[hasbit / 8] &= ~(1 << (hasbit % 8));
586
+ }
587
+
588
+ static bool slot_is_hasbit_set(MessageLayout* layout,
589
+ const void* storage,
590
+ const upb_fielddef* field) {
591
+ size_t hasbit = layout->fields[upb_fielddef_index(field)].hasbit;
592
+ if (hasbit == MESSAGE_FIELD_NO_HASBIT) {
593
+ return false;
594
+ }
595
+
596
+ return DEREF_OFFSET(
597
+ (uint8_t*)storage, hasbit / 8, char) & (1 << (hasbit % 8));
598
+ }
599
+
600
+ VALUE layout_has(MessageLayout* layout,
601
+ const void* storage,
602
+ const upb_fielddef* field) {
603
+ assert(field_contains_hasbit(layout, field));
604
+ return slot_is_hasbit_set(layout, storage, field) ? Qtrue : Qfalse;
605
+ }
606
+
607
+ void layout_clear(MessageLayout* layout,
608
+ const void* storage,
609
+ const upb_fielddef* field) {
610
+ void* memory = slot_memory(layout, storage, field);
611
+ uint32_t* oneof_case = slot_oneof_case(layout, storage, field);
612
+
613
+ if (field_contains_hasbit(layout, field)) {
614
+ slot_clear_hasbit(layout, storage, field);
615
+ }
616
+
617
+ if (upb_fielddef_containingoneof(field)) {
618
+ memset(memory, 0, NATIVE_SLOT_MAX_SIZE);
619
+ *oneof_case = ONEOF_CASE_NONE;
620
+ } else if (is_map_field(field)) {
621
+ VALUE map = Qnil;
622
+
623
+ const upb_fielddef* key_field = map_field_key(field);
624
+ const upb_fielddef* value_field = map_field_value(field);
625
+ VALUE type_class = field_type_class(value_field);
626
+
627
+ if (type_class != Qnil) {
628
+ VALUE args[3] = {
629
+ fieldtype_to_ruby(upb_fielddef_type(key_field)),
630
+ fieldtype_to_ruby(upb_fielddef_type(value_field)),
631
+ type_class,
632
+ };
633
+ map = rb_class_new_instance(3, args, cMap);
634
+ } else {
635
+ VALUE args[2] = {
636
+ fieldtype_to_ruby(upb_fielddef_type(key_field)),
637
+ fieldtype_to_ruby(upb_fielddef_type(value_field)),
638
+ };
639
+ map = rb_class_new_instance(2, args, cMap);
640
+ }
641
+
642
+ DEREF(memory, VALUE) = map;
643
+ } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
644
+ VALUE ary = Qnil;
645
+
646
+ VALUE type_class = field_type_class(field);
647
+
648
+ if (type_class != Qnil) {
649
+ VALUE args[2] = {
650
+ fieldtype_to_ruby(upb_fielddef_type(field)),
651
+ type_class,
652
+ };
653
+ ary = rb_class_new_instance(2, args, cRepeatedField);
654
+ } else {
655
+ VALUE args[1] = { fieldtype_to_ruby(upb_fielddef_type(field)) };
656
+ ary = rb_class_new_instance(1, args, cRepeatedField);
657
+ }
658
+
659
+ DEREF(memory, VALUE) = ary;
660
+ } else {
661
+ native_slot_set(upb_fielddef_type(field), field_type_class(field),
662
+ memory, layout_get_default(field));
663
+ }
664
+ }
665
+
666
+ VALUE layout_get_default(const upb_fielddef *field) {
667
+ switch (upb_fielddef_type(field)) {
668
+ case UPB_TYPE_FLOAT: return DBL2NUM(upb_fielddef_defaultfloat(field));
669
+ case UPB_TYPE_DOUBLE: return DBL2NUM(upb_fielddef_defaultdouble(field));
670
+ case UPB_TYPE_BOOL:
671
+ return upb_fielddef_defaultbool(field) ? Qtrue : Qfalse;
672
+ case UPB_TYPE_MESSAGE: return Qnil;
673
+ case UPB_TYPE_ENUM: {
674
+ const upb_enumdef *enumdef = upb_fielddef_enumsubdef(field);
675
+ int32_t num = upb_fielddef_defaultint32(field);
676
+ const char *label = upb_enumdef_iton(enumdef, num);
677
+ if (label) {
678
+ return ID2SYM(rb_intern(label));
679
+ } else {
680
+ return INT2NUM(num);
681
+ }
682
+ }
683
+ case UPB_TYPE_INT32: return INT2NUM(upb_fielddef_defaultint32(field));
684
+ case UPB_TYPE_INT64: return LL2NUM(upb_fielddef_defaultint64(field));;
685
+ case UPB_TYPE_UINT32: return UINT2NUM(upb_fielddef_defaultuint32(field));
686
+ case UPB_TYPE_UINT64: return ULL2NUM(upb_fielddef_defaultuint64(field));
687
+ case UPB_TYPE_STRING:
688
+ case UPB_TYPE_BYTES: {
689
+ size_t size;
690
+ const char *str = upb_fielddef_defaultstr(field, &size);
691
+ VALUE str_rb = rb_str_new(str, size);
692
+
693
+ rb_enc_associate(str_rb, (upb_fielddef_type(field) == UPB_TYPE_BYTES) ?
694
+ kRubyString8bitEncoding : kRubyStringUtf8Encoding);
695
+ rb_obj_freeze(str_rb);
696
+ return str_rb;
697
+ }
698
+ default: return Qnil;
699
+ }
700
+ }
701
+
702
+ VALUE layout_get(MessageLayout* layout,
703
+ const void* storage,
704
+ const upb_fielddef* field) {
705
+ void* memory = slot_memory(layout, storage, field);
706
+ uint32_t* oneof_case = slot_oneof_case(layout, storage, field);
707
+
708
+ bool field_set;
709
+ if (field_contains_hasbit(layout, field)) {
710
+ field_set = slot_is_hasbit_set(layout, storage, field);
711
+ } else {
712
+ field_set = true;
713
+ }
714
+
715
+ if (upb_fielddef_containingoneof(field)) {
716
+ if (*oneof_case != upb_fielddef_number(field)) {
717
+ return layout_get_default(field);
718
+ }
719
+ return native_slot_get(upb_fielddef_type(field),
720
+ field_type_class(field),
721
+ memory);
722
+ } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
723
+ return *((VALUE *)memory);
724
+ } else if (!field_set) {
725
+ return layout_get_default(field);
726
+ } else {
727
+ return native_slot_get(upb_fielddef_type(field),
728
+ field_type_class(field),
729
+ memory);
730
+ }
731
+ }
732
+
733
+ static void check_repeated_field_type(VALUE val, const upb_fielddef* field) {
734
+ RepeatedField* self;
735
+ assert(upb_fielddef_label(field) == UPB_LABEL_REPEATED);
736
+
737
+ if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) ||
738
+ RTYPEDDATA_TYPE(val) != &RepeatedField_type) {
739
+ rb_raise(cTypeError, "Expected repeated field array");
740
+ }
741
+
742
+ self = ruby_to_RepeatedField(val);
743
+ if (self->field_type != upb_fielddef_type(field)) {
744
+ rb_raise(cTypeError, "Repeated field array has wrong element type");
745
+ }
746
+
747
+ if (self->field_type == UPB_TYPE_MESSAGE) {
748
+ if (self->field_type_class !=
749
+ Descriptor_msgclass(get_def_obj(upb_fielddef_subdef(field)))) {
750
+ rb_raise(cTypeError,
751
+ "Repeated field array has wrong message class");
752
+ }
753
+ }
754
+
755
+
756
+ if (self->field_type == UPB_TYPE_ENUM) {
757
+ if (self->field_type_class !=
758
+ EnumDescriptor_enummodule(get_def_obj(upb_fielddef_subdef(field)))) {
759
+ rb_raise(cTypeError,
760
+ "Repeated field array has wrong enum class");
761
+ }
762
+ }
763
+ }
764
+
765
+ static void check_map_field_type(VALUE val, const upb_fielddef* field) {
766
+ const upb_fielddef* key_field = map_field_key(field);
767
+ const upb_fielddef* value_field = map_field_value(field);
768
+ Map* self;
769
+
770
+ if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) ||
771
+ RTYPEDDATA_TYPE(val) != &Map_type) {
772
+ rb_raise(cTypeError, "Expected Map instance");
773
+ }
774
+
775
+ self = ruby_to_Map(val);
776
+ if (self->key_type != upb_fielddef_type(key_field)) {
777
+ rb_raise(cTypeError, "Map key type does not match field's key type");
778
+ }
779
+ if (self->value_type != upb_fielddef_type(value_field)) {
780
+ rb_raise(cTypeError, "Map value type does not match field's value type");
781
+ }
782
+ if (upb_fielddef_type(value_field) == UPB_TYPE_MESSAGE ||
783
+ upb_fielddef_type(value_field) == UPB_TYPE_ENUM) {
784
+ if (self->value_type_class !=
785
+ get_def_obj(upb_fielddef_subdef(value_field))) {
786
+ rb_raise(cTypeError,
787
+ "Map value type has wrong message/enum class");
788
+ }
789
+ }
790
+ }
791
+
792
+
793
+ void layout_set(MessageLayout* layout,
794
+ void* storage,
795
+ const upb_fielddef* field,
796
+ VALUE val) {
797
+ void* memory = slot_memory(layout, storage, field);
798
+ uint32_t* oneof_case = slot_oneof_case(layout, storage, field);
799
+
800
+ if (upb_fielddef_containingoneof(field)) {
801
+ if (val == Qnil) {
802
+ // Assigning nil to a oneof field clears the oneof completely.
803
+ *oneof_case = ONEOF_CASE_NONE;
804
+ memset(memory, 0, NATIVE_SLOT_MAX_SIZE);
805
+ } else {
806
+ // The transition between field types for a single oneof (union) slot is
807
+ // somewhat complex because we need to ensure that a GC triggered at any
808
+ // point by a call into the Ruby VM sees a valid state for this field and
809
+ // does not either go off into the weeds (following what it thinks is a
810
+ // VALUE but is actually a different field type) or miss an object (seeing
811
+ // what it thinks is a primitive field but is actually a VALUE for the new
812
+ // field type).
813
+ //
814
+ // In order for the transition to be safe, the oneof case slot must be in
815
+ // sync with the value slot whenever the Ruby VM has been called. Thus, we
816
+ // use native_slot_set_value_and_case(), which ensures that both the value
817
+ // and case number are altered atomically (w.r.t. the Ruby VM).
818
+ native_slot_set_value_and_case(
819
+ upb_fielddef_type(field), field_type_class(field),
820
+ memory, val,
821
+ oneof_case, upb_fielddef_number(field));
822
+ }
823
+ } else if (is_map_field(field)) {
824
+ check_map_field_type(val, field);
825
+ DEREF(memory, VALUE) = val;
826
+ } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
827
+ check_repeated_field_type(val, field);
828
+ DEREF(memory, VALUE) = val;
829
+ } else {
830
+ native_slot_set(upb_fielddef_type(field), field_type_class(field), memory,
831
+ val);
832
+ }
833
+
834
+ if (layout->fields[upb_fielddef_index(field)].hasbit !=
835
+ MESSAGE_FIELD_NO_HASBIT) {
836
+ slot_set_hasbit(layout, storage, field);
837
+ }
838
+ }
839
+
840
+ void layout_init(MessageLayout* layout,
841
+ void* storage) {
842
+
843
+ upb_msg_field_iter it;
844
+ for (upb_msg_field_begin(&it, layout->msgdef);
845
+ !upb_msg_field_done(&it);
846
+ upb_msg_field_next(&it)) {
847
+ layout_clear(layout, storage, upb_msg_iter_field(&it));
848
+ }
849
+ }
850
+
851
+ void layout_mark(MessageLayout* layout, void* storage) {
852
+ upb_msg_field_iter it;
853
+ for (upb_msg_field_begin(&it, layout->msgdef);
854
+ !upb_msg_field_done(&it);
855
+ upb_msg_field_next(&it)) {
856
+ const upb_fielddef* field = upb_msg_iter_field(&it);
857
+ void* memory = slot_memory(layout, storage, field);
858
+ uint32_t* oneof_case = slot_oneof_case(layout, storage, field);
859
+
860
+ if (upb_fielddef_containingoneof(field)) {
861
+ if (*oneof_case == upb_fielddef_number(field)) {
862
+ native_slot_mark(upb_fielddef_type(field), memory);
863
+ }
864
+ } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
865
+ rb_gc_mark(DEREF(memory, VALUE));
866
+ } else {
867
+ native_slot_mark(upb_fielddef_type(field), memory);
868
+ }
869
+ }
870
+ }
871
+
872
+ void layout_dup(MessageLayout* layout, void* to, void* from) {
873
+ upb_msg_field_iter it;
874
+ for (upb_msg_field_begin(&it, layout->msgdef);
875
+ !upb_msg_field_done(&it);
876
+ upb_msg_field_next(&it)) {
877
+ const upb_fielddef* field = upb_msg_iter_field(&it);
878
+
879
+ void* to_memory = slot_memory(layout, to, field);
880
+ uint32_t* to_oneof_case = slot_oneof_case(layout, to, field);
881
+ void* from_memory = slot_memory(layout, from, field);
882
+ uint32_t* from_oneof_case = slot_oneof_case(layout, from, field);
883
+
884
+ if (upb_fielddef_containingoneof(field)) {
885
+ if (*from_oneof_case == upb_fielddef_number(field)) {
886
+ *to_oneof_case = *from_oneof_case;
887
+ native_slot_dup(upb_fielddef_type(field), to_memory, from_memory);
888
+ }
889
+ } else if (is_map_field(field)) {
890
+ DEREF(to_memory, VALUE) = Map_dup(DEREF(from_memory, VALUE));
891
+ } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
892
+ DEREF(to_memory, VALUE) = RepeatedField_dup(DEREF(from_memory, VALUE));
893
+ } else {
894
+ if (field_contains_hasbit(layout, field)) {
895
+ if (!slot_is_hasbit_set(layout, from, field)) continue;
896
+ slot_set_hasbit(layout, to, field);
897
+ }
898
+
899
+ native_slot_dup(upb_fielddef_type(field), to_memory, from_memory);
900
+ }
901
+ }
902
+ }
903
+
904
+ void layout_deep_copy(MessageLayout* layout, void* to, void* from) {
905
+ upb_msg_field_iter it;
906
+ for (upb_msg_field_begin(&it, layout->msgdef);
907
+ !upb_msg_field_done(&it);
908
+ upb_msg_field_next(&it)) {
909
+ const upb_fielddef* field = upb_msg_iter_field(&it);
910
+
911
+ void* to_memory = slot_memory(layout, to, field);
912
+ uint32_t* to_oneof_case = slot_oneof_case(layout, to, field);
913
+ void* from_memory = slot_memory(layout, from, field);
914
+ uint32_t* from_oneof_case = slot_oneof_case(layout, from, field);
915
+
916
+ if (upb_fielddef_containingoneof(field)) {
917
+ if (*from_oneof_case == upb_fielddef_number(field)) {
918
+ *to_oneof_case = *from_oneof_case;
919
+ native_slot_deep_copy(upb_fielddef_type(field), to_memory, from_memory);
920
+ }
921
+ } else if (is_map_field(field)) {
922
+ DEREF(to_memory, VALUE) =
923
+ Map_deep_copy(DEREF(from_memory, VALUE));
924
+ } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
925
+ DEREF(to_memory, VALUE) =
926
+ RepeatedField_deep_copy(DEREF(from_memory, VALUE));
927
+ } else {
928
+ if (field_contains_hasbit(layout, field)) {
929
+ if (!slot_is_hasbit_set(layout, from, field)) continue;
930
+ slot_set_hasbit(layout, to, field);
931
+ }
932
+
933
+ native_slot_deep_copy(upb_fielddef_type(field), to_memory, from_memory);
934
+ }
935
+ }
936
+ }
937
+
938
+ VALUE layout_eq(MessageLayout* layout, void* msg1, void* msg2) {
939
+ upb_msg_field_iter it;
940
+ for (upb_msg_field_begin(&it, layout->msgdef);
941
+ !upb_msg_field_done(&it);
942
+ upb_msg_field_next(&it)) {
943
+ const upb_fielddef* field = upb_msg_iter_field(&it);
944
+
945
+ void* msg1_memory = slot_memory(layout, msg1, field);
946
+ uint32_t* msg1_oneof_case = slot_oneof_case(layout, msg1, field);
947
+ void* msg2_memory = slot_memory(layout, msg2, field);
948
+ uint32_t* msg2_oneof_case = slot_oneof_case(layout, msg2, field);
949
+
950
+ if (upb_fielddef_containingoneof(field)) {
951
+ if (*msg1_oneof_case != *msg2_oneof_case ||
952
+ (*msg1_oneof_case == upb_fielddef_number(field) &&
953
+ !native_slot_eq(upb_fielddef_type(field),
954
+ msg1_memory,
955
+ msg2_memory))) {
956
+ return Qfalse;
957
+ }
958
+ } else if (is_map_field(field)) {
959
+ if (!Map_eq(DEREF(msg1_memory, VALUE),
960
+ DEREF(msg2_memory, VALUE))) {
961
+ return Qfalse;
962
+ }
963
+ } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
964
+ if (!RepeatedField_eq(DEREF(msg1_memory, VALUE),
965
+ DEREF(msg2_memory, VALUE))) {
966
+ return Qfalse;
967
+ }
968
+ } else {
969
+ if (slot_is_hasbit_set(layout, msg1, field) !=
970
+ slot_is_hasbit_set(layout, msg2, field) ||
971
+ !native_slot_eq(upb_fielddef_type(field),
972
+ msg1_memory, msg2_memory)) {
973
+ return Qfalse;
974
+ }
975
+ }
976
+ }
977
+ return Qtrue;
978
+ }
979
+
980
+ VALUE layout_hash(MessageLayout* layout, void* storage) {
981
+ upb_msg_field_iter it;
982
+ st_index_t h = rb_hash_start(0);
983
+ VALUE hash_sym = rb_intern("hash");
984
+ for (upb_msg_field_begin(&it, layout->msgdef);
985
+ !upb_msg_field_done(&it);
986
+ upb_msg_field_next(&it)) {
987
+ const upb_fielddef* field = upb_msg_iter_field(&it);
988
+ VALUE field_val = layout_get(layout, storage, field);
989
+ h = rb_hash_uint(h, NUM2LONG(rb_funcall(field_val, hash_sym, 0)));
990
+ }
991
+ h = rb_hash_end(h);
992
+
993
+ return INT2FIX(h);
994
+ }
995
+
996
+ VALUE layout_inspect(MessageLayout* layout, void* storage) {
997
+ VALUE str = rb_str_new2("");
998
+
999
+ upb_msg_field_iter it;
1000
+ bool first = true;
1001
+ for (upb_msg_field_begin(&it, layout->msgdef);
1002
+ !upb_msg_field_done(&it);
1003
+ upb_msg_field_next(&it)) {
1004
+ const upb_fielddef* field = upb_msg_iter_field(&it);
1005
+ VALUE field_val = layout_get(layout, storage, field);
1006
+
1007
+ if (!first) {
1008
+ str = rb_str_cat2(str, ", ");
1009
+ } else {
1010
+ first = false;
1011
+ }
1012
+ str = rb_str_cat2(str, upb_fielddef_name(field));
1013
+ str = rb_str_cat2(str, ": ");
1014
+
1015
+ str = rb_str_append(str, rb_funcall(field_val, rb_intern("inspect"), 0));
1016
+ }
1017
+
1018
+ return str;
1019
+ }