Commit dc89b0fc authored by Giorgio Azzinnaro's avatar Giorgio Azzinnaro

fixed segfault and Key not loading in normalized messages

parent d1d2e8c5
......@@ -36,4 +36,3 @@ public:
}
#endif // PROFANEDB_FORMAT_MARSHALLER_H
......@@ -91,53 +91,53 @@ Loader::Loader(
// The file is now retrieved, and its path for Protobuf must be relative to the mapping
// it's parsed, normalized (nested keyable messages are removed)
FileDescriptorProto normalizedProto = this->ParseFile(
FileDescriptorProto * normalizedProto = this->ParseFile(
schemaPool.FindFileByName(file.path().lexically_relative(path).string()));
BOOST_LOG_TRIVIAL(debug) << "Adding normalized proto " << normalizedProto.name();
BOOST_LOG_TRIVIAL(debug) << "Adding normalized proto " << normalizedProto->name();
BOOST_LOG_TRIVIAL(trace) << std::endl << normalizedProto->DebugString();
// The normalizedDescriptorDb keeps these new Descriptors
normalizedDescriptorDb.AddAndOwn(&normalizedProto);
FileDescriptorProto * proto = new FileDescriptorProto();
normalizedDescriptorDb.FindFileByName(normalizedProto.name(), proto);
// HACK DEBUG
normalizedPool.FindFileByName(normalizedProto.name());
normalizedDescriptorDb.AddAndOwn(normalizedProto);
}
}
}
}
FileDescriptorProto Loader::ParseFile(
FileDescriptorProto * Loader::ParseFile(
const FileDescriptor * fileDescriptor)
{
BOOST_LOG_TRIVIAL(debug) << "Parsing file " << fileDescriptor->name();
// BOOST_LOG_TRIVIAL(trace) << fileDescriptor->DebugString(); // Redundant, is done for each message later
// A FileDescriptorProto is needed to edit messages and populate the normalized descriptor database
FileDescriptorProto normFileDescProto;
fileDescriptor->CopyTo(&normFileDescProto);
FileDescriptorProto * normFileDescProto = new FileDescriptorProto;
fileDescriptor->CopyTo(normFileDescProto);
// storage.proto dependency must be added
// as profanedb.protobuf.Key is used in normalized messages
*normFileDescProto->add_dependency() = "profanedb/protobuf/storage.proto";
// For each message in the file...
for (int i = 0; i < fileDescriptor->message_type_count(); i++) {
// ... parse it, make nested messages of type profanedb.protobuf.Key
*normFileDescProto.mutable_message_type(i) = this->ParseAndNormalizeDescriptor(fileDescriptor->message_type(i));
*normFileDescProto->mutable_message_type(i) = *this->ParseAndNormalizeDescriptor(fileDescriptor->message_type(i));
}
return normFileDescProto;
}
DescriptorProto Loader::ParseAndNormalizeDescriptor(
DescriptorProto * Loader::ParseAndNormalizeDescriptor(
const Descriptor * descriptor)
{
BOOST_LOG_TRIVIAL(debug) << "Parsing descriptor " << descriptor->full_name();
BOOST_LOG_TRIVIAL(trace) << std::endl << descriptor->DebugString();
DescriptorProto normDescProto;
descriptor->CopyTo(&normDescProto);
DescriptorProto * normDescProto = new DescriptorProto;
descriptor->CopyTo(normDescProto);
// Recurse for all messages DEFINED within this message
for (int j = 0; j < descriptor->nested_type_count(); j++) {
*normDescProto.mutable_nested_type(j) = this->ParseAndNormalizeDescriptor(descriptor->nested_type(j));
*normDescProto->mutable_nested_type(j) = *this->ParseAndNormalizeDescriptor(descriptor->nested_type(j));
}
// Now the actual Descriptor normalization
......@@ -149,12 +149,12 @@ DescriptorProto Loader::ParseAndNormalizeDescriptor(
// If this field is effectively a message,
// and that Message is keyable...
if(nestedMessage != nullptr && this->IsKeyable(nestedMessage)) {
if(nestedMessage != NULL && this->IsKeyable(nestedMessage)) {
// ... make the field in the normalized descriptor a Key object
// TODO Maybe we could use an option here as well
normDescProto.mutable_field(k)->set_type(
normDescProto->mutable_field(k)->set_type(
FieldDescriptorProto_Type::FieldDescriptorProto_Type_TYPE_MESSAGE); // Redundant, is message already
normDescProto.mutable_field(k)->set_type_name(Key::descriptor()->full_name()); // TODO Should include Key in normalizedPool
normDescProto->mutable_field(k)->set_type_name(Key::descriptor()->full_name()); // TODO Should include Key in normalizedPool
BOOST_LOG_TRIVIAL(trace) << "Message " << descriptor->name()
<< " has keyable nested message " << field->name()
......
......@@ -81,11 +81,11 @@ private:
// Given a Protobuf FileDescriptor from the pool, parse all of its messages,
// find the keyable messages, and return a FileDescriptorProto,
// ready to be put in the normalizedDescriptorDb
google::protobuf::FileDescriptorProto ParseFile(
google::protobuf::FileDescriptorProto * ParseFile(
const google::protobuf::FileDescriptor * fileDescriptor);
// Parse a Descriptor and its nested messages
google::protobuf::DescriptorProto ParseAndNormalizeDescriptor(
google::protobuf::DescriptorProto * ParseAndNormalizeDescriptor(
const google::protobuf::Descriptor * descriptor);
// Check whether a Descriptor has a field with key option set
......
......@@ -142,7 +142,8 @@ const Message & Marshaller::Unmarshal(const StorableMessage & storable)
->MutableMessage(originalMessage, originalField)
->MergeFrom(nestedMessage);
}
else {
else { // if field is not a reference
// Just like in Marshal, other fields are simply copied over,
// as normalized and original descriptors look the same except for nested keyable messages
this->CopyField(normalizedField, *normalizedMessage, originalMessage);
......
......@@ -2,6 +2,7 @@
#include <boost/test/included/unit_test.hpp>
#include <profanedb/test/protobuf/schema/test.pb.h>
#include <profanedb/protobuf/storage.pb.h>
#include <profanedb/format/protobuf/marshaller.h>
#include <profanedb/vault/rocksdb/storage.h>
......@@ -10,6 +11,7 @@ using profanedb::format::protobuf::Loader;
using profanedb::format::Marshaller;
using ProtobufMarshaller = profanedb::format::protobuf::Marshaller;
using profanedb::vault::Storage;
using profanedb::protobuf::MessageTreeNode;
// FIXME Should mock this
using RocksStorage = profanedb::vault::rocksdb::Storage;
......@@ -41,16 +43,14 @@ struct Format
std::unique_ptr<Loader::RootSourceTree>(schemaSourceTree));
this->marshaller = std::make_shared<ProtobufMarshaller>(storage, loader);
std::cout << loader->GetPool(Loader::SCHEMA).FindMessageTypeByName("schema.Test")->DebugString();
}
};
BOOST_FIXTURE_TEST_CASE(marshal, Format)
{
schema::Test message;
BOOST_TEST_MESSAGE(message.DebugString());
marshaller->Marshal(message);
MessageTreeNode tree = marshaller->Marshal(message);
BOOST_TEST_MESSAGE(tree.DebugString());
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment