protobuffy 3.6.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (209) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +67 -0
  4. data/.rubocop_todo.yml +145 -0
  5. data/.travis.yml +25 -5
  6. data/CHANGES.md +55 -0
  7. data/CONTRIBUTING.md +1 -1
  8. data/LICENSE.txt +17 -9
  9. data/README.md +13 -12
  10. data/Rakefile +15 -11
  11. data/bin/protoc-gen-ruby +8 -3
  12. data/bin/rpc_server +1 -0
  13. data/examples/lib/example/reverse-client.rb +2 -2
  14. data/install-protobuf.sh +28 -0
  15. data/lib/protobuf.rb +57 -53
  16. data/lib/protobuf/cli.rb +94 -74
  17. data/lib/protobuf/code_generator.rb +60 -9
  18. data/lib/protobuf/decoder.rb +19 -65
  19. data/lib/protobuf/deprecation.rb +117 -0
  20. data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +11 -1
  21. data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +55 -3
  22. data/lib/protobuf/encoder.rb +13 -53
  23. data/lib/protobuf/enum.rb +58 -63
  24. data/lib/protobuf/field.rb +4 -4
  25. data/lib/protobuf/field/base_field.rb +101 -173
  26. data/lib/protobuf/field/bool_field.rb +17 -11
  27. data/lib/protobuf/field/bytes_field.rb +21 -35
  28. data/lib/protobuf/field/double_field.rb +0 -1
  29. data/lib/protobuf/field/enum_field.rb +23 -22
  30. data/lib/protobuf/field/field_array.rb +5 -4
  31. data/lib/protobuf/field/fixed32_field.rb +1 -1
  32. data/lib/protobuf/field/fixed64_field.rb +0 -1
  33. data/lib/protobuf/field/float_field.rb +4 -1
  34. data/lib/protobuf/field/int32_field.rb +0 -1
  35. data/lib/protobuf/field/int64_field.rb +0 -1
  36. data/lib/protobuf/field/integer_field.rb +0 -1
  37. data/lib/protobuf/field/message_field.rb +13 -28
  38. data/lib/protobuf/field/sfixed32_field.rb +0 -1
  39. data/lib/protobuf/field/sfixed64_field.rb +0 -1
  40. data/lib/protobuf/field/signed_integer_field.rb +0 -1
  41. data/lib/protobuf/field/sint32_field.rb +0 -1
  42. data/lib/protobuf/field/sint64_field.rb +0 -1
  43. data/lib/protobuf/field/string_field.rb +2 -4
  44. data/lib/protobuf/field/uint32_field.rb +0 -1
  45. data/lib/protobuf/field/uint64_field.rb +0 -1
  46. data/lib/protobuf/field/varint_field.rb +30 -13
  47. data/lib/protobuf/generators/base.rb +30 -16
  48. data/lib/protobuf/generators/enum_generator.rb +6 -9
  49. data/lib/protobuf/generators/extension_generator.rb +1 -2
  50. data/lib/protobuf/generators/field_generator.rb +25 -13
  51. data/lib/protobuf/generators/file_generator.rb +157 -35
  52. data/lib/protobuf/generators/group_generator.rb +22 -17
  53. data/lib/protobuf/generators/message_generator.rb +13 -14
  54. data/lib/protobuf/generators/option_generator.rb +17 -0
  55. data/lib/protobuf/generators/printable.rb +12 -13
  56. data/lib/protobuf/generators/service_generator.rb +2 -3
  57. data/lib/protobuf/http.rb +2 -2
  58. data/lib/protobuf/lifecycle.rb +20 -33
  59. data/lib/protobuf/logging.rb +39 -0
  60. data/lib/protobuf/message.rb +114 -47
  61. data/lib/protobuf/message/fields.rb +170 -88
  62. data/lib/protobuf/message/serialization.rb +19 -18
  63. data/lib/protobuf/optionable.rb +53 -6
  64. data/lib/protobuf/rpc/buffer.rb +18 -19
  65. data/lib/protobuf/rpc/client.rb +22 -50
  66. data/lib/protobuf/rpc/connectors/base.rb +177 -12
  67. data/lib/protobuf/rpc/connectors/http.rb +14 -9
  68. data/lib/protobuf/rpc/connectors/ping.rb +89 -0
  69. data/lib/protobuf/rpc/connectors/socket.rb +13 -8
  70. data/lib/protobuf/rpc/connectors/zmq.rb +178 -73
  71. data/lib/protobuf/rpc/dynamic_discovery.pb.rb +4 -1
  72. data/lib/protobuf/rpc/env.rb +12 -12
  73. data/lib/protobuf/rpc/error.rb +3 -3
  74. data/lib/protobuf/rpc/error/client_error.rb +4 -4
  75. data/lib/protobuf/rpc/error/server_error.rb +9 -9
  76. data/lib/protobuf/rpc/middleware/exception_handler.rb +6 -2
  77. data/lib/protobuf/rpc/middleware/logger.rb +8 -4
  78. data/lib/protobuf/rpc/middleware/request_decoder.rb +17 -21
  79. data/lib/protobuf/rpc/middleware/response_encoder.rb +22 -27
  80. data/lib/protobuf/rpc/middleware/statsd.rb +3 -3
  81. data/lib/protobuf/rpc/rpc.pb.rb +4 -1
  82. data/lib/protobuf/rpc/server.rb +1 -1
  83. data/lib/protobuf/rpc/servers/http/server.rb +19 -17
  84. data/lib/protobuf/rpc/servers/socket/server.rb +78 -70
  85. data/lib/protobuf/rpc/servers/socket/worker.rb +4 -4
  86. data/lib/protobuf/rpc/servers/socket_runner.rb +27 -15
  87. data/lib/protobuf/rpc/servers/zmq/broker.rb +70 -31
  88. data/lib/protobuf/rpc/servers/zmq/server.rb +55 -47
  89. data/lib/protobuf/rpc/servers/zmq/util.rb +14 -13
  90. data/lib/protobuf/rpc/servers/zmq/worker.rb +16 -16
  91. data/lib/protobuf/rpc/servers/zmq_runner.rb +26 -7
  92. data/lib/protobuf/rpc/service.rb +21 -27
  93. data/lib/protobuf/rpc/service_directory.rb +43 -27
  94. data/lib/protobuf/rpc/service_dispatcher.rb +9 -10
  95. data/lib/protobuf/rpc/service_filters.rb +32 -55
  96. data/lib/protobuf/rpc/stat.rb +4 -8
  97. data/lib/protobuf/socket.rb +1 -2
  98. data/lib/protobuf/tasks/compile.rake +3 -4
  99. data/lib/protobuf/varint.rb +9 -0
  100. data/lib/protobuf/varint_pure.rb +13 -0
  101. data/lib/protobuf/version.rb +1 -1
  102. data/lib/protobuf/zmq.rb +2 -2
  103. data/proto/google/protobuf/descriptor.proto +190 -31
  104. data/protobuffy.gemspec +30 -17
  105. data/spec/benchmark/tasks.rb +27 -19
  106. data/spec/bin/protoc-gen-ruby_spec.rb +11 -6
  107. data/spec/encoding/all_types_spec.rb +96 -84
  108. data/spec/encoding/extreme_values_spec.rb +0 -0
  109. data/spec/functional/class_inheritance_spec.rb +52 -0
  110. data/spec/functional/code_generator_spec.rb +38 -0
  111. data/spec/functional/socket_server_spec.rb +15 -15
  112. data/spec/functional/zmq_server_spec.rb +29 -27
  113. data/spec/lib/protobuf/cli_spec.rb +82 -67
  114. data/spec/lib/protobuf/code_generator_spec.rb +37 -10
  115. data/spec/lib/protobuf/enum_spec.rb +77 -46
  116. data/spec/lib/protobuf/field/bool_field_spec.rb +91 -0
  117. data/spec/lib/protobuf/field/double_field_spec.rb +9 -0
  118. data/spec/lib/protobuf/field/enum_field_spec.rb +26 -0
  119. data/spec/lib/protobuf/field/field_array_spec.rb +69 -0
  120. data/spec/lib/protobuf/field/fixed32_field_spec.rb +7 -0
  121. data/spec/lib/protobuf/field/fixed64_field_spec.rb +7 -0
  122. data/spec/lib/protobuf/field/float_field_spec.rb +90 -0
  123. data/spec/lib/protobuf/field/int32_field_spec.rb +114 -1
  124. data/spec/lib/protobuf/field/int64_field_spec.rb +7 -0
  125. data/spec/lib/protobuf/field/message_field_spec.rb +132 -0
  126. data/spec/lib/protobuf/field/sfixed32_field_spec.rb +9 -0
  127. data/spec/lib/protobuf/field/sfixed64_field_spec.rb +9 -0
  128. data/spec/lib/protobuf/field/sint32_field_spec.rb +9 -0
  129. data/spec/lib/protobuf/field/sint64_field_spec.rb +9 -0
  130. data/spec/lib/protobuf/field/string_field_spec.rb +44 -11
  131. data/spec/lib/protobuf/field/uint32_field_spec.rb +7 -0
  132. data/spec/lib/protobuf/field/uint64_field_spec.rb +7 -0
  133. data/spec/lib/protobuf/field_spec.rb +4 -6
  134. data/spec/lib/protobuf/generators/base_spec.rb +80 -13
  135. data/spec/lib/protobuf/generators/enum_generator_spec.rb +35 -21
  136. data/spec/lib/protobuf/generators/extension_generator_spec.rb +12 -13
  137. data/spec/lib/protobuf/generators/field_generator_spec.rb +73 -21
  138. data/spec/lib/protobuf/generators/file_generator_spec.rb +89 -6
  139. data/spec/lib/protobuf/generators/service_generator_spec.rb +25 -13
  140. data/spec/lib/protobuf/lifecycle_spec.rb +25 -20
  141. data/spec/lib/protobuf/message_spec.rb +578 -79
  142. data/spec/lib/protobuf/optionable_spec.rb +202 -26
  143. data/spec/lib/protobuf/rpc/client_spec.rb +16 -16
  144. data/spec/lib/protobuf/rpc/connectors/base_spec.rb +167 -13
  145. data/spec/lib/protobuf/rpc/connectors/connector_spec.rb +4 -5
  146. data/spec/lib/protobuf/rpc/connectors/http_spec.rb +13 -11
  147. data/spec/lib/protobuf/rpc/connectors/ping_spec.rb +69 -0
  148. data/spec/lib/protobuf/rpc/connectors/socket_spec.rb +6 -7
  149. data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +35 -52
  150. data/spec/lib/protobuf/rpc/middleware/exception_handler_spec.rb +10 -10
  151. data/spec/lib/protobuf/rpc/middleware/logger_spec.rb +11 -11
  152. data/spec/lib/protobuf/rpc/middleware/request_decoder_spec.rb +23 -23
  153. data/spec/lib/protobuf/rpc/middleware/response_encoder_spec.rb +11 -11
  154. data/spec/lib/protobuf/rpc/middleware/statsd_spec.rb +6 -6
  155. data/spec/lib/protobuf/rpc/servers/http/server_spec.rb +47 -44
  156. data/spec/lib/protobuf/rpc/servers/socket_server_spec.rb +6 -6
  157. data/spec/lib/protobuf/rpc/servers/zmq/server_spec.rb +12 -10
  158. data/spec/lib/protobuf/rpc/servers/zmq/util_spec.rb +11 -11
  159. data/spec/lib/protobuf/rpc/servers/zmq/worker_spec.rb +7 -7
  160. data/spec/lib/protobuf/rpc/service_directory_spec.rb +47 -49
  161. data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +8 -25
  162. data/spec/lib/protobuf/rpc/service_filters_spec.rb +102 -69
  163. data/spec/lib/protobuf/rpc/service_spec.rb +37 -36
  164. data/spec/lib/protobuf/rpc/stat_spec.rb +7 -9
  165. data/spec/lib/protobuf/varint_spec.rb +29 -0
  166. data/spec/lib/protobuf_spec.rb +55 -28
  167. data/spec/spec_helper.rb +12 -27
  168. data/spec/support/all.rb +0 -1
  169. data/spec/support/packed_field.rb +4 -3
  170. data/spec/support/{test → protos}/all_types.data.bin +0 -0
  171. data/spec/support/{test → protos}/all_types.data.txt +0 -0
  172. data/spec/support/{test → protos}/enum.pb.rb +8 -4
  173. data/spec/support/{test → protos}/enum.proto +4 -1
  174. data/spec/support/{test → protos}/extreme_values.data.bin +0 -0
  175. data/spec/support/protos/google_unittest.bin +0 -0
  176. data/spec/support/protos/google_unittest.pb.rb +798 -0
  177. data/spec/support/{test → protos}/google_unittest.proto +237 -66
  178. data/spec/support/protos/google_unittest_custom_options.bin +0 -0
  179. data/spec/support/protos/google_unittest_custom_options.pb.rb +268 -0
  180. data/spec/support/protos/google_unittest_custom_options.proto +424 -0
  181. data/spec/support/protos/google_unittest_import.pb.rb +55 -0
  182. data/spec/support/{test → protos}/google_unittest_import.proto +19 -10
  183. data/spec/support/protos/google_unittest_import_public.pb.rb +31 -0
  184. data/spec/support/{test → protos}/google_unittest_import_public.proto +8 -5
  185. data/spec/support/{test → protos}/multi_field_extensions.pb.rb +5 -2
  186. data/spec/support/{test → protos}/multi_field_extensions.proto +2 -0
  187. data/spec/support/{test → protos}/resource.pb.rb +47 -11
  188. data/spec/support/{test → protos}/resource.proto +24 -1
  189. data/spec/support/resource_service.rb +23 -0
  190. data/spec/support/server.rb +32 -61
  191. metadata +119 -59
  192. data/lib/protobuf/deprecator.rb +0 -42
  193. data/lib/protobuf/logger.rb +0 -93
  194. data/lib/protobuf/rpc/connector.rb +0 -21
  195. data/lib/protobuf/rpc/connectors/common.rb +0 -172
  196. data/spec/data/data.bin +0 -3
  197. data/spec/data/types.bin +0 -0
  198. data/spec/lib/protobuf/logger_spec.rb +0 -145
  199. data/spec/lib/protobuf/rpc/connector_spec.rb +0 -26
  200. data/spec/lib/protobuf/rpc/connectors/common_spec.rb +0 -170
  201. data/spec/support/test/defaults.pb.rb +0 -25
  202. data/spec/support/test/defaults.proto +0 -9
  203. data/spec/support/test/extended.pb.rb +0 -22
  204. data/spec/support/test/extended.proto +0 -10
  205. data/spec/support/test/google_unittest.pb.rb +0 -543
  206. data/spec/support/test/google_unittest_import.pb.rb +0 -37
  207. data/spec/support/test/google_unittest_import_public.pb.rb +0 -8
  208. data/spec/support/test/resource_service.rb +0 -26
  209. data/spec/support/tolerance_matcher.rb +0 -40
@@ -1,62 +1,22 @@
1
1
  module Protobuf
2
2
  class Encoder
3
-
4
- def self.encode(stream, message)
5
- new(stream, message).encode
6
- end
7
-
8
- attr_reader :message, :stream
9
-
10
- def initialize(message, stream)
11
- unless message.respond_to?(:each_field_for_serialization)
12
- raise ArgumentError, "Message instance must respond to :each_field_for_serialization"
13
- end
14
-
15
- @message = message
16
- @stream = stream
17
- end
18
-
19
- def encode
3
+ def self.encode(message, stream)
20
4
  message.each_field_for_serialization do |field, value|
21
- encode_field(field, value)
5
+ if field.repeated?
6
+ if field.packed?
7
+ packed_value = value.map { |val| field.encode(val) }.join
8
+ stream << "#{field.tag_encoded}#{::Protobuf::Field::VarintField.encode(packed_value.size)}#{packed_value}"
9
+ else
10
+ value.each do |val|
11
+ stream << "#{field.tag_encoded}#{field.encode(val)}"
12
+ end
13
+ end
14
+ else
15
+ stream << "#{field.tag_encoded}#{field.encode(value)}"
16
+ end
22
17
  end
23
18
 
24
19
  stream
25
20
  end
26
-
27
- private
28
-
29
- def encode_field(field, value)
30
- if field.repeated?
31
- encode_repeated_field(field, value)
32
- else
33
- write_pair(field, value)
34
- end
35
- end
36
-
37
- def encode_packed_field(field, value)
38
- key = (field.tag << 3) | ::Protobuf::WireType::LENGTH_DELIMITED
39
- packed_value = value.map { |val| field.encode(val) }.join
40
- stream << ::Protobuf::Field::VarintField.encode(key)
41
- stream << ::Protobuf::Field::VarintField.encode(packed_value.size)
42
- stream << packed_value
43
- end
44
-
45
- def encode_repeated_field(field, value)
46
- if field.packed?
47
- encode_packed_field(field, value)
48
- else
49
- value.each { |val| write_pair(field, val) }
50
- end
51
- end
52
-
53
- # Encode key and value, and write to +stream+.
54
- def write_pair(field, value)
55
- key = (field.tag << 3) | field.wire_type
56
- stream << ::Protobuf::Field::VarintField.encode(key)
57
- stream << field.encode(value)
58
- end
59
-
60
21
  end
61
22
  end
62
-
data/lib/protobuf/enum.rb CHANGED
@@ -1,38 +1,19 @@
1
1
  require 'delegate'
2
- require 'protobuf/optionable'
3
- require 'protobuf/deprecator'
4
2
 
5
3
  ##
6
4
  # Adding extension to Numeric until
7
5
  # we can get people to stop calling #value
8
6
  # on Enum instances.
9
7
  #
10
- class Numeric
11
- unless method_defined?(:value)
12
- def value
13
- $stderr.puts <<-DEPRECATION
14
- [DEPRECATED] Enum#value is deprecated and will be removed in the next release.
15
- Use Enum#to_i instead.
16
- DEPRECATION
17
- self
18
- end
19
- end
20
- end
8
+ ::Protobuf.deprecator.define_deprecated_methods(Numeric, :value => :to_int)
21
9
 
22
10
  module Protobuf
23
11
  class Enum < SimpleDelegator
24
-
25
- ##
26
- # Deprecations
27
- #
28
-
29
- extend ::Protobuf::Deprecator
30
-
31
12
  # Public: Allows setting Options on the Enum class.
32
- include ::Protobuf::Optionable
13
+ ::Protobuf::Optionable.inject(self) { ::Google::Protobuf::EnumOptions }
33
14
 
34
15
  def self.aliases_allowed?
35
- self.get_option(:allow_alias)
16
+ get_option(:allow_alias)
36
17
  end
37
18
 
38
19
  # Public: Get all integer tags defined by this enum.
@@ -51,7 +32,7 @@ module Protobuf
51
32
  # Returns an array of unique integers.
52
33
  #
53
34
  def self.all_tags
54
- @all_tags ||= self.enums.map(&:to_i).uniq
35
+ @all_tags ||= enums.map(&:to_i).uniq
55
36
  end
56
37
 
57
38
  # Internal: DSL method to create a new Enum. The given name will
@@ -70,16 +51,28 @@ module Protobuf
70
51
  # Returns nothing.
71
52
  #
72
53
  def self.define(name, tag)
73
- enum = self.new(self, name, tag)
54
+ enum = new(self, name, tag)
74
55
  @enums ||= []
75
56
  @enums << enum
57
+ # defining a new field for the enum will cause cached @values and @mapped_enums
58
+ # to be incorrect; reset them
59
+ @mapped_enums = @values = nil
76
60
  const_set(name, enum)
77
61
  end
78
62
 
63
+ # Internal: A mapping of enum number -> enums defined
64
+ # used for speeding up our internal enum methods.
65
+ def self.mapped_enums
66
+ @mapped_enums ||= enums.each_with_object({}) do |enum, hash|
67
+ list = hash[enum.to_i] ||= []
68
+ list << enum
69
+ end
70
+ end
71
+
79
72
  # Public: All defined enums.
80
73
  #
81
- def self.enums
82
- @enums
74
+ class << self
75
+ attr_reader :enums
83
76
  end
84
77
 
85
78
  # Public: Get an array of Enum objects with the given tag.
@@ -101,9 +94,7 @@ module Protobuf
101
94
  # Returns an array with zero or more Enum objects or nil.
102
95
  #
103
96
  def self.enums_for_tag(tag)
104
- self.enums.select { |enum|
105
- enum.to_i == tag.to_i
106
- }
97
+ tag && mapped_enums[tag.to_i] || []
107
98
  end
108
99
 
109
100
  # Public: Get the Enum associated with the given name.
@@ -125,7 +116,7 @@ module Protobuf
125
116
  # Returns the Enum object with the given name or nil.
126
117
  #
127
118
  def self.enum_for_name(name)
128
- self.const_get(name)
119
+ const_get(name)
129
120
  rescue ::NameError
130
121
  nil
131
122
  end
@@ -138,7 +129,7 @@ module Protobuf
138
129
  # Enums, the first enum defined will be returned.
139
130
  #
140
131
  def self.enum_for_tag(tag)
141
- self.enums_for_tag(tag).first
132
+ tag && (mapped_enums[tag.to_i] || []).first
142
133
  end
143
134
 
144
135
  # Public: Get an Enum by a variety of type-checking mechanisms.
@@ -162,12 +153,14 @@ module Protobuf
162
153
  # Returns an Enum object or nil.
163
154
  #
164
155
  def self.fetch(candidate)
156
+ return enum_for_tag(candidate) if candidate.is_a?(::Integer)
157
+
165
158
  case candidate
166
- when self then
159
+ when self
167
160
  candidate
168
- when ::Numeric then
161
+ when ::Numeric
169
162
  enum_for_tag(candidate.to_i)
170
- when ::String, ::Symbol then
163
+ when ::String, ::Symbol
171
164
  enum_for_name(candidate)
172
165
  else
173
166
  nil
@@ -206,7 +199,7 @@ module Protobuf
206
199
  # the first defined name will be returned.
207
200
  #
208
201
  def self.name_for_tag(tag)
209
- self.enum_for_tag(tag).try(:name)
202
+ enum_for_tag(tag).try(:name)
210
203
  end
211
204
 
212
205
  # Public: Check if the given tag is defined by this Enum.
@@ -216,37 +209,43 @@ module Protobuf
216
209
  # Returns a boolean.
217
210
  #
218
211
  def self.valid_tag?(tag)
219
- tag.respond_to?(:to_i) && self.all_tags.include?(tag.to_i)
212
+ tag.respond_to?(:to_i) && mapped_enums.key?(tag.to_i)
220
213
  end
221
214
 
222
215
  # Public: [DEPRECATED] Return a hash of Enum objects keyed
223
216
  # by their :name.
224
217
  #
225
218
  def self.values
226
- self.warn_deprecated(:values, :enums)
227
-
228
- @values ||= begin
229
- self.enums.inject({}) do |hash, enum|
230
- hash[enum.name] = enum
231
- hash
232
- end
233
- end
219
+ @values ||= enums.each_with_object({}) do |enum, hash|
220
+ hash[enum.name] = enum
221
+ end
234
222
  end
235
223
 
236
224
  ##
237
225
  # Class Deprecations
238
226
  #
227
+ class << self
228
+ ::Protobuf.deprecator.define_deprecated_methods(
229
+ self,
230
+ :enum_by_value => :enum_for_tag,
231
+ :name_by_value => :name_for_tag,
232
+ :get_name_by_tag => :name_for_tag,
233
+ :value_by_name => :enum_for_name
234
+ )
239
235
 
240
- deprecate_class_method :enum_by_value, :enum_for_tag
241
- deprecate_class_method :name_by_value, :name_for_tag
242
- deprecate_class_method :get_name_by_tag, :name_for_tag
243
- deprecate_class_method :value_by_name, :enum_for_name
244
-
236
+ ::Protobuf.deprecator.deprecate_methods(self, :values => :enums)
237
+ end
245
238
 
246
239
  ##
247
240
  # Attributes
248
241
  #
249
242
 
243
+ private
244
+
245
+ attr_writer :parent_class, :name, :tag
246
+
247
+ public
248
+
250
249
  attr_reader :parent_class, :name, :tag
251
250
 
252
251
  ##
@@ -254,10 +253,10 @@ module Protobuf
254
253
  #
255
254
 
256
255
  def initialize(parent_class, name, tag)
257
- @parent_class = parent_class
258
- @name = name
259
- @tag = tag
260
- super(@tag)
256
+ self.parent_class = parent_class
257
+ self.name = name
258
+ self.tag = tag
259
+ super(tag)
261
260
  end
262
261
 
263
262
  # Overriding the class so ActiveRecord/Arel visitor will visit the enum as a Fixnum
@@ -280,12 +279,12 @@ module Protobuf
280
279
 
281
280
  def to_s(format = :tag)
282
281
  case format
283
- when :tag then
284
- self.to_i.to_s
285
- when :name then
282
+ when :tag
283
+ to_i.to_s
284
+ when :name
286
285
  name.to_s
287
286
  else
288
- self.to_i.to_s
287
+ to_i.to_s
289
288
  end
290
289
  end
291
290
 
@@ -305,15 +304,11 @@ module Protobuf
305
304
  end
306
305
  end
307
306
 
308
- def value
309
- parent_class.warn_deprecated(:value, :to_i)
310
- to_i
311
- end
307
+ ::Protobuf.deprecator.define_deprecated_methods(self, :value => :to_i)
312
308
 
313
309
  ##
314
310
  # Instance Aliases
315
311
  #
316
- alias_method :to_hash_value, :to_i
312
+ alias :to_hash_value to_i
317
313
  end
318
314
  end
319
-
@@ -38,11 +38,11 @@ module Protobuf
38
38
  :sfixed64 => ::Protobuf::Field::Sfixed64Field,
39
39
  :string => ::Protobuf::Field::StringField,
40
40
  :bytes => ::Protobuf::Field::BytesField,
41
- :bool => ::Protobuf::Field::BoolField
41
+ :bool => ::Protobuf::Field::BoolField,
42
42
  }.freeze
43
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)
44
+ def self.build(message_class, rule, type, name, tag, simple_name, options = {})
45
+ field_class(type).new(message_class, rule, field_type(type), name, tag, simple_name, options)
46
46
  end
47
47
 
48
48
  # Returns the field class for primitives,
@@ -59,7 +59,7 @@ module Protobuf
59
59
  elsif type < ::Protobuf::Field::BaseField
60
60
  type
61
61
  else
62
- raise ArgumentError, "Invalid field type #{type}"
62
+ fail ArgumentError, "Invalid field type #{type}"
63
63
  end
64
64
  end
65
65
 
@@ -1,9 +1,10 @@
1
- require 'protobuf/wire_type'
1
+ require 'active_support/core_ext/hash/slice'
2
2
  require 'protobuf/field/field_array'
3
-
4
3
  module Protobuf
5
4
  module Field
6
5
  class BaseField
6
+ include ::Protobuf::Logging
7
+ ::Protobuf::Optionable.inject(self, false) { ::Google::Protobuf::FieldOptions }
7
8
 
8
9
  ##
9
10
  # Constants
@@ -12,17 +13,13 @@ module Protobuf
12
13
  PACKED_TYPES = [
13
14
  ::Protobuf::WireType::VARINT,
14
15
  ::Protobuf::WireType::FIXED32,
15
- ::Protobuf::WireType::FIXED64
16
+ ::Protobuf::WireType::FIXED64,
16
17
  ].freeze
17
18
 
18
19
  ##
19
20
  # Attributes
20
21
  #
21
-
22
- attr_reader :default, :default_value, :deprecated, :extension,
23
- :getter_method_name, :message_class, :name, :optional,
24
- :packed, :repeated, :required, :rule, :setter_method_name,
25
- :tag, :type_class
22
+ attr_reader :message_class, :name, :fully_qualified_name, :options, :rule, :tag, :type_class
26
23
 
27
24
  ##
28
25
  # Class Methods
@@ -36,123 +33,136 @@ module Protobuf
36
33
  # Constructor
37
34
  #
38
35
 
39
- def initialize(message_class, rule, type_class, name, tag, options)
40
- @message_class, @rule, @type_class, @name, @tag = \
41
- message_class, rule, type_class, name, tag
42
-
43
- set_rule_predicates
44
-
45
- @getter_method_name = name
46
- @setter_method_name = "#{name}="
47
- @default = options.delete(:default)
48
- @extension = options.delete(:extension)
49
- @packed = repeated? && options.delete(:packed)
50
- @deprecated = options.delete(:deprecated)
36
+ def initialize(message_class, rule, type_class, fully_qualified_name, tag, simple_name, options)
37
+ @message_class = message_class
38
+ @name = simple_name || fully_qualified_name
39
+ @fully_qualified_name = fully_qualified_name
40
+ @rule = rule
41
+ @tag = tag
42
+ @type_class = type_class
43
+ # Populate the option hash with all the original default field options, for backwards compatibility.
44
+ # However, both default and custom options should ideally be accessed through the Optionable .{get,get!}_option functions.
45
+ @options = options.slice(:ctype, :packed, :deprecated, :lazy, :jstype, :weak, :uninterpreted_option, :default, :extension)
46
+ options.each do |option_name, value|
47
+ set_option(option_name, value)
48
+ end
51
49
 
52
- set_default_value
53
- warn_excess_options(options) unless options.empty?
54
50
  validate_packed_field if packed?
55
- define_accessor
51
+ define_accessor(simple_name, fully_qualified_name) if simple_name
52
+ tag_encoded
56
53
  end
57
54
 
58
55
  ##
59
56
  # Public Instance Methods
60
57
  #
61
58
 
62
- def acceptable?(value)
59
+ def acceptable?(_value)
63
60
  true
64
61
  end
65
62
 
66
- def enum?
67
- false
63
+ def coerce!(value)
64
+ value
68
65
  end
69
66
 
70
- def message?
71
- false
67
+ def decode(_bytes)
68
+ fail NotImplementedError, "#{self.class.name}##{__method__}"
72
69
  end
73
70
 
74
- # Decode +bytes+ and pass to +message_instance+.
75
- def set(message_instance, bytes)
76
- if packed?
77
- array = message_instance.__send__(getter_method_name)
78
- method = \
79
- case wire_type
80
- when ::Protobuf::WireType::FIXED32 then :read_fixed32
81
- when ::Protobuf::WireType::FIXED64 then :read_fixed64
82
- when ::Protobuf::WireType::VARINT then :read_varint
83
- end
84
- stream = StringIO.new(bytes)
85
-
86
- until stream.eof?
87
- array << decode(::Protobuf::Decoder.__send__(method, stream))
88
- end
89
- else
90
- value = decode(bytes)
91
- if repeated?
92
- message_instance.__send__(getter_method_name) << value
93
- else
94
- message_instance.__send__(setter_method_name, value)
95
- end
96
- end
71
+ def default
72
+ options[:default]
73
+ end
74
+
75
+ def default_value
76
+ @default_value ||= if optional? || required?
77
+ typed_default_value
78
+ elsif repeated?
79
+ ::Protobuf::Field::FieldArray.new(self).freeze
80
+ else
81
+ fail "Unknown field label -- something went very wrong"
82
+ end
97
83
  end
98
84
 
99
- # Decode +bytes+ and return a field value.
100
- def decode(bytes)
101
- raise NotImplementedError, "#{self.class.name}\#decode"
85
+ def deprecated?
86
+ options.key?(:deprecated)
102
87
  end
103
88
 
104
- # Encode +value+ and return a byte string.
105
- def encode(value)
106
- raise NotImplementedError, "#{self.class.name}\#encode"
89
+ def encode(_value)
90
+ fail NotImplementedError, "#{self.class.name}##{__method__}"
107
91
  end
108
92
 
109
93
  def extension?
110
- !! extension
94
+ options.key?(:extension)
95
+ end
96
+
97
+ def enum?
98
+ false
99
+ end
100
+
101
+ def message?
102
+ false
103
+ end
104
+
105
+ def optional?
106
+ rule == :optional
107
+ end
108
+
109
+ def packed?
110
+ repeated? && options.key?(:packed)
111
111
  end
112
112
 
113
- # Is this a repeated field?
114
113
  def repeated?
115
- !! repeated
114
+ rule == :repeated
116
115
  end
117
116
 
118
- # Is this a repeated message field?
119
117
  def repeated_message?
120
118
  repeated? && message?
121
119
  end
122
120
 
123
- # Is this a required field?
124
121
  def required?
125
- !! required
122
+ rule == :required
126
123
  end
127
124
 
128
- # Is this a optional field?
129
- def optional?
130
- !! optional
131
- end
132
-
133
- # Is this a deprecated field?
134
- def deprecated?
135
- !! deprecated
125
+ # FIXME: need to cleanup (rename) this warthog of a method.
126
+ def set(message_instance, bytes)
127
+ return message_instance[name] = decode(bytes) unless repeated?
128
+ return message_instance[name] << decode(bytes) unless packed?
129
+
130
+ array = message_instance[name]
131
+ stream = StringIO.new(bytes)
132
+
133
+ if wire_type == ::Protobuf::WireType::VARINT
134
+ array << decode(Varint.decode(stream)) until stream.eof?
135
+ elsif wire_type == ::Protobuf::WireType::FIXED64
136
+ array << decode(stream.read(8)) until stream.eof?
137
+ elsif wire_type == ::Protobuf::WireType::FIXED32
138
+ array << decode(stream.read(4)) until stream.eof?
139
+ end
136
140
  end
137
141
 
138
- # Is this a packed repeated field?
139
- def packed?
140
- !! packed
142
+ def tag_encoded
143
+ @tag_encoded ||= begin
144
+ case
145
+ when repeated? && packed?
146
+ ::Protobuf::Field::VarintField.encode((tag << 3) | ::Protobuf::WireType::LENGTH_DELIMITED)
147
+ else
148
+ ::Protobuf::Field::VarintField.encode((tag << 3) | wire_type)
149
+ end
150
+ end
141
151
  end
142
152
 
153
+ # FIXME: add packed, deprecated, extension options to to_s output
143
154
  def to_s
144
155
  "#{rule} #{type_class} #{name} = #{tag} #{default ? "[default=#{default.inspect}]" : ''}"
145
156
  end
146
157
 
147
- def type
148
- $stderr.puts("[DEPRECATED] #{self.class.name}#type usage is deprecated.\nPlease use #type_class instead.")
149
- type_class
158
+ ::Protobuf.deprecator.define_deprecated_methods(self, :type => :type_class)
159
+
160
+ def wire_type
161
+ ::Protobuf::WireType::VARINT
150
162
  end
151
163
 
152
- def warn_if_deprecated
153
- if ::Protobuf.print_deprecation_warnings? && deprecated?
154
- $stderr.puts("[WARNING] #{message_class.name}##{name} field usage is deprecated.")
155
- end
164
+ def fully_qualified_name_only!
165
+ @name = @fully_qualified_name
156
166
  end
157
167
 
158
168
  private
@@ -161,99 +171,23 @@ module Protobuf
161
171
  # Private Instance Methods
162
172
  #
163
173
 
164
- def define_accessor
165
- if repeated?
166
- define_array_getter
167
- define_array_setter
168
- else
169
- define_getter
170
- define_setter
171
- end
172
- end
173
-
174
- def define_array_getter
175
- field = self
176
- message_class.class_eval do
177
- define_method(field.getter_method_name) do
178
- field.warn_if_deprecated
179
- @values[field.name] ||= ::Protobuf::Field::FieldArray.new(field)
180
- end
181
- end
182
- end
183
-
184
- def define_array_setter
185
- field = self
186
- message_class.class_eval do
187
- define_method(field.setter_method_name) do |val|
188
- field.warn_if_deprecated
189
-
190
- if val.is_a?(Array)
191
- val = val.dup
192
- val.compact!
193
- else
194
- raise TypeError, <<-TYPE_ERROR
195
- Expected repeated value of type '#{field.type_class}'
196
- Got '#{val.class}' for repeated protobuf field #{field.name}
197
- TYPE_ERROR
198
- end
199
-
200
- if val.nil? || (val.respond_to?(:empty?) && val.empty?)
201
- @values.delete(field.name)
202
- else
203
- @values[field.name] ||= ::Protobuf::Field::FieldArray.new(field)
204
- @values[field.name].replace(val)
205
- end
206
- end
207
- end
208
- end
209
-
210
- def define_getter
211
- field = self
174
+ def define_accessor(simple_field_name, fully_qualified_field_name)
212
175
  message_class.class_eval do
213
- define_method(field.getter_method_name) do
214
- field.warn_if_deprecated
215
- @values.fetch(field.name, field.default_value)
176
+ define_method("#{simple_field_name}!") do
177
+ @values[fully_qualified_field_name] if field?(fully_qualified_field_name)
216
178
  end
217
179
  end
218
- end
219
180
 
220
- def define_setter
221
- field = self
222
181
  message_class.class_eval do
223
- define_method(field.setter_method_name) do |val|
224
- field.warn_if_deprecated
225
-
226
- if val.nil? || (val.respond_to?(:empty?) && val.empty?)
227
- @values.delete(field.name)
228
- elsif field.acceptable?(val)
229
- @values[field.name] = val
230
- else
231
- raise TypeError, "Unacceptable value #{val} for field #{field.name} of type #{field.type_class}"
232
- end
233
- end
182
+ define_method(simple_field_name) { self[fully_qualified_field_name] }
183
+ define_method("#{simple_field_name}=") { |v| set_field(fully_qualified_field_name, v, false) }
234
184
  end
235
- end
236
185
 
237
- def set_default_value
238
- @default_value = case
239
- when repeated? then ::Protobuf::Field::FieldArray.new(self).freeze
240
- when required? then nil
241
- when optional? then typed_default_value
242
- end
243
- end
186
+ return unless deprecated?
244
187
 
245
- def set_rule_predicates
246
- case rule
247
- when :repeated then
248
- @required = @optional = false
249
- @repeated = true
250
- when :required then
251
- @repeated = @optional = false
252
- @required = true
253
- when :optional then
254
- @repeated = @required = false
255
- @optional = true
256
- end
188
+ ::Protobuf.field_deprecator.deprecate_method(message_class, simple_field_name)
189
+ ::Protobuf.field_deprecator.deprecate_method(message_class, "#{simple_field_name}!")
190
+ ::Protobuf.field_deprecator.deprecate_method(message_class, "#{simple_field_name}=")
257
191
  end
258
192
 
259
193
  def typed_default_value
@@ -266,15 +200,9 @@ module Protobuf
266
200
 
267
201
  def validate_packed_field
268
202
  if packed? && ! ::Protobuf::Field::BaseField::PACKED_TYPES.include?(wire_type)
269
- raise "Can't use packed encoding for '#{type_class}' type"
203
+ fail "Can't use packed encoding for '#{type_class}' type"
270
204
  end
271
205
  end
272
-
273
- def warn_excess_options(options)
274
- warn "WARNING: Invalid options: #{options.inspect} (in #{message_class.name}##{name})"
275
- end
276
-
277
206
  end
278
207
  end
279
208
  end
280
-