Skip to content

Commit c398592

Browse files
y-yagicopybara-github
authored andcommitted
Ruby: Allow to get a file descriptor by a file name (#20287)
In Python, users can get a file descriptor by a file name. https://googleapis.dev/python/protobuf/latest/google/protobuf/descriptor_pool.html#google.protobuf.descriptor_pool.DescriptorPool.FindFileByName This would be useful for sometimes. For example, GRPC Reflection allows to get a proto by file name. https://github.com/grpc/grpc-proto/blob/483f11e91a30de9c11d65d872c09bc529e94e2ee/grpc/reflection/v1/reflection.proto#L45-L46 This feature would be useful to implement such a case. Closes #20287 PiperOrigin-RevId: 729274388
1 parent 9f46b19 commit c398592

File tree

10 files changed

+54
-8
lines changed

10 files changed

+54
-8
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13130,7 +13130,7 @@ UPB_API const upb_EnumDef* upb_DefPool_FindEnumByName(const upb_DefPool* s,
1313013130
const upb_EnumValueDef* upb_DefPool_FindEnumByNameval(const upb_DefPool* s,
1313113131
const char* sym);
1313213132

13133-
const upb_FileDef* upb_DefPool_FindFileByName(const upb_DefPool* s,
13133+
UPB_API const upb_FileDef* upb_DefPool_FindFileByName(const upb_DefPool* s,
1313413134
const char* name);
1313513135

1313613136
const upb_FileDef* upb_DefPool_FindFileByNameWithSize(const upb_DefPool* s,

ruby/ext/google/protobuf_c/defs.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ static VALUE DescriptorPool_lookup(VALUE _self, VALUE name) {
156156
const upb_EnumDef* enumdef;
157157
const upb_FieldDef* fielddef;
158158
const upb_ServiceDef* servicedef;
159+
const upb_FileDef* filedef;
159160

160161
msgdef = upb_DefPool_FindMessageByName(self->symtab, name_str);
161162
if (msgdef) {
@@ -177,6 +178,11 @@ static VALUE DescriptorPool_lookup(VALUE _self, VALUE name) {
177178
return get_servicedef_obj(_self, servicedef);
178179
}
179180

181+
filedef = upb_DefPool_FindFileByName(self->symtab, name_str);
182+
if (filedef) {
183+
return get_filedef_obj(_self, filedef);
184+
}
185+
180186
return Qnil;
181187
}
182188

ruby/ext/google/protobuf_c/ruby-upb.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13132,7 +13132,7 @@ UPB_API const upb_EnumDef* upb_DefPool_FindEnumByName(const upb_DefPool* s,
1313213132
const upb_EnumValueDef* upb_DefPool_FindEnumByNameval(const upb_DefPool* s,
1313313133
const char* sym);
1313413134

13135-
const upb_FileDef* upb_DefPool_FindFileByName(const upb_DefPool* s,
13135+
UPB_API const upb_FileDef* upb_DefPool_FindFileByName(const upb_DefPool* s,
1313613136
const char* name);
1313713137

1313813138
const upb_FileDef* upb_DefPool_FindFileByNameWithSize(const upb_DefPool* s,

ruby/lib/google/protobuf/ffi/descriptor_pool.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class FFI
1717
attach_function :lookup_extension, :upb_DefPool_FindExtensionByName,[:DefPool, :string], FieldDescriptor
1818
attach_function :lookup_msg, :upb_DefPool_FindMessageByName, [:DefPool, :string], Descriptor
1919
attach_function :lookup_service, :upb_DefPool_FindServiceByName, [:DefPool, :string], ServiceDescriptor
20+
attach_function :lookup_file, :upb_DefPool_FindFileByName, [:DefPool, :string], FileDescriptor
2021

2122
# FileDescriptorProto
2223
attach_function :parse, :FileDescriptorProto_parse, [:binary_string, :size_t, Internal::Arena], :FileDescriptorProto
@@ -56,7 +57,8 @@ def lookup name
5657
Google::Protobuf::FFI.lookup_msg(@descriptor_pool, name) ||
5758
Google::Protobuf::FFI.lookup_enum(@descriptor_pool, name) ||
5859
Google::Protobuf::FFI.lookup_extension(@descriptor_pool, name) ||
59-
Google::Protobuf::FFI.lookup_service(@descriptor_pool, name)
60+
Google::Protobuf::FFI.lookup_service(@descriptor_pool, name) ||
61+
Google::Protobuf::FFI.lookup_file(@descriptor_pool, name)
6062
end
6163

6264
def self.generated_pool

ruby/lib/google/protobuf/ffi/file_descriptor.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,32 @@ class FFI
1818
class FileDescriptor
1919
attr :descriptor_pool, :file_def
2020

21+
# FFI Interface methods and setup
22+
extend ::FFI::DataConverter
23+
native_type ::FFI::Type::POINTER
24+
25+
class << self
26+
prepend Google::Protobuf::Internal::TypeSafety
27+
include Google::Protobuf::Internal::PointerHelper
28+
29+
# @param value [FileDescriptor] FileDescriptor to convert to an FFI native type
30+
# @param _ [Object] Unused
31+
def to_native(value, _)
32+
file_def_ptr = value.nil? ? nil : value.instance_variable_get(:@file_def)
33+
return ::FFI::Pointer::NULL if file_def_ptr.nil?
34+
raise "Underlying file_def was null!" if file_def_ptr.null?
35+
file_def_ptr
36+
end
37+
38+
##
39+
# @param file_def [::FFI::Pointer] FileDef pointer to be wrapped
40+
# @param _ [Object] Unused
41+
def from_native(file_def, _ = nil)
42+
return nil if file_def.nil? or file_def.null?
43+
descriptor_from_file_def(file_def)
44+
end
45+
end
46+
2147
def initialize(file_def, descriptor_pool)
2248
@descriptor_pool = descriptor_pool
2349
@file_def = file_def

ruby/lib/google/protobuf/ffi/internal/pointer_helper.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ module PointerHelper
1313
# the pool, and either retrieve the wrapper object for the given pointer
1414
# or create one. Assumes that the caller is the wrapper class for the
1515
# given pointer and that it implements `private_constructor`.
16-
def descriptor_from_file_def(file_def, pointer)
16+
def descriptor_from_file_def(file_def, pointer = nil)
17+
pointer = file_def if pointer.nil?
1718
raise RuntimeError.new "FileDef is nil" if file_def.nil?
1819
raise RuntimeError.new "FileDef is null" if file_def.null?
1920
pool_def = Google::Protobuf::FFI.file_def_pool file_def

ruby/lib/google/protobuf_ffi.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
require 'google/protobuf/ffi/oneof_descriptor'
1818
require 'google/protobuf/ffi/method_descriptor'
1919
require 'google/protobuf/ffi/service_descriptor'
20-
require 'google/protobuf/ffi/descriptor_pool'
2120
require 'google/protobuf/ffi/file_descriptor'
21+
require 'google/protobuf/ffi/descriptor_pool'
2222
require 'google/protobuf/ffi/map'
2323
require 'google/protobuf/ffi/object_cache'
2424
require 'google/protobuf/ffi/repeated_field'

ruby/src/main/java/com/google/protobuf/jruby/RubyDescriptorPool.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
import com.google.protobuf.Descriptors.FieldDescriptor;
4040
import com.google.protobuf.Descriptors.FileDescriptor;
4141
import com.google.protobuf.Descriptors.ServiceDescriptor;
42-
import com.google.protobuf.Descriptors.MethodDescriptor;
4342
import com.google.protobuf.ExtensionRegistry;
4443
import com.google.protobuf.InvalidProtocolBufferException;
4544
import java.util.ArrayList;
@@ -164,6 +163,11 @@ protected void registerFileDescriptor(
164163
for (ServiceDescriptor serviceDescriptor : fd.getServices())
165164
registerService(context, serviceDescriptor, packageName);
166165

166+
RubyFileDescriptor rfd =
167+
(RubyFileDescriptor) RubyFileDescriptor.getRubyFileDescriptor(context, fd);
168+
RubyString name = context.runtime.newString(fd.getName());
169+
symtab.put(name, rfd);
170+
167171
// Mark this as a loaded file
168172
fileDescriptors.add(fd);
169173
}

ruby/tests/basic.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,13 @@ def test_file_descriptor
560560
assert_equal "basic_test.proto", file_descriptor.name
561561
end
562562

563+
def test_lookup_filename
564+
file_descriptor = Google::Protobuf::DescriptorPool.generated_pool.lookup 'basic_test.proto'
565+
refute_nil file_descriptor
566+
assert_kind_of Google::Protobuf::FileDescriptor, file_descriptor
567+
assert_equal "basic_test.proto", file_descriptor.name
568+
end
569+
563570
def test_map_freeze
564571
m = proto_module::MapMessage.new
565572
m.map_string_int32['a'] = 5

upb/reflection/def_pool.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ UPB_API const upb_EnumDef* upb_DefPool_FindEnumByName(const upb_DefPool* s,
4646
const upb_EnumValueDef* upb_DefPool_FindEnumByNameval(const upb_DefPool* s,
4747
const char* sym);
4848

49-
const upb_FileDef* upb_DefPool_FindFileByName(const upb_DefPool* s,
50-
const char* name);
49+
UPB_API const upb_FileDef* upb_DefPool_FindFileByName(const upb_DefPool* s,
50+
const char* name);
5151

5252
const upb_FileDef* upb_DefPool_FindFileByNameWithSize(const upb_DefPool* s,
5353
const char* name,

0 commit comments

Comments
 (0)