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.
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,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