protobuffy 3.6.0 → 4.0.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 +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +67 -0
- data/.rubocop_todo.yml +145 -0
- data/.travis.yml +25 -5
- data/CHANGES.md +55 -0
- data/CONTRIBUTING.md +1 -1
- data/LICENSE.txt +17 -9
- data/README.md +13 -12
- data/Rakefile +15 -11
- data/bin/protoc-gen-ruby +8 -3
- data/bin/rpc_server +1 -0
- data/examples/lib/example/reverse-client.rb +2 -2
- data/install-protobuf.sh +28 -0
- data/lib/protobuf.rb +57 -53
- data/lib/protobuf/cli.rb +94 -74
- data/lib/protobuf/code_generator.rb +60 -9
- data/lib/protobuf/decoder.rb +19 -65
- data/lib/protobuf/deprecation.rb +117 -0
- data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +11 -1
- data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +55 -3
- data/lib/protobuf/encoder.rb +13 -53
- data/lib/protobuf/enum.rb +58 -63
- data/lib/protobuf/field.rb +4 -4
- data/lib/protobuf/field/base_field.rb +101 -173
- data/lib/protobuf/field/bool_field.rb +17 -11
- data/lib/protobuf/field/bytes_field.rb +21 -35
- data/lib/protobuf/field/double_field.rb +0 -1
- data/lib/protobuf/field/enum_field.rb +23 -22
- data/lib/protobuf/field/field_array.rb +5 -4
- data/lib/protobuf/field/fixed32_field.rb +1 -1
- data/lib/protobuf/field/fixed64_field.rb +0 -1
- data/lib/protobuf/field/float_field.rb +4 -1
- data/lib/protobuf/field/int32_field.rb +0 -1
- data/lib/protobuf/field/int64_field.rb +0 -1
- data/lib/protobuf/field/integer_field.rb +0 -1
- data/lib/protobuf/field/message_field.rb +13 -28
- data/lib/protobuf/field/sfixed32_field.rb +0 -1
- data/lib/protobuf/field/sfixed64_field.rb +0 -1
- data/lib/protobuf/field/signed_integer_field.rb +0 -1
- data/lib/protobuf/field/sint32_field.rb +0 -1
- data/lib/protobuf/field/sint64_field.rb +0 -1
- data/lib/protobuf/field/string_field.rb +2 -4
- data/lib/protobuf/field/uint32_field.rb +0 -1
- data/lib/protobuf/field/uint64_field.rb +0 -1
- data/lib/protobuf/field/varint_field.rb +30 -13
- data/lib/protobuf/generators/base.rb +30 -16
- data/lib/protobuf/generators/enum_generator.rb +6 -9
- data/lib/protobuf/generators/extension_generator.rb +1 -2
- data/lib/protobuf/generators/field_generator.rb +25 -13
- data/lib/protobuf/generators/file_generator.rb +157 -35
- data/lib/protobuf/generators/group_generator.rb +22 -17
- data/lib/protobuf/generators/message_generator.rb +13 -14
- data/lib/protobuf/generators/option_generator.rb +17 -0
- data/lib/protobuf/generators/printable.rb +12 -13
- data/lib/protobuf/generators/service_generator.rb +2 -3
- data/lib/protobuf/http.rb +2 -2
- data/lib/protobuf/lifecycle.rb +20 -33
- data/lib/protobuf/logging.rb +39 -0
- data/lib/protobuf/message.rb +114 -47
- data/lib/protobuf/message/fields.rb +170 -88
- data/lib/protobuf/message/serialization.rb +19 -18
- data/lib/protobuf/optionable.rb +53 -6
- data/lib/protobuf/rpc/buffer.rb +18 -19
- data/lib/protobuf/rpc/client.rb +22 -50
- data/lib/protobuf/rpc/connectors/base.rb +177 -12
- data/lib/protobuf/rpc/connectors/http.rb +14 -9
- data/lib/protobuf/rpc/connectors/ping.rb +89 -0
- data/lib/protobuf/rpc/connectors/socket.rb +13 -8
- data/lib/protobuf/rpc/connectors/zmq.rb +178 -73
- data/lib/protobuf/rpc/dynamic_discovery.pb.rb +4 -1
- data/lib/protobuf/rpc/env.rb +12 -12
- data/lib/protobuf/rpc/error.rb +3 -3
- data/lib/protobuf/rpc/error/client_error.rb +4 -4
- data/lib/protobuf/rpc/error/server_error.rb +9 -9
- data/lib/protobuf/rpc/middleware/exception_handler.rb +6 -2
- data/lib/protobuf/rpc/middleware/logger.rb +8 -4
- data/lib/protobuf/rpc/middleware/request_decoder.rb +17 -21
- data/lib/protobuf/rpc/middleware/response_encoder.rb +22 -27
- data/lib/protobuf/rpc/middleware/statsd.rb +3 -3
- data/lib/protobuf/rpc/rpc.pb.rb +4 -1
- data/lib/protobuf/rpc/server.rb +1 -1
- data/lib/protobuf/rpc/servers/http/server.rb +19 -17
- data/lib/protobuf/rpc/servers/socket/server.rb +78 -70
- data/lib/protobuf/rpc/servers/socket/worker.rb +4 -4
- data/lib/protobuf/rpc/servers/socket_runner.rb +27 -15
- data/lib/protobuf/rpc/servers/zmq/broker.rb +70 -31
- data/lib/protobuf/rpc/servers/zmq/server.rb +55 -47
- data/lib/protobuf/rpc/servers/zmq/util.rb +14 -13
- data/lib/protobuf/rpc/servers/zmq/worker.rb +16 -16
- data/lib/protobuf/rpc/servers/zmq_runner.rb +26 -7
- data/lib/protobuf/rpc/service.rb +21 -27
- data/lib/protobuf/rpc/service_directory.rb +43 -27
- data/lib/protobuf/rpc/service_dispatcher.rb +9 -10
- data/lib/protobuf/rpc/service_filters.rb +32 -55
- data/lib/protobuf/rpc/stat.rb +4 -8
- data/lib/protobuf/socket.rb +1 -2
- data/lib/protobuf/tasks/compile.rake +3 -4
- data/lib/protobuf/varint.rb +9 -0
- data/lib/protobuf/varint_pure.rb +13 -0
- data/lib/protobuf/version.rb +1 -1
- data/lib/protobuf/zmq.rb +2 -2
- data/proto/google/protobuf/descriptor.proto +190 -31
- data/protobuffy.gemspec +30 -17
- data/spec/benchmark/tasks.rb +27 -19
- data/spec/bin/protoc-gen-ruby_spec.rb +11 -6
- data/spec/encoding/all_types_spec.rb +96 -84
- data/spec/encoding/extreme_values_spec.rb +0 -0
- data/spec/functional/class_inheritance_spec.rb +52 -0
- data/spec/functional/code_generator_spec.rb +38 -0
- data/spec/functional/socket_server_spec.rb +15 -15
- data/spec/functional/zmq_server_spec.rb +29 -27
- data/spec/lib/protobuf/cli_spec.rb +82 -67
- data/spec/lib/protobuf/code_generator_spec.rb +37 -10
- data/spec/lib/protobuf/enum_spec.rb +77 -46
- data/spec/lib/protobuf/field/bool_field_spec.rb +91 -0
- data/spec/lib/protobuf/field/double_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/enum_field_spec.rb +26 -0
- data/spec/lib/protobuf/field/field_array_spec.rb +69 -0
- data/spec/lib/protobuf/field/fixed32_field_spec.rb +7 -0
- data/spec/lib/protobuf/field/fixed64_field_spec.rb +7 -0
- data/spec/lib/protobuf/field/float_field_spec.rb +90 -0
- data/spec/lib/protobuf/field/int32_field_spec.rb +114 -1
- data/spec/lib/protobuf/field/int64_field_spec.rb +7 -0
- data/spec/lib/protobuf/field/message_field_spec.rb +132 -0
- data/spec/lib/protobuf/field/sfixed32_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/sfixed64_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/sint32_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/sint64_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/string_field_spec.rb +44 -11
- data/spec/lib/protobuf/field/uint32_field_spec.rb +7 -0
- data/spec/lib/protobuf/field/uint64_field_spec.rb +7 -0
- data/spec/lib/protobuf/field_spec.rb +4 -6
- data/spec/lib/protobuf/generators/base_spec.rb +80 -13
- data/spec/lib/protobuf/generators/enum_generator_spec.rb +35 -21
- data/spec/lib/protobuf/generators/extension_generator_spec.rb +12 -13
- data/spec/lib/protobuf/generators/field_generator_spec.rb +73 -21
- data/spec/lib/protobuf/generators/file_generator_spec.rb +89 -6
- data/spec/lib/protobuf/generators/service_generator_spec.rb +25 -13
- data/spec/lib/protobuf/lifecycle_spec.rb +25 -20
- data/spec/lib/protobuf/message_spec.rb +578 -79
- data/spec/lib/protobuf/optionable_spec.rb +202 -26
- data/spec/lib/protobuf/rpc/client_spec.rb +16 -16
- data/spec/lib/protobuf/rpc/connectors/base_spec.rb +167 -13
- data/spec/lib/protobuf/rpc/connectors/connector_spec.rb +4 -5
- data/spec/lib/protobuf/rpc/connectors/http_spec.rb +13 -11
- data/spec/lib/protobuf/rpc/connectors/ping_spec.rb +69 -0
- data/spec/lib/protobuf/rpc/connectors/socket_spec.rb +6 -7
- data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +35 -52
- data/spec/lib/protobuf/rpc/middleware/exception_handler_spec.rb +10 -10
- data/spec/lib/protobuf/rpc/middleware/logger_spec.rb +11 -11
- data/spec/lib/protobuf/rpc/middleware/request_decoder_spec.rb +23 -23
- data/spec/lib/protobuf/rpc/middleware/response_encoder_spec.rb +11 -11
- data/spec/lib/protobuf/rpc/middleware/statsd_spec.rb +6 -6
- data/spec/lib/protobuf/rpc/servers/http/server_spec.rb +47 -44
- data/spec/lib/protobuf/rpc/servers/socket_server_spec.rb +6 -6
- data/spec/lib/protobuf/rpc/servers/zmq/server_spec.rb +12 -10
- data/spec/lib/protobuf/rpc/servers/zmq/util_spec.rb +11 -11
- data/spec/lib/protobuf/rpc/servers/zmq/worker_spec.rb +7 -7
- data/spec/lib/protobuf/rpc/service_directory_spec.rb +47 -49
- data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +8 -25
- data/spec/lib/protobuf/rpc/service_filters_spec.rb +102 -69
- data/spec/lib/protobuf/rpc/service_spec.rb +37 -36
- data/spec/lib/protobuf/rpc/stat_spec.rb +7 -9
- data/spec/lib/protobuf/varint_spec.rb +29 -0
- data/spec/lib/protobuf_spec.rb +55 -28
- data/spec/spec_helper.rb +12 -27
- data/spec/support/all.rb +0 -1
- data/spec/support/packed_field.rb +4 -3
- data/spec/support/{test → protos}/all_types.data.bin +0 -0
- data/spec/support/{test → protos}/all_types.data.txt +0 -0
- data/spec/support/{test → protos}/enum.pb.rb +8 -4
- data/spec/support/{test → protos}/enum.proto +4 -1
- data/spec/support/{test → protos}/extreme_values.data.bin +0 -0
- data/spec/support/protos/google_unittest.bin +0 -0
- data/spec/support/protos/google_unittest.pb.rb +798 -0
- data/spec/support/{test → protos}/google_unittest.proto +237 -66
- data/spec/support/protos/google_unittest_custom_options.bin +0 -0
- data/spec/support/protos/google_unittest_custom_options.pb.rb +268 -0
- data/spec/support/protos/google_unittest_custom_options.proto +424 -0
- data/spec/support/protos/google_unittest_import.pb.rb +55 -0
- data/spec/support/{test → protos}/google_unittest_import.proto +19 -10
- data/spec/support/protos/google_unittest_import_public.pb.rb +31 -0
- data/spec/support/{test → protos}/google_unittest_import_public.proto +8 -5
- data/spec/support/{test → protos}/multi_field_extensions.pb.rb +5 -2
- data/spec/support/{test → protos}/multi_field_extensions.proto +2 -0
- data/spec/support/{test → protos}/resource.pb.rb +47 -11
- data/spec/support/{test → protos}/resource.proto +24 -1
- data/spec/support/resource_service.rb +23 -0
- data/spec/support/server.rb +32 -61
- metadata +119 -59
- data/lib/protobuf/deprecator.rb +0 -42
- data/lib/protobuf/logger.rb +0 -93
- data/lib/protobuf/rpc/connector.rb +0 -21
- data/lib/protobuf/rpc/connectors/common.rb +0 -172
- data/spec/data/data.bin +0 -3
- data/spec/data/types.bin +0 -0
- data/spec/lib/protobuf/logger_spec.rb +0 -145
- data/spec/lib/protobuf/rpc/connector_spec.rb +0 -26
- data/spec/lib/protobuf/rpc/connectors/common_spec.rb +0 -170
- data/spec/support/test/defaults.pb.rb +0 -25
- data/spec/support/test/defaults.proto +0 -9
- data/spec/support/test/extended.pb.rb +0 -22
- data/spec/support/test/extended.proto +0 -10
- data/spec/support/test/google_unittest.pb.rb +0 -543
- data/spec/support/test/google_unittest_import.pb.rb +0 -37
- data/spec/support/test/google_unittest_import_public.pb.rb +0 -8
- data/spec/support/test/resource_service.rb +0 -26
- data/spec/support/tolerance_matcher.rb +0 -40
@@ -8,6 +8,7 @@ module Protobuf
|
|
8
8
|
# Constants
|
9
9
|
#
|
10
10
|
|
11
|
+
CACHE_LIMIT = 2048
|
11
12
|
INT32_MAX = 2**31 - 1
|
12
13
|
INT32_MIN = -2**31
|
13
14
|
INT64_MAX = 2**63 - 1
|
@@ -23,7 +24,16 @@ module Protobuf
|
|
23
24
|
0
|
24
25
|
end
|
25
26
|
|
26
|
-
|
27
|
+
# Because all tags and enums are calculated as VarInt it is "most common" to have
|
28
|
+
# values < CACHE_LIMIT (low numbers) which is defaulting to 1024
|
29
|
+
def self.cached_varint(value)
|
30
|
+
@_varint_cache ||= {}
|
31
|
+
(@_varint_cache[value] ||= encode(value, false)).dup
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.encode(value, use_cache = true)
|
35
|
+
return cached_varint(value) if use_cache && value >= 0 && value <= CACHE_LIMIT
|
36
|
+
|
27
37
|
bytes = []
|
28
38
|
until value < 128
|
29
39
|
bytes << (0x80 | (value & 0x7f))
|
@@ -32,30 +42,38 @@ module Protobuf
|
|
32
42
|
(bytes << value).pack('C*')
|
33
43
|
end
|
34
44
|
|
45
|
+
# Load the cache of VarInts on load of file
|
46
|
+
(0..CACHE_LIMIT).each do |cached_value|
|
47
|
+
cached_varint(cached_value)
|
48
|
+
end
|
49
|
+
|
35
50
|
##
|
36
51
|
# Public Instance Methods
|
37
52
|
#
|
38
|
-
|
39
53
|
def acceptable?(val)
|
40
|
-
|
54
|
+
int_val = if val.is_a?(Integer)
|
55
|
+
return true if val >= 0 && val < INT32_MAX # return quickly for smallest integer size, hot code path
|
56
|
+
val
|
57
|
+
else
|
58
|
+
coerce!(val)
|
59
|
+
end
|
60
|
+
|
61
|
+
int_val >= self.class.min && int_val <= self.class.max
|
41
62
|
rescue
|
42
63
|
false
|
43
64
|
end
|
44
65
|
|
66
|
+
def coerce!(val)
|
67
|
+
return val.to_i if val.is_a?(Numeric)
|
68
|
+
Integer(val, 10)
|
69
|
+
end
|
70
|
+
|
45
71
|
def decode(value)
|
46
72
|
value
|
47
73
|
end
|
48
74
|
|
49
75
|
def encode(value)
|
50
|
-
|
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*')
|
76
|
+
::Protobuf::Field::VarintField.encode(value)
|
59
77
|
end
|
60
78
|
|
61
79
|
def wire_type
|
@@ -65,4 +83,3 @@ module Protobuf
|
|
65
83
|
end
|
66
84
|
end
|
67
85
|
end
|
68
|
-
|
@@ -15,16 +15,10 @@ module Protobuf
|
|
15
15
|
end
|
16
16
|
|
17
17
|
unless ENV.key?('PB_NO_TAG_WARNINGS')
|
18
|
-
|
19
|
-
if range.respond_to?(:size)
|
20
|
-
expected_size = range.size
|
21
|
-
else
|
22
|
-
expected_size = range.to_a.size
|
23
|
-
end
|
24
|
-
|
18
|
+
expected_size = tags.max - tags.min + 1
|
25
19
|
if tags.size < expected_size
|
26
20
|
::Protobuf::CodeGenerator.print_tag_warning_suppress
|
27
|
-
::Protobuf::CodeGenerator.warn("#{type_name} object should have #{expected_size} tags (#{
|
21
|
+
::Protobuf::CodeGenerator.warn("#{type_name} object should have #{expected_size} tags (#{tags.min}..#{tags.max}), but found #{tags.size} tags.")
|
28
22
|
end
|
29
23
|
end
|
30
24
|
end
|
@@ -42,18 +36,18 @@ module Protobuf
|
|
42
36
|
".#{type_namespace.join('.')}"
|
43
37
|
end
|
44
38
|
|
45
|
-
def run_once(label
|
39
|
+
def run_once(label)
|
46
40
|
tracker_ivar = "@_#{label}_compiled"
|
47
41
|
value_ivar = "@_#{label}_compiled_value"
|
48
42
|
|
49
43
|
if instance_variable_get(tracker_ivar)
|
50
44
|
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
45
|
end
|
46
|
+
|
47
|
+
return_value = yield
|
48
|
+
instance_variable_set(tracker_ivar, true)
|
49
|
+
instance_variable_set(value_ivar, return_value)
|
50
|
+
return_value
|
57
51
|
end
|
58
52
|
|
59
53
|
def to_s
|
@@ -62,10 +56,30 @@ module Protobuf
|
|
62
56
|
end
|
63
57
|
|
64
58
|
def type_namespace
|
65
|
-
@type_namespace ||= @namespace + [
|
59
|
+
@type_namespace ||= @namespace + [descriptor.name]
|
66
60
|
end
|
67
61
|
|
62
|
+
def serialize_value(value)
|
63
|
+
case value
|
64
|
+
when Message
|
65
|
+
fields = value.each_field.map do |field, inner_value|
|
66
|
+
next unless value.field?(field.name)
|
67
|
+
serialized_inner_value = serialize_value(inner_value)
|
68
|
+
"#{field.fully_qualified_name.inspect} => #{serialized_inner_value}"
|
69
|
+
end.compact
|
70
|
+
"{ #{fields.join(', ')} }"
|
71
|
+
when Enum
|
72
|
+
"::#{value.parent_class}::#{value.name}"
|
73
|
+
when String
|
74
|
+
value.inspect
|
75
|
+
when nil
|
76
|
+
"nil"
|
77
|
+
when Array
|
78
|
+
'[' + value.map { |x| serialize_value(x) }.join(', ') + ']'
|
79
|
+
else
|
80
|
+
value
|
81
|
+
end
|
82
|
+
end
|
68
83
|
end
|
69
84
|
end
|
70
85
|
end
|
71
|
-
|
@@ -1,20 +1,17 @@
|
|
1
1
|
require 'protobuf/generators/base'
|
2
|
+
require 'protobuf/generators/option_generator'
|
2
3
|
|
3
4
|
module Protobuf
|
4
5
|
module Generators
|
5
6
|
class EnumGenerator < Base
|
6
7
|
|
7
|
-
def allow_alias?
|
8
|
-
descriptor.options.try(:allow_alias!) { false }
|
9
|
-
end
|
10
|
-
|
11
8
|
def compile
|
12
9
|
run_once(:compile) do
|
13
10
|
tags = []
|
14
11
|
|
15
12
|
print_class(descriptor.name, :enum) do
|
16
|
-
if
|
17
|
-
|
13
|
+
if descriptor.options
|
14
|
+
print OptionGenerator.new(descriptor.options, current_indent).to_s
|
18
15
|
puts
|
19
16
|
end
|
20
17
|
|
@@ -24,7 +21,7 @@ module Protobuf
|
|
24
21
|
end
|
25
22
|
end
|
26
23
|
|
27
|
-
unless allow_alias
|
24
|
+
unless descriptor.options.try(:allow_alias)
|
28
25
|
self.class.validate_tags(fully_qualified_type_namespace, tags)
|
29
26
|
end
|
30
27
|
end
|
@@ -32,11 +29,11 @@ module Protobuf
|
|
32
29
|
|
33
30
|
def build_value(enum_value_descriptor)
|
34
31
|
name = enum_value_descriptor.name
|
32
|
+
name.upcase! if ENV.key?('PB_UPCASE_ENUMS')
|
35
33
|
number = enum_value_descriptor.number
|
36
|
-
|
34
|
+
"define :#{name}, #{number}"
|
37
35
|
end
|
38
36
|
|
39
37
|
end
|
40
38
|
end
|
41
39
|
end
|
42
|
-
|
@@ -16,7 +16,7 @@ module Protobuf
|
|
16
16
|
print_class(@message_type, :message) do
|
17
17
|
group = GroupGenerator.new(current_indent)
|
18
18
|
group.add_extension_fields(@field_descriptors)
|
19
|
-
group.order = [
|
19
|
+
group.order = [:extension_field]
|
20
20
|
print group.to_s
|
21
21
|
end
|
22
22
|
end
|
@@ -25,4 +25,3 @@ module Protobuf
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
28
|
-
|
@@ -7,9 +7,9 @@ module Protobuf
|
|
7
7
|
##
|
8
8
|
# Constants
|
9
9
|
#
|
10
|
-
PROTO_INFINITY_DEFAULT = /^inf$/i
|
11
|
-
PROTO_NEGATIVE_INFINITY_DEFAULT = /^-inf$/i
|
12
|
-
PROTO_NAN_DEFAULT = /^nan$/i
|
10
|
+
PROTO_INFINITY_DEFAULT = /^inf$/i
|
11
|
+
PROTO_NEGATIVE_INFINITY_DEFAULT = /^-inf$/i
|
12
|
+
PROTO_NAN_DEFAULT = /^nan$/i
|
13
13
|
RUBY_INFINITY_DEFAULT = '::Float::INFINITY'.freeze
|
14
14
|
RUBY_NEGATIVE_INFINITY_DEFAULT = '-::Float::INFINITY'.freeze
|
15
15
|
RUBY_NAN_DEFAULT = '::Float::NAN'.freeze
|
@@ -20,18 +20,24 @@ module Protobuf
|
|
20
20
|
attr_reader :field_options
|
21
21
|
|
22
22
|
def applicable_options
|
23
|
-
|
23
|
+
# Note on the strange use of `#inspect`:
|
24
|
+
# :boom.inspect #=> ":boom"
|
25
|
+
# :".boom.foo".inspect #=> ":\".boom.foo\""
|
26
|
+
# An alternative to `#inspect` would be always adding double quotes,
|
27
|
+
# but the generatated code looks un-idiomatic:
|
28
|
+
# ":\"#{:boom}\"" #=> ":\"boom\"" <-- Note the unnecessary double quotes
|
29
|
+
@applicable_options ||= field_options.map { |k, v| "#{k.inspect} => #{v}" }
|
24
30
|
end
|
25
31
|
|
26
32
|
def default_value
|
27
33
|
@default_value ||= begin
|
28
34
|
if defaulted?
|
29
35
|
case descriptor.type.name
|
30
|
-
when :TYPE_ENUM
|
36
|
+
when :TYPE_ENUM
|
31
37
|
enum_default_value
|
32
|
-
when :TYPE_STRING, :TYPE_BYTES
|
38
|
+
when :TYPE_STRING, :TYPE_BYTES
|
33
39
|
string_default_value
|
34
|
-
when :TYPE_FLOAT, :TYPE_DOUBLE
|
40
|
+
when :TYPE_FLOAT, :TYPE_DOUBLE
|
35
41
|
float_double_default_value
|
36
42
|
else
|
37
43
|
verbatim_default_value
|
@@ -54,7 +60,7 @@ module Protobuf
|
|
54
60
|
|
55
61
|
def compile
|
56
62
|
run_once(:compile) do
|
57
|
-
field_definition = [
|
63
|
+
field_definition = ["#{label} #{type_name}", name, number, applicable_options]
|
58
64
|
puts field_definition.flatten.compact.join(', ')
|
59
65
|
end
|
60
66
|
end
|
@@ -64,7 +70,7 @@ module Protobuf
|
|
64
70
|
end
|
65
71
|
|
66
72
|
def name
|
67
|
-
@name ||=
|
73
|
+
@name ||= descriptor.name.to_sym.inspect
|
68
74
|
end
|
69
75
|
|
70
76
|
def number
|
@@ -78,6 +84,13 @@ module Protobuf
|
|
78
84
|
opts[:packed] = 'true' if packed?
|
79
85
|
opts[:deprecated] = 'true' if deprecated?
|
80
86
|
opts[:extension] = 'true' if extension?
|
87
|
+
if descriptor.options
|
88
|
+
descriptor.options.each_field do |field_option|
|
89
|
+
next unless descriptor.options.field?(field_option.name)
|
90
|
+
option_value = descriptor.options[field_option.name]
|
91
|
+
opts[field_option.fully_qualified_name] = serialize_value(option_value)
|
92
|
+
end
|
93
|
+
end
|
81
94
|
opts
|
82
95
|
end
|
83
96
|
end
|
@@ -91,10 +104,10 @@ module Protobuf
|
|
91
104
|
@type_name ||= begin
|
92
105
|
case descriptor.type.name
|
93
106
|
when :TYPE_MESSAGE, :TYPE_ENUM, :TYPE_GROUP then
|
94
|
-
|
107
|
+
modulize(descriptor.type_name)
|
95
108
|
else
|
96
109
|
type_name = descriptor.type.name.to_s.downcase.sub(/type_/, '')
|
97
|
-
|
110
|
+
":#{type_name}"
|
98
111
|
end
|
99
112
|
end
|
100
113
|
end
|
@@ -119,7 +132,7 @@ module Protobuf
|
|
119
132
|
end
|
120
133
|
|
121
134
|
def string_default_value
|
122
|
-
%
|
135
|
+
%("#{verbatim_default_value.gsub(/'/, '\\\\\'')}")
|
123
136
|
end
|
124
137
|
|
125
138
|
def verbatim_default_value
|
@@ -129,4 +142,3 @@ module Protobuf
|
|
129
142
|
end
|
130
143
|
end
|
131
144
|
end
|
132
|
-
|
@@ -12,7 +12,8 @@ module Protobuf
|
|
12
12
|
super
|
13
13
|
@output_file = ::Google::Protobuf::Compiler::CodeGeneratorResponse::File.new(:name => file_name)
|
14
14
|
@extension_fields = Hash.new { |h, k| h[k] = [] }
|
15
|
-
@known_messages =
|
15
|
+
@known_messages = {}
|
16
|
+
@known_enums = {}
|
16
17
|
@dangling_messages = {}
|
17
18
|
end
|
18
19
|
|
@@ -22,23 +23,25 @@ module Protobuf
|
|
22
23
|
|
23
24
|
def compile
|
24
25
|
run_once(:compile) do
|
25
|
-
map_extensions(descriptor, [
|
26
|
-
extract_dangling_extensions
|
26
|
+
map_extensions(descriptor, [descriptor.package])
|
27
27
|
|
28
28
|
print_file_comment
|
29
29
|
print_generic_requires
|
30
30
|
print_import_requires
|
31
31
|
|
32
32
|
print_package do
|
33
|
+
inject_optionable
|
33
34
|
group = GroupGenerator.new(current_indent)
|
34
|
-
group.
|
35
|
+
group.add_options(descriptor.options) if descriptor.options
|
36
|
+
group.add_enums(descriptor.enum_type, :namespace => [descriptor.package])
|
35
37
|
group.add_message_declarations(descriptor.message_type)
|
36
|
-
group.add_messages(descriptor.message_type, :extension_fields => @extension_fields, :namespace => [
|
37
|
-
group.add_extended_messages(
|
38
|
+
group.add_messages(descriptor.message_type, :extension_fields => @extension_fields, :namespace => [descriptor.package])
|
39
|
+
group.add_extended_messages(unknown_extensions)
|
38
40
|
group.add_services(descriptor.service)
|
39
41
|
|
40
42
|
group.add_header(:enum, 'Enum Classes')
|
41
43
|
group.add_header(:message_declaration, 'Message Classes')
|
44
|
+
group.add_header(:options, 'File Options')
|
42
45
|
group.add_header(:message, 'Message Fields')
|
43
46
|
group.add_header(:extended_message, 'Extended Message Fields')
|
44
47
|
group.add_header(:service, 'Service Classes')
|
@@ -48,9 +51,17 @@ module Protobuf
|
|
48
51
|
end
|
49
52
|
end
|
50
53
|
|
51
|
-
def
|
52
|
-
@unknown_extensions
|
53
|
-
|
54
|
+
def unknown_extensions
|
55
|
+
@unknown_extensions ||= @extension_fields.map do |message_name, fields|
|
56
|
+
message_klass = modulize(message_name).safe_constantize
|
57
|
+
if message_klass
|
58
|
+
unknown_fields = fields.reject do |field|
|
59
|
+
@known_messages[message_name] && message_klass.get_field(field.name, true)
|
60
|
+
end
|
61
|
+
[message_name, unknown_fields]
|
62
|
+
else
|
63
|
+
[message_name, fields]
|
64
|
+
end
|
54
65
|
end
|
55
66
|
end
|
56
67
|
|
@@ -65,63 +76,101 @@ module Protobuf
|
|
65
76
|
# the value is an array of field descriptors.
|
66
77
|
#
|
67
78
|
def map_extensions(descriptor, namespaces)
|
79
|
+
if fully_qualified_token?(descriptor.name)
|
80
|
+
fully_qualified_namespace = descriptor.name
|
81
|
+
elsif !(namespace = namespaces.reject(&:empty?).join(".")).empty?
|
82
|
+
fully_qualified_namespace = ".#{namespace}"
|
83
|
+
end
|
68
84
|
# Record all the message descriptor name's we encounter (should be the whole tree).
|
69
85
|
if descriptor.is_a?(::Google::Protobuf::DescriptorProto)
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
@known_messages << fully_qualified_namespace
|
75
|
-
end
|
86
|
+
@known_messages[fully_qualified_namespace || descriptor.name] = descriptor
|
87
|
+
elsif descriptor.is_a?(::Google::Protobuf::EnumDescriptorProto)
|
88
|
+
@known_enums[fully_qualified_namespace || descriptor.name] = descriptor
|
89
|
+
return
|
76
90
|
end
|
77
91
|
|
78
92
|
descriptor.extension.each do |field_descriptor|
|
93
|
+
unless fully_qualified_token?(field_descriptor.name) && fully_qualified_namespace
|
94
|
+
field_descriptor.name = "#{fully_qualified_namespace}.#{field_descriptor.name}"
|
95
|
+
end
|
79
96
|
@extension_fields[field_descriptor.extendee] << field_descriptor
|
80
97
|
end
|
81
98
|
|
82
|
-
|
83
|
-
descriptor.
|
84
|
-
map_extensions(message_descriptor, (namespaces + [ message_descriptor.name ]))
|
85
|
-
end
|
86
|
-
end
|
99
|
+
[:message_type, :nested_type, :enum_type].each do |type|
|
100
|
+
next unless descriptor.respond_to_has_and_present?(type)
|
87
101
|
|
88
|
-
|
89
|
-
|
90
|
-
map_extensions(nested_descriptor, (namespaces + [ nested_descriptor.name ]))
|
102
|
+
descriptor.public_send(type).each do |type_descriptor|
|
103
|
+
map_extensions(type_descriptor, (namespaces + [type_descriptor.name]))
|
91
104
|
end
|
92
105
|
end
|
93
106
|
end
|
94
107
|
|
95
108
|
def print_file_comment
|
109
|
+
puts "# encoding: utf-8"
|
110
|
+
puts
|
96
111
|
puts "##"
|
97
112
|
puts "# This file is auto-generated. DO NOT EDIT!"
|
98
113
|
puts "#"
|
99
114
|
end
|
100
115
|
|
101
116
|
def print_generic_requires
|
102
|
-
print_require("protobuf
|
117
|
+
print_require("protobuf")
|
103
118
|
print_require("protobuf/rpc/service") if descriptor.service.count > 0
|
104
119
|
puts
|
105
120
|
end
|
106
121
|
|
107
122
|
def print_import_requires
|
108
|
-
if descriptor.dependency.
|
109
|
-
header "Imports"
|
123
|
+
return if descriptor.dependency.empty?
|
110
124
|
|
111
|
-
|
112
|
-
print_require(convert_filename(dependency))
|
113
|
-
end
|
125
|
+
header "Imports"
|
114
126
|
|
115
|
-
|
127
|
+
descriptor.dependency.each do |dependency|
|
128
|
+
print_require(convert_filename(dependency))
|
116
129
|
end
|
130
|
+
|
131
|
+
puts
|
117
132
|
end
|
118
133
|
|
119
134
|
def print_package(&block)
|
120
|
-
final = lambda { block.call }
|
121
135
|
namespaces = descriptor.package.split('.')
|
122
|
-
namespaces.
|
123
|
-
|
124
|
-
|
136
|
+
if namespaces.empty? && ENV.key?('PB_ALLOW_DEFAULT_PACKAGE_NAME')
|
137
|
+
namespaces = [File.basename(descriptor.name).sub('.proto', '')]
|
138
|
+
end
|
139
|
+
namespaces.reverse.reduce(block) do |previous, namespace|
|
140
|
+
-> { print_module(namespace, &previous) }
|
141
|
+
end.call
|
142
|
+
end
|
143
|
+
|
144
|
+
def eval_unknown_extensions!
|
145
|
+
@@evaled_dependencies ||= Set.new # rubocop:disable Style/ClassVars
|
146
|
+
@@all_messages ||= {} # rubocop:disable Style/ClassVars
|
147
|
+
@@all_enums ||= {} # rubocop:disable Style/ClassVars
|
148
|
+
|
149
|
+
map_extensions(descriptor, [descriptor.package])
|
150
|
+
@known_messages.each do |name, descriptor|
|
151
|
+
@@all_messages[name] = descriptor
|
152
|
+
end
|
153
|
+
@known_enums.each do |name, descriptor|
|
154
|
+
@@all_enums[name] = descriptor
|
155
|
+
end
|
156
|
+
|
157
|
+
# create package namespace
|
158
|
+
print_package {}
|
159
|
+
eval_code
|
160
|
+
|
161
|
+
unknown_extensions.each do |extendee, fields|
|
162
|
+
eval_dependencies(extendee)
|
163
|
+
fields.each do |field|
|
164
|
+
eval_dependencies(field.type_name)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
group = GroupGenerator.new(0)
|
168
|
+
group.add_extended_messages(unknown_extensions, false)
|
169
|
+
print group.to_s
|
170
|
+
eval_code
|
171
|
+
rescue => e
|
172
|
+
warn "Error loading unknown extensions #{descriptor.name.inspect} error=#{e}"
|
173
|
+
raise e
|
125
174
|
end
|
126
175
|
|
127
176
|
private
|
@@ -134,7 +183,80 @@ module Protobuf
|
|
134
183
|
token[0] == '.'
|
135
184
|
end
|
136
185
|
|
186
|
+
def eval_dependencies(name, namespace = nil)
|
187
|
+
name = "#{namespace}.#{name}" if namespace && !fully_qualified_token?(name)
|
188
|
+
return if name.empty? || @@evaled_dependencies.include?(name) || modulize(name).safe_constantize
|
189
|
+
|
190
|
+
# if name = .foo.bar.Baz look for classes / modules named ::Foo::Bar and ::Foo
|
191
|
+
# module == pure namespace (e.g. the descriptor package name)
|
192
|
+
# class == nested messages
|
193
|
+
create_ruby_namespace_heiarchy(name)
|
194
|
+
|
195
|
+
if (message = @@all_messages[name])
|
196
|
+
# Create the blank namespace in case there are nested types
|
197
|
+
eval_message_code(name)
|
198
|
+
|
199
|
+
message.nested_type.each do |nested_type|
|
200
|
+
eval_dependencies(nested_type.name, name) unless nested_type.name.empty?
|
201
|
+
end
|
202
|
+
message.field.each do |field|
|
203
|
+
eval_dependencies(field.type_name, name) unless field.type_name.empty?
|
204
|
+
end
|
205
|
+
message.enum_type.each do |enum_type|
|
206
|
+
eval_dependencies(enum_type.name, name)
|
207
|
+
end
|
208
|
+
|
209
|
+
# Check @@evaled_dependencies again in case there was a dependency
|
210
|
+
# loop that already loaded this message
|
211
|
+
return if @@evaled_dependencies.include?(name)
|
212
|
+
eval_message_code(name, message.field)
|
213
|
+
@@evaled_dependencies << name
|
214
|
+
|
215
|
+
elsif (enum = @@all_enums[name])
|
216
|
+
# Check @@evaled_dependencies again in case there was a dependency
|
217
|
+
# loop that already loaded this enum
|
218
|
+
return if @@evaled_dependencies.include?(name)
|
219
|
+
namespace = name.split(".")
|
220
|
+
eval_enum_code(enum, namespace[0..-2].join("."))
|
221
|
+
@@evaled_dependencies << name
|
222
|
+
else
|
223
|
+
fail "Error loading unknown dependencies, could not find message or enum #{name.inspect}"
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
def eval_message_code(fully_qualified_namespace, fields = [])
|
228
|
+
group = GroupGenerator.new(0)
|
229
|
+
group.add_extended_messages({ fully_qualified_namespace => fields }, false)
|
230
|
+
print group.to_s
|
231
|
+
eval_code
|
232
|
+
end
|
233
|
+
|
234
|
+
def eval_enum_code(enum, fully_qualified_namespace)
|
235
|
+
group = GroupGenerator.new(0)
|
236
|
+
group.add_enums([enum], :namespace => [fully_qualified_namespace])
|
237
|
+
print group.to_s
|
238
|
+
eval_code(modulize(fully_qualified_namespace).safe_constantize || Object)
|
239
|
+
end
|
240
|
+
|
241
|
+
def eval_code(context = Object)
|
242
|
+
warn "#{context.inspect}.module_eval #{print_contents.inspect}" if ENV['PB_DEBUG']
|
243
|
+
context.module_eval print_contents.to_s
|
244
|
+
@io.truncate(0)
|
245
|
+
@io.rewind
|
246
|
+
end
|
247
|
+
|
248
|
+
def create_ruby_namespace_heiarchy(namespace)
|
249
|
+
loop do
|
250
|
+
namespace, _match, _tail = namespace.rpartition(".")
|
251
|
+
break if namespace.empty?
|
252
|
+
eval_dependencies(namespace)
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
def inject_optionable
|
257
|
+
return if descriptor.package.empty? && !ENV.key?('PB_ALLOW_DEFAULT_PACKAGE_NAME')
|
258
|
+
puts "::Protobuf::Optionable.inject(self) { ::Google::Protobuf::FileOptions }"
|
259
|
+
end
|
137
260
|
end
|
138
261
|
end
|
139
262
|
end
|
140
|
-
|