Class: Beefcake::Generator

Inherits:
Object
  • Object
show all
Defined in:
lib/beefcake/generator.rb

Constant Summary collapse

L =
CodeGeneratorRequest::FieldDescriptorProto::Label
T =
CodeGeneratorRequest::FieldDescriptorProto::Type

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(c) ⇒ Generator

Returns a new instance of Generator.



159
160
161
162
# File 'lib/beefcake/generator.rb', line 159

def initialize(c)
  @c = c
  @n = 0
end

Instance Attribute Details

#cObject (readonly)

Returns the value of attribute c.



157
158
159
# File 'lib/beefcake/generator.rb', line 157

def c
  @c
end

Class Method Details

.compile(ns, req) ⇒ Object



142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/beefcake/generator.rb', line 142

def self.compile(ns, req)
  file = req.proto_file.map do |file|
    g = new(StringIO.new)
    g.compile(ns, file)

    g.c.rewind
    CodeGeneratorResponse::File.new(
      :name => File.basename(file.name, ".proto") + ".pb.rb",
      :content => g.c.read
    )
  end

  CodeGeneratorResponse.new(:file => file)
end

Instance Method Details

#compile(ns, file) ⇒ Object



255
256
257
258
259
260
261
262
263
264
265
# File 'lib/beefcake/generator.rb', line 255

def compile(ns, file)
  puts "## Generated from #{file.name} for #{file.package}"
  puts "require \"beefcake\""
  puts

  ns!(ns) do
    file.message_type.each do |mt|
      message!(file.package, mt)
    end
  end
end

#enum!(et) ⇒ Object



210
211
212
213
214
215
216
217
218
# File 'lib/beefcake/generator.rb', line 210

def enum!(et)
  puts "module #{et.name}"
  indent do
    et.value.each do |v|
      puts "%s = %d" % [v.name, v.number]
    end
  end
  puts "end"
end

#field!(pkg, f) ⇒ Object



220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/beefcake/generator.rb', line 220

def field!(pkg, f)
  # Turn the label into Ruby
  label = name_for(f, L, f.label)

  # Turn the name into a Ruby
  name = ":#{f.name}"

  # Determine the type-name and convert to Ruby
  type = if f.type_name
    # We have a type_name so we will use it after converting to a
    # Ruby friendly version
    t = f.type_name
    t = t.gsub(pkg, "") # Remove the leading package name
    t = t.gsub(/^\.*/, "")       # Remove leading `.`s

    t.gsub(".", "::")  # Convert to Ruby namespacing syntax
  else
    ":#{name_for(f, T, f.type)}"
  end

  # Finally, generate the declaration
  out = "%s %s, %s, %d" % [label, name, type, f.number]

  if f.default_value
    out += ", :default => #{f.default_value}"
  end

  puts out
end

#file!(file) ⇒ Object



164
165
166
167
168
169
170
# File 'lib/beefcake/generator.rb', line 164

def file!(file)
  puts "## Generated from #{file.name} for #{file.package}"

  file.message_type.each do |mt|
    message!("", mt)
  end
end

#indent(&blk) ⇒ Object



172
173
174
175
176
# File 'lib/beefcake/generator.rb', line 172

def indent(&blk)
  @n += 1
  blk.call
  @n -= 1
end

#indent!(n) ⇒ Object



178
179
180
# File 'lib/beefcake/generator.rb', line 178

def indent!(n)
  @n = n
end

#message!(pkg, mt) ⇒ Object



182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/beefcake/generator.rb', line 182

def message!(pkg, mt)
  puts
  puts "class #{mt.name}"

  indent do
    puts "include Beefcake::Message"
    puts

    Array(mt.enum_type).each do |et|
      enum!(et)
    end

    ## Generate Types
    Array(mt.nested_type).each do |nt|
      message!(pkg, nt)
    end
    puts

    ## Generate fields
    Array(mt.field).each do |f|
      field!(pkg, f)
    end
    puts
  end

  puts "end"
end

#name_for(b, mod, val) ⇒ Object

Determines the name for a



251
252
253
# File 'lib/beefcake/generator.rb', line 251

def name_for(b, mod, val)
  b.name_for(mod, val).to_s.gsub(/.*_/, "").downcase
end

#ns!(modules, &blk) ⇒ Object



267
268
269
270
271
272
273
274
275
276
277
# File 'lib/beefcake/generator.rb', line 267

def ns!(modules, &blk)
  if modules.empty?
    blk.call
  else
    puts "module #{modules.first}"
    indent do
      ns!(modules[1..-1], &blk)
    end
    puts "end"
  end
end

#puts(msg = nil) ⇒ Object



279
280
281
282
283
284
285
# File 'lib/beefcake/generator.rb', line 279

def puts(msg=nil)
  if msg
    c.puts(("  " * @n) + msg)
  else
    c.puts
  end
end