google-protobuf 3.17.3-x86-linux → 3.18.0.rc.1-x86-linux
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of google-protobuf might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/ext/google/protobuf_c/convert.c +4 -5
- data/ext/google/protobuf_c/defs.c +26 -1326
- data/ext/google/protobuf_c/extconf.rb +0 -1
- data/ext/google/protobuf_c/message.c +1 -2
- data/ext/google/protobuf_c/repeated_field.c +0 -1
- data/ext/google/protobuf_c/ruby-upb.c +603 -290
- data/ext/google/protobuf_c/ruby-upb.h +420 -127
- 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/2.7/protobuf_c.so +0 -0
- data/lib/google/3.0/protobuf_c.so +0 -0
- data/lib/google/protobuf.rb +1 -69
- data/lib/google/protobuf/api_pb.rb +2 -2
- data/lib/google/protobuf/descriptor_dsl.rb +458 -0
- data/lib/google/protobuf/descriptor_pb.rb +266 -0
- data/lib/google/protobuf/type_pb.rb +2 -2
- metadata +7 -6
- data/ext/google/protobuf_c/third_party/wyhash/wyhash.h +0 -145
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5fa9928445d29031ea4ad6d79c83e4cad35ef0cf8a4aeaf8d5818202bf3edcd9
|
4
|
+
data.tar.gz: c53bf8399f4d75b44b8986a8b7ec62065e230056cb2781d1445c969d71660152
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 97414d4f2b42466a41ce779645a56849d142aa33a98c0f5a3787512313375f3393f4c8b6105cd826367173436d4357a3339f2a5071a45b214ba42650193fd4c5
|
7
|
+
data.tar.gz: b0d7a9ebf79e4f0a3ffda830a66a2f911ff91f7ef10dd8e3040198c7889a548436c1bdc0feeed5f04678d43a9f80c08e449a03a02a59c64619b9136a652517e3
|
@@ -41,7 +41,6 @@
|
|
41
41
|
|
42
42
|
#include "message.h"
|
43
43
|
#include "protobuf.h"
|
44
|
-
#include "third_party/wyhash/wyhash.h"
|
45
44
|
|
46
45
|
static upb_strview Convert_StringData(VALUE str, upb_arena *arena) {
|
47
46
|
upb_strview ret;
|
@@ -328,19 +327,19 @@ bool Msgval_IsEqual(upb_msgval val1, upb_msgval val2, TypeInfo type_info) {
|
|
328
327
|
uint64_t Msgval_GetHash(upb_msgval val, TypeInfo type_info, uint64_t seed) {
|
329
328
|
switch (type_info.type) {
|
330
329
|
case UPB_TYPE_BOOL:
|
331
|
-
return
|
330
|
+
return Wyhash(&val, 1, seed, kWyhashSalt);
|
332
331
|
case UPB_TYPE_FLOAT:
|
333
332
|
case UPB_TYPE_INT32:
|
334
333
|
case UPB_TYPE_UINT32:
|
335
334
|
case UPB_TYPE_ENUM:
|
336
|
-
return
|
335
|
+
return Wyhash(&val, 4, seed, kWyhashSalt);
|
337
336
|
case UPB_TYPE_DOUBLE:
|
338
337
|
case UPB_TYPE_INT64:
|
339
338
|
case UPB_TYPE_UINT64:
|
340
|
-
return
|
339
|
+
return Wyhash(&val, 8, seed, kWyhashSalt);
|
341
340
|
case UPB_TYPE_STRING:
|
342
341
|
case UPB_TYPE_BYTES:
|
343
|
-
return
|
342
|
+
return Wyhash(val.str_val.data, val.str_val.size, seed, kWyhashSalt);
|
344
343
|
case UPB_TYPE_MESSAGE:
|
345
344
|
return Message_Hash(val.msg_val, type_info.def.msgdef, seed);
|
346
345
|
default:
|
@@ -36,13 +36,6 @@
|
|
36
36
|
#include "message.h"
|
37
37
|
#include "protobuf.h"
|
38
38
|
|
39
|
-
static VALUE Builder_build(VALUE _self);
|
40
|
-
|
41
|
-
static VALUE cMessageBuilderContext;
|
42
|
-
static VALUE cOneofBuilderContext;
|
43
|
-
static VALUE cEnumBuilderContext;
|
44
|
-
static VALUE cBuilder;
|
45
|
-
|
46
39
|
// -----------------------------------------------------------------------------
|
47
40
|
// Global map from upb {msg,enum}defs to wrapper Descriptor/EnumDescriptor
|
48
41
|
// instances.
|
@@ -75,167 +68,6 @@ static VALUE rb_str_maybe_null(const char* s) {
|
|
75
68
|
return rb_str_new2(s);
|
76
69
|
}
|
77
70
|
|
78
|
-
// -----------------------------------------------------------------------------
|
79
|
-
// Backward compatibility code.
|
80
|
-
// -----------------------------------------------------------------------------
|
81
|
-
|
82
|
-
static void rewrite_enum_default(const upb_symtab* symtab,
|
83
|
-
google_protobuf_FileDescriptorProto* file,
|
84
|
-
google_protobuf_FieldDescriptorProto* field) {
|
85
|
-
upb_strview defaultval;
|
86
|
-
const char *type_name_str;
|
87
|
-
char *end;
|
88
|
-
long val;
|
89
|
-
const upb_enumdef *e;
|
90
|
-
upb_strview type_name;
|
91
|
-
|
92
|
-
/* Look for TYPE_ENUM fields that have a default. */
|
93
|
-
if (google_protobuf_FieldDescriptorProto_type(field) !=
|
94
|
-
google_protobuf_FieldDescriptorProto_TYPE_ENUM ||
|
95
|
-
!google_protobuf_FieldDescriptorProto_has_default_value(field) ||
|
96
|
-
!google_protobuf_FieldDescriptorProto_has_type_name(field)) {
|
97
|
-
return;
|
98
|
-
}
|
99
|
-
|
100
|
-
defaultval = google_protobuf_FieldDescriptorProto_default_value(field);
|
101
|
-
type_name = google_protobuf_FieldDescriptorProto_type_name(field);
|
102
|
-
|
103
|
-
if (defaultval.size == 0 || !isdigit(defaultval.data[0])) {
|
104
|
-
return;
|
105
|
-
}
|
106
|
-
|
107
|
-
if (type_name.size == 0 || type_name.data[0] != '.') {
|
108
|
-
return;
|
109
|
-
}
|
110
|
-
|
111
|
-
type_name_str = type_name.data + 1;
|
112
|
-
|
113
|
-
errno = 0;
|
114
|
-
val = strtol(defaultval.data, &end, 10);
|
115
|
-
|
116
|
-
if (errno != 0 || *end != 0 || val < INT32_MIN || val > INT32_MAX) {
|
117
|
-
return;
|
118
|
-
}
|
119
|
-
|
120
|
-
/* Now find the corresponding enum definition. */
|
121
|
-
e = upb_symtab_lookupenum(symtab, type_name_str);
|
122
|
-
if (e) {
|
123
|
-
/* Look in previously loaded files. */
|
124
|
-
const char *label = upb_enumdef_iton(e, val);
|
125
|
-
if (!label) {
|
126
|
-
return;
|
127
|
-
}
|
128
|
-
google_protobuf_FieldDescriptorProto_set_default_value(
|
129
|
-
field, upb_strview_makez(label));
|
130
|
-
} else {
|
131
|
-
/* Look in enums defined in this file. */
|
132
|
-
const google_protobuf_EnumDescriptorProto* matching_enum = NULL;
|
133
|
-
size_t i, n;
|
134
|
-
const google_protobuf_EnumDescriptorProto* const* enums =
|
135
|
-
google_protobuf_FileDescriptorProto_enum_type(file, &n);
|
136
|
-
const google_protobuf_EnumValueDescriptorProto* const* values;
|
137
|
-
|
138
|
-
for (i = 0; i < n; i++) {
|
139
|
-
if (upb_strview_eql(google_protobuf_EnumDescriptorProto_name(enums[i]),
|
140
|
-
upb_strview_makez(type_name_str))) {
|
141
|
-
matching_enum = enums[i];
|
142
|
-
break;
|
143
|
-
}
|
144
|
-
}
|
145
|
-
|
146
|
-
if (!matching_enum) {
|
147
|
-
return;
|
148
|
-
}
|
149
|
-
|
150
|
-
values = google_protobuf_EnumDescriptorProto_value(matching_enum, &n);
|
151
|
-
for (i = 0; i < n; i++) {
|
152
|
-
if (google_protobuf_EnumValueDescriptorProto_number(values[i]) == val) {
|
153
|
-
google_protobuf_FieldDescriptorProto_set_default_value(
|
154
|
-
field, google_protobuf_EnumValueDescriptorProto_name(values[i]));
|
155
|
-
return;
|
156
|
-
}
|
157
|
-
}
|
158
|
-
|
159
|
-
/* We failed to find an enum default. But we'll just leave the enum
|
160
|
-
* untouched and let the normal def-building code catch it. */
|
161
|
-
}
|
162
|
-
}
|
163
|
-
|
164
|
-
/* Historically we allowed enum defaults to be specified as a number. In
|
165
|
-
* retrospect this was a mistake as descriptors require defaults to be
|
166
|
-
* specified as a label. This can make a difference if multiple labels have the
|
167
|
-
* same number.
|
168
|
-
*
|
169
|
-
* Here we do a pass over all enum defaults and rewrite numeric defaults by
|
170
|
-
* looking up their labels. This is complicated by the fact that the enum
|
171
|
-
* definition can live in either the symtab or the file_proto.
|
172
|
-
* */
|
173
|
-
static void rewrite_enum_defaults(
|
174
|
-
const upb_symtab* symtab, google_protobuf_FileDescriptorProto* file_proto) {
|
175
|
-
size_t i, n;
|
176
|
-
google_protobuf_DescriptorProto** msgs =
|
177
|
-
google_protobuf_FileDescriptorProto_mutable_message_type(file_proto, &n);
|
178
|
-
|
179
|
-
for (i = 0; i < n; i++) {
|
180
|
-
size_t j, m;
|
181
|
-
google_protobuf_FieldDescriptorProto** fields =
|
182
|
-
google_protobuf_DescriptorProto_mutable_field(msgs[i], &m);
|
183
|
-
for (j = 0; j < m; j++) {
|
184
|
-
rewrite_enum_default(symtab, file_proto, fields[j]);
|
185
|
-
}
|
186
|
-
}
|
187
|
-
}
|
188
|
-
|
189
|
-
static void remove_path(upb_strview *name) {
|
190
|
-
const char* last = strrchr(name->data, '.');
|
191
|
-
if (last) {
|
192
|
-
size_t remove = last - name->data + 1;
|
193
|
-
name->data += remove;
|
194
|
-
name->size -= remove;
|
195
|
-
}
|
196
|
-
}
|
197
|
-
|
198
|
-
static void rewrite_nesting(VALUE msg_ent, google_protobuf_DescriptorProto* msg,
|
199
|
-
google_protobuf_DescriptorProto* const* msgs,
|
200
|
-
google_protobuf_EnumDescriptorProto* const* enums,
|
201
|
-
upb_arena *arena) {
|
202
|
-
VALUE submsgs = rb_hash_aref(msg_ent, ID2SYM(rb_intern("msgs")));
|
203
|
-
VALUE enum_pos = rb_hash_aref(msg_ent, ID2SYM(rb_intern("enums")));
|
204
|
-
int submsg_count;
|
205
|
-
int enum_count;
|
206
|
-
int i;
|
207
|
-
google_protobuf_DescriptorProto** msg_msgs;
|
208
|
-
google_protobuf_EnumDescriptorProto** msg_enums;
|
209
|
-
|
210
|
-
Check_Type(submsgs, T_ARRAY);
|
211
|
-
Check_Type(enum_pos, T_ARRAY);
|
212
|
-
|
213
|
-
submsg_count = RARRAY_LEN(submsgs);
|
214
|
-
enum_count = RARRAY_LEN(enum_pos);
|
215
|
-
|
216
|
-
msg_msgs = google_protobuf_DescriptorProto_resize_nested_type(
|
217
|
-
msg, submsg_count, arena);
|
218
|
-
msg_enums =
|
219
|
-
google_protobuf_DescriptorProto_resize_enum_type(msg, enum_count, arena);
|
220
|
-
|
221
|
-
for (i = 0; i < submsg_count; i++) {
|
222
|
-
VALUE submsg_ent = RARRAY_PTR(submsgs)[i];
|
223
|
-
VALUE pos = rb_hash_aref(submsg_ent, ID2SYM(rb_intern("pos")));
|
224
|
-
upb_strview name;
|
225
|
-
|
226
|
-
msg_msgs[i] = msgs[NUM2INT(pos)];
|
227
|
-
name = google_protobuf_DescriptorProto_name(msg_msgs[i]);
|
228
|
-
remove_path(&name);
|
229
|
-
google_protobuf_DescriptorProto_set_name(msg_msgs[i], name);
|
230
|
-
rewrite_nesting(submsg_ent, msg_msgs[i], msgs, enums, arena);
|
231
|
-
}
|
232
|
-
|
233
|
-
for (i = 0; i < enum_count; i++) {
|
234
|
-
VALUE pos = RARRAY_PTR(enum_pos)[i];
|
235
|
-
msg_enums[i] = enums[NUM2INT(pos)];
|
236
|
-
}
|
237
|
-
}
|
238
|
-
|
239
71
|
// -----------------------------------------------------------------------------
|
240
72
|
// DescriptorPool.
|
241
73
|
// -----------------------------------------------------------------------------
|
@@ -302,20 +134,32 @@ static VALUE DescriptorPool_alloc(VALUE klass) {
|
|
302
134
|
|
303
135
|
/*
|
304
136
|
* call-seq:
|
305
|
-
* DescriptorPool.
|
137
|
+
* DescriptorPool.add_serialized_file(serialized_file_proto)
|
306
138
|
*
|
307
|
-
*
|
308
|
-
* added within the block are committed to the pool atomically, and may refer
|
309
|
-
* (co)recursively to each other. The user should call Builder#add_message and
|
310
|
-
* Builder#add_enum within the block as appropriate. This is the recommended,
|
311
|
-
* idiomatic way to define new message and enum types.
|
139
|
+
* Adds the given serialized FileDescriptorProto to the pool.
|
312
140
|
*/
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
141
|
+
VALUE DescriptorPool_add_serialized_file(VALUE _self,
|
142
|
+
VALUE serialized_file_proto) {
|
143
|
+
DescriptorPool* self = ruby_to_DescriptorPool(_self);
|
144
|
+
Check_Type(serialized_file_proto, T_STRING);
|
145
|
+
VALUE arena_rb = Arena_new();
|
146
|
+
upb_arena *arena = Arena_get(arena_rb);
|
147
|
+
google_protobuf_FileDescriptorProto* file_proto =
|
148
|
+
google_protobuf_FileDescriptorProto_parse(
|
149
|
+
RSTRING_PTR(serialized_file_proto),
|
150
|
+
RSTRING_LEN(serialized_file_proto), arena);
|
151
|
+
if (!file_proto) {
|
152
|
+
rb_raise(rb_eArgError, "Unable to parse FileDescriptorProto");
|
153
|
+
}
|
154
|
+
upb_status status;
|
155
|
+
upb_status_clear(&status);
|
156
|
+
const upb_filedef* filedef =
|
157
|
+
upb_symtab_addfile(self->symtab, file_proto, &status);
|
158
|
+
if (!filedef) {
|
159
|
+
rb_raise(cTypeError, "Unable to build file to DescriptorPool: %s",
|
160
|
+
upb_status_errmsg(&status));
|
161
|
+
}
|
162
|
+
return get_filedef_obj(_self, filedef);
|
319
163
|
}
|
320
164
|
|
321
165
|
/*
|
@@ -361,7 +205,8 @@ static void DescriptorPool_register(VALUE module) {
|
|
361
205
|
VALUE klass = rb_define_class_under(
|
362
206
|
module, "DescriptorPool", rb_cObject);
|
363
207
|
rb_define_alloc_func(klass, DescriptorPool_alloc);
|
364
|
-
rb_define_method(klass, "
|
208
|
+
rb_define_method(klass, "add_serialized_file",
|
209
|
+
DescriptorPool_add_serialized_file, 1);
|
365
210
|
rb_define_method(klass, "lookup", DescriptorPool_lookup, 1);
|
366
211
|
rb_define_singleton_method(klass, "generated_pool",
|
367
212
|
DescriptorPool_generated_pool, 0);
|
@@ -773,41 +618,6 @@ upb_fieldtype_t ruby_to_fieldtype(VALUE type) {
|
|
773
618
|
return 0;
|
774
619
|
}
|
775
620
|
|
776
|
-
static upb_descriptortype_t ruby_to_descriptortype(VALUE type) {
|
777
|
-
if (TYPE(type) != T_SYMBOL) {
|
778
|
-
rb_raise(rb_eArgError, "Expected symbol for field type.");
|
779
|
-
}
|
780
|
-
|
781
|
-
#define CONVERT(upb, ruby) \
|
782
|
-
if (SYM2ID(type) == rb_intern( # ruby )) { \
|
783
|
-
return UPB_DESCRIPTOR_TYPE_ ## upb; \
|
784
|
-
}
|
785
|
-
|
786
|
-
CONVERT(FLOAT, float);
|
787
|
-
CONVERT(DOUBLE, double);
|
788
|
-
CONVERT(BOOL, bool);
|
789
|
-
CONVERT(STRING, string);
|
790
|
-
CONVERT(BYTES, bytes);
|
791
|
-
CONVERT(MESSAGE, message);
|
792
|
-
CONVERT(GROUP, group);
|
793
|
-
CONVERT(ENUM, enum);
|
794
|
-
CONVERT(INT32, int32);
|
795
|
-
CONVERT(INT64, int64);
|
796
|
-
CONVERT(UINT32, uint32);
|
797
|
-
CONVERT(UINT64, uint64);
|
798
|
-
CONVERT(SINT32, sint32);
|
799
|
-
CONVERT(SINT64, sint64);
|
800
|
-
CONVERT(FIXED32, fixed32);
|
801
|
-
CONVERT(FIXED64, fixed64);
|
802
|
-
CONVERT(SFIXED32, sfixed32);
|
803
|
-
CONVERT(SFIXED64, sfixed64);
|
804
|
-
|
805
|
-
#undef CONVERT
|
806
|
-
|
807
|
-
rb_raise(rb_eArgError, "Unknown field type.");
|
808
|
-
return 0;
|
809
|
-
}
|
810
|
-
|
811
621
|
static VALUE descriptortype_to_ruby(upb_descriptortype_t type) {
|
812
622
|
switch (type) {
|
813
623
|
#define CONVERT(upb, ruby) \
|
@@ -1353,1111 +1163,6 @@ static void EnumDescriptor_register(VALUE module) {
|
|
1353
1163
|
cEnumDescriptor = klass;
|
1354
1164
|
}
|
1355
1165
|
|
1356
|
-
// -----------------------------------------------------------------------------
|
1357
|
-
// FileBuilderContext.
|
1358
|
-
// -----------------------------------------------------------------------------
|
1359
|
-
|
1360
|
-
typedef struct {
|
1361
|
-
upb_arena *arena;
|
1362
|
-
google_protobuf_FileDescriptorProto* file_proto;
|
1363
|
-
VALUE descriptor_pool;
|
1364
|
-
} FileBuilderContext;
|
1365
|
-
|
1366
|
-
static VALUE cFileBuilderContext = Qnil;
|
1367
|
-
|
1368
|
-
static void FileBuilderContext_mark(void* _self) {
|
1369
|
-
FileBuilderContext* self = _self;
|
1370
|
-
rb_gc_mark(self->descriptor_pool);
|
1371
|
-
}
|
1372
|
-
|
1373
|
-
static void FileBuilderContext_free(void* _self) {
|
1374
|
-
FileBuilderContext* self = _self;
|
1375
|
-
upb_arena_free(self->arena);
|
1376
|
-
xfree(self);
|
1377
|
-
}
|
1378
|
-
|
1379
|
-
static const rb_data_type_t FileBuilderContext_type = {
|
1380
|
-
"Google::Protobuf::Internal::FileBuilderContext",
|
1381
|
-
{FileBuilderContext_mark, FileBuilderContext_free, NULL},
|
1382
|
-
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
1383
|
-
};
|
1384
|
-
|
1385
|
-
static FileBuilderContext* ruby_to_FileBuilderContext(VALUE val) {
|
1386
|
-
FileBuilderContext* ret;
|
1387
|
-
TypedData_Get_Struct(val, FileBuilderContext, &FileBuilderContext_type, ret);
|
1388
|
-
return ret;
|
1389
|
-
}
|
1390
|
-
|
1391
|
-
static upb_strview FileBuilderContext_strdup2(VALUE _self, const char *str) {
|
1392
|
-
FileBuilderContext* self = ruby_to_FileBuilderContext(_self);
|
1393
|
-
upb_strview ret;
|
1394
|
-
char *data;
|
1395
|
-
|
1396
|
-
ret.size = strlen(str);
|
1397
|
-
data = upb_malloc(upb_arena_alloc(self->arena), ret.size + 1);
|
1398
|
-
ret.data = data;
|
1399
|
-
memcpy(data, str, ret.size);
|
1400
|
-
/* Null-terminate required by rewrite_enum_defaults() above. */
|
1401
|
-
data[ret.size] = '\0';
|
1402
|
-
return ret;
|
1403
|
-
}
|
1404
|
-
|
1405
|
-
static upb_strview FileBuilderContext_strdup(VALUE _self, VALUE rb_str) {
|
1406
|
-
return FileBuilderContext_strdup2(_self, get_str(rb_str));
|
1407
|
-
}
|
1408
|
-
|
1409
|
-
static upb_strview FileBuilderContext_strdup_sym(VALUE _self, VALUE rb_sym) {
|
1410
|
-
Check_Type(rb_sym, T_SYMBOL);
|
1411
|
-
return FileBuilderContext_strdup(_self, rb_id2str(SYM2ID(rb_sym)));
|
1412
|
-
}
|
1413
|
-
|
1414
|
-
static VALUE FileBuilderContext_alloc(VALUE klass) {
|
1415
|
-
FileBuilderContext* self = ALLOC(FileBuilderContext);
|
1416
|
-
VALUE ret = TypedData_Wrap_Struct(klass, &FileBuilderContext_type, self);
|
1417
|
-
self->arena = upb_arena_new();
|
1418
|
-
self->file_proto = google_protobuf_FileDescriptorProto_new(self->arena);
|
1419
|
-
self->descriptor_pool = Qnil;
|
1420
|
-
return ret;
|
1421
|
-
}
|
1422
|
-
|
1423
|
-
/*
|
1424
|
-
* call-seq:
|
1425
|
-
* FileBuilderContext.new(descriptor_pool) => context
|
1426
|
-
*
|
1427
|
-
* Create a new file builder context for the given file descriptor and
|
1428
|
-
* builder context. This class is intended to serve as a DSL context to be used
|
1429
|
-
* with #instance_eval.
|
1430
|
-
*/
|
1431
|
-
static VALUE FileBuilderContext_initialize(VALUE _self, VALUE descriptor_pool,
|
1432
|
-
VALUE name, VALUE options) {
|
1433
|
-
FileBuilderContext* self = ruby_to_FileBuilderContext(_self);
|
1434
|
-
self->descriptor_pool = descriptor_pool;
|
1435
|
-
|
1436
|
-
google_protobuf_FileDescriptorProto_set_name(
|
1437
|
-
self->file_proto, FileBuilderContext_strdup(_self, name));
|
1438
|
-
|
1439
|
-
// Default syntax for Ruby is proto3.
|
1440
|
-
google_protobuf_FileDescriptorProto_set_syntax(
|
1441
|
-
self->file_proto,
|
1442
|
-
FileBuilderContext_strdup(_self, rb_str_new2("proto3")));
|
1443
|
-
|
1444
|
-
if (options != Qnil) {
|
1445
|
-
VALUE syntax;
|
1446
|
-
|
1447
|
-
Check_Type(options, T_HASH);
|
1448
|
-
syntax = rb_hash_lookup2(options, ID2SYM(rb_intern("syntax")), Qnil);
|
1449
|
-
|
1450
|
-
if (syntax != Qnil) {
|
1451
|
-
VALUE syntax_str;
|
1452
|
-
|
1453
|
-
Check_Type(syntax, T_SYMBOL);
|
1454
|
-
syntax_str = rb_id2str(SYM2ID(syntax));
|
1455
|
-
google_protobuf_FileDescriptorProto_set_syntax(
|
1456
|
-
self->file_proto, FileBuilderContext_strdup(_self, syntax_str));
|
1457
|
-
}
|
1458
|
-
}
|
1459
|
-
|
1460
|
-
return Qnil;
|
1461
|
-
}
|
1462
|
-
|
1463
|
-
static void MessageBuilderContext_add_synthetic_oneofs(VALUE _self);
|
1464
|
-
|
1465
|
-
/*
|
1466
|
-
* call-seq:
|
1467
|
-
* FileBuilderContext.add_message(name, &block)
|
1468
|
-
*
|
1469
|
-
* Creates a new, empty descriptor with the given name, and invokes the block in
|
1470
|
-
* the context of a MessageBuilderContext on that descriptor. The block can then
|
1471
|
-
* call, e.g., MessageBuilderContext#optional and MessageBuilderContext#repeated
|
1472
|
-
* methods to define the message fields.
|
1473
|
-
*
|
1474
|
-
* This is the recommended, idiomatic way to build message definitions.
|
1475
|
-
*/
|
1476
|
-
static VALUE FileBuilderContext_add_message(VALUE _self, VALUE name) {
|
1477
|
-
VALUE args[2] = { _self, name };
|
1478
|
-
VALUE ctx = rb_class_new_instance(2, args, cMessageBuilderContext);
|
1479
|
-
VALUE block = rb_block_proc();
|
1480
|
-
rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
|
1481
|
-
MessageBuilderContext_add_synthetic_oneofs(ctx);
|
1482
|
-
return Qnil;
|
1483
|
-
}
|
1484
|
-
|
1485
|
-
/* We have to do some relatively complicated logic here for backward
|
1486
|
-
* compatibility.
|
1487
|
-
*
|
1488
|
-
* In descriptor.proto, messages are nested inside other messages if that is
|
1489
|
-
* what the original .proto file looks like. For example, suppose we have this
|
1490
|
-
* foo.proto:
|
1491
|
-
*
|
1492
|
-
* package foo;
|
1493
|
-
* message Bar {
|
1494
|
-
* message Baz {}
|
1495
|
-
* }
|
1496
|
-
*
|
1497
|
-
* The descriptor for this must look like this:
|
1498
|
-
*
|
1499
|
-
* file {
|
1500
|
-
* name: "test.proto"
|
1501
|
-
* package: "foo"
|
1502
|
-
* message_type {
|
1503
|
-
* name: "Bar"
|
1504
|
-
* nested_type {
|
1505
|
-
* name: "Baz"
|
1506
|
-
* }
|
1507
|
-
* }
|
1508
|
-
* }
|
1509
|
-
*
|
1510
|
-
* However, the Ruby generated code has always generated messages in a flat,
|
1511
|
-
* non-nested way:
|
1512
|
-
*
|
1513
|
-
* Google::Protobuf::DescriptorPool.generated_pool.build do
|
1514
|
-
* add_message "foo.Bar" do
|
1515
|
-
* end
|
1516
|
-
* add_message "foo.Bar.Baz" do
|
1517
|
-
* end
|
1518
|
-
* end
|
1519
|
-
*
|
1520
|
-
* Here we need to do a translation where we turn this generated code into the
|
1521
|
-
* above descriptor. We need to infer that "foo" is the package name, and not
|
1522
|
-
* a message itself.
|
1523
|
-
*
|
1524
|
-
* We delegate to Ruby to compute the transformation, for more concice and
|
1525
|
-
* readable code than we can do in C */
|
1526
|
-
static void rewrite_names(VALUE _file_builder,
|
1527
|
-
google_protobuf_FileDescriptorProto* file_proto) {
|
1528
|
-
FileBuilderContext* file_builder = ruby_to_FileBuilderContext(_file_builder);
|
1529
|
-
upb_arena *arena = file_builder->arena;
|
1530
|
-
// Build params (package, msg_names, enum_names).
|
1531
|
-
VALUE package = Qnil;
|
1532
|
-
VALUE msg_names = rb_ary_new();
|
1533
|
-
VALUE enum_names = rb_ary_new();
|
1534
|
-
size_t msg_count, enum_count, i;
|
1535
|
-
VALUE new_package, nesting, msg_ents, enum_ents;
|
1536
|
-
google_protobuf_DescriptorProto** msgs;
|
1537
|
-
google_protobuf_EnumDescriptorProto** enums;
|
1538
|
-
|
1539
|
-
if (google_protobuf_FileDescriptorProto_has_package(file_proto)) {
|
1540
|
-
upb_strview package_str =
|
1541
|
-
google_protobuf_FileDescriptorProto_package(file_proto);
|
1542
|
-
package = rb_str_new(package_str.data, package_str.size);
|
1543
|
-
}
|
1544
|
-
|
1545
|
-
msgs = google_protobuf_FileDescriptorProto_mutable_message_type(file_proto,
|
1546
|
-
&msg_count);
|
1547
|
-
for (i = 0; i < msg_count; i++) {
|
1548
|
-
upb_strview name = google_protobuf_DescriptorProto_name(msgs[i]);
|
1549
|
-
rb_ary_push(msg_names, rb_str_new(name.data, name.size));
|
1550
|
-
}
|
1551
|
-
|
1552
|
-
enums = google_protobuf_FileDescriptorProto_mutable_enum_type(file_proto,
|
1553
|
-
&enum_count);
|
1554
|
-
for (i = 0; i < enum_count; i++) {
|
1555
|
-
upb_strview name = google_protobuf_EnumDescriptorProto_name(enums[i]);
|
1556
|
-
rb_ary_push(enum_names, rb_str_new(name.data, name.size));
|
1557
|
-
}
|
1558
|
-
|
1559
|
-
{
|
1560
|
-
// Call Ruby code to calculate package name and nesting.
|
1561
|
-
VALUE args[3] = { package, msg_names, enum_names };
|
1562
|
-
VALUE internal = rb_eval_string("Google::Protobuf::Internal");
|
1563
|
-
VALUE ret = rb_funcallv(internal, rb_intern("fixup_descriptor"), 3, args);
|
1564
|
-
|
1565
|
-
new_package = rb_ary_entry(ret, 0);
|
1566
|
-
nesting = rb_ary_entry(ret, 1);
|
1567
|
-
}
|
1568
|
-
|
1569
|
-
// Rewrite package and names.
|
1570
|
-
if (new_package != Qnil) {
|
1571
|
-
upb_strview new_package_str =
|
1572
|
-
FileBuilderContext_strdup(_file_builder, new_package);
|
1573
|
-
google_protobuf_FileDescriptorProto_set_package(file_proto,
|
1574
|
-
new_package_str);
|
1575
|
-
}
|
1576
|
-
|
1577
|
-
for (i = 0; i < msg_count; i++) {
|
1578
|
-
upb_strview name = google_protobuf_DescriptorProto_name(msgs[i]);
|
1579
|
-
remove_path(&name);
|
1580
|
-
google_protobuf_DescriptorProto_set_name(msgs[i], name);
|
1581
|
-
}
|
1582
|
-
|
1583
|
-
for (i = 0; i < enum_count; i++) {
|
1584
|
-
upb_strview name = google_protobuf_EnumDescriptorProto_name(enums[i]);
|
1585
|
-
remove_path(&name);
|
1586
|
-
google_protobuf_EnumDescriptorProto_set_name(enums[i], name);
|
1587
|
-
}
|
1588
|
-
|
1589
|
-
// Rewrite nesting.
|
1590
|
-
msg_ents = rb_hash_aref(nesting, ID2SYM(rb_intern("msgs")));
|
1591
|
-
enum_ents = rb_hash_aref(nesting, ID2SYM(rb_intern("enums")));
|
1592
|
-
|
1593
|
-
Check_Type(msg_ents, T_ARRAY);
|
1594
|
-
Check_Type(enum_ents, T_ARRAY);
|
1595
|
-
|
1596
|
-
for (i = 0; i < (size_t)RARRAY_LEN(msg_ents); i++) {
|
1597
|
-
VALUE msg_ent = rb_ary_entry(msg_ents, i);
|
1598
|
-
VALUE pos = rb_hash_aref(msg_ent, ID2SYM(rb_intern("pos")));
|
1599
|
-
msgs[i] = msgs[NUM2INT(pos)];
|
1600
|
-
rewrite_nesting(msg_ent, msgs[i], msgs, enums, arena);
|
1601
|
-
}
|
1602
|
-
|
1603
|
-
for (i = 0; i < (size_t)RARRAY_LEN(enum_ents); i++) {
|
1604
|
-
VALUE enum_pos = rb_ary_entry(enum_ents, i);
|
1605
|
-
enums[i] = enums[NUM2INT(enum_pos)];
|
1606
|
-
}
|
1607
|
-
|
1608
|
-
google_protobuf_FileDescriptorProto_resize_message_type(
|
1609
|
-
file_proto, RARRAY_LEN(msg_ents), arena);
|
1610
|
-
google_protobuf_FileDescriptorProto_resize_enum_type(
|
1611
|
-
file_proto, RARRAY_LEN(enum_ents), arena);
|
1612
|
-
}
|
1613
|
-
|
1614
|
-
/*
|
1615
|
-
* call-seq:
|
1616
|
-
* FileBuilderContext.add_enum(name, &block)
|
1617
|
-
*
|
1618
|
-
* Creates a new, empty enum descriptor with the given name, and invokes the
|
1619
|
-
* block in the context of an EnumBuilderContext on that descriptor. The block
|
1620
|
-
* can then call EnumBuilderContext#add_value to define the enum values.
|
1621
|
-
*
|
1622
|
-
* This is the recommended, idiomatic way to build enum definitions.
|
1623
|
-
*/
|
1624
|
-
static VALUE FileBuilderContext_add_enum(VALUE _self, VALUE name) {
|
1625
|
-
VALUE args[2] = { _self, name };
|
1626
|
-
VALUE ctx = rb_class_new_instance(2, args, cEnumBuilderContext);
|
1627
|
-
VALUE block = rb_block_proc();
|
1628
|
-
rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
|
1629
|
-
return Qnil;
|
1630
|
-
}
|
1631
|
-
|
1632
|
-
static void FileBuilderContext_build(VALUE _self) {
|
1633
|
-
FileBuilderContext* self = ruby_to_FileBuilderContext(_self);
|
1634
|
-
DescriptorPool* pool = ruby_to_DescriptorPool(self->descriptor_pool);
|
1635
|
-
upb_status status;
|
1636
|
-
|
1637
|
-
rewrite_enum_defaults(pool->symtab, self->file_proto);
|
1638
|
-
rewrite_names(_self, self->file_proto);
|
1639
|
-
|
1640
|
-
upb_status_clear(&status);
|
1641
|
-
if (!upb_symtab_addfile(pool->symtab, self->file_proto, &status)) {
|
1642
|
-
rb_raise(cTypeError, "Unable to add defs to DescriptorPool: %s",
|
1643
|
-
upb_status_errmsg(&status));
|
1644
|
-
}
|
1645
|
-
}
|
1646
|
-
|
1647
|
-
static void FileBuilderContext_register(VALUE module) {
|
1648
|
-
VALUE klass = rb_define_class_under(module, "FileBuilderContext", rb_cObject);
|
1649
|
-
rb_define_alloc_func(klass, FileBuilderContext_alloc);
|
1650
|
-
rb_define_method(klass, "initialize", FileBuilderContext_initialize, 3);
|
1651
|
-
rb_define_method(klass, "add_message", FileBuilderContext_add_message, 1);
|
1652
|
-
rb_define_method(klass, "add_enum", FileBuilderContext_add_enum, 1);
|
1653
|
-
rb_gc_register_address(&cFileBuilderContext);
|
1654
|
-
cFileBuilderContext = klass;
|
1655
|
-
}
|
1656
|
-
|
1657
|
-
// -----------------------------------------------------------------------------
|
1658
|
-
// MessageBuilderContext.
|
1659
|
-
// -----------------------------------------------------------------------------
|
1660
|
-
|
1661
|
-
typedef struct {
|
1662
|
-
google_protobuf_DescriptorProto* msg_proto;
|
1663
|
-
VALUE file_builder;
|
1664
|
-
} MessageBuilderContext;
|
1665
|
-
|
1666
|
-
static VALUE cMessageBuilderContext = Qnil;
|
1667
|
-
|
1668
|
-
static void MessageBuilderContext_mark(void* _self) {
|
1669
|
-
MessageBuilderContext* self = _self;
|
1670
|
-
rb_gc_mark(self->file_builder);
|
1671
|
-
}
|
1672
|
-
|
1673
|
-
static const rb_data_type_t MessageBuilderContext_type = {
|
1674
|
-
"Google::Protobuf::Internal::MessageBuilderContext",
|
1675
|
-
{MessageBuilderContext_mark, RUBY_DEFAULT_FREE, NULL},
|
1676
|
-
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
1677
|
-
};
|
1678
|
-
|
1679
|
-
static MessageBuilderContext* ruby_to_MessageBuilderContext(VALUE val) {
|
1680
|
-
MessageBuilderContext* ret;
|
1681
|
-
TypedData_Get_Struct(val, MessageBuilderContext, &MessageBuilderContext_type,
|
1682
|
-
ret);
|
1683
|
-
return ret;
|
1684
|
-
}
|
1685
|
-
|
1686
|
-
static VALUE MessageBuilderContext_alloc(VALUE klass) {
|
1687
|
-
MessageBuilderContext* self = ALLOC(MessageBuilderContext);
|
1688
|
-
VALUE ret = TypedData_Wrap_Struct(klass, &MessageBuilderContext_type, self);
|
1689
|
-
self->file_builder = Qnil;
|
1690
|
-
return ret;
|
1691
|
-
}
|
1692
|
-
|
1693
|
-
/*
|
1694
|
-
* call-seq:
|
1695
|
-
* MessageBuilderContext.new(file_builder, name) => context
|
1696
|
-
*
|
1697
|
-
* Create a new message builder context around the given message descriptor and
|
1698
|
-
* builder context. This class is intended to serve as a DSL context to be used
|
1699
|
-
* with #instance_eval.
|
1700
|
-
*/
|
1701
|
-
static VALUE MessageBuilderContext_initialize(VALUE _self, VALUE _file_builder,
|
1702
|
-
VALUE name) {
|
1703
|
-
MessageBuilderContext* self = ruby_to_MessageBuilderContext(_self);
|
1704
|
-
FileBuilderContext* file_builder = ruby_to_FileBuilderContext(_file_builder);
|
1705
|
-
google_protobuf_FileDescriptorProto* file_proto = file_builder->file_proto;
|
1706
|
-
|
1707
|
-
self->file_builder = _file_builder;
|
1708
|
-
self->msg_proto = google_protobuf_FileDescriptorProto_add_message_type(
|
1709
|
-
file_proto, file_builder->arena);
|
1710
|
-
|
1711
|
-
google_protobuf_DescriptorProto_set_name(
|
1712
|
-
self->msg_proto, FileBuilderContext_strdup(_file_builder, name));
|
1713
|
-
|
1714
|
-
return Qnil;
|
1715
|
-
}
|
1716
|
-
|
1717
|
-
static void msgdef_add_field(VALUE msgbuilder_rb, upb_label_t label, VALUE name,
|
1718
|
-
VALUE type, VALUE number, VALUE type_class,
|
1719
|
-
VALUE options, int oneof_index,
|
1720
|
-
bool proto3_optional) {
|
1721
|
-
MessageBuilderContext* self = ruby_to_MessageBuilderContext(msgbuilder_rb);
|
1722
|
-
FileBuilderContext* file_context =
|
1723
|
-
ruby_to_FileBuilderContext(self->file_builder);
|
1724
|
-
google_protobuf_FieldDescriptorProto* field_proto;
|
1725
|
-
VALUE name_str;
|
1726
|
-
|
1727
|
-
field_proto = google_protobuf_DescriptorProto_add_field(self->msg_proto,
|
1728
|
-
file_context->arena);
|
1729
|
-
|
1730
|
-
Check_Type(name, T_SYMBOL);
|
1731
|
-
name_str = rb_id2str(SYM2ID(name));
|
1732
|
-
|
1733
|
-
google_protobuf_FieldDescriptorProto_set_name(
|
1734
|
-
field_proto, FileBuilderContext_strdup(self->file_builder, name_str));
|
1735
|
-
google_protobuf_FieldDescriptorProto_set_number(field_proto, NUM2INT(number));
|
1736
|
-
google_protobuf_FieldDescriptorProto_set_label(field_proto, (int)label);
|
1737
|
-
google_protobuf_FieldDescriptorProto_set_type(
|
1738
|
-
field_proto, (int)ruby_to_descriptortype(type));
|
1739
|
-
|
1740
|
-
if (proto3_optional) {
|
1741
|
-
google_protobuf_FieldDescriptorProto_set_proto3_optional(field_proto, true);
|
1742
|
-
}
|
1743
|
-
|
1744
|
-
if (type_class != Qnil) {
|
1745
|
-
Check_Type(type_class, T_STRING);
|
1746
|
-
|
1747
|
-
// Make it an absolute type name by prepending a dot.
|
1748
|
-
type_class = rb_str_append(rb_str_new2("."), type_class);
|
1749
|
-
google_protobuf_FieldDescriptorProto_set_type_name(
|
1750
|
-
field_proto, FileBuilderContext_strdup(self->file_builder, type_class));
|
1751
|
-
}
|
1752
|
-
|
1753
|
-
if (options != Qnil) {
|
1754
|
-
Check_Type(options, T_HASH);
|
1755
|
-
|
1756
|
-
if (rb_funcall(options, rb_intern("key?"), 1,
|
1757
|
-
ID2SYM(rb_intern("default"))) == Qtrue) {
|
1758
|
-
VALUE default_value =
|
1759
|
-
rb_hash_lookup(options, ID2SYM(rb_intern("default")));
|
1760
|
-
|
1761
|
-
/* Call #to_s since all defaults are strings in the descriptor. */
|
1762
|
-
default_value = rb_funcall(default_value, rb_intern("to_s"), 0);
|
1763
|
-
|
1764
|
-
google_protobuf_FieldDescriptorProto_set_default_value(
|
1765
|
-
field_proto,
|
1766
|
-
FileBuilderContext_strdup(self->file_builder, default_value));
|
1767
|
-
}
|
1768
|
-
|
1769
|
-
if (rb_funcall(options, rb_intern("key?"), 1,
|
1770
|
-
ID2SYM(rb_intern("json_name"))) == Qtrue) {
|
1771
|
-
VALUE json_name =
|
1772
|
-
rb_hash_lookup(options, ID2SYM(rb_intern("json_name")));
|
1773
|
-
|
1774
|
-
google_protobuf_FieldDescriptorProto_set_json_name(
|
1775
|
-
field_proto,
|
1776
|
-
FileBuilderContext_strdup(self->file_builder, json_name));
|
1777
|
-
}
|
1778
|
-
}
|
1779
|
-
|
1780
|
-
if (oneof_index >= 0) {
|
1781
|
-
google_protobuf_FieldDescriptorProto_set_oneof_index(field_proto,
|
1782
|
-
oneof_index);
|
1783
|
-
}
|
1784
|
-
}
|
1785
|
-
|
1786
|
-
#if RUBY_API_VERSION_CODE >= 20700
|
1787
|
-
static VALUE make_mapentry(VALUE _message_builder, VALUE types, int argc,
|
1788
|
-
const VALUE* argv, VALUE blockarg) {
|
1789
|
-
(void)blockarg;
|
1790
|
-
#else
|
1791
|
-
static VALUE make_mapentry(VALUE _message_builder, VALUE types, int argc,
|
1792
|
-
VALUE* argv) {
|
1793
|
-
#endif
|
1794
|
-
MessageBuilderContext* message_builder =
|
1795
|
-
ruby_to_MessageBuilderContext(_message_builder);
|
1796
|
-
VALUE type_class = rb_ary_entry(types, 2);
|
1797
|
-
FileBuilderContext* file_context =
|
1798
|
-
ruby_to_FileBuilderContext(message_builder->file_builder);
|
1799
|
-
google_protobuf_MessageOptions* options =
|
1800
|
-
google_protobuf_DescriptorProto_mutable_options(
|
1801
|
-
message_builder->msg_proto, file_context->arena);
|
1802
|
-
|
1803
|
-
google_protobuf_MessageOptions_set_map_entry(options, true);
|
1804
|
-
|
1805
|
-
// optional <type> key = 1;
|
1806
|
-
rb_funcall(_message_builder, rb_intern("optional"), 3,
|
1807
|
-
ID2SYM(rb_intern("key")), rb_ary_entry(types, 0), INT2NUM(1));
|
1808
|
-
|
1809
|
-
// optional <type> value = 2;
|
1810
|
-
if (type_class == Qnil) {
|
1811
|
-
rb_funcall(_message_builder, rb_intern("optional"), 3,
|
1812
|
-
ID2SYM(rb_intern("value")), rb_ary_entry(types, 1), INT2NUM(2));
|
1813
|
-
} else {
|
1814
|
-
rb_funcall(_message_builder, rb_intern("optional"), 4,
|
1815
|
-
ID2SYM(rb_intern("value")), rb_ary_entry(types, 1), INT2NUM(2),
|
1816
|
-
type_class);
|
1817
|
-
}
|
1818
|
-
|
1819
|
-
return Qnil;
|
1820
|
-
}
|
1821
|
-
|
1822
|
-
/*
|
1823
|
-
* call-seq:
|
1824
|
-
* MessageBuilderContext.optional(name, type, number, type_class = nil,
|
1825
|
-
* options = nil)
|
1826
|
-
*
|
1827
|
-
* Defines a new optional field on this message type with the given type, tag
|
1828
|
-
* number, and type class (for message and enum fields). The type must be a Ruby
|
1829
|
-
* symbol (as accepted by FieldDescriptor#type=) and the type_class must be a
|
1830
|
-
* string, if present (as accepted by FieldDescriptor#submsg_name=).
|
1831
|
-
*/
|
1832
|
-
VALUE MessageBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
|
1833
|
-
VALUE name, type, number;
|
1834
|
-
VALUE type_class, options = Qnil;
|
1835
|
-
|
1836
|
-
rb_scan_args(argc, argv, "32", &name, &type, &number, &type_class, &options);
|
1837
|
-
|
1838
|
-
// Allow passing (name, type, number, options) or
|
1839
|
-
// (name, type, number, type_class, options)
|
1840
|
-
if (argc == 4 && RB_TYPE_P(type_class, T_HASH)) {
|
1841
|
-
options = type_class;
|
1842
|
-
type_class = Qnil;
|
1843
|
-
}
|
1844
|
-
|
1845
|
-
msgdef_add_field(_self, UPB_LABEL_OPTIONAL, name, type, number, type_class,
|
1846
|
-
options, -1, false);
|
1847
|
-
|
1848
|
-
return Qnil;
|
1849
|
-
}
|
1850
|
-
|
1851
|
-
/*
|
1852
|
-
* call-seq:
|
1853
|
-
* MessageBuilderContext.proto3_optional(name, type, number,
|
1854
|
-
* type_class = nil, options = nil)
|
1855
|
-
*
|
1856
|
-
* Defines a true proto3 optional field (that tracks presence) on this message
|
1857
|
-
* type with the given type, tag number, and type class (for message and enum
|
1858
|
-
* fields). The type must be a Ruby symbol (as accepted by
|
1859
|
-
* FieldDescriptor#type=) and the type_class must be a string, if present (as
|
1860
|
-
* accepted by FieldDescriptor#submsg_name=).
|
1861
|
-
*/
|
1862
|
-
static VALUE MessageBuilderContext_proto3_optional(int argc, VALUE* argv,
|
1863
|
-
VALUE _self) {
|
1864
|
-
VALUE name, type, number;
|
1865
|
-
VALUE type_class, options = Qnil;
|
1866
|
-
|
1867
|
-
rb_scan_args(argc, argv, "32", &name, &type, &number, &type_class, &options);
|
1868
|
-
|
1869
|
-
// Allow passing (name, type, number, options) or
|
1870
|
-
// (name, type, number, type_class, options)
|
1871
|
-
if (argc == 4 && RB_TYPE_P(type_class, T_HASH)) {
|
1872
|
-
options = type_class;
|
1873
|
-
type_class = Qnil;
|
1874
|
-
}
|
1875
|
-
|
1876
|
-
msgdef_add_field(_self, UPB_LABEL_OPTIONAL, name, type, number, type_class,
|
1877
|
-
options, -1, true);
|
1878
|
-
|
1879
|
-
return Qnil;
|
1880
|
-
}
|
1881
|
-
|
1882
|
-
/*
|
1883
|
-
* call-seq:
|
1884
|
-
* MessageBuilderContext.required(name, type, number, type_class = nil,
|
1885
|
-
* options = nil)
|
1886
|
-
*
|
1887
|
-
* Defines a new required field on this message type with the given type, tag
|
1888
|
-
* number, and type class (for message and enum fields). The type must be a Ruby
|
1889
|
-
* symbol (as accepted by FieldDescriptor#type=) and the type_class must be a
|
1890
|
-
* string, if present (as accepted by FieldDescriptor#submsg_name=).
|
1891
|
-
*
|
1892
|
-
* Proto3 does not have required fields, but this method exists for
|
1893
|
-
* completeness. Any attempt to add a message type with required fields to a
|
1894
|
-
* pool will currently result in an error.
|
1895
|
-
*/
|
1896
|
-
static VALUE MessageBuilderContext_required(int argc, VALUE* argv,
|
1897
|
-
VALUE _self) {
|
1898
|
-
VALUE name, type, number;
|
1899
|
-
VALUE type_class, options = Qnil;
|
1900
|
-
|
1901
|
-
rb_scan_args(argc, argv, "32", &name, &type, &number, &type_class, &options);
|
1902
|
-
|
1903
|
-
// Allow passing (name, type, number, options) or
|
1904
|
-
// (name, type, number, type_class, options)
|
1905
|
-
if (argc == 4 && RB_TYPE_P(type_class, T_HASH)) {
|
1906
|
-
options = type_class;
|
1907
|
-
type_class = Qnil;
|
1908
|
-
}
|
1909
|
-
|
1910
|
-
msgdef_add_field(_self, UPB_LABEL_REQUIRED, name, type, number, type_class,
|
1911
|
-
options, -1, false);
|
1912
|
-
|
1913
|
-
return Qnil;
|
1914
|
-
}
|
1915
|
-
|
1916
|
-
/*
|
1917
|
-
* call-seq:
|
1918
|
-
* MessageBuilderContext.repeated(name, type, number, type_class = nil)
|
1919
|
-
*
|
1920
|
-
* Defines a new repeated field on this message type with the given type, tag
|
1921
|
-
* number, and type class (for message and enum fields). The type must be a Ruby
|
1922
|
-
* symbol (as accepted by FieldDescriptor#type=) and the type_class must be a
|
1923
|
-
* string, if present (as accepted by FieldDescriptor#submsg_name=).
|
1924
|
-
*/
|
1925
|
-
static VALUE MessageBuilderContext_repeated(int argc, VALUE* argv,
|
1926
|
-
VALUE _self) {
|
1927
|
-
VALUE name, type, number;
|
1928
|
-
VALUE type_class, options = Qnil;
|
1929
|
-
|
1930
|
-
rb_scan_args(argc, argv, "32", &name, &type, &number, &type_class, &options);
|
1931
|
-
|
1932
|
-
// Allow passing (name, type, number, options) or
|
1933
|
-
// (name, type, number, type_class, options)
|
1934
|
-
if (argc == 4 && RB_TYPE_P(type_class, T_HASH)) {
|
1935
|
-
options = type_class;
|
1936
|
-
type_class = Qnil;
|
1937
|
-
}
|
1938
|
-
|
1939
|
-
msgdef_add_field(_self, UPB_LABEL_REPEATED, name, type, number, type_class,
|
1940
|
-
options, -1, false);
|
1941
|
-
|
1942
|
-
return Qnil;
|
1943
|
-
}
|
1944
|
-
|
1945
|
-
/*
|
1946
|
-
* call-seq:
|
1947
|
-
* MessageBuilderContext.map(name, key_type, value_type, number,
|
1948
|
-
* value_type_class = nil)
|
1949
|
-
*
|
1950
|
-
* Defines a new map field on this message type with the given key and value
|
1951
|
-
* types, tag number, and type class (for message and enum value types). The key
|
1952
|
-
* type must be :int32/:uint32/:int64/:uint64, :bool, or :string. The value type
|
1953
|
-
* type must be a Ruby symbol (as accepted by FieldDescriptor#type=) and the
|
1954
|
-
* type_class must be a string, if present (as accepted by
|
1955
|
-
* FieldDescriptor#submsg_name=).
|
1956
|
-
*/
|
1957
|
-
static VALUE MessageBuilderContext_map(int argc, VALUE* argv, VALUE _self) {
|
1958
|
-
MessageBuilderContext* self = ruby_to_MessageBuilderContext(_self);
|
1959
|
-
VALUE name, key_type, value_type, number, type_class;
|
1960
|
-
VALUE mapentry_desc_name;
|
1961
|
-
FileBuilderContext* file_builder;
|
1962
|
-
upb_strview msg_name;
|
1963
|
-
|
1964
|
-
if (argc < 4) {
|
1965
|
-
rb_raise(rb_eArgError, "Expected at least 4 arguments.");
|
1966
|
-
}
|
1967
|
-
name = argv[0];
|
1968
|
-
key_type = argv[1];
|
1969
|
-
value_type = argv[2];
|
1970
|
-
number = argv[3];
|
1971
|
-
type_class = (argc > 4) ? argv[4] : Qnil;
|
1972
|
-
|
1973
|
-
// Validate the key type. We can't accept enums, messages, or floats/doubles
|
1974
|
-
// as map keys. (We exclude these explicitly, and the field-descriptor setter
|
1975
|
-
// below then ensures that the type is one of the remaining valid options.)
|
1976
|
-
if (SYM2ID(key_type) == rb_intern("float") ||
|
1977
|
-
SYM2ID(key_type) == rb_intern("double") ||
|
1978
|
-
SYM2ID(key_type) == rb_intern("enum") ||
|
1979
|
-
SYM2ID(key_type) == rb_intern("message")) {
|
1980
|
-
rb_raise(rb_eArgError,
|
1981
|
-
"Cannot add a map field with a float, double, enum, or message "
|
1982
|
-
"type.");
|
1983
|
-
}
|
1984
|
-
|
1985
|
-
file_builder = ruby_to_FileBuilderContext(self->file_builder);
|
1986
|
-
|
1987
|
-
// Create a new message descriptor for the map entry message, and create a
|
1988
|
-
// repeated submessage field here with that type.
|
1989
|
-
msg_name = google_protobuf_DescriptorProto_name(self->msg_proto);
|
1990
|
-
mapentry_desc_name = rb_str_new(msg_name.data, msg_name.size);
|
1991
|
-
mapentry_desc_name = rb_str_cat2(mapentry_desc_name, "_MapEntry_");
|
1992
|
-
mapentry_desc_name =
|
1993
|
-
rb_str_cat2(mapentry_desc_name, rb_id2name(SYM2ID(name)));
|
1994
|
-
|
1995
|
-
{
|
1996
|
-
// message <msgname>_MapEntry_ { /* ... */ }
|
1997
|
-
VALUE args[1] = {mapentry_desc_name};
|
1998
|
-
VALUE types = rb_ary_new3(3, key_type, value_type, type_class);
|
1999
|
-
rb_block_call(self->file_builder, rb_intern("add_message"), 1, args,
|
2000
|
-
make_mapentry, types);
|
2001
|
-
}
|
2002
|
-
|
2003
|
-
// If this file is in a package, we need to qualify the map entry type.
|
2004
|
-
if (google_protobuf_FileDescriptorProto_has_package(file_builder->file_proto)) {
|
2005
|
-
upb_strview package_view =
|
2006
|
-
google_protobuf_FileDescriptorProto_package(file_builder->file_proto);
|
2007
|
-
VALUE package = rb_str_new(package_view.data, package_view.size);
|
2008
|
-
package = rb_str_cat2(package, ".");
|
2009
|
-
mapentry_desc_name = rb_str_concat(package, mapentry_desc_name);
|
2010
|
-
}
|
2011
|
-
|
2012
|
-
// repeated MapEntry <name> = <number>;
|
2013
|
-
rb_funcall(_self, rb_intern("repeated"), 4, name,
|
2014
|
-
ID2SYM(rb_intern("message")), number, mapentry_desc_name);
|
2015
|
-
|
2016
|
-
return Qnil;
|
2017
|
-
}
|
2018
|
-
|
2019
|
-
/*
|
2020
|
-
* call-seq:
|
2021
|
-
* MessageBuilderContext.oneof(name, &block) => nil
|
2022
|
-
*
|
2023
|
-
* Creates a new OneofDescriptor with the given name, creates a
|
2024
|
-
* OneofBuilderContext attached to that OneofDescriptor, evaluates the given
|
2025
|
-
* block in the context of that OneofBuilderContext with #instance_eval, and
|
2026
|
-
* then adds the oneof to the message.
|
2027
|
-
*
|
2028
|
-
* This is the recommended, idiomatic way to build oneof definitions.
|
2029
|
-
*/
|
2030
|
-
static VALUE MessageBuilderContext_oneof(VALUE _self, VALUE name) {
|
2031
|
-
MessageBuilderContext* self = ruby_to_MessageBuilderContext(_self);
|
2032
|
-
size_t oneof_count;
|
2033
|
-
FileBuilderContext* file_context =
|
2034
|
-
ruby_to_FileBuilderContext(self->file_builder);
|
2035
|
-
google_protobuf_OneofDescriptorProto* oneof_proto;
|
2036
|
-
|
2037
|
-
// Existing oneof_count becomes oneof_index.
|
2038
|
-
google_protobuf_DescriptorProto_oneof_decl(self->msg_proto, &oneof_count);
|
2039
|
-
|
2040
|
-
// Create oneof_proto and set its name.
|
2041
|
-
oneof_proto = google_protobuf_DescriptorProto_add_oneof_decl(
|
2042
|
-
self->msg_proto, file_context->arena);
|
2043
|
-
google_protobuf_OneofDescriptorProto_set_name(
|
2044
|
-
oneof_proto, FileBuilderContext_strdup_sym(self->file_builder, name));
|
2045
|
-
|
2046
|
-
// Evaluate the block with the builder as argument.
|
2047
|
-
{
|
2048
|
-
VALUE args[2] = { INT2NUM(oneof_count), _self };
|
2049
|
-
VALUE ctx = rb_class_new_instance(2, args, cOneofBuilderContext);
|
2050
|
-
VALUE block = rb_block_proc();
|
2051
|
-
rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
|
2052
|
-
}
|
2053
|
-
|
2054
|
-
return Qnil;
|
2055
|
-
}
|
2056
|
-
|
2057
|
-
static void MessageBuilderContext_add_synthetic_oneofs(VALUE _self) {
|
2058
|
-
MessageBuilderContext* self = ruby_to_MessageBuilderContext(_self);
|
2059
|
-
FileBuilderContext* file_context =
|
2060
|
-
ruby_to_FileBuilderContext(self->file_builder);
|
2061
|
-
size_t field_count, oneof_count;
|
2062
|
-
google_protobuf_FieldDescriptorProto** fields =
|
2063
|
-
google_protobuf_DescriptorProto_mutable_field(self->msg_proto, &field_count);
|
2064
|
-
const google_protobuf_OneofDescriptorProto*const* oneofs =
|
2065
|
-
google_protobuf_DescriptorProto_oneof_decl(self->msg_proto, &oneof_count);
|
2066
|
-
VALUE names = rb_hash_new();
|
2067
|
-
VALUE underscore = rb_str_new2("_");
|
2068
|
-
size_t i;
|
2069
|
-
|
2070
|
-
// We have to build a set of all names, to ensure that synthetic oneofs are
|
2071
|
-
// not creating conflicts.
|
2072
|
-
for (i = 0; i < field_count; i++) {
|
2073
|
-
upb_strview name = google_protobuf_FieldDescriptorProto_name(fields[i]);
|
2074
|
-
rb_hash_aset(names, rb_str_new(name.data, name.size), Qtrue);
|
2075
|
-
}
|
2076
|
-
for (i = 0; i < oneof_count; i++) {
|
2077
|
-
upb_strview name = google_protobuf_OneofDescriptorProto_name(oneofs[i]);
|
2078
|
-
rb_hash_aset(names, rb_str_new(name.data, name.size), Qtrue);
|
2079
|
-
}
|
2080
|
-
|
2081
|
-
for (i = 0; i < field_count; i++) {
|
2082
|
-
google_protobuf_OneofDescriptorProto* oneof_proto;
|
2083
|
-
VALUE oneof_name;
|
2084
|
-
upb_strview field_name;
|
2085
|
-
|
2086
|
-
if (!google_protobuf_FieldDescriptorProto_proto3_optional(fields[i])) {
|
2087
|
-
continue;
|
2088
|
-
}
|
2089
|
-
|
2090
|
-
// Prepend '_' until we are no longer conflicting.
|
2091
|
-
field_name = google_protobuf_FieldDescriptorProto_name(fields[i]);
|
2092
|
-
oneof_name = rb_str_new(field_name.data, field_name.size);
|
2093
|
-
while (rb_hash_lookup(names, oneof_name) != Qnil) {
|
2094
|
-
oneof_name = rb_str_plus(underscore, oneof_name);
|
2095
|
-
}
|
2096
|
-
|
2097
|
-
rb_hash_aset(names, oneof_name, Qtrue);
|
2098
|
-
google_protobuf_FieldDescriptorProto_set_oneof_index(fields[i],
|
2099
|
-
oneof_count++);
|
2100
|
-
oneof_proto = google_protobuf_DescriptorProto_add_oneof_decl(
|
2101
|
-
self->msg_proto, file_context->arena);
|
2102
|
-
google_protobuf_OneofDescriptorProto_set_name(
|
2103
|
-
oneof_proto, FileBuilderContext_strdup(self->file_builder, oneof_name));
|
2104
|
-
}
|
2105
|
-
}
|
2106
|
-
|
2107
|
-
static void MessageBuilderContext_register(VALUE module) {
|
2108
|
-
VALUE klass = rb_define_class_under(
|
2109
|
-
module, "MessageBuilderContext", rb_cObject);
|
2110
|
-
rb_define_alloc_func(klass, MessageBuilderContext_alloc);
|
2111
|
-
rb_define_method(klass, "initialize",
|
2112
|
-
MessageBuilderContext_initialize, 2);
|
2113
|
-
rb_define_method(klass, "optional", MessageBuilderContext_optional, -1);
|
2114
|
-
rb_define_method(klass, "proto3_optional", MessageBuilderContext_proto3_optional, -1);
|
2115
|
-
rb_define_method(klass, "required", MessageBuilderContext_required, -1);
|
2116
|
-
rb_define_method(klass, "repeated", MessageBuilderContext_repeated, -1);
|
2117
|
-
rb_define_method(klass, "map", MessageBuilderContext_map, -1);
|
2118
|
-
rb_define_method(klass, "oneof", MessageBuilderContext_oneof, 1);
|
2119
|
-
rb_gc_register_address(&cMessageBuilderContext);
|
2120
|
-
cMessageBuilderContext = klass;
|
2121
|
-
}
|
2122
|
-
|
2123
|
-
// -----------------------------------------------------------------------------
|
2124
|
-
// OneofBuilderContext.
|
2125
|
-
// -----------------------------------------------------------------------------
|
2126
|
-
|
2127
|
-
typedef struct {
|
2128
|
-
int oneof_index;
|
2129
|
-
VALUE message_builder;
|
2130
|
-
} OneofBuilderContext;
|
2131
|
-
|
2132
|
-
static VALUE cOneofBuilderContext = Qnil;
|
2133
|
-
|
2134
|
-
void OneofBuilderContext_mark(void* _self) {
|
2135
|
-
OneofBuilderContext* self = _self;
|
2136
|
-
rb_gc_mark(self->message_builder);
|
2137
|
-
}
|
2138
|
-
|
2139
|
-
static const rb_data_type_t OneofBuilderContext_type = {
|
2140
|
-
"Google::Protobuf::Internal::OneofBuilderContext",
|
2141
|
-
{OneofBuilderContext_mark, RUBY_DEFAULT_FREE, NULL},
|
2142
|
-
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
2143
|
-
};
|
2144
|
-
|
2145
|
-
static OneofBuilderContext* ruby_to_OneofBuilderContext(VALUE val) {
|
2146
|
-
OneofBuilderContext* ret;
|
2147
|
-
TypedData_Get_Struct(val, OneofBuilderContext, &OneofBuilderContext_type,
|
2148
|
-
ret);
|
2149
|
-
return ret;
|
2150
|
-
}
|
2151
|
-
|
2152
|
-
static VALUE OneofBuilderContext_alloc(VALUE klass) {
|
2153
|
-
OneofBuilderContext* self = ALLOC(OneofBuilderContext);
|
2154
|
-
VALUE ret = TypedData_Wrap_Struct(klass, &OneofBuilderContext_type, self);
|
2155
|
-
self->oneof_index = 0;
|
2156
|
-
self->message_builder = Qnil;
|
2157
|
-
return ret;
|
2158
|
-
}
|
2159
|
-
|
2160
|
-
/*
|
2161
|
-
* call-seq:
|
2162
|
-
* OneofBuilderContext.new(oneof_index, message_builder) => context
|
2163
|
-
*
|
2164
|
-
* Create a new oneof builder context around the given oneof descriptor and
|
2165
|
-
* builder context. This class is intended to serve as a DSL context to be used
|
2166
|
-
* with #instance_eval.
|
2167
|
-
*/
|
2168
|
-
static VALUE OneofBuilderContext_initialize(VALUE _self, VALUE oneof_index,
|
2169
|
-
VALUE message_builder) {
|
2170
|
-
OneofBuilderContext* self = ruby_to_OneofBuilderContext(_self);
|
2171
|
-
self->oneof_index = NUM2INT(oneof_index);
|
2172
|
-
self->message_builder = message_builder;
|
2173
|
-
return Qnil;
|
2174
|
-
}
|
2175
|
-
|
2176
|
-
/*
|
2177
|
-
* call-seq:
|
2178
|
-
* OneofBuilderContext.optional(name, type, number, type_class = nil,
|
2179
|
-
* default_value = nil)
|
2180
|
-
*
|
2181
|
-
* Defines a new optional field in this oneof with the given type, tag number,
|
2182
|
-
* and type class (for message and enum fields). The type must be a Ruby symbol
|
2183
|
-
* (as accepted by FieldDescriptor#type=) and the type_class must be a string,
|
2184
|
-
* if present (as accepted by FieldDescriptor#submsg_name=).
|
2185
|
-
*/
|
2186
|
-
static VALUE OneofBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
|
2187
|
-
OneofBuilderContext* self = ruby_to_OneofBuilderContext(_self);
|
2188
|
-
VALUE name, type, number;
|
2189
|
-
VALUE type_class, options = Qnil;
|
2190
|
-
|
2191
|
-
rb_scan_args(argc, argv, "32", &name, &type, &number, &type_class, &options);
|
2192
|
-
|
2193
|
-
msgdef_add_field(self->message_builder, UPB_LABEL_OPTIONAL, name, type,
|
2194
|
-
number, type_class, options, self->oneof_index, false);
|
2195
|
-
|
2196
|
-
return Qnil;
|
2197
|
-
}
|
2198
|
-
|
2199
|
-
static void OneofBuilderContext_register(VALUE module) {
|
2200
|
-
VALUE klass = rb_define_class_under(
|
2201
|
-
module, "OneofBuilderContext", rb_cObject);
|
2202
|
-
rb_define_alloc_func(klass, OneofBuilderContext_alloc);
|
2203
|
-
rb_define_method(klass, "initialize",
|
2204
|
-
OneofBuilderContext_initialize, 2);
|
2205
|
-
rb_define_method(klass, "optional", OneofBuilderContext_optional, -1);
|
2206
|
-
rb_gc_register_address(&cOneofBuilderContext);
|
2207
|
-
cOneofBuilderContext = klass;
|
2208
|
-
}
|
2209
|
-
|
2210
|
-
// -----------------------------------------------------------------------------
|
2211
|
-
// EnumBuilderContext.
|
2212
|
-
// -----------------------------------------------------------------------------
|
2213
|
-
|
2214
|
-
typedef struct {
|
2215
|
-
google_protobuf_EnumDescriptorProto* enum_proto;
|
2216
|
-
VALUE file_builder;
|
2217
|
-
} EnumBuilderContext;
|
2218
|
-
|
2219
|
-
static VALUE cEnumBuilderContext = Qnil;
|
2220
|
-
|
2221
|
-
void EnumBuilderContext_mark(void* _self) {
|
2222
|
-
EnumBuilderContext* self = _self;
|
2223
|
-
rb_gc_mark(self->file_builder);
|
2224
|
-
}
|
2225
|
-
|
2226
|
-
static const rb_data_type_t EnumBuilderContext_type = {
|
2227
|
-
"Google::Protobuf::Internal::EnumBuilderContext",
|
2228
|
-
{EnumBuilderContext_mark, RUBY_DEFAULT_FREE, NULL},
|
2229
|
-
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
2230
|
-
};
|
2231
|
-
|
2232
|
-
static EnumBuilderContext* ruby_to_EnumBuilderContext(VALUE val) {
|
2233
|
-
EnumBuilderContext* ret;
|
2234
|
-
TypedData_Get_Struct(val, EnumBuilderContext, &EnumBuilderContext_type, ret);
|
2235
|
-
return ret;
|
2236
|
-
}
|
2237
|
-
|
2238
|
-
static VALUE EnumBuilderContext_alloc(VALUE klass) {
|
2239
|
-
EnumBuilderContext* self = ALLOC(EnumBuilderContext);
|
2240
|
-
VALUE ret = TypedData_Wrap_Struct(klass, &EnumBuilderContext_type, self);
|
2241
|
-
self->enum_proto = NULL;
|
2242
|
-
self->file_builder = Qnil;
|
2243
|
-
return ret;
|
2244
|
-
}
|
2245
|
-
|
2246
|
-
/*
|
2247
|
-
* call-seq:
|
2248
|
-
* EnumBuilderContext.new(file_builder) => context
|
2249
|
-
*
|
2250
|
-
* Create a new builder context around the given enum descriptor. This class is
|
2251
|
-
* intended to serve as a DSL context to be used with #instance_eval.
|
2252
|
-
*/
|
2253
|
-
static VALUE EnumBuilderContext_initialize(VALUE _self, VALUE _file_builder,
|
2254
|
-
VALUE name) {
|
2255
|
-
EnumBuilderContext* self = ruby_to_EnumBuilderContext(_self);
|
2256
|
-
FileBuilderContext* file_builder = ruby_to_FileBuilderContext(_file_builder);
|
2257
|
-
google_protobuf_FileDescriptorProto* file_proto = file_builder->file_proto;
|
2258
|
-
|
2259
|
-
self->file_builder = _file_builder;
|
2260
|
-
self->enum_proto = google_protobuf_FileDescriptorProto_add_enum_type(
|
2261
|
-
file_proto, file_builder->arena);
|
2262
|
-
|
2263
|
-
google_protobuf_EnumDescriptorProto_set_name(
|
2264
|
-
self->enum_proto, FileBuilderContext_strdup(_file_builder, name));
|
2265
|
-
|
2266
|
-
return Qnil;
|
2267
|
-
}
|
2268
|
-
|
2269
|
-
/*
|
2270
|
-
* call-seq:
|
2271
|
-
* EnumBuilder.add_value(name, number)
|
2272
|
-
*
|
2273
|
-
* Adds the given name => number mapping to the enum type. Name must be a Ruby
|
2274
|
-
* symbol.
|
2275
|
-
*/
|
2276
|
-
static VALUE EnumBuilderContext_value(VALUE _self, VALUE name, VALUE number) {
|
2277
|
-
EnumBuilderContext* self = ruby_to_EnumBuilderContext(_self);
|
2278
|
-
FileBuilderContext* file_builder =
|
2279
|
-
ruby_to_FileBuilderContext(self->file_builder);
|
2280
|
-
google_protobuf_EnumValueDescriptorProto* enum_value;
|
2281
|
-
|
2282
|
-
enum_value = google_protobuf_EnumDescriptorProto_add_value(
|
2283
|
-
self->enum_proto, file_builder->arena);
|
2284
|
-
|
2285
|
-
google_protobuf_EnumValueDescriptorProto_set_name(
|
2286
|
-
enum_value, FileBuilderContext_strdup_sym(self->file_builder, name));
|
2287
|
-
google_protobuf_EnumValueDescriptorProto_set_number(enum_value,
|
2288
|
-
NUM2INT(number));
|
2289
|
-
|
2290
|
-
return Qnil;
|
2291
|
-
}
|
2292
|
-
|
2293
|
-
static void EnumBuilderContext_register(VALUE module) {
|
2294
|
-
VALUE klass = rb_define_class_under(
|
2295
|
-
module, "EnumBuilderContext", rb_cObject);
|
2296
|
-
rb_define_alloc_func(klass, EnumBuilderContext_alloc);
|
2297
|
-
rb_define_method(klass, "initialize", EnumBuilderContext_initialize, 2);
|
2298
|
-
rb_define_method(klass, "value", EnumBuilderContext_value, 2);
|
2299
|
-
rb_gc_register_address(&cEnumBuilderContext);
|
2300
|
-
cEnumBuilderContext = klass;
|
2301
|
-
}
|
2302
|
-
|
2303
|
-
// -----------------------------------------------------------------------------
|
2304
|
-
// Builder.
|
2305
|
-
// -----------------------------------------------------------------------------
|
2306
|
-
|
2307
|
-
typedef struct {
|
2308
|
-
VALUE descriptor_pool;
|
2309
|
-
VALUE default_file_builder;
|
2310
|
-
} Builder;
|
2311
|
-
|
2312
|
-
static VALUE cBuilder = Qnil;
|
2313
|
-
|
2314
|
-
static void Builder_mark(void* _self) {
|
2315
|
-
Builder* self = _self;
|
2316
|
-
rb_gc_mark(self->descriptor_pool);
|
2317
|
-
rb_gc_mark(self->default_file_builder);
|
2318
|
-
}
|
2319
|
-
|
2320
|
-
static const rb_data_type_t Builder_type = {
|
2321
|
-
"Google::Protobuf::Internal::Builder",
|
2322
|
-
{Builder_mark, RUBY_DEFAULT_FREE, NULL},
|
2323
|
-
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
2324
|
-
};
|
2325
|
-
|
2326
|
-
static Builder* ruby_to_Builder(VALUE val) {
|
2327
|
-
Builder* ret;
|
2328
|
-
TypedData_Get_Struct(val, Builder, &Builder_type, ret);
|
2329
|
-
return ret;
|
2330
|
-
}
|
2331
|
-
|
2332
|
-
static VALUE Builder_alloc(VALUE klass) {
|
2333
|
-
Builder* self = ALLOC(Builder);
|
2334
|
-
VALUE ret = TypedData_Wrap_Struct(klass, &Builder_type, self);
|
2335
|
-
self->descriptor_pool = Qnil;
|
2336
|
-
self->default_file_builder = Qnil;
|
2337
|
-
return ret;
|
2338
|
-
}
|
2339
|
-
|
2340
|
-
/*
|
2341
|
-
* call-seq:
|
2342
|
-
* Builder.new(descriptor_pool) => builder
|
2343
|
-
*
|
2344
|
-
* Creates a new Builder. A Builder can accumulate a set of new message and enum
|
2345
|
-
* descriptors and atomically register them into a pool in a way that allows for
|
2346
|
-
* (co)recursive type references.
|
2347
|
-
*/
|
2348
|
-
static VALUE Builder_initialize(VALUE _self, VALUE pool) {
|
2349
|
-
Builder* self = ruby_to_Builder(_self);
|
2350
|
-
self->descriptor_pool = pool;
|
2351
|
-
self->default_file_builder = Qnil; // Created lazily if needed.
|
2352
|
-
return Qnil;
|
2353
|
-
}
|
2354
|
-
|
2355
|
-
/*
|
2356
|
-
* call-seq:
|
2357
|
-
* Builder.add_file(name, options = nil, &block)
|
2358
|
-
*
|
2359
|
-
* Creates a new, file descriptor with the given name and options and invokes
|
2360
|
-
* the block in the context of a FileBuilderContext on that descriptor. The
|
2361
|
-
* block can then call FileBuilderContext#add_message or
|
2362
|
-
* FileBuilderContext#add_enum to define new messages or enums, respectively.
|
2363
|
-
*
|
2364
|
-
* This is the recommended, idiomatic way to build file descriptors.
|
2365
|
-
*/
|
2366
|
-
static VALUE Builder_add_file(int argc, VALUE* argv, VALUE _self) {
|
2367
|
-
Builder* self = ruby_to_Builder(_self);
|
2368
|
-
VALUE name, options;
|
2369
|
-
VALUE ctx;
|
2370
|
-
VALUE block;
|
2371
|
-
|
2372
|
-
rb_scan_args(argc, argv, "11", &name, &options);
|
2373
|
-
|
2374
|
-
{
|
2375
|
-
VALUE args[3] = { self->descriptor_pool, name, options };
|
2376
|
-
ctx = rb_class_new_instance(3, args, cFileBuilderContext);
|
2377
|
-
}
|
2378
|
-
|
2379
|
-
block = rb_block_proc();
|
2380
|
-
rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
|
2381
|
-
FileBuilderContext_build(ctx);
|
2382
|
-
|
2383
|
-
return Qnil;
|
2384
|
-
}
|
2385
|
-
|
2386
|
-
static VALUE Builder_get_default_file(VALUE _self) {
|
2387
|
-
Builder* self = ruby_to_Builder(_self);
|
2388
|
-
|
2389
|
-
/* Lazily create only if legacy builder-level methods are called. */
|
2390
|
-
if (self->default_file_builder == Qnil) {
|
2391
|
-
VALUE name = rb_str_new2("ruby_default_file.proto");
|
2392
|
-
VALUE args [3] = { self->descriptor_pool, name, rb_hash_new() };
|
2393
|
-
self->default_file_builder =
|
2394
|
-
rb_class_new_instance(3, args, cFileBuilderContext);
|
2395
|
-
}
|
2396
|
-
|
2397
|
-
return self->default_file_builder;
|
2398
|
-
}
|
2399
|
-
|
2400
|
-
/*
|
2401
|
-
* call-seq:
|
2402
|
-
* Builder.add_message(name, &block)
|
2403
|
-
*
|
2404
|
-
* Old and deprecated way to create a new descriptor.
|
2405
|
-
* See FileBuilderContext.add_message for the recommended way.
|
2406
|
-
*
|
2407
|
-
* Exists for backwards compatibility to allow building descriptor pool for
|
2408
|
-
* files generated by protoc which don't add messages within "add_file" block.
|
2409
|
-
* Descriptors created this way get assigned to a default empty FileDescriptor.
|
2410
|
-
*/
|
2411
|
-
static VALUE Builder_add_message(VALUE _self, VALUE name) {
|
2412
|
-
VALUE file_builder = Builder_get_default_file(_self);
|
2413
|
-
rb_funcall_with_block(file_builder, rb_intern("add_message"), 1, &name,
|
2414
|
-
rb_block_proc());
|
2415
|
-
return Qnil;
|
2416
|
-
}
|
2417
|
-
|
2418
|
-
/*
|
2419
|
-
* call-seq:
|
2420
|
-
* Builder.add_enum(name, &block)
|
2421
|
-
*
|
2422
|
-
* Old and deprecated way to create a new enum descriptor.
|
2423
|
-
* See FileBuilderContext.add_enum for the recommended way.
|
2424
|
-
*
|
2425
|
-
* Exists for backwards compatibility to allow building descriptor pool for
|
2426
|
-
* files generated by protoc which don't add enums within "add_file" block.
|
2427
|
-
* Enum descriptors created this way get assigned to a default empty
|
2428
|
-
* FileDescriptor.
|
2429
|
-
*/
|
2430
|
-
static VALUE Builder_add_enum(VALUE _self, VALUE name) {
|
2431
|
-
VALUE file_builder = Builder_get_default_file(_self);
|
2432
|
-
rb_funcall_with_block(file_builder, rb_intern("add_enum"), 1, &name,
|
2433
|
-
rb_block_proc());
|
2434
|
-
return Qnil;
|
2435
|
-
}
|
2436
|
-
|
2437
|
-
/* This method is hidden from Ruby, and only called directly from
|
2438
|
-
* DescriptorPool_build(). */
|
2439
|
-
static VALUE Builder_build(VALUE _self) {
|
2440
|
-
Builder* self = ruby_to_Builder(_self);
|
2441
|
-
|
2442
|
-
if (self->default_file_builder != Qnil) {
|
2443
|
-
FileBuilderContext_build(self->default_file_builder);
|
2444
|
-
self->default_file_builder = Qnil;
|
2445
|
-
}
|
2446
|
-
|
2447
|
-
return Qnil;
|
2448
|
-
}
|
2449
|
-
|
2450
|
-
static void Builder_register(VALUE module) {
|
2451
|
-
VALUE klass = rb_define_class_under(module, "Builder", rb_cObject);
|
2452
|
-
rb_define_alloc_func(klass, Builder_alloc);
|
2453
|
-
rb_define_method(klass, "initialize", Builder_initialize, 1);
|
2454
|
-
rb_define_method(klass, "add_file", Builder_add_file, -1);
|
2455
|
-
rb_define_method(klass, "add_message", Builder_add_message, 1);
|
2456
|
-
rb_define_method(klass, "add_enum", Builder_add_enum, 1);
|
2457
|
-
rb_gc_register_address(&cBuilder);
|
2458
|
-
cBuilder = klass;
|
2459
|
-
}
|
2460
|
-
|
2461
1166
|
static VALUE get_def_obj(VALUE _descriptor_pool, const void* ptr, VALUE klass) {
|
2462
1167
|
DescriptorPool* descriptor_pool = ruby_to_DescriptorPool(_descriptor_pool);
|
2463
1168
|
VALUE key = ULL2NUM((intptr_t)ptr);
|
@@ -2573,11 +1278,6 @@ void Defs_register(VALUE module) {
|
|
2573
1278
|
FieldDescriptor_register(module);
|
2574
1279
|
OneofDescriptor_register(module);
|
2575
1280
|
EnumDescriptor_register(module);
|
2576
|
-
FileBuilderContext_register(module);
|
2577
|
-
MessageBuilderContext_register(module);
|
2578
|
-
OneofBuilderContext_register(module);
|
2579
|
-
EnumBuilderContext_register(module);
|
2580
|
-
Builder_register(module);
|
2581
1281
|
|
2582
1282
|
rb_gc_register_address(&c_only_cookie);
|
2583
1283
|
c_only_cookie = rb_class_new_instance(0, NULL, rb_cObject);
|