google-protobuf 3.6.1 → 3.9.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.

Potentially problematic release.


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

@@ -100,24 +100,34 @@ void stringsink_uninit(stringsink *sink) {
100
100
 
101
101
  #define DEREF(msg, ofs, type) *(type*)(((uint8_t *)msg) + ofs)
102
102
 
103
- // Creates a handlerdata that simply contains the offset for this field.
104
- static const void* newhandlerdata(upb_handlers* h, uint32_t ofs) {
105
- size_t* hd_ofs = ALLOC(size_t);
106
- *hd_ofs = ofs;
107
- upb_handlers_addcleanup(h, hd_ofs, xfree);
108
- return hd_ofs;
103
+ typedef struct {
104
+ size_t ofs;
105
+ int32_t hasbit;
106
+ } field_handlerdata_t;
107
+
108
+ // Creates a handlerdata that contains the offset and the hasbit for the field
109
+ static const void* newhandlerdata(upb_handlers* h, uint32_t ofs, int32_t hasbit) {
110
+ field_handlerdata_t *hd = ALLOC(field_handlerdata_t);
111
+ hd->ofs = ofs;
112
+ hd->hasbit = hasbit;
113
+ upb_handlers_addcleanup(h, hd, xfree);
114
+ return hd;
109
115
  }
110
116
 
111
117
  typedef struct {
112
118
  size_t ofs;
119
+ int32_t hasbit;
113
120
  const upb_msgdef *md;
114
121
  } submsg_handlerdata_t;
115
122
 
116
123
  // Creates a handlerdata that contains offset and submessage type information.
117
- static const void *newsubmsghandlerdata(upb_handlers* h, uint32_t ofs,
124
+ static const void *newsubmsghandlerdata(upb_handlers* h,
125
+ uint32_t ofs,
126
+ int32_t hasbit,
118
127
  const upb_fielddef* f) {
119
128
  submsg_handlerdata_t *hd = ALLOC(submsg_handlerdata_t);
120
129
  hd->ofs = ofs;
130
+ hd->hasbit = hasbit;
121
131
  hd->md = upb_fielddef_msgsubdef(f);
122
132
  upb_handlers_addcleanup(h, hd, xfree);
123
133
  return hd;
@@ -189,6 +199,13 @@ static void* appendstr_handler(void *closure,
189
199
  return (void*)str;
190
200
  }
191
201
 
202
+ static void set_hasbit(void *closure, int32_t hasbit) {
203
+ if (hasbit > 0) {
204
+ uint8_t* storage = closure;
205
+ storage[hasbit/8] |= 1 << (hasbit % 8);
206
+ }
207
+ }
208
+
192
209
  // Appends a 'bytes' string to a repeated field.
193
210
  static void* appendbytes_handler(void *closure,
194
211
  const void *hd,
@@ -205,10 +222,12 @@ static void* str_handler(void *closure,
205
222
  const void *hd,
206
223
  size_t size_hint) {
207
224
  MessageHeader* msg = closure;
208
- const size_t *ofs = hd;
225
+ const field_handlerdata_t *fieldhandler = hd;
226
+
209
227
  VALUE str = rb_str_new2("");
210
228
  rb_enc_associate(str, kRubyStringUtf8Encoding);
211
- DEREF(msg, *ofs, VALUE) = str;
229
+ DEREF(msg, fieldhandler->ofs, VALUE) = str;
230
+ set_hasbit(closure, fieldhandler->hasbit);
212
231
  return (void*)str;
213
232
  }
214
233
 
@@ -217,10 +236,12 @@ static void* bytes_handler(void *closure,
217
236
  const void *hd,
218
237
  size_t size_hint) {
219
238
  MessageHeader* msg = closure;
220
- const size_t *ofs = hd;
239
+ const field_handlerdata_t *fieldhandler = hd;
240
+
221
241
  VALUE str = rb_str_new2("");
222
242
  rb_enc_associate(str, kRubyString8bitEncoding);
223
- DEREF(msg, *ofs, VALUE) = str;
243
+ DEREF(msg, fieldhandler->ofs, VALUE) = str;
244
+ set_hasbit(closure, fieldhandler->hasbit);
224
245
  return (void*)str;
225
246
  }
226
247
 
@@ -233,18 +254,13 @@ static size_t stringdata_handler(void* closure, const void* hd,
233
254
  }
234
255
 
235
256
  static bool stringdata_end_handler(void* closure, const void* hd) {
236
- MessageHeader* msg = closure;
237
- const size_t *ofs = hd;
238
- VALUE rb_str = DEREF(msg, *ofs, VALUE);
257
+ VALUE rb_str = closure;
239
258
  rb_obj_freeze(rb_str);
240
259
  return true;
241
260
  }
242
261
 
243
262
  static bool appendstring_end_handler(void* closure, const void* hd) {
244
- VALUE ary = (VALUE)closure;
245
- int size = RepeatedField_size(ary);
246
- VALUE* last = RepeatedField_index_native(ary, size - 1);
247
- VALUE rb_str = *last;
263
+ VALUE rb_str = closure;
248
264
  rb_obj_freeze(rb_str);
249
265
  return true;
250
266
  }
@@ -280,8 +296,11 @@ static void *submsg_handler(void *closure, const void *hd) {
280
296
  rb_class_new_instance(0, NULL, subklass);
281
297
  }
282
298
 
299
+ set_hasbit(closure, submsgdata->hasbit);
300
+
283
301
  submsg_rb = DEREF(msg, submsgdata->ofs, VALUE);
284
302
  TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg);
303
+
285
304
  return submsg;
286
305
  }
287
306
 
@@ -370,6 +389,9 @@ static bool endmap_handler(void *closure, const void *hd, upb_status* s) {
370
389
  if (mapdata->value_field_type == UPB_TYPE_MESSAGE ||
371
390
  mapdata->value_field_type == UPB_TYPE_ENUM) {
372
391
  value_field_typeclass = get_def_obj(mapdata->value_field_subdef);
392
+ if (mapdata->value_field_type == UPB_TYPE_ENUM) {
393
+ value_field_typeclass = EnumDescriptor_enummodule(value_field_typeclass);
394
+ }
373
395
  }
374
396
 
375
397
  value = native_slot_get(
@@ -457,9 +479,8 @@ static void *oneofbytes_handler(void *closure,
457
479
  }
458
480
 
459
481
  static bool oneofstring_end_handler(void* closure, const void* hd) {
460
- MessageHeader* msg = closure;
461
- const oneof_handlerdata_t *oneofdata = hd;
462
- rb_obj_freeze(DEREF(msg, oneofdata->ofs, VALUE));
482
+ VALUE rb_str = rb_str_new2("");
483
+ rb_obj_freeze(rb_str);
463
484
  return true;
464
485
  }
465
486
 
@@ -500,7 +521,7 @@ static void add_handlers_for_repeated_field(upb_handlers *h,
500
521
  const upb_fielddef *f,
501
522
  size_t offset) {
502
523
  upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
503
- upb_handlerattr_sethandlerdata(&attr, newhandlerdata(h, offset));
524
+ upb_handlerattr_sethandlerdata(&attr, newhandlerdata(h, offset, -1));
504
525
  upb_handlers_setstartseq(h, f, startseq_handler, &attr);
505
526
  upb_handlerattr_uninit(&attr);
506
527
 
@@ -534,7 +555,7 @@ static void add_handlers_for_repeated_field(upb_handlers *h,
534
555
  }
535
556
  case UPB_TYPE_MESSAGE: {
536
557
  upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
537
- upb_handlerattr_sethandlerdata(&attr, newsubmsghandlerdata(h, 0, f));
558
+ upb_handlerattr_sethandlerdata(&attr, newsubmsghandlerdata(h, 0, -1, f));
538
559
  upb_handlers_setstartsubmsg(h, f, appendsubmsg_handler, &attr);
539
560
  upb_handlerattr_uninit(&attr);
540
561
  break;
@@ -545,7 +566,15 @@ static void add_handlers_for_repeated_field(upb_handlers *h,
545
566
  // Set up handlers for a singular field.
546
567
  static void add_handlers_for_singular_field(upb_handlers *h,
547
568
  const upb_fielddef *f,
548
- size_t offset) {
569
+ size_t offset,
570
+ size_t hasbit_off) {
571
+ // The offset we pass to UPB points to the start of the Message,
572
+ // rather than the start of where our data is stored.
573
+ int32_t hasbit = -1;
574
+ if (hasbit_off != MESSAGE_FIELD_NO_HASBIT) {
575
+ hasbit = hasbit_off + sizeof(MessageHeader) * 8;
576
+ }
577
+
549
578
  switch (upb_fielddef_type(f)) {
550
579
  case UPB_TYPE_BOOL:
551
580
  case UPB_TYPE_INT32:
@@ -555,13 +584,13 @@ static void add_handlers_for_singular_field(upb_handlers *h,
555
584
  case UPB_TYPE_INT64:
556
585
  case UPB_TYPE_UINT64:
557
586
  case UPB_TYPE_DOUBLE:
558
- upb_msg_setscalarhandler(h, f, offset, -1);
587
+ upb_msg_setscalarhandler(h, f, offset, hasbit);
559
588
  break;
560
589
  case UPB_TYPE_STRING:
561
590
  case UPB_TYPE_BYTES: {
562
591
  bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES;
563
592
  upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
564
- upb_handlerattr_sethandlerdata(&attr, newhandlerdata(h, offset));
593
+ upb_handlerattr_sethandlerdata(&attr, newhandlerdata(h, offset, hasbit));
565
594
  upb_handlers_setstartstr(h, f,
566
595
  is_bytes ? bytes_handler : str_handler,
567
596
  &attr);
@@ -572,7 +601,9 @@ static void add_handlers_for_singular_field(upb_handlers *h,
572
601
  }
573
602
  case UPB_TYPE_MESSAGE: {
574
603
  upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
575
- upb_handlerattr_sethandlerdata(&attr, newsubmsghandlerdata(h, offset, f));
604
+ upb_handlerattr_sethandlerdata(&attr,
605
+ newsubmsghandlerdata(h, offset,
606
+ hasbit, f));
576
607
  upb_handlers_setstartsubmsg(h, f, submsg_handler, &attr);
577
608
  upb_handlerattr_uninit(&attr);
578
609
  break;
@@ -610,10 +641,12 @@ static void add_handlers_for_mapentry(const upb_msgdef* msgdef,
610
641
 
611
642
  add_handlers_for_singular_field(
612
643
  h, key_field,
613
- offsetof(map_parse_frame_t, key_storage));
644
+ offsetof(map_parse_frame_t, key_storage),
645
+ MESSAGE_FIELD_NO_HASBIT);
614
646
  add_handlers_for_singular_field(
615
647
  h, value_field,
616
- offsetof(map_parse_frame_t, value_storage));
648
+ offsetof(map_parse_frame_t, value_storage),
649
+ MESSAGE_FIELD_NO_HASBIT);
617
650
  }
618
651
 
619
652
  // Set up handlers for a oneof field.
@@ -718,7 +751,8 @@ static void add_handlers_for_message(const void *closure, upb_handlers *h) {
718
751
  } else if (upb_fielddef_isseq(f)) {
719
752
  add_handlers_for_repeated_field(h, f, offset);
720
753
  } else {
721
- add_handlers_for_singular_field(h, f, offset);
754
+ add_handlers_for_singular_field(
755
+ h, f, offset, desc->layout->fields[upb_fielddef_index(f)].hasbit);
722
756
  }
723
757
  }
724
758
  }
@@ -854,19 +888,38 @@ VALUE Message_decode(VALUE klass, VALUE data) {
854
888
 
855
889
  /*
856
890
  * call-seq:
857
- * MessageClass.decode_json(data) => message
891
+ * MessageClass.decode_json(data, options = {}) => message
858
892
  *
859
893
  * Decodes the given data (as a string containing bytes in protocol buffers wire
860
894
  * format) under the interpretration given by this message class's definition
861
895
  * and returns a message object with the corresponding field values.
896
+ *
897
+ * @param options [Hash] options for the decoder
898
+ * ignore_unknown_fields: set true to ignore unknown fields (default is to raise an error)
862
899
  */
863
- VALUE Message_decode_json(VALUE klass, VALUE data) {
900
+ VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) {
864
901
  VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
865
902
  Descriptor* desc = ruby_to_Descriptor(descriptor);
866
903
  VALUE msgklass = Descriptor_msgclass(descriptor);
867
904
  VALUE msg_rb;
905
+ VALUE data = argv[0];
906
+ VALUE ignore_unknown_fields = Qfalse;
868
907
  MessageHeader* msg;
869
908
 
909
+ if (argc < 1 || argc > 2) {
910
+ rb_raise(rb_eArgError, "Expected 1 or 2 arguments.");
911
+ }
912
+
913
+ if (argc == 2) {
914
+ VALUE hash_args = argv[1];
915
+ if (TYPE(hash_args) != T_HASH) {
916
+ rb_raise(rb_eArgError, "Expected hash arguments.");
917
+ }
918
+
919
+ ignore_unknown_fields = rb_hash_lookup2(
920
+ hash_args, ID2SYM(rb_intern("ignore_unknown_fields")), Qfalse);
921
+ }
922
+
870
923
  if (TYPE(data) != T_STRING) {
871
924
  rb_raise(rb_eArgError, "Expected string for JSON data.");
872
925
  }
@@ -882,10 +935,12 @@ VALUE Message_decode_json(VALUE klass, VALUE data) {
882
935
  stackenv se;
883
936
  upb_sink sink;
884
937
  upb_json_parser* parser;
938
+ DescriptorPool* pool = ruby_to_DescriptorPool(generated_pool);
885
939
  stackenv_init(&se, "Error occurred during parsing: %s");
886
940
 
887
941
  upb_sink_reset(&sink, get_fill_handlers(desc), msg);
888
- parser = upb_json_parser_create(&se.env, method, &sink);
942
+ parser = upb_json_parser_create(&se.env, method, pool->symtab,
943
+ &sink, ignore_unknown_fields);
889
944
  upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data),
890
945
  upb_json_parser_input(parser));
891
946
 
@@ -901,13 +956,9 @@ VALUE Message_decode_json(VALUE klass, VALUE data) {
901
956
 
902
957
  /* msgvisitor *****************************************************************/
903
958
 
904
- // TODO: If/when we support proto2 semantics in addition to the current proto3
905
- // semantics, which means that we have true field presence, we will want to
906
- // modify msgvisitor so that it emits all present fields rather than all
907
- // non-default-value fields.
908
-
909
959
  static void putmsg(VALUE msg, const Descriptor* desc,
910
- upb_sink *sink, int depth, bool emit_defaults);
960
+ upb_sink *sink, int depth, bool emit_defaults,
961
+ bool is_json, bool open_msg);
911
962
 
912
963
  static upb_selector_t getsel(const upb_fielddef *f, upb_handlertype_t type) {
913
964
  upb_selector_t ret;
@@ -939,7 +990,7 @@ static void putstr(VALUE str, const upb_fielddef *f, upb_sink *sink) {
939
990
  }
940
991
 
941
992
  static void putsubmsg(VALUE submsg, const upb_fielddef *f, upb_sink *sink,
942
- int depth, bool emit_defaults) {
993
+ int depth, bool emit_defaults, bool is_json) {
943
994
  upb_sink subsink;
944
995
  VALUE descriptor;
945
996
  Descriptor* subdesc;
@@ -950,18 +1001,22 @@ static void putsubmsg(VALUE submsg, const upb_fielddef *f, upb_sink *sink,
950
1001
  subdesc = ruby_to_Descriptor(descriptor);
951
1002
 
952
1003
  upb_sink_startsubmsg(sink, getsel(f, UPB_HANDLER_STARTSUBMSG), &subsink);
953
- putmsg(submsg, subdesc, &subsink, depth + 1, emit_defaults);
1004
+ putmsg(submsg, subdesc, &subsink, depth + 1, emit_defaults, is_json, true);
954
1005
  upb_sink_endsubmsg(sink, getsel(f, UPB_HANDLER_ENDSUBMSG));
955
1006
  }
956
1007
 
957
1008
  static void putary(VALUE ary, const upb_fielddef *f, upb_sink *sink,
958
- int depth, bool emit_defaults) {
1009
+ int depth, bool emit_defaults, bool is_json) {
959
1010
  upb_sink subsink;
960
1011
  upb_fieldtype_t type = upb_fielddef_type(f);
961
1012
  upb_selector_t sel = 0;
962
1013
  int size;
963
1014
 
964
1015
  if (ary == Qnil) return;
1016
+ if (!emit_defaults && NUM2INT(RepeatedField_length(ary)) == 0) return;
1017
+
1018
+ size = NUM2INT(RepeatedField_length(ary));
1019
+ if (size == 0 && !emit_defaults) return;
965
1020
 
966
1021
  upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);
967
1022
 
@@ -969,7 +1024,6 @@ static void putary(VALUE ary, const upb_fielddef *f, upb_sink *sink,
969
1024
  sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
970
1025
  }
971
1026
 
972
- size = NUM2INT(RepeatedField_length(ary));
973
1027
  for (int i = 0; i < size; i++) {
974
1028
  void* memory = RepeatedField_index_native(ary, i);
975
1029
  switch (type) {
@@ -992,7 +1046,8 @@ static void putary(VALUE ary, const upb_fielddef *f, upb_sink *sink,
992
1046
  putstr(*((VALUE *)memory), f, &subsink);
993
1047
  break;
994
1048
  case UPB_TYPE_MESSAGE:
995
- putsubmsg(*((VALUE *)memory), f, &subsink, depth, emit_defaults);
1049
+ putsubmsg(*((VALUE *)memory), f, &subsink, depth,
1050
+ emit_defaults, is_json);
996
1051
  break;
997
1052
 
998
1053
  #undef T
@@ -1007,7 +1062,13 @@ static void put_ruby_value(VALUE value,
1007
1062
  VALUE type_class,
1008
1063
  int depth,
1009
1064
  upb_sink *sink,
1010
- bool emit_defaults) {
1065
+ bool emit_defaults,
1066
+ bool is_json) {
1067
+ if (depth > ENCODE_MAX_NESTING) {
1068
+ rb_raise(rb_eRuntimeError,
1069
+ "Maximum recursion depth exceeded during encoding.");
1070
+ }
1071
+
1011
1072
  upb_selector_t sel = 0;
1012
1073
  if (upb_fielddef_isprimitive(f)) {
1013
1074
  sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
@@ -1047,12 +1108,12 @@ static void put_ruby_value(VALUE value,
1047
1108
  putstr(value, f, sink);
1048
1109
  break;
1049
1110
  case UPB_TYPE_MESSAGE:
1050
- putsubmsg(value, f, sink, depth, emit_defaults);
1111
+ putsubmsg(value, f, sink, depth, emit_defaults, is_json);
1051
1112
  }
1052
1113
  }
1053
1114
 
1054
1115
  static void putmap(VALUE map, const upb_fielddef *f, upb_sink *sink,
1055
- int depth, bool emit_defaults) {
1116
+ int depth, bool emit_defaults, bool is_json) {
1056
1117
  Map* self;
1057
1118
  upb_sink subsink;
1058
1119
  const upb_fielddef* key_field;
@@ -1060,6 +1121,8 @@ static void putmap(VALUE map, const upb_fielddef *f, upb_sink *sink,
1060
1121
  Map_iter it;
1061
1122
 
1062
1123
  if (map == Qnil) return;
1124
+ if (!emit_defaults && Map_length(map) == 0) return;
1125
+
1063
1126
  self = ruby_to_Map(map);
1064
1127
 
1065
1128
  upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);
@@ -1078,9 +1141,10 @@ static void putmap(VALUE map, const upb_fielddef *f, upb_sink *sink,
1078
1141
  &entry_sink);
1079
1142
  upb_sink_startmsg(&entry_sink);
1080
1143
 
1081
- put_ruby_value(key, key_field, Qnil, depth + 1, &entry_sink, emit_defaults);
1144
+ put_ruby_value(key, key_field, Qnil, depth + 1, &entry_sink,
1145
+ emit_defaults, is_json);
1082
1146
  put_ruby_value(value, value_field, self->value_type_class, depth + 1,
1083
- &entry_sink, emit_defaults);
1147
+ &entry_sink, emit_defaults, is_json);
1084
1148
 
1085
1149
  upb_sink_endmsg(&entry_sink, &status);
1086
1150
  upb_sink_endsubmsg(&subsink, getsel(f, UPB_HANDLER_ENDSUBMSG));
@@ -1089,13 +1153,143 @@ static void putmap(VALUE map, const upb_fielddef *f, upb_sink *sink,
1089
1153
  upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ));
1090
1154
  }
1091
1155
 
1156
+ static const upb_handlers* msgdef_json_serialize_handlers(
1157
+ Descriptor* desc, bool preserve_proto_fieldnames);
1158
+
1159
+ static void putjsonany(VALUE msg_rb, const Descriptor* desc,
1160
+ upb_sink* sink, int depth, bool emit_defaults) {
1161
+ upb_status status;
1162
+ MessageHeader* msg = NULL;
1163
+ const upb_fielddef* type_field = upb_msgdef_itof(desc->msgdef, UPB_ANY_TYPE);
1164
+ const upb_fielddef* value_field = upb_msgdef_itof(desc->msgdef, UPB_ANY_VALUE);
1165
+
1166
+ size_t type_url_offset;
1167
+ VALUE type_url_str_rb;
1168
+ const upb_msgdef *payload_type = NULL;
1169
+
1170
+ TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
1171
+
1172
+ upb_sink_startmsg(sink);
1173
+
1174
+ /* Handle type url */
1175
+ type_url_offset = desc->layout->fields[upb_fielddef_index(type_field)].offset;
1176
+ type_url_str_rb = DEREF(Message_data(msg), type_url_offset, VALUE);
1177
+ if (RSTRING_LEN(type_url_str_rb) > 0) {
1178
+ putstr(type_url_str_rb, type_field, sink);
1179
+ }
1180
+
1181
+ {
1182
+ const char* type_url_str = RSTRING_PTR(type_url_str_rb);
1183
+ size_t type_url_len = RSTRING_LEN(type_url_str_rb);
1184
+ DescriptorPool* pool = ruby_to_DescriptorPool(generated_pool);
1185
+
1186
+ if (type_url_len <= 20 ||
1187
+ strncmp(type_url_str, "type.googleapis.com/", 20) != 0) {
1188
+ rb_raise(rb_eRuntimeError, "Invalid type url: %s", type_url_str);
1189
+ return;
1190
+ }
1191
+
1192
+ /* Resolve type url */
1193
+ type_url_str += 20;
1194
+ type_url_len -= 20;
1195
+
1196
+ payload_type = upb_symtab_lookupmsg2(
1197
+ pool->symtab, type_url_str, type_url_len);
1198
+ if (payload_type == NULL) {
1199
+ rb_raise(rb_eRuntimeError, "Unknown type: %s", type_url_str);
1200
+ return;
1201
+ }
1202
+ }
1203
+
1204
+ {
1205
+ uint32_t value_offset;
1206
+ VALUE value_str_rb;
1207
+ const char* value_str;
1208
+ size_t value_len;
1209
+
1210
+ value_offset = desc->layout->fields[upb_fielddef_index(value_field)].offset;
1211
+ value_str_rb = DEREF(Message_data(msg), value_offset, VALUE);
1212
+ value_str = RSTRING_PTR(value_str_rb);
1213
+ value_len = RSTRING_LEN(value_str_rb);
1214
+
1215
+ if (value_len > 0) {
1216
+ VALUE payload_desc_rb = get_def_obj(payload_type);
1217
+ Descriptor* payload_desc = ruby_to_Descriptor(payload_desc_rb);
1218
+ VALUE payload_class = Descriptor_msgclass(payload_desc_rb);
1219
+ upb_sink subsink;
1220
+ bool is_wellknown;
1221
+
1222
+ VALUE payload_msg_rb = Message_decode(payload_class, value_str_rb);
1223
+
1224
+ is_wellknown =
1225
+ upb_msgdef_wellknowntype(payload_desc->msgdef) !=
1226
+ UPB_WELLKNOWN_UNSPECIFIED;
1227
+ if (is_wellknown) {
1228
+ upb_sink_startstr(sink, getsel(value_field, UPB_HANDLER_STARTSTR), 0,
1229
+ &subsink);
1230
+ }
1231
+
1232
+ subsink.handlers =
1233
+ msgdef_json_serialize_handlers(payload_desc, true);
1234
+ subsink.closure = sink->closure;
1235
+ putmsg(payload_msg_rb, payload_desc, &subsink, depth, emit_defaults, true,
1236
+ is_wellknown);
1237
+ }
1238
+ }
1239
+
1240
+ upb_sink_endmsg(sink, &status);
1241
+ }
1242
+
1243
+ static void putjsonlistvalue(
1244
+ VALUE msg_rb, const Descriptor* desc,
1245
+ upb_sink* sink, int depth, bool emit_defaults) {
1246
+ upb_status status;
1247
+ upb_sink subsink;
1248
+ MessageHeader* msg = NULL;
1249
+ const upb_fielddef* f = upb_msgdef_itof(desc->msgdef, 1);
1250
+ uint32_t offset =
1251
+ desc->layout->fields[upb_fielddef_index(f)].offset +
1252
+ sizeof(MessageHeader);
1253
+ VALUE ary;
1254
+
1255
+ TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
1256
+
1257
+ upb_sink_startmsg(sink);
1258
+
1259
+ ary = DEREF(msg, offset, VALUE);
1260
+
1261
+ if (ary == Qnil || RepeatedField_size(ary) == 0) {
1262
+ upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);
1263
+ upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ));
1264
+ } else {
1265
+ putary(ary, f, sink, depth, emit_defaults, true);
1266
+ }
1267
+
1268
+ upb_sink_endmsg(sink, &status);
1269
+ }
1270
+
1092
1271
  static void putmsg(VALUE msg_rb, const Descriptor* desc,
1093
- upb_sink *sink, int depth, bool emit_defaults) {
1272
+ upb_sink *sink, int depth, bool emit_defaults,
1273
+ bool is_json, bool open_msg) {
1094
1274
  MessageHeader* msg;
1095
1275
  upb_msg_field_iter i;
1096
1276
  upb_status status;
1097
1277
 
1098
- upb_sink_startmsg(sink);
1278
+ if (is_json &&
1279
+ upb_msgdef_wellknowntype(desc->msgdef) == UPB_WELLKNOWN_ANY) {
1280
+ putjsonany(msg_rb, desc, sink, depth, emit_defaults);
1281
+ return;
1282
+ }
1283
+
1284
+ if (is_json &&
1285
+ upb_msgdef_wellknowntype(desc->msgdef) == UPB_WELLKNOWN_LISTVALUE) {
1286
+ putjsonlistvalue(msg_rb, desc, sink, depth, emit_defaults);
1287
+ return;
1288
+ }
1289
+
1290
+ if (open_msg) {
1291
+ upb_sink_startmsg(sink);
1292
+ }
1099
1293
 
1100
1294
  // Protect against cycles (possible because users may freely reassign message
1101
1295
  // and repeated fields) by imposing a maximum recursion depth.
@@ -1140,30 +1334,45 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
1140
1334
  if (is_map_field(f)) {
1141
1335
  VALUE map = DEREF(msg, offset, VALUE);
1142
1336
  if (map != Qnil || emit_defaults) {
1143
- putmap(map, f, sink, depth, emit_defaults);
1337
+ putmap(map, f, sink, depth, emit_defaults, is_json);
1144
1338
  }
1145
1339
  } else if (upb_fielddef_isseq(f)) {
1146
1340
  VALUE ary = DEREF(msg, offset, VALUE);
1147
1341
  if (ary != Qnil) {
1148
- putary(ary, f, sink, depth, emit_defaults);
1342
+ putary(ary, f, sink, depth, emit_defaults, is_json);
1149
1343
  }
1150
1344
  } else if (upb_fielddef_isstring(f)) {
1151
1345
  VALUE str = DEREF(msg, offset, VALUE);
1152
- if (is_matching_oneof || emit_defaults || RSTRING_LEN(str) > 0) {
1346
+ bool is_default = false;
1347
+
1348
+ if (upb_msgdef_syntax(desc->msgdef) == UPB_SYNTAX_PROTO2) {
1349
+ is_default = layout_has(desc->layout, Message_data(msg), f) == Qfalse;
1350
+ } else if (upb_msgdef_syntax(desc->msgdef) == UPB_SYNTAX_PROTO3) {
1351
+ is_default = RSTRING_LEN(str) == 0;
1352
+ }
1353
+
1354
+ if (is_matching_oneof || emit_defaults || !is_default) {
1153
1355
  putstr(str, f, sink);
1154
1356
  }
1155
1357
  } else if (upb_fielddef_issubmsg(f)) {
1156
- putsubmsg(DEREF(msg, offset, VALUE), f, sink, depth, emit_defaults);
1358
+ putsubmsg(DEREF(msg, offset, VALUE), f, sink, depth,
1359
+ emit_defaults, is_json);
1157
1360
  } else {
1158
1361
  upb_selector_t sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
1159
1362
 
1160
- #define T(upbtypeconst, upbtype, ctype, default_value) \
1161
- case upbtypeconst: { \
1162
- ctype value = DEREF(msg, offset, ctype); \
1163
- if (is_matching_oneof || emit_defaults || value != default_value) { \
1164
- upb_sink_put##upbtype(sink, sel, value); \
1165
- } \
1166
- } \
1363
+ #define T(upbtypeconst, upbtype, ctype, default_value) \
1364
+ case upbtypeconst: { \
1365
+ ctype value = DEREF(msg, offset, ctype); \
1366
+ bool is_default = false; \
1367
+ if (upb_fielddef_haspresence(f)) { \
1368
+ is_default = layout_has(desc->layout, Message_data(msg), f) == Qfalse; \
1369
+ } else if (upb_msgdef_syntax(desc->msgdef) == UPB_SYNTAX_PROTO3) { \
1370
+ is_default = default_value == value; \
1371
+ } \
1372
+ if (is_matching_oneof || emit_defaults || !is_default) { \
1373
+ upb_sink_put##upbtype(sink, sel, value); \
1374
+ } \
1375
+ } \
1167
1376
  break;
1168
1377
 
1169
1378
  switch (upb_fielddef_type(f)) {
@@ -1191,7 +1400,9 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
1191
1400
  upb_sink_putunknown(sink, unknown->ptr, unknown->len);
1192
1401
  }
1193
1402
 
1194
- upb_sink_endmsg(sink, &status);
1403
+ if (open_msg) {
1404
+ upb_sink_endmsg(sink, &status);
1405
+ }
1195
1406
  }
1196
1407
 
1197
1408
  static const upb_handlers* msgdef_pb_serialize_handlers(Descriptor* desc) {
@@ -1246,7 +1457,7 @@ VALUE Message_encode(VALUE klass, VALUE msg_rb) {
1246
1457
  stackenv_init(&se, "Error occurred during encoding: %s");
1247
1458
  encoder = upb_pb_encoder_create(&se.env, serialize_handlers, &sink.sink);
1248
1459
 
1249
- putmsg(msg_rb, desc, upb_pb_encoder_input(encoder), 0, false);
1460
+ putmsg(msg_rb, desc, upb_pb_encoder_input(encoder), 0, false, false, true);
1250
1461
 
1251
1462
  ret = rb_str_new(sink.ptr, sink.len);
1252
1463
 
@@ -1259,9 +1470,12 @@ VALUE Message_encode(VALUE klass, VALUE msg_rb) {
1259
1470
 
1260
1471
  /*
1261
1472
  * call-seq:
1262
- * MessageClass.encode_json(msg) => json_string
1473
+ * MessageClass.encode_json(msg, options = {}) => json_string
1263
1474
  *
1264
1475
  * Encodes the given message object into its serialized JSON representation.
1476
+ * @param options [Hash] options for the decoder
1477
+ * preserve_proto_fieldnames: set true to use original fieldnames (default is to camelCase)
1478
+ * emit_defaults: set true to emit 0/false values (default is to omit them)
1265
1479
  */
1266
1480
  VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
1267
1481
  VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
@@ -1301,7 +1515,8 @@ VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
1301
1515
  stackenv_init(&se, "Error occurred during encoding: %s");
1302
1516
  printer = upb_json_printer_create(&se.env, serialize_handlers, &sink.sink);
1303
1517
 
1304
- putmsg(msg_rb, desc, upb_json_printer_input(printer), 0, RTEST(emit_defaults));
1518
+ putmsg(msg_rb, desc, upb_json_printer_input(printer), 0,
1519
+ RTEST(emit_defaults), true, true);
1305
1520
 
1306
1521
  ret = rb_enc_str_new(sink.ptr, sink.len, rb_utf8_encoding());
1307
1522