google-protobuf 3.25.8 → 4.32.1
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.
- checksums.yaml +4 -4
- data/ext/google/protobuf_c/convert.c +33 -15
- data/ext/google/protobuf_c/defs.c +802 -125
- data/ext/google/protobuf_c/extconf.rb +20 -10
- data/ext/google/protobuf_c/glue.c +79 -0
- data/ext/google/protobuf_c/map.c +145 -63
- data/ext/google/protobuf_c/map.h +7 -3
- data/ext/google/protobuf_c/message.c +204 -171
- data/ext/google/protobuf_c/message.h +2 -6
- data/ext/google/protobuf_c/protobuf.c +33 -19
- data/ext/google/protobuf_c/protobuf.h +3 -15
- data/ext/google/protobuf_c/repeated_field.c +130 -58
- data/ext/google/protobuf_c/repeated_field.h +6 -2
- data/ext/google/protobuf_c/ruby-upb.c +10324 -7764
- data/ext/google/protobuf_c/ruby-upb.h +9959 -6442
- data/ext/google/protobuf_c/shared_convert.c +7 -2
- data/ext/google/protobuf_c/shared_message.c +3 -32
- data/ext/google/protobuf_c/shared_message.h +0 -4
- data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.c +207 -0
- data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +9 -8
- data/ext/google/protobuf_c/third_party/utf8_range/utf8_range_neon.inc +117 -0
- data/ext/google/protobuf_c/third_party/utf8_range/utf8_range_sse.inc +272 -0
- data/lib/google/protobuf/any_pb.rb +2 -23
- data/lib/google/protobuf/api_pb.rb +3 -26
- data/lib/google/protobuf/descriptor_pb.rb +8 -24
- data/lib/google/protobuf/duration_pb.rb +2 -23
- data/lib/google/protobuf/empty_pb.rb +2 -23
- data/lib/google/protobuf/ffi/descriptor.rb +14 -4
- data/lib/google/protobuf/ffi/descriptor_pool.rb +5 -1
- data/lib/google/protobuf/ffi/enum_descriptor.rb +13 -1
- data/lib/google/protobuf/ffi/ffi.rb +7 -6
- data/lib/google/protobuf/ffi/field_descriptor.rb +29 -2
- data/lib/google/protobuf/ffi/file_descriptor.rb +39 -13
- data/lib/google/protobuf/ffi/internal/arena.rb +0 -6
- data/lib/google/protobuf/ffi/internal/convert.rb +17 -30
- data/lib/google/protobuf/ffi/internal/pointer_helper.rb +2 -1
- data/lib/google/protobuf/ffi/map.rb +52 -26
- data/lib/google/protobuf/ffi/message.rb +188 -67
- data/lib/google/protobuf/ffi/method_descriptor.rb +124 -0
- data/lib/google/protobuf/ffi/object_cache.rb +3 -3
- data/lib/google/protobuf/ffi/oneof_descriptor.rb +13 -1
- data/lib/google/protobuf/ffi/repeated_field.rb +47 -19
- data/lib/google/protobuf/ffi/service_descriptor.rb +117 -0
- data/lib/google/protobuf/field_mask_pb.rb +2 -23
- data/lib/google/protobuf/internal/object_cache.rb +99 -0
- data/lib/google/protobuf/message_exts.rb +4 -0
- data/lib/google/protobuf/plugin_pb.rb +3 -25
- data/lib/google/protobuf/repeated_field.rb +4 -5
- data/lib/google/protobuf/source_context_pb.rb +2 -23
- data/lib/google/protobuf/struct_pb.rb +2 -23
- data/lib/google/protobuf/timestamp_pb.rb +2 -23
- data/lib/google/protobuf/type_pb.rb +2 -25
- data/lib/google/protobuf/wrappers_pb.rb +2 -23
- data/lib/google/protobuf.rb +1 -1
- data/lib/google/protobuf_ffi.rb +6 -4
- data/lib/google/protobuf_native.rb +0 -1
- data/lib/google/tasks/ffi.rake +2 -4
- metadata +36 -22
- data/ext/google/protobuf_c/third_party/utf8_range/naive.c +0 -92
- data/ext/google/protobuf_c/third_party/utf8_range/range2-neon.c +0 -157
- data/ext/google/protobuf_c/third_party/utf8_range/range2-sse.c +0 -170
- data/ext/google/protobuf_c/wrap_memcpy.c +0 -29
- data/lib/google/protobuf/descriptor_dsl.rb +0 -465
- data/lib/google/protobuf/object_cache.rb +0 -97
@@ -36,7 +36,7 @@ const upb_Message* Message_GetUpbMessage(VALUE value, const upb_MessageDef* m,
|
|
36
36
|
|
37
37
|
// Gets or constructs a Ruby wrapper object for the given message. The wrapper
|
38
38
|
// object will reference |arena| and ensure that it outlives this object.
|
39
|
-
VALUE Message_GetRubyWrapper(upb_Message* msg, const upb_MessageDef* m,
|
39
|
+
VALUE Message_GetRubyWrapper(const upb_Message* msg, const upb_MessageDef* m,
|
40
40
|
VALUE arena);
|
41
41
|
|
42
42
|
// Gets the given field from this message.
|
@@ -54,10 +54,6 @@ uint64_t Message_Hash(const upb_Message* msg, const upb_MessageDef* m,
|
|
54
54
|
upb_Message* Message_deep_copy(const upb_Message* msg, const upb_MessageDef* m,
|
55
55
|
upb_Arena* arena);
|
56
56
|
|
57
|
-
// Returns true if these two messages are equal.
|
58
|
-
bool Message_Equal(const upb_Message* m1, const upb_Message* m2,
|
59
|
-
const upb_MessageDef* m);
|
60
|
-
|
61
57
|
// Checks that this Ruby object is a message, and raises an exception if not.
|
62
58
|
void Message_CheckClass(VALUE klass);
|
63
59
|
|
@@ -78,7 +74,7 @@ VALUE Message_decode_bytes(int size, const char* bytes, int options,
|
|
78
74
|
VALUE klass, bool freeze);
|
79
75
|
|
80
76
|
// Recursively freeze message
|
81
|
-
VALUE
|
77
|
+
VALUE Message_freeze(VALUE _self);
|
82
78
|
|
83
79
|
// Call at startup to register all types in this module.
|
84
80
|
void Message_register(VALUE protobuf);
|
@@ -7,8 +7,6 @@
|
|
7
7
|
|
8
8
|
#include "protobuf.h"
|
9
9
|
|
10
|
-
#include <ruby/version.h>
|
11
|
-
|
12
10
|
#include "defs.h"
|
13
11
|
#include "map.h"
|
14
12
|
#include "message.h"
|
@@ -164,16 +162,28 @@ static void Arena_free(void *data) {
|
|
164
162
|
xfree(arena);
|
165
163
|
}
|
166
164
|
|
165
|
+
static size_t Arena_memsize(const void *data) {
|
166
|
+
const Arena *arena = data;
|
167
|
+
size_t fused_count;
|
168
|
+
size_t memsize = upb_Arena_SpaceAllocated(arena->arena, &fused_count);
|
169
|
+
if (fused_count > 1) {
|
170
|
+
// If other arena were fused we attribute an equal
|
171
|
+
// share of memory usage to each one.
|
172
|
+
memsize /= fused_count;
|
173
|
+
}
|
174
|
+
return memsize + sizeof(Arena);
|
175
|
+
}
|
176
|
+
|
167
177
|
static VALUE cArena;
|
168
178
|
|
169
179
|
const rb_data_type_t Arena_type = {
|
170
180
|
"Google::Protobuf::Internal::Arena",
|
171
|
-
{Arena_mark, Arena_free,
|
181
|
+
{Arena_mark, Arena_free, Arena_memsize},
|
172
182
|
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
173
183
|
};
|
174
184
|
|
175
185
|
static void *ruby_upb_allocfunc(upb_alloc *alloc, void *ptr, size_t oldsize,
|
176
|
-
size_t size) {
|
186
|
+
size_t size, size_t *actual_size) {
|
177
187
|
if (size == 0) {
|
178
188
|
xfree(ptr);
|
179
189
|
return NULL;
|
@@ -209,15 +219,6 @@ void Arena_fuse(VALUE _arena, upb_Arena *other) {
|
|
209
219
|
|
210
220
|
VALUE Arena_new() { return Arena_alloc(cArena); }
|
211
221
|
|
212
|
-
void Arena_Pin(VALUE _arena, VALUE obj) {
|
213
|
-
Arena *arena;
|
214
|
-
TypedData_Get_Struct(_arena, Arena, &Arena_type, arena);
|
215
|
-
if (arena->pinned_objs == Qnil) {
|
216
|
-
RB_OBJ_WRITE(_arena, &arena->pinned_objs, rb_ary_new());
|
217
|
-
}
|
218
|
-
rb_ary_push(arena->pinned_objs, obj);
|
219
|
-
}
|
220
|
-
|
221
222
|
void Arena_register(VALUE module) {
|
222
223
|
VALUE internal = rb_define_module_under(module, "Internal");
|
223
224
|
VALUE klass = rb_define_class_under(internal, "Arena", rb_cObject);
|
@@ -241,16 +242,17 @@ static void ObjectCache_Init(VALUE protobuf) {
|
|
241
242
|
item_try_add = rb_intern("try_add");
|
242
243
|
|
243
244
|
rb_gc_register_address(&weak_obj_cache);
|
245
|
+
VALUE internal = rb_const_get(protobuf, rb_intern("Internal"));
|
244
246
|
#if SIZEOF_LONG >= SIZEOF_VALUE
|
245
|
-
VALUE cache_class = rb_const_get(
|
247
|
+
VALUE cache_class = rb_const_get(internal, rb_intern("ObjectCache"));
|
246
248
|
#else
|
247
|
-
VALUE cache_class = rb_const_get(
|
249
|
+
VALUE cache_class = rb_const_get(internal, rb_intern("LegacyObjectCache"));
|
248
250
|
#endif
|
249
251
|
|
250
252
|
weak_obj_cache = rb_class_new_instance(0, NULL, cache_class);
|
251
|
-
rb_const_set(
|
252
|
-
rb_const_set(
|
253
|
-
rb_const_set(
|
253
|
+
rb_const_set(internal, rb_intern("OBJECT_CACHE"), weak_obj_cache);
|
254
|
+
rb_const_set(internal, rb_intern("SIZEOF_LONG"), INT2NUM(SIZEOF_LONG));
|
255
|
+
rb_const_set(internal, rb_intern("SIZEOF_VALUE"), INT2NUM(SIZEOF_VALUE));
|
254
256
|
}
|
255
257
|
|
256
258
|
static VALUE ObjectCache_GetKey(const void *key) {
|
@@ -284,7 +286,8 @@ VALUE ObjectCache_Get(const void *key) {
|
|
284
286
|
static VALUE Google_Protobuf_discard_unknown(VALUE self, VALUE msg_rb) {
|
285
287
|
const upb_MessageDef *m;
|
286
288
|
upb_Message *msg = Message_GetMutable(msg_rb, &m);
|
287
|
-
|
289
|
+
const upb_DefPool* ext_pool = upb_FileDef_Pool(upb_MessageDef_File(m));
|
290
|
+
if (!upb_Message_DiscardUnknown(msg, m, ext_pool, 128)) {
|
288
291
|
rb_raise(rb_eRuntimeError, "Messages nested too deeply.");
|
289
292
|
}
|
290
293
|
|
@@ -341,3 +344,14 @@ __attribute__((visibility("default"))) void Init_protobuf_c() {
|
|
341
344
|
rb_define_singleton_method(protobuf, "deep_copy", Google_Protobuf_deep_copy,
|
342
345
|
1);
|
343
346
|
}
|
347
|
+
|
348
|
+
// -----------------------------------------------------------------------------
|
349
|
+
// Utilities
|
350
|
+
// -----------------------------------------------------------------------------
|
351
|
+
|
352
|
+
// Raises a Ruby error if val is frozen in Ruby or UPB.
|
353
|
+
void Protobuf_CheckNotFrozen(VALUE val, bool upb_frozen) {
|
354
|
+
if (RB_UNLIKELY(rb_obj_frozen_p(val)||upb_frozen)) {
|
355
|
+
rb_error_frozen_object(val);
|
356
|
+
}
|
357
|
+
}
|
@@ -16,12 +16,6 @@
|
|
16
16
|
#undef NDEBUG
|
17
17
|
#endif
|
18
18
|
|
19
|
-
#include <ruby/version.h>
|
20
|
-
|
21
|
-
#if RUBY_API_VERSION_CODE < 20700
|
22
|
-
#error Protobuf requires Ruby >= 2.7
|
23
|
-
#endif
|
24
|
-
|
25
19
|
#include <assert.h> // Must be included after the NDEBUG logic above.
|
26
20
|
#include <ruby/encoding.h>
|
27
21
|
#include <ruby/vm.h>
|
@@ -50,13 +44,6 @@ upb_Arena* Arena_get(VALUE arena);
|
|
50
44
|
// possible.
|
51
45
|
void Arena_fuse(VALUE arena, upb_Arena* other);
|
52
46
|
|
53
|
-
// Pins this Ruby object to the lifetime of this arena, so that as long as the
|
54
|
-
// arena is alive this object will not be collected.
|
55
|
-
//
|
56
|
-
// We use this to guarantee that the "frozen" bit on the object will be
|
57
|
-
// remembered, even if the user drops their reference to this precise object.
|
58
|
-
void Arena_Pin(VALUE arena, VALUE obj);
|
59
|
-
|
60
47
|
// -----------------------------------------------------------------------------
|
61
48
|
// ObjectCache
|
62
49
|
// -----------------------------------------------------------------------------
|
@@ -105,8 +92,9 @@ extern VALUE cTypeError;
|
|
105
92
|
rb_bug("Assertion failed at %s:%d, expr: %s", __FILE__, __LINE__, #expr)
|
106
93
|
#endif
|
107
94
|
|
108
|
-
|
95
|
+
// Raises a Ruby error if val is frozen in Ruby or upb_frozen is true.
|
96
|
+
void Protobuf_CheckNotFrozen(VALUE val, bool upb_frozen);
|
109
97
|
|
110
|
-
#define
|
98
|
+
#define PBRUBY_MAX(x, y) (((x) > (y)) ? (x) : (y))
|
111
99
|
|
112
100
|
#endif // __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__
|
@@ -44,8 +44,9 @@ static RepeatedField* ruby_to_RepeatedField(VALUE _self) {
|
|
44
44
|
}
|
45
45
|
|
46
46
|
static upb_Array* RepeatedField_GetMutable(VALUE _self) {
|
47
|
-
|
48
|
-
|
47
|
+
const upb_Array* array = ruby_to_RepeatedField(_self)->array;
|
48
|
+
Protobuf_CheckNotFrozen(_self, upb_Array_IsFrozen(array));
|
49
|
+
return (upb_Array*)array;
|
49
50
|
}
|
50
51
|
|
51
52
|
VALUE RepeatedField_alloc(VALUE klass) {
|
@@ -56,9 +57,32 @@ VALUE RepeatedField_alloc(VALUE klass) {
|
|
56
57
|
return TypedData_Wrap_Struct(klass, &RepeatedField_type, self);
|
57
58
|
}
|
58
59
|
|
59
|
-
VALUE
|
60
|
+
VALUE RepeatedField_EmptyFrozen(const upb_FieldDef* f) {
|
61
|
+
PBRUBY_ASSERT(upb_FieldDef_IsRepeated(f));
|
62
|
+
VALUE val = ObjectCache_Get(f);
|
63
|
+
|
64
|
+
if (val == Qnil) {
|
65
|
+
val = RepeatedField_alloc(cRepeatedField);
|
66
|
+
RepeatedField* self;
|
67
|
+
TypedData_Get_Struct(val, RepeatedField, &RepeatedField_type, self);
|
68
|
+
self->arena = Arena_new();
|
69
|
+
TypeInfo type_info = TypeInfo_get(f);
|
70
|
+
self->array = upb_Array_New(Arena_get(self->arena), type_info.type);
|
71
|
+
self->type_info = type_info;
|
72
|
+
if (self->type_info.type == kUpb_CType_Message) {
|
73
|
+
self->type_class = Descriptor_DefToClass(type_info.def.msgdef);
|
74
|
+
}
|
75
|
+
val = ObjectCache_TryAdd(f, RepeatedField_freeze(val));
|
76
|
+
}
|
77
|
+
PBRUBY_ASSERT(RB_OBJ_FROZEN(val));
|
78
|
+
PBRUBY_ASSERT(upb_Array_IsFrozen(ruby_to_RepeatedField(val)->array));
|
79
|
+
return val;
|
80
|
+
}
|
81
|
+
|
82
|
+
VALUE RepeatedField_GetRubyWrapper(const upb_Array* array, TypeInfo type_info,
|
60
83
|
VALUE arena) {
|
61
84
|
PBRUBY_ASSERT(array);
|
85
|
+
PBRUBY_ASSERT(arena != Qnil);
|
62
86
|
VALUE val = ObjectCache_Get(array);
|
63
87
|
|
64
88
|
if (val == Qnil) {
|
@@ -78,7 +102,6 @@ VALUE RepeatedField_GetRubyWrapper(upb_Array* array, TypeInfo type_info,
|
|
78
102
|
PBRUBY_ASSERT(ruby_to_RepeatedField(val)->type_info.def.msgdef ==
|
79
103
|
type_info.def.msgdef);
|
80
104
|
PBRUBY_ASSERT(ruby_to_RepeatedField(val)->array == array);
|
81
|
-
|
82
105
|
return val;
|
83
106
|
}
|
84
107
|
|
@@ -169,13 +192,20 @@ static VALUE RepeatedField_subarray(RepeatedField* self, long beg, long len) {
|
|
169
192
|
return ary;
|
170
193
|
}
|
171
194
|
|
195
|
+
/**
|
196
|
+
* ruby-doc: RepeatedField
|
197
|
+
*
|
198
|
+
*/
|
199
|
+
|
172
200
|
/*
|
173
|
-
*
|
174
|
-
* RepeatedField.each(&block)
|
201
|
+
* ruby-doc: RepeatedField#each
|
175
202
|
*
|
176
203
|
* Invokes the block once for each element of the repeated field. RepeatedField
|
177
204
|
* also includes Enumerable; combined with this method, the repeated field thus
|
178
205
|
* acts like an ordinary Ruby sequence.
|
206
|
+
*
|
207
|
+
* @yield [Object]
|
208
|
+
* @return [self]
|
179
209
|
*/
|
180
210
|
static VALUE RepeatedField_each(VALUE _self) {
|
181
211
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
@@ -191,10 +221,12 @@ static VALUE RepeatedField_each(VALUE _self) {
|
|
191
221
|
}
|
192
222
|
|
193
223
|
/*
|
194
|
-
*
|
195
|
-
* RepeatedField.[](index) => value
|
224
|
+
* ruby-doc: RepeatedField#[]
|
196
225
|
*
|
197
226
|
* Accesses the element at the given index. Returns nil on out-of-bounds
|
227
|
+
*
|
228
|
+
* @param index [Integer]
|
229
|
+
* @return [Object,nil]
|
198
230
|
*/
|
199
231
|
static VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self) {
|
200
232
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
@@ -239,11 +271,14 @@ static VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self) {
|
|
239
271
|
}
|
240
272
|
|
241
273
|
/*
|
242
|
-
*
|
243
|
-
* RepeatedField.[]=(index, value)
|
274
|
+
* ruby-doc: RepeatedField#[]=
|
244
275
|
*
|
245
276
|
* Sets the element at the given index. On out-of-bounds assignments, extends
|
246
277
|
* the array and fills the hole (if any) with default values.
|
278
|
+
*
|
279
|
+
* @param index [Integer]
|
280
|
+
* @param value [Object
|
281
|
+
* @return [nil]
|
247
282
|
*/
|
248
283
|
static VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val) {
|
249
284
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
@@ -273,10 +308,12 @@ static VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val) {
|
|
273
308
|
}
|
274
309
|
|
275
310
|
/*
|
276
|
-
*
|
277
|
-
* RepeatedField.push(value, ...)
|
311
|
+
* ruby-doc: RepeatedField#push
|
278
312
|
*
|
279
313
|
* Adds a new element to the repeated field.
|
314
|
+
*
|
315
|
+
* @param value [Object]
|
316
|
+
* @return [self]
|
280
317
|
*/
|
281
318
|
static VALUE RepeatedField_push_vararg(int argc, VALUE* argv, VALUE _self) {
|
282
319
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
@@ -294,10 +331,12 @@ static VALUE RepeatedField_push_vararg(int argc, VALUE* argv, VALUE _self) {
|
|
294
331
|
}
|
295
332
|
|
296
333
|
/*
|
297
|
-
*
|
298
|
-
* RepeatedField.<<(value)
|
334
|
+
* ruby-doc: RepeatedField#<<
|
299
335
|
*
|
300
336
|
* Adds a new element to the repeated field.
|
337
|
+
*
|
338
|
+
* @param value [Object]
|
339
|
+
* @return [self]
|
301
340
|
*/
|
302
341
|
static VALUE RepeatedField_push(VALUE _self, VALUE val) {
|
303
342
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
@@ -332,10 +371,12 @@ static VALUE RepeatedField_pop_one(VALUE _self) {
|
|
332
371
|
}
|
333
372
|
|
334
373
|
/*
|
335
|
-
*
|
336
|
-
* RepeatedField.replace(list)
|
374
|
+
* ruby-doc: RepeatedField#replace
|
337
375
|
*
|
338
376
|
* Replaces the contents of the repeated field with the given list of elements.
|
377
|
+
*
|
378
|
+
* @param list [Array]
|
379
|
+
* @return [Array]
|
339
380
|
*/
|
340
381
|
static VALUE RepeatedField_replace(VALUE _self, VALUE list) {
|
341
382
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
@@ -353,10 +394,11 @@ static VALUE RepeatedField_replace(VALUE _self, VALUE list) {
|
|
353
394
|
}
|
354
395
|
|
355
396
|
/*
|
356
|
-
*
|
357
|
-
* RepeatedField.clear
|
397
|
+
* ruby-doc: RepeatedField#clear
|
358
398
|
*
|
359
399
|
* Clears (removes all elements from) this repeated field.
|
400
|
+
*
|
401
|
+
* @return [self]
|
360
402
|
*/
|
361
403
|
static VALUE RepeatedField_clear(VALUE _self) {
|
362
404
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
@@ -366,10 +408,11 @@ static VALUE RepeatedField_clear(VALUE _self) {
|
|
366
408
|
}
|
367
409
|
|
368
410
|
/*
|
369
|
-
*
|
370
|
-
* RepeatedField.length
|
411
|
+
* ruby-doc: RepeatedField#length
|
371
412
|
*
|
372
413
|
* Returns the length of this repeated field.
|
414
|
+
*
|
415
|
+
* @return [Integer]
|
373
416
|
*/
|
374
417
|
static VALUE RepeatedField_length(VALUE _self) {
|
375
418
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
@@ -377,11 +420,12 @@ static VALUE RepeatedField_length(VALUE _self) {
|
|
377
420
|
}
|
378
421
|
|
379
422
|
/*
|
380
|
-
*
|
381
|
-
* RepeatedField.dup => repeated_field
|
423
|
+
* ruby-doc: RepeatedField#dup
|
382
424
|
*
|
383
425
|
* Duplicates this repeated field with a shallow copy. References to all
|
384
426
|
* non-primitive element objects (e.g., submessages) are shared.
|
427
|
+
*
|
428
|
+
* @return [RepeatedField]
|
385
429
|
*/
|
386
430
|
static VALUE RepeatedField_dup(VALUE _self) {
|
387
431
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
@@ -403,11 +447,12 @@ static VALUE RepeatedField_dup(VALUE _self) {
|
|
403
447
|
}
|
404
448
|
|
405
449
|
/*
|
406
|
-
*
|
407
|
-
* RepeatedField.to_ary => array
|
450
|
+
* ruby-doc: RepeatedField#to_ary
|
408
451
|
*
|
409
452
|
* Used when converted implicitly into array, e.g. compared to an Array.
|
410
453
|
* Also called as a fallback of Object#to_a
|
454
|
+
*
|
455
|
+
* @return [Array]
|
411
456
|
*/
|
412
457
|
VALUE RepeatedField_to_ary(VALUE _self) {
|
413
458
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
@@ -425,8 +470,7 @@ VALUE RepeatedField_to_ary(VALUE _self) {
|
|
425
470
|
}
|
426
471
|
|
427
472
|
/*
|
428
|
-
*
|
429
|
-
* RepeatedField.==(other) => boolean
|
473
|
+
* ruby-doc: RepeatedField#==
|
430
474
|
*
|
431
475
|
* Compares this repeated field to another. Repeated fields are equal if their
|
432
476
|
* element types are equal, their lengths are equal, and each element is equal.
|
@@ -436,6 +480,9 @@ VALUE RepeatedField_to_ary(VALUE _self) {
|
|
436
480
|
* Repeated fields with dissimilar element types are never equal, even if value
|
437
481
|
* comparison (for example, between integers and floats) would have otherwise
|
438
482
|
* indicated that every element has equal value.
|
483
|
+
*
|
484
|
+
* @param other [RepeatedField]
|
485
|
+
* @return [Boolean]
|
439
486
|
*/
|
440
487
|
VALUE RepeatedField_eq(VALUE _self, VALUE _other) {
|
441
488
|
RepeatedField* self;
|
@@ -472,45 +519,59 @@ VALUE RepeatedField_eq(VALUE _self, VALUE _other) {
|
|
472
519
|
}
|
473
520
|
|
474
521
|
/*
|
475
|
-
*
|
476
|
-
*
|
522
|
+
* ruby-doc: RepeatedField#frozen?
|
523
|
+
*
|
524
|
+
* Returns true if the repeated field is frozen in either Ruby or the underlying
|
525
|
+
* representation. Freezes the Ruby repeated field object if it is not already
|
526
|
+
* frozen in Ruby but it is frozen in the underlying representation.
|
477
527
|
*
|
478
|
-
*
|
479
|
-
* object into memory so we don't forget it's frozen.
|
528
|
+
* @return [Boolean]
|
480
529
|
*/
|
481
|
-
|
530
|
+
VALUE RepeatedField_frozen(VALUE _self) {
|
482
531
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
483
|
-
if (!
|
484
|
-
|
485
|
-
|
532
|
+
if (!upb_Array_IsFrozen(self->array)) {
|
533
|
+
PBRUBY_ASSERT(!RB_OBJ_FROZEN(_self));
|
534
|
+
return Qfalse;
|
486
535
|
}
|
487
|
-
|
536
|
+
|
537
|
+
// Lazily freeze the Ruby wrapper.
|
538
|
+
if (!RB_OBJ_FROZEN(_self)) RB_OBJ_FREEZE(_self);
|
539
|
+
return Qtrue;
|
488
540
|
}
|
489
541
|
|
490
542
|
/*
|
491
|
-
*
|
492
|
-
*
|
543
|
+
* ruby-doc: RepeatedField#freeze
|
544
|
+
*
|
545
|
+
* Freezes the repeated field object. We have to intercept this so we can freeze
|
546
|
+
* the underlying representation, not just the Ruby wrapper.
|
547
|
+
*
|
548
|
+
* @return [self]
|
493
549
|
*/
|
494
|
-
VALUE
|
550
|
+
VALUE RepeatedField_freeze(VALUE _self) {
|
495
551
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
552
|
+
if (RB_OBJ_FROZEN(_self)) {
|
553
|
+
PBRUBY_ASSERT(upb_Array_IsFrozen(self->array));
|
554
|
+
return _self;
|
555
|
+
}
|
556
|
+
|
557
|
+
if (!upb_Array_IsFrozen(self->array)) {
|
558
|
+
if (self->type_info.type == kUpb_CType_Message) {
|
559
|
+
upb_Array_Freeze(RepeatedField_GetMutable(_self),
|
560
|
+
upb_MessageDef_MiniTable(self->type_info.def.msgdef));
|
561
|
+
} else {
|
562
|
+
upb_Array_Freeze(RepeatedField_GetMutable(_self), NULL);
|
504
563
|
}
|
505
564
|
}
|
565
|
+
RB_OBJ_FREEZE(_self);
|
506
566
|
return _self;
|
507
567
|
}
|
508
568
|
|
509
569
|
/*
|
510
|
-
*
|
511
|
-
* RepeatedField.hash => hash_value
|
570
|
+
* ruby-doc: RepeatedField#hash
|
512
571
|
*
|
513
572
|
* Returns a hash value computed from this repeated field's elements.
|
573
|
+
*
|
574
|
+
* @return [Integer]
|
514
575
|
*/
|
515
576
|
VALUE RepeatedField_hash(VALUE _self) {
|
516
577
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
@@ -526,12 +587,14 @@ VALUE RepeatedField_hash(VALUE _self) {
|
|
526
587
|
}
|
527
588
|
|
528
589
|
/*
|
529
|
-
*
|
530
|
-
* RepeatedField.+(other) => repeated field
|
590
|
+
* ruby-doc: RepeatedField#+
|
531
591
|
*
|
532
592
|
* Returns a new repeated field that contains the concatenated list of this
|
533
593
|
* repeated field's elements and other's elements. The other (second) list may
|
534
594
|
* be either another repeated field or a Ruby array.
|
595
|
+
*
|
596
|
+
* @param other [Array,RepeatedField]
|
597
|
+
* @return [RepeatedField]
|
535
598
|
*/
|
536
599
|
VALUE RepeatedField_plus(VALUE _self, VALUE list) {
|
537
600
|
VALUE dupped_ = RepeatedField_dup(_self);
|
@@ -571,10 +634,12 @@ VALUE RepeatedField_plus(VALUE _self, VALUE list) {
|
|
571
634
|
}
|
572
635
|
|
573
636
|
/*
|
574
|
-
*
|
575
|
-
* RepeatedField.concat(other) => self
|
637
|
+
* ruby-doc: RepeatedField#concat
|
576
638
|
*
|
577
639
|
* concats the passed in array to self. Returns a Ruby array.
|
640
|
+
*
|
641
|
+
* @param other [RepeatedField]
|
642
|
+
* @return [Array]
|
578
643
|
*/
|
579
644
|
VALUE RepeatedField_concat(VALUE _self, VALUE list) {
|
580
645
|
int i;
|
@@ -587,15 +652,21 @@ VALUE RepeatedField_concat(VALUE _self, VALUE list) {
|
|
587
652
|
}
|
588
653
|
|
589
654
|
/*
|
590
|
-
*
|
591
|
-
* RepeatedField.new(type, type_class = nil, initial_elems = [])
|
655
|
+
* ruby-doc: RepeatedField#initialize
|
592
656
|
*
|
593
657
|
* Creates a new repeated field. The provided type must be a Ruby symbol, and
|
594
|
-
* can take on the same values as those accepted by FieldDescriptor#type
|
658
|
+
* can take on the same values as those accepted by {FieldDescriptor#type=}. If
|
595
659
|
* the type is :message or :enum, type_class must be non-nil, and must be the
|
596
|
-
* Ruby class or module returned by Descriptor#msgclass or
|
597
|
-
* EnumDescriptor#enummodule, respectively. An initial list of elements may
|
598
|
-
* be provided.
|
660
|
+
* Ruby class or module returned by {Descriptor#msgclass} or
|
661
|
+
* {EnumDescriptor#enummodule}, respectively. An initial list of elements may
|
662
|
+
* also be provided.
|
663
|
+
*
|
664
|
+
* @param type [Symbol]
|
665
|
+
* @param type_class [Class<AbstractMessage>, Module]
|
666
|
+
* @paramdefault type_class nil
|
667
|
+
* @param initial_elems [Array]
|
668
|
+
* @paramdefault initial_elems []
|
669
|
+
* @return [RepeatedField]
|
599
670
|
*/
|
600
671
|
VALUE RepeatedField_init(int argc, VALUE* argv, VALUE _self) {
|
601
672
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
@@ -649,6 +720,7 @@ void RepeatedField_register(VALUE module) {
|
|
649
720
|
rb_define_method(klass, "==", RepeatedField_eq, 1);
|
650
721
|
rb_define_method(klass, "to_ary", RepeatedField_to_ary, 0);
|
651
722
|
rb_define_method(klass, "freeze", RepeatedField_freeze, 0);
|
723
|
+
rb_define_method(klass, "frozen?", RepeatedField_frozen, 0);
|
652
724
|
rb_define_method(klass, "hash", RepeatedField_hash, 0);
|
653
725
|
rb_define_method(klass, "+", RepeatedField_plus, 1);
|
654
726
|
rb_define_method(klass, "concat", RepeatedField_concat, 1);
|
@@ -11,9 +11,13 @@
|
|
11
11
|
#include "protobuf.h"
|
12
12
|
#include "ruby-upb.h"
|
13
13
|
|
14
|
+
// Returns a frozen sentinel Ruby wrapper object for an empty upb_Array of the
|
15
|
+
// type specified by the field. Creates one if it doesn't exist.
|
16
|
+
VALUE RepeatedField_EmptyFrozen(const upb_FieldDef* f);
|
17
|
+
|
14
18
|
// Returns a Ruby wrapper object for the given upb_Array, which will be created
|
15
19
|
// if one does not exist already.
|
16
|
-
VALUE RepeatedField_GetRubyWrapper(upb_Array* msg, TypeInfo type_info,
|
20
|
+
VALUE RepeatedField_GetRubyWrapper(const upb_Array* msg, TypeInfo type_info,
|
17
21
|
VALUE arena);
|
18
22
|
|
19
23
|
// Gets the underlying upb_Array for this Ruby RepeatedField object, which must
|
@@ -36,6 +40,6 @@ extern VALUE cRepeatedField;
|
|
36
40
|
void RepeatedField_register(VALUE module);
|
37
41
|
|
38
42
|
// Recursively freeze RepeatedField.
|
39
|
-
VALUE
|
43
|
+
VALUE RepeatedField_freeze(VALUE _self);
|
40
44
|
|
41
45
|
#endif // RUBY_PROTOBUF_REPEATED_FIELD_H_
|