google-protobuf 3.0.0.alpha.3.1.pre → 3.0.0.alpha.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of google-protobuf might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/ext/google/protobuf_c/defs.c +160 -83
- data/ext/google/protobuf_c/encode_decode.c +177 -144
- data/ext/google/protobuf_c/extconf.rb +1 -1
- data/ext/google/protobuf_c/map.c +15 -12
- data/ext/google/protobuf_c/message.c +104 -40
- data/ext/google/protobuf_c/protobuf.c +16 -6
- data/ext/google/protobuf_c/protobuf.h +11 -8
- data/ext/google/protobuf_c/repeated_field.c +138 -85
- data/ext/google/protobuf_c/storage.c +35 -20
- data/ext/google/protobuf_c/upb.c +3443 -2673
- data/ext/google/protobuf_c/upb.h +5086 -4919
- data/lib/google/protobuf.rb +36 -0
- data/lib/google/protobuf/message_exts.rb +53 -0
- data/lib/google/protobuf/repeated_field.rb +188 -0
- data/tests/basic.rb +119 -9
- metadata +6 -4
data/ext/google/protobuf_c/map.c
CHANGED
@@ -120,7 +120,7 @@ static VALUE table_key_to_ruby(Map* self, const char* buf, size_t length) {
|
|
120
120
|
}
|
121
121
|
|
122
122
|
static void* value_memory(upb_value* v) {
|
123
|
-
return (void*)(&v->val
|
123
|
+
return (void*)(&v->val);
|
124
124
|
}
|
125
125
|
|
126
126
|
// -----------------------------------------------------------------------------
|
@@ -169,8 +169,7 @@ VALUE Map_alloc(VALUE klass) {
|
|
169
169
|
Map* self = ALLOC(Map);
|
170
170
|
memset(self, 0, sizeof(Map));
|
171
171
|
self->value_type_class = Qnil;
|
172
|
-
|
173
|
-
return ret;
|
172
|
+
return TypedData_Wrap_Struct(klass, &Map_type, self);
|
174
173
|
}
|
175
174
|
|
176
175
|
static bool needs_typeclass(upb_fieldtype_t type) {
|
@@ -215,6 +214,7 @@ static bool needs_typeclass(upb_fieldtype_t type) {
|
|
215
214
|
*/
|
216
215
|
VALUE Map_init(int argc, VALUE* argv, VALUE _self) {
|
217
216
|
Map* self = ruby_to_Map(_self);
|
217
|
+
int init_value_arg;
|
218
218
|
|
219
219
|
// We take either two args (:key_type, :value_type), three args (:key_type,
|
220
220
|
// :value_type, "ValueMessageType"), or four args (the above plus an initial
|
@@ -241,7 +241,7 @@ VALUE Map_init(int argc, VALUE* argv, VALUE _self) {
|
|
241
241
|
rb_raise(rb_eArgError, "Invalid key type for map.");
|
242
242
|
}
|
243
243
|
|
244
|
-
|
244
|
+
init_value_arg = 2;
|
245
245
|
if (needs_typeclass(self->value_type) && argc > 2) {
|
246
246
|
self->value_type_class = argv[2];
|
247
247
|
validate_type_class(self->value_type, self->value_type_class);
|
@@ -356,9 +356,9 @@ VALUE Map_index(VALUE _self, VALUE key) {
|
|
356
356
|
char keybuf[TABLE_KEY_BUF_LENGTH];
|
357
357
|
const char* keyval = NULL;
|
358
358
|
size_t length = 0;
|
359
|
+
upb_value v;
|
359
360
|
table_key(self, key, keybuf, &keyval, &length);
|
360
361
|
|
361
|
-
upb_value v;
|
362
362
|
if (upb_strtable_lookup2(&self->table, keyval, length, &v)) {
|
363
363
|
void* mem = value_memory(&v);
|
364
364
|
return native_slot_get(self->value_type, self->value_type_class, mem);
|
@@ -381,10 +381,11 @@ VALUE Map_index_set(VALUE _self, VALUE key, VALUE value) {
|
|
381
381
|
char keybuf[TABLE_KEY_BUF_LENGTH];
|
382
382
|
const char* keyval = NULL;
|
383
383
|
size_t length = 0;
|
384
|
+
upb_value v;
|
385
|
+
void* mem;
|
384
386
|
table_key(self, key, keybuf, &keyval, &length);
|
385
387
|
|
386
|
-
|
387
|
-
void* mem = value_memory(&v);
|
388
|
+
mem = value_memory(&v);
|
388
389
|
native_slot_set(self->value_type, self->value_type_class, mem, value);
|
389
390
|
|
390
391
|
// Replace any existing value by issuing a 'remove' operation first.
|
@@ -432,9 +433,9 @@ VALUE Map_delete(VALUE _self, VALUE key) {
|
|
432
433
|
char keybuf[TABLE_KEY_BUF_LENGTH];
|
433
434
|
const char* keyval = NULL;
|
434
435
|
size_t length = 0;
|
436
|
+
upb_value v;
|
435
437
|
table_key(self, key, keybuf, &keyval, &length);
|
436
438
|
|
437
|
-
upb_value v;
|
438
439
|
if (upb_strtable_remove2(&self->table, keyval, length, &v)) {
|
439
440
|
void* mem = value_memory(&v);
|
440
441
|
return native_slot_get(self->value_type, self->value_type_class, mem);
|
@@ -564,6 +565,8 @@ VALUE Map_deep_copy(VALUE _self) {
|
|
564
565
|
*/
|
565
566
|
VALUE Map_eq(VALUE _self, VALUE _other) {
|
566
567
|
Map* self = ruby_to_Map(_self);
|
568
|
+
Map* other;
|
569
|
+
upb_strtable_iter it;
|
567
570
|
|
568
571
|
// Allow comparisons to Ruby hashmaps by converting to a temporary Map
|
569
572
|
// instance. Slow, but workable.
|
@@ -573,7 +576,7 @@ VALUE Map_eq(VALUE _self, VALUE _other) {
|
|
573
576
|
_other = other_map;
|
574
577
|
}
|
575
578
|
|
576
|
-
|
579
|
+
other = ruby_to_Map(_other);
|
577
580
|
|
578
581
|
if (self == other) {
|
579
582
|
return Qtrue;
|
@@ -589,7 +592,6 @@ VALUE Map_eq(VALUE _self, VALUE _other) {
|
|
589
592
|
|
590
593
|
// For each member of self, check that an equal member exists at the same key
|
591
594
|
// in other.
|
592
|
-
upb_strtable_iter it;
|
593
595
|
for (upb_strtable_begin(&it, &self->table);
|
594
596
|
!upb_strtable_done(&it);
|
595
597
|
upb_strtable_next(&it)) {
|
@@ -719,6 +721,7 @@ VALUE Map_merge_into_self(VALUE _self, VALUE hashmap) {
|
|
719
721
|
|
720
722
|
Map* self = ruby_to_Map(_self);
|
721
723
|
Map* other = ruby_to_Map(hashmap);
|
724
|
+
upb_strtable_iter it;
|
722
725
|
|
723
726
|
if (self->key_type != other->key_type ||
|
724
727
|
self->value_type != other->value_type ||
|
@@ -726,19 +729,19 @@ VALUE Map_merge_into_self(VALUE _self, VALUE hashmap) {
|
|
726
729
|
rb_raise(rb_eArgError, "Attempt to merge Map with mismatching types");
|
727
730
|
}
|
728
731
|
|
729
|
-
upb_strtable_iter it;
|
730
732
|
for (upb_strtable_begin(&it, &other->table);
|
731
733
|
!upb_strtable_done(&it);
|
732
734
|
upb_strtable_next(&it)) {
|
733
735
|
|
734
736
|
// Replace any existing value by issuing a 'remove' operation first.
|
737
|
+
upb_value v;
|
735
738
|
upb_value oldv;
|
736
739
|
upb_strtable_remove2(&self->table,
|
737
740
|
upb_strtable_iter_key(&it),
|
738
741
|
upb_strtable_iter_keylength(&it),
|
739
742
|
&oldv);
|
740
743
|
|
741
|
-
|
744
|
+
v = upb_strtable_iter_value(&it);
|
742
745
|
upb_strtable_insert2(&self->table,
|
743
746
|
upb_strtable_iter_key(&it),
|
744
747
|
upb_strtable_iter_keylength(&it),
|
@@ -53,17 +53,19 @@ rb_data_type_t Message_type = {
|
|
53
53
|
};
|
54
54
|
|
55
55
|
VALUE Message_alloc(VALUE klass) {
|
56
|
-
VALUE descriptor =
|
56
|
+
VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
|
57
57
|
Descriptor* desc = ruby_to_Descriptor(descriptor);
|
58
58
|
MessageHeader* msg = (MessageHeader*)ALLOC_N(
|
59
59
|
uint8_t, sizeof(MessageHeader) + desc->layout->size);
|
60
|
+
VALUE ret;
|
61
|
+
|
60
62
|
memset(Message_data(msg), 0, desc->layout->size);
|
61
63
|
|
62
64
|
// We wrap first so that everything in the message object is GC-rooted in case
|
63
65
|
// a collection happens during object creation in layout_init().
|
64
|
-
|
66
|
+
ret = TypedData_Wrap_Struct(klass, &Message_type, msg);
|
65
67
|
msg->descriptor = desc;
|
66
|
-
|
68
|
+
rb_ivar_set(ret, descriptor_instancevar_interned, descriptor);
|
67
69
|
|
68
70
|
layout_init(desc->layout, Message_data(msg));
|
69
71
|
|
@@ -71,29 +73,34 @@ VALUE Message_alloc(VALUE klass) {
|
|
71
73
|
}
|
72
74
|
|
73
75
|
static VALUE which_oneof_field(MessageHeader* self, const upb_oneofdef* o) {
|
76
|
+
upb_oneof_iter it;
|
77
|
+
size_t case_ofs;
|
78
|
+
uint32_t oneof_case;
|
79
|
+
const upb_fielddef* first_field;
|
80
|
+
const upb_fielddef* f;
|
81
|
+
|
74
82
|
// If no fields in the oneof, always nil.
|
75
83
|
if (upb_oneofdef_numfields(o) == 0) {
|
76
84
|
return Qnil;
|
77
85
|
}
|
78
86
|
// Grab the first field in the oneof so we can get its layout info to find the
|
79
87
|
// oneof_case field.
|
80
|
-
upb_oneof_iter it;
|
81
88
|
upb_oneof_begin(&it, o);
|
82
89
|
assert(!upb_oneof_done(&it));
|
83
|
-
|
90
|
+
first_field = upb_oneof_iter_field(&it);
|
84
91
|
assert(upb_fielddef_containingoneof(first_field) != NULL);
|
85
92
|
|
86
|
-
|
93
|
+
case_ofs =
|
87
94
|
self->descriptor->layout->
|
88
95
|
fields[upb_fielddef_index(first_field)].case_offset;
|
89
|
-
|
96
|
+
oneof_case = *((uint32_t*)((char*)Message_data(self) + case_ofs));
|
90
97
|
|
91
98
|
if (oneof_case == ONEOF_CASE_NONE) {
|
92
99
|
return Qnil;
|
93
100
|
}
|
94
101
|
|
95
102
|
// oneof_case is a field index, so find that field.
|
96
|
-
|
103
|
+
f = upb_oneofdef_itof(o, oneof_case);
|
97
104
|
assert(f != NULL);
|
98
105
|
|
99
106
|
return ID2SYM(rb_intern(upb_fielddef_name(f)));
|
@@ -118,18 +125,25 @@ static VALUE which_oneof_field(MessageHeader* self, const upb_oneofdef* o) {
|
|
118
125
|
*/
|
119
126
|
VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) {
|
120
127
|
MessageHeader* self;
|
128
|
+
VALUE method_name, method_str;
|
129
|
+
char* name;
|
130
|
+
size_t name_len;
|
131
|
+
bool setter;
|
132
|
+
const upb_oneofdef* o;
|
133
|
+
const upb_fielddef* f;
|
134
|
+
|
121
135
|
TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
|
122
136
|
if (argc < 1) {
|
123
137
|
rb_raise(rb_eArgError, "Expected method name as first argument.");
|
124
138
|
}
|
125
|
-
|
139
|
+
method_name = argv[0];
|
126
140
|
if (!SYMBOL_P(method_name)) {
|
127
141
|
rb_raise(rb_eArgError, "Expected symbol as method name.");
|
128
142
|
}
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
143
|
+
method_str = rb_id2str(SYM2ID(method_name));
|
144
|
+
name = RSTRING_PTR(method_str);
|
145
|
+
name_len = RSTRING_LEN(method_str);
|
146
|
+
setter = false;
|
133
147
|
|
134
148
|
// Setters have names that end in '='.
|
135
149
|
if (name[name_len - 1] == '=') {
|
@@ -138,7 +152,7 @@ VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) {
|
|
138
152
|
}
|
139
153
|
|
140
154
|
// Check for a oneof name first.
|
141
|
-
|
155
|
+
o = upb_msgdef_ntoo(self->descriptor->msgdef,
|
142
156
|
name, name_len);
|
143
157
|
if (o != NULL) {
|
144
158
|
if (setter) {
|
@@ -148,7 +162,7 @@ VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) {
|
|
148
162
|
}
|
149
163
|
|
150
164
|
// Otherwise, check for a field with that name.
|
151
|
-
|
165
|
+
f = upb_msgdef_ntof(self->descriptor->msgdef,
|
152
166
|
name, name_len);
|
153
167
|
|
154
168
|
if (f == NULL) {
|
@@ -168,6 +182,9 @@ VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) {
|
|
168
182
|
|
169
183
|
int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) {
|
170
184
|
MessageHeader* self;
|
185
|
+
VALUE method_str;
|
186
|
+
char* name;
|
187
|
+
const upb_fielddef* f;
|
171
188
|
TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
|
172
189
|
|
173
190
|
if (!SYMBOL_P(key)) {
|
@@ -175,27 +192,31 @@ int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) {
|
|
175
192
|
"Expected symbols as hash keys in initialization map.");
|
176
193
|
}
|
177
194
|
|
178
|
-
|
179
|
-
|
180
|
-
|
195
|
+
method_str = rb_id2str(SYM2ID(key));
|
196
|
+
name = RSTRING_PTR(method_str);
|
197
|
+
f = upb_msgdef_ntofz(self->descriptor->msgdef, name);
|
181
198
|
if (f == NULL) {
|
182
199
|
rb_raise(rb_eArgError,
|
183
200
|
"Unknown field name in initialization map entry.");
|
184
201
|
}
|
185
202
|
|
186
203
|
if (is_map_field(f)) {
|
204
|
+
VALUE map;
|
205
|
+
|
187
206
|
if (TYPE(val) != T_HASH) {
|
188
207
|
rb_raise(rb_eArgError,
|
189
208
|
"Expected Hash object as initializer value for map field.");
|
190
209
|
}
|
191
|
-
|
210
|
+
map = layout_get(self->descriptor->layout, Message_data(self), f);
|
192
211
|
Map_merge_into_self(map, val);
|
193
212
|
} else if (upb_fielddef_label(f) == UPB_LABEL_REPEATED) {
|
213
|
+
VALUE ary;
|
214
|
+
|
194
215
|
if (TYPE(val) != T_ARRAY) {
|
195
216
|
rb_raise(rb_eArgError,
|
196
217
|
"Expected array as initializer value for repeated field.");
|
197
218
|
}
|
198
|
-
|
219
|
+
ary = layout_get(self->descriptor->layout, Message_data(self), f);
|
199
220
|
for (int i = 0; i < RARRAY_LEN(val); i++) {
|
200
221
|
RepeatedField_push(ary, rb_ary_entry(val, i));
|
201
222
|
}
|
@@ -218,13 +239,15 @@ int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) {
|
|
218
239
|
* Message class are provided on each concrete message class.
|
219
240
|
*/
|
220
241
|
VALUE Message_initialize(int argc, VALUE* argv, VALUE _self) {
|
242
|
+
VALUE hash_args;
|
243
|
+
|
221
244
|
if (argc == 0) {
|
222
245
|
return Qnil;
|
223
246
|
}
|
224
247
|
if (argc != 1) {
|
225
248
|
rb_raise(rb_eArgError, "Expected 0 or 1 arguments.");
|
226
249
|
}
|
227
|
-
|
250
|
+
hash_args = argv[0];
|
228
251
|
if (TYPE(hash_args) != T_HASH) {
|
229
252
|
rb_raise(rb_eArgError, "Expected hash arguments.");
|
230
253
|
}
|
@@ -241,10 +264,11 @@ VALUE Message_initialize(int argc, VALUE* argv, VALUE _self) {
|
|
241
264
|
*/
|
242
265
|
VALUE Message_dup(VALUE _self) {
|
243
266
|
MessageHeader* self;
|
267
|
+
VALUE new_msg;
|
268
|
+
MessageHeader* new_msg_self;
|
244
269
|
TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
|
245
270
|
|
246
|
-
|
247
|
-
MessageHeader* new_msg_self;
|
271
|
+
new_msg = rb_class_new_instance(0, NULL, CLASS_OF(_self));
|
248
272
|
TypedData_Get_Struct(new_msg, MessageHeader, &Message_type, new_msg_self);
|
249
273
|
|
250
274
|
layout_dup(self->descriptor->layout,
|
@@ -257,10 +281,11 @@ VALUE Message_dup(VALUE _self) {
|
|
257
281
|
// Internal only; used by Google::Protobuf.deep_copy.
|
258
282
|
VALUE Message_deep_copy(VALUE _self) {
|
259
283
|
MessageHeader* self;
|
284
|
+
MessageHeader* new_msg_self;
|
285
|
+
VALUE new_msg;
|
260
286
|
TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
|
261
287
|
|
262
|
-
|
263
|
-
MessageHeader* new_msg_self;
|
288
|
+
new_msg = rb_class_new_instance(0, NULL, CLASS_OF(_self));
|
264
289
|
TypedData_Get_Struct(new_msg, MessageHeader, &Message_type, new_msg_self);
|
265
290
|
|
266
291
|
layout_deep_copy(self->descriptor->layout,
|
@@ -281,9 +306,8 @@ VALUE Message_deep_copy(VALUE _self) {
|
|
281
306
|
*/
|
282
307
|
VALUE Message_eq(VALUE _self, VALUE _other) {
|
283
308
|
MessageHeader* self;
|
284
|
-
TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
|
285
|
-
|
286
309
|
MessageHeader* other;
|
310
|
+
TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
|
287
311
|
TypedData_Get_Struct(_other, MessageHeader, &Message_type, other);
|
288
312
|
|
289
313
|
if (self->descriptor != other->descriptor) {
|
@@ -318,9 +342,10 @@ VALUE Message_hash(VALUE _self) {
|
|
318
342
|
*/
|
319
343
|
VALUE Message_inspect(VALUE _self) {
|
320
344
|
MessageHeader* self;
|
345
|
+
VALUE str;
|
321
346
|
TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
|
322
347
|
|
323
|
-
|
348
|
+
str = rb_str_new2("<");
|
324
349
|
str = rb_str_append(str, rb_str_new2(rb_class2name(CLASS_OF(_self))));
|
325
350
|
str = rb_str_cat2(str, ": ");
|
326
351
|
str = rb_str_append(str, layout_inspect(
|
@@ -329,6 +354,32 @@ VALUE Message_inspect(VALUE _self) {
|
|
329
354
|
return str;
|
330
355
|
}
|
331
356
|
|
357
|
+
|
358
|
+
VALUE Message_to_h(VALUE _self) {
|
359
|
+
MessageHeader* self;
|
360
|
+
VALUE hash;
|
361
|
+
upb_msg_field_iter it;
|
362
|
+
TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
|
363
|
+
|
364
|
+
hash = rb_hash_new();
|
365
|
+
|
366
|
+
for (upb_msg_field_begin(&it, self->descriptor->msgdef);
|
367
|
+
!upb_msg_field_done(&it);
|
368
|
+
upb_msg_field_next(&it)) {
|
369
|
+
const upb_fielddef* field = upb_msg_iter_field(&it);
|
370
|
+
VALUE msg_value = layout_get(self->descriptor->layout, Message_data(self),
|
371
|
+
field);
|
372
|
+
VALUE msg_key = ID2SYM(rb_intern(upb_fielddef_name(field)));
|
373
|
+
if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
|
374
|
+
msg_value = RepeatedField_to_ary(msg_value);
|
375
|
+
}
|
376
|
+
rb_hash_aset(hash, msg_key, msg_value);
|
377
|
+
}
|
378
|
+
return hash;
|
379
|
+
}
|
380
|
+
|
381
|
+
|
382
|
+
|
332
383
|
/*
|
333
384
|
* call-seq:
|
334
385
|
* Message.[](index) => value
|
@@ -338,10 +389,10 @@ VALUE Message_inspect(VALUE _self) {
|
|
338
389
|
*/
|
339
390
|
VALUE Message_index(VALUE _self, VALUE field_name) {
|
340
391
|
MessageHeader* self;
|
392
|
+
const upb_fielddef* field;
|
341
393
|
TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
|
342
394
|
Check_Type(field_name, T_STRING);
|
343
|
-
|
344
|
-
upb_msgdef_ntofz(self->descriptor->msgdef, RSTRING_PTR(field_name));
|
395
|
+
field = upb_msgdef_ntofz(self->descriptor->msgdef, RSTRING_PTR(field_name));
|
345
396
|
if (field == NULL) {
|
346
397
|
return Qnil;
|
347
398
|
}
|
@@ -357,10 +408,10 @@ VALUE Message_index(VALUE _self, VALUE field_name) {
|
|
357
408
|
*/
|
358
409
|
VALUE Message_index_set(VALUE _self, VALUE field_name, VALUE value) {
|
359
410
|
MessageHeader* self;
|
411
|
+
const upb_fielddef* field;
|
360
412
|
TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
|
361
413
|
Check_Type(field_name, T_STRING);
|
362
|
-
|
363
|
-
upb_msgdef_ntofz(self->descriptor->msgdef, RSTRING_PTR(field_name));
|
414
|
+
field = upb_msgdef_ntofz(self->descriptor->msgdef, RSTRING_PTR(field_name));
|
364
415
|
if (field == NULL) {
|
365
416
|
rb_raise(rb_eArgError, "Unknown field: %s", RSTRING_PTR(field_name));
|
366
417
|
}
|
@@ -376,10 +427,13 @@ VALUE Message_index_set(VALUE _self, VALUE field_name, VALUE value) {
|
|
376
427
|
* message class's type.
|
377
428
|
*/
|
378
429
|
VALUE Message_descriptor(VALUE klass) {
|
379
|
-
return
|
430
|
+
return rb_ivar_get(klass, descriptor_instancevar_interned);
|
380
431
|
}
|
381
432
|
|
382
433
|
VALUE build_class_from_descriptor(Descriptor* desc) {
|
434
|
+
const char *name;
|
435
|
+
VALUE klass;
|
436
|
+
|
383
437
|
if (desc->layout == NULL) {
|
384
438
|
desc->layout = create_layout(desc->msgdef);
|
385
439
|
}
|
@@ -387,18 +441,24 @@ VALUE build_class_from_descriptor(Descriptor* desc) {
|
|
387
441
|
desc->fill_method = new_fillmsg_decodermethod(desc, &desc->fill_method);
|
388
442
|
}
|
389
443
|
|
390
|
-
|
444
|
+
name = upb_msgdef_fullname(desc->msgdef);
|
391
445
|
if (name == NULL) {
|
392
446
|
rb_raise(rb_eRuntimeError, "Descriptor does not have assigned name.");
|
393
447
|
}
|
394
448
|
|
395
|
-
|
449
|
+
klass = rb_define_class_id(
|
396
450
|
// Docs say this parameter is ignored. User will assign return value to
|
397
451
|
// their own toplevel constant class name.
|
398
452
|
rb_intern("Message"),
|
399
453
|
rb_cObject);
|
400
|
-
|
454
|
+
rb_ivar_set(klass, descriptor_instancevar_interned,
|
455
|
+
get_def_obj(desc->msgdef));
|
401
456
|
rb_define_alloc_func(klass, Message_alloc);
|
457
|
+
rb_require("google/protobuf/message_exts");
|
458
|
+
rb_include_module(klass, rb_eval_string("Google::Protobuf::MessageExts"));
|
459
|
+
rb_extend_object(
|
460
|
+
klass, rb_eval_string("Google::Protobuf::MessageExts::ClassMethods"));
|
461
|
+
|
402
462
|
rb_define_method(klass, "method_missing",
|
403
463
|
Message_method_missing, -1);
|
404
464
|
rb_define_method(klass, "initialize", Message_initialize, -1);
|
@@ -407,6 +467,8 @@ VALUE build_class_from_descriptor(Descriptor* desc) {
|
|
407
467
|
rb_define_method(klass, "clone", Message_dup, 0);
|
408
468
|
rb_define_method(klass, "==", Message_eq, 1);
|
409
469
|
rb_define_method(klass, "hash", Message_hash, 0);
|
470
|
+
rb_define_method(klass, "to_h", Message_to_h, 0);
|
471
|
+
rb_define_method(klass, "to_hash", Message_to_h, 0);
|
410
472
|
rb_define_method(klass, "inspect", Message_inspect, 0);
|
411
473
|
rb_define_method(klass, "[]", Message_index, 1);
|
412
474
|
rb_define_method(klass, "[]=", Message_index_set, 2);
|
@@ -415,6 +477,7 @@ VALUE build_class_from_descriptor(Descriptor* desc) {
|
|
415
477
|
rb_define_singleton_method(klass, "decode_json", Message_decode_json, 1);
|
416
478
|
rb_define_singleton_method(klass, "encode_json", Message_encode_json, 1);
|
417
479
|
rb_define_singleton_method(klass, "descriptor", Message_descriptor, 0);
|
480
|
+
|
418
481
|
return klass;
|
419
482
|
}
|
420
483
|
|
@@ -427,7 +490,7 @@ VALUE build_class_from_descriptor(Descriptor* desc) {
|
|
427
490
|
*/
|
428
491
|
VALUE enum_lookup(VALUE self, VALUE number) {
|
429
492
|
int32_t num = NUM2INT(number);
|
430
|
-
VALUE desc =
|
493
|
+
VALUE desc = rb_ivar_get(self, descriptor_instancevar_interned);
|
431
494
|
EnumDescriptor* enumdesc = ruby_to_EnumDescriptor(desc);
|
432
495
|
|
433
496
|
const char* name = upb_enumdef_iton(enumdesc->enumdef, num);
|
@@ -447,7 +510,7 @@ VALUE enum_lookup(VALUE self, VALUE number) {
|
|
447
510
|
*/
|
448
511
|
VALUE enum_resolve(VALUE self, VALUE sym) {
|
449
512
|
const char* name = rb_id2name(SYM2ID(sym));
|
450
|
-
VALUE desc =
|
513
|
+
VALUE desc = rb_ivar_get(self, descriptor_instancevar_interned);
|
451
514
|
EnumDescriptor* enumdesc = ruby_to_EnumDescriptor(desc);
|
452
515
|
|
453
516
|
int32_t num = 0;
|
@@ -467,7 +530,7 @@ VALUE enum_resolve(VALUE self, VALUE sym) {
|
|
467
530
|
* EnumDescriptor corresponding to this enum type.
|
468
531
|
*/
|
469
532
|
VALUE enum_descriptor(VALUE self) {
|
470
|
-
return
|
533
|
+
return rb_ivar_get(self, descriptor_instancevar_interned);
|
471
534
|
}
|
472
535
|
|
473
536
|
VALUE build_module_from_enumdesc(EnumDescriptor* enumdesc) {
|
@@ -492,7 +555,8 @@ VALUE build_module_from_enumdesc(EnumDescriptor* enumdesc) {
|
|
492
555
|
rb_define_singleton_method(mod, "lookup", enum_lookup, 1);
|
493
556
|
rb_define_singleton_method(mod, "resolve", enum_resolve, 1);
|
494
557
|
rb_define_singleton_method(mod, "descriptor", enum_descriptor, 0);
|
495
|
-
|
558
|
+
rb_ivar_set(mod, descriptor_instancevar_interned,
|
559
|
+
get_def_obj(enumdesc->enumdef));
|
496
560
|
|
497
561
|
return mod;
|
498
562
|
}
|