protobuf-core 3.5.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 +10 -0
- data/.rspec +2 -0
- data/.travis.yml +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +23 -0
- data/Rakefile +5 -0
- data/bin/protoc-gen-ruby +16 -0
- data/lib/protobuf.rb +27 -0
- data/lib/protobuf/code_generator.rb +44 -0
- data/lib/protobuf/core.rb +2 -0
- data/lib/protobuf/core/version.rb +5 -0
- data/lib/protobuf/decoder.rb +73 -0
- data/lib/protobuf/deprecation.rb +112 -0
- data/lib/protobuf/descriptors.rb +3 -0
- data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +54 -0
- data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +251 -0
- data/lib/protobuf/encoder.rb +67 -0
- data/lib/protobuf/enum.rb +303 -0
- data/lib/protobuf/exceptions.rb +9 -0
- data/lib/protobuf/field.rb +74 -0
- data/lib/protobuf/field/base_field.rb +267 -0
- data/lib/protobuf/field/bool_field.rb +59 -0
- data/lib/protobuf/field/bytes_field.rb +82 -0
- data/lib/protobuf/field/double_field.rb +25 -0
- data/lib/protobuf/field/enum_field.rb +68 -0
- data/lib/protobuf/field/field_array.rb +87 -0
- data/lib/protobuf/field/fixed32_field.rb +25 -0
- data/lib/protobuf/field/fixed64_field.rb +28 -0
- data/lib/protobuf/field/float_field.rb +41 -0
- data/lib/protobuf/field/int32_field.rb +21 -0
- data/lib/protobuf/field/int64_field.rb +21 -0
- data/lib/protobuf/field/integer_field.rb +23 -0
- data/lib/protobuf/field/message_field.rb +65 -0
- data/lib/protobuf/field/sfixed32_field.rb +27 -0
- data/lib/protobuf/field/sfixed64_field.rb +28 -0
- data/lib/protobuf/field/signed_integer_field.rb +29 -0
- data/lib/protobuf/field/sint32_field.rb +21 -0
- data/lib/protobuf/field/sint64_field.rb +21 -0
- data/lib/protobuf/field/string_field.rb +34 -0
- data/lib/protobuf/field/uint32_field.rb +21 -0
- data/lib/protobuf/field/uint64_field.rb +21 -0
- data/lib/protobuf/field/varint_field.rb +73 -0
- data/lib/protobuf/generators/base.rb +70 -0
- data/lib/protobuf/generators/enum_generator.rb +41 -0
- data/lib/protobuf/generators/extension_generator.rb +27 -0
- data/lib/protobuf/generators/field_generator.rb +131 -0
- data/lib/protobuf/generators/file_generator.rb +132 -0
- data/lib/protobuf/generators/group_generator.rb +105 -0
- data/lib/protobuf/generators/message_generator.rb +98 -0
- data/lib/protobuf/generators/printable.rb +160 -0
- data/lib/protobuf/logging.rb +39 -0
- data/lib/protobuf/message.rb +193 -0
- data/lib/protobuf/message/fields.rb +133 -0
- data/lib/protobuf/message/serialization.rb +89 -0
- data/lib/protobuf/optionable.rb +23 -0
- data/lib/protobuf/wire_type.rb +10 -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/protobuf-core.gemspec +31 -0
- data/spec/bin/protoc-gen-ruby_spec.rb +23 -0
- data/spec/data/data.bin +3 -0
- data/spec/data/types.bin +0 -0
- data/spec/encoding/all_types_spec.rb +105 -0
- data/spec/encoding/extreme_values_spec.rb +0 -0
- data/spec/functional/class_inheritance_spec.rb +52 -0
- data/spec/functional/compile_and_require_spec.rb +29 -0
- data/spec/lib/protobuf/base_spec.rb +84 -0
- data/spec/lib/protobuf/code_generator_spec.rb +60 -0
- data/spec/lib/protobuf/enum_generator_spec.rb +73 -0
- data/spec/lib/protobuf/enum_spec.rb +265 -0
- data/spec/lib/protobuf/extension_generator_spec.rb +42 -0
- data/spec/lib/protobuf/field/bool_field_spec.rb +51 -0
- data/spec/lib/protobuf/field/field_array_spec.rb +69 -0
- data/spec/lib/protobuf/field/float_field_spec.rb +55 -0
- data/spec/lib/protobuf/field/int32_field_spec.rb +90 -0
- data/spec/lib/protobuf/field/string_field_spec.rb +45 -0
- data/spec/lib/protobuf/field_generator_spec.rb +102 -0
- data/spec/lib/protobuf/field_spec.rb +191 -0
- data/spec/lib/protobuf/file_generator_spec.rb +32 -0
- data/spec/lib/protobuf/message_generator_spec.rb +0 -0
- data/spec/lib/protobuf/message_spec.rb +526 -0
- data/spec/lib/protobuf/optionable_spec.rb +46 -0
- data/spec/lib/protobuf_spec.rb +45 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/support/packed_field.rb +22 -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/bacon.proto +14 -0
- data/spec/support/test/defaults.pb.rb +27 -0
- data/spec/support/test/defaults.proto +9 -0
- data/spec/support/test/enum.pb.rb +61 -0
- data/spec/support/test/enum.proto +34 -0
- data/spec/support/test/extended.pb.rb +24 -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 +530 -0
- data/spec/support/test/google_unittest.proto +713 -0
- data/spec/support/test/google_unittest_import.pb.rb +39 -0
- data/spec/support/test/google_unittest_import.proto +64 -0
- data/spec/support/test/google_unittest_import_public.pb.rb +10 -0
- data/spec/support/test/google_unittest_import_public.proto +38 -0
- data/spec/support/test/multi_field_extensions.pb.rb +58 -0
- data/spec/support/test/multi_field_extensions.proto +33 -0
- data/spec/support/test/resource.pb.rb +106 -0
- data/spec/support/test/resource.proto +94 -0
- metadata +306 -0
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'protobuf/field/varint_field'
|
2
|
+
|
3
|
+
module Protobuf
|
4
|
+
module Field
|
5
|
+
class SignedIntegerField < VarintField
|
6
|
+
|
7
|
+
##
|
8
|
+
# Public Instance Methods
|
9
|
+
#
|
10
|
+
|
11
|
+
def decode(value)
|
12
|
+
if (value & 1).zero?
|
13
|
+
value >> 1 # positive value
|
14
|
+
else
|
15
|
+
~value >> 1 # negative value
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def encode(value)
|
20
|
+
if value >= 0
|
21
|
+
VarintField.encode(value << 1)
|
22
|
+
else
|
23
|
+
VarintField.encode(~(value << 1))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'protobuf/field/signed_integer_field'
|
2
|
+
|
3
|
+
module Protobuf
|
4
|
+
module Field
|
5
|
+
class Sint32Field < SignedIntegerField
|
6
|
+
|
7
|
+
##
|
8
|
+
# Class Methods
|
9
|
+
#
|
10
|
+
|
11
|
+
def self.max
|
12
|
+
INT32_MAX
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.min
|
16
|
+
INT32_MIN
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'protobuf/field/signed_integer_field'
|
2
|
+
|
3
|
+
module Protobuf
|
4
|
+
module Field
|
5
|
+
class Sint64Field < SignedIntegerField
|
6
|
+
|
7
|
+
##
|
8
|
+
# Class Methods
|
9
|
+
#
|
10
|
+
|
11
|
+
def self.max
|
12
|
+
INT64_MAX
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.min
|
16
|
+
INT64_MIN
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,34 @@
|
|
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 = Encoding::UTF_8
|
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
|
@@ -0,0 +1,73 @@
|
|
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
|
+
int_val = coerce!(val)
|
41
|
+
int_val >= self.class.min && int_val <= self.class.max
|
42
|
+
rescue
|
43
|
+
false
|
44
|
+
end
|
45
|
+
|
46
|
+
def coerce!(val)
|
47
|
+
return val.to_i if val.is_a?(Numeric)
|
48
|
+
Integer(val, 10)
|
49
|
+
end
|
50
|
+
|
51
|
+
def decode(value)
|
52
|
+
value
|
53
|
+
end
|
54
|
+
|
55
|
+
def encode(value)
|
56
|
+
return [value].pack('C') if value < 128
|
57
|
+
|
58
|
+
bytes = []
|
59
|
+
until value == 0
|
60
|
+
bytes << (0x80 | (value & 0x7f))
|
61
|
+
value >>= 7
|
62
|
+
end
|
63
|
+
bytes[-1] &= 0x7f
|
64
|
+
bytes.pack('C*')
|
65
|
+
end
|
66
|
+
|
67
|
+
def wire_type
|
68
|
+
::Protobuf::WireType::VARINT
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,70 @@
|
|
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
|
@@ -0,0 +1,41 @@
|
|
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
|
+
"define :#{name}, #{number}"
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,27 @@
|
|
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
|
@@ -0,0 +1,131 @@
|
|
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
|
+
modulize(descriptor.type_name)
|
95
|
+
else
|
96
|
+
type_name = descriptor.type.name.to_s.downcase.sub(/type_/, '')
|
97
|
+
":#{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
|
+
%("#{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
|