Browse Source

Encode empty ListValue (#5857)

* Encode empty ListValue

* Update mac ruby conformance failure list
Paul Yang 6 years ago
parent
commit
a18680890b

+ 18 - 0
conformance/binary_json_conformance_suite.cc

@@ -2125,6 +2125,24 @@ void BinaryAndJsonConformanceSuite::RunSuiteImpl() {
           }
           }
         }
         }
       )");
       )");
+  RunValidJsonTest(
+      "StructWithEmptyListValue", REQUIRED,
+      R"({
+        "optionalStruct": {
+          "listValue": []
+        }
+      })",
+      R"(
+        optional_struct: {
+          fields: {
+            key: "listValue"
+            value: {
+              list_value: {
+              }
+            }
+          }
+        }
+      )");
   // Value
   // Value
   RunValidJsonTest(
   RunValidJsonTest(
       "ValueAcceptInteger", REQUIRED,
       "ValueAcceptInteger", REQUIRED,

+ 1 - 0
conformance/failure_list_ruby.txt

@@ -26,6 +26,7 @@ Required.Proto3.JsonInput.DoubleFieldMinPositiveValue.ProtobufOutput
 Required.Proto3.JsonInput.DoubleFieldNan.JsonOutput
 Required.Proto3.JsonInput.DoubleFieldNan.JsonOutput
 Required.Proto3.JsonInput.DurationMinValue.JsonOutput
 Required.Proto3.JsonInput.DurationMinValue.JsonOutput
 Required.Proto3.JsonInput.DurationRepeatedValue.JsonOutput
 Required.Proto3.JsonInput.DurationRepeatedValue.JsonOutput
+Required.Proto3.JsonInput.EmptyFieldMask.JsonOutput
 Required.Proto3.JsonInput.FloatFieldInfinity.JsonOutput
 Required.Proto3.JsonInput.FloatFieldInfinity.JsonOutput
 Required.Proto3.JsonInput.FloatFieldNan.JsonOutput
 Required.Proto3.JsonInput.FloatFieldNan.JsonOutput
 Required.Proto3.JsonInput.FloatFieldNegativeInfinity.JsonOutput
 Required.Proto3.JsonInput.FloatFieldNegativeInfinity.JsonOutput

+ 2 - 22
conformance/failure_list_ruby_mac.txt

@@ -18,26 +18,6 @@ Recommended.Proto3.JsonInput.TimestampHas6FractionalDigits.Validator
 Recommended.Proto3.JsonInput.Uint64FieldBeString.Validator
 Recommended.Proto3.JsonInput.Uint64FieldBeString.Validator
 Required.DurationProtoInputTooLarge.JsonOutput
 Required.DurationProtoInputTooLarge.JsonOutput
 Required.DurationProtoInputTooSmall.JsonOutput
 Required.DurationProtoInputTooSmall.JsonOutput
-Required.Proto3.JsonInput.Any.JsonOutput
-Required.Proto3.JsonInput.Any.ProtobufOutput
-Required.Proto3.JsonInput.AnyNested.JsonOutput
-Required.Proto3.JsonInput.AnyNested.ProtobufOutput
-Required.Proto3.JsonInput.AnyUnorderedTypeTag.JsonOutput
-Required.Proto3.JsonInput.AnyUnorderedTypeTag.ProtobufOutput
-Required.Proto3.JsonInput.AnyWithDuration.JsonOutput
-Required.Proto3.JsonInput.AnyWithDuration.ProtobufOutput
-Required.Proto3.JsonInput.AnyWithFieldMask.JsonOutput
-Required.Proto3.JsonInput.AnyWithFieldMask.ProtobufOutput
-Required.Proto3.JsonInput.AnyWithInt32ValueWrapper.JsonOutput
-Required.Proto3.JsonInput.AnyWithInt32ValueWrapper.ProtobufOutput
-Required.Proto3.JsonInput.AnyWithStruct.JsonOutput
-Required.Proto3.JsonInput.AnyWithStruct.ProtobufOutput
-Required.Proto3.JsonInput.AnyWithTimestamp.JsonOutput
-Required.Proto3.JsonInput.AnyWithTimestamp.ProtobufOutput
-Required.Proto3.JsonInput.AnyWithValueForInteger.JsonOutput
-Required.Proto3.JsonInput.AnyWithValueForInteger.ProtobufOutput
-Required.Proto3.JsonInput.AnyWithValueForJsonObject.JsonOutput
-Required.Proto3.JsonInput.AnyWithValueForJsonObject.ProtobufOutput
 Required.Proto3.JsonInput.DoubleFieldMaxNegativeValue.JsonOutput
 Required.Proto3.JsonInput.DoubleFieldMaxNegativeValue.JsonOutput
 Required.Proto3.JsonInput.DoubleFieldMaxNegativeValue.ProtobufOutput
 Required.Proto3.JsonInput.DoubleFieldMaxNegativeValue.ProtobufOutput
 Required.Proto3.JsonInput.DoubleFieldMinPositiveValue.JsonOutput
 Required.Proto3.JsonInput.DoubleFieldMinPositiveValue.JsonOutput
@@ -45,8 +25,6 @@ Required.Proto3.JsonInput.DoubleFieldMinPositiveValue.ProtobufOutput
 Required.Proto3.JsonInput.DoubleFieldNan.JsonOutput
 Required.Proto3.JsonInput.DoubleFieldNan.JsonOutput
 Required.Proto3.JsonInput.DurationMinValue.JsonOutput
 Required.Proto3.JsonInput.DurationMinValue.JsonOutput
 Required.Proto3.JsonInput.DurationRepeatedValue.JsonOutput
 Required.Proto3.JsonInput.DurationRepeatedValue.JsonOutput
-Required.Proto3.JsonInput.FieldMask.JsonOutput
-Required.Proto3.JsonInput.FieldMask.ProtobufOutput
 Required.Proto3.JsonInput.FloatFieldInfinity.JsonOutput
 Required.Proto3.JsonInput.FloatFieldInfinity.JsonOutput
 Required.Proto3.JsonInput.FloatFieldNan.JsonOutput
 Required.Proto3.JsonInput.FloatFieldNan.JsonOutput
 Required.Proto3.JsonInput.FloatFieldNegativeInfinity.JsonOutput
 Required.Proto3.JsonInput.FloatFieldNegativeInfinity.JsonOutput
@@ -91,3 +69,5 @@ Required.Proto3.JsonInput.IgnoreUnknownJsonNumber.ProtobufOutput
 Required.Proto3.JsonInput.IgnoreUnknownJsonObject.ProtobufOutput
 Required.Proto3.JsonInput.IgnoreUnknownJsonObject.ProtobufOutput
 Required.Proto3.JsonInput.IgnoreUnknownJsonString.ProtobufOutput
 Required.Proto3.JsonInput.IgnoreUnknownJsonString.ProtobufOutput
 Required.Proto3.JsonInput.IgnoreUnknownJsonTrue.ProtobufOutput
 Required.Proto3.JsonInput.IgnoreUnknownJsonTrue.ProtobufOutput
+Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter
+Required.Proto3.JsonInput.EmptyFieldMask.JsonOutput

+ 36 - 1
ruby/ext/google/protobuf_c/encode_decode.c

@@ -1237,6 +1237,34 @@ static void putjsonany(VALUE msg_rb, const Descriptor* desc,
   upb_sink_endmsg(sink, &status);
   upb_sink_endmsg(sink, &status);
 }
 }
 
 
+static void putjsonlistvalue(
+    VALUE msg_rb, const Descriptor* desc,
+    upb_sink* sink, int depth, bool emit_defaults) {
+  upb_status status;
+  upb_sink subsink;
+  MessageHeader* msg = NULL;
+  const upb_fielddef* f = upb_msgdef_itof(desc->msgdef, 1);
+  uint32_t offset =
+      desc->layout->fields[upb_fielddef_index(f)].offset +
+      sizeof(MessageHeader);
+  VALUE ary;
+
+  TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
+
+  upb_sink_startmsg(sink);
+
+  ary = DEREF(msg, offset, VALUE);
+
+  if (ary == Qnil || RepeatedField_size(ary) == 0) {
+    upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);
+    upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ));
+  } else {
+    putary(ary, f, sink, depth, emit_defaults, true);
+  }
+
+  upb_sink_endmsg(sink, &status);
+}
+
 static void putmsg(VALUE msg_rb, const Descriptor* desc,
 static void putmsg(VALUE msg_rb, const Descriptor* desc,
                    upb_sink *sink, int depth, bool emit_defaults,
                    upb_sink *sink, int depth, bool emit_defaults,
                    bool is_json, bool open_msg) {
                    bool is_json, bool open_msg) {
@@ -1244,11 +1272,18 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
   upb_msg_field_iter i;
   upb_msg_field_iter i;
   upb_status status;
   upb_status status;
 
 
-  if (is_json && upb_msgdef_wellknowntype(desc->msgdef) == UPB_WELLKNOWN_ANY) {
+  if (is_json &&
+      upb_msgdef_wellknowntype(desc->msgdef) == UPB_WELLKNOWN_ANY) {
     putjsonany(msg_rb, desc, sink, depth, emit_defaults);
     putjsonany(msg_rb, desc, sink, depth, emit_defaults);
     return;
     return;
   }
   }
 
 
+  if (is_json &&
+      upb_msgdef_wellknowntype(desc->msgdef) == UPB_WELLKNOWN_LISTVALUE) {
+    putjsonlistvalue(msg_rb, desc, sink, depth, emit_defaults);
+    return;
+  }
+
   if (open_msg) {
   if (open_msg) {
     upb_sink_startmsg(sink);
     upb_sink_startmsg(sink);
   }
   }

+ 0 - 1
ruby/travis-test.sh

@@ -15,7 +15,6 @@ test_version() {
     # TODO(teboring): timestamp parsing is incorrect only on mac due to mktime.
     # TODO(teboring): timestamp parsing is incorrect only on mac due to mktime.
     RUBY_CONFORMANCE=test_ruby_mac
     RUBY_CONFORMANCE=test_ruby_mac
   fi
   fi
-  return 0
 
 
   if [ "$version" == "jruby-1.7" ] ; then
   if [ "$version" == "jruby-1.7" ] ; then
     # No conformance tests yet -- JRuby is too broken to run them.
     # No conformance tests yet -- JRuby is too broken to run them.