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,39 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module Protobuf
|
4
|
+
module Logging
|
5
|
+
def self.initialize_logger(log_target = $stdout, log_level = ::Logger::INFO)
|
6
|
+
@logger = Logger.new(log_target)
|
7
|
+
@logger.level = log_level
|
8
|
+
@logger
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.logger
|
12
|
+
defined?(@logger) ? @logger : initialize_logger
|
13
|
+
end
|
14
|
+
|
15
|
+
class << self
|
16
|
+
attr_writer :logger
|
17
|
+
end
|
18
|
+
|
19
|
+
def logger
|
20
|
+
::Protobuf::Logging.logger
|
21
|
+
end
|
22
|
+
|
23
|
+
def log_exception(ex)
|
24
|
+
logger.error { ex.message }
|
25
|
+
logger.error { ex.backtrace[0..5].join("\n") }
|
26
|
+
logger.debug { ex.backtrace.join("\n") }
|
27
|
+
end
|
28
|
+
|
29
|
+
def log_signature
|
30
|
+
@_log_signature ||= "[#{self.class == Class ? name : self.class.name}]"
|
31
|
+
end
|
32
|
+
|
33
|
+
def sign_message(message)
|
34
|
+
"#{log_signature} #{message}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Inspired by [mperham](https://github.com/mperham/sidekiq)
|
@@ -0,0 +1,193 @@
|
|
1
|
+
require 'protobuf/field'
|
2
|
+
require 'protobuf/enum'
|
3
|
+
require 'protobuf/exceptions'
|
4
|
+
require 'protobuf/message/fields'
|
5
|
+
require 'protobuf/message/serialization'
|
6
|
+
|
7
|
+
module Protobuf
|
8
|
+
class Message
|
9
|
+
|
10
|
+
##
|
11
|
+
# Includes & Extends
|
12
|
+
#
|
13
|
+
|
14
|
+
extend ::Protobuf::Message::Fields
|
15
|
+
include ::Protobuf::Message::Serialization
|
16
|
+
|
17
|
+
##
|
18
|
+
# Class Methods
|
19
|
+
#
|
20
|
+
|
21
|
+
def self.to_json
|
22
|
+
name
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Constructor
|
27
|
+
#
|
28
|
+
|
29
|
+
def initialize(fields = {})
|
30
|
+
@values = {}
|
31
|
+
fields.to_hash.each_pair do |name, value|
|
32
|
+
self[name] = value
|
33
|
+
end
|
34
|
+
|
35
|
+
yield self if block_given?
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# Public Instance Methods
|
40
|
+
#
|
41
|
+
|
42
|
+
def clear!
|
43
|
+
@values.delete_if do |_, value|
|
44
|
+
if value.is_a?(::Protobuf::Field::FieldArray)
|
45
|
+
value.clear
|
46
|
+
false
|
47
|
+
else
|
48
|
+
true
|
49
|
+
end
|
50
|
+
end
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
def clone
|
55
|
+
copy_to(super, :clone)
|
56
|
+
end
|
57
|
+
|
58
|
+
def dup
|
59
|
+
copy_to(super, :dup)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Iterate over every field, invoking the given block
|
63
|
+
#
|
64
|
+
def each_field
|
65
|
+
self.class.all_fields.each do |field|
|
66
|
+
value = __send__(field.getter)
|
67
|
+
yield(field, value)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def each_field_for_serialization
|
72
|
+
self.class.all_fields.each do |field|
|
73
|
+
next unless field_must_be_serialized?(field)
|
74
|
+
|
75
|
+
value = @values[field.getter]
|
76
|
+
|
77
|
+
if value.nil?
|
78
|
+
fail ::Protobuf::SerializationError, "Required field #{self.class.name}##{field.name} does not have a value."
|
79
|
+
else
|
80
|
+
yield(field, value)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def field?(name)
|
86
|
+
@values.key?(name)
|
87
|
+
end
|
88
|
+
::Protobuf.deprecator.define_deprecated_methods(self, :has_field? => :field?)
|
89
|
+
|
90
|
+
def inspect
|
91
|
+
attrs = self.class.fields.map do |field|
|
92
|
+
[field.name, send(field.name).inspect].join('=')
|
93
|
+
end.join(' ')
|
94
|
+
|
95
|
+
"#<#{self.class} #{attrs}>"
|
96
|
+
end
|
97
|
+
|
98
|
+
def respond_to_has?(key)
|
99
|
+
respond_to?(key) && field?(key)
|
100
|
+
end
|
101
|
+
|
102
|
+
def respond_to_has_and_present?(key)
|
103
|
+
respond_to_has?(key) &&
|
104
|
+
(__send__(key).present? || [true, false].include?(__send__(key)))
|
105
|
+
end
|
106
|
+
|
107
|
+
# Return a hash-representation of the given fields for this message type.
|
108
|
+
def to_hash
|
109
|
+
result = {}
|
110
|
+
|
111
|
+
@values.keys.each do |field_name|
|
112
|
+
value = __send__(field_name)
|
113
|
+
hashed_value = value.respond_to?(:to_hash_value) ? value.to_hash_value : value
|
114
|
+
result.merge!(field_name => hashed_value)
|
115
|
+
end
|
116
|
+
|
117
|
+
result
|
118
|
+
end
|
119
|
+
|
120
|
+
def to_json(options = {})
|
121
|
+
to_hash.to_json(options)
|
122
|
+
end
|
123
|
+
|
124
|
+
def to_proto
|
125
|
+
self
|
126
|
+
end
|
127
|
+
|
128
|
+
def ==(other)
|
129
|
+
return false unless other.is_a?(self.class)
|
130
|
+
each_field do |field, value|
|
131
|
+
return false unless value == other.__send__(field.name)
|
132
|
+
end
|
133
|
+
true
|
134
|
+
end
|
135
|
+
|
136
|
+
def [](name)
|
137
|
+
if (field = self.class.get_field(name, true))
|
138
|
+
__send__(field.getter)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def []=(name, value)
|
143
|
+
if (field = self.class.get_field(name, true))
|
144
|
+
__send__(field.setter, value) unless value.nil?
|
145
|
+
else
|
146
|
+
unless ::Protobuf.ignore_unknown_fields?
|
147
|
+
fail ::Protobuf::FieldNotDefinedError, name
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
##
|
153
|
+
# Instance Aliases
|
154
|
+
#
|
155
|
+
alias_method :to_hash_value, :to_hash
|
156
|
+
alias_method :to_proto_hash, :to_hash
|
157
|
+
alias_method :responds_to_has?, :respond_to_has?
|
158
|
+
alias_method :respond_to_and_has?, :respond_to_has?
|
159
|
+
alias_method :responds_to_and_has?, :respond_to_has?
|
160
|
+
alias_method :respond_to_has_present?, :respond_to_has_and_present?
|
161
|
+
alias_method :respond_to_and_has_present?, :respond_to_has_and_present?
|
162
|
+
alias_method :respond_to_and_has_and_present?, :respond_to_has_and_present?
|
163
|
+
alias_method :responds_to_has_present?, :respond_to_has_and_present?
|
164
|
+
alias_method :responds_to_and_has_present?, :respond_to_has_and_present?
|
165
|
+
alias_method :responds_to_and_has_and_present?, :respond_to_has_and_present?
|
166
|
+
|
167
|
+
##
|
168
|
+
# Private Instance Methods
|
169
|
+
#
|
170
|
+
|
171
|
+
private
|
172
|
+
|
173
|
+
def copy_to(object, method)
|
174
|
+
duplicate = proc do |obj|
|
175
|
+
case obj
|
176
|
+
when Message, String then obj.__send__(method)
|
177
|
+
else obj
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
object.__send__(:initialize)
|
182
|
+
@values.each do |name, value|
|
183
|
+
if value.is_a?(::Protobuf::Field::FieldArray)
|
184
|
+
object.__send__(name).replace(value.map { |v| duplicate.call(v) })
|
185
|
+
else
|
186
|
+
object.__send__("#{name}=", duplicate.call(value))
|
187
|
+
end
|
188
|
+
end
|
189
|
+
object
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|
193
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
module Protobuf
|
2
|
+
class Message
|
3
|
+
module Fields
|
4
|
+
|
5
|
+
def self.extended(other)
|
6
|
+
other.extend(ClassMethods)
|
7
|
+
::Protobuf.deprecator.define_deprecated_methods(
|
8
|
+
other.singleton_class,
|
9
|
+
:get_ext_field_by_name => :get_extension_field,
|
10
|
+
:get_ext_field_by_tag => :get_extension_field,
|
11
|
+
:get_field_by_name => :get_field,
|
12
|
+
:get_field_by_tag => :get_field,
|
13
|
+
)
|
14
|
+
|
15
|
+
def inherited(subclass)
|
16
|
+
inherit_fields!(subclass)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module ClassMethods
|
21
|
+
|
22
|
+
##
|
23
|
+
# Field Definition Methods
|
24
|
+
#
|
25
|
+
|
26
|
+
# Define an optional field.
|
27
|
+
#
|
28
|
+
def optional(type_class, name, tag, options = {})
|
29
|
+
define_field(:optional, type_class, name, tag, options)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Define a repeated field.
|
33
|
+
#
|
34
|
+
def repeated(type_class, name, tag, options = {})
|
35
|
+
define_field(:repeated, type_class, name, tag, options)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Define a required field.
|
39
|
+
#
|
40
|
+
def required(type_class, name, tag, options = {})
|
41
|
+
define_field(:required, type_class, name, tag, options)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Define an extension range.
|
45
|
+
#
|
46
|
+
def extensions(range)
|
47
|
+
extension_ranges << range
|
48
|
+
end
|
49
|
+
|
50
|
+
##
|
51
|
+
# Field Access Methods
|
52
|
+
#
|
53
|
+
def all_fields
|
54
|
+
@all_fields ||= field_store.values.uniq.sort_by(&:tag)
|
55
|
+
end
|
56
|
+
|
57
|
+
def extension_fields
|
58
|
+
@extension_fields ||= all_fields.select(&:extension?)
|
59
|
+
end
|
60
|
+
|
61
|
+
def extension_ranges
|
62
|
+
@extension_ranges ||= []
|
63
|
+
end
|
64
|
+
|
65
|
+
def extension_tag?(tag)
|
66
|
+
tag.respond_to?(:to_i) && get_extension_field(tag).present?
|
67
|
+
end
|
68
|
+
|
69
|
+
def field_store
|
70
|
+
@field_store ||= {}
|
71
|
+
end
|
72
|
+
|
73
|
+
def fields
|
74
|
+
@fields ||= all_fields.reject(&:extension?)
|
75
|
+
end
|
76
|
+
|
77
|
+
def field_tag?(tag, allow_extension = false)
|
78
|
+
tag.respond_to?(:to_i) && get_field(tag, allow_extension).present?
|
79
|
+
end
|
80
|
+
|
81
|
+
def get_extension_field(name_or_tag)
|
82
|
+
name_or_tag = name_or_tag.to_sym if name_or_tag.respond_to?(:to_sym)
|
83
|
+
field = field_store[name_or_tag]
|
84
|
+
field if field.try(:extension?) { false }
|
85
|
+
end
|
86
|
+
|
87
|
+
def get_field(name_or_tag, allow_extension = false)
|
88
|
+
name_or_tag = name_or_tag.to_sym if name_or_tag.respond_to?(:to_sym)
|
89
|
+
field = field_store[name_or_tag]
|
90
|
+
|
91
|
+
if field && (allow_extension || !field.extension?)
|
92
|
+
field
|
93
|
+
else
|
94
|
+
nil
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def define_field(rule, type_class, field_name, tag, options)
|
99
|
+
raise_if_tag_collision(tag, field_name)
|
100
|
+
raise_if_name_collision(field_name)
|
101
|
+
|
102
|
+
field = ::Protobuf::Field.build(self, rule, type_class, field_name, tag, options)
|
103
|
+
field_store[field_name] = field
|
104
|
+
field_store[tag] = field
|
105
|
+
|
106
|
+
define_method("#{field_name}!") do
|
107
|
+
@values[field_name]
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def raise_if_tag_collision(tag, field_name)
|
112
|
+
if get_field(tag, true)
|
113
|
+
fail TagCollisionError, %(Field number #{tag} has already been used in "#{name}" by field "#{field_name}".)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def raise_if_name_collision(field_name)
|
118
|
+
if get_field(field_name, true)
|
119
|
+
fail DuplicateFieldNameError, %(Field name #{field_name} has already been used in "#{name}".)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def inherit_fields!(subclass)
|
124
|
+
instance_variables.each do |iv|
|
125
|
+
subclass.instance_variable_set(iv, instance_variable_get(iv))
|
126
|
+
end
|
127
|
+
end
|
128
|
+
private :inherit_fields!
|
129
|
+
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
require 'protobuf/decoder'
|
3
|
+
require 'protobuf/encoder'
|
4
|
+
|
5
|
+
module Protobuf
|
6
|
+
class Message
|
7
|
+
module Serialization
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def decode(bytes)
|
11
|
+
new.decode(bytes)
|
12
|
+
end
|
13
|
+
|
14
|
+
def decode_from(stream)
|
15
|
+
new.decode_from(stream)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Create a new object with the given values and return the encoded bytes.
|
19
|
+
def encode(fields = {})
|
20
|
+
new(fields).encode
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.included(other)
|
25
|
+
other.extend(ClassMethods)
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# Instance Methods
|
30
|
+
#
|
31
|
+
|
32
|
+
# Decode the given non-stream bytes into this message.
|
33
|
+
#
|
34
|
+
def decode(bytes)
|
35
|
+
decode_from(::StringIO.new(bytes))
|
36
|
+
end
|
37
|
+
|
38
|
+
# Decode the given stream into this message.
|
39
|
+
#
|
40
|
+
def decode_from(stream)
|
41
|
+
::Protobuf::Decoder.decode_each_field(stream) do |tag, bytes|
|
42
|
+
set_field_bytes(tag, bytes)
|
43
|
+
end
|
44
|
+
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
48
|
+
# Encode this message
|
49
|
+
#
|
50
|
+
def encode
|
51
|
+
stream = ::StringIO.new
|
52
|
+
stream.set_encoding(::Protobuf::Field::BytesField::BYTES_ENCODING)
|
53
|
+
encode_to(stream)
|
54
|
+
stream.string
|
55
|
+
end
|
56
|
+
|
57
|
+
# Encode this message to the given stream.
|
58
|
+
#
|
59
|
+
def encode_to(stream)
|
60
|
+
::Protobuf::Encoder.encode(self, stream)
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# Instance Aliases
|
65
|
+
#
|
66
|
+
alias_method :parse_from_string, :decode
|
67
|
+
alias_method :deserialize, :decode
|
68
|
+
alias_method :parse_from, :decode_from
|
69
|
+
alias_method :deserialize_from, :decode_from
|
70
|
+
alias_method :to_s, :encode
|
71
|
+
alias_method :bytes, :encode
|
72
|
+
alias_method :serialize, :encode
|
73
|
+
alias_method :serialize_to_string, :encode
|
74
|
+
alias_method :serialize_to, :encode_to
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def field_must_be_serialized?(field)
|
79
|
+
field.required? || ! @values[field.name].nil?
|
80
|
+
end
|
81
|
+
|
82
|
+
def set_field_bytes(tag, bytes)
|
83
|
+
field = self.class.get_field(tag, true)
|
84
|
+
field.set(self, bytes) if field
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|