parser.cpp 2.31 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
#include "parser.h"

prodisdb::server::Parser::Parser()
{
    sourceTree.MapPath("", "/usr/include"); // google/protobuf/... should be here
    sourceTree.MapPath("", "/home/giorgio/Documents/ProdisDB/src"); // HACK prodisdb/options
    sourceTree.MapPath("", "/home/giorgio/Documents/ProdisDB/test"); // HACK The DB schema defined by the user
    
    inputStream = sourceTree.Open("");
    if (inputStream == NULL) {
        std::cerr << "Couldn't open .proto source tree: " << sourceTree.GetLastErrorMessage() << std::endl;
    }
    
    descriptorDb = new compiler::SourceTreeDescriptorDatabase(&sourceTree);
    descriptorDb->RecordErrorsTo(errCollector);
    
    pool = new DescriptorPool(descriptorDb);
    
    pool->FindFileByName("prodisdb/protobuf/options.proto");
    pool->FindFileByName("test.proto");
}

prodisdb::server::Parser::~Parser()
{
}

27
void prodisdb::server::Parser::ParseMessage(const Any& serializable)
28
{
29 30 31
    std::string type = serializable.type_url();
    
    const Descriptor* definition = pool->FindMessageTypeByName(type.substr(type.rfind('/')+1, string::npos));
32 33 34 35 36 37 38
    const FieldDescriptor* fd;
    
    // TODO Should check for multiple keys (might be supported later), for now throw error
    for (int idx = 0; idx < definition->field_count(); idx++) {
        fd = definition->field(idx);
        
        if (fd->options().GetExtension(prodisdb::protobuf::options).key()) {
39
            std::cout << fd->full_name() << " is key" << std::endl;
40 41 42 43
            break;
        }
    }
    
44 45 46 47
    Message* container = messageFactory.GetPrototype(definition)->New();
    
    serializable.UnpackTo(container);
    std::cout << container->GetReflection()->GetInt32(*container, fd) << std::endl;
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
}

prodisdb::server::Parser::ErrorCollector::ErrorCollector()
{
}

void prodisdb::server::Parser::ErrorCollector::AddError(const string& filename, int line, int column, const string& message)
{
    if (line == -1) { // Entire file error
        std::cerr << filename << " error: " << message << "\n";
    } else {
        std::cerr << filename << " " << line+1 << ":" << column+1 << " error: " << message << "\n";
    }
}

void prodisdb::server::Parser::ErrorCollector::AddWarning(const string& filename, int line, int column, const string& message)
{
    std::cerr << filename << " " << line+1 << ":" << column+1 << " warning: " << message << "\n";
}