google-protobuf 3.14.0 → 4.26.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/ext/google/protobuf_c/Rakefile +3 -0
  3. data/ext/google/protobuf_c/convert.c +317 -0
  4. data/ext/google/protobuf_c/convert.h +50 -0
  5. data/ext/google/protobuf_c/defs.c +759 -1709
  6. data/ext/google/protobuf_c/defs.h +82 -0
  7. data/ext/google/protobuf_c/extconf.rb +15 -8
  8. data/ext/google/protobuf_c/glue.c +56 -0
  9. data/ext/google/protobuf_c/map.c +328 -485
  10. data/ext/google/protobuf_c/map.h +44 -0
  11. data/ext/google/protobuf_c/message.c +1061 -530
  12. data/ext/google/protobuf_c/message.h +86 -0
  13. data/ext/google/protobuf_c/protobuf.c +314 -94
  14. data/ext/google/protobuf_c/protobuf.h +66 -621
  15. data/ext/google/protobuf_c/repeated_field.c +314 -353
  16. data/ext/google/protobuf_c/repeated_field.h +41 -0
  17. data/ext/google/protobuf_c/ruby-upb.c +15407 -0
  18. data/ext/google/protobuf_c/ruby-upb.h +13966 -0
  19. data/ext/google/protobuf_c/shared_convert.c +66 -0
  20. data/ext/google/protobuf_c/shared_convert.h +26 -0
  21. data/ext/google/protobuf_c/shared_message.c +67 -0
  22. data/ext/google/protobuf_c/shared_message.h +25 -0
  23. data/ext/google/protobuf_c/third_party/utf8_range/LICENSE +22 -0
  24. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.c +467 -0
  25. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +22 -0
  26. data/ext/google/protobuf_c/wrap_memcpy.c +7 -29
  27. data/lib/google/protobuf/any_pb.rb +6 -8
  28. data/lib/google/protobuf/api_pb.rb +7 -26
  29. data/lib/google/protobuf/descriptor_pb.rb +65 -0
  30. data/lib/google/protobuf/duration_pb.rb +6 -8
  31. data/lib/google/protobuf/empty_pb.rb +6 -6
  32. data/lib/google/protobuf/ffi/descriptor.rb +164 -0
  33. data/lib/google/protobuf/ffi/descriptor_pool.rb +75 -0
  34. data/lib/google/protobuf/ffi/enum_descriptor.rb +171 -0
  35. data/lib/google/protobuf/ffi/ffi.rb +215 -0
  36. data/lib/google/protobuf/ffi/field_descriptor.rb +328 -0
  37. data/lib/google/protobuf/ffi/file_descriptor.rb +47 -0
  38. data/lib/google/protobuf/ffi/internal/arena.rb +66 -0
  39. data/lib/google/protobuf/ffi/internal/convert.rb +289 -0
  40. data/lib/google/protobuf/ffi/internal/pointer_helper.rb +35 -0
  41. data/lib/google/protobuf/ffi/internal/type_safety.rb +25 -0
  42. data/lib/google/protobuf/ffi/map.rb +409 -0
  43. data/lib/google/protobuf/ffi/message.rb +659 -0
  44. data/lib/google/protobuf/ffi/object_cache.rb +30 -0
  45. data/lib/google/protobuf/ffi/oneof_descriptor.rb +95 -0
  46. data/lib/google/protobuf/ffi/repeated_field.rb +385 -0
  47. data/lib/google/protobuf/field_mask_pb.rb +6 -7
  48. data/lib/google/protobuf/internal/object_cache.rb +99 -0
  49. data/lib/google/protobuf/message_exts.rb +10 -28
  50. data/lib/google/protobuf/plugin_pb.rb +25 -0
  51. data/lib/google/protobuf/repeated_field.rb +19 -30
  52. data/lib/google/protobuf/source_context_pb.rb +6 -7
  53. data/lib/google/protobuf/struct_pb.rb +6 -23
  54. data/lib/google/protobuf/timestamp_pb.rb +6 -8
  55. data/lib/google/protobuf/type_pb.rb +7 -71
  56. data/lib/google/protobuf/well_known_types.rb +17 -36
  57. data/lib/google/protobuf/wrappers_pb.rb +6 -31
  58. data/lib/google/protobuf.rb +32 -118
  59. data/lib/google/protobuf_ffi.rb +49 -0
  60. data/lib/google/protobuf_native.rb +19 -0
  61. data/lib/google/tasks/ffi.rake +100 -0
  62. metadata +88 -37
  63. data/ext/google/protobuf_c/encode_decode.c +0 -1795
  64. data/ext/google/protobuf_c/storage.c +0 -1198
  65. data/ext/google/protobuf_c/upb.c +0 -13817
  66. data/ext/google/protobuf_c/upb.h +0 -6777
  67. data/tests/basic.rb +0 -543
  68. data/tests/generated_code_test.rb +0 -23
  69. data/tests/stress.rb +0 -38
@@ -1,76 +1,169 @@
1
1
  // Protocol Buffers - Google's data interchange format
2
2
  // Copyright 2014 Google Inc. All rights reserved.
3
- // https://developers.google.com/protocol-buffers/
4
3
  //
5
- // Redistribution and use in source and binary forms, with or without
6
- // modification, are permitted provided that the following conditions are
7
- // met:
8
- //
9
- // * Redistributions of source code must retain the above copyright
10
- // notice, this list of conditions and the following disclaimer.
11
- // * Redistributions in binary form must reproduce the above
12
- // copyright notice, this list of conditions and the following disclaimer
13
- // in the documentation and/or other materials provided with the
14
- // distribution.
15
- // * Neither the name of Google Inc. nor the names of its
16
- // contributors may be used to endorse or promote products derived from
17
- // this software without specific prior written permission.
18
- //
19
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
- // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
- // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
- // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
- // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
- // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
- // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
- // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
- // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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 "repeated_field.h"
30
9
 
10
+ #include "convert.h"
11
+ #include "defs.h"
12
+ #include "message.h"
31
13
  #include "protobuf.h"
32
14
 
33
15
  // -----------------------------------------------------------------------------
34
16
  // Repeated field container type.
35
17
  // -----------------------------------------------------------------------------
36
18
 
37
- const rb_data_type_t RepeatedField_type = {
38
- "Google::Protobuf::RepeatedField",
39
- { RepeatedField_mark, RepeatedField_free, NULL },
40
- };
19
+ typedef struct {
20
+ const upb_Array* array; // Can get as mutable when non-frozen.
21
+ TypeInfo type_info;
22
+ VALUE type_class; // To GC-root the msgdef/enumdef in type_info.
23
+ VALUE arena; // To GC-root the upb_Array.
24
+ } RepeatedField;
41
25
 
42
26
  VALUE cRepeatedField;
43
27
 
44
- RepeatedField* ruby_to_RepeatedField(VALUE _self) {
28
+ static void RepeatedField_mark(void* _self) {
29
+ RepeatedField* self = (RepeatedField*)_self;
30
+ rb_gc_mark(self->type_class);
31
+ rb_gc_mark(self->arena);
32
+ }
33
+
34
+ const rb_data_type_t RepeatedField_type = {
35
+ "Google::Protobuf::RepeatedField",
36
+ {RepeatedField_mark, RUBY_DEFAULT_FREE, NULL},
37
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
38
+ };
39
+
40
+ static RepeatedField* ruby_to_RepeatedField(VALUE _self) {
45
41
  RepeatedField* self;
46
42
  TypedData_Get_Struct(_self, RepeatedField, &RepeatedField_type, self);
47
43
  return self;
48
44
  }
49
45
 
50
- void* RepeatedField_memoryat(RepeatedField* self, int index, int element_size) {
51
- return ((uint8_t *)self->elements) + index * element_size;
46
+ static upb_Array* RepeatedField_GetMutable(VALUE _self) {
47
+ rb_check_frozen(_self);
48
+ return (upb_Array*)ruby_to_RepeatedField(_self)->array;
49
+ }
50
+
51
+ VALUE RepeatedField_alloc(VALUE klass) {
52
+ RepeatedField* self = ALLOC(RepeatedField);
53
+ self->arena = Qnil;
54
+ self->type_class = Qnil;
55
+ self->array = NULL;
56
+ return TypedData_Wrap_Struct(klass, &RepeatedField_type, self);
57
+ }
58
+
59
+ VALUE RepeatedField_GetRubyWrapper(upb_Array* array, TypeInfo type_info,
60
+ VALUE arena) {
61
+ PBRUBY_ASSERT(array);
62
+ VALUE val = ObjectCache_Get(array);
63
+
64
+ if (val == Qnil) {
65
+ val = RepeatedField_alloc(cRepeatedField);
66
+ RepeatedField* self;
67
+ TypedData_Get_Struct(val, RepeatedField, &RepeatedField_type, self);
68
+ self->array = array;
69
+ self->arena = arena;
70
+ self->type_info = type_info;
71
+ if (self->type_info.type == kUpb_CType_Message) {
72
+ self->type_class = Descriptor_DefToClass(type_info.def.msgdef);
73
+ }
74
+ val = ObjectCache_TryAdd(array, val);
75
+ }
76
+
77
+ PBRUBY_ASSERT(ruby_to_RepeatedField(val)->type_info.type == type_info.type);
78
+ PBRUBY_ASSERT(ruby_to_RepeatedField(val)->type_info.def.msgdef ==
79
+ type_info.def.msgdef);
80
+ PBRUBY_ASSERT(ruby_to_RepeatedField(val)->array == array);
81
+
82
+ return val;
83
+ }
84
+
85
+ static VALUE RepeatedField_new_this_type(RepeatedField* from) {
86
+ VALUE arena_rb = Arena_new();
87
+ upb_Array* array = upb_Array_New(Arena_get(arena_rb), from->type_info.type);
88
+ VALUE ret = RepeatedField_GetRubyWrapper(array, from->type_info, arena_rb);
89
+ PBRUBY_ASSERT(ruby_to_RepeatedField(ret)->type_class == from->type_class);
90
+ return ret;
91
+ }
92
+
93
+ void RepeatedField_Inspect(StringBuilder* b, const upb_Array* array,
94
+ TypeInfo info) {
95
+ bool first = true;
96
+ StringBuilder_Printf(b, "[");
97
+ size_t n = array ? upb_Array_Size(array) : 0;
98
+ for (size_t i = 0; i < n; i++) {
99
+ if (first) {
100
+ first = false;
101
+ } else {
102
+ StringBuilder_Printf(b, ", ");
103
+ }
104
+ StringBuilder_PrintMsgval(b, upb_Array_Get(array, i), info);
105
+ }
106
+ StringBuilder_Printf(b, "]");
107
+ }
108
+
109
+ VALUE RepeatedField_deep_copy(VALUE _self) {
110
+ RepeatedField* self = ruby_to_RepeatedField(_self);
111
+ VALUE new_rptfield = RepeatedField_new_this_type(self);
112
+ RepeatedField* new_self = ruby_to_RepeatedField(new_rptfield);
113
+ VALUE arena_rb = new_self->arena;
114
+ upb_Array* new_array = RepeatedField_GetMutable(new_rptfield);
115
+ upb_Arena* arena = Arena_get(arena_rb);
116
+ size_t elements = upb_Array_Size(self->array);
117
+
118
+ upb_Array_Resize(new_array, elements, arena);
119
+
120
+ size_t size = upb_Array_Size(self->array);
121
+ for (size_t i = 0; i < size; i++) {
122
+ upb_MessageValue msgval = upb_Array_Get(self->array, i);
123
+ upb_MessageValue copy = Msgval_DeepCopy(msgval, self->type_info, arena);
124
+ upb_Array_Set(new_array, i, copy);
125
+ }
126
+
127
+ return new_rptfield;
128
+ }
129
+
130
+ const upb_Array* RepeatedField_GetUpbArray(VALUE val, const upb_FieldDef* field,
131
+ upb_Arena* arena) {
132
+ RepeatedField* self;
133
+ TypeInfo type_info = TypeInfo_get(field);
134
+
135
+ if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) ||
136
+ RTYPEDDATA_TYPE(val) != &RepeatedField_type) {
137
+ rb_raise(cTypeError, "Expected repeated field array");
138
+ }
139
+
140
+ self = ruby_to_RepeatedField(val);
141
+ if (self->type_info.type != type_info.type) {
142
+ rb_raise(cTypeError, "Repeated field array has wrong element type");
143
+ }
144
+
145
+ if (self->type_info.def.msgdef != type_info.def.msgdef) {
146
+ rb_raise(cTypeError, "Repeated field array has wrong message/enum class");
147
+ }
148
+
149
+ Arena_fuse(self->arena, arena);
150
+ return self->array;
52
151
  }
53
152
 
54
153
  static int index_position(VALUE _index, RepeatedField* repeated_field) {
55
154
  int index = NUM2INT(_index);
56
- if (index < 0 && repeated_field->size > 0) {
57
- index = repeated_field->size + index;
58
- }
155
+ if (index < 0) index += upb_Array_Size(repeated_field->array);
59
156
  return index;
60
157
  }
61
158
 
62
- VALUE RepeatedField_subarray(VALUE _self, long beg, long len) {
63
- RepeatedField* self = ruby_to_RepeatedField(_self);
64
- int element_size = native_slot_size(self->field_type);
65
- upb_fieldtype_t field_type = self->field_type;
66
- VALUE field_type_class = self->field_type_class;
67
- size_t off = beg * element_size;
68
- VALUE ary = rb_ary_new2(len);
69
- int i;
159
+ static VALUE RepeatedField_subarray(RepeatedField* self, long beg, long len) {
160
+ size_t size = upb_Array_Size(self->array);
161
+ VALUE ary = rb_ary_new2(size);
162
+ long i;
70
163
 
71
- for (i = beg; i < beg + len; i++, off += element_size) {
72
- void* mem = ((uint8_t *)self->elements) + off;
73
- VALUE elem = native_slot_get(field_type, field_type_class, mem);
164
+ for (i = beg; i < beg + len; i++) {
165
+ upb_MessageValue msgval = upb_Array_Get(self->array, i);
166
+ VALUE elem = Convert_UpbToRuby(msgval, self->type_info, self->arena);
74
167
  rb_ary_push(ary, elem);
75
168
  }
76
169
  return ary;
@@ -84,70 +177,65 @@ VALUE RepeatedField_subarray(VALUE _self, long beg, long len) {
84
177
  * also includes Enumerable; combined with this method, the repeated field thus
85
178
  * acts like an ordinary Ruby sequence.
86
179
  */
87
- VALUE RepeatedField_each(VALUE _self) {
180
+ static VALUE RepeatedField_each(VALUE _self) {
88
181
  RepeatedField* self = ruby_to_RepeatedField(_self);
89
- upb_fieldtype_t field_type = self->field_type;
90
- VALUE field_type_class = self->field_type_class;
91
- int element_size = native_slot_size(field_type);
92
- size_t off = 0;
182
+ int size = upb_Array_Size(self->array);
93
183
  int i;
94
184
 
95
- for (i = 0; i < self->size; i++, off += element_size) {
96
- void* memory = (void *) (((uint8_t *)self->elements) + off);
97
- VALUE val = native_slot_get(field_type, field_type_class, memory);
185
+ for (i = 0; i < size; i++) {
186
+ upb_MessageValue msgval = upb_Array_Get(self->array, i);
187
+ VALUE val = Convert_UpbToRuby(msgval, self->type_info, self->arena);
98
188
  rb_yield(val);
99
189
  }
100
190
  return _self;
101
191
  }
102
192
 
103
-
104
193
  /*
105
194
  * call-seq:
106
195
  * RepeatedField.[](index) => value
107
196
  *
108
197
  * Accesses the element at the given index. Returns nil on out-of-bounds
109
198
  */
110
- VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self) {
199
+ static VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self) {
111
200
  RepeatedField* self = ruby_to_RepeatedField(_self);
112
- int element_size = native_slot_size(self->field_type);
113
- upb_fieldtype_t field_type = self->field_type;
114
- VALUE field_type_class = self->field_type_class;
201
+ long size = upb_Array_Size(self->array);
115
202
 
116
203
  VALUE arg = argv[0];
117
204
  long beg, len;
118
205
 
119
- if (argc == 1){
206
+ if (argc == 1) {
120
207
  if (FIXNUM_P(arg)) {
121
208
  /* standard case */
122
- void* memory;
209
+ upb_MessageValue msgval;
123
210
  int index = index_position(argv[0], self);
124
- if (index < 0 || index >= self->size) {
211
+ if (index < 0 || (size_t)index >= upb_Array_Size(self->array)) {
125
212
  return Qnil;
126
213
  }
127
- memory = RepeatedField_memoryat(self, index, element_size);
128
- return native_slot_get(field_type, field_type_class, memory);
129
- }else{
214
+ msgval = upb_Array_Get(self->array, index);
215
+ return Convert_UpbToRuby(msgval, self->type_info, self->arena);
216
+ } else {
130
217
  /* check if idx is Range */
131
- switch (rb_range_beg_len(arg, &beg, &len, self->size, 0)) {
218
+ switch (rb_range_beg_len(arg, &beg, &len, size, 0)) {
132
219
  case Qfalse:
133
220
  break;
134
221
  case Qnil:
135
222
  return Qnil;
136
223
  default:
137
- return RepeatedField_subarray(_self, beg, len);
224
+ return RepeatedField_subarray(self, beg, len);
138
225
  }
139
226
  }
140
227
  }
228
+
141
229
  /* assume 2 arguments */
142
230
  beg = NUM2LONG(argv[0]);
143
231
  len = NUM2LONG(argv[1]);
144
232
  if (beg < 0) {
145
- beg += self->size;
233
+ beg += size;
146
234
  }
147
- if (beg >= self->size) {
235
+ if (beg >= size) {
148
236
  return Qnil;
149
237
  }
150
- return RepeatedField_subarray(_self, beg, len);
238
+ return RepeatedField_subarray(self, beg, len);
151
239
  }
152
240
 
153
241
  /*
@@ -157,128 +245,89 @@ VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self) {
157
245
  * Sets the element at the given index. On out-of-bounds assignments, extends
158
246
  * the array and fills the hole (if any) with default values.
159
247
  */
160
- VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val) {
248
+ static VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val) {
161
249
  RepeatedField* self = ruby_to_RepeatedField(_self);
162
- upb_fieldtype_t field_type = self->field_type;
163
- VALUE field_type_class = self->field_type_class;
164
- int element_size = native_slot_size(field_type);
165
- void* memory;
250
+ int size = upb_Array_Size(self->array);
251
+ upb_Array* array = RepeatedField_GetMutable(_self);
252
+ upb_Arena* arena = Arena_get(self->arena);
253
+ upb_MessageValue msgval = Convert_RubyToUpb(val, "", self->type_info, arena);
166
254
 
167
255
  int index = index_position(_index, self);
168
256
  if (index < 0 || index >= (INT_MAX - 1)) {
169
257
  return Qnil;
170
258
  }
171
- if (index >= self->size) {
172
- upb_fieldtype_t field_type = self->field_type;
173
- int element_size = native_slot_size(field_type);
174
- int i;
175
259
 
176
- RepeatedField_reserve(self, index + 1);
177
- for (i = self->size; i <= index; i++) {
178
- void* elem = RepeatedField_memoryat(self, i, element_size);
179
- native_slot_init(field_type, elem);
260
+ if (index >= size) {
261
+ upb_Array_Resize(array, index + 1, arena);
262
+ upb_MessageValue fill;
263
+ memset(&fill, 0, sizeof(fill));
264
+ for (int i = size; i < index; i++) {
265
+ // Fill default values.
266
+ // TODO: should this happen at the upb level?
267
+ upb_Array_Set(array, i, fill);
180
268
  }
181
- self->size = index + 1;
182
269
  }
183
270
 
184
- memory = RepeatedField_memoryat(self, index, element_size);
185
- native_slot_set("", field_type, field_type_class, memory, val);
271
+ upb_Array_Set(array, index, msgval);
186
272
  return Qnil;
187
273
  }
188
274
 
189
- static int kInitialSize = 8;
190
-
191
- void RepeatedField_reserve(RepeatedField* self, int new_size) {
192
- void* old_elems = self->elements;
193
- int elem_size = native_slot_size(self->field_type);
194
- if (new_size <= self->capacity) {
195
- return;
196
- }
197
- if (self->capacity == 0) {
198
- self->capacity = kInitialSize;
199
- }
200
- while (self->capacity < new_size) {
201
- self->capacity *= 2;
202
- }
203
- self->elements = ALLOC_N(uint8_t, elem_size * self->capacity);
204
- if (old_elems != NULL) {
205
- memcpy(self->elements, old_elems, self->size * elem_size);
206
- xfree(old_elems);
207
- }
208
- }
209
-
210
275
  /*
211
276
  * call-seq:
212
- * RepeatedField.push(value)
277
+ * RepeatedField.push(value, ...)
213
278
  *
214
279
  * Adds a new element to the repeated field.
215
280
  */
216
- VALUE RepeatedField_push(VALUE _self, VALUE val) {
281
+ static VALUE RepeatedField_push_vararg(int argc, VALUE* argv, VALUE _self) {
217
282
  RepeatedField* self = ruby_to_RepeatedField(_self);
218
- upb_fieldtype_t field_type = self->field_type;
219
- int element_size = native_slot_size(field_type);
220
- void* memory;
221
-
222
- RepeatedField_reserve(self, self->size + 1);
223
- memory = (void *) (((uint8_t *)self->elements) + self->size * element_size);
224
- native_slot_set("", field_type, self->field_type_class, memory, val);
225
- // native_slot_set may raise an error; bump size only after set.
226
- self->size++;
227
- return _self;
228
- }
229
-
230
- VALUE RepeatedField_push_vararg(VALUE _self, VALUE args) {
283
+ upb_Arena* arena = Arena_get(self->arena);
284
+ upb_Array* array = RepeatedField_GetMutable(_self);
231
285
  int i;
232
- for (i = 0; i < RARRAY_LEN(args); i++) {
233
- RepeatedField_push(_self, rb_ary_entry(args, i));
286
+
287
+ for (i = 0; i < argc; i++) {
288
+ upb_MessageValue msgval =
289
+ Convert_RubyToUpb(argv[i], "", self->type_info, arena);
290
+ upb_Array_Append(array, msgval, arena);
234
291
  }
292
+
235
293
  return _self;
236
294
  }
237
295
 
238
- // Used by parsing handlers.
239
- void RepeatedField_push_native(VALUE _self, void* data) {
296
+ /*
297
+ * call-seq:
298
+ * RepeatedField.<<(value)
299
+ *
300
+ * Adds a new element to the repeated field.
301
+ */
302
+ static VALUE RepeatedField_push(VALUE _self, VALUE val) {
240
303
  RepeatedField* self = ruby_to_RepeatedField(_self);
241
- upb_fieldtype_t field_type = self->field_type;
242
- int element_size = native_slot_size(field_type);
243
- void* memory;
244
-
245
- RepeatedField_reserve(self, self->size + 1);
246
- memory = (void *) (((uint8_t *)self->elements) + self->size * element_size);
247
- memcpy(memory, data, element_size);
248
- self->size++;
249
- }
304
+ upb_Arena* arena = Arena_get(self->arena);
305
+ upb_Array* array = RepeatedField_GetMutable(_self);
250
306
 
251
- void* RepeatedField_index_native(VALUE _self, int index) {
252
- RepeatedField* self = ruby_to_RepeatedField(_self);
253
- upb_fieldtype_t field_type = self->field_type;
254
- int element_size = native_slot_size(field_type);
255
- return RepeatedField_memoryat(self, index, element_size);
256
- }
307
+ upb_MessageValue msgval = Convert_RubyToUpb(val, "", self->type_info, arena);
308
+ upb_Array_Append(array, msgval, arena);
257
309
 
258
- int RepeatedField_size(VALUE _self) {
259
- RepeatedField* self = ruby_to_RepeatedField(_self);
260
- return self->size;
310
+ return _self;
261
311
  }
262
312
 
263
313
  /*
264
314
  * Private ruby method, used by RepeatedField.pop
265
315
  */
266
- VALUE RepeatedField_pop_one(VALUE _self) {
316
+ static VALUE RepeatedField_pop_one(VALUE _self) {
267
317
  RepeatedField* self = ruby_to_RepeatedField(_self);
268
- upb_fieldtype_t field_type = self->field_type;
269
- VALUE field_type_class = self->field_type_class;
270
- int element_size = native_slot_size(field_type);
271
- int index;
272
- void* memory;
318
+ size_t size = upb_Array_Size(self->array);
319
+ upb_Array* array = RepeatedField_GetMutable(_self);
320
+ upb_MessageValue last;
273
321
  VALUE ret;
274
322
 
275
- if (self->size == 0) {
323
+ if (size == 0) {
276
324
  return Qnil;
277
325
  }
278
- index = self->size - 1;
279
- memory = RepeatedField_memoryat(self, index, element_size);
280
- ret = native_slot_get(field_type, field_type_class, memory);
281
- self->size--;
326
+
327
+ last = upb_Array_Get(self->array, size - 1);
328
+ ret = Convert_UpbToRuby(last, self->type_info, self->arena);
329
+
330
+ upb_Array_Resize(array, size - 1, Arena_get(self->arena));
282
331
  return ret;
283
332
  }
284
333
 
@@ -288,15 +337,18 @@ VALUE RepeatedField_pop_one(VALUE _self) {
288
337
  *
289
338
  * Replaces the contents of the repeated field with the given list of elements.
290
339
  */
291
- VALUE RepeatedField_replace(VALUE _self, VALUE list) {
340
+ static VALUE RepeatedField_replace(VALUE _self, VALUE list) {
292
341
  RepeatedField* self = ruby_to_RepeatedField(_self);
342
+ upb_Array* array = RepeatedField_GetMutable(_self);
293
343
  int i;
294
344
 
295
345
  Check_Type(list, T_ARRAY);
296
- self->size = 0;
346
+ upb_Array_Resize(array, 0, Arena_get(self->arena));
347
+
297
348
  for (i = 0; i < RARRAY_LEN(list); i++) {
298
349
  RepeatedField_push(_self, rb_ary_entry(list, i));
299
350
  }
351
+
300
352
  return list;
301
353
  }
302
354
 
@@ -306,9 +358,10 @@ VALUE RepeatedField_replace(VALUE _self, VALUE list) {
306
358
  *
307
359
  * Clears (removes all elements from) this repeated field.
308
360
  */
309
- VALUE RepeatedField_clear(VALUE _self) {
361
+ static VALUE RepeatedField_clear(VALUE _self) {
310
362
  RepeatedField* self = ruby_to_RepeatedField(_self);
311
- self->size = 0;
363
+ upb_Array* array = RepeatedField_GetMutable(_self);
364
+ upb_Array_Resize(array, 0, Arena_get(self->arena));
312
365
  return _self;
313
366
  }
314
367
 
@@ -318,23 +371,9 @@ VALUE RepeatedField_clear(VALUE _self) {
318
371
  *
319
372
  * Returns the length of this repeated field.
320
373
  */
321
- VALUE RepeatedField_length(VALUE _self) {
322
- RepeatedField* self = ruby_to_RepeatedField(_self);
323
- return INT2NUM(self->size);
324
- }
325
-
326
- VALUE RepeatedField_new_this_type(VALUE _self) {
374
+ static VALUE RepeatedField_length(VALUE _self) {
327
375
  RepeatedField* self = ruby_to_RepeatedField(_self);
328
- VALUE new_rptfield = Qnil;
329
- VALUE element_type = fieldtype_to_ruby(self->field_type);
330
- if (self->field_type_class != Qnil) {
331
- new_rptfield = rb_funcall(CLASS_OF(_self), rb_intern("new"), 2,
332
- element_type, self->field_type_class);
333
- } else {
334
- new_rptfield = rb_funcall(CLASS_OF(_self), rb_intern("new"), 1,
335
- element_type);
336
- }
337
- return new_rptfield;
376
+ return INT2NUM(upb_Array_Size(self->array));
338
377
  }
339
378
 
340
379
  /*
@@ -344,42 +383,20 @@ VALUE RepeatedField_new_this_type(VALUE _self) {
344
383
  * Duplicates this repeated field with a shallow copy. References to all
345
384
  * non-primitive element objects (e.g., submessages) are shared.
346
385
  */
347
- VALUE RepeatedField_dup(VALUE _self) {
386
+ static VALUE RepeatedField_dup(VALUE _self) {
348
387
  RepeatedField* self = ruby_to_RepeatedField(_self);
349
- VALUE new_rptfield = RepeatedField_new_this_type(_self);
388
+ VALUE new_rptfield = RepeatedField_new_this_type(self);
350
389
  RepeatedField* new_rptfield_self = ruby_to_RepeatedField(new_rptfield);
351
- upb_fieldtype_t field_type = self->field_type;
352
- size_t elem_size = native_slot_size(field_type);
353
- size_t off = 0;
390
+ upb_Array* new_array = RepeatedField_GetMutable(new_rptfield);
391
+ upb_Arena* arena = Arena_get(new_rptfield_self->arena);
392
+ int size = upb_Array_Size(self->array);
354
393
  int i;
355
394
 
356
- RepeatedField_reserve(new_rptfield_self, self->size);
357
- for (i = 0; i < self->size; i++, off += elem_size) {
358
- void* to_mem = (uint8_t *)new_rptfield_self->elements + off;
359
- void* from_mem = (uint8_t *)self->elements + off;
360
- native_slot_dup(field_type, to_mem, from_mem);
361
- new_rptfield_self->size++;
362
- }
363
-
364
- return new_rptfield;
365
- }
395
+ Arena_fuse(self->arena, arena);
366
396
 
367
- // Internal only: used by Google::Protobuf.deep_copy.
368
- VALUE RepeatedField_deep_copy(VALUE _self) {
369
- RepeatedField* self = ruby_to_RepeatedField(_self);
370
- VALUE new_rptfield = RepeatedField_new_this_type(_self);
371
- RepeatedField* new_rptfield_self = ruby_to_RepeatedField(new_rptfield);
372
- upb_fieldtype_t field_type = self->field_type;
373
- size_t elem_size = native_slot_size(field_type);
374
- size_t off = 0;
375
- int i;
376
-
377
- RepeatedField_reserve(new_rptfield_self, self->size);
378
- for (i = 0; i < self->size; i++, off += elem_size) {
379
- void* to_mem = (uint8_t *)new_rptfield_self->elements + off;
380
- void* from_mem = (uint8_t *)self->elements + off;
381
- native_slot_deep_copy(field_type, self->field_type_class, to_mem, from_mem);
382
- new_rptfield_self->size++;
397
+ for (i = 0; i < size; i++) {
398
+ upb_MessageValue msgval = upb_Array_Get(self->array, i);
399
+ upb_Array_Append(new_array, msgval, arena);
383
400
  }
384
401
 
385
402
  return new_rptfield;
@@ -394,17 +411,16 @@ VALUE RepeatedField_deep_copy(VALUE _self) {
394
411
  */
395
412
  VALUE RepeatedField_to_ary(VALUE _self) {
396
413
  RepeatedField* self = ruby_to_RepeatedField(_self);
397
- upb_fieldtype_t field_type = self->field_type;
398
- size_t elem_size = native_slot_size(field_type);
399
- size_t off = 0;
400
- VALUE ary = rb_ary_new2(self->size);
414
+ int size = upb_Array_Size(self->array);
415
+ VALUE ary = rb_ary_new2(size);
401
416
  int i;
402
417
 
403
- for (i = 0; i < self->size; i++, off += elem_size) {
404
- void* mem = ((uint8_t *)self->elements) + off;
405
- VALUE elem = native_slot_get(field_type, self->field_type_class, mem);
406
- rb_ary_push(ary, elem);
418
+ for (i = 0; i < size; i++) {
419
+ upb_MessageValue msgval = upb_Array_Get(self->array, i);
420
+ VALUE val = Convert_UpbToRuby(msgval, self->type_info, self->arena);
421
+ rb_ary_push(ary, val);
407
422
  }
423
+
408
424
  return ary;
409
425
  }
410
426
 
@@ -436,28 +452,49 @@ VALUE RepeatedField_eq(VALUE _self, VALUE _other) {
436
452
 
437
453
  self = ruby_to_RepeatedField(_self);
438
454
  other = ruby_to_RepeatedField(_other);
439
- if (self->field_type != other->field_type ||
440
- self->field_type_class != other->field_type_class ||
441
- self->size != other->size) {
455
+ size_t n = upb_Array_Size(self->array);
456
+
457
+ if (self->type_info.type != other->type_info.type ||
458
+ self->type_class != other->type_class ||
459
+ upb_Array_Size(other->array) != n) {
442
460
  return Qfalse;
443
461
  }
444
462
 
445
- {
446
- upb_fieldtype_t field_type = self->field_type;
447
- size_t elem_size = native_slot_size(field_type);
448
- size_t off = 0;
449
- int i;
463
+ for (size_t i = 0; i < n; i++) {
464
+ upb_MessageValue val1 = upb_Array_Get(self->array, i);
465
+ upb_MessageValue val2 = upb_Array_Get(other->array, i);
466
+ if (!Msgval_IsEqual(val1, val2, self->type_info)) {
467
+ return Qfalse;
468
+ }
469
+ }
450
470
 
451
- for (i = 0; i < self->size; i++, off += elem_size) {
452
- void* self_mem = ((uint8_t *)self->elements) + off;
453
- void* other_mem = ((uint8_t *)other->elements) + off;
454
- if (!native_slot_eq(field_type, self->field_type_class, self_mem,
455
- other_mem)) {
456
- return Qfalse;
457
- }
471
+ return Qtrue;
472
+ }
473
+
474
+ /*
475
+ * call-seq:
476
+ * RepeatedField.freeze => self
477
+ *
478
+ * Freezes the repeated field. We have to intercept this so we can pin the Ruby
479
+ * object into memory so we don't forget it's frozen.
480
+ */
481
+ VALUE RepeatedField_freeze(VALUE _self) {
482
+ RepeatedField* self = ruby_to_RepeatedField(_self);
483
+
484
+ if (RB_OBJ_FROZEN(_self)) return _self;
485
+ Arena_Pin(self->arena, _self);
486
+ RB_OBJ_FREEZE(_self);
487
+
488
+ if (self->type_info.type == kUpb_CType_Message) {
489
+ int size = upb_Array_Size(self->array);
490
+ int i;
491
+ for (i = 0; i < size; i++) {
492
+ upb_MessageValue msgval = upb_Array_Get(self->array, i);
493
+ VALUE val = Convert_UpbToRuby(msgval, self->type_info, self->arena);
494
+ Message_freeze(val);
458
495
  }
459
- return Qtrue;
460
496
  }
497
+ return _self;
461
498
  }
462
499
 
463
500
  /*
@@ -468,22 +505,15 @@ VALUE RepeatedField_eq(VALUE _self, VALUE _other) {
468
505
  */
469
506
  VALUE RepeatedField_hash(VALUE _self) {
470
507
  RepeatedField* self = ruby_to_RepeatedField(_self);
471
- st_index_t h = rb_hash_start(0);
472
- VALUE hash_sym = rb_intern("hash");
473
- upb_fieldtype_t field_type = self->field_type;
474
- VALUE field_type_class = self->field_type_class;
475
- size_t elem_size = native_slot_size(field_type);
476
- size_t off = 0;
477
- int i;
508
+ uint64_t hash = 0;
509
+ size_t n = upb_Array_Size(self->array);
478
510
 
479
- for (i = 0; i < self->size; i++, off += elem_size) {
480
- void* mem = ((uint8_t *)self->elements) + off;
481
- VALUE elem = native_slot_get(field_type, field_type_class, mem);
482
- h = rb_hash_uint(h, NUM2LONG(rb_funcall(elem, hash_sym, 0)));
511
+ for (size_t i = 0; i < n; i++) {
512
+ upb_MessageValue val = upb_Array_Get(self->array, i);
513
+ hash = Msgval_GetHash(val, self->type_info, hash);
483
514
  }
484
- h = rb_hash_end(h);
485
515
 
486
- return INT2FIX(h);
516
+ return LL2NUM(hash);
487
517
  }
488
518
 
489
519
  /*
@@ -495,34 +525,40 @@ VALUE RepeatedField_hash(VALUE _self) {
495
525
  * be either another repeated field or a Ruby array.
496
526
  */
497
527
  VALUE RepeatedField_plus(VALUE _self, VALUE list) {
498
- VALUE dupped = RepeatedField_dup(_self);
528
+ VALUE dupped_ = RepeatedField_dup(_self);
499
529
 
500
530
  if (TYPE(list) == T_ARRAY) {
501
531
  int i;
502
532
  for (i = 0; i < RARRAY_LEN(list); i++) {
503
533
  VALUE elem = rb_ary_entry(list, i);
504
- RepeatedField_push(dupped, elem);
534
+ RepeatedField_push(dupped_, elem);
505
535
  }
506
536
  } else if (RB_TYPE_P(list, T_DATA) && RTYPEDDATA_P(list) &&
507
537
  RTYPEDDATA_TYPE(list) == &RepeatedField_type) {
508
538
  RepeatedField* self = ruby_to_RepeatedField(_self);
509
539
  RepeatedField* list_rptfield = ruby_to_RepeatedField(list);
540
+ RepeatedField* dupped = ruby_to_RepeatedField(dupped_);
541
+ upb_Array* dupped_array = RepeatedField_GetMutable(dupped_);
542
+ upb_Arena* arena = Arena_get(dupped->arena);
543
+ Arena_fuse(list_rptfield->arena, arena);
544
+ int size = upb_Array_Size(list_rptfield->array);
510
545
  int i;
511
546
 
512
- if (self->field_type != list_rptfield->field_type ||
513
- self->field_type_class != list_rptfield->field_type_class) {
547
+ if (self->type_info.type != list_rptfield->type_info.type ||
548
+ self->type_class != list_rptfield->type_class) {
514
549
  rb_raise(rb_eArgError,
515
550
  "Attempt to append RepeatedField with different element type.");
516
551
  }
517
- for (i = 0; i < list_rptfield->size; i++) {
518
- void* mem = RepeatedField_index_native(list, i);
519
- RepeatedField_push_native(dupped, mem);
552
+
553
+ for (i = 0; i < size; i++) {
554
+ upb_MessageValue msgval = upb_Array_Get(list_rptfield->array, i);
555
+ upb_Array_Append(dupped_array, msgval, arena);
520
556
  }
521
557
  } else {
522
558
  rb_raise(rb_eArgError, "Unknown type appending to RepeatedField");
523
559
  }
524
560
 
525
- return dupped;
561
+ return dupped_;
526
562
  }
527
563
 
528
564
  /*
@@ -541,133 +577,57 @@ VALUE RepeatedField_concat(VALUE _self, VALUE list) {
541
577
  return _self;
542
578
  }
543
579
 
544
-
545
- void validate_type_class(upb_fieldtype_t type, VALUE klass) {
546
- if (rb_ivar_get(klass, descriptor_instancevar_interned) == Qnil) {
547
- rb_raise(rb_eArgError,
548
- "Type class has no descriptor. Please pass a "
549
- "class or enum as returned by the DescriptorPool.");
550
- }
551
- if (type == UPB_TYPE_MESSAGE) {
552
- VALUE desc = rb_ivar_get(klass, descriptor_instancevar_interned);
553
- if (!RB_TYPE_P(desc, T_DATA) || !RTYPEDDATA_P(desc) ||
554
- RTYPEDDATA_TYPE(desc) != &_Descriptor_type) {
555
- rb_raise(rb_eArgError, "Descriptor has an incorrect type.");
556
- }
557
- if (rb_get_alloc_func(klass) != &Message_alloc) {
558
- rb_raise(rb_eArgError,
559
- "Message class was not returned by the DescriptorPool.");
560
- }
561
- } else if (type == UPB_TYPE_ENUM) {
562
- VALUE enumdesc = rb_ivar_get(klass, descriptor_instancevar_interned);
563
- if (!RB_TYPE_P(enumdesc, T_DATA) || !RTYPEDDATA_P(enumdesc) ||
564
- RTYPEDDATA_TYPE(enumdesc) != &_EnumDescriptor_type) {
565
- rb_raise(rb_eArgError, "Descriptor has an incorrect type.");
566
- }
567
- }
568
- }
569
-
570
- void RepeatedField_init_args(int argc, VALUE* argv,
571
- VALUE _self) {
580
+ /*
581
+ * call-seq:
582
+ * RepeatedField.new(type, type_class = nil, initial_elems = [])
583
+ *
584
+ * Creates a new repeated field. The provided type must be a Ruby symbol, and
585
+ * can take on the same values as those accepted by FieldDescriptor#type=. If
586
+ * the type is :message or :enum, type_class must be non-nil, and must be the
587
+ * Ruby class or module returned by Descriptor#msgclass or
588
+ * EnumDescriptor#enummodule, respectively. An initial list of elements may also
589
+ * be provided.
590
+ */
591
+ VALUE RepeatedField_init(int argc, VALUE* argv, VALUE _self) {
572
592
  RepeatedField* self = ruby_to_RepeatedField(_self);
593
+ upb_Arena* arena;
573
594
  VALUE ary = Qnil;
595
+
596
+ self->arena = Arena_new();
597
+ arena = Arena_get(self->arena);
598
+
574
599
  if (argc < 1) {
575
600
  rb_raise(rb_eArgError, "Expected at least 1 argument.");
576
601
  }
577
- self->field_type = ruby_to_fieldtype(argv[0]);
578
602
 
579
- if (self->field_type == UPB_TYPE_MESSAGE ||
580
- self->field_type == UPB_TYPE_ENUM) {
581
- if (argc < 2) {
582
- rb_raise(rb_eArgError, "Expected at least 2 arguments for message/enum.");
583
- }
584
- self->field_type_class = argv[1];
585
- if (argc > 2) {
586
- ary = argv[2];
587
- }
588
- validate_type_class(self->field_type, self->field_type_class);
589
- } else {
590
- if (argc > 2) {
591
- rb_raise(rb_eArgError, "Too many arguments: expected 1 or 2.");
592
- }
593
- if (argc > 1) {
594
- ary = argv[1];
595
- }
596
- }
603
+ self->type_info = TypeInfo_FromClass(argc, argv, 0, &self->type_class, &ary);
604
+ self->array = upb_Array_New(arena, self->type_info.type);
605
+ VALUE stored_val = ObjectCache_TryAdd(self->array, _self);
606
+ PBRUBY_ASSERT(stored_val == _self);
597
607
 
598
608
  if (ary != Qnil) {
599
- int i;
600
-
601
609
  if (!RB_TYPE_P(ary, T_ARRAY)) {
602
610
  rb_raise(rb_eArgError, "Expected array as initialize argument");
603
611
  }
604
- for (i = 0; i < RARRAY_LEN(ary); i++) {
612
+ for (int i = 0; i < RARRAY_LEN(ary); i++) {
605
613
  RepeatedField_push(_self, rb_ary_entry(ary, i));
606
614
  }
607
615
  }
608
- }
609
-
610
- // Mark, free, alloc, init and class setup functions.
611
-
612
- void RepeatedField_mark(void* _self) {
613
- RepeatedField* self = (RepeatedField*)_self;
614
- upb_fieldtype_t field_type = self->field_type;
615
- int element_size = native_slot_size(field_type);
616
- int i;
617
-
618
- rb_gc_mark(self->field_type_class);
619
- for (i = 0; i < self->size; i++) {
620
- void* memory = (((uint8_t *)self->elements) + i * element_size);
621
- native_slot_mark(self->field_type, memory);
622
- }
623
- }
624
-
625
- void RepeatedField_free(void* _self) {
626
- RepeatedField* self = (RepeatedField*)_self;
627
- xfree(self->elements);
628
- xfree(self);
629
- }
630
-
631
- /*
632
- * call-seq:
633
- * RepeatedField.new(type, type_class = nil, initial_elems = [])
634
- *
635
- * Creates a new repeated field. The provided type must be a Ruby symbol, and
636
- * can take on the same values as those accepted by FieldDescriptor#type=. If
637
- * the type is :message or :enum, type_class must be non-nil, and must be the
638
- * Ruby class or module returned by Descriptor#msgclass or
639
- * EnumDescriptor#enummodule, respectively. An initial list of elements may also
640
- * be provided.
641
- */
642
- VALUE RepeatedField_alloc(VALUE klass) {
643
- RepeatedField* self = ALLOC(RepeatedField);
644
- self->elements = NULL;
645
- self->size = 0;
646
- self->capacity = 0;
647
- self->field_type = -1;
648
- self->field_type_class = Qnil;
649
- return TypedData_Wrap_Struct(klass, &RepeatedField_type, self);
650
- }
651
-
652
- VALUE RepeatedField_init(int argc, VALUE* argv, VALUE self) {
653
- RepeatedField_init_args(argc, argv, self);
654
616
  return Qnil;
655
617
  }
656
618
 
657
619
  void RepeatedField_register(VALUE module) {
658
- VALUE klass = rb_define_class_under(
659
- module, "RepeatedField", rb_cObject);
620
+ VALUE klass = rb_define_class_under(module, "RepeatedField", rb_cObject);
660
621
  rb_define_alloc_func(klass, RepeatedField_alloc);
661
622
  rb_gc_register_address(&cRepeatedField);
662
623
  cRepeatedField = klass;
663
624
 
664
- rb_define_method(klass, "initialize",
665
- RepeatedField_init, -1);
625
+ rb_define_method(klass, "initialize", RepeatedField_init, -1);
666
626
  rb_define_method(klass, "each", RepeatedField_each, 0);
667
627
  rb_define_method(klass, "[]", RepeatedField_index, -1);
668
628
  rb_define_method(klass, "at", RepeatedField_index, -1);
669
629
  rb_define_method(klass, "[]=", RepeatedField_index_set, 2);
670
- rb_define_method(klass, "push", RepeatedField_push_vararg, -2);
630
+ rb_define_method(klass, "push", RepeatedField_push_vararg, -1);
671
631
  rb_define_method(klass, "<<", RepeatedField_push, 1);
672
632
  rb_define_private_method(klass, "pop_one", RepeatedField_pop_one, 0);
673
633
  rb_define_method(klass, "replace", RepeatedField_replace, 1);
@@ -679,6 +639,7 @@ void RepeatedField_register(VALUE module) {
679
639
  rb_define_method(klass, "clone", RepeatedField_dup, 0);
680
640
  rb_define_method(klass, "==", RepeatedField_eq, 1);
681
641
  rb_define_method(klass, "to_ary", RepeatedField_to_ary, 0);
642
+ rb_define_method(klass, "freeze", RepeatedField_freeze, 0);
682
643
  rb_define_method(klass, "hash", RepeatedField_hash, 0);
683
644
  rb_define_method(klass, "+", RepeatedField_plus, 1);
684
645
  rb_define_method(klass, "concat", RepeatedField_concat, 1);