protobuf 2.8.13 → 3.0.0.rc1

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 (116) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +84 -5
  3. data/CONTRIBUTING.md +3 -3
  4. data/Rakefile +46 -7
  5. data/lib/protobuf/cli.rb +2 -20
  6. data/lib/protobuf/decoder.rb +74 -0
  7. data/lib/protobuf/deprecator.rb +42 -0
  8. data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +17 -16
  9. data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +86 -85
  10. data/lib/protobuf/encoder.rb +62 -0
  11. data/lib/protobuf/enum.rb +298 -37
  12. data/lib/protobuf/field/base_field.rb +41 -27
  13. data/lib/protobuf/field/bool_field.rb +22 -4
  14. data/lib/protobuf/field/bytes_field.rb +36 -15
  15. data/lib/protobuf/field/double_field.rb +10 -3
  16. data/lib/protobuf/field/enum_field.rb +21 -18
  17. data/lib/protobuf/field/field_array.rb +26 -16
  18. data/lib/protobuf/field/fixed32_field.rb +10 -4
  19. data/lib/protobuf/field/fixed64_field.rb +10 -3
  20. data/lib/protobuf/field/float_field.rb +18 -5
  21. data/lib/protobuf/field/int32_field.rb +14 -4
  22. data/lib/protobuf/field/int64_field.rb +14 -4
  23. data/lib/protobuf/field/integer_field.rb +9 -4
  24. data/lib/protobuf/field/message_field.rb +16 -7
  25. data/lib/protobuf/field/sfixed32_field.rb +10 -3
  26. data/lib/protobuf/field/sfixed64_field.rb +12 -7
  27. data/lib/protobuf/field/signed_integer_field.rb +7 -0
  28. data/lib/protobuf/field/sint32_field.rb +14 -4
  29. data/lib/protobuf/field/sint64_field.rb +14 -4
  30. data/lib/protobuf/field/string_field.rb +11 -1
  31. data/lib/protobuf/field/uint32_field.rb +14 -4
  32. data/lib/protobuf/field/uint64_field.rb +14 -4
  33. data/lib/protobuf/field/varint_field.rb +11 -9
  34. data/lib/protobuf/field.rb +42 -25
  35. data/lib/protobuf/generators/enum_generator.rb +12 -1
  36. data/lib/protobuf/generators/field_generator.rb +1 -1
  37. data/lib/protobuf/lifecycle.rb +3 -4
  38. data/lib/protobuf/message/fields.rb +122 -0
  39. data/lib/protobuf/message/serialization.rb +84 -0
  40. data/lib/protobuf/message.rb +21 -221
  41. data/lib/protobuf/optionable.rb +23 -0
  42. data/lib/protobuf/rpc/client.rb +2 -4
  43. data/lib/protobuf/rpc/connector.rb +0 -2
  44. data/lib/protobuf/rpc/connectors/common.rb +2 -2
  45. data/lib/protobuf/rpc/dynamic_discovery.pb.rb +14 -16
  46. data/lib/protobuf/rpc/env.rb +58 -0
  47. data/lib/protobuf/rpc/error.rb +8 -5
  48. data/lib/protobuf/rpc/middleware/exception_handler.rb +36 -0
  49. data/lib/protobuf/rpc/middleware/logger.rb +91 -0
  50. data/lib/protobuf/rpc/middleware/request_decoder.rb +83 -0
  51. data/lib/protobuf/rpc/middleware/response_encoder.rb +88 -0
  52. data/lib/protobuf/rpc/middleware/runner.rb +18 -0
  53. data/lib/protobuf/rpc/middleware.rb +25 -0
  54. data/lib/protobuf/rpc/rpc.pb.rb +15 -16
  55. data/lib/protobuf/rpc/server.rb +14 -64
  56. data/lib/protobuf/rpc/servers/socket/server.rb +0 -2
  57. data/lib/protobuf/rpc/servers/socket/worker.rb +11 -15
  58. data/lib/protobuf/rpc/servers/zmq/util.rb +4 -1
  59. data/lib/protobuf/rpc/servers/zmq/worker.rb +5 -13
  60. data/lib/protobuf/rpc/servers/zmq_runner.rb +1 -1
  61. data/lib/protobuf/rpc/service.rb +38 -72
  62. data/lib/protobuf/rpc/service_dispatcher.rb +20 -108
  63. data/lib/protobuf/version.rb +1 -2
  64. data/lib/protobuf.rb +5 -13
  65. data/protobuf.gemspec +5 -5
  66. data/spec/benchmark/tasks.rb +2 -77
  67. data/spec/functional/zmq_server_spec.rb +13 -21
  68. data/spec/lib/protobuf/cli_spec.rb +5 -43
  69. data/spec/lib/protobuf/enum_spec.rb +194 -61
  70. data/spec/lib/protobuf/field_spec.rb +194 -0
  71. data/spec/lib/protobuf/generators/enum_generator_spec.rb +24 -1
  72. data/spec/lib/protobuf/generators/field_generator_spec.rb +6 -6
  73. data/spec/lib/protobuf/message_spec.rb +52 -70
  74. data/spec/lib/protobuf/optionable_spec.rb +46 -0
  75. data/spec/lib/protobuf/rpc/client_spec.rb +1 -93
  76. data/spec/lib/protobuf/rpc/connector_spec.rb +1 -7
  77. data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +8 -0
  78. data/spec/lib/protobuf/rpc/middleware/exception_handler_spec.rb +62 -0
  79. data/spec/lib/protobuf/rpc/middleware/logger_spec.rb +49 -0
  80. data/spec/lib/protobuf/rpc/middleware/request_decoder_spec.rb +115 -0
  81. data/spec/lib/protobuf/rpc/middleware/response_encoder_spec.rb +75 -0
  82. data/spec/lib/protobuf/rpc/servers/socket_server_spec.rb +0 -6
  83. data/spec/lib/protobuf/rpc/servers/zmq/util_spec.rb +10 -0
  84. data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +30 -105
  85. data/spec/lib/protobuf/rpc/service_filters_spec.rb +4 -4
  86. data/spec/lib/protobuf/rpc/service_spec.rb +20 -24
  87. data/spec/lib/protobuf_spec.rb +3 -3
  88. data/spec/spec_helper.rb +5 -4
  89. data/spec/support/packed_field.rb +15 -14
  90. data/spec/support/server.rb +4 -21
  91. data/spec/support/test/defaults.pb.rb +4 -4
  92. data/spec/support/test/enum.pb.rb +13 -1
  93. data/spec/support/test/enum.proto +15 -0
  94. data/spec/support/test/extended.pb.rb +1 -1
  95. data/spec/support/test/google_unittest.pb.rb +239 -241
  96. data/spec/support/test/google_unittest_import.pb.rb +2 -2
  97. data/spec/support/test/multi_field_extensions.pb.rb +2 -2
  98. data/spec/support/test/resource.pb.rb +19 -18
  99. data/spec/support/test/resource.proto +1 -0
  100. data/spec/support/test/resource_service.rb +5 -0
  101. metadata +78 -57
  102. data/bin/rprotoc +0 -8
  103. data/lib/protobuf/enum_value.rb +0 -85
  104. data/lib/protobuf/evented.rb +0 -37
  105. data/lib/protobuf/ext/eventmachine.rb +0 -14
  106. data/lib/protobuf/field/extension_fields.rb +0 -32
  107. data/lib/protobuf/message/decoder.rb +0 -72
  108. data/lib/protobuf/message/message.rb +0 -1
  109. data/lib/protobuf/rpc/connectors/em_client.rb +0 -84
  110. data/lib/protobuf/rpc/connectors/eventmachine.rb +0 -87
  111. data/lib/protobuf/rpc/servers/evented/server.rb +0 -36
  112. data/lib/protobuf/rpc/servers/evented_runner.rb +0 -31
  113. data/spec/functional/embedded_service_spec.rb +0 -7
  114. data/spec/functional/evented_server_spec.rb +0 -64
  115. data/spec/lib/protobuf/enum_value_spec.rb +0 -29
  116. data/spec/lib/protobuf/rpc/servers/evented_server_spec.rb +0 -19
@@ -19,38 +19,55 @@ require 'protobuf/field/sfixed32_field'
19
19
  require 'protobuf/field/sfixed64_field'
20
20
  require 'protobuf/field/fixed32_field'
21
21
  require 'protobuf/field/fixed64_field'
22
- require 'protobuf/field/extension_fields'
23
22
 
24
23
  module Protobuf
25
24
  module Field
26
- PREDEFINED_TYPES = [
27
- ::Protobuf::Field::DoubleField,
28
- ::Protobuf::Field::FloatField,
29
- ::Protobuf::Field::Int32Field,
30
- ::Protobuf::Field::Int64Field,
31
- ::Protobuf::Field::Uint32Field,
32
- ::Protobuf::Field::Uint64Field,
33
- ::Protobuf::Field::Sint32Field,
34
- ::Protobuf::Field::Sint64Field,
35
- ::Protobuf::Field::Fixed32Field,
36
- ::Protobuf::Field::Fixed64Field,
37
- ::Protobuf::Field::Sfixed32Field,
38
- ::Protobuf::Field::Sfixed64Field,
39
- ::Protobuf::Field::StringField,
40
- ::Protobuf::Field::BytesField,
41
- ::Protobuf::Field::BoolField
42
- ].freeze
25
+
26
+ PRIMITIVE_FIELD_MAP = {
27
+ :double => ::Protobuf::Field::DoubleField,
28
+ :float => ::Protobuf::Field::FloatField,
29
+ :int32 => ::Protobuf::Field::Int32Field,
30
+ :int64 => ::Protobuf::Field::Int64Field,
31
+ :uint32 => ::Protobuf::Field::Uint32Field,
32
+ :uint64 => ::Protobuf::Field::Uint64Field,
33
+ :sint32 => ::Protobuf::Field::Sint32Field,
34
+ :sint64 => ::Protobuf::Field::Sint64Field,
35
+ :fixed32 => ::Protobuf::Field::Fixed32Field,
36
+ :fixed64 => ::Protobuf::Field::Fixed64Field,
37
+ :sfixed32 => ::Protobuf::Field::Sfixed32Field,
38
+ :sfixed64 => ::Protobuf::Field::Sfixed64Field,
39
+ :string => ::Protobuf::Field::StringField,
40
+ :bytes => ::Protobuf::Field::BytesField,
41
+ :bool => ::Protobuf::Field::BoolField
42
+ }.freeze
43
43
 
44
44
  def self.build(message_class, rule, type, name, tag, options = {})
45
- field_class = type_message_or_enum(type)
46
- field_class.new(message_class, rule, type, name, tag, options)
45
+ field_class(type).new(message_class, rule, field_type(type), name, tag, options)
46
+ end
47
+
48
+ # Returns the field class for primitives,
49
+ # EnumField for types that inherit from Protobuf::Enum,
50
+ # and MessageField for types that inherit from Protobuf::Message.
51
+ #
52
+ def self.field_class(type)
53
+ if PRIMITIVE_FIELD_MAP.key?(type)
54
+ PRIMITIVE_FIELD_MAP[type]
55
+ elsif type < ::Protobuf::Enum
56
+ EnumField
57
+ elsif type < ::Protobuf::Message
58
+ MessageField
59
+ elsif type < ::Protobuf::Field::BaseField
60
+ type
61
+ else
62
+ raise ArgumentError, "Invalid field type #{type}"
63
+ end
47
64
  end
48
65
 
49
- def self.type_message_or_enum(defined_type)
50
- return defined_type if ::Protobuf::Field::PREDEFINED_TYPES.include?(defined_type)
51
- return EnumField if defined_type < Enum
52
- return MessageField if defined_type < Message
53
- raise "lost in the wilderness #{defined_type}"
66
+ # Returns the mapped type for primitives,
67
+ # otherwise the given type is returned.
68
+ #
69
+ def self.field_type(type)
70
+ PRIMITIVE_FIELD_MAP.fetch(type) { type }
54
71
  end
55
72
 
56
73
  end
@@ -4,18 +4,29 @@ module Protobuf
4
4
  module Generators
5
5
  class EnumGenerator < Base
6
6
 
7
+ def allow_alias?
8
+ descriptor.options.try(:allow_alias!) { false }
9
+ end
10
+
7
11
  def compile
8
12
  run_once(:compile) do
9
13
  tags = []
10
14
 
11
15
  print_class(descriptor.name, :enum) do
16
+ if allow_alias?
17
+ puts "set_option :allow_alias"
18
+ puts
19
+ end
20
+
12
21
  descriptor.value.each do |enum_value_descriptor|
13
22
  tags << enum_value_descriptor.number
14
23
  puts build_value(enum_value_descriptor)
15
24
  end
16
25
  end
17
26
 
18
- self.class.validate_tags(fully_qualified_type_namespace, tags)
27
+ unless allow_alias?
28
+ self.class.validate_tags(fully_qualified_type_namespace, tags)
29
+ end
19
30
  end
20
31
  end
21
32
 
@@ -94,7 +94,7 @@ module Protobuf
94
94
  type_name = modulize(descriptor.type_name)
95
95
  else
96
96
  type_name = descriptor.type.name.to_s.downcase.sub(/type_/, '')
97
- type_name = "::Protobuf::Field::#{modulize(type_name)}Field"
97
+ type_name = ":#{type_name}"
98
98
  end
99
99
  end
100
100
  end
@@ -2,10 +2,9 @@ module Protobuf
2
2
  class Lifecycle
3
3
  include ::Protobuf::Logger::LogMethods
4
4
 
5
- def self.register( event_name, &blk )
5
+ def self.register(event_name, &blk)
6
6
  raise "Lifecycle register must have a block" unless block_given?
7
-
8
- event_name = normalized_event_name( event_name )
7
+ event_name = normalized_event_name(event_name)
9
8
 
10
9
  if ::Protobuf.print_deprecation_warnings?
11
10
  $stderr.puts <<-ERROR
@@ -32,7 +31,7 @@ module Protobuf
32
31
  ::ActiveSupport::Notifications.instrument(event_name, args)
33
32
  end
34
33
 
35
- def self.normalized_event_name( event_name )
34
+ def self.normalized_event_name(event_name)
36
35
  return "#{event_name}".downcase
37
36
  end
38
37
 
@@ -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
+
@@ -1,147 +1,33 @@
1
- require 'stringio'
2
- require 'set'
3
1
  require 'protobuf/field'
4
2
  require 'protobuf/enum'
5
3
  require 'protobuf/exceptions'
6
- require 'protobuf/message/decoder'
4
+ require 'protobuf/message/fields'
5
+ require 'protobuf/message/serialization'
7
6
 
8
7
  module Protobuf
9
8
  class Message
10
9
 
11
10
  ##
12
- # Class Methods
11
+ # Includes & Extends
13
12
  #
14
- def self.all_fields
15
- @all_fields ||= begin
16
- all_fields_array = []
17
- max_fields = fields.size > extension_fields.size ? fields.size : extension_fields.size
18
- max_fields.times do |field_number|
19
- all_fields_array << (fields[field_number] || extension_fields[field_number])
20
- end
21
- all_fields_array.compact!
22
- all_fields_array
23
- end
24
- end
25
-
26
- def self.decode(bytes)
27
- self.new.decode(bytes)
28
- end
29
-
30
- # Define a field. Don't use this method directly.
31
- def self.define_field(rule, type, fname, tag, options)
32
- field_array = options[:extension] ? extension_fields : fields
33
- field_name_hash = options[:extension] ? extension_field_name_to_tag : field_name_to_tag
34
-
35
- previous_tag_field = get_field_by_tag(tag) || get_ext_field_by_tag(tag)
36
- if previous_tag_field
37
- raise TagCollisionError, %!Field number #{tag} has already been used in "#{self.name}" by field "#{fname}".!
38
- end
39
-
40
- previous_name_field = get_field_by_name(fname) || get_ext_field_by_name(fname)
41
- if previous_name_field
42
- raise DuplicateFieldNameError, %!Field name #{fname} has already been used in "#{self.name}".!
43
- end
44
-
45
- field_definition = ::Protobuf::Field.build(self, rule, type, fname, tag, options)
46
- field_name_hash[fname] = tag
47
- field_array[tag] = field_definition
48
-
49
- define_method("#{fname}!") do
50
- @values[fname]
51
- end
52
- end
53
-
54
- # Create a new object with the given values and return the encoded bytes.
55
- def self.encode(values = {})
56
- self.new(values).encode
57
- end
58
-
59
- # Reserve field numbers for extensions. Don't use this method directly.
60
- def self.extensions(range)
61
- extension_fields.add_range(range)
62
- end
63
-
64
- def self.extension_field_name_to_tag
65
- @extension_fields_by_name ||= {}
66
- end
67
-
68
- # An extension field object.
69
- def self.extension_fields
70
- @extension_fields ||= ::Protobuf::Field::ExtensionFields.new
71
- end
72
-
73
- def self.extension_tag?(tag)
74
- extension_fields.include_tag?(tag)
75
- end
76
-
77
- # A collection of field object.
78
- def self.fields
79
- @fields ||= []
80
- end
81
-
82
- def self.field_name_to_tag
83
- @field_name_to_tag ||= {}
84
- end
85
-
86
- def self.get_ext_field_by_name(name)
87
- tag = extension_field_name_to_tag[name.to_sym]
88
- extension_fields[tag] unless tag.nil?
89
- end
90
-
91
- def self.get_ext_field_by_tag(tag)
92
- extension_fields[tag]
93
- end
94
-
95
- # Find a field object by +name+.
96
- def self.get_field_by_name(name)
97
- name = name.to_sym if name.respond_to?(:to_sym)
98
- tag = field_name_to_tag[name]
99
- fields[tag] unless tag.nil?
100
- end
101
-
102
- # Find a field object by +tag+ number.
103
- def self.get_field_by_tag(tag)
104
- fields[tag]
105
- rescue TypeError
106
- tag = tag.nil? ? 'nil' : tag.to_s
107
- raise FieldNotDefinedError.new("Tag '#{tag}' does not reference a message field for '#{self.name}'")
108
- end
109
-
110
- # Define a optional field. Don't use this method directly.
111
- def self.optional(type, name, tag, options = {})
112
- define_field(:optional, type, name, tag, options)
113
- end
114
-
115
- # Define a repeated field. Don't use this method directly.
116
- def self.repeated(type, name, tag, options = {})
117
- define_field(:repeated, type, name, tag, options)
118
- end
119
13
 
120
- # Define a required field. Don't use this method directly.
121
- def self.required(type, name, tag, options = {})
122
- define_field(:required, type, name, tag, options)
123
- end
124
-
125
- # Backported fix to prevent recursive to_json issues.
126
- def self.to_json
127
- name
128
- end
14
+ extend ::Protobuf::Message::Fields
15
+ include ::Protobuf::Message::Serialization
129
16
 
130
17
  ##
131
18
  # Constructor
132
19
  #
133
- def initialize(values = {})
20
+ def initialize(fields = {})
134
21
  @values = {}
135
- values = values.to_hash
136
- values.each { |name, val| self[name] = val unless val.nil? }
22
+
23
+ fields.to_hash.each_pair do |name, value|
24
+ self[name] = value unless value.nil?
25
+ end
137
26
  end
138
27
 
139
28
  ##
140
29
  # Public Instance Methods
141
30
  #
142
- def all_fields
143
- self.class.all_fields
144
- end
145
31
 
146
32
  def clear!
147
33
  @values.delete_if do |_, value|
@@ -159,95 +45,33 @@ module Protobuf
159
45
  copy_to(super, :clone)
160
46
  end
161
47
 
162
- # Decode the given string bytes into this object.
163
- def decode(string)
164
- decode_from(::StringIO.new(string))
165
- end
166
-
167
- # Decode the given stream into this object.
168
- def decode_from(stream)
169
- Decoder.decode(stream, self)
170
- end
171
-
172
48
  def dup
173
49
  copy_to(super, :dup)
174
50
  end
175
51
 
176
- # Iterate over a field collection.
177
- # message.each_field do |field_object, value|
178
- # # do something
179
- # end
52
+ # Iterate over every field, invoking the given block
53
+ #
180
54
  def each_field
181
- all_fields.each do |field|
55
+ self.class.all_fields.each do |field|
182
56
  value = __send__(field.name)
183
57
  yield(field, value)
184
58
  end
185
59
  end
186
60
 
187
61
  def each_field_for_serialization
188
- all_fields.each do |field|
189
- next unless __field_must_be_serialized__?(field)
62
+ self.class.all_fields.each do |field|
63
+ next unless field_must_be_serialized?(field)
190
64
 
191
65
  value = @values[field.name]
192
66
 
193
67
  if value.nil?
194
- # Only way you can get here is if you are required and nil
195
- raise ::Protobuf::SerializationError, "#{field.name} is required on #{field.message_class}"
68
+ raise ::Protobuf::SerializationError, "Required field #{self.name}##{field.name} does not have a value."
196
69
  else
197
70
  yield(field, value)
198
71
  end
199
72
  end
200
73
  end
201
74
 
202
- def encode
203
- stream = ""
204
-
205
- each_field_for_serialization do |field, value|
206
- if field.repeated?
207
- if field.packed?
208
- key = (field.tag << 3) | ::Protobuf::WireType::LENGTH_DELIMITED
209
- packed_value = value.map { |val| field.encode(val) }.join
210
- stream << ::Protobuf::Field::VarintField.encode(key)
211
- stream << ::Protobuf::Field::VarintField.encode(packed_value.size)
212
- stream << packed_value
213
- else
214
- value.each { |val| write_pair(stream, field, val) }
215
- end
216
- else
217
- write_pair(stream, field, value)
218
- end
219
- end
220
-
221
- return stream
222
- end
223
-
224
- # Returns extension fields. See Message#fields method.
225
- def extension_fields
226
- self.class.extension_fields
227
- end
228
-
229
- def fields
230
- self.class.fields
231
- end
232
-
233
- def get_ext_field_by_name(name) # :nodoc:
234
- self.class.get_ext_field_by_name(name)
235
- end
236
-
237
- def get_ext_field_by_tag(tag) # :nodoc:
238
- self.class.get_ext_field_by_tag(tag)
239
- end
240
-
241
- # Returns field object or +nil+.
242
- def get_field_by_name(name)
243
- self.class.get_field_by_name(name)
244
- end
245
-
246
- # Returns field object or +nil+.
247
- def get_field_by_tag(tag)
248
- self.class.get_field_by_tag(tag)
249
- end
250
-
251
75
  def has_field?(name)
252
76
  @values.has_key?(name)
253
77
  end
@@ -257,17 +81,12 @@ module Protobuf
257
81
  end
258
82
 
259
83
  def respond_to_has?(key)
260
- self.respond_to?(key) && self.has_field?(key)
84
+ respond_to?(key) && has_field?(key)
261
85
  end
262
86
 
263
87
  def respond_to_has_and_present?(key)
264
- self.respond_to_has?(key) &&
265
- (self.__send__(key).present? || [true, false].include?(self.__send__(key)))
266
- end
267
-
268
- def set_field(tag, bytes)
269
- field = (get_field_by_tag(tag) || get_ext_field_by_tag(tag))
270
- field.set(self, bytes) if field
88
+ respond_to_has?(key) &&
89
+ (__send__(key).present? || [true, false].include?(__send__(key)))
271
90
  end
272
91
 
273
92
  # Return a hash-representation of the given fields for this message type.
@@ -300,13 +119,13 @@ module Protobuf
300
119
  end
301
120
 
302
121
  def [](name)
303
- if field = get_field_by_name(name) || get_ext_field_by_name(name)
122
+ if field = self.class.get_field(name, true)
304
123
  __send__(field.name)
305
124
  end
306
125
  end
307
126
 
308
127
  def []=(name, value)
309
- if field = get_field_by_name(name) || get_ext_field_by_name(name)
128
+ if field = self.class.get_field(name, true)
310
129
  __send__(field.setter_method_name, value)
311
130
  end
312
131
  end
@@ -314,14 +133,6 @@ module Protobuf
314
133
  ##
315
134
  # Instance Aliases
316
135
  #
317
- alias_method :parse_from_string, :decode
318
- alias_method :deserialize, :decode
319
- alias_method :parse_from, :decode_from
320
- alias_method :deserialize_from, :decode_from
321
- alias_method :to_s, :encode
322
- alias_method :bytes, :encode
323
- alias_method :serialize, :encode
324
- alias_method :serialize_to_string, :encode
325
136
  alias_method :to_hash_value, :to_hash
326
137
  alias_method :to_proto_hash, :to_hash
327
138
  alias_method :responds_to_has?, :respond_to_has?
@@ -358,16 +169,5 @@ module Protobuf
358
169
  object
359
170
  end
360
171
 
361
- def __field_must_be_serialized__?(field)
362
- field.required? || !@values[field.name].nil?
363
- end
364
-
365
- # Encode key and value, and write to +stream+.
366
- def write_pair(stream, field, value)
367
- key = (field.tag << 3) | field.wire_type
368
- stream << ::Protobuf::Field::VarintField.encode(key)
369
- stream << field.encode(value)
370
- end
371
-
372
172
  end
373
173
  end
@@ -0,0 +1,23 @@
1
+ require 'active_support/concern'
2
+
3
+ module Protobuf
4
+ module Optionable
5
+ extend ::ActiveSupport::Concern
6
+
7
+ module ClassMethods
8
+ def get_option(name)
9
+ @_optionable_options.try(:[], name)
10
+ end
11
+
12
+ def set_option(name, value = true)
13
+ @_optionable_options ||= {}
14
+ @_optionable_options[name] = value
15
+ end
16
+ end
17
+
18
+ def get_option(name)
19
+ self.class.get_option(name)
20
+ end
21
+
22
+ end
23
+ end