Fix build issues from backport of changes at HEAD
diff --git a/.bazelrc b/.bazelrc
index f6a6f73..664da5f 100644
--- a/.bazelrc
+++ b/.bazelrc
@@ -1,6 +1,6 @@
 test --test_output=errors
 build --copt="-w" --host_copt="-w"
-build --cxxopt=-std=c++14 --host_cxxopt=-std=c++14
+build --cxxopt=-std=c++17 --host_cxxopt=-std=c++17
 
 build --action_env=CXXFLAGS=-stdlib=libc++ --action_env=LDFLAGS=-stdlib=libc++ --action_env=BAZEL_CXXOPTS=-stdlib=libc++ --action_env=BAZEL_LINKOPTS=-lc++:-lm
 
diff --git a/BUILD.bazel b/BUILD.bazel
index 4e00fcb..cb4a173 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -1065,9 +1065,18 @@
 cc_library(
     name = "proto_api",
     hdrs = ["python/google/protobuf/proto_api.h"],
+    srcs = ["python/google/protobuf/proto_api.cc"],
     visibility = ["//visibility:public"],
+    copts = COPTS,
+    strip_include_prefix = "python/",
+    linkopts = LINK_OPTS,
+    includes = [
+        "python/",
+        "src/",
+    ],
     deps = [
         "//external:python_headers",
+        ":protobuf",
     ],
 )
 
diff --git a/python/google/protobuf/proto_api.cc b/python/google/protobuf/proto_api.cc
index 299c03a..928229a 100644
--- a/python/google/protobuf/proto_api.cc
+++ b/python/google/protobuf/proto_api.cc
@@ -5,7 +5,6 @@
 #include <memory>
 #include <string>
 
-#include "absl/log/absl_check.h"
 #include "google/protobuf/io/zero_copy_stream_impl_lite.h"
 #include "google/protobuf/message.h"
 namespace google {
@@ -15,8 +14,8 @@
 PythonMessageMutator::PythonMessageMutator(Message* owned_msg, Message* message,
                                            PyObject* py_msg)
     : owned_msg_(owned_msg), message_(message), py_msg_(py_msg) {
-  ABSL_DCHECK(py_msg != nullptr);
-  ABSL_DCHECK(message != nullptr);
+  GOOGLE_DCHECK(py_msg != nullptr);
+  GOOGLE_DCHECK(message != nullptr);
   Py_INCREF(py_msg_);
 }
 
@@ -60,8 +59,8 @@
                                                      const Message* message,
                                                      PyObject* py_msg)
     : owned_msg_(owned_msg), message_(message), py_msg_(py_msg) {
-  ABSL_DCHECK(py_msg != nullptr);
-  ABSL_DCHECK(message != nullptr);
+  GOOGLE_DCHECK(py_msg != nullptr);
+  GOOGLE_DCHECK(message != nullptr);
   Py_INCREF(py_msg_);
 }
 
@@ -76,7 +75,7 @@
 }
 
 bool PythonConstMessagePointer::NotChanged() {
-  ABSL_DCHECK(!PyErr_Occurred());
+  GOOGLE_DCHECK(!PyErr_Occurred());
   if (owned_msg_ == nullptr) {
     return false;
   }
@@ -123,12 +122,12 @@
 
 PythonConstMessagePointer::~PythonConstMessagePointer() {
   if (py_msg_ == nullptr) {
-    ABSL_DCHECK(message_ == nullptr);
-    ABSL_DCHECK(owned_msg_ == nullptr);
+    GOOGLE_DCHECK(message_ == nullptr);
+    GOOGLE_DCHECK(owned_msg_ == nullptr);
     return;
   }
-  ABSL_DCHECK(owned_msg_ != nullptr);
-  ABSL_DCHECK(NotChanged());
+  GOOGLE_DCHECK(owned_msg_ != nullptr);
+  GOOGLE_DCHECK(NotChanged());
   Py_DECREF(py_msg_);
 }
 
diff --git a/python/google/protobuf/proto_api.h b/python/google/protobuf/proto_api.h
index 1a906d2..1404906 100644
--- a/python/google/protobuf/proto_api.h
+++ b/python/google/protobuf/proto_api.h
@@ -50,9 +50,9 @@
 #define PY_SSIZE_T_CLEAN
 #include <Python.h>
 
-#include "absl/status/status.h"
 #include "google/protobuf/descriptor_database.h"
 #include "google/protobuf/message.h"
+#include "google/protobuf/stubs/statusor.h"
 
 PyObject* pymessage_mutate_const(PyObject* self, PyObject* args);
 
@@ -86,7 +86,7 @@
   // calling back into Python.
   // Warning: there is a risk of deadlock with Python/C++ if users use the
   // returned message->GetDescriptor()->file->pool()
-  virtual absl::StatusOr<PythonMessageMutator> GetClearedMessageMutator(
+  virtual util::StatusOr<PythonMessageMutator> GetClearedMessageMutator(
       PyObject* msg) const = 0;
 
   // Returns a PythonConstMessagePointer. For UPB and Pure Python, it points
@@ -94,7 +94,7 @@
   // points the internal c++ message.
   // User should not hold onto the returned PythonConstMessagePointer
   // while calling back into Python.
-  virtual absl::StatusOr<PythonConstMessagePointer> GetConstMessagePointer(
+  virtual util::StatusOr<PythonConstMessagePointer> GetConstMessagePointer(
       PyObject* msg) const = 0;
 
   // If the passed object is a Python Message, returns its internal pointer.
@@ -179,6 +179,7 @@
 // User should not hold onto this object while calling back into Python
 class PythonMessageMutator {
  public:
+  PythonMessageMutator() = default;
   PythonMessageMutator(PythonMessageMutator&& other);
   ~PythonMessageMutator();
 
@@ -204,6 +205,7 @@
 
 class PythonConstMessagePointer {
  public:
+  PythonConstMessagePointer() = default;
   PythonConstMessagePointer(PythonConstMessagePointer&& other);
   ~PythonConstMessagePointer();
 
diff --git a/python/google/protobuf/pyext/message_module.cc b/python/google/protobuf/pyext/message_module.cc
index f1d40c4..9f2013e 100644
--- a/python/google/protobuf/pyext/message_module.cc
+++ b/python/google/protobuf/pyext/message_module.cc
@@ -32,7 +32,6 @@
 #include <Python.h>
 
 #include "google/protobuf/descriptor.pb.h"
-#include "absl/log/absl_log.h"
 #include "google/protobuf/dynamic_message.h"
 #include "google/protobuf/message_lite.h"
 #include "google/protobuf/proto_api.h"
@@ -47,19 +46,25 @@
 
 namespace {
 
+using ::google::protobuf::StrCat;
+using ::google::protobuf::util::Status;
+using ::google::protobuf::util::StatusOr;
+using ::google::protobuf::util::InternalError;
+using ::google::protobuf::util::InvalidArgumentError;
+
 class ProtoAPIDescriptorDatabase : public google::protobuf::DescriptorDatabase {
  public:
   ProtoAPIDescriptorDatabase() {
     PyObject* descriptor_pool =
         PyImport_ImportModule("google.protobuf.descriptor_pool");
     if (descriptor_pool == nullptr) {
-      ABSL_LOG(ERROR)
+      GOOGLE_LOG(ERROR)
           << "Failed to import google.protobuf.descriptor_pool module.";
     }
 
     pool_ = PyObject_CallMethod(descriptor_pool, "Default", nullptr);
     if (pool_ == nullptr) {
-      ABSL_LOG(ERROR) << "Failed to get python Default pool.";
+      GOOGLE_LOG(ERROR) << "Failed to get python Default pool.";
     }
     Py_DECREF(descriptor_pool);
   };
@@ -70,7 +75,7 @@
     // in which destructors of static objects run is unpredictable. In
     // particular, it is possible that the Python interpreter may have been
     // finalized already.
-    ABSL_DLOG(ERROR) << "MEANT TO BE UNREACHABLE.";
+    GOOGLE_DLOG(ERROR) << "MEANT TO BE UNREACHABLE.";
   };
 
   bool FindFileByName(const std::string& filename,
@@ -104,7 +109,7 @@
         reinterpret_cast<uint8_t*>(PyBytes_AS_STRING(pyfile_serialized)),
         PyBytes_GET_SIZE(pyfile_serialized));
     if (!ok) {
-      ABSL_LOG(ERROR) << "Failed to parse descriptor for " << filename;
+      GOOGLE_LOG(ERROR) << "Failed to parse descriptor for " << filename;
     }
     Py_DECREF(pyfile_serialized);
     return ok;
@@ -127,18 +132,18 @@
   PyObject* pool_;
 };
 
-absl::StatusOr<const google::protobuf::Descriptor*> FindMessageDescriptor(
+StatusOr<const google::protobuf::Descriptor*> FindMessageDescriptor(
     PyObject* pyfile, const char* descriptor_full_name) {
   static auto* database = new ProtoAPIDescriptorDatabase();
   static auto* pool = new google::protobuf::DescriptorPool(database);
   PyObject* pyfile_name = PyObject_GetAttrString(pyfile, "name");
   if (pyfile_name == nullptr) {
-    return absl::InvalidArgumentError("FileDescriptor has no attribute 'name'");
+    return InvalidArgumentError("FileDescriptor has no attribute 'name'");
   }
   PyObject* pyfile_pool = PyObject_GetAttrString(pyfile, "pool");
   if (pyfile_pool == nullptr) {
     Py_DECREF(pyfile_name);
-    return absl::InvalidArgumentError("FileDescriptor has no attribute 'pool'");
+    return InvalidArgumentError("FileDescriptor has no attribute 'pool'");
   }
   // Check the file descriptor is from generated pool.
   bool is_from_generated_pool = database->pool() == pyfile_pool;
@@ -146,14 +151,14 @@
   const char* pyfile_name_char_ptr = PyUnicode_AsUTF8(pyfile_name);
   if (pyfile_name_char_ptr == nullptr) {
     Py_DECREF(pyfile_name);
-    return absl::InvalidArgumentError(
+    return InvalidArgumentError(
         "FileDescriptor 'name' PyUnicode_AsUTF8() failure.");
   }
   if (!is_from_generated_pool) {
-    std::string error_msg = absl::StrCat(pyfile_name_char_ptr,
+    std::string error_msg = StrCat(pyfile_name_char_ptr,
                                          " is not from generated pool");
     Py_DECREF(pyfile_name);
-    return absl::InvalidArgumentError(error_msg);
+    return InvalidArgumentError(error_msg);
   }
   const google::protobuf::FileDescriptor* file_descriptor =
       pool->FindFileByName(pyfile_name_char_ptr);
@@ -161,16 +166,16 @@
   if (file_descriptor == nullptr) {
     // Already checked the file is from generated pool above, this
     // error should never be reached.
-    ABSL_DLOG(ERROR) << "MEANT TO BE UNREACHABLE.";
-    std::string error_msg = absl::StrCat("Fail to find/build file ",
+    GOOGLE_DLOG(ERROR) << "MEANT TO BE UNREACHABLE.";
+    std::string error_msg = StrCat("Fail to find/build file ",
                                          pyfile_name_char_ptr);
-    return absl::InternalError(error_msg);
+    return InternalError(error_msg);
   }
 
   const google::protobuf::Descriptor* descriptor =
       pool->FindMessageTypeByName(descriptor_full_name);
   if (descriptor == nullptr) {
-    return absl::InternalError("Fail to find descriptor by name.");
+    return InternalError("Fail to find descriptor by name.");
   }
   return descriptor;
 }
@@ -181,27 +186,27 @@
   return factory;
 }
 
-absl::StatusOr<google::protobuf::Message*> CreateNewMessage(PyObject* py_msg) {
+StatusOr<google::protobuf::Message*> CreateNewMessage(PyObject* py_msg) {
   PyObject* pyd = PyObject_GetAttrString(py_msg, "DESCRIPTOR");
   if (pyd == nullptr) {
-    return absl::InvalidArgumentError("py_msg has no attribute 'DESCRIPTOR'");
+    return InvalidArgumentError("py_msg has no attribute 'DESCRIPTOR'");
   }
 
   PyObject* fn = PyObject_GetAttrString(pyd, "full_name");
   if (fn == nullptr) {
-    return absl::InvalidArgumentError(
+    return InvalidArgumentError(
         "DESCRIPTOR has no attribute 'full_name'");
   }
 
   const char* descriptor_full_name = PyUnicode_AsUTF8(fn);
   if (descriptor_full_name == nullptr) {
-    return absl::InternalError("Fail to convert descriptor full name");
+    return InternalError("Fail to convert descriptor full name");
   }
 
   PyObject* pyfile = PyObject_GetAttrString(pyd, "file");
   Py_DECREF(pyd);
   if (pyfile == nullptr) {
-    return absl::InvalidArgumentError("DESCRIPTOR has no attribute 'file'");
+    return InvalidArgumentError("DESCRIPTOR has no attribute 'file'");
   }
   auto gen_d = google::protobuf::DescriptorPool::generated_pool()->FindMessageTypeByName(
       descriptor_full_name);
@@ -216,7 +221,7 @@
   Py_DECREF(pyfile);
   RETURN_IF_ERROR(d.status());
   Py_DECREF(fn);
-  return GetFactory()->GetPrototype(*d)->New();
+  return GetFactory()->GetPrototype(d.value())->New();
 }
 
 bool CopyToOwnedMsg(google::protobuf::Message** copy, const google::protobuf::Message& message) {
@@ -229,13 +234,13 @@
 
 // C++ API.  Clients get at this via proto_api.h
 struct ApiImplementation : google::protobuf::python::PyProto_API {
-  absl::StatusOr<google::protobuf::python::PythonMessageMutator> GetClearedMessageMutator(
+  StatusOr<google::protobuf::python::PythonMessageMutator> GetClearedMessageMutator(
       PyObject* py_msg) const override {
     if (PyObject_TypeCheck(py_msg, google::protobuf::python::CMessage_Type)) {
       google::protobuf::Message* message =
           google::protobuf::python::PyMessage_GetMutableMessagePointer(py_msg);
       if (message == nullptr) {
-        return absl::InternalError(
+        return InternalError(
             "Fail to get message pointer. The message "
             "may already had a reference.");
       }
@@ -245,16 +250,16 @@
 
     auto msg = CreateNewMessage(py_msg);
     RETURN_IF_ERROR(msg.status());
-    return CreatePythonMessageMutator(*msg, *msg, py_msg);
+    return CreatePythonMessageMutator(msg.value(), msg.value(), py_msg);
   }
 
-  absl::StatusOr<google::protobuf::python::PythonConstMessagePointer>
+  StatusOr<google::protobuf::python::PythonConstMessagePointer>
   GetConstMessagePointer(PyObject* py_msg) const override {
     if (PyObject_TypeCheck(py_msg, google::protobuf::python::CMessage_Type)) {
       const google::protobuf::Message* message =
           google::protobuf::python::PyMessage_GetMessagePointer(py_msg);
       google::protobuf::Message* owned_msg = nullptr;
-      ABSL_DCHECK(CopyToOwnedMsg(&owned_msg, *message));
+      GOOGLE_DCHECK(CopyToOwnedMsg(&owned_msg, *message));
       return CreatePythonConstMessagePointer(owned_msg, message, py_msg);
     }
     auto msg = CreateNewMessage(py_msg);
@@ -262,22 +267,22 @@
     PyObject* serialized_pb(
         PyObject_CallMethod(py_msg, "SerializeToString", nullptr));
     if (serialized_pb == nullptr) {
-      return absl::InternalError("Fail to serialize py_msg");
+      return InternalError("Fail to serialize py_msg");
     }
     char* data;
     Py_ssize_t len;
     if (PyBytes_AsStringAndSize(serialized_pb, &data, &len) < 0) {
       Py_DECREF(serialized_pb);
-      return absl::InternalError(
+      return InternalError(
           "Fail to get bytes from py_msg serialized data");
     }
-    if (!(*msg)->ParseFromArray(data, len)) {
+    if (!(msg.value())->ParseFromArray(data, len)) {
       Py_DECREF(serialized_pb);
-      return absl::InternalError(
+      return InternalError(
           "Couldn't parse py_message to google::protobuf::Message*!");
     }
     Py_DECREF(serialized_pb);
-    return CreatePythonConstMessagePointer(*msg, *msg, py_msg);
+    return CreatePythonConstMessagePointer(msg.value(), msg.value(), py_msg);
   }
 
   const google::protobuf::Message* GetMessagePointer(PyObject* msg) const override {
diff --git a/src/google/protobuf/stubs/statusor.h b/src/google/protobuf/stubs/statusor.h
index 20e603e..78be519 100644
--- a/src/google/protobuf/stubs/statusor.h
+++ b/src/google/protobuf/stubs/statusor.h
@@ -120,6 +120,7 @@
   // DCHECKed. In optimized builds, passing a null pointer here will have
   // the effect of passing PosixErrorSpace::EINVAL as a fallback.
   StatusOr(const T& value);  // NOLINT
+  StatusOr(T&& value);
 
   // Copy constructor.
   StatusOr(const StatusOr& other);
@@ -197,6 +198,9 @@
 }
 
 template<typename T>
+inline StatusOr<T>::StatusOr(T&& value) : value_(std::move(value)) {}
+
+template<typename T>
 inline StatusOr<T>::StatusOr(const StatusOr<T>& other)
     : status_(other.status_), value_(other.value_) {
 }