Is FileDescriptorSet functionality available in Ruby?

152 views
Skip to first unread message

Shine Garg

unread,
Oct 22, 2021, 8:20:50 PM10/22/21
to Protocol Buffers
I'd like to leverage this to read a `.proto` file in Ruby and get a handle on the underlying `FileDescriptorProto` to do some validations. But it's not clear to me how to read the proto file into this object. 

I tried to read both the .proto file as well as the output of the `--descriptor_set_out`. Any guidance would be appreciated.

In bundle console:

// output of --descriptor_set_out dumped to set.txt
2.6.3 :114 > fl = File.open("<full path to/set.txt>", "r")
 => #<File:/path/to/set.txt>

2.6.3 :115 > Google::Protobuf::FileDescriptor.new(file: fl, package: "tutorial")
Traceback (most recent call last):
       16: from ~/.rvm/gems/ruby-2.6.3/bin/bundle:23:in `<main>'
       15: from ~/.rvm/gems/ruby-2.6.3/bin/bundle:23:in `load'
       14: from ~/.rvm/rubies/ruby-2.6.3/lib/ruby/gems/2.6.0/gems/bundler-1.17.3/exe/bundle:22:in `<top (required)>'
       13: from ~/.rvm/rubies/ruby-2.6.3/lib/ruby/site_ruby/2.6.0/bundler/friendly_errors.rb:124:in `with_friendly_errors'
       12: from ~/.rvm/rubies/ruby-2.6.3/lib/ruby/gems/2.6.0/gems/bundler-1.17.3/exe/bundle:30:in `block in <top (required)>'
       11: from ~/.rvm/rubies/ruby-2.6.3/lib/ruby/site_ruby/2.6.0/bundler/cli.rb:18:in `start'
       10: from ~/.rvm/rubies/ruby-2.6.3/lib/ruby/site_ruby/2.6.0/bundler/vendor/thor/lib/thor/base.rb:466:in `start'
        9: from ~/.rvm/rubies/ruby-2.6.3/lib/ruby/site_ruby/2.6.0/bundler/cli.rb:27:in `dispatch'
        8: from ~/.rvm/rubies/ruby-2.6.3/lib/ruby/site_ruby/2.6.0/bundler/vendor/thor/lib/thor.rb:387:in `dispatch'
        7: from ~/.rvm/rubies/ruby-2.6.3/lib/ruby/site_ruby/2.6.0/bundler/vendor/thor/lib/thor/invocation.rb:126:in `invoke_command'
        6: from ~/.rvm/rubies/ruby-2.6.3/lib/ruby/site_ruby/2.6.0/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
        5: from ~/.rvm/rubies/ruby-2.6.3/lib/ruby/site_ruby/2.6.0/bundler/cli.rb:494:in `console'
        4: from ~/.rvm/rubies/ruby-2.6.3/lib/ruby/site_ruby/2.6.0/bundler/cli/console.rb:19:in `run'
        3: from (irb):115
        2: from (irb):115:in `new'
        1: from (irb):115:in `initialize'
ArgumentError (wrong number of arguments (given 1, expected 3))

Shine Garg

unread,
Oct 27, 2021, 9:48:05 PM10/27/21
to Protocol Buffers
For anyone who stumbles upon this...

The code reference is here. Most classes do not have public methods to instantiate them in Ruby, so creating new protos programmatically doesn't seem possible.

But it's possible to traverse a proto programmatically and get all the fields and types:

```
class TraverseDescriptor
def get_all_fields(klass)
if !klass.respond_to?(:descriptor)
puts "The provided class doesn't have a descriptor!"
return
end

klass.descriptor.each do |n|
puts("#{klass.descriptor.name}: #{n.label}, #{n.name}, #{n.type}")
if n.type == :message
msg_class = n.subtype.msgclass.descriptor.name
get_all_fields(::Google::Protobuf::DescriptorPool.generated_pool.lookup(msg_class).msgclass)
end
end
end
end
```

To run: # bundle exec ruby -e "require '<path_to_pb>'; require './traverse_descriptor'; TraverseDescriptor.new.get_all_fields(Tutorial::AddressBook)"
Reply all
Reply to author
Forward
0 new messages