google-protobuf 3.10.1-x86-linux → 3.11.0.rc.1-x86-linux

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of google-protobuf might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 60495afd0ec05a7704f0a345aea232f1a879ffebe91158e36e5c937e5fc5e772
4
- data.tar.gz: 62e1730b2c461c9326db2291343828d55df0fdd017e25d2b51425f3e8797e1e7
3
+ metadata.gz: b24a90084e11c7d2155e6cd767f960a463afd7bffa8bda8684f7de285cb70e4c
4
+ data.tar.gz: 9e4f0a89e0a8bfd90b8e07b7ac459d76dc2b22bfd849cf4be84f213d2deb04cc
5
5
  SHA512:
6
- metadata.gz: 81ae26f8b4d0cf208309f9016d841063c4cb7da16568f6508fdf0840cdef05aef949e43e33b9372add2b7b35a7b7636fa1d128a522171329829e6955e5be4199
7
- data.tar.gz: 8bf38f972fa3ea085dd4c8bf5d242c552e4e6f1c5bb749f94993f32996d2dec4ff605039b654f0d1a5b4dccb45bcb7ccebaba71f76b6a55336b0dbd80c0e8d05
6
+ metadata.gz: 8701056a2cb3b7fd8ba42d75f461e6fc27f1fc310055347a9fab4af28b36faa913b4acc4d40b52d233ddcf4d8a115a66e666db1ec8005a00502b0947a2cc3980
7
+ data.tar.gz: ffd57459df42483edb8f7e7eed8268b0f62b07b4d50d0045b0382016ead2e297d4e960edd4c4a1a35f2879d1883549341cf67af59f2c79a512e659d326632d7e
@@ -1232,7 +1232,7 @@ VALUE OneofDescriptor_name(VALUE _self) {
1232
1232
  *
1233
1233
  * Iterates through fields in this oneof, yielding to the block on each one.
1234
1234
  */
1235
- VALUE OneofDescriptor_each(VALUE _self, VALUE field) {
1235
+ VALUE OneofDescriptor_each(VALUE _self) {
1236
1236
  DEFINE_SELF(OneofDescriptor, self, _self);
1237
1237
  upb_oneof_iter it;
1238
1238
  for (upb_oneof_begin(&it, self->oneofdef);
@@ -278,6 +278,17 @@ static void *appendsubmsg_handler(void *closure, const void *hd) {
278
278
  return submsg;
279
279
  }
280
280
 
281
+ // Appends a wrapper to a repeated field (a regular Ruby array for now).
282
+ static void *appendwrapper_handler(void *closure, const void *hd) {
283
+ VALUE ary = (VALUE)closure;
284
+ int size = RepeatedField_size(ary);
285
+ (void)hd;
286
+
287
+ RepeatedField_push(ary, Qnil);
288
+
289
+ return RepeatedField_index_native(ary, size);
290
+ }
291
+
281
292
  // Sets a non-repeated submessage field in a message.
282
293
  static void *submsg_handler(void *closure, const void *hd) {
283
294
  MessageHeader* msg = closure;
@@ -298,6 +309,15 @@ static void *submsg_handler(void *closure, const void *hd) {
298
309
  return submsg;
299
310
  }
300
311
 
312
+ static void* startwrapper(void* closure, const void* hd) {
313
+ char* msg = closure;
314
+ const submsg_handlerdata_t* submsgdata = hd;
315
+
316
+ set_hasbit(closure, submsgdata->hasbit);
317
+
318
+ return msg + submsgdata->ofs;
319
+ }
320
+
301
321
  // Handler data for startmap/endmap handlers.
302
322
  typedef struct {
303
323
  size_t ofs;
@@ -486,14 +506,39 @@ static void *oneofsubmsg_handler(void *closure,
486
506
  // indicating a VALUE is present and expect a valid VALUE. See comment in
487
507
  // layout_set() for more detail: basically, the change to the value and the
488
508
  // case must be atomic w.r.t. the Ruby VM.
489
- DEREF(msg, oneofdata->case_ofs, uint32_t) =
490
- oneofdata->oneof_case_num;
509
+ DEREF(msg, oneofdata->case_ofs, uint32_t) = oneofdata->oneof_case_num;
491
510
 
492
511
  submsg_rb = DEREF(msg, oneofdata->ofs, VALUE);
493
512
  TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg);
494
513
  return submsg;
495
514
  }
496
515
 
516
+ static void* oneof_startwrapper(void* closure, const void* hd) {
517
+ char* msg = closure;
518
+ const oneof_handlerdata_t *oneofdata = hd;
519
+
520
+ DEREF(msg, oneofdata->case_ofs, uint32_t) = oneofdata->oneof_case_num;
521
+
522
+ return msg + oneofdata->ofs;
523
+ }
524
+
525
+ bool is_wrapper(const upb_msgdef* m) {
526
+ switch (upb_msgdef_wellknowntype(m)) {
527
+ case UPB_WELLKNOWN_DOUBLEVALUE:
528
+ case UPB_WELLKNOWN_FLOATVALUE:
529
+ case UPB_WELLKNOWN_INT64VALUE:
530
+ case UPB_WELLKNOWN_UINT64VALUE:
531
+ case UPB_WELLKNOWN_INT32VALUE:
532
+ case UPB_WELLKNOWN_UINT32VALUE:
533
+ case UPB_WELLKNOWN_STRINGVALUE:
534
+ case UPB_WELLKNOWN_BYTESVALUE:
535
+ case UPB_WELLKNOWN_BOOLVALUE:
536
+ return true;
537
+ default:
538
+ return false;
539
+ }
540
+ }
541
+
497
542
  // Set up handlers for a repeated field.
498
543
  static void add_handlers_for_repeated_field(upb_handlers *h,
499
544
  const Descriptor* desc,
@@ -535,12 +580,96 @@ static void add_handlers_for_repeated_field(upb_handlers *h,
535
580
  VALUE subklass = field_type_class(desc->layout, f);
536
581
  upb_handlerattr attr = UPB_HANDLERATTR_INIT;
537
582
  attr.handler_data = newsubmsghandlerdata(h, 0, -1, subklass);
538
- upb_handlers_setstartsubmsg(h, f, appendsubmsg_handler, &attr);
583
+ if (is_wrapper(upb_fielddef_msgsubdef(f))) {
584
+ upb_handlers_setstartsubmsg(h, f, appendwrapper_handler, &attr);
585
+ } else {
586
+ upb_handlers_setstartsubmsg(h, f, appendsubmsg_handler, &attr);
587
+ }
539
588
  break;
540
589
  }
541
590
  }
542
591
  }
543
592
 
593
+ static bool doublewrapper_handler(void* closure, const void* hd, double val) {
594
+ VALUE* rbval = closure;
595
+ *rbval = DBL2NUM(val);
596
+ return true;
597
+ }
598
+
599
+ static bool floatwrapper_handler(void* closure, const void* hd, float val) {
600
+ VALUE* rbval = closure;
601
+ *rbval = DBL2NUM(val);
602
+ return true;
603
+ }
604
+
605
+ static bool int64wrapper_handler(void* closure, const void* hd, int64_t val) {
606
+ VALUE* rbval = closure;
607
+ *rbval = LL2NUM(val);
608
+ return true;
609
+ }
610
+
611
+ static bool uint64wrapper_handler(void* closure, const void* hd, uint64_t val) {
612
+ VALUE* rbval = closure;
613
+ *rbval = ULL2NUM(val);
614
+ return true;
615
+ }
616
+
617
+ static bool int32wrapper_handler(void* closure, const void* hd, int32_t val) {
618
+ VALUE* rbval = closure;
619
+ *rbval = INT2NUM(val);
620
+ return true;
621
+ }
622
+
623
+ static bool uint32wrapper_handler(void* closure, const void* hd, uint32_t val) {
624
+ VALUE* rbval = closure;
625
+ *rbval = UINT2NUM(val);
626
+ return true;
627
+ }
628
+
629
+ static void* startstringwrapper_handler(void* closure, const void* hd,
630
+ size_t size_hint) {
631
+ VALUE* rbval = closure;
632
+ (void)size_hint;
633
+ *rbval = rb_str_new(NULL, 0);
634
+ rb_enc_associate(*rbval, kRubyStringUtf8Encoding);
635
+ return closure;
636
+ }
637
+
638
+ static size_t stringwrapper_handler(void* closure, const void* hd,
639
+ const char* ptr, size_t len,
640
+ const upb_bufhandle* handle) {
641
+ VALUE* rbval = closure;
642
+ *rbval = noleak_rb_str_cat(*rbval, ptr, len);
643
+ return len;
644
+ }
645
+
646
+ static void* startbyteswrapper_handler(void* closure, const void* hd,
647
+ size_t size_hint) {
648
+ VALUE* rbval = closure;
649
+ (void)size_hint;
650
+ *rbval = rb_str_new(NULL, 0);
651
+ rb_enc_associate(*rbval, kRubyString8bitEncoding);
652
+ return closure;
653
+ }
654
+
655
+ static size_t byteswrapper_handler(void* closure, const void* hd,
656
+ const char* ptr, size_t len,
657
+ const upb_bufhandle* handle) {
658
+ VALUE* rbval = closure;
659
+ *rbval = noleak_rb_str_cat(*rbval, ptr, len);
660
+ return len;
661
+ }
662
+
663
+ static bool boolwrapper_handler(void* closure, const void* hd, bool val) {
664
+ VALUE* rbval = closure;
665
+ if (val) {
666
+ *rbval = Qtrue;
667
+ } else {
668
+ *rbval = Qfalse;
669
+ }
670
+ return true;
671
+ }
672
+
544
673
  // Set up handlers for a singular field.
545
674
  static void add_handlers_for_singular_field(const Descriptor* desc,
546
675
  upb_handlers* h,
@@ -580,8 +709,11 @@ static void add_handlers_for_singular_field(const Descriptor* desc,
580
709
  upb_handlerattr attr = UPB_HANDLERATTR_INIT;
581
710
  attr.handler_data = newsubmsghandlerdata(
582
711
  h, offset, hasbit, field_type_class(desc->layout, f));
583
- upb_handlers_setstartsubmsg(h, f, submsg_handler, &attr);
584
- break;
712
+ if (is_wrapper(upb_fielddef_msgsubdef(f))) {
713
+ upb_handlers_setstartsubmsg(h, f, startwrapper, &attr);
714
+ } else {
715
+ upb_handlers_setstartsubmsg(h, f, submsg_handler, &attr);
716
+ }
585
717
  }
586
718
  }
587
719
  }
@@ -623,6 +755,45 @@ static void add_handlers_for_mapentry(const upb_msgdef* msgdef, upb_handlers* h,
623
755
  MESSAGE_FIELD_NO_HASBIT);
624
756
  }
625
757
 
758
+ static void add_handlers_for_wrapper(const upb_msgdef* msgdef,
759
+ upb_handlers* h) {
760
+ const upb_fielddef* f = upb_msgdef_itof(msgdef, 1);
761
+ switch (upb_msgdef_wellknowntype(msgdef)) {
762
+ case UPB_WELLKNOWN_DOUBLEVALUE:
763
+ upb_handlers_setdouble(h, f, doublewrapper_handler, NULL);
764
+ break;
765
+ case UPB_WELLKNOWN_FLOATVALUE:
766
+ upb_handlers_setfloat(h, f, floatwrapper_handler, NULL);
767
+ break;
768
+ case UPB_WELLKNOWN_INT64VALUE:
769
+ upb_handlers_setint64(h, f, int64wrapper_handler, NULL);
770
+ break;
771
+ case UPB_WELLKNOWN_UINT64VALUE:
772
+ upb_handlers_setuint64(h, f, uint64wrapper_handler, NULL);
773
+ break;
774
+ case UPB_WELLKNOWN_INT32VALUE:
775
+ upb_handlers_setint32(h, f, int32wrapper_handler, NULL);
776
+ break;
777
+ case UPB_WELLKNOWN_UINT32VALUE:
778
+ upb_handlers_setuint32(h, f, uint32wrapper_handler, NULL);
779
+ break;
780
+ case UPB_WELLKNOWN_STRINGVALUE:
781
+ upb_handlers_setstartstr(h, f, startstringwrapper_handler, NULL);
782
+ upb_handlers_setstring(h, f, stringwrapper_handler, NULL);
783
+ break;
784
+ case UPB_WELLKNOWN_BYTESVALUE:
785
+ upb_handlers_setstartstr(h, f, startbyteswrapper_handler, NULL);
786
+ upb_handlers_setstring(h, f, byteswrapper_handler, NULL);
787
+ break;
788
+ case UPB_WELLKNOWN_BOOLVALUE:
789
+ upb_handlers_setbool(h, f, boolwrapper_handler, NULL);
790
+ return;
791
+ default:
792
+ rb_raise(rb_eRuntimeError,
793
+ "Internal logic error with well-known types.");
794
+ }
795
+ }
796
+
626
797
  // Set up handlers for a oneof field.
627
798
  static void add_handlers_for_oneof_field(upb_handlers *h,
628
799
  const upb_fielddef *f,
@@ -662,7 +833,11 @@ static void add_handlers_for_oneof_field(upb_handlers *h,
662
833
  break;
663
834
  }
664
835
  case UPB_TYPE_MESSAGE: {
665
- upb_handlers_setstartsubmsg(h, f, oneofsubmsg_handler, &attr);
836
+ if (is_wrapper(upb_fielddef_msgsubdef(f))) {
837
+ upb_handlers_setstartsubmsg(h, f, oneof_startwrapper, &attr);
838
+ } else {
839
+ upb_handlers_setstartsubmsg(h, f, oneofsubmsg_handler, &attr);
840
+ }
666
841
  break;
667
842
  }
668
843
  }
@@ -683,6 +858,10 @@ static bool unknown_field_handler(void* closure, const void* hd,
683
858
  return true;
684
859
  }
685
860
 
861
+ size_t get_field_offset(MessageLayout* layout, const upb_fielddef* f) {
862
+ return layout->fields[upb_fielddef_index(f)].offset + sizeof(MessageHeader);
863
+ }
864
+
686
865
  void add_handlers_for_message(const void *closure, upb_handlers *h) {
687
866
  const VALUE descriptor_pool = (VALUE)closure;
688
867
  const upb_msgdef* msgdef = upb_handlers_msgdef(h);
@@ -706,6 +885,12 @@ void add_handlers_for_message(const void *closure, upb_handlers *h) {
706
885
  return;
707
886
  }
708
887
 
888
+ // If this is a wrapper type, use special handlers and bail.
889
+ if (is_wrapper(msgdef)) {
890
+ add_handlers_for_wrapper(msgdef, h);
891
+ return;
892
+ }
893
+
709
894
  upb_handlers_setunknown(h, unknown_field_handler, &attr);
710
895
 
711
896
  for (upb_msg_field_begin(&i, desc->msgdef);
@@ -713,8 +898,7 @@ void add_handlers_for_message(const void *closure, upb_handlers *h) {
713
898
  upb_msg_field_next(&i)) {
714
899
  const upb_fielddef *f = upb_msg_iter_field(&i);
715
900
  const upb_oneofdef *oneof = upb_fielddef_containingoneof(f);
716
- size_t offset = desc->layout->fields[upb_fielddef_index(f)].offset +
717
- sizeof(MessageHeader);
901
+ size_t offset = get_field_offset(desc->layout, f);
718
902
 
719
903
  if (oneof) {
720
904
  size_t oneof_case_offset =
@@ -826,17 +1010,28 @@ VALUE Message_decode(VALUE klass, VALUE data) {
826
1010
  {
827
1011
  const upb_pbdecodermethod* method = msgdef_decodermethod(desc);
828
1012
  const upb_handlers* h = upb_pbdecodermethod_desthandlers(method);
1013
+ const upb_msgdef* m = upb_handlers_msgdef(h);
1014
+ VALUE wrapper = Qnil;
1015
+ void* ptr = msg;
829
1016
  stackenv se;
830
1017
  upb_sink sink;
831
1018
  upb_pbdecoder* decoder;
832
1019
  stackenv_init(&se, "Error occurred during parsing: %" PRIsVALUE);
833
1020
 
834
- upb_sink_reset(&sink, h, msg);
1021
+ if (is_wrapper(m)) {
1022
+ ptr = &wrapper;
1023
+ }
1024
+
1025
+ upb_sink_reset(&sink, h, ptr);
835
1026
  decoder = upb_pbdecoder_create(se.arena, method, sink, &se.status);
836
1027
  upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data),
837
1028
  upb_pbdecoder_input(decoder));
838
1029
 
839
1030
  stackenv_uninit(&se);
1031
+
1032
+ if (is_wrapper(m)) {
1033
+ msg_rb = ruby_wrapper_type(msgklass, wrapper);
1034
+ }
840
1035
  }
841
1036
 
842
1037
  return msg_rb;
@@ -890,13 +1085,21 @@ VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) {
890
1085
 
891
1086
  {
892
1087
  const upb_json_parsermethod* method = msgdef_jsonparsermethod(desc);
1088
+ const upb_handlers* h = get_fill_handlers(desc);
1089
+ const upb_msgdef* m = upb_handlers_msgdef(h);
893
1090
  stackenv se;
894
1091
  upb_sink sink;
895
1092
  upb_json_parser* parser;
896
1093
  DescriptorPool* pool = ruby_to_DescriptorPool(generated_pool);
897
1094
  stackenv_init(&se, "Error occurred during parsing: %" PRIsVALUE);
898
1095
 
899
- upb_sink_reset(&sink, get_fill_handlers(desc), msg);
1096
+ if (is_wrapper(m)) {
1097
+ rb_raise(
1098
+ rb_eRuntimeError,
1099
+ "Parsing a wrapper type from JSON at the top level does not work.");
1100
+ }
1101
+
1102
+ upb_sink_reset(&sink, h, msg);
900
1103
  parser = upb_json_parser_create(se.arena, method, pool->symtab, sink,
901
1104
  &se.status, RTEST(ignore_unknown_fields));
902
1105
  upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data),
@@ -969,6 +1172,7 @@ static void putary(VALUE ary, const upb_fielddef* f, upb_sink sink, int depth,
969
1172
  upb_selector_t sel = 0;
970
1173
  int size;
971
1174
  int i;
1175
+ VALUE type_class = ruby_to_RepeatedField(ary)->field_type_class;
972
1176
 
973
1177
  if (ary == Qnil) return;
974
1178
  if (!emit_defaults && NUM2INT(RepeatedField_length(ary)) == 0) return;
@@ -1003,9 +1207,11 @@ static void putary(VALUE ary, const upb_fielddef* f, upb_sink sink, int depth,
1003
1207
  case UPB_TYPE_BYTES:
1004
1208
  putstr(*((VALUE *)memory), f, subsink);
1005
1209
  break;
1006
- case UPB_TYPE_MESSAGE:
1007
- putsubmsg(*((VALUE*)memory), f, subsink, depth, emit_defaults, is_json);
1210
+ case UPB_TYPE_MESSAGE: {
1211
+ VALUE val = native_slot_get(UPB_TYPE_MESSAGE, type_class, memory);
1212
+ putsubmsg(val, f, subsink, depth, emit_defaults, is_json);
1008
1213
  break;
1214
+ }
1009
1215
 
1010
1216
  #undef T
1011
1217
 
@@ -1306,8 +1512,10 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
1306
1512
  putstr(str, f, sink);
1307
1513
  }
1308
1514
  } else if (upb_fielddef_issubmsg(f)) {
1309
- putsubmsg(DEREF(msg, offset, VALUE), f, sink, depth,
1310
- emit_defaults, is_json);
1515
+ // OPT: could try to avoid the layout_get() (which will expand lazy
1516
+ // wrappers).
1517
+ VALUE val = layout_get(desc->layout, Message_data(msg), f);
1518
+ putsubmsg(val, f, sink, depth, emit_defaults, is_json);
1311
1519
  } else {
1312
1520
  upb_selector_t sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
1313
1521
 
@@ -1341,7 +1549,6 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
1341
1549
  }
1342
1550
 
1343
1551
  #undef T
1344
-
1345
1552
  }
1346
1553
  }
1347
1554
 
@@ -559,7 +559,8 @@ VALUE Map_deep_copy(VALUE _self) {
559
559
  void* mem = value_memory(&v);
560
560
  upb_value dup;
561
561
  void* dup_mem = value_memory(&dup);
562
- native_slot_deep_copy(self->value_type, dup_mem, mem);
562
+ native_slot_deep_copy(self->value_type, self->value_type_class, dup_mem,
563
+ mem);
563
564
 
564
565
  if (!upb_strtable_insert2(&new_self->table,
565
566
  upb_strtable_iter_key(&it),
@@ -631,7 +632,8 @@ VALUE Map_eq(VALUE _self, VALUE _other) {
631
632
  return Qfalse;
632
633
  }
633
634
 
634
- if (!native_slot_eq(self->value_type, mem, other_mem)) {
635
+ if (!native_slot_eq(self->value_type, self->value_type_class, mem,
636
+ other_mem)) {
635
637
  // Present, but value not equal.
636
638
  return Qfalse;
637
639
  }
@@ -62,13 +62,12 @@ VALUE Message_alloc(VALUE klass) {
62
62
  Descriptor* desc = ruby_to_Descriptor(descriptor);
63
63
  MessageHeader* msg;
64
64
  VALUE ret;
65
- size_t size;
66
65
 
67
66
  if (desc->layout == NULL) {
68
67
  create_layout(desc);
69
68
  }
70
69
 
71
- msg = ALLOC_N(uint8_t, sizeof(MessageHeader) + desc->layout->size);
70
+ msg = (void*)ALLOC_N(uint8_t, sizeof(MessageHeader) + desc->layout->size);
72
71
  msg->descriptor = desc;
73
72
  msg->unknown_fields = NULL;
74
73
  memcpy(Message_data(msg), desc->layout->empty_template, desc->layout->size);
@@ -109,30 +108,36 @@ enum {
109
108
  };
110
109
 
111
110
  // Check if the field is a well known wrapper type
112
- static bool is_wrapper_type_field(const MessageLayout* layout,
113
- const upb_fielddef* field) {
114
- const char* field_type_name = rb_class2name(field_type_class(layout, field));
115
-
116
- return strcmp(field_type_name, "Google::Protobuf::DoubleValue") == 0 ||
117
- strcmp(field_type_name, "Google::Protobuf::FloatValue") == 0 ||
118
- strcmp(field_type_name, "Google::Protobuf::Int32Value") == 0 ||
119
- strcmp(field_type_name, "Google::Protobuf::Int64Value") == 0 ||
120
- strcmp(field_type_name, "Google::Protobuf::UInt32Value") == 0 ||
121
- strcmp(field_type_name, "Google::Protobuf::UInt64Value") == 0 ||
122
- strcmp(field_type_name, "Google::Protobuf::BoolValue") == 0 ||
123
- strcmp(field_type_name, "Google::Protobuf::StringValue") == 0 ||
124
- strcmp(field_type_name, "Google::Protobuf::BytesValue") == 0;
111
+ bool is_wrapper_type_field(const upb_fielddef* field) {
112
+ const upb_msgdef *m;
113
+ if (upb_fielddef_type(field) != UPB_TYPE_MESSAGE) {
114
+ return false;
115
+ }
116
+ m = upb_fielddef_msgsubdef(field);
117
+ switch (upb_msgdef_wellknowntype(m)) {
118
+ case UPB_WELLKNOWN_DOUBLEVALUE:
119
+ case UPB_WELLKNOWN_FLOATVALUE:
120
+ case UPB_WELLKNOWN_INT64VALUE:
121
+ case UPB_WELLKNOWN_UINT64VALUE:
122
+ case UPB_WELLKNOWN_INT32VALUE:
123
+ case UPB_WELLKNOWN_UINT32VALUE:
124
+ case UPB_WELLKNOWN_STRINGVALUE:
125
+ case UPB_WELLKNOWN_BYTESVALUE:
126
+ case UPB_WELLKNOWN_BOOLVALUE:
127
+ return true;
128
+ default:
129
+ return false;
130
+ }
125
131
  }
126
132
 
127
133
  // Get a new Ruby wrapper type and set the initial value
128
- static VALUE ruby_wrapper_type(const MessageLayout* layout,
129
- const upb_fielddef* field, const VALUE value) {
130
- if (is_wrapper_type_field(layout, field) && value != Qnil) {
134
+ VALUE ruby_wrapper_type(VALUE type_class, VALUE value) {
135
+ if (value != Qnil) {
131
136
  VALUE hash = rb_hash_new();
132
137
  rb_hash_aset(hash, rb_str_new2("value"), value);
133
138
  {
134
139
  VALUE args[1] = {hash};
135
- return rb_class_new_instance(1, args, field_type_class(layout, field));
140
+ return rb_class_new_instance(1, args, type_class);
136
141
  }
137
142
  }
138
143
  return Qnil;
@@ -193,8 +198,7 @@ static int extract_method_call(VALUE method_name, MessageHeader* self,
193
198
  // Check if field exists and is a wrapper type
194
199
  if (upb_msgdef_lookupname(self->descriptor->msgdef, wrapper_field_name,
195
200
  name_len - 9, &test_f_wrapper, &test_o_wrapper) &&
196
- upb_fielddef_type(test_f_wrapper) == UPB_TYPE_MESSAGE &&
197
- is_wrapper_type_field(self->descriptor->layout, test_f_wrapper)) {
201
+ is_wrapper_type_field(test_f_wrapper)) {
198
202
  // It does exist!
199
203
  has_field = true;
200
204
  if (accessor_type == METHOD_SETTER) {
@@ -329,12 +333,17 @@ VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) {
329
333
  return layout_has(self->descriptor->layout, Message_data(self), f);
330
334
  } else if (accessor_type == METHOD_WRAPPER_GETTER) {
331
335
  VALUE value = layout_get(self->descriptor->layout, Message_data(self), f);
332
- if (value != Qnil) {
333
- value = rb_funcall(value, rb_intern("value"), 0);
336
+ switch (TYPE(value)) {
337
+ case T_DATA:
338
+ return rb_funcall(value, rb_intern("value"), 0);
339
+ case T_NIL:
340
+ return Qnil;
341
+ default:
342
+ return value;
334
343
  }
335
- return value;
336
344
  } else if (accessor_type == METHOD_WRAPPER_SETTER) {
337
- VALUE wrapper = ruby_wrapper_type(self->descriptor->layout, f, argv[1]);
345
+ VALUE wrapper = ruby_wrapper_type(
346
+ field_type_class(self->descriptor->layout, f), argv[1]);
338
347
  layout_set(self->descriptor->layout, Message_data(self), f, wrapper);
339
348
  return Qnil;
340
349
  } else if (accessor_type == METHOD_ENUM_GETTER) {
@@ -259,7 +259,7 @@ OneofDescriptor* ruby_to_OneofDescriptor(VALUE value);
259
259
  VALUE OneofDescriptor_initialize(VALUE _self, VALUE cookie,
260
260
  VALUE descriptor_pool, VALUE ptr);
261
261
  VALUE OneofDescriptor_name(VALUE _self);
262
- VALUE OneofDescriptor_each(VALUE _self, VALUE field);
262
+ VALUE OneofDescriptor_each(VALUE _self);
263
263
 
264
264
  void EnumDescriptor_mark(void* _self);
265
265
  void EnumDescriptor_free(void* _self);
@@ -363,8 +363,10 @@ VALUE native_slot_get(upb_fieldtype_t type,
363
363
  void native_slot_init(upb_fieldtype_t type, void* memory);
364
364
  void native_slot_mark(upb_fieldtype_t type, void* memory);
365
365
  void native_slot_dup(upb_fieldtype_t type, void* to, void* from);
366
- void native_slot_deep_copy(upb_fieldtype_t type, void* to, void* from);
367
- bool native_slot_eq(upb_fieldtype_t type, void* mem1, void* mem2);
366
+ void native_slot_deep_copy(upb_fieldtype_t type, VALUE type_class, void* to,
367
+ void* from);
368
+ bool native_slot_eq(upb_fieldtype_t type, VALUE type_class, void* mem1,
369
+ void* mem2);
368
370
 
369
371
  VALUE native_slot_encode_and_freeze_string(upb_fieldtype_t type, VALUE value);
370
372
  void native_slot_check_int_range_precision(const char* name, upb_fieldtype_t type, VALUE value);
@@ -556,6 +558,9 @@ VALUE layout_eq(MessageLayout* layout, void* msg1, void* msg2);
556
558
  VALUE layout_hash(MessageLayout* layout, void* storage);
557
559
  VALUE layout_inspect(MessageLayout* layout, void* storage);
558
560
 
561
+ bool is_wrapper_type_field(const upb_fielddef* field);
562
+ VALUE ruby_wrapper_type(VALUE type_class, VALUE value);
563
+
559
564
  // -----------------------------------------------------------------------------
560
565
  // Message class creation.
561
566
  // -----------------------------------------------------------------------------
@@ -378,7 +378,7 @@ VALUE RepeatedField_deep_copy(VALUE _self) {
378
378
  for (i = 0; i < self->size; i++, off += elem_size) {
379
379
  void* to_mem = (uint8_t *)new_rptfield_self->elements + off;
380
380
  void* from_mem = (uint8_t *)self->elements + off;
381
- native_slot_deep_copy(field_type, to_mem, from_mem);
381
+ native_slot_deep_copy(field_type, self->field_type_class, to_mem, from_mem);
382
382
  new_rptfield_self->size++;
383
383
  }
384
384
 
@@ -451,7 +451,8 @@ VALUE RepeatedField_eq(VALUE _self, VALUE _other) {
451
451
  for (i = 0; i < self->size; i++, off += elem_size) {
452
452
  void* self_mem = ((uint8_t *)self->elements) + off;
453
453
  void* other_mem = ((uint8_t *)other->elements) + off;
454
- if (!native_slot_eq(field_type, self_mem, other_mem)) {
454
+ if (!native_slot_eq(field_type, self->field_type_class, self_mem,
455
+ other_mem)) {
455
456
  return Qfalse;
456
457
  }
457
458
  }
@@ -294,8 +294,20 @@ VALUE native_slot_get(upb_fieldtype_t type,
294
294
  return DEREF(memory, int8_t) ? Qtrue : Qfalse;
295
295
  case UPB_TYPE_STRING:
296
296
  case UPB_TYPE_BYTES:
297
- case UPB_TYPE_MESSAGE:
298
297
  return DEREF(memory, VALUE);
298
+ case UPB_TYPE_MESSAGE: {
299
+ VALUE val = DEREF(memory, VALUE);
300
+
301
+ // Lazily expand wrapper type if necessary.
302
+ int type = TYPE(val);
303
+ if (type != T_DATA && type != T_NIL) {
304
+ // This must be a wrapper type.
305
+ val = ruby_wrapper_type(type_class, val);
306
+ DEREF(memory, VALUE) = val;
307
+ }
308
+
309
+ return val;
310
+ }
299
311
  case UPB_TYPE_ENUM: {
300
312
  int32_t val = DEREF(memory, int32_t);
301
313
  VALUE symbol = enum_lookup(type_class, INT2NUM(val));
@@ -372,7 +384,8 @@ void native_slot_dup(upb_fieldtype_t type, void* to, void* from) {
372
384
  memcpy(to, from, native_slot_size(type));
373
385
  }
374
386
 
375
- void native_slot_deep_copy(upb_fieldtype_t type, void* to, void* from) {
387
+ void native_slot_deep_copy(upb_fieldtype_t type, VALUE type_class, void* to,
388
+ void* from) {
376
389
  switch (type) {
377
390
  case UPB_TYPE_STRING:
378
391
  case UPB_TYPE_BYTES: {
@@ -382,7 +395,7 @@ void native_slot_deep_copy(upb_fieldtype_t type, void* to, void* from) {
382
395
  break;
383
396
  }
384
397
  case UPB_TYPE_MESSAGE: {
385
- VALUE from_val = DEREF(from, VALUE);
398
+ VALUE from_val = native_slot_get(type, type_class, from);
386
399
  DEREF(to, VALUE) = (from_val != Qnil) ?
387
400
  Message_deep_copy(from_val) : Qnil;
388
401
  break;
@@ -392,13 +405,14 @@ void native_slot_deep_copy(upb_fieldtype_t type, void* to, void* from) {
392
405
  }
393
406
  }
394
407
 
395
- bool native_slot_eq(upb_fieldtype_t type, void* mem1, void* mem2) {
408
+ bool native_slot_eq(upb_fieldtype_t type, VALUE type_class, void* mem1,
409
+ void* mem2) {
396
410
  switch (type) {
397
411
  case UPB_TYPE_STRING:
398
412
  case UPB_TYPE_BYTES:
399
413
  case UPB_TYPE_MESSAGE: {
400
- VALUE val1 = DEREF(mem1, VALUE);
401
- VALUE val2 = DEREF(mem2, VALUE);
414
+ VALUE val1 = native_slot_get(type, type_class, mem1);
415
+ VALUE val2 = native_slot_get(type, type_class, mem2);
402
416
  VALUE ret = rb_funcall(val1, rb_intern("=="), 1, val2);
403
417
  return ret == Qtrue;
404
418
  }
@@ -1025,7 +1039,9 @@ void layout_deep_copy(MessageLayout* layout, void* to, void* from) {
1025
1039
  if (slot_read_oneof_case(layout, from, oneof) ==
1026
1040
  upb_fielddef_number(field)) {
1027
1041
  *to_oneof_case = *from_oneof_case;
1028
- native_slot_deep_copy(upb_fielddef_type(field), to_memory, from_memory);
1042
+ native_slot_deep_copy(upb_fielddef_type(field),
1043
+ field_type_class(layout, field), to_memory,
1044
+ from_memory);
1029
1045
  }
1030
1046
  } else if (is_map_field(field)) {
1031
1047
  DEREF(to_memory, VALUE) =
@@ -1039,7 +1055,9 @@ void layout_deep_copy(MessageLayout* layout, void* to, void* from) {
1039
1055
  slot_set_hasbit(layout, to, field);
1040
1056
  }
1041
1057
 
1042
- native_slot_deep_copy(upb_fielddef_type(field), to_memory, from_memory);
1058
+ native_slot_deep_copy(upb_fielddef_type(field),
1059
+ field_type_class(layout, field), to_memory,
1060
+ from_memory);
1043
1061
  }
1044
1062
  }
1045
1063
  }
@@ -1061,7 +1079,8 @@ VALUE layout_eq(MessageLayout* layout, void* msg1, void* msg2) {
1061
1079
  if (*msg1_oneof_case != *msg2_oneof_case ||
1062
1080
  (slot_read_oneof_case(layout, msg1, oneof) ==
1063
1081
  upb_fielddef_number(field) &&
1064
- !native_slot_eq(upb_fielddef_type(field), msg1_memory,
1082
+ !native_slot_eq(upb_fielddef_type(field),
1083
+ field_type_class(layout, field), msg1_memory,
1065
1084
  msg2_memory))) {
1066
1085
  return Qfalse;
1067
1086
  }
@@ -1078,7 +1097,9 @@ VALUE layout_eq(MessageLayout* layout, void* msg1, void* msg2) {
1078
1097
  } else {
1079
1098
  if (slot_is_hasbit_set(layout, msg1, field) !=
1080
1099
  slot_is_hasbit_set(layout, msg2, field) ||
1081
- !native_slot_eq(upb_fielddef_type(field), msg1_memory, msg2_memory)) {
1100
+ !native_slot_eq(upb_fielddef_type(field),
1101
+ field_type_class(layout, field), msg1_memory,
1102
+ msg2_memory)) {
1082
1103
  return Qfalse;
1083
1104
  }
1084
1105
  }
Binary file
Binary file
Binary file
Binary file
data/tests/basic.rb CHANGED
@@ -234,6 +234,48 @@ module BasicTest
234
234
  m.map_string_int32['aaa'] = 3
235
235
  end
236
236
 
237
+ def test_map_wrappers
238
+ run_asserts = ->(m) {
239
+ assert_equal 2.0, m.map_double[0].value
240
+ assert_equal 4.0, m.map_float[0].value
241
+ assert_equal 3, m.map_int32[0].value
242
+ assert_equal 4, m.map_int64[0].value
243
+ assert_equal 5, m.map_uint32[0].value
244
+ assert_equal 6, m.map_uint64[0].value
245
+ assert_equal true, m.map_bool[0].value
246
+ assert_equal 'str', m.map_string[0].value
247
+ assert_equal 'fun', m.map_bytes[0].value
248
+ }
249
+
250
+ m = proto_module::Wrapper.new(
251
+ map_double: {0 => Google::Protobuf::DoubleValue.new(value: 2.0)},
252
+ map_float: {0 => Google::Protobuf::FloatValue.new(value: 4.0)},
253
+ map_int32: {0 => Google::Protobuf::Int32Value.new(value: 3)},
254
+ map_int64: {0 => Google::Protobuf::Int64Value.new(value: 4)},
255
+ map_uint32: {0 => Google::Protobuf::UInt32Value.new(value: 5)},
256
+ map_uint64: {0 => Google::Protobuf::UInt64Value.new(value: 6)},
257
+ map_bool: {0 => Google::Protobuf::BoolValue.new(value: true)},
258
+ map_string: {0 => Google::Protobuf::StringValue.new(value: 'str')},
259
+ map_bytes: {0 => Google::Protobuf::BytesValue.new(value: 'fun')},
260
+ )
261
+
262
+ run_asserts.call(m)
263
+ serialized = proto_module::Wrapper::encode(m)
264
+ m2 = proto_module::Wrapper::decode(serialized)
265
+ run_asserts.call(m2)
266
+
267
+ # Test the case where we are serializing directly from the parsed form
268
+ # (before anything lazy is materialized).
269
+ m3 = proto_module::Wrapper::decode(serialized)
270
+ serialized2 = proto_module::Wrapper::encode(m3)
271
+ m4 = proto_module::Wrapper::decode(serialized2)
272
+ run_asserts.call(m4)
273
+
274
+ # Test that the lazy form compares equal to the expanded form.
275
+ m5 = proto_module::Wrapper::decode(serialized2)
276
+ assert_equal m5, m
277
+ end
278
+
237
279
  def test_concurrent_decoding
238
280
  o = Outer.new
239
281
  o.items[0] = Inner.new
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google-protobuf
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.10.1
4
+ version: 3.11.0.rc.1
5
5
  platform: x86-linux
6
6
  authors:
7
7
  - Protobuf Authors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-29 00:00:00.000000000 Z
11
+ date: 2019-11-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler-dock
@@ -115,7 +115,7 @@ homepage: https://developers.google.com/protocol-buffers
115
115
  licenses:
116
116
  - BSD-3-Clause
117
117
  metadata:
118
- source_code_uri: https://github.com/protocolbuffers/protobuf/tree/v3.10.1/ruby
118
+ source_code_uri: https://github.com/protocolbuffers/protobuf/tree/v3.11.0-rc1/ruby
119
119
  post_install_message:
120
120
  rdoc_options: []
121
121
  require_paths:
@@ -127,9 +127,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
127
127
  version: '2.3'
128
128
  required_rubygems_version: !ruby/object:Gem::Requirement
129
129
  requirements:
130
- - - ">="
130
+ - - ">"
131
131
  - !ruby/object:Gem::Version
132
- version: '0'
132
+ version: 1.3.1
133
133
  requirements: []
134
134
  rubyforge_project:
135
135
  rubygems_version: 2.7.9