diff --git a/CMakeLists.txt b/CMakeLists.txt index 8449ffb610b862194b32a5d82a68548c3b486445..47a66e6cccd6c6650fc2826a5320e2c8fe61eb54 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,7 @@ if(NOT FLATBUFFERS_BUILD_FLATC AND FLATBUFFERS_BUILD_TESTS) endif() set(FlatBuffers_Library_SRCS + include/flatbuffers/code_generators.h include/flatbuffers/flatbuffers.h include/flatbuffers/hash.h include/flatbuffers/idl.h diff --git a/include/flatbuffers/code_generators.h b/include/flatbuffers/code_generators.h new file mode 100644 index 0000000000000000000000000000000000000000..666e1aa8c7586f7164c410331427c4b969e7d681 --- /dev/null +++ b/include/flatbuffers/code_generators.h @@ -0,0 +1,64 @@ +/* + * 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_ + +/** This file defines some classes, that code generators should extend to gain + common functionalities : + + BaseGenerator is the base class for all (binary, textual, strongly typed, + dynamically typed, whatever) generators. + It is really abstract, general and flexible and doesn't do much appart from + holding the parser, a path and a filename being processed. + Still, it brings a common structure (normalization) among generators + + The many advantages of object based generators will come later from : + + A) the CodeWriter class (semi-automatic indentation (python), semi-automatic + (C++) namespace scopes, export to different files (classic, top level + methods), + simpler code to generate string from things (comments (vector of strings), + indentation commands (TAB BAT), newlines (NL), numbers, const char* or + std::string) + + B) the Generator subclass (heritance for supporting different versions of a + language, avoid field name clash, write text/binary to file, types + management, + common computations and sctructures : enum analysis (function, array, map, + ordered list + binarysearch),...) + +*/ +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_ diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp index e043b01468c90df1860c2cdf28fdbf112af50169..7ea09c2814bbb4a0e492494cc0535db972183e2c 100644 --- a/src/idl_gen_cpp.cpp +++ b/src/idl_gen_cpp.cpp @@ -19,6 +19,7 @@ #include "flatbuffers/flatbuffers.h" #include "flatbuffers/idl.h" #include "flatbuffers/util.h" +#include "flatbuffers/code_generators.h" namespace flatbuffers { namespace cpp { @@ -708,10 +709,20 @@ 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) { +static std::string GeneratedFileName(const std::string &path, + const std::string &file_name) { + return path + file_name + "_generated.h"; +} + +namespace cpp { +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) { @@ -722,7 +733,7 @@ std::string GenerateCPP(const Parser &parser, if (!(*it)->generated) goto generate_code; } // No code to generate, exit: - return std::string(); + return true; generate_code: @@ -885,20 +896,17 @@ std::string GenerateCPP(const Parser &parser, // Close the include guard. code += "\n#endif // " + include_guard + "\n"; - return code; -} + return SaveFile(GeneratedFileName(path, file_name).c_str(), code, false); + } +}; +} // namespace cpp -static std::string GeneratedFileName(const std::string &path, - const std::string &file_name) { - return path + file_name + "_generated.h"; -} bool GenerateCPP(const Parser &parser, const std::string &path, const std::string &file_name) { - auto code = GenerateCPP(parser, file_name); - return !code.length() || - SaveFile(GeneratedFileName(path, file_name).c_str(), code, false); + cpp::CppGenerator *generator = new cpp::CppGenerator(parser, path, file_name); + return generator->generate(); } std::string CPPMakeRule(const Parser &parser, diff --git a/src/idl_gen_general.cpp b/src/idl_gen_general.cpp index e663ddb52468a4f999cba453cec59bf6d02ed296..09913c4c3d4903a2160dc4132284246e8c7ee779 100644 --- a/src/idl_gen_general.cpp +++ b/src/idl_gen_general.cpp @@ -19,6 +19,7 @@ #include "flatbuffers/flatbuffers.h" #include "flatbuffers/idl.h" #include "flatbuffers/util.h" +#include "flatbuffers/code_generators.h" #include <algorithm> namespace flatbuffers { @@ -1146,11 +1147,18 @@ static bool SaveClass(const LanguageParameters &lang, const Parser &parser, return SaveFile(filename.c_str(), code, false); } -bool GenerateGeneral(const Parser &parser, - const std::string &path, - const std::string & file_name) { - - assert(parser.opts.lang <= IDLOptions::kMAX); +/** it'll be split later in java/csharp... and moved to separate files */ +namespace general { +/** members methods signature will be simpler as they won't have to pass parser, + * filename & path */ +/** more features coming through the JavaGenerator, CSharpGenerator ...*/ +class GeneralGenerator : public BaseGenerator { +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; @@ -1184,6 +1192,16 @@ bool GenerateGeneral(const Parser &parser, return SaveClass(lang, parser, file_name, one_file_code,path, true, true); } return true; + } +}; +} // namespace general + +bool GenerateGeneral(const Parser &parser, + const std::string &path, + const std::string & file_name) { + general::GeneralGenerator *generator = + new general::GeneralGenerator(parser, path, file_name); + return generator->generate(); } static std::string ClassFileName(const LanguageParameters &lang, diff --git a/src/idl_gen_go.cpp b/src/idl_gen_go.cpp index 88ce1f2a58ce99fefa92c2ac2b6fe337684c523c..473e0fe600a277f9b577d7166ec0836bd0f186f4 100644 --- a/src/idl_gen_go.cpp +++ b/src/idl_gen_go.cpp @@ -21,6 +21,7 @@ #include "flatbuffers/flatbuffers.h" #include "flatbuffers/idl.h" #include "flatbuffers/util.h" +#include "flatbuffers/code_generators.h" #ifdef _WIN32 #include <direct.h> @@ -660,11 +661,12 @@ static void GenStructBuilder(const StructDef &struct_def, EndBuilderBody(code_ptr); } -} // namespace go - -bool GenerateGo(const Parser &parser, - const std::string &path, - const std::string & /*file_name*/) { +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; @@ -682,6 +684,15 @@ bool GenerateGo(const Parser &parser, } return true; + } +}; +} // namespace go + +bool GenerateGo(const Parser &parser, + const std::string &path, + const std::string & file_name) { + go::GoGenerator *generator = new go::GoGenerator(parser, path, file_name); + return generator->generate(); } } // namespace flatbuffers