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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 53ff771120813dbc8978524eb29dad6b6a9013fe432bc711c4f82a108c053d04
4
- data.tar.gz: 2a23ace983918657e9a2c8e81e84a4138274fe2fa5c7caf9ae075b5e99364d04
3
+ metadata.gz: 5fa9928445d29031ea4ad6d79c83e4cad35ef0cf8a4aeaf8d5818202bf3edcd9
4
+ data.tar.gz: c53bf8399f4d75b44b8986a8b7ec62065e230056cb2781d1445c969d71660152
5
5
  SHA512:
6
- metadata.gz: a35d11998a4b03546460b2869c0d9827c3d122a97d1e85083e8f428d8a0ce3da51b3f38e26b07378302f40e3c684fc241a916c4c70b63f9b7403ebfc46ada999
7
- data.tar.gz: 1a183c0801108ed713bed698050f67a5ecc2a2acbe38f84499cea573ad86a388e9a2ff9e6bf681f621d3ad53267213fa4ebb12ab523cdd8315b5fbb67d127f0e
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 wyhash(&val, 1, seed, _wyp);
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 wyhash(&val, 4, seed, _wyp);
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 wyhash(&val, 8, seed, _wyp);
339
+ return Wyhash(&val, 8, seed, kWyhashSalt);
341
340
  case UPB_TYPE_STRING:
342
341
  case UPB_TYPE_BYTES:
343
- return wyhash(val.str_val.data, val.str_val.size, seed, _wyp);
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.build(&block)
137
+ * DescriptorPool.add_serialized_file(serialized_file_proto)
306
138
  *
307
- * Invokes the block with a Builder instance as self. All message and enum types
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
- static VALUE DescriptorPool_build(int argc, VALUE* argv, VALUE _self) {
314
- VALUE ctx = rb_class_new_instance(1, &_self, cBuilder);
315
- VALUE block = rb_block_proc();
316
- rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
317
- Builder_build(ctx);
318
- return Qnil;
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, "build", DescriptorPool_build, -1);
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);