Skip to content

Commit

Permalink
Merge pull request #7 from cocoahero/enum-descriptor
Browse files Browse the repository at this point in the history
Add `EnumDescriptor` wrapper
  • Loading branch information
cocoahero authored Oct 5, 2024
2 parents 1578201 + ad15263 commit de4038e
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 7 deletions.
1 change: 1 addition & 0 deletions lib/proto_plugin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module ProtoPlugin

require_relative "proto_plugin/utils"
require_relative "proto_plugin/file_descriptor"
require_relative "proto_plugin/enum_descriptor"
require_relative "proto_plugin/message_descriptor"
require_relative "proto_plugin/base"
require_relative "proto_plugin/version"
47 changes: 47 additions & 0 deletions lib/proto_plugin/enum_descriptor.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# frozen_string_literal: true

module ProtoPlugin
# A wrapper class around `Google::Protobuf::EnumDescriptorProto`
# which provides helpers and more idiomatic Ruby access patterns.
#
# Any method not defined directly is delegated to the descriptor the wrapper was initialized with.
#
# @see https://github.com/protocolbuffers/protobuf/blob/v28.2/src/google/protobuf/descriptor.proto#L336
class EnumDescriptor < SimpleDelegator
# @return [Google::Protobuf::EnumDescriptorProto]
attr_reader :descriptor

# The file or message descriptor this enum was defined within.
#
# @return [FileDescriptor] if defined as a root enum
# @return [MessageDescriptor] if defined as a nested enum (inverse of `enum_type`)
attr_reader :parent

# @param descriptor [Google::Protobuf::EnumDescriptorProto]
# @param parent [FileDescriptorFileDescriptorProto, MessageDescriptor]
# The file or message descriptor this enum was defined within.
def initialize(descriptor, parent)
super(descriptor)
@descriptor = descriptor
@parent = parent
end

# The full name of the enum, including parent namespace.
#
# @example
# "My::Ruby::Package::EnumName"
#
# @return [String]
def full_name
@full_name ||= begin
prefix = case parent
when MessageDescriptor
parent.full_name
when FileDescriptor
parent.namespace
end
"#{prefix}::#{name}"
end
end
end
end
20 changes: 19 additions & 1 deletion lib/proto_plugin/file_descriptor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module ProtoPlugin
#
# Any method not defined directly is delegated to the descriptor the wrapper was initialized with.
#
# @see https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto#L97
# @see https://github.com/protocolbuffers/protobuf/blob/v28.2/src/google/protobuf/descriptor.proto#L97
# Google::Protobuf::FileDescriptorProto
class FileDescriptor < SimpleDelegator
# @return [Google::Protobuf::FileDescriptorProto]
Expand All @@ -18,6 +18,24 @@ def initialize(descriptor)
@descriptor = descriptor
end

# The enums defined as children of this file.
#
# @return [Array]
#
# @see https://github.com/protocolbuffers/protobuf/blob/v28.2/src/google/protobuf/descriptor.proto#L111
# Google::Protobuf::DescriptorProto#enum_type
def enums
@enums ||= @descriptor.enum_type.map do |e|
EnumDescriptor.new(e, self)
end
end

# The messages defined as children of this file.
#
# @return [Array]
#
# @see https://github.com/protocolbuffers/protobuf/blob/v28.2/src/google/protobuf/descriptor.proto#L110
# Google::Protobuf::DescriptorProto#message_type
def messages
@messages ||= @descriptor.message_type.map do |m|
MessageDescriptor.new(m, self)
Expand Down
16 changes: 14 additions & 2 deletions lib/proto_plugin/message_descriptor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module ProtoPlugin
#
# Any method not defined directly is delegated to the descriptor the wrapper was initialized with.
#
# @see https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto#L134
# @see https://github.com/protocolbuffers/protobuf/blob/v28.2/src/google/protobuf/descriptor.proto#L134
# Google::Protobuf::DescriptorProto
class MessageDescriptor < SimpleDelegator
# @return [Google::Protobuf::DescriptorProto]
Expand All @@ -27,11 +27,23 @@ def initialize(descriptor, parent)
@parent = parent
end

# The enums defined as children of this message.
#
# @return [Array]
#
# @see https://github.com/protocolbuffers/protobuf/blob/v28.2/src/google/protobuf/descriptor.proto#L141
# Google::Protobuf::DescriptorProto#enum_type
def enums
@enums ||= @descriptor.enum_type.map do |e|
EnumDescriptor.new(e, self)
end
end

# The messages defined as children of this message.
#
# @return [Array]
#
# @see https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto#L140
# @see https://github.com/protocolbuffers/protobuf/blob/v28.2/src/google/protobuf/descriptor.proto#L140
# Google::Protobuf::DescriptorProto#nested_type
def messages
@nested_messages ||= @descriptor.nested_type.map do |m|
Expand Down
39 changes: 39 additions & 0 deletions test/proto_plugin/enum_descriptor_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# frozen_string_literal: true

module ProtoPlugin
class EnumDescriptorTest < Minitest::Test
def setup
@file = FileDescriptor.new(
Google::Protobuf::FileDescriptorProto.new(
package: "my.package.name",
message_type: [
Google::Protobuf::DescriptorProto.new(
name: "RootMessage",
enum_type: [
Google::Protobuf::EnumDescriptorProto.new(
name: "ChildEnumOne",
),
],
),
],
enum_type: [
Google::Protobuf::EnumDescriptorProto.new(
name: "RootEnum",
),
],
),
)

@enum = @file.enums.first
end

def test_full_name_of_file_enum
assert_equal("My::Package::Name::RootEnum", @enum.full_name)
end

def test_full_name_of_message_enum
enum = @file.messages.first.enums.first
assert_equal("My::Package::Name::RootMessage::ChildEnumOne", enum.full_name)
end
end
end
23 changes: 23 additions & 0 deletions test/proto_plugin/file_descriptor_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,29 @@ def test_name
assert_equal("sample.proto", file.name)
end

def test_enums
file = FileDescriptor.new(
Google::Protobuf::FileDescriptorProto.new(
package: "my.package.name", enum_type: [
Google::Protobuf::EnumDescriptorProto.new(
name: "RootEnumOne",
),
Google::Protobuf::EnumDescriptorProto.new(
name: "RootEnumTwo",
),
]
),
)

assert_equal(2, file.enums.count)

enum_one = file.enums[0]
assert_instance_of(EnumDescriptor, enum_one)

enum_two = file.enums[1]
assert_instance_of(EnumDescriptor, enum_two)
end

def test_messages
file = FileDescriptor.new(
Google::Protobuf::FileDescriptorProto.new(
Expand Down
25 changes: 21 additions & 4 deletions test/proto_plugin/message_descriptor_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,30 @@ class MessageDescriptorTest < Minitest::Test
def setup
@file = FileDescriptor.new(
Google::Protobuf::FileDescriptorProto.new(
package: "my.package.name", message_type: [
package: "my.package.name",
message_type: [
Google::Protobuf::DescriptorProto.new(
name: "RootMessage", nested_type: [
name: "RootMessage",
nested_type: [
Google::Protobuf::DescriptorProto.new(
name: "ChildMessageOne",
),
Google::Protobuf::DescriptorProto.new(
name: "ChildMessageTwo",
),
]
],
enum_type: [
Google::Protobuf::EnumDescriptorProto.new(
name: "ChildEnumOne",
),
],
),
],
enum_type: [
Google::Protobuf::EnumDescriptorProto.new(
name: "RootEnum",
),
]
],
),
)

Expand All @@ -27,6 +39,11 @@ def test_name
assert_equal("RootMessage", @message.name)
end

def test_enums
assert_equal(1, @message.enums.count)
assert_equal("ChildEnumOne", @message.enums.first.name)
end

def test_messages
assert_equal(2, @message.messages.count)

Expand Down

0 comments on commit de4038e

Please sign in to comment.