google-protobuf 3.21.12 → 3.24.4
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.
Potentially problematic release.
This version of google-protobuf might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/ext/google/protobuf_c/convert.c +0 -0
- data/ext/google/protobuf_c/convert.h +0 -2
- data/ext/google/protobuf_c/defs.c +36 -25
- data/ext/google/protobuf_c/defs.h +0 -2
- data/ext/google/protobuf_c/extconf.rb +2 -3
- data/ext/google/protobuf_c/map.c +31 -44
- data/ext/google/protobuf_c/map.h +0 -2
- data/ext/google/protobuf_c/message.c +132 -105
- data/ext/google/protobuf_c/message.h +0 -2
- data/ext/google/protobuf_c/protobuf.c +36 -150
- data/ext/google/protobuf_c/protobuf.h +21 -6
- data/ext/google/protobuf_c/repeated_field.c +5 -2
- data/ext/google/protobuf_c/repeated_field.h +0 -2
- data/ext/google/protobuf_c/ruby-upb.c +11395 -9701
- data/ext/google/protobuf_c/ruby-upb.h +11620 -5210
- data/ext/google/protobuf_c/third_party/utf8_range/LICENSE +1 -0
- data/ext/google/protobuf_c/third_party/utf8_range/naive.c +0 -0
- data/ext/google/protobuf_c/third_party/utf8_range/range2-neon.c +1 -1
- data/ext/google/protobuf_c/third_party/utf8_range/range2-sse.c +0 -0
- data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +13 -1
- data/ext/google/protobuf_c/wrap_memcpy.c +0 -0
- data/lib/google/protobuf/any_pb.rb +24 -5
- data/lib/google/protobuf/api_pb.rb +26 -23
- data/lib/google/protobuf/descriptor_dsl.rb +0 -0
- data/lib/google/protobuf/descriptor_pb.rb +40 -226
- data/lib/google/protobuf/duration_pb.rb +24 -5
- data/lib/google/protobuf/empty_pb.rb +24 -3
- data/lib/google/protobuf/field_mask_pb.rb +24 -4
- data/lib/google/protobuf/message_exts.rb +5 -0
- data/lib/google/protobuf/object_cache.rb +120 -0
- data/lib/google/protobuf/plugin_pb.rb +47 -0
- data/lib/google/protobuf/repeated_field.rb +0 -0
- data/lib/google/protobuf/source_context_pb.rb +24 -4
- data/lib/google/protobuf/struct_pb.rb +24 -20
- data/lib/google/protobuf/timestamp_pb.rb +24 -5
- data/lib/google/protobuf/type_pb.rb +26 -68
- data/lib/google/protobuf/well_known_types.rb +2 -8
- data/lib/google/protobuf/wrappers_pb.rb +24 -28
- data/lib/google/protobuf.rb +1 -0
- metadata +8 -12
- data/tests/basic.rb +0 -739
- data/tests/generated_code_test.rb +0 -23
- data/tests/stress.rb +0 -38
@@ -37,6 +37,7 @@
|
|
37
37
|
#include "repeated_field.h"
|
38
38
|
|
39
39
|
static VALUE cParseError = Qnil;
|
40
|
+
static VALUE cAbstractMessage = Qnil;
|
40
41
|
static ID descriptor_instancevar_interned;
|
41
42
|
|
42
43
|
static VALUE initialize_rb_class_with_no_args(VALUE klass) {
|
@@ -52,6 +53,8 @@ VALUE MessageOrEnum_GetDescriptor(VALUE klass) {
|
|
52
53
|
// -----------------------------------------------------------------------------
|
53
54
|
|
54
55
|
typedef struct {
|
56
|
+
// IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
|
57
|
+
// macro to update VALUE references, as to trigger write barriers.
|
55
58
|
VALUE arena;
|
56
59
|
const upb_Message* msg; // Can get as mutable when non-frozen.
|
57
60
|
const upb_MessageDef*
|
@@ -64,9 +67,9 @@ static void Message_mark(void* _self) {
|
|
64
67
|
}
|
65
68
|
|
66
69
|
static rb_data_type_t Message_type = {
|
67
|
-
"Message",
|
70
|
+
"Google::Protobuf::Message",
|
68
71
|
{Message_mark, RUBY_DEFAULT_FREE, NULL},
|
69
|
-
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
72
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
70
73
|
};
|
71
74
|
|
72
75
|
static Message* ruby_to_Message(VALUE msg_rb) {
|
@@ -104,8 +107,10 @@ upb_Message* Message_GetMutable(VALUE msg_rb, const upb_MessageDef** m) {
|
|
104
107
|
void Message_InitPtr(VALUE self_, upb_Message* msg, VALUE arena) {
|
105
108
|
Message* self = ruby_to_Message(self_);
|
106
109
|
self->msg = msg;
|
107
|
-
self->arena
|
108
|
-
|
110
|
+
RB_OBJ_WRITE(self_, &self->arena, arena);
|
111
|
+
VALUE stored = ObjectCache_TryAdd(msg, self_);
|
112
|
+
(void)stored;
|
113
|
+
PBRUBY_ASSERT(stored == self_);
|
109
114
|
}
|
110
115
|
|
111
116
|
VALUE Message_GetArena(VALUE msg_rb) {
|
@@ -145,7 +150,8 @@ void Message_PrintMessage(StringBuilder* b, const upb_Message* msg,
|
|
145
150
|
for (int i = 0; i < n; i++) {
|
146
151
|
const upb_FieldDef* field = upb_MessageDef_Field(m, i);
|
147
152
|
|
148
|
-
if (upb_FieldDef_HasPresence(field) &&
|
153
|
+
if (upb_FieldDef_HasPresence(field) &&
|
154
|
+
!upb_Message_HasFieldByDef(msg, field)) {
|
149
155
|
continue;
|
150
156
|
}
|
151
157
|
|
@@ -155,7 +161,7 @@ void Message_PrintMessage(StringBuilder* b, const upb_Message* msg,
|
|
155
161
|
first = false;
|
156
162
|
}
|
157
163
|
|
158
|
-
upb_MessageValue msgval =
|
164
|
+
upb_MessageValue msgval = upb_Message_GetFieldByDef(msg, field);
|
159
165
|
|
160
166
|
StringBuilder_Printf(b, "%s: ", upb_FieldDef_Name(field));
|
161
167
|
|
@@ -241,15 +247,6 @@ static int extract_method_call(VALUE method_name, Message* self,
|
|
241
247
|
if (Match(m, name, f, o, "clear_", "")) return METHOD_CLEAR;
|
242
248
|
if (Match(m, name, f, o, "has_", "?") &&
|
243
249
|
(*o || (*f && upb_FieldDef_HasPresence(*f)))) {
|
244
|
-
// Disallow oneof hazzers for proto3.
|
245
|
-
// TODO(haberman): remove this test when we are enabling oneof hazzers for
|
246
|
-
// proto3.
|
247
|
-
if (*f && !upb_FieldDef_IsSubMessage(*f) &&
|
248
|
-
upb_FieldDef_RealContainingOneof(*f) &&
|
249
|
-
upb_MessageDef_Syntax(upb_FieldDef_ContainingType(*f)) !=
|
250
|
-
kUpb_Syntax_Proto2) {
|
251
|
-
return METHOD_UNKNOWN;
|
252
|
-
}
|
253
250
|
return METHOD_PRESENCE;
|
254
251
|
}
|
255
252
|
if (Match(m, name, f, o, "", "_as_value") && *f &&
|
@@ -278,7 +275,8 @@ static VALUE Message_oneof_accessor(VALUE _self, const upb_OneofDef* o,
|
|
278
275
|
return oneof_field == NULL ? Qfalse : Qtrue;
|
279
276
|
case METHOD_CLEAR:
|
280
277
|
if (oneof_field != NULL) {
|
281
|
-
|
278
|
+
upb_Message_ClearFieldByDef(Message_GetMutable(_self, NULL),
|
279
|
+
oneof_field);
|
282
280
|
}
|
283
281
|
return Qnil;
|
284
282
|
case METHOD_GETTER:
|
@@ -301,13 +299,13 @@ static void Message_setfield(upb_Message* msg, const upb_FieldDef* f, VALUE val,
|
|
301
299
|
} else {
|
302
300
|
if (val == Qnil &&
|
303
301
|
(upb_FieldDef_IsSubMessage(f) || upb_FieldDef_RealContainingOneof(f))) {
|
304
|
-
|
302
|
+
upb_Message_ClearFieldByDef(msg, f);
|
305
303
|
return;
|
306
304
|
}
|
307
305
|
msgval =
|
308
306
|
Convert_RubyToUpb(val, upb_FieldDef_Name(f), TypeInfo_get(f), arena);
|
309
307
|
}
|
310
|
-
|
308
|
+
upb_Message_SetFieldByDef(msg, f, msgval, arena);
|
311
309
|
}
|
312
310
|
|
313
311
|
VALUE Message_getfield(VALUE _self, const upb_FieldDef* f) {
|
@@ -329,12 +327,12 @@ VALUE Message_getfield(VALUE _self, const upb_FieldDef* f) {
|
|
329
327
|
upb_Array* arr = upb_Message_Mutable(msg, f, arena).array;
|
330
328
|
return RepeatedField_GetRubyWrapper(arr, TypeInfo_get(f), self->arena);
|
331
329
|
} else if (upb_FieldDef_IsSubMessage(f)) {
|
332
|
-
if (!
|
330
|
+
if (!upb_Message_HasFieldByDef(self->msg, f)) return Qnil;
|
333
331
|
upb_Message* submsg = upb_Message_Mutable(msg, f, arena).msg;
|
334
332
|
const upb_MessageDef* m = upb_FieldDef_MessageSubDef(f);
|
335
333
|
return Message_GetRubyWrapper(submsg, m, self->arena);
|
336
334
|
} else {
|
337
|
-
upb_MessageValue msgval =
|
335
|
+
upb_MessageValue msgval = upb_Message_GetFieldByDef(self->msg, f);
|
338
336
|
return Convert_UpbToRuby(msgval, TypeInfo_get(f), self->arena);
|
339
337
|
}
|
340
338
|
}
|
@@ -348,23 +346,24 @@ static VALUE Message_field_accessor(VALUE _self, const upb_FieldDef* f,
|
|
348
346
|
Message_setfield(Message_GetMutable(_self, NULL), f, argv[1], arena);
|
349
347
|
return Qnil;
|
350
348
|
case METHOD_CLEAR:
|
351
|
-
|
349
|
+
upb_Message_ClearFieldByDef(Message_GetMutable(_self, NULL), f);
|
352
350
|
return Qnil;
|
353
351
|
case METHOD_PRESENCE:
|
354
352
|
if (!upb_FieldDef_HasPresence(f)) {
|
355
353
|
rb_raise(rb_eRuntimeError, "Field does not have presence.");
|
356
354
|
}
|
357
|
-
return
|
355
|
+
return upb_Message_HasFieldByDef(Message_Get(_self, NULL), f);
|
358
356
|
case METHOD_WRAPPER_GETTER: {
|
359
357
|
Message* self = ruby_to_Message(_self);
|
360
|
-
if (
|
358
|
+
if (upb_Message_HasFieldByDef(self->msg, f)) {
|
361
359
|
PBRUBY_ASSERT(upb_FieldDef_IsSubMessage(f) &&
|
362
360
|
!upb_FieldDef_IsRepeated(f));
|
363
|
-
upb_MessageValue wrapper =
|
361
|
+
upb_MessageValue wrapper = upb_Message_GetFieldByDef(self->msg, f);
|
364
362
|
const upb_MessageDef* wrapper_m = upb_FieldDef_MessageSubDef(f);
|
365
363
|
const upb_FieldDef* value_f =
|
366
364
|
upb_MessageDef_FindFieldByNumber(wrapper_m, 1);
|
367
|
-
upb_MessageValue value =
|
365
|
+
upb_MessageValue value =
|
366
|
+
upb_Message_GetFieldByDef(wrapper.msg_val, value_f);
|
368
367
|
return Convert_UpbToRuby(value, TypeInfo_get(value_f), self->arena);
|
369
368
|
} else {
|
370
369
|
return Qnil;
|
@@ -373,19 +372,20 @@ static VALUE Message_field_accessor(VALUE _self, const upb_FieldDef* f,
|
|
373
372
|
case METHOD_WRAPPER_SETTER: {
|
374
373
|
upb_Message* msg = Message_GetMutable(_self, NULL);
|
375
374
|
if (argv[1] == Qnil) {
|
376
|
-
|
375
|
+
upb_Message_ClearFieldByDef(msg, f);
|
377
376
|
} else {
|
378
377
|
const upb_FieldDef* val_f =
|
379
378
|
upb_MessageDef_FindFieldByNumber(upb_FieldDef_MessageSubDef(f), 1);
|
380
379
|
upb_MessageValue msgval = Convert_RubyToUpb(
|
381
380
|
argv[1], upb_FieldDef_Name(f), TypeInfo_get(val_f), arena);
|
382
381
|
upb_Message* wrapper = upb_Message_Mutable(msg, f, arena).msg;
|
383
|
-
|
382
|
+
upb_Message_SetFieldByDef(wrapper, val_f, msgval, arena);
|
384
383
|
}
|
385
384
|
return Qnil;
|
386
385
|
}
|
387
386
|
case METHOD_ENUM_GETTER: {
|
388
|
-
upb_MessageValue msgval =
|
387
|
+
upb_MessageValue msgval =
|
388
|
+
upb_Message_GetFieldByDef(Message_Get(_self, NULL), f);
|
389
389
|
|
390
390
|
if (upb_FieldDef_Label(f) == kUpb_Label_Repeated) {
|
391
391
|
// Map repeated fields to a new type with ints
|
@@ -510,8 +510,8 @@ static int Map_initialize_kwarg(VALUE key, VALUE val, VALUE _self) {
|
|
510
510
|
k = Convert_RubyToUpb(key, "", map_init->key_type, NULL);
|
511
511
|
|
512
512
|
if (map_init->val_type.type == kUpb_CType_Message && TYPE(val) == T_HASH) {
|
513
|
-
|
514
|
-
|
513
|
+
upb_MiniTable* t = upb_MessageDef_MiniTable(map_init->val_type.def.msgdef);
|
514
|
+
upb_Message* msg = upb_Message_New(t, map_init->arena);
|
515
515
|
Message_InitFromValue(msg, map_init->val_type.def.msgdef, val,
|
516
516
|
map_init->arena);
|
517
517
|
v.msg_val = msg;
|
@@ -541,7 +541,8 @@ static upb_MessageValue MessageValue_FromValue(VALUE val, TypeInfo info,
|
|
541
541
|
upb_Arena* arena) {
|
542
542
|
if (info.type == kUpb_CType_Message) {
|
543
543
|
upb_MessageValue msgval;
|
544
|
-
|
544
|
+
upb_MiniTable* t = upb_MessageDef_MiniTable(info.def.msgdef);
|
545
|
+
upb_Message* msg = upb_Message_New(t, arena);
|
545
546
|
Message_InitFromValue(msg, info.def.msgdef, val, arena);
|
546
547
|
msgval.msg_val = msg;
|
547
548
|
return msgval;
|
@@ -593,7 +594,7 @@ static void Message_InitFieldFromValue(upb_Message* msg, const upb_FieldDef* f,
|
|
593
594
|
} else {
|
594
595
|
upb_MessageValue msgval =
|
595
596
|
Convert_RubyToUpb(val, upb_FieldDef_Name(f), TypeInfo_get(f), arena);
|
596
|
-
|
597
|
+
upb_Message_SetFieldByDef(msg, f, msgval, arena);
|
597
598
|
}
|
598
599
|
}
|
599
600
|
|
@@ -656,7 +657,8 @@ static VALUE Message_initialize(int argc, VALUE* argv, VALUE _self) {
|
|
656
657
|
Message* self = ruby_to_Message(_self);
|
657
658
|
VALUE arena_rb = Arena_new();
|
658
659
|
upb_Arena* arena = Arena_get(arena_rb);
|
659
|
-
|
660
|
+
upb_MiniTable* t = upb_MessageDef_MiniTable(self->msgdef);
|
661
|
+
upb_Message* msg = upb_Message_New(t, arena);
|
660
662
|
|
661
663
|
Message_InitPtr(_self, msg, arena_rb);
|
662
664
|
|
@@ -695,15 +697,20 @@ bool Message_Equal(const upb_Message* m1, const upb_Message* m2,
|
|
695
697
|
if (m1 == m2) return true;
|
696
698
|
|
697
699
|
size_t size1, size2;
|
698
|
-
int encode_opts =
|
700
|
+
int encode_opts =
|
701
|
+
kUpb_EncodeOption_SkipUnknown | kUpb_EncodeOption_Deterministic;
|
699
702
|
upb_Arena* arena_tmp = upb_Arena_New();
|
700
703
|
const upb_MiniTable* layout = upb_MessageDef_MiniTable(m);
|
701
704
|
|
702
705
|
// Compare deterministically serialized payloads with no unknown fields.
|
703
|
-
char* data1
|
704
|
-
char* data2
|
705
|
-
|
706
|
-
|
706
|
+
char* data1;
|
707
|
+
char* data2;
|
708
|
+
upb_EncodeStatus status1 =
|
709
|
+
upb_Encode(m1, layout, encode_opts, arena_tmp, &data1, &size1);
|
710
|
+
upb_EncodeStatus status2 =
|
711
|
+
upb_Encode(m2, layout, encode_opts, arena_tmp, &data2, &size2);
|
712
|
+
|
713
|
+
if (status1 == kUpb_EncodeStatus_Ok && status2 == kUpb_EncodeStatus_Ok) {
|
707
714
|
bool ret = (size1 == size2) && (memcmp(data1, data2, size1) == 0);
|
708
715
|
upb_Arena_Free(arena_tmp);
|
709
716
|
return ret;
|
@@ -735,15 +742,16 @@ static VALUE Message_eq(VALUE _self, VALUE _other) {
|
|
735
742
|
uint64_t Message_Hash(const upb_Message* msg, const upb_MessageDef* m,
|
736
743
|
uint64_t seed) {
|
737
744
|
upb_Arena* arena = upb_Arena_New();
|
738
|
-
|
745
|
+
char* data;
|
739
746
|
size_t size;
|
740
747
|
|
741
748
|
// Hash a deterministically serialized payloads with no unknown fields.
|
742
|
-
|
743
|
-
|
744
|
-
|
749
|
+
upb_EncodeStatus status = upb_Encode(
|
750
|
+
msg, upb_MessageDef_MiniTable(m),
|
751
|
+
kUpb_EncodeOption_SkipUnknown | kUpb_EncodeOption_Deterministic, arena,
|
752
|
+
&data, &size);
|
745
753
|
|
746
|
-
if (
|
754
|
+
if (status == kUpb_EncodeStatus_Ok) {
|
747
755
|
uint64_t ret = _upb_Hash(data, size, seed);
|
748
756
|
upb_Arena_Free(arena);
|
749
757
|
return ret;
|
@@ -823,7 +831,8 @@ static VALUE Message_CreateHash(const upb_Message* msg,
|
|
823
831
|
VALUE msg_key;
|
824
832
|
|
825
833
|
if (!is_proto2 && upb_FieldDef_IsSubMessage(field) &&
|
826
|
-
!upb_FieldDef_IsRepeated(field) &&
|
834
|
+
!upb_FieldDef_IsRepeated(field) &&
|
835
|
+
!upb_Message_HasFieldByDef(msg, field)) {
|
827
836
|
// TODO: Legacy behavior, remove when we fix the is_proto2 differences.
|
828
837
|
msg_key = ID2SYM(rb_intern(upb_FieldDef_Name(field)));
|
829
838
|
rb_hash_aset(hash, msg_key, Qnil);
|
@@ -832,12 +841,12 @@ static VALUE Message_CreateHash(const upb_Message* msg,
|
|
832
841
|
|
833
842
|
// Do not include fields that are not present (oneof or optional fields).
|
834
843
|
if (is_proto2 && upb_FieldDef_HasPresence(field) &&
|
835
|
-
!
|
844
|
+
!upb_Message_HasFieldByDef(msg, field)) {
|
836
845
|
continue;
|
837
846
|
}
|
838
847
|
|
839
848
|
msg_key = ID2SYM(rb_intern(upb_FieldDef_Name(field)));
|
840
|
-
msgval =
|
849
|
+
msgval = upb_Message_GetFieldByDef(msg, field);
|
841
850
|
|
842
851
|
// Proto2 omits empty map/repeated filds also.
|
843
852
|
|
@@ -940,7 +949,7 @@ static VALUE Message_index_set(VALUE _self, VALUE field_name, VALUE value) {
|
|
940
949
|
}
|
941
950
|
|
942
951
|
val = Convert_RubyToUpb(value, upb_FieldDef_Name(f), TypeInfo_get(f), arena);
|
943
|
-
|
952
|
+
upb_Message_SetFieldByDef(Message_GetMutable(_self, NULL), f, val, arena);
|
944
953
|
|
945
954
|
return Qnil;
|
946
955
|
}
|
@@ -969,10 +978,11 @@ static VALUE Message_decode(int argc, VALUE* argv, VALUE klass) {
|
|
969
978
|
rb_raise(rb_eArgError, "Expected hash arguments.");
|
970
979
|
}
|
971
980
|
|
972
|
-
VALUE depth =
|
981
|
+
VALUE depth =
|
982
|
+
rb_hash_lookup(hash_args, ID2SYM(rb_intern("recursion_limit")));
|
973
983
|
|
974
984
|
if (depth != Qnil && TYPE(depth) == T_FIXNUM) {
|
975
|
-
options |=
|
985
|
+
options |= upb_DecodeOptions_MaxDepth(FIX2INT(depth));
|
976
986
|
}
|
977
987
|
}
|
978
988
|
|
@@ -983,9 +993,10 @@ static VALUE Message_decode(int argc, VALUE* argv, VALUE klass) {
|
|
983
993
|
VALUE msg_rb = initialize_rb_class_with_no_args(klass);
|
984
994
|
Message* msg = ruby_to_Message(msg_rb);
|
985
995
|
|
986
|
-
upb_DecodeStatus status =
|
987
|
-
RSTRING_PTR(data), RSTRING_LEN(data), (upb_Message*)msg->msg,
|
988
|
-
|
996
|
+
upb_DecodeStatus status =
|
997
|
+
upb_Decode(RSTRING_PTR(data), RSTRING_LEN(data), (upb_Message*)msg->msg,
|
998
|
+
upb_MessageDef_MiniTable(msg->msgdef), NULL, options,
|
999
|
+
Arena_get(msg->arena));
|
989
1000
|
|
990
1001
|
if (status != kUpb_DecodeStatus_Ok) {
|
991
1002
|
rb_raise(cParseError, "Error occurred during parsing");
|
@@ -1069,7 +1080,7 @@ static VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) {
|
|
1069
1080
|
static VALUE Message_encode(int argc, VALUE* argv, VALUE klass) {
|
1070
1081
|
Message* msg = ruby_to_Message(argv[0]);
|
1071
1082
|
int options = 0;
|
1072
|
-
|
1083
|
+
char* data;
|
1073
1084
|
size_t size;
|
1074
1085
|
|
1075
1086
|
if (CLASS_OF(argv[0]) != klass) {
|
@@ -1085,19 +1096,21 @@ static VALUE Message_encode(int argc, VALUE* argv, VALUE klass) {
|
|
1085
1096
|
if (TYPE(hash_args) != T_HASH) {
|
1086
1097
|
rb_raise(rb_eArgError, "Expected hash arguments.");
|
1087
1098
|
}
|
1088
|
-
VALUE depth =
|
1099
|
+
VALUE depth =
|
1100
|
+
rb_hash_lookup(hash_args, ID2SYM(rb_intern("recursion_limit")));
|
1089
1101
|
|
1090
1102
|
if (depth != Qnil && TYPE(depth) == T_FIXNUM) {
|
1091
|
-
options |=
|
1103
|
+
options |= upb_DecodeOptions_MaxDepth(FIX2INT(depth));
|
1092
1104
|
}
|
1093
1105
|
}
|
1094
1106
|
|
1095
|
-
upb_Arena
|
1107
|
+
upb_Arena* arena = upb_Arena_New();
|
1096
1108
|
|
1097
|
-
|
1098
|
-
|
1109
|
+
upb_EncodeStatus status =
|
1110
|
+
upb_Encode(msg->msg, upb_MessageDef_MiniTable(msg->msgdef), options,
|
1111
|
+
arena, &data, &size);
|
1099
1112
|
|
1100
|
-
if (
|
1113
|
+
if (status == kUpb_EncodeStatus_Ok) {
|
1101
1114
|
VALUE ret = rb_str_new(data, size);
|
1102
1115
|
rb_enc_associate(ret, rb_ascii8bit_encoding());
|
1103
1116
|
upb_Arena_Free(arena);
|
@@ -1135,7 +1148,8 @@ static VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
|
|
1135
1148
|
if (argc == 2) {
|
1136
1149
|
VALUE hash_args = argv[1];
|
1137
1150
|
if (TYPE(hash_args) != T_HASH) {
|
1138
|
-
if (RTEST(rb_funcall(hash_args, rb_intern("respond_to?"), 1,
|
1151
|
+
if (RTEST(rb_funcall(hash_args, rb_intern("respond_to?"), 1,
|
1152
|
+
rb_str_new2("to_h")))) {
|
1139
1153
|
hash_args = rb_funcall(hash_args, rb_intern("to_h"), 0);
|
1140
1154
|
} else {
|
1141
1155
|
rb_raise(rb_eArgError, "Expected hash arguments.");
|
@@ -1152,6 +1166,12 @@ static VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
|
|
1152
1166
|
Qfalse))) {
|
1153
1167
|
options |= upb_JsonEncode_EmitDefaults;
|
1154
1168
|
}
|
1169
|
+
|
1170
|
+
if (RTEST(rb_hash_lookup2(hash_args,
|
1171
|
+
ID2SYM(rb_intern("format_enums_as_integers")),
|
1172
|
+
Qfalse))) {
|
1173
|
+
options |= upb_JsonEncode_FormatEnumsAsIntegers;
|
1174
|
+
}
|
1155
1175
|
}
|
1156
1176
|
|
1157
1177
|
upb_Status_Clear(&status);
|
@@ -1201,36 +1221,8 @@ VALUE build_class_from_descriptor(VALUE descriptor) {
|
|
1201
1221
|
klass = rb_define_class_id(
|
1202
1222
|
// Docs say this parameter is ignored. User will assign return value to
|
1203
1223
|
// their own toplevel constant class name.
|
1204
|
-
rb_intern("Message"),
|
1224
|
+
rb_intern("Message"), cAbstractMessage);
|
1205
1225
|
rb_ivar_set(klass, descriptor_instancevar_interned, descriptor);
|
1206
|
-
rb_define_alloc_func(klass, Message_alloc);
|
1207
|
-
rb_require("google/protobuf/message_exts");
|
1208
|
-
rb_include_module(klass, rb_eval_string("::Google::Protobuf::MessageExts"));
|
1209
|
-
rb_extend_object(
|
1210
|
-
klass, rb_eval_string("::Google::Protobuf::MessageExts::ClassMethods"));
|
1211
|
-
|
1212
|
-
rb_define_method(klass, "method_missing", Message_method_missing, -1);
|
1213
|
-
rb_define_method(klass, "respond_to_missing?", Message_respond_to_missing,
|
1214
|
-
-1);
|
1215
|
-
rb_define_method(klass, "initialize", Message_initialize, -1);
|
1216
|
-
rb_define_method(klass, "dup", Message_dup, 0);
|
1217
|
-
// Also define #clone so that we don't inherit Object#clone.
|
1218
|
-
rb_define_method(klass, "clone", Message_dup, 0);
|
1219
|
-
rb_define_method(klass, "==", Message_eq, 1);
|
1220
|
-
rb_define_method(klass, "eql?", Message_eq, 1);
|
1221
|
-
rb_define_method(klass, "freeze", Message_freeze, 0);
|
1222
|
-
rb_define_method(klass, "hash", Message_hash, 0);
|
1223
|
-
rb_define_method(klass, "to_h", Message_to_h, 0);
|
1224
|
-
rb_define_method(klass, "inspect", Message_inspect, 0);
|
1225
|
-
rb_define_method(klass, "to_s", Message_inspect, 0);
|
1226
|
-
rb_define_method(klass, "[]", Message_index, 1);
|
1227
|
-
rb_define_method(klass, "[]=", Message_index_set, 2);
|
1228
|
-
rb_define_singleton_method(klass, "decode", Message_decode, -1);
|
1229
|
-
rb_define_singleton_method(klass, "encode", Message_encode, -1);
|
1230
|
-
rb_define_singleton_method(klass, "decode_json", Message_decode_json, -1);
|
1231
|
-
rb_define_singleton_method(klass, "encode_json", Message_encode_json, -1);
|
1232
|
-
rb_define_singleton_method(klass, "descriptor", Message_descriptor, 0);
|
1233
|
-
|
1234
1226
|
return klass;
|
1235
1227
|
}
|
1236
1228
|
|
@@ -1296,12 +1288,12 @@ VALUE build_module_from_enumdesc(VALUE _enumdesc) {
|
|
1296
1288
|
int32_t value = upb_EnumValueDef_Number(ev);
|
1297
1289
|
if (name[0] < 'A' || name[0] > 'Z') {
|
1298
1290
|
if (name[0] >= 'a' && name[0] <= 'z') {
|
1299
|
-
name[0] -= 32;
|
1291
|
+
name[0] -= 32; // auto capitalize
|
1300
1292
|
} else {
|
1301
1293
|
rb_warn(
|
1302
|
-
|
1303
|
-
|
1304
|
-
|
1294
|
+
"Enum value '%s' does not start with an uppercase letter "
|
1295
|
+
"as is required for Ruby constants.",
|
1296
|
+
name);
|
1305
1297
|
}
|
1306
1298
|
}
|
1307
1299
|
rb_define_const(mod, name, INT2NUM(value));
|
@@ -1316,7 +1308,7 @@ VALUE build_module_from_enumdesc(VALUE _enumdesc) {
|
|
1316
1308
|
return mod;
|
1317
1309
|
}
|
1318
1310
|
|
1319
|
-
// Internal
|
1311
|
+
// Internal to the library; used by Google::Protobuf.deep_copy.
|
1320
1312
|
upb_Message* Message_deep_copy(const upb_Message* msg, const upb_MessageDef* m,
|
1321
1313
|
upb_Arena* arena) {
|
1322
1314
|
// Serialize and parse.
|
@@ -1324,11 +1316,13 @@ upb_Message* Message_deep_copy(const upb_Message* msg, const upb_MessageDef* m,
|
|
1324
1316
|
const upb_MiniTable* layout = upb_MessageDef_MiniTable(m);
|
1325
1317
|
size_t size;
|
1326
1318
|
|
1327
|
-
|
1328
|
-
|
1319
|
+
upb_Message* new_msg = upb_Message_New(layout, arena);
|
1320
|
+
char* data;
|
1329
1321
|
|
1330
|
-
if (
|
1331
|
-
|
1322
|
+
if (upb_Encode(msg, layout, 0, tmp_arena, &data, &size) !=
|
1323
|
+
kUpb_EncodeStatus_Ok ||
|
1324
|
+
upb_Decode(data, size, new_msg, layout, NULL, 0, arena) !=
|
1325
|
+
kUpb_DecodeStatus_Ok) {
|
1332
1326
|
upb_Arena_Free(tmp_arena);
|
1333
1327
|
rb_raise(cParseError, "Error occurred copying proto");
|
1334
1328
|
}
|
@@ -1355,7 +1349,8 @@ const upb_Message* Message_GetUpbMessage(VALUE value, const upb_MessageDef* m,
|
|
1355
1349
|
switch (upb_MessageDef_WellKnownType(m)) {
|
1356
1350
|
case kUpb_WellKnown_Timestamp: {
|
1357
1351
|
// Time -> Google::Protobuf::Timestamp
|
1358
|
-
|
1352
|
+
const upb_MiniTable* t = upb_MessageDef_MiniTable(m);
|
1353
|
+
upb_Message* msg = upb_Message_New(t, arena);
|
1359
1354
|
upb_MessageValue sec, nsec;
|
1360
1355
|
struct timespec time;
|
1361
1356
|
const upb_FieldDef* sec_f = upb_MessageDef_FindFieldByNumber(m, 1);
|
@@ -1366,13 +1361,14 @@ const upb_Message* Message_GetUpbMessage(VALUE value, const upb_MessageDef* m,
|
|
1366
1361
|
time = rb_time_timespec(value);
|
1367
1362
|
sec.int64_val = time.tv_sec;
|
1368
1363
|
nsec.int32_val = time.tv_nsec;
|
1369
|
-
|
1370
|
-
|
1364
|
+
upb_Message_SetFieldByDef(msg, sec_f, sec, arena);
|
1365
|
+
upb_Message_SetFieldByDef(msg, nsec_f, nsec, arena);
|
1371
1366
|
return msg;
|
1372
1367
|
}
|
1373
1368
|
case kUpb_WellKnown_Duration: {
|
1374
1369
|
// Numeric -> Google::Protobuf::Duration
|
1375
|
-
|
1370
|
+
const upb_MiniTable* t = upb_MessageDef_MiniTable(m);
|
1371
|
+
upb_Message* msg = upb_Message_New(t, arena);
|
1376
1372
|
upb_MessageValue sec, nsec;
|
1377
1373
|
const upb_FieldDef* sec_f = upb_MessageDef_FindFieldByNumber(m, 1);
|
1378
1374
|
const upb_FieldDef* nsec_f = upb_MessageDef_FindFieldByNumber(m, 2);
|
@@ -1381,8 +1377,8 @@ const upb_Message* Message_GetUpbMessage(VALUE value, const upb_MessageDef* m,
|
|
1381
1377
|
|
1382
1378
|
sec.int64_val = NUM2LL(value);
|
1383
1379
|
nsec.int32_val = round((NUM2DBL(value) - NUM2LL(value)) * 1000000000);
|
1384
|
-
|
1385
|
-
|
1380
|
+
upb_Message_SetFieldByDef(msg, sec_f, sec, arena);
|
1381
|
+
upb_Message_SetFieldByDef(msg, nsec_f, nsec, arena);
|
1386
1382
|
return msg;
|
1387
1383
|
}
|
1388
1384
|
default:
|
@@ -1399,11 +1395,42 @@ const upb_Message* Message_GetUpbMessage(VALUE value, const upb_MessageDef* m,
|
|
1399
1395
|
return self->msg;
|
1400
1396
|
}
|
1401
1397
|
|
1398
|
+
static void Message_define_class(VALUE klass) {
|
1399
|
+
rb_define_alloc_func(klass, Message_alloc);
|
1400
|
+
|
1401
|
+
rb_require("google/protobuf/message_exts");
|
1402
|
+
rb_define_method(klass, "method_missing", Message_method_missing, -1);
|
1403
|
+
rb_define_method(klass, "respond_to_missing?", Message_respond_to_missing,
|
1404
|
+
-1);
|
1405
|
+
rb_define_method(klass, "initialize", Message_initialize, -1);
|
1406
|
+
rb_define_method(klass, "dup", Message_dup, 0);
|
1407
|
+
// Also define #clone so that we don't inherit Object#clone.
|
1408
|
+
rb_define_method(klass, "clone", Message_dup, 0);
|
1409
|
+
rb_define_method(klass, "==", Message_eq, 1);
|
1410
|
+
rb_define_method(klass, "eql?", Message_eq, 1);
|
1411
|
+
rb_define_method(klass, "freeze", Message_freeze, 0);
|
1412
|
+
rb_define_method(klass, "hash", Message_hash, 0);
|
1413
|
+
rb_define_method(klass, "to_h", Message_to_h, 0);
|
1414
|
+
rb_define_method(klass, "inspect", Message_inspect, 0);
|
1415
|
+
rb_define_method(klass, "to_s", Message_inspect, 0);
|
1416
|
+
rb_define_method(klass, "[]", Message_index, 1);
|
1417
|
+
rb_define_method(klass, "[]=", Message_index_set, 2);
|
1418
|
+
rb_define_singleton_method(klass, "decode", Message_decode, -1);
|
1419
|
+
rb_define_singleton_method(klass, "encode", Message_encode, -1);
|
1420
|
+
rb_define_singleton_method(klass, "decode_json", Message_decode_json, -1);
|
1421
|
+
rb_define_singleton_method(klass, "encode_json", Message_encode_json, -1);
|
1422
|
+
rb_define_singleton_method(klass, "descriptor", Message_descriptor, 0);
|
1423
|
+
}
|
1424
|
+
|
1402
1425
|
void Message_register(VALUE protobuf) {
|
1403
1426
|
cParseError = rb_const_get(protobuf, rb_intern("ParseError"));
|
1427
|
+
cAbstractMessage =
|
1428
|
+
rb_define_class_under(protobuf, "AbstractMessage", rb_cObject);
|
1429
|
+
Message_define_class(cAbstractMessage);
|
1430
|
+
rb_gc_register_address(&cAbstractMessage);
|
1404
1431
|
|
1405
1432
|
// Ruby-interned string: "descriptor". We use this identifier to store an
|
1406
1433
|
// instance variable on message classes we create in order to link them back
|
1407
1434
|
// to their descriptors.
|
1408
|
-
descriptor_instancevar_interned = rb_intern("descriptor");
|
1435
|
+
descriptor_instancevar_interned = rb_intern("@descriptor");
|
1409
1436
|
}
|