protobuffy 3.6.0 → 4.0.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 (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
-