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.
- checksums.yaml +4 -4
- data/ext/google/protobuf_c/convert.c +32 -14
- data/ext/google/protobuf_c/defs.c +475 -133
- data/ext/google/protobuf_c/extconf.rb +20 -10
- data/ext/google/protobuf_c/glue.c +63 -0
- data/ext/google/protobuf_c/map.c +145 -56
- data/ext/google/protobuf_c/map.h +6 -2
- data/ext/google/protobuf_c/message.c +180 -97
- data/ext/google/protobuf_c/message.h +2 -2
- data/ext/google/protobuf_c/protobuf.c +14 -13
- data/ext/google/protobuf_c/protobuf.h +3 -15
- data/ext/google/protobuf_c/repeated_field.c +134 -53
- data/ext/google/protobuf_c/repeated_field.h +5 -1
- data/ext/google/protobuf_c/ruby-upb.c +14522 -12698
- data/ext/google/protobuf_c/ruby-upb.h +8273 -4619
- data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.c +22 -282
- data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +2 -1
- data/ext/google/protobuf_c/third_party/utf8_range/utf8_range_neon.inc +117 -0
- data/ext/google/protobuf_c/third_party/utf8_range/utf8_range_sse.inc +272 -0
- data/lib/google/protobuf/any_pb.rb +1 -1
- data/lib/google/protobuf/api_pb.rb +2 -2
- data/lib/google/protobuf/descriptor_pb.rb +6 -2
- data/lib/google/protobuf/duration_pb.rb +1 -1
- data/lib/google/protobuf/empty_pb.rb +1 -1
- data/lib/google/protobuf/ffi/descriptor.rb +11 -2
- data/lib/google/protobuf/ffi/descriptor_pool.rb +7 -1
- data/lib/google/protobuf/ffi/enum_descriptor.rb +10 -0
- data/lib/google/protobuf/ffi/ffi.rb +5 -2
- data/lib/google/protobuf/ffi/field_descriptor.rb +16 -0
- data/lib/google/protobuf/ffi/file_descriptor.rb +36 -0
- data/lib/google/protobuf/ffi/internal/arena.rb +0 -6
- data/lib/google/protobuf/ffi/internal/convert.rb +9 -6
- data/lib/google/protobuf/ffi/internal/pointer_helper.rb +2 -1
- data/lib/google/protobuf/ffi/map.rb +47 -23
- data/lib/google/protobuf/ffi/message.rb +188 -64
- data/lib/google/protobuf/ffi/method_descriptor.rb +11 -1
- data/lib/google/protobuf/ffi/oneof_descriptor.rb +10 -0
- data/lib/google/protobuf/ffi/repeated_field.rb +42 -16
- data/lib/google/protobuf/ffi/service_descriptor.rb +11 -1
- data/lib/google/protobuf/field_mask_pb.rb +1 -1
- data/lib/google/protobuf/message_exts.rb +4 -0
- data/lib/google/protobuf/plugin_pb.rb +1 -1
- data/lib/google/protobuf/source_context_pb.rb +1 -1
- data/lib/google/protobuf/struct_pb.rb +1 -1
- data/lib/google/protobuf/timestamp_pb.rb +1 -1
- data/lib/google/protobuf/type_pb.rb +1 -1
- data/lib/google/protobuf/wrappers_pb.rb +1 -1
- data/lib/google/protobuf_ffi.rb +3 -2
- data/lib/google/tasks/ffi.rake +1 -1
- metadata +29 -34
- 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
|
-
|
|
84
|
-
|
|
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 =
|
|
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
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
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(
|
|
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(
|
|
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 (
|
|
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
|
-
*
|
|
393
|
-
* Message.method_missing(*args)
|
|
423
|
+
* ruby-doc: AbstractMessage
|
|
394
424
|
*
|
|
395
|
-
*
|
|
396
|
-
*
|
|
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 (
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
815
|
-
*
|
|
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
|
-
*
|
|
818
|
-
* Ruby object into memory so we don't forget it's frozen.
|
|
851
|
+
* @return [Boolean]
|
|
819
852
|
*/
|
|
820
|
-
VALUE
|
|
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
|
-
|
|
824
|
-
|
|
825
|
-
|
|
860
|
+
// Lazily freeze the Ruby wrapper.
|
|
861
|
+
if (!RB_OBJ_FROZEN(_self)) RB_OBJ_FREEZE(_self);
|
|
862
|
+
return Qtrue;
|
|
863
|
+
}
|
|
826
864
|
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
|
900
|
-
*
|
|
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(
|
|
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
|
-
*
|
|
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
|
-
*
|
|
961
|
-
*
|
|
962
|
-
*
|
|
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
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
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
|
-
*
|
|
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
|
-
*
|
|
1020
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
1072
|
-
*
|
|
1073
|
-
*
|
|
1074
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
95
|
+
// Raises a Ruby error if val is frozen in Ruby or upb_frozen is true.
|
|
96
|
+
void Protobuf_CheckNotFrozen(VALUE val, bool upb_frozen);
|
|
109
97
|
|
|
110
|
-
#define
|
|
98
|
+
#define PBRUBY_MAX(x, y) (((x) > (y)) ? (x) : (y))
|
|
111
99
|
|
|
112
100
|
#endif // __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__
|