module Protobuf::Generators::Printable
def comment(message)
Print a one-line comment.
def comment(message) puts "# #{message}" end
def header(message)
# Lorem ipsum dolor
##
header("Lorem ipsum dolor")
Print a "header" comment.
def header(message) puts puts "##" puts "# #{message}" puts "#" end
def indent
(after the block is finished).
Increase the indent level. An outdent will only occur if given a block
def indent self.current_indent += 1 yield outdent end
def init_printer(indent_level)
Must be called by any class/module that includes the Printable module.
Initialize the printer.
def init_printer(indent_level) @io = ::StringIO.new self.current_indent = indent_level.to_i end
def modulize(name)
modulize("foo.bar.BAZ") -> "::Foo::Bar::BAZ"
modulize("foo.bar.baz") -> "::Foo::Bar::Baz"
modulize("foo.bar.Baz") -> "::Foo::Bar::Baz"
token's definition.
as a constant. Otherwise we do not attempt to change the
to capitalize the first character to ensure ruby will treat the value
(e.g. CamelCase, Underscore_Case, SCREAMING_SNAKE_CASE), we only want
Due to the nature of varying standards about how class/modules are named
Take a string and upcase the first character of each namespace.
def modulize(name) name = name.gsub(/\./, '::') name = name.gsub(/(^(?:::)?[a-z]|::[a-z])/, &:upcase) name end
def outdent
Decrease the indent level. Cannot be negative.
def outdent self.current_indent -= 1 unless current_indent.zero? end
def parent_class(type)
will be thrown.
Valid types are :message, :enum, and :service, otherwise an error
Return the parent class for a given type.
def parent_class(type) case type when :message then PARENT_CLASS_MESSAGE when :enum then PARENT_CLASS_ENUM when :service then PARENT_CLASS_SERVICE else fail "Unknown parent class type #{type}: #{caller[0..5].join("\n")}" end end
def print(contents)
Print the given message raw, no indent.
def print(contents) @io.print(contents) end
def print_block(name, parent_klass, type)
Otherwise, end the block on the same line.
If a block is given, call the block from within an indent block.
If a class, can be given a parent class to inherit from.
Print a class or module block, indicated by type.
def print_block(name, parent_klass, type) name = modulize(name) block_def = "#{type} #{name}" block_def += " < #{parent_class(parent_klass)}" if parent_klass if block_given? puts block_def indent { yield } puts "end" puts else block_def += "; end" puts block_def end end
def print_class(name, parent_klass, &block)
to inherit from. Accepts a block for use with print_block.
Use print_block to print a class, with optional parent class
def print_class(name, parent_klass, &block) print_block(name, parent_klass, :class, &block) end
def print_contents
Returns the contents of the underlying StringIO object.
def print_contents @io.rewind @io.read end
def print_module(name, &block)
Accepts a block for use with print_block.
Use print_block to print a module.
def print_module(name, &block) print_block(name, nil, :module, &block) end
def print_require(file, relative = false)
print_require('foo/bar/baz') -> "require 'foo/bar/baz'"
Print a file require.
def print_require(file, relative = false) puts "require#{'_relative' if relative} '#{file}'" end
def puts(message = nil)
If no message is given print a newline.
Puts the given message prefixed by the indent level.
def puts(message = nil) if message @io.puts((" " * current_indent) + message) else @io.puts end end