google-protobuf 3.25.3 → 4.26.1-java

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 (57) hide show
  1. checksums.yaml +4 -4
  2. data/ext/google/protobuf_c/message.c +41 -77
  3. data/ext/google/protobuf_c/message.h +1 -1
  4. data/ext/google/protobuf_c/protobuf.c +19 -6
  5. data/ext/google/protobuf_c/ruby-upb.c +11788 -10795
  6. data/ext/google/protobuf_c/ruby-upb.h +5164 -4242
  7. data/ext/google/protobuf_c/shared_convert.c +5 -3
  8. data/ext/google/protobuf_c/shared_convert.h +2 -2
  9. data/ext/google/protobuf_c/shared_message.c +8 -6
  10. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.c +467 -0
  11. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +9 -8
  12. data/lib/google/protobuf/any_pb.rb +1 -22
  13. data/lib/google/protobuf/api_pb.rb +1 -24
  14. data/lib/google/protobuf/descriptor_pb.rb +2 -23
  15. data/lib/google/protobuf/duration_pb.rb +1 -22
  16. data/lib/google/protobuf/empty_pb.rb +1 -22
  17. data/lib/google/protobuf/ffi/descriptor.rb +2 -3
  18. data/lib/google/protobuf/ffi/enum_descriptor.rb +1 -1
  19. data/lib/google/protobuf/ffi/ffi.rb +3 -1
  20. data/lib/google/protobuf/ffi/field_descriptor.rb +10 -1
  21. data/lib/google/protobuf/ffi/file_descriptor.rb +1 -13
  22. data/lib/google/protobuf/ffi/internal/convert.rb +7 -23
  23. data/lib/google/protobuf/ffi/map.rb +13 -11
  24. data/lib/google/protobuf/ffi/message.rb +10 -13
  25. data/lib/google/protobuf/ffi/object_cache.rb +3 -3
  26. data/lib/google/protobuf/ffi/oneof_descriptor.rb +1 -1
  27. data/lib/google/protobuf/ffi/repeated_field.rb +12 -10
  28. data/lib/google/protobuf/field_mask_pb.rb +1 -22
  29. data/lib/google/protobuf/internal/object_cache.rb +99 -0
  30. data/lib/google/protobuf/plugin_pb.rb +2 -24
  31. data/lib/google/protobuf/repeated_field.rb +1 -2
  32. data/lib/google/protobuf/source_context_pb.rb +1 -22
  33. data/lib/google/protobuf/struct_pb.rb +1 -22
  34. data/lib/google/protobuf/timestamp_pb.rb +1 -22
  35. data/lib/google/protobuf/type_pb.rb +1 -24
  36. data/lib/google/protobuf/wrappers_pb.rb +1 -22
  37. data/lib/google/protobuf.rb +1 -1
  38. data/lib/google/protobuf_ffi.rb +1 -2
  39. data/lib/google/protobuf_java.jar +0 -0
  40. data/lib/google/protobuf_native.rb +0 -1
  41. data/lib/google/tasks/ffi.rake +1 -3
  42. metadata +42 -41
  43. data/ext/google/protobuf_c/convert.c +0 -314
  44. data/ext/google/protobuf_c/convert.h +0 -50
  45. data/ext/google/protobuf_c/defs.c +0 -1403
  46. data/ext/google/protobuf_c/defs.h +0 -82
  47. data/ext/google/protobuf_c/extconf.rb +0 -28
  48. data/ext/google/protobuf_c/map.c +0 -686
  49. data/ext/google/protobuf_c/map.h +0 -44
  50. data/ext/google/protobuf_c/repeated_field.c +0 -656
  51. data/ext/google/protobuf_c/repeated_field.h +0 -41
  52. data/ext/google/protobuf_c/third_party/utf8_range/naive.c +0 -92
  53. data/ext/google/protobuf_c/third_party/utf8_range/range2-neon.c +0 -157
  54. data/ext/google/protobuf_c/third_party/utf8_range/range2-sse.c +0 -170
  55. data/ext/google/protobuf_c/wrap_memcpy.c +0 -29
  56. data/lib/google/protobuf/descriptor_dsl.rb +0 -465
  57. data/lib/google/protobuf/object_cache.rb +0 -97
@@ -1,686 +0,0 @@
1
- // Protocol Buffers - Google's data interchange format
2
- // Copyright 2014 Google Inc. All rights reserved.
3
- //
4
- // Use of this source code is governed by a BSD-style
5
- // license that can be found in the LICENSE file or at
6
- // https://developers.google.com/open-source/licenses/bsd
7
-
8
- #include "convert.h"
9
- #include "defs.h"
10
- #include "message.h"
11
- #include "protobuf.h"
12
-
13
- // -----------------------------------------------------------------------------
14
- // Basic map operations on top of upb_Map.
15
- //
16
- // Note that we roll our own `Map` container here because, as for
17
- // `RepeatedField`, we want a strongly-typed container. This is so that any user
18
- // errors due to incorrect map key or value types are raised as close as
19
- // possible to the error site, rather than at some deferred point (e.g.,
20
- // serialization).
21
- // -----------------------------------------------------------------------------
22
-
23
- // -----------------------------------------------------------------------------
24
- // Map container type.
25
- // -----------------------------------------------------------------------------
26
-
27
- typedef struct {
28
- const upb_Map* map; // Can convert to mutable when non-frozen.
29
- upb_CType key_type;
30
- TypeInfo value_type_info;
31
- VALUE value_type_class;
32
- VALUE arena;
33
- } Map;
34
-
35
- static void Map_mark(void* _self) {
36
- Map* self = _self;
37
- rb_gc_mark(self->value_type_class);
38
- rb_gc_mark(self->arena);
39
- }
40
-
41
- const rb_data_type_t Map_type = {
42
- "Google::Protobuf::Map",
43
- {Map_mark, RUBY_DEFAULT_FREE, NULL},
44
- .flags = RUBY_TYPED_FREE_IMMEDIATELY,
45
- };
46
-
47
- VALUE cMap;
48
-
49
- static Map* ruby_to_Map(VALUE _self) {
50
- Map* self;
51
- TypedData_Get_Struct(_self, Map, &Map_type, self);
52
- return self;
53
- }
54
-
55
- static VALUE Map_alloc(VALUE klass) {
56
- Map* self = ALLOC(Map);
57
- self->map = NULL;
58
- self->value_type_class = Qnil;
59
- self->value_type_info.def.msgdef = NULL;
60
- self->arena = Qnil;
61
- return TypedData_Wrap_Struct(klass, &Map_type, self);
62
- }
63
-
64
- VALUE Map_GetRubyWrapper(upb_Map* map, upb_CType key_type, TypeInfo value_type,
65
- VALUE arena) {
66
- PBRUBY_ASSERT(map);
67
-
68
- VALUE val = ObjectCache_Get(map);
69
-
70
- if (val == Qnil) {
71
- val = Map_alloc(cMap);
72
- Map* self;
73
- TypedData_Get_Struct(val, Map, &Map_type, self);
74
- self->map = map;
75
- self->arena = arena;
76
- self->key_type = key_type;
77
- self->value_type_info = value_type;
78
- if (self->value_type_info.type == kUpb_CType_Message) {
79
- const upb_MessageDef* val_m = self->value_type_info.def.msgdef;
80
- self->value_type_class = Descriptor_DefToClass(val_m);
81
- }
82
- return ObjectCache_TryAdd(map, val);
83
- }
84
-
85
- return val;
86
- }
87
-
88
- static VALUE Map_new_this_type(Map* from) {
89
- VALUE arena_rb = Arena_new();
90
- upb_Map* map = upb_Map_New(Arena_get(arena_rb), from->key_type,
91
- from->value_type_info.type);
92
- VALUE ret =
93
- Map_GetRubyWrapper(map, from->key_type, from->value_type_info, arena_rb);
94
- PBRUBY_ASSERT(ruby_to_Map(ret)->value_type_class == from->value_type_class);
95
- return ret;
96
- }
97
-
98
- static TypeInfo Map_keyinfo(Map* self) {
99
- TypeInfo ret;
100
- ret.type = self->key_type;
101
- ret.def.msgdef = NULL;
102
- return ret;
103
- }
104
-
105
- static upb_Map* Map_GetMutable(VALUE _self) {
106
- rb_check_frozen(_self);
107
- return (upb_Map*)ruby_to_Map(_self)->map;
108
- }
109
-
110
- VALUE Map_CreateHash(const upb_Map* map, upb_CType key_type,
111
- TypeInfo val_info) {
112
- VALUE hash = rb_hash_new();
113
- TypeInfo key_info = TypeInfo_from_type(key_type);
114
-
115
- if (!map) return hash;
116
-
117
- size_t iter = kUpb_Map_Begin;
118
- upb_MessageValue key, val;
119
- while (upb_Map_Next(map, &key, &val, &iter)) {
120
- VALUE key_val = Convert_UpbToRuby(key, key_info, Qnil);
121
- VALUE val_val = Scalar_CreateHash(val, val_info);
122
- rb_hash_aset(hash, key_val, val_val);
123
- }
124
-
125
- return hash;
126
- }
127
-
128
- VALUE Map_deep_copy(VALUE obj) {
129
- Map* self = ruby_to_Map(obj);
130
- VALUE new_arena_rb = Arena_new();
131
- upb_Arena* arena = Arena_get(new_arena_rb);
132
- upb_Map* new_map =
133
- upb_Map_New(arena, self->key_type, self->value_type_info.type);
134
- size_t iter = kUpb_Map_Begin;
135
- upb_MessageValue key, val;
136
- while (upb_Map_Next(self->map, &key, &val, &iter)) {
137
- upb_MessageValue val_copy =
138
- Msgval_DeepCopy(val, self->value_type_info, arena);
139
- upb_Map_Set(new_map, key, val_copy, arena);
140
- }
141
-
142
- return Map_GetRubyWrapper(new_map, self->key_type, self->value_type_info,
143
- new_arena_rb);
144
- }
145
-
146
- const upb_Map* Map_GetUpbMap(VALUE val, const upb_FieldDef* field,
147
- upb_Arena* arena) {
148
- const upb_FieldDef* key_field = map_field_key(field);
149
- const upb_FieldDef* value_field = map_field_value(field);
150
- TypeInfo value_type_info = TypeInfo_get(value_field);
151
- Map* self;
152
-
153
- if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) ||
154
- RTYPEDDATA_TYPE(val) != &Map_type) {
155
- rb_raise(cTypeError, "Expected Map instance");
156
- }
157
-
158
- self = ruby_to_Map(val);
159
- if (self->key_type != upb_FieldDef_CType(key_field)) {
160
- rb_raise(cTypeError, "Map key type does not match field's key type");
161
- }
162
- if (self->value_type_info.type != value_type_info.type) {
163
- rb_raise(cTypeError, "Map value type does not match field's value type");
164
- }
165
- if (self->value_type_info.def.msgdef != value_type_info.def.msgdef) {
166
- rb_raise(cTypeError, "Map value type has wrong message/enum class");
167
- }
168
-
169
- Arena_fuse(self->arena, arena);
170
- return self->map;
171
- }
172
-
173
- void Map_Inspect(StringBuilder* b, const upb_Map* map, upb_CType key_type,
174
- TypeInfo val_type) {
175
- bool first = true;
176
- TypeInfo key_type_info = {key_type};
177
- StringBuilder_Printf(b, "{");
178
- if (map) {
179
- size_t iter = kUpb_Map_Begin;
180
- upb_MessageValue key, val;
181
- while (upb_Map_Next(map, &key, &val, &iter)) {
182
- if (first) {
183
- first = false;
184
- } else {
185
- StringBuilder_Printf(b, ", ");
186
- }
187
- StringBuilder_PrintMsgval(b, key, key_type_info);
188
- StringBuilder_Printf(b, "=>");
189
- StringBuilder_PrintMsgval(b, val, val_type);
190
- }
191
- }
192
- StringBuilder_Printf(b, "}");
193
- }
194
-
195
- static int merge_into_self_callback(VALUE key, VALUE val, VALUE _self) {
196
- Map* self = ruby_to_Map(_self);
197
- upb_Arena* arena = Arena_get(self->arena);
198
- upb_MessageValue key_val =
199
- Convert_RubyToUpb(key, "", Map_keyinfo(self), arena);
200
- upb_MessageValue val_val =
201
- Convert_RubyToUpb(val, "", self->value_type_info, arena);
202
- upb_Map_Set(Map_GetMutable(_self), key_val, val_val, arena);
203
- return ST_CONTINUE;
204
- }
205
-
206
- // Used only internally -- shared by #merge and #initialize.
207
- static VALUE Map_merge_into_self(VALUE _self, VALUE hashmap) {
208
- if (TYPE(hashmap) == T_HASH) {
209
- rb_hash_foreach(hashmap, merge_into_self_callback, _self);
210
- } else if (RB_TYPE_P(hashmap, T_DATA) && RTYPEDDATA_P(hashmap) &&
211
- RTYPEDDATA_TYPE(hashmap) == &Map_type) {
212
- Map* self = ruby_to_Map(_self);
213
- Map* other = ruby_to_Map(hashmap);
214
- upb_Arena* arena = Arena_get(self->arena);
215
- upb_Message* self_msg = Map_GetMutable(_self);
216
-
217
- Arena_fuse(other->arena, arena);
218
-
219
- if (self->key_type != other->key_type ||
220
- self->value_type_info.type != other->value_type_info.type ||
221
- self->value_type_class != other->value_type_class) {
222
- rb_raise(rb_eArgError, "Attempt to merge Map with mismatching types");
223
- }
224
-
225
- size_t iter = kUpb_Map_Begin;
226
- upb_MessageValue key, val;
227
- while (upb_Map_Next(other->map, &key, &val, &iter)) {
228
- upb_Map_Set(self_msg, key, val, arena);
229
- }
230
- } else {
231
- rb_raise(rb_eArgError, "Unknown type merging into Map");
232
- }
233
- return _self;
234
- }
235
-
236
- /*
237
- * call-seq:
238
- * Map.new(key_type, value_type, value_typeclass = nil, init_hashmap = {})
239
- * => new map
240
- *
241
- * Allocates a new Map container. This constructor may be called with 2, 3, or 4
242
- * arguments. The first two arguments are always present and are symbols (taking
243
- * on the same values as field-type symbols in message descriptors) that
244
- * indicate the type of the map key and value fields.
245
- *
246
- * The supported key types are: :int32, :int64, :uint32, :uint64, :bool,
247
- * :string, :bytes.
248
- *
249
- * The supported value types are: :int32, :int64, :uint32, :uint64, :bool,
250
- * :string, :bytes, :enum, :message.
251
- *
252
- * The third argument, value_typeclass, must be present if value_type is :enum
253
- * or :message. As in RepeatedField#new, this argument must be a message class
254
- * (for :message) or enum module (for :enum).
255
- *
256
- * The last argument, if present, provides initial content for map. Note that
257
- * this may be an ordinary Ruby hashmap or another Map instance with identical
258
- * key and value types. Also note that this argument may be present whether or
259
- * not value_typeclass is present (and it is unambiguously separate from
260
- * value_typeclass because value_typeclass's presence is strictly determined by
261
- * value_type). The contents of this initial hashmap or Map instance are
262
- * shallow-copied into the new Map: the original map is unmodified, but
263
- * references to underlying objects will be shared if the value type is a
264
- * message type.
265
- */
266
- static VALUE Map_init(int argc, VALUE* argv, VALUE _self) {
267
- Map* self = ruby_to_Map(_self);
268
- VALUE init_arg;
269
-
270
- // We take either two args (:key_type, :value_type), three args (:key_type,
271
- // :value_type, "ValueMessageType"), or four args (the above plus an initial
272
- // hashmap).
273
- if (argc < 2 || argc > 4) {
274
- rb_raise(rb_eArgError, "Map constructor expects 2, 3 or 4 arguments.");
275
- }
276
-
277
- self->key_type = ruby_to_fieldtype(argv[0]);
278
- self->value_type_info =
279
- TypeInfo_FromClass(argc, argv, 1, &self->value_type_class, &init_arg);
280
- self->arena = Arena_new();
281
-
282
- // Check that the key type is an allowed type.
283
- switch (self->key_type) {
284
- case kUpb_CType_Int32:
285
- case kUpb_CType_Int64:
286
- case kUpb_CType_UInt32:
287
- case kUpb_CType_UInt64:
288
- case kUpb_CType_Bool:
289
- case kUpb_CType_String:
290
- case kUpb_CType_Bytes:
291
- // These are OK.
292
- break;
293
- default:
294
- rb_raise(rb_eArgError, "Invalid key type for map.");
295
- }
296
-
297
- self->map = upb_Map_New(Arena_get(self->arena), self->key_type,
298
- self->value_type_info.type);
299
- VALUE stored = ObjectCache_TryAdd(self->map, _self);
300
- (void)stored;
301
- PBRUBY_ASSERT(stored == _self);
302
-
303
- if (init_arg != Qnil) {
304
- Map_merge_into_self(_self, init_arg);
305
- }
306
-
307
- return Qnil;
308
- }
309
-
310
- /*
311
- * call-seq:
312
- * Map.each(&block)
313
- *
314
- * Invokes &block on each |key, value| pair in the map, in unspecified order.
315
- * Note that Map also includes Enumerable; map thus acts like a normal Ruby
316
- * sequence.
317
- */
318
- static VALUE Map_each(VALUE _self) {
319
- Map* self = ruby_to_Map(_self);
320
- size_t iter = kUpb_Map_Begin;
321
- upb_MessageValue key, val;
322
-
323
- while (upb_Map_Next(self->map, &key, &val, &iter)) {
324
- VALUE key_val = Convert_UpbToRuby(key, Map_keyinfo(self), self->arena);
325
- VALUE val_val = Convert_UpbToRuby(val, self->value_type_info, self->arena);
326
- rb_yield_values(2, key_val, val_val);
327
- }
328
-
329
- return Qnil;
330
- }
331
-
332
- /*
333
- * call-seq:
334
- * Map.keys => [list_of_keys]
335
- *
336
- * Returns the list of keys contained in the map, in unspecified order.
337
- */
338
- static VALUE Map_keys(VALUE _self) {
339
- Map* self = ruby_to_Map(_self);
340
- size_t iter = kUpb_Map_Begin;
341
- VALUE ret = rb_ary_new();
342
- upb_MessageValue key, val;
343
-
344
- while (upb_Map_Next(self->map, &key, &val, &iter)) {
345
- VALUE key_val = Convert_UpbToRuby(key, Map_keyinfo(self), self->arena);
346
- rb_ary_push(ret, key_val);
347
- }
348
-
349
- return ret;
350
- }
351
-
352
- /*
353
- * call-seq:
354
- * Map.values => [list_of_values]
355
- *
356
- * Returns the list of values contained in the map, in unspecified order.
357
- */
358
- static VALUE Map_values(VALUE _self) {
359
- Map* self = ruby_to_Map(_self);
360
- size_t iter = kUpb_Map_Begin;
361
- VALUE ret = rb_ary_new();
362
- upb_MessageValue key, val;
363
-
364
- while (upb_Map_Next(self->map, &key, &val, &iter)) {
365
- VALUE val_val = Convert_UpbToRuby(val, self->value_type_info, self->arena);
366
- rb_ary_push(ret, val_val);
367
- }
368
-
369
- return ret;
370
- }
371
-
372
- /*
373
- * call-seq:
374
- * Map.[](key) => value
375
- *
376
- * Accesses the element at the given key. Throws an exception if the key type is
377
- * incorrect. Returns nil when the key is not present in the map.
378
- */
379
- static VALUE Map_index(VALUE _self, VALUE key) {
380
- Map* self = ruby_to_Map(_self);
381
- upb_MessageValue key_upb =
382
- Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL);
383
- upb_MessageValue val;
384
-
385
- if (upb_Map_Get(self->map, key_upb, &val)) {
386
- return Convert_UpbToRuby(val, self->value_type_info, self->arena);
387
- } else {
388
- return Qnil;
389
- }
390
- }
391
-
392
- /*
393
- * call-seq:
394
- * Map.[]=(key, value) => value
395
- *
396
- * Inserts or overwrites the value at the given key with the given new value.
397
- * Throws an exception if the key type is incorrect. Returns the new value that
398
- * was just inserted.
399
- */
400
- static VALUE Map_index_set(VALUE _self, VALUE key, VALUE val) {
401
- Map* self = ruby_to_Map(_self);
402
- upb_Arena* arena = Arena_get(self->arena);
403
- upb_MessageValue key_upb =
404
- Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL);
405
- upb_MessageValue val_upb =
406
- Convert_RubyToUpb(val, "", self->value_type_info, arena);
407
-
408
- upb_Map_Set(Map_GetMutable(_self), key_upb, val_upb, arena);
409
-
410
- return val;
411
- }
412
-
413
- /*
414
- * call-seq:
415
- * Map.has_key?(key) => bool
416
- *
417
- * Returns true if the given key is present in the map. Throws an exception if
418
- * the key has the wrong type.
419
- */
420
- static VALUE Map_has_key(VALUE _self, VALUE key) {
421
- Map* self = ruby_to_Map(_self);
422
- upb_MessageValue key_upb =
423
- Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL);
424
-
425
- if (upb_Map_Get(self->map, key_upb, NULL)) {
426
- return Qtrue;
427
- } else {
428
- return Qfalse;
429
- }
430
- }
431
-
432
- /*
433
- * call-seq:
434
- * Map.delete(key) => old_value
435
- *
436
- * Deletes the value at the given key, if any, returning either the old value or
437
- * nil if none was present. Throws an exception if the key is of the wrong type.
438
- */
439
- static VALUE Map_delete(VALUE _self, VALUE key) {
440
- Map* self = ruby_to_Map(_self);
441
- rb_check_frozen(_self);
442
-
443
- upb_MessageValue key_upb =
444
- Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL);
445
- upb_MessageValue val_upb;
446
-
447
- if (upb_Map_Delete(self->map, key_upb, &val_upb)) {
448
- return Convert_UpbToRuby(val_upb, self->value_type_info, self->arena);
449
- } else {
450
- return Qnil;
451
- }
452
- }
453
-
454
- /*
455
- * call-seq:
456
- * Map.clear
457
- *
458
- * Removes all entries from the map.
459
- */
460
- static VALUE Map_clear(VALUE _self) {
461
- upb_Map_Clear(Map_GetMutable(_self));
462
- return Qnil;
463
- }
464
-
465
- /*
466
- * call-seq:
467
- * Map.length
468
- *
469
- * Returns the number of entries (key-value pairs) in the map.
470
- */
471
- static VALUE Map_length(VALUE _self) {
472
- Map* self = ruby_to_Map(_self);
473
- return ULL2NUM(upb_Map_Size(self->map));
474
- }
475
-
476
- /*
477
- * call-seq:
478
- * Map.dup => new_map
479
- *
480
- * Duplicates this map with a shallow copy. References to all non-primitive
481
- * element objects (e.g., submessages) are shared.
482
- */
483
- static VALUE Map_dup(VALUE _self) {
484
- Map* self = ruby_to_Map(_self);
485
- VALUE new_map_rb = Map_new_this_type(self);
486
- Map* new_self = ruby_to_Map(new_map_rb);
487
- size_t iter = kUpb_Map_Begin;
488
- upb_Arena* arena = Arena_get(new_self->arena);
489
- upb_Map* new_map = Map_GetMutable(new_map_rb);
490
-
491
- Arena_fuse(self->arena, arena);
492
-
493
- upb_MessageValue key, val;
494
- while (upb_Map_Next(self->map, &key, &val, &iter)) {
495
- upb_Map_Set(new_map, key, val, arena);
496
- }
497
-
498
- return new_map_rb;
499
- }
500
-
501
- /*
502
- * call-seq:
503
- * Map.==(other) => boolean
504
- *
505
- * Compares this map to another. Maps are equal if they have identical key sets,
506
- * and for each key, the values in both maps compare equal. Elements are
507
- * compared as per normal Ruby semantics, by calling their :== methods (or
508
- * performing a more efficient comparison for primitive types).
509
- *
510
- * Maps with dissimilar key types or value types/typeclasses are never equal,
511
- * even if value comparison (for example, between integers and floats) would
512
- * have otherwise indicated that every element has equal value.
513
- */
514
- VALUE Map_eq(VALUE _self, VALUE _other) {
515
- Map* self = ruby_to_Map(_self);
516
- Map* other;
517
-
518
- // Allow comparisons to Ruby hashmaps by converting to a temporary Map
519
- // instance. Slow, but workable.
520
- if (TYPE(_other) == T_HASH) {
521
- VALUE other_map = Map_new_this_type(self);
522
- Map_merge_into_self(other_map, _other);
523
- _other = other_map;
524
- }
525
-
526
- other = ruby_to_Map(_other);
527
-
528
- if (self == other) {
529
- return Qtrue;
530
- }
531
- if (self->key_type != other->key_type ||
532
- self->value_type_info.type != other->value_type_info.type ||
533
- self->value_type_class != other->value_type_class) {
534
- return Qfalse;
535
- }
536
- if (upb_Map_Size(self->map) != upb_Map_Size(other->map)) {
537
- return Qfalse;
538
- }
539
-
540
- // For each member of self, check that an equal member exists at the same key
541
- // in other.
542
- size_t iter = kUpb_Map_Begin;
543
- upb_MessageValue key, val;
544
- while (upb_Map_Next(self->map, &key, &val, &iter)) {
545
- upb_MessageValue other_val;
546
- if (!upb_Map_Get(other->map, key, &other_val)) {
547
- // Not present in other map.
548
- return Qfalse;
549
- }
550
- if (!Msgval_IsEqual(val, other_val, self->value_type_info)) {
551
- // Present but different value.
552
- return Qfalse;
553
- }
554
- }
555
-
556
- return Qtrue;
557
- }
558
-
559
- /*
560
- * call-seq:
561
- * Message.freeze => self
562
- *
563
- * Freezes the message object. We have to intercept this so we can pin the
564
- * Ruby object into memory so we don't forget it's frozen.
565
- */
566
- static VALUE Map_freeze(VALUE _self) {
567
- Map* self = ruby_to_Map(_self);
568
- if (!RB_OBJ_FROZEN(_self)) {
569
- Arena_Pin(self->arena, _self);
570
- RB_OBJ_FREEZE(_self);
571
- }
572
- return _self;
573
- }
574
-
575
- /*
576
- * Deep freezes the map and values recursively.
577
- * Internal use only.
578
- */
579
- VALUE Map_internal_deep_freeze(VALUE _self) {
580
- Map* self = ruby_to_Map(_self);
581
- Map_freeze(_self);
582
- if (self->value_type_info.type == kUpb_CType_Message) {
583
- size_t iter = kUpb_Map_Begin;
584
- upb_MessageValue key, val;
585
-
586
- while (upb_Map_Next(self->map, &key, &val, &iter)) {
587
- VALUE val_val =
588
- Convert_UpbToRuby(val, self->value_type_info, self->arena);
589
- Message_internal_deep_freeze(val_val);
590
- }
591
- }
592
- return _self;
593
- }
594
-
595
- /*
596
- * call-seq:
597
- * Map.hash => hash_value
598
- *
599
- * Returns a hash value based on this map's contents.
600
- */
601
- VALUE Map_hash(VALUE _self) {
602
- Map* self = ruby_to_Map(_self);
603
- uint64_t hash = 0;
604
-
605
- size_t iter = kUpb_Map_Begin;
606
- TypeInfo key_info = {self->key_type};
607
- upb_MessageValue key, val;
608
- while (upb_Map_Next(self->map, &key, &val, &iter)) {
609
- hash = Msgval_GetHash(key, key_info, hash);
610
- hash = Msgval_GetHash(val, self->value_type_info, hash);
611
- }
612
-
613
- return LL2NUM(hash);
614
- }
615
-
616
- /*
617
- * call-seq:
618
- * Map.to_h => {}
619
- *
620
- * Returns a Ruby Hash object containing all the values within the map
621
- */
622
- VALUE Map_to_h(VALUE _self) {
623
- Map* self = ruby_to_Map(_self);
624
- return Map_CreateHash(self->map, self->key_type, self->value_type_info);
625
- }
626
-
627
- /*
628
- * call-seq:
629
- * Map.inspect => string
630
- *
631
- * Returns a string representing this map's elements. It will be formatted as
632
- * "{key => value, key => value, ...}", with each key and value string
633
- * representation computed by its own #inspect method.
634
- */
635
- VALUE Map_inspect(VALUE _self) {
636
- Map* self = ruby_to_Map(_self);
637
-
638
- StringBuilder* builder = StringBuilder_New();
639
- Map_Inspect(builder, self->map, self->key_type, self->value_type_info);
640
- VALUE ret = StringBuilder_ToRubyString(builder);
641
- StringBuilder_Free(builder);
642
- return ret;
643
- }
644
-
645
- /*
646
- * call-seq:
647
- * Map.merge(other_map) => map
648
- *
649
- * Copies key/value pairs from other_map into a copy of this map. If a key is
650
- * set in other_map and this map, the value from other_map overwrites the value
651
- * in the new copy of this map. Returns the new copy of this map with merged
652
- * contents.
653
- */
654
- static VALUE Map_merge(VALUE _self, VALUE hashmap) {
655
- VALUE dupped = Map_dup(_self);
656
- return Map_merge_into_self(dupped, hashmap);
657
- }
658
-
659
- void Map_register(VALUE module) {
660
- VALUE klass = rb_define_class_under(module, "Map", rb_cObject);
661
- rb_define_alloc_func(klass, Map_alloc);
662
- rb_gc_register_address(&cMap);
663
- cMap = klass;
664
-
665
- rb_define_method(klass, "initialize", Map_init, -1);
666
- rb_define_method(klass, "each", Map_each, 0);
667
- rb_define_method(klass, "keys", Map_keys, 0);
668
- rb_define_method(klass, "values", Map_values, 0);
669
- rb_define_method(klass, "[]", Map_index, 1);
670
- rb_define_method(klass, "[]=", Map_index_set, 2);
671
- rb_define_method(klass, "has_key?", Map_has_key, 1);
672
- rb_define_method(klass, "delete", Map_delete, 1);
673
- rb_define_method(klass, "clear", Map_clear, 0);
674
- rb_define_method(klass, "length", Map_length, 0);
675
- rb_define_method(klass, "size", Map_length, 0);
676
- rb_define_method(klass, "dup", Map_dup, 0);
677
- // Also define #clone so that we don't inherit Object#clone.
678
- rb_define_method(klass, "clone", Map_dup, 0);
679
- rb_define_method(klass, "==", Map_eq, 1);
680
- rb_define_method(klass, "freeze", Map_freeze, 0);
681
- rb_define_method(klass, "hash", Map_hash, 0);
682
- rb_define_method(klass, "to_h", Map_to_h, 0);
683
- rb_define_method(klass, "inspect", Map_inspect, 0);
684
- rb_define_method(klass, "merge", Map_merge, 1);
685
- rb_include_module(klass, rb_mEnumerable);
686
- }