mirror of
https://github.com/google/flatbuffers.git
synced 2026-07-02 08:38:20 +00:00
Merge pull request #3843 from Lakedaemon/refactoring
Transition 1 (nice diffs) Go, C++ and General generators with class
This commit is contained in:
@@ -17,6 +17,7 @@ if(NOT FLATBUFFERS_BUILD_FLATC AND FLATBUFFERS_BUILD_TESTS)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(FlatBuffers_Library_SRCS
|
set(FlatBuffers_Library_SRCS
|
||||||
|
include/flatbuffers/code_generators.h
|
||||||
include/flatbuffers/flatbuffers.h
|
include/flatbuffers/flatbuffers.h
|
||||||
include/flatbuffers/hash.h
|
include/flatbuffers/hash.h
|
||||||
include/flatbuffers/idl.h
|
include/flatbuffers/idl.h
|
||||||
|
|||||||
39
include/flatbuffers/code_generators.h
Normal file
39
include/flatbuffers/code_generators.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 Google Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FLATBUFFERS_CODE_GENERATORS_H_
|
||||||
|
#define FLATBUFFERS_CODE_GENERATORS_H_
|
||||||
|
|
||||||
|
namespace flatbuffers {
|
||||||
|
|
||||||
|
class BaseGenerator {
|
||||||
|
public:
|
||||||
|
BaseGenerator(const Parser &parser, const std::string &path,
|
||||||
|
const std::string &file_name)
|
||||||
|
: parser_(parser), path_(path), file_name_(file_name){};
|
||||||
|
virtual bool generate() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ~BaseGenerator(){};
|
||||||
|
|
||||||
|
const Parser &parser_;
|
||||||
|
const std::string &path_;
|
||||||
|
const std::string &file_name_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace flatbuffers
|
||||||
|
|
||||||
|
#endif // FLATBUFFERS_CODE_GENERATORS_H_
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
#include "flatbuffers/flatbuffers.h"
|
#include "flatbuffers/flatbuffers.h"
|
||||||
#include "flatbuffers/idl.h"
|
#include "flatbuffers/idl.h"
|
||||||
#include "flatbuffers/util.h"
|
#include "flatbuffers/util.h"
|
||||||
|
#include "flatbuffers/code_generators.h"
|
||||||
|
|
||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
namespace cpp {
|
namespace cpp {
|
||||||
@@ -714,197 +715,205 @@ struct IsAlnum {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Iterate through all definitions we haven't generate code for (enums, structs,
|
|
||||||
// and tables) and output them to a single file.
|
|
||||||
std::string GenerateCPP(const Parser &parser,
|
|
||||||
const std::string &file_name) {
|
|
||||||
// Check if we have any code to generate at all, to avoid an empty header.
|
|
||||||
for (auto it = parser.enums_.vec.begin(); it != parser.enums_.vec.end();
|
|
||||||
++it) {
|
|
||||||
if (!(*it)->generated) goto generate_code;
|
|
||||||
}
|
|
||||||
for (auto it = parser.structs_.vec.begin(); it != parser.structs_.vec.end();
|
|
||||||
++it) {
|
|
||||||
if (!(*it)->generated) goto generate_code;
|
|
||||||
}
|
|
||||||
// No code to generate, exit:
|
|
||||||
return std::string();
|
|
||||||
|
|
||||||
generate_code:
|
|
||||||
|
|
||||||
using namespace cpp;
|
|
||||||
|
|
||||||
std::string code;
|
|
||||||
code = "// automatically generated by the FlatBuffers compiler,"
|
|
||||||
" do not modify\n\n";
|
|
||||||
|
|
||||||
// Generate include guard.
|
|
||||||
std::string include_guard_ident = file_name;
|
|
||||||
// Remove any non-alpha-numeric characters that may appear in a filename.
|
|
||||||
include_guard_ident.erase(
|
|
||||||
std::remove_if(include_guard_ident.begin(),
|
|
||||||
include_guard_ident.end(),
|
|
||||||
IsAlnum()),
|
|
||||||
include_guard_ident.end());
|
|
||||||
std::string include_guard = "FLATBUFFERS_GENERATED_" + include_guard_ident;
|
|
||||||
include_guard += "_";
|
|
||||||
// For further uniqueness, also add the namespace.
|
|
||||||
auto name_space = parser.namespaces_.back();
|
|
||||||
for (auto it = name_space->components.begin();
|
|
||||||
it != name_space->components.end(); ++it) {
|
|
||||||
include_guard += *it + "_";
|
|
||||||
}
|
|
||||||
include_guard += "H_";
|
|
||||||
std::transform(include_guard.begin(), include_guard.end(),
|
|
||||||
include_guard.begin(), ::toupper);
|
|
||||||
code += "#ifndef " + include_guard + "\n";
|
|
||||||
code += "#define " + include_guard + "\n\n";
|
|
||||||
|
|
||||||
code += "#include \"flatbuffers/flatbuffers.h\"\n\n";
|
|
||||||
|
|
||||||
if (parser.opts.include_dependence_headers) {
|
|
||||||
int num_includes = 0;
|
|
||||||
for (auto it = parser.included_files_.begin();
|
|
||||||
it != parser.included_files_.end(); ++it) {
|
|
||||||
auto basename = flatbuffers::StripPath(
|
|
||||||
flatbuffers::StripExtension(it->first));
|
|
||||||
if (basename != file_name) {
|
|
||||||
code += "#include \"" + basename + "_generated.h\"\n";
|
|
||||||
num_includes++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (num_includes) code += "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(!code_generator_cur_name_space);
|
|
||||||
|
|
||||||
// Generate forward declarations for all structs/tables, since they may
|
|
||||||
// have circular references.
|
|
||||||
for (auto it = parser.structs_.vec.begin();
|
|
||||||
it != parser.structs_.vec.end(); ++it) {
|
|
||||||
auto &struct_def = **it;
|
|
||||||
if (!struct_def.generated) {
|
|
||||||
CheckNameSpace(struct_def, &code);
|
|
||||||
code += "struct " + struct_def.name + ";\n\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate code for all the enum declarations.
|
|
||||||
for (auto it = parser.enums_.vec.begin();
|
|
||||||
it != parser.enums_.vec.end(); ++it) {
|
|
||||||
auto &enum_def = **it;
|
|
||||||
if (!enum_def.generated) {
|
|
||||||
CheckNameSpace(**it, &code);
|
|
||||||
GenEnum(parser, **it, &code);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate code for all structs, then all tables.
|
|
||||||
for (auto it = parser.structs_.vec.begin();
|
|
||||||
it != parser.structs_.vec.end(); ++it) {
|
|
||||||
auto &struct_def = **it;
|
|
||||||
if (struct_def.fixed && !struct_def.generated) {
|
|
||||||
CheckNameSpace(struct_def, &code);
|
|
||||||
GenStruct(parser, struct_def, &code);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (auto it = parser.structs_.vec.begin();
|
|
||||||
it != parser.structs_.vec.end(); ++it) {
|
|
||||||
auto &struct_def = **it;
|
|
||||||
if (!struct_def.fixed && !struct_def.generated) {
|
|
||||||
CheckNameSpace(struct_def, &code);
|
|
||||||
GenTable(parser, struct_def, &code);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate code for union verifiers.
|
|
||||||
for (auto it = parser.enums_.vec.begin();
|
|
||||||
it != parser.enums_.vec.end(); ++it) {
|
|
||||||
auto &enum_def = **it;
|
|
||||||
if (enum_def.is_union && !enum_def.generated) {
|
|
||||||
CheckNameSpace(enum_def, &code);
|
|
||||||
GenEnumPost(parser, enum_def, &code);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate convenient global helper functions:
|
|
||||||
if (parser.root_struct_def_) {
|
|
||||||
CheckNameSpace(*parser.root_struct_def_, &code);
|
|
||||||
auto &name = parser.root_struct_def_->name;
|
|
||||||
std::string qualified_name =
|
|
||||||
parser.namespaces_.back()->GetFullyQualifiedName(name);
|
|
||||||
std::string cpp_qualified_name = TranslateNameSpace(qualified_name);
|
|
||||||
|
|
||||||
// The root datatype accessor:
|
|
||||||
code += "inline const " + cpp_qualified_name + " *Get";
|
|
||||||
code += name;
|
|
||||||
code += "(const void *buf) { return flatbuffers::GetRoot<";
|
|
||||||
code += cpp_qualified_name + ">(buf); }\n\n";
|
|
||||||
if (parser.opts.mutable_buffer) {
|
|
||||||
code += "inline " + name + " *GetMutable";
|
|
||||||
code += name;
|
|
||||||
code += "(void *buf) { return flatbuffers::GetMutableRoot<";
|
|
||||||
code += name + ">(buf); }\n\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// The root verifier:
|
|
||||||
code += "inline bool Verify";
|
|
||||||
code += name;
|
|
||||||
code += "Buffer(flatbuffers::Verifier &verifier) { "
|
|
||||||
"return verifier.VerifyBuffer<";
|
|
||||||
code += cpp_qualified_name + ">(); }\n\n";
|
|
||||||
|
|
||||||
if (parser.file_identifier_.length()) {
|
|
||||||
// Return the identifier
|
|
||||||
code += "inline const char *" + name;
|
|
||||||
code += "Identifier() { return \"" + parser.file_identifier_;
|
|
||||||
code += "\"; }\n\n";
|
|
||||||
|
|
||||||
// Check if a buffer has the identifier.
|
|
||||||
code += "inline bool " + name;
|
|
||||||
code += "BufferHasIdentifier(const void *buf) { return flatbuffers::";
|
|
||||||
code += "BufferHasIdentifier(buf, ";
|
|
||||||
code += name + "Identifier()); }\n\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parser.file_extension_.length()) {
|
|
||||||
// Return the extension
|
|
||||||
code += "inline const char *" + name;
|
|
||||||
code += "Extension() { return \"" + parser.file_extension_;
|
|
||||||
code += "\"; }\n\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finish a buffer with a given root object:
|
|
||||||
code += "inline void Finish" + name;
|
|
||||||
code += "Buffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<";
|
|
||||||
code += cpp_qualified_name + "> root) { fbb.Finish(root";
|
|
||||||
if (parser.file_identifier_.length())
|
|
||||||
code += ", " + name + "Identifier()";
|
|
||||||
code += "); }\n\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(code_generator_cur_name_space);
|
|
||||||
CloseNestedNameSpaces(code_generator_cur_name_space, &code);
|
|
||||||
|
|
||||||
code_generator_cur_name_space = nullptr;
|
|
||||||
|
|
||||||
// Close the include guard.
|
|
||||||
code += "\n#endif // " + include_guard + "\n";
|
|
||||||
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string GeneratedFileName(const std::string &path,
|
static std::string GeneratedFileName(const std::string &path,
|
||||||
const std::string &file_name) {
|
const std::string &file_name) {
|
||||||
return path + file_name + "_generated.h";
|
return path + file_name + "_generated.h";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GenerateCPP(const Parser &parser,
|
namespace cpp {
|
||||||
const std::string &path,
|
class CppGenerator : public BaseGenerator {
|
||||||
|
public:
|
||||||
|
CppGenerator(const Parser &parser, const std::string &path,
|
||||||
|
const std::string &file_name)
|
||||||
|
: BaseGenerator(parser, path, file_name){};
|
||||||
|
// Iterate through all definitions we haven't generate code for (enums,
|
||||||
|
// structs,
|
||||||
|
// and tables) and output them to a single file.
|
||||||
|
bool generate() {
|
||||||
|
// Check if we have any code to generate at all, to avoid an empty header.
|
||||||
|
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
||||||
|
++it) {
|
||||||
|
if (!(*it)->generated) goto generate_code;
|
||||||
|
}
|
||||||
|
for (auto it = parser_.structs_.vec.begin(); it != parser_.structs_.vec.end();
|
||||||
|
++it) {
|
||||||
|
if (!(*it)->generated) goto generate_code;
|
||||||
|
}
|
||||||
|
// No code to generate, exit:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
generate_code:
|
||||||
|
|
||||||
|
using namespace cpp;
|
||||||
|
|
||||||
|
std::string code;
|
||||||
|
code =
|
||||||
|
"// automatically generated by the FlatBuffers compiler,"
|
||||||
|
" do not modify\n\n";
|
||||||
|
|
||||||
|
// Generate include guard.
|
||||||
|
std::string include_guard_ident = file_name_;
|
||||||
|
// Remove any non-alpha-numeric characters that may appear in a filename.
|
||||||
|
include_guard_ident.erase(
|
||||||
|
std::remove_if(include_guard_ident.begin(), include_guard_ident.end(),
|
||||||
|
IsAlnum()),
|
||||||
|
include_guard_ident.end());
|
||||||
|
std::string include_guard = "FLATBUFFERS_GENERATED_" + include_guard_ident;
|
||||||
|
include_guard += "_";
|
||||||
|
// For further uniqueness, also add the namespace.
|
||||||
|
auto name_space = parser_.namespaces_.back();
|
||||||
|
for (auto it = name_space->components.begin();
|
||||||
|
it != name_space->components.end(); ++it) {
|
||||||
|
include_guard += *it + "_";
|
||||||
|
}
|
||||||
|
include_guard += "H_";
|
||||||
|
std::transform(include_guard.begin(), include_guard.end(),
|
||||||
|
include_guard.begin(), ::toupper);
|
||||||
|
code += "#ifndef " + include_guard + "\n";
|
||||||
|
code += "#define " + include_guard + "\n\n";
|
||||||
|
|
||||||
|
code += "#include \"flatbuffers/flatbuffers.h\"\n\n";
|
||||||
|
|
||||||
|
if (parser_.opts.include_dependence_headers) {
|
||||||
|
int num_includes = 0;
|
||||||
|
for (auto it = parser_.included_files_.begin();
|
||||||
|
it != parser_.included_files_.end(); ++it) {
|
||||||
|
auto basename =
|
||||||
|
flatbuffers::StripPath(flatbuffers::StripExtension(it->first));
|
||||||
|
if (basename != file_name_) {
|
||||||
|
code += "#include \"" + basename + "_generated.h\"\n";
|
||||||
|
num_includes++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (num_includes) code += "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(!code_generator_cur_name_space);
|
||||||
|
|
||||||
|
// Generate forward declarations for all structs/tables, since they may
|
||||||
|
// have circular references.
|
||||||
|
for (auto it = parser_.structs_.vec.begin(); it != parser_.structs_.vec.end();
|
||||||
|
++it) {
|
||||||
|
auto &struct_def = **it;
|
||||||
|
if (!struct_def.generated) {
|
||||||
|
CheckNameSpace(struct_def, &code);
|
||||||
|
code += "struct " + struct_def.name + ";\n\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate code for all the enum declarations.
|
||||||
|
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
||||||
|
++it) {
|
||||||
|
auto &enum_def = **it;
|
||||||
|
if (!enum_def.generated) {
|
||||||
|
CheckNameSpace(**it, &code);
|
||||||
|
GenEnum(parser_, **it, &code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate code for all structs, then all tables.
|
||||||
|
for (auto it = parser_.structs_.vec.begin(); it != parser_.structs_.vec.end();
|
||||||
|
++it) {
|
||||||
|
auto &struct_def = **it;
|
||||||
|
if (struct_def.fixed && !struct_def.generated) {
|
||||||
|
CheckNameSpace(struct_def, &code);
|
||||||
|
GenStruct(parser_, struct_def, &code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto it = parser_.structs_.vec.begin(); it != parser_.structs_.vec.end();
|
||||||
|
++it) {
|
||||||
|
auto &struct_def = **it;
|
||||||
|
if (!struct_def.fixed && !struct_def.generated) {
|
||||||
|
CheckNameSpace(struct_def, &code);
|
||||||
|
GenTable(parser_, struct_def, &code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate code for union verifiers.
|
||||||
|
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
||||||
|
++it) {
|
||||||
|
auto &enum_def = **it;
|
||||||
|
if (enum_def.is_union && !enum_def.generated) {
|
||||||
|
CheckNameSpace(enum_def, &code);
|
||||||
|
GenEnumPost(parser_, enum_def, &code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate convenient global helper functions:
|
||||||
|
if (parser_.root_struct_def_) {
|
||||||
|
CheckNameSpace(*parser_.root_struct_def_, &code);
|
||||||
|
auto &name = parser_.root_struct_def_->name;
|
||||||
|
std::string qualified_name =
|
||||||
|
parser_.namespaces_.back()->GetFullyQualifiedName(name);
|
||||||
|
std::string cpp_qualified_name = TranslateNameSpace(qualified_name);
|
||||||
|
|
||||||
|
// The root datatype accessor:
|
||||||
|
code += "inline const " + cpp_qualified_name + " *Get";
|
||||||
|
code += name;
|
||||||
|
code += "(const void *buf) { return flatbuffers::GetRoot<";
|
||||||
|
code += cpp_qualified_name + ">(buf); }\n\n";
|
||||||
|
if (parser_.opts.mutable_buffer) {
|
||||||
|
code += "inline " + name + " *GetMutable";
|
||||||
|
code += name;
|
||||||
|
code += "(void *buf) { return flatbuffers::GetMutableRoot<";
|
||||||
|
code += name + ">(buf); }\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// The root verifier:
|
||||||
|
code += "inline bool Verify";
|
||||||
|
code += name;
|
||||||
|
code +=
|
||||||
|
"Buffer(flatbuffers::Verifier &verifier) { "
|
||||||
|
"return verifier.VerifyBuffer<";
|
||||||
|
code += cpp_qualified_name + ">(); }\n\n";
|
||||||
|
|
||||||
|
if (parser_.file_identifier_.length()) {
|
||||||
|
// Return the identifier
|
||||||
|
code += "inline const char *" + name;
|
||||||
|
code += "Identifier() { return \"" + parser_.file_identifier_;
|
||||||
|
code += "\"; }\n\n";
|
||||||
|
|
||||||
|
// Check if a buffer has the identifier.
|
||||||
|
code += "inline bool " + name;
|
||||||
|
code += "BufferHasIdentifier(const void *buf) { return flatbuffers::";
|
||||||
|
code += "BufferHasIdentifier(buf, ";
|
||||||
|
code += name + "Identifier()); }\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parser_.file_extension_.length()) {
|
||||||
|
// Return the extension
|
||||||
|
code += "inline const char *" + name;
|
||||||
|
code += "Extension() { return \"" + parser_.file_extension_;
|
||||||
|
code += "\"; }\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finish a buffer with a given root object:
|
||||||
|
code += "inline void Finish" + name;
|
||||||
|
code +=
|
||||||
|
"Buffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<";
|
||||||
|
code += cpp_qualified_name + "> root) { fbb.Finish(root";
|
||||||
|
if (parser_.file_identifier_.length())
|
||||||
|
code += ", " + name + "Identifier()";
|
||||||
|
code += "); }\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(code_generator_cur_name_space);
|
||||||
|
CloseNestedNameSpaces(code_generator_cur_name_space, &code);
|
||||||
|
|
||||||
|
code_generator_cur_name_space = nullptr;
|
||||||
|
|
||||||
|
// Close the include guard.
|
||||||
|
code += "\n#endif // " + include_guard + "\n";
|
||||||
|
|
||||||
|
return SaveFile(GeneratedFileName(path_, file_name_).c_str(), code, false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace cpp
|
||||||
|
|
||||||
|
bool GenerateCPP(const Parser &parser, const std::string &path,
|
||||||
const std::string &file_name) {
|
const std::string &file_name) {
|
||||||
auto code = GenerateCPP(parser, file_name);
|
cpp::CppGenerator generator(parser, path, file_name);
|
||||||
return !code.length() ||
|
return generator.generate();
|
||||||
SaveFile(GeneratedFileName(path, file_name).c_str(), code, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CPPMakeRule(const Parser &parser,
|
std::string CPPMakeRule(const Parser &parser,
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include "flatbuffers/flatbuffers.h"
|
#include "flatbuffers/flatbuffers.h"
|
||||||
#include "flatbuffers/idl.h"
|
#include "flatbuffers/idl.h"
|
||||||
#include "flatbuffers/util.h"
|
#include "flatbuffers/util.h"
|
||||||
|
#include "flatbuffers/code_generators.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
@@ -1148,44 +1149,56 @@ static bool SaveClass(const LanguageParameters &lang, const Parser &parser,
|
|||||||
return SaveFile(filename.c_str(), code, false);
|
return SaveFile(filename.c_str(), code, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GenerateGeneral(const Parser &parser,
|
namespace general {
|
||||||
const std::string &path,
|
class GeneralGenerator : public BaseGenerator {
|
||||||
const std::string & file_name) {
|
public:
|
||||||
|
GeneralGenerator(const Parser &parser, const std::string &path,
|
||||||
|
const std::string &file_name)
|
||||||
|
: BaseGenerator(parser, path, file_name){};
|
||||||
|
bool generate() {
|
||||||
|
assert(parser_.opts.lang <= IDLOptions::kMAX);
|
||||||
|
auto lang = language_parameters[parser_.opts.lang];
|
||||||
|
std::string one_file_code;
|
||||||
|
|
||||||
assert(parser.opts.lang <= IDLOptions::kMAX);
|
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
||||||
auto lang = language_parameters[parser.opts.lang];
|
++it) {
|
||||||
std::string one_file_code;
|
std::string enumcode;
|
||||||
|
GenEnum(lang, parser_, **it, &enumcode);
|
||||||
|
if (parser_.opts.one_file) {
|
||||||
|
one_file_code += enumcode;
|
||||||
|
} else {
|
||||||
|
if (!SaveClass(lang, parser_, (**it).name, enumcode, path_, false,
|
||||||
|
false))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (auto it = parser.enums_.vec.begin();
|
for (auto it = parser_.structs_.vec.begin();
|
||||||
it != parser.enums_.vec.end(); ++it) {
|
it != parser_.structs_.vec.end(); ++it) {
|
||||||
std::string enumcode;
|
std::string declcode;
|
||||||
GenEnum(lang, parser, **it, &enumcode);
|
GenStruct(lang, parser_, **it, &declcode);
|
||||||
if (parser.opts.one_file) {
|
if (parser_.opts.one_file) {
|
||||||
one_file_code += enumcode;
|
one_file_code += declcode;
|
||||||
|
} else {
|
||||||
|
if (!SaveClass(lang, parser_, (**it).name, declcode, path_, true,
|
||||||
|
false))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
if (!SaveClass(lang, parser, (**it).name, enumcode, path, false, false))
|
if (parser_.opts.one_file) {
|
||||||
return false;
|
return SaveClass(lang, parser_, file_name_, one_file_code, path_, true,
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
} // namespace general
|
||||||
|
|
||||||
for (auto it = parser.structs_.vec.begin();
|
bool GenerateGeneral(const Parser &parser, const std::string &path,
|
||||||
it != parser.structs_.vec.end(); ++it) {
|
const std::string &file_name) {
|
||||||
std::string declcode;
|
general::GeneralGenerator generator(parser, path, file_name);
|
||||||
GenStruct(lang, parser, **it, &declcode);
|
return generator.generate();
|
||||||
if (parser.opts.one_file) {
|
|
||||||
one_file_code += declcode;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (!SaveClass(lang, parser, (**it).name, declcode, path, true, false))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parser.opts.one_file) {
|
|
||||||
return SaveClass(lang, parser, file_name, one_file_code,path, true, true);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string ClassFileName(const LanguageParameters &lang,
|
static std::string ClassFileName(const LanguageParameters &lang,
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "flatbuffers/flatbuffers.h"
|
#include "flatbuffers/flatbuffers.h"
|
||||||
#include "flatbuffers/idl.h"
|
#include "flatbuffers/idl.h"
|
||||||
#include "flatbuffers/util.h"
|
#include "flatbuffers/util.h"
|
||||||
|
#include "flatbuffers/code_generators.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
@@ -660,28 +661,35 @@ static void GenStructBuilder(const StructDef &struct_def,
|
|||||||
EndBuilderBody(code_ptr);
|
EndBuilderBody(code_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class GoGenerator : public BaseGenerator {
|
||||||
|
public:
|
||||||
|
GoGenerator(const Parser &parser, const std::string &path,
|
||||||
|
const std::string &file_name)
|
||||||
|
: BaseGenerator(parser, path, file_name){};
|
||||||
|
bool generate() {
|
||||||
|
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
||||||
|
++it) {
|
||||||
|
std::string enumcode;
|
||||||
|
go::GenEnum(**it, &enumcode);
|
||||||
|
if (!go::SaveType(parser_, **it, enumcode, path_, false)) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto it = parser_.structs_.vec.begin();
|
||||||
|
it != parser_.structs_.vec.end(); ++it) {
|
||||||
|
std::string declcode;
|
||||||
|
go::GenStruct(**it, &declcode, parser_.root_struct_def_);
|
||||||
|
if (!go::SaveType(parser_, **it, declcode, path_, true)) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
} // namespace go
|
} // namespace go
|
||||||
|
|
||||||
bool GenerateGo(const Parser &parser,
|
bool GenerateGo(const Parser &parser, const std::string &path,
|
||||||
const std::string &path,
|
const std::string &file_name) {
|
||||||
const std::string & /*file_name*/) {
|
go::GoGenerator generator(parser, path, file_name);
|
||||||
for (auto it = parser.enums_.vec.begin();
|
return generator.generate();
|
||||||
it != parser.enums_.vec.end(); ++it) {
|
|
||||||
std::string enumcode;
|
|
||||||
go::GenEnum(**it, &enumcode);
|
|
||||||
if (!go::SaveType(parser, **it, enumcode, path, false))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto it = parser.structs_.vec.begin();
|
|
||||||
it != parser.structs_.vec.end(); ++it) {
|
|
||||||
std::string declcode;
|
|
||||||
go::GenStruct(**it, &declcode, parser.root_struct_def_);
|
|
||||||
if (!go::SaveType(parser, **it, declcode, path, true))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace flatbuffers
|
} // namespace flatbuffers
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include "flatbuffers/flatbuffers.h"
|
#include "flatbuffers/flatbuffers.h"
|
||||||
#include "flatbuffers/idl.h"
|
#include "flatbuffers/idl.h"
|
||||||
#include "flatbuffers/util.h"
|
#include "flatbuffers/util.h"
|
||||||
|
#include "flatbuffers/code_generators.h"
|
||||||
|
|
||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
namespace js {
|
namespace js {
|
||||||
@@ -661,60 +662,76 @@ static void GenStruct(const Parser &parser, StructDef &struct_def,
|
|||||||
|
|
||||||
} // namespace js
|
} // namespace js
|
||||||
|
|
||||||
// Iterate through all definitions we haven't generate code for (enums, structs,
|
|
||||||
// and tables) and output them to a single file.
|
|
||||||
std::string GenerateJS(const Parser &parser) {
|
|
||||||
using namespace js;
|
|
||||||
|
|
||||||
// Generate code for all the enum declarations.
|
|
||||||
std::string enum_code, exports_code;
|
|
||||||
for (auto it = parser.enums_.vec.begin();
|
|
||||||
it != parser.enums_.vec.end(); ++it) {
|
|
||||||
GenEnum(**it, &enum_code, &exports_code);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate code for all structs, then all tables.
|
|
||||||
std::string decl_code;
|
|
||||||
for (auto it = parser.structs_.vec.begin();
|
|
||||||
it != parser.structs_.vec.end(); ++it) {
|
|
||||||
GenStruct(parser, **it, &decl_code, &exports_code);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only output file-level code if there were any declarations.
|
|
||||||
if (enum_code.length() || decl_code.length()) {
|
|
||||||
std::string code;
|
|
||||||
code = "// automatically generated by the FlatBuffers compiler,"
|
|
||||||
" do not modify\n\n";
|
|
||||||
|
|
||||||
// Generate code for all the namespace declarations.
|
|
||||||
GenNamespaces(parser, &code, &exports_code);
|
|
||||||
|
|
||||||
// Output the main declaration code from above.
|
|
||||||
code += enum_code;
|
|
||||||
code += decl_code;
|
|
||||||
|
|
||||||
if (!exports_code.empty() && !parser.opts.skip_js_exports) {
|
|
||||||
code += "// Exports for Node.js and RequireJS\n";
|
|
||||||
code += exports_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string GeneratedFileName(const std::string &path,
|
static std::string GeneratedFileName(const std::string &path,
|
||||||
const std::string &file_name) {
|
const std::string &file_name) {
|
||||||
return path + file_name + "_generated.js";
|
return path + file_name + "_generated.js";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GenerateJS(const Parser &parser,
|
namespace js {
|
||||||
const std::string &path,
|
// Iterate through all definitions we haven't generate code for (enums, structs,
|
||||||
const std::string &file_name) {
|
// and tables) and output them to a single file.
|
||||||
auto code = GenerateJS(parser);
|
class JsGenerator : public BaseGenerator {
|
||||||
|
public:
|
||||||
|
JsGenerator(const Parser &parser, const std::string &path,
|
||||||
|
const std::string &file_name)
|
||||||
|
: BaseGenerator(parser, path, file_name){};
|
||||||
|
// Iterate through all definitions we haven't generate code for (enums,
|
||||||
|
// structs, and tables) and output them to a single file.
|
||||||
|
bool generate() {
|
||||||
|
std::string enum_code, struct_code, exports_code, code;
|
||||||
|
generateEnums(&enum_code, &exports_code);
|
||||||
|
generateStructs(&struct_code, &exports_code);
|
||||||
|
|
||||||
|
// Only output file-level code if there were any declarations.
|
||||||
|
if (enum_code.length() || struct_code.length()) {
|
||||||
|
code +=
|
||||||
|
"// automatically generated by the FlatBuffers compiler, do not "
|
||||||
|
"modify\n\n";
|
||||||
|
|
||||||
|
// Generate code for all the namespace declarations.
|
||||||
|
GenNamespaces(parser_, &code, &exports_code);
|
||||||
|
|
||||||
|
// Output the main declaration code from above.
|
||||||
|
code += enum_code;
|
||||||
|
code += struct_code;
|
||||||
|
|
||||||
|
if (!exports_code.empty() && !parser_.opts.skip_js_exports) {
|
||||||
|
code += "// Exports for Node.js and RequireJS\n";
|
||||||
|
code += exports_code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return !code.length() ||
|
return !code.length() ||
|
||||||
SaveFile(GeneratedFileName(path, file_name).c_str(), code, false);
|
SaveFile(GeneratedFileName(path_, file_name_).c_str(), code, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Generate code for all enums.
|
||||||
|
void generateEnums(std::string *enum_code_ptr,
|
||||||
|
std::string *exports_code_ptr) {
|
||||||
|
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
||||||
|
++it) {
|
||||||
|
auto &enum_def = **it;
|
||||||
|
GenEnum(enum_def, enum_code_ptr, exports_code_ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate code for all structs.
|
||||||
|
void generateStructs(std::string *decl_code_ptr,
|
||||||
|
std::string *exports_code_ptr) {
|
||||||
|
for (auto it = parser_.structs_.vec.begin();
|
||||||
|
it != parser_.structs_.vec.end(); ++it) {
|
||||||
|
auto &struct_def = **it;
|
||||||
|
GenStruct(parser_, struct_def, decl_code_ptr, exports_code_ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace js
|
||||||
|
|
||||||
|
bool GenerateJS(const Parser &parser, const std::string &path,
|
||||||
|
const std::string &file_name) {
|
||||||
|
js::JsGenerator generator(parser, path, file_name);
|
||||||
|
return generator.generate();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string JSMakeRule(const Parser &parser,
|
std::string JSMakeRule(const Parser &parser,
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "flatbuffers/flatbuffers.h"
|
#include "flatbuffers/flatbuffers.h"
|
||||||
#include "flatbuffers/idl.h"
|
#include "flatbuffers/idl.h"
|
||||||
#include "flatbuffers/util.h"
|
#include "flatbuffers/util.h"
|
||||||
|
#include "flatbuffers/code_generators.h"
|
||||||
|
|
||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
namespace php {
|
namespace php {
|
||||||
@@ -974,29 +975,47 @@ namespace php {
|
|||||||
code += Indent + "}\n";
|
code += Indent + "}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace php
|
class PhpGenerator : public BaseGenerator {
|
||||||
|
public:
|
||||||
|
PhpGenerator(const Parser &parser, const std::string &path,
|
||||||
|
const std::string &file_name)
|
||||||
|
: BaseGenerator(parser, path, file_name){};
|
||||||
|
bool generate() {
|
||||||
|
if (!generateEnums()) return false;
|
||||||
|
if (!generateStructs()) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool GeneratePhp(const Parser &parser,
|
private:
|
||||||
const std::string &path,
|
bool generateEnums() {
|
||||||
const std::string & /*file_name*/) {
|
for (auto it = parser_.enums_.vec.begin();
|
||||||
for (auto it = parser.enums_.vec.begin();
|
it != parser_.enums_.vec.end(); ++it) {
|
||||||
it != parser.enums_.vec.end(); ++it) {
|
auto &enum_def = **it;
|
||||||
std::string enumcode;
|
std::string enumcode;
|
||||||
php::GenEnum(**it, &enumcode);
|
GenEnum(enum_def, &enumcode);
|
||||||
|
if (!SaveType(parser_, enum_def, enumcode, path_, false))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!php::SaveType(parser, **it, enumcode, path, false))
|
bool generateStructs() {
|
||||||
return false;
|
for (auto it = parser_.structs_.vec.begin();
|
||||||
|
it != parser_.structs_.vec.end(); ++it) {
|
||||||
|
auto &struct_def = **it;
|
||||||
|
std::string declcode;
|
||||||
|
GenStruct(parser_, struct_def, &declcode);
|
||||||
|
if (!SaveType(parser_, struct_def, declcode, path_, true))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace php
|
||||||
|
|
||||||
|
bool GeneratePhp(const Parser &parser, const std::string &path,
|
||||||
|
const std::string &file_name) {
|
||||||
|
php::PhpGenerator generator(parser, path, file_name);
|
||||||
|
return generator.generate();
|
||||||
}
|
}
|
||||||
|
} // namespace flatbuffers
|
||||||
for (auto it = parser.structs_.vec.begin();
|
|
||||||
it != parser.structs_.vec.end(); ++it) {
|
|
||||||
std::string declcode;
|
|
||||||
php::GenStruct(parser, **it, &declcode);
|
|
||||||
|
|
||||||
if (!php::SaveType(parser, **it, declcode, path, true))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} // namespace flatbuffers
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "flatbuffers/flatbuffers.h"
|
#include "flatbuffers/flatbuffers.h"
|
||||||
#include "flatbuffers/idl.h"
|
#include "flatbuffers/idl.h"
|
||||||
#include "flatbuffers/util.h"
|
#include "flatbuffers/util.h"
|
||||||
|
#include "flatbuffers/code_generators.h"
|
||||||
|
|
||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
namespace python {
|
namespace python {
|
||||||
@@ -634,28 +635,47 @@ static void GenStructBuilder(const StructDef &struct_def,
|
|||||||
EndBuilderBody(code_ptr);
|
EndBuilderBody(code_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PythonGenerator : public BaseGenerator {
|
||||||
|
public:
|
||||||
|
PythonGenerator(const Parser &parser, const std::string &path,
|
||||||
|
const std::string &file_name)
|
||||||
|
: BaseGenerator(parser, path, file_name){};
|
||||||
|
bool generate() {
|
||||||
|
if (!generateEnums()) return false;
|
||||||
|
if (!generateStructs()) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool generateEnums() {
|
||||||
|
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
||||||
|
++it) {
|
||||||
|
auto &enum_def = **it;
|
||||||
|
std::string enumcode;
|
||||||
|
GenEnum(enum_def, &enumcode);
|
||||||
|
if (!SaveType(parser_, enum_def, enumcode, path_, false)) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool generateStructs() {
|
||||||
|
for (auto it = parser_.structs_.vec.begin();
|
||||||
|
it != parser_.structs_.vec.end(); ++it) {
|
||||||
|
auto &struct_def = **it;
|
||||||
|
std::string declcode;
|
||||||
|
GenStruct(struct_def, &declcode, parser_.root_struct_def_);
|
||||||
|
if (!SaveType(parser_, struct_def, declcode, path_, true)) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace python
|
} // namespace python
|
||||||
|
|
||||||
bool GeneratePython(const Parser &parser,
|
bool GeneratePython(const Parser &parser, const std::string &path,
|
||||||
const std::string &path,
|
const std::string &file_name) {
|
||||||
const std::string & /*file_name*/) {
|
python::PythonGenerator generator(parser, path, file_name);
|
||||||
for (auto it = parser.enums_.vec.begin();
|
return generator.generate();
|
||||||
it != parser.enums_.vec.end(); ++it) {
|
|
||||||
std::string enumcode;
|
|
||||||
python::GenEnum(**it, &enumcode);
|
|
||||||
if (!python::SaveType(parser, **it, enumcode, path, false))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto it = parser.structs_.vec.begin();
|
|
||||||
it != parser.structs_.vec.end(); ++it) {
|
|
||||||
std::string declcode;
|
|
||||||
python::GenStruct(**it, &declcode, parser.root_struct_def_);
|
|
||||||
if (!python::SaveType(parser, **it, declcode, path, true))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace flatbuffers
|
} // namespace flatbuffers
|
||||||
|
|||||||
Reference in New Issue
Block a user