google-protobuf 4.26.1 → 4.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of google-protobuf might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/ext/google/protobuf_c/convert.c +39 -14
- data/ext/google/protobuf_c/defs.c +327 -1
- data/ext/google/protobuf_c/glue.c +16 -0
- data/ext/google/protobuf_c/map.c +72 -20
- data/ext/google/protobuf_c/map.h +6 -2
- data/ext/google/protobuf_c/message.c +78 -50
- data/ext/google/protobuf_c/message.h +1 -5
- data/ext/google/protobuf_c/protobuf.c +11 -9
- data/ext/google/protobuf_c/protobuf.h +3 -7
- data/ext/google/protobuf_c/repeated_field.c +61 -17
- data/ext/google/protobuf_c/repeated_field.h +5 -1
- data/ext/google/protobuf_c/ruby-upb.c +1693 -475
- data/ext/google/protobuf_c/ruby-upb.h +2526 -1386
- data/ext/google/protobuf_c/shared_convert.c +5 -2
- data/ext/google/protobuf_c/shared_message.c +0 -30
- data/ext/google/protobuf_c/shared_message.h +0 -4
- data/lib/google/protobuf/descriptor_pb.rb +2 -1
- data/lib/google/protobuf/ffi/descriptor.rb +4 -3
- data/lib/google/protobuf/ffi/descriptor_pool.rb +3 -1
- data/lib/google/protobuf/ffi/enum_descriptor.rb +3 -1
- data/lib/google/protobuf/ffi/ffi.rb +0 -5
- data/lib/google/protobuf/ffi/field_descriptor.rb +4 -2
- data/lib/google/protobuf/ffi/file_descriptor.rb +3 -1
- data/lib/google/protobuf/ffi/internal/arena.rb +0 -6
- data/lib/google/protobuf/ffi/internal/convert.rb +14 -7
- data/lib/google/protobuf/ffi/map.rb +45 -21
- data/lib/google/protobuf/ffi/message.rb +182 -60
- data/lib/google/protobuf/ffi/method_descriptor.rb +114 -0
- data/lib/google/protobuf/ffi/oneof_descriptor.rb +3 -1
- data/lib/google/protobuf/ffi/repeated_field.rb +42 -16
- data/lib/google/protobuf/ffi/service_descriptor.rb +107 -0
- data/lib/google/protobuf/repeated_field.rb +3 -3
- data/lib/google/protobuf_ffi.rb +2 -0
- metadata +20 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 531c1d4e78630f992244bac8fac8176297a60073b58bd92d344083f478f8dcb5
|
4
|
+
data.tar.gz: de1b062231118253de9063e495ce188907760bf536a368a426d0ab1cf59ea5bb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec022839412e0210fa1cd44b34d96defb2c83a0ca7c1b84bc62f00526f2af64d70abbfda7c405b0a8eaa718ab366a80bbbd7ee3a072144a539282adc7fb24059
|
7
|
+
data.tar.gz: 87463961cb841e762147dcdbd648557cd0a5228e122a717f6429220d485a2dea1fe32f3f1efbcb71504e2b2ad1a191810adcf4327c93bcb047bb6fb244a7748b
|
@@ -104,6 +104,41 @@ unknownval:
|
|
104
104
|
rb_raise(rb_eRangeError, "Unknown symbol value for enum field '%s'.", name);
|
105
105
|
}
|
106
106
|
|
107
|
+
VALUE Convert_CheckStringUtf8(VALUE str) {
|
108
|
+
VALUE utf8 = rb_enc_from_encoding(rb_utf8_encoding());
|
109
|
+
|
110
|
+
if (rb_obj_encoding(str) == utf8) {
|
111
|
+
// Note: Just because a string is marked as having UTF-8 encoding does
|
112
|
+
// not mean that it is *valid* UTF-8. We have to check separately
|
113
|
+
// whether it is valid.
|
114
|
+
if (rb_enc_str_coderange(str) == ENC_CODERANGE_BROKEN) {
|
115
|
+
// TODO: For now
|
116
|
+
// we only warn for this case. We will remove the warning and throw an
|
117
|
+
// exception below in the 30.x release
|
118
|
+
|
119
|
+
rb_warn(
|
120
|
+
"String is invalid UTF-8. This will be an error in a future "
|
121
|
+
"version.");
|
122
|
+
// VALUE exc = rb_const_get_at(
|
123
|
+
// rb_cEncoding, rb_intern("InvalidByteSequenceError"));
|
124
|
+
// rb_raise(exc, "String is invalid UTF-8");
|
125
|
+
}
|
126
|
+
} else {
|
127
|
+
// Note: this will not duplicate underlying string data unless
|
128
|
+
// necessary.
|
129
|
+
//
|
130
|
+
// This will throw an exception if the conversion cannot be performed:
|
131
|
+
// - Encoding::UndefinedConversionError if certain characters cannot be
|
132
|
+
// converted to UTF-8.
|
133
|
+
// - Encoding::InvalidByteSequenceError if certain characters were invalid
|
134
|
+
// in the source encoding.
|
135
|
+
str = rb_str_encode(str, utf8, 0, Qnil);
|
136
|
+
PBRUBY_ASSERT(rb_enc_str_coderange(str) != ENC_CODERANGE_BROKEN);
|
137
|
+
}
|
138
|
+
|
139
|
+
return str;
|
140
|
+
}
|
141
|
+
|
107
142
|
upb_MessageValue Convert_RubyToUpb(VALUE value, const char* name,
|
108
143
|
TypeInfo type_info, upb_Arena* arena) {
|
109
144
|
upb_MessageValue ret;
|
@@ -137,8 +172,7 @@ upb_MessageValue Convert_RubyToUpb(VALUE value, const char* name,
|
|
137
172
|
}
|
138
173
|
break;
|
139
174
|
}
|
140
|
-
case kUpb_CType_String:
|
141
|
-
VALUE utf8 = rb_enc_from_encoding(rb_utf8_encoding());
|
175
|
+
case kUpb_CType_String:
|
142
176
|
if (rb_obj_class(value) == rb_cSymbol) {
|
143
177
|
value = rb_funcall(value, rb_intern("to_s"), 0);
|
144
178
|
} else if (!rb_obj_is_kind_of(value, rb_cString)) {
|
@@ -147,19 +181,9 @@ upb_MessageValue Convert_RubyToUpb(VALUE value, const char* name,
|
|
147
181
|
rb_class2name(CLASS_OF(value)));
|
148
182
|
}
|
149
183
|
|
150
|
-
|
151
|
-
// Note: this will not duplicate underlying string data unless
|
152
|
-
// necessary.
|
153
|
-
value = rb_str_encode(value, utf8, 0, Qnil);
|
154
|
-
|
155
|
-
if (rb_enc_str_coderange(value) == ENC_CODERANGE_BROKEN) {
|
156
|
-
rb_raise(rb_eEncodingError, "String is invalid UTF-8");
|
157
|
-
}
|
158
|
-
}
|
159
|
-
|
184
|
+
value = Convert_CheckStringUtf8(value);
|
160
185
|
ret.str_val = Convert_StringData(value, arena);
|
161
186
|
break;
|
162
|
-
}
|
163
187
|
case kUpb_CType_Bytes: {
|
164
188
|
VALUE bytes = rb_enc_from_encoding(rb_ascii8bit_encoding());
|
165
189
|
if (rb_obj_class(value) != rb_cString) {
|
@@ -204,7 +228,8 @@ upb_MessageValue Convert_RubyToUpb(VALUE value, const char* name,
|
|
204
228
|
ret.uint64_val = NUM2ULL(value);
|
205
229
|
break;
|
206
230
|
default:
|
207
|
-
|
231
|
+
rb_raise(cTypeError, "Convert_RubyToUpb(): Unexpected type %d",
|
232
|
+
(int)type_info.type);
|
208
233
|
}
|
209
234
|
break;
|
210
235
|
default:
|
@@ -23,6 +23,9 @@ static VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_EnumDef* def);
|
|
23
23
|
static VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_FieldDef* def);
|
24
24
|
static VALUE get_filedef_obj(VALUE descriptor_pool, const upb_FileDef* def);
|
25
25
|
static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_OneofDef* def);
|
26
|
+
static VALUE get_servicedef_obj(VALUE descriptor_pool,
|
27
|
+
const upb_ServiceDef* def);
|
28
|
+
static VALUE get_methoddef_obj(VALUE descriptor_pool, const upb_MethodDef* def);
|
26
29
|
|
27
30
|
// A distinct object that is not accessible from Ruby. We use this as a
|
28
31
|
// constructor argument to enforce that certain objects cannot be created from
|
@@ -153,6 +156,7 @@ static VALUE DescriptorPool_lookup(VALUE _self, VALUE name) {
|
|
153
156
|
const upb_MessageDef* msgdef;
|
154
157
|
const upb_EnumDef* enumdef;
|
155
158
|
const upb_FieldDef* fielddef;
|
159
|
+
const upb_ServiceDef* servicedef;
|
156
160
|
|
157
161
|
msgdef = upb_DefPool_FindMessageByName(self->symtab, name_str);
|
158
162
|
if (msgdef) {
|
@@ -169,6 +173,11 @@ static VALUE DescriptorPool_lookup(VALUE _self, VALUE name) {
|
|
169
173
|
return get_enumdef_obj(_self, enumdef);
|
170
174
|
}
|
171
175
|
|
176
|
+
servicedef = upb_DefPool_FindServiceByName(self->symtab, name_str);
|
177
|
+
if (servicedef) {
|
178
|
+
return get_servicedef_obj(_self, servicedef);
|
179
|
+
}
|
180
|
+
|
172
181
|
return Qnil;
|
173
182
|
}
|
174
183
|
|
@@ -257,7 +266,20 @@ static VALUE decode_options(VALUE self, const char* option_type, int size,
|
|
257
266
|
VALUE desc_rb = get_msgdef_obj(descriptor_pool, msgdef);
|
258
267
|
const Descriptor* desc = ruby_to_Descriptor(desc_rb);
|
259
268
|
|
260
|
-
options_rb = Message_decode_bytes(size, bytes, 0, desc->klass,
|
269
|
+
options_rb = Message_decode_bytes(size, bytes, 0, desc->klass, false);
|
270
|
+
|
271
|
+
// Strip features from the options proto to keep it internal.
|
272
|
+
const upb_MessageDef* decoded_desc = NULL;
|
273
|
+
upb_Message* options = Message_GetMutable(options_rb, &decoded_desc);
|
274
|
+
PBRUBY_ASSERT(options != NULL);
|
275
|
+
PBRUBY_ASSERT(decoded_desc == msgdef);
|
276
|
+
const upb_FieldDef* field =
|
277
|
+
upb_MessageDef_FindFieldByName(decoded_desc, "features");
|
278
|
+
PBRUBY_ASSERT(field != NULL);
|
279
|
+
upb_Message_ClearFieldByDef(options, field);
|
280
|
+
|
281
|
+
Message_freeze(options_rb);
|
282
|
+
|
261
283
|
rb_ivar_set(self, options_instancevar_interned, options_rb);
|
262
284
|
return options_rb;
|
263
285
|
}
|
@@ -1294,6 +1316,298 @@ static void EnumDescriptor_register(VALUE module) {
|
|
1294
1316
|
cEnumDescriptor = klass;
|
1295
1317
|
}
|
1296
1318
|
|
1319
|
+
// -----------------------------------------------------------------------------
|
1320
|
+
// ServiceDescriptor
|
1321
|
+
// -----------------------------------------------------------------------------
|
1322
|
+
|
1323
|
+
typedef struct {
|
1324
|
+
const upb_ServiceDef* servicedef;
|
1325
|
+
// IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
|
1326
|
+
// macro to update VALUE references, as to trigger write barriers.
|
1327
|
+
VALUE module; // begins as nil
|
1328
|
+
VALUE descriptor_pool; // Owns the upb_ServiceDef.
|
1329
|
+
} ServiceDescriptor;
|
1330
|
+
|
1331
|
+
static VALUE cServiceDescriptor = Qnil;
|
1332
|
+
|
1333
|
+
static void ServiceDescriptor_mark(void* _self) {
|
1334
|
+
ServiceDescriptor* self = _self;
|
1335
|
+
rb_gc_mark(self->module);
|
1336
|
+
rb_gc_mark(self->descriptor_pool);
|
1337
|
+
}
|
1338
|
+
|
1339
|
+
static const rb_data_type_t ServiceDescriptor_type = {
|
1340
|
+
"Google::Protobuf::ServicDescriptor",
|
1341
|
+
{ServiceDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
|
1342
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
1343
|
+
};
|
1344
|
+
|
1345
|
+
static ServiceDescriptor* ruby_to_ServiceDescriptor(VALUE val) {
|
1346
|
+
ServiceDescriptor* ret;
|
1347
|
+
TypedData_Get_Struct(val, ServiceDescriptor, &ServiceDescriptor_type, ret);
|
1348
|
+
return ret;
|
1349
|
+
}
|
1350
|
+
|
1351
|
+
static VALUE ServiceDescriptor_alloc(VALUE klass) {
|
1352
|
+
ServiceDescriptor* self = ALLOC(ServiceDescriptor);
|
1353
|
+
VALUE ret = TypedData_Wrap_Struct(klass, &ServiceDescriptor_type, self);
|
1354
|
+
self->servicedef = NULL;
|
1355
|
+
self->module = Qnil;
|
1356
|
+
self->descriptor_pool = Qnil;
|
1357
|
+
return ret;
|
1358
|
+
}
|
1359
|
+
|
1360
|
+
/*
|
1361
|
+
* call-seq:
|
1362
|
+
* ServiceDescriptor.new(c_only_cookie, ptr) => ServiceDescriptor
|
1363
|
+
*
|
1364
|
+
* Creates a descriptor wrapper object. May only be called from C.
|
1365
|
+
*/
|
1366
|
+
static VALUE ServiceDescriptor_initialize(VALUE _self, VALUE cookie,
|
1367
|
+
VALUE descriptor_pool, VALUE ptr) {
|
1368
|
+
ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self);
|
1369
|
+
|
1370
|
+
if (cookie != c_only_cookie) {
|
1371
|
+
rb_raise(rb_eRuntimeError,
|
1372
|
+
"Descriptor objects may not be created from Ruby.");
|
1373
|
+
}
|
1374
|
+
|
1375
|
+
RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool);
|
1376
|
+
self->servicedef = (const upb_ServiceDef*)NUM2ULL(ptr);
|
1377
|
+
|
1378
|
+
return Qnil;
|
1379
|
+
}
|
1380
|
+
|
1381
|
+
/*
|
1382
|
+
* call-seq:
|
1383
|
+
* ServiceDescriptor.name => name
|
1384
|
+
*
|
1385
|
+
* Returns the name of this service.
|
1386
|
+
*/
|
1387
|
+
static VALUE ServiceDescriptor_name(VALUE _self) {
|
1388
|
+
ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self);
|
1389
|
+
return rb_str_maybe_null(upb_ServiceDef_FullName(self->servicedef));
|
1390
|
+
}
|
1391
|
+
|
1392
|
+
/*
|
1393
|
+
* call-seq:
|
1394
|
+
* ServiceDescriptor.file_descriptor
|
1395
|
+
*
|
1396
|
+
* Returns the FileDescriptor object this service belongs to.
|
1397
|
+
*/
|
1398
|
+
static VALUE ServiceDescriptor_file_descriptor(VALUE _self) {
|
1399
|
+
ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self);
|
1400
|
+
return get_filedef_obj(self->descriptor_pool,
|
1401
|
+
upb_ServiceDef_File(self->servicedef));
|
1402
|
+
}
|
1403
|
+
|
1404
|
+
/*
|
1405
|
+
* call-seq:
|
1406
|
+
* ServiceDescriptor.each(&block)
|
1407
|
+
*
|
1408
|
+
* Iterates over methods in this service, yielding to the block on each one.
|
1409
|
+
*/
|
1410
|
+
static VALUE ServiceDescriptor_each(VALUE _self) {
|
1411
|
+
ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self);
|
1412
|
+
|
1413
|
+
int n = upb_ServiceDef_MethodCount(self->servicedef);
|
1414
|
+
for (int i = 0; i < n; i++) {
|
1415
|
+
const upb_MethodDef* method = upb_ServiceDef_Method(self->servicedef, i);
|
1416
|
+
VALUE obj = get_methoddef_obj(self->descriptor_pool, method);
|
1417
|
+
rb_yield(obj);
|
1418
|
+
}
|
1419
|
+
return Qnil;
|
1420
|
+
}
|
1421
|
+
|
1422
|
+
/*
|
1423
|
+
* call-seq:
|
1424
|
+
* ServiceDescriptor.options => options
|
1425
|
+
*
|
1426
|
+
* Returns the `ServiceOptions` for this `ServiceDescriptor`.
|
1427
|
+
*/
|
1428
|
+
static VALUE ServiceDescriptor_options(VALUE _self) {
|
1429
|
+
ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self);
|
1430
|
+
const google_protobuf_ServiceOptions* opts =
|
1431
|
+
upb_ServiceDef_Options(self->servicedef);
|
1432
|
+
upb_Arena* arena = upb_Arena_New();
|
1433
|
+
size_t size;
|
1434
|
+
char* serialized =
|
1435
|
+
google_protobuf_ServiceOptions_serialize(opts, arena, &size);
|
1436
|
+
VALUE service_options = decode_options(_self, "ServiceOptions", size,
|
1437
|
+
serialized, self->descriptor_pool);
|
1438
|
+
upb_Arena_Free(arena);
|
1439
|
+
return service_options;
|
1440
|
+
}
|
1441
|
+
|
1442
|
+
static void ServiceDescriptor_register(VALUE module) {
|
1443
|
+
VALUE klass = rb_define_class_under(module, "ServiceDescriptor", rb_cObject);
|
1444
|
+
rb_define_alloc_func(klass, ServiceDescriptor_alloc);
|
1445
|
+
rb_define_method(klass, "initialize", ServiceDescriptor_initialize, 3);
|
1446
|
+
rb_define_method(klass, "name", ServiceDescriptor_name, 0);
|
1447
|
+
rb_define_method(klass, "each", ServiceDescriptor_each, 0);
|
1448
|
+
rb_define_method(klass, "file_descriptor", ServiceDescriptor_file_descriptor,
|
1449
|
+
0);
|
1450
|
+
rb_define_method(klass, "options", ServiceDescriptor_options, 0);
|
1451
|
+
rb_include_module(klass, rb_mEnumerable);
|
1452
|
+
rb_gc_register_address(&cServiceDescriptor);
|
1453
|
+
cServiceDescriptor = klass;
|
1454
|
+
}
|
1455
|
+
|
1456
|
+
// -----------------------------------------------------------------------------
|
1457
|
+
// MethodDescriptor
|
1458
|
+
// -----------------------------------------------------------------------------
|
1459
|
+
|
1460
|
+
typedef struct {
|
1461
|
+
const upb_MethodDef* methoddef;
|
1462
|
+
// IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
|
1463
|
+
// macro to update VALUE references, as to trigger write barriers.
|
1464
|
+
VALUE module; // begins as nil
|
1465
|
+
VALUE descriptor_pool; // Owns the upb_MethodDef.
|
1466
|
+
} MethodDescriptor;
|
1467
|
+
|
1468
|
+
static VALUE cMethodDescriptor = Qnil;
|
1469
|
+
|
1470
|
+
static void MethodDescriptor_mark(void* _self) {
|
1471
|
+
MethodDescriptor* self = _self;
|
1472
|
+
rb_gc_mark(self->module);
|
1473
|
+
rb_gc_mark(self->descriptor_pool);
|
1474
|
+
}
|
1475
|
+
|
1476
|
+
static const rb_data_type_t MethodDescriptor_type = {
|
1477
|
+
"Google::Protobuf::MethodDescriptor",
|
1478
|
+
{MethodDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
|
1479
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
1480
|
+
};
|
1481
|
+
|
1482
|
+
static MethodDescriptor* ruby_to_MethodDescriptor(VALUE val) {
|
1483
|
+
MethodDescriptor* ret;
|
1484
|
+
TypedData_Get_Struct(val, MethodDescriptor, &MethodDescriptor_type, ret);
|
1485
|
+
return ret;
|
1486
|
+
}
|
1487
|
+
|
1488
|
+
static VALUE MethodDescriptor_alloc(VALUE klass) {
|
1489
|
+
MethodDescriptor* self = ALLOC(MethodDescriptor);
|
1490
|
+
VALUE ret = TypedData_Wrap_Struct(klass, &MethodDescriptor_type, self);
|
1491
|
+
self->methoddef = NULL;
|
1492
|
+
self->module = Qnil;
|
1493
|
+
self->descriptor_pool = Qnil;
|
1494
|
+
return ret;
|
1495
|
+
}
|
1496
|
+
|
1497
|
+
/*
|
1498
|
+
* call-seq:
|
1499
|
+
* MethodDescriptor.new(c_only_cookie, ptr) => MethodDescriptor
|
1500
|
+
*
|
1501
|
+
* Creates a descriptor wrapper object. May only be called from C.
|
1502
|
+
*/
|
1503
|
+
static VALUE MethodDescriptor_initialize(VALUE _self, VALUE cookie,
|
1504
|
+
VALUE descriptor_pool, VALUE ptr) {
|
1505
|
+
MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
|
1506
|
+
|
1507
|
+
if (cookie != c_only_cookie) {
|
1508
|
+
rb_raise(rb_eRuntimeError,
|
1509
|
+
"Descriptor objects may not be created from Ruby.");
|
1510
|
+
}
|
1511
|
+
|
1512
|
+
RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool);
|
1513
|
+
self->methoddef = (const upb_MethodDef*)NUM2ULL(ptr);
|
1514
|
+
|
1515
|
+
return Qnil;
|
1516
|
+
}
|
1517
|
+
|
1518
|
+
/*
|
1519
|
+
* call-seq:
|
1520
|
+
* MethodDescriptor.name => name
|
1521
|
+
*
|
1522
|
+
* Returns the name of this method
|
1523
|
+
*/
|
1524
|
+
static VALUE MethodDescriptor_name(VALUE _self) {
|
1525
|
+
MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
|
1526
|
+
return rb_str_maybe_null(upb_MethodDef_Name(self->methoddef));
|
1527
|
+
}
|
1528
|
+
|
1529
|
+
/*
|
1530
|
+
* call-seq:
|
1531
|
+
* MethodDescriptor.options => options
|
1532
|
+
*
|
1533
|
+
* Returns the `MethodOptions` for this `MethodDescriptor`.
|
1534
|
+
*/
|
1535
|
+
static VALUE MethodDescriptor_options(VALUE _self) {
|
1536
|
+
MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
|
1537
|
+
const google_protobuf_MethodOptions* opts =
|
1538
|
+
upb_MethodDef_Options(self->methoddef);
|
1539
|
+
upb_Arena* arena = upb_Arena_New();
|
1540
|
+
size_t size;
|
1541
|
+
char* serialized =
|
1542
|
+
google_protobuf_MethodOptions_serialize(opts, arena, &size);
|
1543
|
+
VALUE method_options = decode_options(_self, "MethodOptions", size,
|
1544
|
+
serialized, self->descriptor_pool);
|
1545
|
+
upb_Arena_Free(arena);
|
1546
|
+
return method_options;
|
1547
|
+
}
|
1548
|
+
|
1549
|
+
/*
|
1550
|
+
* call-seq:
|
1551
|
+
* MethodDescriptor.input_type => Descriptor
|
1552
|
+
*
|
1553
|
+
* Returns the `Descriptor` for the request message type of this method
|
1554
|
+
*/
|
1555
|
+
static VALUE MethodDescriptor_input_type(VALUE _self) {
|
1556
|
+
MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
|
1557
|
+
const upb_MessageDef* type = upb_MethodDef_InputType(self->methoddef);
|
1558
|
+
return get_msgdef_obj(self->descriptor_pool, type);
|
1559
|
+
}
|
1560
|
+
|
1561
|
+
/*
|
1562
|
+
* call-seq:
|
1563
|
+
* MethodDescriptor.output_type => Descriptor
|
1564
|
+
*
|
1565
|
+
* Returns the `Descriptor` for the response message type of this method
|
1566
|
+
*/
|
1567
|
+
static VALUE MethodDescriptor_output_type(VALUE _self) {
|
1568
|
+
MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
|
1569
|
+
const upb_MessageDef* type = upb_MethodDef_OutputType(self->methoddef);
|
1570
|
+
return get_msgdef_obj(self->descriptor_pool, type);
|
1571
|
+
}
|
1572
|
+
|
1573
|
+
/*
|
1574
|
+
* call-seq:
|
1575
|
+
* MethodDescriptor.client_streaming => bool
|
1576
|
+
*
|
1577
|
+
* Returns whether or not this is a streaming request method
|
1578
|
+
*/
|
1579
|
+
static VALUE MethodDescriptor_client_streaming(VALUE _self) {
|
1580
|
+
MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
|
1581
|
+
return upb_MethodDef_ClientStreaming(self->methoddef) ? Qtrue : Qfalse;
|
1582
|
+
}
|
1583
|
+
|
1584
|
+
/*
|
1585
|
+
* call-seq:
|
1586
|
+
* MethodDescriptor.server_streaming => bool
|
1587
|
+
*
|
1588
|
+
* Returns whether or not this is a streaming response method
|
1589
|
+
*/
|
1590
|
+
static VALUE MethodDescriptor_server_streaming(VALUE _self) {
|
1591
|
+
MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
|
1592
|
+
return upb_MethodDef_ServerStreaming(self->methoddef) ? Qtrue : Qfalse;
|
1593
|
+
}
|
1594
|
+
|
1595
|
+
static void MethodDescriptor_register(VALUE module) {
|
1596
|
+
VALUE klass = rb_define_class_under(module, "MethodDescriptor", rb_cObject);
|
1597
|
+
rb_define_alloc_func(klass, MethodDescriptor_alloc);
|
1598
|
+
rb_define_method(klass, "initialize", MethodDescriptor_initialize, 3);
|
1599
|
+
rb_define_method(klass, "name", MethodDescriptor_name, 0);
|
1600
|
+
rb_define_method(klass, "options", MethodDescriptor_options, 0);
|
1601
|
+
rb_define_method(klass, "input_type", MethodDescriptor_input_type, 0);
|
1602
|
+
rb_define_method(klass, "output_type", MethodDescriptor_output_type, 0);
|
1603
|
+
rb_define_method(klass, "client_streaming", MethodDescriptor_client_streaming,
|
1604
|
+
0);
|
1605
|
+
rb_define_method(klass, "server_streaming", MethodDescriptor_server_streaming,
|
1606
|
+
0);
|
1607
|
+
rb_gc_register_address(&cMethodDescriptor);
|
1608
|
+
cMethodDescriptor = klass;
|
1609
|
+
}
|
1610
|
+
|
1297
1611
|
static VALUE get_def_obj(VALUE _descriptor_pool, const void* ptr, VALUE klass) {
|
1298
1612
|
DescriptorPool* descriptor_pool = ruby_to_DescriptorPool(_descriptor_pool);
|
1299
1613
|
VALUE key = ULL2NUM((intptr_t)ptr);
|
@@ -1335,6 +1649,16 @@ static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_OneofDef* def) {
|
|
1335
1649
|
return get_def_obj(descriptor_pool, def, cOneofDescriptor);
|
1336
1650
|
}
|
1337
1651
|
|
1652
|
+
static VALUE get_servicedef_obj(VALUE descriptor_pool,
|
1653
|
+
const upb_ServiceDef* def) {
|
1654
|
+
return get_def_obj(descriptor_pool, def, cServiceDescriptor);
|
1655
|
+
}
|
1656
|
+
|
1657
|
+
static VALUE get_methoddef_obj(VALUE descriptor_pool,
|
1658
|
+
const upb_MethodDef* def) {
|
1659
|
+
return get_def_obj(descriptor_pool, def, cMethodDescriptor);
|
1660
|
+
}
|
1661
|
+
|
1338
1662
|
// -----------------------------------------------------------------------------
|
1339
1663
|
// Shared functions
|
1340
1664
|
// -----------------------------------------------------------------------------
|
@@ -1410,6 +1734,8 @@ void Defs_register(VALUE module) {
|
|
1410
1734
|
FieldDescriptor_register(module);
|
1411
1735
|
OneofDescriptor_register(module);
|
1412
1736
|
EnumDescriptor_register(module);
|
1737
|
+
ServiceDescriptor_register(module);
|
1738
|
+
MethodDescriptor_register(module);
|
1413
1739
|
|
1414
1740
|
rb_gc_register_address(&c_only_cookie);
|
1415
1741
|
c_only_cookie = rb_class_new_instance(0, NULL, rb_cObject);
|
@@ -54,3 +54,19 @@ char* FieldDescriptor_serialized_options(const upb_FieldDef* fielddef,
|
|
54
54
|
char* serialized = google_protobuf_FieldOptions_serialize(opts, arena, size);
|
55
55
|
return serialized;
|
56
56
|
}
|
57
|
+
|
58
|
+
char* ServiceDescriptor_serialized_options(const upb_ServiceDef* servicedef,
|
59
|
+
size_t* size, upb_Arena* arena) {
|
60
|
+
const google_protobuf_ServiceOptions* opts =
|
61
|
+
upb_ServiceDef_Options(servicedef);
|
62
|
+
char* serialized =
|
63
|
+
google_protobuf_ServiceOptions_serialize(opts, arena, size);
|
64
|
+
return serialized;
|
65
|
+
}
|
66
|
+
|
67
|
+
char* MethodDescriptor_serialized_options(const upb_MethodDef* methoddef,
|
68
|
+
size_t* size, upb_Arena* arena) {
|
69
|
+
const google_protobuf_MethodOptions* opts = upb_MethodDef_Options(methoddef);
|
70
|
+
char* serialized = google_protobuf_MethodOptions_serialize(opts, arena, size);
|
71
|
+
return serialized;
|
72
|
+
}
|
data/ext/google/protobuf_c/map.c
CHANGED
@@ -63,9 +63,10 @@ static VALUE Map_alloc(VALUE klass) {
|
|
63
63
|
return TypedData_Wrap_Struct(klass, &Map_type, self);
|
64
64
|
}
|
65
65
|
|
66
|
-
VALUE Map_GetRubyWrapper(upb_Map* map, upb_CType key_type,
|
67
|
-
VALUE arena) {
|
66
|
+
VALUE Map_GetRubyWrapper(const upb_Map* map, upb_CType key_type,
|
67
|
+
TypeInfo value_type, VALUE arena) {
|
68
68
|
PBRUBY_ASSERT(map);
|
69
|
+
PBRUBY_ASSERT(arena != Qnil);
|
69
70
|
|
70
71
|
VALUE val = ObjectCache_Get(map);
|
71
72
|
|
@@ -83,7 +84,6 @@ VALUE Map_GetRubyWrapper(upb_Map* map, upb_CType key_type, TypeInfo value_type,
|
|
83
84
|
}
|
84
85
|
return ObjectCache_TryAdd(map, val);
|
85
86
|
}
|
86
|
-
|
87
87
|
return val;
|
88
88
|
}
|
89
89
|
|
@@ -105,8 +105,9 @@ static TypeInfo Map_keyinfo(Map* self) {
|
|
105
105
|
}
|
106
106
|
|
107
107
|
static upb_Map* Map_GetMutable(VALUE _self) {
|
108
|
-
|
109
|
-
|
108
|
+
const upb_Map* map = ruby_to_Map(_self)->map;
|
109
|
+
Protobuf_CheckNotFrozen(_self, upb_Map_IsFrozen(map));
|
110
|
+
return (upb_Map*)map;
|
110
111
|
}
|
111
112
|
|
112
113
|
VALUE Map_CreateHash(const upb_Map* map, upb_CType key_type,
|
@@ -439,14 +440,14 @@ static VALUE Map_has_key(VALUE _self, VALUE key) {
|
|
439
440
|
* nil if none was present. Throws an exception if the key is of the wrong type.
|
440
441
|
*/
|
441
442
|
static VALUE Map_delete(VALUE _self, VALUE key) {
|
443
|
+
upb_Map* map = Map_GetMutable(_self);
|
442
444
|
Map* self = ruby_to_Map(_self);
|
443
|
-
rb_check_frozen(_self);
|
444
445
|
|
445
446
|
upb_MessageValue key_upb =
|
446
447
|
Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL);
|
447
448
|
upb_MessageValue val_upb;
|
448
449
|
|
449
|
-
if (upb_Map_Delete(
|
450
|
+
if (upb_Map_Delete(map, key_upb, &val_upb)) {
|
450
451
|
return Convert_UpbToRuby(val_upb, self->value_type_info, self->arena);
|
451
452
|
} else {
|
452
453
|
return Qnil;
|
@@ -560,29 +561,79 @@ VALUE Map_eq(VALUE _self, VALUE _other) {
|
|
560
561
|
|
561
562
|
/*
|
562
563
|
* call-seq:
|
563
|
-
*
|
564
|
+
* Map.frozen? => bool
|
565
|
+
*
|
566
|
+
* Returns true if the map is frozen in either Ruby or the underlying
|
567
|
+
* representation. Freezes the Ruby map object if it is not already frozen in
|
568
|
+
* Ruby but it is frozen in the underlying representation.
|
569
|
+
*/
|
570
|
+
VALUE Map_frozen(VALUE _self) {
|
571
|
+
Map* self = ruby_to_Map(_self);
|
572
|
+
if (!upb_Map_IsFrozen(self->map)) {
|
573
|
+
PBRUBY_ASSERT(!RB_OBJ_FROZEN(_self));
|
574
|
+
return Qfalse;
|
575
|
+
}
|
576
|
+
|
577
|
+
// Lazily freeze the Ruby wrapper.
|
578
|
+
if (!RB_OBJ_FROZEN(_self)) RB_OBJ_FREEZE(_self);
|
579
|
+
return Qtrue;
|
580
|
+
}
|
581
|
+
|
582
|
+
/*
|
583
|
+
* call-seq:
|
584
|
+
* Map.freeze => self
|
564
585
|
*
|
565
|
-
* Freezes the
|
566
|
-
*
|
586
|
+
* Freezes the map object. We have to intercept this so we can freeze the
|
587
|
+
* underlying representation, not just the Ruby wrapper.
|
567
588
|
*/
|
568
589
|
VALUE Map_freeze(VALUE _self) {
|
569
590
|
Map* self = ruby_to_Map(_self);
|
591
|
+
if (RB_OBJ_FROZEN(_self)) {
|
592
|
+
PBRUBY_ASSERT(upb_Map_IsFrozen(self->map));
|
593
|
+
return _self;
|
594
|
+
}
|
595
|
+
|
596
|
+
if (!upb_Map_IsFrozen(self->map)) {
|
597
|
+
if (self->value_type_info.type == kUpb_CType_Message) {
|
598
|
+
upb_Map_Freeze(
|
599
|
+
Map_GetMutable(_self),
|
600
|
+
upb_MessageDef_MiniTable(self->value_type_info.def.msgdef));
|
601
|
+
} else {
|
602
|
+
upb_Map_Freeze(Map_GetMutable(_self), NULL);
|
603
|
+
}
|
604
|
+
}
|
570
605
|
|
571
|
-
if (RB_OBJ_FROZEN(_self)) return _self;
|
572
|
-
Arena_Pin(self->arena, _self);
|
573
606
|
RB_OBJ_FREEZE(_self);
|
574
607
|
|
575
|
-
|
576
|
-
|
577
|
-
|
608
|
+
return _self;
|
609
|
+
}
|
610
|
+
|
611
|
+
VALUE Map_EmptyFrozen(const upb_FieldDef* f) {
|
612
|
+
PBRUBY_ASSERT(upb_FieldDef_IsMap(f));
|
613
|
+
VALUE val = ObjectCache_Get(f);
|
578
614
|
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
615
|
+
if (val == Qnil) {
|
616
|
+
const upb_FieldDef* key_f = map_field_key(f);
|
617
|
+
const upb_FieldDef* val_f = map_field_value(f);
|
618
|
+
upb_CType key_type = upb_FieldDef_CType(key_f);
|
619
|
+
TypeInfo value_type_info = TypeInfo_get(val_f);
|
620
|
+
val = Map_alloc(cMap);
|
621
|
+
Map* self;
|
622
|
+
TypedData_Get_Struct(val, Map, &Map_type, self);
|
623
|
+
self->arena = Arena_new();
|
624
|
+
self->map =
|
625
|
+
upb_Map_New(Arena_get(self->arena), key_type, value_type_info.type);
|
626
|
+
self->key_type = key_type;
|
627
|
+
self->value_type_info = value_type_info;
|
628
|
+
if (self->value_type_info.type == kUpb_CType_Message) {
|
629
|
+
const upb_MessageDef* val_m = value_type_info.def.msgdef;
|
630
|
+
self->value_type_class = Descriptor_DefToClass(val_m);
|
583
631
|
}
|
632
|
+
return ObjectCache_TryAdd(f, Map_freeze(val));
|
584
633
|
}
|
585
|
-
|
634
|
+
PBRUBY_ASSERT(RB_OBJ_FROZEN(val));
|
635
|
+
PBRUBY_ASSERT(upb_Map_IsFrozen(ruby_to_Map(val)->map));
|
636
|
+
return val;
|
586
637
|
}
|
587
638
|
|
588
639
|
/*
|
@@ -671,6 +722,7 @@ void Map_register(VALUE module) {
|
|
671
722
|
rb_define_method(klass, "clone", Map_dup, 0);
|
672
723
|
rb_define_method(klass, "==", Map_eq, 1);
|
673
724
|
rb_define_method(klass, "freeze", Map_freeze, 0);
|
725
|
+
rb_define_method(klass, "frozen?", Map_frozen, 0);
|
674
726
|
rb_define_method(klass, "hash", Map_hash, 0);
|
675
727
|
rb_define_method(klass, "to_h", Map_to_h, 0);
|
676
728
|
rb_define_method(klass, "inspect", Map_inspect, 0);
|
data/ext/google/protobuf_c/map.h
CHANGED
@@ -11,10 +11,14 @@
|
|
11
11
|
#include "protobuf.h"
|
12
12
|
#include "ruby-upb.h"
|
13
13
|
|
14
|
+
// Returns a frozen sentinel Ruby wrapper object for an empty upb_Map with the
|
15
|
+
// key and value types specified by the field. Creates one if it doesn't exist.
|
16
|
+
VALUE Map_EmptyFrozen(const upb_FieldDef* f);
|
17
|
+
|
14
18
|
// Returns a Ruby wrapper object for the given map, which will be created if
|
15
19
|
// one does not exist already.
|
16
|
-
VALUE Map_GetRubyWrapper(upb_Map *map, upb_CType key_type,
|
17
|
-
VALUE arena);
|
20
|
+
VALUE Map_GetRubyWrapper(const upb_Map *map, upb_CType key_type,
|
21
|
+
TypeInfo value_type, VALUE arena);
|
18
22
|
|
19
23
|
// Gets the underlying upb_Map for this Ruby map object, which must have
|
20
24
|
// key/value type that match |field|. If this is not a map or the type doesn't
|