diff --git a/php/ext/google/protobuf/php-upb.c b/php/ext/google/protobuf/php-upb.c index 05d026c17ea71..c89034dd7b0f2 100644 --- a/php/ext/google/protobuf/php-upb.c +++ b/php/ext/google/protobuf/php-upb.c @@ -15420,7 +15420,7 @@ bool upb_FileDef_Resolves(const upb_FileDef* f, const char* path) { return false; } -static char* strviewdup(upb_DefBuilder* ctx, upb_StringView view) { +static char* _strviewdup(upb_DefBuilder* ctx, upb_StringView view) { char* ret = upb_strdup2(view.data, view.size, _upb_DefBuilder_Arena(ctx)); if (!ret) _upb_DefBuilder_OomErr(ctx); return ret; @@ -15549,7 +15549,7 @@ void _upb_FileDef_Create(upb_DefBuilder* ctx, } upb_StringView name = UPB_DESC(FileDescriptorProto_name)(file_proto); - file->name = strviewdup(ctx, name); + file->name = _strviewdup(ctx, name); if (strlen(file->name) != name.size) { _upb_DefBuilder_Errf(ctx, "File name contained embedded NULL"); } @@ -15558,7 +15558,7 @@ void _upb_FileDef_Create(upb_DefBuilder* ctx, if (package.size) { _upb_DefBuilder_CheckIdentFull(ctx, package); - file->package = strviewdup(ctx, package); + file->package = _strviewdup(ctx, package); } else { file->package = NULL; } diff --git a/ruby/ext/google/protobuf_c/defs.c b/ruby/ext/google/protobuf_c/defs.c index dd34e2ce27fba..7a5b022196cc6 100644 --- a/ruby/ext/google/protobuf_c/defs.c +++ b/ruby/ext/google/protobuf_c/defs.c @@ -451,6 +451,27 @@ static VALUE Descriptor_options(VALUE _self) { return message_options; } +/* + * call-seq: + * Descriptor.to_proto => DescriptorProto + * + * Returns the `DescriptorProto` of this `Descriptor`. + */ +static VALUE Descriptor_to_proto(VALUE _self) { + Descriptor* self = ruby_to_Descriptor(_self); + upb_Arena* arena = upb_Arena_New(); + google_protobuf_DescriptorProto* proto = + upb_MessageDef_ToProto(self->msgdef, arena); + size_t size; + const char* serialized = + google_protobuf_DescriptorProto_serialize(proto, arena, &size); + VALUE proto_class = rb_path2class("Google::Protobuf::DescriptorProto"); + VALUE proto_rb = + Message_decode_bytes(size, serialized, 0, proto_class, false); + upb_Arena_Free(arena); + return proto_rb; +} + static void Descriptor_register(VALUE module) { VALUE klass = rb_define_class_under(module, "Descriptor", rb_cObject); rb_define_alloc_func(klass, Descriptor_alloc); @@ -463,6 +484,7 @@ static void Descriptor_register(VALUE module) { rb_define_method(klass, "name", Descriptor_name, 0); rb_define_method(klass, "file_descriptor", Descriptor_file_descriptor, 0); rb_define_method(klass, "options", Descriptor_options, 0); + rb_define_method(klass, "to_proto", Descriptor_to_proto, 0); rb_include_module(klass, rb_mEnumerable); rb_gc_register_address(&cDescriptor); cDescriptor = klass; @@ -558,12 +580,37 @@ static VALUE FileDescriptor_options(VALUE _self) { return file_options; } +/* + * call-seq: + * FileDescriptor.to_proto => FileDescriptorProto + * + * Returns the `FileDescriptorProto` of this `FileDescriptor`. + */ +static VALUE FileDescriptor_to_proto(VALUE _self) { + FileDescriptor* self = ruby_to_FileDescriptor(_self); + upb_Arena* arena = upb_Arena_New(); + google_protobuf_FileDescriptorProto* file_proto = + upb_FileDef_ToProto(self->filedef, arena); + + size_t size; + const char* serialized = + google_protobuf_FileDescriptorProto_serialize(file_proto, arena, &size); + + VALUE file_proto_class = + rb_path2class("Google::Protobuf::FileDescriptorProto"); + VALUE proto_rb = + Message_decode_bytes(size, serialized, 0, file_proto_class, false); + upb_Arena_Free(arena); + return proto_rb; +} + static void FileDescriptor_register(VALUE module) { VALUE klass = rb_define_class_under(module, "FileDescriptor", rb_cObject); rb_define_alloc_func(klass, FileDescriptor_alloc); rb_define_method(klass, "initialize", FileDescriptor_initialize, 3); rb_define_method(klass, "name", FileDescriptor_name, 0); rb_define_method(klass, "options", FileDescriptor_options, 0); + rb_define_method(klass, "to_proto", FileDescriptor_to_proto, 0); rb_gc_register_address(&cFileDescriptor); cFileDescriptor = klass; } @@ -956,6 +1003,27 @@ static VALUE FieldDescriptor_options(VALUE _self) { return field_options; } +/* + * call-seq: + * FieldDescriptor.to_proto => FieldDescriptorProto + * + * Returns the `FieldDescriptorProto` of this `FieldDescriptor`. + */ +static VALUE FieldDescriptor_to_proto(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + upb_Arena* arena = upb_Arena_New(); + google_protobuf_FieldDescriptorProto* proto = + upb_FieldDef_ToProto(self->fielddef, arena); + size_t size; + const char* serialized = + google_protobuf_FieldDescriptorProto_serialize(proto, arena, &size); + VALUE proto_class = rb_path2class("Google::Protobuf::FieldDescriptorProto"); + VALUE proto_rb = + Message_decode_bytes(size, serialized, 0, proto_class, false); + upb_Arena_Free(arena); + return proto_rb; +} + static void FieldDescriptor_register(VALUE module) { VALUE klass = rb_define_class_under(module, "FieldDescriptor", rb_cObject); rb_define_alloc_func(klass, FieldDescriptor_alloc); @@ -975,6 +1043,7 @@ static void FieldDescriptor_register(VALUE module) { rb_define_method(klass, "get", FieldDescriptor_get, 1); rb_define_method(klass, "set", FieldDescriptor_set, 2); rb_define_method(klass, "options", FieldDescriptor_options, 0); + rb_define_method(klass, "to_proto", FieldDescriptor_to_proto, 0); rb_gc_register_address(&cFieldDescriptor); cFieldDescriptor = klass; } @@ -1093,6 +1162,27 @@ static VALUE OneOfDescriptor_options(VALUE _self) { return oneof_options; } +/* + * call-seq: + * OneofDescriptor.to_proto => OneofDescriptorProto + * + * Returns the `OneofDescriptorProto` of this `OneofDescriptor`. + */ +static VALUE OneOfDescriptor_to_proto(VALUE _self) { + OneofDescriptor* self = ruby_to_OneofDescriptor(_self); + upb_Arena* arena = upb_Arena_New(); + google_protobuf_OneofDescriptorProto* proto = + upb_OneofDef_ToProto(self->oneofdef, arena); + size_t size; + const char* serialized = + google_protobuf_OneofDescriptorProto_serialize(proto, arena, &size); + VALUE proto_class = rb_path2class("Google::Protobuf::OneofDescriptorProto"); + VALUE proto_rb = + Message_decode_bytes(size, serialized, 0, proto_class, false); + upb_Arena_Free(arena); + return proto_rb; +} + static void OneofDescriptor_register(VALUE module) { VALUE klass = rb_define_class_under(module, "OneofDescriptor", rb_cObject); rb_define_alloc_func(klass, OneofDescriptor_alloc); @@ -1100,6 +1190,7 @@ static void OneofDescriptor_register(VALUE module) { rb_define_method(klass, "name", OneofDescriptor_name, 0); rb_define_method(klass, "each", OneofDescriptor_each, 0); rb_define_method(klass, "options", OneOfDescriptor_options, 0); + rb_define_method(klass, "to_proto", OneOfDescriptor_to_proto, 0); rb_include_module(klass, rb_mEnumerable); rb_gc_register_address(&cOneofDescriptor); cOneofDescriptor = klass; @@ -1298,6 +1389,29 @@ static VALUE EnumDescriptor_options(VALUE _self) { return enum_options; } +/* + * call-seq: + * EnumDescriptor.to_proto => EnumDescriptorProto + * + * Returns the `EnumDescriptorProto` of this `EnumDescriptor`. + */ +static VALUE EnumDescriptor_to_proto(VALUE _self) { + EnumDescriptor* self = ruby_to_EnumDescriptor(_self); + upb_Arena* arena = upb_Arena_New(); + google_protobuf_EnumDescriptorProto* proto = + upb_EnumDef_ToProto(self->enumdef, arena); + + size_t size; + const char* serialized = + google_protobuf_EnumDescriptorProto_serialize(proto, arena, &size); + + VALUE proto_class = rb_path2class("Google::Protobuf::EnumDescriptorProto"); + VALUE proto_rb = + Message_decode_bytes(size, serialized, 0, proto_class, false); + upb_Arena_Free(arena); + return proto_rb; +} + static void EnumDescriptor_register(VALUE module) { VALUE klass = rb_define_class_under(module, "EnumDescriptor", rb_cObject); rb_define_alloc_func(klass, EnumDescriptor_alloc); @@ -1310,6 +1424,7 @@ static void EnumDescriptor_register(VALUE module) { rb_define_method(klass, "file_descriptor", EnumDescriptor_file_descriptor, 0); rb_define_method(klass, "is_closed?", EnumDescriptor_is_closed, 0); rb_define_method(klass, "options", EnumDescriptor_options, 0); + rb_define_method(klass, "to_proto", EnumDescriptor_to_proto, 0); rb_include_module(klass, rb_mEnumerable); rb_gc_register_address(&cEnumDescriptor); cEnumDescriptor = klass; @@ -1438,6 +1553,27 @@ static VALUE ServiceDescriptor_options(VALUE _self) { return service_options; } +/* + * call-seq: + * ServiceDescriptor.to_proto => ServiceDescriptorProto + * + * Returns the `ServiceDescriptorProto` of this `ServiceDescriptor`. + */ +static VALUE ServiceDescriptor_to_proto(VALUE _self) { + ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self); + upb_Arena* arena = upb_Arena_New(); + google_protobuf_ServiceDescriptorProto* proto = + upb_ServiceDef_ToProto(self->servicedef, arena); + size_t size; + const char* serialized = + google_protobuf_ServiceDescriptorProto_serialize(proto, arena, &size); + VALUE proto_class = rb_path2class("Google::Protobuf::ServiceDescriptorProto"); + VALUE proto_rb = + Message_decode_bytes(size, serialized, 0, proto_class, false); + upb_Arena_Free(arena); + return proto_rb; +} + static void ServiceDescriptor_register(VALUE module) { VALUE klass = rb_define_class_under(module, "ServiceDescriptor", rb_cObject); rb_define_alloc_func(klass, ServiceDescriptor_alloc); @@ -1447,6 +1583,7 @@ static void ServiceDescriptor_register(VALUE module) { rb_define_method(klass, "file_descriptor", ServiceDescriptor_file_descriptor, 0); rb_define_method(klass, "options", ServiceDescriptor_options, 0); + rb_define_method(klass, "to_proto", ServiceDescriptor_to_proto, 0); rb_include_module(klass, rb_mEnumerable); rb_gc_register_address(&cServiceDescriptor); cServiceDescriptor = klass; @@ -1580,6 +1717,27 @@ static VALUE MethodDescriptor_client_streaming(VALUE _self) { return upb_MethodDef_ClientStreaming(self->methoddef) ? Qtrue : Qfalse; } +/* + * call-seq: + * MethodDescriptor.to_proto => MethodDescriptorProto + * + * Returns the `MethodDescriptorProto` of this `MethodDescriptor`. + */ +static VALUE MethodDescriptor_to_proto(VALUE _self) { + MethodDescriptor* self = ruby_to_MethodDescriptor(_self); + upb_Arena* arena = upb_Arena_New(); + google_protobuf_MethodDescriptorProto* proto = + upb_MethodDef_ToProto(self->methoddef, arena); + size_t size; + const char* serialized = + google_protobuf_MethodDescriptorProto_serialize(proto, arena, &size); + VALUE proto_class = rb_path2class("Google::Protobuf::MethodDescriptorProto"); + VALUE proto_rb = + Message_decode_bytes(size, serialized, 0, proto_class, false); + upb_Arena_Free(arena); + return proto_rb; +} + /* * call-seq: * MethodDescriptor.server_streaming => bool @@ -1603,6 +1761,7 @@ static void MethodDescriptor_register(VALUE module) { 0); rb_define_method(klass, "server_streaming", MethodDescriptor_server_streaming, 0); + rb_define_method(klass, "to_proto", MethodDescriptor_to_proto, 0); rb_gc_register_address(&cMethodDescriptor); cMethodDescriptor = klass; } diff --git a/ruby/ext/google/protobuf_c/glue.c b/ruby/ext/google/protobuf_c/glue.c index 3c84d7fb47555..46e9146347128 100644 --- a/ruby/ext/google/protobuf_c/glue.c +++ b/ruby/ext/google/protobuf_c/glue.c @@ -26,6 +26,15 @@ char* EnumDescriptor_serialized_options(const upb_EnumDef* enumdef, return serialized; } +char* EnumDescriptor_serialized_to_proto(const upb_EnumDef* enumdef, + size_t* size, upb_Arena* arena) { + const google_protobuf_EnumDescriptorProto* file_proto = + upb_EnumDef_ToProto(enumdef, arena); + char* serialized = + google_protobuf_EnumDescriptorProto_serialize(file_proto, arena, size); + return serialized; +} + char* FileDescriptor_serialized_options(const upb_FileDef* filedef, size_t* size, upb_Arena* arena) { const google_protobuf_FileOptions* opts = upb_FileDef_Options(filedef); @@ -33,6 +42,15 @@ char* FileDescriptor_serialized_options(const upb_FileDef* filedef, return serialized; } +char* FileDescriptor_serialized_to_proto(const upb_FileDef* filedef, + size_t* size, upb_Arena* arena) { + const google_protobuf_FileDescriptorProto* file_proto = + upb_FileDef_ToProto(filedef, arena); + char* serialized = + google_protobuf_FileDescriptorProto_serialize(file_proto, arena, size); + return serialized; +} + char* Descriptor_serialized_options(const upb_MessageDef* msgdef, size_t* size, upb_Arena* arena) { const google_protobuf_MessageOptions* opts = upb_MessageDef_Options(msgdef); @@ -41,6 +59,15 @@ char* Descriptor_serialized_options(const upb_MessageDef* msgdef, size_t* size, return serialized; } +char* Descriptor_serialized_to_proto(const upb_MessageDef* msgdef, size_t* size, + upb_Arena* arena) { + const google_protobuf_DescriptorProto* proto = + upb_MessageDef_ToProto(msgdef, arena); + char* serialized = + google_protobuf_DescriptorProto_serialize(proto, arena, size); + return serialized; +} + char* OneOfDescriptor_serialized_options(const upb_OneofDef* oneofdef, size_t* size, upb_Arena* arena) { const google_protobuf_OneofOptions* opts = upb_OneofDef_Options(oneofdef); @@ -48,6 +75,15 @@ char* OneOfDescriptor_serialized_options(const upb_OneofDef* oneofdef, return serialized; } +char* OneOfDescriptor_serialized_to_proto(const upb_OneofDef* oneofdef, + size_t* size, upb_Arena* arena) { + const google_protobuf_OneofDescriptorProto* proto = + upb_OneofDef_ToProto(oneofdef, arena); + char* serialized = + google_protobuf_OneofDescriptorProto_serialize(proto, arena, size); + return serialized; +} + char* FieldDescriptor_serialized_options(const upb_FieldDef* fielddef, size_t* size, upb_Arena* arena) { const google_protobuf_FieldOptions* opts = upb_FieldDef_Options(fielddef); @@ -55,6 +91,15 @@ char* FieldDescriptor_serialized_options(const upb_FieldDef* fielddef, return serialized; } +char* FieldDescriptor_serialized_to_proto(const upb_FieldDef* fieldef, + size_t* size, upb_Arena* arena) { + const google_protobuf_FieldDescriptorProto* proto = + upb_FieldDef_ToProto(fieldef, arena); + char* serialized = + google_protobuf_FieldDescriptorProto_serialize(proto, arena, size); + return serialized; +} + char* ServiceDescriptor_serialized_options(const upb_ServiceDef* servicedef, size_t* size, upb_Arena* arena) { const google_protobuf_ServiceOptions* opts = @@ -64,9 +109,27 @@ char* ServiceDescriptor_serialized_options(const upb_ServiceDef* servicedef, return serialized; } +char* ServiceDescriptor_serialized_to_proto(const upb_ServiceDef* servicedef, + size_t* size, upb_Arena* arena) { + const google_protobuf_ServiceDescriptorProto* proto = + upb_ServiceDef_ToProto(servicedef, arena); + char* serialized = + google_protobuf_ServiceDescriptorProto_serialize(proto, arena, size); + return serialized; +} + char* MethodDescriptor_serialized_options(const upb_MethodDef* methoddef, size_t* size, upb_Arena* arena) { const google_protobuf_MethodOptions* opts = upb_MethodDef_Options(methoddef); char* serialized = google_protobuf_MethodOptions_serialize(opts, arena, size); return serialized; } + +char* MethodDescriptor_serialized_to_proto(const upb_MethodDef* methodef, + size_t* size, upb_Arena* arena) { + const google_protobuf_MethodDescriptorProto* proto = + upb_MethodDef_ToProto(methodef, arena); + char* serialized = + google_protobuf_MethodDescriptorProto_serialize(proto, arena, size); + return serialized; +} \ No newline at end of file diff --git a/ruby/ext/google/protobuf_c/ruby-upb.c b/ruby/ext/google/protobuf_c/ruby-upb.c index 128485432b608..eb2ac74c70e3f 100644 --- a/ruby/ext/google/protobuf_c/ruby-upb.c +++ b/ruby/ext/google/protobuf_c/ruby-upb.c @@ -14896,7 +14896,7 @@ bool upb_FileDef_Resolves(const upb_FileDef* f, const char* path) { return false; } -static char* strviewdup(upb_DefBuilder* ctx, upb_StringView view) { +static char* _strviewdup(upb_DefBuilder* ctx, upb_StringView view) { char* ret = upb_strdup2(view.data, view.size, _upb_DefBuilder_Arena(ctx)); if (!ret) _upb_DefBuilder_OomErr(ctx); return ret; @@ -15025,7 +15025,7 @@ void _upb_FileDef_Create(upb_DefBuilder* ctx, } upb_StringView name = UPB_DESC(FileDescriptorProto_name)(file_proto); - file->name = strviewdup(ctx, name); + file->name = _strviewdup(ctx, name); if (strlen(file->name) != name.size) { _upb_DefBuilder_Errf(ctx, "File name contained embedded NULL"); } @@ -15034,7 +15034,7 @@ void _upb_FileDef_Create(upb_DefBuilder* ctx, if (package.size) { _upb_DefBuilder_CheckIdentFull(ctx, package); - file->package = strviewdup(ctx, package); + file->package = _strviewdup(ctx, package); } else { file->package = NULL; } @@ -17035,6 +17035,671 @@ upb_ServiceDef* _upb_ServiceDefs_New(upb_DefBuilder* ctx, int n, return s; } + +#include +#include + + +// Must be last. + +typedef struct { + upb_Arena* arena; + jmp_buf err; +} upb_ToProto_Context; + +#define CHK_OOM(val) \ + if (!(val)) UPB_LONGJMP(ctx->err, 1); + +// We want to copy the options verbatim into the destination options proto. +// We use serialize+parse as our deep copy. +#define SET_OPTIONS(proto, desc_type, options_type, src) \ + { \ + size_t size; \ + /* MEM: could use a temporary arena here instead. */ \ + char* pb = google_protobuf_##options_type##_serialize(src, ctx->arena, &size); \ + CHK_OOM(pb); \ + google_protobuf_##options_type* dst = \ + google_protobuf_##options_type##_parse(pb, size, ctx->arena); \ + CHK_OOM(dst); \ + google_protobuf_##desc_type##_set_options(proto, dst); \ + } + +static upb_StringView strviewdup2(upb_ToProto_Context* ctx, + upb_StringView str) { + char* p = upb_Arena_Malloc(ctx->arena, str.size); + CHK_OOM(p); + memcpy(p, str.data, str.size); + return (upb_StringView){.data = p, .size = str.size}; +} + +static upb_StringView strviewdup(upb_ToProto_Context* ctx, const char* s) { + return strviewdup2(ctx, (upb_StringView){.data = s, .size = strlen(s)}); +} + +static upb_StringView qual_dup(upb_ToProto_Context* ctx, const char* s) { + size_t n = strlen(s); + char* p = upb_Arena_Malloc(ctx->arena, n + 1); + CHK_OOM(p); + p[0] = '.'; + memcpy(p + 1, s, n); + return (upb_StringView){.data = p, .size = n + 1}; +} + +UPB_PRINTF(2, 3) +static upb_StringView printf_dup(upb_ToProto_Context* ctx, const char* fmt, + ...) { + const size_t max = 32; + char* p = upb_Arena_Malloc(ctx->arena, max); + CHK_OOM(p); + va_list args; + va_start(args, fmt); + size_t n = _upb_vsnprintf(p, max, fmt, args); + va_end(args); + UPB_ASSERT(n < max); + return (upb_StringView){.data = p, .size = n}; +} + +static bool upb_isprint(char ch) { return ch >= 0x20 && ch <= 0x7f; } + +static int special_escape(char ch) { + switch (ch) { + // This is the same set of special escapes recognized by + // absl::CEscape(). + case '\n': + return 'n'; + case '\r': + return 'r'; + case '\t': + return 't'; + case '\\': + return '\\'; + case '\'': + return '\''; + case '"': + return '"'; + default: + return -1; + } +} + +static upb_StringView default_bytes(upb_ToProto_Context* ctx, + upb_StringView val) { + size_t n = 0; + for (size_t i = 0; i < val.size; i++) { + char ch = val.data[i]; + if (special_escape(ch) >= 0) + n += 2; // '\C' + else if (upb_isprint(ch)) + n += 1; + else + n += 4; // '\123' + } + char* p = upb_Arena_Malloc(ctx->arena, n); + CHK_OOM(p); + char* dst = p; + const char* src = val.data; + const char* end = src + val.size; + while (src < end) { + unsigned char ch = *src++; + if (special_escape(ch) >= 0) { + *dst++ = '\\'; + *dst++ = (char)special_escape(ch); + } else if (upb_isprint(ch)) { + *dst++ = ch; + } else { + *dst++ = '\\'; + *dst++ = '0' + (ch >> 6); + *dst++ = '0' + ((ch >> 3) & 0x7); + *dst++ = '0' + (ch & 0x7); + } + } + return (upb_StringView){.data = p, .size = n}; +} + +static upb_StringView default_string(upb_ToProto_Context* ctx, + const upb_FieldDef* f) { + upb_MessageValue d = upb_FieldDef_Default(f); + upb_CType type = upb_FieldDef_CType(f); + + if (type == kUpb_CType_Float || type == kUpb_CType_Double) { + double val = type == kUpb_CType_Float ? d.float_val : d.double_val; + if (val == INFINITY) { + return strviewdup(ctx, "inf"); + } else if (val == -INFINITY) { + return strviewdup(ctx, "-inf"); + } else if (val != val) { + return strviewdup(ctx, "nan"); + } + } + + switch (upb_FieldDef_CType(f)) { + case kUpb_CType_Bool: + return strviewdup(ctx, d.bool_val ? "true" : "false"); + case kUpb_CType_Enum: { + const upb_EnumDef* e = upb_FieldDef_EnumSubDef(f); + const upb_EnumValueDef* ev = + upb_EnumDef_FindValueByNumber(e, d.int32_val); + return strviewdup(ctx, upb_EnumValueDef_Name(ev)); + } + case kUpb_CType_Int64: + return printf_dup(ctx, "%" PRId64, d.int64_val); + case kUpb_CType_UInt64: + return printf_dup(ctx, "%" PRIu64, d.uint64_val); + case kUpb_CType_Int32: + return printf_dup(ctx, "%" PRId32, d.int32_val); + case kUpb_CType_UInt32: + return printf_dup(ctx, "%" PRIu32, d.uint32_val); + case kUpb_CType_Float: + return printf_dup(ctx, "%.9g", d.float_val); + case kUpb_CType_Double: + return printf_dup(ctx, "%.17g", d.double_val); + case kUpb_CType_String: + return strviewdup2(ctx, d.str_val); + case kUpb_CType_Bytes: + return default_bytes(ctx, d.str_val); + default: + UPB_UNREACHABLE(); + } +} + +static google_protobuf_DescriptorProto_ReservedRange* resrange_toproto( + upb_ToProto_Context* ctx, const upb_MessageReservedRange* r) { + google_protobuf_DescriptorProto_ReservedRange* proto = + google_protobuf_DescriptorProto_ReservedRange_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_DescriptorProto_ReservedRange_set_start( + proto, upb_MessageReservedRange_Start(r)); + google_protobuf_DescriptorProto_ReservedRange_set_end(proto, + upb_MessageReservedRange_End(r)); + + return proto; +} + +static google_protobuf_EnumDescriptorProto_EnumReservedRange* enumresrange_toproto( + upb_ToProto_Context* ctx, const upb_EnumReservedRange* r) { + google_protobuf_EnumDescriptorProto_EnumReservedRange* proto = + google_protobuf_EnumDescriptorProto_EnumReservedRange_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_EnumDescriptorProto_EnumReservedRange_set_start( + proto, upb_EnumReservedRange_Start(r)); + google_protobuf_EnumDescriptorProto_EnumReservedRange_set_end( + proto, upb_EnumReservedRange_End(r)); + + return proto; +} + +static google_protobuf_FieldDescriptorProto* fielddef_toproto(upb_ToProto_Context* ctx, + const upb_FieldDef* f) { + google_protobuf_FieldDescriptorProto* proto = + google_protobuf_FieldDescriptorProto_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_FieldDescriptorProto_set_name(proto, + strviewdup(ctx, upb_FieldDef_Name(f))); + google_protobuf_FieldDescriptorProto_set_number(proto, upb_FieldDef_Number(f)); + + if (upb_FieldDef_IsRequired(f) && + upb_FileDef_Edition(upb_FieldDef_File(f)) >= UPB_DESC(EDITION_2023)) { + google_protobuf_FieldDescriptorProto_set_label( + proto, UPB_DESC(FieldDescriptorProto_LABEL_OPTIONAL)); + } else { + google_protobuf_FieldDescriptorProto_set_label(proto, upb_FieldDef_Label(f)); + } + if (upb_FieldDef_Type(f) == kUpb_FieldType_Group && + upb_FileDef_Edition(upb_FieldDef_File(f)) >= UPB_DESC(EDITION_2023)) { + google_protobuf_FieldDescriptorProto_set_type(proto, kUpb_FieldType_Message); + } else { + google_protobuf_FieldDescriptorProto_set_type(proto, upb_FieldDef_Type(f)); + } + + if (upb_FieldDef_HasJsonName(f)) { + google_protobuf_FieldDescriptorProto_set_json_name( + proto, strviewdup(ctx, upb_FieldDef_JsonName(f))); + } + + if (upb_FieldDef_IsSubMessage(f)) { + google_protobuf_FieldDescriptorProto_set_type_name( + proto, + qual_dup(ctx, upb_MessageDef_FullName(upb_FieldDef_MessageSubDef(f)))); + } else if (upb_FieldDef_CType(f) == kUpb_CType_Enum) { + google_protobuf_FieldDescriptorProto_set_type_name( + proto, qual_dup(ctx, upb_EnumDef_FullName(upb_FieldDef_EnumSubDef(f)))); + } + + if (upb_FieldDef_IsExtension(f)) { + google_protobuf_FieldDescriptorProto_set_extendee( + proto, + qual_dup(ctx, upb_MessageDef_FullName(upb_FieldDef_ContainingType(f)))); + } + + if (upb_FieldDef_HasDefault(f)) { + google_protobuf_FieldDescriptorProto_set_default_value(proto, + default_string(ctx, f)); + } + + const upb_OneofDef* o = upb_FieldDef_ContainingOneof(f); + if (o) { + google_protobuf_FieldDescriptorProto_set_oneof_index(proto, upb_OneofDef_Index(o)); + } + + if (_upb_FieldDef_IsProto3Optional(f)) { + google_protobuf_FieldDescriptorProto_set_proto3_optional(proto, true); + } + + if (upb_FieldDef_HasOptions(f)) { + SET_OPTIONS(proto, FieldDescriptorProto, FieldOptions, + upb_FieldDef_Options(f)); + } + + return proto; +} + +static google_protobuf_OneofDescriptorProto* oneofdef_toproto(upb_ToProto_Context* ctx, + const upb_OneofDef* o) { + google_protobuf_OneofDescriptorProto* proto = + google_protobuf_OneofDescriptorProto_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_OneofDescriptorProto_set_name(proto, + strviewdup(ctx, upb_OneofDef_Name(o))); + + if (upb_OneofDef_HasOptions(o)) { + SET_OPTIONS(proto, OneofDescriptorProto, OneofOptions, + upb_OneofDef_Options(o)); + } + + return proto; +} + +static google_protobuf_EnumValueDescriptorProto* enumvaldef_toproto( + upb_ToProto_Context* ctx, const upb_EnumValueDef* e) { + google_protobuf_EnumValueDescriptorProto* proto = + google_protobuf_EnumValueDescriptorProto_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_EnumValueDescriptorProto_set_name( + proto, strviewdup(ctx, upb_EnumValueDef_Name(e))); + google_protobuf_EnumValueDescriptorProto_set_number(proto, upb_EnumValueDef_Number(e)); + + if (upb_EnumValueDef_HasOptions(e)) { + SET_OPTIONS(proto, EnumValueDescriptorProto, EnumValueOptions, + upb_EnumValueDef_Options(e)); + } + + return proto; +} + +static google_protobuf_EnumDescriptorProto* enumdef_toproto(upb_ToProto_Context* ctx, + const upb_EnumDef* e) { + google_protobuf_EnumDescriptorProto* proto = + google_protobuf_EnumDescriptorProto_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_EnumDescriptorProto_set_name(proto, + strviewdup(ctx, upb_EnumDef_Name(e))); + + int n = upb_EnumDef_ValueCount(e); + google_protobuf_EnumValueDescriptorProto** vals = + google_protobuf_EnumDescriptorProto_resize_value(proto, n, ctx->arena); + CHK_OOM(vals); + for (int i = 0; i < n; i++) { + vals[i] = enumvaldef_toproto(ctx, upb_EnumDef_Value(e, i)); + } + + n = upb_EnumDef_ReservedRangeCount(e); + google_protobuf_EnumDescriptorProto_EnumReservedRange** res_ranges = + google_protobuf_EnumDescriptorProto_resize_reserved_range(proto, n, ctx->arena); + for (int i = 0; i < n; i++) { + res_ranges[i] = enumresrange_toproto(ctx, upb_EnumDef_ReservedRange(e, i)); + } + + n = upb_EnumDef_ReservedNameCount(e); + upb_StringView* res_names = + google_protobuf_EnumDescriptorProto_resize_reserved_name(proto, n, ctx->arena); + for (int i = 0; i < n; i++) { + res_names[i] = upb_EnumDef_ReservedName(e, i); + } + + if (upb_EnumDef_HasOptions(e)) { + SET_OPTIONS(proto, EnumDescriptorProto, EnumOptions, + upb_EnumDef_Options(e)); + } + + return proto; +} + +static google_protobuf_DescriptorProto_ExtensionRange* extrange_toproto( + upb_ToProto_Context* ctx, const upb_ExtensionRange* e) { + google_protobuf_DescriptorProto_ExtensionRange* proto = + google_protobuf_DescriptorProto_ExtensionRange_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_DescriptorProto_ExtensionRange_set_start(proto, + upb_ExtensionRange_Start(e)); + google_protobuf_DescriptorProto_ExtensionRange_set_end(proto, + upb_ExtensionRange_End(e)); + + if (upb_ExtensionRange_HasOptions(e)) { + SET_OPTIONS(proto, DescriptorProto_ExtensionRange, ExtensionRangeOptions, + upb_ExtensionRange_Options(e)); + } + + return proto; +} + +static google_protobuf_DescriptorProto* msgdef_toproto(upb_ToProto_Context* ctx, + const upb_MessageDef* m) { + google_protobuf_DescriptorProto* proto = google_protobuf_DescriptorProto_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_DescriptorProto_set_name(proto, + strviewdup(ctx, upb_MessageDef_Name(m))); + + int n; + + n = upb_MessageDef_FieldCount(m); + google_protobuf_FieldDescriptorProto** fields = + google_protobuf_DescriptorProto_resize_field(proto, n, ctx->arena); + CHK_OOM(fields); + for (int i = 0; i < n; i++) { + fields[i] = fielddef_toproto(ctx, upb_MessageDef_Field(m, i)); + } + + n = upb_MessageDef_OneofCount(m); + google_protobuf_OneofDescriptorProto** oneofs = + google_protobuf_DescriptorProto_resize_oneof_decl(proto, n, ctx->arena); + for (int i = 0; i < n; i++) { + oneofs[i] = oneofdef_toproto(ctx, upb_MessageDef_Oneof(m, i)); + } + + n = upb_MessageDef_NestedMessageCount(m); + google_protobuf_DescriptorProto** nested_msgs = + google_protobuf_DescriptorProto_resize_nested_type(proto, n, ctx->arena); + for (int i = 0; i < n; i++) { + nested_msgs[i] = msgdef_toproto(ctx, upb_MessageDef_NestedMessage(m, i)); + } + + n = upb_MessageDef_NestedEnumCount(m); + google_protobuf_EnumDescriptorProto** nested_enums = + google_protobuf_DescriptorProto_resize_enum_type(proto, n, ctx->arena); + for (int i = 0; i < n; i++) { + nested_enums[i] = enumdef_toproto(ctx, upb_MessageDef_NestedEnum(m, i)); + } + + n = upb_MessageDef_NestedExtensionCount(m); + google_protobuf_FieldDescriptorProto** nested_exts = + google_protobuf_DescriptorProto_resize_extension(proto, n, ctx->arena); + for (int i = 0; i < n; i++) { + nested_exts[i] = + fielddef_toproto(ctx, upb_MessageDef_NestedExtension(m, i)); + } + + n = upb_MessageDef_ExtensionRangeCount(m); + google_protobuf_DescriptorProto_ExtensionRange** ext_ranges = + google_protobuf_DescriptorProto_resize_extension_range(proto, n, ctx->arena); + for (int i = 0; i < n; i++) { + ext_ranges[i] = extrange_toproto(ctx, upb_MessageDef_ExtensionRange(m, i)); + } + + n = upb_MessageDef_ReservedRangeCount(m); + google_protobuf_DescriptorProto_ReservedRange** res_ranges = + google_protobuf_DescriptorProto_resize_reserved_range(proto, n, ctx->arena); + for (int i = 0; i < n; i++) { + res_ranges[i] = resrange_toproto(ctx, upb_MessageDef_ReservedRange(m, i)); + } + + n = upb_MessageDef_ReservedNameCount(m); + upb_StringView* res_names = + google_protobuf_DescriptorProto_resize_reserved_name(proto, n, ctx->arena); + for (int i = 0; i < n; i++) { + res_names[i] = upb_MessageDef_ReservedName(m, i); + } + + if (upb_MessageDef_HasOptions(m)) { + SET_OPTIONS(proto, DescriptorProto, MessageOptions, + upb_MessageDef_Options(m)); + } + + return proto; +} + +static google_protobuf_MethodDescriptorProto* methoddef_toproto(upb_ToProto_Context* ctx, + const upb_MethodDef* m) { + google_protobuf_MethodDescriptorProto* proto = + google_protobuf_MethodDescriptorProto_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_MethodDescriptorProto_set_name(proto, + strviewdup(ctx, upb_MethodDef_Name(m))); + + google_protobuf_MethodDescriptorProto_set_input_type( + proto, + qual_dup(ctx, upb_MessageDef_FullName(upb_MethodDef_InputType(m)))); + google_protobuf_MethodDescriptorProto_set_output_type( + proto, + qual_dup(ctx, upb_MessageDef_FullName(upb_MethodDef_OutputType(m)))); + + if (upb_MethodDef_ClientStreaming(m)) { + google_protobuf_MethodDescriptorProto_set_client_streaming(proto, true); + } + + if (upb_MethodDef_ServerStreaming(m)) { + google_protobuf_MethodDescriptorProto_set_server_streaming(proto, true); + } + + if (upb_MethodDef_HasOptions(m)) { + SET_OPTIONS(proto, MethodDescriptorProto, MethodOptions, + upb_MethodDef_Options(m)); + } + + return proto; +} + +static google_protobuf_ServiceDescriptorProto* servicedef_toproto( + upb_ToProto_Context* ctx, const upb_ServiceDef* s) { + google_protobuf_ServiceDescriptorProto* proto = + google_protobuf_ServiceDescriptorProto_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_ServiceDescriptorProto_set_name( + proto, strviewdup(ctx, upb_ServiceDef_Name(s))); + + size_t n = upb_ServiceDef_MethodCount(s); + google_protobuf_MethodDescriptorProto** methods = + google_protobuf_ServiceDescriptorProto_resize_method(proto, n, ctx->arena); + for (size_t i = 0; i < n; i++) { + methods[i] = methoddef_toproto(ctx, upb_ServiceDef_Method(s, i)); + } + + if (upb_ServiceDef_HasOptions(s)) { + SET_OPTIONS(proto, ServiceDescriptorProto, ServiceOptions, + upb_ServiceDef_Options(s)); + } + + return proto; +} + +static google_protobuf_FileDescriptorProto* filedef_toproto(upb_ToProto_Context* ctx, + const upb_FileDef* f) { + google_protobuf_FileDescriptorProto* proto = + google_protobuf_FileDescriptorProto_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_FileDescriptorProto_set_name(proto, + strviewdup(ctx, upb_FileDef_Name(f))); + + const char* package = upb_FileDef_Package(f); + if (package) { + size_t n = strlen(package); + if (n) { + google_protobuf_FileDescriptorProto_set_package(proto, strviewdup(ctx, package)); + } + } + + if (upb_FileDef_Syntax(f) == kUpb_Syntax_Editions) { + google_protobuf_FileDescriptorProto_set_edition(proto, upb_FileDef_Edition(f)); + } + + if (upb_FileDef_Syntax(f) == kUpb_Syntax_Proto3) { + google_protobuf_FileDescriptorProto_set_syntax(proto, strviewdup(ctx, "proto3")); + } else if (upb_FileDef_Syntax(f) == kUpb_Syntax_Editions) { + google_protobuf_FileDescriptorProto_set_syntax(proto, strviewdup(ctx, "editions")); + } + + size_t n; + n = upb_FileDef_DependencyCount(f); + upb_StringView* deps = + google_protobuf_FileDescriptorProto_resize_dependency(proto, n, ctx->arena); + for (size_t i = 0; i < n; i++) { + deps[i] = strviewdup(ctx, upb_FileDef_Name(upb_FileDef_Dependency(f, i))); + } + + n = upb_FileDef_PublicDependencyCount(f); + int32_t* public_deps = + google_protobuf_FileDescriptorProto_resize_public_dependency(proto, n, ctx->arena); + const int32_t* public_dep_nums = _upb_FileDef_PublicDependencyIndexes(f); + if (n) memcpy(public_deps, public_dep_nums, n * sizeof(int32_t)); + + n = upb_FileDef_WeakDependencyCount(f); + int32_t* weak_deps = + google_protobuf_FileDescriptorProto_resize_weak_dependency(proto, n, ctx->arena); + const int32_t* weak_dep_nums = _upb_FileDef_WeakDependencyIndexes(f); + if (n) memcpy(weak_deps, weak_dep_nums, n * sizeof(int32_t)); + + n = upb_FileDef_TopLevelMessageCount(f); + google_protobuf_DescriptorProto** msgs = + google_protobuf_FileDescriptorProto_resize_message_type(proto, n, ctx->arena); + for (size_t i = 0; i < n; i++) { + msgs[i] = msgdef_toproto(ctx, upb_FileDef_TopLevelMessage(f, i)); + } + + n = upb_FileDef_TopLevelEnumCount(f); + google_protobuf_EnumDescriptorProto** enums = + google_protobuf_FileDescriptorProto_resize_enum_type(proto, n, ctx->arena); + for (size_t i = 0; i < n; i++) { + enums[i] = enumdef_toproto(ctx, upb_FileDef_TopLevelEnum(f, i)); + } + + n = upb_FileDef_ServiceCount(f); + google_protobuf_ServiceDescriptorProto** services = + google_protobuf_FileDescriptorProto_resize_service(proto, n, ctx->arena); + for (size_t i = 0; i < n; i++) { + services[i] = servicedef_toproto(ctx, upb_FileDef_Service(f, i)); + } + + n = upb_FileDef_TopLevelExtensionCount(f); + google_protobuf_FieldDescriptorProto** exts = + google_protobuf_FileDescriptorProto_resize_extension(proto, n, ctx->arena); + for (size_t i = 0; i < n; i++) { + exts[i] = fielddef_toproto(ctx, upb_FileDef_TopLevelExtension(f, i)); + } + + if (upb_FileDef_HasOptions(f)) { + SET_OPTIONS(proto, FileDescriptorProto, FileOptions, + upb_FileDef_Options(f)); + } + + return proto; +} + +static google_protobuf_DescriptorProto* upb_ToProto_ConvertMessageDef( + upb_ToProto_Context* const ctx, const upb_MessageDef* const m) { + if (UPB_SETJMP(ctx->err)) return NULL; + return msgdef_toproto(ctx, m); +} + +google_protobuf_DescriptorProto* upb_MessageDef_ToProto(const upb_MessageDef* m, + upb_Arena* a) { + upb_ToProto_Context ctx = {a}; + return upb_ToProto_ConvertMessageDef(&ctx, m); +} + +google_protobuf_EnumDescriptorProto* upb_ToProto_ConvertEnumDef( + upb_ToProto_Context* const ctx, const upb_EnumDef* const e) { + if (UPB_SETJMP(ctx->err)) return NULL; + return enumdef_toproto(ctx, e); +} + +google_protobuf_EnumDescriptorProto* upb_EnumDef_ToProto(const upb_EnumDef* e, + upb_Arena* a) { + upb_ToProto_Context ctx = {a}; + return upb_ToProto_ConvertEnumDef(&ctx, e); +} + +google_protobuf_EnumValueDescriptorProto* upb_ToProto_ConvertEnumValueDef( + upb_ToProto_Context* const ctx, const upb_EnumValueDef* e) { + if (UPB_SETJMP(ctx->err)) return NULL; + return enumvaldef_toproto(ctx, e); +} + +google_protobuf_EnumValueDescriptorProto* upb_EnumValueDef_ToProto( + const upb_EnumValueDef* e, upb_Arena* a) { + upb_ToProto_Context ctx = {a}; + return upb_ToProto_ConvertEnumValueDef(&ctx, e); +} + +google_protobuf_FieldDescriptorProto* upb_ToProto_ConvertFieldDef( + upb_ToProto_Context* const ctx, const upb_FieldDef* f) { + if (UPB_SETJMP(ctx->err)) return NULL; + return fielddef_toproto(ctx, f); +} + +google_protobuf_FieldDescriptorProto* upb_FieldDef_ToProto(const upb_FieldDef* f, + upb_Arena* a) { + upb_ToProto_Context ctx = {a}; + return upb_ToProto_ConvertFieldDef(&ctx, f); +} + +google_protobuf_OneofDescriptorProto* upb_ToProto_ConvertOneofDef( + upb_ToProto_Context* const ctx, const upb_OneofDef* o) { + if (UPB_SETJMP(ctx->err)) return NULL; + return oneofdef_toproto(ctx, o); +} + +google_protobuf_OneofDescriptorProto* upb_OneofDef_ToProto(const upb_OneofDef* o, + upb_Arena* a) { + upb_ToProto_Context ctx = {a}; + return upb_ToProto_ConvertOneofDef(&ctx, o); +} + +google_protobuf_FileDescriptorProto* upb_ToProto_ConvertFileDef( + upb_ToProto_Context* const ctx, const upb_FileDef* const f) { + if (UPB_SETJMP(ctx->err)) return NULL; + return filedef_toproto(ctx, f); +} + +google_protobuf_FileDescriptorProto* upb_FileDef_ToProto(const upb_FileDef* f, + upb_Arena* a) { + upb_ToProto_Context ctx = {a}; + return upb_ToProto_ConvertFileDef(&ctx, f); +} + +google_protobuf_MethodDescriptorProto* upb_ToProto_ConvertMethodDef( + upb_ToProto_Context* const ctx, const upb_MethodDef* m) { + if (UPB_SETJMP(ctx->err)) return NULL; + return methoddef_toproto(ctx, m); +} + +google_protobuf_MethodDescriptorProto* upb_MethodDef_ToProto( + const upb_MethodDef* const m, upb_Arena* a) { + upb_ToProto_Context ctx = {a}; + return upb_ToProto_ConvertMethodDef(&ctx, m); +} + +google_protobuf_ServiceDescriptorProto* upb_ToProto_ConvertServiceDef( + upb_ToProto_Context* const ctx, const upb_ServiceDef* const s) { + if (UPB_SETJMP(ctx->err)) return NULL; + return servicedef_toproto(ctx, s); +} + +google_protobuf_ServiceDescriptorProto* upb_ServiceDef_ToProto(const upb_ServiceDef* s, + upb_Arena* a) { + upb_ToProto_Context ctx = {a}; + return upb_ToProto_ConvertServiceDef(&ctx, s); +} + // This should #undef all macros #defined in def.inc #undef UPB_SIZE diff --git a/ruby/ext/google/protobuf_c/ruby-upb.h b/ruby/ext/google/protobuf_c/ruby-upb.h index 2ea940c0bf25c..f2e37583e8fdd 100755 --- a/ruby/ext/google/protobuf_c/ruby-upb.h +++ b/ruby/ext/google/protobuf_c/ruby-upb.h @@ -15809,6 +15809,41 @@ upb_MethodDef* _upb_MethodDefs_New(upb_DefBuilder* ctx, int n, #endif /* UPB_REFLECTION_METHOD_DEF_INTERNAL_H_ */ +#ifndef UPB_UTIL_DEF_TO_PROTO_H_ +#define UPB_UTIL_DEF_TO_PROTO_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +// Functions for converting defs back to the equivalent descriptor proto. +// Ultimately the goal is that a round-trip proto->def->proto is lossless. Each +// function returns a new proto created in arena `a`, or NULL if memory +// allocation failed. +google_protobuf_DescriptorProto* upb_MessageDef_ToProto(const upb_MessageDef* m, + upb_Arena* a); +google_protobuf_EnumDescriptorProto* upb_EnumDef_ToProto(const upb_EnumDef* e, + upb_Arena* a); +google_protobuf_EnumValueDescriptorProto* upb_EnumValueDef_ToProto( + const upb_EnumValueDef* e, upb_Arena* a); +google_protobuf_FieldDescriptorProto* upb_FieldDef_ToProto( + const upb_FieldDef* f, upb_Arena* a); +google_protobuf_OneofDescriptorProto* upb_OneofDef_ToProto( + const upb_OneofDef* o, upb_Arena* a); +google_protobuf_FileDescriptorProto* upb_FileDef_ToProto(const upb_FileDef* f, + upb_Arena* a); +google_protobuf_MethodDescriptorProto* upb_MethodDef_ToProto( + const upb_MethodDef* m, upb_Arena* a); +google_protobuf_ServiceDescriptorProto* upb_ServiceDef_ToProto( + const upb_ServiceDef* s, upb_Arena* a); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* UPB_UTIL_DEF_TO_PROTO_H_ */ + // This should #undef all macros #defined in def.inc #undef UPB_SIZE diff --git a/ruby/lib/google/protobuf/ffi/descriptor.rb b/ruby/lib/google/protobuf/ffi/descriptor.rb index ee52a5cbe8819..c30da20b409c3 100644 --- a/ruby/lib/google/protobuf/ffi/descriptor.rb +++ b/ruby/lib/google/protobuf/ffi/descriptor.rb @@ -106,6 +106,15 @@ def options end end + def to_proto + @to_proto ||= begin + size_ptr = ::FFI::MemoryPointer.new(:size_t, 1) + temporary_arena = Google::Protobuf::FFI.create_arena + buffer = Google::Protobuf::FFI.message_to_proto(self, size_ptr, temporary_arena) + Google::Protobuf::DescriptorProto.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze) + end + end + private extend Google::Protobuf::Internal::Convert @@ -160,6 +169,7 @@ class FFI attach_function :message_options, :Descriptor_serialized_options, [Descriptor, :pointer, Internal::Arena], :pointer attach_function :get_well_known_type, :upb_MessageDef_WellKnownType, [Descriptor], WellKnown attach_function :find_msg_def_by_name, :upb_MessageDef_FindByNameWithSize, [Descriptor, :string, :size_t, :FieldDefPointer, :OneofDefPointer], :bool + attach_function :message_to_proto, :Descriptor_serialized_to_proto, [Descriptor, :pointer, Internal::Arena], :pointer end end end diff --git a/ruby/lib/google/protobuf/ffi/enum_descriptor.rb b/ruby/lib/google/protobuf/ffi/enum_descriptor.rb index e7ce04dab0abb..f95e0915ee0d0 100644 --- a/ruby/lib/google/protobuf/ffi/enum_descriptor.rb +++ b/ruby/lib/google/protobuf/ffi/enum_descriptor.rb @@ -90,6 +90,15 @@ def options end end + def to_proto + @to_proto ||= begin + size_ptr = ::FFI::MemoryPointer.new(:size_t, 1) + temporary_arena = Google::Protobuf::FFI.create_arena + buffer = Google::Protobuf::FFI.enum_to_proto(self, size_ptr, temporary_arena) + Google::Protobuf::EnumDescriptorProto.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze) + end + end + private def initialize(enum_def, descriptor_pool) @@ -164,6 +173,7 @@ class FFI attach_function :enum_value_by_number, :upb_EnumDef_FindValueByNumber, [EnumDescriptor, :int], :EnumValueDef attach_function :get_enum_fullname, :upb_EnumDef_FullName, [EnumDescriptor], :string attach_function :enum_options, :EnumDescriptor_serialized_options, [EnumDescriptor, :pointer, Internal::Arena], :pointer + attach_function :enum_to_proto, :EnumDescriptor_serialized_to_proto, [EnumDescriptor, :pointer, Internal::Arena], :pointer attach_function :enum_value_by_index, :upb_EnumDef_Value, [EnumDescriptor, :int], :EnumValueDef attach_function :enum_value_count, :upb_EnumDef_ValueCount, [EnumDescriptor], :int attach_function :enum_name, :upb_EnumValueDef_Name, [:EnumValueDef], :string diff --git a/ruby/lib/google/protobuf/ffi/field_descriptor.rb b/ruby/lib/google/protobuf/ffi/field_descriptor.rb index 632692b75db94..5d6bfa48f19f4 100644 --- a/ruby/lib/google/protobuf/ffi/field_descriptor.rb +++ b/ruby/lib/google/protobuf/ffi/field_descriptor.rb @@ -225,6 +225,15 @@ def options end end + def to_proto + @to_proto ||= begin + size_ptr = ::FFI::MemoryPointer.new(:size_t, 1) + temporary_arena = Google::Protobuf::FFI.create_arena + buffer = Google::Protobuf::FFI.field_to_proto(self, size_ptr, temporary_arena) + Google::Protobuf::FieldDescriptorProto.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze) + end + end + private def initialize(field_def, descriptor_pool) @@ -325,6 +334,7 @@ class FFI attach_function :get_number, :upb_FieldDef_Number, [FieldDescriptor], :uint32_t attach_function :get_type, :upb_FieldDef_Type, [FieldDescriptor], FieldType attach_function :file_def_by_raw_field_def, :upb_FieldDef_File, [:pointer], :FileDef + attach_function :field_to_proto, :FieldDescriptor_serialized_to_proto,[FieldDescriptor, :pointer, Internal::Arena], :pointer end end end diff --git a/ruby/lib/google/protobuf/ffi/file_descriptor.rb b/ruby/lib/google/protobuf/ffi/file_descriptor.rb index 2a7bf87e6d39b..7c3de9f1756c2 100644 --- a/ruby/lib/google/protobuf/ffi/file_descriptor.rb +++ b/ruby/lib/google/protobuf/ffi/file_descriptor.rb @@ -12,6 +12,7 @@ class FFI attach_function :file_def_name, :upb_FileDef_Name, [:FileDef], :string attach_function :file_def_pool, :upb_FileDef_Pool, [:FileDef], :DefPool attach_function :file_options, :FileDescriptor_serialized_options, [:FileDef, :pointer, Internal::Arena], :pointer + attach_function :file_to_proto, :FileDescriptor_serialized_to_proto, [:FileDef, :pointer, Internal::Arena], :pointer end class FileDescriptor @@ -44,6 +45,15 @@ def options opts.freeze end end + + def to_proto + @to_proto ||= begin + size_ptr = ::FFI::MemoryPointer.new(:size_t, 1) + temporary_arena = Google::Protobuf::FFI.create_arena + buffer = Google::Protobuf::FFI.file_to_proto(@file_def, size_ptr, temporary_arena) + Google::Protobuf::FileDescriptorProto.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze) + end + end end end end diff --git a/ruby/lib/google/protobuf/ffi/method_descriptor.rb b/ruby/lib/google/protobuf/ffi/method_descriptor.rb index b7bbf0af08747..f879d49c070f7 100644 --- a/ruby/lib/google/protobuf/ffi/method_descriptor.rb +++ b/ruby/lib/google/protobuf/ffi/method_descriptor.rb @@ -7,7 +7,7 @@ module Google module Protobuf - class MethodDescriptor + class MethodDescriptor attr :method_def, :descriptor_pool include Google::Protobuf::Internal::Convert @@ -81,6 +81,15 @@ def server_streaming @server_streaming ||= Google::Protobuf::FFI.method_server_streaming(self) end + def to_proto + @to_proto ||= begin + size_ptr = ::FFI::MemoryPointer.new(:size_t, 1) + temporary_arena = Google::Protobuf::FFI.create_arena + buffer = Google::Protobuf::FFI.method_to_proto(self, size_ptr, temporary_arena) + Google::Protobuf::MethodDescriptorProto.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze) + end + end + private def initialize(method_def, descriptor_pool) @@ -108,6 +117,7 @@ class FFI attach_function :method_output_type, :upb_MethodDef_OutputType, [MethodDescriptor], Descriptor attach_function :method_client_streaming, :upb_MethodDef_ClientStreaming, [MethodDescriptor], :bool attach_function :method_server_streaming, :upb_MethodDef_ServerStreaming, [MethodDescriptor], :bool + attach_function :method_to_proto, :MethodDescriptor_serialized_to_proto, [MethodDescriptor, :pointer, Internal::Arena], :pointer end end end diff --git a/ruby/lib/google/protobuf/ffi/oneof_descriptor.rb b/ruby/lib/google/protobuf/ffi/oneof_descriptor.rb index 65050ef0acb69..3733900c499c6 100644 --- a/ruby/lib/google/protobuf/ffi/oneof_descriptor.rb +++ b/ruby/lib/google/protobuf/ffi/oneof_descriptor.rb @@ -64,6 +64,15 @@ def options end end + def to_proto + @to_proto ||= begin + size_ptr = ::FFI::MemoryPointer.new(:size_t, 1) + temporary_arena = Google::Protobuf::FFI.create_arena + buffer = Google::Protobuf::FFI.oneof_to_proto(self, size_ptr, temporary_arena) + Google::Protobuf::OneofDescriptorProto.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze) + end + end + private def initialize(oneof_def, descriptor_pool) @@ -89,6 +98,7 @@ class FFI attach_function :get_oneof_field_by_index, :upb_OneofDef_Field, [OneofDescriptor, :int], FieldDescriptor attach_function :get_oneof_containing_type,:upb_OneofDef_ContainingType, [:pointer], Descriptor attach_function :oneof_options, :OneOfDescriptor_serialized_options, [OneofDescriptor, :pointer, Internal::Arena], :pointer + attach_function :oneof_to_proto, :OneOfDescriptor_serialized_to_proto, [OneofDescriptor, :pointer, Internal::Arena], :pointer # FieldDescriptor attach_function :real_containing_oneof, :upb_FieldDef_RealContainingOneof, [FieldDescriptor], OneofDescriptor diff --git a/ruby/lib/google/protobuf/ffi/service_descriptor.rb b/ruby/lib/google/protobuf/ffi/service_descriptor.rb index d8554d379d6d0..72fd679c51f6a 100644 --- a/ruby/lib/google/protobuf/ffi/service_descriptor.rb +++ b/ruby/lib/google/protobuf/ffi/service_descriptor.rb @@ -77,10 +77,19 @@ def options end end + def to_proto + @to_proto ||= begin + size_ptr = ::FFI::MemoryPointer.new(:size_t, 1) + temporary_arena = Google::Protobuf::FFI.create_arena + buffer = Google::Protobuf::FFI.service_to_proto(self, size_ptr, temporary_arena) + Google::Protobuf::ServiceDescriptorProto.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze) + end + end + private def initialize(service_def, descriptor_pool) - @service_def = service_def + @service_def = service_def @descriptor_pool = descriptor_pool end @@ -102,6 +111,7 @@ class FFI attach_function :method_count, :upb_ServiceDef_MethodCount, [ServiceDescriptor], :int attach_function :get_method_by_index, :upb_ServiceDef_Method, [ServiceDescriptor, :int], MethodDescriptor attach_function :service_options, :ServiceDescriptor_serialized_options, [ServiceDescriptor, :pointer, Internal::Arena], :pointer + attach_function :service_to_proto, :ServiceDescriptor_serialized_to_proto, [ServiceDescriptor, :pointer, Internal::Arena], :pointer end end end diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyDescriptor.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyDescriptor.java index aa64d1a5e74f2..b41450c97ff12 100644 --- a/ruby/src/main/java/com/google/protobuf/jruby/RubyDescriptor.java +++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyDescriptor.java @@ -175,6 +175,27 @@ public IRubyObject options(ThreadContext context) { true); } + /* + * call-seq: + * Descriptor.to_proto => DescriptorProto + * + * Returns the `DescriptorProto` of this `Descriptor`. + */ + @JRubyMethod(name = "to_proto") + public IRubyObject toProto(ThreadContext context) { + RubyDescriptorPool pool = (RubyDescriptorPool) RubyDescriptorPool.generatedPool(null, null); + RubyDescriptor descriptorProto = + (RubyDescriptor) + pool.lookup(context, context.runtime.newString("google.protobuf.DescriptorProto")); + RubyClass msgClass = (RubyClass) descriptorProto.msgclass(context); + RubyMessage msg = (RubyMessage) msgClass.newInstance(context, Block.NULL_BLOCK); + return msg.decodeBytes( + context, + msg, + CodedInputStream.newInstance(descriptor.toProto().toByteString().toByteArray()), /*freeze*/ + true); + } + protected FieldDescriptor getField(String name) { return descriptor.findFieldByName(name); } diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyEnumDescriptor.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyEnumDescriptor.java index 3ef946f12d6fd..c280de4d361a5 100644 --- a/ruby/src/main/java/com/google/protobuf/jruby/RubyEnumDescriptor.java +++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyEnumDescriptor.java @@ -140,6 +140,27 @@ public IRubyObject options(ThreadContext context) { true); } + /* + * call-seq: + * EnumDescriptor.to_proto => EnumDescriptorProto + * + * Returns the `EnumDescriptorProto` of this `EnumDescriptor`. + */ + @JRubyMethod(name = "to_proto") + public IRubyObject toProto(ThreadContext context) { + RubyDescriptorPool pool = (RubyDescriptorPool) RubyDescriptorPool.generatedPool(null, null); + RubyDescriptor enumDescriptorProto = + (RubyDescriptor) + pool.lookup(context, context.runtime.newString("google.protobuf.EnumDescriptorProto")); + RubyClass msgClass = (RubyClass) enumDescriptorProto.msgclass(context); + RubyMessage msg = (RubyMessage) msgClass.newInstance(context, Block.NULL_BLOCK); + return msg.decodeBytes( + context, + msg, + CodedInputStream.newInstance(descriptor.toProto().toByteString().toByteArray()), /*freeze*/ + true); + } + public boolean isValidValue(ThreadContext context, IRubyObject value) { EnumValueDescriptor enumValue; diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyFieldDescriptor.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyFieldDescriptor.java index 189d881fbc258..1227a28b6fbb4 100644 --- a/ruby/src/main/java/com/google/protobuf/jruby/RubyFieldDescriptor.java +++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyFieldDescriptor.java @@ -273,6 +273,27 @@ public IRubyObject options(ThreadContext context) { true); } + /* + * call-seq: + * FieldDescriptor.to_proto => FieldDescriptorProto + * + * Returns the `FieldDescriptorProto` of this `FieldDescriptor`. + */ + @JRubyMethod(name = "to_proto") + public IRubyObject toProto(ThreadContext context) { + RubyDescriptorPool pool = (RubyDescriptorPool) RubyDescriptorPool.generatedPool(null, null); + RubyDescriptor fieldDescriptorProto = + (RubyDescriptor) + pool.lookup(context, context.runtime.newString("google.protobuf.FieldDescriptorProto")); + RubyClass msgClass = (RubyClass) fieldDescriptorProto.msgclass(context); + RubyMessage msg = (RubyMessage) msgClass.newInstance(context, Block.NULL_BLOCK); + return msg.decodeBytes( + context, + msg, + CodedInputStream.newInstance(descriptor.toProto().toByteString().toByteArray()), /*freeze*/ + true); + } + protected void setDescriptor( ThreadContext context, FieldDescriptor descriptor, RubyDescriptorPool pool) { this.descriptor = descriptor; diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyFileDescriptor.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyFileDescriptor.java index f0147d686c338..238926b1e6aad 100644 --- a/ruby/src/main/java/com/google/protobuf/jruby/RubyFileDescriptor.java +++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyFileDescriptor.java @@ -100,6 +100,28 @@ public IRubyObject options(ThreadContext context) { true); } + /* + * call-seq: + * FileDescriptor.to_proto => FileDescriptorProto + * + * Returns the `FileDescriptorProto` of this `FileDescriptor`. + */ + @JRubyMethod(name = "to_proto") + public IRubyObject toProto(ThreadContext context) { + RubyDescriptorPool pool = (RubyDescriptorPool) RubyDescriptorPool.generatedPool(null, null); + RubyDescriptor fileDescriptorProto = + (RubyDescriptor) + pool.lookup(context, context.runtime.newString("google.protobuf.FileDescriptorProto")); + RubyClass msgClass = (RubyClass) fileDescriptorProto.msgclass(context); + RubyMessage msg = (RubyMessage) msgClass.newInstance(context, Block.NULL_BLOCK); + return msg.decodeBytes( + context, + msg, + CodedInputStream.newInstance( + fileDescriptor.toProto().toByteString().toByteArray()), /*freeze*/ + true); + } + private static RubyClass cFileDescriptor; private FileDescriptor fileDescriptor; diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyMethodDescriptor.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyMethodDescriptor.java index 1f339357934a8..4d2a28f62ca97 100644 --- a/ruby/src/main/java/com/google/protobuf/jruby/RubyMethodDescriptor.java +++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyMethodDescriptor.java @@ -148,6 +148,28 @@ public IRubyObject getServerStreaming(ThreadContext context) { : context.runtime.getFalse(); } + /* + * call-seq: + * MethodDescriptor.to_proto => MethodDescriptorProto + * + * Returns the `MethodDescriptorProto` of this `MethodDescriptor`. + */ + @JRubyMethod(name = "to_proto") + public IRubyObject toProto(ThreadContext context) { + RubyDescriptorPool pool = (RubyDescriptorPool) RubyDescriptorPool.generatedPool(null, null); + RubyDescriptor methodDescriptorProto = + (RubyDescriptor) + pool.lookup( + context, context.runtime.newString("google.protobuf.MethodDescriptorProto")); + RubyClass msgClass = (RubyClass) methodDescriptorProto.msgclass(context); + RubyMessage msg = (RubyMessage) msgClass.newInstance(context, Block.NULL_BLOCK); + return msg.decodeBytes( + context, + msg, + CodedInputStream.newInstance(descriptor.toProto().toByteString().toByteArray()), /*freeze*/ + true); + } + protected void setDescriptor( ThreadContext context, MethodDescriptor descriptor, RubyDescriptorPool pool) { this.descriptor = descriptor; diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyOneofDescriptor.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyOneofDescriptor.java index 36fe2d0e8a5f5..82e55a28af931 100644 --- a/ruby/src/main/java/com/google/protobuf/jruby/RubyOneofDescriptor.java +++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyOneofDescriptor.java @@ -83,6 +83,27 @@ public IRubyObject options(ThreadContext context) { true); } + /* + * call-seq: + * OneofDescriptor.to_proto => OneofDescriptor + * + * Returns the `OneofDescriptorProto` of this `OneofDescriptor`. + */ + @JRubyMethod(name = "to_proto") + public IRubyObject toProto(ThreadContext context) { + RubyDescriptorPool pool = (RubyDescriptorPool) RubyDescriptorPool.generatedPool(null, null); + RubyDescriptor oneofDescriptorProto = + (RubyDescriptor) + pool.lookup(context, context.runtime.newString("google.protobuf.OneofDescriptorProto")); + RubyClass msgClass = (RubyClass) oneofDescriptorProto.msgclass(context); + RubyMessage msg = (RubyMessage) msgClass.newInstance(context, Block.NULL_BLOCK); + return msg.decodeBytes( + context, + msg, + CodedInputStream.newInstance(descriptor.toProto().toByteString().toByteArray()), /*freeze*/ + true); + } + protected Collection getFields() { return fields; } diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyServiceDescriptor.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyServiceDescriptor.java index 0a7a7e346efdc..fd9fde5227e17 100644 --- a/ruby/src/main/java/com/google/protobuf/jruby/RubyServiceDescriptor.java +++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyServiceDescriptor.java @@ -129,6 +129,28 @@ public IRubyObject each(ThreadContext context, Block block) { return context.nil; } + /* + * call-seq: + * ServiceDescriptor.to_proto => ServiceDescriptorProto + * + * Returns the `ServiceDescriptorProto` of this `ServiceDescriptor`. + */ + @JRubyMethod(name = "to_proto") + public IRubyObject toProto(ThreadContext context) { + RubyDescriptorPool pool = (RubyDescriptorPool) RubyDescriptorPool.generatedPool(null, null); + RubyDescriptor serviceDescriptorProto = + (RubyDescriptor) + pool.lookup( + context, context.runtime.newString("google.protobuf.ServiceDescriptorProto")); + RubyClass msgClass = (RubyClass) serviceDescriptorProto.msgclass(context); + RubyMessage msg = (RubyMessage) msgClass.newInstance(context, Block.NULL_BLOCK); + return msg.decodeBytes( + context, + msg, + CodedInputStream.newInstance(descriptor.toProto().toByteString().toByteArray()), /*freeze*/ + true); + } + protected void setDescriptor( ThreadContext context, ServiceDescriptor descriptor, RubyDescriptorPool pool) { this.descriptor = descriptor; diff --git a/ruby/tests/basic.rb b/ruby/tests/basic.rb index a55f921011cc7..afff9c7907686 100755 --- a/ruby/tests/basic.rb +++ b/ruby/tests/basic.rb @@ -656,6 +656,12 @@ def test_file_descriptor_options assert file_descriptor.options.deprecated end + def test_file_descriptor_to_proto + file_descriptor = TestMessage.descriptor.file_descriptor + + assert_instance_of Google::Protobuf::FileDescriptorProto, file_descriptor.to_proto + end + def test_field_descriptor_options field_descriptor = TestDeprecatedMessage.descriptor.lookup("foo") @@ -663,6 +669,12 @@ def test_field_descriptor_options assert field_descriptor.options.deprecated end + def test_field_descriptor_to_proto + field_descriptor = TestDeprecatedMessage.descriptor.lookup("foo") + + assert_instance_of Google::Protobuf::FieldDescriptorProto, field_descriptor.to_proto + end + def test_descriptor_options descriptor = TestDeprecatedMessage.descriptor @@ -670,6 +682,12 @@ def test_descriptor_options assert descriptor.options.deprecated end + def test_descriptor_to_proto + descriptor = TestDeprecatedMessage.descriptor + + assert_instance_of Google::Protobuf::DescriptorProto, descriptor.to_proto + end + def test_enum_descriptor_options enum_descriptor = TestDeprecatedEnum.descriptor @@ -677,6 +695,12 @@ def test_enum_descriptor_options assert enum_descriptor.options.deprecated end + def test_enum_descriptor_to_proto + enum_descriptor = TestDeprecatedEnum.descriptor + + assert_instance_of Google::Protobuf::EnumDescriptorProto, enum_descriptor.to_proto + end + def test_oneof_descriptor_options descriptor = TestDeprecatedMessage.descriptor oneof_descriptor = descriptor.lookup_oneof("test_deprecated_message_oneof") @@ -687,6 +711,13 @@ def test_oneof_descriptor_options assert_equal "Custom option value", test_top_level_option.get(oneof_descriptor.options) end + def test_oneof_descriptor_to_proto + descriptor = TestDeprecatedMessage.descriptor + oneof_descriptor = descriptor.lookup_oneof("test_deprecated_message_oneof") + + assert_instance_of Google::Protobuf::OneofDescriptorProto, oneof_descriptor.to_proto + end + def test_nested_extension descriptor = TestDeprecatedMessage.descriptor oneof_descriptor = descriptor.lookup_oneof("test_deprecated_message_oneof") diff --git a/ruby/tests/service_test.rb b/ruby/tests/service_test.rb index 9f95abc1b3f75..2cd1e2f7b5474 100644 --- a/ruby/tests/service_test.rb +++ b/ruby/tests/service_test.rb @@ -23,7 +23,10 @@ def test_file_descriptor end def test_method_iteration - @test_service.each { |method| assert_kind_of Google::Protobuf::MethodDescriptor, method } + @test_service.each do |method| + assert_kind_of Google::Protobuf::MethodDescriptor, method + assert_instance_of Google::Protobuf::MethodDescriptorProto, method.to_proto + end assert_equal %w(UnaryOne UnaryTwo), @test_service.map { |method| method.name }.first(2) end @@ -38,6 +41,10 @@ def test_service_options_extensions assert_equal 8325, extension_field.get(@test_service.options).int_option_value end + def test_service_to_proto + assert_instance_of Google::Protobuf::ServiceDescriptorProto, @test_service.to_proto + end + def test_method_options assert_equal :IDEMPOTENT, @test_service_methods['IdempotentMethod'].options.idempotency_level assert_equal :NO_SIDE_EFFECTS, @test_service_methods['PureMethod'].options.idempotency_level diff --git a/upb/BUILD b/upb/BUILD index b282b6eeb2d05..025bc1baf0246 100644 --- a/upb/BUILD +++ b/upb/BUILD @@ -352,6 +352,7 @@ upb_amalgamation( "//upb/mini_table:internal", "//upb/reflection:descriptor_upb_proto", "//upb/reflection:internal", + "//upb/util:def_to_proto", ], prefix = "ruby-", strip_import_prefix = ["src"], diff --git a/upb/reflection/file_def.c b/upb/reflection/file_def.c index 27e7f18209073..906b81d05a7f3 100644 --- a/upb/reflection/file_def.c +++ b/upb/reflection/file_def.c @@ -181,7 +181,7 @@ bool upb_FileDef_Resolves(const upb_FileDef* f, const char* path) { return false; } -static char* strviewdup(upb_DefBuilder* ctx, upb_StringView view) { +static char* _strviewdup(upb_DefBuilder* ctx, upb_StringView view) { char* ret = upb_strdup2(view.data, view.size, _upb_DefBuilder_Arena(ctx)); if (!ret) _upb_DefBuilder_OomErr(ctx); return ret; @@ -310,7 +310,7 @@ void _upb_FileDef_Create(upb_DefBuilder* ctx, } upb_StringView name = UPB_DESC(FileDescriptorProto_name)(file_proto); - file->name = strviewdup(ctx, name); + file->name = _strviewdup(ctx, name); if (strlen(file->name) != name.size) { _upb_DefBuilder_Errf(ctx, "File name contained embedded NULL"); } @@ -319,7 +319,7 @@ void _upb_FileDef_Create(upb_DefBuilder* ctx, if (package.size) { _upb_DefBuilder_CheckIdentFull(ctx, package); - file->package = strviewdup(ctx, package); + file->package = _strviewdup(ctx, package); } else { file->package = NULL; }