Class: Protobuf::Generators::FileGenerator

Inherits:
Base
  • Object
show all
Defined in:
lib/protobuf/generators/file_generator.rb

Constant Summary

Constants included from Printable

Printable::PARENT_CLASS_ENUM, Printable::PARENT_CLASS_MESSAGE, Printable::PARENT_CLASS_SERVICE

Instance Attribute Summary collapse

Attributes inherited from Base

#descriptor, #namespace, #options

Instance Method Summary collapse

Methods inherited from Base

#fully_qualified_type_namespace, #run_once, #to_s, #type_namespace, validate_tags

Methods included from Printable

#init_printer

Constructor Details

#initialize(*args) ⇒ FileGenerator

Returns a new instance of FileGenerator.



11
12
13
14
15
16
17
# File 'lib/protobuf/generators/file_generator.rb', line 11

def initialize(*args)
  super
  @output_file = ::Google::Protobuf::Compiler::CodeGeneratorResponse::File.new(:name => file_name)
  @extension_fields = Hash.new { |h, k| h[k] = [] }
  @known_messages = []
  @dangling_messages = {}
end

Instance Attribute Details

#output_fileObject (readonly)

Returns the value of attribute output_file.



9
10
11
# File 'lib/protobuf/generators/file_generator.rb', line 9

def output_file
  @output_file
end

Instance Method Details

#compileObject



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/protobuf/generators/file_generator.rb', line 23

def compile
  run_once(:compile) do
    map_extensions(descriptor, [ descriptor.package ])
    extract_dangling_extensions

    print_file_comment
    print_generic_requires
    print_import_requires

    print_package do
      group = GroupGenerator.new(current_indent)
      group.add_enums(descriptor.enum_type, :namespace => [ descriptor.package ])
      group.add_message_declarations(descriptor.message_type)
      group.add_messages(descriptor.message_type, :extension_fields => @extension_fields, :namespace => [ descriptor.package ])
      group.add_extended_messages(@unknown_extensions)
      group.add_services(descriptor.service)

      group.add_header(:enum, 'Enum Classes')
      group.add_header(:message_declaration, 'Message Classes')
      group.add_header(:message, 'Message Fields')
      group.add_header(:extended_message, 'Extended Message Fields')
      group.add_header(:service, 'Service Classes')
      print group.to_s
    end

  end
end

#extract_dangling_extensionsObject



51
52
53
54
55
# File 'lib/protobuf/generators/file_generator.rb', line 51

def extract_dangling_extensions
  @unknown_extensions = @extension_fields.select do |k, v|
    ! @known_messages.include?(k)
  end
end

#file_nameObject



19
20
21
# File 'lib/protobuf/generators/file_generator.rb', line 19

def file_name
  convert_filename(descriptor.name, false)
end

#generate_output_fileObject



57
58
59
60
61
# File 'lib/protobuf/generators/file_generator.rb', line 57

def generate_output_file
  compile
  output_file.content = to_s
  output_file
end

#map_extensions(descriptor, namespaces) ⇒ Object

Recursively map out all extensions known in this file. The key is the type_name of the message being extended, and the value is an array of field descriptors.



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/protobuf/generators/file_generator.rb', line 67

def map_extensions(descriptor, namespaces)
  # Record all the message descriptor name's we encounter (should be the whole tree).
  if descriptor.is_a?(::Google::Protobuf::DescriptorProto)
    if fully_qualified_token?(descriptor.name)
      @known_messages << descriptor.name
    else
      fully_qualified_namespace = ".#{namespaces.join('.')}"
      @known_messages << fully_qualified_namespace
    end
  end

  descriptor.extension.each do |field_descriptor|
    @extension_fields[field_descriptor.extendee] << field_descriptor
  end

  if descriptor.respond_to_has_and_present?(:message_type)
    descriptor.message_type.each do |message_descriptor|
      map_extensions(message_descriptor, (namespaces + [ message_descriptor.name ]))
    end
  end

  if descriptor.respond_to_has_and_present?(:nested_type)
    descriptor.nested_type.each do |nested_descriptor|
      map_extensions(nested_descriptor, (namespaces + [ nested_descriptor.name ]))
    end
  end
end


95
96
97
98
99
# File 'lib/protobuf/generators/file_generator.rb', line 95

def print_file_comment
  puts "##"
  puts "# This file is auto-generated. DO NOT EDIT!"
  puts "#"
end


101
102
103
104
105
# File 'lib/protobuf/generators/file_generator.rb', line 101

def print_generic_requires
  print_require("protobuf/message")
  print_require("protobuf/rpc/service") if descriptor.service.count > 0
  puts
end


107
108
109
110
111
112
113
114
115
116
117
# File 'lib/protobuf/generators/file_generator.rb', line 107

def print_import_requires
  if descriptor.dependency.count > 0
    header "Imports"

    descriptor.dependency.each do |dependency|
      print_require(convert_filename(dependency))
    end

    puts
  end
end


119
120
121
122
123
124
125
# File 'lib/protobuf/generators/file_generator.rb', line 119

def print_package(&block)
  final = lambda { block.call }
  namespaces = descriptor.package.split('.')
  namespaces.reverse.inject(final) { |previous, namespace|
    lambda { print_module(namespace, &previous) }
  }.call
end