Skip to content

Commit 74122eb

Browse files
y-yagicopybara-github
authored andcommitted
Add to_proto to descriptor classes (protocolbuffers#19971)
Some APIs (e.g. [BigQuery Storage](https://github.com/googleapis/googleapis/blob/ab61c52324b39d1c8619a96ab19cc6c173b13f2c/google/cloud/bigquery/storage/v1/protobuf.proto#L39)) use DescriptorProto for schema descriptions. But, in Ruby, there are no methods for that so far. This PR implements the method for that(`to_proto`) to descriptor classes. Fixes protocolbuffers#12044. Closes protocolbuffers#19971 PiperOrigin-RevId: 723149905
1 parent de9f4ff commit 74122eb

23 files changed

+1193
-12
lines changed

php/ext/google/protobuf/php-upb.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15420,7 +15420,7 @@ bool upb_FileDef_Resolves(const upb_FileDef* f, const char* path) {
1542015420
return false;
1542115421
}
1542215422

15423-
static char* strviewdup(upb_DefBuilder* ctx, upb_StringView view) {
15423+
static char* _strviewdup(upb_DefBuilder* ctx, upb_StringView view) {
1542415424
char* ret = upb_strdup2(view.data, view.size, _upb_DefBuilder_Arena(ctx));
1542515425
if (!ret) _upb_DefBuilder_OomErr(ctx);
1542615426
return ret;
@@ -15549,7 +15549,7 @@ void _upb_FileDef_Create(upb_DefBuilder* ctx,
1554915549
}
1555015550

1555115551
upb_StringView name = UPB_DESC(FileDescriptorProto_name)(file_proto);
15552-
file->name = strviewdup(ctx, name);
15552+
file->name = _strviewdup(ctx, name);
1555315553
if (strlen(file->name) != name.size) {
1555415554
_upb_DefBuilder_Errf(ctx, "File name contained embedded NULL");
1555515555
}
@@ -15558,7 +15558,7 @@ void _upb_FileDef_Create(upb_DefBuilder* ctx,
1555815558

1555915559
if (package.size) {
1556015560
_upb_DefBuilder_CheckIdentFull(ctx, package);
15561-
file->package = strviewdup(ctx, package);
15561+
file->package = _strviewdup(ctx, package);
1556215562
} else {
1556315563
file->package = NULL;
1556415564
}

ruby/ext/google/protobuf_c/defs.c

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,27 @@ static VALUE Descriptor_options(VALUE _self) {
451451
return message_options;
452452
}
453453

454+
/*
455+
* call-seq:
456+
* Descriptor.to_proto => DescriptorProto
457+
*
458+
* Returns the `DescriptorProto` of this `Descriptor`.
459+
*/
460+
static VALUE Descriptor_to_proto(VALUE _self) {
461+
Descriptor* self = ruby_to_Descriptor(_self);
462+
upb_Arena* arena = upb_Arena_New();
463+
google_protobuf_DescriptorProto* proto =
464+
upb_MessageDef_ToProto(self->msgdef, arena);
465+
size_t size;
466+
const char* serialized =
467+
google_protobuf_DescriptorProto_serialize(proto, arena, &size);
468+
VALUE proto_class = rb_path2class("Google::Protobuf::DescriptorProto");
469+
VALUE proto_rb =
470+
Message_decode_bytes(size, serialized, 0, proto_class, false);
471+
upb_Arena_Free(arena);
472+
return proto_rb;
473+
}
474+
454475
static void Descriptor_register(VALUE module) {
455476
VALUE klass = rb_define_class_under(module, "Descriptor", rb_cObject);
456477
rb_define_alloc_func(klass, Descriptor_alloc);
@@ -463,6 +484,7 @@ static void Descriptor_register(VALUE module) {
463484
rb_define_method(klass, "name", Descriptor_name, 0);
464485
rb_define_method(klass, "file_descriptor", Descriptor_file_descriptor, 0);
465486
rb_define_method(klass, "options", Descriptor_options, 0);
487+
rb_define_method(klass, "to_proto", Descriptor_to_proto, 0);
466488
rb_include_module(klass, rb_mEnumerable);
467489
rb_gc_register_address(&cDescriptor);
468490
cDescriptor = klass;
@@ -558,12 +580,37 @@ static VALUE FileDescriptor_options(VALUE _self) {
558580
return file_options;
559581
}
560582

583+
/*
584+
* call-seq:
585+
* FileDescriptor.to_proto => FileDescriptorProto
586+
*
587+
* Returns the `FileDescriptorProto` of this `FileDescriptor`.
588+
*/
589+
static VALUE FileDescriptor_to_proto(VALUE _self) {
590+
FileDescriptor* self = ruby_to_FileDescriptor(_self);
591+
upb_Arena* arena = upb_Arena_New();
592+
google_protobuf_FileDescriptorProto* file_proto =
593+
upb_FileDef_ToProto(self->filedef, arena);
594+
595+
size_t size;
596+
const char* serialized =
597+
google_protobuf_FileDescriptorProto_serialize(file_proto, arena, &size);
598+
599+
VALUE file_proto_class =
600+
rb_path2class("Google::Protobuf::FileDescriptorProto");
601+
VALUE proto_rb =
602+
Message_decode_bytes(size, serialized, 0, file_proto_class, false);
603+
upb_Arena_Free(arena);
604+
return proto_rb;
605+
}
606+
561607
static void FileDescriptor_register(VALUE module) {
562608
VALUE klass = rb_define_class_under(module, "FileDescriptor", rb_cObject);
563609
rb_define_alloc_func(klass, FileDescriptor_alloc);
564610
rb_define_method(klass, "initialize", FileDescriptor_initialize, 3);
565611
rb_define_method(klass, "name", FileDescriptor_name, 0);
566612
rb_define_method(klass, "options", FileDescriptor_options, 0);
613+
rb_define_method(klass, "to_proto", FileDescriptor_to_proto, 0);
567614
rb_gc_register_address(&cFileDescriptor);
568615
cFileDescriptor = klass;
569616
}
@@ -956,6 +1003,27 @@ static VALUE FieldDescriptor_options(VALUE _self) {
9561003
return field_options;
9571004
}
9581005

1006+
/*
1007+
* call-seq:
1008+
* FieldDescriptor.to_proto => FieldDescriptorProto
1009+
*
1010+
* Returns the `FieldDescriptorProto` of this `FieldDescriptor`.
1011+
*/
1012+
static VALUE FieldDescriptor_to_proto(VALUE _self) {
1013+
FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
1014+
upb_Arena* arena = upb_Arena_New();
1015+
google_protobuf_FieldDescriptorProto* proto =
1016+
upb_FieldDef_ToProto(self->fielddef, arena);
1017+
size_t size;
1018+
const char* serialized =
1019+
google_protobuf_FieldDescriptorProto_serialize(proto, arena, &size);
1020+
VALUE proto_class = rb_path2class("Google::Protobuf::FieldDescriptorProto");
1021+
VALUE proto_rb =
1022+
Message_decode_bytes(size, serialized, 0, proto_class, false);
1023+
upb_Arena_Free(arena);
1024+
return proto_rb;
1025+
}
1026+
9591027
static void FieldDescriptor_register(VALUE module) {
9601028
VALUE klass = rb_define_class_under(module, "FieldDescriptor", rb_cObject);
9611029
rb_define_alloc_func(klass, FieldDescriptor_alloc);
@@ -975,6 +1043,7 @@ static void FieldDescriptor_register(VALUE module) {
9751043
rb_define_method(klass, "get", FieldDescriptor_get, 1);
9761044
rb_define_method(klass, "set", FieldDescriptor_set, 2);
9771045
rb_define_method(klass, "options", FieldDescriptor_options, 0);
1046+
rb_define_method(klass, "to_proto", FieldDescriptor_to_proto, 0);
9781047
rb_gc_register_address(&cFieldDescriptor);
9791048
cFieldDescriptor = klass;
9801049
}
@@ -1093,13 +1162,35 @@ static VALUE OneOfDescriptor_options(VALUE _self) {
10931162
return oneof_options;
10941163
}
10951164

1165+
/*
1166+
* call-seq:
1167+
* OneofDescriptor.to_proto => OneofDescriptorProto
1168+
*
1169+
* Returns the `OneofDescriptorProto` of this `OneofDescriptor`.
1170+
*/
1171+
static VALUE OneOfDescriptor_to_proto(VALUE _self) {
1172+
OneofDescriptor* self = ruby_to_OneofDescriptor(_self);
1173+
upb_Arena* arena = upb_Arena_New();
1174+
google_protobuf_OneofDescriptorProto* proto =
1175+
upb_OneofDef_ToProto(self->oneofdef, arena);
1176+
size_t size;
1177+
const char* serialized =
1178+
google_protobuf_OneofDescriptorProto_serialize(proto, arena, &size);
1179+
VALUE proto_class = rb_path2class("Google::Protobuf::OneofDescriptorProto");
1180+
VALUE proto_rb =
1181+
Message_decode_bytes(size, serialized, 0, proto_class, false);
1182+
upb_Arena_Free(arena);
1183+
return proto_rb;
1184+
}
1185+
10961186
static void OneofDescriptor_register(VALUE module) {
10971187
VALUE klass = rb_define_class_under(module, "OneofDescriptor", rb_cObject);
10981188
rb_define_alloc_func(klass, OneofDescriptor_alloc);
10991189
rb_define_method(klass, "initialize", OneofDescriptor_initialize, 3);
11001190
rb_define_method(klass, "name", OneofDescriptor_name, 0);
11011191
rb_define_method(klass, "each", OneofDescriptor_each, 0);
11021192
rb_define_method(klass, "options", OneOfDescriptor_options, 0);
1193+
rb_define_method(klass, "to_proto", OneOfDescriptor_to_proto, 0);
11031194
rb_include_module(klass, rb_mEnumerable);
11041195
rb_gc_register_address(&cOneofDescriptor);
11051196
cOneofDescriptor = klass;
@@ -1298,6 +1389,29 @@ static VALUE EnumDescriptor_options(VALUE _self) {
12981389
return enum_options;
12991390
}
13001391

1392+
/*
1393+
* call-seq:
1394+
* EnumDescriptor.to_proto => EnumDescriptorProto
1395+
*
1396+
* Returns the `EnumDescriptorProto` of this `EnumDescriptor`.
1397+
*/
1398+
static VALUE EnumDescriptor_to_proto(VALUE _self) {
1399+
EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1400+
upb_Arena* arena = upb_Arena_New();
1401+
google_protobuf_EnumDescriptorProto* proto =
1402+
upb_EnumDef_ToProto(self->enumdef, arena);
1403+
1404+
size_t size;
1405+
const char* serialized =
1406+
google_protobuf_EnumDescriptorProto_serialize(proto, arena, &size);
1407+
1408+
VALUE proto_class = rb_path2class("Google::Protobuf::EnumDescriptorProto");
1409+
VALUE proto_rb =
1410+
Message_decode_bytes(size, serialized, 0, proto_class, false);
1411+
upb_Arena_Free(arena);
1412+
return proto_rb;
1413+
}
1414+
13011415
static void EnumDescriptor_register(VALUE module) {
13021416
VALUE klass = rb_define_class_under(module, "EnumDescriptor", rb_cObject);
13031417
rb_define_alloc_func(klass, EnumDescriptor_alloc);
@@ -1310,6 +1424,7 @@ static void EnumDescriptor_register(VALUE module) {
13101424
rb_define_method(klass, "file_descriptor", EnumDescriptor_file_descriptor, 0);
13111425
rb_define_method(klass, "is_closed?", EnumDescriptor_is_closed, 0);
13121426
rb_define_method(klass, "options", EnumDescriptor_options, 0);
1427+
rb_define_method(klass, "to_proto", EnumDescriptor_to_proto, 0);
13131428
rb_include_module(klass, rb_mEnumerable);
13141429
rb_gc_register_address(&cEnumDescriptor);
13151430
cEnumDescriptor = klass;
@@ -1438,6 +1553,27 @@ static VALUE ServiceDescriptor_options(VALUE _self) {
14381553
return service_options;
14391554
}
14401555

1556+
/*
1557+
* call-seq:
1558+
* ServiceDescriptor.to_proto => ServiceDescriptorProto
1559+
*
1560+
* Returns the `ServiceDescriptorProto` of this `ServiceDescriptor`.
1561+
*/
1562+
static VALUE ServiceDescriptor_to_proto(VALUE _self) {
1563+
ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self);
1564+
upb_Arena* arena = upb_Arena_New();
1565+
google_protobuf_ServiceDescriptorProto* proto =
1566+
upb_ServiceDef_ToProto(self->servicedef, arena);
1567+
size_t size;
1568+
const char* serialized =
1569+
google_protobuf_ServiceDescriptorProto_serialize(proto, arena, &size);
1570+
VALUE proto_class = rb_path2class("Google::Protobuf::ServiceDescriptorProto");
1571+
VALUE proto_rb =
1572+
Message_decode_bytes(size, serialized, 0, proto_class, false);
1573+
upb_Arena_Free(arena);
1574+
return proto_rb;
1575+
}
1576+
14411577
static void ServiceDescriptor_register(VALUE module) {
14421578
VALUE klass = rb_define_class_under(module, "ServiceDescriptor", rb_cObject);
14431579
rb_define_alloc_func(klass, ServiceDescriptor_alloc);
@@ -1447,6 +1583,7 @@ static void ServiceDescriptor_register(VALUE module) {
14471583
rb_define_method(klass, "file_descriptor", ServiceDescriptor_file_descriptor,
14481584
0);
14491585
rb_define_method(klass, "options", ServiceDescriptor_options, 0);
1586+
rb_define_method(klass, "to_proto", ServiceDescriptor_to_proto, 0);
14501587
rb_include_module(klass, rb_mEnumerable);
14511588
rb_gc_register_address(&cServiceDescriptor);
14521589
cServiceDescriptor = klass;
@@ -1580,6 +1717,27 @@ static VALUE MethodDescriptor_client_streaming(VALUE _self) {
15801717
return upb_MethodDef_ClientStreaming(self->methoddef) ? Qtrue : Qfalse;
15811718
}
15821719

1720+
/*
1721+
* call-seq:
1722+
* MethodDescriptor.to_proto => MethodDescriptorProto
1723+
*
1724+
* Returns the `MethodDescriptorProto` of this `MethodDescriptor`.
1725+
*/
1726+
static VALUE MethodDescriptor_to_proto(VALUE _self) {
1727+
MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
1728+
upb_Arena* arena = upb_Arena_New();
1729+
google_protobuf_MethodDescriptorProto* proto =
1730+
upb_MethodDef_ToProto(self->methoddef, arena);
1731+
size_t size;
1732+
const char* serialized =
1733+
google_protobuf_MethodDescriptorProto_serialize(proto, arena, &size);
1734+
VALUE proto_class = rb_path2class("Google::Protobuf::MethodDescriptorProto");
1735+
VALUE proto_rb =
1736+
Message_decode_bytes(size, serialized, 0, proto_class, false);
1737+
upb_Arena_Free(arena);
1738+
return proto_rb;
1739+
}
1740+
15831741
/*
15841742
* call-seq:
15851743
* MethodDescriptor.server_streaming => bool
@@ -1603,6 +1761,7 @@ static void MethodDescriptor_register(VALUE module) {
16031761
0);
16041762
rb_define_method(klass, "server_streaming", MethodDescriptor_server_streaming,
16051763
0);
1764+
rb_define_method(klass, "to_proto", MethodDescriptor_to_proto, 0);
16061765
rb_gc_register_address(&cMethodDescriptor);
16071766
cMethodDescriptor = klass;
16081767
}

ruby/ext/google/protobuf_c/glue.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,31 @@ char* EnumDescriptor_serialized_options(const upb_EnumDef* enumdef,
2626
return serialized;
2727
}
2828

29+
char* EnumDescriptor_serialized_to_proto(const upb_EnumDef* enumdef,
30+
size_t* size, upb_Arena* arena) {
31+
const google_protobuf_EnumDescriptorProto* file_proto =
32+
upb_EnumDef_ToProto(enumdef, arena);
33+
char* serialized =
34+
google_protobuf_EnumDescriptorProto_serialize(file_proto, arena, size);
35+
return serialized;
36+
}
37+
2938
char* FileDescriptor_serialized_options(const upb_FileDef* filedef,
3039
size_t* size, upb_Arena* arena) {
3140
const google_protobuf_FileOptions* opts = upb_FileDef_Options(filedef);
3241
char* serialized = google_protobuf_FileOptions_serialize(opts, arena, size);
3342
return serialized;
3443
}
3544

45+
char* FileDescriptor_serialized_to_proto(const upb_FileDef* filedef,
46+
size_t* size, upb_Arena* arena) {
47+
const google_protobuf_FileDescriptorProto* file_proto =
48+
upb_FileDef_ToProto(filedef, arena);
49+
char* serialized =
50+
google_protobuf_FileDescriptorProto_serialize(file_proto, arena, size);
51+
return serialized;
52+
}
53+
3654
char* Descriptor_serialized_options(const upb_MessageDef* msgdef, size_t* size,
3755
upb_Arena* arena) {
3856
const google_protobuf_MessageOptions* opts = upb_MessageDef_Options(msgdef);
@@ -41,20 +59,47 @@ char* Descriptor_serialized_options(const upb_MessageDef* msgdef, size_t* size,
4159
return serialized;
4260
}
4361

62+
char* Descriptor_serialized_to_proto(const upb_MessageDef* msgdef, size_t* size,
63+
upb_Arena* arena) {
64+
const google_protobuf_DescriptorProto* proto =
65+
upb_MessageDef_ToProto(msgdef, arena);
66+
char* serialized =
67+
google_protobuf_DescriptorProto_serialize(proto, arena, size);
68+
return serialized;
69+
}
70+
4471
char* OneOfDescriptor_serialized_options(const upb_OneofDef* oneofdef,
4572
size_t* size, upb_Arena* arena) {
4673
const google_protobuf_OneofOptions* opts = upb_OneofDef_Options(oneofdef);
4774
char* serialized = google_protobuf_OneofOptions_serialize(opts, arena, size);
4875
return serialized;
4976
}
5077

78+
char* OneOfDescriptor_serialized_to_proto(const upb_OneofDef* oneofdef,
79+
size_t* size, upb_Arena* arena) {
80+
const google_protobuf_OneofDescriptorProto* proto =
81+
upb_OneofDef_ToProto(oneofdef, arena);
82+
char* serialized =
83+
google_protobuf_OneofDescriptorProto_serialize(proto, arena, size);
84+
return serialized;
85+
}
86+
5187
char* FieldDescriptor_serialized_options(const upb_FieldDef* fielddef,
5288
size_t* size, upb_Arena* arena) {
5389
const google_protobuf_FieldOptions* opts = upb_FieldDef_Options(fielddef);
5490
char* serialized = google_protobuf_FieldOptions_serialize(opts, arena, size);
5591
return serialized;
5692
}
5793

94+
char* FieldDescriptor_serialized_to_proto(const upb_FieldDef* fieldef,
95+
size_t* size, upb_Arena* arena) {
96+
const google_protobuf_FieldDescriptorProto* proto =
97+
upb_FieldDef_ToProto(fieldef, arena);
98+
char* serialized =
99+
google_protobuf_FieldDescriptorProto_serialize(proto, arena, size);
100+
return serialized;
101+
}
102+
58103
char* ServiceDescriptor_serialized_options(const upb_ServiceDef* servicedef,
59104
size_t* size, upb_Arena* arena) {
60105
const google_protobuf_ServiceOptions* opts =
@@ -64,9 +109,27 @@ char* ServiceDescriptor_serialized_options(const upb_ServiceDef* servicedef,
64109
return serialized;
65110
}
66111

112+
char* ServiceDescriptor_serialized_to_proto(const upb_ServiceDef* servicedef,
113+
size_t* size, upb_Arena* arena) {
114+
const google_protobuf_ServiceDescriptorProto* proto =
115+
upb_ServiceDef_ToProto(servicedef, arena);
116+
char* serialized =
117+
google_protobuf_ServiceDescriptorProto_serialize(proto, arena, size);
118+
return serialized;
119+
}
120+
67121
char* MethodDescriptor_serialized_options(const upb_MethodDef* methoddef,
68122
size_t* size, upb_Arena* arena) {
69123
const google_protobuf_MethodOptions* opts = upb_MethodDef_Options(methoddef);
70124
char* serialized = google_protobuf_MethodOptions_serialize(opts, arena, size);
71125
return serialized;
72126
}
127+
128+
char* MethodDescriptor_serialized_to_proto(const upb_MethodDef* methodef,
129+
size_t* size, upb_Arena* arena) {
130+
const google_protobuf_MethodDescriptorProto* proto =
131+
upb_MethodDef_ToProto(methodef, arena);
132+
char* serialized =
133+
google_protobuf_MethodDescriptorProto_serialize(proto, arena, size);
134+
return serialized;
135+
}

0 commit comments

Comments
 (0)