contrast-agent 6.3.0 → 6.4.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 (74) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -3
  3. data/.simplecov +1 -0
  4. data/Rakefile +0 -27
  5. data/lib/contrast/agent/assess/policy/propagation_method.rb +0 -2
  6. data/lib/contrast/agent/assess/policy/trigger_method.rb +1 -1
  7. data/lib/contrast/agent/version.rb +1 -1
  8. data/lib/contrast/api/dtm.pb.rb +1 -1
  9. data/lib/contrast/api/settings.pb.rb +1 -1
  10. data/lib/contrast/utils/patching/policy/patch_utils.rb +5 -22
  11. data/lib/contrast.rb +34 -0
  12. data/lib/protobuf/code_generator.rb +129 -0
  13. data/lib/protobuf/decoder.rb +28 -0
  14. data/lib/protobuf/deprecation.rb +117 -0
  15. data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +79 -0
  16. data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +360 -0
  17. data/lib/protobuf/descriptors.rb +3 -0
  18. data/lib/protobuf/encoder.rb +11 -0
  19. data/lib/protobuf/enum.rb +365 -0
  20. data/lib/protobuf/exceptions.rb +9 -0
  21. data/lib/protobuf/field/base_field.rb +380 -0
  22. data/lib/protobuf/field/base_field_object_definitions.rb +504 -0
  23. data/lib/protobuf/field/bool_field.rb +64 -0
  24. data/lib/protobuf/field/bytes_field.rb +67 -0
  25. data/lib/protobuf/field/double_field.rb +25 -0
  26. data/lib/protobuf/field/enum_field.rb +56 -0
  27. data/lib/protobuf/field/field_array.rb +102 -0
  28. data/lib/protobuf/field/field_hash.rb +122 -0
  29. data/lib/protobuf/field/fixed32_field.rb +25 -0
  30. data/lib/protobuf/field/fixed64_field.rb +28 -0
  31. data/lib/protobuf/field/float_field.rb +43 -0
  32. data/lib/protobuf/field/int32_field.rb +21 -0
  33. data/lib/protobuf/field/int64_field.rb +34 -0
  34. data/lib/protobuf/field/integer_field.rb +23 -0
  35. data/lib/protobuf/field/message_field.rb +51 -0
  36. data/lib/protobuf/field/sfixed32_field.rb +27 -0
  37. data/lib/protobuf/field/sfixed64_field.rb +28 -0
  38. data/lib/protobuf/field/signed_integer_field.rb +29 -0
  39. data/lib/protobuf/field/sint32_field.rb +21 -0
  40. data/lib/protobuf/field/sint64_field.rb +21 -0
  41. data/lib/protobuf/field/string_field.rb +51 -0
  42. data/lib/protobuf/field/uint32_field.rb +21 -0
  43. data/lib/protobuf/field/uint64_field.rb +21 -0
  44. data/lib/protobuf/field/varint_field.rb +77 -0
  45. data/lib/protobuf/field.rb +74 -0
  46. data/lib/protobuf/generators/base.rb +85 -0
  47. data/lib/protobuf/generators/enum_generator.rb +39 -0
  48. data/lib/protobuf/generators/extension_generator.rb +27 -0
  49. data/lib/protobuf/generators/field_generator.rb +193 -0
  50. data/lib/protobuf/generators/file_generator.rb +262 -0
  51. data/lib/protobuf/generators/group_generator.rb +122 -0
  52. data/lib/protobuf/generators/message_generator.rb +104 -0
  53. data/lib/protobuf/generators/option_generator.rb +17 -0
  54. data/lib/protobuf/generators/printable.rb +160 -0
  55. data/lib/protobuf/generators/service_generator.rb +50 -0
  56. data/lib/protobuf/lifecycle.rb +33 -0
  57. data/lib/protobuf/logging.rb +39 -0
  58. data/lib/protobuf/message/fields.rb +233 -0
  59. data/lib/protobuf/message/serialization.rb +85 -0
  60. data/lib/protobuf/message.rb +241 -0
  61. data/lib/protobuf/optionable.rb +72 -0
  62. data/lib/protobuf/tasks/compile.rake +80 -0
  63. data/lib/protobuf/tasks.rb +1 -0
  64. data/lib/protobuf/varint.rb +20 -0
  65. data/lib/protobuf/varint_pure.rb +31 -0
  66. data/lib/protobuf/version.rb +3 -0
  67. data/lib/protobuf/wire_type.rb +10 -0
  68. data/lib/protobuf.rb +91 -0
  69. data/proto/dynamic_discovery.proto +46 -0
  70. data/proto/google/protobuf/compiler/plugin.proto +183 -0
  71. data/proto/google/protobuf/descriptor.proto +911 -0
  72. data/proto/rpc.proto +71 -0
  73. data/ruby-agent.gemspec +1 -1
  74. metadata +71 -10
@@ -0,0 +1,50 @@
1
+ require 'protobuf/generators/base'
2
+ require 'protobuf/generators/option_generator'
3
+
4
+ module Protobuf
5
+ module Generators
6
+ class ServiceGenerator < Base
7
+
8
+ def compile
9
+ run_once(:compile) do
10
+ print_class(descriptor.name, :service) do
11
+ print OptionGenerator.new(descriptor.options, current_indent).to_s if descriptor.options
12
+ descriptor.method.each do |method_descriptor|
13
+ print_method(method_descriptor)
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def print_method(method_descriptor)
22
+ request_klass = modulize(method_descriptor.input_type)
23
+ response_klass = modulize(method_descriptor.output_type)
24
+ name = ENV.key?('PB_USE_RAW_RPC_NAMES') ? method_descriptor.name : method_descriptor.name.underscore
25
+ options = {}
26
+ if method_descriptor.options
27
+ method_descriptor.options.each_field do |field_option|
28
+ option_value = method_descriptor.options[field_option.name]
29
+ next unless method_descriptor.options.field?(field_option.name)
30
+ options[field_option.fully_qualified_name] = serialize_value(option_value)
31
+ end
32
+ end
33
+
34
+ rpc = "rpc :#{name}, #{request_klass}, #{response_klass}"
35
+
36
+ if options.empty?
37
+ puts rpc
38
+ return
39
+ end
40
+
41
+ puts rpc + " do"
42
+ options.each do |option_name, value|
43
+ indent { puts "set_option #{option_name.inspect}, #{value}" }
44
+ end
45
+ puts "end"
46
+ end
47
+
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,33 @@
1
+ module Protobuf
2
+ class Lifecycle
3
+ class << self
4
+ def register(event_name)
5
+ fail "Lifecycle register must have a block" unless block_given?
6
+ event_name = normalized_event_name(event_name)
7
+
8
+ ::ActiveSupport::Notifications.subscribe(event_name) do |_name, _start, _finish, _id, args|
9
+ yield(*args)
10
+ end
11
+ end
12
+ alias :on register
13
+
14
+ def trigger(event_name, *args)
15
+ event_name = normalized_event_name(event_name)
16
+
17
+ ::ActiveSupport::Notifications.instrument(event_name, args)
18
+ end
19
+
20
+ replacement = ::ActiveSupport::Notifications
21
+
22
+ ::Protobuf.deprecator.deprecate_methods(
23
+ self,
24
+ :register => "#{replacement}.#{replacement.method(:subscribe).name}".to_sym,
25
+ :trigger => "#{replacement}.#{replacement.method(:instrument).name}".to_sym,
26
+ )
27
+
28
+ def normalized_event_name(event_name)
29
+ event_name.to_s.downcase
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,39 @@
1
+ require 'logger'
2
+
3
+ module Protobuf
4
+ module Logging
5
+ def self.initialize_logger(log_target = $stdout, log_level = ::Logger::INFO)
6
+ @logger = Logger.new(log_target)
7
+ @logger.level = log_level
8
+ @logger
9
+ end
10
+
11
+ def self.logger
12
+ defined?(@logger) ? @logger : initialize_logger
13
+ end
14
+
15
+ class << self
16
+ attr_writer :logger
17
+ end
18
+
19
+ def logger
20
+ ::Protobuf::Logging.logger
21
+ end
22
+
23
+ def log_exception(ex)
24
+ logger.error { ex.message }
25
+ logger.error { ex.backtrace[0..5].join("\n") }
26
+ logger.debug { ex.backtrace.join("\n") }
27
+ end
28
+
29
+ def log_signature
30
+ @_log_signature ||= "[#{self.class == Class ? name : self.class.name}]"
31
+ end
32
+
33
+ def sign_message(message)
34
+ "#{log_signature} #{message}"
35
+ end
36
+ end
37
+ end
38
+
39
+ # Inspired by [mperham](https://github.com/mperham/sidekiq)
@@ -0,0 +1,233 @@
1
+ require "set"
2
+
3
+ module Protobuf
4
+ class Message
5
+ module Fields
6
+
7
+ ACCESSOR_SUFFIXES = ["", "=", "!", "?"].freeze
8
+
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
+ subclass.const_set("PROTOBUF_MESSAGE_REQUIRED_FIELD_TAGS", subclass.required_field_tags)
24
+ subclass.const_set("PROTOBUF_MESSAGE_GET_FIELD", subclass.field_store)
25
+ subclass.class_eval <<-RUBY, __FILE__, __LINE__
26
+ def _protobuf_message_field
27
+ PROTOBUF_MESSAGE_GET_FIELD
28
+ end
29
+
30
+ def _protobuf_message_unset_required_field_tags
31
+ @_protobuf_message_unset_required_field_tags ||= PROTOBUF_MESSAGE_REQUIRED_FIELD_TAGS.dup
32
+ end
33
+ RUBY
34
+ end
35
+
36
+ ##
37
+ # Field Definition Methods
38
+ #
39
+
40
+ # Define an optional field.
41
+ #
42
+ def optional(type_class, name, tag, options = {})
43
+ define_field(:optional, type_class, name, tag, options)
44
+ end
45
+
46
+ # Define a repeated field.
47
+ #
48
+ def repeated(type_class, name, tag, options = {})
49
+ define_field(:repeated, type_class, name, tag, options)
50
+ end
51
+
52
+ # Define a required field.
53
+ #
54
+ def required(type_class, name, tag, options = {})
55
+ required_field_tags << tag
56
+ define_field(:required, type_class, name, tag, options)
57
+ end
58
+
59
+ # Define a map field.
60
+ #
61
+ def map(key_type_class, value_type_class, name, tag, options = {})
62
+ # manufacture a message that represents the map entry, used for
63
+ # serialization and deserialization
64
+ entry_type = Class.new(::Protobuf::Message) do
65
+ set_option :map_entry, true
66
+ optional key_type_class, :key, 1
67
+ optional value_type_class, :value, 2
68
+ end
69
+ define_field(:repeated, entry_type, name, tag, options)
70
+ end
71
+
72
+ # Define an extension range.
73
+ #
74
+ def extensions(range)
75
+ extension_ranges << range
76
+ end
77
+
78
+ ##
79
+ # Field Access Methods
80
+ #
81
+ def all_fields
82
+ @all_fields ||= field_store.values.uniq.sort_by(&:tag)
83
+ end
84
+
85
+ def extension_fields
86
+ @extension_fields ||= all_fields.select(&:extension?)
87
+ end
88
+
89
+ def extension_ranges
90
+ @extension_ranges ||= []
91
+ end
92
+
93
+ def required_field_tags
94
+ @required_field_tags ||= []
95
+ end
96
+
97
+ def extension_tag?(tag)
98
+ tag.respond_to?(:to_i) && get_extension_field(tag).present?
99
+ end
100
+
101
+ def field_store
102
+ @field_store ||= {}
103
+ end
104
+
105
+ def fields
106
+ @fields ||= all_fields.reject(&:extension?)
107
+ end
108
+
109
+ def field_tag?(tag, allow_extension = false)
110
+ tag.respond_to?(:to_i) && get_field(tag, allow_extension).present?
111
+ end
112
+
113
+ def get_extension_field(name_or_tag)
114
+ field = field_store[name_or_tag]
115
+ field if field.try(:extension?) { false }
116
+ end
117
+
118
+ def get_field(name_or_tag, allow_extension = false)
119
+ field = field_store[name_or_tag]
120
+
121
+ if field && (allow_extension || !field.extension?)
122
+ field
123
+ else
124
+ nil
125
+ end
126
+ end
127
+
128
+ def define_field(rule, type_class, fully_qualified_field_name, tag, options)
129
+ raise_if_tag_collision(tag, fully_qualified_field_name)
130
+ raise_if_name_collision(fully_qualified_field_name)
131
+
132
+ # Determine appropirate accessor for fields depending on name collisions via extensions:
133
+
134
+ # Case 1: Base field = "string_field" and no extensions of the same name
135
+ # Result:
136
+ # message.string_field #=> @values["string_field"]
137
+ # message[:string_field] #=> @values["string_field"]
138
+ # message['string_field'] #=> @values["string_field"]
139
+
140
+ # Case 2: Base field = "string_field" and extension 1 = ".my_package.string_field", extension N = ".package_N.string_field"...
141
+ # Result:
142
+ # message.string_field #=> @values["string_field"]
143
+ # message[:string_field] #=> @values["string_field"]
144
+ # message['string_field'] #=> @values["string_field"]
145
+ # message[:'.my_package.string_field'] #=> @values[".my_package.string_field"]
146
+ # message['.my_package.string_field'] #=> @values[".my_package.string_field"]
147
+
148
+ # Case 3: No base field, extension 1 = ".my_package.string_field", extension 2 = ".other_package.string_field", extension N...
149
+ # Result:
150
+ # message.string_field #=> raise NoMethodError (no simple accessor allowed)
151
+ # message[:string_field] #=> raise NoMethodError (no simple accessor allowed)
152
+ # message['string_field'] #=> raise NoMethodError (no simple accessor allowed)
153
+ # message[:'.my_package.string_field'] #=> @values[".my_package.string_field"]
154
+ # message['.my_package.string_field'] #=> @values[".my_package.string_field"]
155
+ # message[:'.other_package.string_field'] #=> @values[".other_package.string_field"]
156
+ # message['.other_package.string_field'] #=> @values[".other_package.string_field"]
157
+
158
+ # Case 4: No base field, extension = ".my_package.string_field", no other extensions
159
+ # Result:
160
+ # message.string_field #=> @values[".my_package.string_field"]
161
+ # message[:string_field] #=> @values[".my_package.string_field"]
162
+ # message['string_field'] #=> @values[".my_package.string_field"]
163
+ # message[:'.my_package.string_field'] #=> @values[".my_package.string_field"]
164
+ # message[:'.my_package.string_field'] #=> @values[".my_package.string_field"]
165
+
166
+ simple_name =
167
+ if options[:extension]
168
+ base_name = fully_qualified_field_name.to_s.split('.').last.to_sym
169
+ if field_store[base_name]
170
+ # Case 3
171
+ if field_store[base_name].extension?
172
+ remove_existing_accessors(base_name)
173
+ end
174
+ nil
175
+ # Case 4
176
+ else
177
+ base_name
178
+ end
179
+ else
180
+ # Case 1
181
+ fully_qualified_field_name
182
+ end
183
+
184
+ field = ::Protobuf::Field.build(self, rule, type_class, fully_qualified_field_name,
185
+ tag, simple_name, options)
186
+ field_store[tag] = field
187
+ field_store[fully_qualified_field_name.to_sym] = field
188
+ field_store[fully_qualified_field_name.to_s] = field
189
+ if simple_name && simple_name != fully_qualified_field_name
190
+ field_store[simple_name.to_sym] = field
191
+ field_store[simple_name.to_s] = field
192
+ end
193
+ # defining a new field for the message will cause cached @all_fields, @extension_fields,
194
+ # and @fields to be incorrect; reset them
195
+ @all_fields = @extension_fields = @fields = nil
196
+ end
197
+
198
+ def remove_existing_accessors(accessor)
199
+ field_store.delete(accessor.to_sym).try(:fully_qualified_name_only!)
200
+ field_store.delete(accessor.to_s)
201
+ ACCESSOR_SUFFIXES.each do |modifier|
202
+ begin
203
+ remove_method("#{accessor}#{modifier}")
204
+ # rubocop: disable Lint/HandleExceptions
205
+ rescue NameError
206
+ # Do not remove the method
207
+ end
208
+ end
209
+ end
210
+
211
+ def raise_if_tag_collision(tag, field_name)
212
+ if get_field(tag, true)
213
+ fail TagCollisionError, %(Field number #{tag} has already been used in "#{name}" by field "#{field_name}".)
214
+ end
215
+ end
216
+
217
+ def raise_if_name_collision(field_name)
218
+ if get_field(field_name, true)
219
+ fail DuplicateFieldNameError, %(Field name #{field_name} has already been used in "#{name}".)
220
+ end
221
+ end
222
+
223
+ def inherit_fields!(subclass)
224
+ instance_variables.each do |iv|
225
+ subclass.instance_variable_set(iv, instance_variable_get(iv))
226
+ end
227
+ end
228
+ private :inherit_fields!
229
+
230
+ end
231
+ end
232
+ end
233
+ end
@@ -0,0 +1,85 @@
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
+ new.decode(bytes)
12
+ end
13
+
14
+ def decode_from(stream)
15
+ new.decode_from(stream)
16
+ end
17
+
18
+ # Create a new object with the given values and return the encoded bytes.
19
+ def encode(fields = {})
20
+ new(fields).encode
21
+ end
22
+ end
23
+
24
+ def self.included(other)
25
+ other.extend(ClassMethods)
26
+ end
27
+
28
+ ##
29
+ # Instance Methods
30
+ #
31
+
32
+ # Decode the given non-stream bytes into this message.
33
+ #
34
+ def decode(bytes)
35
+ decode_from(::StringIO.new(bytes))
36
+ end
37
+
38
+ # Decode the given stream into this message.
39
+ #
40
+ def decode_from(stream)
41
+ ::Protobuf::Decoder.decode_each_field(stream) do |tag, bytes|
42
+ set_field_bytes(tag, bytes)
43
+ end
44
+
45
+ self
46
+ end
47
+
48
+ # Encode this message
49
+ #
50
+ def encode
51
+ stream = ::StringIO.new
52
+ stream.set_encoding(::Protobuf::Field::BytesField::BYTES_ENCODING)
53
+ encode_to(stream)
54
+ stream.string
55
+ end
56
+
57
+ # Encode this message to the given stream.
58
+ #
59
+ def encode_to(stream)
60
+ ::Protobuf::Encoder.encode(self, stream)
61
+ end
62
+
63
+ ##
64
+ # Instance Aliases
65
+ #
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
75
+
76
+ private
77
+
78
+ def set_field_bytes(tag, bytes)
79
+ field = _protobuf_message_field[tag]
80
+ field.set(self, bytes) if field
81
+ end
82
+
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,241 @@
1
+ require 'protobuf/message/fields'
2
+ require 'protobuf/message/serialization'
3
+ require 'protobuf/varint'
4
+
5
+ module Protobuf
6
+ class Message
7
+
8
+ ##
9
+ # Includes & Extends
10
+ #
11
+
12
+ extend ::Protobuf::Message::Fields
13
+ include ::Protobuf::Message::Serialization
14
+ ::Protobuf::Optionable.inject(self) { ::CSGoogle::Protobuf::MessageOptions }
15
+
16
+ ##
17
+ # Class Methods
18
+ #
19
+
20
+ def self.to_json
21
+ name
22
+ end
23
+
24
+ ##
25
+ # Constructor
26
+ #
27
+
28
+ def initialize(fields = {})
29
+ @values = {}
30
+ fields.to_hash.each do |name, value|
31
+ set_field(name, value, true)
32
+ end
33
+
34
+ yield self if block_given?
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) || value.is_a?(::Protobuf::Field::FieldHash)
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
+ return to_enum(:each_field) unless block_given?
65
+
66
+ self.class.all_fields.each do |field|
67
+ value = self[field.name]
68
+ yield(field, value)
69
+ end
70
+ end
71
+
72
+ def each_field_for_serialization
73
+ _protobuf_message_unset_required_field_tags.each do |tag|
74
+ fail ::Protobuf::SerializationError, "Required field #{self.class.name}##{_protobuf_message_field[tag].name} does not have a value."
75
+ end
76
+
77
+ @values.each_key do |fully_qualified_name|
78
+ field = _protobuf_message_field[fully_qualified_name]
79
+ yield(field, field.value_from_values_for_serialization(@values))
80
+ end
81
+ end
82
+
83
+ def field?(name)
84
+ field = _protobuf_message_field[name]
85
+
86
+ if field
87
+ field.field?(@values)
88
+ else
89
+ false
90
+ end
91
+ end
92
+ alias :respond_to_has? field?
93
+ ::Protobuf.deprecator.define_deprecated_methods(self, :has_field? => :field?)
94
+
95
+ def inspect
96
+ attrs = self.class.fields.map do |field|
97
+ [field.name, self[field.name].inspect].join('=')
98
+ end.join(' ')
99
+
100
+ "#<#{self.class} #{attrs}>"
101
+ end
102
+
103
+ def respond_to_has_and_present?(key)
104
+ field = _protobuf_message_field[key]
105
+
106
+ if field
107
+ field.field_and_present?(@values)
108
+ else
109
+ false
110
+ end
111
+ end
112
+
113
+ # Return a hash-representation of the given fields for this message type.
114
+ def to_hash
115
+ result = {}
116
+
117
+ @values.each_key do |field_name|
118
+ field = _protobuf_message_field[field_name]
119
+ field.to_message_hash(@values, result)
120
+ end
121
+
122
+ result
123
+ end
124
+
125
+ def to_hash_with_string_keys
126
+ result = {}
127
+
128
+ @values.each_key do |field_name|
129
+ field = _protobuf_message_field[field_name]
130
+ field.to_message_hash_with_string_key(@values, result)
131
+ end
132
+
133
+ result
134
+ end
135
+
136
+ def to_json(options = {})
137
+ to_json_hash.to_json(options)
138
+ end
139
+
140
+ # Return a hash-representation of the given fields for this message type that
141
+ # is safe to convert to JSON.
142
+ def to_json_hash
143
+ result = {}
144
+
145
+ @values.each_key do |field_name|
146
+ value = self[field_name]
147
+ field = self.class.get_field(field_name, true)
148
+
149
+ # NB: to_json_hash_value should come before json_encode so as to handle
150
+ # repeated fields without extra logic.
151
+ hashed_value = if value.respond_to?(:to_json_hash_value)
152
+ value.to_json_hash_value
153
+ elsif field.respond_to?(:json_encode)
154
+ field.json_encode(value)
155
+ else
156
+ value
157
+ end
158
+
159
+ result[field.name] = hashed_value
160
+ end
161
+
162
+ result
163
+ end
164
+
165
+ def to_proto
166
+ self
167
+ end
168
+
169
+ def ==(other)
170
+ return false unless other.is_a?(self.class)
171
+ each_field do |field, value|
172
+ return false unless value == other[field.name]
173
+ end
174
+ true
175
+ end
176
+
177
+ def [](name)
178
+ field = _protobuf_message_field[name]
179
+ field.value_from_values(@values)
180
+ rescue # not having a field should be the exceptional state
181
+ raise if field
182
+ fail ArgumentError, "invalid field name=#{name.inspect}"
183
+ end
184
+
185
+ def []=(name, value)
186
+ set_field(name, value, true)
187
+ end
188
+
189
+ def set_field(name, value, ignore_nil_for_repeated, field = nil)
190
+ field ||= _protobuf_message_field[name]
191
+
192
+ if field
193
+ field.set_field(@values, value, ignore_nil_for_repeated, self)
194
+ else
195
+ fail(::Protobuf::FieldNotDefinedError, name) unless ::Protobuf.ignore_unknown_fields?
196
+ end
197
+ end
198
+
199
+ ##
200
+ # Instance Aliases
201
+ #
202
+ alias :to_hash_value to_hash
203
+ alias :to_json_hash_value to_json_hash
204
+ alias :to_proto_hash to_hash
205
+ alias :responds_to_has? respond_to_has?
206
+ alias :respond_to_and_has? respond_to_has?
207
+ alias :responds_to_and_has? respond_to_has?
208
+ alias :respond_to_has_present? respond_to_has_and_present?
209
+ alias :respond_to_and_has_present? respond_to_has_and_present?
210
+ alias :respond_to_and_has_and_present? respond_to_has_and_present?
211
+ alias :responds_to_has_present? respond_to_has_and_present?
212
+ alias :responds_to_and_has_present? respond_to_has_and_present?
213
+ alias :responds_to_and_has_and_present? respond_to_has_and_present?
214
+
215
+ ##
216
+ # Private Instance Methods
217
+ #
218
+
219
+ private
220
+
221
+ def copy_to(object, method)
222
+ duplicate = proc do |obj|
223
+ case obj
224
+ when Message, String then obj.__send__(method)
225
+ else obj
226
+ end
227
+ end
228
+
229
+ object.__send__(:initialize)
230
+ @values.each do |name, value|
231
+ if value.is_a?(::Protobuf::Field::FieldArray)
232
+ object[name].replace(value.map { |v| duplicate.call(v) })
233
+ else
234
+ object[name] = duplicate.call(value)
235
+ end
236
+ end
237
+ object
238
+ end
239
+
240
+ end
241
+ end