Skip to content

Support oneOf groups #399

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions lib/protobuf/generators/group_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
require 'protobuf/generators/message_generator'
require 'protobuf/generators/option_generator'
require 'protobuf/generators/service_generator'
require 'protobuf/generators/oneof_group_generator'

module Protobuf
module Generators
Expand All @@ -27,6 +28,12 @@ def add_options(option_descriptor)
@groups[:options] << OptionGenerator.new(option_descriptor, indent_level)
end

def add_oneof_groups(field_descriptors, msg_descriptor)
return unless msg_descriptor.oneof_decl.length > 0

@groups[:oneof_group] << OneofGroupGenerator.new(msg_descriptor.oneof_decl, field_descriptors, indent_level)
end

def add_enums(enum_descriptors, options)
enum_descriptors.each do |enum_descriptor|
@groups[:enum] << EnumGenerator.new(enum_descriptor, indent_level, options)
Expand Down
5 changes: 4 additions & 1 deletion lib/protobuf/generators/message_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ def compile_message
group.add_messages(descriptor.nested_type, :extension_fields => @extension_fields, :namespace => type_namespace)
group.add_comment(:options, 'Message Options')
group.add_options(descriptor.options) if options?
group.add_oneof_groups(descriptor.field, descriptor)
group.add_comment(:oneof_group, 'Oneof Groups')

group.add_message_fields(descriptor.field, descriptor)
self.class.validate_tags(fully_qualified_type_namespace, descriptor.field.map(&:number))

Expand All @@ -54,7 +57,7 @@ def compile_message

group.add_extension_fields(message_extension_fields)

group.order = [:message, :options, :field, :extension_range, :extension_field]
group.order = [:message, :options, :oneof_group, :field, :extension_range, :extension_field]
print group.to_s
end
end
Expand Down
29 changes: 29 additions & 0 deletions lib/protobuf/generators/oneof_group_generators.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
require 'protobuf/generators/base'

module Protobuf
module Generators
class OneofGroupGenerator < Base
def initialize(oneof_decl, field_descriptors, indent_level, options = {})
super(oneof_decl, indent_level, options)
@field_descriptors = field_descriptors
end

def compile
run_once(:compile) do
descriptor.each_with_index do |oneof_descriptor, idx|
puts build_value(oneof_descriptor.name, idx)
end
puts
end
end

def build_value(name, oneof_index)
oneof_fields = @field_descriptors.select { |field_descriptor| field_descriptor.oneof_index == oneof_index }

"oneof_group :#{name.strip}, [:#{oneof_fields.map(&:name).join(', :')}]"
end
end
end
end


2 changes: 2 additions & 0 deletions lib/protobuf/message.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require 'protobuf/message/fields'
require 'protobuf/message/serialization'
require 'protobuf/message/oneof_groups'
require 'protobuf/varint'

module Protobuf
Expand All @@ -10,6 +11,7 @@ class Message
#

extend ::Protobuf::Message::Fields
extend ::Protobuf::Message::OneofGroups
include ::Protobuf::Message::Serialization
::Protobuf::Optionable.inject(self) { ::Google::Protobuf::MessageOptions }

Expand Down
31 changes: 31 additions & 0 deletions lib/protobuf/message/oneof_groups.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module Protobuf
class Message
module OneofGroups
def self.extended(other)
other.extend(ClassMethods)
end

module ClassMethods
# Define a oneOf group
#
def oneof_group(group_name, field_names)
oneof_groups[group_name] = field_names
end

def get_oneof_group(group_name)
oneof_groups[group_name]
end

def raise_if_oneof_group_name_collision(group_name)
if get_oneof_group(group_name)
fail DuplicateOneofGroupNameError, %(Oneof group name #{group_name} has already been used in "#{name}".)
end
end

def oneof_groups
@oneof_groups ||= {}
end
end
end
end
end