Down-integrate internal changes to github. (#5555)

* Down-integrate internal changes to github.

* fix python conformance test

* fix csharp conformance test

* add back java map_lite_test.proto's optimize for option

* fix php conformance test
diff --git a/conformance/Makefile.am b/conformance/Makefile.am
index 8f30124..f45bfe3 100644
--- a/conformance/Makefile.am
+++ b/conformance/Makefile.am
@@ -107,6 +107,7 @@
   google/protobuf/wrappers_pb2.py                              \
   Conformance/ConformanceRequest.php                           \
   Conformance/ConformanceResponse.php                          \
+  Conformance/FailureSet.php                                   \
   Conformance/WireFormat.php                                   \
   GPBMetadata/Conformance.php                                  \
   GPBMetadata/Google/Protobuf/Any.php                          \
diff --git a/conformance/conformance.proto b/conformance/conformance.proto
index b0dc762..91e2ad3 100644
--- a/conformance/conformance.proto
+++ b/conformance/conformance.proto
@@ -61,7 +61,7 @@
 enum TestCategory {
   UNSPECIFIED_TEST = 0;
   BINARY_TEST = 1;  // Test binary wire format.
-  JSON_TEST = 2;  // Test json wire format.
+  JSON_TEST = 2;    // Test json wire format.
   // Similar to JSON_TEST. However, during parsing json, testee should ignore
   // unknown fields. This feature is optional. Each implementation can descide
   // whether to support it.  See
@@ -72,6 +72,10 @@
                   // Opensource testees just skip it.
 }
 
+message FailureSet {
+  repeated string failure = 1;
+}
+
 // Represents a single test case's input.  The testee should:
 //
 //   1. parse this proto (which should always succeed)
diff --git a/conformance/conformance_cpp.cc b/conformance/conformance_cpp.cc
index ce333ee..a451ab0 100644
--- a/conformance/conformance_cpp.cc
+++ b/conformance/conformance_cpp.cc
@@ -57,6 +57,35 @@
 
 static const char kTypeUrlPrefix[] = "type.googleapis.com";
 
+const char* kFailures[] = {
+#if !GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+    "Required.Proto2.ProtobufInput."
+    "PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE",
+    "Required.Proto2.ProtobufInput."
+    "PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE",
+    "Required.Proto2.ProtobufInput.PrematureEofInPackedField.BOOL",
+    "Required.Proto2.ProtobufInput.PrematureEofInPackedField.ENUM",
+    "Required.Proto2.ProtobufInput.PrematureEofInPackedField.INT32",
+    "Required.Proto2.ProtobufInput.PrematureEofInPackedField.INT64",
+    "Required.Proto2.ProtobufInput.PrematureEofInPackedField.SINT32",
+    "Required.Proto2.ProtobufInput.PrematureEofInPackedField.SINT64",
+    "Required.Proto2.ProtobufInput.PrematureEofInPackedField.UINT32",
+    "Required.Proto2.ProtobufInput.PrematureEofInPackedField.UINT64",
+    "Required.Proto3.ProtobufInput."
+    "PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE",
+    "Required.Proto3.ProtobufInput."
+    "PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE",
+    "Required.Proto3.ProtobufInput.PrematureEofInPackedField.BOOL",
+    "Required.Proto3.ProtobufInput.PrematureEofInPackedField.ENUM",
+    "Required.Proto3.ProtobufInput.PrematureEofInPackedField.INT32",
+    "Required.Proto3.ProtobufInput.PrematureEofInPackedField.INT64",
+    "Required.Proto3.ProtobufInput.PrematureEofInPackedField.SINT32",
+    "Required.Proto3.ProtobufInput.PrematureEofInPackedField.SINT64",
+    "Required.Proto3.ProtobufInput.PrematureEofInPackedField.UINT32",
+    "Required.Proto3.ProtobufInput.PrematureEofInPackedField.UINT64",
+#endif
+};
+
 static string GetTypeUrl(const Descriptor* message) {
   return string(kTypeUrlPrefix) + "/" + message->full_name();
 }
@@ -144,6 +173,12 @@
       break;
   }
 
+  conformance::FailureSet failures;
+  if (descriptor == failures.GetDescriptor()) {
+    for (const char* s : kFailures) failures.add_failure(s);
+    test_message = &failures;
+  }
+
   switch (request.requested_output_format()) {
     case conformance::UNSPECIFIED:
       GOOGLE_LOG(FATAL) << "Unspecified output format";
diff --git a/conformance/conformance_php.php b/conformance/conformance_php.php
index 80860c9..2eeaa63 100755
--- a/conformance/conformance_php.php
+++ b/conformance/conformance_php.php
@@ -3,6 +3,7 @@
 require_once("Conformance/WireFormat.php");
 require_once("Conformance/ConformanceResponse.php");
 require_once("Conformance/ConformanceRequest.php");
+require_once("Conformance/FailureSet.php");
 require_once("Conformance/JspbEncodingConfig.php");
 require_once("Conformance/TestCategory.php");
 require_once("Protobuf_test_messages/Proto3/ForeignMessage.php");
@@ -29,7 +30,10 @@
     $test_message = new \Protobuf_test_messages\Proto3\TestAllTypesProto3();
     $response = new \Conformance\ConformanceResponse();
     if ($request->getPayload() == "protobuf_payload") {
-      if ($request->getMessageType() == "protobuf_test_messages.proto3.TestAllTypesProto3") {
+      if ($request->getMessageType() == "conformance.FailureSet") {
+        $response->setProtobufPayload("");
+        return $response;
+      } elseif ($request->getMessageType() == "protobuf_test_messages.proto3.TestAllTypesProto3") {
         try {
           $test_message->mergeFromString($request->getProtobufPayload());
         } catch (Exception $e) {
diff --git a/conformance/conformance_python.py b/conformance/conformance_python.py
index 876642b..f1975e0 100755
--- a/conformance/conformance_python.py
+++ b/conformance/conformance_python.py
@@ -56,26 +56,75 @@
   pass
 
 def do_test(request):
+  response = conformance_pb2.ConformanceResponse()
+
+  if request.message_type == "conformance.FailureSet":
+    failure_set = conformance_pb2.FailureSet()
+    failures = []
+    # TODO(gerbens): Remove, this is a hack to detect if the old vs new
+    # parser is used by the cpp code. Relying on a bug in the old parser.
+    hack_proto = test_messages_proto2_pb2.TestAllTypesProto2()
+    if hack_proto.ParseFromString(b"\322\002\001"):
+      # the string above is one of the failing conformance test strings of the
+      # old parser. If we succeed the c++ implementation is using the old
+      # parser so we add the list of failing conformance tests.
+      failures = [
+          "Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE",
+          "Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE",
+          "Required.Proto3.ProtobufInput.PrematureEofInPackedField.BOOL",
+          "Required.Proto3.ProtobufInput.PrematureEofInPackedField.DOUBLE",
+          "Required.Proto3.ProtobufInput.PrematureEofInPackedField.ENUM",
+          "Required.Proto3.ProtobufInput.PrematureEofInPackedField.FIXED32",
+          "Required.Proto3.ProtobufInput.PrematureEofInPackedField.FIXED64",
+          "Required.Proto3.ProtobufInput.PrematureEofInPackedField.FLOAT",
+          "Required.Proto3.ProtobufInput.PrematureEofInPackedField.INT32",
+          "Required.Proto3.ProtobufInput.PrematureEofInPackedField.INT64",
+          "Required.Proto3.ProtobufInput.PrematureEofInPackedField.SFIXED32",
+          "Required.Proto3.ProtobufInput.PrematureEofInPackedField.SFIXED64",
+          "Required.Proto3.ProtobufInput.PrematureEofInPackedField.SINT32",
+          "Required.Proto3.ProtobufInput.PrematureEofInPackedField.SINT64",
+          "Required.Proto3.ProtobufInput.PrematureEofInPackedField.UINT32",
+          "Required.Proto3.ProtobufInput.PrematureEofInPackedField.UINT64",
+          "Required.Proto2.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE",
+          "Required.Proto2.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE",
+          "Required.Proto2.ProtobufInput.PrematureEofInPackedField.BOOL",
+          "Required.Proto2.ProtobufInput.PrematureEofInPackedField.DOUBLE",
+          "Required.Proto2.ProtobufInput.PrematureEofInPackedField.ENUM",
+          "Required.Proto2.ProtobufInput.PrematureEofInPackedField.FIXED32",
+          "Required.Proto2.ProtobufInput.PrematureEofInPackedField.FIXED64",
+          "Required.Proto2.ProtobufInput.PrematureEofInPackedField.FLOAT",
+          "Required.Proto2.ProtobufInput.PrematureEofInPackedField.INT32",
+          "Required.Proto2.ProtobufInput.PrematureEofInPackedField.INT64",
+          "Required.Proto2.ProtobufInput.PrematureEofInPackedField.SFIXED32",
+          "Required.Proto2.ProtobufInput.PrematureEofInPackedField.SFIXED64",
+          "Required.Proto2.ProtobufInput.PrematureEofInPackedField.SINT32",
+          "Required.Proto2.ProtobufInput.PrematureEofInPackedField.SINT64",
+          "Required.Proto2.ProtobufInput.PrematureEofInPackedField.UINT32",
+          "Required.Proto2.ProtobufInput.PrematureEofInPackedField.UINT64",
+      ]
+    for x in failures:
+      failure_set.failure.append(x)
+    response.protobuf_payload = failure_set.SerializeToString()
+    return response
+
   isProto3 = (request.message_type == "protobuf_test_messages.proto3.TestAllTypesProto3")
   isJson = (request.WhichOneof('payload') == 'json_payload')
   isProto2 = (request.message_type == "protobuf_test_messages.proto2.TestAllTypesProto2")
-  
+
   if (not isProto3) and (not isJson) and (not isProto2):
     raise ProtocolError("Protobuf request doesn't have specific payload type")
-      
+
   test_message = test_messages_proto2_pb2.TestAllTypesProto2() if isProto2 else \
     test_messages_proto3_pb2.TestAllTypesProto3()
 
-  response = conformance_pb2.ConformanceResponse()
-
   try:
     if request.WhichOneof('payload') == 'protobuf_payload':
       try:
         test_message.ParseFromString(request.protobuf_payload)
       except message.DecodeError as e:
         response.parse_error = str(e)
-        return response  
-      
+        return response
+
     elif request.WhichOneof('payload') == 'json_payload':
       try:
         ignore_unknown_fields = \
@@ -97,7 +146,7 @@
       response.protobuf_payload = test_message.SerializeToString()
 
     elif request.requested_output_format == conformance_pb2.JSON:
-      try: 
+      try:
         response.json_payload = json_format.MessageToJson(test_message)
       except Exception as e:
         response.serialize_error = str(e)
diff --git a/conformance/conformance_test.cc b/conformance/conformance_test.cc
index 68b813d..265a053 100644
--- a/conformance/conformance_test.cc
+++ b/conformance/conformance_test.cc
@@ -150,15 +150,6 @@
   return "";
 }
 
-void ConformanceTestSuite::SetFailureList(
-    const string& filename,
-    const std::vector<string>& failure_list) {
-  failure_list_filename_ = filename;
-  expected_to_fail_.clear();
-  std::copy(failure_list.begin(), failure_list.end(),
-            std::inserter(expected_to_fail_, expected_to_fail_.end()));
-}
-
 void ConformanceTestSuite::ReportSuccess(const string& test_name) {
   if (expected_to_fail_.erase(test_name) != 0) {
     StringAppendF(&output_,
@@ -359,8 +350,9 @@
   return "";
 }
 
-bool ConformanceTestSuite::RunSuite(
-    ConformanceTestRunner* runner, std::string* output) {
+bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
+                                    std::string* output, const string& filename,
+                                    conformance::FailureSet* failure_list) {
   runner_ = runner;
   successes_ = 0;
   expected_failures_ = 0;
@@ -371,6 +363,18 @@
 
   output_ = "\nCONFORMANCE TEST BEGIN ====================================\n\n";
 
+  ConformanceRequest req;
+  ConformanceResponse res;
+  req.set_message_type(failure_list->GetTypeName());
+  req.set_protobuf_payload("");
+  req.set_requested_output_format(conformance::WireFormat::PROTOBUF);
+  RunTest("FindFailures", req, &res);
+  GOOGLE_CHECK(failure_list->MergeFromString(res.protobuf_payload()));
+  failure_list_filename_ = filename;
+  expected_to_fail_.clear();
+  for (const string& failure : failure_list->failure()) {
+    expected_to_fail_.insert(failure);
+  }
   RunSuiteImpl();
 
   bool ok = true;
diff --git a/conformance/conformance_test.h b/conformance/conformance_test.h
index ab82bbe..e0bc1e0 100644
--- a/conformance/conformance_test.h
+++ b/conformance/conformance_test.h
@@ -144,15 +144,6 @@
 
   void SetVerbose(bool verbose) { verbose_ = verbose; }
 
-  // Sets the list of tests that are expected to fail when RunSuite() is called.
-  // RunSuite() will fail unless the set of failing tests is exactly the same
-  // as this list.
-  //
-  // The filename here is *only* used to create/format useful error messages for
-  // how to update the failure list.  We do NOT read this file at all.
-  void SetFailureList(const std::string& filename,
-                      const std::vector<std::string>& failure_list);
-
   // Whether to require the testee to pass RECOMMENDED tests. By default failing
   // a RECOMMENDED test case will not fail the entire suite but will only
   // generated a warning. If this flag is set to true, RECOMMENDED tests will
@@ -169,9 +160,12 @@
   // Test output will be stored in "output".
   //
   // Returns true if the set of failing tests was exactly the same as the
-  // failure list.  If SetFailureList() was not called, returns true if all
-  // tests passed.
-  bool RunSuite(ConformanceTestRunner* runner, std::string* output);
+  // failure list.
+  // The filename here is *only* used to create/format useful error messages for
+  // how to update the failure list.  We do NOT read this file at all.
+  bool RunSuite(ConformanceTestRunner* runner, std::string* output,
+                const std::string& filename,
+                conformance::FailureSet* failure_list);
 
  protected:
   // Test cases are classified into a few categories:
diff --git a/conformance/conformance_test_runner.cc b/conformance/conformance_test_runner.cc
index 8b44752..0279bb6 100644
--- a/conformance/conformance_test_runner.cc
+++ b/conformance/conformance_test_runner.cc
@@ -84,7 +84,7 @@
 namespace protobuf {
 
 void ParseFailureList(const char *filename,
-                      std::vector<string>* failure_list) {
+                      conformance::FailureSet *failure_list) {
   std::ifstream infile(filename);
 
   if (!infile.is_open()) {
@@ -101,7 +101,7 @@
     line = line.substr(0, line.find("#"));
 
     if (!line.empty()) {
-      failure_list->push_back(line);
+      failure_list->add_failure(line);
     }
   }
 }
@@ -178,7 +178,7 @@
     int argc, char *argv[], ConformanceTestSuite* suite) {
   char *program;
   string failure_list_filename;
-  std::vector<string> failure_list;
+  conformance::FailureSet failure_list;
 
   for (int arg = 1; arg < argc; ++arg) {
     if (strcmp(argv[arg], "--failure_list") == 0) {
@@ -201,11 +201,11 @@
     }
   }
 
-  suite->SetFailureList(failure_list_filename, failure_list);
   ForkPipeRunner runner(program);
 
   std::string output;
-  bool ok =  suite->RunSuite(&runner, &output);
+  bool ok =
+      suite->RunSuite(&runner, &output, failure_list_filename, &failure_list);
 
   fwrite(output.c_str(), 1, output.size(), stderr);
 
diff --git a/conformance/failure_list_cpp.txt b/conformance/failure_list_cpp.txt
index 752fbb5..0c01e1e 100644
--- a/conformance/failure_list_cpp.txt
+++ b/conformance/failure_list_cpp.txt
@@ -34,23 +34,3 @@
 Recommended.Proto3.JsonInput.TrailingCommaInAnObjectWithNewlines
 Recommended.Proto3.JsonInput.TrailingCommaInAnObjectWithSpace
 Recommended.Proto3.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace
-Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
-Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.BOOL
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.ENUM
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.INT32
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.INT64
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.SINT32
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.SINT64
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.UINT32
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.UINT64
-Required.Proto2.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
-Required.Proto2.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.BOOL
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.ENUM
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.INT32
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.INT64
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.SINT32
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.SINT64
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.UINT32
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.UINT64
diff --git a/conformance/failure_list_python_cpp.txt b/conformance/failure_list_python_cpp.txt
index a498ad1..59a969d 100644
--- a/conformance/failure_list_python_cpp.txt
+++ b/conformance/failure_list_python_cpp.txt
@@ -20,35 +20,3 @@
 Required.Proto3.JsonInput.FloatFieldTooSmall
 Required.Proto3.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool
 Required.Proto3.JsonInput.TimestampJsonInputLowercaseT
-Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
-Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.BOOL
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.DOUBLE
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.ENUM
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.FIXED32
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.FIXED64
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.FLOAT
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.INT32
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.INT64
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.SFIXED32
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.SFIXED64
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.SINT32
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.SINT64
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.UINT32
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.UINT64
-Required.Proto2.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
-Required.Proto2.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.BOOL
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.DOUBLE
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.ENUM
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.FIXED32
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.FIXED64
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.FLOAT
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.INT32
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.INT64
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.SFIXED32
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.SFIXED64
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.SINT32
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.SINT64
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.UINT32
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.UINT64