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,122 +1,204 @@
1
- require 'protobuf/deprecator'
1
+ require "set"
2
2
 
3
3
  module Protobuf
4
4
  class Message
5
5
  module Fields
6
6
 
7
- def self.extended(other)
8
- other.extend(::Protobuf::Deprecator)
9
- other.deprecate_class_method(:get_ext_field_by_name, :get_extension_field)
10
- other.deprecate_class_method(:get_ext_field_by_tag, :get_extension_field)
11
- other.deprecate_class_method(:get_field_by_name, :get_field)
12
- other.deprecate_class_method(:get_field_by_tag, :get_field)
13
- end
7
+ ACCESSOR_SUFFIXES = ["", "=", "!", "?"].freeze
14
8
 
15
- ##
16
- # Field Definition Methods
17
- #
9
+ def self.extended(other)
10
+ other.extend(ClassMethods)
11
+ ::Protobuf.deprecator.define_deprecated_methods(
12
+ other.singleton_class,
13
+ :get_ext_field_by_name => :get_extension_field,
14
+ :get_ext_field_by_tag => :get_extension_field,
15
+ :get_field_by_name => :get_field,
16
+ :get_field_by_tag => :get_field
17
+ )
18
+ end
19
+
20
+ module ClassMethods
21
+ def inherited(subclass)
22
+ inherit_fields!(subclass)
23
+ end
18
24
 
19
- # Define an optional field.
20
- #
21
- def optional(type_class, name, tag, options = {})
22
- define_field(:optional, type_class, name, tag, options)
23
- end
25
+ ##
26
+ # Field Definition Methods
27
+ #
24
28
 
25
- # Define a repeated field.
26
- #
27
- def repeated(type_class, name, tag, options = {})
28
- define_field(:repeated, type_class, name, tag, options)
29
- end
29
+ # Define an optional field.
30
+ #
31
+ def optional(type_class, name, tag, options = {})
32
+ define_field(:optional, type_class, name, tag, options)
33
+ end
30
34
 
31
- # Define a required field.
32
- #
33
- def required(type_class, name, tag, options = {})
34
- define_field(:required, type_class, name, tag, options)
35
- end
35
+ # Define a repeated field.
36
+ #
37
+ def repeated(type_class, name, tag, options = {})
38
+ define_field(:repeated, type_class, name, tag, options)
39
+ end
36
40
 
37
- # Define an extension range.
38
- #
39
- def extensions(range)
40
- extension_ranges << range
41
- end
41
+ # Define a required field.
42
+ #
43
+ def required(type_class, name, tag, options = {})
44
+ define_field(:required, type_class, name, tag, options)
45
+ end
42
46
 
43
- ##
44
- # Field Access Methods
45
- #
47
+ # Define an extension range.
48
+ #
49
+ def extensions(range)
50
+ extension_ranges << range
51
+ end
46
52
 
47
- def all_fields
48
- @all_fields ||= field_store.values.uniq
49
- end
53
+ ##
54
+ # Field Access Methods
55
+ #
56
+ def all_fields
57
+ @all_fields ||= field_store.values.uniq.sort_by(&:tag)
58
+ end
50
59
 
51
- def extension_fields
52
- @extension_fields ||= all_fields.select(&:extension?)
53
- end
60
+ def extension_fields
61
+ @extension_fields ||= all_fields.select(&:extension?)
62
+ end
54
63
 
55
- def extension_ranges
56
- @extension_ranges ||= []
57
- end
64
+ def extension_ranges
65
+ @extension_ranges ||= []
66
+ end
58
67
 
59
- def extension_tag?(tag)
60
- tag.respond_to?(:to_i) && get_extension_field(tag).present?
61
- end
68
+ def extension_tag?(tag)
69
+ tag.respond_to?(:to_i) && get_extension_field(tag).present?
70
+ end
62
71
 
63
- def field_store
64
- @field_store ||= {}
65
- end
72
+ def field_store
73
+ @field_store ||= {}
74
+ end
66
75
 
67
- def fields
68
- @fields ||= all_fields.reject(&:extension?)
69
- end
76
+ def fields
77
+ @fields ||= all_fields.reject(&:extension?)
78
+ end
70
79
 
71
- def field_tag?(tag, allow_extension = false)
72
- tag.respond_to?(:to_i) && get_field(tag, allow_extension).present?
73
- end
80
+ def field_tag?(tag, allow_extension = false)
81
+ tag.respond_to?(:to_i) && get_field(tag, allow_extension).present?
82
+ end
74
83
 
75
- def get_extension_field(name_or_tag)
76
- name_or_tag = name_or_tag.to_sym if name_or_tag.respond_to?(:to_sym)
77
- field = field_store[name_or_tag]
78
- field if field.try(:extension?) { false }
79
- end
84
+ def get_extension_field(name_or_tag)
85
+ field = field_store[name_or_tag]
86
+ field if field.try(:extension?) { false }
87
+ end
80
88
 
81
- def get_field(name_or_tag, allow_extension = false)
82
- name_or_tag = name_or_tag.to_sym if name_or_tag.respond_to?(:to_sym)
83
- field = field_store[name_or_tag]
89
+ def get_field(name_or_tag, allow_extension = false)
90
+ field = field_store[name_or_tag]
84
91
 
85
- if field && (allow_extension || ! field.extension?)
86
- field
87
- else
88
- nil
92
+ if field && (allow_extension || !field.extension?)
93
+ field
94
+ else
95
+ nil
96
+ end
89
97
  end
90
- end
91
98
 
92
- def define_field(rule, type_class, field_name, tag, options)
93
- raise_if_tag_collision(tag, field_name)
94
- raise_if_name_collision(field_name)
99
+ def define_field(rule, type_class, fully_qualified_field_name, tag, options)
100
+ raise_if_tag_collision(tag, fully_qualified_field_name)
101
+ raise_if_name_collision(fully_qualified_field_name)
102
+
103
+ # Determine appropirate accessor for fields depending on name collisions via extensions:
104
+
105
+ # Case 1: Base field = "string_field" and no extensions of the same name
106
+ # Result:
107
+ # message.string_field #=> @values["string_field"]
108
+ # message[:string_field] #=> @values["string_field"]
109
+ # message['string_field'] #=> @values["string_field"]
110
+
111
+ # Case 2: Base field = "string_field" and extension 1 = ".my_package.string_field", extension N = ".package_N.string_field"...
112
+ # Result:
113
+ # message.string_field #=> @values["string_field"]
114
+ # message[:string_field] #=> @values["string_field"]
115
+ # message['string_field'] #=> @values["string_field"]
116
+ # message[:'.my_package.string_field'] #=> @values[".my_package.string_field"]
117
+ # message['.my_package.string_field'] #=> @values[".my_package.string_field"]
118
+
119
+ # Case 3: No base field, extension 1 = ".my_package.string_field", extension 2 = ".other_package.string_field", extension N...
120
+ # Result:
121
+ # message.string_field #=> raise NoMethodError (no simple accessor allowed)
122
+ # message[:string_field] #=> raise NoMethodError (no simple accessor allowed)
123
+ # message['string_field'] #=> raise NoMethodError (no simple accessor allowed)
124
+ # message[:'.my_package.string_field'] #=> @values[".my_package.string_field"]
125
+ # message['.my_package.string_field'] #=> @values[".my_package.string_field"]
126
+ # message[:'.other_package.string_field'] #=> @values[".other_package.string_field"]
127
+ # message['.other_package.string_field'] #=> @values[".other_package.string_field"]
128
+
129
+ # Case 4: No base field, extension = ".my_package.string_field", no other extensions
130
+ # Result:
131
+ # message.string_field #=> @values[".my_package.string_field"]
132
+ # message[:string_field] #=> @values[".my_package.string_field"]
133
+ # message['string_field'] #=> @values[".my_package.string_field"]
134
+ # message[:'.my_package.string_field'] #=> @values[".my_package.string_field"]
135
+ # message[:'.my_package.string_field'] #=> @values[".my_package.string_field"]
136
+
137
+ simple_name =
138
+ if options[:extension]
139
+ base_name = fully_qualified_field_name.to_s.split('.').last.to_sym
140
+ if field_store[base_name]
141
+ # Case 3
142
+ if field_store[base_name].extension?
143
+ remove_existing_accessors(base_name)
144
+ end
145
+ nil
146
+ # Case 4
147
+ else
148
+ base_name
149
+ end
150
+ else
151
+ # Case 1
152
+ fully_qualified_field_name
153
+ end
154
+
155
+ field = ::Protobuf::Field.build(self, rule, type_class, fully_qualified_field_name,
156
+ tag, simple_name, options)
157
+ field_store[tag] = field
158
+ field_store[fully_qualified_field_name.to_sym] = field
159
+ field_store[fully_qualified_field_name.to_s] = field
160
+ if simple_name && simple_name != fully_qualified_field_name
161
+ field_store[simple_name.to_sym] = field
162
+ field_store[simple_name.to_s] = field
163
+ end
164
+ # defining a new field for the message will cause cached @all_fields, @extension_fields,
165
+ # and @fields to be incorrect; reset them
166
+ @all_fields = @extension_fields = @fields = nil
167
+ end
95
168
 
96
- field = ::Protobuf::Field.build(self, rule, type_class, field_name, tag, options)
97
- field_store[field_name] = field
98
- field_store[tag] = field
169
+ def remove_existing_accessors(accessor)
170
+ field_store.delete(accessor.to_sym).try(:fully_qualified_name_only!)
171
+ field_store.delete(accessor.to_s)
172
+ ACCESSOR_SUFFIXES.each do |modifier|
173
+ begin
174
+ remove_method("#{accessor}#{modifier}")
175
+ # rubocop: disable Lint/HandleExceptions
176
+ rescue NameError
177
+ # Do not remove the method
178
+ end
179
+ end
180
+ end
99
181
 
100
- class_eval(<<-RAW_GETTER, __FILE__, __LINE__ + 1)
101
- define_method("#{field_name}!") do
102
- @values[:#{field_name}]
182
+ def raise_if_tag_collision(tag, field_name)
183
+ if get_field(tag, true)
184
+ fail TagCollisionError, %(Field number #{tag} has already been used in "#{name}" by field "#{field_name}".)
103
185
  end
104
- RAW_GETTER
105
- end
186
+ end
106
187
 
107
- def raise_if_tag_collision(tag, field_name)
108
- if get_field(tag, true)
109
- raise TagCollisionError, %!Field number #{tag} has already been used in "#{name}" by field "#{field_name}".!
188
+ def raise_if_name_collision(field_name)
189
+ if get_field(field_name, true)
190
+ fail DuplicateFieldNameError, %(Field name #{field_name} has already been used in "#{name}".)
191
+ end
110
192
  end
111
- end
112
193
 
113
- def raise_if_name_collision(field_name)
114
- if get_field(field_name, true)
115
- raise DuplicateFieldNameError, %!Field name #{field_name} has already been used in "#{name}".!
194
+ def inherit_fields!(subclass)
195
+ instance_variables.each do |iv|
196
+ subclass.instance_variable_set(iv, instance_variable_get(iv))
197
+ end
116
198
  end
117
- end
199
+ private :inherit_fields!
118
200
 
201
+ end
119
202
  end
120
203
  end
121
204
  end
122
-
@@ -8,12 +8,16 @@ module Protobuf
8
8
 
9
9
  module ClassMethods
10
10
  def decode(bytes)
11
- self.new.decode(bytes)
11
+ new.decode(bytes)
12
+ end
13
+
14
+ def decode_from(stream)
15
+ new.decode_from(stream)
12
16
  end
13
17
 
14
18
  # Create a new object with the given values and return the encoded bytes.
15
19
  def encode(fields = {})
16
- self.new(fields).encode
20
+ new(fields).encode
17
21
  end
18
22
  end
19
23
 
@@ -44,8 +48,10 @@ module Protobuf
44
48
  # Encode this message
45
49
  #
46
50
  def encode
47
- stream = ::StringIO.new.set_encoding(::Protobuf::Field::BytesField::BYTES_ENCODING)
48
- encode_to(stream).string
51
+ stream = ::StringIO.new
52
+ stream.set_encoding(::Protobuf::Field::BytesField::BYTES_ENCODING)
53
+ encode_to(stream)
54
+ stream.string
49
55
  end
50
56
 
51
57
  # Encode this message to the given stream.
@@ -57,22 +63,18 @@ module Protobuf
57
63
  ##
58
64
  # Instance Aliases
59
65
  #
60
- alias_method :parse_from_string, :decode
61
- alias_method :deserialize, :decode
62
- alias_method :parse_from, :decode_from
63
- alias_method :deserialize_from, :decode_from
64
- alias_method :to_s, :encode
65
- alias_method :bytes, :encode
66
- alias_method :serialize, :encode
67
- alias_method :serialize_to_string, :encode
68
- alias_method :serialize_to, :encode_to
66
+ alias :parse_from_string decode
67
+ alias :deserialize decode
68
+ alias :parse_from decode_from
69
+ alias :deserialize_from decode_from
70
+ alias :to_s encode
71
+ alias :bytes encode
72
+ alias :serialize encode
73
+ alias :serialize_to_string encode
74
+ alias :serialize_to encode_to
69
75
 
70
76
  private
71
77
 
72
- def field_must_be_serialized?(field)
73
- field.required? || ! @values[field.name].nil?
74
- end
75
-
76
78
  def set_field_bytes(tag, bytes)
77
79
  field = self.class.get_field(tag, true)
78
80
  field.set(self, bytes) if field
@@ -81,4 +83,3 @@ module Protobuf
81
83
  end
82
84
  end
83
85
  end
84
-
@@ -1,17 +1,37 @@
1
- require 'active_support/concern'
2
-
3
1
  module Protobuf
4
2
  module Optionable
5
- extend ::ActiveSupport::Concern
6
-
7
3
  module ClassMethods
8
4
  def get_option(name)
9
- @_optionable_options.try(:[], name)
5
+ name = name.to_s
6
+ option = optionable_descriptor_class.get_field(name, true)
7
+ fail ArgumentError, "invalid option=#{name}" unless option
8
+ unless option.fully_qualified_name.to_s == name
9
+ # Eventually we'll deprecate the use of simple names of fields completely, but for now make sure people
10
+ # are accessing options correctly. We allow simple names in other places for backwards compatibility.
11
+ fail ArgumentError, "must access option using its fully qualified name: #{option.fully_qualified_name.inspect}"
12
+ end
13
+ value =
14
+ if @_optionable_options.try(:key?, name)
15
+ @_optionable_options[name]
16
+ else
17
+ option.default_value
18
+ end
19
+ if option.type_class < ::Protobuf::Message
20
+ option.type_class.new(value)
21
+ else
22
+ value
23
+ end
24
+ end
25
+
26
+ def get_option!(name)
27
+ get_option(name) if @_optionable_options.try(:key?, name.to_s)
10
28
  end
11
29
 
30
+ private
31
+
12
32
  def set_option(name, value = true)
13
33
  @_optionable_options ||= {}
14
- @_optionable_options[name] = value
34
+ @_optionable_options[name.to_s] = value
15
35
  end
16
36
  end
17
37
 
@@ -19,5 +39,32 @@ module Protobuf
19
39
  self.class.get_option(name)
20
40
  end
21
41
 
42
+ def get_option!(name)
43
+ self.class.get_option!(name)
44
+ end
45
+
46
+ def self.inject(base_class, extend_class = true, &block)
47
+ unless block_given?
48
+ fail ArgumentError, 'missing option class block (e.g: ::Google::Protobuf::MessageOptions)'
49
+ end
50
+ if extend_class
51
+ # Check if optionable_descriptor_class is already defined and short circuit if so.
52
+ # File options are injected per module, and since a module can be defined more than once,
53
+ # we will get a warning if we try to define optionable_descriptor_class twice.
54
+ if base_class.respond_to?(:optionable_descriptor_class)
55
+ # Don't define optionable_descriptor_class twice
56
+ return if base_class.optionable_descriptor_class == block.call
57
+
58
+ fail 'A class is being defined with two different descriptor classes, something is very wrong'
59
+ end
60
+
61
+ base_class.extend(ClassMethods)
62
+ base_class.__send__(:include, self)
63
+ base_class.define_singleton_method(:optionable_descriptor_class, block)
64
+ else
65
+ base_class.__send__(:include, ClassMethods)
66
+ base_class.module_eval { define_method(:optionable_descriptor_class, block) }
67
+ end
68
+ end
22
69
  end
23
70
  end
@@ -4,12 +4,12 @@ module Protobuf
4
4
 
5
5
  attr_accessor :mode, :data, :size
6
6
 
7
- MODES = [:read, :write]
7
+ MODES = [:read, :write].freeze
8
8
 
9
9
  # constantize this so we don't re-initialize the regex every time we need it
10
10
  SIZE_REGEX = /^\d+-/
11
11
 
12
- def initialize(mode=:read)
12
+ def initialize(mode = :read)
13
13
  @flush = false
14
14
  @data = ""
15
15
  @size = 0
@@ -17,18 +17,19 @@ module Protobuf
17
17
  end
18
18
 
19
19
  def mode=(mode)
20
- if MODES.include?(mode)
21
- @mode = mode
22
- else
23
- @mode = :read
24
- end
20
+ @mode =
21
+ if MODES.include?(mode)
22
+ mode
23
+ else
24
+ :read
25
+ end
25
26
  end
26
27
 
27
- def write(force_mode=true)
28
- if force_mode and reading?
29
- mode = :write
30
- elsif not force_mode and reading?
31
- raise = 'You chose to write the buffer when in read mode'
28
+ def write(force_mode = true)
29
+ if force_mode && reading?
30
+ self.mode = :write
31
+ elsif !force_mode && reading?
32
+ fail 'You chose to write the buffer when in read mode'
32
33
  end
33
34
 
34
35
  @size = @data.length
@@ -43,7 +44,7 @@ module Protobuf
43
44
  end
44
45
  end
45
46
 
46
- def set_data(data)
47
+ def set_data(data) # rubocop:disable Style/AccessorMethodName
47
48
  @data = data.to_s
48
49
  @size = @data.size
49
50
  end
@@ -60,19 +61,17 @@ module Protobuf
60
61
  @flush
61
62
  end
62
63
 
63
- def get_data_size
64
+ def get_data_size # rubocop:disable Style/AccessorMethodName
64
65
  if @size == 0 || @data.match(SIZE_REGEX)
65
66
  sliced_size = @data.slice!(SIZE_REGEX)
66
- @size = sliced_size.gsub('-', '').to_i unless sliced_size.nil?
67
+ @size = sliced_size.delete('-').to_i unless sliced_size.nil?
67
68
  end
68
69
  end
69
70
 
70
- private
71
+ private
71
72
 
72
73
  def check_for_flush
73
- if !@size.nil? && @data.length == @size
74
- @flush = true
75
- end
74
+ @flush = true if !@size.nil? && @data.length == @size
76
75
  end
77
76
  end
78
77
  end