class FileDescriptorToRuby
Constants
- LABEL_MAPPING
- TYPE_MAPPING
Public Class Methods
new(descriptor)
click to toggle source
Calls superclass method
# File lib/protocol_buffers/compiler/file_descriptor_to_ruby.rb, line 9 def initialize(descriptor) super @package_modules = descriptor.package ? descriptor.package.split('.') : [] @ns = [] end
Public Instance Methods
write(io)
click to toggle source
# File lib/protocol_buffers/compiler/file_descriptor_to_ruby.rb, line 15 def write(io) @io = io @io.write <<HEADER #!/usr/bin/env ruby # Generated by the protocol buffer compiler. DO NOT EDIT! require 'protocol_buffers' HEADER descriptor.dependency.each do |dep| dir = File.dirname(dep) filename = File.basename(dep, ".proto") + ".pb" path = if dir == '.' filename else File.join(dir, filename) end @io.write("begin; require '#{path}'; rescue LoadError; end\n") end @io.write("\n") unless descriptor.dependency.empty? in_namespace("module", @package_modules) do declare(descriptor.package, descriptor.message_type, descriptor.enum_type) descriptor.message_type.each do |message| dump_message(descriptor.package, message) end descriptor.service.each do |service| dump_service(descriptor.package, service) end end end
Protected Instance Methods
camelize(lower_case_and_underscored_word)
click to toggle source
# File lib/protocol_buffers/compiler/file_descriptor_to_ruby.rb, line 215 def camelize(lower_case_and_underscored_word) lower_case_and_underscored_word.to_s.gsub(/(?:^|_)(.)/) { $1.upcase } end
capfirst(s)
click to toggle source
# File lib/protocol_buffers/compiler/file_descriptor_to_ruby.rb, line 211 def capfirst(s) "#{s[0,1].capitalize}#{s[1..-1]}" if s end
declare(package, messages, enums)
click to toggle source
# File lib/protocol_buffers/compiler/file_descriptor_to_ruby.rb, line 54 def declare(package, messages, enums) return if messages.empty? && enums.empty? line %{# forward declarations} messages.each do |message| line %{class #{name([@package_modules, message.name].flatten)} < ::ProtocolBuffers::Message; end} end if enums.empty? line else line line %{# enums} enums.each do |enum| dump_enum(package, enum) end end end
default_value(field)
click to toggle source
TODO: this probably doesn’t work for all default values, expand
# File lib/protocol_buffers/compiler/file_descriptor_to_ruby.rb, line 193 def default_value(field) case field.type when TYPE_STRING, TYPE_BYTES %{"#{field.default_value}"} when TYPE_BOOL field.default_value when TYPE_ENUM typename = field_typename(field) %{#{typename}::#{field.default_value}} else field.default_value end end
dump_enum(package, enum)
click to toggle source
# File lib/protocol_buffers/compiler/file_descriptor_to_ruby.rb, line 158 def dump_enum(package, enum) in_namespace("module", enum.name) do line %{include ::ProtocolBuffers::Enum} line line %{set_fully_qualified_name "#{fully_qualified_name(package, enum.name)}"} line enum.value.each do |value| line %{#{capfirst(value.name)} = #{value.number}} end end line end
dump_message(package, message)
click to toggle source
# File lib/protocol_buffers/compiler/file_descriptor_to_ruby.rb, line 126 def dump_message(package, message) in_namespace("class", message.name, " < ::ProtocolBuffers::Message") do fully_qualified_name = fully_qualified_name(package, message.name) declare(fully_qualified_name, message.nested_type, message.enum_type) line %{set_fully_qualified_name "#{fully_qualified_name}"} line line %{# nested messages} unless message.nested_type.empty? message.nested_type.each { |inner| dump_message(fully_qualified_name, inner) } message.field.each do |field| typename = field_typename(field) fieldline = %{#{LABEL_MAPPING[field.label]} #{typename}, :#{field.name}, #{field.number}} if field.type == TYPE_GROUP fieldline << %{, :group => true} end if field.default_value && field.default_value != "" fieldline << %{, :default => #{default_value(field)}} end # Dont need to check for 'repeated' attribute or type, protoc will take care of this. if field.options.packed fieldline << %{, :packed => true } end line fieldline end end line end
dump_service(package, service)
click to toggle source
# File lib/protocol_buffers/compiler/file_descriptor_to_ruby.rb, line 173 def dump_service(package, service) in_namespace("class", service.name, " < ::ProtocolBuffers::Service") do fully_qualified_name = fully_qualified_name(package, service.name) line %{set_fully_qualified_name "#{fully_qualified_name}"} line service.method.each do |method| line %{rpc :#{underscore(method.name)}, "#{method.name}", #{service_typename(method.input_type)}, #{service_typename(method.output_type)}} end end end
field_typename(field)
click to toggle source
# File lib/protocol_buffers/compiler/file_descriptor_to_ruby.rb, line 184 def field_typename(field) TYPE_MAPPING[field.type] || service_typename(field.type_name) end
fully_qualified_name(package, name)
click to toggle source
# File lib/protocol_buffers/compiler/file_descriptor_to_ruby.rb, line 207 def fully_qualified_name(package, name) package == nil || package.empty? ? name : "#{package}.#{name}" end
in_namespace(type, namespace, rest = "") { || ... }
click to toggle source
# File lib/protocol_buffers/compiler/file_descriptor_to_ruby.rb, line 81 def in_namespace(type, namespace, rest = "") namespace_array = [namespace].flatten namespace_array.each do |n| line "#{type} #{camelize(n)}#{rest}" @ns.push n end yield namespace_array.each do |n| @ns.pop line "end" end end
line(str = nil)
click to toggle source
# File lib/protocol_buffers/compiler/file_descriptor_to_ruby.rb, line 73 def line(str = nil) if str @ns.size.times { @io.write(" ") } @io.write(str) end @io.write("\n") end
name(parts)
click to toggle source
# File lib/protocol_buffers/compiler/file_descriptor_to_ruby.rb, line 96 def name(parts) ns = @ns.dup (parts.shift; ns.shift) while !parts.empty? && parts.first == ns.first parts.map { |p| camelize(p) }.join("::") end
service_typename(type_name)
click to toggle source
# File lib/protocol_buffers/compiler/file_descriptor_to_ruby.rb, line 188 def service_typename(type_name) type_name.split(".").map { |t| camelize(t) }.join("::") end
underscore(camelized_word)
click to toggle source
# File lib/protocol_buffers/compiler/file_descriptor_to_ruby.rb, line 219 def underscore(camelized_word) word = camelized_word.to_s.dup word.gsub!(/::/, '/') word.gsub!(/(?:([A-Za-z\d])|^)((?=\a)\b)(?=\b|[^a-z])/) { "#{$1}#{$1 && '_'}#{$2.downcase}" } word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2') word.gsub!(/([a-z\d])([A-Z])/,'\1_\2') word.tr!("-", "_") word.downcase! word end