google-protobuf 3.25.0.rc.2 → 4.26.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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/ext/google/protobuf_c/convert.c +7 -4
  3. data/ext/google/protobuf_c/defs.c +172 -24
  4. data/ext/google/protobuf_c/extconf.rb +1 -1
  5. data/ext/google/protobuf_c/glue.c +37 -2
  6. data/ext/google/protobuf_c/map.c +21 -8
  7. data/ext/google/protobuf_c/map.h +3 -0
  8. data/ext/google/protobuf_c/message.c +73 -71
  9. data/ext/google/protobuf_c/message.h +7 -0
  10. data/ext/google/protobuf_c/protobuf.c +19 -6
  11. data/ext/google/protobuf_c/repeated_field.c +14 -4
  12. data/ext/google/protobuf_c/repeated_field.h +3 -0
  13. data/ext/google/protobuf_c/ruby-upb.c +11788 -10795
  14. data/ext/google/protobuf_c/ruby-upb.h +5164 -4242
  15. data/ext/google/protobuf_c/shared_convert.c +5 -3
  16. data/ext/google/protobuf_c/shared_convert.h +2 -2
  17. data/ext/google/protobuf_c/shared_message.c +8 -6
  18. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.c +467 -0
  19. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +9 -8
  20. data/lib/google/protobuf/any_pb.rb +1 -22
  21. data/lib/google/protobuf/api_pb.rb +1 -24
  22. data/lib/google/protobuf/descriptor_pb.rb +2 -23
  23. data/lib/google/protobuf/duration_pb.rb +1 -22
  24. data/lib/google/protobuf/empty_pb.rb +1 -22
  25. data/lib/google/protobuf/ffi/descriptor.rb +11 -1
  26. data/lib/google/protobuf/ffi/descriptor_pool.rb +14 -9
  27. data/lib/google/protobuf/ffi/enum_descriptor.rb +11 -1
  28. data/lib/google/protobuf/ffi/ffi.rb +3 -1
  29. data/lib/google/protobuf/ffi/field_descriptor.rb +34 -15
  30. data/lib/google/protobuf/ffi/file_descriptor.rb +11 -12
  31. data/lib/google/protobuf/ffi/internal/convert.rb +7 -23
  32. data/lib/google/protobuf/ffi/map.rb +13 -0
  33. data/lib/google/protobuf/ffi/message.rb +20 -2
  34. data/lib/google/protobuf/ffi/object_cache.rb +3 -3
  35. data/lib/google/protobuf/ffi/oneof_descriptor.rb +18 -11
  36. data/lib/google/protobuf/ffi/repeated_field.rb +15 -133
  37. data/lib/google/protobuf/field_mask_pb.rb +1 -22
  38. data/lib/google/protobuf/internal/object_cache.rb +99 -0
  39. data/lib/google/protobuf/plugin_pb.rb +2 -24
  40. data/lib/google/protobuf/repeated_field.rb +1 -2
  41. data/lib/google/protobuf/source_context_pb.rb +1 -22
  42. data/lib/google/protobuf/struct_pb.rb +1 -22
  43. data/lib/google/protobuf/timestamp_pb.rb +1 -22
  44. data/lib/google/protobuf/type_pb.rb +1 -24
  45. data/lib/google/protobuf/wrappers_pb.rb +1 -22
  46. data/lib/google/protobuf.rb +1 -1
  47. data/lib/google/protobuf_ffi.rb +1 -2
  48. data/lib/google/protobuf_native.rb +0 -1
  49. data/lib/google/tasks/ffi.rake +43 -37
  50. metadata +10 -13
  51. data/ext/google/protobuf_c/third_party/utf8_range/naive.c +0 -92
  52. data/ext/google/protobuf_c/third_party/utf8_range/range2-neon.c +0 -157
  53. data/ext/google/protobuf_c/third_party/utf8_range/range2-sse.c +0 -170
  54. data/lib/google/protobuf/descriptor_dsl.rb +0 -465
  55. data/lib/google/protobuf/object_cache.rb +0 -97
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 505661946dbff838475e8429c5d92e69334ff5d50f98592cde20d25963cd7fe3
4
- data.tar.gz: 9c87020874a79b2e6218c3859767cd417fdd9d294fc5518964f35c9d165b765e
3
+ metadata.gz: 6b75ef03befb2ebc24da2bd1395901962c7b0ba053ebf3dbf9e48c4414e89452
4
+ data.tar.gz: 1ade6d79bcca36e4dafe613c0392c14d5cbadcb721c49cec0651699750b567a8
5
5
  SHA512:
6
- metadata.gz: 01d8116f7f598cd78e6b5a496ecfd27c085e306b3588bb8bb95efc267354b0677927527ba09db079f10418e63e89dc0950a5cfc78273a3a9e89a14dad047fecb
7
- data.tar.gz: 3a634b67704153433dfa3d8abaf5b6b54e0db179431edf3278edaa6efa70b1cb041c14bd0cc2183bda5f3fb2d9f118fd19c01403f7a9de22a19786200bbd9de5
6
+ metadata.gz: 87a7972ae24b8f883a5dd5fe215184afa703097f3252bc2a4a7e7306c09bdc6d23ce72ea3b0742b3e60928dc46a71fb85df600fc199802b5b8f0db88806204a9
7
+ data.tar.gz: cdda124179218236560080105ba0ed5f5dde5137a01fb9db8691533cc4bdcb907d076fe24685227928f3f41cdf456c82e9d067f38ed9a01f18289d6e26504467
@@ -141,7 +141,7 @@ upb_MessageValue Convert_RubyToUpb(VALUE value, const char* name,
141
141
  VALUE utf8 = rb_enc_from_encoding(rb_utf8_encoding());
142
142
  if (rb_obj_class(value) == rb_cSymbol) {
143
143
  value = rb_funcall(value, rb_intern("to_s"), 0);
144
- } else if (rb_obj_class(value) != rb_cString) {
144
+ } else if (!rb_obj_is_kind_of(value, rb_cString)) {
145
145
  rb_raise(cTypeError,
146
146
  "Invalid argument for string field '%s' (given %s).", name,
147
147
  rb_class2name(CLASS_OF(value)));
@@ -208,7 +208,8 @@ upb_MessageValue Convert_RubyToUpb(VALUE value, const char* name,
208
208
  }
209
209
  break;
210
210
  default:
211
- break;
211
+ rb_raise(cTypeError,
212
+ "Convert_RubyToUpb(): Unexpected type %d", (int)type_info.type);
212
213
  }
213
214
 
214
215
  return ret;
@@ -296,7 +297,8 @@ bool Msgval_IsEqual(upb_MessageValue val1, upb_MessageValue val2,
296
297
  if (upb_Status_IsOk(&status)) {
297
298
  return return_value;
298
299
  } else {
299
- rb_raise(rb_eRuntimeError, upb_Status_ErrorMessage(&status));
300
+ rb_raise(rb_eRuntimeError, "Msgval_IsEqual(): %s",
301
+ upb_Status_ErrorMessage(&status));
300
302
  }
301
303
  }
302
304
 
@@ -309,6 +311,7 @@ uint64_t Msgval_GetHash(upb_MessageValue val, TypeInfo type_info,
309
311
  if (upb_Status_IsOk(&status)) {
310
312
  return return_value;
311
313
  } else {
312
- rb_raise(rb_eRuntimeError, upb_Status_ErrorMessage(&status));
314
+ rb_raise(rb_eRuntimeError, "Msgval_GetHash(): %s",
315
+ upb_Status_ErrorMessage(&status));
313
316
  }
314
317
  }
@@ -44,7 +44,7 @@ static VALUE rb_str_maybe_null(const char* s) {
44
44
  }
45
45
  return rb_str_new2(s);
46
46
  }
47
-
47
+ static ID options_instancevar_interned;
48
48
  // -----------------------------------------------------------------------------
49
49
  // DescriptorPool.
50
50
  // -----------------------------------------------------------------------------
@@ -144,20 +144,26 @@ VALUE DescriptorPool_add_serialized_file(VALUE _self,
144
144
  * call-seq:
145
145
  * DescriptorPool.lookup(name) => descriptor
146
146
  *
147
- * Finds a Descriptor or EnumDescriptor by name and returns it, or nil if none
148
- * exists with the given name.
147
+ * Finds a Descriptor, EnumDescriptor or FieldDescriptor by name and returns it,
148
+ * or nil if none exists with the given name.
149
149
  */
150
150
  static VALUE DescriptorPool_lookup(VALUE _self, VALUE name) {
151
151
  DescriptorPool* self = ruby_to_DescriptorPool(_self);
152
152
  const char* name_str = get_str(name);
153
153
  const upb_MessageDef* msgdef;
154
154
  const upb_EnumDef* enumdef;
155
+ const upb_FieldDef* fielddef;
155
156
 
156
157
  msgdef = upb_DefPool_FindMessageByName(self->symtab, name_str);
157
158
  if (msgdef) {
158
159
  return get_msgdef_obj(_self, msgdef);
159
160
  }
160
161
 
162
+ fielddef = upb_DefPool_FindExtensionByName(self->symtab, name_str);
163
+ if (fielddef) {
164
+ return get_fielddef_obj(_self, fielddef);
165
+ }
166
+
161
167
  enumdef = upb_DefPool_FindEnumByName(self->symtab, name_str);
162
168
  if (enumdef) {
163
169
  return get_enumdef_obj(_self, enumdef);
@@ -192,6 +198,7 @@ static void DescriptorPool_register(VALUE module) {
192
198
 
193
199
  rb_gc_register_address(&generated_pool);
194
200
  generated_pool = rb_class_new_instance(0, NULL, klass);
201
+ options_instancevar_interned = rb_intern("options");
195
202
  }
196
203
 
197
204
  // -----------------------------------------------------------------------------
@@ -226,6 +233,35 @@ static Descriptor* ruby_to_Descriptor(VALUE val) {
226
233
  return ret;
227
234
  }
228
235
 
236
+ // Decode and return a frozen instance of a Descriptor Option for the given pool
237
+ static VALUE decode_options(VALUE self, const char* option_type, int size,
238
+ const char* bytes, VALUE descriptor_pool) {
239
+ VALUE options_rb = rb_ivar_get(self, options_instancevar_interned);
240
+ if (options_rb != Qnil) {
241
+ return options_rb;
242
+ }
243
+
244
+ static const char* prefix = "google.protobuf.";
245
+ char fullname
246
+ [/*strlen(prefix)*/ 16 +
247
+ /*strln(longest option type supported e.g. "MessageOptions")*/ 14 +
248
+ /*null terminator*/ 1];
249
+
250
+ snprintf(fullname, sizeof(fullname), "%s%s", prefix, option_type);
251
+ const upb_MessageDef* msgdef = upb_DefPool_FindMessageByName(
252
+ ruby_to_DescriptorPool(descriptor_pool)->symtab, fullname);
253
+ if (!msgdef) {
254
+ rb_raise(rb_eRuntimeError, "Cannot find %s in DescriptorPool", option_type);
255
+ }
256
+
257
+ VALUE desc_rb = get_msgdef_obj(descriptor_pool, msgdef);
258
+ const Descriptor* desc = ruby_to_Descriptor(desc_rb);
259
+
260
+ options_rb = Message_decode_bytes(size, bytes, 0, desc->klass, true);
261
+ rb_ivar_set(self, options_instancevar_interned, options_rb);
262
+ return options_rb;
263
+ }
264
+
229
265
  /*
230
266
  * call-seq:
231
267
  * Descriptor.new => descriptor
@@ -374,6 +410,26 @@ static VALUE Descriptor_msgclass(VALUE _self) {
374
410
  return self->klass;
375
411
  }
376
412
 
413
+ /*
414
+ * call-seq:
415
+ * Descriptor.options => options
416
+ *
417
+ * Returns the `MessageOptions` for this `Descriptor`.
418
+ */
419
+ static VALUE Descriptor_options(VALUE _self) {
420
+ Descriptor* self = ruby_to_Descriptor(_self);
421
+ const google_protobuf_MessageOptions* opts =
422
+ upb_MessageDef_Options(self->msgdef);
423
+ upb_Arena* arena = upb_Arena_New();
424
+ size_t size;
425
+ char* serialized =
426
+ google_protobuf_MessageOptions_serialize(opts, arena, &size);
427
+ VALUE message_options = decode_options(_self, "MessageOptions", size,
428
+ serialized, self->descriptor_pool);
429
+ upb_Arena_Free(arena);
430
+ return message_options;
431
+ }
432
+
377
433
  static void Descriptor_register(VALUE module) {
378
434
  VALUE klass = rb_define_class_under(module, "Descriptor", rb_cObject);
379
435
  rb_define_alloc_func(klass, Descriptor_alloc);
@@ -385,6 +441,7 @@ static void Descriptor_register(VALUE module) {
385
441
  rb_define_method(klass, "msgclass", Descriptor_msgclass, 0);
386
442
  rb_define_method(klass, "name", Descriptor_name, 0);
387
443
  rb_define_method(klass, "file_descriptor", Descriptor_file_descriptor, 0);
444
+ rb_define_method(klass, "options", Descriptor_options, 0);
388
445
  rb_include_module(klass, rb_mEnumerable);
389
446
  rb_gc_register_address(&cDescriptor);
390
447
  cDescriptor = klass;
@@ -432,7 +489,7 @@ static VALUE FileDescriptor_alloc(VALUE klass) {
432
489
  * call-seq:
433
490
  * FileDescriptor.new => file
434
491
  *
435
- * Returns a new file descriptor. The syntax must be set before it's passed
492
+ * Returns a new file descriptor. May
436
493
  * to a builder.
437
494
  */
438
495
  static VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie,
@@ -464,24 +521,20 @@ static VALUE FileDescriptor_name(VALUE _self) {
464
521
 
465
522
  /*
466
523
  * call-seq:
467
- * FileDescriptor.syntax => syntax
524
+ * FileDescriptor.options => options
468
525
  *
469
- * Returns this file descriptors syntax.
470
- *
471
- * Valid syntax versions are:
472
- * :proto2 or :proto3.
526
+ * Returns the `FileOptions` for this `FileDescriptor`.
473
527
  */
474
- static VALUE FileDescriptor_syntax(VALUE _self) {
528
+ static VALUE FileDescriptor_options(VALUE _self) {
475
529
  FileDescriptor* self = ruby_to_FileDescriptor(_self);
476
-
477
- switch (upb_FileDef_Syntax(self->filedef)) {
478
- case kUpb_Syntax_Proto3:
479
- return ID2SYM(rb_intern("proto3"));
480
- case kUpb_Syntax_Proto2:
481
- return ID2SYM(rb_intern("proto2"));
482
- default:
483
- return Qnil;
484
- }
530
+ const google_protobuf_FileOptions* opts = upb_FileDef_Options(self->filedef);
531
+ upb_Arena* arena = upb_Arena_New();
532
+ size_t size;
533
+ char* serialized = google_protobuf_FileOptions_serialize(opts, arena, &size);
534
+ VALUE file_options = decode_options(_self, "FileOptions", size, serialized,
535
+ self->descriptor_pool);
536
+ upb_Arena_Free(arena);
537
+ return file_options;
485
538
  }
486
539
 
487
540
  static void FileDescriptor_register(VALUE module) {
@@ -489,7 +542,7 @@ static void FileDescriptor_register(VALUE module) {
489
542
  rb_define_alloc_func(klass, FileDescriptor_alloc);
490
543
  rb_define_method(klass, "initialize", FileDescriptor_initialize, 3);
491
544
  rb_define_method(klass, "name", FileDescriptor_name, 0);
492
- rb_define_method(klass, "syntax", FileDescriptor_syntax, 0);
545
+ rb_define_method(klass, "options", FileDescriptor_options, 0);
493
546
  rb_gc_register_address(&cFileDescriptor);
494
547
  cFileDescriptor = klass;
495
548
  }
@@ -540,7 +593,7 @@ static VALUE FieldDescriptor_alloc(VALUE klass) {
540
593
 
541
594
  /*
542
595
  * call-seq:
543
- * EnumDescriptor.new(c_only_cookie, pool, ptr) => EnumDescriptor
596
+ * FieldDescriptor.new(c_only_cookie, pool, ptr) => FieldDescriptor
544
597
  *
545
598
  * Creates a descriptor wrapper object. May only be called from C.
546
599
  */
@@ -660,6 +713,28 @@ static VALUE FieldDescriptor_default(VALUE _self) {
660
713
  return Convert_UpbToRuby(default_val, TypeInfo_get(self->fielddef), Qnil);
661
714
  }
662
715
 
716
+ /*
717
+ * call-seq:
718
+ * FieldDescriptor.has_presence? => bool
719
+ *
720
+ * Returns whether this field tracks presence.
721
+ */
722
+ static VALUE FieldDescriptor_has_presence(VALUE _self) {
723
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
724
+ return upb_FieldDef_HasPresence(self->fielddef) ? Qtrue : Qfalse;
725
+ }
726
+
727
+ /*
728
+ * call-seq:
729
+ * FieldDescriptor.is_packed? => bool
730
+ *
731
+ * Returns whether this is a repeated field that uses packed encoding.
732
+ */
733
+ static VALUE FieldDescriptor_is_packed(VALUE _self) {
734
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
735
+ return upb_FieldDef_IsPacked(self->fielddef) ? Qtrue : Qfalse;
736
+ }
737
+
663
738
  /*
664
739
  * call-seq:
665
740
  * FieldDescriptor.json_name => json_name
@@ -786,7 +861,7 @@ static VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) {
786
861
  static VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) {
787
862
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
788
863
  const upb_MessageDef* m;
789
- const upb_MessageDef* msg = Message_Get(msg_rb, &m);
864
+ const upb_Message* msg = Message_Get(msg_rb, &m);
790
865
 
791
866
  if (m != upb_FieldDef_ContainingType(self->fielddef)) {
792
867
  rb_raise(cTypeError, "has method called on wrong message type");
@@ -806,7 +881,7 @@ static VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) {
806
881
  static VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb) {
807
882
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
808
883
  const upb_MessageDef* m;
809
- upb_MessageDef* msg = Message_GetMutable(msg_rb, &m);
884
+ upb_Message* msg = Message_GetMutable(msg_rb, &m);
810
885
 
811
886
  if (m != upb_FieldDef_ContainingType(self->fielddef)) {
812
887
  rb_raise(cTypeError, "has method called on wrong message type");
@@ -827,7 +902,7 @@ static VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb) {
827
902
  static VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) {
828
903
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
829
904
  const upb_MessageDef* m;
830
- upb_MessageDef* msg = Message_GetMutable(msg_rb, &m);
905
+ upb_Message* msg = Message_GetMutable(msg_rb, &m);
831
906
  upb_Arena* arena = Arena_get(Message_GetArena(msg_rb));
832
907
  upb_MessageValue msgval;
833
908
 
@@ -841,6 +916,25 @@ static VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) {
841
916
  return Qnil;
842
917
  }
843
918
 
919
+ /*
920
+ * call-seq:
921
+ * FieldDescriptor.options => options
922
+ *
923
+ * Returns the `FieldOptions` for this `FieldDescriptor`.
924
+ */
925
+ static VALUE FieldDescriptor_options(VALUE _self) {
926
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
927
+ const google_protobuf_FieldOptions* opts =
928
+ upb_FieldDef_Options(self->fielddef);
929
+ upb_Arena* arena = upb_Arena_New();
930
+ size_t size;
931
+ char* serialized = google_protobuf_FieldOptions_serialize(opts, arena, &size);
932
+ VALUE field_options = decode_options(_self, "FieldOptions", size, serialized,
933
+ self->descriptor_pool);
934
+ upb_Arena_Free(arena);
935
+ return field_options;
936
+ }
937
+
844
938
  static void FieldDescriptor_register(VALUE module) {
845
939
  VALUE klass = rb_define_class_under(module, "FieldDescriptor", rb_cObject);
846
940
  rb_define_alloc_func(klass, FieldDescriptor_alloc);
@@ -848,6 +942,8 @@ static void FieldDescriptor_register(VALUE module) {
848
942
  rb_define_method(klass, "name", FieldDescriptor_name, 0);
849
943
  rb_define_method(klass, "type", FieldDescriptor__type, 0);
850
944
  rb_define_method(klass, "default", FieldDescriptor_default, 0);
945
+ rb_define_method(klass, "has_presence?", FieldDescriptor_has_presence, 0);
946
+ rb_define_method(klass, "is_packed?", FieldDescriptor_is_packed, 0);
851
947
  rb_define_method(klass, "json_name", FieldDescriptor_json_name, 0);
852
948
  rb_define_method(klass, "label", FieldDescriptor_label, 0);
853
949
  rb_define_method(klass, "number", FieldDescriptor_number, 0);
@@ -857,6 +953,7 @@ static void FieldDescriptor_register(VALUE module) {
857
953
  rb_define_method(klass, "clear", FieldDescriptor_clear, 1);
858
954
  rb_define_method(klass, "get", FieldDescriptor_get, 1);
859
955
  rb_define_method(klass, "set", FieldDescriptor_set, 2);
956
+ rb_define_method(klass, "options", FieldDescriptor_options, 0);
860
957
  rb_gc_register_address(&cFieldDescriptor);
861
958
  cFieldDescriptor = klass;
862
959
  }
@@ -956,12 +1053,32 @@ static VALUE OneofDescriptor_each(VALUE _self) {
956
1053
  return Qnil;
957
1054
  }
958
1055
 
1056
+ /*
1057
+ * call-seq:
1058
+ * OneofDescriptor.options => options
1059
+ *
1060
+ * Returns the `OneofOptions` for this `OneofDescriptor`.
1061
+ */
1062
+ static VALUE OneOfDescriptor_options(VALUE _self) {
1063
+ OneofDescriptor* self = ruby_to_OneofDescriptor(_self);
1064
+ const google_protobuf_OneofOptions* opts =
1065
+ upb_OneofDef_Options(self->oneofdef);
1066
+ upb_Arena* arena = upb_Arena_New();
1067
+ size_t size;
1068
+ char* serialized = google_protobuf_OneofOptions_serialize(opts, arena, &size);
1069
+ VALUE oneof_options = decode_options(_self, "OneofOptions", size, serialized,
1070
+ self->descriptor_pool);
1071
+ upb_Arena_Free(arena);
1072
+ return oneof_options;
1073
+ }
1074
+
959
1075
  static void OneofDescriptor_register(VALUE module) {
960
1076
  VALUE klass = rb_define_class_under(module, "OneofDescriptor", rb_cObject);
961
1077
  rb_define_alloc_func(klass, OneofDescriptor_alloc);
962
1078
  rb_define_method(klass, "initialize", OneofDescriptor_initialize, 3);
963
1079
  rb_define_method(klass, "name", OneofDescriptor_name, 0);
964
1080
  rb_define_method(klass, "each", OneofDescriptor_each, 0);
1081
+ rb_define_method(klass, "options", OneOfDescriptor_options, 0);
965
1082
  rb_include_module(klass, rb_mEnumerable);
966
1083
  rb_gc_register_address(&cOneofDescriptor);
967
1084
  cOneofDescriptor = klass;
@@ -1047,6 +1164,17 @@ static VALUE EnumDescriptor_file_descriptor(VALUE _self) {
1047
1164
  upb_EnumDef_File(self->enumdef));
1048
1165
  }
1049
1166
 
1167
+ /*
1168
+ * call-seq:
1169
+ * EnumDescriptor.is_closed? => bool
1170
+ *
1171
+ * Returns whether this enum is open or closed.
1172
+ */
1173
+ static VALUE EnumDescriptor_is_closed(VALUE _self) {
1174
+ EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1175
+ return upb_EnumDef_IsClosed(self->enumdef) ? Qtrue : Qfalse;
1176
+ }
1177
+
1050
1178
  /*
1051
1179
  * call-seq:
1052
1180
  * EnumDescriptor.name => name
@@ -1131,6 +1259,24 @@ static VALUE EnumDescriptor_enummodule(VALUE _self) {
1131
1259
  return self->module;
1132
1260
  }
1133
1261
 
1262
+ /*
1263
+ * call-seq:
1264
+ * EnumDescriptor.options => options
1265
+ *
1266
+ * Returns the `EnumOptions` for this `EnumDescriptor`.
1267
+ */
1268
+ static VALUE EnumDescriptor_options(VALUE _self) {
1269
+ EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1270
+ const google_protobuf_EnumOptions* opts = upb_EnumDef_Options(self->enumdef);
1271
+ upb_Arena* arena = upb_Arena_New();
1272
+ size_t size;
1273
+ char* serialized = google_protobuf_EnumOptions_serialize(opts, arena, &size);
1274
+ VALUE enum_options = decode_options(_self, "EnumOptions", size, serialized,
1275
+ self->descriptor_pool);
1276
+ upb_Arena_Free(arena);
1277
+ return enum_options;
1278
+ }
1279
+
1134
1280
  static void EnumDescriptor_register(VALUE module) {
1135
1281
  VALUE klass = rb_define_class_under(module, "EnumDescriptor", rb_cObject);
1136
1282
  rb_define_alloc_func(klass, EnumDescriptor_alloc);
@@ -1141,6 +1287,8 @@ static void EnumDescriptor_register(VALUE module) {
1141
1287
  rb_define_method(klass, "each", EnumDescriptor_each, 0);
1142
1288
  rb_define_method(klass, "enummodule", EnumDescriptor_enummodule, 0);
1143
1289
  rb_define_method(klass, "file_descriptor", EnumDescriptor_file_descriptor, 0);
1290
+ rb_define_method(klass, "is_closed?", EnumDescriptor_is_closed, 0);
1291
+ rb_define_method(klass, "options", EnumDescriptor_options, 0);
1144
1292
  rb_include_module(klass, rb_mEnumerable);
1145
1293
  rb_gc_register_address(&cEnumDescriptor);
1146
1294
  cEnumDescriptor = klass;
@@ -22,7 +22,7 @@ $INCFLAGS += " -I$(srcdir)/third_party/utf8_range"
22
22
 
23
23
  $srcs = ["protobuf.c", "convert.c", "defs.c", "message.c",
24
24
  "repeated_field.c", "map.c", "ruby-upb.c", "wrap_memcpy.c",
25
- "naive.c", "range2-neon.c", "range2-sse.c", "shared_convert.c",
25
+ "utf8_range.c", "shared_convert.c",
26
26
  "shared_message.c"]
27
27
 
28
28
  create_makefile(ext_name)
@@ -14,8 +14,43 @@
14
14
  upb_Arena* Arena_create() { return upb_Arena_Init(NULL, 0, &upb_alloc_global); }
15
15
 
16
16
  google_protobuf_FileDescriptorProto* FileDescriptorProto_parse(
17
- const char* serialized_file_proto, size_t length) {
18
- upb_Arena* arena = Arena_create();
17
+ const char* serialized_file_proto, size_t length, upb_Arena* arena) {
19
18
  return google_protobuf_FileDescriptorProto_parse(serialized_file_proto,
20
19
  length, arena);
21
20
  }
21
+
22
+ char* EnumDescriptor_serialized_options(const upb_EnumDef* enumdef,
23
+ size_t* size, upb_Arena* arena) {
24
+ const google_protobuf_EnumOptions* opts = upb_EnumDef_Options(enumdef);
25
+ char* serialized = google_protobuf_EnumOptions_serialize(opts, arena, size);
26
+ return serialized;
27
+ }
28
+
29
+ char* FileDescriptor_serialized_options(const upb_FileDef* filedef,
30
+ size_t* size, upb_Arena* arena) {
31
+ const google_protobuf_FileOptions* opts = upb_FileDef_Options(filedef);
32
+ char* serialized = google_protobuf_FileOptions_serialize(opts, arena, size);
33
+ return serialized;
34
+ }
35
+
36
+ char* Descriptor_serialized_options(const upb_MessageDef* msgdef, size_t* size,
37
+ upb_Arena* arena) {
38
+ const google_protobuf_MessageOptions* opts = upb_MessageDef_Options(msgdef);
39
+ char* serialized =
40
+ google_protobuf_MessageOptions_serialize(opts, arena, size);
41
+ return serialized;
42
+ }
43
+
44
+ char* OneOfDescriptor_serialized_options(const upb_OneofDef* oneofdef,
45
+ size_t* size, upb_Arena* arena) {
46
+ const google_protobuf_OneofOptions* opts = upb_OneofDef_Options(oneofdef);
47
+ char* serialized = google_protobuf_OneofOptions_serialize(opts, arena, size);
48
+ return serialized;
49
+ }
50
+
51
+ char* FieldDescriptor_serialized_options(const upb_FieldDef* fielddef,
52
+ size_t* size, upb_Arena* arena) {
53
+ const google_protobuf_FieldOptions* opts = upb_FieldDef_Options(fielddef);
54
+ char* serialized = google_protobuf_FieldOptions_serialize(opts, arena, size);
55
+ return serialized;
56
+ }
@@ -38,9 +38,11 @@ static void Map_mark(void* _self) {
38
38
  rb_gc_mark(self->arena);
39
39
  }
40
40
 
41
+ static size_t Map_memsize(const void* _self) { return sizeof(Map); }
42
+
41
43
  const rb_data_type_t Map_type = {
42
44
  "Google::Protobuf::Map",
43
- {Map_mark, RUBY_DEFAULT_FREE, NULL},
45
+ {Map_mark, RUBY_DEFAULT_FREE, Map_memsize},
44
46
  .flags = RUBY_TYPED_FREE_IMMEDIATELY,
45
47
  };
46
48
 
@@ -212,7 +214,7 @@ static VALUE Map_merge_into_self(VALUE _self, VALUE hashmap) {
212
214
  Map* self = ruby_to_Map(_self);
213
215
  Map* other = ruby_to_Map(hashmap);
214
216
  upb_Arena* arena = Arena_get(self->arena);
215
- upb_Message* self_msg = Map_GetMutable(_self);
217
+ upb_Map* self_map = Map_GetMutable(_self);
216
218
 
217
219
  Arena_fuse(other->arena, arena);
218
220
 
@@ -225,7 +227,7 @@ static VALUE Map_merge_into_self(VALUE _self, VALUE hashmap) {
225
227
  size_t iter = kUpb_Map_Begin;
226
228
  upb_MessageValue key, val;
227
229
  while (upb_Map_Next(other->map, &key, &val, &iter)) {
228
- upb_Map_Set(self_msg, key, val, arena);
230
+ upb_Map_Set(self_map, key, val, arena);
229
231
  }
230
232
  } else {
231
233
  rb_raise(rb_eArgError, "Unknown type merging into Map");
@@ -444,7 +446,7 @@ static VALUE Map_delete(VALUE _self, VALUE key) {
444
446
  Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL);
445
447
  upb_MessageValue val_upb;
446
448
 
447
- if (upb_Map_Delete(self->map, key_upb, &val_upb)) {
449
+ if (upb_Map_Delete(Map_GetMutable(_self), key_upb, &val_upb)) {
448
450
  return Convert_UpbToRuby(val_upb, self->value_type_info, self->arena);
449
451
  } else {
450
452
  return Qnil;
@@ -563,11 +565,22 @@ VALUE Map_eq(VALUE _self, VALUE _other) {
563
565
  * Freezes the message object. We have to intercept this so we can pin the
564
566
  * Ruby object into memory so we don't forget it's frozen.
565
567
  */
566
- static VALUE Map_freeze(VALUE _self) {
568
+ VALUE Map_freeze(VALUE _self) {
567
569
  Map* self = ruby_to_Map(_self);
568
- if (!RB_OBJ_FROZEN(_self)) {
569
- Arena_Pin(self->arena, _self);
570
- RB_OBJ_FREEZE(_self);
570
+
571
+ if (RB_OBJ_FROZEN(_self)) return _self;
572
+ Arena_Pin(self->arena, _self);
573
+ RB_OBJ_FREEZE(_self);
574
+
575
+ if (self->value_type_info.type == kUpb_CType_Message) {
576
+ size_t iter = kUpb_Map_Begin;
577
+ upb_MessageValue key, val;
578
+
579
+ while (upb_Map_Next(self->map, &key, &val, &iter)) {
580
+ VALUE val_val =
581
+ Convert_UpbToRuby(val, self->value_type_info, self->arena);
582
+ Message_freeze(val_val);
583
+ }
571
584
  }
572
585
  return _self;
573
586
  }
@@ -38,4 +38,7 @@ extern VALUE cMap;
38
38
  // Call at startup to register all types in this module.
39
39
  void Map_register(VALUE module);
40
40
 
41
+ // Recursively freeze map
42
+ VALUE Map_freeze(VALUE _self);
43
+
41
44
  #endif // RUBY_PROTOBUF_MAP_H_