protobuffy 3.1.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 (192) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.travis.yml +12 -0
  4. data/.yardopts +5 -0
  5. data/CHANGES.md +261 -0
  6. data/CONTRIBUTING.md +16 -0
  7. data/Gemfile +3 -0
  8. data/LICENSE.txt +14 -0
  9. data/README.md +58 -0
  10. data/Rakefile +61 -0
  11. data/bin/protoc-gen-ruby +17 -0
  12. data/bin/rpc_server +4 -0
  13. data/examples/bin/reverse-client-http +4 -0
  14. data/examples/bin/reverse-client-socket +4 -0
  15. data/examples/bin/reverse-client-zmq +4 -0
  16. data/examples/config.ru +6 -0
  17. data/examples/definitions/example/reverse.proto +12 -0
  18. data/examples/lib/example/reverse-client.rb +23 -0
  19. data/examples/lib/example/reverse-service.rb +9 -0
  20. data/examples/lib/example/reverse.pb.rb +36 -0
  21. data/lib/protobuf.rb +106 -0
  22. data/lib/protobuf/cli.rb +249 -0
  23. data/lib/protobuf/code_generator.rb +41 -0
  24. data/lib/protobuf/decoder.rb +74 -0
  25. data/lib/protobuf/deprecator.rb +42 -0
  26. data/lib/protobuf/descriptors.rb +3 -0
  27. data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +52 -0
  28. data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +249 -0
  29. data/lib/protobuf/encoder.rb +62 -0
  30. data/lib/protobuf/enum.rb +319 -0
  31. data/lib/protobuf/exceptions.rb +9 -0
  32. data/lib/protobuf/field.rb +74 -0
  33. data/lib/protobuf/field/base_field.rb +280 -0
  34. data/lib/protobuf/field/bool_field.rb +53 -0
  35. data/lib/protobuf/field/bytes_field.rb +81 -0
  36. data/lib/protobuf/field/double_field.rb +26 -0
  37. data/lib/protobuf/field/enum_field.rb +57 -0
  38. data/lib/protobuf/field/field_array.rb +86 -0
  39. data/lib/protobuf/field/fixed32_field.rb +25 -0
  40. data/lib/protobuf/field/fixed64_field.rb +29 -0
  41. data/lib/protobuf/field/float_field.rb +38 -0
  42. data/lib/protobuf/field/int32_field.rb +22 -0
  43. data/lib/protobuf/field/int64_field.rb +22 -0
  44. data/lib/protobuf/field/integer_field.rb +24 -0
  45. data/lib/protobuf/field/message_field.rb +66 -0
  46. data/lib/protobuf/field/sfixed32_field.rb +28 -0
  47. data/lib/protobuf/field/sfixed64_field.rb +29 -0
  48. data/lib/protobuf/field/signed_integer_field.rb +30 -0
  49. data/lib/protobuf/field/sint32_field.rb +22 -0
  50. data/lib/protobuf/field/sint64_field.rb +22 -0
  51. data/lib/protobuf/field/string_field.rb +35 -0
  52. data/lib/protobuf/field/uint32_field.rb +22 -0
  53. data/lib/protobuf/field/uint64_field.rb +22 -0
  54. data/lib/protobuf/field/varint_field.rb +68 -0
  55. data/lib/protobuf/generators/base.rb +71 -0
  56. data/lib/protobuf/generators/enum_generator.rb +42 -0
  57. data/lib/protobuf/generators/extension_generator.rb +28 -0
  58. data/lib/protobuf/generators/field_generator.rb +132 -0
  59. data/lib/protobuf/generators/file_generator.rb +140 -0
  60. data/lib/protobuf/generators/group_generator.rb +113 -0
  61. data/lib/protobuf/generators/message_generator.rb +99 -0
  62. data/lib/protobuf/generators/printable.rb +161 -0
  63. data/lib/protobuf/generators/service_generator.rb +27 -0
  64. data/lib/protobuf/http.rb +20 -0
  65. data/lib/protobuf/lifecycle.rb +46 -0
  66. data/lib/protobuf/logger.rb +86 -0
  67. data/lib/protobuf/message.rb +182 -0
  68. data/lib/protobuf/message/fields.rb +122 -0
  69. data/lib/protobuf/message/serialization.rb +84 -0
  70. data/lib/protobuf/optionable.rb +23 -0
  71. data/lib/protobuf/rpc/buffer.rb +79 -0
  72. data/lib/protobuf/rpc/client.rb +168 -0
  73. data/lib/protobuf/rpc/connector.rb +21 -0
  74. data/lib/protobuf/rpc/connectors/base.rb +54 -0
  75. data/lib/protobuf/rpc/connectors/common.rb +172 -0
  76. data/lib/protobuf/rpc/connectors/http.rb +90 -0
  77. data/lib/protobuf/rpc/connectors/socket.rb +73 -0
  78. data/lib/protobuf/rpc/connectors/zmq.rb +205 -0
  79. data/lib/protobuf/rpc/dynamic_discovery.pb.rb +47 -0
  80. data/lib/protobuf/rpc/env.rb +58 -0
  81. data/lib/protobuf/rpc/error.rb +28 -0
  82. data/lib/protobuf/rpc/error/client_error.rb +31 -0
  83. data/lib/protobuf/rpc/error/server_error.rb +43 -0
  84. data/lib/protobuf/rpc/middleware.rb +25 -0
  85. data/lib/protobuf/rpc/middleware/exception_handler.rb +36 -0
  86. data/lib/protobuf/rpc/middleware/logger.rb +91 -0
  87. data/lib/protobuf/rpc/middleware/request_decoder.rb +83 -0
  88. data/lib/protobuf/rpc/middleware/response_encoder.rb +88 -0
  89. data/lib/protobuf/rpc/middleware/runner.rb +18 -0
  90. data/lib/protobuf/rpc/rpc.pb.rb +53 -0
  91. data/lib/protobuf/rpc/server.rb +39 -0
  92. data/lib/protobuf/rpc/servers/http/server.rb +101 -0
  93. data/lib/protobuf/rpc/servers/http_runner.rb +34 -0
  94. data/lib/protobuf/rpc/servers/socket/server.rb +113 -0
  95. data/lib/protobuf/rpc/servers/socket/worker.rb +56 -0
  96. data/lib/protobuf/rpc/servers/socket_runner.rb +34 -0
  97. data/lib/protobuf/rpc/servers/zmq/broker.rb +155 -0
  98. data/lib/protobuf/rpc/servers/zmq/server.rb +313 -0
  99. data/lib/protobuf/rpc/servers/zmq/util.rb +47 -0
  100. data/lib/protobuf/rpc/servers/zmq/worker.rb +105 -0
  101. data/lib/protobuf/rpc/servers/zmq_runner.rb +51 -0
  102. data/lib/protobuf/rpc/service.rb +179 -0
  103. data/lib/protobuf/rpc/service_directory.rb +245 -0
  104. data/lib/protobuf/rpc/service_dispatcher.rb +46 -0
  105. data/lib/protobuf/rpc/service_filters.rb +273 -0
  106. data/lib/protobuf/rpc/stat.rb +148 -0
  107. data/lib/protobuf/socket.rb +22 -0
  108. data/lib/protobuf/tasks.rb +1 -0
  109. data/lib/protobuf/tasks/compile.rake +61 -0
  110. data/lib/protobuf/version.rb +3 -0
  111. data/lib/protobuf/wire_type.rb +10 -0
  112. data/lib/protobuf/zmq.rb +21 -0
  113. data/proto/dynamic_discovery.proto +44 -0
  114. data/proto/google/protobuf/compiler/plugin.proto +147 -0
  115. data/proto/google/protobuf/descriptor.proto +620 -0
  116. data/proto/rpc.proto +62 -0
  117. data/protobuffy.gemspec +37 -0
  118. data/spec/benchmark/tasks.rb +113 -0
  119. data/spec/bin/protoc-gen-ruby_spec.rb +18 -0
  120. data/spec/data/data.bin +3 -0
  121. data/spec/data/types.bin +0 -0
  122. data/spec/encoding/all_types_spec.rb +91 -0
  123. data/spec/encoding/extreme_values_spec.rb +0 -0
  124. data/spec/functional/socket_server_spec.rb +59 -0
  125. data/spec/functional/zmq_server_spec.rb +103 -0
  126. data/spec/lib/protobuf/cli_spec.rb +267 -0
  127. data/spec/lib/protobuf/code_generator_spec.rb +60 -0
  128. data/spec/lib/protobuf/enum_spec.rb +239 -0
  129. data/spec/lib/protobuf/field/int32_field_spec.rb +7 -0
  130. data/spec/lib/protobuf/field/string_field_spec.rb +46 -0
  131. data/spec/lib/protobuf/field_spec.rb +194 -0
  132. data/spec/lib/protobuf/generators/base_spec.rb +87 -0
  133. data/spec/lib/protobuf/generators/enum_generator_spec.rb +68 -0
  134. data/spec/lib/protobuf/generators/extension_generator_spec.rb +43 -0
  135. data/spec/lib/protobuf/generators/field_generator_spec.rb +99 -0
  136. data/spec/lib/protobuf/generators/file_generator_spec.rb +29 -0
  137. data/spec/lib/protobuf/generators/message_generator_spec.rb +0 -0
  138. data/spec/lib/protobuf/generators/service_generator_spec.rb +43 -0
  139. data/spec/lib/protobuf/lifecycle_spec.rb +89 -0
  140. data/spec/lib/protobuf/logger_spec.rb +136 -0
  141. data/spec/lib/protobuf/message_spec.rb +368 -0
  142. data/spec/lib/protobuf/optionable_spec.rb +46 -0
  143. data/spec/lib/protobuf/rpc/client_spec.rb +66 -0
  144. data/spec/lib/protobuf/rpc/connector_spec.rb +26 -0
  145. data/spec/lib/protobuf/rpc/connectors/base_spec.rb +50 -0
  146. data/spec/lib/protobuf/rpc/connectors/common_spec.rb +170 -0
  147. data/spec/lib/protobuf/rpc/connectors/connector_spec.rb +13 -0
  148. data/spec/lib/protobuf/rpc/connectors/http_spec.rb +61 -0
  149. data/spec/lib/protobuf/rpc/connectors/socket_spec.rb +24 -0
  150. data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +129 -0
  151. data/spec/lib/protobuf/rpc/middleware/exception_handler_spec.rb +62 -0
  152. data/spec/lib/protobuf/rpc/middleware/logger_spec.rb +49 -0
  153. data/spec/lib/protobuf/rpc/middleware/request_decoder_spec.rb +115 -0
  154. data/spec/lib/protobuf/rpc/middleware/response_encoder_spec.rb +75 -0
  155. data/spec/lib/protobuf/rpc/servers/http/server_spec.rb +104 -0
  156. data/spec/lib/protobuf/rpc/servers/socket_server_spec.rb +38 -0
  157. data/spec/lib/protobuf/rpc/servers/zmq/server_spec.rb +41 -0
  158. data/spec/lib/protobuf/rpc/servers/zmq/util_spec.rb +55 -0
  159. data/spec/lib/protobuf/rpc/servers/zmq/worker_spec.rb +35 -0
  160. data/spec/lib/protobuf/rpc/service_directory_spec.rb +295 -0
  161. data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +52 -0
  162. data/spec/lib/protobuf/rpc/service_filters_spec.rb +484 -0
  163. data/spec/lib/protobuf/rpc/service_spec.rb +161 -0
  164. data/spec/lib/protobuf/rpc/stat_spec.rb +151 -0
  165. data/spec/lib/protobuf_spec.rb +78 -0
  166. data/spec/spec_helper.rb +57 -0
  167. data/spec/support/all.rb +7 -0
  168. data/spec/support/packed_field.rb +22 -0
  169. data/spec/support/server.rb +94 -0
  170. data/spec/support/test/all_types.data.bin +0 -0
  171. data/spec/support/test/all_types.data.txt +119 -0
  172. data/spec/support/test/defaults.pb.rb +25 -0
  173. data/spec/support/test/defaults.proto +9 -0
  174. data/spec/support/test/enum.pb.rb +59 -0
  175. data/spec/support/test/enum.proto +34 -0
  176. data/spec/support/test/extended.pb.rb +22 -0
  177. data/spec/support/test/extended.proto +10 -0
  178. data/spec/support/test/extreme_values.data.bin +0 -0
  179. data/spec/support/test/google_unittest.pb.rb +543 -0
  180. data/spec/support/test/google_unittest.proto +713 -0
  181. data/spec/support/test/google_unittest_import.pb.rb +37 -0
  182. data/spec/support/test/google_unittest_import.proto +64 -0
  183. data/spec/support/test/google_unittest_import_public.pb.rb +8 -0
  184. data/spec/support/test/google_unittest_import_public.proto +38 -0
  185. data/spec/support/test/multi_field_extensions.pb.rb +56 -0
  186. data/spec/support/test/multi_field_extensions.proto +33 -0
  187. data/spec/support/test/resource.pb.rb +117 -0
  188. data/spec/support/test/resource.proto +94 -0
  189. data/spec/support/test/resource_service.rb +26 -0
  190. data/spec/support/test_app_file.rb +2 -0
  191. data/spec/support/tolerance_matcher.rb +40 -0
  192. metadata +367 -0
@@ -0,0 +1,86 @@
1
+ require 'logger'
2
+
3
+ module Protobuf
4
+ class Logger < ::Logger
5
+
6
+ class << self
7
+ attr_accessor :file, :level
8
+
9
+ # Stub out the log methods for Protobuf::Logger as singleton methods
10
+ [:debug, :info, :warn, :error, :fatal, :any, :add, :log].each do |m|
11
+ define_method(m) do |*params, &block|
12
+ instance && instance.__send__(m, *params, &block)
13
+ end
14
+ end
15
+ end
16
+
17
+ # One-line file/level configuration
18
+ def self.configure(options)
19
+ self.file = options.fetch(:file, false)
20
+ self.level = options.fetch(:level, false)
21
+ end
22
+
23
+ # Use to reset the instance
24
+ def self.reset_device!
25
+ self.file = self.level = @__instance = nil
26
+ end
27
+
28
+ # Singleton instance
29
+ def self.instance
30
+ @__instance ||= begin
31
+ log = nil
32
+
33
+ if @file && @level
34
+ log = new(self.file)
35
+ log.level = self.level
36
+ end
37
+
38
+ log
39
+ end
40
+ end
41
+
42
+ #
43
+ # LogMethods module for log method including, e.g.:
44
+ #
45
+ # class MyClass
46
+ # include Protobuf::Logger::LogMethods
47
+ # ...
48
+ # end
49
+ #
50
+ # Produce a module to allow "include" in other classes to avoid
51
+ # cluttering the namespace of the including class with the other methods defined above
52
+ #
53
+ module LogMethods
54
+ [:debug, :info, :warn, :error, :fatal, :any, :add, :log].each do |m|
55
+ define_method("log_#{m}") do |*params, &block|
56
+ params.map! { |message| sign_message(message) }
57
+ ::Protobuf::Logger.__send__(m, *params, &block)
58
+ end
59
+ end
60
+
61
+ # When included, also extend the LogMethods module for class access.
62
+ def self.included(base)
63
+ base.extend(LogMethods)
64
+ end
65
+
66
+ # We often want to log an exception, so let's make that a core
67
+ # concern of the logger.
68
+ #
69
+ def log_exception(ex)
70
+ log_error { ex.message }
71
+ log_error { ex.backtrace[0..5].join("\n") }
72
+ log_debug { ex.backtrace.join("\n") }
73
+ end
74
+
75
+ def log_signature
76
+ @_log_signature ||= "[#{self.class == Class ? self.name : self.class.name}]"
77
+ end
78
+
79
+ def sign_message(message)
80
+ "#{log_signature} #{message}"
81
+ end
82
+
83
+ end
84
+
85
+ end
86
+ end
@@ -0,0 +1,182 @@
1
+ require 'protobuf/field'
2
+ require 'protobuf/enum'
3
+ require 'protobuf/exceptions'
4
+ require 'protobuf/message/fields'
5
+ require 'protobuf/message/serialization'
6
+
7
+ module Protobuf
8
+ class Message
9
+
10
+ ##
11
+ # Includes & Extends
12
+ #
13
+
14
+ extend ::Protobuf::Message::Fields
15
+ include ::Protobuf::Message::Serialization
16
+
17
+ ##
18
+ # Class Methods
19
+ #
20
+
21
+ def self.to_json
22
+ name
23
+ end
24
+
25
+ ##
26
+ # Constructor
27
+ #
28
+
29
+ def initialize(fields = {})
30
+ @values = {}
31
+
32
+ fields.to_hash.each_pair do |name, value|
33
+ self[name] = value unless value.nil?
34
+ end
35
+ end
36
+
37
+ ##
38
+ # Public Instance Methods
39
+ #
40
+
41
+ def clear!
42
+ @values.delete_if do |_, value|
43
+ if value.is_a?(::Protobuf::Field::FieldArray)
44
+ value.clear
45
+ false
46
+ else
47
+ true
48
+ end
49
+ end
50
+ self
51
+ end
52
+
53
+ def clone
54
+ copy_to(super, :clone)
55
+ end
56
+
57
+ def dup
58
+ copy_to(super, :dup)
59
+ end
60
+
61
+ # Iterate over every field, invoking the given block
62
+ #
63
+ def each_field
64
+ self.class.all_fields.each do |field|
65
+ value = __send__(field.name)
66
+ yield(field, value)
67
+ end
68
+ end
69
+
70
+ def each_field_for_serialization
71
+ self.class.all_fields.each do |field|
72
+ next unless field_must_be_serialized?(field)
73
+
74
+ value = @values[field.name]
75
+
76
+ if value.nil?
77
+ raise ::Protobuf::SerializationError, "Required field #{self.class.name}##{field.name} does not have a value."
78
+ else
79
+ yield(field, value)
80
+ end
81
+ end
82
+ end
83
+
84
+ def has_field?(name)
85
+ @values.has_key?(name)
86
+ end
87
+
88
+ def inspect
89
+ to_hash.inspect
90
+ end
91
+
92
+ def respond_to_has?(key)
93
+ respond_to?(key) && has_field?(key)
94
+ end
95
+
96
+ def respond_to_has_and_present?(key)
97
+ respond_to_has?(key) &&
98
+ (__send__(key).present? || [true, false].include?(__send__(key)))
99
+ end
100
+
101
+ # Return a hash-representation of the given fields for this message type.
102
+ def to_hash
103
+ result = Hash.new
104
+
105
+ @values.keys.each do |field_name|
106
+ value = __send__(field_name)
107
+ hashed_value = value.respond_to?(:to_hash_value) ? value.to_hash_value : value
108
+ result.merge!(field_name => hashed_value)
109
+ end
110
+
111
+ return result
112
+ end
113
+
114
+ def to_json(options = {})
115
+ to_hash.to_json(options)
116
+ end
117
+
118
+ def to_proto
119
+ self
120
+ end
121
+
122
+ def ==(obj)
123
+ return false unless obj.is_a?(self.class)
124
+ each_field do |field, value|
125
+ return false unless value == obj.__send__(field.name)
126
+ end
127
+ true
128
+ end
129
+
130
+ def [](name)
131
+ if field = self.class.get_field(name, true)
132
+ __send__(field.name)
133
+ end
134
+ end
135
+
136
+ def []=(name, value)
137
+ if field = self.class.get_field(name, true)
138
+ __send__(field.setter_method_name, value)
139
+ end
140
+ end
141
+
142
+ ##
143
+ # Instance Aliases
144
+ #
145
+ alias_method :to_hash_value, :to_hash
146
+ alias_method :to_proto_hash, :to_hash
147
+ alias_method :responds_to_has?, :respond_to_has?
148
+ alias_method :respond_to_and_has?, :respond_to_has?
149
+ alias_method :responds_to_and_has?, :respond_to_has?
150
+ alias_method :respond_to_has_present?, :respond_to_has_and_present?
151
+ alias_method :respond_to_and_has_present?, :respond_to_has_and_present?
152
+ alias_method :respond_to_and_has_and_present?, :respond_to_has_and_present?
153
+ alias_method :responds_to_has_present?, :respond_to_has_and_present?
154
+ alias_method :responds_to_and_has_present?, :respond_to_has_and_present?
155
+ alias_method :responds_to_and_has_and_present?, :respond_to_has_and_present?
156
+
157
+ ##
158
+ # Private Instance Methods
159
+ #
160
+ private
161
+
162
+ def copy_to(object, method)
163
+ duplicate = proc { |obj|
164
+ case obj
165
+ when Message, String then obj.__send__(method)
166
+ else obj
167
+ end
168
+ }
169
+
170
+ object.__send__(:initialize)
171
+ @values.each do |name, value|
172
+ if value.is_a?(::Protobuf::Field::FieldArray)
173
+ object.__send__(name).replace(value.map {|v| duplicate.call(v)})
174
+ else
175
+ object.__send__("#{name}=", duplicate.call(value))
176
+ end
177
+ end
178
+ object
179
+ end
180
+
181
+ end
182
+ end
@@ -0,0 +1,122 @@
1
+ require 'protobuf/deprecator'
2
+
3
+ module Protobuf
4
+ class Message
5
+ module Fields
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
14
+
15
+ ##
16
+ # Field Definition Methods
17
+ #
18
+
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
24
+
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
30
+
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
36
+
37
+ # Define an extension range.
38
+ #
39
+ def extensions(range)
40
+ extension_ranges << range
41
+ end
42
+
43
+ ##
44
+ # Field Access Methods
45
+ #
46
+
47
+ def all_fields
48
+ @all_fields ||= field_store.values.uniq
49
+ end
50
+
51
+ def extension_fields
52
+ @extension_fields ||= all_fields.select(&:extension?)
53
+ end
54
+
55
+ def extension_ranges
56
+ @extension_ranges ||= []
57
+ end
58
+
59
+ def extension_tag?(tag)
60
+ tag.respond_to?(:to_i) && get_extension_field(tag).present?
61
+ end
62
+
63
+ def field_store
64
+ @field_store ||= {}
65
+ end
66
+
67
+ def fields
68
+ @fields ||= all_fields.reject(&:extension?)
69
+ end
70
+
71
+ def field_tag?(tag, allow_extension = false)
72
+ tag.respond_to?(:to_i) && get_field(tag, allow_extension).present?
73
+ end
74
+
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
80
+
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]
84
+
85
+ if field && (allow_extension || ! field.extension?)
86
+ field
87
+ else
88
+ nil
89
+ end
90
+ end
91
+
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)
95
+
96
+ field = ::Protobuf::Field.build(self, rule, type_class, field_name, tag, options)
97
+ field_store[field_name] = field
98
+ field_store[tag] = field
99
+
100
+ class_eval(<<-RAW_GETTER, __FILE__, __LINE__ + 1)
101
+ define_method("#{field_name}!") do
102
+ @values[:#{field_name}]
103
+ end
104
+ RAW_GETTER
105
+ end
106
+
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}".!
110
+ end
111
+ end
112
+
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}".!
116
+ end
117
+ end
118
+
119
+ end
120
+ end
121
+ end
122
+
@@ -0,0 +1,84 @@
1
+ require 'stringio'
2
+ require 'protobuf/decoder'
3
+ require 'protobuf/encoder'
4
+
5
+ module Protobuf
6
+ class Message
7
+ module Serialization
8
+
9
+ module ClassMethods
10
+ def decode(bytes)
11
+ self.new.decode(bytes)
12
+ end
13
+
14
+ # Create a new object with the given values and return the encoded bytes.
15
+ def encode(fields = {})
16
+ self.new(fields).encode
17
+ end
18
+ end
19
+
20
+ def self.included(other)
21
+ other.extend(ClassMethods)
22
+ end
23
+
24
+ ##
25
+ # Instance Methods
26
+ #
27
+
28
+ # Decode the given non-stream bytes into this message.
29
+ #
30
+ def decode(bytes)
31
+ decode_from(::StringIO.new(bytes))
32
+ end
33
+
34
+ # Decode the given stream into this message.
35
+ #
36
+ def decode_from(stream)
37
+ ::Protobuf::Decoder.decode_each_field(stream) do |tag, bytes|
38
+ set_field_bytes(tag, bytes)
39
+ end
40
+
41
+ self
42
+ end
43
+
44
+ # Encode this message
45
+ #
46
+ def encode
47
+ stream = ::StringIO.new.set_encoding(::Protobuf::Field::BytesField::BYTES_ENCODING)
48
+ encode_to(stream).string
49
+ end
50
+
51
+ # Encode this message to the given stream.
52
+ #
53
+ def encode_to(stream)
54
+ ::Protobuf::Encoder.encode(self, stream)
55
+ end
56
+
57
+ ##
58
+ # Instance Aliases
59
+ #
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
69
+
70
+ private
71
+
72
+ def field_must_be_serialized?(field)
73
+ field.required? || ! @values[field.name].nil?
74
+ end
75
+
76
+ def set_field_bytes(tag, bytes)
77
+ field = self.class.get_field(tag, true)
78
+ field.set(self, bytes) if field
79
+ end
80
+
81
+ end
82
+ end
83
+ end
84
+