google-protobuf 4.27.2 → 4.35.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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/ext/google/protobuf_c/convert.c +32 -14
  3. data/ext/google/protobuf_c/defs.c +475 -133
  4. data/ext/google/protobuf_c/extconf.rb +20 -10
  5. data/ext/google/protobuf_c/glue.c +63 -0
  6. data/ext/google/protobuf_c/map.c +145 -56
  7. data/ext/google/protobuf_c/map.h +6 -2
  8. data/ext/google/protobuf_c/message.c +180 -97
  9. data/ext/google/protobuf_c/message.h +2 -2
  10. data/ext/google/protobuf_c/protobuf.c +14 -13
  11. data/ext/google/protobuf_c/protobuf.h +3 -15
  12. data/ext/google/protobuf_c/repeated_field.c +134 -53
  13. data/ext/google/protobuf_c/repeated_field.h +5 -1
  14. data/ext/google/protobuf_c/ruby-upb.c +14522 -12698
  15. data/ext/google/protobuf_c/ruby-upb.h +8273 -4619
  16. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.c +22 -282
  17. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +2 -1
  18. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range_neon.inc +117 -0
  19. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range_sse.inc +272 -0
  20. data/lib/google/protobuf/any_pb.rb +1 -1
  21. data/lib/google/protobuf/api_pb.rb +2 -2
  22. data/lib/google/protobuf/descriptor_pb.rb +6 -2
  23. data/lib/google/protobuf/duration_pb.rb +1 -1
  24. data/lib/google/protobuf/empty_pb.rb +1 -1
  25. data/lib/google/protobuf/ffi/descriptor.rb +11 -2
  26. data/lib/google/protobuf/ffi/descriptor_pool.rb +7 -1
  27. data/lib/google/protobuf/ffi/enum_descriptor.rb +10 -0
  28. data/lib/google/protobuf/ffi/ffi.rb +5 -2
  29. data/lib/google/protobuf/ffi/field_descriptor.rb +16 -0
  30. data/lib/google/protobuf/ffi/file_descriptor.rb +36 -0
  31. data/lib/google/protobuf/ffi/internal/arena.rb +0 -6
  32. data/lib/google/protobuf/ffi/internal/convert.rb +9 -6
  33. data/lib/google/protobuf/ffi/internal/pointer_helper.rb +2 -1
  34. data/lib/google/protobuf/ffi/map.rb +47 -23
  35. data/lib/google/protobuf/ffi/message.rb +188 -64
  36. data/lib/google/protobuf/ffi/method_descriptor.rb +11 -1
  37. data/lib/google/protobuf/ffi/oneof_descriptor.rb +10 -0
  38. data/lib/google/protobuf/ffi/repeated_field.rb +42 -16
  39. data/lib/google/protobuf/ffi/service_descriptor.rb +11 -1
  40. data/lib/google/protobuf/field_mask_pb.rb +1 -1
  41. data/lib/google/protobuf/message_exts.rb +4 -0
  42. data/lib/google/protobuf/plugin_pb.rb +1 -1
  43. data/lib/google/protobuf/source_context_pb.rb +1 -1
  44. data/lib/google/protobuf/struct_pb.rb +1 -1
  45. data/lib/google/protobuf/timestamp_pb.rb +1 -1
  46. data/lib/google/protobuf/type_pb.rb +1 -1
  47. data/lib/google/protobuf/wrappers_pb.rb +1 -1
  48. data/lib/google/protobuf_ffi.rb +3 -2
  49. data/lib/google/tasks/ffi.rake +1 -1
  50. metadata +29 -34
  51. data/ext/google/protobuf_c/wrap_memcpy.c +0 -29
@@ -80,11 +80,13 @@ const upb_Message* Message_Get(VALUE msg_rb, const upb_MessageDef** m) {
80
80
  }
81
81
 
82
82
  upb_Message* Message_GetMutable(VALUE msg_rb, const upb_MessageDef** m) {
83
- rb_check_frozen(msg_rb);
84
- return (upb_Message*)Message_Get(msg_rb, m);
83
+ const upb_Message* upb_msg = Message_Get(msg_rb, m);
84
+ Protobuf_CheckNotFrozen(msg_rb, upb_Message_IsFrozen(upb_msg));
85
+ return (upb_Message*)upb_msg;
85
86
  }
86
87
 
87
- void Message_InitPtr(VALUE self_, upb_Message* msg, VALUE arena) {
88
+ void Message_InitPtr(VALUE self_, const upb_Message* msg, VALUE arena) {
89
+ PBRUBY_ASSERT(arena != Qnil);
88
90
  Message* self = ruby_to_Message(self_);
89
91
  self->msg = msg;
90
92
  RB_OBJ_WRITE(self_, &self->arena, arena);
@@ -105,7 +107,7 @@ void Message_CheckClass(VALUE klass) {
105
107
  }
106
108
  }
107
109
 
108
- VALUE Message_GetRubyWrapper(upb_Message* msg, const upb_MessageDef* m,
110
+ VALUE Message_GetRubyWrapper(const upb_Message* msg, const upb_MessageDef* m,
109
111
  VALUE arena) {
110
112
  if (msg == NULL) return Qnil;
111
113
 
@@ -116,7 +118,6 @@ VALUE Message_GetRubyWrapper(upb_Message* msg, const upb_MessageDef* m,
116
118
  val = Message_alloc(klass);
117
119
  Message_InitPtr(val, msg, arena);
118
120
  }
119
-
120
121
  return val;
121
122
  }
122
123
 
@@ -248,7 +249,7 @@ static int extract_method_call(VALUE method_name, Message* self,
248
249
  static VALUE Message_oneof_accessor(VALUE _self, const upb_OneofDef* o,
249
250
  int accessor_type) {
250
251
  Message* self = ruby_to_Message(_self);
251
- const upb_FieldDef* oneof_field = upb_Message_WhichOneof(self->msg, o);
252
+ const upb_FieldDef* oneof_field = upb_Message_WhichOneofByDef(self->msg, o);
252
253
 
253
254
  switch (accessor_type) {
254
255
  case METHOD_PRESENCE:
@@ -288,13 +289,42 @@ static void Message_setfield(upb_Message* msg, const upb_FieldDef* f, VALUE val,
288
289
  upb_Message_SetFieldByDef(msg, f, msgval, arena);
289
290
  }
290
291
 
292
+ VALUE Message_getfield_frozen(const upb_Message* msg, const upb_FieldDef* f,
293
+ VALUE arena) {
294
+ upb_MessageValue msgval = upb_Message_GetFieldByDef(msg, f);
295
+ if (upb_FieldDef_IsMap(f)) {
296
+ if (msgval.map_val == NULL) {
297
+ return Map_EmptyFrozen(f);
298
+ }
299
+ const upb_FieldDef* key_f = map_field_key(f);
300
+ const upb_FieldDef* val_f = map_field_value(f);
301
+ upb_CType key_type = upb_FieldDef_CType(key_f);
302
+ TypeInfo value_type_info = TypeInfo_get(val_f);
303
+ return Map_GetRubyWrapper(msgval.map_val, key_type, value_type_info, arena);
304
+ }
305
+ if (upb_FieldDef_IsRepeated(f)) {
306
+ if (msgval.array_val == NULL) {
307
+ return RepeatedField_EmptyFrozen(f);
308
+ }
309
+ return RepeatedField_GetRubyWrapper(msgval.array_val, TypeInfo_get(f),
310
+ arena);
311
+ }
312
+ VALUE ret;
313
+ if (upb_FieldDef_IsSubMessage(f)) {
314
+ const upb_MessageDef* m = upb_FieldDef_MessageSubDef(f);
315
+ ret = Message_GetRubyWrapper(msgval.msg_val, m, arena);
316
+ } else {
317
+ ret = Convert_UpbToRuby(msgval, TypeInfo_get(f), Qnil);
318
+ }
319
+ return ret;
320
+ }
321
+
291
322
  VALUE Message_getfield(VALUE _self, const upb_FieldDef* f) {
292
323
  Message* self = ruby_to_Message(_self);
293
- // This is a special-case: upb_Message_Mutable() for map & array are logically
294
- // const (they will not change what is serialized) but physically
295
- // non-const, as they do allocate a repeated field or map. The logical
296
- // constness means it's ok to do even if the message is frozen.
297
- upb_Message* msg = (upb_Message*)self->msg;
324
+ if (upb_Message_IsFrozen(self->msg)) {
325
+ return Message_getfield_frozen(self->msg, f, self->arena);
326
+ }
327
+ upb_Message* msg = Message_GetMutable(_self, NULL);
298
328
  upb_Arena* arena = Arena_get(self->arena);
299
329
  if (upb_FieldDef_IsMap(f)) {
300
330
  upb_Map* map = upb_Message_Mutable(msg, f, arena).map;
@@ -307,12 +337,12 @@ VALUE Message_getfield(VALUE _self, const upb_FieldDef* f) {
307
337
  upb_Array* arr = upb_Message_Mutable(msg, f, arena).array;
308
338
  return RepeatedField_GetRubyWrapper(arr, TypeInfo_get(f), self->arena);
309
339
  } else if (upb_FieldDef_IsSubMessage(f)) {
310
- if (!upb_Message_HasFieldByDef(self->msg, f)) return Qnil;
340
+ if (!upb_Message_HasFieldByDef(msg, f)) return Qnil;
311
341
  upb_Message* submsg = upb_Message_Mutable(msg, f, arena).msg;
312
342
  const upb_MessageDef* m = upb_FieldDef_MessageSubDef(f);
313
343
  return Message_GetRubyWrapper(submsg, m, self->arena);
314
344
  } else {
315
- upb_MessageValue msgval = upb_Message_GetFieldByDef(self->msg, f);
345
+ upb_MessageValue msgval = upb_Message_GetFieldByDef(msg, f);
316
346
  return Convert_UpbToRuby(msgval, TypeInfo_get(f), self->arena);
317
347
  }
318
348
  }
@@ -332,7 +362,8 @@ static VALUE Message_field_accessor(VALUE _self, const upb_FieldDef* f,
332
362
  if (!upb_FieldDef_HasPresence(f)) {
333
363
  rb_raise(rb_eRuntimeError, "Field does not have presence.");
334
364
  }
335
- return upb_Message_HasFieldByDef(Message_Get(_self, NULL), f);
365
+ return upb_Message_HasFieldByDef(Message_Get(_self, NULL), f) ? Qtrue
366
+ : Qfalse;
336
367
  case METHOD_WRAPPER_GETTER: {
337
368
  Message* self = ruby_to_Message(_self);
338
369
  if (upb_Message_HasFieldByDef(self->msg, f)) {
@@ -367,7 +398,7 @@ static VALUE Message_field_accessor(VALUE _self, const upb_FieldDef* f,
367
398
  upb_MessageValue msgval =
368
399
  upb_Message_GetFieldByDef(Message_Get(_self, NULL), f);
369
400
 
370
- if (upb_FieldDef_Label(f) == kUpb_Label_Repeated) {
401
+ if (upb_FieldDef_IsRepeated(f)) {
371
402
  // Map repeated fields to a new type with ints
372
403
  VALUE arr = rb_ary_new();
373
404
  size_t i, n = upb_Array_Size(msgval.array_val);
@@ -389,11 +420,10 @@ static VALUE Message_field_accessor(VALUE _self, const upb_FieldDef* f,
389
420
  }
390
421
 
391
422
  /*
392
- * call-seq:
393
- * Message.method_missing(*args)
423
+ * ruby-doc: AbstractMessage
394
424
  *
395
- * Provides accessors and setters and methods to clear and check for presence of
396
- * message fields according to their field names.
425
+ * The {AbstractMessage} class is the parent class for all Protobuf messages,
426
+ * and is generated from C code.
397
427
  *
398
428
  * For any field whose name does not conflict with a built-in method, an
399
429
  * accessor is provided with the same name as the field, and a setter is
@@ -436,7 +466,6 @@ static VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) {
436
466
  if (argc != 2) {
437
467
  rb_raise(rb_eArgError, "Expected 2 arguments, received %d", argc);
438
468
  }
439
- rb_check_frozen(_self);
440
469
  break;
441
470
  default:
442
471
  if (argc != 1) {
@@ -562,7 +591,7 @@ static void Message_InitFieldFromValue(upb_Message* msg, const upb_FieldDef* f,
562
591
  if (upb_FieldDef_IsMap(f)) {
563
592
  upb_Map* map = upb_Message_Mutable(msg, f, arena).map;
564
593
  Map_InitFromValue(map, f, val, arena);
565
- } else if (upb_FieldDef_Label(f) == kUpb_Label_Repeated) {
594
+ } else if (upb_FieldDef_IsRepeated(f)) {
566
595
  upb_Array* arr = upb_Message_Mutable(msg, f, arena).array;
567
596
  RepeatedField_InitFromValue(arr, f, val, arena);
568
597
  } else if (upb_FieldDef_IsSubMessage(f)) {
@@ -623,16 +652,12 @@ void Message_InitFromValue(upb_Message* msg, const upb_MessageDef* m, VALUE val,
623
652
  }
624
653
 
625
654
  /*
626
- * call-seq:
627
- * Message.new(kwargs) => new_message
655
+ * ruby-doc: AbstractMessage#initialize
628
656
  *
629
657
  * Creates a new instance of the given message class. Keyword arguments may be
630
658
  * provided with keywords corresponding to field names.
631
659
  *
632
- * Note that no literal Message class exists. Only concrete classes per message
633
- * type exist, as provided by the #msgclass method on Descriptors after they
634
- * have been added to a pool. The method definitions described here on the
635
- * Message class are provided on each concrete message class.
660
+ * @param kwargs the list of field keys and values.
636
661
  */
637
662
  static VALUE Message_initialize(int argc, VALUE* argv, VALUE _self) {
638
663
  Message* self = ruby_to_Message(_self);
@@ -654,10 +679,11 @@ static VALUE Message_initialize(int argc, VALUE* argv, VALUE _self) {
654
679
  }
655
680
 
656
681
  /*
657
- * call-seq:
658
- * Message.dup => new_message
682
+ * ruby-doc: AbstractMessage#dup
659
683
  *
660
684
  * Performs a shallow copy of this message and returns the new copy.
685
+ *
686
+ * @return [AbstractMessage]
661
687
  */
662
688
  static VALUE Message_dup(VALUE _self) {
663
689
  Message* self = ruby_to_Message(_self);
@@ -670,13 +696,15 @@ static VALUE Message_dup(VALUE _self) {
670
696
  }
671
697
 
672
698
  /*
673
- * call-seq:
674
- * Message.==(other) => boolean
699
+ * ruby-doc: AbstractMessage#==
675
700
  *
676
701
  * Performs a deep comparison of this message with another. Messages are equal
677
702
  * if they have the same type and if each field is equal according to the :==
678
703
  * method's semantics (a more efficient comparison may actually be done if the
679
704
  * field is of a primitive type).
705
+ *
706
+ * @param other [AbstractMessage]
707
+ * @return [Boolean]
680
708
  */
681
709
  static VALUE Message_eq(VALUE _self, VALUE _other) {
682
710
  if (CLASS_OF(_self) != CLASS_OF(_other)) return Qfalse;
@@ -705,10 +733,11 @@ uint64_t Message_Hash(const upb_Message* msg, const upb_MessageDef* m,
705
733
  }
706
734
 
707
735
  /*
708
- * call-seq:
709
- * Message.hash => hash_value
736
+ * ruby-doc: AbstractMessage#hash
710
737
  *
711
738
  * Returns a hash value that represents this message's field values.
739
+ *
740
+ * @return [Integer]
712
741
  */
713
742
  static VALUE Message_hash(VALUE _self) {
714
743
  Message* self = ruby_to_Message(_self);
@@ -719,12 +748,13 @@ static VALUE Message_hash(VALUE _self) {
719
748
  }
720
749
 
721
750
  /*
722
- * call-seq:
723
- * Message.inspect => string
751
+ * ruby-doc: AbstractMessage#inspect
724
752
  *
725
753
  * Returns a human-readable string representing this message. It will be
726
754
  * formatted as "<MessageType: field1: value1, field2: value2, ...>". Each
727
755
  * field's value is represented according to its own #inspect method.
756
+ *
757
+ * @return [String]
728
758
  */
729
759
  static VALUE Message_inspect(VALUE _self) {
730
760
  Message* self = ruby_to_Message(_self);
@@ -800,10 +830,11 @@ VALUE Scalar_CreateHash(upb_MessageValue msgval, TypeInfo type_info) {
800
830
  }
801
831
 
802
832
  /*
803
- * call-seq:
804
- * Message.to_h => {}
833
+ * ruby-doc: AbstractMessage#to_h
805
834
  *
806
835
  * Returns the message as a Ruby Hash object, with keys as symbols.
836
+ *
837
+ * @return [Hash]
807
838
  */
808
839
  static VALUE Message_to_h(VALUE _self) {
809
840
  Message* self = ruby_to_Message(_self);
@@ -811,43 +842,56 @@ static VALUE Message_to_h(VALUE _self) {
811
842
  }
812
843
 
813
844
  /*
814
- * call-seq:
815
- * Message.freeze => self
845
+ * ruby-doc: AbstractMessage#frozen?
846
+ *
847
+ * Returns true if the message is frozen in either Ruby or the underlying
848
+ * representation. Freezes the Ruby message object if it is not already frozen
849
+ * in Ruby but it is frozen in the underlying representation.
816
850
  *
817
- * Freezes the message object. We have to intercept this so we can pin the
818
- * Ruby object into memory so we don't forget it's frozen.
851
+ * @return [Boolean]
819
852
  */
820
- VALUE Message_freeze(VALUE _self) {
853
+ VALUE Message_frozen(VALUE _self) {
821
854
  Message* self = ruby_to_Message(_self);
855
+ if (!upb_Message_IsFrozen(self->msg)) {
856
+ PBRUBY_ASSERT(!RB_OBJ_FROZEN(_self));
857
+ return Qfalse;
858
+ }
822
859
 
823
- if (RB_OBJ_FROZEN(_self)) return _self;
824
- Arena_Pin(self->arena, _self);
825
- RB_OBJ_FREEZE(_self);
860
+ // Lazily freeze the Ruby wrapper.
861
+ if (!RB_OBJ_FROZEN(_self)) RB_OBJ_FREEZE(_self);
862
+ return Qtrue;
863
+ }
826
864
 
827
- int n = upb_MessageDef_FieldCount(self->msgdef);
828
- for (int i = 0; i < n; i++) {
829
- const upb_FieldDef* f = upb_MessageDef_Field(self->msgdef, i);
830
- VALUE field = Message_getfield(_self, f);
831
-
832
- if (field != Qnil) {
833
- if (upb_FieldDef_IsMap(f)) {
834
- Map_freeze(field);
835
- } else if (upb_FieldDef_IsRepeated(f)) {
836
- RepeatedField_freeze(field);
837
- } else if (upb_FieldDef_IsSubMessage(f)) {
838
- Message_freeze(field);
839
- }
840
- }
865
+ /*
866
+ * ruby-doc: AbstractMessage#freeze
867
+ *
868
+ * Freezes the message object. We have to intercept this so we can freeze the
869
+ * underlying representation, not just the Ruby wrapper.
870
+ *
871
+ * @return [self]
872
+ */
873
+ VALUE Message_freeze(VALUE _self) {
874
+ Message* self = ruby_to_Message(_self);
875
+ if (RB_OBJ_FROZEN(_self)) {
876
+ PBRUBY_ASSERT(upb_Message_IsFrozen(self->msg));
877
+ return _self;
841
878
  }
879
+ if (!upb_Message_IsFrozen(self->msg)) {
880
+ upb_Message_Freeze(Message_GetMutable(_self, NULL),
881
+ upb_MessageDef_MiniTable(self->msgdef));
882
+ }
883
+ RB_OBJ_FREEZE(_self);
842
884
  return _self;
843
885
  }
844
886
 
845
887
  /*
846
- * call-seq:
847
- * Message.[](index) => value
888
+ * ruby-doc: AbstractMessage#[]
848
889
  *
849
890
  * Accesses a field's value by field name. The provided field name should be a
850
891
  * string.
892
+ *
893
+ * @param index [Integer]
894
+ * @return [Object]
851
895
  */
852
896
  static VALUE Message_index(VALUE _self, VALUE field_name) {
853
897
  Message* self = ruby_to_Message(_self);
@@ -864,11 +908,14 @@ static VALUE Message_index(VALUE _self, VALUE field_name) {
864
908
  }
865
909
 
866
910
  /*
867
- * call-seq:
868
- * Message.[]=(index, value)
911
+ * ruby-doc: AbstractMessage#[]=
869
912
  *
870
913
  * Sets a field's value by field name. The provided field name should be a
871
914
  * string.
915
+ *
916
+ * @param index [Integer]
917
+ * @param value [Object]
918
+ * @return [nil]
872
919
  */
873
920
  static VALUE Message_index_set(VALUE _self, VALUE field_name, VALUE value) {
874
921
  Message* self = ruby_to_Message(_self);
@@ -890,14 +937,16 @@ static VALUE Message_index_set(VALUE _self, VALUE field_name, VALUE value) {
890
937
  }
891
938
 
892
939
  /*
893
- * call-seq:
894
- * MessageClass.decode(data, options) => message
940
+ * ruby-doc: AbstractMessage.decode
895
941
  *
896
942
  * Decodes the given data (as a string containing bytes in protocol buffers wire
897
943
  * format) under the interpretation given by this message class's definition
898
944
  * and returns a message object with the corresponding field values.
899
- * @param options [Hash] options for the decoder
900
- * recursion_limit: set to maximum decoding depth for message (default is 64)
945
+ * @param data [String]
946
+ * @param options [Hash]
947
+ * @option recursion_limit [Integer] set to maximum decoding depth for message
948
+ * (default is 64)
949
+ * @return [AbstractMessage]
901
950
  */
902
951
  static VALUE Message_decode(int argc, VALUE* argv, VALUE klass) {
903
952
  VALUE data = argv[0];
@@ -929,7 +978,7 @@ static VALUE Message_decode(int argc, VALUE* argv, VALUE klass) {
929
978
  klass, /*freeze*/ false);
930
979
  }
931
980
 
932
- VALUE Message_decode_bytes(int size, const char* bytes, int options,
981
+ VALUE Message_decode_bytes(size_t size, const char* bytes, int options,
933
982
  VALUE klass, bool freeze) {
934
983
  VALUE msg_rb = initialize_rb_class_with_no_args(klass);
935
984
  Message* msg = ruby_to_Message(msg_rb);
@@ -950,16 +999,17 @@ VALUE Message_decode_bytes(int size, const char* bytes, int options,
950
999
  }
951
1000
 
952
1001
  /*
953
- * call-seq:
954
- * MessageClass.decode_json(data, options = {}) => message
1002
+ * ruby-doc: AbstractMessage.decode_json
955
1003
  *
956
1004
  * Decodes the given data (as a string containing bytes in protocol buffers wire
957
1005
  * format) under the interpretration given by this message class's definition
958
1006
  * and returns a message object with the corresponding field values.
959
1007
  *
960
- * @param options [Hash] options for the decoder
961
- * ignore_unknown_fields: set true to ignore unknown fields (default is to
962
- * raise an error)
1008
+ * @param data [String]
1009
+ * @param options [Hash]
1010
+ * @option ignore_unknown_fields [Boolean] set true to ignore unknown fields
1011
+ * (default is to raise an error)
1012
+ * @return [AbstractMessage]
963
1013
  */
964
1014
  static VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) {
965
1015
  VALUE data = argv[0];
@@ -1000,24 +1050,34 @@ static VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) {
1000
1050
 
1001
1051
  upb_Status_Clear(&status);
1002
1052
  const upb_DefPool* pool = upb_FileDef_Pool(upb_MessageDef_File(msg->msgdef));
1003
- if (!upb_JsonDecode(RSTRING_PTR(data), RSTRING_LEN(data),
1004
- (upb_Message*)msg->msg, msg->msgdef, pool, options,
1005
- Arena_get(msg->arena), &status)) {
1006
- rb_raise(cParseError, "Error occurred during parsing: %s",
1007
- upb_Status_ErrorMessage(&status));
1053
+
1054
+ int result = upb_JsonDecodeDetectingNonconformance(
1055
+ RSTRING_PTR(data), RSTRING_LEN(data), (upb_Message*)msg->msg,
1056
+ msg->msgdef, pool, options, Arena_get(msg->arena), &status);
1057
+
1058
+ switch (result) {
1059
+ case kUpb_JsonDecodeResult_Ok:
1060
+ break;
1061
+ case kUpb_JsonDecodeResult_Error:
1062
+ rb_raise(cParseError, "Error occurred during parsing: %s",
1063
+ upb_Status_ErrorMessage(&status));
1064
+ break;
1008
1065
  }
1009
1066
 
1010
1067
  return msg_rb;
1011
1068
  }
1012
1069
 
1013
1070
  /*
1014
- * call-seq:
1015
- * MessageClass.encode(msg, options) => bytes
1071
+ * ruby-doc: AbstractMessage.encode
1016
1072
  *
1017
1073
  * Encodes the given message object to its serialized form in protocol buffers
1018
1074
  * wire format.
1019
- * @param options [Hash] options for the encoder
1020
- * recursion_limit: set to maximum encoding depth for message (default is 64)
1075
+ *
1076
+ * @param msg [AbstractMessage]
1077
+ * @param options [Hash]
1078
+ * @option recursion_limit [Integer] set to maximum encoding depth for message
1079
+ * (default is 64)
1080
+ * @return [String]
1021
1081
  */
1022
1082
  static VALUE Message_encode(int argc, VALUE* argv, VALUE klass) {
1023
1083
  Message* msg = ruby_to_Message(argv[0]);
@@ -1064,14 +1124,17 @@ static VALUE Message_encode(int argc, VALUE* argv, VALUE klass) {
1064
1124
  }
1065
1125
 
1066
1126
  /*
1067
- * call-seq:
1068
- * MessageClass.encode_json(msg, options = {}) => json_string
1127
+ * ruby-doc: AbstractMessage.encode_json
1069
1128
  *
1070
1129
  * Encodes the given message object into its serialized JSON representation.
1071
- * @param options [Hash] options for the decoder
1072
- * preserve_proto_fieldnames: set true to use original fieldnames (default is
1073
- * to camelCase) emit_defaults: set true to emit 0/false values (default is to
1074
- * omit them)
1130
+ *
1131
+ * @param msg [AbstractMessage]
1132
+ * @param options [Hash]
1133
+ * @option preserve_proto_fieldnames [Boolean] set true to use original
1134
+ * fieldnames (default is to camelCase)
1135
+ * @option emit_defaults [Boolean] set true to emit 0/false values (default is
1136
+ * to omit them)
1137
+ * @return [String]
1075
1138
  */
1076
1139
  static VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
1077
1140
  Message* msg = ruby_to_Message(argv[0]);
@@ -1139,11 +1202,12 @@ static VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
1139
1202
  }
1140
1203
 
1141
1204
  /*
1142
- * call-seq:
1143
- * Message.descriptor => descriptor
1205
+ * ruby-doc: AbstractMessage.descriptor
1144
1206
  *
1145
1207
  * Class method that returns the Descriptor instance corresponding to this
1146
1208
  * message class's type.
1209
+ *
1210
+ * @return [Descriptor]
1147
1211
  */
1148
1212
  static VALUE Message_descriptor(VALUE klass) {
1149
1213
  return rb_ivar_get(klass, descriptor_instancevar_interned);
@@ -1166,12 +1230,26 @@ VALUE build_class_from_descriptor(VALUE descriptor) {
1166
1230
  return klass;
1167
1231
  }
1168
1232
 
1233
+ /* ruby-doc: Enum
1234
+ *
1235
+ * There isn't really a concrete `Enum` module generated by Protobuf. Instead,
1236
+ * you can use this documentation as an indicator of methods that are defined on
1237
+ * each `Enum` module that is generated. E.g. if you have:
1238
+ *
1239
+ * enum my_enum_type
1240
+ *
1241
+ * in your Proto file and generate Ruby code, a module
1242
+ * called `MyEnumType` will be generated with the following methods available.
1243
+ */
1244
+
1169
1245
  /*
1170
- * call-seq:
1171
- * Enum.lookup(number) => name
1246
+ * ruby-doc: Enum.lookup
1172
1247
  *
1173
1248
  * This module method, provided on each generated enum module, looks up an enum
1174
1249
  * value by number and returns its name as a Ruby symbol, or nil if not found.
1250
+ *
1251
+ * @param number [Integer]
1252
+ * @return [String]
1175
1253
  */
1176
1254
  static VALUE enum_lookup(VALUE self, VALUE number) {
1177
1255
  int32_t num = NUM2INT(number);
@@ -1186,11 +1264,13 @@ static VALUE enum_lookup(VALUE self, VALUE number) {
1186
1264
  }
1187
1265
 
1188
1266
  /*
1189
- * call-seq:
1190
- * Enum.resolve(name) => number
1267
+ * ruby-doc: Enum.resolve
1191
1268
  *
1192
1269
  * This module method, provided on each generated enum module, looks up an enum
1193
1270
  * value by name (as a Ruby symbol) and returns its name, or nil if not found.
1271
+ *
1272
+ * @param name [String]
1273
+ * @return [Integer]
1194
1274
  */
1195
1275
  static VALUE enum_resolve(VALUE self, VALUE sym) {
1196
1276
  const char* name = rb_id2name(SYM2ID(sym));
@@ -1205,11 +1285,13 @@ static VALUE enum_resolve(VALUE self, VALUE sym) {
1205
1285
  }
1206
1286
 
1207
1287
  /*
1208
- * call-seq:
1209
- * Enum.descriptor
1288
+ * ruby-doc: Enum.descriptor
1210
1289
  *
1211
1290
  * This module method, provided on each generated enum module, returns the
1212
- * EnumDescriptor corresponding to this enum type.
1291
+ * {EnumDescriptor} corresponding to this enum type.
1292
+ *
1293
+ * @return [EnumDescriptor]
1294
+ *
1213
1295
  */
1214
1296
  static VALUE enum_descriptor(VALUE self) {
1215
1297
  return rb_ivar_get(self, descriptor_instancevar_interned);
@@ -1352,6 +1434,7 @@ static void Message_define_class(VALUE klass) {
1352
1434
  rb_define_method(klass, "==", Message_eq, 1);
1353
1435
  rb_define_method(klass, "eql?", Message_eq, 1);
1354
1436
  rb_define_method(klass, "freeze", Message_freeze, 0);
1437
+ rb_define_method(klass, "frozen?", Message_frozen, 0);
1355
1438
  rb_define_method(klass, "hash", Message_hash, 0);
1356
1439
  rb_define_method(klass, "to_h", Message_to_h, 0);
1357
1440
  rb_define_method(klass, "inspect", Message_inspect, 0);
@@ -36,7 +36,7 @@ const upb_Message* Message_GetUpbMessage(VALUE value, const upb_MessageDef* m,
36
36
 
37
37
  // Gets or constructs a Ruby wrapper object for the given message. The wrapper
38
38
  // object will reference |arena| and ensure that it outlives this object.
39
- VALUE Message_GetRubyWrapper(upb_Message* msg, const upb_MessageDef* m,
39
+ VALUE Message_GetRubyWrapper(const upb_Message* msg, const upb_MessageDef* m,
40
40
  VALUE arena);
41
41
 
42
42
  // Gets the given field from this message.
@@ -70,7 +70,7 @@ VALUE build_module_from_enumdesc(VALUE _enumdesc);
70
70
  VALUE MessageOrEnum_GetDescriptor(VALUE klass);
71
71
 
72
72
  // Decodes a Message from a byte sequence.
73
- VALUE Message_decode_bytes(int size, const char* bytes, int options,
73
+ VALUE Message_decode_bytes(size_t size, const char* bytes, int options,
74
74
  VALUE klass, bool freeze);
75
75
 
76
76
  // Recursively freeze message
@@ -7,8 +7,6 @@
7
7
 
8
8
  #include "protobuf.h"
9
9
 
10
- #include <ruby/version.h>
11
-
12
10
  #include "defs.h"
13
11
  #include "map.h"
14
12
  #include "message.h"
@@ -185,7 +183,7 @@ const rb_data_type_t Arena_type = {
185
183
  };
186
184
 
187
185
  static void *ruby_upb_allocfunc(upb_alloc *alloc, void *ptr, size_t oldsize,
188
- size_t size) {
186
+ size_t size, size_t *actual_size) {
189
187
  if (size == 0) {
190
188
  xfree(ptr);
191
189
  return NULL;
@@ -221,15 +219,6 @@ void Arena_fuse(VALUE _arena, upb_Arena *other) {
221
219
 
222
220
  VALUE Arena_new() { return Arena_alloc(cArena); }
223
221
 
224
- void Arena_Pin(VALUE _arena, VALUE obj) {
225
- Arena *arena;
226
- TypedData_Get_Struct(_arena, Arena, &Arena_type, arena);
227
- if (arena->pinned_objs == Qnil) {
228
- RB_OBJ_WRITE(_arena, &arena->pinned_objs, rb_ary_new());
229
- }
230
- rb_ary_push(arena->pinned_objs, obj);
231
- }
232
-
233
222
  void Arena_register(VALUE module) {
234
223
  VALUE internal = rb_define_module_under(module, "Internal");
235
224
  VALUE klass = rb_define_class_under(internal, "Arena", rb_cObject);
@@ -297,7 +286,8 @@ VALUE ObjectCache_Get(const void *key) {
297
286
  static VALUE Google_Protobuf_discard_unknown(VALUE self, VALUE msg_rb) {
298
287
  const upb_MessageDef *m;
299
288
  upb_Message *msg = Message_GetMutable(msg_rb, &m);
300
- if (!upb_Message_DiscardUnknown(msg, m, 128)) {
289
+ const upb_DefPool* ext_pool = upb_FileDef_Pool(upb_MessageDef_File(m));
290
+ if (!upb_Message_DiscardUnknown(msg, m, ext_pool, 128)) {
301
291
  rb_raise(rb_eRuntimeError, "Messages nested too deeply.");
302
292
  }
303
293
 
@@ -354,3 +344,14 @@ __attribute__((visibility("default"))) void Init_protobuf_c() {
354
344
  rb_define_singleton_method(protobuf, "deep_copy", Google_Protobuf_deep_copy,
355
345
  1);
356
346
  }
347
+
348
+ // -----------------------------------------------------------------------------
349
+ // Utilities
350
+ // -----------------------------------------------------------------------------
351
+
352
+ // Raises a Ruby error if val is frozen in Ruby or UPB.
353
+ void Protobuf_CheckNotFrozen(VALUE val, bool upb_frozen) {
354
+ if (RB_UNLIKELY(rb_obj_frozen_p(val)||upb_frozen)) {
355
+ rb_error_frozen_object(val);
356
+ }
357
+ }
@@ -16,12 +16,6 @@
16
16
  #undef NDEBUG
17
17
  #endif
18
18
 
19
- #include <ruby/version.h>
20
-
21
- #if RUBY_API_VERSION_CODE < 20700
22
- #error Protobuf requires Ruby >= 2.7
23
- #endif
24
-
25
19
  #include <assert.h> // Must be included after the NDEBUG logic above.
26
20
  #include <ruby/encoding.h>
27
21
  #include <ruby/vm.h>
@@ -50,13 +44,6 @@ upb_Arena* Arena_get(VALUE arena);
50
44
  // possible.
51
45
  void Arena_fuse(VALUE arena, upb_Arena* other);
52
46
 
53
- // Pins this Ruby object to the lifetime of this arena, so that as long as the
54
- // arena is alive this object will not be collected.
55
- //
56
- // We use this to guarantee that the "frozen" bit on the object will be
57
- // remembered, even if the user drops their reference to this precise object.
58
- void Arena_Pin(VALUE arena, VALUE obj);
59
-
60
47
  // -----------------------------------------------------------------------------
61
48
  // ObjectCache
62
49
  // -----------------------------------------------------------------------------
@@ -105,8 +92,9 @@ extern VALUE cTypeError;
105
92
  rb_bug("Assertion failed at %s:%d, expr: %s", __FILE__, __LINE__, #expr)
106
93
  #endif
107
94
 
108
- #define PBRUBY_MAX(x, y) (((x) > (y)) ? (x) : (y))
95
+ // Raises a Ruby error if val is frozen in Ruby or upb_frozen is true.
96
+ void Protobuf_CheckNotFrozen(VALUE val, bool upb_frozen);
109
97
 
110
- #define UPB_UNUSED(var) (void)var
98
+ #define PBRUBY_MAX(x, y) (((x) > (y)) ? (x) : (y))
111
99
 
112
100
  #endif // __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__