google-protobuf 3.9.2-x64-mingw32 → 3.10.0.rc.1-x64-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of google-protobuf might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/ext/google/protobuf_c/defs.c +851 -830
- data/ext/google/protobuf_c/encode_decode.c +219 -285
- data/ext/google/protobuf_c/extconf.rb +2 -4
- data/ext/google/protobuf_c/map.c +15 -9
- data/ext/google/protobuf_c/message.c +84 -91
- data/ext/google/protobuf_c/protobuf.c +30 -15
- data/ext/google/protobuf_c/protobuf.h +100 -54
- data/ext/google/protobuf_c/repeated_field.c +44 -19
- data/ext/google/protobuf_c/storage.c +219 -153
- data/ext/google/protobuf_c/upb.c +4516 -8706
- data/ext/google/protobuf_c/upb.h +4920 -8476
- data/lib/google/2.3/protobuf_c.so +0 -0
- data/lib/google/2.4/protobuf_c.so +0 -0
- data/lib/google/2.5/protobuf_c.so +0 -0
- data/lib/google/2.6/protobuf_c.so +0 -0
- data/lib/google/protobuf.rb +66 -0
- data/lib/google/protobuf/any_pb.rb +1 -1
- data/lib/google/protobuf/api_pb.rb +3 -3
- data/lib/google/protobuf/duration_pb.rb +1 -1
- data/lib/google/protobuf/empty_pb.rb +1 -1
- data/lib/google/protobuf/field_mask_pb.rb +1 -1
- data/lib/google/protobuf/source_context_pb.rb +1 -1
- data/lib/google/protobuf/struct_pb.rb +4 -4
- data/lib/google/protobuf/timestamp_pb.rb +1 -1
- data/lib/google/protobuf/type_pb.rb +8 -8
- data/lib/google/protobuf/well_known_types.rb +8 -2
- data/lib/google/protobuf/wrappers_pb.rb +9 -9
- data/tests/basic.rb +22 -6
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a7740fcdceef1e14dd5b0959a10b0165fb5d0b843986b646fd228bc86c65bac6
|
4
|
+
data.tar.gz: 0530aa4dc7cb4fd6d52784dc0ca4ba309a9c0a353e949ff6cad8df15f820b6de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ea4bfefbcd3ca7742a0831116e03ffada82c8c1d90b17676004e65a2ea9ed81282614b97288caea5343e53a0a0befabfeb458d9dd4afb0aa404db630a91aaaa8
|
7
|
+
data.tar.gz: 1665adc6eb0013fe6e2b9a6ec883324bff929b0d4f8535f2b3967a1a3e102338c75e7d0137e632d58e7f8cda28b30e703db39157651913b5878dfddd0150f2fb
|
@@ -28,6 +28,8 @@
|
|
28
28
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
29
29
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
30
|
|
31
|
+
#include <ctype.h>
|
32
|
+
#include <errno.h>
|
31
33
|
#include "protobuf.h"
|
32
34
|
|
33
35
|
// -----------------------------------------------------------------------------
|
@@ -46,29 +48,290 @@ static VALUE rb_str_maybe_null(const char* s) {
|
|
46
48
|
return rb_str_new2(s);
|
47
49
|
}
|
48
50
|
|
49
|
-
static
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
51
|
+
static void rewrite_enum_default(const upb_symtab* symtab,
|
52
|
+
google_protobuf_FileDescriptorProto* file,
|
53
|
+
google_protobuf_FieldDescriptorProto* field) {
|
54
|
+
upb_strview defaultval;
|
55
|
+
const char *type_name_str;
|
56
|
+
char *end;
|
57
|
+
long val;
|
58
|
+
const upb_enumdef *e;
|
59
|
+
upb_strview type_name;
|
60
|
+
|
61
|
+
/* Look for TYPE_ENUM fields that have a default. */
|
62
|
+
if (google_protobuf_FieldDescriptorProto_type(field) !=
|
63
|
+
google_protobuf_FieldDescriptorProto_TYPE_ENUM ||
|
64
|
+
!google_protobuf_FieldDescriptorProto_has_default_value(field) ||
|
65
|
+
!google_protobuf_FieldDescriptorProto_has_type_name(field)) {
|
66
|
+
return;
|
54
67
|
}
|
55
|
-
return (upb_def*)def;
|
56
|
-
}
|
57
68
|
|
58
|
-
|
59
|
-
|
69
|
+
defaultval = google_protobuf_FieldDescriptorProto_default_value(field);
|
70
|
+
type_name = google_protobuf_FieldDescriptorProto_type_name(field);
|
71
|
+
|
72
|
+
if (defaultval.size == 0 || !isdigit(defaultval.data[0])) {
|
73
|
+
return;
|
74
|
+
}
|
75
|
+
|
76
|
+
if (type_name.size == 0 || type_name.data[0] != '.') {
|
77
|
+
return;
|
78
|
+
}
|
79
|
+
|
80
|
+
type_name_str = type_name.data + 1;
|
81
|
+
|
82
|
+
errno = 0;
|
83
|
+
val = strtol(defaultval.data, &end, 10);
|
84
|
+
|
85
|
+
if (errno != 0 || *end != 0 || val < INT32_MIN || val > INT32_MAX) {
|
86
|
+
return;
|
87
|
+
}
|
88
|
+
|
89
|
+
/* Now find the corresponding enum definition. */
|
90
|
+
e = upb_symtab_lookupenum(symtab, type_name_str);
|
91
|
+
if (e) {
|
92
|
+
/* Look in previously loaded files. */
|
93
|
+
const char *label = upb_enumdef_iton(e, val);
|
94
|
+
if (!label) {
|
95
|
+
return;
|
96
|
+
}
|
97
|
+
google_protobuf_FieldDescriptorProto_set_default_value(
|
98
|
+
field, upb_strview_makez(label));
|
99
|
+
} else {
|
100
|
+
/* Look in enums defined in this file. */
|
101
|
+
const google_protobuf_EnumDescriptorProto* matching_enum = NULL;
|
102
|
+
size_t i, n;
|
103
|
+
const google_protobuf_EnumDescriptorProto* const* enums =
|
104
|
+
google_protobuf_FileDescriptorProto_enum_type(file, &n);
|
105
|
+
const google_protobuf_EnumValueDescriptorProto* const* values;
|
106
|
+
|
107
|
+
for (i = 0; i < n; i++) {
|
108
|
+
if (upb_strview_eql(google_protobuf_EnumDescriptorProto_name(enums[i]),
|
109
|
+
upb_strview_makez(type_name_str))) {
|
110
|
+
matching_enum = enums[i];
|
111
|
+
break;
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
115
|
+
if (!matching_enum) {
|
116
|
+
return;
|
117
|
+
}
|
118
|
+
|
119
|
+
values = google_protobuf_EnumDescriptorProto_value(matching_enum, &n);
|
120
|
+
for (i = 0; i < n; i++) {
|
121
|
+
if (google_protobuf_EnumValueDescriptorProto_number(values[i]) == val) {
|
122
|
+
google_protobuf_FieldDescriptorProto_set_default_value(
|
123
|
+
field, google_protobuf_EnumValueDescriptorProto_name(values[i]));
|
124
|
+
return;
|
125
|
+
}
|
126
|
+
}
|
127
|
+
|
128
|
+
/* We failed to find an enum default. But we'll just leave the enum
|
129
|
+
* untouched and let the normal def-building code catch it. */
|
130
|
+
}
|
60
131
|
}
|
61
132
|
|
62
|
-
|
63
|
-
|
133
|
+
/* Historically we allowed enum defaults to be specified as a number. In
|
134
|
+
* retrospect this was a mistake as descriptors require defaults to be
|
135
|
+
* specified as a label. This can make a difference if multiple labels have the
|
136
|
+
* same number.
|
137
|
+
*
|
138
|
+
* Here we do a pass over all enum defaults and rewrite numeric defaults by
|
139
|
+
* looking up their labels. This is compilcated by the fact that the enum
|
140
|
+
* definition can live in either the symtab or the file_proto.
|
141
|
+
* */
|
142
|
+
static void rewrite_enum_defaults(
|
143
|
+
const upb_symtab* symtab, google_protobuf_FileDescriptorProto* file_proto) {
|
144
|
+
size_t i, n;
|
145
|
+
google_protobuf_DescriptorProto** msgs =
|
146
|
+
google_protobuf_FileDescriptorProto_mutable_message_type(file_proto, &n);
|
147
|
+
|
148
|
+
for (i = 0; i < n; i++) {
|
149
|
+
size_t j, m;
|
150
|
+
google_protobuf_FieldDescriptorProto** fields =
|
151
|
+
google_protobuf_DescriptorProto_mutable_field(msgs[i], &m);
|
152
|
+
for (j = 0; j < m; j++) {
|
153
|
+
rewrite_enum_default(symtab, file_proto, fields[j]);
|
154
|
+
}
|
155
|
+
}
|
64
156
|
}
|
65
157
|
|
66
|
-
static
|
67
|
-
|
158
|
+
static void remove_path(upb_strview *name) {
|
159
|
+
const char* last = strrchr(name->data, '.');
|
160
|
+
if (last) {
|
161
|
+
size_t remove = last - name->data + 1;
|
162
|
+
name->data += remove;
|
163
|
+
name->size -= remove;
|
164
|
+
}
|
165
|
+
}
|
166
|
+
|
167
|
+
static void rewrite_nesting(VALUE msg_ent, google_protobuf_DescriptorProto* msg,
|
168
|
+
google_protobuf_DescriptorProto* const* msgs,
|
169
|
+
google_protobuf_EnumDescriptorProto* const* enums,
|
170
|
+
upb_arena *arena) {
|
171
|
+
VALUE submsgs = rb_hash_aref(msg_ent, ID2SYM(rb_intern("msgs")));
|
172
|
+
VALUE enum_pos = rb_hash_aref(msg_ent, ID2SYM(rb_intern("enums")));
|
173
|
+
int submsg_count;
|
174
|
+
int enum_count;
|
175
|
+
int i;
|
176
|
+
google_protobuf_DescriptorProto** msg_msgs;
|
177
|
+
google_protobuf_EnumDescriptorProto** msg_enums;
|
178
|
+
|
179
|
+
Check_Type(submsgs, T_ARRAY);
|
180
|
+
Check_Type(enum_pos, T_ARRAY);
|
181
|
+
|
182
|
+
submsg_count = RARRAY_LEN(submsgs);
|
183
|
+
enum_count = RARRAY_LEN(enum_pos);
|
184
|
+
|
185
|
+
msg_msgs = google_protobuf_DescriptorProto_resize_nested_type(
|
186
|
+
msg, submsg_count, arena);
|
187
|
+
msg_enums =
|
188
|
+
google_protobuf_DescriptorProto_resize_enum_type(msg, enum_count, arena);
|
189
|
+
|
190
|
+
for (i = 0; i < submsg_count; i++) {
|
191
|
+
VALUE submsg_ent = RARRAY_PTR(submsgs)[i];
|
192
|
+
VALUE pos = rb_hash_aref(submsg_ent, ID2SYM(rb_intern("pos")));
|
193
|
+
upb_strview name;
|
194
|
+
|
195
|
+
msg_msgs[i] = msgs[NUM2INT(pos)];
|
196
|
+
name = google_protobuf_DescriptorProto_name(msg_msgs[i]);
|
197
|
+
remove_path(&name);
|
198
|
+
google_protobuf_DescriptorProto_set_name(msg_msgs[i], name);
|
199
|
+
rewrite_nesting(submsg_ent, msg_msgs[i], msgs, enums, arena);
|
200
|
+
}
|
201
|
+
|
202
|
+
for (i = 0; i < enum_count; i++) {
|
203
|
+
VALUE pos = RARRAY_PTR(enum_pos)[i];
|
204
|
+
msg_enums[i] = enums[NUM2INT(pos)];
|
205
|
+
}
|
68
206
|
}
|
69
207
|
|
70
|
-
|
71
|
-
|
208
|
+
/* We have to do some relatively complicated logic here for backward
|
209
|
+
* compatibility.
|
210
|
+
*
|
211
|
+
* In descriptor.proto, messages are nested inside other messages if that is
|
212
|
+
* what the original .proto file looks like. For example, suppose we have this
|
213
|
+
* foo.proto:
|
214
|
+
*
|
215
|
+
* package foo;
|
216
|
+
* message Bar {
|
217
|
+
* message Baz {}
|
218
|
+
* }
|
219
|
+
*
|
220
|
+
* The descriptor for this must look like this:
|
221
|
+
*
|
222
|
+
* file {
|
223
|
+
* name: "test.proto"
|
224
|
+
* package: "foo"
|
225
|
+
* message_type {
|
226
|
+
* name: "Bar"
|
227
|
+
* nested_type {
|
228
|
+
* name: "Baz"
|
229
|
+
* }
|
230
|
+
* }
|
231
|
+
* }
|
232
|
+
*
|
233
|
+
* However, the Ruby generated code has always generated messages in a flat,
|
234
|
+
* non-nested way:
|
235
|
+
*
|
236
|
+
* Google::Protobuf::DescriptorPool.generated_pool.build do
|
237
|
+
* add_message "foo.Bar" do
|
238
|
+
* end
|
239
|
+
* add_message "foo.Bar.Baz" do
|
240
|
+
* end
|
241
|
+
* end
|
242
|
+
*
|
243
|
+
* Here we need to do a translation where we turn this generated code into the
|
244
|
+
* above descriptor. We need to infer that "foo" is the package name, and not
|
245
|
+
* a message itself.
|
246
|
+
*
|
247
|
+
* We delegate to Ruby to compute the transformation, for more concice and
|
248
|
+
* readable code than we can do in C */
|
249
|
+
static void rewrite_names(VALUE _file_builder,
|
250
|
+
google_protobuf_FileDescriptorProto* file_proto) {
|
251
|
+
FileBuilderContext* file_builder = ruby_to_FileBuilderContext(_file_builder);
|
252
|
+
upb_arena *arena = file_builder->arena;
|
253
|
+
// Build params (package, msg_names, enum_names).
|
254
|
+
VALUE package = Qnil;
|
255
|
+
VALUE msg_names = rb_ary_new();
|
256
|
+
VALUE enum_names = rb_ary_new();
|
257
|
+
size_t msg_count, enum_count, i;
|
258
|
+
VALUE new_package, nesting, msg_ents, enum_ents;
|
259
|
+
google_protobuf_DescriptorProto** msgs;
|
260
|
+
google_protobuf_EnumDescriptorProto** enums;
|
261
|
+
|
262
|
+
if (google_protobuf_FileDescriptorProto_has_package(file_proto)) {
|
263
|
+
upb_strview package_str =
|
264
|
+
google_protobuf_FileDescriptorProto_package(file_proto);
|
265
|
+
package = rb_str_new(package_str.data, package_str.size);
|
266
|
+
}
|
267
|
+
|
268
|
+
msgs = google_protobuf_FileDescriptorProto_mutable_message_type(file_proto,
|
269
|
+
&msg_count);
|
270
|
+
for (i = 0; i < msg_count; i++) {
|
271
|
+
upb_strview name = google_protobuf_DescriptorProto_name(msgs[i]);
|
272
|
+
rb_ary_push(msg_names, rb_str_new(name.data, name.size));
|
273
|
+
}
|
274
|
+
|
275
|
+
enums = google_protobuf_FileDescriptorProto_mutable_enum_type(file_proto,
|
276
|
+
&enum_count);
|
277
|
+
for (i = 0; i < enum_count; i++) {
|
278
|
+
upb_strview name = google_protobuf_EnumDescriptorProto_name(enums[i]);
|
279
|
+
rb_ary_push(enum_names, rb_str_new(name.data, name.size));
|
280
|
+
}
|
281
|
+
|
282
|
+
{
|
283
|
+
// Call Ruby code to calculate package name and nesting.
|
284
|
+
VALUE args[3] = { package, msg_names, enum_names };
|
285
|
+
VALUE internal = rb_eval_string("Google::Protobuf::Internal");
|
286
|
+
VALUE ret = rb_funcallv(internal, rb_intern("fixup_descriptor"), 3, args);
|
287
|
+
|
288
|
+
new_package = rb_ary_entry(ret, 0);
|
289
|
+
nesting = rb_ary_entry(ret, 1);
|
290
|
+
}
|
291
|
+
|
292
|
+
// Rewrite package and names.
|
293
|
+
if (new_package != Qnil) {
|
294
|
+
upb_strview new_package_str =
|
295
|
+
FileBuilderContext_strdup(_file_builder, new_package);
|
296
|
+
google_protobuf_FileDescriptorProto_set_package(file_proto,
|
297
|
+
new_package_str);
|
298
|
+
}
|
299
|
+
|
300
|
+
for (i = 0; i < msg_count; i++) {
|
301
|
+
upb_strview name = google_protobuf_DescriptorProto_name(msgs[i]);
|
302
|
+
remove_path(&name);
|
303
|
+
google_protobuf_DescriptorProto_set_name(msgs[i], name);
|
304
|
+
}
|
305
|
+
|
306
|
+
for (i = 0; i < enum_count; i++) {
|
307
|
+
upb_strview name = google_protobuf_EnumDescriptorProto_name(enums[i]);
|
308
|
+
remove_path(&name);
|
309
|
+
google_protobuf_EnumDescriptorProto_set_name(enums[i], name);
|
310
|
+
}
|
311
|
+
|
312
|
+
// Rewrite nesting.
|
313
|
+
msg_ents = rb_hash_aref(nesting, ID2SYM(rb_intern("msgs")));
|
314
|
+
enum_ents = rb_hash_aref(nesting, ID2SYM(rb_intern("enums")));
|
315
|
+
|
316
|
+
Check_Type(msg_ents, T_ARRAY);
|
317
|
+
Check_Type(enum_ents, T_ARRAY);
|
318
|
+
|
319
|
+
for (i = 0; i < (size_t)RARRAY_LEN(msg_ents); i++) {
|
320
|
+
VALUE msg_ent = rb_ary_entry(msg_ents, i);
|
321
|
+
VALUE pos = rb_hash_aref(msg_ent, ID2SYM(rb_intern("pos")));
|
322
|
+
msgs[i] = msgs[NUM2INT(pos)];
|
323
|
+
rewrite_nesting(msg_ent, msgs[i], msgs, enums, arena);
|
324
|
+
}
|
325
|
+
|
326
|
+
for (i = 0; i < (size_t)RARRAY_LEN(enum_ents); i++) {
|
327
|
+
VALUE enum_pos = rb_ary_entry(enum_ents, i);
|
328
|
+
enums[i] = enums[NUM2INT(enum_pos)];
|
329
|
+
}
|
330
|
+
|
331
|
+
google_protobuf_FileDescriptorProto_resize_message_type(
|
332
|
+
file_proto, RARRAY_LEN(msg_ents), arena);
|
333
|
+
google_protobuf_FileDescriptorProto_resize_enum_type(
|
334
|
+
file_proto, RARRAY_LEN(enum_ents), arena);
|
72
335
|
}
|
73
336
|
|
74
337
|
// -----------------------------------------------------------------------------
|
@@ -92,16 +355,26 @@ static upb_enumdef* check_enum_notfrozen(const upb_enumdef* def) {
|
|
92
355
|
|
93
356
|
// Global singleton DescriptorPool. The user is free to create others, but this
|
94
357
|
// is used by generated code.
|
95
|
-
VALUE generated_pool;
|
358
|
+
VALUE generated_pool = Qnil;
|
96
359
|
|
97
360
|
DEFINE_CLASS(DescriptorPool, "Google::Protobuf::DescriptorPool");
|
98
361
|
|
99
362
|
void DescriptorPool_mark(void* _self) {
|
363
|
+
DescriptorPool* self = _self;
|
364
|
+
rb_gc_mark(self->def_to_descriptor);
|
100
365
|
}
|
101
366
|
|
102
367
|
void DescriptorPool_free(void* _self) {
|
103
368
|
DescriptorPool* self = _self;
|
369
|
+
|
104
370
|
upb_symtab_free(self->symtab);
|
371
|
+
upb_handlercache_free(self->fill_handler_cache);
|
372
|
+
upb_handlercache_free(self->pb_serialize_handler_cache);
|
373
|
+
upb_handlercache_free(self->json_serialize_handler_cache);
|
374
|
+
upb_handlercache_free(self->json_serialize_handler_preserve_cache);
|
375
|
+
upb_pbcodecache_free(self->fill_method_cache);
|
376
|
+
upb_json_codecache_free(self->json_fill_method_cache);
|
377
|
+
|
105
378
|
xfree(self);
|
106
379
|
}
|
107
380
|
|
@@ -113,15 +386,29 @@ void DescriptorPool_free(void* _self) {
|
|
113
386
|
*/
|
114
387
|
VALUE DescriptorPool_alloc(VALUE klass) {
|
115
388
|
DescriptorPool* self = ALLOC(DescriptorPool);
|
389
|
+
VALUE ret;
|
390
|
+
|
391
|
+
self->def_to_descriptor = Qnil;
|
392
|
+
ret = TypedData_Wrap_Struct(klass, &_DescriptorPool_type, self);
|
393
|
+
|
394
|
+
self->def_to_descriptor = rb_hash_new();
|
116
395
|
self->symtab = upb_symtab_new();
|
117
|
-
|
396
|
+
self->fill_handler_cache =
|
397
|
+
upb_handlercache_new(add_handlers_for_message, (void*)ret);
|
398
|
+
self->pb_serialize_handler_cache = upb_pb_encoder_newcache();
|
399
|
+
self->json_serialize_handler_cache = upb_json_printer_newcache(false);
|
400
|
+
self->json_serialize_handler_preserve_cache =
|
401
|
+
upb_json_printer_newcache(true);
|
402
|
+
self->fill_method_cache = upb_pbcodecache_new(self->fill_handler_cache);
|
403
|
+
self->json_fill_method_cache = upb_json_codecache_new();
|
404
|
+
|
405
|
+
return ret;
|
118
406
|
}
|
119
407
|
|
120
408
|
void DescriptorPool_register(VALUE module) {
|
121
409
|
VALUE klass = rb_define_class_under(
|
122
410
|
module, "DescriptorPool", rb_cObject);
|
123
411
|
rb_define_alloc_func(klass, DescriptorPool_alloc);
|
124
|
-
rb_define_method(klass, "add", DescriptorPool_add, 1);
|
125
412
|
rb_define_method(klass, "build", DescriptorPool_build, -1);
|
126
413
|
rb_define_method(klass, "lookup", DescriptorPool_lookup, 1);
|
127
414
|
rb_define_singleton_method(klass, "generated_pool",
|
@@ -133,44 +420,6 @@ void DescriptorPool_register(VALUE module) {
|
|
133
420
|
generated_pool = rb_class_new_instance(0, NULL, klass);
|
134
421
|
}
|
135
422
|
|
136
|
-
static void add_descriptor_to_pool(DescriptorPool* self,
|
137
|
-
Descriptor* descriptor) {
|
138
|
-
CHECK_UPB(
|
139
|
-
upb_symtab_add(self->symtab, (upb_def**)&descriptor->msgdef, 1,
|
140
|
-
NULL, &status),
|
141
|
-
"Adding Descriptor to DescriptorPool failed");
|
142
|
-
}
|
143
|
-
|
144
|
-
static void add_enumdesc_to_pool(DescriptorPool* self,
|
145
|
-
EnumDescriptor* enumdesc) {
|
146
|
-
CHECK_UPB(
|
147
|
-
upb_symtab_add(self->symtab, (upb_def**)&enumdesc->enumdef, 1,
|
148
|
-
NULL, &status),
|
149
|
-
"Adding EnumDescriptor to DescriptorPool failed");
|
150
|
-
}
|
151
|
-
|
152
|
-
/*
|
153
|
-
* call-seq:
|
154
|
-
* DescriptorPool.add(descriptor)
|
155
|
-
*
|
156
|
-
* Adds the given Descriptor or EnumDescriptor to this pool. All references to
|
157
|
-
* other types in a Descriptor's fields must be resolvable within this pool or
|
158
|
-
* an exception will be raised.
|
159
|
-
*/
|
160
|
-
VALUE DescriptorPool_add(VALUE _self, VALUE def) {
|
161
|
-
DEFINE_SELF(DescriptorPool, self, _self);
|
162
|
-
VALUE def_klass = rb_obj_class(def);
|
163
|
-
if (def_klass == cDescriptor) {
|
164
|
-
add_descriptor_to_pool(self, ruby_to_Descriptor(def));
|
165
|
-
} else if (def_klass == cEnumDescriptor) {
|
166
|
-
add_enumdesc_to_pool(self, ruby_to_EnumDescriptor(def));
|
167
|
-
} else {
|
168
|
-
rb_raise(rb_eArgError,
|
169
|
-
"Second argument must be a Descriptor or EnumDescriptor.");
|
170
|
-
}
|
171
|
-
return Qnil;
|
172
|
-
}
|
173
|
-
|
174
423
|
/*
|
175
424
|
* call-seq:
|
176
425
|
* DescriptorPool.build(&block)
|
@@ -182,10 +431,10 @@ VALUE DescriptorPool_add(VALUE _self, VALUE def) {
|
|
182
431
|
* idiomatic way to define new message and enum types.
|
183
432
|
*/
|
184
433
|
VALUE DescriptorPool_build(int argc, VALUE* argv, VALUE _self) {
|
185
|
-
VALUE ctx = rb_class_new_instance(
|
434
|
+
VALUE ctx = rb_class_new_instance(1, &_self, cBuilder);
|
186
435
|
VALUE block = rb_block_proc();
|
187
436
|
rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
|
188
|
-
|
437
|
+
Builder_build(ctx);
|
189
438
|
return Qnil;
|
190
439
|
}
|
191
440
|
|
@@ -199,11 +448,20 @@ VALUE DescriptorPool_build(int argc, VALUE* argv, VALUE _self) {
|
|
199
448
|
VALUE DescriptorPool_lookup(VALUE _self, VALUE name) {
|
200
449
|
DEFINE_SELF(DescriptorPool, self, _self);
|
201
450
|
const char* name_str = get_str(name);
|
202
|
-
const
|
203
|
-
|
204
|
-
|
451
|
+
const upb_msgdef* msgdef;
|
452
|
+
const upb_enumdef* enumdef;
|
453
|
+
|
454
|
+
msgdef = upb_symtab_lookupmsg(self->symtab, name_str);
|
455
|
+
if (msgdef) {
|
456
|
+
return get_msgdef_obj(_self, msgdef);
|
205
457
|
}
|
206
|
-
|
458
|
+
|
459
|
+
enumdef = upb_symtab_lookupenum(self->symtab, name_str);
|
460
|
+
if (enumdef) {
|
461
|
+
return get_enumdef_obj(_self, enumdef);
|
462
|
+
}
|
463
|
+
|
464
|
+
return Qnil;
|
207
465
|
}
|
208
466
|
|
209
467
|
/*
|
@@ -228,36 +486,17 @@ DEFINE_CLASS(Descriptor, "Google::Protobuf::Descriptor");
|
|
228
486
|
void Descriptor_mark(void* _self) {
|
229
487
|
Descriptor* self = _self;
|
230
488
|
rb_gc_mark(self->klass);
|
489
|
+
rb_gc_mark(self->descriptor_pool);
|
490
|
+
if (self->layout && self->layout->empty_template) {
|
491
|
+
layout_mark(self->layout, self->layout->empty_template);
|
492
|
+
}
|
231
493
|
}
|
232
494
|
|
233
495
|
void Descriptor_free(void* _self) {
|
234
496
|
Descriptor* self = _self;
|
235
|
-
upb_msgdef_unref(self->msgdef, &self->msgdef);
|
236
497
|
if (self->layout) {
|
237
498
|
free_layout(self->layout);
|
238
499
|
}
|
239
|
-
if (self->fill_handlers) {
|
240
|
-
upb_handlers_unref(self->fill_handlers, &self->fill_handlers);
|
241
|
-
}
|
242
|
-
if (self->fill_method) {
|
243
|
-
upb_pbdecodermethod_unref(self->fill_method, &self->fill_method);
|
244
|
-
}
|
245
|
-
if (self->json_fill_method) {
|
246
|
-
upb_json_parsermethod_unref(self->json_fill_method,
|
247
|
-
&self->json_fill_method);
|
248
|
-
}
|
249
|
-
if (self->pb_serialize_handlers) {
|
250
|
-
upb_handlers_unref(self->pb_serialize_handlers,
|
251
|
-
&self->pb_serialize_handlers);
|
252
|
-
}
|
253
|
-
if (self->json_serialize_handlers) {
|
254
|
-
upb_handlers_unref(self->json_serialize_handlers,
|
255
|
-
&self->json_serialize_handlers);
|
256
|
-
}
|
257
|
-
if (self->json_serialize_handlers_preserve) {
|
258
|
-
upb_handlers_unref(self->json_serialize_handlers_preserve,
|
259
|
-
&self->json_serialize_handlers_preserve);
|
260
|
-
}
|
261
500
|
xfree(self);
|
262
501
|
}
|
263
502
|
|
@@ -273,15 +512,10 @@ void Descriptor_free(void* _self) {
|
|
273
512
|
VALUE Descriptor_alloc(VALUE klass) {
|
274
513
|
Descriptor* self = ALLOC(Descriptor);
|
275
514
|
VALUE ret = TypedData_Wrap_Struct(klass, &_Descriptor_type, self);
|
276
|
-
self->msgdef =
|
515
|
+
self->msgdef = NULL;
|
277
516
|
self->klass = Qnil;
|
517
|
+
self->descriptor_pool = Qnil;
|
278
518
|
self->layout = NULL;
|
279
|
-
self->fill_handlers = NULL;
|
280
|
-
self->fill_method = NULL;
|
281
|
-
self->json_fill_method = NULL;
|
282
|
-
self->pb_serialize_handlers = NULL;
|
283
|
-
self->json_serialize_handlers = NULL;
|
284
|
-
self->json_serialize_handlers_preserve = NULL;
|
285
519
|
return ret;
|
286
520
|
}
|
287
521
|
|
@@ -289,16 +523,13 @@ void Descriptor_register(VALUE module) {
|
|
289
523
|
VALUE klass = rb_define_class_under(
|
290
524
|
module, "Descriptor", rb_cObject);
|
291
525
|
rb_define_alloc_func(klass, Descriptor_alloc);
|
292
|
-
rb_define_method(klass, "initialize", Descriptor_initialize,
|
526
|
+
rb_define_method(klass, "initialize", Descriptor_initialize, 3);
|
293
527
|
rb_define_method(klass, "each", Descriptor_each, 0);
|
294
528
|
rb_define_method(klass, "lookup", Descriptor_lookup, 1);
|
295
|
-
rb_define_method(klass, "add_field", Descriptor_add_field, 1);
|
296
|
-
rb_define_method(klass, "add_oneof", Descriptor_add_oneof, 1);
|
297
529
|
rb_define_method(klass, "each_oneof", Descriptor_each_oneof, 0);
|
298
530
|
rb_define_method(klass, "lookup_oneof", Descriptor_lookup_oneof, 1);
|
299
531
|
rb_define_method(klass, "msgclass", Descriptor_msgclass, 0);
|
300
532
|
rb_define_method(klass, "name", Descriptor_name, 0);
|
301
|
-
rb_define_method(klass, "name=", Descriptor_name_set, 1);
|
302
533
|
rb_define_method(klass, "file_descriptor", Descriptor_file_descriptor, 0);
|
303
534
|
rb_include_module(klass, rb_mEnumerable);
|
304
535
|
rb_gc_register_address(&cDescriptor);
|
@@ -307,19 +538,21 @@ void Descriptor_register(VALUE module) {
|
|
307
538
|
|
308
539
|
/*
|
309
540
|
* call-seq:
|
310
|
-
* Descriptor.new(
|
541
|
+
* Descriptor.new(c_only_cookie, ptr) => Descriptor
|
311
542
|
*
|
312
|
-
*
|
543
|
+
* Creates a descriptor wrapper object. May only be called from C.
|
313
544
|
*/
|
314
|
-
VALUE Descriptor_initialize(VALUE _self, VALUE
|
545
|
+
VALUE Descriptor_initialize(VALUE _self, VALUE cookie,
|
546
|
+
VALUE descriptor_pool, VALUE ptr) {
|
315
547
|
DEFINE_SELF(Descriptor, self, _self);
|
316
548
|
|
317
|
-
|
549
|
+
if (cookie != c_only_cookie) {
|
550
|
+
rb_raise(rb_eRuntimeError,
|
551
|
+
"Descriptor objects may not be created from Ruby.");
|
552
|
+
}
|
318
553
|
|
319
|
-
|
320
|
-
|
321
|
-
"Failed to associate message to file descriptor.");
|
322
|
-
add_def_obj(file_descriptor->filedef, file_descriptor_rb);
|
554
|
+
self->descriptor_pool = descriptor_pool;
|
555
|
+
self->msgdef = (const upb_msgdef*)NUM2ULL(ptr);
|
323
556
|
|
324
557
|
return Qnil;
|
325
558
|
}
|
@@ -332,7 +565,7 @@ VALUE Descriptor_initialize(VALUE _self, VALUE file_descriptor_rb) {
|
|
332
565
|
*/
|
333
566
|
VALUE Descriptor_file_descriptor(VALUE _self) {
|
334
567
|
DEFINE_SELF(Descriptor, self, _self);
|
335
|
-
return
|
568
|
+
return get_filedef_obj(self->descriptor_pool, upb_msgdef_file(self->msgdef));
|
336
569
|
}
|
337
570
|
|
338
571
|
/*
|
@@ -347,23 +580,6 @@ VALUE Descriptor_name(VALUE _self) {
|
|
347
580
|
return rb_str_maybe_null(upb_msgdef_fullname(self->msgdef));
|
348
581
|
}
|
349
582
|
|
350
|
-
/*
|
351
|
-
* call-seq:
|
352
|
-
* Descriptor.name = name
|
353
|
-
*
|
354
|
-
* Assigns a name to this message type. The descriptor must not have been added
|
355
|
-
* to a pool yet.
|
356
|
-
*/
|
357
|
-
VALUE Descriptor_name_set(VALUE _self, VALUE str) {
|
358
|
-
DEFINE_SELF(Descriptor, self, _self);
|
359
|
-
upb_msgdef* mut_def = check_msg_notfrozen(self->msgdef);
|
360
|
-
const char* name = get_str(str);
|
361
|
-
CHECK_UPB(
|
362
|
-
upb_msgdef_setfullname(mut_def, name, &status),
|
363
|
-
"Error setting Descriptor name");
|
364
|
-
return Qnil;
|
365
|
-
}
|
366
|
-
|
367
583
|
/*
|
368
584
|
* call-seq:
|
369
585
|
* Descriptor.each(&block)
|
@@ -378,7 +594,7 @@ VALUE Descriptor_each(VALUE _self) {
|
|
378
594
|
!upb_msg_field_done(&it);
|
379
595
|
upb_msg_field_next(&it)) {
|
380
596
|
const upb_fielddef* field = upb_msg_iter_field(&it);
|
381
|
-
VALUE obj =
|
597
|
+
VALUE obj = get_fielddef_obj(self->descriptor_pool, field);
|
382
598
|
rb_yield(obj);
|
383
599
|
}
|
384
600
|
return Qnil;
|
@@ -398,51 +614,7 @@ VALUE Descriptor_lookup(VALUE _self, VALUE name) {
|
|
398
614
|
if (field == NULL) {
|
399
615
|
return Qnil;
|
400
616
|
}
|
401
|
-
return
|
402
|
-
}
|
403
|
-
|
404
|
-
/*
|
405
|
-
* call-seq:
|
406
|
-
* Descriptor.add_field(field) => nil
|
407
|
-
*
|
408
|
-
* Adds the given FieldDescriptor to this message type. This descriptor must not
|
409
|
-
* have been added to a pool yet. Raises an exception if a field with the same
|
410
|
-
* name or number already exists. Sub-type references (e.g. for fields of type
|
411
|
-
* message) are not resolved at this point.
|
412
|
-
*/
|
413
|
-
VALUE Descriptor_add_field(VALUE _self, VALUE obj) {
|
414
|
-
DEFINE_SELF(Descriptor, self, _self);
|
415
|
-
upb_msgdef* mut_def = check_msg_notfrozen(self->msgdef);
|
416
|
-
FieldDescriptor* def = ruby_to_FieldDescriptor(obj);
|
417
|
-
upb_fielddef* mut_field_def = check_field_notfrozen(def->fielddef);
|
418
|
-
CHECK_UPB(
|
419
|
-
upb_msgdef_addfield(mut_def, mut_field_def, NULL, &status),
|
420
|
-
"Adding field to Descriptor failed");
|
421
|
-
add_def_obj(def->fielddef, obj);
|
422
|
-
return Qnil;
|
423
|
-
}
|
424
|
-
|
425
|
-
/*
|
426
|
-
* call-seq:
|
427
|
-
* Descriptor.add_oneof(oneof) => nil
|
428
|
-
*
|
429
|
-
* Adds the given OneofDescriptor to this message type. This descriptor must not
|
430
|
-
* have been added to a pool yet. Raises an exception if a oneof with the same
|
431
|
-
* name already exists, or if any of the oneof's fields' names or numbers
|
432
|
-
* conflict with an existing field in this message type. All fields in the oneof
|
433
|
-
* are added to the message descriptor. Sub-type references (e.g. for fields of
|
434
|
-
* type message) are not resolved at this point.
|
435
|
-
*/
|
436
|
-
VALUE Descriptor_add_oneof(VALUE _self, VALUE obj) {
|
437
|
-
DEFINE_SELF(Descriptor, self, _self);
|
438
|
-
upb_msgdef* mut_def = check_msg_notfrozen(self->msgdef);
|
439
|
-
OneofDescriptor* def = ruby_to_OneofDescriptor(obj);
|
440
|
-
upb_oneofdef* mut_oneof_def = check_oneof_notfrozen(def->oneofdef);
|
441
|
-
CHECK_UPB(
|
442
|
-
upb_msgdef_addoneof(mut_def, mut_oneof_def, NULL, &status),
|
443
|
-
"Adding oneof to Descriptor failed");
|
444
|
-
add_def_obj(def->oneofdef, obj);
|
445
|
-
return Qnil;
|
617
|
+
return get_fielddef_obj(self->descriptor_pool, field);
|
446
618
|
}
|
447
619
|
|
448
620
|
/*
|
@@ -460,7 +632,7 @@ VALUE Descriptor_each_oneof(VALUE _self) {
|
|
460
632
|
!upb_msg_oneof_done(&it);
|
461
633
|
upb_msg_oneof_next(&it)) {
|
462
634
|
const upb_oneofdef* oneof = upb_msg_iter_oneof(&it);
|
463
|
-
VALUE obj =
|
635
|
+
VALUE obj = get_oneofdef_obj(self->descriptor_pool, oneof);
|
464
636
|
rb_yield(obj);
|
465
637
|
}
|
466
638
|
return Qnil;
|
@@ -480,24 +652,19 @@ VALUE Descriptor_lookup_oneof(VALUE _self, VALUE name) {
|
|
480
652
|
if (oneof == NULL) {
|
481
653
|
return Qnil;
|
482
654
|
}
|
483
|
-
return
|
655
|
+
return get_oneofdef_obj(self->descriptor_pool, oneof);
|
484
656
|
}
|
485
657
|
|
486
658
|
/*
|
487
659
|
* call-seq:
|
488
660
|
* Descriptor.msgclass => message_klass
|
489
661
|
*
|
490
|
-
* Returns the Ruby class created for this message type.
|
491
|
-
* message type has been added to a pool.
|
662
|
+
* Returns the Ruby class created for this message type.
|
492
663
|
*/
|
493
664
|
VALUE Descriptor_msgclass(VALUE _self) {
|
494
665
|
DEFINE_SELF(Descriptor, self, _self);
|
495
|
-
if (!upb_def_isfrozen((const upb_def*)self->msgdef)) {
|
496
|
-
rb_raise(rb_eRuntimeError,
|
497
|
-
"Cannot fetch message class from a Descriptor not yet in a pool.");
|
498
|
-
}
|
499
666
|
if (self->klass == Qnil) {
|
500
|
-
self->klass = build_class_from_descriptor(
|
667
|
+
self->klass = build_class_from_descriptor(_self);
|
501
668
|
}
|
502
669
|
return self->klass;
|
503
670
|
}
|
@@ -509,12 +676,20 @@ VALUE Descriptor_msgclass(VALUE _self) {
|
|
509
676
|
DEFINE_CLASS(FileDescriptor, "Google::Protobuf::FileDescriptor");
|
510
677
|
|
511
678
|
void FileDescriptor_mark(void* _self) {
|
679
|
+
FileDescriptor* self = _self;
|
680
|
+
rb_gc_mark(self->descriptor_pool);
|
512
681
|
}
|
513
682
|
|
514
683
|
void FileDescriptor_free(void* _self) {
|
515
|
-
|
516
|
-
|
517
|
-
|
684
|
+
xfree(_self);
|
685
|
+
}
|
686
|
+
|
687
|
+
VALUE FileDescriptor_alloc(VALUE klass) {
|
688
|
+
FileDescriptor* self = ALLOC(FileDescriptor);
|
689
|
+
VALUE ret = TypedData_Wrap_Struct(klass, &_FileDescriptor_type, self);
|
690
|
+
self->descriptor_pool = Qnil;
|
691
|
+
self->filedef = NULL;
|
692
|
+
return ret;
|
518
693
|
}
|
519
694
|
|
520
695
|
/*
|
@@ -524,64 +699,32 @@ void FileDescriptor_free(void* _self) {
|
|
524
699
|
* Returns a new file descriptor. The syntax must be set before it's passed
|
525
700
|
* to a builder.
|
526
701
|
*/
|
527
|
-
VALUE
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
702
|
+
VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie,
|
703
|
+
VALUE descriptor_pool, VALUE ptr) {
|
704
|
+
DEFINE_SELF(FileDescriptor, self, _self);
|
705
|
+
|
706
|
+
if (cookie != c_only_cookie) {
|
707
|
+
rb_raise(rb_eRuntimeError,
|
708
|
+
"Descriptor objects may not be created from Ruby.");
|
709
|
+
}
|
710
|
+
|
711
|
+
self->descriptor_pool = descriptor_pool;
|
712
|
+
self->filedef = (const upb_filedef*)NUM2ULL(ptr);
|
713
|
+
|
714
|
+
return Qnil;
|
533
715
|
}
|
534
716
|
|
535
717
|
void FileDescriptor_register(VALUE module) {
|
536
718
|
VALUE klass = rb_define_class_under(
|
537
719
|
module, "FileDescriptor", rb_cObject);
|
538
720
|
rb_define_alloc_func(klass, FileDescriptor_alloc);
|
539
|
-
rb_define_method(klass, "initialize", FileDescriptor_initialize,
|
721
|
+
rb_define_method(klass, "initialize", FileDescriptor_initialize, 3);
|
540
722
|
rb_define_method(klass, "name", FileDescriptor_name, 0);
|
541
723
|
rb_define_method(klass, "syntax", FileDescriptor_syntax, 0);
|
542
|
-
rb_define_method(klass, "syntax=", FileDescriptor_syntax_set, 1);
|
543
724
|
rb_gc_register_address(&cFileDescriptor);
|
544
725
|
cFileDescriptor = klass;
|
545
726
|
}
|
546
727
|
|
547
|
-
/*
|
548
|
-
* call-seq:
|
549
|
-
* FileDescriptor.new(name, options = nil) => file
|
550
|
-
*
|
551
|
-
* Initializes a new file descriptor with the given file name.
|
552
|
-
* Also accepts an optional "options" hash, specifying other optional
|
553
|
-
* metadata about the file. The options hash currently accepts the following
|
554
|
-
* * "syntax": :proto2 or :proto3 (default: :proto3)
|
555
|
-
*/
|
556
|
-
VALUE FileDescriptor_initialize(int argc, VALUE* argv, VALUE _self) {
|
557
|
-
DEFINE_SELF(FileDescriptor, self, _self);
|
558
|
-
|
559
|
-
VALUE name_rb;
|
560
|
-
VALUE options = Qnil;
|
561
|
-
rb_scan_args(argc, argv, "11", &name_rb, &options);
|
562
|
-
|
563
|
-
if (name_rb != Qnil) {
|
564
|
-
Check_Type(name_rb, T_STRING);
|
565
|
-
const char* name = get_str(name_rb);
|
566
|
-
CHECK_UPB(upb_filedef_setname(self->filedef, name, &status),
|
567
|
-
"Error setting file name");
|
568
|
-
}
|
569
|
-
|
570
|
-
// Default syntax is proto3.
|
571
|
-
VALUE syntax = ID2SYM(rb_intern("proto3"));
|
572
|
-
if (options != Qnil) {
|
573
|
-
Check_Type(options, T_HASH);
|
574
|
-
|
575
|
-
if (rb_funcall(options, rb_intern("key?"), 1,
|
576
|
-
ID2SYM(rb_intern("syntax"))) == Qtrue) {
|
577
|
-
syntax = rb_hash_lookup(options, ID2SYM(rb_intern("syntax")));
|
578
|
-
}
|
579
|
-
}
|
580
|
-
FileDescriptor_syntax_set(_self, syntax);
|
581
|
-
|
582
|
-
return Qnil;
|
583
|
-
}
|
584
|
-
|
585
728
|
/*
|
586
729
|
* call-seq:
|
587
730
|
* FileDescriptor.name => name
|
@@ -613,31 +756,6 @@ VALUE FileDescriptor_syntax(VALUE _self) {
|
|
613
756
|
}
|
614
757
|
}
|
615
758
|
|
616
|
-
/*
|
617
|
-
* call-seq:
|
618
|
-
* FileDescriptor.syntax = version
|
619
|
-
*
|
620
|
-
* Sets this file descriptor's syntax, can be :proto3 or :proto2.
|
621
|
-
*/
|
622
|
-
VALUE FileDescriptor_syntax_set(VALUE _self, VALUE syntax_rb) {
|
623
|
-
DEFINE_SELF(FileDescriptor, self, _self);
|
624
|
-
Check_Type(syntax_rb, T_SYMBOL);
|
625
|
-
|
626
|
-
upb_syntax_t syntax;
|
627
|
-
if (SYM2ID(syntax_rb) == rb_intern("proto3")) {
|
628
|
-
syntax = UPB_SYNTAX_PROTO3;
|
629
|
-
} else if (SYM2ID(syntax_rb) == rb_intern("proto2")) {
|
630
|
-
syntax = UPB_SYNTAX_PROTO2;
|
631
|
-
} else {
|
632
|
-
rb_raise(rb_eArgError, "Expected :proto3 or :proto3, received '%s'",
|
633
|
-
rb_id2name(SYM2ID(syntax_rb)));
|
634
|
-
}
|
635
|
-
|
636
|
-
CHECK_UPB(upb_filedef_setsyntax(self->filedef, syntax, &status),
|
637
|
-
"Error setting file syntax for proto");
|
638
|
-
return Qnil;
|
639
|
-
}
|
640
|
-
|
641
759
|
// -----------------------------------------------------------------------------
|
642
760
|
// FieldDescriptor.
|
643
761
|
// -----------------------------------------------------------------------------
|
@@ -645,12 +763,12 @@ VALUE FileDescriptor_syntax_set(VALUE _self, VALUE syntax_rb) {
|
|
645
763
|
DEFINE_CLASS(FieldDescriptor, "Google::Protobuf::FieldDescriptor");
|
646
764
|
|
647
765
|
void FieldDescriptor_mark(void* _self) {
|
766
|
+
FieldDescriptor* self = _self;
|
767
|
+
rb_gc_mark(self->descriptor_pool);
|
648
768
|
}
|
649
769
|
|
650
770
|
void FieldDescriptor_free(void* _self) {
|
651
|
-
|
652
|
-
upb_fielddef_unref(self->fielddef, &self->fielddef);
|
653
|
-
xfree(self);
|
771
|
+
xfree(_self);
|
654
772
|
}
|
655
773
|
|
656
774
|
/*
|
@@ -663,9 +781,7 @@ void FieldDescriptor_free(void* _self) {
|
|
663
781
|
VALUE FieldDescriptor_alloc(VALUE klass) {
|
664
782
|
FieldDescriptor* self = ALLOC(FieldDescriptor);
|
665
783
|
VALUE ret = TypedData_Wrap_Struct(klass, &_FieldDescriptor_type, self);
|
666
|
-
|
667
|
-
upb_fielddef_setpacked(fielddef, false);
|
668
|
-
self->fielddef = fielddef;
|
784
|
+
self->fielddef = NULL;
|
669
785
|
return ret;
|
670
786
|
}
|
671
787
|
|
@@ -673,18 +789,13 @@ void FieldDescriptor_register(VALUE module) {
|
|
673
789
|
VALUE klass = rb_define_class_under(
|
674
790
|
module, "FieldDescriptor", rb_cObject);
|
675
791
|
rb_define_alloc_func(klass, FieldDescriptor_alloc);
|
792
|
+
rb_define_method(klass, "initialize", FieldDescriptor_initialize, 3);
|
676
793
|
rb_define_method(klass, "name", FieldDescriptor_name, 0);
|
677
|
-
rb_define_method(klass, "name=", FieldDescriptor_name_set, 1);
|
678
794
|
rb_define_method(klass, "type", FieldDescriptor_type, 0);
|
679
|
-
rb_define_method(klass, "type=", FieldDescriptor_type_set, 1);
|
680
795
|
rb_define_method(klass, "default", FieldDescriptor_default, 0);
|
681
|
-
rb_define_method(klass, "default=", FieldDescriptor_default_set, 1);
|
682
796
|
rb_define_method(klass, "label", FieldDescriptor_label, 0);
|
683
|
-
rb_define_method(klass, "label=", FieldDescriptor_label_set, 1);
|
684
797
|
rb_define_method(klass, "number", FieldDescriptor_number, 0);
|
685
|
-
rb_define_method(klass, "number=", FieldDescriptor_number_set, 1);
|
686
798
|
rb_define_method(klass, "submsg_name", FieldDescriptor_submsg_name, 0);
|
687
|
-
rb_define_method(klass, "submsg_name=", FieldDescriptor_submsg_name_set, 1);
|
688
799
|
rb_define_method(klass, "subtype", FieldDescriptor_subtype, 0);
|
689
800
|
rb_define_method(klass, "has?", FieldDescriptor_has, 1);
|
690
801
|
rb_define_method(klass, "clear", FieldDescriptor_clear, 1);
|
@@ -696,29 +807,34 @@ void FieldDescriptor_register(VALUE module) {
|
|
696
807
|
|
697
808
|
/*
|
698
809
|
* call-seq:
|
699
|
-
*
|
810
|
+
* EnumDescriptor.new(c_only_cookie, pool, ptr) => EnumDescriptor
|
700
811
|
*
|
701
|
-
*
|
812
|
+
* Creates a descriptor wrapper object. May only be called from C.
|
702
813
|
*/
|
703
|
-
VALUE
|
814
|
+
VALUE FieldDescriptor_initialize(VALUE _self, VALUE cookie,
|
815
|
+
VALUE descriptor_pool, VALUE ptr) {
|
704
816
|
DEFINE_SELF(FieldDescriptor, self, _self);
|
705
|
-
|
817
|
+
|
818
|
+
if (cookie != c_only_cookie) {
|
819
|
+
rb_raise(rb_eRuntimeError,
|
820
|
+
"Descriptor objects may not be created from Ruby.");
|
821
|
+
}
|
822
|
+
|
823
|
+
self->descriptor_pool = descriptor_pool;
|
824
|
+
self->fielddef = (const upb_fielddef*)NUM2ULL(ptr);
|
825
|
+
|
826
|
+
return Qnil;
|
706
827
|
}
|
707
828
|
|
708
829
|
/*
|
709
830
|
* call-seq:
|
710
|
-
* FieldDescriptor.name
|
831
|
+
* FieldDescriptor.name => name
|
711
832
|
*
|
712
|
-
*
|
713
|
-
* type, if any, is added to a pool.
|
833
|
+
* Returns the name of this field.
|
714
834
|
*/
|
715
|
-
VALUE
|
835
|
+
VALUE FieldDescriptor_name(VALUE _self) {
|
716
836
|
DEFINE_SELF(FieldDescriptor, self, _self);
|
717
|
-
|
718
|
-
const char* name = get_str(str);
|
719
|
-
CHECK_UPB(upb_fielddef_setname(mut_def, name, &status),
|
720
|
-
"Error setting FieldDescriptor name");
|
721
|
-
return Qnil;
|
837
|
+
return rb_str_maybe_null(upb_fielddef_name(self->fielddef));
|
722
838
|
}
|
723
839
|
|
724
840
|
upb_fieldtype_t ruby_to_fieldtype(VALUE type) {
|
@@ -831,6 +947,29 @@ VALUE descriptortype_to_ruby(upb_descriptortype_t type) {
|
|
831
947
|
return Qnil;
|
832
948
|
}
|
833
949
|
|
950
|
+
VALUE ruby_to_label(VALUE label) {
|
951
|
+
upb_label_t upb_label;
|
952
|
+
bool converted = false;
|
953
|
+
|
954
|
+
#define CONVERT(upb, ruby) \
|
955
|
+
if (SYM2ID(label) == rb_intern( # ruby )) { \
|
956
|
+
upb_label = UPB_LABEL_ ## upb; \
|
957
|
+
converted = true; \
|
958
|
+
}
|
959
|
+
|
960
|
+
CONVERT(OPTIONAL, optional);
|
961
|
+
CONVERT(REQUIRED, required);
|
962
|
+
CONVERT(REPEATED, repeated);
|
963
|
+
|
964
|
+
#undef CONVERT
|
965
|
+
|
966
|
+
if (!converted) {
|
967
|
+
rb_raise(rb_eArgError, "Unknown field label.");
|
968
|
+
}
|
969
|
+
|
970
|
+
return upb_label;
|
971
|
+
}
|
972
|
+
|
834
973
|
/*
|
835
974
|
* call-seq:
|
836
975
|
* FieldDescriptor.type => type
|
@@ -843,26 +982,9 @@ VALUE descriptortype_to_ruby(upb_descriptortype_t type) {
|
|
843
982
|
*/
|
844
983
|
VALUE FieldDescriptor_type(VALUE _self) {
|
845
984
|
DEFINE_SELF(FieldDescriptor, self, _self);
|
846
|
-
if (!upb_fielddef_typeisset(self->fielddef)) {
|
847
|
-
return Qnil;
|
848
|
-
}
|
849
985
|
return descriptortype_to_ruby(upb_fielddef_descriptortype(self->fielddef));
|
850
986
|
}
|
851
987
|
|
852
|
-
/*
|
853
|
-
* call-seq:
|
854
|
-
* FieldDescriptor.type = type
|
855
|
-
*
|
856
|
-
* Sets this field's type. Cannot be called if field is part of a message type
|
857
|
-
* already in a pool.
|
858
|
-
*/
|
859
|
-
VALUE FieldDescriptor_type_set(VALUE _self, VALUE type) {
|
860
|
-
DEFINE_SELF(FieldDescriptor, self, _self);
|
861
|
-
upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
|
862
|
-
upb_fielddef_setdescriptortype(mut_def, ruby_to_descriptortype(type));
|
863
|
-
return Qnil;
|
864
|
-
}
|
865
|
-
|
866
988
|
/*
|
867
989
|
* call-seq:
|
868
990
|
* FieldDescriptor.default => default
|
@@ -874,60 +996,6 @@ VALUE FieldDescriptor_default(VALUE _self) {
|
|
874
996
|
return layout_get_default(self->fielddef);
|
875
997
|
}
|
876
998
|
|
877
|
-
/*
|
878
|
-
* call-seq:
|
879
|
-
* FieldDescriptor.default = default
|
880
|
-
*
|
881
|
-
* Sets this field's default value. Raises an exception when calling with
|
882
|
-
* proto syntax 3.
|
883
|
-
*/
|
884
|
-
VALUE FieldDescriptor_default_set(VALUE _self, VALUE default_value) {
|
885
|
-
DEFINE_SELF(FieldDescriptor, self, _self);
|
886
|
-
upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
|
887
|
-
|
888
|
-
switch (upb_fielddef_type(mut_def)) {
|
889
|
-
case UPB_TYPE_FLOAT:
|
890
|
-
upb_fielddef_setdefaultfloat(mut_def, NUM2DBL(default_value));
|
891
|
-
break;
|
892
|
-
case UPB_TYPE_DOUBLE:
|
893
|
-
upb_fielddef_setdefaultdouble(mut_def, NUM2DBL(default_value));
|
894
|
-
break;
|
895
|
-
case UPB_TYPE_BOOL:
|
896
|
-
if (!RB_TYPE_P(default_value, T_TRUE) &&
|
897
|
-
!RB_TYPE_P(default_value, T_FALSE) &&
|
898
|
-
!RB_TYPE_P(default_value, T_NIL)) {
|
899
|
-
rb_raise(cTypeError, "Expected boolean for default value.");
|
900
|
-
}
|
901
|
-
|
902
|
-
upb_fielddef_setdefaultbool(mut_def, RTEST(default_value));
|
903
|
-
break;
|
904
|
-
case UPB_TYPE_ENUM:
|
905
|
-
case UPB_TYPE_INT32:
|
906
|
-
upb_fielddef_setdefaultint32(mut_def, NUM2INT(default_value));
|
907
|
-
break;
|
908
|
-
case UPB_TYPE_INT64:
|
909
|
-
upb_fielddef_setdefaultint64(mut_def, NUM2INT(default_value));
|
910
|
-
break;
|
911
|
-
case UPB_TYPE_UINT32:
|
912
|
-
upb_fielddef_setdefaultuint32(mut_def, NUM2UINT(default_value));
|
913
|
-
break;
|
914
|
-
case UPB_TYPE_UINT64:
|
915
|
-
upb_fielddef_setdefaultuint64(mut_def, NUM2UINT(default_value));
|
916
|
-
break;
|
917
|
-
case UPB_TYPE_STRING:
|
918
|
-
case UPB_TYPE_BYTES:
|
919
|
-
CHECK_UPB(upb_fielddef_setdefaultcstr(mut_def, StringValuePtr(default_value),
|
920
|
-
&status),
|
921
|
-
"Error setting default string");
|
922
|
-
break;
|
923
|
-
default:
|
924
|
-
rb_raise(rb_eArgError, "Defaults not supported on field %s.%s",
|
925
|
-
upb_fielddef_fullname(mut_def), upb_fielddef_name(mut_def));
|
926
|
-
}
|
927
|
-
|
928
|
-
return Qnil;
|
929
|
-
}
|
930
|
-
|
931
999
|
/*
|
932
1000
|
* call-seq:
|
933
1001
|
* FieldDescriptor.label => label
|
@@ -953,44 +1021,6 @@ VALUE FieldDescriptor_label(VALUE _self) {
|
|
953
1021
|
return Qnil;
|
954
1022
|
}
|
955
1023
|
|
956
|
-
/*
|
957
|
-
* call-seq:
|
958
|
-
* FieldDescriptor.label = label
|
959
|
-
*
|
960
|
-
* Sets the label on this field. Cannot be called if field is part of a message
|
961
|
-
* type already in a pool.
|
962
|
-
*/
|
963
|
-
VALUE FieldDescriptor_label_set(VALUE _self, VALUE label) {
|
964
|
-
DEFINE_SELF(FieldDescriptor, self, _self);
|
965
|
-
upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
|
966
|
-
upb_label_t upb_label = -1;
|
967
|
-
bool converted = false;
|
968
|
-
|
969
|
-
if (TYPE(label) != T_SYMBOL) {
|
970
|
-
rb_raise(rb_eArgError, "Expected symbol for field label.");
|
971
|
-
}
|
972
|
-
|
973
|
-
#define CONVERT(upb, ruby) \
|
974
|
-
if (SYM2ID(label) == rb_intern( # ruby )) { \
|
975
|
-
upb_label = UPB_LABEL_ ## upb; \
|
976
|
-
converted = true; \
|
977
|
-
}
|
978
|
-
|
979
|
-
CONVERT(OPTIONAL, optional);
|
980
|
-
CONVERT(REQUIRED, required);
|
981
|
-
CONVERT(REPEATED, repeated);
|
982
|
-
|
983
|
-
#undef CONVERT
|
984
|
-
|
985
|
-
if (!converted) {
|
986
|
-
rb_raise(rb_eArgError, "Unknown field label.");
|
987
|
-
}
|
988
|
-
|
989
|
-
upb_fielddef_setlabel(mut_def, upb_label);
|
990
|
-
|
991
|
-
return Qnil;
|
992
|
-
}
|
993
|
-
|
994
1024
|
/*
|
995
1025
|
* call-seq:
|
996
1026
|
* FieldDescriptor.number => number
|
@@ -1002,21 +1032,6 @@ VALUE FieldDescriptor_number(VALUE _self) {
|
|
1002
1032
|
return INT2NUM(upb_fielddef_number(self->fielddef));
|
1003
1033
|
}
|
1004
1034
|
|
1005
|
-
/*
|
1006
|
-
* call-seq:
|
1007
|
-
* FieldDescriptor.number = number
|
1008
|
-
*
|
1009
|
-
* Sets the tag number for this field. Cannot be called if field is part of a
|
1010
|
-
* message type already in a pool.
|
1011
|
-
*/
|
1012
|
-
VALUE FieldDescriptor_number_set(VALUE _self, VALUE number) {
|
1013
|
-
DEFINE_SELF(FieldDescriptor, self, _self);
|
1014
|
-
upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
|
1015
|
-
CHECK_UPB(upb_fielddef_setnumber(mut_def, NUM2INT(number), &status),
|
1016
|
-
"Error setting field number");
|
1017
|
-
return Qnil;
|
1018
|
-
}
|
1019
|
-
|
1020
1035
|
/*
|
1021
1036
|
* call-seq:
|
1022
1037
|
* FieldDescriptor.submsg_name => submsg_name
|
@@ -1028,32 +1043,16 @@ VALUE FieldDescriptor_number_set(VALUE _self, VALUE number) {
|
|
1028
1043
|
*/
|
1029
1044
|
VALUE FieldDescriptor_submsg_name(VALUE _self) {
|
1030
1045
|
DEFINE_SELF(FieldDescriptor, self, _self);
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
*
|
1041
|
-
* Sets the name of the message or enum type corresponding to this field, if it
|
1042
|
-
* is a message or enum field (respectively). This type name will be resolved
|
1043
|
-
* within the context of the pool to which the containing message type is added.
|
1044
|
-
* Cannot be called on field that are not of message or enum type, or on fields
|
1045
|
-
* that are part of a message type already added to a pool.
|
1046
|
-
*/
|
1047
|
-
VALUE FieldDescriptor_submsg_name_set(VALUE _self, VALUE value) {
|
1048
|
-
DEFINE_SELF(FieldDescriptor, self, _self);
|
1049
|
-
upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
|
1050
|
-
const char* str = get_str(value);
|
1051
|
-
if (!upb_fielddef_hassubdef(self->fielddef)) {
|
1052
|
-
rb_raise(cTypeError, "FieldDescriptor does not have subdef.");
|
1046
|
+
switch (upb_fielddef_type(self->fielddef)) {
|
1047
|
+
case UPB_TYPE_ENUM:
|
1048
|
+
return rb_str_new2(
|
1049
|
+
upb_enumdef_fullname(upb_fielddef_enumsubdef(self->fielddef)));
|
1050
|
+
case UPB_TYPE_MESSAGE:
|
1051
|
+
return rb_str_new2(
|
1052
|
+
upb_msgdef_fullname(upb_fielddef_msgsubdef(self->fielddef)));
|
1053
|
+
default:
|
1054
|
+
return Qnil;
|
1053
1055
|
}
|
1054
|
-
CHECK_UPB(upb_fielddef_setsubdefname(mut_def, str, &status),
|
1055
|
-
"Error setting submessage name");
|
1056
|
-
return Qnil;
|
1057
1056
|
}
|
1058
1057
|
|
1059
1058
|
/*
|
@@ -1067,16 +1066,16 @@ VALUE FieldDescriptor_submsg_name_set(VALUE _self, VALUE value) {
|
|
1067
1066
|
*/
|
1068
1067
|
VALUE FieldDescriptor_subtype(VALUE _self) {
|
1069
1068
|
DEFINE_SELF(FieldDescriptor, self, _self);
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1069
|
+
switch (upb_fielddef_type(self->fielddef)) {
|
1070
|
+
case UPB_TYPE_ENUM:
|
1071
|
+
return get_enumdef_obj(self->descriptor_pool,
|
1072
|
+
upb_fielddef_enumsubdef(self->fielddef));
|
1073
|
+
case UPB_TYPE_MESSAGE:
|
1074
|
+
return get_msgdef_obj(self->descriptor_pool,
|
1075
|
+
upb_fielddef_msgsubdef(self->fielddef));
|
1076
|
+
default:
|
1077
|
+
return Qnil;
|
1078
1078
|
}
|
1079
|
-
return get_def_obj(def);
|
1080
1079
|
}
|
1081
1080
|
|
1082
1081
|
/*
|
@@ -1160,12 +1159,12 @@ VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) {
|
|
1160
1159
|
DEFINE_CLASS(OneofDescriptor, "Google::Protobuf::OneofDescriptor");
|
1161
1160
|
|
1162
1161
|
void OneofDescriptor_mark(void* _self) {
|
1162
|
+
OneofDescriptor* self = _self;
|
1163
|
+
rb_gc_mark(self->descriptor_pool);
|
1163
1164
|
}
|
1164
1165
|
|
1165
1166
|
void OneofDescriptor_free(void* _self) {
|
1166
|
-
|
1167
|
-
upb_oneofdef_unref(self->oneofdef, &self->oneofdef);
|
1168
|
-
xfree(self);
|
1167
|
+
xfree(_self);
|
1169
1168
|
}
|
1170
1169
|
|
1171
1170
|
/*
|
@@ -1178,7 +1177,8 @@ void OneofDescriptor_free(void* _self) {
|
|
1178
1177
|
VALUE OneofDescriptor_alloc(VALUE klass) {
|
1179
1178
|
OneofDescriptor* self = ALLOC(OneofDescriptor);
|
1180
1179
|
VALUE ret = TypedData_Wrap_Struct(klass, &_OneofDescriptor_type, self);
|
1181
|
-
self->oneofdef =
|
1180
|
+
self->oneofdef = NULL;
|
1181
|
+
self->descriptor_pool = Qnil;
|
1182
1182
|
return ret;
|
1183
1183
|
}
|
1184
1184
|
|
@@ -1186,9 +1186,8 @@ void OneofDescriptor_register(VALUE module) {
|
|
1186
1186
|
VALUE klass = rb_define_class_under(
|
1187
1187
|
module, "OneofDescriptor", rb_cObject);
|
1188
1188
|
rb_define_alloc_func(klass, OneofDescriptor_alloc);
|
1189
|
+
rb_define_method(klass, "initialize", OneofDescriptor_initialize, 3);
|
1189
1190
|
rb_define_method(klass, "name", OneofDescriptor_name, 0);
|
1190
|
-
rb_define_method(klass, "name=", OneofDescriptor_name_set, 1);
|
1191
|
-
rb_define_method(klass, "add_field", OneofDescriptor_add_field, 1);
|
1192
1191
|
rb_define_method(klass, "each", OneofDescriptor_each, 0);
|
1193
1192
|
rb_include_module(klass, rb_mEnumerable);
|
1194
1193
|
rb_gc_register_address(&cOneofDescriptor);
|
@@ -1197,55 +1196,34 @@ void OneofDescriptor_register(VALUE module) {
|
|
1197
1196
|
|
1198
1197
|
/*
|
1199
1198
|
* call-seq:
|
1200
|
-
*
|
1199
|
+
* OneofDescriptor.new(c_only_cookie, pool, ptr) => OneofDescriptor
|
1201
1200
|
*
|
1202
|
-
*
|
1201
|
+
* Creates a descriptor wrapper object. May only be called from C.
|
1203
1202
|
*/
|
1204
|
-
VALUE
|
1203
|
+
VALUE OneofDescriptor_initialize(VALUE _self, VALUE cookie,
|
1204
|
+
VALUE descriptor_pool, VALUE ptr) {
|
1205
1205
|
DEFINE_SELF(OneofDescriptor, self, _self);
|
1206
|
-
return rb_str_maybe_null(upb_oneofdef_name(self->oneofdef));
|
1207
|
-
}
|
1208
1206
|
|
1209
|
-
|
1210
|
-
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1216
|
-
|
1217
|
-
DEFINE_SELF(OneofDescriptor, self, _self);
|
1218
|
-
upb_oneofdef* mut_def = check_oneof_notfrozen(self->oneofdef);
|
1219
|
-
const char* str = get_str(value);
|
1220
|
-
CHECK_UPB(upb_oneofdef_setname(mut_def, str, &status),
|
1221
|
-
"Error setting oneof name");
|
1207
|
+
if (cookie != c_only_cookie) {
|
1208
|
+
rb_raise(rb_eRuntimeError,
|
1209
|
+
"Descriptor objects may not be created from Ruby.");
|
1210
|
+
}
|
1211
|
+
|
1212
|
+
self->descriptor_pool = descriptor_pool;
|
1213
|
+
self->oneofdef = (const upb_oneofdef*)NUM2ULL(ptr);
|
1214
|
+
|
1222
1215
|
return Qnil;
|
1223
1216
|
}
|
1224
1217
|
|
1225
1218
|
/*
|
1226
1219
|
* call-seq:
|
1227
|
-
* OneofDescriptor.
|
1228
|
-
*
|
1229
|
-
* Adds a field to this oneof. The field may have been added to this oneof in
|
1230
|
-
* the past, or the message to which this oneof belongs (if any), but may not
|
1231
|
-
* have already been added to any other oneof or message. Otherwise, an
|
1232
|
-
* exception is raised.
|
1220
|
+
* OneofDescriptor.name => name
|
1233
1221
|
*
|
1234
|
-
*
|
1235
|
-
* the message to which this oneof belongs, if it belongs to one currently, or
|
1236
|
-
* else will be added to any message to which the oneof is later added at the
|
1237
|
-
* time that it is added.
|
1222
|
+
* Returns the name of this oneof.
|
1238
1223
|
*/
|
1239
|
-
VALUE
|
1224
|
+
VALUE OneofDescriptor_name(VALUE _self) {
|
1240
1225
|
DEFINE_SELF(OneofDescriptor, self, _self);
|
1241
|
-
|
1242
|
-
FieldDescriptor* def = ruby_to_FieldDescriptor(obj);
|
1243
|
-
upb_fielddef* mut_field_def = check_field_notfrozen(def->fielddef);
|
1244
|
-
CHECK_UPB(
|
1245
|
-
upb_oneofdef_addfield(mut_def, mut_field_def, NULL, &status),
|
1246
|
-
"Adding field to OneofDescriptor failed");
|
1247
|
-
add_def_obj(def->fielddef, obj);
|
1248
|
-
return Qnil;
|
1226
|
+
return rb_str_maybe_null(upb_oneofdef_name(self->oneofdef));
|
1249
1227
|
}
|
1250
1228
|
|
1251
1229
|
/*
|
@@ -1261,7 +1239,7 @@ VALUE OneofDescriptor_each(VALUE _self, VALUE field) {
|
|
1261
1239
|
!upb_oneof_done(&it);
|
1262
1240
|
upb_oneof_next(&it)) {
|
1263
1241
|
const upb_fielddef* f = upb_oneof_iter_field(&it);
|
1264
|
-
VALUE obj =
|
1242
|
+
VALUE obj = get_fielddef_obj(self->descriptor_pool, f);
|
1265
1243
|
rb_yield(obj);
|
1266
1244
|
}
|
1267
1245
|
return Qnil;
|
@@ -1276,38 +1254,49 @@ DEFINE_CLASS(EnumDescriptor, "Google::Protobuf::EnumDescriptor");
|
|
1276
1254
|
void EnumDescriptor_mark(void* _self) {
|
1277
1255
|
EnumDescriptor* self = _self;
|
1278
1256
|
rb_gc_mark(self->module);
|
1257
|
+
rb_gc_mark(self->descriptor_pool);
|
1279
1258
|
}
|
1280
1259
|
|
1281
1260
|
void EnumDescriptor_free(void* _self) {
|
1282
|
-
|
1283
|
-
upb_enumdef_unref(self->enumdef, &self->enumdef);
|
1284
|
-
xfree(self);
|
1261
|
+
xfree(_self);
|
1285
1262
|
}
|
1286
1263
|
|
1287
|
-
/*
|
1288
|
-
* call-seq:
|
1289
|
-
* EnumDescriptor.new => enum_descriptor
|
1290
|
-
*
|
1291
|
-
* Creates a new, empty, enum descriptor. Must be added to a pool before the
|
1292
|
-
* enum type can be used. The enum type may only be modified prior to adding to
|
1293
|
-
* a pool.
|
1294
|
-
*/
|
1295
1264
|
VALUE EnumDescriptor_alloc(VALUE klass) {
|
1296
1265
|
EnumDescriptor* self = ALLOC(EnumDescriptor);
|
1297
1266
|
VALUE ret = TypedData_Wrap_Struct(klass, &_EnumDescriptor_type, self);
|
1298
|
-
self->enumdef =
|
1267
|
+
self->enumdef = NULL;
|
1299
1268
|
self->module = Qnil;
|
1269
|
+
self->descriptor_pool = Qnil;
|
1300
1270
|
return ret;
|
1301
1271
|
}
|
1302
1272
|
|
1273
|
+
/*
|
1274
|
+
* call-seq:
|
1275
|
+
* EnumDescriptor.new(c_only_cookie, ptr) => EnumDescriptor
|
1276
|
+
*
|
1277
|
+
* Creates a descriptor wrapper object. May only be called from C.
|
1278
|
+
*/
|
1279
|
+
VALUE EnumDescriptor_initialize(VALUE _self, VALUE cookie,
|
1280
|
+
VALUE descriptor_pool, VALUE ptr) {
|
1281
|
+
DEFINE_SELF(EnumDescriptor, self, _self);
|
1282
|
+
|
1283
|
+
if (cookie != c_only_cookie) {
|
1284
|
+
rb_raise(rb_eRuntimeError,
|
1285
|
+
"Descriptor objects may not be created from Ruby.");
|
1286
|
+
}
|
1287
|
+
|
1288
|
+
self->descriptor_pool = descriptor_pool;
|
1289
|
+
self->enumdef = (const upb_enumdef*)NUM2ULL(ptr);
|
1290
|
+
|
1291
|
+
return Qnil;
|
1292
|
+
}
|
1293
|
+
|
1303
1294
|
void EnumDescriptor_register(VALUE module) {
|
1304
1295
|
VALUE klass = rb_define_class_under(
|
1305
1296
|
module, "EnumDescriptor", rb_cObject);
|
1306
1297
|
rb_define_alloc_func(klass, EnumDescriptor_alloc);
|
1307
|
-
rb_define_method(klass, "initialize", EnumDescriptor_initialize,
|
1298
|
+
rb_define_method(klass, "initialize", EnumDescriptor_initialize, 3);
|
1308
1299
|
rb_define_method(klass, "name", EnumDescriptor_name, 0);
|
1309
|
-
rb_define_method(klass, "name=", EnumDescriptor_name_set, 1);
|
1310
|
-
rb_define_method(klass, "add_value", EnumDescriptor_add_value, 2);
|
1311
1300
|
rb_define_method(klass, "lookup_name", EnumDescriptor_lookup_name, 1);
|
1312
1301
|
rb_define_method(klass, "lookup_value", EnumDescriptor_lookup_value, 1);
|
1313
1302
|
rb_define_method(klass, "each", EnumDescriptor_each, 0);
|
@@ -1320,31 +1309,14 @@ void EnumDescriptor_register(VALUE module) {
|
|
1320
1309
|
|
1321
1310
|
/*
|
1322
1311
|
* call-seq:
|
1323
|
-
*
|
1324
|
-
*
|
1325
|
-
* Initializes a new descriptor and assigns a file descriptor to it.
|
1326
|
-
*/
|
1327
|
-
VALUE EnumDescriptor_initialize(VALUE _self, VALUE file_descriptor_rb) {
|
1328
|
-
DEFINE_SELF(EnumDescriptor, self, _self);
|
1329
|
-
FileDescriptor* file_descriptor = ruby_to_FileDescriptor(file_descriptor_rb);
|
1330
|
-
CHECK_UPB(
|
1331
|
-
upb_filedef_addenum(file_descriptor->filedef, self->enumdef,
|
1332
|
-
NULL, &status),
|
1333
|
-
"Failed to associate enum to file descriptor.");
|
1334
|
-
add_def_obj(file_descriptor->filedef, file_descriptor_rb);
|
1335
|
-
|
1336
|
-
return Qnil;
|
1337
|
-
}
|
1338
|
-
|
1339
|
-
/*
|
1340
|
-
* call-seq:
|
1341
|
-
* Descriptor.file_descriptor
|
1312
|
+
* EnumDescriptor.file_descriptor
|
1342
1313
|
*
|
1343
1314
|
* Returns the FileDescriptor object this enum belongs to.
|
1344
1315
|
*/
|
1345
1316
|
VALUE EnumDescriptor_file_descriptor(VALUE _self) {
|
1346
1317
|
DEFINE_SELF(EnumDescriptor, self, _self);
|
1347
|
-
return
|
1318
|
+
return get_filedef_obj(self->descriptor_pool,
|
1319
|
+
upb_enumdef_file(self->enumdef));
|
1348
1320
|
}
|
1349
1321
|
|
1350
1322
|
/*
|
@@ -1358,40 +1330,6 @@ VALUE EnumDescriptor_name(VALUE _self) {
|
|
1358
1330
|
return rb_str_maybe_null(upb_enumdef_fullname(self->enumdef));
|
1359
1331
|
}
|
1360
1332
|
|
1361
|
-
/*
|
1362
|
-
* call-seq:
|
1363
|
-
* EnumDescriptor.name = name
|
1364
|
-
*
|
1365
|
-
* Sets the name of this enum type. Cannot be called if the enum type has
|
1366
|
-
* already been added to a pool.
|
1367
|
-
*/
|
1368
|
-
VALUE EnumDescriptor_name_set(VALUE _self, VALUE str) {
|
1369
|
-
DEFINE_SELF(EnumDescriptor, self, _self);
|
1370
|
-
upb_enumdef* mut_def = check_enum_notfrozen(self->enumdef);
|
1371
|
-
const char* name = get_str(str);
|
1372
|
-
CHECK_UPB(upb_enumdef_setfullname(mut_def, name, &status),
|
1373
|
-
"Error setting EnumDescriptor name");
|
1374
|
-
return Qnil;
|
1375
|
-
}
|
1376
|
-
|
1377
|
-
/*
|
1378
|
-
* call-seq:
|
1379
|
-
* EnumDescriptor.add_value(key, value)
|
1380
|
-
*
|
1381
|
-
* Adds a new key => value mapping to this enum type. Key must be given as a
|
1382
|
-
* Ruby symbol. Cannot be called if the enum type has already been added to a
|
1383
|
-
* pool. Will raise an exception if the key or value is already in use.
|
1384
|
-
*/
|
1385
|
-
VALUE EnumDescriptor_add_value(VALUE _self, VALUE name, VALUE number) {
|
1386
|
-
DEFINE_SELF(EnumDescriptor, self, _self);
|
1387
|
-
upb_enumdef* mut_def = check_enum_notfrozen(self->enumdef);
|
1388
|
-
const char* name_str = rb_id2name(SYM2ID(name));
|
1389
|
-
int32_t val = NUM2INT(number);
|
1390
|
-
CHECK_UPB(upb_enumdef_addval(mut_def, name_str, val, &status),
|
1391
|
-
"Error adding value to enum");
|
1392
|
-
return Qnil;
|
1393
|
-
}
|
1394
|
-
|
1395
1333
|
/*
|
1396
1334
|
* call-seq:
|
1397
1335
|
* EnumDescriptor.lookup_name(name) => value
|
@@ -1454,18 +1392,12 @@ VALUE EnumDescriptor_each(VALUE _self) {
|
|
1454
1392
|
* call-seq:
|
1455
1393
|
* EnumDescriptor.enummodule => module
|
1456
1394
|
*
|
1457
|
-
* Returns the Ruby module corresponding to this enum type.
|
1458
|
-
* until the enum descriptor has been added to a pool.
|
1395
|
+
* Returns the Ruby module corresponding to this enum type.
|
1459
1396
|
*/
|
1460
1397
|
VALUE EnumDescriptor_enummodule(VALUE _self) {
|
1461
1398
|
DEFINE_SELF(EnumDescriptor, self, _self);
|
1462
|
-
if (!upb_def_isfrozen((const upb_def*)self->enumdef)) {
|
1463
|
-
rb_raise(rb_eRuntimeError,
|
1464
|
-
"Cannot fetch enum module from an EnumDescriptor not yet "
|
1465
|
-
"in a pool.");
|
1466
|
-
}
|
1467
1399
|
if (self->module == Qnil) {
|
1468
|
-
self->module = build_module_from_enumdesc(
|
1400
|
+
self->module = build_module_from_enumdesc(_self);
|
1469
1401
|
}
|
1470
1402
|
return self->module;
|
1471
1403
|
}
|
@@ -1479,8 +1411,7 @@ DEFINE_CLASS(MessageBuilderContext,
|
|
1479
1411
|
|
1480
1412
|
void MessageBuilderContext_mark(void* _self) {
|
1481
1413
|
MessageBuilderContext* self = _self;
|
1482
|
-
rb_gc_mark(self->
|
1483
|
-
rb_gc_mark(self->builder);
|
1414
|
+
rb_gc_mark(self->file_builder);
|
1484
1415
|
}
|
1485
1416
|
|
1486
1417
|
void MessageBuilderContext_free(void* _self) {
|
@@ -1492,8 +1423,7 @@ VALUE MessageBuilderContext_alloc(VALUE klass) {
|
|
1492
1423
|
MessageBuilderContext* self = ALLOC(MessageBuilderContext);
|
1493
1424
|
VALUE ret = TypedData_Wrap_Struct(
|
1494
1425
|
klass, &_MessageBuilderContext_type, self);
|
1495
|
-
self->
|
1496
|
-
self->builder = Qnil;
|
1426
|
+
self->file_builder = Qnil;
|
1497
1427
|
return ret;
|
1498
1428
|
}
|
1499
1429
|
|
@@ -1514,65 +1444,110 @@ void MessageBuilderContext_register(VALUE module) {
|
|
1514
1444
|
|
1515
1445
|
/*
|
1516
1446
|
* call-seq:
|
1517
|
-
* MessageBuilderContext.new(
|
1447
|
+
* MessageBuilderContext.new(file_builder, name) => context
|
1518
1448
|
*
|
1519
1449
|
* Create a new message builder context around the given message descriptor and
|
1520
1450
|
* builder context. This class is intended to serve as a DSL context to be used
|
1521
1451
|
* with #instance_eval.
|
1522
1452
|
*/
|
1523
1453
|
VALUE MessageBuilderContext_initialize(VALUE _self,
|
1524
|
-
VALUE
|
1525
|
-
VALUE
|
1454
|
+
VALUE _file_builder,
|
1455
|
+
VALUE name) {
|
1526
1456
|
DEFINE_SELF(MessageBuilderContext, self, _self);
|
1527
|
-
|
1528
|
-
|
1457
|
+
FileBuilderContext* file_builder = ruby_to_FileBuilderContext(_file_builder);
|
1458
|
+
google_protobuf_FileDescriptorProto* file_proto = file_builder->file_proto;
|
1459
|
+
|
1460
|
+
self->file_builder = _file_builder;
|
1461
|
+
self->msg_proto = google_protobuf_FileDescriptorProto_add_message_type(
|
1462
|
+
file_proto, file_builder->arena);
|
1463
|
+
|
1464
|
+
google_protobuf_DescriptorProto_set_name(
|
1465
|
+
self->msg_proto, FileBuilderContext_strdup(_file_builder, name));
|
1466
|
+
|
1529
1467
|
return Qnil;
|
1530
1468
|
}
|
1531
1469
|
|
1532
|
-
static
|
1533
|
-
|
1534
|
-
|
1535
|
-
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1470
|
+
static void msgdef_add_field(VALUE msgbuilder_rb, upb_label_t label, VALUE name,
|
1471
|
+
VALUE type, VALUE number, VALUE type_class,
|
1472
|
+
VALUE options, int oneof_index) {
|
1473
|
+
DEFINE_SELF(MessageBuilderContext, self, msgbuilder_rb);
|
1474
|
+
FileBuilderContext* file_context =
|
1475
|
+
ruby_to_FileBuilderContext(self->file_builder);
|
1476
|
+
google_protobuf_FieldDescriptorProto* field_proto;
|
1477
|
+
VALUE name_str;
|
1478
|
+
|
1479
|
+
field_proto = google_protobuf_DescriptorProto_add_field(self->msg_proto,
|
1480
|
+
file_context->arena);
|
1481
|
+
|
1482
|
+
Check_Type(name, T_SYMBOL);
|
1483
|
+
name_str = rb_id2str(SYM2ID(name));
|
1539
1484
|
|
1540
|
-
|
1541
|
-
|
1542
|
-
|
1543
|
-
|
1485
|
+
google_protobuf_FieldDescriptorProto_set_name(
|
1486
|
+
field_proto, FileBuilderContext_strdup(self->file_builder, name_str));
|
1487
|
+
google_protobuf_FieldDescriptorProto_set_number(field_proto, NUM2INT(number));
|
1488
|
+
google_protobuf_FieldDescriptorProto_set_label(field_proto, (int)label);
|
1489
|
+
google_protobuf_FieldDescriptorProto_set_type(
|
1490
|
+
field_proto, (int)ruby_to_descriptortype(type));
|
1544
1491
|
|
1545
1492
|
if (type_class != Qnil) {
|
1546
1493
|
Check_Type(type_class, T_STRING);
|
1547
1494
|
|
1548
1495
|
// Make it an absolute type name by prepending a dot.
|
1549
1496
|
type_class = rb_str_append(rb_str_new2("."), type_class);
|
1550
|
-
|
1497
|
+
google_protobuf_FieldDescriptorProto_set_type_name(
|
1498
|
+
field_proto, FileBuilderContext_strdup(self->file_builder, type_class));
|
1551
1499
|
}
|
1552
1500
|
|
1553
1501
|
if (options != Qnil) {
|
1554
1502
|
Check_Type(options, T_HASH);
|
1555
1503
|
|
1556
1504
|
if (rb_funcall(options, rb_intern("key?"), 1,
|
1557
|
-
|
1558
|
-
|
1559
|
-
|
1560
|
-
rb_raise(rb_eArgError, "Cannot set :default when using proto3 syntax.");
|
1561
|
-
}
|
1505
|
+
ID2SYM(rb_intern("default"))) == Qtrue) {
|
1506
|
+
VALUE default_value =
|
1507
|
+
rb_hash_lookup(options, ID2SYM(rb_intern("default")));
|
1562
1508
|
|
1563
|
-
|
1564
|
-
|
1565
|
-
upb_fielddef_issubmsg((upb_fielddef*)fielddef->fielddef)) {
|
1566
|
-
rb_raise(rb_eArgError, "Cannot set :default on this kind of field.");
|
1567
|
-
}
|
1509
|
+
/* Call #to_s since all defaults are strings in the descriptor. */
|
1510
|
+
default_value = rb_funcall(default_value, rb_intern("to_s"), 0);
|
1568
1511
|
|
1569
|
-
|
1570
|
-
|
1512
|
+
google_protobuf_FieldDescriptorProto_set_default_value(
|
1513
|
+
field_proto,
|
1514
|
+
FileBuilderContext_strdup(self->file_builder, default_value));
|
1571
1515
|
}
|
1572
1516
|
}
|
1573
1517
|
|
1574
|
-
|
1575
|
-
|
1518
|
+
if (oneof_index >= 0) {
|
1519
|
+
google_protobuf_FieldDescriptorProto_set_oneof_index(field_proto,
|
1520
|
+
oneof_index);
|
1521
|
+
}
|
1522
|
+
}
|
1523
|
+
|
1524
|
+
static VALUE make_mapentry(VALUE _message_builder, VALUE types, int argc,
|
1525
|
+
VALUE* argv) {
|
1526
|
+
DEFINE_SELF(MessageBuilderContext, message_builder, _message_builder);
|
1527
|
+
VALUE type_class = rb_ary_entry(types, 2);
|
1528
|
+
FileBuilderContext* file_context =
|
1529
|
+
ruby_to_FileBuilderContext(message_builder->file_builder);
|
1530
|
+
google_protobuf_MessageOptions* options =
|
1531
|
+
google_protobuf_DescriptorProto_mutable_options(
|
1532
|
+
message_builder->msg_proto, file_context->arena);
|
1533
|
+
|
1534
|
+
google_protobuf_MessageOptions_set_map_entry(options, true);
|
1535
|
+
|
1536
|
+
// optional <type> key = 1;
|
1537
|
+
rb_funcall(_message_builder, rb_intern("optional"), 3,
|
1538
|
+
ID2SYM(rb_intern("key")), rb_ary_entry(types, 0), INT2NUM(1));
|
1539
|
+
|
1540
|
+
// optional <type> value = 2;
|
1541
|
+
if (type_class == Qnil) {
|
1542
|
+
rb_funcall(_message_builder, rb_intern("optional"), 3,
|
1543
|
+
ID2SYM(rb_intern("value")), rb_ary_entry(types, 1), INT2NUM(2));
|
1544
|
+
} else {
|
1545
|
+
rb_funcall(_message_builder, rb_intern("optional"), 4,
|
1546
|
+
ID2SYM(rb_intern("value")), rb_ary_entry(types, 1), INT2NUM(2),
|
1547
|
+
type_class);
|
1548
|
+
}
|
1549
|
+
|
1550
|
+
return Qnil;
|
1576
1551
|
}
|
1577
1552
|
|
1578
1553
|
/*
|
@@ -1586,7 +1561,6 @@ static VALUE msgdef_add_field(VALUE msgdef_rb,
|
|
1586
1561
|
* string, if present (as accepted by FieldDescriptor#submsg_name=).
|
1587
1562
|
*/
|
1588
1563
|
VALUE MessageBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
|
1589
|
-
DEFINE_SELF(MessageBuilderContext, self, _self);
|
1590
1564
|
VALUE name, type, number;
|
1591
1565
|
VALUE type_class, options = Qnil;
|
1592
1566
|
|
@@ -1599,8 +1573,10 @@ VALUE MessageBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
|
|
1599
1573
|
type_class = Qnil;
|
1600
1574
|
}
|
1601
1575
|
|
1602
|
-
|
1603
|
-
|
1576
|
+
msgdef_add_field(_self, UPB_LABEL_OPTIONAL, name, type, number, type_class,
|
1577
|
+
options, -1);
|
1578
|
+
|
1579
|
+
return Qnil;
|
1604
1580
|
}
|
1605
1581
|
|
1606
1582
|
/*
|
@@ -1618,7 +1594,6 @@ VALUE MessageBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
|
|
1618
1594
|
* pool will currently result in an error.
|
1619
1595
|
*/
|
1620
1596
|
VALUE MessageBuilderContext_required(int argc, VALUE* argv, VALUE _self) {
|
1621
|
-
DEFINE_SELF(MessageBuilderContext, self, _self);
|
1622
1597
|
VALUE name, type, number;
|
1623
1598
|
VALUE type_class, options = Qnil;
|
1624
1599
|
|
@@ -1631,8 +1606,10 @@ VALUE MessageBuilderContext_required(int argc, VALUE* argv, VALUE _self) {
|
|
1631
1606
|
type_class = Qnil;
|
1632
1607
|
}
|
1633
1608
|
|
1634
|
-
|
1635
|
-
|
1609
|
+
msgdef_add_field(_self, UPB_LABEL_REQUIRED, name, type, number, type_class,
|
1610
|
+
options, -1);
|
1611
|
+
|
1612
|
+
return Qnil;
|
1636
1613
|
}
|
1637
1614
|
|
1638
1615
|
/*
|
@@ -1645,7 +1622,6 @@ VALUE MessageBuilderContext_required(int argc, VALUE* argv, VALUE _self) {
|
|
1645
1622
|
* string, if present (as accepted by FieldDescriptor#submsg_name=).
|
1646
1623
|
*/
|
1647
1624
|
VALUE MessageBuilderContext_repeated(int argc, VALUE* argv, VALUE _self) {
|
1648
|
-
DEFINE_SELF(MessageBuilderContext, self, _self);
|
1649
1625
|
VALUE name, type, number, type_class;
|
1650
1626
|
|
1651
1627
|
if (argc < 3) {
|
@@ -1656,8 +1632,10 @@ VALUE MessageBuilderContext_repeated(int argc, VALUE* argv, VALUE _self) {
|
|
1656
1632
|
number = argv[2];
|
1657
1633
|
type_class = (argc > 3) ? argv[3] : Qnil;
|
1658
1634
|
|
1659
|
-
|
1660
|
-
|
1635
|
+
msgdef_add_field(_self, UPB_LABEL_REPEATED, name, type, number, type_class,
|
1636
|
+
Qnil, -1);
|
1637
|
+
|
1638
|
+
return Qnil;
|
1661
1639
|
}
|
1662
1640
|
|
1663
1641
|
/*
|
@@ -1675,7 +1653,9 @@ VALUE MessageBuilderContext_repeated(int argc, VALUE* argv, VALUE _self) {
|
|
1675
1653
|
VALUE MessageBuilderContext_map(int argc, VALUE* argv, VALUE _self) {
|
1676
1654
|
DEFINE_SELF(MessageBuilderContext, self, _self);
|
1677
1655
|
VALUE name, key_type, value_type, number, type_class;
|
1678
|
-
VALUE
|
1656
|
+
VALUE mapentry_desc_name;
|
1657
|
+
FileBuilderContext* file_builder;
|
1658
|
+
upb_strview msg_name;
|
1679
1659
|
|
1680
1660
|
if (argc < 4) {
|
1681
1661
|
rb_raise(rb_eArgError, "Expected at least 4 arguments.");
|
@@ -1698,77 +1678,44 @@ VALUE MessageBuilderContext_map(int argc, VALUE* argv, VALUE _self) {
|
|
1698
1678
|
"type.");
|
1699
1679
|
}
|
1700
1680
|
|
1701
|
-
|
1702
|
-
|
1681
|
+
file_builder = ruby_to_FileBuilderContext(self->file_builder);
|
1682
|
+
|
1683
|
+
// TODO(haberman): remove this restriction, maps are supported in proto2.
|
1684
|
+
if (upb_strview_eql(
|
1685
|
+
google_protobuf_FileDescriptorProto_syntax(file_builder->file_proto),
|
1686
|
+
upb_strview_makez("proto2"))) {
|
1703
1687
|
rb_raise(rb_eArgError,
|
1704
|
-
|
1688
|
+
"Cannot add a native map field using proto2 syntax.");
|
1705
1689
|
}
|
1706
1690
|
|
1707
1691
|
// Create a new message descriptor for the map entry message, and create a
|
1708
1692
|
// repeated submessage field here with that type.
|
1709
|
-
|
1710
|
-
|
1711
|
-
mapentry_desc = rb_class_new_instance(1, &file_descriptor_rb, cDescriptor);
|
1712
|
-
mapentry_desc_name = rb_funcall(self->descriptor, rb_intern("name"), 0);
|
1693
|
+
msg_name = google_protobuf_DescriptorProto_name(self->msg_proto);
|
1694
|
+
mapentry_desc_name = rb_str_new(msg_name.data, msg_name.size);
|
1713
1695
|
mapentry_desc_name = rb_str_cat2(mapentry_desc_name, "_MapEntry_");
|
1714
|
-
mapentry_desc_name =
|
1715
|
-
|
1716
|
-
Descriptor_name_set(mapentry_desc, mapentry_desc_name);
|
1717
|
-
|
1718
|
-
{
|
1719
|
-
// The 'mapentry' attribute has no Ruby setter because we do not want the
|
1720
|
-
// user attempting to DIY the setup below; we want to ensure that the fields
|
1721
|
-
// are correct. So we reach into the msgdef here to set the bit manually.
|
1722
|
-
Descriptor* mapentry_desc_self = ruby_to_Descriptor(mapentry_desc);
|
1723
|
-
upb_msgdef_setmapentry((upb_msgdef*)mapentry_desc_self->msgdef, true);
|
1724
|
-
}
|
1725
|
-
|
1726
|
-
{
|
1727
|
-
// optional <type> key = 1;
|
1728
|
-
VALUE key_field = rb_class_new_instance(0, NULL, cFieldDescriptor);
|
1729
|
-
FieldDescriptor_name_set(key_field, rb_str_new2("key"));
|
1730
|
-
FieldDescriptor_label_set(key_field, ID2SYM(rb_intern("optional")));
|
1731
|
-
FieldDescriptor_number_set(key_field, INT2NUM(1));
|
1732
|
-
FieldDescriptor_type_set(key_field, key_type);
|
1733
|
-
Descriptor_add_field(mapentry_desc, key_field);
|
1734
|
-
}
|
1696
|
+
mapentry_desc_name =
|
1697
|
+
rb_str_cat2(mapentry_desc_name, rb_id2name(SYM2ID(name)));
|
1735
1698
|
|
1736
1699
|
{
|
1737
|
-
//
|
1738
|
-
VALUE
|
1739
|
-
|
1740
|
-
|
1741
|
-
|
1742
|
-
FieldDescriptor_type_set(value_field, value_type);
|
1743
|
-
if (type_class != Qnil) {
|
1744
|
-
VALUE submsg_name = rb_str_new2("."); // prepend '.' to make absolute.
|
1745
|
-
submsg_name = rb_str_append(submsg_name, type_class);
|
1746
|
-
FieldDescriptor_submsg_name_set(value_field, submsg_name);
|
1747
|
-
}
|
1748
|
-
Descriptor_add_field(mapentry_desc, value_field);
|
1700
|
+
// message <msgname>_MapEntry_ { /* ... */ }
|
1701
|
+
VALUE args[1] = {mapentry_desc_name};
|
1702
|
+
VALUE types = rb_ary_new3(3, key_type, value_type, type_class);
|
1703
|
+
rb_block_call(self->file_builder, rb_intern("add_message"), 1, args,
|
1704
|
+
make_mapentry, types);
|
1749
1705
|
}
|
1750
1706
|
|
1751
|
-
|
1752
|
-
|
1753
|
-
|
1754
|
-
|
1755
|
-
|
1707
|
+
// If this file is in a package, we need to qualify the map entry type.
|
1708
|
+
if (google_protobuf_FileDescriptorProto_has_package(file_builder->file_proto)) {
|
1709
|
+
upb_strview package_view =
|
1710
|
+
google_protobuf_FileDescriptorProto_package(file_builder->file_proto);
|
1711
|
+
VALUE package = rb_str_new(package_view.data, package_view.size);
|
1712
|
+
package = rb_str_cat2(package, ".");
|
1713
|
+
mapentry_desc_name = rb_str_concat(package, mapentry_desc_name);
|
1756
1714
|
}
|
1757
1715
|
|
1758
|
-
|
1759
|
-
|
1760
|
-
|
1761
|
-
VALUE submsg_name;
|
1762
|
-
|
1763
|
-
FieldDescriptor_name_set(map_field, name_str);
|
1764
|
-
FieldDescriptor_number_set(map_field, number);
|
1765
|
-
FieldDescriptor_label_set(map_field, ID2SYM(rb_intern("repeated")));
|
1766
|
-
FieldDescriptor_type_set(map_field, ID2SYM(rb_intern("message")));
|
1767
|
-
submsg_name = rb_str_new2("."); // prepend '.' to make name absolute.
|
1768
|
-
submsg_name = rb_str_append(submsg_name, mapentry_desc_name);
|
1769
|
-
FieldDescriptor_submsg_name_set(map_field, submsg_name);
|
1770
|
-
Descriptor_add_field(self->descriptor, map_field);
|
1771
|
-
}
|
1716
|
+
// repeated MapEntry <name> = <number>;
|
1717
|
+
rb_funcall(_self, rb_intern("repeated"), 4, name,
|
1718
|
+
ID2SYM(rb_intern("message")), number, mapentry_desc_name);
|
1772
1719
|
|
1773
1720
|
return Qnil;
|
1774
1721
|
}
|
@@ -1786,14 +1733,27 @@ VALUE MessageBuilderContext_map(int argc, VALUE* argv, VALUE _self) {
|
|
1786
1733
|
*/
|
1787
1734
|
VALUE MessageBuilderContext_oneof(VALUE _self, VALUE name) {
|
1788
1735
|
DEFINE_SELF(MessageBuilderContext, self, _self);
|
1789
|
-
|
1790
|
-
|
1791
|
-
|
1792
|
-
|
1793
|
-
|
1794
|
-
|
1795
|
-
|
1796
|
-
|
1736
|
+
size_t oneof_count;
|
1737
|
+
FileBuilderContext* file_context =
|
1738
|
+
ruby_to_FileBuilderContext(self->file_builder);
|
1739
|
+
google_protobuf_OneofDescriptorProto* oneof_proto;
|
1740
|
+
|
1741
|
+
// Existing oneof_count becomes oneof_index.
|
1742
|
+
google_protobuf_DescriptorProto_oneof_decl(self->msg_proto, &oneof_count);
|
1743
|
+
|
1744
|
+
// Create oneof_proto and set its name.
|
1745
|
+
oneof_proto = google_protobuf_DescriptorProto_add_oneof_decl(
|
1746
|
+
self->msg_proto, file_context->arena);
|
1747
|
+
google_protobuf_OneofDescriptorProto_set_name(
|
1748
|
+
oneof_proto, FileBuilderContext_strdup_sym(self->file_builder, name));
|
1749
|
+
|
1750
|
+
// Evaluate the block with the builder as argument.
|
1751
|
+
{
|
1752
|
+
VALUE args[2] = { INT2NUM(oneof_count), _self };
|
1753
|
+
VALUE ctx = rb_class_new_instance(2, args, cOneofBuilderContext);
|
1754
|
+
VALUE block = rb_block_proc();
|
1755
|
+
rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
|
1756
|
+
}
|
1797
1757
|
|
1798
1758
|
return Qnil;
|
1799
1759
|
}
|
@@ -1807,21 +1767,19 @@ DEFINE_CLASS(OneofBuilderContext,
|
|
1807
1767
|
|
1808
1768
|
void OneofBuilderContext_mark(void* _self) {
|
1809
1769
|
OneofBuilderContext* self = _self;
|
1810
|
-
rb_gc_mark(self->
|
1811
|
-
rb_gc_mark(self->builder);
|
1770
|
+
rb_gc_mark(self->message_builder);
|
1812
1771
|
}
|
1813
1772
|
|
1814
1773
|
void OneofBuilderContext_free(void* _self) {
|
1815
|
-
|
1816
|
-
xfree(self);
|
1774
|
+
xfree(_self);
|
1817
1775
|
}
|
1818
1776
|
|
1819
1777
|
VALUE OneofBuilderContext_alloc(VALUE klass) {
|
1820
1778
|
OneofBuilderContext* self = ALLOC(OneofBuilderContext);
|
1821
1779
|
VALUE ret = TypedData_Wrap_Struct(
|
1822
1780
|
klass, &_OneofBuilderContext_type, self);
|
1823
|
-
self->
|
1824
|
-
self->
|
1781
|
+
self->oneof_index = 0;
|
1782
|
+
self->message_builder = Qnil;
|
1825
1783
|
return ret;
|
1826
1784
|
}
|
1827
1785
|
|
@@ -1838,18 +1796,18 @@ void OneofBuilderContext_register(VALUE module) {
|
|
1838
1796
|
|
1839
1797
|
/*
|
1840
1798
|
* call-seq:
|
1841
|
-
* OneofBuilderContext.new(
|
1799
|
+
* OneofBuilderContext.new(oneof_index, message_builder) => context
|
1842
1800
|
*
|
1843
1801
|
* Create a new oneof builder context around the given oneof descriptor and
|
1844
1802
|
* builder context. This class is intended to serve as a DSL context to be used
|
1845
1803
|
* with #instance_eval.
|
1846
1804
|
*/
|
1847
1805
|
VALUE OneofBuilderContext_initialize(VALUE _self,
|
1848
|
-
VALUE
|
1849
|
-
VALUE
|
1806
|
+
VALUE oneof_index,
|
1807
|
+
VALUE message_builder) {
|
1850
1808
|
DEFINE_SELF(OneofBuilderContext, self, _self);
|
1851
|
-
self->
|
1852
|
-
self->
|
1809
|
+
self->oneof_index = NUM2INT(oneof_index);
|
1810
|
+
self->message_builder = message_builder;
|
1853
1811
|
return Qnil;
|
1854
1812
|
}
|
1855
1813
|
|
@@ -1870,8 +1828,10 @@ VALUE OneofBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
|
|
1870
1828
|
|
1871
1829
|
rb_scan_args(argc, argv, "32", &name, &type, &number, &type_class, &options);
|
1872
1830
|
|
1873
|
-
|
1874
|
-
|
1831
|
+
msgdef_add_field(self->message_builder, UPB_LABEL_OPTIONAL, name, type,
|
1832
|
+
number, type_class, options, self->oneof_index);
|
1833
|
+
|
1834
|
+
return Qnil;
|
1875
1835
|
}
|
1876
1836
|
|
1877
1837
|
// -----------------------------------------------------------------------------
|
@@ -1883,19 +1843,19 @@ DEFINE_CLASS(EnumBuilderContext,
|
|
1883
1843
|
|
1884
1844
|
void EnumBuilderContext_mark(void* _self) {
|
1885
1845
|
EnumBuilderContext* self = _self;
|
1886
|
-
rb_gc_mark(self->
|
1846
|
+
rb_gc_mark(self->file_builder);
|
1887
1847
|
}
|
1888
1848
|
|
1889
1849
|
void EnumBuilderContext_free(void* _self) {
|
1890
|
-
|
1891
|
-
xfree(self);
|
1850
|
+
xfree(_self);
|
1892
1851
|
}
|
1893
1852
|
|
1894
1853
|
VALUE EnumBuilderContext_alloc(VALUE klass) {
|
1895
1854
|
EnumBuilderContext* self = ALLOC(EnumBuilderContext);
|
1896
1855
|
VALUE ret = TypedData_Wrap_Struct(
|
1897
1856
|
klass, &_EnumBuilderContext_type, self);
|
1898
|
-
self->
|
1857
|
+
self->enum_proto = NULL;
|
1858
|
+
self->file_builder = Qnil;
|
1899
1859
|
return ret;
|
1900
1860
|
}
|
1901
1861
|
|
@@ -1903,8 +1863,7 @@ void EnumBuilderContext_register(VALUE module) {
|
|
1903
1863
|
VALUE klass = rb_define_class_under(
|
1904
1864
|
module, "EnumBuilderContext", rb_cObject);
|
1905
1865
|
rb_define_alloc_func(klass, EnumBuilderContext_alloc);
|
1906
|
-
rb_define_method(klass, "initialize",
|
1907
|
-
EnumBuilderContext_initialize, 1);
|
1866
|
+
rb_define_method(klass, "initialize", EnumBuilderContext_initialize, 2);
|
1908
1867
|
rb_define_method(klass, "value", EnumBuilderContext_value, 2);
|
1909
1868
|
rb_gc_register_address(&cEnumBuilderContext);
|
1910
1869
|
cEnumBuilderContext = klass;
|
@@ -1912,20 +1871,24 @@ void EnumBuilderContext_register(VALUE module) {
|
|
1912
1871
|
|
1913
1872
|
/*
|
1914
1873
|
* call-seq:
|
1915
|
-
* EnumBuilderContext.new(
|
1874
|
+
* EnumBuilderContext.new(file_builder) => context
|
1916
1875
|
*
|
1917
1876
|
* Create a new builder context around the given enum descriptor. This class is
|
1918
1877
|
* intended to serve as a DSL context to be used with #instance_eval.
|
1919
1878
|
*/
|
1920
|
-
VALUE EnumBuilderContext_initialize(VALUE _self, VALUE
|
1879
|
+
VALUE EnumBuilderContext_initialize(VALUE _self, VALUE _file_builder,
|
1880
|
+
VALUE name) {
|
1921
1881
|
DEFINE_SELF(EnumBuilderContext, self, _self);
|
1922
|
-
|
1923
|
-
|
1924
|
-
|
1882
|
+
FileBuilderContext* file_builder = ruby_to_FileBuilderContext(_file_builder);
|
1883
|
+
google_protobuf_FileDescriptorProto* file_proto = file_builder->file_proto;
|
1884
|
+
|
1885
|
+
self->file_builder = _file_builder;
|
1886
|
+
self->enum_proto = google_protobuf_FileDescriptorProto_add_enum_type(
|
1887
|
+
file_proto, file_builder->arena);
|
1888
|
+
|
1889
|
+
google_protobuf_EnumDescriptorProto_set_name(
|
1890
|
+
self->enum_proto, FileBuilderContext_strdup(_file_builder, name));
|
1925
1891
|
|
1926
|
-
static VALUE enumdef_add_value(VALUE enumdef,
|
1927
|
-
VALUE name, VALUE number) {
|
1928
|
-
rb_funcall(enumdef, rb_intern("add_value"), 2, name, number);
|
1929
1892
|
return Qnil;
|
1930
1893
|
}
|
1931
1894
|
|
@@ -1938,7 +1901,19 @@ static VALUE enumdef_add_value(VALUE enumdef,
|
|
1938
1901
|
*/
|
1939
1902
|
VALUE EnumBuilderContext_value(VALUE _self, VALUE name, VALUE number) {
|
1940
1903
|
DEFINE_SELF(EnumBuilderContext, self, _self);
|
1941
|
-
|
1904
|
+
FileBuilderContext* file_builder =
|
1905
|
+
ruby_to_FileBuilderContext(self->file_builder);
|
1906
|
+
google_protobuf_EnumValueDescriptorProto* enum_value;
|
1907
|
+
|
1908
|
+
enum_value = google_protobuf_EnumDescriptorProto_add_value(
|
1909
|
+
self->enum_proto, file_builder->arena);
|
1910
|
+
|
1911
|
+
google_protobuf_EnumValueDescriptorProto_set_name(
|
1912
|
+
enum_value, FileBuilderContext_strdup_sym(self->file_builder, name));
|
1913
|
+
google_protobuf_EnumValueDescriptorProto_set_number(enum_value,
|
1914
|
+
NUM2INT(number));
|
1915
|
+
|
1916
|
+
return Qnil;
|
1942
1917
|
}
|
1943
1918
|
|
1944
1919
|
|
@@ -1947,33 +1922,55 @@ VALUE EnumBuilderContext_value(VALUE _self, VALUE name, VALUE number) {
|
|
1947
1922
|
// -----------------------------------------------------------------------------
|
1948
1923
|
|
1949
1924
|
DEFINE_CLASS(FileBuilderContext,
|
1950
|
-
|
1925
|
+
"Google::Protobuf::Internal::FileBuilderContext");
|
1951
1926
|
|
1952
1927
|
void FileBuilderContext_mark(void* _self) {
|
1953
1928
|
FileBuilderContext* self = _self;
|
1954
|
-
rb_gc_mark(self->
|
1955
|
-
rb_gc_mark(self->file_descriptor);
|
1956
|
-
rb_gc_mark(self->builder);
|
1929
|
+
rb_gc_mark(self->descriptor_pool);
|
1957
1930
|
}
|
1958
1931
|
|
1959
1932
|
void FileBuilderContext_free(void* _self) {
|
1960
1933
|
FileBuilderContext* self = _self;
|
1934
|
+
upb_arena_free(self->arena);
|
1961
1935
|
xfree(self);
|
1962
1936
|
}
|
1963
1937
|
|
1938
|
+
upb_strview FileBuilderContext_strdup2(VALUE _self, const char *str) {
|
1939
|
+
DEFINE_SELF(FileBuilderContext, self, _self);
|
1940
|
+
upb_strview ret;
|
1941
|
+
char *data;
|
1942
|
+
|
1943
|
+
ret.size = strlen(str);
|
1944
|
+
data = upb_malloc(upb_arena_alloc(self->arena), ret.size + 1);
|
1945
|
+
ret.data = data;
|
1946
|
+
memcpy(data, str, ret.size);
|
1947
|
+
/* Null-terminate required by rewrite_enum_defaults() above. */
|
1948
|
+
data[ret.size] = '\0';
|
1949
|
+
return ret;
|
1950
|
+
}
|
1951
|
+
|
1952
|
+
upb_strview FileBuilderContext_strdup(VALUE _self, VALUE rb_str) {
|
1953
|
+
return FileBuilderContext_strdup2(_self, get_str(rb_str));
|
1954
|
+
}
|
1955
|
+
|
1956
|
+
upb_strview FileBuilderContext_strdup_sym(VALUE _self, VALUE rb_sym) {
|
1957
|
+
Check_Type(rb_sym, T_SYMBOL);
|
1958
|
+
return FileBuilderContext_strdup(_self, rb_id2str(SYM2ID(rb_sym)));
|
1959
|
+
}
|
1960
|
+
|
1964
1961
|
VALUE FileBuilderContext_alloc(VALUE klass) {
|
1965
1962
|
FileBuilderContext* self = ALLOC(FileBuilderContext);
|
1966
1963
|
VALUE ret = TypedData_Wrap_Struct(klass, &_FileBuilderContext_type, self);
|
1967
|
-
self->
|
1968
|
-
self->
|
1969
|
-
self->
|
1964
|
+
self->arena = upb_arena_new();
|
1965
|
+
self->file_proto = google_protobuf_FileDescriptorProto_new(self->arena);
|
1966
|
+
self->descriptor_pool = Qnil;
|
1970
1967
|
return ret;
|
1971
1968
|
}
|
1972
1969
|
|
1973
1970
|
void FileBuilderContext_register(VALUE module) {
|
1974
1971
|
VALUE klass = rb_define_class_under(module, "FileBuilderContext", rb_cObject);
|
1975
1972
|
rb_define_alloc_func(klass, FileBuilderContext_alloc);
|
1976
|
-
rb_define_method(klass, "initialize", FileBuilderContext_initialize,
|
1973
|
+
rb_define_method(klass, "initialize", FileBuilderContext_initialize, 3);
|
1977
1974
|
rb_define_method(klass, "add_message", FileBuilderContext_add_message, 1);
|
1978
1975
|
rb_define_method(klass, "add_enum", FileBuilderContext_add_enum, 1);
|
1979
1976
|
rb_gc_register_address(&cFileBuilderContext);
|
@@ -1982,18 +1979,41 @@ void FileBuilderContext_register(VALUE module) {
|
|
1982
1979
|
|
1983
1980
|
/*
|
1984
1981
|
* call-seq:
|
1985
|
-
* FileBuilderContext.new(
|
1982
|
+
* FileBuilderContext.new(descriptor_pool) => context
|
1986
1983
|
*
|
1987
1984
|
* Create a new file builder context for the given file descriptor and
|
1988
1985
|
* builder context. This class is intended to serve as a DSL context to be used
|
1989
1986
|
* with #instance_eval.
|
1990
1987
|
*/
|
1991
|
-
VALUE FileBuilderContext_initialize(VALUE _self, VALUE
|
1992
|
-
|
1988
|
+
VALUE FileBuilderContext_initialize(VALUE _self, VALUE descriptor_pool,
|
1989
|
+
VALUE name, VALUE options) {
|
1993
1990
|
DEFINE_SELF(FileBuilderContext, self, _self);
|
1994
|
-
self->
|
1995
|
-
|
1996
|
-
|
1991
|
+
self->descriptor_pool = descriptor_pool;
|
1992
|
+
|
1993
|
+
google_protobuf_FileDescriptorProto_set_name(
|
1994
|
+
self->file_proto, FileBuilderContext_strdup(_self, name));
|
1995
|
+
|
1996
|
+
// Default syntax for Ruby is proto3.
|
1997
|
+
google_protobuf_FileDescriptorProto_set_syntax(
|
1998
|
+
self->file_proto,
|
1999
|
+
FileBuilderContext_strdup(_self, rb_str_new2("proto3")));
|
2000
|
+
|
2001
|
+
if (options != Qnil) {
|
2002
|
+
VALUE syntax;
|
2003
|
+
|
2004
|
+
Check_Type(options, T_HASH);
|
2005
|
+
syntax = rb_hash_lookup2(options, ID2SYM(rb_intern("syntax")), Qnil);
|
2006
|
+
|
2007
|
+
if (syntax != Qnil) {
|
2008
|
+
VALUE syntax_str;
|
2009
|
+
|
2010
|
+
Check_Type(syntax, T_SYMBOL);
|
2011
|
+
syntax_str = rb_id2str(SYM2ID(syntax));
|
2012
|
+
google_protobuf_FileDescriptorProto_set_syntax(
|
2013
|
+
self->file_proto, FileBuilderContext_strdup(_self, syntax_str));
|
2014
|
+
}
|
2015
|
+
}
|
2016
|
+
|
1997
2017
|
return Qnil;
|
1998
2018
|
}
|
1999
2019
|
|
@@ -2009,14 +2029,10 @@ VALUE FileBuilderContext_initialize(VALUE _self, VALUE file_descriptor,
|
|
2009
2029
|
* This is the recommended, idiomatic way to build message definitions.
|
2010
2030
|
*/
|
2011
2031
|
VALUE FileBuilderContext_add_message(VALUE _self, VALUE name) {
|
2012
|
-
|
2013
|
-
VALUE msgdef = rb_class_new_instance(1, &self->file_descriptor, cDescriptor);
|
2014
|
-
VALUE args[2] = { msgdef, self->builder };
|
2032
|
+
VALUE args[2] = { _self, name };
|
2015
2033
|
VALUE ctx = rb_class_new_instance(2, args, cMessageBuilderContext);
|
2016
2034
|
VALUE block = rb_block_proc();
|
2017
|
-
rb_funcall(msgdef, rb_intern("name="), 1, name);
|
2018
2035
|
rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
|
2019
|
-
rb_ary_push(self->pending_list, msgdef);
|
2020
2036
|
return Qnil;
|
2021
2037
|
}
|
2022
2038
|
|
@@ -2031,20 +2047,26 @@ VALUE FileBuilderContext_add_message(VALUE _self, VALUE name) {
|
|
2031
2047
|
* This is the recommended, idiomatic way to build enum definitions.
|
2032
2048
|
*/
|
2033
2049
|
VALUE FileBuilderContext_add_enum(VALUE _self, VALUE name) {
|
2034
|
-
|
2035
|
-
VALUE
|
2036
|
-
rb_class_new_instance(1, &self->file_descriptor, cEnumDescriptor);
|
2037
|
-
VALUE ctx = rb_class_new_instance(1, &enumdef, cEnumBuilderContext);
|
2050
|
+
VALUE args[2] = { _self, name };
|
2051
|
+
VALUE ctx = rb_class_new_instance(2, args, cEnumBuilderContext);
|
2038
2052
|
VALUE block = rb_block_proc();
|
2039
|
-
rb_funcall(enumdef, rb_intern("name="), 1, name);
|
2040
2053
|
rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
|
2041
|
-
rb_ary_push(self->pending_list, enumdef);
|
2042
2054
|
return Qnil;
|
2043
2055
|
}
|
2044
2056
|
|
2045
|
-
|
2057
|
+
void FileBuilderContext_build(VALUE _self) {
|
2046
2058
|
DEFINE_SELF(FileBuilderContext, self, _self);
|
2047
|
-
|
2059
|
+
DescriptorPool* pool = ruby_to_DescriptorPool(self->descriptor_pool);
|
2060
|
+
upb_status status;
|
2061
|
+
|
2062
|
+
rewrite_enum_defaults(pool->symtab, self->file_proto);
|
2063
|
+
rewrite_names(_self, self->file_proto);
|
2064
|
+
|
2065
|
+
upb_status_clear(&status);
|
2066
|
+
if (!upb_symtab_addfile(pool->symtab, self->file_proto, &status)) {
|
2067
|
+
rb_raise(cTypeError, "Unable to add defs to DescriptorPool: %s",
|
2068
|
+
upb_status_errmsg(&status));
|
2069
|
+
}
|
2048
2070
|
}
|
2049
2071
|
|
2050
2072
|
// -----------------------------------------------------------------------------
|
@@ -2055,58 +2077,46 @@ DEFINE_CLASS(Builder, "Google::Protobuf::Internal::Builder");
|
|
2055
2077
|
|
2056
2078
|
void Builder_mark(void* _self) {
|
2057
2079
|
Builder* self = _self;
|
2058
|
-
rb_gc_mark(self->
|
2059
|
-
rb_gc_mark(self->
|
2080
|
+
rb_gc_mark(self->descriptor_pool);
|
2081
|
+
rb_gc_mark(self->default_file_builder);
|
2060
2082
|
}
|
2061
2083
|
|
2062
2084
|
void Builder_free(void* _self) {
|
2063
|
-
|
2064
|
-
xfree(self->defs);
|
2065
|
-
xfree(self);
|
2085
|
+
xfree(_self);
|
2066
2086
|
}
|
2067
2087
|
|
2068
|
-
/*
|
2069
|
-
* call-seq:
|
2070
|
-
* Builder.new => builder
|
2071
|
-
*
|
2072
|
-
* Creates a new Builder. A Builder can accumulate a set of new message and enum
|
2073
|
-
* descriptors and atomically register them into a pool in a way that allows for
|
2074
|
-
* (co)recursive type references.
|
2075
|
-
*/
|
2076
2088
|
VALUE Builder_alloc(VALUE klass) {
|
2077
2089
|
Builder* self = ALLOC(Builder);
|
2078
2090
|
VALUE ret = TypedData_Wrap_Struct(
|
2079
2091
|
klass, &_Builder_type, self);
|
2080
|
-
self->
|
2081
|
-
self->
|
2082
|
-
self->default_file_descriptor = Qnil;
|
2092
|
+
self->descriptor_pool = Qnil;
|
2093
|
+
self->default_file_builder = Qnil;
|
2083
2094
|
return ret;
|
2084
2095
|
}
|
2085
2096
|
|
2086
2097
|
void Builder_register(VALUE module) {
|
2087
2098
|
VALUE klass = rb_define_class_under(module, "Builder", rb_cObject);
|
2088
|
-
rb_define_alloc_func(klass, Builder_alloc);
|
2089
|
-
rb_define_method(klass, "initialize", Builder_initialize,
|
2099
|
+
rb_define_alloc_func(klass, Builder_alloc);
|
2100
|
+
rb_define_method(klass, "initialize", Builder_initialize, 1);
|
2090
2101
|
rb_define_method(klass, "add_file", Builder_add_file, -1);
|
2091
2102
|
rb_define_method(klass, "add_message", Builder_add_message, 1);
|
2092
2103
|
rb_define_method(klass, "add_enum", Builder_add_enum, 1);
|
2093
|
-
rb_define_method(klass, "finalize_to_pool", Builder_finalize_to_pool, 1);
|
2094
2104
|
rb_gc_register_address(&cBuilder);
|
2095
2105
|
cBuilder = klass;
|
2096
2106
|
}
|
2097
2107
|
|
2098
2108
|
/*
|
2099
2109
|
* call-seq:
|
2100
|
-
*
|
2110
|
+
* Builder.new(descriptor_pool) => builder
|
2101
2111
|
*
|
2102
|
-
*
|
2112
|
+
* Creates a new Builder. A Builder can accumulate a set of new message and enum
|
2113
|
+
* descriptors and atomically register them into a pool in a way that allows for
|
2114
|
+
* (co)recursive type references.
|
2103
2115
|
*/
|
2104
|
-
VALUE Builder_initialize(VALUE _self) {
|
2116
|
+
VALUE Builder_initialize(VALUE _self, VALUE pool) {
|
2105
2117
|
DEFINE_SELF(Builder, self, _self);
|
2106
|
-
self->
|
2107
|
-
|
2108
|
-
self->default_file_descriptor =
|
2109
|
-
rb_class_new_instance(1, &file_name, cFileDescriptor);
|
2118
|
+
self->descriptor_pool = pool;
|
2119
|
+
self->default_file_builder = Qnil; // Created lazily if needed.
|
2110
2120
|
return Qnil;
|
2111
2121
|
}
|
2112
2122
|
|
@@ -2123,17 +2133,38 @@ VALUE Builder_initialize(VALUE _self) {
|
|
2123
2133
|
*/
|
2124
2134
|
VALUE Builder_add_file(int argc, VALUE* argv, VALUE _self) {
|
2125
2135
|
DEFINE_SELF(Builder, self, _self);
|
2126
|
-
VALUE
|
2127
|
-
VALUE
|
2128
|
-
VALUE
|
2129
|
-
|
2136
|
+
VALUE name, options;
|
2137
|
+
VALUE ctx;
|
2138
|
+
VALUE block;
|
2139
|
+
|
2140
|
+
rb_scan_args(argc, argv, "11", &name, &options);
|
2141
|
+
|
2142
|
+
{
|
2143
|
+
VALUE args[3] = { self->descriptor_pool, name, options };
|
2144
|
+
ctx = rb_class_new_instance(3, args, cFileBuilderContext);
|
2145
|
+
}
|
2146
|
+
|
2147
|
+
block = rb_block_proc();
|
2130
2148
|
rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
|
2149
|
+
FileBuilderContext_build(ctx);
|
2131
2150
|
|
2132
|
-
rb_ary_concat(self->pending_list,
|
2133
|
-
FileBuilderContext_pending_descriptors(ctx));
|
2134
2151
|
return Qnil;
|
2135
2152
|
}
|
2136
2153
|
|
2154
|
+
static VALUE Builder_get_default_file(VALUE _self) {
|
2155
|
+
DEFINE_SELF(Builder, self, _self);
|
2156
|
+
|
2157
|
+
/* Lazily create only if legacy builder-level methods are called. */
|
2158
|
+
if (self->default_file_builder == Qnil) {
|
2159
|
+
VALUE name = rb_str_new2("ruby_default_file.proto");
|
2160
|
+
VALUE args [3] = { self->descriptor_pool, name, rb_hash_new() };
|
2161
|
+
self->default_file_builder =
|
2162
|
+
rb_class_new_instance(3, args, cFileBuilderContext);
|
2163
|
+
}
|
2164
|
+
|
2165
|
+
return self->default_file_builder;
|
2166
|
+
}
|
2167
|
+
|
2137
2168
|
/*
|
2138
2169
|
* call-seq:
|
2139
2170
|
* Builder.add_message(name, &block)
|
@@ -2146,15 +2177,9 @@ VALUE Builder_add_file(int argc, VALUE* argv, VALUE _self) {
|
|
2146
2177
|
* Descriptors created this way get assigned to a default empty FileDescriptor.
|
2147
2178
|
*/
|
2148
2179
|
VALUE Builder_add_message(VALUE _self, VALUE name) {
|
2149
|
-
|
2150
|
-
|
2151
|
-
|
2152
|
-
VALUE args[2] = { msgdef, _self };
|
2153
|
-
VALUE ctx = rb_class_new_instance(2, args, cMessageBuilderContext);
|
2154
|
-
VALUE block = rb_block_proc();
|
2155
|
-
rb_funcall(msgdef, rb_intern("name="), 1, name);
|
2156
|
-
rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
|
2157
|
-
rb_ary_push(self->pending_list, msgdef);
|
2180
|
+
VALUE file_builder = Builder_get_default_file(_self);
|
2181
|
+
rb_funcall_with_block(file_builder, rb_intern("add_message"), 1, &name,
|
2182
|
+
rb_block_proc());
|
2158
2183
|
return Qnil;
|
2159
2184
|
}
|
2160
2185
|
|
@@ -2171,87 +2196,83 @@ VALUE Builder_add_message(VALUE _self, VALUE name) {
|
|
2171
2196
|
* FileDescriptor.
|
2172
2197
|
*/
|
2173
2198
|
VALUE Builder_add_enum(VALUE _self, VALUE name) {
|
2174
|
-
|
2175
|
-
|
2176
|
-
|
2177
|
-
VALUE ctx = rb_class_new_instance(1, &enumdef, cEnumBuilderContext);
|
2178
|
-
VALUE block = rb_block_proc();
|
2179
|
-
rb_funcall(enumdef, rb_intern("name="), 1, name);
|
2180
|
-
rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
|
2181
|
-
rb_ary_push(self->pending_list, enumdef);
|
2199
|
+
VALUE file_builder = Builder_get_default_file(_self);
|
2200
|
+
rb_funcall_with_block(file_builder, rb_intern("add_enum"), 1, &name,
|
2201
|
+
rb_block_proc());
|
2182
2202
|
return Qnil;
|
2183
2203
|
}
|
2184
2204
|
|
2185
|
-
|
2186
|
-
|
2187
|
-
|
2188
|
-
|
2189
|
-
!upb_msg_field_done(&it);
|
2190
|
-
upb_msg_field_next(&it)) {
|
2191
|
-
const upb_fielddef* field = upb_msg_iter_field(&it);
|
2192
|
-
if (upb_fielddef_label(field) == UPB_LABEL_REQUIRED) {
|
2193
|
-
rb_raise(cTypeError, "Required fields are unsupported in proto3.");
|
2194
|
-
}
|
2195
|
-
}
|
2196
|
-
}
|
2205
|
+
/* This method is hidden from Ruby, and only called directly from
|
2206
|
+
* DescriptorPool_build(). */
|
2207
|
+
VALUE Builder_build(VALUE _self) {
|
2208
|
+
DEFINE_SELF(Builder, self, _self);
|
2197
2209
|
|
2198
|
-
|
2199
|
-
|
2200
|
-
|
2201
|
-
const char* lookup = upb_enumdef_iton(enumdef, 0);
|
2202
|
-
if (lookup == NULL) {
|
2203
|
-
rb_raise(cTypeError,
|
2204
|
-
"Enum definition does not contain a value for '0'.");
|
2210
|
+
if (self->default_file_builder != Qnil) {
|
2211
|
+
FileBuilderContext_build(self->default_file_builder);
|
2212
|
+
self->default_file_builder = Qnil;
|
2205
2213
|
}
|
2206
|
-
}
|
2207
|
-
|
2208
|
-
/*
|
2209
|
-
* call-seq:
|
2210
|
-
* Builder.finalize_to_pool(pool)
|
2211
|
-
*
|
2212
|
-
* Adds all accumulated message and enum descriptors created in this builder
|
2213
|
-
* context to the given pool. The operation occurs atomically, and all
|
2214
|
-
* descriptors can refer to each other (including in cycles). This is the only
|
2215
|
-
* way to build (co)recursive message definitions.
|
2216
|
-
*
|
2217
|
-
* This method is usually called automatically by DescriptorPool#build after it
|
2218
|
-
* invokes the given user block in the context of the builder. The user should
|
2219
|
-
* not normally need to call this manually because a Builder is not normally
|
2220
|
-
* created manually.
|
2221
|
-
*/
|
2222
|
-
VALUE Builder_finalize_to_pool(VALUE _self, VALUE pool_rb) {
|
2223
|
-
DEFINE_SELF(Builder, self, _self);
|
2224
2214
|
|
2225
|
-
|
2215
|
+
return Qnil;
|
2216
|
+
}
|
2226
2217
|
|
2227
|
-
|
2218
|
+
static VALUE get_def_obj(VALUE _descriptor_pool, const void* ptr, VALUE klass) {
|
2219
|
+
DEFINE_SELF(DescriptorPool, descriptor_pool, _descriptor_pool);
|
2220
|
+
VALUE key = ULL2NUM((intptr_t)ptr);
|
2221
|
+
VALUE def;
|
2228
2222
|
|
2229
|
-
|
2230
|
-
VALUE def_rb = rb_ary_entry(self->pending_list, i);
|
2231
|
-
if (CLASS_OF(def_rb) == cDescriptor) {
|
2232
|
-
self->defs[i] = (upb_def*)ruby_to_Descriptor(def_rb)->msgdef;
|
2223
|
+
def = rb_hash_aref(descriptor_pool->def_to_descriptor, key);
|
2233
2224
|
|
2234
|
-
|
2235
|
-
|
2236
|
-
|
2237
|
-
} else if (CLASS_OF(def_rb) == cEnumDescriptor) {
|
2238
|
-
self->defs[i] = (upb_def*)ruby_to_EnumDescriptor(def_rb)->enumdef;
|
2225
|
+
if (ptr == NULL) {
|
2226
|
+
return Qnil;
|
2227
|
+
}
|
2239
2228
|
|
2240
|
-
|
2241
|
-
|
2229
|
+
if (def == Qnil) {
|
2230
|
+
// Lazily create wrapper object.
|
2231
|
+
VALUE args[3] = { c_only_cookie, _descriptor_pool, key };
|
2232
|
+
def = rb_class_new_instance(3, args, klass);
|
2233
|
+
rb_hash_aset(descriptor_pool->def_to_descriptor, key, def);
|
2234
|
+
|
2235
|
+
// For message defs, we now eagerly get/create descriptors for all
|
2236
|
+
// submessages. We will need these anyway to parse or serialize this
|
2237
|
+
// message type. But more importantly, we must do this now so that
|
2238
|
+
// add_handlers_for_message() (which calls get_msgdef_obj()) does *not*
|
2239
|
+
// need to create a Ruby object or insert into a Ruby Hash. We need to
|
2240
|
+
// avoid triggering GC, which can switch Ruby threads and re-enter our
|
2241
|
+
// C extension from a different thread. This wreaks havoc on our state
|
2242
|
+
// if we were in the middle of building handlers.
|
2243
|
+
if (klass == cDescriptor) {
|
2244
|
+
const upb_msgdef *m = ptr;
|
2245
|
+
upb_msg_field_iter it;
|
2246
|
+
for (upb_msg_field_begin(&it, m);
|
2247
|
+
!upb_msg_field_done(&it);
|
2248
|
+
upb_msg_field_next(&it)) {
|
2249
|
+
const upb_fielddef* f = upb_msg_iter_field(&it);
|
2250
|
+
if (upb_fielddef_issubmsg(f)) {
|
2251
|
+
get_msgdef_obj(_descriptor_pool, upb_fielddef_msgsubdef(f));
|
2252
|
+
}
|
2242
2253
|
}
|
2243
2254
|
}
|
2244
2255
|
}
|
2245
2256
|
|
2246
|
-
|
2247
|
-
|
2248
|
-
"Unable to add defs to DescriptorPool");
|
2257
|
+
return def;
|
2258
|
+
}
|
2249
2259
|
|
2250
|
-
|
2251
|
-
|
2252
|
-
|
2253
|
-
}
|
2260
|
+
VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_msgdef* def) {
|
2261
|
+
return get_def_obj(descriptor_pool, def, cDescriptor);
|
2262
|
+
}
|
2254
2263
|
|
2255
|
-
|
2256
|
-
return
|
2264
|
+
VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_enumdef* def) {
|
2265
|
+
return get_def_obj(descriptor_pool, def, cEnumDescriptor);
|
2266
|
+
}
|
2267
|
+
|
2268
|
+
VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_fielddef* def) {
|
2269
|
+
return get_def_obj(descriptor_pool, def, cFieldDescriptor);
|
2270
|
+
}
|
2271
|
+
|
2272
|
+
VALUE get_filedef_obj(VALUE descriptor_pool, const upb_filedef* def) {
|
2273
|
+
return get_def_obj(descriptor_pool, def, cFileDescriptor);
|
2274
|
+
}
|
2275
|
+
|
2276
|
+
VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_oneofdef* def) {
|
2277
|
+
return get_def_obj(descriptor_pool, def, cOneofDescriptor);
|
2257
2278
|
}
|