protobuffy 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.travis.yml +12 -0
- data/.yardopts +5 -0
- data/CHANGES.md +261 -0
- data/CONTRIBUTING.md +16 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +14 -0
- data/README.md +58 -0
- data/Rakefile +61 -0
- data/bin/protoc-gen-ruby +17 -0
- data/bin/rpc_server +4 -0
- data/examples/bin/reverse-client-http +4 -0
- data/examples/bin/reverse-client-socket +4 -0
- data/examples/bin/reverse-client-zmq +4 -0
- data/examples/config.ru +6 -0
- data/examples/definitions/example/reverse.proto +12 -0
- data/examples/lib/example/reverse-client.rb +23 -0
- data/examples/lib/example/reverse-service.rb +9 -0
- data/examples/lib/example/reverse.pb.rb +36 -0
- data/lib/protobuf.rb +106 -0
- data/lib/protobuf/cli.rb +249 -0
- data/lib/protobuf/code_generator.rb +41 -0
- data/lib/protobuf/decoder.rb +74 -0
- data/lib/protobuf/deprecator.rb +42 -0
- data/lib/protobuf/descriptors.rb +3 -0
- data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +52 -0
- data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +249 -0
- data/lib/protobuf/encoder.rb +62 -0
- data/lib/protobuf/enum.rb +319 -0
- data/lib/protobuf/exceptions.rb +9 -0
- data/lib/protobuf/field.rb +74 -0
- data/lib/protobuf/field/base_field.rb +280 -0
- data/lib/protobuf/field/bool_field.rb +53 -0
- data/lib/protobuf/field/bytes_field.rb +81 -0
- data/lib/protobuf/field/double_field.rb +26 -0
- data/lib/protobuf/field/enum_field.rb +57 -0
- data/lib/protobuf/field/field_array.rb +86 -0
- data/lib/protobuf/field/fixed32_field.rb +25 -0
- data/lib/protobuf/field/fixed64_field.rb +29 -0
- data/lib/protobuf/field/float_field.rb +38 -0
- data/lib/protobuf/field/int32_field.rb +22 -0
- data/lib/protobuf/field/int64_field.rb +22 -0
- data/lib/protobuf/field/integer_field.rb +24 -0
- data/lib/protobuf/field/message_field.rb +66 -0
- data/lib/protobuf/field/sfixed32_field.rb +28 -0
- data/lib/protobuf/field/sfixed64_field.rb +29 -0
- data/lib/protobuf/field/signed_integer_field.rb +30 -0
- data/lib/protobuf/field/sint32_field.rb +22 -0
- data/lib/protobuf/field/sint64_field.rb +22 -0
- data/lib/protobuf/field/string_field.rb +35 -0
- data/lib/protobuf/field/uint32_field.rb +22 -0
- data/lib/protobuf/field/uint64_field.rb +22 -0
- data/lib/protobuf/field/varint_field.rb +68 -0
- data/lib/protobuf/generators/base.rb +71 -0
- data/lib/protobuf/generators/enum_generator.rb +42 -0
- data/lib/protobuf/generators/extension_generator.rb +28 -0
- data/lib/protobuf/generators/field_generator.rb +132 -0
- data/lib/protobuf/generators/file_generator.rb +140 -0
- data/lib/protobuf/generators/group_generator.rb +113 -0
- data/lib/protobuf/generators/message_generator.rb +99 -0
- data/lib/protobuf/generators/printable.rb +161 -0
- data/lib/protobuf/generators/service_generator.rb +27 -0
- data/lib/protobuf/http.rb +20 -0
- data/lib/protobuf/lifecycle.rb +46 -0
- data/lib/protobuf/logger.rb +86 -0
- data/lib/protobuf/message.rb +182 -0
- data/lib/protobuf/message/fields.rb +122 -0
- data/lib/protobuf/message/serialization.rb +84 -0
- data/lib/protobuf/optionable.rb +23 -0
- data/lib/protobuf/rpc/buffer.rb +79 -0
- data/lib/protobuf/rpc/client.rb +168 -0
- data/lib/protobuf/rpc/connector.rb +21 -0
- data/lib/protobuf/rpc/connectors/base.rb +54 -0
- data/lib/protobuf/rpc/connectors/common.rb +172 -0
- data/lib/protobuf/rpc/connectors/http.rb +90 -0
- data/lib/protobuf/rpc/connectors/socket.rb +73 -0
- data/lib/protobuf/rpc/connectors/zmq.rb +205 -0
- data/lib/protobuf/rpc/dynamic_discovery.pb.rb +47 -0
- data/lib/protobuf/rpc/env.rb +58 -0
- data/lib/protobuf/rpc/error.rb +28 -0
- data/lib/protobuf/rpc/error/client_error.rb +31 -0
- data/lib/protobuf/rpc/error/server_error.rb +43 -0
- data/lib/protobuf/rpc/middleware.rb +25 -0
- data/lib/protobuf/rpc/middleware/exception_handler.rb +36 -0
- data/lib/protobuf/rpc/middleware/logger.rb +91 -0
- data/lib/protobuf/rpc/middleware/request_decoder.rb +83 -0
- data/lib/protobuf/rpc/middleware/response_encoder.rb +88 -0
- data/lib/protobuf/rpc/middleware/runner.rb +18 -0
- data/lib/protobuf/rpc/rpc.pb.rb +53 -0
- data/lib/protobuf/rpc/server.rb +39 -0
- data/lib/protobuf/rpc/servers/http/server.rb +101 -0
- data/lib/protobuf/rpc/servers/http_runner.rb +34 -0
- data/lib/protobuf/rpc/servers/socket/server.rb +113 -0
- data/lib/protobuf/rpc/servers/socket/worker.rb +56 -0
- data/lib/protobuf/rpc/servers/socket_runner.rb +34 -0
- data/lib/protobuf/rpc/servers/zmq/broker.rb +155 -0
- data/lib/protobuf/rpc/servers/zmq/server.rb +313 -0
- data/lib/protobuf/rpc/servers/zmq/util.rb +47 -0
- data/lib/protobuf/rpc/servers/zmq/worker.rb +105 -0
- data/lib/protobuf/rpc/servers/zmq_runner.rb +51 -0
- data/lib/protobuf/rpc/service.rb +179 -0
- data/lib/protobuf/rpc/service_directory.rb +245 -0
- data/lib/protobuf/rpc/service_dispatcher.rb +46 -0
- data/lib/protobuf/rpc/service_filters.rb +273 -0
- data/lib/protobuf/rpc/stat.rb +148 -0
- data/lib/protobuf/socket.rb +22 -0
- data/lib/protobuf/tasks.rb +1 -0
- data/lib/protobuf/tasks/compile.rake +61 -0
- data/lib/protobuf/version.rb +3 -0
- data/lib/protobuf/wire_type.rb +10 -0
- data/lib/protobuf/zmq.rb +21 -0
- data/proto/dynamic_discovery.proto +44 -0
- data/proto/google/protobuf/compiler/plugin.proto +147 -0
- data/proto/google/protobuf/descriptor.proto +620 -0
- data/proto/rpc.proto +62 -0
- data/protobuffy.gemspec +37 -0
- data/spec/benchmark/tasks.rb +113 -0
- data/spec/bin/protoc-gen-ruby_spec.rb +18 -0
- data/spec/data/data.bin +3 -0
- data/spec/data/types.bin +0 -0
- data/spec/encoding/all_types_spec.rb +91 -0
- data/spec/encoding/extreme_values_spec.rb +0 -0
- data/spec/functional/socket_server_spec.rb +59 -0
- data/spec/functional/zmq_server_spec.rb +103 -0
- data/spec/lib/protobuf/cli_spec.rb +267 -0
- data/spec/lib/protobuf/code_generator_spec.rb +60 -0
- data/spec/lib/protobuf/enum_spec.rb +239 -0
- data/spec/lib/protobuf/field/int32_field_spec.rb +7 -0
- data/spec/lib/protobuf/field/string_field_spec.rb +46 -0
- data/spec/lib/protobuf/field_spec.rb +194 -0
- data/spec/lib/protobuf/generators/base_spec.rb +87 -0
- data/spec/lib/protobuf/generators/enum_generator_spec.rb +68 -0
- data/spec/lib/protobuf/generators/extension_generator_spec.rb +43 -0
- data/spec/lib/protobuf/generators/field_generator_spec.rb +99 -0
- data/spec/lib/protobuf/generators/file_generator_spec.rb +29 -0
- data/spec/lib/protobuf/generators/message_generator_spec.rb +0 -0
- data/spec/lib/protobuf/generators/service_generator_spec.rb +43 -0
- data/spec/lib/protobuf/lifecycle_spec.rb +89 -0
- data/spec/lib/protobuf/logger_spec.rb +136 -0
- data/spec/lib/protobuf/message_spec.rb +368 -0
- data/spec/lib/protobuf/optionable_spec.rb +46 -0
- data/spec/lib/protobuf/rpc/client_spec.rb +66 -0
- data/spec/lib/protobuf/rpc/connector_spec.rb +26 -0
- data/spec/lib/protobuf/rpc/connectors/base_spec.rb +50 -0
- data/spec/lib/protobuf/rpc/connectors/common_spec.rb +170 -0
- data/spec/lib/protobuf/rpc/connectors/connector_spec.rb +13 -0
- data/spec/lib/protobuf/rpc/connectors/http_spec.rb +61 -0
- data/spec/lib/protobuf/rpc/connectors/socket_spec.rb +24 -0
- data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +129 -0
- data/spec/lib/protobuf/rpc/middleware/exception_handler_spec.rb +62 -0
- data/spec/lib/protobuf/rpc/middleware/logger_spec.rb +49 -0
- data/spec/lib/protobuf/rpc/middleware/request_decoder_spec.rb +115 -0
- data/spec/lib/protobuf/rpc/middleware/response_encoder_spec.rb +75 -0
- data/spec/lib/protobuf/rpc/servers/http/server_spec.rb +104 -0
- data/spec/lib/protobuf/rpc/servers/socket_server_spec.rb +38 -0
- data/spec/lib/protobuf/rpc/servers/zmq/server_spec.rb +41 -0
- data/spec/lib/protobuf/rpc/servers/zmq/util_spec.rb +55 -0
- data/spec/lib/protobuf/rpc/servers/zmq/worker_spec.rb +35 -0
- data/spec/lib/protobuf/rpc/service_directory_spec.rb +295 -0
- data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +52 -0
- data/spec/lib/protobuf/rpc/service_filters_spec.rb +484 -0
- data/spec/lib/protobuf/rpc/service_spec.rb +161 -0
- data/spec/lib/protobuf/rpc/stat_spec.rb +151 -0
- data/spec/lib/protobuf_spec.rb +78 -0
- data/spec/spec_helper.rb +57 -0
- data/spec/support/all.rb +7 -0
- data/spec/support/packed_field.rb +22 -0
- data/spec/support/server.rb +94 -0
- data/spec/support/test/all_types.data.bin +0 -0
- data/spec/support/test/all_types.data.txt +119 -0
- data/spec/support/test/defaults.pb.rb +25 -0
- data/spec/support/test/defaults.proto +9 -0
- data/spec/support/test/enum.pb.rb +59 -0
- data/spec/support/test/enum.proto +34 -0
- data/spec/support/test/extended.pb.rb +22 -0
- data/spec/support/test/extended.proto +10 -0
- data/spec/support/test/extreme_values.data.bin +0 -0
- data/spec/support/test/google_unittest.pb.rb +543 -0
- data/spec/support/test/google_unittest.proto +713 -0
- data/spec/support/test/google_unittest_import.pb.rb +37 -0
- data/spec/support/test/google_unittest_import.proto +64 -0
- data/spec/support/test/google_unittest_import_public.pb.rb +8 -0
- data/spec/support/test/google_unittest_import_public.proto +38 -0
- data/spec/support/test/multi_field_extensions.pb.rb +56 -0
- data/spec/support/test/multi_field_extensions.proto +33 -0
- data/spec/support/test/resource.pb.rb +117 -0
- data/spec/support/test/resource.proto +94 -0
- data/spec/support/test/resource_service.rb +26 -0
- data/spec/support/test_app_file.rb +2 -0
- data/spec/support/tolerance_matcher.rb +40 -0
- metadata +367 -0
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'protobuf/field/bytes_field'
|
2
|
+
|
3
|
+
module Protobuf
|
4
|
+
module Field
|
5
|
+
class StringField < BytesField
|
6
|
+
|
7
|
+
##
|
8
|
+
# Constants
|
9
|
+
#
|
10
|
+
|
11
|
+
ENCODING = 'UTF-8'.freeze
|
12
|
+
|
13
|
+
##
|
14
|
+
# Public Instance Methods
|
15
|
+
#
|
16
|
+
|
17
|
+
def decode(bytes)
|
18
|
+
bytes_to_decode = bytes.dup
|
19
|
+
bytes_to_decode.force_encoding(::Protobuf::Field::StringField::ENCODING)
|
20
|
+
bytes_to_decode
|
21
|
+
end
|
22
|
+
|
23
|
+
def encode(value)
|
24
|
+
value_to_encode = value.dup
|
25
|
+
value_to_encode.encode!(::Protobuf::Field::StringField::ENCODING, :invalid => :replace, :undef => :replace, :replace => "")
|
26
|
+
value_to_encode.force_encoding(::Protobuf::Field::BytesField::BYTES_ENCODING)
|
27
|
+
|
28
|
+
string_size = ::Protobuf::Field::VarintField.encode(value_to_encode.size)
|
29
|
+
string_size << value_to_encode
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'protobuf/field/base_field'
|
2
|
+
|
3
|
+
module Protobuf
|
4
|
+
module Field
|
5
|
+
class VarintField < BaseField
|
6
|
+
|
7
|
+
##
|
8
|
+
# Constants
|
9
|
+
#
|
10
|
+
|
11
|
+
INT32_MAX = 2**31 - 1
|
12
|
+
INT32_MIN = -2**31
|
13
|
+
INT64_MAX = 2**63 - 1
|
14
|
+
INT64_MIN = -2**63
|
15
|
+
UINT32_MAX = 2**32 - 1
|
16
|
+
UINT64_MAX = 2**64 - 1
|
17
|
+
|
18
|
+
##
|
19
|
+
# Class Methods
|
20
|
+
#
|
21
|
+
|
22
|
+
def self.default
|
23
|
+
0
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.encode(value)
|
27
|
+
bytes = []
|
28
|
+
until value < 128
|
29
|
+
bytes << (0x80 | (value & 0x7f))
|
30
|
+
value >>= 7
|
31
|
+
end
|
32
|
+
(bytes << value).pack('C*')
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# Public Instance Methods
|
37
|
+
#
|
38
|
+
|
39
|
+
def acceptable?(val)
|
40
|
+
(val > self.class.min || val < self.class.max)
|
41
|
+
rescue
|
42
|
+
false
|
43
|
+
end
|
44
|
+
|
45
|
+
def decode(value)
|
46
|
+
value
|
47
|
+
end
|
48
|
+
|
49
|
+
def encode(value)
|
50
|
+
return [value].pack('C') if value < 128
|
51
|
+
|
52
|
+
bytes = []
|
53
|
+
until value == 0
|
54
|
+
bytes << (0x80 | (value & 0x7f))
|
55
|
+
value >>= 7
|
56
|
+
end
|
57
|
+
bytes[-1] &= 0x7f
|
58
|
+
bytes.pack('C*')
|
59
|
+
end
|
60
|
+
|
61
|
+
def wire_type
|
62
|
+
::Protobuf::WireType::VARINT
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'protobuf/generators/printable'
|
2
|
+
|
3
|
+
module Protobuf
|
4
|
+
module Generators
|
5
|
+
class Base
|
6
|
+
include ::Protobuf::Generators::Printable
|
7
|
+
|
8
|
+
def self.validate_tags(type_name, tags)
|
9
|
+
return if tags.empty?
|
10
|
+
|
11
|
+
unique_tags = tags.uniq
|
12
|
+
|
13
|
+
if unique_tags.size < tags.size
|
14
|
+
::Protobuf::CodeGenerator.fatal("#{type_name} object has duplicate tags. Expected #{unique_tags.size} tags, but got #{tags.size}. Suppress with PB_NO_TAG_WARNINGS=1.")
|
15
|
+
end
|
16
|
+
|
17
|
+
unless ENV.key?('PB_NO_TAG_WARNINGS')
|
18
|
+
range = (tags.min)..(tags.max)
|
19
|
+
if range.respond_to?(:size)
|
20
|
+
expected_size = range.size
|
21
|
+
else
|
22
|
+
expected_size = range.to_a.size
|
23
|
+
end
|
24
|
+
|
25
|
+
if tags.size < expected_size
|
26
|
+
::Protobuf::CodeGenerator.print_tag_warning_suppress
|
27
|
+
::Protobuf::CodeGenerator.warn("#{type_name} object should have #{expected_size} tags (#{range.begin}..#{range.end}), but found #{tags.size} tags.")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_reader :descriptor, :namespace, :options
|
33
|
+
|
34
|
+
def initialize(descriptor, indent_level = 0, options = {})
|
35
|
+
@descriptor = descriptor
|
36
|
+
@options = options
|
37
|
+
@namespace = @options.fetch(:namespace) { [] }
|
38
|
+
init_printer(indent_level)
|
39
|
+
end
|
40
|
+
|
41
|
+
def fully_qualified_type_namespace
|
42
|
+
".#{type_namespace.join('.')}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def run_once(label, &block)
|
46
|
+
tracker_ivar = "@_#{label}_compiled"
|
47
|
+
value_ivar = "@_#{label}_compiled_value"
|
48
|
+
|
49
|
+
if instance_variable_get(tracker_ivar)
|
50
|
+
return instance_variable_get(value_ivar)
|
51
|
+
else
|
52
|
+
return_value = block.call
|
53
|
+
instance_variable_set(tracker_ivar, true)
|
54
|
+
instance_variable_set(value_ivar, return_value)
|
55
|
+
return return_value
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def to_s
|
60
|
+
compile
|
61
|
+
print_contents # see Printable
|
62
|
+
end
|
63
|
+
|
64
|
+
def type_namespace
|
65
|
+
@type_namespace ||= @namespace + [ descriptor.name ]
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'protobuf/generators/base'
|
2
|
+
|
3
|
+
module Protobuf
|
4
|
+
module Generators
|
5
|
+
class EnumGenerator < Base
|
6
|
+
|
7
|
+
def allow_alias?
|
8
|
+
descriptor.options.try(:allow_alias!) { false }
|
9
|
+
end
|
10
|
+
|
11
|
+
def compile
|
12
|
+
run_once(:compile) do
|
13
|
+
tags = []
|
14
|
+
|
15
|
+
print_class(descriptor.name, :enum) do
|
16
|
+
if allow_alias?
|
17
|
+
puts "set_option :allow_alias"
|
18
|
+
puts
|
19
|
+
end
|
20
|
+
|
21
|
+
descriptor.value.each do |enum_value_descriptor|
|
22
|
+
tags << enum_value_descriptor.number
|
23
|
+
puts build_value(enum_value_descriptor)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
unless allow_alias?
|
28
|
+
self.class.validate_tags(fully_qualified_type_namespace, tags)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def build_value(enum_value_descriptor)
|
34
|
+
name = enum_value_descriptor.name
|
35
|
+
number = enum_value_descriptor.number
|
36
|
+
return "define :#{name}, #{number}"
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'protobuf/generators/base'
|
2
|
+
require 'protobuf/generators/group_generator'
|
3
|
+
|
4
|
+
module Protobuf
|
5
|
+
module Generators
|
6
|
+
class ExtensionGenerator < Base
|
7
|
+
|
8
|
+
def initialize(message_type, field_descriptors, indent_level)
|
9
|
+
super(nil, indent_level)
|
10
|
+
@message_type = modulize(message_type)
|
11
|
+
@field_descriptors = field_descriptors
|
12
|
+
end
|
13
|
+
|
14
|
+
def compile
|
15
|
+
run_once(:compile) do
|
16
|
+
print_class(@message_type, :message) do
|
17
|
+
group = GroupGenerator.new(current_indent)
|
18
|
+
group.add_extension_fields(@field_descriptors)
|
19
|
+
group.order = [ :extension_field ]
|
20
|
+
print group.to_s
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'protobuf/generators/base'
|
2
|
+
|
3
|
+
module Protobuf
|
4
|
+
module Generators
|
5
|
+
class FieldGenerator < Base
|
6
|
+
|
7
|
+
##
|
8
|
+
# Constants
|
9
|
+
#
|
10
|
+
PROTO_INFINITY_DEFAULT = /^inf$/i.freeze
|
11
|
+
PROTO_NEGATIVE_INFINITY_DEFAULT = /^-inf$/i.freeze
|
12
|
+
PROTO_NAN_DEFAULT = /^nan$/i.freeze
|
13
|
+
RUBY_INFINITY_DEFAULT = '::Float::INFINITY'.freeze
|
14
|
+
RUBY_NEGATIVE_INFINITY_DEFAULT = '-::Float::INFINITY'.freeze
|
15
|
+
RUBY_NAN_DEFAULT = '::Float::NAN'.freeze
|
16
|
+
|
17
|
+
##
|
18
|
+
# Attributes
|
19
|
+
#
|
20
|
+
attr_reader :field_options
|
21
|
+
|
22
|
+
def applicable_options
|
23
|
+
@applicable_options ||= field_options.map { |k, v| ":#{k} => #{v}" }
|
24
|
+
end
|
25
|
+
|
26
|
+
def default_value
|
27
|
+
@default_value ||= begin
|
28
|
+
if defaulted?
|
29
|
+
case descriptor.type.name
|
30
|
+
when :TYPE_ENUM then
|
31
|
+
enum_default_value
|
32
|
+
when :TYPE_STRING, :TYPE_BYTES then
|
33
|
+
string_default_value
|
34
|
+
when :TYPE_FLOAT, :TYPE_DOUBLE then
|
35
|
+
float_double_default_value
|
36
|
+
else
|
37
|
+
verbatim_default_value
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def defaulted?
|
44
|
+
descriptor.respond_to_has_and_present?(:default_value)
|
45
|
+
end
|
46
|
+
|
47
|
+
def deprecated?
|
48
|
+
descriptor.options.try(:deprecated?) { false }
|
49
|
+
end
|
50
|
+
|
51
|
+
def extension?
|
52
|
+
descriptor.respond_to_has_and_present?(:extendee)
|
53
|
+
end
|
54
|
+
|
55
|
+
def compile
|
56
|
+
run_once(:compile) do
|
57
|
+
field_definition = [ "#{label} #{type_name}", name, number, applicable_options ]
|
58
|
+
puts field_definition.flatten.compact.join(', ')
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def label
|
63
|
+
@label ||= descriptor.label.name.to_s.downcase.sub(/label_/, '') # required, optional, repeated
|
64
|
+
end
|
65
|
+
|
66
|
+
def name
|
67
|
+
@name ||= ":#{descriptor.name}"
|
68
|
+
end
|
69
|
+
|
70
|
+
def number
|
71
|
+
@number ||= descriptor.number
|
72
|
+
end
|
73
|
+
|
74
|
+
def field_options
|
75
|
+
@field_options ||= begin
|
76
|
+
opts = {}
|
77
|
+
opts[:default] = default_value if defaulted?
|
78
|
+
opts[:packed] = 'true' if packed?
|
79
|
+
opts[:deprecated] = 'true' if deprecated?
|
80
|
+
opts[:extension] = 'true' if extension?
|
81
|
+
opts
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def packed?
|
86
|
+
descriptor.options.try(:packed?) { false }
|
87
|
+
end
|
88
|
+
|
89
|
+
# Determine the field type
|
90
|
+
def type_name
|
91
|
+
@type_name ||= begin
|
92
|
+
case descriptor.type.name
|
93
|
+
when :TYPE_MESSAGE, :TYPE_ENUM, :TYPE_GROUP then
|
94
|
+
type_name = modulize(descriptor.type_name)
|
95
|
+
else
|
96
|
+
type_name = descriptor.type.name.to_s.downcase.sub(/type_/, '')
|
97
|
+
type_name = ":#{type_name}"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
private
|
103
|
+
|
104
|
+
def enum_default_value
|
105
|
+
"#{type_name}::#{verbatim_default_value}"
|
106
|
+
end
|
107
|
+
|
108
|
+
def float_double_default_value
|
109
|
+
case verbatim_default_value
|
110
|
+
when PROTO_INFINITY_DEFAULT then
|
111
|
+
RUBY_INFINITY_DEFAULT
|
112
|
+
when PROTO_NEGATIVE_INFINITY_DEFAULT then
|
113
|
+
RUBY_NEGATIVE_INFINITY_DEFAULT
|
114
|
+
when PROTO_NAN_DEFAULT then
|
115
|
+
RUBY_NAN_DEFAULT
|
116
|
+
else
|
117
|
+
verbatim_default_value
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def string_default_value
|
122
|
+
%Q{"#{verbatim_default_value.gsub(/'/, '\\\\\'')}"}
|
123
|
+
end
|
124
|
+
|
125
|
+
def verbatim_default_value
|
126
|
+
descriptor.default_value
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'set'
|
2
|
+
require 'protobuf/generators/base'
|
3
|
+
require 'protobuf/generators/group_generator'
|
4
|
+
|
5
|
+
module Protobuf
|
6
|
+
module Generators
|
7
|
+
class FileGenerator < Base
|
8
|
+
|
9
|
+
attr_reader :output_file
|
10
|
+
|
11
|
+
def initialize(*args)
|
12
|
+
super
|
13
|
+
@output_file = ::Google::Protobuf::Compiler::CodeGeneratorResponse::File.new(:name => file_name)
|
14
|
+
@extension_fields = Hash.new { |h, k| h[k] = [] }
|
15
|
+
@known_messages = []
|
16
|
+
@dangling_messages = {}
|
17
|
+
end
|
18
|
+
|
19
|
+
def file_name
|
20
|
+
convert_filename(descriptor.name, false)
|
21
|
+
end
|
22
|
+
|
23
|
+
def compile
|
24
|
+
run_once(:compile) do
|
25
|
+
map_extensions(descriptor, [ descriptor.package ])
|
26
|
+
extract_dangling_extensions
|
27
|
+
|
28
|
+
print_file_comment
|
29
|
+
print_generic_requires
|
30
|
+
print_import_requires
|
31
|
+
|
32
|
+
print_package do
|
33
|
+
group = GroupGenerator.new(current_indent)
|
34
|
+
group.add_enums(descriptor.enum_type, :namespace => [ descriptor.package ])
|
35
|
+
group.add_message_declarations(descriptor.message_type)
|
36
|
+
group.add_messages(descriptor.message_type, :extension_fields => @extension_fields, :namespace => [ descriptor.package ])
|
37
|
+
group.add_extended_messages(@unknown_extensions)
|
38
|
+
group.add_services(descriptor.service)
|
39
|
+
|
40
|
+
group.add_header(:enum, 'Enum Classes')
|
41
|
+
group.add_header(:message_declaration, 'Message Classes')
|
42
|
+
group.add_header(:message, 'Message Fields')
|
43
|
+
group.add_header(:extended_message, 'Extended Message Fields')
|
44
|
+
group.add_header(:service, 'Service Classes')
|
45
|
+
print group.to_s
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def extract_dangling_extensions
|
52
|
+
@unknown_extensions = @extension_fields.select do |k, v|
|
53
|
+
! @known_messages.include?(k)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def generate_output_file
|
58
|
+
compile
|
59
|
+
output_file.content = to_s
|
60
|
+
output_file
|
61
|
+
end
|
62
|
+
|
63
|
+
# Recursively map out all extensions known in this file.
|
64
|
+
# The key is the type_name of the message being extended, and
|
65
|
+
# the value is an array of field descriptors.
|
66
|
+
#
|
67
|
+
def map_extensions(descriptor, namespaces)
|
68
|
+
# Record all the message descriptor name's we encounter (should be the whole tree).
|
69
|
+
if descriptor.is_a?(::Google::Protobuf::DescriptorProto)
|
70
|
+
if fully_qualified_token?(descriptor.name)
|
71
|
+
@known_messages << descriptor.name
|
72
|
+
else
|
73
|
+
fully_qualified_namespace = ".#{namespaces.join('.')}"
|
74
|
+
@known_messages << fully_qualified_namespace
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
descriptor.extension.each do |field_descriptor|
|
79
|
+
@extension_fields[field_descriptor.extendee] << field_descriptor
|
80
|
+
end
|
81
|
+
|
82
|
+
if descriptor.respond_to_has_and_present?(:message_type)
|
83
|
+
descriptor.message_type.each do |message_descriptor|
|
84
|
+
map_extensions(message_descriptor, (namespaces + [ message_descriptor.name ]))
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
if descriptor.respond_to_has_and_present?(:nested_type)
|
89
|
+
descriptor.nested_type.each do |nested_descriptor|
|
90
|
+
map_extensions(nested_descriptor, (namespaces + [ nested_descriptor.name ]))
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def print_file_comment
|
96
|
+
puts "##"
|
97
|
+
puts "# This file is auto-generated. DO NOT EDIT!"
|
98
|
+
puts "#"
|
99
|
+
end
|
100
|
+
|
101
|
+
def print_generic_requires
|
102
|
+
print_require("protobuf/message")
|
103
|
+
print_require("protobuf/rpc/service") if descriptor.service.count > 0
|
104
|
+
puts
|
105
|
+
end
|
106
|
+
|
107
|
+
def print_import_requires
|
108
|
+
if descriptor.dependency.count > 0
|
109
|
+
header "Imports"
|
110
|
+
|
111
|
+
descriptor.dependency.each do |dependency|
|
112
|
+
print_require(convert_filename(dependency))
|
113
|
+
end
|
114
|
+
|
115
|
+
puts
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def print_package(&block)
|
120
|
+
final = lambda { block.call }
|
121
|
+
namespaces = descriptor.package.split('.')
|
122
|
+
namespaces.reverse.inject(final) { |previous, namespace|
|
123
|
+
lambda { print_module(namespace, &previous) }
|
124
|
+
}.call
|
125
|
+
end
|
126
|
+
|
127
|
+
private
|
128
|
+
|
129
|
+
def convert_filename(filename, for_require = true)
|
130
|
+
filename.sub(/\.proto/, (for_require ? '.pb' : '.pb.rb'))
|
131
|
+
end
|
132
|
+
|
133
|
+
def fully_qualified_token?(token)
|
134
|
+
token[0] == '.'
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|