From 020a24dfdc2de06678f3f7f3547ba748fb5e5d42 Mon Sep 17 00:00:00 2001
From: Yilun Chong <yilunchong@google.com>
Date: Thu, 29 Jun 2017 11:33:22 -0700
Subject: [PATCH] change cpp and python to uniform message

---
 conformance/conformance_cpp.cc    | 50 ++++++++++-----------
 conformance/conformance_python.py | 47 ++++++++------------
 conformance/conformance_test.cc   | 72 ++++++++++++-------------------
 3 files changed, 67 insertions(+), 102 deletions(-)

diff --git a/conformance/conformance_cpp.cc b/conformance/conformance_cpp.cc
index 9c5907027..8d204dd2e 100644
--- a/conformance/conformance_cpp.cc
+++ b/conformance/conformance_cpp.cc
@@ -35,6 +35,7 @@
 #include "conformance.pb.h"
 #include <google/protobuf/test_messages_proto3.pb.h>
 #include <google/protobuf/test_messages_proto2.pb.h>
+#include <google/protobuf/message.h>
 #include <google/protobuf/util/json_util.h>
 #include <google/protobuf/util/type_resolver_util.h>
 
@@ -42,6 +43,7 @@ using conformance::ConformanceRequest;
 using conformance::ConformanceResponse;
 using google::protobuf::Descriptor;
 using google::protobuf::DescriptorPool;
+using google::protobuf::Message;
 using google::protobuf::internal::scoped_ptr;
 using google::protobuf::util::BinaryToJsonString;
 using google::protobuf::util::JsonToBinaryString;
@@ -89,27 +91,27 @@ void CheckedWrite(int fd, const void *buf, size_t len) {
 }
 
 void DoTest(const ConformanceRequest& request, ConformanceResponse* response) {
-  TestAllTypes test_message;
-  TestAllTypesProto2 test_message_proto2;
-  bool isProto3 = request.message_type() == "proto3";
+  Message *test_message;
+  bool isProto3 =
+      request.message_type() == "protobuf_test_messages.proto3.TestAllTypes";
   bool isJson = request.payload_case() == ConformanceRequest::kJsonPayload;
+  bool isProto2 =
+      request.message_type() == "protobuf_test_messages.proto2.TestAllTypesProto2";
+  if (isJson || isProto3) {
+    test_message = new TestAllTypes;
+  } else if (isProto2) {
+    test_message = new TestAllTypesProto2;
+  } else {
+    GOOGLE_LOG(FATAL) << "Protobuf request doesn't have specific payload type";
+  }
 
   switch (request.payload_case()) {
     case ConformanceRequest::kProtobufPayload: {
-      if (isProto3) {
-        if (!test_message.ParseFromString(request.protobuf_payload())) {
-          // Getting parse details would involve something like:
-          //   http://stackoverflow.com/questions/22121922/how-can-i-get-more-details-about-errors-generated-during-protobuf-parsing-c
-          response->set_parse_error("Parse error (no more details available).");
-          return;
-        }
-      } else if (request.message_type() == "proto2") {
-        if (!test_message_proto2.ParseFromString(request.protobuf_payload())) {
-          response->set_parse_error("Parse error (no more details available).");
-          return;
-        }
-      } else {
-        GOOGLE_LOG(FATAL) << "Protobuf request doesn't have specific payload type";
+      if (!test_message->ParseFromString(request.protobuf_payload())) {
+        // Getting parse details would involve something like:
+        //   http://stackoverflow.com/questions/22121922/how-can-i-get-more-details-about-errors-generated-during-protobuf-parsing-c
+        response->set_parse_error("Parse error (no more details available).");
+        return;
       }
       break;
     }
@@ -124,7 +126,7 @@ void DoTest(const ConformanceRequest& request, ConformanceResponse* response) {
         return;
       }
 
-      if (!test_message.ParseFromString(proto_binary)) {
+      if (!test_message->ParseFromString(proto_binary)) {
         response->set_runtime_error(
             "Parsing JSON generates invalid proto output.");
         return;
@@ -143,21 +145,13 @@ void DoTest(const ConformanceRequest& request, ConformanceResponse* response) {
       break;
 
     case conformance::PROTOBUF: {
-      (isProto3 || isJson) ?
-        GOOGLE_CHECK(
-              test_message.SerializeToString(response->mutable_protobuf_payload()))
-              :
-        GOOGLE_CHECK(
-              test_message_proto2.SerializeToString(response->mutable_protobuf_payload()));
+      GOOGLE_CHECK(test_message->SerializeToString(response->mutable_protobuf_payload()));
       break;
     }
 
     case conformance::JSON: {
       string proto_binary;
-      (isProto3 || isJson) ?
-          GOOGLE_CHECK(test_message.SerializeToString(&proto_binary))
-               :
-          GOOGLE_CHECK(test_message_proto2.SerializeToString(&proto_binary));
+      GOOGLE_CHECK(test_message->SerializeToString(&proto_binary));
       Status status = BinaryToJsonString(type_resolver, *type_url, proto_binary,
                                          response->mutable_json_payload());
       if (!status.ok()) {
diff --git a/conformance/conformance_python.py b/conformance/conformance_python.py
index 846ccbc64..62cfce87b 100755
--- a/conformance/conformance_python.py
+++ b/conformance/conformance_python.py
@@ -54,30 +54,25 @@ class ProtocolError(Exception):
   pass
 
 def do_test(request):
-  test_message = test_messages_proto3_pb2.TestAllTypes()
-  response = conformance_pb2.ConformanceResponse()
-  test_message = test_messages_proto3_pb2.TestAllTypes()
-  test_message_proto2 = test_messages_proto2_pb2.TestAllTypesProto2()
-  isProto3 = (request.message_type == "proto3")
+  isProto3 = (request.message_type == "protobuf_test_messages.proto3.TestAllTypes")
   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.TestAllTypes()
+  response = conformance_pb2.ConformanceResponse()
 
   try:
     if request.WhichOneof('payload') == 'protobuf_payload':
-      if isProto3:
-        try:
-          test_message.ParseFromString(request.protobuf_payload)
-        except message.DecodeError as e:
-          response.parse_error = str(e)
-          return response
-      elif request.message_type == "proto2":
-        try:
-          test_message_proto2.ParseFromString(request.protobuf_payload)
-        except message.DecodeError as e:
-          response.parse_error = str(e)
-          return response
-      else:
-        raise ProtocolError("Protobuf request doesn't have specific payload type")
-
+      try:
+        test_message.ParseFromString(request.protobuf_payload)
+      except message.DecodeError as e:
+        response.parse_error = str(e)
+        return response  
+      
     elif request.WhichOneof('payload') == 'json_payload':
       try:
         json_format.Parse(request.json_payload, test_message)
@@ -92,17 +87,11 @@ def do_test(request):
       raise ProtocolError("Unspecified output format")
 
     elif request.requested_output_format == conformance_pb2.PROTOBUF:
-      if isProto3 or isJson:
-        response.protobuf_payload = test_message.SerializeToString()
-      else:
-        response.protobuf_payload = test_message_proto2.SerializeToString()
+      response.protobuf_payload = test_message.SerializeToString()
 
     elif request.requested_output_format == conformance_pb2.JSON:
-      try:
-        if isProto3 or isJson:        
-          response.json_payload = json_format.MessageToJson(test_message)
-        else:
-          response.json_payload = json_format.MessageToJson(test_message_proto2)
+      try: 
+        response.json_payload = json_format.MessageToJson(test_message)
       except Exception as e:
         response.serialize_error = str(e)
         return response
diff --git a/conformance/conformance_test.cc b/conformance/conformance_test.cc
index f44fe8a10..7583c88db 100644
--- a/conformance/conformance_test.cc
+++ b/conformance/conformance_test.cc
@@ -276,14 +276,18 @@ void ConformanceTestSuite::RunValidInputTest(
     const string& test_name, ConformanceLevel level, const string& input,
     WireFormat input_format, const string& equivalent_text_format,
     WireFormat requested_output, bool isProto3) {
-  TestAllTypes reference_message;
-  TestAllTypesProto2 reference_message_proto2;
+  auto newTestMessage = [&isProto3]() {
+    Message* newMessage;
+    if (isProto3) {
+      newMessage = new TestAllTypes;
+    } else {
+      newMessage = new TestAllTypesProto2;
+    }
+    return newMessage;
+  };
+  Message* reference_message = newTestMessage();
   GOOGLE_CHECK(
-      isProto3 ?
-          TextFormat::ParseFromString(equivalent_text_format, &reference_message)
-          :
-          TextFormat::ParseFromString(equivalent_text_format, &reference_message_proto2)
-  )
+      TextFormat::ParseFromString(equivalent_text_format, reference_message))
           << "Failed to parse data for test case: " << test_name
           << ", data: " << equivalent_text_format;
 
@@ -294,9 +298,9 @@ void ConformanceTestSuite::RunValidInputTest(
     case conformance::PROTOBUF: {
       request.set_protobuf_payload(input);
       if (isProto3) {
-        request.set_message_type("proto3");
+        request.set_message_type("protobuf_test_messages.proto3.TestAllTypes");
       } else {
-        request.set_message_type("proto2");
+        request.set_message_type("protobuf_test_messages.proto2.TestAllTypesProto2");
       }
       break;
     }
@@ -313,8 +317,7 @@ void ConformanceTestSuite::RunValidInputTest(
 
   RunTest(test_name, request, &response);
 
-  TestAllTypes test_message;
-  TestAllTypesProto2 test_message_proto2;
+  Message *test_message = newTestMessage();
 
   switch (response.result_case()) {
     case ConformanceResponse::RESULT_NOT_SET:
@@ -350,20 +353,11 @@ void ConformanceTestSuite::RunValidInputTest(
         return;
       }
 
-      if (isProto3) {
-        if (!test_message.ParseFromString(binary_protobuf)) {
-          ReportFailure(test_name, level, request, response,
-                      "INTERNAL ERROR: internal JSON->protobuf transcode "
-                      "yielded unparseable proto.");
-          return;
-        }
-      } else {
-        if (!test_message_proto2.ParseFromString(binary_protobuf)) {
-          ReportFailure(test_name, level, request, response,
-                      "INTERNAL ERROR: internal JSON->protobuf transcode "
-                      "yielded unparseable proto.");
-          return;
-        }
+      if (!test_message->ParseFromString(binary_protobuf)) {
+        ReportFailure(test_name, level, request, response,
+                    "INTERNAL ERROR: internal JSON->protobuf transcode "
+                    "yielded unparseable proto.");
+        return;
       }
 
       break;
@@ -377,18 +371,10 @@ void ConformanceTestSuite::RunValidInputTest(
         return;
       }
 
-      if (isProto3) {
-        if (!test_message.ParseFromString(response.protobuf_payload())) {
-          ReportFailure(test_name, level, request, response,
-                     "Protobuf output we received from test was unparseable.");
-          return;
-        }
-      } else {
-        if (!test_message_proto2.ParseFromString(response.protobuf_payload())) {
-          ReportFailure(test_name, level, request, response,
-                     "Protobuf output we received from test was unparseable.");
-          return;
-        }
+      if (!test_message->ParseFromString(response.protobuf_payload())) {
+        ReportFailure(test_name, level, request, response,
+                   "Protobuf output we received from test was unparseable.");
+        return;
       }
 
       break;
@@ -407,11 +393,7 @@ void ConformanceTestSuite::RunValidInputTest(
   differencer.ReportDifferencesToString(&differences);
 
   bool check;
-  if (isProto3) {
-    check = differencer.Compare(reference_message, test_message);
-  } else {
-    check = differencer.Compare(reference_message_proto2, test_message_proto2);
-  }
+  check = differencer.Compare(*reference_message, *test_message);
   if (check) {
     ReportSuccess(test_name);
   } else {
@@ -429,9 +411,9 @@ void ConformanceTestSuite::ExpectParseFailureForProto(
   ConformanceResponse response;
   request.set_protobuf_payload(proto);
   if (isProto3) {
-    request.set_message_type("proto3");
+    request.set_message_type("protobuf_test_messages.proto3.TestAllTypes");
   } else {
-    request.set_message_type("proto2");
+    request.set_message_type("protobuf_test_messages.proto2.TestAllTypesProto2");
   }
   string effective_test_name = ConformanceLevelToString(level) +
       ".ProtobufInput." + test_name;
@@ -586,7 +568,7 @@ void ConformanceTestSuite::ExpectSerializeFailureForJson(
   ConformanceRequest request;
   ConformanceResponse response;
   request.set_protobuf_payload(payload_message.SerializeAsString());
-  request.set_message_type("proto3");
+  request.set_message_type("protobuf_test_messages.proto3.TestAllTypes");
   string effective_test_name =
       ConformanceLevelToString(level) + "." + test_name + ".JsonOutput";
   request.set_requested_output_format(conformance::JSON);
-- 
2.18.0