Commit ecb27817 authored by Brett Cooley's avatar Brett Cooley Committed by Android (Google) Code Review

Merge "Initial support for propagating namespaces from schema files to generated…

Merge "Initial support for propagating namespaces from schema files to generated code" into ub-games-master
parents f59bfdd0 249f71a1
......@@ -19,7 +19,9 @@
**/*.dir/**
**/CMakeFiles/**
**/cmake_install.cmake
**/install_manifest.txt
**/CMakeCache.txt
**/CMakeTestfile.cmake
**/Debug/**
**/Release/**
build.xml
......
......@@ -313,6 +313,12 @@ class Parser {
// Mark all definitions as already having code generated.
void MarkGenerated();
// Given a (potentally unqualified) name, return the "fully qualified" name
// which has a full namespaced descriptor. If the parser has no current
// namespace context, or if the name passed is partially qualified the input
// is simply returned.
std::string GetFullyQualifiedName(const std::string &name) const;
// Get the files recursively included by the given file. The returned
// container will have at least the given file.
std::set<std::string> GetIncludedFilesRecursive(
......
......@@ -127,13 +127,13 @@ inline bool VerifyAny(flatbuffers::Verifier &verifier, const void *union_obj, An
}
}
inline const Monster *GetMonster(const void *buf) { return flatbuffers::GetRoot<Monster>(buf); }
inline const MyGame::Sample::Monster *GetMonster(const void *buf) { return flatbuffers::GetRoot<MyGame::Sample::Monster>(buf); }
inline Monster *GetMutableMonster(void *buf) { return flatbuffers::GetMutableRoot<Monster>(buf); }
inline bool VerifyMonsterBuffer(flatbuffers::Verifier &verifier) { return verifier.VerifyBuffer<Monster>(); }
inline bool VerifyMonsterBuffer(flatbuffers::Verifier &verifier) { return verifier.VerifyBuffer<MyGame::Sample::Monster>(); }
inline void FinishMonsterBuffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<Monster> root) { fbb.Finish(root); }
inline void FinishMonsterBuffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<MyGame::Sample::Monster> root) { fbb.Finish(root); }
} // namespace Sample
} // namespace MyGame
......
......@@ -44,6 +44,18 @@ static std::string WrapInNameSpace(const Parser &parser,
return WrapInNameSpace(parser, def.defined_namespace, def.name);
}
// Translates a qualified name in flatbuffer text format to the same name in
// the equivalent C++ namepsace.
static std::string TranslateNameSpace(const std::string &qualified_name) {
std::string cpp_qualified_name = qualified_name;
size_t start_pos = 0;
while((start_pos = cpp_qualified_name.find(".", start_pos)) !=
std::string::npos) {
cpp_qualified_name.replace(start_pos, 1, "::");
}
return cpp_qualified_name;
}
// Return a C++ type from the table in idl.h
static std::string GenTypeBasic(const Parser &parser, const Type &type,
......@@ -258,11 +270,15 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
}
auto nested = field.attributes.Lookup("nested_flatbuffer");
if (nested) {
auto nested_root = parser.structs_.Lookup(nested->constant);
std::string qualified_name = parser.GetFullyQualifiedName(
nested->constant);
auto nested_root = parser.structs_.Lookup(qualified_name);
assert(nested_root); // Guaranteed to exist by parser.
code += " const " + nested_root->name + " *" + field.name;
std::string cpp_qualified_name = TranslateNameSpace(qualified_name);
code += " const " + cpp_qualified_name + " *" + field.name;
code += "_nested_root() const { return flatbuffers::GetRoot<";
code += nested_root->name + ">(" + field.name + "()->Data()); }\n";
code += cpp_qualified_name + ">(" + field.name + "()->Data()); }\n";
}
// Generate a comparison function for this field if it is a key.
if (field.key) {
......@@ -685,11 +701,14 @@ std::string GenerateCPP(const Parser &parser,
// Generate convenient global helper functions:
if (parser.root_struct_def) {
auto &name = parser.root_struct_def->name;
std::string qualified_name = parser.GetFullyQualifiedName(name);
std::string cpp_qualified_name = TranslateNameSpace(qualified_name);
// The root datatype accessor:
code += "inline const " + name + " *Get";
code += "inline const " + cpp_qualified_name + " *Get";
code += name;
code += "(const void *buf) { return flatbuffers::GetRoot<";
code += name + ">(buf); }\n\n";
code += cpp_qualified_name + ">(buf); }\n\n";
if (opts.mutable_buffer) {
code += "inline " + name + " *GetMutable";
code += name;
......@@ -702,7 +721,7 @@ std::string GenerateCPP(const Parser &parser,
code += name;
code += "Buffer(flatbuffers::Verifier &verifier) { "
"return verifier.VerifyBuffer<";
code += name + ">(); }\n\n";
code += cpp_qualified_name + ">(); }\n\n";
if (parser.file_identifier_.length()) {
// Return the identifier
......@@ -727,7 +746,7 @@ std::string GenerateCPP(const Parser &parser,
// Finish a buffer with a given root object:
code += "inline void Finish" + name;
code += "Buffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<";
code += name + "> root) { fbb.Finish(root";
code += cpp_qualified_name + "> root) { fbb.Finish(root";
if (parser.file_identifier_.length())
code += ", " + name + "Identifier()";
code += "); }\n\n";
......
......@@ -773,12 +773,13 @@ void Parser::ParseSingleValue(Value &e) {
}
StructDef *Parser::LookupCreateStruct(const std::string &name) {
auto struct_def = structs_.Lookup(name);
std::string qualified_name = GetFullyQualifiedName(name);
auto struct_def = structs_.Lookup(qualified_name);
if (!struct_def) {
// Rather than failing, we create a "pre declared" StructDef, due to
// circular references, and check for errors at the end of parsing.
struct_def = new StructDef();
structs_.Add(name, struct_def);
structs_.Add(qualified_name, struct_def);
struct_def->name = name;
struct_def->predecl = true;
struct_def->defined_namespace = namespaces_.back();
......@@ -951,10 +952,30 @@ void Parser::ParseDecl() {
}
bool Parser::SetRootType(const char *name) {
root_struct_def = structs_.Lookup(name);
root_struct_def = structs_.Lookup(GetFullyQualifiedName(name));
return root_struct_def != nullptr;
}
std::string Parser::GetFullyQualifiedName(const std::string &name) const {
Namespace *ns = namespaces_.back();
// Early exit if we don't have a defined namespace, or if the name is already
// partially qualified
if (ns->components.size() == 0 || name.find(".") != std::string::npos) {
return name;
}
std::stringstream stream;
for (size_t i = 0; i != ns->components.size(); ++i) {
if (i != 0) {
stream << ".";
}
stream << ns->components[i];
}
stream << "." << name;
return stream.str();
}
void Parser::MarkGenerated() {
// Since the Parser object retains definitions across files, we must
// ensure we only output code for definitions once, in the file they are first
......
......@@ -167,7 +167,7 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
Monster *mutable_enemy() { return GetPointer<Monster *>(28); }
const flatbuffers::Vector<uint8_t> *testnestedflatbuffer() const { return GetPointer<const flatbuffers::Vector<uint8_t> *>(30); }
flatbuffers::Vector<uint8_t> *mutable_testnestedflatbuffer() { return GetPointer<flatbuffers::Vector<uint8_t> *>(30); }
const Monster *testnestedflatbuffer_nested_root() const { return flatbuffers::GetRoot<Monster>(testnestedflatbuffer()->Data()); }
const MyGame::Example::Monster *testnestedflatbuffer_nested_root() const { return flatbuffers::GetRoot<MyGame::Example::Monster>(testnestedflatbuffer()->Data()); }
const Stat *testempty() const { return GetPointer<const Stat *>(32); }
Stat *mutable_testempty() { return GetPointer<Stat *>(32); }
uint8_t testbool() const { return GetField<uint8_t>(34, 0); }
......@@ -322,11 +322,11 @@ inline bool VerifyAny(flatbuffers::Verifier &verifier, const void *union_obj, An
}
}
inline const Monster *GetMonster(const void *buf) { return flatbuffers::GetRoot<Monster>(buf); }
inline const MyGame::Example::Monster *GetMonster(const void *buf) { return flatbuffers::GetRoot<MyGame::Example::Monster>(buf); }
inline Monster *GetMutableMonster(void *buf) { return flatbuffers::GetMutableRoot<Monster>(buf); }
inline bool VerifyMonsterBuffer(flatbuffers::Verifier &verifier) { return verifier.VerifyBuffer<Monster>(); }
inline bool VerifyMonsterBuffer(flatbuffers::Verifier &verifier) { return verifier.VerifyBuffer<MyGame::Example::Monster>(); }
inline const char *MonsterIdentifier() { return "MONS"; }
......@@ -334,7 +334,7 @@ inline bool MonsterBufferHasIdentifier(const void *buf) { return flatbuffers::Bu
inline const char *MonsterExtension() { return "mon"; }
inline void FinishMonsterBuffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<Monster> root) { fbb.Finish(root, MonsterIdentifier()); }
inline void FinishMonsterBuffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<MyGame::Example::Monster> root) { fbb.Finish(root, MonsterIdentifier()); }
} // namespace Example
} // namespace MyGame
......
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