blob: 50277a3f02d6e9dc1334f8f2be3d184686724160 [file] [log] [blame]
#include "google/protobuf/proto_api.h"
#include <string>
#include "absl/log/absl_check.h"
#include "google/protobuf/message.h"
namespace google {
namespace protobuf {
namespace python {
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);
Py_INCREF(py_msg_);
}
PythonMessageMutator::PythonMessageMutator(PythonMessageMutator&& other)
: owned_msg_(other.owned_msg_ == nullptr ? nullptr
: other.owned_msg_.release()),
message_(other.message_),
py_msg_(other.py_msg_) {
other.message_ = nullptr;
other.py_msg_ = nullptr;
}
PythonMessageMutator::~PythonMessageMutator() {
if (py_msg_ == nullptr) {
return;
}
// PyErr_Occurred check is required because PyObject_CallMethod need this
// check.
if (!PyErr_Occurred() && owned_msg_ != nullptr) {
std::string wire;
message_->SerializeToString(&wire);
PyObject* py_wire = PyBytes_FromStringAndSize(
wire.data(), static_cast<Py_ssize_t>(wire.size()));
PyObject* parse =
PyObject_CallMethod(py_msg_, "ParseFromString", "O", py_wire);
Py_DECREF(py_wire);
if (parse != nullptr) {
Py_DECREF(parse);
}
}
Py_DECREF(py_msg_);
}
PythonMessageMutator PyProto_API::CreatePythonMessageMutator(
Message* owned_msg, Message* msg, PyObject* py_msg) const {
return PythonMessageMutator(owned_msg, msg, py_msg);
}
} // namespace python
} // namespace protobuf
} // namespace google