google-protobuf 3.25.3 → 4.32.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 +39 -18
- data/ext/google/protobuf_c/defs.c +805 -128
- data/ext/google/protobuf_c/extconf.rb +20 -10
- data/ext/google/protobuf_c/glue.c +79 -0
- data/ext/google/protobuf_c/map.c +147 -65
- data/ext/google/protobuf_c/map.h +7 -3
- data/ext/google/protobuf_c/message.c +210 -174
- data/ext/google/protobuf_c/message.h +2 -6
- data/ext/google/protobuf_c/protobuf.c +33 -19
- data/ext/google/protobuf_c/protobuf.h +3 -15
- data/ext/google/protobuf_c/repeated_field.c +130 -58
- data/ext/google/protobuf_c/repeated_field.h +6 -2
- data/ext/google/protobuf_c/ruby-upb.c +10326 -7740
- data/ext/google/protobuf_c/ruby-upb.h +9952 -6435
- data/ext/google/protobuf_c/shared_convert.c +10 -5
- data/ext/google/protobuf_c/shared_convert.h +2 -2
- data/ext/google/protobuf_c/shared_message.c +3 -31
- data/ext/google/protobuf_c/shared_message.h +0 -4
- data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.c +207 -0
- data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +9 -8
- 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 +2 -23
- data/lib/google/protobuf/api_pb.rb +3 -26
- data/lib/google/protobuf/descriptor_pb.rb +8 -24
- data/lib/google/protobuf/duration_pb.rb +2 -23
- data/lib/google/protobuf/empty_pb.rb +2 -23
- data/lib/google/protobuf/ffi/descriptor.rb +14 -4
- data/lib/google/protobuf/ffi/descriptor_pool.rb +5 -1
- data/lib/google/protobuf/ffi/enum_descriptor.rb +13 -1
- data/lib/google/protobuf/ffi/ffi.rb +7 -6
- data/lib/google/protobuf/ffi/field_descriptor.rb +29 -2
- data/lib/google/protobuf/ffi/file_descriptor.rb +39 -13
- data/lib/google/protobuf/ffi/internal/arena.rb +0 -6
- data/lib/google/protobuf/ffi/internal/convert.rb +17 -30
- data/lib/google/protobuf/ffi/internal/pointer_helper.rb +2 -1
- data/lib/google/protobuf/ffi/map.rb +52 -26
- data/lib/google/protobuf/ffi/message.rb +188 -67
- data/lib/google/protobuf/ffi/method_descriptor.rb +124 -0
- data/lib/google/protobuf/ffi/object_cache.rb +3 -3
- data/lib/google/protobuf/ffi/oneof_descriptor.rb +13 -1
- data/lib/google/protobuf/ffi/repeated_field.rb +47 -19
- data/lib/google/protobuf/ffi/service_descriptor.rb +117 -0
- data/lib/google/protobuf/field_mask_pb.rb +2 -23
- data/lib/google/protobuf/internal/object_cache.rb +99 -0
- data/lib/google/protobuf/message_exts.rb +4 -0
- data/lib/google/protobuf/plugin_pb.rb +3 -25
- data/lib/google/protobuf/repeated_field.rb +4 -5
- data/lib/google/protobuf/source_context_pb.rb +2 -23
- data/lib/google/protobuf/struct_pb.rb +2 -23
- data/lib/google/protobuf/timestamp_pb.rb +2 -23
- data/lib/google/protobuf/type_pb.rb +2 -25
- data/lib/google/protobuf/wrappers_pb.rb +2 -23
- data/lib/google/protobuf.rb +1 -1
- data/lib/google/protobuf_ffi.rb +6 -4
- data/lib/google/protobuf_native.rb +0 -1
- data/lib/google/tasks/ffi.rake +2 -4
- metadata +36 -22
- data/ext/google/protobuf_c/third_party/utf8_range/naive.c +0 -92
- data/ext/google/protobuf_c/third_party/utf8_range/range2-neon.c +0 -157
- data/ext/google/protobuf_c/third_party/utf8_range/range2-sse.c +0 -170
- data/ext/google/protobuf_c/wrap_memcpy.c +0 -29
- data/lib/google/protobuf/descriptor_dsl.rb +0 -465
- data/lib/google/protobuf/object_cache.rb +0 -97
@@ -44,9 +44,11 @@ static void Message_mark(void* _self) {
|
|
44
44
|
rb_gc_mark(self->arena);
|
45
45
|
}
|
46
46
|
|
47
|
+
static size_t Message_memsize(const void* _self) { return sizeof(Message); }
|
48
|
+
|
47
49
|
static rb_data_type_t Message_type = {
|
48
50
|
"Google::Protobuf::Message",
|
49
|
-
{Message_mark, RUBY_DEFAULT_FREE,
|
51
|
+
{Message_mark, RUBY_DEFAULT_FREE, Message_memsize},
|
50
52
|
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
51
53
|
};
|
52
54
|
|
@@ -78,11 +80,13 @@ const upb_Message* Message_Get(VALUE msg_rb, const upb_MessageDef** m) {
|
|
78
80
|
}
|
79
81
|
|
80
82
|
upb_Message* Message_GetMutable(VALUE msg_rb, const upb_MessageDef** m) {
|
81
|
-
|
82
|
-
|
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;
|
83
86
|
}
|
84
87
|
|
85
|
-
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);
|
86
90
|
Message* self = ruby_to_Message(self_);
|
87
91
|
self->msg = msg;
|
88
92
|
RB_OBJ_WRITE(self_, &self->arena, arena);
|
@@ -103,7 +107,7 @@ void Message_CheckClass(VALUE klass) {
|
|
103
107
|
}
|
104
108
|
}
|
105
109
|
|
106
|
-
VALUE Message_GetRubyWrapper(upb_Message* msg, const upb_MessageDef* m,
|
110
|
+
VALUE Message_GetRubyWrapper(const upb_Message* msg, const upb_MessageDef* m,
|
107
111
|
VALUE arena) {
|
108
112
|
if (msg == NULL) return Qnil;
|
109
113
|
|
@@ -114,7 +118,6 @@ VALUE Message_GetRubyWrapper(upb_Message* msg, const upb_MessageDef* m,
|
|
114
118
|
val = Message_alloc(klass);
|
115
119
|
Message_InitPtr(val, msg, arena);
|
116
120
|
}
|
117
|
-
|
118
121
|
return val;
|
119
122
|
}
|
120
123
|
|
@@ -246,7 +249,7 @@ static int extract_method_call(VALUE method_name, Message* self,
|
|
246
249
|
static VALUE Message_oneof_accessor(VALUE _self, const upb_OneofDef* o,
|
247
250
|
int accessor_type) {
|
248
251
|
Message* self = ruby_to_Message(_self);
|
249
|
-
const upb_FieldDef* oneof_field =
|
252
|
+
const upb_FieldDef* oneof_field = upb_Message_WhichOneofByDef(self->msg, o);
|
250
253
|
|
251
254
|
switch (accessor_type) {
|
252
255
|
case METHOD_PRESENCE:
|
@@ -286,13 +289,42 @@ static void Message_setfield(upb_Message* msg, const upb_FieldDef* f, VALUE val,
|
|
286
289
|
upb_Message_SetFieldByDef(msg, f, msgval, arena);
|
287
290
|
}
|
288
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
|
+
|
289
322
|
VALUE Message_getfield(VALUE _self, const upb_FieldDef* f) {
|
290
323
|
Message* self = ruby_to_Message(_self);
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
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);
|
296
328
|
upb_Arena* arena = Arena_get(self->arena);
|
297
329
|
if (upb_FieldDef_IsMap(f)) {
|
298
330
|
upb_Map* map = upb_Message_Mutable(msg, f, arena).map;
|
@@ -305,12 +337,12 @@ VALUE Message_getfield(VALUE _self, const upb_FieldDef* f) {
|
|
305
337
|
upb_Array* arr = upb_Message_Mutable(msg, f, arena).array;
|
306
338
|
return RepeatedField_GetRubyWrapper(arr, TypeInfo_get(f), self->arena);
|
307
339
|
} else if (upb_FieldDef_IsSubMessage(f)) {
|
308
|
-
if (!upb_Message_HasFieldByDef(
|
340
|
+
if (!upb_Message_HasFieldByDef(msg, f)) return Qnil;
|
309
341
|
upb_Message* submsg = upb_Message_Mutable(msg, f, arena).msg;
|
310
342
|
const upb_MessageDef* m = upb_FieldDef_MessageSubDef(f);
|
311
343
|
return Message_GetRubyWrapper(submsg, m, self->arena);
|
312
344
|
} else {
|
313
|
-
upb_MessageValue msgval = upb_Message_GetFieldByDef(
|
345
|
+
upb_MessageValue msgval = upb_Message_GetFieldByDef(msg, f);
|
314
346
|
return Convert_UpbToRuby(msgval, TypeInfo_get(f), self->arena);
|
315
347
|
}
|
316
348
|
}
|
@@ -330,7 +362,8 @@ static VALUE Message_field_accessor(VALUE _self, const upb_FieldDef* f,
|
|
330
362
|
if (!upb_FieldDef_HasPresence(f)) {
|
331
363
|
rb_raise(rb_eRuntimeError, "Field does not have presence.");
|
332
364
|
}
|
333
|
-
return upb_Message_HasFieldByDef(Message_Get(_self, NULL), f)
|
365
|
+
return upb_Message_HasFieldByDef(Message_Get(_self, NULL), f) ? Qtrue
|
366
|
+
: Qfalse;
|
334
367
|
case METHOD_WRAPPER_GETTER: {
|
335
368
|
Message* self = ruby_to_Message(_self);
|
336
369
|
if (upb_Message_HasFieldByDef(self->msg, f)) {
|
@@ -365,7 +398,7 @@ static VALUE Message_field_accessor(VALUE _self, const upb_FieldDef* f,
|
|
365
398
|
upb_MessageValue msgval =
|
366
399
|
upb_Message_GetFieldByDef(Message_Get(_self, NULL), f);
|
367
400
|
|
368
|
-
if (
|
401
|
+
if (upb_FieldDef_IsRepeated(f)) {
|
369
402
|
// Map repeated fields to a new type with ints
|
370
403
|
VALUE arr = rb_ary_new();
|
371
404
|
size_t i, n = upb_Array_Size(msgval.array_val);
|
@@ -387,11 +420,10 @@ static VALUE Message_field_accessor(VALUE _self, const upb_FieldDef* f,
|
|
387
420
|
}
|
388
421
|
|
389
422
|
/*
|
390
|
-
*
|
391
|
-
* Message.method_missing(*args)
|
423
|
+
* ruby-doc: AbstractMessage
|
392
424
|
*
|
393
|
-
*
|
394
|
-
*
|
425
|
+
* The {AbstractMessage} class is the parent class for all Protobuf messages,
|
426
|
+
* and is generated from C code.
|
395
427
|
*
|
396
428
|
* For any field whose name does not conflict with a built-in method, an
|
397
429
|
* accessor is provided with the same name as the field, and a setter is
|
@@ -434,7 +466,6 @@ static VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) {
|
|
434
466
|
if (argc != 2) {
|
435
467
|
rb_raise(rb_eArgError, "Expected 2 arguments, received %d", argc);
|
436
468
|
}
|
437
|
-
rb_check_frozen(_self);
|
438
469
|
break;
|
439
470
|
default:
|
440
471
|
if (argc != 1) {
|
@@ -488,7 +519,8 @@ static int Map_initialize_kwarg(VALUE key, VALUE val, VALUE _self) {
|
|
488
519
|
k = Convert_RubyToUpb(key, "", map_init->key_type, NULL);
|
489
520
|
|
490
521
|
if (map_init->val_type.type == kUpb_CType_Message && TYPE(val) == T_HASH) {
|
491
|
-
upb_MiniTable* t =
|
522
|
+
const upb_MiniTable* t =
|
523
|
+
upb_MessageDef_MiniTable(map_init->val_type.def.msgdef);
|
492
524
|
upb_Message* msg = upb_Message_New(t, map_init->arena);
|
493
525
|
Message_InitFromValue(msg, map_init->val_type.def.msgdef, val,
|
494
526
|
map_init->arena);
|
@@ -519,7 +551,7 @@ static upb_MessageValue MessageValue_FromValue(VALUE val, TypeInfo info,
|
|
519
551
|
upb_Arena* arena) {
|
520
552
|
if (info.type == kUpb_CType_Message) {
|
521
553
|
upb_MessageValue msgval;
|
522
|
-
upb_MiniTable* t = upb_MessageDef_MiniTable(info.def.msgdef);
|
554
|
+
const upb_MiniTable* t = upb_MessageDef_MiniTable(info.def.msgdef);
|
523
555
|
upb_Message* msg = upb_Message_New(t, arena);
|
524
556
|
Message_InitFromValue(msg, info.def.msgdef, val, arena);
|
525
557
|
msgval.msg_val = msg;
|
@@ -559,7 +591,7 @@ static void Message_InitFieldFromValue(upb_Message* msg, const upb_FieldDef* f,
|
|
559
591
|
if (upb_FieldDef_IsMap(f)) {
|
560
592
|
upb_Map* map = upb_Message_Mutable(msg, f, arena).map;
|
561
593
|
Map_InitFromValue(map, f, val, arena);
|
562
|
-
} else if (
|
594
|
+
} else if (upb_FieldDef_IsRepeated(f)) {
|
563
595
|
upb_Array* arr = upb_Message_Mutable(msg, f, arena).array;
|
564
596
|
RepeatedField_InitFromValue(arr, f, val, arena);
|
565
597
|
} else if (upb_FieldDef_IsSubMessage(f)) {
|
@@ -620,22 +652,18 @@ void Message_InitFromValue(upb_Message* msg, const upb_MessageDef* m, VALUE val,
|
|
620
652
|
}
|
621
653
|
|
622
654
|
/*
|
623
|
-
*
|
624
|
-
* Message.new(kwargs) => new_message
|
655
|
+
* ruby-doc: AbstractMessage#initialize
|
625
656
|
*
|
626
657
|
* Creates a new instance of the given message class. Keyword arguments may be
|
627
658
|
* provided with keywords corresponding to field names.
|
628
659
|
*
|
629
|
-
*
|
630
|
-
* type exist, as provided by the #msgclass method on Descriptors after they
|
631
|
-
* have been added to a pool. The method definitions described here on the
|
632
|
-
* Message class are provided on each concrete message class.
|
660
|
+
* @param kwargs the list of field keys and values.
|
633
661
|
*/
|
634
662
|
static VALUE Message_initialize(int argc, VALUE* argv, VALUE _self) {
|
635
663
|
Message* self = ruby_to_Message(_self);
|
636
664
|
VALUE arena_rb = Arena_new();
|
637
665
|
upb_Arena* arena = Arena_get(arena_rb);
|
638
|
-
upb_MiniTable* t = upb_MessageDef_MiniTable(self->msgdef);
|
666
|
+
const upb_MiniTable* t = upb_MessageDef_MiniTable(self->msgdef);
|
639
667
|
upb_Message* msg = upb_Message_New(t, arena);
|
640
668
|
|
641
669
|
Message_InitPtr(_self, msg, arena_rb);
|
@@ -651,45 +679,32 @@ static VALUE Message_initialize(int argc, VALUE* argv, VALUE _self) {
|
|
651
679
|
}
|
652
680
|
|
653
681
|
/*
|
654
|
-
*
|
655
|
-
* Message.dup => new_message
|
682
|
+
* ruby-doc: AbstractMessage#dup
|
656
683
|
*
|
657
684
|
* Performs a shallow copy of this message and returns the new copy.
|
685
|
+
*
|
686
|
+
* @return [AbstractMessage]
|
658
687
|
*/
|
659
688
|
static VALUE Message_dup(VALUE _self) {
|
660
689
|
Message* self = ruby_to_Message(_self);
|
661
690
|
VALUE new_msg = rb_class_new_instance(0, NULL, CLASS_OF(_self));
|
662
691
|
Message* new_msg_self = ruby_to_Message(new_msg);
|
663
|
-
|
664
|
-
|
665
|
-
// TODO
|
666
|
-
// TODO
|
667
|
-
memcpy((upb_Message*)new_msg_self->msg, self->msg, size);
|
692
|
+
const upb_MiniTable* m = upb_MessageDef_MiniTable(self->msgdef);
|
693
|
+
upb_Message_ShallowCopy((upb_Message*)new_msg_self->msg, self->msg, m);
|
668
694
|
Arena_fuse(self->arena, Arena_get(new_msg_self->arena));
|
669
695
|
return new_msg;
|
670
696
|
}
|
671
697
|
|
672
|
-
// Support function for Message_eq, and also used by other #eq functions.
|
673
|
-
bool Message_Equal(const upb_Message* m1, const upb_Message* m2,
|
674
|
-
const upb_MessageDef* m) {
|
675
|
-
upb_Status status;
|
676
|
-
upb_Status_Clear(&status);
|
677
|
-
bool return_value = shared_Message_Equal(m1, m2, m, &status);
|
678
|
-
if (upb_Status_IsOk(&status)) {
|
679
|
-
return return_value;
|
680
|
-
} else {
|
681
|
-
rb_raise(cParseError, upb_Status_ErrorMessage(&status));
|
682
|
-
}
|
683
|
-
}
|
684
|
-
|
685
698
|
/*
|
686
|
-
*
|
687
|
-
* Message.==(other) => boolean
|
699
|
+
* ruby-doc: AbstractMessage#==
|
688
700
|
*
|
689
701
|
* Performs a deep comparison of this message with another. Messages are equal
|
690
702
|
* if they have the same type and if each field is equal according to the :==
|
691
703
|
* method's semantics (a more efficient comparison may actually be done if the
|
692
704
|
* field is of a primitive type).
|
705
|
+
*
|
706
|
+
* @param other [AbstractMessage]
|
707
|
+
* @return [Boolean]
|
693
708
|
*/
|
694
709
|
static VALUE Message_eq(VALUE _self, VALUE _other) {
|
695
710
|
if (CLASS_OF(_self) != CLASS_OF(_other)) return Qfalse;
|
@@ -698,7 +713,10 @@ static VALUE Message_eq(VALUE _self, VALUE _other) {
|
|
698
713
|
Message* other = ruby_to_Message(_other);
|
699
714
|
assert(self->msgdef == other->msgdef);
|
700
715
|
|
701
|
-
|
716
|
+
const upb_MiniTable* m = upb_MessageDef_MiniTable(self->msgdef);
|
717
|
+
const int options = 0;
|
718
|
+
return upb_Message_IsEqual(self->msg, other->msg, m, options) ? Qtrue
|
719
|
+
: Qfalse;
|
702
720
|
}
|
703
721
|
|
704
722
|
uint64_t Message_Hash(const upb_Message* msg, const upb_MessageDef* m,
|
@@ -709,15 +727,17 @@ uint64_t Message_Hash(const upb_Message* msg, const upb_MessageDef* m,
|
|
709
727
|
if (upb_Status_IsOk(&status)) {
|
710
728
|
return return_value;
|
711
729
|
} else {
|
712
|
-
rb_raise(cParseError,
|
730
|
+
rb_raise(cParseError, "Message_Hash(): %s",
|
731
|
+
upb_Status_ErrorMessage(&status));
|
713
732
|
}
|
714
733
|
}
|
715
734
|
|
716
735
|
/*
|
717
|
-
*
|
718
|
-
* Message.hash => hash_value
|
736
|
+
* ruby-doc: AbstractMessage#hash
|
719
737
|
*
|
720
738
|
* Returns a hash value that represents this message's field values.
|
739
|
+
*
|
740
|
+
* @return [Integer]
|
721
741
|
*/
|
722
742
|
static VALUE Message_hash(VALUE _self) {
|
723
743
|
Message* self = ruby_to_Message(_self);
|
@@ -728,12 +748,13 @@ static VALUE Message_hash(VALUE _self) {
|
|
728
748
|
}
|
729
749
|
|
730
750
|
/*
|
731
|
-
*
|
732
|
-
* Message.inspect => string
|
751
|
+
* ruby-doc: AbstractMessage#inspect
|
733
752
|
*
|
734
753
|
* Returns a human-readable string representing this message. It will be
|
735
754
|
* formatted as "<MessageType: field1: value1, field2: value2, ...>". Each
|
736
755
|
* field's value is represented according to its own #inspect method.
|
756
|
+
*
|
757
|
+
* @return [String]
|
737
758
|
*/
|
738
759
|
static VALUE Message_inspect(VALUE _self) {
|
739
760
|
Message* self = ruby_to_Message(_self);
|
@@ -766,58 +787,34 @@ static VALUE Message_CreateHash(const upb_Message* msg,
|
|
766
787
|
if (!msg) return Qnil;
|
767
788
|
|
768
789
|
VALUE hash = rb_hash_new();
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
// This is unfortunate, we should key behaviors off field attributes (like
|
774
|
-
// whether a field has presence), not proto2 vs. proto3. We should see if we
|
775
|
-
// can change this without breaking users.
|
776
|
-
is_proto2 = upb_MessageDef_Syntax(m) == kUpb_Syntax_Proto2;
|
777
|
-
|
778
|
-
for (int i = 0; i < n; i++) {
|
779
|
-
const upb_FieldDef* field = upb_MessageDef_Field(m, i);
|
780
|
-
TypeInfo type_info = TypeInfo_get(field);
|
781
|
-
upb_MessageValue msgval;
|
782
|
-
VALUE msg_value;
|
783
|
-
VALUE msg_key;
|
784
|
-
|
785
|
-
if (!is_proto2 && upb_FieldDef_IsSubMessage(field) &&
|
786
|
-
!upb_FieldDef_IsRepeated(field) &&
|
787
|
-
!upb_Message_HasFieldByDef(msg, field)) {
|
788
|
-
// TODO: Legacy behavior, remove when we fix the is_proto2 differences.
|
789
|
-
msg_key = ID2SYM(rb_intern(upb_FieldDef_Name(field)));
|
790
|
-
rb_hash_aset(hash, msg_key, Qnil);
|
791
|
-
continue;
|
792
|
-
}
|
790
|
+
size_t iter = kUpb_Message_Begin;
|
791
|
+
const upb_DefPool* pool = upb_FileDef_Pool(upb_MessageDef_File(m));
|
792
|
+
const upb_FieldDef* field;
|
793
|
+
upb_MessageValue val;
|
793
794
|
|
794
|
-
|
795
|
-
if (
|
796
|
-
|
795
|
+
while (upb_Message_Next(msg, m, pool, &field, &val, &iter)) {
|
796
|
+
if (upb_FieldDef_IsExtension(field)) {
|
797
|
+
// TODO: allow extensions once we have decided what naming scheme the
|
798
|
+
// symbol should use. eg. :"[pkg.ext]"
|
797
799
|
continue;
|
798
800
|
}
|
799
801
|
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
// Proto2 omits empty map/repeated filds also.
|
802
|
+
TypeInfo type_info = TypeInfo_get(field);
|
803
|
+
VALUE msg_value;
|
804
804
|
|
805
805
|
if (upb_FieldDef_IsMap(field)) {
|
806
806
|
const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(field);
|
807
807
|
const upb_FieldDef* key_f = upb_MessageDef_FindFieldByNumber(entry_m, 1);
|
808
808
|
const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(entry_m, 2);
|
809
809
|
upb_CType key_type = upb_FieldDef_CType(key_f);
|
810
|
-
msg_value = Map_CreateHash(
|
810
|
+
msg_value = Map_CreateHash(val.map_val, key_type, TypeInfo_get(val_f));
|
811
811
|
} else if (upb_FieldDef_IsRepeated(field)) {
|
812
|
-
|
813
|
-
(!msgval.array_val || upb_Array_Size(msgval.array_val) == 0)) {
|
814
|
-
continue;
|
815
|
-
}
|
816
|
-
msg_value = RepeatedField_CreateArray(msgval.array_val, type_info);
|
812
|
+
msg_value = RepeatedField_CreateArray(val.array_val, type_info);
|
817
813
|
} else {
|
818
|
-
msg_value = Scalar_CreateHash(
|
814
|
+
msg_value = Scalar_CreateHash(val, type_info);
|
819
815
|
}
|
820
816
|
|
817
|
+
VALUE msg_key = ID2SYM(rb_intern(upb_FieldDef_Name(field)));
|
821
818
|
rb_hash_aset(hash, msg_key, msg_value);
|
822
819
|
}
|
823
820
|
|
@@ -833,10 +830,11 @@ VALUE Scalar_CreateHash(upb_MessageValue msgval, TypeInfo type_info) {
|
|
833
830
|
}
|
834
831
|
|
835
832
|
/*
|
836
|
-
*
|
837
|
-
* Message.to_h => {}
|
833
|
+
* ruby-doc: AbstractMessage#to_h
|
838
834
|
*
|
839
835
|
* Returns the message as a Ruby Hash object, with keys as symbols.
|
836
|
+
*
|
837
|
+
* @return [Hash]
|
840
838
|
*/
|
841
839
|
static VALUE Message_to_h(VALUE _self) {
|
842
840
|
Message* self = ruby_to_Message(_self);
|
@@ -844,53 +842,56 @@ static VALUE Message_to_h(VALUE _self) {
|
|
844
842
|
}
|
845
843
|
|
846
844
|
/*
|
847
|
-
*
|
848
|
-
* Message.freeze => self
|
845
|
+
* ruby-doc: AbstractMessage#frozen?
|
849
846
|
*
|
850
|
-
*
|
851
|
-
* Ruby object
|
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.
|
850
|
+
*
|
851
|
+
* @return [Boolean]
|
852
852
|
*/
|
853
|
-
|
853
|
+
VALUE Message_frozen(VALUE _self) {
|
854
854
|
Message* self = ruby_to_Message(_self);
|
855
|
-
if (!
|
856
|
-
|
857
|
-
|
855
|
+
if (!upb_Message_IsFrozen(self->msg)) {
|
856
|
+
PBRUBY_ASSERT(!RB_OBJ_FROZEN(_self));
|
857
|
+
return Qfalse;
|
858
858
|
}
|
859
|
-
|
859
|
+
|
860
|
+
// Lazily freeze the Ruby wrapper.
|
861
|
+
if (!RB_OBJ_FROZEN(_self)) RB_OBJ_FREEZE(_self);
|
862
|
+
return Qtrue;
|
860
863
|
}
|
861
864
|
|
862
865
|
/*
|
863
|
-
*
|
864
|
-
*
|
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]
|
865
872
|
*/
|
866
|
-
VALUE
|
873
|
+
VALUE Message_freeze(VALUE _self) {
|
867
874
|
Message* self = ruby_to_Message(_self);
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
if (field != Qnil) {
|
876
|
-
if (upb_FieldDef_IsMap(f)) {
|
877
|
-
Map_internal_deep_freeze(field);
|
878
|
-
} else if (upb_FieldDef_IsRepeated(f)) {
|
879
|
-
RepeatedField_internal_deep_freeze(field);
|
880
|
-
} else if (upb_FieldDef_IsSubMessage(f)) {
|
881
|
-
Message_internal_deep_freeze(field);
|
882
|
-
}
|
883
|
-
}
|
875
|
+
if (RB_OBJ_FROZEN(_self)) {
|
876
|
+
PBRUBY_ASSERT(upb_Message_IsFrozen(self->msg));
|
877
|
+
return _self;
|
878
|
+
}
|
879
|
+
if (!upb_Message_IsFrozen(self->msg)) {
|
880
|
+
upb_Message_Freeze(Message_GetMutable(_self, NULL),
|
881
|
+
upb_MessageDef_MiniTable(self->msgdef));
|
884
882
|
}
|
883
|
+
RB_OBJ_FREEZE(_self);
|
885
884
|
return _self;
|
886
885
|
}
|
887
886
|
|
888
887
|
/*
|
889
|
-
*
|
890
|
-
* Message.[](index) => value
|
888
|
+
* ruby-doc: AbstractMessage#[]
|
891
889
|
*
|
892
890
|
* Accesses a field's value by field name. The provided field name should be a
|
893
891
|
* string.
|
892
|
+
*
|
893
|
+
* @param index [Integer]
|
894
|
+
* @return [Object]
|
894
895
|
*/
|
895
896
|
static VALUE Message_index(VALUE _self, VALUE field_name) {
|
896
897
|
Message* self = ruby_to_Message(_self);
|
@@ -907,11 +908,14 @@ static VALUE Message_index(VALUE _self, VALUE field_name) {
|
|
907
908
|
}
|
908
909
|
|
909
910
|
/*
|
910
|
-
*
|
911
|
-
* Message.[]=(index, value)
|
911
|
+
* ruby-doc: AbstractMessage#[]=
|
912
912
|
*
|
913
913
|
* Sets a field's value by field name. The provided field name should be a
|
914
914
|
* string.
|
915
|
+
*
|
916
|
+
* @param index [Integer]
|
917
|
+
* @param value [Object]
|
918
|
+
* @return [nil]
|
915
919
|
*/
|
916
920
|
static VALUE Message_index_set(VALUE _self, VALUE field_name, VALUE value) {
|
917
921
|
Message* self = ruby_to_Message(_self);
|
@@ -933,14 +937,16 @@ static VALUE Message_index_set(VALUE _self, VALUE field_name, VALUE value) {
|
|
933
937
|
}
|
934
938
|
|
935
939
|
/*
|
936
|
-
*
|
937
|
-
* MessageClass.decode(data, options) => message
|
940
|
+
* ruby-doc: AbstractMessage.decode
|
938
941
|
*
|
939
942
|
* Decodes the given data (as a string containing bytes in protocol buffers wire
|
940
943
|
* format) under the interpretation given by this message class's definition
|
941
944
|
* and returns a message object with the corresponding field values.
|
942
|
-
* @param
|
943
|
-
*
|
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]
|
944
950
|
*/
|
945
951
|
static VALUE Message_decode(int argc, VALUE* argv, VALUE klass) {
|
946
952
|
VALUE data = argv[0];
|
@@ -987,31 +993,29 @@ VALUE Message_decode_bytes(int size, const char* bytes, int options,
|
|
987
993
|
rb_raise(cParseError, "Error occurred during parsing");
|
988
994
|
}
|
989
995
|
if (freeze) {
|
990
|
-
|
996
|
+
Message_freeze(msg_rb);
|
991
997
|
}
|
992
998
|
return msg_rb;
|
993
999
|
}
|
994
1000
|
|
995
1001
|
/*
|
996
|
-
*
|
997
|
-
* MessageClass.decode_json(data, options = {}) => message
|
1002
|
+
* ruby-doc: AbstractMessage.decode_json
|
998
1003
|
*
|
999
1004
|
* Decodes the given data (as a string containing bytes in protocol buffers wire
|
1000
1005
|
* format) under the interpretration given by this message class's definition
|
1001
1006
|
* and returns a message object with the corresponding field values.
|
1002
1007
|
*
|
1003
|
-
*
|
1004
|
-
*
|
1005
|
-
*
|
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]
|
1006
1013
|
*/
|
1007
1014
|
static VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) {
|
1008
1015
|
VALUE data = argv[0];
|
1009
1016
|
int options = 0;
|
1010
1017
|
upb_Status status;
|
1011
1018
|
|
1012
|
-
// TODO: use this message's pool instead.
|
1013
|
-
const upb_DefPool* symtab = DescriptorPool_GetSymtab(generated_pool);
|
1014
|
-
|
1015
1019
|
if (argc < 1 || argc > 2) {
|
1016
1020
|
rb_raise(rb_eArgError, "Expected 1 or 2 arguments.");
|
1017
1021
|
}
|
@@ -1045,24 +1049,35 @@ static VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) {
|
|
1045
1049
|
}
|
1046
1050
|
|
1047
1051
|
upb_Status_Clear(&status);
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1052
|
+
const upb_DefPool* pool = upb_FileDef_Pool(upb_MessageDef_File(msg->msgdef));
|
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;
|
1053
1065
|
}
|
1054
1066
|
|
1055
1067
|
return msg_rb;
|
1056
1068
|
}
|
1057
1069
|
|
1058
1070
|
/*
|
1059
|
-
*
|
1060
|
-
* MessageClass.encode(msg, options) => bytes
|
1071
|
+
* ruby-doc: AbstractMessage.encode
|
1061
1072
|
*
|
1062
1073
|
* Encodes the given message object to its serialized form in protocol buffers
|
1063
1074
|
* wire format.
|
1064
|
-
*
|
1065
|
-
*
|
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]
|
1066
1081
|
*/
|
1067
1082
|
static VALUE Message_encode(int argc, VALUE* argv, VALUE klass) {
|
1068
1083
|
Message* msg = ruby_to_Message(argv[0]);
|
@@ -1109,14 +1124,17 @@ static VALUE Message_encode(int argc, VALUE* argv, VALUE klass) {
|
|
1109
1124
|
}
|
1110
1125
|
|
1111
1126
|
/*
|
1112
|
-
*
|
1113
|
-
* MessageClass.encode_json(msg, options = {}) => json_string
|
1127
|
+
* ruby-doc: AbstractMessage.encode_json
|
1114
1128
|
*
|
1115
1129
|
* Encodes the given message object into its serialized JSON representation.
|
1116
|
-
*
|
1117
|
-
*
|
1118
|
-
*
|
1119
|
-
*
|
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]
|
1120
1138
|
*/
|
1121
1139
|
static VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
|
1122
1140
|
Message* msg = ruby_to_Message(argv[0]);
|
@@ -1125,9 +1143,6 @@ static VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
|
|
1125
1143
|
size_t size;
|
1126
1144
|
upb_Status status;
|
1127
1145
|
|
1128
|
-
// TODO: use this message's pool instead.
|
1129
|
-
const upb_DefPool* symtab = DescriptorPool_GetSymtab(generated_pool);
|
1130
|
-
|
1131
1146
|
if (argc < 1 || argc > 2) {
|
1132
1147
|
rb_raise(rb_eArgError, "Expected 1 or 2 arguments.");
|
1133
1148
|
}
|
@@ -1162,8 +1177,9 @@ static VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
|
|
1162
1177
|
}
|
1163
1178
|
|
1164
1179
|
upb_Status_Clear(&status);
|
1165
|
-
|
1166
|
-
|
1180
|
+
const upb_DefPool* pool = upb_FileDef_Pool(upb_MessageDef_File(msg->msgdef));
|
1181
|
+
size = upb_JsonEncode(msg->msg, msg->msgdef, pool, options, buf, sizeof(buf),
|
1182
|
+
&status);
|
1167
1183
|
|
1168
1184
|
if (!upb_Status_IsOk(&status)) {
|
1169
1185
|
rb_raise(cParseError, "Error occurred during encoding: %s",
|
@@ -1173,7 +1189,7 @@ static VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
|
|
1173
1189
|
VALUE ret;
|
1174
1190
|
if (size >= sizeof(buf)) {
|
1175
1191
|
char* buf2 = malloc(size + 1);
|
1176
|
-
upb_JsonEncode(msg->msg, msg->msgdef,
|
1192
|
+
upb_JsonEncode(msg->msg, msg->msgdef, pool, options, buf2, size + 1,
|
1177
1193
|
&status);
|
1178
1194
|
ret = rb_str_new(buf2, size);
|
1179
1195
|
free(buf2);
|
@@ -1186,11 +1202,12 @@ static VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
|
|
1186
1202
|
}
|
1187
1203
|
|
1188
1204
|
/*
|
1189
|
-
*
|
1190
|
-
* Message.descriptor => descriptor
|
1205
|
+
* ruby-doc: AbstractMessage.descriptor
|
1191
1206
|
*
|
1192
1207
|
* Class method that returns the Descriptor instance corresponding to this
|
1193
1208
|
* message class's type.
|
1209
|
+
*
|
1210
|
+
* @return [Descriptor]
|
1194
1211
|
*/
|
1195
1212
|
static VALUE Message_descriptor(VALUE klass) {
|
1196
1213
|
return rb_ivar_get(klass, descriptor_instancevar_interned);
|
@@ -1213,12 +1230,26 @@ VALUE build_class_from_descriptor(VALUE descriptor) {
|
|
1213
1230
|
return klass;
|
1214
1231
|
}
|
1215
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
|
+
|
1216
1245
|
/*
|
1217
|
-
*
|
1218
|
-
* Enum.lookup(number) => name
|
1246
|
+
* ruby-doc: Enum.lookup
|
1219
1247
|
*
|
1220
1248
|
* This module method, provided on each generated enum module, looks up an enum
|
1221
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]
|
1222
1253
|
*/
|
1223
1254
|
static VALUE enum_lookup(VALUE self, VALUE number) {
|
1224
1255
|
int32_t num = NUM2INT(number);
|
@@ -1233,11 +1264,13 @@ static VALUE enum_lookup(VALUE self, VALUE number) {
|
|
1233
1264
|
}
|
1234
1265
|
|
1235
1266
|
/*
|
1236
|
-
*
|
1237
|
-
* Enum.resolve(name) => number
|
1267
|
+
* ruby-doc: Enum.resolve
|
1238
1268
|
*
|
1239
1269
|
* This module method, provided on each generated enum module, looks up an enum
|
1240
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]
|
1241
1274
|
*/
|
1242
1275
|
static VALUE enum_resolve(VALUE self, VALUE sym) {
|
1243
1276
|
const char* name = rb_id2name(SYM2ID(sym));
|
@@ -1252,11 +1285,13 @@ static VALUE enum_resolve(VALUE self, VALUE sym) {
|
|
1252
1285
|
}
|
1253
1286
|
|
1254
1287
|
/*
|
1255
|
-
*
|
1256
|
-
* Enum.descriptor
|
1288
|
+
* ruby-doc: Enum.descriptor
|
1257
1289
|
*
|
1258
1290
|
* This module method, provided on each generated enum module, returns the
|
1259
|
-
* EnumDescriptor corresponding to this enum type.
|
1291
|
+
* {EnumDescriptor} corresponding to this enum type.
|
1292
|
+
*
|
1293
|
+
* @return [EnumDescriptor]
|
1294
|
+
*
|
1260
1295
|
*/
|
1261
1296
|
static VALUE enum_descriptor(VALUE self) {
|
1262
1297
|
return rb_ivar_get(self, descriptor_instancevar_interned);
|
@@ -1399,6 +1434,7 @@ static void Message_define_class(VALUE klass) {
|
|
1399
1434
|
rb_define_method(klass, "==", Message_eq, 1);
|
1400
1435
|
rb_define_method(klass, "eql?", Message_eq, 1);
|
1401
1436
|
rb_define_method(klass, "freeze", Message_freeze, 0);
|
1437
|
+
rb_define_method(klass, "frozen?", Message_frozen, 0);
|
1402
1438
|
rb_define_method(klass, "hash", Message_hash, 0);
|
1403
1439
|
rb_define_method(klass, "to_h", Message_to_h, 0);
|
1404
1440
|
rb_define_method(klass, "inspect", Message_inspect, 0);
|