google-protobuf 3.25.8 → 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 +33 -15
- data/ext/google/protobuf_c/defs.c +802 -125
- 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 +145 -63
- data/ext/google/protobuf_c/map.h +7 -3
- data/ext/google/protobuf_c/message.c +204 -171
- 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 +10324 -7764
- data/ext/google/protobuf_c/ruby-upb.h +9959 -6442
- data/ext/google/protobuf_c/shared_convert.c +7 -2
- data/ext/google/protobuf_c/shared_message.c +3 -32
- 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) {
|
@@ -560,7 +591,7 @@ static void Message_InitFieldFromValue(upb_Message* msg, const upb_FieldDef* f,
|
|
560
591
|
if (upb_FieldDef_IsMap(f)) {
|
561
592
|
upb_Map* map = upb_Message_Mutable(msg, f, arena).map;
|
562
593
|
Map_InitFromValue(map, f, val, arena);
|
563
|
-
} else if (
|
594
|
+
} else if (upb_FieldDef_IsRepeated(f)) {
|
564
595
|
upb_Array* arr = upb_Message_Mutable(msg, f, arena).array;
|
565
596
|
RepeatedField_InitFromValue(arr, f, val, arena);
|
566
597
|
} else if (upb_FieldDef_IsSubMessage(f)) {
|
@@ -621,16 +652,12 @@ void Message_InitFromValue(upb_Message* msg, const upb_MessageDef* m, VALUE val,
|
|
621
652
|
}
|
622
653
|
|
623
654
|
/*
|
624
|
-
*
|
625
|
-
* Message.new(kwargs) => new_message
|
655
|
+
* ruby-doc: AbstractMessage#initialize
|
626
656
|
*
|
627
657
|
* Creates a new instance of the given message class. Keyword arguments may be
|
628
658
|
* provided with keywords corresponding to field names.
|
629
659
|
*
|
630
|
-
*
|
631
|
-
* type exist, as provided by the #msgclass method on Descriptors after they
|
632
|
-
* have been added to a pool. The method definitions described here on the
|
633
|
-
* Message class are provided on each concrete message class.
|
660
|
+
* @param kwargs the list of field keys and values.
|
634
661
|
*/
|
635
662
|
static VALUE Message_initialize(int argc, VALUE* argv, VALUE _self) {
|
636
663
|
Message* self = ruby_to_Message(_self);
|
@@ -652,46 +679,32 @@ static VALUE Message_initialize(int argc, VALUE* argv, VALUE _self) {
|
|
652
679
|
}
|
653
680
|
|
654
681
|
/*
|
655
|
-
*
|
656
|
-
* Message.dup => new_message
|
682
|
+
* ruby-doc: AbstractMessage#dup
|
657
683
|
*
|
658
684
|
* Performs a shallow copy of this message and returns the new copy.
|
685
|
+
*
|
686
|
+
* @return [AbstractMessage]
|
659
687
|
*/
|
660
688
|
static VALUE Message_dup(VALUE _self) {
|
661
689
|
Message* self = ruby_to_Message(_self);
|
662
690
|
VALUE new_msg = rb_class_new_instance(0, NULL, CLASS_OF(_self));
|
663
691
|
Message* new_msg_self = ruby_to_Message(new_msg);
|
664
|
-
|
665
|
-
|
666
|
-
// TODO
|
667
|
-
// TODO
|
668
|
-
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);
|
669
694
|
Arena_fuse(self->arena, Arena_get(new_msg_self->arena));
|
670
695
|
return new_msg;
|
671
696
|
}
|
672
697
|
|
673
|
-
// Support function for Message_eq, and also used by other #eq functions.
|
674
|
-
bool Message_Equal(const upb_Message* m1, const upb_Message* m2,
|
675
|
-
const upb_MessageDef* m) {
|
676
|
-
upb_Status status;
|
677
|
-
upb_Status_Clear(&status);
|
678
|
-
bool return_value = shared_Message_Equal(m1, m2, m, &status);
|
679
|
-
if (upb_Status_IsOk(&status)) {
|
680
|
-
return return_value;
|
681
|
-
} else {
|
682
|
-
rb_raise(cParseError, "Message_Equal(): %s",
|
683
|
-
upb_Status_ErrorMessage(&status));
|
684
|
-
}
|
685
|
-
}
|
686
|
-
|
687
698
|
/*
|
688
|
-
*
|
689
|
-
* Message.==(other) => boolean
|
699
|
+
* ruby-doc: AbstractMessage#==
|
690
700
|
*
|
691
701
|
* Performs a deep comparison of this message with another. Messages are equal
|
692
702
|
* if they have the same type and if each field is equal according to the :==
|
693
703
|
* method's semantics (a more efficient comparison may actually be done if the
|
694
704
|
* field is of a primitive type).
|
705
|
+
*
|
706
|
+
* @param other [AbstractMessage]
|
707
|
+
* @return [Boolean]
|
695
708
|
*/
|
696
709
|
static VALUE Message_eq(VALUE _self, VALUE _other) {
|
697
710
|
if (CLASS_OF(_self) != CLASS_OF(_other)) return Qfalse;
|
@@ -700,7 +713,10 @@ static VALUE Message_eq(VALUE _self, VALUE _other) {
|
|
700
713
|
Message* other = ruby_to_Message(_other);
|
701
714
|
assert(self->msgdef == other->msgdef);
|
702
715
|
|
703
|
-
|
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;
|
704
720
|
}
|
705
721
|
|
706
722
|
uint64_t Message_Hash(const upb_Message* msg, const upb_MessageDef* m,
|
@@ -717,10 +733,11 @@ uint64_t Message_Hash(const upb_Message* msg, const upb_MessageDef* m,
|
|
717
733
|
}
|
718
734
|
|
719
735
|
/*
|
720
|
-
*
|
721
|
-
* Message.hash => hash_value
|
736
|
+
* ruby-doc: AbstractMessage#hash
|
722
737
|
*
|
723
738
|
* Returns a hash value that represents this message's field values.
|
739
|
+
*
|
740
|
+
* @return [Integer]
|
724
741
|
*/
|
725
742
|
static VALUE Message_hash(VALUE _self) {
|
726
743
|
Message* self = ruby_to_Message(_self);
|
@@ -731,12 +748,13 @@ static VALUE Message_hash(VALUE _self) {
|
|
731
748
|
}
|
732
749
|
|
733
750
|
/*
|
734
|
-
*
|
735
|
-
* Message.inspect => string
|
751
|
+
* ruby-doc: AbstractMessage#inspect
|
736
752
|
*
|
737
753
|
* Returns a human-readable string representing this message. It will be
|
738
754
|
* formatted as "<MessageType: field1: value1, field2: value2, ...>". Each
|
739
755
|
* field's value is represented according to its own #inspect method.
|
756
|
+
*
|
757
|
+
* @return [String]
|
740
758
|
*/
|
741
759
|
static VALUE Message_inspect(VALUE _self) {
|
742
760
|
Message* self = ruby_to_Message(_self);
|
@@ -769,58 +787,34 @@ static VALUE Message_CreateHash(const upb_Message* msg,
|
|
769
787
|
if (!msg) return Qnil;
|
770
788
|
|
771
789
|
VALUE hash = rb_hash_new();
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
// This is unfortunate, we should key behaviors off field attributes (like
|
777
|
-
// whether a field has presence), not proto2 vs. proto3. We should see if we
|
778
|
-
// can change this without breaking users.
|
779
|
-
is_proto2 = upb_MessageDef_Syntax(m) == kUpb_Syntax_Proto2;
|
780
|
-
|
781
|
-
for (int i = 0; i < n; i++) {
|
782
|
-
const upb_FieldDef* field = upb_MessageDef_Field(m, i);
|
783
|
-
TypeInfo type_info = TypeInfo_get(field);
|
784
|
-
upb_MessageValue msgval;
|
785
|
-
VALUE msg_value;
|
786
|
-
VALUE msg_key;
|
787
|
-
|
788
|
-
if (!is_proto2 && upb_FieldDef_IsSubMessage(field) &&
|
789
|
-
!upb_FieldDef_IsRepeated(field) &&
|
790
|
-
!upb_Message_HasFieldByDef(msg, field)) {
|
791
|
-
// TODO: Legacy behavior, remove when we fix the is_proto2 differences.
|
792
|
-
msg_key = ID2SYM(rb_intern(upb_FieldDef_Name(field)));
|
793
|
-
rb_hash_aset(hash, msg_key, Qnil);
|
794
|
-
continue;
|
795
|
-
}
|
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;
|
796
794
|
|
797
|
-
|
798
|
-
if (
|
799
|
-
|
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]"
|
800
799
|
continue;
|
801
800
|
}
|
802
801
|
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
// Proto2 omits empty map/repeated filds also.
|
802
|
+
TypeInfo type_info = TypeInfo_get(field);
|
803
|
+
VALUE msg_value;
|
807
804
|
|
808
805
|
if (upb_FieldDef_IsMap(field)) {
|
809
806
|
const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(field);
|
810
807
|
const upb_FieldDef* key_f = upb_MessageDef_FindFieldByNumber(entry_m, 1);
|
811
808
|
const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(entry_m, 2);
|
812
809
|
upb_CType key_type = upb_FieldDef_CType(key_f);
|
813
|
-
msg_value = Map_CreateHash(
|
810
|
+
msg_value = Map_CreateHash(val.map_val, key_type, TypeInfo_get(val_f));
|
814
811
|
} else if (upb_FieldDef_IsRepeated(field)) {
|
815
|
-
|
816
|
-
(!msgval.array_val || upb_Array_Size(msgval.array_val) == 0)) {
|
817
|
-
continue;
|
818
|
-
}
|
819
|
-
msg_value = RepeatedField_CreateArray(msgval.array_val, type_info);
|
812
|
+
msg_value = RepeatedField_CreateArray(val.array_val, type_info);
|
820
813
|
} else {
|
821
|
-
msg_value = Scalar_CreateHash(
|
814
|
+
msg_value = Scalar_CreateHash(val, type_info);
|
822
815
|
}
|
823
816
|
|
817
|
+
VALUE msg_key = ID2SYM(rb_intern(upb_FieldDef_Name(field)));
|
824
818
|
rb_hash_aset(hash, msg_key, msg_value);
|
825
819
|
}
|
826
820
|
|
@@ -836,10 +830,11 @@ VALUE Scalar_CreateHash(upb_MessageValue msgval, TypeInfo type_info) {
|
|
836
830
|
}
|
837
831
|
|
838
832
|
/*
|
839
|
-
*
|
840
|
-
* Message.to_h => {}
|
833
|
+
* ruby-doc: AbstractMessage#to_h
|
841
834
|
*
|
842
835
|
* Returns the message as a Ruby Hash object, with keys as symbols.
|
836
|
+
*
|
837
|
+
* @return [Hash]
|
843
838
|
*/
|
844
839
|
static VALUE Message_to_h(VALUE _self) {
|
845
840
|
Message* self = ruby_to_Message(_self);
|
@@ -847,53 +842,56 @@ static VALUE Message_to_h(VALUE _self) {
|
|
847
842
|
}
|
848
843
|
|
849
844
|
/*
|
850
|
-
*
|
851
|
-
* Message.freeze => self
|
845
|
+
* ruby-doc: AbstractMessage#frozen?
|
852
846
|
*
|
853
|
-
*
|
854
|
-
* 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]
|
855
852
|
*/
|
856
|
-
|
853
|
+
VALUE Message_frozen(VALUE _self) {
|
857
854
|
Message* self = ruby_to_Message(_self);
|
858
|
-
if (!
|
859
|
-
|
860
|
-
|
855
|
+
if (!upb_Message_IsFrozen(self->msg)) {
|
856
|
+
PBRUBY_ASSERT(!RB_OBJ_FROZEN(_self));
|
857
|
+
return Qfalse;
|
861
858
|
}
|
862
|
-
|
859
|
+
|
860
|
+
// Lazily freeze the Ruby wrapper.
|
861
|
+
if (!RB_OBJ_FROZEN(_self)) RB_OBJ_FREEZE(_self);
|
862
|
+
return Qtrue;
|
863
863
|
}
|
864
864
|
|
865
865
|
/*
|
866
|
-
*
|
867
|
-
*
|
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]
|
868
872
|
*/
|
869
|
-
VALUE
|
873
|
+
VALUE Message_freeze(VALUE _self) {
|
870
874
|
Message* self = ruby_to_Message(_self);
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
if (field != Qnil) {
|
879
|
-
if (upb_FieldDef_IsMap(f)) {
|
880
|
-
Map_internal_deep_freeze(field);
|
881
|
-
} else if (upb_FieldDef_IsRepeated(f)) {
|
882
|
-
RepeatedField_internal_deep_freeze(field);
|
883
|
-
} else if (upb_FieldDef_IsSubMessage(f)) {
|
884
|
-
Message_internal_deep_freeze(field);
|
885
|
-
}
|
886
|
-
}
|
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));
|
887
882
|
}
|
883
|
+
RB_OBJ_FREEZE(_self);
|
888
884
|
return _self;
|
889
885
|
}
|
890
886
|
|
891
887
|
/*
|
892
|
-
*
|
893
|
-
* Message.[](index) => value
|
888
|
+
* ruby-doc: AbstractMessage#[]
|
894
889
|
*
|
895
890
|
* Accesses a field's value by field name. The provided field name should be a
|
896
891
|
* string.
|
892
|
+
*
|
893
|
+
* @param index [Integer]
|
894
|
+
* @return [Object]
|
897
895
|
*/
|
898
896
|
static VALUE Message_index(VALUE _self, VALUE field_name) {
|
899
897
|
Message* self = ruby_to_Message(_self);
|
@@ -910,11 +908,14 @@ static VALUE Message_index(VALUE _self, VALUE field_name) {
|
|
910
908
|
}
|
911
909
|
|
912
910
|
/*
|
913
|
-
*
|
914
|
-
* Message.[]=(index, value)
|
911
|
+
* ruby-doc: AbstractMessage#[]=
|
915
912
|
*
|
916
913
|
* Sets a field's value by field name. The provided field name should be a
|
917
914
|
* string.
|
915
|
+
*
|
916
|
+
* @param index [Integer]
|
917
|
+
* @param value [Object]
|
918
|
+
* @return [nil]
|
918
919
|
*/
|
919
920
|
static VALUE Message_index_set(VALUE _self, VALUE field_name, VALUE value) {
|
920
921
|
Message* self = ruby_to_Message(_self);
|
@@ -936,14 +937,16 @@ static VALUE Message_index_set(VALUE _self, VALUE field_name, VALUE value) {
|
|
936
937
|
}
|
937
938
|
|
938
939
|
/*
|
939
|
-
*
|
940
|
-
* MessageClass.decode(data, options) => message
|
940
|
+
* ruby-doc: AbstractMessage.decode
|
941
941
|
*
|
942
942
|
* Decodes the given data (as a string containing bytes in protocol buffers wire
|
943
943
|
* format) under the interpretation given by this message class's definition
|
944
944
|
* and returns a message object with the corresponding field values.
|
945
|
-
* @param
|
946
|
-
*
|
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]
|
947
950
|
*/
|
948
951
|
static VALUE Message_decode(int argc, VALUE* argv, VALUE klass) {
|
949
952
|
VALUE data = argv[0];
|
@@ -990,31 +993,29 @@ VALUE Message_decode_bytes(int size, const char* bytes, int options,
|
|
990
993
|
rb_raise(cParseError, "Error occurred during parsing");
|
991
994
|
}
|
992
995
|
if (freeze) {
|
993
|
-
|
996
|
+
Message_freeze(msg_rb);
|
994
997
|
}
|
995
998
|
return msg_rb;
|
996
999
|
}
|
997
1000
|
|
998
1001
|
/*
|
999
|
-
*
|
1000
|
-
* MessageClass.decode_json(data, options = {}) => message
|
1002
|
+
* ruby-doc: AbstractMessage.decode_json
|
1001
1003
|
*
|
1002
1004
|
* Decodes the given data (as a string containing bytes in protocol buffers wire
|
1003
1005
|
* format) under the interpretration given by this message class's definition
|
1004
1006
|
* and returns a message object with the corresponding field values.
|
1005
1007
|
*
|
1006
|
-
*
|
1007
|
-
*
|
1008
|
-
*
|
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]
|
1009
1013
|
*/
|
1010
1014
|
static VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) {
|
1011
1015
|
VALUE data = argv[0];
|
1012
1016
|
int options = 0;
|
1013
1017
|
upb_Status status;
|
1014
1018
|
|
1015
|
-
// TODO: use this message's pool instead.
|
1016
|
-
const upb_DefPool* symtab = DescriptorPool_GetSymtab(generated_pool);
|
1017
|
-
|
1018
1019
|
if (argc < 1 || argc > 2) {
|
1019
1020
|
rb_raise(rb_eArgError, "Expected 1 or 2 arguments.");
|
1020
1021
|
}
|
@@ -1048,24 +1049,35 @@ static VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) {
|
|
1048
1049
|
}
|
1049
1050
|
|
1050
1051
|
upb_Status_Clear(&status);
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
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;
|
1056
1065
|
}
|
1057
1066
|
|
1058
1067
|
return msg_rb;
|
1059
1068
|
}
|
1060
1069
|
|
1061
1070
|
/*
|
1062
|
-
*
|
1063
|
-
* MessageClass.encode(msg, options) => bytes
|
1071
|
+
* ruby-doc: AbstractMessage.encode
|
1064
1072
|
*
|
1065
1073
|
* Encodes the given message object to its serialized form in protocol buffers
|
1066
1074
|
* wire format.
|
1067
|
-
*
|
1068
|
-
*
|
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]
|
1069
1081
|
*/
|
1070
1082
|
static VALUE Message_encode(int argc, VALUE* argv, VALUE klass) {
|
1071
1083
|
Message* msg = ruby_to_Message(argv[0]);
|
@@ -1112,14 +1124,17 @@ static VALUE Message_encode(int argc, VALUE* argv, VALUE klass) {
|
|
1112
1124
|
}
|
1113
1125
|
|
1114
1126
|
/*
|
1115
|
-
*
|
1116
|
-
* MessageClass.encode_json(msg, options = {}) => json_string
|
1127
|
+
* ruby-doc: AbstractMessage.encode_json
|
1117
1128
|
*
|
1118
1129
|
* Encodes the given message object into its serialized JSON representation.
|
1119
|
-
*
|
1120
|
-
*
|
1121
|
-
*
|
1122
|
-
*
|
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]
|
1123
1138
|
*/
|
1124
1139
|
static VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
|
1125
1140
|
Message* msg = ruby_to_Message(argv[0]);
|
@@ -1128,9 +1143,6 @@ static VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
|
|
1128
1143
|
size_t size;
|
1129
1144
|
upb_Status status;
|
1130
1145
|
|
1131
|
-
// TODO: use this message's pool instead.
|
1132
|
-
const upb_DefPool* symtab = DescriptorPool_GetSymtab(generated_pool);
|
1133
|
-
|
1134
1146
|
if (argc < 1 || argc > 2) {
|
1135
1147
|
rb_raise(rb_eArgError, "Expected 1 or 2 arguments.");
|
1136
1148
|
}
|
@@ -1165,8 +1177,9 @@ static VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
|
|
1165
1177
|
}
|
1166
1178
|
|
1167
1179
|
upb_Status_Clear(&status);
|
1168
|
-
|
1169
|
-
|
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);
|
1170
1183
|
|
1171
1184
|
if (!upb_Status_IsOk(&status)) {
|
1172
1185
|
rb_raise(cParseError, "Error occurred during encoding: %s",
|
@@ -1176,7 +1189,7 @@ static VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
|
|
1176
1189
|
VALUE ret;
|
1177
1190
|
if (size >= sizeof(buf)) {
|
1178
1191
|
char* buf2 = malloc(size + 1);
|
1179
|
-
upb_JsonEncode(msg->msg, msg->msgdef,
|
1192
|
+
upb_JsonEncode(msg->msg, msg->msgdef, pool, options, buf2, size + 1,
|
1180
1193
|
&status);
|
1181
1194
|
ret = rb_str_new(buf2, size);
|
1182
1195
|
free(buf2);
|
@@ -1189,11 +1202,12 @@ static VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
|
|
1189
1202
|
}
|
1190
1203
|
|
1191
1204
|
/*
|
1192
|
-
*
|
1193
|
-
* Message.descriptor => descriptor
|
1205
|
+
* ruby-doc: AbstractMessage.descriptor
|
1194
1206
|
*
|
1195
1207
|
* Class method that returns the Descriptor instance corresponding to this
|
1196
1208
|
* message class's type.
|
1209
|
+
*
|
1210
|
+
* @return [Descriptor]
|
1197
1211
|
*/
|
1198
1212
|
static VALUE Message_descriptor(VALUE klass) {
|
1199
1213
|
return rb_ivar_get(klass, descriptor_instancevar_interned);
|
@@ -1216,12 +1230,26 @@ VALUE build_class_from_descriptor(VALUE descriptor) {
|
|
1216
1230
|
return klass;
|
1217
1231
|
}
|
1218
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
|
+
|
1219
1245
|
/*
|
1220
|
-
*
|
1221
|
-
* Enum.lookup(number) => name
|
1246
|
+
* ruby-doc: Enum.lookup
|
1222
1247
|
*
|
1223
1248
|
* This module method, provided on each generated enum module, looks up an enum
|
1224
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]
|
1225
1253
|
*/
|
1226
1254
|
static VALUE enum_lookup(VALUE self, VALUE number) {
|
1227
1255
|
int32_t num = NUM2INT(number);
|
@@ -1236,11 +1264,13 @@ static VALUE enum_lookup(VALUE self, VALUE number) {
|
|
1236
1264
|
}
|
1237
1265
|
|
1238
1266
|
/*
|
1239
|
-
*
|
1240
|
-
* Enum.resolve(name) => number
|
1267
|
+
* ruby-doc: Enum.resolve
|
1241
1268
|
*
|
1242
1269
|
* This module method, provided on each generated enum module, looks up an enum
|
1243
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]
|
1244
1274
|
*/
|
1245
1275
|
static VALUE enum_resolve(VALUE self, VALUE sym) {
|
1246
1276
|
const char* name = rb_id2name(SYM2ID(sym));
|
@@ -1255,11 +1285,13 @@ static VALUE enum_resolve(VALUE self, VALUE sym) {
|
|
1255
1285
|
}
|
1256
1286
|
|
1257
1287
|
/*
|
1258
|
-
*
|
1259
|
-
* Enum.descriptor
|
1288
|
+
* ruby-doc: Enum.descriptor
|
1260
1289
|
*
|
1261
1290
|
* This module method, provided on each generated enum module, returns the
|
1262
|
-
* EnumDescriptor corresponding to this enum type.
|
1291
|
+
* {EnumDescriptor} corresponding to this enum type.
|
1292
|
+
*
|
1293
|
+
* @return [EnumDescriptor]
|
1294
|
+
*
|
1263
1295
|
*/
|
1264
1296
|
static VALUE enum_descriptor(VALUE self) {
|
1265
1297
|
return rb_ivar_get(self, descriptor_instancevar_interned);
|
@@ -1402,6 +1434,7 @@ static void Message_define_class(VALUE klass) {
|
|
1402
1434
|
rb_define_method(klass, "==", Message_eq, 1);
|
1403
1435
|
rb_define_method(klass, "eql?", Message_eq, 1);
|
1404
1436
|
rb_define_method(klass, "freeze", Message_freeze, 0);
|
1437
|
+
rb_define_method(klass, "frozen?", Message_frozen, 0);
|
1405
1438
|
rb_define_method(klass, "hash", Message_hash, 0);
|
1406
1439
|
rb_define_method(klass, "to_h", Message_to_h, 0);
|
1407
1440
|
rb_define_method(klass, "inspect", Message_inspect, 0);
|