contrast-agent 6.3.0 → 6.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -3
  3. data/.simplecov +1 -0
  4. data/Rakefile +0 -27
  5. data/ext/cs__contrast_patch/cs__contrast_patch.c +14 -1
  6. data/lib/contrast/agent/assess/finalizers/hash.rb +1 -0
  7. data/lib/contrast/agent/assess/policy/propagation_method.rb +5 -3
  8. data/lib/contrast/agent/assess/policy/propagator/custom.rb +4 -0
  9. data/lib/contrast/agent/assess/policy/propagator/database_write.rb +5 -0
  10. data/lib/contrast/agent/assess/policy/propagator/split.rb +3 -0
  11. data/lib/contrast/agent/assess/policy/source_method.rb +5 -0
  12. data/lib/contrast/agent/assess/policy/trigger_method.rb +9 -3
  13. data/lib/contrast/agent/assess/tracker.rb +12 -0
  14. data/lib/contrast/agent/inventory/dependency_analysis.rb +2 -2
  15. data/lib/contrast/agent/inventory/dependency_usage_analysis.rb +1 -1
  16. data/lib/contrast/agent/inventory/policy/datastores.rb +1 -1
  17. data/lib/contrast/agent/inventory/policy/policy.rb +1 -1
  18. data/lib/contrast/agent/patching/policy/method_policy.rb +3 -3
  19. data/lib/contrast/agent/protect/rule/base.rb +1 -1
  20. data/lib/contrast/agent/reporting/reporter_heartbeat.rb +1 -3
  21. data/lib/contrast/agent/reporting/reporting_events/application_defend_activity.rb +17 -21
  22. data/lib/contrast/agent/reporting/reporting_events/application_defend_attack_sample.rb +1 -1
  23. data/lib/contrast/agent/reporting/reporting_events/application_defend_attack_sample_activity.rb +26 -3
  24. data/lib/contrast/agent/reporting/reporting_utilities/audit.rb +5 -5
  25. data/lib/contrast/agent/reporting/reporting_utilities/headers.rb +1 -1
  26. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb +1 -1
  27. data/lib/contrast/agent/reporting/reporting_utilities/response_handler_utils.rb +1 -1
  28. data/lib/contrast/agent/request_context.rb +8 -0
  29. data/lib/contrast/agent/service_heartbeat.rb +2 -3
  30. data/lib/contrast/agent/static_analysis.rb +1 -1
  31. data/lib/contrast/agent/version.rb +1 -1
  32. data/lib/contrast/agent/worker_thread.rb +10 -0
  33. data/lib/contrast/api/communication/response_processor.rb +1 -1
  34. data/lib/contrast/api/dtm.pb.rb +1 -1
  35. data/lib/contrast/api/settings.pb.rb +1 -1
  36. data/lib/contrast/components/agent.rb +52 -14
  37. data/lib/contrast/components/api.rb +60 -23
  38. data/lib/contrast/components/assess.rb +16 -0
  39. data/lib/contrast/components/contrast_service.rb +1 -1
  40. data/lib/contrast/components/heap_dump.rb +51 -1
  41. data/lib/contrast/components/inventory.rb +19 -13
  42. data/lib/contrast/components/logger.rb +18 -0
  43. data/lib/contrast/components/protect.rb +41 -1
  44. data/lib/contrast/components/sampling.rb +29 -0
  45. data/lib/contrast/config/assess_configuration.rb +33 -3
  46. data/lib/contrast/config/base_configuration.rb +8 -2
  47. data/lib/contrast/config/root_configuration.rb +19 -16
  48. data/lib/contrast/config/service_configuration.rb +4 -4
  49. data/lib/contrast/config.rb +0 -9
  50. data/lib/contrast/extension/object.rb +19 -0
  51. data/lib/contrast/framework/rails/support.rb +4 -1
  52. data/lib/contrast/logger/log.rb +2 -1
  53. data/lib/contrast/utils/assess/event_limit_utils.rb +96 -0
  54. data/lib/contrast/utils/assess/propagation_method_utils.rb +27 -7
  55. data/lib/contrast/utils/log_utils.rb +2 -2
  56. data/lib/contrast/utils/net_http_base.rb +2 -2
  57. data/lib/contrast/utils/patching/policy/patch_utils.rb +6 -23
  58. data/lib/contrast.rb +39 -20
  59. data/lib/protobuf/code_generator.rb +129 -0
  60. data/lib/protobuf/decoder.rb +28 -0
  61. data/lib/protobuf/deprecation.rb +117 -0
  62. data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +79 -0
  63. data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +360 -0
  64. data/lib/protobuf/descriptors.rb +3 -0
  65. data/lib/protobuf/encoder.rb +11 -0
  66. data/lib/protobuf/enum.rb +365 -0
  67. data/lib/protobuf/exceptions.rb +9 -0
  68. data/lib/protobuf/field/base_field.rb +380 -0
  69. data/lib/protobuf/field/base_field_object_definitions.rb +504 -0
  70. data/lib/protobuf/field/bool_field.rb +64 -0
  71. data/lib/protobuf/field/bytes_field.rb +67 -0
  72. data/lib/protobuf/field/double_field.rb +25 -0
  73. data/lib/protobuf/field/enum_field.rb +56 -0
  74. data/lib/protobuf/field/field_array.rb +102 -0
  75. data/lib/protobuf/field/field_hash.rb +122 -0
  76. data/lib/protobuf/field/fixed32_field.rb +25 -0
  77. data/lib/protobuf/field/fixed64_field.rb +28 -0
  78. data/lib/protobuf/field/float_field.rb +43 -0
  79. data/lib/protobuf/field/int32_field.rb +21 -0
  80. data/lib/protobuf/field/int64_field.rb +34 -0
  81. data/lib/protobuf/field/integer_field.rb +23 -0
  82. data/lib/protobuf/field/message_field.rb +51 -0
  83. data/lib/protobuf/field/sfixed32_field.rb +27 -0
  84. data/lib/protobuf/field/sfixed64_field.rb +28 -0
  85. data/lib/protobuf/field/signed_integer_field.rb +29 -0
  86. data/lib/protobuf/field/sint32_field.rb +21 -0
  87. data/lib/protobuf/field/sint64_field.rb +21 -0
  88. data/lib/protobuf/field/string_field.rb +51 -0
  89. data/lib/protobuf/field/uint32_field.rb +21 -0
  90. data/lib/protobuf/field/uint64_field.rb +21 -0
  91. data/lib/protobuf/field/varint_field.rb +77 -0
  92. data/lib/protobuf/field.rb +74 -0
  93. data/lib/protobuf/generators/base.rb +85 -0
  94. data/lib/protobuf/generators/enum_generator.rb +39 -0
  95. data/lib/protobuf/generators/extension_generator.rb +27 -0
  96. data/lib/protobuf/generators/field_generator.rb +193 -0
  97. data/lib/protobuf/generators/file_generator.rb +262 -0
  98. data/lib/protobuf/generators/group_generator.rb +122 -0
  99. data/lib/protobuf/generators/message_generator.rb +104 -0
  100. data/lib/protobuf/generators/option_generator.rb +17 -0
  101. data/lib/protobuf/generators/printable.rb +160 -0
  102. data/lib/protobuf/generators/service_generator.rb +50 -0
  103. data/lib/protobuf/lifecycle.rb +33 -0
  104. data/lib/protobuf/logging.rb +39 -0
  105. data/lib/protobuf/message/fields.rb +233 -0
  106. data/lib/protobuf/message/serialization.rb +85 -0
  107. data/lib/protobuf/message.rb +241 -0
  108. data/lib/protobuf/optionable.rb +72 -0
  109. data/lib/protobuf/tasks/compile.rake +80 -0
  110. data/lib/protobuf/tasks.rb +1 -0
  111. data/lib/protobuf/varint.rb +20 -0
  112. data/lib/protobuf/varint_pure.rb +31 -0
  113. data/lib/protobuf/version.rb +3 -0
  114. data/lib/protobuf/wire_type.rb +10 -0
  115. data/lib/protobuf.rb +91 -0
  116. data/proto/dynamic_discovery.proto +46 -0
  117. data/proto/google/protobuf/compiler/plugin.proto +183 -0
  118. data/proto/google/protobuf/descriptor.proto +911 -0
  119. data/proto/rpc.proto +71 -0
  120. data/resources/assess/policy.json +15 -12
  121. data/resources/deadzone/policy.json +132 -19
  122. data/ruby-agent.gemspec +3 -1
  123. metadata +112 -28
  124. data/lib/contrast/config/agent_configuration.rb +0 -63
  125. data/lib/contrast/config/api_configuration.rb +0 -56
  126. data/lib/contrast/config/heap_dump_configuration.rb +0 -59
  127. data/lib/contrast/config/inventory_configuration.rb +0 -33
  128. data/lib/contrast/config/logger_configuration.rb +0 -26
  129. data/lib/contrast/config/protect_configuration.rb +0 -33
  130. data/lib/contrast/config/sampling_configuration.rb +0 -35
@@ -0,0 +1,504 @@
1
+ module Protobuf
2
+ module Field
3
+ module BaseFieldObjectDefinitions
4
+
5
+ class ToHashValueToMessageHashWithStringKey
6
+ def initialize(selph)
7
+ @selph = selph
8
+ @name = selph.name.to_s
9
+ end
10
+
11
+ def call(values, result)
12
+ result[@name] = @selph.value_from_values(values).to_hash_value
13
+ end
14
+ end
15
+
16
+ class BaseToMessageHashWithStringKey
17
+ def initialize(selph)
18
+ @selph = selph
19
+ @name = selph.name.to_s
20
+ end
21
+
22
+ def call(values, result)
23
+ result[@name] = @selph.value_from_values(values)
24
+ end
25
+ end
26
+
27
+ class ToHashValueToMessageHash
28
+ def initialize(selph)
29
+ @selph = selph
30
+ @name = selph.name.to_sym
31
+ end
32
+
33
+ def call(values, result)
34
+ result[@name] = @selph.value_from_values(values).to_hash_value
35
+ end
36
+ end
37
+
38
+ class BaseToMessageHash
39
+ def initialize(selph)
40
+ @selph = selph
41
+ @name = selph.name.to_sym
42
+ end
43
+
44
+ def call(values, result)
45
+ result[@name] = @selph.value_from_values(values)
46
+ end
47
+ end
48
+
49
+ class RepeatedPackedEncodeToStream
50
+ def initialize(selph)
51
+ @selph = selph
52
+ @tag_encoded = selph.tag_encoded
53
+ end
54
+
55
+ def call(value, stream)
56
+ packed_value = value.map { |val| @selph.encode(val) }.join
57
+ stream << @tag_encoded << "#{::Protobuf::Field::VarintField.encode(packed_value.size)}#{packed_value}"
58
+ end
59
+ end
60
+
61
+ class BytesEncodeToStream
62
+ def initialize(selph)
63
+ @selph = selph
64
+ @tag_encoded = selph.tag_encoded
65
+ end
66
+
67
+ def call(value, stream)
68
+ value = value.encode if value.is_a?(::Protobuf::Message)
69
+ byte_size = ::Protobuf::Field::VarintField.encode(value.bytesize)
70
+
71
+ stream << @tag_encoded << byte_size << value
72
+ end
73
+ end
74
+
75
+ class StringEncodeToStream
76
+ def initialize(selph)
77
+ @selph = selph
78
+ @tag_encoded = selph.tag_encoded
79
+ end
80
+
81
+ def call(value, stream)
82
+ new_value = "" + value
83
+ if new_value.encoding != ::Protobuf::Field::StringField::ENCODING
84
+ new_value.encode!(::Protobuf::Field::StringField::ENCODING, :invalid => :replace, :undef => :replace, :replace => "")
85
+ end
86
+
87
+ stream << @tag_encoded << ::Protobuf::Field::VarintField.encode(new_value.bytesize) << new_value
88
+ end
89
+ end
90
+
91
+ class BaseEncodeToStream
92
+ def initialize(selph)
93
+ @selph = selph
94
+ @tag_encoded = selph.tag_encoded
95
+ end
96
+
97
+ def call(value, stream)
98
+ stream << @tag_encoded << @selph.encode(value)
99
+ end
100
+ end
101
+
102
+ class RepeatedNotPackedEncodeToStream
103
+ def initialize(selph)
104
+ @selph = selph
105
+ @tag_encoded = selph.tag_encoded
106
+ end
107
+
108
+ def call(value, stream)
109
+ value.each do |val|
110
+ stream << @tag_encoded << @selph.encode(val)
111
+ end
112
+ end
113
+ end
114
+
115
+ class BaseSetMethod
116
+ def initialize(selph)
117
+ @selph = selph
118
+ @name = selph.name
119
+ end
120
+
121
+ def call(message_instance, bytes)
122
+ message_instance.set_field(@name, @selph.decode(bytes), true, @selph)
123
+ end
124
+ end
125
+
126
+ class MapSetMethod
127
+ def initialize(selph)
128
+ @selph = selph
129
+ @name = selph.name
130
+ end
131
+
132
+ def call(message_instance, bytes)
133
+ hash = message_instance[@name]
134
+ entry = @selph.decode(bytes)
135
+ # decoded value could be nil for an
136
+ # enum value that is not recognized
137
+ hash[entry.key] = entry.value unless entry.value.nil?
138
+ hash[entry.key]
139
+ end
140
+ end
141
+
142
+ class RepeatedNotPackedSetMethod
143
+ def initialize(selph)
144
+ @selph = selph
145
+ @name = selph.name
146
+ end
147
+
148
+ def call(message_instance, bytes)
149
+ message_instance[@name] << @selph.decode(bytes)
150
+ end
151
+ end
152
+
153
+ class RepeatedPackedSetMethod
154
+ def initialize(selph)
155
+ @selph = selph
156
+ @name = selph.name
157
+ @wire_type = selph.wire_type
158
+ end
159
+
160
+ def call(message_instance, bytes)
161
+ array = message_instance[@name]
162
+ stream = ::StringIO.new(bytes)
163
+
164
+ if @wire_type == ::Protobuf::WireType::VARINT
165
+ array << @selph.decode(Varint.decode(stream)) until stream.eof?
166
+ elsif @wire_type == ::Protobuf::WireType::FIXED64
167
+ array << @selph.decode(stream.read(8)) until stream.eof?
168
+ elsif @wire_type == ::Protobuf::WireType::FIXED32
169
+ array << @selph.decode(stream.read(4)) until stream.eof?
170
+ end
171
+ end
172
+ end
173
+
174
+ class RequiredMapSetField
175
+ def initialize(selph)
176
+ @selph = selph
177
+ @tag = selph.tag
178
+ @fully_qualified_name = selph.fully_qualified_name
179
+ end
180
+
181
+ def call(values, value, _ignore_nil_for_repeated, message_instance)
182
+ unless value.is_a?(Hash)
183
+ fail TypeError, <<-TYPE_ERROR
184
+ Expected map value
185
+ Got '#{value.class}' for map protobuf field #{@selph.name}
186
+ TYPE_ERROR
187
+ end
188
+
189
+ if value.empty?
190
+ values.delete(@fully_qualified_name)
191
+ message_instance._protobuf_message_unset_required_field_tags << @tag
192
+ else
193
+ message_instance._protobuf_message_unset_required_field_tags.delete(@tag)
194
+ values[@fully_qualified_name] ||= ::Protobuf::Field::FieldHash.new(@selph)
195
+ values[@fully_qualified_name].replace(value)
196
+ end
197
+ end
198
+ end
199
+
200
+ class MapSetField
201
+ def initialize(selph)
202
+ @selph = selph
203
+ @tag = selph.tag
204
+ @fully_qualified_name = selph.fully_qualified_name
205
+ end
206
+
207
+ def call(values, value, _ignore_nil_for_repeated, _message_instance)
208
+ unless value.is_a?(Hash)
209
+ fail TypeError, <<-TYPE_ERROR
210
+ Expected map value
211
+ Got '#{value.class}' for map protobuf field #{@selph.name}
212
+ TYPE_ERROR
213
+ end
214
+
215
+ if value.empty?
216
+ values.delete(@fully_qualified_name)
217
+ else
218
+ values[@fully_qualified_name] ||= ::Protobuf::Field::FieldHash.new(@selph)
219
+ values[@fully_qualified_name].replace(value)
220
+ end
221
+ end
222
+ end
223
+
224
+ class RequiredRepeatedSetField
225
+ def initialize(selph)
226
+ @selph = selph
227
+ @tag = selph.tag
228
+ @fully_qualified_name = selph.fully_qualified_name
229
+ end
230
+
231
+ def call(values, value, ignore_nil_for_repeated, message_instance)
232
+ if value.nil? && ignore_nil_for_repeated
233
+ ::Protobuf.deprecator.deprecation_warning("['#{@fully_qualified_name}']=nil", "use an empty array instead of nil")
234
+ return
235
+ end
236
+
237
+ unless value.is_a?(Array)
238
+ fail TypeError, <<-TYPE_ERROR
239
+ Expected repeated value of type '#{@selph.type_class}'
240
+ Got '#{value.class}' for repeated protobuf field #{@selph.name}
241
+ TYPE_ERROR
242
+ end
243
+
244
+ value = value.compact
245
+
246
+ if value.empty?
247
+ values.delete(@fully_qualified_name)
248
+ message_instance._protobuf_message_unset_required_field_tags << @tag
249
+ else
250
+ message_instance._protobuf_message_unset_required_field_tags.delete(@tag)
251
+ values[@fully_qualified_name] ||= ::Protobuf::Field::FieldArray.new(@selph)
252
+ values[@fully_qualified_name].replace(value)
253
+ end
254
+ end
255
+ end
256
+
257
+ class RepeatedSetField
258
+ def initialize(selph)
259
+ @selph = selph
260
+ @tag = selph.tag
261
+ @fully_qualified_name = selph.fully_qualified_name
262
+ end
263
+
264
+ def call(values, value, ignore_nil_for_repeated, _message_instance)
265
+ if value.nil? && ignore_nil_for_repeated
266
+ ::Protobuf.deprecator.deprecation_warning("['#{@fully_qualified_name}']=nil", "use an empty array instead of nil")
267
+ return
268
+ end
269
+
270
+ unless value.is_a?(Array)
271
+ fail TypeError, <<-TYPE_ERROR
272
+ Expected repeated value of type '#{@selph.type_class}'
273
+ Got '#{value.class}' for repeated protobuf field #{@selph.name}
274
+ TYPE_ERROR
275
+ end
276
+
277
+ value = value.compact
278
+
279
+ if value.empty?
280
+ values.delete(@fully_qualified_name)
281
+ else
282
+ values[@fully_qualified_name] ||= ::Protobuf::Field::FieldArray.new(@selph)
283
+ values[@fully_qualified_name].replace(value)
284
+ end
285
+ end
286
+ end
287
+
288
+ class RequiredStringSetField
289
+ def initialize(selph)
290
+ @selph = selph
291
+ @tag = selph.tag
292
+ @fully_qualified_name = selph.fully_qualified_name
293
+ end
294
+
295
+ def call(values, value, _ignore_nil_for_repeated, message_instance)
296
+ if value
297
+ message_instance._protobuf_message_unset_required_field_tags.delete(@tag)
298
+ values[@fully_qualified_name] = if value.is_a?(String)
299
+ value
300
+ else
301
+ @selph.coerce!(value)
302
+ end
303
+ else
304
+ values.delete(@fully_qualified_name)
305
+ message_instance._protobuf_message_unset_required_field_tags << @tag
306
+ end
307
+ end
308
+ end
309
+
310
+ class StringSetField
311
+ def initialize(selph)
312
+ @selph = selph
313
+ @tag = selph.tag
314
+ @fully_qualified_name = selph.fully_qualified_name
315
+ end
316
+
317
+ def call(values, value, _ignore_nil_for_repeated, _message_instance)
318
+ if value
319
+ values[@fully_qualified_name] = if value.is_a?(String)
320
+ value
321
+ else
322
+ @selph.coerce!(value)
323
+ end
324
+ else
325
+ values.delete(@fully_qualified_name)
326
+ end
327
+ end
328
+ end
329
+
330
+ class RequiredBaseSetField
331
+ def initialize(selph)
332
+ @selph = selph
333
+ @tag = selph.tag
334
+ @fully_qualified_name = selph.fully_qualified_name
335
+ end
336
+
337
+ def call(values, value, _ignore_nil_for_repeated, message_instance)
338
+ if value.nil?
339
+ values.delete(@fully_qualified_name)
340
+ message_instance._protobuf_message_unset_required_field_tags << @tag
341
+ else
342
+ message_instance._protobuf_message_unset_required_field_tags.delete(@tag)
343
+ values[@fully_qualified_name] = @selph.coerce!(value)
344
+ end
345
+ end
346
+ end
347
+
348
+ class BaseSetField
349
+ def initialize(selph)
350
+ @selph = selph
351
+ @tag = selph.tag
352
+ @fully_qualified_name = selph.fully_qualified_name
353
+ end
354
+
355
+ def call(values, value, _ignore_nil_for_repeated, _message_instance)
356
+ if value.nil?
357
+ values.delete(@fully_qualified_name)
358
+ else
359
+ values[@fully_qualified_name] = @selph.coerce!(value)
360
+ end
361
+ end
362
+ end
363
+
364
+ class BaseFieldAndPresentPredicate
365
+ def initialize(selph)
366
+ @fully_qualified_name = selph.fully_qualified_name
367
+ end
368
+
369
+ def call(values)
370
+ values[@fully_qualified_name].present?
371
+ end
372
+ end
373
+
374
+ class BoolFieldAndPresentPredicate
375
+ BOOL_VALUES = [true, false].freeze
376
+
377
+ def initialize(selph)
378
+ @fully_qualified_name = selph.fully_qualified_name
379
+ end
380
+
381
+ def call(values)
382
+ BOOL_VALUES.include?(values[@fully_qualified_name])
383
+ end
384
+ end
385
+
386
+ class BaseFieldPredicate
387
+ def initialize(selph)
388
+ @fully_qualified_name = selph.fully_qualified_name
389
+ end
390
+
391
+ def call(values)
392
+ values.key?(@fully_qualified_name)
393
+ end
394
+ end
395
+
396
+ class RepeatedFieldPredicate
397
+ def initialize(selph)
398
+ @fully_qualified_name = selph.fully_qualified_name
399
+ end
400
+
401
+ def call(values)
402
+ values.key?(@fully_qualified_name) &&
403
+ values[@fully_qualified_name].present?
404
+ end
405
+ end
406
+
407
+ class BoolFieldValueFromValues
408
+ def initialize(selph)
409
+ @selph = selph
410
+ @fully_qualified_name = selph.fully_qualified_name
411
+ end
412
+
413
+ def call(values)
414
+ values.fetch(@fully_qualified_name) { @selph.default_value }
415
+ end
416
+ end
417
+
418
+ class BoolFieldValueFromValuesForSerialization
419
+ def initialize(selph)
420
+ @selph = selph
421
+ @fully_qualified_name = selph.fully_qualified_name
422
+ end
423
+
424
+ def call(values)
425
+ values.fetch(@fully_qualified_name) { @selph.default_value }
426
+ end
427
+ end
428
+
429
+ class BaseFieldValueFromValues
430
+ def initialize(selph)
431
+ @selph = selph
432
+ @fully_qualified_name = selph.fully_qualified_name
433
+ end
434
+
435
+ def call(values)
436
+ values[@fully_qualified_name] || @selph.default_value
437
+ end
438
+ end
439
+
440
+ class BaseFieldValueFromValuesForSerialization
441
+ def initialize(selph)
442
+ @selph = selph
443
+ @fully_qualified_name = selph.fully_qualified_name
444
+ end
445
+
446
+ def call(values)
447
+ values[@fully_qualified_name] || @selph.default_value
448
+ end
449
+ end
450
+
451
+ class MapValueFromValues
452
+ def initialize(selph)
453
+ @selph = selph
454
+ @fully_qualified_name = selph.fully_qualified_name
455
+ end
456
+
457
+ def call(values)
458
+ values[@fully_qualified_name] ||= ::Protobuf::Field::FieldHash.new(@selph)
459
+ end
460
+ end
461
+
462
+ class MapValueFromValuesForSerialization
463
+ def initialize(selph)
464
+ @selph = selph
465
+ @fully_qualified_name = selph.fully_qualified_name
466
+ @type_class = selph.type_class
467
+ end
468
+
469
+ def call(values)
470
+ value = values[@fully_qualified_name] ||= ::Protobuf::Field::FieldHash.new(@selph)
471
+
472
+ array = []
473
+ value.each do |k, v|
474
+ array << @type_class.new(:key => k, :value => v)
475
+ end
476
+
477
+ array
478
+ end
479
+ end
480
+
481
+ class RepeatedFieldValueFromValues
482
+ def initialize(selph)
483
+ @selph = selph
484
+ @fully_qualified_name = selph.fully_qualified_name
485
+ end
486
+
487
+ def call(values)
488
+ values[@fully_qualified_name] ||= ::Protobuf::Field::FieldArray.new(@selph)
489
+ end
490
+ end
491
+
492
+ class RepeatedFieldValueFromValuesForSerialization
493
+ def initialize(selph)
494
+ @selph = selph
495
+ @fully_qualified_name = selph.fully_qualified_name
496
+ end
497
+
498
+ def call(values)
499
+ values[@fully_qualified_name] ||= ::Protobuf::Field::FieldArray.new(@selph)
500
+ end
501
+ end
502
+ end
503
+ end
504
+ end
@@ -0,0 +1,64 @@
1
+ require 'protobuf/field/varint_field'
2
+
3
+ module Protobuf
4
+ module Field
5
+ class BoolField < VarintField
6
+ ONE = 1
7
+ FALSE_ENCODE = [0].pack('C')
8
+ FALSE_STRING = "false".freeze
9
+ FALSE_VALUES = [false, FALSE_STRING].freeze
10
+ TRUE_ENCODE = [1].pack('C')
11
+ TRUE_STRING = "true".freeze
12
+ TRUE_VALUES = [true, TRUE_STRING].freeze
13
+ ACCEPTABLES = [true, false, TRUE_STRING, FALSE_STRING].freeze
14
+
15
+ ##
16
+ # Class Methods
17
+ #
18
+
19
+ def self.default
20
+ false
21
+ end
22
+
23
+ ##
24
+ # Public Instance Methods
25
+ # #
26
+
27
+ def acceptable?(val)
28
+ ACCEPTABLES.include?(val)
29
+ end
30
+
31
+ def coerce!(val)
32
+ if TRUE_VALUES.include?(val)
33
+ true
34
+ elsif FALSE_VALUES.include?(val)
35
+ false
36
+ else
37
+ fail TypeError, "Expected value of type '#{type_class}' for field #{name}, but got '#{val.class}'"
38
+ end
39
+ end
40
+
41
+ def decode(value)
42
+ value == ONE
43
+ end
44
+
45
+ def encode(value)
46
+ value ? TRUE_ENCODE : FALSE_ENCODE
47
+ end
48
+
49
+ private
50
+
51
+ ##
52
+ # Private Instance Methods
53
+ #
54
+
55
+ def define_accessor(simple_field_name, _fully_qualified_field_name)
56
+ super
57
+ message_class.class_eval do
58
+ alias_method "#{simple_field_name}?", simple_field_name
59
+ end
60
+ end
61
+
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,67 @@
1
+ require 'protobuf/wire_type'
2
+
3
+ module Protobuf
4
+ module Field
5
+ class BytesField < BaseField
6
+
7
+ ##
8
+ # Constants
9
+ #
10
+
11
+ BYTES_ENCODING = Encoding::BINARY
12
+
13
+ ##
14
+ # Class Methods
15
+ #
16
+
17
+ def self.default
18
+ ''
19
+ end
20
+
21
+ ##
22
+ # Public Instance Methods
23
+ #
24
+
25
+ def acceptable?(val)
26
+ val.is_a?(String) || val.nil? || val.is_a?(Symbol) || val.is_a?(::Protobuf::Message)
27
+ end
28
+
29
+ def decode(bytes)
30
+ bytes.force_encoding(::Protobuf::Field::BytesField::BYTES_ENCODING)
31
+ bytes
32
+ end
33
+
34
+ def encode(value)
35
+ value_to_encode = if value.is_a?(::Protobuf::Message)
36
+ value.encode
37
+ else
38
+ "" + value
39
+ end
40
+
41
+ value_to_encode.force_encoding(::Protobuf::Field::BytesField::BYTES_ENCODING)
42
+ "#{::Protobuf::Field::VarintField.encode(value_to_encode.bytesize)}#{value_to_encode}"
43
+ end
44
+
45
+ def wire_type
46
+ ::Protobuf::WireType::LENGTH_DELIMITED
47
+ end
48
+
49
+ def coerce!(value)
50
+ case value
51
+ when String, Symbol
52
+ value.to_s
53
+ when NilClass
54
+ nil
55
+ when ::Protobuf::Message
56
+ value.dup
57
+ else
58
+ fail TypeError, "Unacceptable value #{value} for field #{name} of type #{type_class}"
59
+ end
60
+ end
61
+
62
+ def json_encode(value)
63
+ Base64.strict_encode64(value)
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,25 @@
1
+ require 'protobuf/field/float_field'
2
+
3
+ module Protobuf
4
+ module Field
5
+ class DoubleField < FloatField
6
+
7
+ ##
8
+ # Public Instance Methods
9
+ #
10
+
11
+ def decode(bytes)
12
+ bytes.unpack('E').first
13
+ end
14
+
15
+ def encode(value)
16
+ [value].pack('E')
17
+ end
18
+
19
+ def wire_type
20
+ WireType::FIXED64
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,56 @@
1
+ require 'protobuf/field/integer_field'
2
+
3
+ module Protobuf
4
+ module Field
5
+ class EnumField < IntegerField
6
+
7
+ ##
8
+ # Class Methods
9
+ #
10
+
11
+ def self.default
12
+ fail NoMethodError, "#{self}.#{__method__} must be called on an instance"
13
+ end
14
+
15
+ ##
16
+ # Public Instance Methods
17
+ #
18
+ def encode(value)
19
+ # original CSGoogle's library uses 64bits integer for negative value
20
+ ::Protobuf::Field::VarintField.encode(value.to_i & 0xffff_ffff_ffff_ffff)
21
+ end
22
+
23
+ def decode(value)
24
+ value -= 0x1_0000_0000_0000_0000 if (value & 0x8000_0000_0000_0000).nonzero?
25
+ value if acceptable?(value)
26
+ end
27
+
28
+ def acceptable?(val)
29
+ !type_class.fetch(val).nil?
30
+ end
31
+
32
+ def enum?
33
+ true
34
+ end
35
+
36
+ def coerce!(value)
37
+ type_class.fetch(value) || fail(TypeError, "Invalid Enum value: #{value.inspect} for #{name}")
38
+ end
39
+
40
+ private
41
+
42
+ ##
43
+ # Private Instance Methods
44
+ #
45
+
46
+ def typed_default_value
47
+ if default.is_a?(Symbol)
48
+ type_class.const_get(default)
49
+ else
50
+ type_class.fetch(default) || type_class.enums.first
51
+ end
52
+ end
53
+
54
+ end
55
+ end
56
+ end