google-protobuf 4.36.2-java → 4.37.0.rc.1-java
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/message.c +199 -37
- data/ext/google/protobuf_c/message.h +2 -1
- data/ext/google/protobuf_c/protobuf.c +75 -6
- data/ext/google/protobuf_c/protobuf.h +1 -0
- data/ext/google/protobuf_c/ruby-upb.c +1324 -531
- data/ext/google/protobuf_c/ruby-upb.h +2282 -805
- data/ext/google/protobuf_c/shared_message.c +9 -1
- data/lib/google/protobuf/ffi/internal/convert.rb +32 -10
- data/lib/google/protobuf/ffi/map.rb +0 -1
- data/lib/google/protobuf/ffi/message.rb +10 -2
- data/lib/google/protobuf/ffi/repeated_field.rb +9 -1
- data/lib/google/protobuf/json_enumvalue_options_pb.rb +1 -1
- data/lib/google/protobuf/json_options_pb.rb +1 -1
- data/lib/google/protobuf/repeated_field.rb +2 -2
- data/lib/google/protobuf_java.jar +0 -0
- metadata +19 -19
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2cff40a754cba2763c4bdd5bac2ea7ed53266991c7ba26d985d79f34b2d99e3d
|
|
4
|
+
data.tar.gz: 0cd3f1806abab5b5a62390493debb96d66bbd05c6e0521dc379c516cb0466a9e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 973a8163db63fa331207141ef170cba75abab4d1ed4d558c64d95929994e5561fe3acab7a712a0de036a64f8c834a37801a3194a6128503dd4ea459eecefd546
|
|
7
|
+
data.tar.gz: 54067bee74a01cbe063ac6c534d4b2c9c2ff4bdf45cc74bc8be47310f5847f19cb36931455680e424165763524c1ad8ef4acc003775183bb88749372818af859
|
|
@@ -286,7 +286,9 @@ static void Message_setfield(upb_Message* msg, const upb_FieldDef* f, VALUE val,
|
|
|
286
286
|
msgval =
|
|
287
287
|
Convert_RubyToUpb(val, upb_FieldDef_Name(f), TypeInfo_get(f), arena);
|
|
288
288
|
}
|
|
289
|
-
upb_Message_SetFieldByDef(msg, f, msgval, arena)
|
|
289
|
+
if (!upb_Message_SetFieldByDef(msg, f, msgval, arena)) {
|
|
290
|
+
Arena_raise_oom();
|
|
291
|
+
}
|
|
290
292
|
}
|
|
291
293
|
|
|
292
294
|
VALUE Message_getfield_frozen(const upb_Message* msg, const upb_FieldDef* f,
|
|
@@ -328,6 +330,7 @@ VALUE Message_getfield(VALUE _self, const upb_FieldDef* f) {
|
|
|
328
330
|
upb_Arena* arena = Arena_get(self->arena);
|
|
329
331
|
if (upb_FieldDef_IsMap(f)) {
|
|
330
332
|
upb_Map* map = upb_Message_Mutable(msg, f, arena).map;
|
|
333
|
+
if (!map) Arena_raise_oom();
|
|
331
334
|
const upb_FieldDef* key_f = map_field_key(f);
|
|
332
335
|
const upb_FieldDef* val_f = map_field_value(f);
|
|
333
336
|
upb_CType key_type = upb_FieldDef_CType(key_f);
|
|
@@ -335,10 +338,12 @@ VALUE Message_getfield(VALUE _self, const upb_FieldDef* f) {
|
|
|
335
338
|
return Map_GetRubyWrapper(map, key_type, value_type_info, self->arena);
|
|
336
339
|
} else if (upb_FieldDef_IsRepeated(f)) {
|
|
337
340
|
upb_Array* arr = upb_Message_Mutable(msg, f, arena).array;
|
|
341
|
+
if (!arr) Arena_raise_oom();
|
|
338
342
|
return RepeatedField_GetRubyWrapper(arr, TypeInfo_get(f), self->arena);
|
|
339
343
|
} else if (upb_FieldDef_IsSubMessage(f)) {
|
|
340
344
|
if (!upb_Message_HasFieldByDef(msg, f)) return Qnil;
|
|
341
345
|
upb_Message* submsg = upb_Message_Mutable(msg, f, arena).msg;
|
|
346
|
+
if (!submsg) Arena_raise_oom();
|
|
342
347
|
const upb_MessageDef* m = upb_FieldDef_MessageSubDef(f);
|
|
343
348
|
return Message_GetRubyWrapper(submsg, m, self->arena);
|
|
344
349
|
} else {
|
|
@@ -390,7 +395,10 @@ static VALUE Message_field_accessor(VALUE _self, const upb_FieldDef* f,
|
|
|
390
395
|
upb_MessageValue msgval = Convert_RubyToUpb(
|
|
391
396
|
argv[1], upb_FieldDef_Name(f), TypeInfo_get(val_f), arena);
|
|
392
397
|
upb_Message* wrapper = upb_Message_Mutable(msg, f, arena).msg;
|
|
393
|
-
|
|
398
|
+
if (!wrapper) Arena_raise_oom();
|
|
399
|
+
if (!upb_Message_SetFieldByDef(wrapper, val_f, msgval, arena)) {
|
|
400
|
+
Arena_raise_oom();
|
|
401
|
+
}
|
|
394
402
|
}
|
|
395
403
|
return Qnil;
|
|
396
404
|
}
|
|
@@ -519,19 +527,25 @@ typedef struct {
|
|
|
519
527
|
static int Map_initialize_kwarg(VALUE key, VALUE val, VALUE _self) {
|
|
520
528
|
MapInit* map_init = (MapInit*)_self;
|
|
521
529
|
upb_MessageValue k, v;
|
|
522
|
-
|
|
530
|
+
// Copy the key into the arena rather than aliasing it: building the value
|
|
531
|
+
// below allocates, which can trigger GC and free or move the String the key
|
|
532
|
+
// would otherwise point into.
|
|
533
|
+
k = Convert_RubyToUpb(key, "", map_init->key_type, map_init->arena);
|
|
523
534
|
|
|
524
535
|
if (map_init->val_type.type == kUpb_CType_Message && TYPE(val) == T_HASH) {
|
|
525
536
|
const upb_MiniTable* t =
|
|
526
537
|
upb_MessageDef_MiniTable(map_init->val_type.def.msgdef);
|
|
527
538
|
upb_Message* msg = upb_Message_New(t, map_init->arena);
|
|
539
|
+
if (!msg) Arena_raise_oom();
|
|
528
540
|
Message_InitFromValue(msg, map_init->val_type.def.msgdef, val,
|
|
529
541
|
map_init->arena);
|
|
530
542
|
v.msg_val = msg;
|
|
531
543
|
} else {
|
|
532
544
|
v = Convert_RubyToUpb(val, "", map_init->val_type, map_init->arena);
|
|
533
545
|
}
|
|
534
|
-
upb_Map_Set(map_init->map, k, v, map_init->arena)
|
|
546
|
+
if (!upb_Map_Set(map_init->map, k, v, map_init->arena)) {
|
|
547
|
+
Arena_raise_oom();
|
|
548
|
+
}
|
|
535
549
|
return ST_CONTINUE;
|
|
536
550
|
}
|
|
537
551
|
|
|
@@ -556,6 +570,7 @@ static upb_MessageValue MessageValue_FromValue(VALUE val, TypeInfo info,
|
|
|
556
570
|
upb_MessageValue msgval;
|
|
557
571
|
const upb_MiniTable* t = upb_MessageDef_MiniTable(info.def.msgdef);
|
|
558
572
|
upb_Message* msg = upb_Message_New(t, arena);
|
|
573
|
+
if (!msg) Arena_raise_oom();
|
|
559
574
|
Message_InitFromValue(msg, info.def.msgdef, val, arena);
|
|
560
575
|
msgval.msg_val = msg;
|
|
561
576
|
return msgval;
|
|
@@ -583,7 +598,9 @@ static void RepeatedField_InitFromValue(upb_Array* arr, const upb_FieldDef* f,
|
|
|
583
598
|
} else {
|
|
584
599
|
msgval = Convert_RubyToUpb(entry, upb_FieldDef_Name(f), type_info, arena);
|
|
585
600
|
}
|
|
586
|
-
upb_Array_Append(arr, msgval, arena)
|
|
601
|
+
if (!upb_Array_Append(arr, msgval, arena)) {
|
|
602
|
+
Arena_raise_oom();
|
|
603
|
+
}
|
|
587
604
|
}
|
|
588
605
|
}
|
|
589
606
|
|
|
@@ -593,13 +610,16 @@ static void Message_InitFieldFromValue(upb_Message* msg, const upb_FieldDef* f,
|
|
|
593
610
|
|
|
594
611
|
if (upb_FieldDef_IsMap(f)) {
|
|
595
612
|
upb_Map* map = upb_Message_Mutable(msg, f, arena).map;
|
|
613
|
+
if (!map) Arena_raise_oom();
|
|
596
614
|
Map_InitFromValue(map, f, val, arena);
|
|
597
615
|
} else if (upb_FieldDef_IsRepeated(f)) {
|
|
598
616
|
upb_Array* arr = upb_Message_Mutable(msg, f, arena).array;
|
|
617
|
+
if (!arr) Arena_raise_oom();
|
|
599
618
|
RepeatedField_InitFromValue(arr, f, val, arena);
|
|
600
619
|
} else if (upb_FieldDef_IsSubMessage(f)) {
|
|
601
620
|
if (TYPE(val) == T_HASH) {
|
|
602
621
|
upb_Message* submsg = upb_Message_Mutable(msg, f, arena).msg;
|
|
622
|
+
if (!submsg) Arena_raise_oom();
|
|
603
623
|
Message_InitFromValue(submsg, upb_FieldDef_MessageSubDef(f), val, arena);
|
|
604
624
|
} else {
|
|
605
625
|
Message_setfield(msg, f, val, arena);
|
|
@@ -607,7 +627,9 @@ static void Message_InitFieldFromValue(upb_Message* msg, const upb_FieldDef* f,
|
|
|
607
627
|
} else {
|
|
608
628
|
upb_MessageValue msgval =
|
|
609
629
|
Convert_RubyToUpb(val, upb_FieldDef_Name(f), TypeInfo_get(f), arena);
|
|
610
|
-
upb_Message_SetFieldByDef(msg, f, msgval, arena)
|
|
630
|
+
if (!upb_Message_SetFieldByDef(msg, f, msgval, arena)) {
|
|
631
|
+
Arena_raise_oom();
|
|
632
|
+
}
|
|
611
633
|
}
|
|
612
634
|
}
|
|
613
635
|
|
|
@@ -668,6 +690,7 @@ static VALUE Message_initialize(int argc, VALUE* argv, VALUE _self) {
|
|
|
668
690
|
upb_Arena* arena = Arena_get(arena_rb);
|
|
669
691
|
const upb_MiniTable* t = upb_MessageDef_MiniTable(self->msgdef);
|
|
670
692
|
upb_Message* msg = upb_Message_New(t, arena);
|
|
693
|
+
if (!msg) Arena_raise_oom();
|
|
671
694
|
|
|
672
695
|
Message_InitPtr(_self, msg, arena_rb);
|
|
673
696
|
|
|
@@ -733,6 +756,9 @@ uint64_t Message_Hash(const upb_Message* msg, const upb_MessageDef* m,
|
|
|
733
756
|
if (upb_Status_IsOk(&status)) {
|
|
734
757
|
return return_value;
|
|
735
758
|
} else {
|
|
759
|
+
if (strcmp(upb_Status_ErrorMessage(&status), "Out of memory") == 0) {
|
|
760
|
+
Arena_raise_oom();
|
|
761
|
+
}
|
|
736
762
|
rb_raise(cParseError, "Message_Hash(): %s",
|
|
737
763
|
upb_Status_ErrorMessage(&status));
|
|
738
764
|
}
|
|
@@ -774,25 +800,64 @@ static VALUE Message_inspect(VALUE _self) {
|
|
|
774
800
|
|
|
775
801
|
// Support functions for Message_to_h //////////////////////////////////////////
|
|
776
802
|
|
|
777
|
-
static VALUE RepeatedField_CreateArray(const upb_Array* arr,
|
|
778
|
-
|
|
803
|
+
static VALUE RepeatedField_CreateArray(const upb_Array* arr, TypeInfo type_info,
|
|
804
|
+
bool emit_defaults) {
|
|
779
805
|
int size = arr ? upb_Array_Size(arr) : 0;
|
|
780
806
|
VALUE ary = rb_ary_new2(size);
|
|
781
807
|
|
|
782
808
|
for (int i = 0; i < size; i++) {
|
|
783
809
|
upb_MessageValue msgval = upb_Array_Get(arr, i);
|
|
784
|
-
VALUE val = Scalar_CreateHash(msgval, type_info);
|
|
810
|
+
VALUE val = Scalar_CreateHash(msgval, type_info, emit_defaults);
|
|
785
811
|
rb_ary_push(ary, val);
|
|
786
812
|
}
|
|
787
813
|
|
|
788
814
|
return ary;
|
|
789
815
|
}
|
|
790
816
|
|
|
791
|
-
static VALUE Message_CreateHash(const upb_Message* msg,
|
|
792
|
-
|
|
817
|
+
static VALUE Message_CreateHash(const upb_Message* msg, const upb_MessageDef* m,
|
|
818
|
+
bool emit_defaults) {
|
|
793
819
|
if (!msg) return Qnil;
|
|
794
820
|
|
|
795
821
|
VALUE hash = rb_hash_new();
|
|
822
|
+
|
|
823
|
+
if (emit_defaults) {
|
|
824
|
+
int n = upb_MessageDef_FieldCount(m);
|
|
825
|
+
|
|
826
|
+
for (int i = 0; i < n; i++) {
|
|
827
|
+
const upb_FieldDef* field = upb_MessageDef_Field(m, i);
|
|
828
|
+
|
|
829
|
+
if (upb_FieldDef_HasPresence(field) &&
|
|
830
|
+
!upb_Message_HasFieldByDef(msg, field)) {
|
|
831
|
+
continue;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
TypeInfo type_info = TypeInfo_get(field);
|
|
835
|
+
upb_MessageValue val = upb_Message_GetFieldByDef(msg, field);
|
|
836
|
+
VALUE msg_value;
|
|
837
|
+
|
|
838
|
+
if (upb_FieldDef_IsMap(field)) {
|
|
839
|
+
const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(field);
|
|
840
|
+
const upb_FieldDef* key_f =
|
|
841
|
+
upb_MessageDef_FindFieldByNumber(entry_m, 1);
|
|
842
|
+
const upb_FieldDef* val_f =
|
|
843
|
+
upb_MessageDef_FindFieldByNumber(entry_m, 2);
|
|
844
|
+
upb_CType key_type = upb_FieldDef_CType(key_f);
|
|
845
|
+
msg_value = Map_CreateHash(val.map_val, key_type, TypeInfo_get(val_f),
|
|
846
|
+
emit_defaults);
|
|
847
|
+
} else if (upb_FieldDef_IsRepeated(field)) {
|
|
848
|
+
msg_value =
|
|
849
|
+
RepeatedField_CreateArray(val.array_val, type_info, emit_defaults);
|
|
850
|
+
} else {
|
|
851
|
+
msg_value = Scalar_CreateHash(val, type_info, emit_defaults);
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
VALUE msg_key = ID2SYM(rb_intern(upb_FieldDef_Name(field)));
|
|
855
|
+
rb_hash_aset(hash, msg_key, msg_value);
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
return hash;
|
|
859
|
+
}
|
|
860
|
+
|
|
796
861
|
size_t iter = kUpb_Message_Begin;
|
|
797
862
|
const upb_DefPool* pool = upb_FileDef_Pool(upb_MessageDef_File(m));
|
|
798
863
|
const upb_FieldDef* field;
|
|
@@ -813,11 +878,13 @@ static VALUE Message_CreateHash(const upb_Message* msg,
|
|
|
813
878
|
const upb_FieldDef* key_f = upb_MessageDef_FindFieldByNumber(entry_m, 1);
|
|
814
879
|
const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(entry_m, 2);
|
|
815
880
|
upb_CType key_type = upb_FieldDef_CType(key_f);
|
|
816
|
-
msg_value = Map_CreateHash(val.map_val, key_type, TypeInfo_get(val_f)
|
|
881
|
+
msg_value = Map_CreateHash(val.map_val, key_type, TypeInfo_get(val_f),
|
|
882
|
+
emit_defaults);
|
|
817
883
|
} else if (upb_FieldDef_IsRepeated(field)) {
|
|
818
|
-
msg_value =
|
|
884
|
+
msg_value =
|
|
885
|
+
RepeatedField_CreateArray(val.array_val, type_info, emit_defaults);
|
|
819
886
|
} else {
|
|
820
|
-
msg_value = Scalar_CreateHash(val, type_info);
|
|
887
|
+
msg_value = Scalar_CreateHash(val, type_info, emit_defaults);
|
|
821
888
|
}
|
|
822
889
|
|
|
823
890
|
VALUE msg_key = ID2SYM(rb_intern(upb_FieldDef_Name(field)));
|
|
@@ -827,9 +894,11 @@ static VALUE Message_CreateHash(const upb_Message* msg,
|
|
|
827
894
|
return hash;
|
|
828
895
|
}
|
|
829
896
|
|
|
830
|
-
VALUE Scalar_CreateHash(upb_MessageValue msgval, TypeInfo type_info
|
|
897
|
+
VALUE Scalar_CreateHash(upb_MessageValue msgval, TypeInfo type_info,
|
|
898
|
+
bool emit_defaults) {
|
|
831
899
|
if (type_info.type == kUpb_CType_Message) {
|
|
832
|
-
return Message_CreateHash(msgval.msg_val, type_info.def.msgdef
|
|
900
|
+
return Message_CreateHash(msgval.msg_val, type_info.def.msgdef,
|
|
901
|
+
emit_defaults);
|
|
833
902
|
} else {
|
|
834
903
|
return Convert_UpbToRuby(msgval, type_info, Qnil);
|
|
835
904
|
}
|
|
@@ -840,11 +909,49 @@ VALUE Scalar_CreateHash(upb_MessageValue msgval, TypeInfo type_info) {
|
|
|
840
909
|
*
|
|
841
910
|
* Returns the message as a Ruby Hash object, with keys as symbols.
|
|
842
911
|
*
|
|
912
|
+
* By default, only fields that are present are included. A field without
|
|
913
|
+
* presence (an implicit presence scalar or enum, or a repeated or map field)
|
|
914
|
+
* counts as present only when it holds a non-default value or is non-empty.
|
|
915
|
+
*
|
|
916
|
+
* +emit_defaults+ does not emit a default value for every field. It only
|
|
917
|
+
* additionally includes the fields that have no presence, using their default
|
|
918
|
+
* values (for example 0, "" or false, and empty arrays and hashes for repeated
|
|
919
|
+
* and map fields). This is the ProtoJSON "always emit fields without presence"
|
|
920
|
+
* option, called +always_print_fields_with_no_presence+ in C++ and Python.
|
|
921
|
+
*
|
|
922
|
+
* Fields that have presence are never added by +emit_defaults+ and are
|
|
923
|
+
* included only when they are set: singular message fields, fields in a
|
|
924
|
+
* oneof, and fields with explicit presence such as proto3 +optional+ fields
|
|
925
|
+
* and proto2 singular fields. To include one of these, set it explicitly.
|
|
926
|
+
*
|
|
927
|
+
* The option applies recursively, including to messages in repeated fields
|
|
928
|
+
* and map values. It selects the same fields as #inspect and as .encode_json
|
|
929
|
+
* with +emit_defaults+.
|
|
930
|
+
*
|
|
931
|
+
* @param kwargs [Hash]
|
|
932
|
+
* @option emit_defaults [Boolean] set true to also include fields that have
|
|
933
|
+
* no presence, with their default values (default is false). Fields that have
|
|
934
|
+
* presence are not affected.
|
|
843
935
|
* @return [Hash]
|
|
844
936
|
*/
|
|
845
|
-
static VALUE Message_to_h(VALUE _self) {
|
|
937
|
+
static VALUE Message_to_h(int argc, VALUE* argv, VALUE _self) {
|
|
846
938
|
Message* self = ruby_to_Message(_self);
|
|
847
|
-
|
|
939
|
+
VALUE kwargs = Qnil;
|
|
940
|
+
bool emit_defaults = false;
|
|
941
|
+
|
|
942
|
+
rb_scan_args_kw(RB_SCAN_ARGS_PASS_CALLED_KEYWORDS, argc, argv, ":", &kwargs);
|
|
943
|
+
|
|
944
|
+
if (!NIL_P(kwargs)) {
|
|
945
|
+
ID keyword_ids[1];
|
|
946
|
+
VALUE values[1];
|
|
947
|
+
keyword_ids[0] = rb_intern("emit_defaults");
|
|
948
|
+
rb_get_kwargs(kwargs, keyword_ids, 0, 1, values);
|
|
949
|
+
if (values[0] != Qundef) {
|
|
950
|
+
emit_defaults = RTEST(values[0]);
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
return Message_CreateHash(self->msg, self->msgdef, emit_defaults);
|
|
848
955
|
}
|
|
849
956
|
|
|
850
957
|
/*
|
|
@@ -937,8 +1044,10 @@ static VALUE Message_index_set(VALUE _self, VALUE field_name, VALUE value) {
|
|
|
937
1044
|
}
|
|
938
1045
|
|
|
939
1046
|
val = Convert_RubyToUpb(value, upb_FieldDef_Name(f), TypeInfo_get(f), arena);
|
|
940
|
-
upb_Message_SetFieldByDef(Message_GetMutable(_self, NULL), f, val,
|
|
941
|
-
|
|
1047
|
+
if (!upb_Message_SetFieldByDef(Message_GetMutable(_self, NULL), f, val,
|
|
1048
|
+
arena)) {
|
|
1049
|
+
Arena_raise_oom();
|
|
1050
|
+
}
|
|
942
1051
|
return Qnil;
|
|
943
1052
|
}
|
|
944
1053
|
|
|
@@ -995,6 +1104,9 @@ VALUE Message_decode_bytes(size_t size, const char* bytes, int options,
|
|
|
995
1104
|
upb_DecodeStatus status = upb_Decode(bytes, size, (upb_Message*)msg->msg,
|
|
996
1105
|
upb_MessageDef_MiniTable(msg->msgdef),
|
|
997
1106
|
extreg, options, Arena_get(msg->arena));
|
|
1107
|
+
if (status == kUpb_DecodeStatus_OutOfMemory) {
|
|
1108
|
+
Arena_raise_oom();
|
|
1109
|
+
}
|
|
998
1110
|
if (status != kUpb_DecodeStatus_Ok) {
|
|
999
1111
|
rb_raise(cParseError, "Error occurred during parsing");
|
|
1000
1112
|
}
|
|
@@ -1064,10 +1176,18 @@ static VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) {
|
|
|
1064
1176
|
switch (result) {
|
|
1065
1177
|
case kUpb_JsonDecodeResult_Ok:
|
|
1066
1178
|
break;
|
|
1067
|
-
case kUpb_JsonDecodeResult_Error:
|
|
1179
|
+
case kUpb_JsonDecodeResult_Error: {
|
|
1180
|
+
VALUE pending_err = rb_errinfo();
|
|
1181
|
+
if (!NIL_P(pending_err)) {
|
|
1182
|
+
rb_set_errinfo(Qnil);
|
|
1183
|
+
rb_exc_raise(pending_err);
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1068
1186
|
rb_raise(cParseError, "Error occurred during parsing: %s",
|
|
1069
1187
|
upb_Status_ErrorMessage(&status));
|
|
1188
|
+
|
|
1070
1189
|
break;
|
|
1190
|
+
}
|
|
1071
1191
|
}
|
|
1072
1192
|
|
|
1073
1193
|
return msg_rb;
|
|
@@ -1113,6 +1233,9 @@ static VALUE Message_encode(int argc, VALUE* argv, VALUE klass) {
|
|
|
1113
1233
|
}
|
|
1114
1234
|
|
|
1115
1235
|
upb_Arena* arena = upb_Arena_New();
|
|
1236
|
+
if (!arena) {
|
|
1237
|
+
Arena_raise_oom();
|
|
1238
|
+
}
|
|
1116
1239
|
|
|
1117
1240
|
upb_EncodeStatus status =
|
|
1118
1241
|
upb_Encode(msg->msg, upb_MessageDef_MiniTable(msg->msgdef), options,
|
|
@@ -1123,10 +1246,18 @@ static VALUE Message_encode(int argc, VALUE* argv, VALUE klass) {
|
|
|
1123
1246
|
rb_enc_associate(ret, rb_ascii8bit_encoding());
|
|
1124
1247
|
upb_Arena_Free(arena);
|
|
1125
1248
|
return ret;
|
|
1126
|
-
}
|
|
1127
|
-
|
|
1249
|
+
}
|
|
1250
|
+
upb_Arena_Free(arena);
|
|
1251
|
+
if (status == kUpb_EncodeStatus_OutOfMemory) {
|
|
1252
|
+
Arena_raise_oom();
|
|
1253
|
+
}
|
|
1254
|
+
if (status == kUpb_EncodeStatus_MaxDepthExceeded) {
|
|
1128
1255
|
rb_raise(rb_eRuntimeError, "Exceeded maximum depth (possibly cycle)");
|
|
1129
1256
|
}
|
|
1257
|
+
if (status == kUpb_EncodeStatus_MaxSizeExceeded) {
|
|
1258
|
+
rb_raise(rb_eRuntimeError, "Exceeded maximum size");
|
|
1259
|
+
}
|
|
1260
|
+
rb_raise(cParseError, "Unknown encoding error");
|
|
1130
1261
|
}
|
|
1131
1262
|
|
|
1132
1263
|
/*
|
|
@@ -1138,8 +1269,10 @@ static VALUE Message_encode(int argc, VALUE* argv, VALUE klass) {
|
|
|
1138
1269
|
* @param options [Hash]
|
|
1139
1270
|
* @option preserve_proto_fieldnames [Boolean] set true to use original
|
|
1140
1271
|
* fieldnames (default is to camelCase)
|
|
1141
|
-
* @option emit_defaults [Boolean] set true to emit
|
|
1142
|
-
* to omit them)
|
|
1272
|
+
* @option emit_defaults [Boolean] set true to also emit fields that have no
|
|
1273
|
+
* presence, with their default values (default is to omit them). Fields that
|
|
1274
|
+
* have presence, such as message fields, oneof fields and +optional+ fields,
|
|
1275
|
+
* are emitted only when set. See #to_h.
|
|
1143
1276
|
* @return [String]
|
|
1144
1277
|
*/
|
|
1145
1278
|
static VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
|
|
@@ -1310,9 +1443,15 @@ VALUE build_module_from_enumdesc(VALUE _enumdesc) {
|
|
|
1310
1443
|
int n = upb_EnumDef_ValueCount(e);
|
|
1311
1444
|
for (int i = 0; i < n; i++) {
|
|
1312
1445
|
const upb_EnumValueDef* ev = upb_EnumDef_Value(e, i);
|
|
1313
|
-
upb_Arena* arena = upb_Arena_New();
|
|
1314
1446
|
const char* src_name = upb_EnumValueDef_Name(ev);
|
|
1315
|
-
|
|
1447
|
+
size_t len = strlen(src_name);
|
|
1448
|
+
upb_Arena* arena = upb_Arena_NewSized(len);
|
|
1449
|
+
if (!arena) Arena_raise_oom();
|
|
1450
|
+
char* name = upb_strdup2(src_name, len, arena);
|
|
1451
|
+
if (!name) {
|
|
1452
|
+
upb_Arena_Free(arena);
|
|
1453
|
+
Arena_raise_oom();
|
|
1454
|
+
}
|
|
1316
1455
|
int32_t value = upb_EnumValueDef_Number(ev);
|
|
1317
1456
|
if (name[0] < 'A' || name[0] > 'Z') {
|
|
1318
1457
|
if (name[0] >= 'a' && name[0] <= 'z') {
|
|
@@ -1341,21 +1480,40 @@ upb_Message* Message_deep_copy(const upb_Message* msg, const upb_MessageDef* m,
|
|
|
1341
1480
|
upb_Arena* arena) {
|
|
1342
1481
|
// Serialize and parse.
|
|
1343
1482
|
upb_Arena* tmp_arena = upb_Arena_New();
|
|
1483
|
+
if (!tmp_arena) {
|
|
1484
|
+
Arena_raise_oom();
|
|
1485
|
+
}
|
|
1344
1486
|
const upb_MiniTable* layout = upb_MessageDef_MiniTable(m);
|
|
1345
1487
|
size_t size;
|
|
1346
1488
|
|
|
1347
1489
|
upb_Message* new_msg = upb_Message_New(layout, arena);
|
|
1490
|
+
if (!new_msg) {
|
|
1491
|
+
upb_Arena_Free(tmp_arena);
|
|
1492
|
+
Arena_raise_oom();
|
|
1493
|
+
}
|
|
1348
1494
|
char* data;
|
|
1349
1495
|
|
|
1350
1496
|
const upb_FileDef* file = upb_MessageDef_File(m);
|
|
1351
1497
|
const upb_ExtensionRegistry* extreg =
|
|
1352
1498
|
upb_DefPool_ExtensionRegistry(upb_FileDef_Pool(file));
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1499
|
+
upb_EncodeStatus encode_status =
|
|
1500
|
+
upb_Encode(msg, layout, 0, tmp_arena, &data, &size);
|
|
1501
|
+
if (encode_status == kUpb_EncodeStatus_OutOfMemory) {
|
|
1502
|
+
upb_Arena_Free(tmp_arena);
|
|
1503
|
+
Arena_raise_oom();
|
|
1504
|
+
} else if (encode_status != kUpb_EncodeStatus_Ok) {
|
|
1357
1505
|
upb_Arena_Free(tmp_arena);
|
|
1358
|
-
rb_raise(cParseError, "Error occurred copying proto");
|
|
1506
|
+
rb_raise(cParseError, "Error occurred copying proto during encode");
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1509
|
+
upb_DecodeStatus decode_status =
|
|
1510
|
+
upb_Decode(data, size, new_msg, layout, extreg, 0, arena);
|
|
1511
|
+
if (decode_status == kUpb_DecodeStatus_OutOfMemory) {
|
|
1512
|
+
upb_Arena_Free(tmp_arena);
|
|
1513
|
+
Arena_raise_oom();
|
|
1514
|
+
} else if (decode_status != kUpb_DecodeStatus_Ok) {
|
|
1515
|
+
upb_Arena_Free(tmp_arena);
|
|
1516
|
+
rb_raise(cParseError, "Error occurred copying proto during decode");
|
|
1359
1517
|
}
|
|
1360
1518
|
|
|
1361
1519
|
upb_Arena_Free(tmp_arena);
|
|
@@ -1392,8 +1550,10 @@ const upb_Message* Message_GetUpbMessage(VALUE value, const upb_MessageDef* m,
|
|
|
1392
1550
|
time = rb_time_timespec(value);
|
|
1393
1551
|
sec.int64_val = time.tv_sec;
|
|
1394
1552
|
nsec.int32_val = time.tv_nsec;
|
|
1395
|
-
upb_Message_SetFieldByDef(msg, sec_f, sec, arena)
|
|
1396
|
-
|
|
1553
|
+
if (!upb_Message_SetFieldByDef(msg, sec_f, sec, arena) ||
|
|
1554
|
+
!upb_Message_SetFieldByDef(msg, nsec_f, nsec, arena)) {
|
|
1555
|
+
Arena_raise_oom();
|
|
1556
|
+
}
|
|
1397
1557
|
return msg;
|
|
1398
1558
|
}
|
|
1399
1559
|
case kUpb_WellKnown_Duration: {
|
|
@@ -1408,8 +1568,10 @@ const upb_Message* Message_GetUpbMessage(VALUE value, const upb_MessageDef* m,
|
|
|
1408
1568
|
|
|
1409
1569
|
sec.int64_val = NUM2LL(value);
|
|
1410
1570
|
nsec.int32_val = round((NUM2DBL(value) - NUM2LL(value)) * 1000000000);
|
|
1411
|
-
upb_Message_SetFieldByDef(msg, sec_f, sec, arena)
|
|
1412
|
-
|
|
1571
|
+
if (!upb_Message_SetFieldByDef(msg, sec_f, sec, arena) ||
|
|
1572
|
+
!upb_Message_SetFieldByDef(msg, nsec_f, nsec, arena)) {
|
|
1573
|
+
Arena_raise_oom();
|
|
1574
|
+
}
|
|
1413
1575
|
return msg;
|
|
1414
1576
|
}
|
|
1415
1577
|
default:
|
|
@@ -1442,7 +1604,7 @@ static void Message_define_class(VALUE klass) {
|
|
|
1442
1604
|
rb_define_method(klass, "freeze", Message_freeze, 0);
|
|
1443
1605
|
rb_define_method(klass, "frozen?", Message_frozen, 0);
|
|
1444
1606
|
rb_define_method(klass, "hash", Message_hash, 0);
|
|
1445
|
-
rb_define_method(klass, "to_h", Message_to_h,
|
|
1607
|
+
rb_define_method(klass, "to_h", Message_to_h, -1);
|
|
1446
1608
|
rb_define_method(klass, "inspect", Message_inspect, 0);
|
|
1447
1609
|
rb_define_method(klass, "to_s", Message_inspect, 0);
|
|
1448
1610
|
rb_define_method(klass, "[]", Message_index, 1);
|
|
@@ -58,7 +58,8 @@ upb_Message* Message_deep_copy(const upb_Message* msg, const upb_MessageDef* m,
|
|
|
58
58
|
void Message_CheckClass(VALUE klass);
|
|
59
59
|
|
|
60
60
|
// Returns a new Hash object containing the contents of this message.
|
|
61
|
-
VALUE Scalar_CreateHash(upb_MessageValue val, TypeInfo type_info
|
|
61
|
+
VALUE Scalar_CreateHash(upb_MessageValue val, TypeInfo type_info,
|
|
62
|
+
bool emit_defaults);
|
|
62
63
|
|
|
63
64
|
// Creates a message class or enum module for this descriptor, respectively.
|
|
64
65
|
VALUE build_class_from_descriptor(VALUE descriptor);
|
|
@@ -182,23 +182,59 @@ const rb_data_type_t Arena_type = {
|
|
|
182
182
|
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
|
183
183
|
};
|
|
184
184
|
|
|
185
|
+
struct ruby_upb_xrealloc_args {
|
|
186
|
+
void* ptr;
|
|
187
|
+
size_t size;
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
static VALUE safe_xrealloc_wrapper(VALUE arg) {
|
|
191
|
+
struct ruby_upb_xrealloc_args* args = (struct ruby_upb_xrealloc_args*)arg;
|
|
192
|
+
|
|
193
|
+
// If xrealloc fails, it will longjmp out of this function immediately.
|
|
194
|
+
// If it succeeds, we return the pointer cast as a VALUE.
|
|
195
|
+
void* new_ptr = xrealloc(args->ptr, args->size);
|
|
196
|
+
return (VALUE)new_ptr;
|
|
197
|
+
}
|
|
198
|
+
|
|
185
199
|
static void* ruby_upb_allocfunc(upb_alloc* alloc, void* ptr, size_t oldsize,
|
|
186
200
|
size_t size, size_t* actual_size) {
|
|
187
201
|
if (size == 0) {
|
|
188
202
|
xfree(ptr);
|
|
189
203
|
return NULL;
|
|
190
204
|
} else {
|
|
191
|
-
|
|
205
|
+
struct ruby_upb_xrealloc_args args = {ptr, size};
|
|
206
|
+
int state = 0;
|
|
207
|
+
|
|
208
|
+
void* new_ptr =
|
|
209
|
+
(void*)rb_protect(safe_xrealloc_wrapper, (VALUE)&args, &state);
|
|
210
|
+
|
|
211
|
+
// Exception caught, but rb_errinfo still has the original error for
|
|
212
|
+
// consumption by the caller
|
|
213
|
+
return state ? NULL : new_ptr;
|
|
192
214
|
}
|
|
193
215
|
}
|
|
194
216
|
|
|
195
217
|
upb_alloc ruby_upb_alloc = {&ruby_upb_allocfunc};
|
|
196
218
|
|
|
219
|
+
void Arena_raise_oom() {
|
|
220
|
+
VALUE pending_err = rb_errinfo();
|
|
221
|
+
if (!NIL_P(pending_err)) {
|
|
222
|
+
rb_set_errinfo(Qnil);
|
|
223
|
+
rb_exc_raise(pending_err);
|
|
224
|
+
}
|
|
225
|
+
rb_raise(rb_eNoMemError, "Failed to allocate arena.");
|
|
226
|
+
}
|
|
227
|
+
|
|
197
228
|
static VALUE Arena_alloc(VALUE klass) {
|
|
198
|
-
Arena*
|
|
199
|
-
arena
|
|
200
|
-
arena
|
|
201
|
-
|
|
229
|
+
Arena* rb_arena = ALLOC(Arena);
|
|
230
|
+
upb_Arena* arena = upb_Arena_Init(NULL, 0, &ruby_upb_alloc);
|
|
231
|
+
if (!arena) {
|
|
232
|
+
xfree(rb_arena);
|
|
233
|
+
Arena_raise_oom();
|
|
234
|
+
}
|
|
235
|
+
rb_arena->arena = arena;
|
|
236
|
+
rb_arena->pinned_objs = Qnil;
|
|
237
|
+
return TypedData_Wrap_Struct(klass, &Arena_type, rb_arena);
|
|
202
238
|
}
|
|
203
239
|
|
|
204
240
|
upb_Arena* Arena_get(VALUE _arena) {
|
|
@@ -317,13 +353,33 @@ VALUE Google_Protobuf_deep_copy(VALUE self, VALUE obj) {
|
|
|
317
353
|
}
|
|
318
354
|
}
|
|
319
355
|
|
|
356
|
+
static VALUE Google_Protobuf_Internal_allocation_count_is_available(
|
|
357
|
+
VALUE self) {
|
|
358
|
+
return upb_AllocationCount_IsAvailable() ? Qtrue : Qfalse;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
static VALUE Google_Protobuf_Internal_allocation_count_get(VALUE self) {
|
|
362
|
+
return ULL2NUM(upb_AllocationCount_Get());
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
static VALUE Google_Protobuf_Internal_allocation_count_reset(VALUE self) {
|
|
366
|
+
upb_AllocationCount_Reset();
|
|
367
|
+
return Qnil;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
static VALUE Google_Protobuf_Internal_allocation_count_fail_on(VALUE self,
|
|
371
|
+
VALUE n) {
|
|
372
|
+
upb_AllocationCount_FailOn(NUM2ULL(n));
|
|
373
|
+
return Qnil;
|
|
374
|
+
}
|
|
375
|
+
|
|
320
376
|
// -----------------------------------------------------------------------------
|
|
321
377
|
// Initialization/entry point.
|
|
322
378
|
// -----------------------------------------------------------------------------
|
|
323
379
|
|
|
324
380
|
// This must be named "Init_protobuf_c" because the Ruby module is named
|
|
325
381
|
// "protobuf_c" -- the VM looks for this symbol in our .so.
|
|
326
|
-
|
|
382
|
+
RUBY_FUNC_EXPORTED void Init_protobuf_c() {
|
|
327
383
|
VALUE google = rb_define_module("Google");
|
|
328
384
|
VALUE protobuf = rb_define_module_under(google, "Protobuf");
|
|
329
385
|
|
|
@@ -343,6 +399,19 @@ __attribute__((visibility("default"))) void Init_protobuf_c() {
|
|
|
343
399
|
Google_Protobuf_discard_unknown, 1);
|
|
344
400
|
rb_define_singleton_method(protobuf, "deep_copy", Google_Protobuf_deep_copy,
|
|
345
401
|
1);
|
|
402
|
+
|
|
403
|
+
VALUE internal = rb_const_get(protobuf, rb_intern("Internal"));
|
|
404
|
+
rb_define_singleton_method(
|
|
405
|
+
internal, "allocation_count_is_available",
|
|
406
|
+
Google_Protobuf_Internal_allocation_count_is_available, 0);
|
|
407
|
+
rb_define_singleton_method(internal, "allocation_count_get",
|
|
408
|
+
Google_Protobuf_Internal_allocation_count_get, 0);
|
|
409
|
+
rb_define_singleton_method(internal, "allocation_count_reset",
|
|
410
|
+
Google_Protobuf_Internal_allocation_count_reset,
|
|
411
|
+
0);
|
|
412
|
+
rb_define_singleton_method(internal, "allocation_count_fail_on",
|
|
413
|
+
Google_Protobuf_Internal_allocation_count_fail_on,
|
|
414
|
+
1);
|
|
346
415
|
}
|
|
347
416
|
|
|
348
417
|
// -----------------------------------------------------------------------------
|