google-protobuf 3.17.0 → 3.23.3
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/convert.c +128 -116
- data/ext/google/protobuf_c/convert.h +12 -9
- data/ext/google/protobuf_c/defs.c +235 -1529
- data/ext/google/protobuf_c/defs.h +19 -19
- data/ext/google/protobuf_c/extconf.rb +12 -6
- data/ext/google/protobuf_c/map.c +108 -110
- data/ext/google/protobuf_c/map.h +7 -7
- data/ext/google/protobuf_c/message.c +456 -343
- data/ext/google/protobuf_c/message.h +22 -19
- data/ext/google/protobuf_c/protobuf.c +78 -56
- data/ext/google/protobuf_c/protobuf.h +16 -9
- data/ext/google/protobuf_c/repeated_field.c +85 -85
- data/ext/google/protobuf_c/repeated_field.h +6 -5
- data/ext/google/protobuf_c/ruby-upb.c +11806 -6746
- data/ext/google/protobuf_c/ruby-upb.h +10860 -3532
- data/ext/google/protobuf_c/third_party/utf8_range/LICENSE +22 -0
- data/ext/google/protobuf_c/third_party/utf8_range/naive.c +92 -0
- data/ext/google/protobuf_c/third_party/utf8_range/range2-neon.c +157 -0
- data/ext/google/protobuf_c/third_party/utf8_range/range2-sse.c +170 -0
- data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +21 -0
- data/ext/google/protobuf_c/wrap_memcpy.c +4 -3
- data/lib/google/protobuf/any_pb.rb +24 -5
- data/lib/google/protobuf/api_pb.rb +27 -23
- data/lib/google/protobuf/descriptor_dsl.rb +465 -0
- data/lib/google/protobuf/descriptor_pb.rb +75 -0
- data/lib/google/protobuf/duration_pb.rb +24 -5
- data/lib/google/protobuf/empty_pb.rb +24 -3
- data/lib/google/protobuf/field_mask_pb.rb +24 -4
- data/lib/google/protobuf/message_exts.rb +7 -2
- data/lib/google/protobuf/plugin_pb.rb +47 -0
- data/lib/google/protobuf/repeated_field.rb +15 -2
- data/lib/google/protobuf/source_context_pb.rb +24 -4
- data/lib/google/protobuf/struct_pb.rb +24 -20
- data/lib/google/protobuf/timestamp_pb.rb +24 -5
- data/lib/google/protobuf/type_pb.rb +27 -68
- data/lib/google/protobuf/well_known_types.rb +12 -2
- data/lib/google/protobuf/wrappers_pb.rb +24 -28
- data/lib/google/protobuf.rb +5 -73
- metadata +17 -36
- data/ext/google/protobuf_c/third_party/wyhash/wyhash.h +0 -145
- data/tests/basic.rb +0 -604
- data/tests/generated_code_test.rb +0 -23
- data/tests/stress.rb +0 -38
@@ -36,23 +36,16 @@
|
|
36
36
|
#include "message.h"
|
37
37
|
#include "protobuf.h"
|
38
38
|
|
39
|
-
static VALUE Builder_build(VALUE _self);
|
40
|
-
|
41
|
-
static VALUE cMessageBuilderContext;
|
42
|
-
static VALUE cOneofBuilderContext;
|
43
|
-
static VALUE cEnumBuilderContext;
|
44
|
-
static VALUE cBuilder;
|
45
|
-
|
46
39
|
// -----------------------------------------------------------------------------
|
47
40
|
// Global map from upb {msg,enum}defs to wrapper Descriptor/EnumDescriptor
|
48
41
|
// instances.
|
49
42
|
// -----------------------------------------------------------------------------
|
50
43
|
|
51
|
-
static VALUE get_msgdef_obj(VALUE descriptor_pool, const
|
52
|
-
static VALUE get_enumdef_obj(VALUE descriptor_pool, const
|
53
|
-
static VALUE get_fielddef_obj(VALUE descriptor_pool, const
|
54
|
-
static VALUE get_filedef_obj(VALUE descriptor_pool, const
|
55
|
-
static VALUE get_oneofdef_obj(VALUE descriptor_pool, const
|
44
|
+
static VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_MessageDef* def);
|
45
|
+
static VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_EnumDef* def);
|
46
|
+
static VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_FieldDef* def);
|
47
|
+
static VALUE get_filedef_obj(VALUE descriptor_pool, const upb_FileDef* def);
|
48
|
+
static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_OneofDef* def);
|
56
49
|
|
57
50
|
// A distinct object that is not accessible from Ruby. We use this as a
|
58
51
|
// constructor argument to enforce that certain objects cannot be created from
|
@@ -75,174 +68,13 @@ static VALUE rb_str_maybe_null(const char* s) {
|
|
75
68
|
return rb_str_new2(s);
|
76
69
|
}
|
77
70
|
|
78
|
-
// -----------------------------------------------------------------------------
|
79
|
-
// Backward compatibility code.
|
80
|
-
// -----------------------------------------------------------------------------
|
81
|
-
|
82
|
-
static void rewrite_enum_default(const upb_symtab* symtab,
|
83
|
-
google_protobuf_FileDescriptorProto* file,
|
84
|
-
google_protobuf_FieldDescriptorProto* field) {
|
85
|
-
upb_strview defaultval;
|
86
|
-
const char *type_name_str;
|
87
|
-
char *end;
|
88
|
-
long val;
|
89
|
-
const upb_enumdef *e;
|
90
|
-
upb_strview type_name;
|
91
|
-
|
92
|
-
/* Look for TYPE_ENUM fields that have a default. */
|
93
|
-
if (google_protobuf_FieldDescriptorProto_type(field) !=
|
94
|
-
google_protobuf_FieldDescriptorProto_TYPE_ENUM ||
|
95
|
-
!google_protobuf_FieldDescriptorProto_has_default_value(field) ||
|
96
|
-
!google_protobuf_FieldDescriptorProto_has_type_name(field)) {
|
97
|
-
return;
|
98
|
-
}
|
99
|
-
|
100
|
-
defaultval = google_protobuf_FieldDescriptorProto_default_value(field);
|
101
|
-
type_name = google_protobuf_FieldDescriptorProto_type_name(field);
|
102
|
-
|
103
|
-
if (defaultval.size == 0 || !isdigit(defaultval.data[0])) {
|
104
|
-
return;
|
105
|
-
}
|
106
|
-
|
107
|
-
if (type_name.size == 0 || type_name.data[0] != '.') {
|
108
|
-
return;
|
109
|
-
}
|
110
|
-
|
111
|
-
type_name_str = type_name.data + 1;
|
112
|
-
|
113
|
-
errno = 0;
|
114
|
-
val = strtol(defaultval.data, &end, 10);
|
115
|
-
|
116
|
-
if (errno != 0 || *end != 0 || val < INT32_MIN || val > INT32_MAX) {
|
117
|
-
return;
|
118
|
-
}
|
119
|
-
|
120
|
-
/* Now find the corresponding enum definition. */
|
121
|
-
e = upb_symtab_lookupenum(symtab, type_name_str);
|
122
|
-
if (e) {
|
123
|
-
/* Look in previously loaded files. */
|
124
|
-
const char *label = upb_enumdef_iton(e, val);
|
125
|
-
if (!label) {
|
126
|
-
return;
|
127
|
-
}
|
128
|
-
google_protobuf_FieldDescriptorProto_set_default_value(
|
129
|
-
field, upb_strview_makez(label));
|
130
|
-
} else {
|
131
|
-
/* Look in enums defined in this file. */
|
132
|
-
const google_protobuf_EnumDescriptorProto* matching_enum = NULL;
|
133
|
-
size_t i, n;
|
134
|
-
const google_protobuf_EnumDescriptorProto* const* enums =
|
135
|
-
google_protobuf_FileDescriptorProto_enum_type(file, &n);
|
136
|
-
const google_protobuf_EnumValueDescriptorProto* const* values;
|
137
|
-
|
138
|
-
for (i = 0; i < n; i++) {
|
139
|
-
if (upb_strview_eql(google_protobuf_EnumDescriptorProto_name(enums[i]),
|
140
|
-
upb_strview_makez(type_name_str))) {
|
141
|
-
matching_enum = enums[i];
|
142
|
-
break;
|
143
|
-
}
|
144
|
-
}
|
145
|
-
|
146
|
-
if (!matching_enum) {
|
147
|
-
return;
|
148
|
-
}
|
149
|
-
|
150
|
-
values = google_protobuf_EnumDescriptorProto_value(matching_enum, &n);
|
151
|
-
for (i = 0; i < n; i++) {
|
152
|
-
if (google_protobuf_EnumValueDescriptorProto_number(values[i]) == val) {
|
153
|
-
google_protobuf_FieldDescriptorProto_set_default_value(
|
154
|
-
field, google_protobuf_EnumValueDescriptorProto_name(values[i]));
|
155
|
-
return;
|
156
|
-
}
|
157
|
-
}
|
158
|
-
|
159
|
-
/* We failed to find an enum default. But we'll just leave the enum
|
160
|
-
* untouched and let the normal def-building code catch it. */
|
161
|
-
}
|
162
|
-
}
|
163
|
-
|
164
|
-
/* Historically we allowed enum defaults to be specified as a number. In
|
165
|
-
* retrospect this was a mistake as descriptors require defaults to be
|
166
|
-
* specified as a label. This can make a difference if multiple labels have the
|
167
|
-
* same number.
|
168
|
-
*
|
169
|
-
* Here we do a pass over all enum defaults and rewrite numeric defaults by
|
170
|
-
* looking up their labels. This is complicated by the fact that the enum
|
171
|
-
* definition can live in either the symtab or the file_proto.
|
172
|
-
* */
|
173
|
-
static void rewrite_enum_defaults(
|
174
|
-
const upb_symtab* symtab, google_protobuf_FileDescriptorProto* file_proto) {
|
175
|
-
size_t i, n;
|
176
|
-
google_protobuf_DescriptorProto** msgs =
|
177
|
-
google_protobuf_FileDescriptorProto_mutable_message_type(file_proto, &n);
|
178
|
-
|
179
|
-
for (i = 0; i < n; i++) {
|
180
|
-
size_t j, m;
|
181
|
-
google_protobuf_FieldDescriptorProto** fields =
|
182
|
-
google_protobuf_DescriptorProto_mutable_field(msgs[i], &m);
|
183
|
-
for (j = 0; j < m; j++) {
|
184
|
-
rewrite_enum_default(symtab, file_proto, fields[j]);
|
185
|
-
}
|
186
|
-
}
|
187
|
-
}
|
188
|
-
|
189
|
-
static void remove_path(upb_strview *name) {
|
190
|
-
const char* last = strrchr(name->data, '.');
|
191
|
-
if (last) {
|
192
|
-
size_t remove = last - name->data + 1;
|
193
|
-
name->data += remove;
|
194
|
-
name->size -= remove;
|
195
|
-
}
|
196
|
-
}
|
197
|
-
|
198
|
-
static void rewrite_nesting(VALUE msg_ent, google_protobuf_DescriptorProto* msg,
|
199
|
-
google_protobuf_DescriptorProto* const* msgs,
|
200
|
-
google_protobuf_EnumDescriptorProto* const* enums,
|
201
|
-
upb_arena *arena) {
|
202
|
-
VALUE submsgs = rb_hash_aref(msg_ent, ID2SYM(rb_intern("msgs")));
|
203
|
-
VALUE enum_pos = rb_hash_aref(msg_ent, ID2SYM(rb_intern("enums")));
|
204
|
-
int submsg_count;
|
205
|
-
int enum_count;
|
206
|
-
int i;
|
207
|
-
google_protobuf_DescriptorProto** msg_msgs;
|
208
|
-
google_protobuf_EnumDescriptorProto** msg_enums;
|
209
|
-
|
210
|
-
Check_Type(submsgs, T_ARRAY);
|
211
|
-
Check_Type(enum_pos, T_ARRAY);
|
212
|
-
|
213
|
-
submsg_count = RARRAY_LEN(submsgs);
|
214
|
-
enum_count = RARRAY_LEN(enum_pos);
|
215
|
-
|
216
|
-
msg_msgs = google_protobuf_DescriptorProto_resize_nested_type(
|
217
|
-
msg, submsg_count, arena);
|
218
|
-
msg_enums =
|
219
|
-
google_protobuf_DescriptorProto_resize_enum_type(msg, enum_count, arena);
|
220
|
-
|
221
|
-
for (i = 0; i < submsg_count; i++) {
|
222
|
-
VALUE submsg_ent = RARRAY_PTR(submsgs)[i];
|
223
|
-
VALUE pos = rb_hash_aref(submsg_ent, ID2SYM(rb_intern("pos")));
|
224
|
-
upb_strview name;
|
225
|
-
|
226
|
-
msg_msgs[i] = msgs[NUM2INT(pos)];
|
227
|
-
name = google_protobuf_DescriptorProto_name(msg_msgs[i]);
|
228
|
-
remove_path(&name);
|
229
|
-
google_protobuf_DescriptorProto_set_name(msg_msgs[i], name);
|
230
|
-
rewrite_nesting(submsg_ent, msg_msgs[i], msgs, enums, arena);
|
231
|
-
}
|
232
|
-
|
233
|
-
for (i = 0; i < enum_count; i++) {
|
234
|
-
VALUE pos = RARRAY_PTR(enum_pos)[i];
|
235
|
-
msg_enums[i] = enums[NUM2INT(pos)];
|
236
|
-
}
|
237
|
-
}
|
238
|
-
|
239
71
|
// -----------------------------------------------------------------------------
|
240
72
|
// DescriptorPool.
|
241
73
|
// -----------------------------------------------------------------------------
|
242
74
|
|
243
75
|
typedef struct {
|
244
76
|
VALUE def_to_descriptor; // Hash table of def* -> Ruby descriptor.
|
245
|
-
|
77
|
+
upb_DefPool* symtab;
|
246
78
|
} DescriptorPool;
|
247
79
|
|
248
80
|
VALUE cDescriptorPool = Qnil;
|
@@ -258,14 +90,14 @@ static void DescriptorPool_mark(void* _self) {
|
|
258
90
|
|
259
91
|
static void DescriptorPool_free(void* _self) {
|
260
92
|
DescriptorPool* self = _self;
|
261
|
-
|
93
|
+
upb_DefPool_Free(self->symtab);
|
262
94
|
xfree(self);
|
263
95
|
}
|
264
96
|
|
265
97
|
static const rb_data_type_t DescriptorPool_type = {
|
266
|
-
|
267
|
-
|
268
|
-
|
98
|
+
"Google::Protobuf::DescriptorPool",
|
99
|
+
{DescriptorPool_mark, DescriptorPool_free, NULL},
|
100
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
269
101
|
};
|
270
102
|
|
271
103
|
static DescriptorPool* ruby_to_DescriptorPool(VALUE val) {
|
@@ -275,8 +107,8 @@ static DescriptorPool* ruby_to_DescriptorPool(VALUE val) {
|
|
275
107
|
}
|
276
108
|
|
277
109
|
// Exposed to other modules in defs.h.
|
278
|
-
const
|
279
|
-
DescriptorPool
|
110
|
+
const upb_DefPool* DescriptorPool_GetSymtab(VALUE desc_pool_rb) {
|
111
|
+
DescriptorPool* pool = ruby_to_DescriptorPool(desc_pool_rb);
|
280
112
|
return pool->symtab;
|
281
113
|
}
|
282
114
|
|
@@ -294,7 +126,7 @@ static VALUE DescriptorPool_alloc(VALUE klass) {
|
|
294
126
|
ret = TypedData_Wrap_Struct(klass, &DescriptorPool_type, self);
|
295
127
|
|
296
128
|
self->def_to_descriptor = rb_hash_new();
|
297
|
-
self->symtab =
|
129
|
+
self->symtab = upb_DefPool_New();
|
298
130
|
ObjectCache_Add(self->symtab, ret);
|
299
131
|
|
300
132
|
return ret;
|
@@ -302,20 +134,33 @@ static VALUE DescriptorPool_alloc(VALUE klass) {
|
|
302
134
|
|
303
135
|
/*
|
304
136
|
* call-seq:
|
305
|
-
* DescriptorPool.
|
137
|
+
* DescriptorPool.add_serialized_file(serialized_file_proto)
|
306
138
|
*
|
307
|
-
*
|
308
|
-
* added within the block are committed to the pool atomically, and may refer
|
309
|
-
* (co)recursively to each other. The user should call Builder#add_message and
|
310
|
-
* Builder#add_enum within the block as appropriate. This is the recommended,
|
311
|
-
* idiomatic way to define new message and enum types.
|
139
|
+
* Adds the given serialized FileDescriptorProto to the pool.
|
312
140
|
*/
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
141
|
+
VALUE DescriptorPool_add_serialized_file(VALUE _self,
|
142
|
+
VALUE serialized_file_proto) {
|
143
|
+
DescriptorPool* self = ruby_to_DescriptorPool(_self);
|
144
|
+
Check_Type(serialized_file_proto, T_STRING);
|
145
|
+
VALUE arena_rb = Arena_new();
|
146
|
+
upb_Arena* arena = Arena_get(arena_rb);
|
147
|
+
google_protobuf_FileDescriptorProto* file_proto =
|
148
|
+
google_protobuf_FileDescriptorProto_parse(
|
149
|
+
RSTRING_PTR(serialized_file_proto),
|
150
|
+
RSTRING_LEN(serialized_file_proto), arena);
|
151
|
+
if (!file_proto) {
|
152
|
+
rb_raise(rb_eArgError, "Unable to parse FileDescriptorProto");
|
153
|
+
}
|
154
|
+
upb_Status status;
|
155
|
+
upb_Status_Clear(&status);
|
156
|
+
const upb_FileDef* filedef =
|
157
|
+
upb_DefPool_AddFile(self->symtab, file_proto, &status);
|
158
|
+
if (!filedef) {
|
159
|
+
rb_raise(cTypeError, "Unable to build file to DescriptorPool: %s",
|
160
|
+
upb_Status_ErrorMessage(&status));
|
161
|
+
}
|
162
|
+
RB_GC_GUARD(arena_rb);
|
163
|
+
return get_filedef_obj(_self, filedef);
|
319
164
|
}
|
320
165
|
|
321
166
|
/*
|
@@ -328,15 +173,15 @@ static VALUE DescriptorPool_build(int argc, VALUE* argv, VALUE _self) {
|
|
328
173
|
static VALUE DescriptorPool_lookup(VALUE _self, VALUE name) {
|
329
174
|
DescriptorPool* self = ruby_to_DescriptorPool(_self);
|
330
175
|
const char* name_str = get_str(name);
|
331
|
-
const
|
332
|
-
const
|
176
|
+
const upb_MessageDef* msgdef;
|
177
|
+
const upb_EnumDef* enumdef;
|
333
178
|
|
334
|
-
msgdef =
|
179
|
+
msgdef = upb_DefPool_FindMessageByName(self->symtab, name_str);
|
335
180
|
if (msgdef) {
|
336
181
|
return get_msgdef_obj(_self, msgdef);
|
337
182
|
}
|
338
183
|
|
339
|
-
enumdef =
|
184
|
+
enumdef = upb_DefPool_FindEnumByName(self->symtab, name_str);
|
340
185
|
if (enumdef) {
|
341
186
|
return get_enumdef_obj(_self, enumdef);
|
342
187
|
}
|
@@ -358,10 +203,10 @@ static VALUE DescriptorPool_generated_pool(VALUE _self) {
|
|
358
203
|
}
|
359
204
|
|
360
205
|
static void DescriptorPool_register(VALUE module) {
|
361
|
-
VALUE klass = rb_define_class_under(
|
362
|
-
module, "DescriptorPool", rb_cObject);
|
206
|
+
VALUE klass = rb_define_class_under(module, "DescriptorPool", rb_cObject);
|
363
207
|
rb_define_alloc_func(klass, DescriptorPool_alloc);
|
364
|
-
rb_define_method(klass, "
|
208
|
+
rb_define_method(klass, "add_serialized_file",
|
209
|
+
DescriptorPool_add_serialized_file, 1);
|
365
210
|
rb_define_method(klass, "lookup", DescriptorPool_lookup, 1);
|
366
211
|
rb_define_singleton_method(klass, "generated_pool",
|
367
212
|
DescriptorPool_generated_pool, 0);
|
@@ -377,7 +222,9 @@ static void DescriptorPool_register(VALUE module) {
|
|
377
222
|
// -----------------------------------------------------------------------------
|
378
223
|
|
379
224
|
typedef struct {
|
380
|
-
const
|
225
|
+
const upb_MessageDef* msgdef;
|
226
|
+
// IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
|
227
|
+
// macro to update VALUE references, as to trigger write barriers.
|
381
228
|
VALUE klass;
|
382
229
|
VALUE descriptor_pool;
|
383
230
|
} Descriptor;
|
@@ -391,9 +238,9 @@ static void Descriptor_mark(void* _self) {
|
|
391
238
|
}
|
392
239
|
|
393
240
|
static const rb_data_type_t Descriptor_type = {
|
394
|
-
|
395
|
-
|
396
|
-
|
241
|
+
"Google::Protobuf::Descriptor",
|
242
|
+
{Descriptor_mark, RUBY_DEFAULT_FREE, NULL},
|
243
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
397
244
|
};
|
398
245
|
|
399
246
|
static Descriptor* ruby_to_Descriptor(VALUE val) {
|
@@ -435,8 +282,8 @@ static VALUE Descriptor_initialize(VALUE _self, VALUE cookie,
|
|
435
282
|
"Descriptor objects may not be created from Ruby.");
|
436
283
|
}
|
437
284
|
|
438
|
-
self->descriptor_pool
|
439
|
-
self->msgdef = (const
|
285
|
+
RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool);
|
286
|
+
self->msgdef = (const upb_MessageDef*)NUM2ULL(ptr);
|
440
287
|
|
441
288
|
return Qnil;
|
442
289
|
}
|
@@ -449,7 +296,8 @@ static VALUE Descriptor_initialize(VALUE _self, VALUE cookie,
|
|
449
296
|
*/
|
450
297
|
static VALUE Descriptor_file_descriptor(VALUE _self) {
|
451
298
|
Descriptor* self = ruby_to_Descriptor(_self);
|
452
|
-
return get_filedef_obj(self->descriptor_pool,
|
299
|
+
return get_filedef_obj(self->descriptor_pool,
|
300
|
+
upb_MessageDef_File(self->msgdef));
|
453
301
|
}
|
454
302
|
|
455
303
|
/*
|
@@ -461,7 +309,7 @@ static VALUE Descriptor_file_descriptor(VALUE _self) {
|
|
461
309
|
*/
|
462
310
|
static VALUE Descriptor_name(VALUE _self) {
|
463
311
|
Descriptor* self = ruby_to_Descriptor(_self);
|
464
|
-
return rb_str_maybe_null(
|
312
|
+
return rb_str_maybe_null(upb_MessageDef_FullName(self->msgdef));
|
465
313
|
}
|
466
314
|
|
467
315
|
/*
|
@@ -473,11 +321,9 @@ static VALUE Descriptor_name(VALUE _self) {
|
|
473
321
|
static VALUE Descriptor_each(VALUE _self) {
|
474
322
|
Descriptor* self = ruby_to_Descriptor(_self);
|
475
323
|
|
476
|
-
|
477
|
-
for (
|
478
|
-
|
479
|
-
upb_msg_field_next(&it)) {
|
480
|
-
const upb_fielddef* field = upb_msg_iter_field(&it);
|
324
|
+
int n = upb_MessageDef_FieldCount(self->msgdef);
|
325
|
+
for (int i = 0; i < n; i++) {
|
326
|
+
const upb_FieldDef* field = upb_MessageDef_Field(self->msgdef, i);
|
481
327
|
VALUE obj = get_fielddef_obj(self->descriptor_pool, field);
|
482
328
|
rb_yield(obj);
|
483
329
|
}
|
@@ -494,7 +340,7 @@ static VALUE Descriptor_each(VALUE _self) {
|
|
494
340
|
static VALUE Descriptor_lookup(VALUE _self, VALUE name) {
|
495
341
|
Descriptor* self = ruby_to_Descriptor(_self);
|
496
342
|
const char* s = get_str(name);
|
497
|
-
const
|
343
|
+
const upb_FieldDef* field = upb_MessageDef_FindFieldByName(self->msgdef, s);
|
498
344
|
if (field == NULL) {
|
499
345
|
return Qnil;
|
500
346
|
}
|
@@ -511,11 +357,9 @@ static VALUE Descriptor_lookup(VALUE _self, VALUE name) {
|
|
511
357
|
static VALUE Descriptor_each_oneof(VALUE _self) {
|
512
358
|
Descriptor* self = ruby_to_Descriptor(_self);
|
513
359
|
|
514
|
-
|
515
|
-
for (
|
516
|
-
|
517
|
-
upb_msg_oneof_next(&it)) {
|
518
|
-
const upb_oneofdef* oneof = upb_msg_iter_oneof(&it);
|
360
|
+
int n = upb_MessageDef_OneofCount(self->msgdef);
|
361
|
+
for (int i = 0; i < n; i++) {
|
362
|
+
const upb_OneofDef* oneof = upb_MessageDef_Oneof(self->msgdef, i);
|
519
363
|
VALUE obj = get_oneofdef_obj(self->descriptor_pool, oneof);
|
520
364
|
rb_yield(obj);
|
521
365
|
}
|
@@ -532,7 +376,7 @@ static VALUE Descriptor_each_oneof(VALUE _self) {
|
|
532
376
|
static VALUE Descriptor_lookup_oneof(VALUE _self, VALUE name) {
|
533
377
|
Descriptor* self = ruby_to_Descriptor(_self);
|
534
378
|
const char* s = get_str(name);
|
535
|
-
const
|
379
|
+
const upb_OneofDef* oneof = upb_MessageDef_FindOneofByName(self->msgdef, s);
|
536
380
|
if (oneof == NULL) {
|
537
381
|
return Qnil;
|
538
382
|
}
|
@@ -548,14 +392,13 @@ static VALUE Descriptor_lookup_oneof(VALUE _self, VALUE name) {
|
|
548
392
|
static VALUE Descriptor_msgclass(VALUE _self) {
|
549
393
|
Descriptor* self = ruby_to_Descriptor(_self);
|
550
394
|
if (self->klass == Qnil) {
|
551
|
-
self->klass
|
395
|
+
RB_OBJ_WRITE(_self, &self->klass, build_class_from_descriptor(_self));
|
552
396
|
}
|
553
397
|
return self->klass;
|
554
398
|
}
|
555
399
|
|
556
400
|
static void Descriptor_register(VALUE module) {
|
557
|
-
VALUE klass = rb_define_class_under(
|
558
|
-
module, "Descriptor", rb_cObject);
|
401
|
+
VALUE klass = rb_define_class_under(module, "Descriptor", rb_cObject);
|
559
402
|
rb_define_alloc_func(klass, Descriptor_alloc);
|
560
403
|
rb_define_method(klass, "initialize", Descriptor_initialize, 3);
|
561
404
|
rb_define_method(klass, "each", Descriptor_each, 0);
|
@@ -575,8 +418,10 @@ static void Descriptor_register(VALUE module) {
|
|
575
418
|
// -----------------------------------------------------------------------------
|
576
419
|
|
577
420
|
typedef struct {
|
578
|
-
const
|
579
|
-
|
421
|
+
const upb_FileDef* filedef;
|
422
|
+
// IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
|
423
|
+
// macro to update VALUE references, as to trigger write barriers.
|
424
|
+
VALUE descriptor_pool; // Owns the upb_FileDef.
|
580
425
|
} FileDescriptor;
|
581
426
|
|
582
427
|
static VALUE cFileDescriptor = Qnil;
|
@@ -587,9 +432,9 @@ static void FileDescriptor_mark(void* _self) {
|
|
587
432
|
}
|
588
433
|
|
589
434
|
static const rb_data_type_t FileDescriptor_type = {
|
590
|
-
|
591
|
-
|
592
|
-
|
435
|
+
"Google::Protobuf::FileDescriptor",
|
436
|
+
{FileDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
|
437
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
593
438
|
};
|
594
439
|
|
595
440
|
static FileDescriptor* ruby_to_FileDescriptor(VALUE val) {
|
@@ -614,7 +459,7 @@ static VALUE FileDescriptor_alloc(VALUE klass) {
|
|
614
459
|
* to a builder.
|
615
460
|
*/
|
616
461
|
static VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie,
|
617
|
-
|
462
|
+
VALUE descriptor_pool, VALUE ptr) {
|
618
463
|
FileDescriptor* self = ruby_to_FileDescriptor(_self);
|
619
464
|
|
620
465
|
if (cookie != c_only_cookie) {
|
@@ -622,8 +467,8 @@ static VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie,
|
|
622
467
|
"Descriptor objects may not be created from Ruby.");
|
623
468
|
}
|
624
469
|
|
625
|
-
self->descriptor_pool
|
626
|
-
self->filedef = (const
|
470
|
+
RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool);
|
471
|
+
self->filedef = (const upb_FileDef*)NUM2ULL(ptr);
|
627
472
|
|
628
473
|
return Qnil;
|
629
474
|
}
|
@@ -636,7 +481,7 @@ static VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie,
|
|
636
481
|
*/
|
637
482
|
static VALUE FileDescriptor_name(VALUE _self) {
|
638
483
|
FileDescriptor* self = ruby_to_FileDescriptor(_self);
|
639
|
-
const char* name =
|
484
|
+
const char* name = upb_FileDef_Name(self->filedef);
|
640
485
|
return name == NULL ? Qnil : rb_str_new2(name);
|
641
486
|
}
|
642
487
|
|
@@ -652,16 +497,18 @@ static VALUE FileDescriptor_name(VALUE _self) {
|
|
652
497
|
static VALUE FileDescriptor_syntax(VALUE _self) {
|
653
498
|
FileDescriptor* self = ruby_to_FileDescriptor(_self);
|
654
499
|
|
655
|
-
switch (
|
656
|
-
case
|
657
|
-
|
658
|
-
|
500
|
+
switch (upb_FileDef_Syntax(self->filedef)) {
|
501
|
+
case kUpb_Syntax_Proto3:
|
502
|
+
return ID2SYM(rb_intern("proto3"));
|
503
|
+
case kUpb_Syntax_Proto2:
|
504
|
+
return ID2SYM(rb_intern("proto2"));
|
505
|
+
default:
|
506
|
+
return Qnil;
|
659
507
|
}
|
660
508
|
}
|
661
509
|
|
662
510
|
static void FileDescriptor_register(VALUE module) {
|
663
|
-
VALUE klass = rb_define_class_under(
|
664
|
-
module, "FileDescriptor", rb_cObject);
|
511
|
+
VALUE klass = rb_define_class_under(module, "FileDescriptor", rb_cObject);
|
665
512
|
rb_define_alloc_func(klass, FileDescriptor_alloc);
|
666
513
|
rb_define_method(klass, "initialize", FileDescriptor_initialize, 3);
|
667
514
|
rb_define_method(klass, "name", FileDescriptor_name, 0);
|
@@ -675,8 +522,10 @@ static void FileDescriptor_register(VALUE module) {
|
|
675
522
|
// -----------------------------------------------------------------------------
|
676
523
|
|
677
524
|
typedef struct {
|
678
|
-
const
|
679
|
-
|
525
|
+
const upb_FieldDef* fielddef;
|
526
|
+
// IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
|
527
|
+
// macro to update VALUE references, as to trigger write barriers.
|
528
|
+
VALUE descriptor_pool; // Owns the upb_FieldDef.
|
680
529
|
} FieldDescriptor;
|
681
530
|
|
682
531
|
static VALUE cFieldDescriptor = Qnil;
|
@@ -687,9 +536,9 @@ static void FieldDescriptor_mark(void* _self) {
|
|
687
536
|
}
|
688
537
|
|
689
538
|
static const rb_data_type_t FieldDescriptor_type = {
|
690
|
-
|
691
|
-
|
692
|
-
|
539
|
+
"Google::Protobuf::FieldDescriptor",
|
540
|
+
{FieldDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
|
541
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
693
542
|
};
|
694
543
|
|
695
544
|
static FieldDescriptor* ruby_to_FieldDescriptor(VALUE val) {
|
@@ -727,8 +576,8 @@ static VALUE FieldDescriptor_initialize(VALUE _self, VALUE cookie,
|
|
727
576
|
"Descriptor objects may not be created from Ruby.");
|
728
577
|
}
|
729
578
|
|
730
|
-
self->descriptor_pool
|
731
|
-
self->fielddef = (const
|
579
|
+
RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool);
|
580
|
+
self->fielddef = (const upb_FieldDef*)NUM2ULL(ptr);
|
732
581
|
|
733
582
|
return Qnil;
|
734
583
|
}
|
@@ -741,66 +590,31 @@ static VALUE FieldDescriptor_initialize(VALUE _self, VALUE cookie,
|
|
741
590
|
*/
|
742
591
|
static VALUE FieldDescriptor_name(VALUE _self) {
|
743
592
|
FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
|
744
|
-
return rb_str_maybe_null(
|
593
|
+
return rb_str_maybe_null(upb_FieldDef_Name(self->fielddef));
|
745
594
|
}
|
746
595
|
|
747
596
|
// Non-static, exposed to other .c files.
|
748
|
-
|
749
|
-
if (TYPE(type) != T_SYMBOL) {
|
750
|
-
rb_raise(rb_eArgError, "Expected symbol for field type.");
|
751
|
-
}
|
752
|
-
|
753
|
-
#define CONVERT(upb, ruby) \
|
754
|
-
if (SYM2ID(type) == rb_intern( # ruby )) { \
|
755
|
-
return UPB_TYPE_ ## upb; \
|
756
|
-
}
|
757
|
-
|
758
|
-
CONVERT(FLOAT, float);
|
759
|
-
CONVERT(DOUBLE, double);
|
760
|
-
CONVERT(BOOL, bool);
|
761
|
-
CONVERT(STRING, string);
|
762
|
-
CONVERT(BYTES, bytes);
|
763
|
-
CONVERT(MESSAGE, message);
|
764
|
-
CONVERT(ENUM, enum);
|
765
|
-
CONVERT(INT32, int32);
|
766
|
-
CONVERT(INT64, int64);
|
767
|
-
CONVERT(UINT32, uint32);
|
768
|
-
CONVERT(UINT64, uint64);
|
769
|
-
|
770
|
-
#undef CONVERT
|
771
|
-
|
772
|
-
rb_raise(rb_eArgError, "Unknown field type.");
|
773
|
-
return 0;
|
774
|
-
}
|
775
|
-
|
776
|
-
static upb_descriptortype_t ruby_to_descriptortype(VALUE type) {
|
597
|
+
upb_CType ruby_to_fieldtype(VALUE type) {
|
777
598
|
if (TYPE(type) != T_SYMBOL) {
|
778
599
|
rb_raise(rb_eArgError, "Expected symbol for field type.");
|
779
600
|
}
|
780
601
|
|
781
|
-
#define CONVERT(upb, ruby)
|
782
|
-
if (SYM2ID(type) == rb_intern(
|
783
|
-
return
|
602
|
+
#define CONVERT(upb, ruby) \
|
603
|
+
if (SYM2ID(type) == rb_intern(#ruby)) { \
|
604
|
+
return kUpb_CType_##upb; \
|
784
605
|
}
|
785
606
|
|
786
|
-
CONVERT(
|
787
|
-
CONVERT(
|
788
|
-
CONVERT(
|
789
|
-
CONVERT(
|
790
|
-
CONVERT(
|
791
|
-
CONVERT(
|
792
|
-
CONVERT(
|
793
|
-
CONVERT(
|
794
|
-
CONVERT(
|
795
|
-
CONVERT(
|
796
|
-
CONVERT(
|
797
|
-
CONVERT(UINT64, uint64);
|
798
|
-
CONVERT(SINT32, sint32);
|
799
|
-
CONVERT(SINT64, sint64);
|
800
|
-
CONVERT(FIXED32, fixed32);
|
801
|
-
CONVERT(FIXED64, fixed64);
|
802
|
-
CONVERT(SFIXED32, sfixed32);
|
803
|
-
CONVERT(SFIXED64, sfixed64);
|
607
|
+
CONVERT(Float, float);
|
608
|
+
CONVERT(Double, double);
|
609
|
+
CONVERT(Bool, bool);
|
610
|
+
CONVERT(String, string);
|
611
|
+
CONVERT(Bytes, bytes);
|
612
|
+
CONVERT(Message, message);
|
613
|
+
CONVERT(Enum, enum);
|
614
|
+
CONVERT(Int32, int32);
|
615
|
+
CONVERT(Int64, int64);
|
616
|
+
CONVERT(UInt32, uint32);
|
617
|
+
CONVERT(UInt64, uint64);
|
804
618
|
|
805
619
|
#undef CONVERT
|
806
620
|
|
@@ -808,28 +622,29 @@ static upb_descriptortype_t ruby_to_descriptortype(VALUE type) {
|
|
808
622
|
return 0;
|
809
623
|
}
|
810
624
|
|
811
|
-
static VALUE descriptortype_to_ruby(
|
625
|
+
static VALUE descriptortype_to_ruby(upb_FieldType type) {
|
812
626
|
switch (type) {
|
813
|
-
#define CONVERT(upb, ruby)
|
814
|
-
|
815
|
-
|
816
|
-
CONVERT(
|
817
|
-
CONVERT(
|
818
|
-
CONVERT(
|
819
|
-
CONVERT(
|
820
|
-
CONVERT(
|
821
|
-
CONVERT(
|
822
|
-
CONVERT(
|
823
|
-
CONVERT(
|
824
|
-
CONVERT(
|
825
|
-
CONVERT(
|
826
|
-
CONVERT(
|
827
|
-
CONVERT(
|
828
|
-
CONVERT(
|
829
|
-
CONVERT(
|
830
|
-
CONVERT(
|
831
|
-
CONVERT(
|
832
|
-
CONVERT(
|
627
|
+
#define CONVERT(upb, ruby) \
|
628
|
+
case kUpb_FieldType_##upb: \
|
629
|
+
return ID2SYM(rb_intern(#ruby));
|
630
|
+
CONVERT(Float, float);
|
631
|
+
CONVERT(Double, double);
|
632
|
+
CONVERT(Bool, bool);
|
633
|
+
CONVERT(String, string);
|
634
|
+
CONVERT(Bytes, bytes);
|
635
|
+
CONVERT(Message, message);
|
636
|
+
CONVERT(Group, group);
|
637
|
+
CONVERT(Enum, enum);
|
638
|
+
CONVERT(Int32, int32);
|
639
|
+
CONVERT(Int64, int64);
|
640
|
+
CONVERT(UInt32, uint32);
|
641
|
+
CONVERT(UInt64, uint64);
|
642
|
+
CONVERT(SInt32, sint32);
|
643
|
+
CONVERT(SInt64, sint64);
|
644
|
+
CONVERT(Fixed32, fixed32);
|
645
|
+
CONVERT(Fixed64, fixed64);
|
646
|
+
CONVERT(SFixed32, sfixed32);
|
647
|
+
CONVERT(SFixed64, sfixed64);
|
833
648
|
#undef CONVERT
|
834
649
|
}
|
835
650
|
return Qnil;
|
@@ -847,7 +662,7 @@ static VALUE descriptortype_to_ruby(upb_descriptortype_t type) {
|
|
847
662
|
*/
|
848
663
|
static VALUE FieldDescriptor__type(VALUE _self) {
|
849
664
|
FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
|
850
|
-
return descriptortype_to_ruby(
|
665
|
+
return descriptortype_to_ruby(upb_FieldDef_Type(self->fielddef));
|
851
666
|
}
|
852
667
|
|
853
668
|
/*
|
@@ -858,17 +673,16 @@ static VALUE FieldDescriptor__type(VALUE _self) {
|
|
858
673
|
*/
|
859
674
|
static VALUE FieldDescriptor_default(VALUE _self) {
|
860
675
|
FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
|
861
|
-
const
|
862
|
-
|
863
|
-
if (
|
676
|
+
const upb_FieldDef* f = self->fielddef;
|
677
|
+
upb_MessageValue default_val = {0};
|
678
|
+
if (upb_FieldDef_IsSubMessage(f)) {
|
864
679
|
return Qnil;
|
865
|
-
} else if (!
|
866
|
-
default_val =
|
680
|
+
} else if (!upb_FieldDef_IsRepeated(f)) {
|
681
|
+
default_val = upb_FieldDef_Default(f);
|
867
682
|
}
|
868
683
|
return Convert_UpbToRuby(default_val, TypeInfo_get(self->fielddef), Qnil);
|
869
684
|
}
|
870
685
|
|
871
|
-
|
872
686
|
/*
|
873
687
|
* call-seq:
|
874
688
|
* FieldDescriptor.json_name => json_name
|
@@ -877,8 +691,8 @@ static VALUE FieldDescriptor_default(VALUE _self) {
|
|
877
691
|
*/
|
878
692
|
static VALUE FieldDescriptor_json_name(VALUE _self) {
|
879
693
|
FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
|
880
|
-
const
|
881
|
-
const char
|
694
|
+
const upb_FieldDef* f = self->fielddef;
|
695
|
+
const char* json_name = upb_FieldDef_JsonName(f);
|
882
696
|
return rb_str_new2(json_name);
|
883
697
|
}
|
884
698
|
|
@@ -893,13 +707,14 @@ static VALUE FieldDescriptor_json_name(VALUE _self) {
|
|
893
707
|
*/
|
894
708
|
static VALUE FieldDescriptor_label(VALUE _self) {
|
895
709
|
FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
|
896
|
-
switch (
|
897
|
-
#define CONVERT(upb, ruby)
|
898
|
-
|
710
|
+
switch (upb_FieldDef_Label(self->fielddef)) {
|
711
|
+
#define CONVERT(upb, ruby) \
|
712
|
+
case kUpb_Label_##upb: \
|
713
|
+
return ID2SYM(rb_intern(#ruby));
|
899
714
|
|
900
|
-
CONVERT(
|
901
|
-
CONVERT(
|
902
|
-
CONVERT(
|
715
|
+
CONVERT(Optional, optional);
|
716
|
+
CONVERT(Required, required);
|
717
|
+
CONVERT(Repeated, repeated);
|
903
718
|
|
904
719
|
#undef CONVERT
|
905
720
|
}
|
@@ -915,7 +730,7 @@ static VALUE FieldDescriptor_label(VALUE _self) {
|
|
915
730
|
*/
|
916
731
|
static VALUE FieldDescriptor_number(VALUE _self) {
|
917
732
|
FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
|
918
|
-
return INT2NUM(
|
733
|
+
return INT2NUM(upb_FieldDef_Number(self->fielddef));
|
919
734
|
}
|
920
735
|
|
921
736
|
/*
|
@@ -929,13 +744,13 @@ static VALUE FieldDescriptor_number(VALUE _self) {
|
|
929
744
|
*/
|
930
745
|
static VALUE FieldDescriptor_submsg_name(VALUE _self) {
|
931
746
|
FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
|
932
|
-
switch (
|
933
|
-
case
|
747
|
+
switch (upb_FieldDef_CType(self->fielddef)) {
|
748
|
+
case kUpb_CType_Enum:
|
934
749
|
return rb_str_new2(
|
935
|
-
|
936
|
-
case
|
750
|
+
upb_EnumDef_FullName(upb_FieldDef_EnumSubDef(self->fielddef)));
|
751
|
+
case kUpb_CType_Message:
|
937
752
|
return rb_str_new2(
|
938
|
-
|
753
|
+
upb_MessageDef_FullName(upb_FieldDef_MessageSubDef(self->fielddef)));
|
939
754
|
default:
|
940
755
|
return Qnil;
|
941
756
|
}
|
@@ -952,13 +767,13 @@ static VALUE FieldDescriptor_submsg_name(VALUE _self) {
|
|
952
767
|
*/
|
953
768
|
static VALUE FieldDescriptor_subtype(VALUE _self) {
|
954
769
|
FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
|
955
|
-
switch (
|
956
|
-
case
|
770
|
+
switch (upb_FieldDef_CType(self->fielddef)) {
|
771
|
+
case kUpb_CType_Enum:
|
957
772
|
return get_enumdef_obj(self->descriptor_pool,
|
958
|
-
|
959
|
-
case
|
773
|
+
upb_FieldDef_EnumSubDef(self->fielddef));
|
774
|
+
case kUpb_CType_Message:
|
960
775
|
return get_msgdef_obj(self->descriptor_pool,
|
961
|
-
|
776
|
+
upb_FieldDef_MessageSubDef(self->fielddef));
|
962
777
|
default:
|
963
778
|
return Qnil;
|
964
779
|
}
|
@@ -973,11 +788,11 @@ static VALUE FieldDescriptor_subtype(VALUE _self) {
|
|
973
788
|
*/
|
974
789
|
static VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) {
|
975
790
|
FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
|
976
|
-
const
|
791
|
+
const upb_MessageDef* m;
|
977
792
|
|
978
793
|
Message_Get(msg_rb, &m);
|
979
794
|
|
980
|
-
if (m !=
|
795
|
+
if (m != upb_FieldDef_ContainingType(self->fielddef)) {
|
981
796
|
rb_raise(cTypeError, "get method called on wrong message type");
|
982
797
|
}
|
983
798
|
|
@@ -993,16 +808,16 @@ static VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) {
|
|
993
808
|
*/
|
994
809
|
static VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) {
|
995
810
|
FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
|
996
|
-
const
|
997
|
-
const
|
811
|
+
const upb_MessageDef* m;
|
812
|
+
const upb_MessageDef* msg = Message_Get(msg_rb, &m);
|
998
813
|
|
999
|
-
if (m !=
|
814
|
+
if (m != upb_FieldDef_ContainingType(self->fielddef)) {
|
1000
815
|
rb_raise(cTypeError, "has method called on wrong message type");
|
1001
|
-
} else if (!
|
816
|
+
} else if (!upb_FieldDef_HasPresence(self->fielddef)) {
|
1002
817
|
rb_raise(rb_eArgError, "does not track presence");
|
1003
818
|
}
|
1004
819
|
|
1005
|
-
return
|
820
|
+
return upb_Message_HasFieldByDef(msg, self->fielddef) ? Qtrue : Qfalse;
|
1006
821
|
}
|
1007
822
|
|
1008
823
|
/*
|
@@ -1013,14 +828,14 @@ static VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) {
|
|
1013
828
|
*/
|
1014
829
|
static VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb) {
|
1015
830
|
FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
|
1016
|
-
const
|
1017
|
-
|
831
|
+
const upb_MessageDef* m;
|
832
|
+
upb_MessageDef* msg = Message_GetMutable(msg_rb, &m);
|
1018
833
|
|
1019
|
-
if (m !=
|
834
|
+
if (m != upb_FieldDef_ContainingType(self->fielddef)) {
|
1020
835
|
rb_raise(cTypeError, "has method called on wrong message type");
|
1021
836
|
}
|
1022
837
|
|
1023
|
-
|
838
|
+
upb_Message_ClearFieldByDef(msg, self->fielddef);
|
1024
839
|
return Qnil;
|
1025
840
|
}
|
1026
841
|
|
@@ -1034,24 +849,23 @@ static VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb) {
|
|
1034
849
|
*/
|
1035
850
|
static VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) {
|
1036
851
|
FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
|
1037
|
-
const
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
852
|
+
const upb_MessageDef* m;
|
853
|
+
upb_MessageDef* msg = Message_GetMutable(msg_rb, &m);
|
854
|
+
upb_Arena* arena = Arena_get(Message_GetArena(msg_rb));
|
855
|
+
upb_MessageValue msgval;
|
1041
856
|
|
1042
|
-
if (m !=
|
857
|
+
if (m != upb_FieldDef_ContainingType(self->fielddef)) {
|
1043
858
|
rb_raise(cTypeError, "set method called on wrong message type");
|
1044
859
|
}
|
1045
860
|
|
1046
|
-
msgval = Convert_RubyToUpb(value,
|
861
|
+
msgval = Convert_RubyToUpb(value, upb_FieldDef_Name(self->fielddef),
|
1047
862
|
TypeInfo_get(self->fielddef), arena);
|
1048
|
-
|
863
|
+
upb_Message_SetFieldByDef(msg, self->fielddef, msgval, arena);
|
1049
864
|
return Qnil;
|
1050
865
|
}
|
1051
866
|
|
1052
867
|
static void FieldDescriptor_register(VALUE module) {
|
1053
|
-
VALUE klass = rb_define_class_under(
|
1054
|
-
module, "FieldDescriptor", rb_cObject);
|
868
|
+
VALUE klass = rb_define_class_under(module, "FieldDescriptor", rb_cObject);
|
1055
869
|
rb_define_alloc_func(klass, FieldDescriptor_alloc);
|
1056
870
|
rb_define_method(klass, "initialize", FieldDescriptor_initialize, 3);
|
1057
871
|
rb_define_method(klass, "name", FieldDescriptor_name, 0);
|
@@ -1075,8 +889,10 @@ static void FieldDescriptor_register(VALUE module) {
|
|
1075
889
|
// -----------------------------------------------------------------------------
|
1076
890
|
|
1077
891
|
typedef struct {
|
1078
|
-
const
|
1079
|
-
|
892
|
+
const upb_OneofDef* oneofdef;
|
893
|
+
// IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
|
894
|
+
// macro to update VALUE references, as to trigger write barriers.
|
895
|
+
VALUE descriptor_pool; // Owns the upb_OneofDef.
|
1080
896
|
} OneofDescriptor;
|
1081
897
|
|
1082
898
|
static VALUE cOneofDescriptor = Qnil;
|
@@ -1089,7 +905,7 @@ static void OneofDescriptor_mark(void* _self) {
|
|
1089
905
|
static const rb_data_type_t OneofDescriptor_type = {
|
1090
906
|
"Google::Protobuf::OneofDescriptor",
|
1091
907
|
{OneofDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
|
1092
|
-
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
908
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
1093
909
|
};
|
1094
910
|
|
1095
911
|
static OneofDescriptor* ruby_to_OneofDescriptor(VALUE val) {
|
@@ -1120,7 +936,7 @@ static VALUE OneofDescriptor_alloc(VALUE klass) {
|
|
1120
936
|
* Creates a descriptor wrapper object. May only be called from C.
|
1121
937
|
*/
|
1122
938
|
static VALUE OneofDescriptor_initialize(VALUE _self, VALUE cookie,
|
1123
|
-
|
939
|
+
VALUE descriptor_pool, VALUE ptr) {
|
1124
940
|
OneofDescriptor* self = ruby_to_OneofDescriptor(_self);
|
1125
941
|
|
1126
942
|
if (cookie != c_only_cookie) {
|
@@ -1128,8 +944,8 @@ static VALUE OneofDescriptor_initialize(VALUE _self, VALUE cookie,
|
|
1128
944
|
"Descriptor objects may not be created from Ruby.");
|
1129
945
|
}
|
1130
946
|
|
1131
|
-
self->descriptor_pool
|
1132
|
-
self->oneofdef = (const
|
947
|
+
RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool);
|
948
|
+
self->oneofdef = (const upb_OneofDef*)NUM2ULL(ptr);
|
1133
949
|
|
1134
950
|
return Qnil;
|
1135
951
|
}
|
@@ -1142,7 +958,7 @@ static VALUE OneofDescriptor_initialize(VALUE _self, VALUE cookie,
|
|
1142
958
|
*/
|
1143
959
|
static VALUE OneofDescriptor_name(VALUE _self) {
|
1144
960
|
OneofDescriptor* self = ruby_to_OneofDescriptor(_self);
|
1145
|
-
return rb_str_maybe_null(
|
961
|
+
return rb_str_maybe_null(upb_OneofDef_Name(self->oneofdef));
|
1146
962
|
}
|
1147
963
|
|
1148
964
|
/*
|
@@ -1153,11 +969,10 @@ static VALUE OneofDescriptor_name(VALUE _self) {
|
|
1153
969
|
*/
|
1154
970
|
static VALUE OneofDescriptor_each(VALUE _self) {
|
1155
971
|
OneofDescriptor* self = ruby_to_OneofDescriptor(_self);
|
1156
|
-
|
1157
|
-
|
1158
|
-
|
1159
|
-
|
1160
|
-
const upb_fielddef* f = upb_oneof_iter_field(&it);
|
972
|
+
|
973
|
+
int n = upb_OneofDef_FieldCount(self->oneofdef);
|
974
|
+
for (int i = 0; i < n; i++) {
|
975
|
+
const upb_FieldDef* f = upb_OneofDef_Field(self->oneofdef, i);
|
1161
976
|
VALUE obj = get_fielddef_obj(self->descriptor_pool, f);
|
1162
977
|
rb_yield(obj);
|
1163
978
|
}
|
@@ -1165,8 +980,7 @@ static VALUE OneofDescriptor_each(VALUE _self) {
|
|
1165
980
|
}
|
1166
981
|
|
1167
982
|
static void OneofDescriptor_register(VALUE module) {
|
1168
|
-
VALUE klass = rb_define_class_under(
|
1169
|
-
module, "OneofDescriptor", rb_cObject);
|
983
|
+
VALUE klass = rb_define_class_under(module, "OneofDescriptor", rb_cObject);
|
1170
984
|
rb_define_alloc_func(klass, OneofDescriptor_alloc);
|
1171
985
|
rb_define_method(klass, "initialize", OneofDescriptor_initialize, 3);
|
1172
986
|
rb_define_method(klass, "name", OneofDescriptor_name, 0);
|
@@ -1181,9 +995,11 @@ static void OneofDescriptor_register(VALUE module) {
|
|
1181
995
|
// -----------------------------------------------------------------------------
|
1182
996
|
|
1183
997
|
typedef struct {
|
1184
|
-
const
|
1185
|
-
|
1186
|
-
VALUE
|
998
|
+
const upb_EnumDef* enumdef;
|
999
|
+
// IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
|
1000
|
+
// macro to update VALUE references, as to trigger write barriers.
|
1001
|
+
VALUE module; // begins as nil
|
1002
|
+
VALUE descriptor_pool; // Owns the upb_EnumDef.
|
1187
1003
|
} EnumDescriptor;
|
1188
1004
|
|
1189
1005
|
static VALUE cEnumDescriptor = Qnil;
|
@@ -1195,9 +1011,9 @@ static void EnumDescriptor_mark(void* _self) {
|
|
1195
1011
|
}
|
1196
1012
|
|
1197
1013
|
static const rb_data_type_t EnumDescriptor_type = {
|
1198
|
-
|
1199
|
-
|
1200
|
-
|
1014
|
+
"Google::Protobuf::EnumDescriptor",
|
1015
|
+
{EnumDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
|
1016
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
1201
1017
|
};
|
1202
1018
|
|
1203
1019
|
static EnumDescriptor* ruby_to_EnumDescriptor(VALUE val) {
|
@@ -1216,8 +1032,8 @@ static VALUE EnumDescriptor_alloc(VALUE klass) {
|
|
1216
1032
|
}
|
1217
1033
|
|
1218
1034
|
// Exposed to other modules in defs.h.
|
1219
|
-
const
|
1220
|
-
EnumDescriptor
|
1035
|
+
const upb_EnumDef* EnumDescriptor_GetEnumDef(VALUE enum_desc_rb) {
|
1036
|
+
EnumDescriptor* desc = ruby_to_EnumDescriptor(enum_desc_rb);
|
1221
1037
|
return desc->enumdef;
|
1222
1038
|
}
|
1223
1039
|
|
@@ -1236,8 +1052,8 @@ static VALUE EnumDescriptor_initialize(VALUE _self, VALUE cookie,
|
|
1236
1052
|
"Descriptor objects may not be created from Ruby.");
|
1237
1053
|
}
|
1238
1054
|
|
1239
|
-
self->descriptor_pool
|
1240
|
-
self->enumdef = (const
|
1055
|
+
RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool);
|
1056
|
+
self->enumdef = (const upb_EnumDef*)NUM2ULL(ptr);
|
1241
1057
|
|
1242
1058
|
return Qnil;
|
1243
1059
|
}
|
@@ -1251,7 +1067,7 @@ static VALUE EnumDescriptor_initialize(VALUE _self, VALUE cookie,
|
|
1251
1067
|
static VALUE EnumDescriptor_file_descriptor(VALUE _self) {
|
1252
1068
|
EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
|
1253
1069
|
return get_filedef_obj(self->descriptor_pool,
|
1254
|
-
|
1070
|
+
upb_EnumDef_File(self->enumdef));
|
1255
1071
|
}
|
1256
1072
|
|
1257
1073
|
/*
|
@@ -1262,7 +1078,7 @@ static VALUE EnumDescriptor_file_descriptor(VALUE _self) {
|
|
1262
1078
|
*/
|
1263
1079
|
static VALUE EnumDescriptor_name(VALUE _self) {
|
1264
1080
|
EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
|
1265
|
-
return rb_str_maybe_null(
|
1081
|
+
return rb_str_maybe_null(upb_EnumDef_FullName(self->enumdef));
|
1266
1082
|
}
|
1267
1083
|
|
1268
1084
|
/*
|
@@ -1274,10 +1090,11 @@ static VALUE EnumDescriptor_name(VALUE _self) {
|
|
1274
1090
|
*/
|
1275
1091
|
static VALUE EnumDescriptor_lookup_name(VALUE _self, VALUE name) {
|
1276
1092
|
EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
|
1277
|
-
const char* name_str= rb_id2name(SYM2ID(name));
|
1278
|
-
|
1279
|
-
|
1280
|
-
|
1093
|
+
const char* name_str = rb_id2name(SYM2ID(name));
|
1094
|
+
const upb_EnumValueDef *ev =
|
1095
|
+
upb_EnumDef_FindValueByName(self->enumdef, name_str);
|
1096
|
+
if (ev) {
|
1097
|
+
return INT2NUM(upb_EnumValueDef_Number(ev));
|
1281
1098
|
} else {
|
1282
1099
|
return Qnil;
|
1283
1100
|
}
|
@@ -1293,9 +1110,9 @@ static VALUE EnumDescriptor_lookup_name(VALUE _self, VALUE name) {
|
|
1293
1110
|
static VALUE EnumDescriptor_lookup_value(VALUE _self, VALUE number) {
|
1294
1111
|
EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
|
1295
1112
|
int32_t val = NUM2INT(number);
|
1296
|
-
const
|
1297
|
-
if (
|
1298
|
-
return ID2SYM(rb_intern(
|
1113
|
+
const upb_EnumValueDef* ev = upb_EnumDef_FindValueByNumber(self->enumdef, val);
|
1114
|
+
if (ev) {
|
1115
|
+
return ID2SYM(rb_intern(upb_EnumValueDef_Name(ev)));
|
1299
1116
|
} else {
|
1300
1117
|
return Qnil;
|
1301
1118
|
}
|
@@ -1311,12 +1128,11 @@ static VALUE EnumDescriptor_lookup_value(VALUE _self, VALUE number) {
|
|
1311
1128
|
static VALUE EnumDescriptor_each(VALUE _self) {
|
1312
1129
|
EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
|
1313
1130
|
|
1314
|
-
|
1315
|
-
for (
|
1316
|
-
|
1317
|
-
|
1318
|
-
VALUE
|
1319
|
-
VALUE number = INT2NUM(upb_enum_iter_number(&it));
|
1131
|
+
int n = upb_EnumDef_ValueCount(self->enumdef);
|
1132
|
+
for (int i = 0; i < n; i++) {
|
1133
|
+
const upb_EnumValueDef* ev = upb_EnumDef_Value(self->enumdef, i);
|
1134
|
+
VALUE key = ID2SYM(rb_intern(upb_EnumValueDef_Name(ev)));
|
1135
|
+
VALUE number = INT2NUM(upb_EnumValueDef_Number(ev));
|
1320
1136
|
rb_yield_values(2, key, number);
|
1321
1137
|
}
|
1322
1138
|
|
@@ -1332,14 +1148,13 @@ static VALUE EnumDescriptor_each(VALUE _self) {
|
|
1332
1148
|
static VALUE EnumDescriptor_enummodule(VALUE _self) {
|
1333
1149
|
EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
|
1334
1150
|
if (self->module == Qnil) {
|
1335
|
-
self->module
|
1151
|
+
RB_OBJ_WRITE(_self, &self->module, build_module_from_enumdesc(_self));
|
1336
1152
|
}
|
1337
1153
|
return self->module;
|
1338
1154
|
}
|
1339
1155
|
|
1340
1156
|
static void EnumDescriptor_register(VALUE module) {
|
1341
|
-
VALUE klass = rb_define_class_under(
|
1342
|
-
module, "EnumDescriptor", rb_cObject);
|
1157
|
+
VALUE klass = rb_define_class_under(module, "EnumDescriptor", rb_cObject);
|
1343
1158
|
rb_define_alloc_func(klass, EnumDescriptor_alloc);
|
1344
1159
|
rb_define_method(klass, "initialize", EnumDescriptor_initialize, 3);
|
1345
1160
|
rb_define_method(klass, "name", EnumDescriptor_name, 0);
|
@@ -1353,1111 +1168,6 @@ static void EnumDescriptor_register(VALUE module) {
|
|
1353
1168
|
cEnumDescriptor = klass;
|
1354
1169
|
}
|
1355
1170
|
|
1356
|
-
// -----------------------------------------------------------------------------
|
1357
|
-
// FileBuilderContext.
|
1358
|
-
// -----------------------------------------------------------------------------
|
1359
|
-
|
1360
|
-
typedef struct {
|
1361
|
-
upb_arena *arena;
|
1362
|
-
google_protobuf_FileDescriptorProto* file_proto;
|
1363
|
-
VALUE descriptor_pool;
|
1364
|
-
} FileBuilderContext;
|
1365
|
-
|
1366
|
-
static VALUE cFileBuilderContext = Qnil;
|
1367
|
-
|
1368
|
-
static void FileBuilderContext_mark(void* _self) {
|
1369
|
-
FileBuilderContext* self = _self;
|
1370
|
-
rb_gc_mark(self->descriptor_pool);
|
1371
|
-
}
|
1372
|
-
|
1373
|
-
static void FileBuilderContext_free(void* _self) {
|
1374
|
-
FileBuilderContext* self = _self;
|
1375
|
-
upb_arena_free(self->arena);
|
1376
|
-
xfree(self);
|
1377
|
-
}
|
1378
|
-
|
1379
|
-
static const rb_data_type_t FileBuilderContext_type = {
|
1380
|
-
"Google::Protobuf::Internal::FileBuilderContext",
|
1381
|
-
{FileBuilderContext_mark, FileBuilderContext_free, NULL},
|
1382
|
-
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
1383
|
-
};
|
1384
|
-
|
1385
|
-
static FileBuilderContext* ruby_to_FileBuilderContext(VALUE val) {
|
1386
|
-
FileBuilderContext* ret;
|
1387
|
-
TypedData_Get_Struct(val, FileBuilderContext, &FileBuilderContext_type, ret);
|
1388
|
-
return ret;
|
1389
|
-
}
|
1390
|
-
|
1391
|
-
static upb_strview FileBuilderContext_strdup2(VALUE _self, const char *str) {
|
1392
|
-
FileBuilderContext* self = ruby_to_FileBuilderContext(_self);
|
1393
|
-
upb_strview ret;
|
1394
|
-
char *data;
|
1395
|
-
|
1396
|
-
ret.size = strlen(str);
|
1397
|
-
data = upb_malloc(upb_arena_alloc(self->arena), ret.size + 1);
|
1398
|
-
ret.data = data;
|
1399
|
-
memcpy(data, str, ret.size);
|
1400
|
-
/* Null-terminate required by rewrite_enum_defaults() above. */
|
1401
|
-
data[ret.size] = '\0';
|
1402
|
-
return ret;
|
1403
|
-
}
|
1404
|
-
|
1405
|
-
static upb_strview FileBuilderContext_strdup(VALUE _self, VALUE rb_str) {
|
1406
|
-
return FileBuilderContext_strdup2(_self, get_str(rb_str));
|
1407
|
-
}
|
1408
|
-
|
1409
|
-
static upb_strview FileBuilderContext_strdup_sym(VALUE _self, VALUE rb_sym) {
|
1410
|
-
Check_Type(rb_sym, T_SYMBOL);
|
1411
|
-
return FileBuilderContext_strdup(_self, rb_id2str(SYM2ID(rb_sym)));
|
1412
|
-
}
|
1413
|
-
|
1414
|
-
static VALUE FileBuilderContext_alloc(VALUE klass) {
|
1415
|
-
FileBuilderContext* self = ALLOC(FileBuilderContext);
|
1416
|
-
VALUE ret = TypedData_Wrap_Struct(klass, &FileBuilderContext_type, self);
|
1417
|
-
self->arena = upb_arena_new();
|
1418
|
-
self->file_proto = google_protobuf_FileDescriptorProto_new(self->arena);
|
1419
|
-
self->descriptor_pool = Qnil;
|
1420
|
-
return ret;
|
1421
|
-
}
|
1422
|
-
|
1423
|
-
/*
|
1424
|
-
* call-seq:
|
1425
|
-
* FileBuilderContext.new(descriptor_pool) => context
|
1426
|
-
*
|
1427
|
-
* Create a new file builder context for the given file descriptor and
|
1428
|
-
* builder context. This class is intended to serve as a DSL context to be used
|
1429
|
-
* with #instance_eval.
|
1430
|
-
*/
|
1431
|
-
static VALUE FileBuilderContext_initialize(VALUE _self, VALUE descriptor_pool,
|
1432
|
-
VALUE name, VALUE options) {
|
1433
|
-
FileBuilderContext* self = ruby_to_FileBuilderContext(_self);
|
1434
|
-
self->descriptor_pool = descriptor_pool;
|
1435
|
-
|
1436
|
-
google_protobuf_FileDescriptorProto_set_name(
|
1437
|
-
self->file_proto, FileBuilderContext_strdup(_self, name));
|
1438
|
-
|
1439
|
-
// Default syntax for Ruby is proto3.
|
1440
|
-
google_protobuf_FileDescriptorProto_set_syntax(
|
1441
|
-
self->file_proto,
|
1442
|
-
FileBuilderContext_strdup(_self, rb_str_new2("proto3")));
|
1443
|
-
|
1444
|
-
if (options != Qnil) {
|
1445
|
-
VALUE syntax;
|
1446
|
-
|
1447
|
-
Check_Type(options, T_HASH);
|
1448
|
-
syntax = rb_hash_lookup2(options, ID2SYM(rb_intern("syntax")), Qnil);
|
1449
|
-
|
1450
|
-
if (syntax != Qnil) {
|
1451
|
-
VALUE syntax_str;
|
1452
|
-
|
1453
|
-
Check_Type(syntax, T_SYMBOL);
|
1454
|
-
syntax_str = rb_id2str(SYM2ID(syntax));
|
1455
|
-
google_protobuf_FileDescriptorProto_set_syntax(
|
1456
|
-
self->file_proto, FileBuilderContext_strdup(_self, syntax_str));
|
1457
|
-
}
|
1458
|
-
}
|
1459
|
-
|
1460
|
-
return Qnil;
|
1461
|
-
}
|
1462
|
-
|
1463
|
-
static void MessageBuilderContext_add_synthetic_oneofs(VALUE _self);
|
1464
|
-
|
1465
|
-
/*
|
1466
|
-
* call-seq:
|
1467
|
-
* FileBuilderContext.add_message(name, &block)
|
1468
|
-
*
|
1469
|
-
* Creates a new, empty descriptor with the given name, and invokes the block in
|
1470
|
-
* the context of a MessageBuilderContext on that descriptor. The block can then
|
1471
|
-
* call, e.g., MessageBuilderContext#optional and MessageBuilderContext#repeated
|
1472
|
-
* methods to define the message fields.
|
1473
|
-
*
|
1474
|
-
* This is the recommended, idiomatic way to build message definitions.
|
1475
|
-
*/
|
1476
|
-
static VALUE FileBuilderContext_add_message(VALUE _self, VALUE name) {
|
1477
|
-
VALUE args[2] = { _self, name };
|
1478
|
-
VALUE ctx = rb_class_new_instance(2, args, cMessageBuilderContext);
|
1479
|
-
VALUE block = rb_block_proc();
|
1480
|
-
rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
|
1481
|
-
MessageBuilderContext_add_synthetic_oneofs(ctx);
|
1482
|
-
return Qnil;
|
1483
|
-
}
|
1484
|
-
|
1485
|
-
/* We have to do some relatively complicated logic here for backward
|
1486
|
-
* compatibility.
|
1487
|
-
*
|
1488
|
-
* In descriptor.proto, messages are nested inside other messages if that is
|
1489
|
-
* what the original .proto file looks like. For example, suppose we have this
|
1490
|
-
* foo.proto:
|
1491
|
-
*
|
1492
|
-
* package foo;
|
1493
|
-
* message Bar {
|
1494
|
-
* message Baz {}
|
1495
|
-
* }
|
1496
|
-
*
|
1497
|
-
* The descriptor for this must look like this:
|
1498
|
-
*
|
1499
|
-
* file {
|
1500
|
-
* name: "test.proto"
|
1501
|
-
* package: "foo"
|
1502
|
-
* message_type {
|
1503
|
-
* name: "Bar"
|
1504
|
-
* nested_type {
|
1505
|
-
* name: "Baz"
|
1506
|
-
* }
|
1507
|
-
* }
|
1508
|
-
* }
|
1509
|
-
*
|
1510
|
-
* However, the Ruby generated code has always generated messages in a flat,
|
1511
|
-
* non-nested way:
|
1512
|
-
*
|
1513
|
-
* Google::Protobuf::DescriptorPool.generated_pool.build do
|
1514
|
-
* add_message "foo.Bar" do
|
1515
|
-
* end
|
1516
|
-
* add_message "foo.Bar.Baz" do
|
1517
|
-
* end
|
1518
|
-
* end
|
1519
|
-
*
|
1520
|
-
* Here we need to do a translation where we turn this generated code into the
|
1521
|
-
* above descriptor. We need to infer that "foo" is the package name, and not
|
1522
|
-
* a message itself.
|
1523
|
-
*
|
1524
|
-
* We delegate to Ruby to compute the transformation, for more concice and
|
1525
|
-
* readable code than we can do in C */
|
1526
|
-
static void rewrite_names(VALUE _file_builder,
|
1527
|
-
google_protobuf_FileDescriptorProto* file_proto) {
|
1528
|
-
FileBuilderContext* file_builder = ruby_to_FileBuilderContext(_file_builder);
|
1529
|
-
upb_arena *arena = file_builder->arena;
|
1530
|
-
// Build params (package, msg_names, enum_names).
|
1531
|
-
VALUE package = Qnil;
|
1532
|
-
VALUE msg_names = rb_ary_new();
|
1533
|
-
VALUE enum_names = rb_ary_new();
|
1534
|
-
size_t msg_count, enum_count, i;
|
1535
|
-
VALUE new_package, nesting, msg_ents, enum_ents;
|
1536
|
-
google_protobuf_DescriptorProto** msgs;
|
1537
|
-
google_protobuf_EnumDescriptorProto** enums;
|
1538
|
-
|
1539
|
-
if (google_protobuf_FileDescriptorProto_has_package(file_proto)) {
|
1540
|
-
upb_strview package_str =
|
1541
|
-
google_protobuf_FileDescriptorProto_package(file_proto);
|
1542
|
-
package = rb_str_new(package_str.data, package_str.size);
|
1543
|
-
}
|
1544
|
-
|
1545
|
-
msgs = google_protobuf_FileDescriptorProto_mutable_message_type(file_proto,
|
1546
|
-
&msg_count);
|
1547
|
-
for (i = 0; i < msg_count; i++) {
|
1548
|
-
upb_strview name = google_protobuf_DescriptorProto_name(msgs[i]);
|
1549
|
-
rb_ary_push(msg_names, rb_str_new(name.data, name.size));
|
1550
|
-
}
|
1551
|
-
|
1552
|
-
enums = google_protobuf_FileDescriptorProto_mutable_enum_type(file_proto,
|
1553
|
-
&enum_count);
|
1554
|
-
for (i = 0; i < enum_count; i++) {
|
1555
|
-
upb_strview name = google_protobuf_EnumDescriptorProto_name(enums[i]);
|
1556
|
-
rb_ary_push(enum_names, rb_str_new(name.data, name.size));
|
1557
|
-
}
|
1558
|
-
|
1559
|
-
{
|
1560
|
-
// Call Ruby code to calculate package name and nesting.
|
1561
|
-
VALUE args[3] = { package, msg_names, enum_names };
|
1562
|
-
VALUE internal = rb_eval_string("Google::Protobuf::Internal");
|
1563
|
-
VALUE ret = rb_funcallv(internal, rb_intern("fixup_descriptor"), 3, args);
|
1564
|
-
|
1565
|
-
new_package = rb_ary_entry(ret, 0);
|
1566
|
-
nesting = rb_ary_entry(ret, 1);
|
1567
|
-
}
|
1568
|
-
|
1569
|
-
// Rewrite package and names.
|
1570
|
-
if (new_package != Qnil) {
|
1571
|
-
upb_strview new_package_str =
|
1572
|
-
FileBuilderContext_strdup(_file_builder, new_package);
|
1573
|
-
google_protobuf_FileDescriptorProto_set_package(file_proto,
|
1574
|
-
new_package_str);
|
1575
|
-
}
|
1576
|
-
|
1577
|
-
for (i = 0; i < msg_count; i++) {
|
1578
|
-
upb_strview name = google_protobuf_DescriptorProto_name(msgs[i]);
|
1579
|
-
remove_path(&name);
|
1580
|
-
google_protobuf_DescriptorProto_set_name(msgs[i], name);
|
1581
|
-
}
|
1582
|
-
|
1583
|
-
for (i = 0; i < enum_count; i++) {
|
1584
|
-
upb_strview name = google_protobuf_EnumDescriptorProto_name(enums[i]);
|
1585
|
-
remove_path(&name);
|
1586
|
-
google_protobuf_EnumDescriptorProto_set_name(enums[i], name);
|
1587
|
-
}
|
1588
|
-
|
1589
|
-
// Rewrite nesting.
|
1590
|
-
msg_ents = rb_hash_aref(nesting, ID2SYM(rb_intern("msgs")));
|
1591
|
-
enum_ents = rb_hash_aref(nesting, ID2SYM(rb_intern("enums")));
|
1592
|
-
|
1593
|
-
Check_Type(msg_ents, T_ARRAY);
|
1594
|
-
Check_Type(enum_ents, T_ARRAY);
|
1595
|
-
|
1596
|
-
for (i = 0; i < (size_t)RARRAY_LEN(msg_ents); i++) {
|
1597
|
-
VALUE msg_ent = rb_ary_entry(msg_ents, i);
|
1598
|
-
VALUE pos = rb_hash_aref(msg_ent, ID2SYM(rb_intern("pos")));
|
1599
|
-
msgs[i] = msgs[NUM2INT(pos)];
|
1600
|
-
rewrite_nesting(msg_ent, msgs[i], msgs, enums, arena);
|
1601
|
-
}
|
1602
|
-
|
1603
|
-
for (i = 0; i < (size_t)RARRAY_LEN(enum_ents); i++) {
|
1604
|
-
VALUE enum_pos = rb_ary_entry(enum_ents, i);
|
1605
|
-
enums[i] = enums[NUM2INT(enum_pos)];
|
1606
|
-
}
|
1607
|
-
|
1608
|
-
google_protobuf_FileDescriptorProto_resize_message_type(
|
1609
|
-
file_proto, RARRAY_LEN(msg_ents), arena);
|
1610
|
-
google_protobuf_FileDescriptorProto_resize_enum_type(
|
1611
|
-
file_proto, RARRAY_LEN(enum_ents), arena);
|
1612
|
-
}
|
1613
|
-
|
1614
|
-
/*
|
1615
|
-
* call-seq:
|
1616
|
-
* FileBuilderContext.add_enum(name, &block)
|
1617
|
-
*
|
1618
|
-
* Creates a new, empty enum descriptor with the given name, and invokes the
|
1619
|
-
* block in the context of an EnumBuilderContext on that descriptor. The block
|
1620
|
-
* can then call EnumBuilderContext#add_value to define the enum values.
|
1621
|
-
*
|
1622
|
-
* This is the recommended, idiomatic way to build enum definitions.
|
1623
|
-
*/
|
1624
|
-
static VALUE FileBuilderContext_add_enum(VALUE _self, VALUE name) {
|
1625
|
-
VALUE args[2] = { _self, name };
|
1626
|
-
VALUE ctx = rb_class_new_instance(2, args, cEnumBuilderContext);
|
1627
|
-
VALUE block = rb_block_proc();
|
1628
|
-
rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
|
1629
|
-
return Qnil;
|
1630
|
-
}
|
1631
|
-
|
1632
|
-
static void FileBuilderContext_build(VALUE _self) {
|
1633
|
-
FileBuilderContext* self = ruby_to_FileBuilderContext(_self);
|
1634
|
-
DescriptorPool* pool = ruby_to_DescriptorPool(self->descriptor_pool);
|
1635
|
-
upb_status status;
|
1636
|
-
|
1637
|
-
rewrite_enum_defaults(pool->symtab, self->file_proto);
|
1638
|
-
rewrite_names(_self, self->file_proto);
|
1639
|
-
|
1640
|
-
upb_status_clear(&status);
|
1641
|
-
if (!upb_symtab_addfile(pool->symtab, self->file_proto, &status)) {
|
1642
|
-
rb_raise(cTypeError, "Unable to add defs to DescriptorPool: %s",
|
1643
|
-
upb_status_errmsg(&status));
|
1644
|
-
}
|
1645
|
-
}
|
1646
|
-
|
1647
|
-
static void FileBuilderContext_register(VALUE module) {
|
1648
|
-
VALUE klass = rb_define_class_under(module, "FileBuilderContext", rb_cObject);
|
1649
|
-
rb_define_alloc_func(klass, FileBuilderContext_alloc);
|
1650
|
-
rb_define_method(klass, "initialize", FileBuilderContext_initialize, 3);
|
1651
|
-
rb_define_method(klass, "add_message", FileBuilderContext_add_message, 1);
|
1652
|
-
rb_define_method(klass, "add_enum", FileBuilderContext_add_enum, 1);
|
1653
|
-
rb_gc_register_address(&cFileBuilderContext);
|
1654
|
-
cFileBuilderContext = klass;
|
1655
|
-
}
|
1656
|
-
|
1657
|
-
// -----------------------------------------------------------------------------
|
1658
|
-
// MessageBuilderContext.
|
1659
|
-
// -----------------------------------------------------------------------------
|
1660
|
-
|
1661
|
-
typedef struct {
|
1662
|
-
google_protobuf_DescriptorProto* msg_proto;
|
1663
|
-
VALUE file_builder;
|
1664
|
-
} MessageBuilderContext;
|
1665
|
-
|
1666
|
-
static VALUE cMessageBuilderContext = Qnil;
|
1667
|
-
|
1668
|
-
static void MessageBuilderContext_mark(void* _self) {
|
1669
|
-
MessageBuilderContext* self = _self;
|
1670
|
-
rb_gc_mark(self->file_builder);
|
1671
|
-
}
|
1672
|
-
|
1673
|
-
static const rb_data_type_t MessageBuilderContext_type = {
|
1674
|
-
"Google::Protobuf::Internal::MessageBuilderContext",
|
1675
|
-
{MessageBuilderContext_mark, RUBY_DEFAULT_FREE, NULL},
|
1676
|
-
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
1677
|
-
};
|
1678
|
-
|
1679
|
-
static MessageBuilderContext* ruby_to_MessageBuilderContext(VALUE val) {
|
1680
|
-
MessageBuilderContext* ret;
|
1681
|
-
TypedData_Get_Struct(val, MessageBuilderContext, &MessageBuilderContext_type,
|
1682
|
-
ret);
|
1683
|
-
return ret;
|
1684
|
-
}
|
1685
|
-
|
1686
|
-
static VALUE MessageBuilderContext_alloc(VALUE klass) {
|
1687
|
-
MessageBuilderContext* self = ALLOC(MessageBuilderContext);
|
1688
|
-
VALUE ret = TypedData_Wrap_Struct(klass, &MessageBuilderContext_type, self);
|
1689
|
-
self->file_builder = Qnil;
|
1690
|
-
return ret;
|
1691
|
-
}
|
1692
|
-
|
1693
|
-
/*
|
1694
|
-
* call-seq:
|
1695
|
-
* MessageBuilderContext.new(file_builder, name) => context
|
1696
|
-
*
|
1697
|
-
* Create a new message builder context around the given message descriptor and
|
1698
|
-
* builder context. This class is intended to serve as a DSL context to be used
|
1699
|
-
* with #instance_eval.
|
1700
|
-
*/
|
1701
|
-
static VALUE MessageBuilderContext_initialize(VALUE _self, VALUE _file_builder,
|
1702
|
-
VALUE name) {
|
1703
|
-
MessageBuilderContext* self = ruby_to_MessageBuilderContext(_self);
|
1704
|
-
FileBuilderContext* file_builder = ruby_to_FileBuilderContext(_file_builder);
|
1705
|
-
google_protobuf_FileDescriptorProto* file_proto = file_builder->file_proto;
|
1706
|
-
|
1707
|
-
self->file_builder = _file_builder;
|
1708
|
-
self->msg_proto = google_protobuf_FileDescriptorProto_add_message_type(
|
1709
|
-
file_proto, file_builder->arena);
|
1710
|
-
|
1711
|
-
google_protobuf_DescriptorProto_set_name(
|
1712
|
-
self->msg_proto, FileBuilderContext_strdup(_file_builder, name));
|
1713
|
-
|
1714
|
-
return Qnil;
|
1715
|
-
}
|
1716
|
-
|
1717
|
-
static void msgdef_add_field(VALUE msgbuilder_rb, upb_label_t label, VALUE name,
|
1718
|
-
VALUE type, VALUE number, VALUE type_class,
|
1719
|
-
VALUE options, int oneof_index,
|
1720
|
-
bool proto3_optional) {
|
1721
|
-
MessageBuilderContext* self = ruby_to_MessageBuilderContext(msgbuilder_rb);
|
1722
|
-
FileBuilderContext* file_context =
|
1723
|
-
ruby_to_FileBuilderContext(self->file_builder);
|
1724
|
-
google_protobuf_FieldDescriptorProto* field_proto;
|
1725
|
-
VALUE name_str;
|
1726
|
-
|
1727
|
-
field_proto = google_protobuf_DescriptorProto_add_field(self->msg_proto,
|
1728
|
-
file_context->arena);
|
1729
|
-
|
1730
|
-
Check_Type(name, T_SYMBOL);
|
1731
|
-
name_str = rb_id2str(SYM2ID(name));
|
1732
|
-
|
1733
|
-
google_protobuf_FieldDescriptorProto_set_name(
|
1734
|
-
field_proto, FileBuilderContext_strdup(self->file_builder, name_str));
|
1735
|
-
google_protobuf_FieldDescriptorProto_set_number(field_proto, NUM2INT(number));
|
1736
|
-
google_protobuf_FieldDescriptorProto_set_label(field_proto, (int)label);
|
1737
|
-
google_protobuf_FieldDescriptorProto_set_type(
|
1738
|
-
field_proto, (int)ruby_to_descriptortype(type));
|
1739
|
-
|
1740
|
-
if (proto3_optional) {
|
1741
|
-
google_protobuf_FieldDescriptorProto_set_proto3_optional(field_proto, true);
|
1742
|
-
}
|
1743
|
-
|
1744
|
-
if (type_class != Qnil) {
|
1745
|
-
Check_Type(type_class, T_STRING);
|
1746
|
-
|
1747
|
-
// Make it an absolute type name by prepending a dot.
|
1748
|
-
type_class = rb_str_append(rb_str_new2("."), type_class);
|
1749
|
-
google_protobuf_FieldDescriptorProto_set_type_name(
|
1750
|
-
field_proto, FileBuilderContext_strdup(self->file_builder, type_class));
|
1751
|
-
}
|
1752
|
-
|
1753
|
-
if (options != Qnil) {
|
1754
|
-
Check_Type(options, T_HASH);
|
1755
|
-
|
1756
|
-
if (rb_funcall(options, rb_intern("key?"), 1,
|
1757
|
-
ID2SYM(rb_intern("default"))) == Qtrue) {
|
1758
|
-
VALUE default_value =
|
1759
|
-
rb_hash_lookup(options, ID2SYM(rb_intern("default")));
|
1760
|
-
|
1761
|
-
/* Call #to_s since all defaults are strings in the descriptor. */
|
1762
|
-
default_value = rb_funcall(default_value, rb_intern("to_s"), 0);
|
1763
|
-
|
1764
|
-
google_protobuf_FieldDescriptorProto_set_default_value(
|
1765
|
-
field_proto,
|
1766
|
-
FileBuilderContext_strdup(self->file_builder, default_value));
|
1767
|
-
}
|
1768
|
-
|
1769
|
-
if (rb_funcall(options, rb_intern("key?"), 1,
|
1770
|
-
ID2SYM(rb_intern("json_name"))) == Qtrue) {
|
1771
|
-
VALUE json_name =
|
1772
|
-
rb_hash_lookup(options, ID2SYM(rb_intern("json_name")));
|
1773
|
-
|
1774
|
-
google_protobuf_FieldDescriptorProto_set_json_name(
|
1775
|
-
field_proto,
|
1776
|
-
FileBuilderContext_strdup(self->file_builder, json_name));
|
1777
|
-
}
|
1778
|
-
}
|
1779
|
-
|
1780
|
-
if (oneof_index >= 0) {
|
1781
|
-
google_protobuf_FieldDescriptorProto_set_oneof_index(field_proto,
|
1782
|
-
oneof_index);
|
1783
|
-
}
|
1784
|
-
}
|
1785
|
-
|
1786
|
-
#if RUBY_API_VERSION_CODE >= 20700
|
1787
|
-
static VALUE make_mapentry(VALUE _message_builder, VALUE types, int argc,
|
1788
|
-
const VALUE* argv, VALUE blockarg) {
|
1789
|
-
(void)blockarg;
|
1790
|
-
#else
|
1791
|
-
static VALUE make_mapentry(VALUE _message_builder, VALUE types, int argc,
|
1792
|
-
VALUE* argv) {
|
1793
|
-
#endif
|
1794
|
-
MessageBuilderContext* message_builder =
|
1795
|
-
ruby_to_MessageBuilderContext(_message_builder);
|
1796
|
-
VALUE type_class = rb_ary_entry(types, 2);
|
1797
|
-
FileBuilderContext* file_context =
|
1798
|
-
ruby_to_FileBuilderContext(message_builder->file_builder);
|
1799
|
-
google_protobuf_MessageOptions* options =
|
1800
|
-
google_protobuf_DescriptorProto_mutable_options(
|
1801
|
-
message_builder->msg_proto, file_context->arena);
|
1802
|
-
|
1803
|
-
google_protobuf_MessageOptions_set_map_entry(options, true);
|
1804
|
-
|
1805
|
-
// optional <type> key = 1;
|
1806
|
-
rb_funcall(_message_builder, rb_intern("optional"), 3,
|
1807
|
-
ID2SYM(rb_intern("key")), rb_ary_entry(types, 0), INT2NUM(1));
|
1808
|
-
|
1809
|
-
// optional <type> value = 2;
|
1810
|
-
if (type_class == Qnil) {
|
1811
|
-
rb_funcall(_message_builder, rb_intern("optional"), 3,
|
1812
|
-
ID2SYM(rb_intern("value")), rb_ary_entry(types, 1), INT2NUM(2));
|
1813
|
-
} else {
|
1814
|
-
rb_funcall(_message_builder, rb_intern("optional"), 4,
|
1815
|
-
ID2SYM(rb_intern("value")), rb_ary_entry(types, 1), INT2NUM(2),
|
1816
|
-
type_class);
|
1817
|
-
}
|
1818
|
-
|
1819
|
-
return Qnil;
|
1820
|
-
}
|
1821
|
-
|
1822
|
-
/*
|
1823
|
-
* call-seq:
|
1824
|
-
* MessageBuilderContext.optional(name, type, number, type_class = nil,
|
1825
|
-
* options = nil)
|
1826
|
-
*
|
1827
|
-
* Defines a new optional field on this message type with the given type, tag
|
1828
|
-
* number, and type class (for message and enum fields). The type must be a Ruby
|
1829
|
-
* symbol (as accepted by FieldDescriptor#type=) and the type_class must be a
|
1830
|
-
* string, if present (as accepted by FieldDescriptor#submsg_name=).
|
1831
|
-
*/
|
1832
|
-
VALUE MessageBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
|
1833
|
-
VALUE name, type, number;
|
1834
|
-
VALUE type_class, options = Qnil;
|
1835
|
-
|
1836
|
-
rb_scan_args(argc, argv, "32", &name, &type, &number, &type_class, &options);
|
1837
|
-
|
1838
|
-
// Allow passing (name, type, number, options) or
|
1839
|
-
// (name, type, number, type_class, options)
|
1840
|
-
if (argc == 4 && RB_TYPE_P(type_class, T_HASH)) {
|
1841
|
-
options = type_class;
|
1842
|
-
type_class = Qnil;
|
1843
|
-
}
|
1844
|
-
|
1845
|
-
msgdef_add_field(_self, UPB_LABEL_OPTIONAL, name, type, number, type_class,
|
1846
|
-
options, -1, false);
|
1847
|
-
|
1848
|
-
return Qnil;
|
1849
|
-
}
|
1850
|
-
|
1851
|
-
/*
|
1852
|
-
* call-seq:
|
1853
|
-
* MessageBuilderContext.proto3_optional(name, type, number,
|
1854
|
-
* type_class = nil, options = nil)
|
1855
|
-
*
|
1856
|
-
* Defines a true proto3 optional field (that tracks presence) on this message
|
1857
|
-
* type with the given type, tag number, and type class (for message and enum
|
1858
|
-
* fields). The type must be a Ruby symbol (as accepted by
|
1859
|
-
* FieldDescriptor#type=) and the type_class must be a string, if present (as
|
1860
|
-
* accepted by FieldDescriptor#submsg_name=).
|
1861
|
-
*/
|
1862
|
-
static VALUE MessageBuilderContext_proto3_optional(int argc, VALUE* argv,
|
1863
|
-
VALUE _self) {
|
1864
|
-
VALUE name, type, number;
|
1865
|
-
VALUE type_class, options = Qnil;
|
1866
|
-
|
1867
|
-
rb_scan_args(argc, argv, "32", &name, &type, &number, &type_class, &options);
|
1868
|
-
|
1869
|
-
// Allow passing (name, type, number, options) or
|
1870
|
-
// (name, type, number, type_class, options)
|
1871
|
-
if (argc == 4 && RB_TYPE_P(type_class, T_HASH)) {
|
1872
|
-
options = type_class;
|
1873
|
-
type_class = Qnil;
|
1874
|
-
}
|
1875
|
-
|
1876
|
-
msgdef_add_field(_self, UPB_LABEL_OPTIONAL, name, type, number, type_class,
|
1877
|
-
options, -1, true);
|
1878
|
-
|
1879
|
-
return Qnil;
|
1880
|
-
}
|
1881
|
-
|
1882
|
-
/*
|
1883
|
-
* call-seq:
|
1884
|
-
* MessageBuilderContext.required(name, type, number, type_class = nil,
|
1885
|
-
* options = nil)
|
1886
|
-
*
|
1887
|
-
* Defines a new required field on this message type with the given type, tag
|
1888
|
-
* number, and type class (for message and enum fields). The type must be a Ruby
|
1889
|
-
* symbol (as accepted by FieldDescriptor#type=) and the type_class must be a
|
1890
|
-
* string, if present (as accepted by FieldDescriptor#submsg_name=).
|
1891
|
-
*
|
1892
|
-
* Proto3 does not have required fields, but this method exists for
|
1893
|
-
* completeness. Any attempt to add a message type with required fields to a
|
1894
|
-
* pool will currently result in an error.
|
1895
|
-
*/
|
1896
|
-
static VALUE MessageBuilderContext_required(int argc, VALUE* argv,
|
1897
|
-
VALUE _self) {
|
1898
|
-
VALUE name, type, number;
|
1899
|
-
VALUE type_class, options = Qnil;
|
1900
|
-
|
1901
|
-
rb_scan_args(argc, argv, "32", &name, &type, &number, &type_class, &options);
|
1902
|
-
|
1903
|
-
// Allow passing (name, type, number, options) or
|
1904
|
-
// (name, type, number, type_class, options)
|
1905
|
-
if (argc == 4 && RB_TYPE_P(type_class, T_HASH)) {
|
1906
|
-
options = type_class;
|
1907
|
-
type_class = Qnil;
|
1908
|
-
}
|
1909
|
-
|
1910
|
-
msgdef_add_field(_self, UPB_LABEL_REQUIRED, name, type, number, type_class,
|
1911
|
-
options, -1, false);
|
1912
|
-
|
1913
|
-
return Qnil;
|
1914
|
-
}
|
1915
|
-
|
1916
|
-
/*
|
1917
|
-
* call-seq:
|
1918
|
-
* MessageBuilderContext.repeated(name, type, number, type_class = nil)
|
1919
|
-
*
|
1920
|
-
* Defines a new repeated field on this message type with the given type, tag
|
1921
|
-
* number, and type class (for message and enum fields). The type must be a Ruby
|
1922
|
-
* symbol (as accepted by FieldDescriptor#type=) and the type_class must be a
|
1923
|
-
* string, if present (as accepted by FieldDescriptor#submsg_name=).
|
1924
|
-
*/
|
1925
|
-
static VALUE MessageBuilderContext_repeated(int argc, VALUE* argv,
|
1926
|
-
VALUE _self) {
|
1927
|
-
VALUE name, type, number;
|
1928
|
-
VALUE type_class, options = Qnil;
|
1929
|
-
|
1930
|
-
rb_scan_args(argc, argv, "32", &name, &type, &number, &type_class, &options);
|
1931
|
-
|
1932
|
-
// Allow passing (name, type, number, options) or
|
1933
|
-
// (name, type, number, type_class, options)
|
1934
|
-
if (argc == 4 && RB_TYPE_P(type_class, T_HASH)) {
|
1935
|
-
options = type_class;
|
1936
|
-
type_class = Qnil;
|
1937
|
-
}
|
1938
|
-
|
1939
|
-
msgdef_add_field(_self, UPB_LABEL_REPEATED, name, type, number, type_class,
|
1940
|
-
options, -1, false);
|
1941
|
-
|
1942
|
-
return Qnil;
|
1943
|
-
}
|
1944
|
-
|
1945
|
-
/*
|
1946
|
-
* call-seq:
|
1947
|
-
* MessageBuilderContext.map(name, key_type, value_type, number,
|
1948
|
-
* value_type_class = nil)
|
1949
|
-
*
|
1950
|
-
* Defines a new map field on this message type with the given key and value
|
1951
|
-
* types, tag number, and type class (for message and enum value types). The key
|
1952
|
-
* type must be :int32/:uint32/:int64/:uint64, :bool, or :string. The value type
|
1953
|
-
* type must be a Ruby symbol (as accepted by FieldDescriptor#type=) and the
|
1954
|
-
* type_class must be a string, if present (as accepted by
|
1955
|
-
* FieldDescriptor#submsg_name=).
|
1956
|
-
*/
|
1957
|
-
static VALUE MessageBuilderContext_map(int argc, VALUE* argv, VALUE _self) {
|
1958
|
-
MessageBuilderContext* self = ruby_to_MessageBuilderContext(_self);
|
1959
|
-
VALUE name, key_type, value_type, number, type_class;
|
1960
|
-
VALUE mapentry_desc_name;
|
1961
|
-
FileBuilderContext* file_builder;
|
1962
|
-
upb_strview msg_name;
|
1963
|
-
|
1964
|
-
if (argc < 4) {
|
1965
|
-
rb_raise(rb_eArgError, "Expected at least 4 arguments.");
|
1966
|
-
}
|
1967
|
-
name = argv[0];
|
1968
|
-
key_type = argv[1];
|
1969
|
-
value_type = argv[2];
|
1970
|
-
number = argv[3];
|
1971
|
-
type_class = (argc > 4) ? argv[4] : Qnil;
|
1972
|
-
|
1973
|
-
// Validate the key type. We can't accept enums, messages, or floats/doubles
|
1974
|
-
// as map keys. (We exclude these explicitly, and the field-descriptor setter
|
1975
|
-
// below then ensures that the type is one of the remaining valid options.)
|
1976
|
-
if (SYM2ID(key_type) == rb_intern("float") ||
|
1977
|
-
SYM2ID(key_type) == rb_intern("double") ||
|
1978
|
-
SYM2ID(key_type) == rb_intern("enum") ||
|
1979
|
-
SYM2ID(key_type) == rb_intern("message")) {
|
1980
|
-
rb_raise(rb_eArgError,
|
1981
|
-
"Cannot add a map field with a float, double, enum, or message "
|
1982
|
-
"type.");
|
1983
|
-
}
|
1984
|
-
|
1985
|
-
file_builder = ruby_to_FileBuilderContext(self->file_builder);
|
1986
|
-
|
1987
|
-
// Create a new message descriptor for the map entry message, and create a
|
1988
|
-
// repeated submessage field here with that type.
|
1989
|
-
msg_name = google_protobuf_DescriptorProto_name(self->msg_proto);
|
1990
|
-
mapentry_desc_name = rb_str_new(msg_name.data, msg_name.size);
|
1991
|
-
mapentry_desc_name = rb_str_cat2(mapentry_desc_name, "_MapEntry_");
|
1992
|
-
mapentry_desc_name =
|
1993
|
-
rb_str_cat2(mapentry_desc_name, rb_id2name(SYM2ID(name)));
|
1994
|
-
|
1995
|
-
{
|
1996
|
-
// message <msgname>_MapEntry_ { /* ... */ }
|
1997
|
-
VALUE args[1] = {mapentry_desc_name};
|
1998
|
-
VALUE types = rb_ary_new3(3, key_type, value_type, type_class);
|
1999
|
-
rb_block_call(self->file_builder, rb_intern("add_message"), 1, args,
|
2000
|
-
make_mapentry, types);
|
2001
|
-
}
|
2002
|
-
|
2003
|
-
// If this file is in a package, we need to qualify the map entry type.
|
2004
|
-
if (google_protobuf_FileDescriptorProto_has_package(file_builder->file_proto)) {
|
2005
|
-
upb_strview package_view =
|
2006
|
-
google_protobuf_FileDescriptorProto_package(file_builder->file_proto);
|
2007
|
-
VALUE package = rb_str_new(package_view.data, package_view.size);
|
2008
|
-
package = rb_str_cat2(package, ".");
|
2009
|
-
mapentry_desc_name = rb_str_concat(package, mapentry_desc_name);
|
2010
|
-
}
|
2011
|
-
|
2012
|
-
// repeated MapEntry <name> = <number>;
|
2013
|
-
rb_funcall(_self, rb_intern("repeated"), 4, name,
|
2014
|
-
ID2SYM(rb_intern("message")), number, mapentry_desc_name);
|
2015
|
-
|
2016
|
-
return Qnil;
|
2017
|
-
}
|
2018
|
-
|
2019
|
-
/*
|
2020
|
-
* call-seq:
|
2021
|
-
* MessageBuilderContext.oneof(name, &block) => nil
|
2022
|
-
*
|
2023
|
-
* Creates a new OneofDescriptor with the given name, creates a
|
2024
|
-
* OneofBuilderContext attached to that OneofDescriptor, evaluates the given
|
2025
|
-
* block in the context of that OneofBuilderContext with #instance_eval, and
|
2026
|
-
* then adds the oneof to the message.
|
2027
|
-
*
|
2028
|
-
* This is the recommended, idiomatic way to build oneof definitions.
|
2029
|
-
*/
|
2030
|
-
static VALUE MessageBuilderContext_oneof(VALUE _self, VALUE name) {
|
2031
|
-
MessageBuilderContext* self = ruby_to_MessageBuilderContext(_self);
|
2032
|
-
size_t oneof_count;
|
2033
|
-
FileBuilderContext* file_context =
|
2034
|
-
ruby_to_FileBuilderContext(self->file_builder);
|
2035
|
-
google_protobuf_OneofDescriptorProto* oneof_proto;
|
2036
|
-
|
2037
|
-
// Existing oneof_count becomes oneof_index.
|
2038
|
-
google_protobuf_DescriptorProto_oneof_decl(self->msg_proto, &oneof_count);
|
2039
|
-
|
2040
|
-
// Create oneof_proto and set its name.
|
2041
|
-
oneof_proto = google_protobuf_DescriptorProto_add_oneof_decl(
|
2042
|
-
self->msg_proto, file_context->arena);
|
2043
|
-
google_protobuf_OneofDescriptorProto_set_name(
|
2044
|
-
oneof_proto, FileBuilderContext_strdup_sym(self->file_builder, name));
|
2045
|
-
|
2046
|
-
// Evaluate the block with the builder as argument.
|
2047
|
-
{
|
2048
|
-
VALUE args[2] = { INT2NUM(oneof_count), _self };
|
2049
|
-
VALUE ctx = rb_class_new_instance(2, args, cOneofBuilderContext);
|
2050
|
-
VALUE block = rb_block_proc();
|
2051
|
-
rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
|
2052
|
-
}
|
2053
|
-
|
2054
|
-
return Qnil;
|
2055
|
-
}
|
2056
|
-
|
2057
|
-
static void MessageBuilderContext_add_synthetic_oneofs(VALUE _self) {
|
2058
|
-
MessageBuilderContext* self = ruby_to_MessageBuilderContext(_self);
|
2059
|
-
FileBuilderContext* file_context =
|
2060
|
-
ruby_to_FileBuilderContext(self->file_builder);
|
2061
|
-
size_t field_count, oneof_count;
|
2062
|
-
google_protobuf_FieldDescriptorProto** fields =
|
2063
|
-
google_protobuf_DescriptorProto_mutable_field(self->msg_proto, &field_count);
|
2064
|
-
const google_protobuf_OneofDescriptorProto*const* oneofs =
|
2065
|
-
google_protobuf_DescriptorProto_oneof_decl(self->msg_proto, &oneof_count);
|
2066
|
-
VALUE names = rb_hash_new();
|
2067
|
-
VALUE underscore = rb_str_new2("_");
|
2068
|
-
size_t i;
|
2069
|
-
|
2070
|
-
// We have to build a set of all names, to ensure that synthetic oneofs are
|
2071
|
-
// not creating conflicts.
|
2072
|
-
for (i = 0; i < field_count; i++) {
|
2073
|
-
upb_strview name = google_protobuf_FieldDescriptorProto_name(fields[i]);
|
2074
|
-
rb_hash_aset(names, rb_str_new(name.data, name.size), Qtrue);
|
2075
|
-
}
|
2076
|
-
for (i = 0; i < oneof_count; i++) {
|
2077
|
-
upb_strview name = google_protobuf_OneofDescriptorProto_name(oneofs[i]);
|
2078
|
-
rb_hash_aset(names, rb_str_new(name.data, name.size), Qtrue);
|
2079
|
-
}
|
2080
|
-
|
2081
|
-
for (i = 0; i < field_count; i++) {
|
2082
|
-
google_protobuf_OneofDescriptorProto* oneof_proto;
|
2083
|
-
VALUE oneof_name;
|
2084
|
-
upb_strview field_name;
|
2085
|
-
|
2086
|
-
if (!google_protobuf_FieldDescriptorProto_proto3_optional(fields[i])) {
|
2087
|
-
continue;
|
2088
|
-
}
|
2089
|
-
|
2090
|
-
// Prepend '_' until we are no longer conflicting.
|
2091
|
-
field_name = google_protobuf_FieldDescriptorProto_name(fields[i]);
|
2092
|
-
oneof_name = rb_str_new(field_name.data, field_name.size);
|
2093
|
-
while (rb_hash_lookup(names, oneof_name) != Qnil) {
|
2094
|
-
oneof_name = rb_str_plus(underscore, oneof_name);
|
2095
|
-
}
|
2096
|
-
|
2097
|
-
rb_hash_aset(names, oneof_name, Qtrue);
|
2098
|
-
google_protobuf_FieldDescriptorProto_set_oneof_index(fields[i],
|
2099
|
-
oneof_count++);
|
2100
|
-
oneof_proto = google_protobuf_DescriptorProto_add_oneof_decl(
|
2101
|
-
self->msg_proto, file_context->arena);
|
2102
|
-
google_protobuf_OneofDescriptorProto_set_name(
|
2103
|
-
oneof_proto, FileBuilderContext_strdup(self->file_builder, oneof_name));
|
2104
|
-
}
|
2105
|
-
}
|
2106
|
-
|
2107
|
-
static void MessageBuilderContext_register(VALUE module) {
|
2108
|
-
VALUE klass = rb_define_class_under(
|
2109
|
-
module, "MessageBuilderContext", rb_cObject);
|
2110
|
-
rb_define_alloc_func(klass, MessageBuilderContext_alloc);
|
2111
|
-
rb_define_method(klass, "initialize",
|
2112
|
-
MessageBuilderContext_initialize, 2);
|
2113
|
-
rb_define_method(klass, "optional", MessageBuilderContext_optional, -1);
|
2114
|
-
rb_define_method(klass, "proto3_optional", MessageBuilderContext_proto3_optional, -1);
|
2115
|
-
rb_define_method(klass, "required", MessageBuilderContext_required, -1);
|
2116
|
-
rb_define_method(klass, "repeated", MessageBuilderContext_repeated, -1);
|
2117
|
-
rb_define_method(klass, "map", MessageBuilderContext_map, -1);
|
2118
|
-
rb_define_method(klass, "oneof", MessageBuilderContext_oneof, 1);
|
2119
|
-
rb_gc_register_address(&cMessageBuilderContext);
|
2120
|
-
cMessageBuilderContext = klass;
|
2121
|
-
}
|
2122
|
-
|
2123
|
-
// -----------------------------------------------------------------------------
|
2124
|
-
// OneofBuilderContext.
|
2125
|
-
// -----------------------------------------------------------------------------
|
2126
|
-
|
2127
|
-
typedef struct {
|
2128
|
-
int oneof_index;
|
2129
|
-
VALUE message_builder;
|
2130
|
-
} OneofBuilderContext;
|
2131
|
-
|
2132
|
-
static VALUE cOneofBuilderContext = Qnil;
|
2133
|
-
|
2134
|
-
void OneofBuilderContext_mark(void* _self) {
|
2135
|
-
OneofBuilderContext* self = _self;
|
2136
|
-
rb_gc_mark(self->message_builder);
|
2137
|
-
}
|
2138
|
-
|
2139
|
-
static const rb_data_type_t OneofBuilderContext_type = {
|
2140
|
-
"Google::Protobuf::Internal::OneofBuilderContext",
|
2141
|
-
{OneofBuilderContext_mark, RUBY_DEFAULT_FREE, NULL},
|
2142
|
-
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
2143
|
-
};
|
2144
|
-
|
2145
|
-
static OneofBuilderContext* ruby_to_OneofBuilderContext(VALUE val) {
|
2146
|
-
OneofBuilderContext* ret;
|
2147
|
-
TypedData_Get_Struct(val, OneofBuilderContext, &OneofBuilderContext_type,
|
2148
|
-
ret);
|
2149
|
-
return ret;
|
2150
|
-
}
|
2151
|
-
|
2152
|
-
static VALUE OneofBuilderContext_alloc(VALUE klass) {
|
2153
|
-
OneofBuilderContext* self = ALLOC(OneofBuilderContext);
|
2154
|
-
VALUE ret = TypedData_Wrap_Struct(klass, &OneofBuilderContext_type, self);
|
2155
|
-
self->oneof_index = 0;
|
2156
|
-
self->message_builder = Qnil;
|
2157
|
-
return ret;
|
2158
|
-
}
|
2159
|
-
|
2160
|
-
/*
|
2161
|
-
* call-seq:
|
2162
|
-
* OneofBuilderContext.new(oneof_index, message_builder) => context
|
2163
|
-
*
|
2164
|
-
* Create a new oneof builder context around the given oneof descriptor and
|
2165
|
-
* builder context. This class is intended to serve as a DSL context to be used
|
2166
|
-
* with #instance_eval.
|
2167
|
-
*/
|
2168
|
-
static VALUE OneofBuilderContext_initialize(VALUE _self, VALUE oneof_index,
|
2169
|
-
VALUE message_builder) {
|
2170
|
-
OneofBuilderContext* self = ruby_to_OneofBuilderContext(_self);
|
2171
|
-
self->oneof_index = NUM2INT(oneof_index);
|
2172
|
-
self->message_builder = message_builder;
|
2173
|
-
return Qnil;
|
2174
|
-
}
|
2175
|
-
|
2176
|
-
/*
|
2177
|
-
* call-seq:
|
2178
|
-
* OneofBuilderContext.optional(name, type, number, type_class = nil,
|
2179
|
-
* default_value = nil)
|
2180
|
-
*
|
2181
|
-
* Defines a new optional field in this oneof with the given type, tag number,
|
2182
|
-
* and type class (for message and enum fields). The type must be a Ruby symbol
|
2183
|
-
* (as accepted by FieldDescriptor#type=) and the type_class must be a string,
|
2184
|
-
* if present (as accepted by FieldDescriptor#submsg_name=).
|
2185
|
-
*/
|
2186
|
-
static VALUE OneofBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
|
2187
|
-
OneofBuilderContext* self = ruby_to_OneofBuilderContext(_self);
|
2188
|
-
VALUE name, type, number;
|
2189
|
-
VALUE type_class, options = Qnil;
|
2190
|
-
|
2191
|
-
rb_scan_args(argc, argv, "32", &name, &type, &number, &type_class, &options);
|
2192
|
-
|
2193
|
-
msgdef_add_field(self->message_builder, UPB_LABEL_OPTIONAL, name, type,
|
2194
|
-
number, type_class, options, self->oneof_index, false);
|
2195
|
-
|
2196
|
-
return Qnil;
|
2197
|
-
}
|
2198
|
-
|
2199
|
-
static void OneofBuilderContext_register(VALUE module) {
|
2200
|
-
VALUE klass = rb_define_class_under(
|
2201
|
-
module, "OneofBuilderContext", rb_cObject);
|
2202
|
-
rb_define_alloc_func(klass, OneofBuilderContext_alloc);
|
2203
|
-
rb_define_method(klass, "initialize",
|
2204
|
-
OneofBuilderContext_initialize, 2);
|
2205
|
-
rb_define_method(klass, "optional", OneofBuilderContext_optional, -1);
|
2206
|
-
rb_gc_register_address(&cOneofBuilderContext);
|
2207
|
-
cOneofBuilderContext = klass;
|
2208
|
-
}
|
2209
|
-
|
2210
|
-
// -----------------------------------------------------------------------------
|
2211
|
-
// EnumBuilderContext.
|
2212
|
-
// -----------------------------------------------------------------------------
|
2213
|
-
|
2214
|
-
typedef struct {
|
2215
|
-
google_protobuf_EnumDescriptorProto* enum_proto;
|
2216
|
-
VALUE file_builder;
|
2217
|
-
} EnumBuilderContext;
|
2218
|
-
|
2219
|
-
static VALUE cEnumBuilderContext = Qnil;
|
2220
|
-
|
2221
|
-
void EnumBuilderContext_mark(void* _self) {
|
2222
|
-
EnumBuilderContext* self = _self;
|
2223
|
-
rb_gc_mark(self->file_builder);
|
2224
|
-
}
|
2225
|
-
|
2226
|
-
static const rb_data_type_t EnumBuilderContext_type = {
|
2227
|
-
"Google::Protobuf::Internal::EnumBuilderContext",
|
2228
|
-
{EnumBuilderContext_mark, RUBY_DEFAULT_FREE, NULL},
|
2229
|
-
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
2230
|
-
};
|
2231
|
-
|
2232
|
-
static EnumBuilderContext* ruby_to_EnumBuilderContext(VALUE val) {
|
2233
|
-
EnumBuilderContext* ret;
|
2234
|
-
TypedData_Get_Struct(val, EnumBuilderContext, &EnumBuilderContext_type, ret);
|
2235
|
-
return ret;
|
2236
|
-
}
|
2237
|
-
|
2238
|
-
static VALUE EnumBuilderContext_alloc(VALUE klass) {
|
2239
|
-
EnumBuilderContext* self = ALLOC(EnumBuilderContext);
|
2240
|
-
VALUE ret = TypedData_Wrap_Struct(klass, &EnumBuilderContext_type, self);
|
2241
|
-
self->enum_proto = NULL;
|
2242
|
-
self->file_builder = Qnil;
|
2243
|
-
return ret;
|
2244
|
-
}
|
2245
|
-
|
2246
|
-
/*
|
2247
|
-
* call-seq:
|
2248
|
-
* EnumBuilderContext.new(file_builder) => context
|
2249
|
-
*
|
2250
|
-
* Create a new builder context around the given enum descriptor. This class is
|
2251
|
-
* intended to serve as a DSL context to be used with #instance_eval.
|
2252
|
-
*/
|
2253
|
-
static VALUE EnumBuilderContext_initialize(VALUE _self, VALUE _file_builder,
|
2254
|
-
VALUE name) {
|
2255
|
-
EnumBuilderContext* self = ruby_to_EnumBuilderContext(_self);
|
2256
|
-
FileBuilderContext* file_builder = ruby_to_FileBuilderContext(_file_builder);
|
2257
|
-
google_protobuf_FileDescriptorProto* file_proto = file_builder->file_proto;
|
2258
|
-
|
2259
|
-
self->file_builder = _file_builder;
|
2260
|
-
self->enum_proto = google_protobuf_FileDescriptorProto_add_enum_type(
|
2261
|
-
file_proto, file_builder->arena);
|
2262
|
-
|
2263
|
-
google_protobuf_EnumDescriptorProto_set_name(
|
2264
|
-
self->enum_proto, FileBuilderContext_strdup(_file_builder, name));
|
2265
|
-
|
2266
|
-
return Qnil;
|
2267
|
-
}
|
2268
|
-
|
2269
|
-
/*
|
2270
|
-
* call-seq:
|
2271
|
-
* EnumBuilder.add_value(name, number)
|
2272
|
-
*
|
2273
|
-
* Adds the given name => number mapping to the enum type. Name must be a Ruby
|
2274
|
-
* symbol.
|
2275
|
-
*/
|
2276
|
-
static VALUE EnumBuilderContext_value(VALUE _self, VALUE name, VALUE number) {
|
2277
|
-
EnumBuilderContext* self = ruby_to_EnumBuilderContext(_self);
|
2278
|
-
FileBuilderContext* file_builder =
|
2279
|
-
ruby_to_FileBuilderContext(self->file_builder);
|
2280
|
-
google_protobuf_EnumValueDescriptorProto* enum_value;
|
2281
|
-
|
2282
|
-
enum_value = google_protobuf_EnumDescriptorProto_add_value(
|
2283
|
-
self->enum_proto, file_builder->arena);
|
2284
|
-
|
2285
|
-
google_protobuf_EnumValueDescriptorProto_set_name(
|
2286
|
-
enum_value, FileBuilderContext_strdup_sym(self->file_builder, name));
|
2287
|
-
google_protobuf_EnumValueDescriptorProto_set_number(enum_value,
|
2288
|
-
NUM2INT(number));
|
2289
|
-
|
2290
|
-
return Qnil;
|
2291
|
-
}
|
2292
|
-
|
2293
|
-
static void EnumBuilderContext_register(VALUE module) {
|
2294
|
-
VALUE klass = rb_define_class_under(
|
2295
|
-
module, "EnumBuilderContext", rb_cObject);
|
2296
|
-
rb_define_alloc_func(klass, EnumBuilderContext_alloc);
|
2297
|
-
rb_define_method(klass, "initialize", EnumBuilderContext_initialize, 2);
|
2298
|
-
rb_define_method(klass, "value", EnumBuilderContext_value, 2);
|
2299
|
-
rb_gc_register_address(&cEnumBuilderContext);
|
2300
|
-
cEnumBuilderContext = klass;
|
2301
|
-
}
|
2302
|
-
|
2303
|
-
// -----------------------------------------------------------------------------
|
2304
|
-
// Builder.
|
2305
|
-
// -----------------------------------------------------------------------------
|
2306
|
-
|
2307
|
-
typedef struct {
|
2308
|
-
VALUE descriptor_pool;
|
2309
|
-
VALUE default_file_builder;
|
2310
|
-
} Builder;
|
2311
|
-
|
2312
|
-
static VALUE cBuilder = Qnil;
|
2313
|
-
|
2314
|
-
static void Builder_mark(void* _self) {
|
2315
|
-
Builder* self = _self;
|
2316
|
-
rb_gc_mark(self->descriptor_pool);
|
2317
|
-
rb_gc_mark(self->default_file_builder);
|
2318
|
-
}
|
2319
|
-
|
2320
|
-
static const rb_data_type_t Builder_type = {
|
2321
|
-
"Google::Protobuf::Internal::Builder",
|
2322
|
-
{Builder_mark, RUBY_DEFAULT_FREE, NULL},
|
2323
|
-
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
2324
|
-
};
|
2325
|
-
|
2326
|
-
static Builder* ruby_to_Builder(VALUE val) {
|
2327
|
-
Builder* ret;
|
2328
|
-
TypedData_Get_Struct(val, Builder, &Builder_type, ret);
|
2329
|
-
return ret;
|
2330
|
-
}
|
2331
|
-
|
2332
|
-
static VALUE Builder_alloc(VALUE klass) {
|
2333
|
-
Builder* self = ALLOC(Builder);
|
2334
|
-
VALUE ret = TypedData_Wrap_Struct(klass, &Builder_type, self);
|
2335
|
-
self->descriptor_pool = Qnil;
|
2336
|
-
self->default_file_builder = Qnil;
|
2337
|
-
return ret;
|
2338
|
-
}
|
2339
|
-
|
2340
|
-
/*
|
2341
|
-
* call-seq:
|
2342
|
-
* Builder.new(descriptor_pool) => builder
|
2343
|
-
*
|
2344
|
-
* Creates a new Builder. A Builder can accumulate a set of new message and enum
|
2345
|
-
* descriptors and atomically register them into a pool in a way that allows for
|
2346
|
-
* (co)recursive type references.
|
2347
|
-
*/
|
2348
|
-
static VALUE Builder_initialize(VALUE _self, VALUE pool) {
|
2349
|
-
Builder* self = ruby_to_Builder(_self);
|
2350
|
-
self->descriptor_pool = pool;
|
2351
|
-
self->default_file_builder = Qnil; // Created lazily if needed.
|
2352
|
-
return Qnil;
|
2353
|
-
}
|
2354
|
-
|
2355
|
-
/*
|
2356
|
-
* call-seq:
|
2357
|
-
* Builder.add_file(name, options = nil, &block)
|
2358
|
-
*
|
2359
|
-
* Creates a new, file descriptor with the given name and options and invokes
|
2360
|
-
* the block in the context of a FileBuilderContext on that descriptor. The
|
2361
|
-
* block can then call FileBuilderContext#add_message or
|
2362
|
-
* FileBuilderContext#add_enum to define new messages or enums, respectively.
|
2363
|
-
*
|
2364
|
-
* This is the recommended, idiomatic way to build file descriptors.
|
2365
|
-
*/
|
2366
|
-
static VALUE Builder_add_file(int argc, VALUE* argv, VALUE _self) {
|
2367
|
-
Builder* self = ruby_to_Builder(_self);
|
2368
|
-
VALUE name, options;
|
2369
|
-
VALUE ctx;
|
2370
|
-
VALUE block;
|
2371
|
-
|
2372
|
-
rb_scan_args(argc, argv, "11", &name, &options);
|
2373
|
-
|
2374
|
-
{
|
2375
|
-
VALUE args[3] = { self->descriptor_pool, name, options };
|
2376
|
-
ctx = rb_class_new_instance(3, args, cFileBuilderContext);
|
2377
|
-
}
|
2378
|
-
|
2379
|
-
block = rb_block_proc();
|
2380
|
-
rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
|
2381
|
-
FileBuilderContext_build(ctx);
|
2382
|
-
|
2383
|
-
return Qnil;
|
2384
|
-
}
|
2385
|
-
|
2386
|
-
static VALUE Builder_get_default_file(VALUE _self) {
|
2387
|
-
Builder* self = ruby_to_Builder(_self);
|
2388
|
-
|
2389
|
-
/* Lazily create only if legacy builder-level methods are called. */
|
2390
|
-
if (self->default_file_builder == Qnil) {
|
2391
|
-
VALUE name = rb_str_new2("ruby_default_file.proto");
|
2392
|
-
VALUE args [3] = { self->descriptor_pool, name, rb_hash_new() };
|
2393
|
-
self->default_file_builder =
|
2394
|
-
rb_class_new_instance(3, args, cFileBuilderContext);
|
2395
|
-
}
|
2396
|
-
|
2397
|
-
return self->default_file_builder;
|
2398
|
-
}
|
2399
|
-
|
2400
|
-
/*
|
2401
|
-
* call-seq:
|
2402
|
-
* Builder.add_message(name, &block)
|
2403
|
-
*
|
2404
|
-
* Old and deprecated way to create a new descriptor.
|
2405
|
-
* See FileBuilderContext.add_message for the recommended way.
|
2406
|
-
*
|
2407
|
-
* Exists for backwards compatibility to allow building descriptor pool for
|
2408
|
-
* files generated by protoc which don't add messages within "add_file" block.
|
2409
|
-
* Descriptors created this way get assigned to a default empty FileDescriptor.
|
2410
|
-
*/
|
2411
|
-
static VALUE Builder_add_message(VALUE _self, VALUE name) {
|
2412
|
-
VALUE file_builder = Builder_get_default_file(_self);
|
2413
|
-
rb_funcall_with_block(file_builder, rb_intern("add_message"), 1, &name,
|
2414
|
-
rb_block_proc());
|
2415
|
-
return Qnil;
|
2416
|
-
}
|
2417
|
-
|
2418
|
-
/*
|
2419
|
-
* call-seq:
|
2420
|
-
* Builder.add_enum(name, &block)
|
2421
|
-
*
|
2422
|
-
* Old and deprecated way to create a new enum descriptor.
|
2423
|
-
* See FileBuilderContext.add_enum for the recommended way.
|
2424
|
-
*
|
2425
|
-
* Exists for backwards compatibility to allow building descriptor pool for
|
2426
|
-
* files generated by protoc which don't add enums within "add_file" block.
|
2427
|
-
* Enum descriptors created this way get assigned to a default empty
|
2428
|
-
* FileDescriptor.
|
2429
|
-
*/
|
2430
|
-
static VALUE Builder_add_enum(VALUE _self, VALUE name) {
|
2431
|
-
VALUE file_builder = Builder_get_default_file(_self);
|
2432
|
-
rb_funcall_with_block(file_builder, rb_intern("add_enum"), 1, &name,
|
2433
|
-
rb_block_proc());
|
2434
|
-
return Qnil;
|
2435
|
-
}
|
2436
|
-
|
2437
|
-
/* This method is hidden from Ruby, and only called directly from
|
2438
|
-
* DescriptorPool_build(). */
|
2439
|
-
static VALUE Builder_build(VALUE _self) {
|
2440
|
-
Builder* self = ruby_to_Builder(_self);
|
2441
|
-
|
2442
|
-
if (self->default_file_builder != Qnil) {
|
2443
|
-
FileBuilderContext_build(self->default_file_builder);
|
2444
|
-
self->default_file_builder = Qnil;
|
2445
|
-
}
|
2446
|
-
|
2447
|
-
return Qnil;
|
2448
|
-
}
|
2449
|
-
|
2450
|
-
static void Builder_register(VALUE module) {
|
2451
|
-
VALUE klass = rb_define_class_under(module, "Builder", rb_cObject);
|
2452
|
-
rb_define_alloc_func(klass, Builder_alloc);
|
2453
|
-
rb_define_method(klass, "initialize", Builder_initialize, 1);
|
2454
|
-
rb_define_method(klass, "add_file", Builder_add_file, -1);
|
2455
|
-
rb_define_method(klass, "add_message", Builder_add_message, 1);
|
2456
|
-
rb_define_method(klass, "add_enum", Builder_add_enum, 1);
|
2457
|
-
rb_gc_register_address(&cBuilder);
|
2458
|
-
cBuilder = klass;
|
2459
|
-
}
|
2460
|
-
|
2461
1171
|
static VALUE get_def_obj(VALUE _descriptor_pool, const void* ptr, VALUE klass) {
|
2462
1172
|
DescriptorPool* descriptor_pool = ruby_to_DescriptorPool(_descriptor_pool);
|
2463
1173
|
VALUE key = ULL2NUM((intptr_t)ptr);
|
@@ -2471,7 +1181,7 @@ static VALUE get_def_obj(VALUE _descriptor_pool, const void* ptr, VALUE klass) {
|
|
2471
1181
|
|
2472
1182
|
if (def == Qnil) {
|
2473
1183
|
// Lazily create wrapper object.
|
2474
|
-
VALUE args[3] = {
|
1184
|
+
VALUE args[3] = {c_only_cookie, _descriptor_pool, key};
|
2475
1185
|
def = rb_class_new_instance(3, args, klass);
|
2476
1186
|
rb_hash_aset(descriptor_pool->def_to_descriptor, key, def);
|
2477
1187
|
}
|
@@ -2479,23 +1189,23 @@ static VALUE get_def_obj(VALUE _descriptor_pool, const void* ptr, VALUE klass) {
|
|
2479
1189
|
return def;
|
2480
1190
|
}
|
2481
1191
|
|
2482
|
-
static VALUE get_msgdef_obj(VALUE descriptor_pool, const
|
1192
|
+
static VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_MessageDef* def) {
|
2483
1193
|
return get_def_obj(descriptor_pool, def, cDescriptor);
|
2484
1194
|
}
|
2485
1195
|
|
2486
|
-
static VALUE get_enumdef_obj(VALUE descriptor_pool, const
|
1196
|
+
static VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_EnumDef* def) {
|
2487
1197
|
return get_def_obj(descriptor_pool, def, cEnumDescriptor);
|
2488
1198
|
}
|
2489
1199
|
|
2490
|
-
static VALUE get_fielddef_obj(VALUE descriptor_pool, const
|
1200
|
+
static VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_FieldDef* def) {
|
2491
1201
|
return get_def_obj(descriptor_pool, def, cFieldDescriptor);
|
2492
1202
|
}
|
2493
1203
|
|
2494
|
-
static VALUE get_filedef_obj(VALUE descriptor_pool, const
|
1204
|
+
static VALUE get_filedef_obj(VALUE descriptor_pool, const upb_FileDef* def) {
|
2495
1205
|
return get_def_obj(descriptor_pool, def, cFileDescriptor);
|
2496
1206
|
}
|
2497
1207
|
|
2498
|
-
static VALUE get_oneofdef_obj(VALUE descriptor_pool, const
|
1208
|
+
static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_OneofDef* def) {
|
2499
1209
|
return get_def_obj(descriptor_pool, def, cOneofDescriptor);
|
2500
1210
|
}
|
2501
1211
|
|
@@ -2505,8 +1215,8 @@ static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_oneofdef* def) {
|
|
2505
1215
|
|
2506
1216
|
// Functions exposed to other modules in defs.h.
|
2507
1217
|
|
2508
|
-
VALUE Descriptor_DefToClass(const
|
2509
|
-
const
|
1218
|
+
VALUE Descriptor_DefToClass(const upb_MessageDef* m) {
|
1219
|
+
const upb_DefPool* symtab = upb_FileDef_Pool(upb_MessageDef_File(m));
|
2510
1220
|
VALUE pool = ObjectCache_Get(symtab);
|
2511
1221
|
PBRUBY_ASSERT(pool != Qnil);
|
2512
1222
|
VALUE desc_rb = get_msgdef_obj(pool, m);
|
@@ -2514,15 +1224,16 @@ VALUE Descriptor_DefToClass(const upb_msgdef *m) {
|
|
2514
1224
|
return desc->klass;
|
2515
1225
|
}
|
2516
1226
|
|
2517
|
-
const
|
1227
|
+
const upb_MessageDef* Descriptor_GetMsgDef(VALUE desc_rb) {
|
2518
1228
|
const Descriptor* desc = ruby_to_Descriptor(desc_rb);
|
2519
1229
|
return desc->msgdef;
|
2520
1230
|
}
|
2521
1231
|
|
2522
|
-
VALUE TypeInfo_InitArg(int argc, VALUE
|
1232
|
+
VALUE TypeInfo_InitArg(int argc, VALUE* argv, int skip_arg) {
|
2523
1233
|
if (argc > skip_arg) {
|
2524
1234
|
if (argc > 1 + skip_arg) {
|
2525
|
-
rb_raise(rb_eArgError, "Expected a maximum of %d arguments.",
|
1235
|
+
rb_raise(rb_eArgError, "Expected a maximum of %d arguments.",
|
1236
|
+
skip_arg + 1);
|
2526
1237
|
}
|
2527
1238
|
return argv[skip_arg];
|
2528
1239
|
} else {
|
@@ -2534,7 +1245,7 @@ TypeInfo TypeInfo_FromClass(int argc, VALUE* argv, int skip_arg,
|
|
2534
1245
|
VALUE* type_class, VALUE* init_arg) {
|
2535
1246
|
TypeInfo ret = {ruby_to_fieldtype(argv[skip_arg])};
|
2536
1247
|
|
2537
|
-
if (ret.type ==
|
1248
|
+
if (ret.type == kUpb_CType_Message || ret.type == kUpb_CType_Enum) {
|
2538
1249
|
*init_arg = TypeInfo_InitArg(argc, argv, skip_arg + 2);
|
2539
1250
|
|
2540
1251
|
if (argc < 2 + skip_arg) {
|
@@ -2552,11 +1263,11 @@ TypeInfo TypeInfo_FromClass(int argc, VALUE* argv, int skip_arg,
|
|
2552
1263
|
"class or enum as returned by the DescriptorPool.");
|
2553
1264
|
}
|
2554
1265
|
|
2555
|
-
if (ret.type ==
|
1266
|
+
if (ret.type == kUpb_CType_Message) {
|
2556
1267
|
ret.def.msgdef = ruby_to_Descriptor(desc)->msgdef;
|
2557
1268
|
Message_CheckClass(klass);
|
2558
1269
|
} else {
|
2559
|
-
PBRUBY_ASSERT(ret.type ==
|
1270
|
+
PBRUBY_ASSERT(ret.type == kUpb_CType_Enum);
|
2560
1271
|
ret.def.enumdef = ruby_to_EnumDescriptor(desc)->enumdef;
|
2561
1272
|
}
|
2562
1273
|
} else {
|
@@ -2573,11 +1284,6 @@ void Defs_register(VALUE module) {
|
|
2573
1284
|
FieldDescriptor_register(module);
|
2574
1285
|
OneofDescriptor_register(module);
|
2575
1286
|
EnumDescriptor_register(module);
|
2576
|
-
FileBuilderContext_register(module);
|
2577
|
-
MessageBuilderContext_register(module);
|
2578
|
-
OneofBuilderContext_register(module);
|
2579
|
-
EnumBuilderContext_register(module);
|
2580
|
-
Builder_register(module);
|
2581
1287
|
|
2582
1288
|
rb_gc_register_address(&c_only_cookie);
|
2583
1289
|
c_only_cookie = rb_class_new_instance(0, NULL, rb_cObject);
|