Commit 8a64afab authored by Lakedaemon's avatar Lakedaemon

Transition 1 (with nice diffs) Go, Cpp and General code generators with class

parent 9f2b05df
......@@ -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
......
/*
* 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_
......@@ -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,
......
......@@ -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,
......
......@@ -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
......
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