google-protobuf 3.19.1 → 4.30.2

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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/ext/google/protobuf_c/Rakefile +3 -0
  3. data/ext/google/protobuf_c/convert.c +153 -166
  4. data/ext/google/protobuf_c/convert.h +15 -37
  5. data/ext/google/protobuf_c/defs.c +867 -251
  6. data/ext/google/protobuf_c/defs.h +22 -47
  7. data/ext/google/protobuf_c/extconf.rb +25 -5
  8. data/ext/google/protobuf_c/glue.c +135 -0
  9. data/ext/google/protobuf_c/map.c +182 -145
  10. data/ext/google/protobuf_c/map.h +16 -35
  11. data/ext/google/protobuf_c/message.c +534 -437
  12. data/ext/google/protobuf_c/message.h +30 -49
  13. data/ext/google/protobuf_c/protobuf.c +125 -238
  14. data/ext/google/protobuf_c/protobuf.h +40 -49
  15. data/ext/google/protobuf_c/repeated_field.c +152 -120
  16. data/ext/google/protobuf_c/repeated_field.h +16 -34
  17. data/ext/google/protobuf_c/ruby-upb.c +15827 -7228
  18. data/ext/google/protobuf_c/ruby-upb.h +15075 -3866
  19. data/ext/google/protobuf_c/shared_convert.c +69 -0
  20. data/ext/google/protobuf_c/shared_convert.h +26 -0
  21. data/ext/google/protobuf_c/shared_message.c +37 -0
  22. data/ext/google/protobuf_c/shared_message.h +21 -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 +207 -0
  25. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +22 -0
  26. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range_neon.inc +117 -0
  27. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range_sse.inc +272 -0
  28. data/ext/google/protobuf_c/wrap_memcpy.c +7 -29
  29. data/lib/google/protobuf/any_pb.rb +6 -8
  30. data/lib/google/protobuf/api_pb.rb +6 -26
  31. data/lib/google/protobuf/descriptor_pb.rb +24 -225
  32. data/lib/google/protobuf/duration_pb.rb +6 -8
  33. data/lib/google/protobuf/empty_pb.rb +6 -6
  34. data/lib/google/protobuf/ffi/descriptor.rb +175 -0
  35. data/lib/google/protobuf/ffi/descriptor_pool.rb +77 -0
  36. data/lib/google/protobuf/ffi/enum_descriptor.rb +183 -0
  37. data/lib/google/protobuf/ffi/ffi.rb +214 -0
  38. data/lib/google/protobuf/ffi/field_descriptor.rb +340 -0
  39. data/lib/google/protobuf/ffi/file_descriptor.rb +59 -0
  40. data/lib/google/protobuf/ffi/internal/arena.rb +60 -0
  41. data/lib/google/protobuf/ffi/internal/convert.rb +292 -0
  42. data/lib/google/protobuf/ffi/internal/pointer_helper.rb +35 -0
  43. data/lib/google/protobuf/ffi/internal/type_safety.rb +25 -0
  44. data/lib/google/protobuf/ffi/map.rb +433 -0
  45. data/lib/google/protobuf/ffi/message.rb +783 -0
  46. data/lib/google/protobuf/ffi/method_descriptor.rb +124 -0
  47. data/lib/google/protobuf/ffi/object_cache.rb +30 -0
  48. data/lib/google/protobuf/ffi/oneof_descriptor.rb +107 -0
  49. data/lib/google/protobuf/ffi/repeated_field.rb +411 -0
  50. data/lib/google/protobuf/ffi/service_descriptor.rb +117 -0
  51. data/lib/google/protobuf/field_mask_pb.rb +6 -7
  52. data/lib/google/protobuf/internal/object_cache.rb +99 -0
  53. data/lib/google/protobuf/message_exts.rb +10 -28
  54. data/lib/google/protobuf/plugin_pb.rb +25 -0
  55. data/lib/google/protobuf/repeated_field.rb +22 -33
  56. data/lib/google/protobuf/source_context_pb.rb +6 -7
  57. data/lib/google/protobuf/struct_pb.rb +6 -23
  58. data/lib/google/protobuf/timestamp_pb.rb +6 -8
  59. data/lib/google/protobuf/type_pb.rb +6 -71
  60. data/lib/google/protobuf/well_known_types.rb +16 -40
  61. data/lib/google/protobuf/wrappers_pb.rb +6 -31
  62. data/lib/google/protobuf.rb +32 -50
  63. data/lib/google/protobuf_ffi.rb +52 -0
  64. data/lib/google/protobuf_native.rb +19 -0
  65. data/lib/google/tasks/ffi.rake +100 -0
  66. metadata +97 -20
  67. data/lib/google/protobuf/descriptor_dsl.rb +0 -458
  68. data/tests/basic.rb +0 -640
  69. data/tests/generated_code_test.rb +0 -23
  70. data/tests/stress.rb +0 -38
@@ -1,32 +1,9 @@
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
30
7
 
31
8
  #include "repeated_field.h"
32
9
 
@@ -40,10 +17,10 @@
40
17
  // -----------------------------------------------------------------------------
41
18
 
42
19
  typedef struct {
43
- const upb_array *array; // Can get as mutable when non-frozen.
20
+ const upb_Array* array; // Can get as mutable when non-frozen.
44
21
  TypeInfo type_info;
45
22
  VALUE type_class; // To GC-root the msgdef/enumdef in type_info.
46
- VALUE arena; // To GC-root the upb_array.
23
+ VALUE arena; // To GC-root the upb_Array.
47
24
  } RepeatedField;
48
25
 
49
26
  VALUE cRepeatedField;
@@ -55,9 +32,9 @@ static void RepeatedField_mark(void* _self) {
55
32
  }
56
33
 
57
34
  const rb_data_type_t RepeatedField_type = {
58
- "Google::Protobuf::RepeatedField",
59
- { RepeatedField_mark, RUBY_DEFAULT_FREE, NULL },
60
- .flags = RUBY_TYPED_FREE_IMMEDIATELY,
35
+ "Google::Protobuf::RepeatedField",
36
+ {RepeatedField_mark, RUBY_DEFAULT_FREE, NULL},
37
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
61
38
  };
62
39
 
63
40
  static RepeatedField* ruby_to_RepeatedField(VALUE _self) {
@@ -66,9 +43,10 @@ static RepeatedField* ruby_to_RepeatedField(VALUE _self) {
66
43
  return self;
67
44
  }
68
45
 
69
- static upb_array *RepeatedField_GetMutable(VALUE _self) {
70
- rb_check_frozen(_self);
71
- return (upb_array*)ruby_to_RepeatedField(_self)->array;
46
+ static upb_Array* RepeatedField_GetMutable(VALUE _self) {
47
+ const upb_Array* array = ruby_to_RepeatedField(_self)->array;
48
+ Protobuf_CheckNotFrozen(_self, upb_Array_IsFrozen(array));
49
+ return (upb_Array*)array;
72
50
  }
73
51
 
74
52
  VALUE RepeatedField_alloc(VALUE klass) {
@@ -79,50 +57,74 @@ VALUE RepeatedField_alloc(VALUE klass) {
79
57
  return TypedData_Wrap_Struct(klass, &RepeatedField_type, self);
80
58
  }
81
59
 
82
- VALUE RepeatedField_GetRubyWrapper(upb_array* array, TypeInfo type_info,
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,
83
83
  VALUE arena) {
84
84
  PBRUBY_ASSERT(array);
85
+ PBRUBY_ASSERT(arena != Qnil);
85
86
  VALUE val = ObjectCache_Get(array);
86
87
 
87
88
  if (val == Qnil) {
88
89
  val = RepeatedField_alloc(cRepeatedField);
89
90
  RepeatedField* self;
90
- ObjectCache_Add(array, val);
91
91
  TypedData_Get_Struct(val, RepeatedField, &RepeatedField_type, self);
92
92
  self->array = array;
93
93
  self->arena = arena;
94
94
  self->type_info = type_info;
95
- if (self->type_info.type == UPB_TYPE_MESSAGE) {
95
+ if (self->type_info.type == kUpb_CType_Message) {
96
96
  self->type_class = Descriptor_DefToClass(type_info.def.msgdef);
97
97
  }
98
+ val = ObjectCache_TryAdd(array, val);
98
99
  }
99
100
 
100
101
  PBRUBY_ASSERT(ruby_to_RepeatedField(val)->type_info.type == type_info.type);
101
102
  PBRUBY_ASSERT(ruby_to_RepeatedField(val)->type_info.def.msgdef ==
102
103
  type_info.def.msgdef);
104
+ PBRUBY_ASSERT(ruby_to_RepeatedField(val)->array == array);
103
105
  return val;
104
106
  }
105
107
 
106
108
  static VALUE RepeatedField_new_this_type(RepeatedField* from) {
107
109
  VALUE arena_rb = Arena_new();
108
- upb_array *array = upb_array_new(Arena_get(arena_rb), from->type_info.type);
110
+ upb_Array* array = upb_Array_New(Arena_get(arena_rb), from->type_info.type);
109
111
  VALUE ret = RepeatedField_GetRubyWrapper(array, from->type_info, arena_rb);
110
112
  PBRUBY_ASSERT(ruby_to_RepeatedField(ret)->type_class == from->type_class);
111
113
  return ret;
112
114
  }
113
115
 
114
- void RepeatedField_Inspect(StringBuilder* b, const upb_array* array,
116
+ void RepeatedField_Inspect(StringBuilder* b, const upb_Array* array,
115
117
  TypeInfo info) {
116
118
  bool first = true;
117
119
  StringBuilder_Printf(b, "[");
118
- size_t n = array ? upb_array_size(array) : 0;
120
+ size_t n = array ? upb_Array_Size(array) : 0;
119
121
  for (size_t i = 0; i < n; i++) {
120
122
  if (first) {
121
123
  first = false;
122
124
  } else {
123
125
  StringBuilder_Printf(b, ", ");
124
126
  }
125
- StringBuilder_PrintMsgval(b, upb_array_get(array, i), info);
127
+ StringBuilder_PrintMsgval(b, upb_Array_Get(array, i), info);
126
128
  }
127
129
  StringBuilder_Printf(b, "]");
128
130
  }
@@ -132,24 +134,24 @@ VALUE RepeatedField_deep_copy(VALUE _self) {
132
134
  VALUE new_rptfield = RepeatedField_new_this_type(self);
133
135
  RepeatedField* new_self = ruby_to_RepeatedField(new_rptfield);
134
136
  VALUE arena_rb = new_self->arena;
135
- upb_array *new_array = RepeatedField_GetMutable(new_rptfield);
136
- upb_arena *arena = Arena_get(arena_rb);
137
- size_t elements = upb_array_size(self->array);
137
+ upb_Array* new_array = RepeatedField_GetMutable(new_rptfield);
138
+ upb_Arena* arena = Arena_get(arena_rb);
139
+ size_t elements = upb_Array_Size(self->array);
138
140
 
139
- upb_array_resize(new_array, elements, arena);
141
+ upb_Array_Resize(new_array, elements, arena);
140
142
 
141
- size_t size = upb_array_size(self->array);
143
+ size_t size = upb_Array_Size(self->array);
142
144
  for (size_t i = 0; i < size; i++) {
143
- upb_msgval msgval = upb_array_get(self->array, i);
144
- upb_msgval copy = Msgval_DeepCopy(msgval, self->type_info, arena);
145
- upb_array_set(new_array, i, copy);
145
+ upb_MessageValue msgval = upb_Array_Get(self->array, i);
146
+ upb_MessageValue copy = Msgval_DeepCopy(msgval, self->type_info, arena);
147
+ upb_Array_Set(new_array, i, copy);
146
148
  }
147
149
 
148
150
  return new_rptfield;
149
151
  }
150
152
 
151
- const upb_array* RepeatedField_GetUpbArray(VALUE val, const upb_fielddef* field,
152
- upb_arena* arena) {
153
+ const upb_Array* RepeatedField_GetUpbArray(VALUE val, const upb_FieldDef* field,
154
+ upb_Arena* arena) {
153
155
  RepeatedField* self;
154
156
  TypeInfo type_info = TypeInfo_get(field);
155
157
 
@@ -173,17 +175,17 @@ const upb_array* RepeatedField_GetUpbArray(VALUE val, const upb_fielddef* field,
173
175
 
174
176
  static int index_position(VALUE _index, RepeatedField* repeated_field) {
175
177
  int index = NUM2INT(_index);
176
- if (index < 0) index += upb_array_size(repeated_field->array);
178
+ if (index < 0) index += upb_Array_Size(repeated_field->array);
177
179
  return index;
178
180
  }
179
181
 
180
182
  static VALUE RepeatedField_subarray(RepeatedField* self, long beg, long len) {
181
- size_t size = upb_array_size(self->array);
183
+ size_t size = upb_Array_Size(self->array);
182
184
  VALUE ary = rb_ary_new2(size);
183
185
  long i;
184
186
 
185
187
  for (i = beg; i < beg + len; i++) {
186
- upb_msgval msgval = upb_array_get(self->array, i);
188
+ upb_MessageValue msgval = upb_Array_Get(self->array, i);
187
189
  VALUE elem = Convert_UpbToRuby(msgval, self->type_info, self->arena);
188
190
  rb_ary_push(ary, elem);
189
191
  }
@@ -200,18 +202,17 @@ static VALUE RepeatedField_subarray(RepeatedField* self, long beg, long len) {
200
202
  */
201
203
  static VALUE RepeatedField_each(VALUE _self) {
202
204
  RepeatedField* self = ruby_to_RepeatedField(_self);
203
- int size = upb_array_size(self->array);
205
+ int size = upb_Array_Size(self->array);
204
206
  int i;
205
207
 
206
208
  for (i = 0; i < size; i++) {
207
- upb_msgval msgval = upb_array_get(self->array, i);
209
+ upb_MessageValue msgval = upb_Array_Get(self->array, i);
208
210
  VALUE val = Convert_UpbToRuby(msgval, self->type_info, self->arena);
209
211
  rb_yield(val);
210
212
  }
211
213
  return _self;
212
214
  }
213
215
 
214
-
215
216
  /*
216
217
  * call-seq:
217
218
  * RepeatedField.[](index) => value
@@ -220,20 +221,20 @@ static VALUE RepeatedField_each(VALUE _self) {
220
221
  */
221
222
  static VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self) {
222
223
  RepeatedField* self = ruby_to_RepeatedField(_self);
223
- long size = upb_array_size(self->array);
224
+ long size = upb_Array_Size(self->array);
224
225
 
225
226
  VALUE arg = argv[0];
226
227
  long beg, len;
227
228
 
228
- if (argc == 1){
229
+ if (argc == 1) {
229
230
  if (FIXNUM_P(arg)) {
230
231
  /* standard case */
231
- upb_msgval msgval;
232
+ upb_MessageValue msgval;
232
233
  int index = index_position(argv[0], self);
233
- if (index < 0 || (size_t)index >= upb_array_size(self->array)) {
234
+ if (index < 0 || (size_t)index >= upb_Array_Size(self->array)) {
234
235
  return Qnil;
235
236
  }
236
- msgval = upb_array_get(self->array, index);
237
+ msgval = upb_Array_Get(self->array, index);
237
238
  return Convert_UpbToRuby(msgval, self->type_info, self->arena);
238
239
  } else {
239
240
  /* check if idx is Range */
@@ -269,10 +270,10 @@ static VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self) {
269
270
  */
270
271
  static VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val) {
271
272
  RepeatedField* self = ruby_to_RepeatedField(_self);
272
- int size = upb_array_size(self->array);
273
- upb_array *array = RepeatedField_GetMutable(_self);
274
- upb_arena *arena = Arena_get(self->arena);
275
- upb_msgval msgval = Convert_RubyToUpb(val, "", self->type_info, arena);
273
+ int size = upb_Array_Size(self->array);
274
+ upb_Array* array = RepeatedField_GetMutable(_self);
275
+ upb_Arena* arena = Arena_get(self->arena);
276
+ upb_MessageValue msgval = Convert_RubyToUpb(val, "", self->type_info, arena);
276
277
 
277
278
  int index = index_position(_index, self);
278
279
  if (index < 0 || index >= (INT_MAX - 1)) {
@@ -280,17 +281,17 @@ static VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val) {
280
281
  }
281
282
 
282
283
  if (index >= size) {
283
- upb_array_resize(array, index + 1, arena);
284
- upb_msgval fill;
284
+ upb_Array_Resize(array, index + 1, arena);
285
+ upb_MessageValue fill;
285
286
  memset(&fill, 0, sizeof(fill));
286
287
  for (int i = size; i < index; i++) {
287
288
  // Fill default values.
288
- // TODO(haberman): should this happen at the upb level?
289
- upb_array_set(array, i, fill);
289
+ // TODO: should this happen at the upb level?
290
+ upb_Array_Set(array, i, fill);
290
291
  }
291
292
  }
292
293
 
293
- upb_array_set(array, index, msgval);
294
+ upb_Array_Set(array, index, msgval);
294
295
  return Qnil;
295
296
  }
296
297
 
@@ -302,13 +303,14 @@ static VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val) {
302
303
  */
303
304
  static VALUE RepeatedField_push_vararg(int argc, VALUE* argv, VALUE _self) {
304
305
  RepeatedField* self = ruby_to_RepeatedField(_self);
305
- upb_arena *arena = Arena_get(self->arena);
306
- upb_array *array = RepeatedField_GetMutable(_self);
306
+ upb_Arena* arena = Arena_get(self->arena);
307
+ upb_Array* array = RepeatedField_GetMutable(_self);
307
308
  int i;
308
309
 
309
310
  for (i = 0; i < argc; i++) {
310
- upb_msgval msgval = Convert_RubyToUpb(argv[i], "", self->type_info, arena);
311
- upb_array_append(array, msgval, arena);
311
+ upb_MessageValue msgval =
312
+ Convert_RubyToUpb(argv[i], "", self->type_info, arena);
313
+ upb_Array_Append(array, msgval, arena);
312
314
  }
313
315
 
314
316
  return _self;
@@ -322,11 +324,11 @@ static VALUE RepeatedField_push_vararg(int argc, VALUE* argv, VALUE _self) {
322
324
  */
323
325
  static VALUE RepeatedField_push(VALUE _self, VALUE val) {
324
326
  RepeatedField* self = ruby_to_RepeatedField(_self);
325
- upb_arena *arena = Arena_get(self->arena);
326
- upb_array *array = RepeatedField_GetMutable(_self);
327
+ upb_Arena* arena = Arena_get(self->arena);
328
+ upb_Array* array = RepeatedField_GetMutable(_self);
327
329
 
328
- upb_msgval msgval = Convert_RubyToUpb(val, "", self->type_info, arena);
329
- upb_array_append(array, msgval, arena);
330
+ upb_MessageValue msgval = Convert_RubyToUpb(val, "", self->type_info, arena);
331
+ upb_Array_Append(array, msgval, arena);
330
332
 
331
333
  return _self;
332
334
  }
@@ -336,19 +338,19 @@ static VALUE RepeatedField_push(VALUE _self, VALUE val) {
336
338
  */
337
339
  static VALUE RepeatedField_pop_one(VALUE _self) {
338
340
  RepeatedField* self = ruby_to_RepeatedField(_self);
339
- size_t size = upb_array_size(self->array);
340
- upb_array *array = RepeatedField_GetMutable(_self);
341
- upb_msgval last;
341
+ size_t size = upb_Array_Size(self->array);
342
+ upb_Array* array = RepeatedField_GetMutable(_self);
343
+ upb_MessageValue last;
342
344
  VALUE ret;
343
345
 
344
346
  if (size == 0) {
345
347
  return Qnil;
346
348
  }
347
349
 
348
- last = upb_array_get(self->array, size - 1);
350
+ last = upb_Array_Get(self->array, size - 1);
349
351
  ret = Convert_UpbToRuby(last, self->type_info, self->arena);
350
352
 
351
- upb_array_resize(array, size - 1, Arena_get(self->arena));
353
+ upb_Array_Resize(array, size - 1, Arena_get(self->arena));
352
354
  return ret;
353
355
  }
354
356
 
@@ -360,11 +362,11 @@ static VALUE RepeatedField_pop_one(VALUE _self) {
360
362
  */
361
363
  static VALUE RepeatedField_replace(VALUE _self, VALUE list) {
362
364
  RepeatedField* self = ruby_to_RepeatedField(_self);
363
- upb_array *array = RepeatedField_GetMutable(_self);
365
+ upb_Array* array = RepeatedField_GetMutable(_self);
364
366
  int i;
365
367
 
366
368
  Check_Type(list, T_ARRAY);
367
- upb_array_resize(array, 0, Arena_get(self->arena));
369
+ upb_Array_Resize(array, 0, Arena_get(self->arena));
368
370
 
369
371
  for (i = 0; i < RARRAY_LEN(list); i++) {
370
372
  RepeatedField_push(_self, rb_ary_entry(list, i));
@@ -381,8 +383,8 @@ static VALUE RepeatedField_replace(VALUE _self, VALUE list) {
381
383
  */
382
384
  static VALUE RepeatedField_clear(VALUE _self) {
383
385
  RepeatedField* self = ruby_to_RepeatedField(_self);
384
- upb_array *array = RepeatedField_GetMutable(_self);
385
- upb_array_resize(array, 0, Arena_get(self->arena));
386
+ upb_Array* array = RepeatedField_GetMutable(_self);
387
+ upb_Array_Resize(array, 0, Arena_get(self->arena));
386
388
  return _self;
387
389
  }
388
390
 
@@ -394,7 +396,7 @@ static VALUE RepeatedField_clear(VALUE _self) {
394
396
  */
395
397
  static VALUE RepeatedField_length(VALUE _self) {
396
398
  RepeatedField* self = ruby_to_RepeatedField(_self);
397
- return INT2NUM(upb_array_size(self->array));
399
+ return INT2NUM(upb_Array_Size(self->array));
398
400
  }
399
401
 
400
402
  /*
@@ -408,16 +410,16 @@ static VALUE RepeatedField_dup(VALUE _self) {
408
410
  RepeatedField* self = ruby_to_RepeatedField(_self);
409
411
  VALUE new_rptfield = RepeatedField_new_this_type(self);
410
412
  RepeatedField* new_rptfield_self = ruby_to_RepeatedField(new_rptfield);
411
- upb_array *new_array = RepeatedField_GetMutable(new_rptfield);
412
- upb_arena* arena = Arena_get(new_rptfield_self->arena);
413
- int size = upb_array_size(self->array);
413
+ upb_Array* new_array = RepeatedField_GetMutable(new_rptfield);
414
+ upb_Arena* arena = Arena_get(new_rptfield_self->arena);
415
+ int size = upb_Array_Size(self->array);
414
416
  int i;
415
417
 
416
418
  Arena_fuse(self->arena, arena);
417
419
 
418
420
  for (i = 0; i < size; i++) {
419
- upb_msgval msgval = upb_array_get(self->array, i);
420
- upb_array_append(new_array, msgval, arena);
421
+ upb_MessageValue msgval = upb_Array_Get(self->array, i);
422
+ upb_Array_Append(new_array, msgval, arena);
421
423
  }
422
424
 
423
425
  return new_rptfield;
@@ -432,12 +434,12 @@ static VALUE RepeatedField_dup(VALUE _self) {
432
434
  */
433
435
  VALUE RepeatedField_to_ary(VALUE _self) {
434
436
  RepeatedField* self = ruby_to_RepeatedField(_self);
435
- int size = upb_array_size(self->array);
437
+ int size = upb_Array_Size(self->array);
436
438
  VALUE ary = rb_ary_new2(size);
437
439
  int i;
438
440
 
439
441
  for (i = 0; i < size; i++) {
440
- upb_msgval msgval = upb_array_get(self->array, i);
442
+ upb_MessageValue msgval = upb_Array_Get(self->array, i);
441
443
  VALUE val = Convert_UpbToRuby(msgval, self->type_info, self->arena);
442
444
  rb_ary_push(ary, val);
443
445
  }
@@ -473,17 +475,17 @@ VALUE RepeatedField_eq(VALUE _self, VALUE _other) {
473
475
 
474
476
  self = ruby_to_RepeatedField(_self);
475
477
  other = ruby_to_RepeatedField(_other);
476
- size_t n = upb_array_size(self->array);
478
+ size_t n = upb_Array_Size(self->array);
477
479
 
478
480
  if (self->type_info.type != other->type_info.type ||
479
481
  self->type_class != other->type_class ||
480
- upb_array_size(other->array) != n) {
482
+ upb_Array_Size(other->array) != n) {
481
483
  return Qfalse;
482
484
  }
483
485
 
484
486
  for (size_t i = 0; i < n; i++) {
485
- upb_msgval val1 = upb_array_get(self->array, i);
486
- upb_msgval val2 = upb_array_get(other->array, i);
487
+ upb_MessageValue val1 = upb_Array_Get(self->array, i);
488
+ upb_MessageValue val2 = upb_Array_Get(other->array, i);
487
489
  if (!Msgval_IsEqual(val1, val2, self->type_info)) {
488
490
  return Qfalse;
489
491
  }
@@ -492,19 +494,49 @@ VALUE RepeatedField_eq(VALUE _self, VALUE _other) {
492
494
  return Qtrue;
493
495
  }
494
496
 
497
+ /*
498
+ * call-seq:
499
+ * RepeatedField.frozen? => bool
500
+ *
501
+ * Returns true if the repeated field is frozen in either Ruby or the underlying
502
+ * representation. Freezes the Ruby repeated field object if it is not already
503
+ * frozen in Ruby but it is frozen in the underlying representation.
504
+ */
505
+ VALUE RepeatedField_frozen(VALUE _self) {
506
+ RepeatedField* self = ruby_to_RepeatedField(_self);
507
+ if (!upb_Array_IsFrozen(self->array)) {
508
+ PBRUBY_ASSERT(!RB_OBJ_FROZEN(_self));
509
+ return Qfalse;
510
+ }
511
+
512
+ // Lazily freeze the Ruby wrapper.
513
+ if (!RB_OBJ_FROZEN(_self)) RB_OBJ_FREEZE(_self);
514
+ return Qtrue;
515
+ }
516
+
495
517
  /*
496
518
  * call-seq:
497
519
  * RepeatedField.freeze => self
498
520
  *
499
- * Freezes the repeated field. We have to intercept this so we can pin the Ruby
500
- * object into memory so we don't forget it's frozen.
521
+ * Freezes the repeated field object. We have to intercept this so we can freeze
522
+ * the underlying representation, not just the Ruby wrapper.
501
523
  */
502
- static VALUE RepeatedField_freeze(VALUE _self) {
524
+ VALUE RepeatedField_freeze(VALUE _self) {
503
525
  RepeatedField* self = ruby_to_RepeatedField(_self);
504
- if (!RB_OBJ_FROZEN(_self)) {
505
- Arena_Pin(self->arena, _self);
506
- RB_OBJ_FREEZE(_self);
526
+ if (RB_OBJ_FROZEN(_self)) {
527
+ PBRUBY_ASSERT(upb_Array_IsFrozen(self->array));
528
+ return _self;
529
+ }
530
+
531
+ if (!upb_Array_IsFrozen(self->array)) {
532
+ if (self->type_info.type == kUpb_CType_Message) {
533
+ upb_Array_Freeze(RepeatedField_GetMutable(_self),
534
+ upb_MessageDef_MiniTable(self->type_info.def.msgdef));
535
+ } else {
536
+ upb_Array_Freeze(RepeatedField_GetMutable(_self), NULL);
537
+ }
507
538
  }
539
+ RB_OBJ_FREEZE(_self);
508
540
  return _self;
509
541
  }
510
542
 
@@ -517,10 +549,10 @@ static VALUE RepeatedField_freeze(VALUE _self) {
517
549
  VALUE RepeatedField_hash(VALUE _self) {
518
550
  RepeatedField* self = ruby_to_RepeatedField(_self);
519
551
  uint64_t hash = 0;
520
- size_t n = upb_array_size(self->array);
552
+ size_t n = upb_Array_Size(self->array);
521
553
 
522
554
  for (size_t i = 0; i < n; i++) {
523
- upb_msgval val = upb_array_get(self->array, i);
555
+ upb_MessageValue val = upb_Array_Get(self->array, i);
524
556
  hash = Msgval_GetHash(val, self->type_info, hash);
525
557
  }
526
558
 
@@ -549,10 +581,10 @@ VALUE RepeatedField_plus(VALUE _self, VALUE list) {
549
581
  RepeatedField* self = ruby_to_RepeatedField(_self);
550
582
  RepeatedField* list_rptfield = ruby_to_RepeatedField(list);
551
583
  RepeatedField* dupped = ruby_to_RepeatedField(dupped_);
552
- upb_array *dupped_array = RepeatedField_GetMutable(dupped_);
553
- upb_arena* arena = Arena_get(dupped->arena);
584
+ upb_Array* dupped_array = RepeatedField_GetMutable(dupped_);
585
+ upb_Arena* arena = Arena_get(dupped->arena);
554
586
  Arena_fuse(list_rptfield->arena, arena);
555
- int size = upb_array_size(list_rptfield->array);
587
+ int size = upb_Array_Size(list_rptfield->array);
556
588
  int i;
557
589
 
558
590
  if (self->type_info.type != list_rptfield->type_info.type ||
@@ -562,8 +594,8 @@ VALUE RepeatedField_plus(VALUE _self, VALUE list) {
562
594
  }
563
595
 
564
596
  for (i = 0; i < size; i++) {
565
- upb_msgval msgval = upb_array_get(list_rptfield->array, i);
566
- upb_array_append(dupped_array, msgval, arena);
597
+ upb_MessageValue msgval = upb_Array_Get(list_rptfield->array, i);
598
+ upb_Array_Append(dupped_array, msgval, arena);
567
599
  }
568
600
  } else {
569
601
  rb_raise(rb_eArgError, "Unknown type appending to RepeatedField");
@@ -601,7 +633,7 @@ VALUE RepeatedField_concat(VALUE _self, VALUE list) {
601
633
  */
602
634
  VALUE RepeatedField_init(int argc, VALUE* argv, VALUE _self) {
603
635
  RepeatedField* self = ruby_to_RepeatedField(_self);
604
- upb_arena *arena;
636
+ upb_Arena* arena;
605
637
  VALUE ary = Qnil;
606
638
 
607
639
  self->arena = Arena_new();
@@ -612,8 +644,9 @@ VALUE RepeatedField_init(int argc, VALUE* argv, VALUE _self) {
612
644
  }
613
645
 
614
646
  self->type_info = TypeInfo_FromClass(argc, argv, 0, &self->type_class, &ary);
615
- self->array = upb_array_new(arena, self->type_info.type);
616
- ObjectCache_Add(self->array, _self);
647
+ self->array = upb_Array_New(arena, self->type_info.type);
648
+ VALUE stored_val = ObjectCache_TryAdd(self->array, _self);
649
+ PBRUBY_ASSERT(stored_val == _self);
617
650
 
618
651
  if (ary != Qnil) {
619
652
  if (!RB_TYPE_P(ary, T_ARRAY)) {
@@ -627,14 +660,12 @@ VALUE RepeatedField_init(int argc, VALUE* argv, VALUE _self) {
627
660
  }
628
661
 
629
662
  void RepeatedField_register(VALUE module) {
630
- VALUE klass = rb_define_class_under(
631
- module, "RepeatedField", rb_cObject);
663
+ VALUE klass = rb_define_class_under(module, "RepeatedField", rb_cObject);
632
664
  rb_define_alloc_func(klass, RepeatedField_alloc);
633
665
  rb_gc_register_address(&cRepeatedField);
634
666
  cRepeatedField = klass;
635
667
 
636
- rb_define_method(klass, "initialize",
637
- RepeatedField_init, -1);
668
+ rb_define_method(klass, "initialize", RepeatedField_init, -1);
638
669
  rb_define_method(klass, "each", RepeatedField_each, 0);
639
670
  rb_define_method(klass, "[]", RepeatedField_index, -1);
640
671
  rb_define_method(klass, "at", RepeatedField_index, -1);
@@ -652,6 +683,7 @@ void RepeatedField_register(VALUE module) {
652
683
  rb_define_method(klass, "==", RepeatedField_eq, 1);
653
684
  rb_define_method(klass, "to_ary", RepeatedField_to_ary, 0);
654
685
  rb_define_method(klass, "freeze", RepeatedField_freeze, 0);
686
+ rb_define_method(klass, "frozen?", RepeatedField_frozen, 0);
655
687
  rb_define_method(klass, "hash", RepeatedField_hash, 0);
656
688
  rb_define_method(klass, "+", RepeatedField_plus, 1);
657
689
  rb_define_method(klass, "concat", RepeatedField_concat, 1);
@@ -1,54 +1,33 @@
1
1
  // Protocol Buffers - Google's data interchange format
2
2
  // Copyright 2008 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
30
7
 
31
8
  #ifndef RUBY_PROTOBUF_REPEATED_FIELD_H_
32
9
  #define RUBY_PROTOBUF_REPEATED_FIELD_H_
33
10
 
34
- #include <ruby/ruby.h>
35
-
36
11
  #include "protobuf.h"
37
12
  #include "ruby-upb.h"
38
13
 
39
- // Returns a Ruby wrapper object for the given upb_array, which will be created
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
+
18
+ // Returns a Ruby wrapper object for the given upb_Array, which will be created
40
19
  // if one does not exist already.
41
- VALUE RepeatedField_GetRubyWrapper(upb_array* msg, TypeInfo type_info,
20
+ VALUE RepeatedField_GetRubyWrapper(const upb_Array* msg, TypeInfo type_info,
42
21
  VALUE arena);
43
22
 
44
- // Gets the underlying upb_array for this Ruby RepeatedField object, which must
23
+ // Gets the underlying upb_Array for this Ruby RepeatedField object, which must
45
24
  // have a type that matches |f|. If this is not a repeated field or the type
46
25
  // doesn't match, raises an exception.
47
- const upb_array* RepeatedField_GetUpbArray(VALUE value, const upb_fielddef* f,
48
- upb_arena* arena);
26
+ const upb_Array* RepeatedField_GetUpbArray(VALUE value, const upb_FieldDef* f,
27
+ upb_Arena* arena);
49
28
 
50
29
  // Implements #inspect for this repeated field by appending its contents to |b|.
51
- void RepeatedField_Inspect(StringBuilder* b, const upb_array* array,
30
+ void RepeatedField_Inspect(StringBuilder* b, const upb_Array* array,
52
31
  TypeInfo info);
53
32
 
54
33
  // Returns a deep copy of this RepeatedField object.
@@ -60,4 +39,7 @@ extern VALUE cRepeatedField;
60
39
  // Call at startup to register all types in this module.
61
40
  void RepeatedField_register(VALUE module);
62
41
 
42
+ // Recursively freeze RepeatedField.
43
+ VALUE RepeatedField_freeze(VALUE _self);
44
+
63
45
  #endif // RUBY_PROTOBUF_REPEATED_FIELD_H_