protobuf-core 3.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +18 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +23 -0
  8. data/Rakefile +5 -0
  9. data/bin/protoc-gen-ruby +16 -0
  10. data/lib/protobuf.rb +27 -0
  11. data/lib/protobuf/code_generator.rb +44 -0
  12. data/lib/protobuf/core.rb +2 -0
  13. data/lib/protobuf/core/version.rb +5 -0
  14. data/lib/protobuf/decoder.rb +73 -0
  15. data/lib/protobuf/deprecation.rb +112 -0
  16. data/lib/protobuf/descriptors.rb +3 -0
  17. data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +54 -0
  18. data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +251 -0
  19. data/lib/protobuf/encoder.rb +67 -0
  20. data/lib/protobuf/enum.rb +303 -0
  21. data/lib/protobuf/exceptions.rb +9 -0
  22. data/lib/protobuf/field.rb +74 -0
  23. data/lib/protobuf/field/base_field.rb +267 -0
  24. data/lib/protobuf/field/bool_field.rb +59 -0
  25. data/lib/protobuf/field/bytes_field.rb +82 -0
  26. data/lib/protobuf/field/double_field.rb +25 -0
  27. data/lib/protobuf/field/enum_field.rb +68 -0
  28. data/lib/protobuf/field/field_array.rb +87 -0
  29. data/lib/protobuf/field/fixed32_field.rb +25 -0
  30. data/lib/protobuf/field/fixed64_field.rb +28 -0
  31. data/lib/protobuf/field/float_field.rb +41 -0
  32. data/lib/protobuf/field/int32_field.rb +21 -0
  33. data/lib/protobuf/field/int64_field.rb +21 -0
  34. data/lib/protobuf/field/integer_field.rb +23 -0
  35. data/lib/protobuf/field/message_field.rb +65 -0
  36. data/lib/protobuf/field/sfixed32_field.rb +27 -0
  37. data/lib/protobuf/field/sfixed64_field.rb +28 -0
  38. data/lib/protobuf/field/signed_integer_field.rb +29 -0
  39. data/lib/protobuf/field/sint32_field.rb +21 -0
  40. data/lib/protobuf/field/sint64_field.rb +21 -0
  41. data/lib/protobuf/field/string_field.rb +34 -0
  42. data/lib/protobuf/field/uint32_field.rb +21 -0
  43. data/lib/protobuf/field/uint64_field.rb +21 -0
  44. data/lib/protobuf/field/varint_field.rb +73 -0
  45. data/lib/protobuf/generators/base.rb +70 -0
  46. data/lib/protobuf/generators/enum_generator.rb +41 -0
  47. data/lib/protobuf/generators/extension_generator.rb +27 -0
  48. data/lib/protobuf/generators/field_generator.rb +131 -0
  49. data/lib/protobuf/generators/file_generator.rb +132 -0
  50. data/lib/protobuf/generators/group_generator.rb +105 -0
  51. data/lib/protobuf/generators/message_generator.rb +98 -0
  52. data/lib/protobuf/generators/printable.rb +160 -0
  53. data/lib/protobuf/logging.rb +39 -0
  54. data/lib/protobuf/message.rb +193 -0
  55. data/lib/protobuf/message/fields.rb +133 -0
  56. data/lib/protobuf/message/serialization.rb +89 -0
  57. data/lib/protobuf/optionable.rb +23 -0
  58. data/lib/protobuf/wire_type.rb +10 -0
  59. data/proto/dynamic_discovery.proto +44 -0
  60. data/proto/google/protobuf/compiler/plugin.proto +147 -0
  61. data/proto/google/protobuf/descriptor.proto +620 -0
  62. data/proto/rpc.proto +62 -0
  63. data/protobuf-core.gemspec +31 -0
  64. data/spec/bin/protoc-gen-ruby_spec.rb +23 -0
  65. data/spec/data/data.bin +3 -0
  66. data/spec/data/types.bin +0 -0
  67. data/spec/encoding/all_types_spec.rb +105 -0
  68. data/spec/encoding/extreme_values_spec.rb +0 -0
  69. data/spec/functional/class_inheritance_spec.rb +52 -0
  70. data/spec/functional/compile_and_require_spec.rb +29 -0
  71. data/spec/lib/protobuf/base_spec.rb +84 -0
  72. data/spec/lib/protobuf/code_generator_spec.rb +60 -0
  73. data/spec/lib/protobuf/enum_generator_spec.rb +73 -0
  74. data/spec/lib/protobuf/enum_spec.rb +265 -0
  75. data/spec/lib/protobuf/extension_generator_spec.rb +42 -0
  76. data/spec/lib/protobuf/field/bool_field_spec.rb +51 -0
  77. data/spec/lib/protobuf/field/field_array_spec.rb +69 -0
  78. data/spec/lib/protobuf/field/float_field_spec.rb +55 -0
  79. data/spec/lib/protobuf/field/int32_field_spec.rb +90 -0
  80. data/spec/lib/protobuf/field/string_field_spec.rb +45 -0
  81. data/spec/lib/protobuf/field_generator_spec.rb +102 -0
  82. data/spec/lib/protobuf/field_spec.rb +191 -0
  83. data/spec/lib/protobuf/file_generator_spec.rb +32 -0
  84. data/spec/lib/protobuf/message_generator_spec.rb +0 -0
  85. data/spec/lib/protobuf/message_spec.rb +526 -0
  86. data/spec/lib/protobuf/optionable_spec.rb +46 -0
  87. data/spec/lib/protobuf_spec.rb +45 -0
  88. data/spec/spec_helper.rb +9 -0
  89. data/spec/support/packed_field.rb +22 -0
  90. data/spec/support/test/all_types.data.bin +0 -0
  91. data/spec/support/test/all_types.data.txt +119 -0
  92. data/spec/support/test/bacon.proto +14 -0
  93. data/spec/support/test/defaults.pb.rb +27 -0
  94. data/spec/support/test/defaults.proto +9 -0
  95. data/spec/support/test/enum.pb.rb +61 -0
  96. data/spec/support/test/enum.proto +34 -0
  97. data/spec/support/test/extended.pb.rb +24 -0
  98. data/spec/support/test/extended.proto +10 -0
  99. data/spec/support/test/extreme_values.data.bin +0 -0
  100. data/spec/support/test/google_unittest.pb.rb +530 -0
  101. data/spec/support/test/google_unittest.proto +713 -0
  102. data/spec/support/test/google_unittest_import.pb.rb +39 -0
  103. data/spec/support/test/google_unittest_import.proto +64 -0
  104. data/spec/support/test/google_unittest_import_public.pb.rb +10 -0
  105. data/spec/support/test/google_unittest_import_public.proto +38 -0
  106. data/spec/support/test/multi_field_extensions.pb.rb +58 -0
  107. data/spec/support/test/multi_field_extensions.proto +33 -0
  108. data/spec/support/test/resource.pb.rb +106 -0
  109. data/spec/support/test/resource.proto +94 -0
  110. metadata +306 -0
@@ -0,0 +1,9 @@
1
+ module Protobuf
2
+ class Error < StandardError; end
3
+ class InvalidWireType < Error; end
4
+ class NotInitializedError < Error; end
5
+ class TagCollisionError < Error; end
6
+ class SerializationError < StandardError; end
7
+ class FieldNotDefinedError < StandardError; end
8
+ class DuplicateFieldNameError < StandardError; end
9
+ end
@@ -0,0 +1,74 @@
1
+ require 'protobuf/field/base_field'
2
+ require 'protobuf/field/bytes_field'
3
+ require 'protobuf/field/float_field'
4
+ require 'protobuf/field/message_field'
5
+ require 'protobuf/field/varint_field'
6
+ require 'protobuf/field/string_field'
7
+ require 'protobuf/field/double_field'
8
+ require 'protobuf/field/enum_field'
9
+ require 'protobuf/field/integer_field'
10
+ require 'protobuf/field/signed_integer_field'
11
+ require 'protobuf/field/uint32_field'
12
+ require 'protobuf/field/uint64_field'
13
+ require 'protobuf/field/int32_field'
14
+ require 'protobuf/field/int64_field'
15
+ require 'protobuf/field/sint32_field'
16
+ require 'protobuf/field/sint64_field'
17
+ require 'protobuf/field/bool_field'
18
+ require 'protobuf/field/sfixed32_field'
19
+ require 'protobuf/field/sfixed64_field'
20
+ require 'protobuf/field/fixed32_field'
21
+ require 'protobuf/field/fixed64_field'
22
+
23
+ module Protobuf
24
+ module Field
25
+
26
+ PRIMITIVE_FIELD_MAP = {
27
+ :double => ::Protobuf::Field::DoubleField,
28
+ :float => ::Protobuf::Field::FloatField,
29
+ :int32 => ::Protobuf::Field::Int32Field,
30
+ :int64 => ::Protobuf::Field::Int64Field,
31
+ :uint32 => ::Protobuf::Field::Uint32Field,
32
+ :uint64 => ::Protobuf::Field::Uint64Field,
33
+ :sint32 => ::Protobuf::Field::Sint32Field,
34
+ :sint64 => ::Protobuf::Field::Sint64Field,
35
+ :fixed32 => ::Protobuf::Field::Fixed32Field,
36
+ :fixed64 => ::Protobuf::Field::Fixed64Field,
37
+ :sfixed32 => ::Protobuf::Field::Sfixed32Field,
38
+ :sfixed64 => ::Protobuf::Field::Sfixed64Field,
39
+ :string => ::Protobuf::Field::StringField,
40
+ :bytes => ::Protobuf::Field::BytesField,
41
+ :bool => ::Protobuf::Field::BoolField,
42
+ }.freeze
43
+
44
+ def self.build(message_class, rule, type, name, tag, options = {})
45
+ field_class(type).new(message_class, rule, field_type(type), name, tag, options)
46
+ end
47
+
48
+ # Returns the field class for primitives,
49
+ # EnumField for types that inherit from Protobuf::Enum,
50
+ # and MessageField for types that inherit from Protobuf::Message.
51
+ #
52
+ def self.field_class(type)
53
+ if PRIMITIVE_FIELD_MAP.key?(type)
54
+ PRIMITIVE_FIELD_MAP[type]
55
+ elsif type < ::Protobuf::Enum
56
+ EnumField
57
+ elsif type < ::Protobuf::Message
58
+ MessageField
59
+ elsif type < ::Protobuf::Field::BaseField
60
+ type
61
+ else
62
+ fail ArgumentError, "Invalid field type #{type}"
63
+ end
64
+ end
65
+
66
+ # Returns the mapped type for primitives,
67
+ # otherwise the given type is returned.
68
+ #
69
+ def self.field_type(type)
70
+ PRIMITIVE_FIELD_MAP.fetch(type) { type }
71
+ end
72
+
73
+ end
74
+ end
@@ -0,0 +1,267 @@
1
+ require 'protobuf/field/field_array'
2
+ require 'protobuf/logging'
3
+ require 'protobuf/wire_type'
4
+
5
+ module Protobuf
6
+ module Field
7
+ class BaseField
8
+ include ::Protobuf::Logging
9
+
10
+ ##
11
+ # Constants
12
+ #
13
+
14
+ PACKED_TYPES = [
15
+ ::Protobuf::WireType::VARINT,
16
+ ::Protobuf::WireType::FIXED32,
17
+ ::Protobuf::WireType::FIXED64,
18
+ ].freeze
19
+
20
+ ##
21
+ # Attributes
22
+ #
23
+
24
+ attr_reader :message_class, :name, :options, :rule, :tag, :type_class
25
+
26
+ ##
27
+ # Class Methods
28
+ #
29
+
30
+ def self.default
31
+ nil
32
+ end
33
+
34
+ ##
35
+ # Constructor
36
+ #
37
+
38
+ def initialize(message_class, rule, type_class, name, tag, options)
39
+ @message_class = message_class
40
+ @name = name
41
+ @rule = rule
42
+ @tag = tag
43
+ @type_class = type_class
44
+ @options = options
45
+
46
+ validate_packed_field if packed?
47
+ define_accessor
48
+ end
49
+
50
+ ##
51
+ # Public Instance Methods
52
+ #
53
+
54
+ def acceptable?(_value)
55
+ true
56
+ end
57
+
58
+ def coerce!(value)
59
+ value
60
+ end
61
+
62
+ def decode(_bytes)
63
+ fail NotImplementedError, "#{self.class.name}##{__method__}"
64
+ end
65
+
66
+ def default
67
+ options[:default]
68
+ end
69
+
70
+ def default_value
71
+ @default_value ||= case
72
+ when repeated? then ::Protobuf::Field::FieldArray.new(self).freeze
73
+ when required? then nil
74
+ when optional? then typed_default_value
75
+ end
76
+ end
77
+
78
+ def deprecated?
79
+ options.key?(:deprecated)
80
+ end
81
+
82
+ def encode(_value)
83
+ fail NotImplementedError, "#{self.class.name}##{__method__}"
84
+ end
85
+
86
+ def extension?
87
+ options.key?(:extension)
88
+ end
89
+
90
+ def enum?
91
+ false
92
+ end
93
+
94
+ def getter
95
+ name
96
+ end
97
+
98
+ def message?
99
+ false
100
+ end
101
+
102
+ def optional?
103
+ rule == :optional
104
+ end
105
+
106
+ def packed?
107
+ repeated? && options.key?(:packed)
108
+ end
109
+
110
+ def repeated?
111
+ rule == :repeated
112
+ end
113
+
114
+ def repeated_message?
115
+ repeated? && message?
116
+ end
117
+
118
+ def required?
119
+ rule == :required
120
+ end
121
+
122
+ # FIXME: need to cleanup (rename) this warthog of a method.
123
+ def set(message_instance, bytes)
124
+ if packed?
125
+ array = message_instance.__send__(getter)
126
+ method = \
127
+ case wire_type
128
+ when ::Protobuf::WireType::FIXED32 then :read_fixed32
129
+ when ::Protobuf::WireType::FIXED64 then :read_fixed64
130
+ when ::Protobuf::WireType::VARINT then :read_varint
131
+ end
132
+ stream = StringIO.new(bytes)
133
+
134
+ until stream.eof?
135
+ array << decode(::Protobuf::Decoder.__send__(method, stream))
136
+ end
137
+ else
138
+ value = decode(bytes)
139
+ if repeated?
140
+ message_instance.__send__(getter) << value
141
+ else
142
+ message_instance.__send__(setter, value)
143
+ end
144
+ end
145
+ end
146
+
147
+ def setter
148
+ @setter ||= "#{name}="
149
+ end
150
+
151
+ # FIXME: add packed, deprecated, extension options to to_s output
152
+ def to_s
153
+ "#{rule} #{type_class} #{name} = #{tag} #{default ? "[default=#{default.inspect}]" : ''}"
154
+ end
155
+
156
+ ::Protobuf.deprecator.define_deprecated_methods(self, :type => :type_class)
157
+
158
+ def wire_type
159
+ ::Protobuf::WireType::VARINT
160
+ end
161
+
162
+ private
163
+
164
+ ##
165
+ # Private Instance Methods
166
+ #
167
+
168
+ def define_accessor
169
+ if repeated?
170
+ define_array_getter
171
+ define_array_setter
172
+ else
173
+ define_getter
174
+ define_setter
175
+ end
176
+ end
177
+
178
+ def define_array_getter
179
+ field = self
180
+ method_name = field.getter
181
+
182
+ message_class.class_eval do
183
+ define_method(method_name) do
184
+ @values[field.name] ||= ::Protobuf::Field::FieldArray.new(field)
185
+ end
186
+ end
187
+
188
+ ::Protobuf.field_deprecator.deprecate_method(message_class, method_name) if field.deprecated?
189
+ end
190
+
191
+ def define_array_setter
192
+ field = self
193
+ method_name = field.setter
194
+
195
+ message_class.class_eval do
196
+ define_method(method_name) do |val|
197
+ if val.is_a?(Array)
198
+ val = val.dup
199
+ val.compact!
200
+ else
201
+ fail TypeError, <<-TYPE_ERROR
202
+ Expected repeated value of type '#{field.type_class}'
203
+ Got '#{val.class}' for repeated protobuf field #{field.name}
204
+ TYPE_ERROR
205
+ end
206
+
207
+ if val.nil? || (val.respond_to?(:empty?) && val.empty?)
208
+ @values.delete(field.name)
209
+ else
210
+ @values[field.name] ||= ::Protobuf::Field::FieldArray.new(field)
211
+ @values[field.name].replace(val)
212
+ end
213
+ end
214
+ end
215
+
216
+ ::Protobuf.field_deprecator.deprecate_method(message_class, method_name) if field.deprecated?
217
+ end
218
+
219
+ def define_getter
220
+ field = self
221
+ method_name = field.getter
222
+
223
+ message_class.class_eval do
224
+ define_method(method_name) do
225
+ @values.fetch(field.name, field.default_value)
226
+ end
227
+ end
228
+
229
+ ::Protobuf.field_deprecator.deprecate_method(message_class, method_name) if field.deprecated?
230
+ end
231
+
232
+ def define_setter
233
+ field = self
234
+ method_name = field.setter
235
+
236
+ message_class.class_eval do
237
+ define_method(method_name) do |val|
238
+ if val.nil? || (val.respond_to?(:empty?) && val.empty?)
239
+ @values.delete(field.name)
240
+ elsif field.acceptable?(val)
241
+ @values[field.name] = field.coerce!(val)
242
+ else
243
+ fail TypeError, "Unacceptable value #{val} for field #{field.name} of type #{field.type_class}"
244
+ end
245
+ end
246
+ end
247
+
248
+ ::Protobuf.field_deprecator.deprecate_method(message_class, method_name) if field.deprecated?
249
+ end
250
+
251
+ def typed_default_value
252
+ if default.nil?
253
+ self.class.default
254
+ else
255
+ default
256
+ end
257
+ end
258
+
259
+ def validate_packed_field
260
+ if packed? && ! ::Protobuf::Field::BaseField::PACKED_TYPES.include?(wire_type)
261
+ fail "Can't use packed encoding for '#{type_class}' type"
262
+ end
263
+ end
264
+
265
+ end
266
+ end
267
+ end
@@ -0,0 +1,59 @@
1
+ require 'protobuf/field/varint_field'
2
+
3
+ module Protobuf
4
+ module Field
5
+ class BoolField < VarintField
6
+
7
+ ##
8
+ # Class Methods
9
+ #
10
+
11
+ def self.default
12
+ false
13
+ end
14
+
15
+ ##
16
+ # Public Instance Methods
17
+ # #
18
+
19
+ def acceptable?(val)
20
+ [true, false].include?(val) || %w(true false).include?(val)
21
+ end
22
+
23
+ def coerce!(val)
24
+ if val == 'true'
25
+ true
26
+ elsif val == 'false'
27
+ false
28
+ else
29
+ val
30
+ end
31
+ end
32
+
33
+ def decode(value)
34
+ value == 1
35
+ end
36
+
37
+ def encode(value)
38
+ [value ? 1 : 0].pack('C')
39
+ end
40
+
41
+ private
42
+
43
+ ##
44
+ # Private Instance Methods
45
+ #
46
+
47
+ def define_getter
48
+ super
49
+
50
+ field = self
51
+
52
+ message_class.class_eval do
53
+ alias_method "#{field.getter}?", field.getter
54
+ end
55
+ end
56
+
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,82 @@
1
+ require 'protobuf/wire_type'
2
+
3
+ module Protobuf
4
+ module Field
5
+ class BytesField < BaseField
6
+
7
+ ##
8
+ # Constants
9
+ #
10
+
11
+ BYTES_ENCODING = Encoding::BINARY
12
+
13
+ ##
14
+ # Class Methods
15
+ #
16
+
17
+ def self.default
18
+ ''
19
+ end
20
+
21
+ ##
22
+ # Public Instance Methods
23
+ #
24
+
25
+ def acceptable?(val)
26
+ val.nil? || val.is_a?(String) || val.is_a?(Symbol) || val.is_a?(::Protobuf::Message)
27
+ end
28
+
29
+ def decode(bytes)
30
+ bytes_to_decode = bytes.dup
31
+ bytes_to_decode.force_encoding(::Protobuf::Field::BytesField::BYTES_ENCODING)
32
+ bytes_to_decode
33
+ end
34
+
35
+ def encode(value)
36
+ value_to_encode = value.dup
37
+ value_to_encode = value.encode if value.is_a?(::Protobuf::Message)
38
+ value_to_encode.force_encoding(::Protobuf::Field::BytesField::BYTES_ENCODING)
39
+
40
+ string_size = ::Protobuf::Field::VarintField.encode(value_to_encode.size)
41
+ string_size << value_to_encode
42
+ end
43
+
44
+ def wire_type
45
+ ::Protobuf::WireType::LENGTH_DELIMITED
46
+ end
47
+
48
+ private
49
+
50
+ ##
51
+ # Private Instance Methods
52
+ #
53
+
54
+ def define_setter
55
+ field = self
56
+ method_name = field.setter
57
+
58
+ message_class.class_eval do
59
+ define_method(method_name) do |val|
60
+ begin
61
+ val = "#{val}" if val.is_a?(Symbol)
62
+
63
+ if val.nil?
64
+ @values.delete(field.name)
65
+ elsif field.acceptable?(val)
66
+ @values[field.name] = val.dup
67
+ else
68
+ fail TypeError, "Unacceptable value #{val} for field #{field.name} of type #{field.type_class}"
69
+ end
70
+ rescue NoMethodError => ex
71
+ logger.error { ex.message }
72
+ logger.error { ex.backtrace.join("\n") }
73
+ raise TypeError, "Got NoMethodError attempting to set #{val} for field #{field.name} of type #{field.type_class}: #{ex.message}"
74
+ end
75
+ end
76
+ end
77
+
78
+ ::Protobuf.field_deprecator.deprecate_method(message_class, method_name) if field.deprecated?
79
+ end
80
+ end
81
+ end
82
+ end