From 45bda6e08de1436e8a25e791b776e0bcc38f232b Mon Sep 17 00:00:00 2001 From: Wouter van Oortmerssen <wvo@google.com> Date: Mon, 30 Nov 2015 17:42:19 -0800 Subject: [PATCH] Added --gen-all to generate code for a schema and all its includes. Also refactored the way options are stored. Change-Id: I709ac908cd2aba396c9c282725cf1d42ccce0882 Tested: on Linux. --- docs/html/md__compiler.html | 1 + docs/source/Compiler.md | 5 ++ include/flatbuffers/idl.h | 131 ++++++++++++++++-------------------- samples/sample_text.cpp | 3 +- src/flatc.cpp | 50 +++++++------- src/idl_gen_cpp.cpp | 53 +++++++-------- src/idl_gen_fbs.cpp | 10 ++- src/idl_gen_general.cpp | 111 +++++++++++++++--------------- src/idl_gen_go.cpp | 3 +- src/idl_gen_js.cpp | 13 ++-- src/idl_gen_php.cpp | 35 +++++----- src/idl_gen_python.cpp | 3 +- src/idl_gen_text.cpp | 35 +++++----- src/idl_parser.cpp | 28 ++++---- tests/test.cpp | 27 ++++---- 15 files changed, 240 insertions(+), 268 deletions(-) diff --git a/docs/html/md__compiler.html b/docs/html/md__compiler.html index 1b3cd1db..d82b5b47 100644 --- a/docs/html/md__compiler.html +++ b/docs/html/md__compiler.html @@ -94,6 +94,7 @@ $(document).ready(function(){initNavTree('md__compiler.html','');}); <li><code>--no-includes</code> : Don't generate include statements for included schemas the generated file depends on (C++).</li> <li><code>--gen-mutable</code> : Generate additional non-const accessors for mutating FlatBuffers in-place.</li> <li><code>--gen-onefile</code> : Generate single output file (useful for C#)</li> +<li><code>--gen-all</code>: Generate not just code for the current schema files, but for all files it includes as well. If the language uses a single file for output (by default the case for C++ and JS), all code will end up in this one file.</li> <li><code>--raw-binary</code> : Allow binaries without a file_indentifier to be read. This may crash flatc given a mismatched schema.</li> <li><code>--proto</code>: Expect input files to be .proto files (protocol buffers). Output the corresponding .fbs file. Currently supports: <code>package</code>, <code>message</code>, <code>enum</code>, nested declarations, <code>import</code> (use <code>-I</code> for paths), <code>extend</code>, <code>oneof</code>, <code>group</code>. Does not support, but will skip without error: <code>option</code>, <code>service</code>, <code>extensions</code>, and most everything else.</li> <li><code>--schema</code>: Serialize schemas instead of JSON (use with -b). This will output a binary version of the specified schema that itself corresponds to the reflection/reflection.fbs schema. Loading this binary file is the basis for reflection functionality.</li> diff --git a/docs/source/Compiler.md b/docs/source/Compiler.md index 9d89cb10..6c93fb4b 100755 --- a/docs/source/Compiler.md +++ b/docs/source/Compiler.md @@ -80,6 +80,11 @@ Additional options: - `--gen-onefile` : Generate single output file (useful for C#) +- `--gen-all`: Generate not just code for the current schema files, but + for all files it includes as well. If the language uses a single file for + output (by default the case for C++ and JS), all code will end up in + this one file. + - `--raw-binary` : Allow binaries without a file_indentifier to be read. This may crash flatc given a mismatched schema. diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h index f1276f01..1ed360be 100644 --- a/include/flatbuffers/idl.h +++ b/include/flatbuffers/idl.h @@ -306,15 +306,48 @@ struct EnumDef : public Definition { Type underlying_type; }; +// Container of options that may apply to any of the source/text generators. +struct IDLOptions { + bool strict_json; + bool skip_js_exports; + bool output_default_scalars_in_json; + int indent_step; + bool output_enum_identifiers; + bool prefixed_enums; + bool scoped_enums; + bool include_dependence_headers; + bool mutable_buffer; + bool one_file; + bool proto_mode; + bool generate_all; + + // Possible options for the more general generator below. + enum Language { kJava, kCSharp, kGo, kMAX }; + + Language lang; + + IDLOptions() + : strict_json(false), + skip_js_exports(false), + output_default_scalars_in_json(false), + indent_step(2), + output_enum_identifiers(true), prefixed_enums(true), scoped_enums(false), + include_dependence_headers(true), + mutable_buffer(false), + one_file(false), + proto_mode(false), + generate_all(false), + lang(IDLOptions::kJava) {} +}; + class Parser { public: - Parser(bool strict_json = false, bool proto_mode = false) + explicit Parser(const IDLOptions &options = IDLOptions()) : root_struct_def_(nullptr), + opts(options), source_(nullptr), cursor_(nullptr), line_(1), - proto_mode_(proto_mode), - strict_json_(strict_json), anonymous_counter(0) { // Just in case none are declared: namespaces_.push_back(new Namespace()); @@ -415,13 +448,14 @@ class Parser { std::map<std::string, bool> included_files_; std::map<std::string, std::set<std::string>> files_included_per_file_; + IDLOptions opts; + private: const char *source_, *cursor_; int line_; // the current line being parsed int token_; std::string files_being_parsed_; - bool proto_mode_; - bool strict_json_; + std::string attribute_; std::vector<std::string> doc_comment_; @@ -443,35 +477,6 @@ extern void GenComment(const std::vector<std::string> &dc, const CommentConfig *config, const char *prefix = ""); -// Container of options that may apply to any of the source/text generators. -struct GeneratorOptions { - bool strict_json; - bool skip_js_exports; - bool output_default_scalars_in_json; - int indent_step; - bool output_enum_identifiers; - bool prefixed_enums; - bool scoped_enums; - bool include_dependence_headers; - bool mutable_buffer; - bool one_file; - - // Possible options for the more general generator below. - enum Language { kJava, kCSharp, kGo, kMAX }; - - Language lang; - - GeneratorOptions() : strict_json(false), - skip_js_exports(false), - output_default_scalars_in_json(false), - indent_step(2), - output_enum_identifiers(true), prefixed_enums(true), scoped_enums(false), - include_dependence_headers(true), - mutable_buffer(false), - one_file(false), - lang(GeneratorOptions::kJava) {} -}; - // Generate text (JSON) from a given FlatBuffer, and a given Parser // object that has been populated with the corresponding schema. // If ident_step is 0, no indentation will be generated. Additionally, @@ -480,126 +485,106 @@ struct GeneratorOptions { // strict_json adds "quotes" around field names if true. extern void GenerateText(const Parser &parser, const void *flatbuffer, - const GeneratorOptions &opts, std::string *text); extern bool GenerateTextFile(const Parser &parser, const std::string &path, - const std::string &file_name, - const GeneratorOptions &opts); + const std::string &file_name); // Generate binary files from a given FlatBuffer, and a given Parser // object that has been populated with the corresponding schema. // See idl_gen_general.cpp. extern bool GenerateBinary(const Parser &parser, const std::string &path, - const std::string &file_name, - const GeneratorOptions &opts); + const std::string &file_name); // Generate a C++ header from the definitions in the Parser object. // See idl_gen_cpp. extern std::string GenerateCPP(const Parser &parser, - const std::string &include_guard_ident, - const GeneratorOptions &opts); + const std::string &include_guard_ident); extern bool GenerateCPP(const Parser &parser, const std::string &path, - const std::string &file_name, - const GeneratorOptions &opts); + const std::string &file_name); // Generate JavaScript code from the definitions in the Parser object. // See idl_gen_js. -extern std::string GenerateJS(const Parser &parser, - const GeneratorOptions &opts); +extern std::string GenerateJS(const Parser &parser); extern bool GenerateJS(const Parser &parser, const std::string &path, - const std::string &file_name, - const GeneratorOptions &opts); + const std::string &file_name); // Generate Go files from the definitions in the Parser object. // See idl_gen_go.cpp. extern bool GenerateGo(const Parser &parser, const std::string &path, - const std::string &file_name, - const GeneratorOptions &opts); + const std::string &file_name); // Generate Java files from the definitions in the Parser object. // See idl_gen_java.cpp. extern bool GenerateJava(const Parser &parser, const std::string &path, - const std::string &file_name, - const GeneratorOptions &opts); + const std::string &file_name); // Generate Php code from the definitions in the Parser object. // See idl_gen_php. extern bool GeneratePhp(const Parser &parser, const std::string &path, - const std::string &file_name, - const GeneratorOptions &opts); + const std::string &file_name); // Generate Python files from the definitions in the Parser object. // See idl_gen_python.cpp. extern bool GeneratePython(const Parser &parser, const std::string &path, - const std::string &file_name, - const GeneratorOptions &opts); + const std::string &file_name); // Generate C# files from the definitions in the Parser object. // See idl_gen_csharp.cpp. extern bool GenerateCSharp(const Parser &parser, const std::string &path, - const std::string &file_name, - const GeneratorOptions &opts); + const std::string &file_name); // Generate Java/C#/.. files from the definitions in the Parser object. // See idl_gen_general.cpp. extern bool GenerateGeneral(const Parser &parser, const std::string &path, - const std::string &file_name, - const GeneratorOptions &opts); + const std::string &file_name); // Generate a schema file from the internal representation, useful after // parsing a .proto schema. extern std::string GenerateFBS(const Parser &parser, - const std::string &file_name, - const GeneratorOptions &opts); + const std::string &file_name); extern bool GenerateFBS(const Parser &parser, const std::string &path, - const std::string &file_name, - const GeneratorOptions &opts); + const std::string &file_name); // Generate a make rule for the generated JavaScript code. // See idl_gen_js.cpp. extern std::string JSMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name, - const GeneratorOptions &opts); + const std::string &file_name); // Generate a make rule for the generated C++ header. // See idl_gen_cpp.cpp. extern std::string CPPMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name, - const GeneratorOptions &opts); + const std::string &file_name); // Generate a make rule for the generated Java/C#/... files. // See idl_gen_general.cpp. extern std::string GeneralMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name, - const GeneratorOptions &opts); + const std::string &file_name); // Generate a make rule for the generated text (JSON) files. // See idl_gen_text.cpp. extern std::string TextMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name, - const GeneratorOptions &opts); + const std::string &file_names); // Generate a make rule for the generated binary files. // See idl_gen_general.cpp. extern std::string BinaryMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name, - const GeneratorOptions &opts); + const std::string &file_name); } // namespace flatbuffers diff --git a/samples/sample_text.cpp b/samples/sample_text.cpp index 88d761cb..e1a3bf7e 100644 --- a/samples/sample_text.cpp +++ b/samples/sample_text.cpp @@ -47,8 +47,7 @@ int main(int /*argc*/, const char * /*argv*/[]) { // to ensure it is correct, we now generate text back from the binary, // and compare the two: std::string jsongen; - GenerateText(parser, parser.builder_.GetBufferPointer(), - flatbuffers::GeneratorOptions(), &jsongen); + GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen); if (jsongen != jsonfile) { printf("%s----------------\n%s", jsongen.c_str(), jsonfile.c_str()); diff --git a/src/flatc.cpp b/src/flatc.cpp index a27af795..a51e488d 100644 --- a/src/flatc.cpp +++ b/src/flatc.cpp @@ -26,55 +26,53 @@ static void Error(const std::string &err, bool usage = false, struct Generator { bool (*generate)(const flatbuffers::Parser &parser, const std::string &path, - const std::string &file_name, - const flatbuffers::GeneratorOptions &opts); + const std::string &file_name); const char *generator_opt_short; const char *generator_opt_long; const char *lang_name; - flatbuffers::GeneratorOptions::Language lang; + flatbuffers::IDLOptions::Language lang; const char *generator_help; std::string (*make_rule)(const flatbuffers::Parser &parser, const std::string &path, - const std::string &file_name, - const flatbuffers::GeneratorOptions &opts); + const std::string &file_name); }; const Generator generators[] = { { flatbuffers::GenerateBinary, "-b", "--binary", "binary", - flatbuffers::GeneratorOptions::kMAX, + flatbuffers::IDLOptions::kMAX, "Generate wire format binaries for any data definitions", flatbuffers::BinaryMakeRule }, { flatbuffers::GenerateTextFile, "-t", "--json", "text", - flatbuffers::GeneratorOptions::kMAX, + flatbuffers::IDLOptions::kMAX, "Generate text output for any data definitions", flatbuffers::TextMakeRule }, { flatbuffers::GenerateCPP, "-c", "--cpp", "C++", - flatbuffers::GeneratorOptions::kMAX, + flatbuffers::IDLOptions::kMAX, "Generate C++ headers for tables/structs", flatbuffers::CPPMakeRule }, { flatbuffers::GenerateGo, "-g", "--go", "Go", - flatbuffers::GeneratorOptions::kGo, + flatbuffers::IDLOptions::kGo, "Generate Go files for tables/structs", flatbuffers::GeneralMakeRule }, { flatbuffers::GenerateGeneral, "-j", "--java", "Java", - flatbuffers::GeneratorOptions::kJava, + flatbuffers::IDLOptions::kJava, "Generate Java classes for tables/structs", flatbuffers::GeneralMakeRule }, { flatbuffers::GenerateJS, "-s", "--js", "JavaScript", - flatbuffers::GeneratorOptions::kMAX, + flatbuffers::IDLOptions::kMAX, "Generate JavaScript code for tables/structs", flatbuffers::JSMakeRule }, { flatbuffers::GenerateGeneral, "-n", "--csharp", "C#", - flatbuffers::GeneratorOptions::kCSharp, + flatbuffers::IDLOptions::kCSharp, "Generate C# classes for tables/structs", flatbuffers::GeneralMakeRule }, { flatbuffers::GeneratePython, "-p", "--python", "Python", - flatbuffers::GeneratorOptions::kMAX, + flatbuffers::IDLOptions::kMAX, "Generate Python files for tables/structs", flatbuffers::GeneralMakeRule }, { flatbuffers::GeneratePhp, nullptr, "--php", "PHP", - flatbuffers::GeneratorOptions::kMAX, + flatbuffers::IDLOptions::kMAX, "Generate PHP files for tables/structs", flatbuffers::GeneralMakeRule }, }; @@ -129,13 +127,12 @@ static void Error(const std::string &err, bool usage, bool show_exe_name) { int main(int argc, const char *argv[]) { program_name = argv[0]; - flatbuffers::GeneratorOptions opts; + flatbuffers::IDLOptions opts; std::string output_path; const size_t num_generators = sizeof(generators) / sizeof(generators[0]); bool generator_enabled[num_generators] = { false }; bool any_generator = false; bool print_make_rules = false; - bool proto_mode = false; bool raw_binary = false; bool schema_binary = false; std::vector<std::string> filenames; @@ -165,6 +162,9 @@ int main(int argc, const char *argv[]) { opts.scoped_enums = true; } else if(arg == "--gen-mutable") { opts.mutable_buffer = true; + } else if(arg == "--gen-all") { + opts.generate_all = true; + opts.include_dependence_headers = false; } else if(arg == "--gen-includes") { // Deprecated, remove this option some time in the future. printf("warning: --gen-includes is deprecated (it is now default)\n"); @@ -177,7 +177,7 @@ int main(int argc, const char *argv[]) { } else if(arg == "--") { // Separator between text and binary inputs. binary_files_from = filenames.size(); } else if(arg == "--proto") { - proto_mode = true; + opts.proto_mode = true; any_generator = true; } else if(arg == "--schema") { schema_binary = true; @@ -204,10 +204,10 @@ int main(int argc, const char *argv[]) { if (!filenames.size()) Error("missing input files", false, true); if (!any_generator) - Error("no options: specify one of -c -g -j -t -b etc.", true); + Error("no options: specify at least one generator.", true); // Now process the files: - parser = new flatbuffers::Parser(opts.strict_json, proto_mode); + parser = new flatbuffers::Parser(opts); for (auto file_it = filenames.begin(); file_it != filenames.end(); ++file_it) { @@ -248,7 +248,7 @@ int main(int argc, const char *argv[]) { // one from scratch. If it depends on previous schemas it must do // so explicitly using an include. delete parser; - parser = new flatbuffers::Parser(opts.strict_json, proto_mode); + parser = new flatbuffers::Parser(opts); } auto local_include_directory = flatbuffers::StripFileName(*file_it); include_directories.push_back(local_include_directory.c_str()); @@ -272,7 +272,7 @@ int main(int argc, const char *argv[]) { if (generator_enabled[i]) { if (!print_make_rules) { flatbuffers::EnsureDirExists(output_path); - if (!generators[i].generate(*parser, output_path, filebase, opts)) { + if (!generators[i].generate(*parser, output_path, filebase)) { Error(std::string("Unable to generate ") + generators[i].lang_name + " for " + @@ -280,7 +280,7 @@ int main(int argc, const char *argv[]) { } } else { std::string make_rule = generators[i].make_rule( - *parser, output_path, *file_it, opts); + *parser, output_path, *file_it); if (!make_rule.empty()) printf("%s\n", flatbuffers::WordWrap( make_rule, 80, " ", " \\").c_str()); @@ -288,7 +288,11 @@ int main(int argc, const char *argv[]) { } } - if (proto_mode) GenerateFBS(*parser, output_path, filebase, opts); + if (opts.proto_mode) GenerateFBS(*parser, output_path, filebase); + + // We do not want to generate code for the definitions in this file + // in any files coming up next. + parser->MarkGenerated(); } delete parser; diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp index ca523dcd..8a440e85 100644 --- a/src/idl_gen_cpp.cpp +++ b/src/idl_gen_cpp.cpp @@ -127,18 +127,18 @@ static std::string GenTypeGet(const Parser &parser, const Type &type, } static std::string GenEnumDecl(const EnumDef &enum_def, - const GeneratorOptions &opts) { + const IDLOptions &opts) { return (opts.scoped_enums ? "enum class " : "enum ") + enum_def.name; } static std::string GenEnumVal(const EnumDef &enum_def, const EnumVal &enum_val, - const GeneratorOptions &opts) { + const IDLOptions &opts) { return opts.prefixed_enums ? enum_def.name + "_" + enum_val.name : enum_val.name; } static std::string GetEnumVal(const EnumDef &enum_def, const EnumVal &enum_val, - const GeneratorOptions &opts) { + const IDLOptions &opts) { if (opts.scoped_enums) { return enum_def.name + "::" + enum_val.name; } else if (opts.prefixed_enums) { @@ -150,14 +150,13 @@ static std::string GetEnumVal(const EnumDef &enum_def, const EnumVal &enum_val, // Generate an enum declaration and an enum string lookup table. static void GenEnum(const Parser &parser, EnumDef &enum_def, - std::string *code_ptr, std::string *code_ptr_post, - const GeneratorOptions &opts) { + std::string *code_ptr, std::string *code_ptr_post) { if (enum_def.generated) return; std::string &code = *code_ptr; std::string &code_post = *code_ptr_post; GenComment(enum_def.doc_comment, code_ptr, nullptr); - code += GenEnumDecl(enum_def, opts); - if (opts.scoped_enums) + code += GenEnumDecl(enum_def, parser.opts); + if (parser.opts.scoped_enums) code += " : " + GenTypeBasic(parser, enum_def.underlying_type, false); code += " {\n"; for (auto it = enum_def.vals.vec.begin(); @@ -165,7 +164,7 @@ static void GenEnum(const Parser &parser, EnumDef &enum_def, ++it) { auto &ev = **it; GenComment(ev.doc_comment, code_ptr, nullptr, " "); - code += " " + GenEnumVal(enum_def, ev, opts) + " = "; + code += " " + GenEnumVal(enum_def, ev, parser.opts) + " = "; code += NumToString(ev.value); code += (it + 1) != enum_def.vals.vec.end() ? ",\n" : "\n"; } @@ -196,7 +195,7 @@ static void GenEnum(const Parser &parser, EnumDef &enum_def, code += "()[static_cast<int>(e)"; if (enum_def.vals.vec.front()->value) { code += " - static_cast<int>("; - code += GetEnumVal(enum_def, *enum_def.vals.vec.front(), opts) +")"; + code += GetEnumVal(enum_def, *enum_def.vals.vec.front(), parser.opts) +")"; } code += "]; }\n\n"; } @@ -216,7 +215,7 @@ static void GenEnum(const Parser &parser, EnumDef &enum_def, it != enum_def.vals.vec.end(); ++it) { auto &ev = **it; - code_post += " case " + GetEnumVal(enum_def, ev, opts); + code_post += " case " + GetEnumVal(enum_def, ev, parser.opts); if (!ev.value) { code_post += ": return true;\n"; // "NONE" enum value. } else { @@ -250,7 +249,7 @@ std::string GenFieldOffsetName(const FieldDef &field) { // Generate an accessor struct, builder structs & function for a table. static void GenTable(const Parser &parser, StructDef &struct_def, - const GeneratorOptions &opts, std::string *code_ptr) { + std::string *code_ptr) { if (struct_def.generated) return; std::string &code = *code_ptr; @@ -298,7 +297,7 @@ static void GenTable(const Parser &parser, StructDef &struct_def, call += ")"; code += GenUnderlyingCast(parser, field, true, call); code += "; }\n"; - if (opts.mutable_buffer) { + if (parser.opts.mutable_buffer) { if (is_scalar) { code += " bool mutate_" + field.name + "("; code += GenTypeBasic(parser, field.value.type, true); @@ -339,7 +338,7 @@ static void GenTable(const Parser &parser, StructDef &struct_def, code += "const char *val) const { return strcmp(" + field.name; code += "()->c_str(), val); }\n"; } else { - if (opts.scoped_enums && + if (parser.opts.scoped_enums && field.value.type.enum_def && IsScalar(field.value.type.base_type)) { code += GenTypeGet(parser, field.value.type, " ", "const ", " *", @@ -477,7 +476,7 @@ static void GenTable(const Parser &parser, StructDef &struct_def, code += WrapInNameSpace(parser, field.value.type.enum_def->defined_namespace, GetEnumVal(*field.value.type.enum_def, *ev, - opts)); + parser.opts)); } else { code += GenUnderlyingCast(parser, field, true, field.value.constant); } @@ -518,7 +517,7 @@ static void GenPadding(const FieldDef &field, // Generate an accessor struct with constructor for a flatbuffers struct. static void GenStruct(const Parser &parser, StructDef &struct_def, - const GeneratorOptions &opts, std::string *code_ptr) { + std::string *code_ptr) { if (struct_def.generated) return; std::string &code = *code_ptr; @@ -602,7 +601,7 @@ static void GenStruct(const Parser &parser, StructDef &struct_def, ? "flatbuffers::EndianScalar(" + field.name + "_)" : field.name + "_"); code += "; }\n"; - if (opts.mutable_buffer) { + if (parser.opts.mutable_buffer) { if (is_scalar) { code += " void mutate_" + field.name + "("; code += GenTypeBasic(parser, field.value.type, true); @@ -639,15 +638,14 @@ void CloseNestedNameSpaces(Namespace *ns, std::string *code_ptr) { // 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, - const GeneratorOptions &opts) { + const std::string &file_name) { using namespace cpp; // Generate code for all the enum declarations. std::string enum_code, enum_code_post; for (auto it = parser.enums_.vec.begin(); it != parser.enums_.vec.end(); ++it) { - GenEnum(parser, **it, &enum_code, &enum_code_post, opts); + GenEnum(parser, **it, &enum_code, &enum_code_post); } // Generate forward declarations for all structs/tables, since they may @@ -688,11 +686,11 @@ std::string GenerateCPP(const Parser &parser, std::string decl_code; for (auto it = parser.structs_.vec.begin(); it != parser.structs_.vec.end(); ++it) { - if ((**it).fixed) GenStruct(parser, **it, opts, &decl_code); + if ((**it).fixed) GenStruct(parser, **it, &decl_code); } for (auto it = parser.structs_.vec.begin(); it != parser.structs_.vec.end(); ++it) { - if (!(**it).fixed) GenTable(parser, **it, opts, &decl_code); + if (!(**it).fixed) GenTable(parser, **it, &decl_code); } // Only output file-level code if there were any declarations. @@ -725,7 +723,7 @@ std::string GenerateCPP(const Parser &parser, code += "#include \"flatbuffers/flatbuffers.h\"\n\n"; - if (opts.include_dependence_headers) { + if (parser.opts.include_dependence_headers) { int num_includes = 0; for (auto it = parser.included_files_.begin(); it != parser.included_files_.end(); ++it) { @@ -765,7 +763,7 @@ std::string GenerateCPP(const Parser &parser, code += name; code += "(const void *buf) { return flatbuffers::GetRoot<"; code += cpp_qualified_name + ">(buf); }\n\n"; - if (opts.mutable_buffer) { + if (parser.opts.mutable_buffer) { code += "inline " + name + " *GetMutable"; code += name; code += "(void *buf) { return flatbuffers::GetMutableRoot<"; @@ -806,7 +804,6 @@ std::string GenerateCPP(const Parser &parser, if (parser.file_identifier_.length()) code += ", " + name + "Identifier()"; code += "); }\n\n"; - } CloseNestedNameSpaces(name_space, &code); @@ -827,17 +824,15 @@ static std::string GeneratedFileName(const std::string &path, bool GenerateCPP(const Parser &parser, const std::string &path, - const std::string &file_name, - const GeneratorOptions &opts) { - auto code = GenerateCPP(parser, file_name, opts); + const std::string &file_name) { + auto code = GenerateCPP(parser, file_name); return !code.length() || SaveFile(GeneratedFileName(path, file_name).c_str(), code, false); } std::string CPPMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name, - const GeneratorOptions & /*opts*/) { + const std::string &file_name) { std::string filebase = flatbuffers::StripPath( flatbuffers::StripExtension(file_name)); std::string make_rule = GeneratedFileName(path, filebase) + ": "; diff --git a/src/idl_gen_fbs.cpp b/src/idl_gen_fbs.cpp index a55d42a8..00afe25d 100644 --- a/src/idl_gen_fbs.cpp +++ b/src/idl_gen_fbs.cpp @@ -52,8 +52,7 @@ static void GenNameSpace(const Namespace &name_space, std::string *_schema, } // Generate a flatbuffer schema from the Parser's internal representation. -std::string GenerateFBS(const Parser &parser, const std::string &file_name, - const GeneratorOptions &opts) { +std::string GenerateFBS(const Parser &parser, const std::string &file_name) { // Proto namespaces may clash with table names, so we have to prefix all: for (auto it = parser.namespaces_.begin(); it != parser.namespaces_.end(); ++it) { @@ -65,7 +64,7 @@ std::string GenerateFBS(const Parser &parser, const std::string &file_name, std::string schema; schema += "// Generated from " + file_name + ".proto\n\n"; - if (opts.include_dependence_headers) { + if (parser.opts.include_dependence_headers) { #ifdef FBS_GEN_INCLUDES // TODO: currently all in one file. int num_includes = 0; for (auto it = parser.included_files_.begin(); @@ -120,10 +119,9 @@ std::string GenerateFBS(const Parser &parser, const std::string &file_name, bool GenerateFBS(const Parser &parser, const std::string &path, - const std::string &file_name, - const GeneratorOptions &opts) { + const std::string &file_name) { return SaveFile((path + file_name + ".fbs").c_str(), - GenerateFBS(parser, file_name, opts), false); + GenerateFBS(parser, file_name), false); } } // namespace flatbuffers diff --git a/src/idl_gen_general.cpp b/src/idl_gen_general.cpp index 33b863e6..88aa4dae 100644 --- a/src/idl_gen_general.cpp +++ b/src/idl_gen_general.cpp @@ -69,10 +69,10 @@ void GenComment(const std::vector<std::string> &dc, std::string *code_ptr, } } -// These arrays need to correspond to the GeneratorOptions::k enum. +// These arrays need to correspond to the IDLOptions::k enum. struct LanguageParameters { - GeneratorOptions::Language language; + IDLOptions::Language language; // Whether function names in the language typically start with uppercase. bool first_camel_upper; const char *file_extension; @@ -98,7 +98,7 @@ struct LanguageParameters { LanguageParameters language_parameters[] = { { - GeneratorOptions::kJava, + IDLOptions::kJava, false, ".java", "String", @@ -126,7 +126,7 @@ LanguageParameters language_parameters[] = { }, }, { - GeneratorOptions::kCSharp, + IDLOptions::kCSharp, true, ".cs", "string", @@ -155,7 +155,7 @@ LanguageParameters language_parameters[] = { // TODO: add Go support to the general generator. // WARNING: this is currently only used for generating make rules for Go. { - GeneratorOptions::kGo, + IDLOptions::kGo, true, ".go", "string", @@ -184,12 +184,12 @@ LanguageParameters language_parameters[] = { }; static_assert(sizeof(language_parameters) / sizeof(LanguageParameters) == - GeneratorOptions::kMAX, + IDLOptions::kMAX, "Please add extra elements to the arrays above."); static std::string FunctionStart(const LanguageParameters &lang, char upper) { return std::string() + - (lang.language == GeneratorOptions::kJava + (lang.language == IDLOptions::kJava ? static_cast<char>(tolower(upper)) : upper); } @@ -209,13 +209,13 @@ static std::string GenTypeBasic(const LanguageParameters &lang, }; if (enableLangOverrides) { - if (lang.language == GeneratorOptions::kCSharp) { + if (lang.language == IDLOptions::kCSharp) { if (IsEnum(type)) return type.enum_def->name; if (type.base_type == BASE_TYPE_STRUCT) return "Offset<" + type.struct_def->name + ">"; } } - return gtypename[type.base_type * GeneratorOptions::kMAX + lang.language]; + return gtypename[type.base_type * IDLOptions::kMAX + lang.language]; } static std::string GenTypeBasic(const LanguageParameters &lang, const Type &type) { @@ -236,7 +236,7 @@ static std::string GenTypePointer(const LanguageParameters &lang, return type.struct_def->name; case BASE_TYPE_UNION: // Unions in C# use a generic Table-derived type for better type safety - if (lang.language == GeneratorOptions::kCSharp) return "TTable"; + if (lang.language == IDLOptions::kCSharp) return "TTable"; // fall through default: return "Table"; @@ -254,7 +254,7 @@ static std::string GenTypeGet(const LanguageParameters &lang, // one size higher signed types for unsigned serialized values in Java). static Type DestinationType(const LanguageParameters &lang, const Type &type, bool vectorelem) { - if (lang.language != GeneratorOptions::kJava) return type; + if (lang.language != IDLOptions::kJava) return type; switch (type.base_type) { // We use int for both uchar/ushort, since that generally means less casting // than using short for uchar. @@ -270,7 +270,7 @@ static Type DestinationType(const LanguageParameters &lang, const Type &type, } static std::string GenOffsetType(const LanguageParameters &lang, const StructDef &struct_def) { - if(lang.language == GeneratorOptions::kCSharp) { + if(lang.language == IDLOptions::kCSharp) { return "Offset<" + struct_def.name + ">"; } else { return "int"; @@ -281,14 +281,14 @@ static std::string GenOffsetConstruct(const LanguageParameters &lang, const StructDef &struct_def, const std::string &variable_name) { - if(lang.language == GeneratorOptions::kCSharp) { + if(lang.language == IDLOptions::kCSharp) { return "new Offset<" + struct_def.name + ">(" + variable_name + ")"; } return variable_name; } static std::string GenVectorOffsetType(const LanguageParameters &lang) { - if(lang.language == GeneratorOptions::kCSharp) { + if(lang.language == IDLOptions::kCSharp) { return "VectorOffset"; } else { return "int"; @@ -304,7 +304,7 @@ static std::string GenTypeNameDest(const LanguageParameters &lang, const Type &t // Mask to turn serialized value into destination type value. static std::string DestinationMask(const LanguageParameters &lang, const Type &type, bool vectorelem) { - if (lang.language != GeneratorOptions::kJava) return ""; + if (lang.language != IDLOptions::kJava) return ""; switch (type.base_type) { case BASE_TYPE_UCHAR: return " & 0xFF"; case BASE_TYPE_USHORT: return " & 0xFFFF"; @@ -324,12 +324,12 @@ static std::string DestinationCast(const LanguageParameters &lang, return DestinationCast(lang, type.VectorType()); } else { switch (lang.language) { - case GeneratorOptions::kJava: + case IDLOptions::kJava: // Cast necessary to correctly read serialized unsigned values. if (type.base_type == BASE_TYPE_UINT) return "(long)"; break; - case GeneratorOptions::kCSharp: + case IDLOptions::kCSharp: // Cast from raw integral types to enum. if (IsEnum(type)) return "(" + type.enum_def->name + ")"; break; @@ -352,14 +352,14 @@ static std::string SourceCast(const LanguageParameters &lang, return SourceCast(lang, type.VectorType(), castFromDest); } else { switch (lang.language) { - case GeneratorOptions::kJava: + case IDLOptions::kJava: if (castFromDest) { if (type.base_type == BASE_TYPE_UINT) return "(int)"; else if (type.base_type == BASE_TYPE_USHORT) return "(short)"; else if (type.base_type == BASE_TYPE_UCHAR) return "(byte)"; } break; - case GeneratorOptions::kCSharp: + case IDLOptions::kCSharp: if (IsEnum(type)) return "(" + GenTypeBasic(lang, type, false) + ")"; break; default: @@ -406,7 +406,7 @@ static std::string GenEnumDefaultValue(const Value &value) { static std::string GenDefaultValue(const LanguageParameters &lang, const Value &value, bool enableLangOverrides) { if (enableLangOverrides) { // handles both enum case and vector of enum case - if (lang.language == GeneratorOptions::kCSharp && + if (lang.language == IDLOptions::kCSharp && value.type.enum_def != nullptr && value.type.base_type != BASE_TYPE_UNION) { return GenEnumDefaultValue(value); @@ -424,7 +424,7 @@ static std::string GenDefaultValue(const LanguageParameters &lang, const Value & static std::string GenDefaultValueBasic(const LanguageParameters &lang, const Value &value, bool enableLangOverrides) { if (!IsScalar(value.type.base_type)) { if (enableLangOverrides) { - if (lang.language == GeneratorOptions::kCSharp) { + if (lang.language == IDLOptions::kCSharp) { switch (value.type.base_type) { case BASE_TYPE_STRING: return "default(StringOffset)"; @@ -458,11 +458,11 @@ static void GenEnum(const LanguageParameters &lang, EnumDef &enum_def, // That, and Java Enums are expensive, and not universally liked. GenComment(enum_def.doc_comment, code_ptr, &lang.comment_config); code += std::string("public ") + lang.enum_decl + enum_def.name; - if (lang.language == GeneratorOptions::kCSharp) { + if (lang.language == IDLOptions::kCSharp) { code += lang.inheritance_marker + GenTypeBasic(lang, enum_def.underlying_type, false); } code += lang.open_curly; - if (lang.language == GeneratorOptions::kJava) { + if (lang.language == IDLOptions::kJava) { code += " private " + enum_def.name + "() { }\n"; } for (auto it = enum_def.vals.vec.begin(); @@ -470,7 +470,7 @@ static void GenEnum(const LanguageParameters &lang, EnumDef &enum_def, ++it) { auto &ev = **it; GenComment(ev.doc_comment, code_ptr, &lang.comment_config, " "); - if (lang.language != GeneratorOptions::kCSharp) { + if (lang.language != IDLOptions::kCSharp) { code += " public static"; code += lang.const_decl; code += GenTypeBasic(lang, enum_def.underlying_type, false); @@ -482,7 +482,7 @@ static void GenEnum(const LanguageParameters &lang, EnumDef &enum_def, // Generate a generate string table for enum values. // We do not do that for C# where this functionality is native. - if (lang.language != GeneratorOptions::kCSharp) { + if (lang.language != IDLOptions::kCSharp) { // Problem is, if values are very sparse that could generate really big // tables. Ideally in that case we generate a map lookup instead, but for // the moment we simply don't output a table at all. @@ -544,7 +544,7 @@ static std::string GenSetter(const LanguageParameters &lang, const Type &type) { if (IsScalar(type.base_type)) { std::string setter = "bb." + FunctionStart(lang, 'P') + "ut"; - if (GenTypeBasic(lang, type, false) != "byte" && + if (GenTypeBasic(lang, type, false) != "byte" && type.base_type != BASE_TYPE_BOOL) { setter += MakeCamel(GenTypeBasic(lang, type, false)); } @@ -619,8 +619,7 @@ static void GenStructBody(const LanguageParameters &lang, } static void GenStruct(const LanguageParameters &lang, const Parser &parser, - StructDef &struct_def, const GeneratorOptions &opts, - std::string *code_ptr) { + StructDef &struct_def, std::string *code_ptr) { if (struct_def.generated) return; std::string &code = *code_ptr; @@ -692,13 +691,13 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser, // Generate the accessors that don't do object reuse. if (field.value.type.base_type == BASE_TYPE_STRUCT) { // Calls the accessor that takes an accessor object with a new object. - if (lang.language == GeneratorOptions::kCSharp) { + if (lang.language == IDLOptions::kCSharp) { code += method_start + " { get { return Get"; code += MakeCamel(field.name, lang.first_camel_upper); code += "(new "; code += type_name + "()); } }\n"; method_start = " public " + type_name_dest + " Get" + MakeCamel(field.name, lang.first_camel_upper); - } + } else { code += method_start + "() { return "; code += MakeCamel(field.name, lang.first_camel_upper); @@ -709,7 +708,7 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser, field.value.type.element == BASE_TYPE_STRUCT) { // Accessors for vectors of structs also take accessor objects, this // generates a variant without that argument. - if (lang.language == GeneratorOptions::kCSharp) { + if (lang.language == IDLOptions::kCSharp) { method_start = " public " + type_name_dest + " Get" + MakeCamel(field.name, lang.first_camel_upper); code += method_start + "(int j) { return Get"; } else { @@ -719,11 +718,11 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser, code += "(new "; code += type_name + "(), j); }\n"; } else if (field.value.type.base_type == BASE_TYPE_VECTOR) { - if (lang.language == GeneratorOptions::kCSharp) { + if (lang.language == IDLOptions::kCSharp) { method_start = " public " + type_name_dest + " Get" + MakeCamel(field.name, lang.first_camel_upper); } } else if (field.value.type.base_type == BASE_TYPE_UNION) { - if (lang.language == GeneratorOptions::kCSharp) { + if (lang.language == IDLOptions::kCSharp) { // union types in C# use generic Table-derived type for better type safety method_start = " public " + type_name_dest + " Get" + MakeCamel(field.name, lang.first_camel_upper) + "<TTable>"; offset_prefix = " where TTable : Table" + offset_prefix; @@ -734,8 +733,8 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser, code += method_start; std::string default_cast = ""; // only create default casts for c# scalars or vectors of scalars - if (lang.language == GeneratorOptions::kCSharp && - (IsScalar(field.value.type.base_type) || + if (lang.language == IDLOptions::kCSharp && + (IsScalar(field.value.type.base_type) || (field.value.type.base_type == BASE_TYPE_VECTOR && IsScalar(field.value.type.element)))) { // For scalars, default value will be returned by GetDefaultValue(). If the scalar is an enum, GetDefaultValue() // returns an actual c# enum that doesn't need to be casted. However, default values for enum elements of @@ -827,7 +826,7 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser, if (((field.value.type.base_type == BASE_TYPE_VECTOR && IsScalar(field.value.type.VectorType().base_type)) || field.value.type.base_type == BASE_TYPE_STRING) && - lang.language == GeneratorOptions::kJava) { + lang.language == IDLOptions::kJava) { code += " public ByteBuffer "; code += MakeCamel(field.name, lang.first_camel_upper); code += "AsByteBuffer() { return __vector_as_bytebuffer("; @@ -838,7 +837,7 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser, } // generate mutators for scalar fields or vectors of scalars - if (opts.mutable_buffer) { + if (parser.opts.mutable_buffer) { auto underlying_type = field.value.type.base_type == BASE_TYPE_VECTOR ? field.value.type.VectorType() : field.value.type; @@ -852,7 +851,7 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser, auto setter_index = field.value.type.base_type == BASE_TYPE_VECTOR ? "__vector(o) + j * " + NumToString(InlineSize(underlying_type)) : (struct_def.fixed ? "bb_pos + " + NumToString(field.value.offset) : "o + bb_pos"); - if (IsScalar(field.value.type.base_type) || + if (IsScalar(field.value.type.base_type) || (field.value.type.base_type == BASE_TYPE_VECTOR && IsScalar(field.value.type.VectorType().base_type))) { code += " public "; @@ -916,7 +915,7 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser, // Java doesn't have defaults, which means this method must always // supply all arguments, and thus won't compile when fields are added. - if (lang.language != GeneratorOptions::kJava) { + if (lang.language != IDLOptions::kJava) { code += " = "; code += GenDefaultValueBasic(lang, field.value); } @@ -970,7 +969,7 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser, code += NumToString(it - struct_def.fields.vec.begin()) + ", "; code += SourceCastBasic(lang, field.value.type); code += argname; - if(!IsScalar(field.value.type.base_type) && field.value.type.base_type != BASE_TYPE_UNION && lang.language == GeneratorOptions::kCSharp) { + if(!IsScalar(field.value.type.base_type) && field.value.type.base_type != BASE_TYPE_UNION && lang.language == IDLOptions::kCSharp) { code += ".Value"; } code += ", " + GenDefaultValue(lang, field.value, false); @@ -996,7 +995,7 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser, code += "("; code += SourceCastBasic(lang, vector_type, false); code += "data[i]"; - if (lang.language == GeneratorOptions::kCSharp && + if (lang.language == IDLOptions::kCSharp && (vector_type.base_type == BASE_TYPE_STRUCT || vector_type.base_type == BASE_TYPE_STRING)) code += ".Value"; code += "); return "; @@ -1032,7 +1031,7 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser, code += FunctionStart(lang, 'F') + "inish" + struct_def.name; code += "Buffer(FlatBufferBuilder builder, " + GenOffsetType(lang, struct_def) + " offset) {"; code += " builder." + FunctionStart(lang, 'F') + "inish(offset"; - if (lang.language == GeneratorOptions::kCSharp) { + if (lang.language == IDLOptions::kCSharp) { code += ".Value"; } @@ -1080,18 +1079,17 @@ static bool SaveClass(const LanguageParameters &lang, const Parser &parser, bool GenerateGeneral(const Parser &parser, const std::string &path, - const std::string & file_name, - const GeneratorOptions &opts) { + const std::string & file_name) { - assert(opts.lang <= GeneratorOptions::kMAX); - auto lang = language_parameters[opts.lang]; + assert(parser.opts.lang <= IDLOptions::kMAX); + auto lang = language_parameters[parser.opts.lang]; std::string one_file_code; for (auto it = parser.enums_.vec.begin(); it != parser.enums_.vec.end(); ++it) { std::string enumcode; GenEnum(lang, **it, &enumcode); - if (opts.one_file) { + if (parser.opts.one_file) { one_file_code += enumcode; } else { @@ -1103,8 +1101,8 @@ bool GenerateGeneral(const Parser &parser, for (auto it = parser.structs_.vec.begin(); it != parser.structs_.vec.end(); ++it) { std::string declcode; - GenStruct(lang, parser, **it, opts, &declcode); - if (opts.one_file) { + GenStruct(lang, parser, **it, &declcode); + if (parser.opts.one_file) { one_file_code += declcode; } else { @@ -1113,7 +1111,7 @@ bool GenerateGeneral(const Parser &parser, } } - if (opts.one_file) { + if (parser.opts.one_file) { return SaveClass(lang, parser, file_name, one_file_code,path, true, true); } return true; @@ -1139,10 +1137,9 @@ static std::string ClassFileName(const LanguageParameters &lang, std::string GeneralMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name, - const GeneratorOptions &opts) { - assert(opts.lang <= GeneratorOptions::kMAX); - auto lang = language_parameters[opts.lang]; + const std::string &file_name) { + assert(parser.opts.lang <= IDLOptions::kMAX); + auto lang = language_parameters[parser.opts.lang]; std::string make_rule; @@ -1178,8 +1175,7 @@ std::string BinaryFileName(const Parser &parser, bool GenerateBinary(const Parser &parser, const std::string &path, - const std::string &file_name, - const GeneratorOptions & /*opts*/) { + const std::string &file_name) { return !parser.builder_.GetSize() || flatbuffers::SaveFile( BinaryFileName(parser, path, file_name).c_str(), @@ -1190,8 +1186,7 @@ bool GenerateBinary(const Parser &parser, std::string BinaryMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name, - const GeneratorOptions & /*opts*/) { + const std::string &file_name) { if (!parser.builder_.GetSize()) return ""; std::string filebase = flatbuffers::StripPath( flatbuffers::StripExtension(file_name)); diff --git a/src/idl_gen_go.cpp b/src/idl_gen_go.cpp index 04ee3dbd..88ce1f2a 100644 --- a/src/idl_gen_go.cpp +++ b/src/idl_gen_go.cpp @@ -664,8 +664,7 @@ static void GenStructBuilder(const StructDef &struct_def, bool GenerateGo(const Parser &parser, const std::string &path, - const std::string & /*file_name*/, - const GeneratorOptions & /*opts*/) { + const std::string & /*file_name*/) { for (auto it = parser.enums_.vec.begin(); it != parser.enums_.vec.end(); ++it) { std::string enumcode; diff --git a/src/idl_gen_js.cpp b/src/idl_gen_js.cpp index 84ee6ae8..7efc3957 100644 --- a/src/idl_gen_js.cpp +++ b/src/idl_gen_js.cpp @@ -653,8 +653,7 @@ static void GenStruct(const Parser &parser, StructDef &struct_def, // 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, - const GeneratorOptions &opts) { +std::string GenerateJS(const Parser &parser) { using namespace js; // Generate code for all the enum declarations. @@ -684,7 +683,7 @@ std::string GenerateJS(const Parser &parser, code += enum_code; code += decl_code; - if (!exports_code.empty() && !opts.skip_js_exports) { + if (!exports_code.empty() && !parser.opts.skip_js_exports) { code += "// Exports for Node.js and RequireJS\n"; code += exports_code; } @@ -702,17 +701,15 @@ static std::string GeneratedFileName(const std::string &path, bool GenerateJS(const Parser &parser, const std::string &path, - const std::string &file_name, - const GeneratorOptions &opts) { - auto code = GenerateJS(parser, opts); + const std::string &file_name) { + auto code = GenerateJS(parser); return !code.length() || SaveFile(GeneratedFileName(path, file_name).c_str(), code, false); } std::string JSMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name, - const GeneratorOptions & /*opts*/) { + const std::string &file_name) { std::string filebase = flatbuffers::StripPath( flatbuffers::StripExtension(file_name)); std::string make_rule = GeneratedFileName(path, filebase) + ": "; diff --git a/src/idl_gen_php.cpp b/src/idl_gen_php.cpp index aba16507..2aa7e222 100644 --- a/src/idl_gen_php.cpp +++ b/src/idl_gen_php.cpp @@ -140,8 +140,8 @@ namespace php { code += Indent + " * @return " + struct_def.name + "\n"; code += Indent + " **/\n"; code += Indent + "public function init($_i, ByteBuffer $_bb)\n"; - code += Indent + "{\n"; - code += Indent + Indent + "$this->bb_pos = $_i;\n"; + code += Indent + "{\n"; + code += Indent + Indent + "$this->bb_pos = $_i;\n"; code += Indent + Indent + "$this->bb = $_bb;\n"; code += Indent + Indent + "return $this;\n"; code += Indent + "}\n\n"; @@ -241,7 +241,7 @@ namespace php { code += Indent + "public function get"; code += MakeCamel(field.name); code += "()\n"; - code += Indent + "{\n"; + code += Indent + "{\n"; code += Indent + Indent + "$obj = new "; code += MakeCamel(GenTypeGet(field.value.type)) + "();\n"; code += Indent + Indent + @@ -251,8 +251,6 @@ namespace php { code += Indent + Indent; code += "return $o != 0 ? $obj->init($o + $this->bb_pos, $this->bb) : "; code += GenDefaultValue(field.value) + ";\n"; - - code += Indent + "}\n\n"; } @@ -263,7 +261,7 @@ namespace php { code += Indent + "public function get"; code += MakeCamel(field.name); code += "()\n"; - code += Indent + "{\n"; + code += Indent + "{\n"; code += Indent + Indent + "$o = $this->__offset(" + NumToString(field.value.offset) + @@ -307,7 +305,7 @@ namespace php { code += Indent + "public function get"; code += MakeCamel(field.name); code += "($j)\n"; - code += Indent + "{\n"; + code += Indent + "{\n"; code += Indent + Indent + "$o = $this->__offset(" + NumToString(field.value.offset) + @@ -371,7 +369,7 @@ namespace php { code += Indent + "public function get"; code += MakeCamel(field.name); code += "($j)\n"; - code += Indent + "{\n"; + code += Indent + "{\n"; code += Indent + Indent + "$o = $this->__offset(" + NumToString(field.value.offset) + @@ -456,7 +454,7 @@ namespace php { code += Indent + " */\n"; code += Indent + "public static function start" + struct_def.name; code += "(FlatBufferBuilder $builder)\n"; - code += Indent + "{\n"; + code += Indent + "{\n"; code += Indent + Indent + "$builder->StartObject("; code += NumToString(struct_def.fields.vec.size()); code += ");\n"; @@ -528,7 +526,7 @@ namespace php { code += "(FlatBufferBuilder $builder, "; code += "$" + MakeCamel(field.name, false); code += ")\n"; - code += Indent + "{\n"; + code += Indent + "{\n"; code += Indent + Indent + "$builder->add"; code += GenMethod(field) + "X("; code += NumToString(offset) + ", "; @@ -562,7 +560,7 @@ namespace php { code += Indent + "public static function create"; code += MakeCamel(field.name); code += "Vector(FlatBufferBuilder $builder, array $data)\n"; - code += Indent + "{\n"; + code += Indent + "{\n"; code += Indent + Indent + "$builder->startVector("; code += NumToString(elem_size); code += ", count($data), " + NumToString(alignment); @@ -591,7 +589,7 @@ namespace php { code += Indent + "public static function start"; code += MakeCamel(field.name); code += "Vector(FlatBufferBuilder $builder, $numElems)\n"; - code += Indent + "{\n"; + code += Indent + "{\n"; code += Indent + Indent + "$builder->startVector("; code += NumToString(elem_size); code += ", $numElems, " + NumToString(alignment); @@ -612,7 +610,7 @@ namespace php { code += Indent + " */\n"; code += Indent + "public static function end" + struct_def.name; code += "(FlatBufferBuilder $builder)\n"; - code += Indent + "{\n"; + code += Indent + "{\n"; code += Indent + Indent + "$o = $builder->endObject();\n"; @@ -644,7 +642,7 @@ namespace php { } } - // Generate a struct field, conditioned on its child type(s). + // Generate a struct field, conditioned on its child type(s). static void GenStructAccessor(const StructDef &struct_def, const FieldDef &field, std::string *code_ptr) { @@ -707,7 +705,7 @@ namespace php { code += Indent + "public static function add"; code += MakeCamel(field.name); code += "(FlatBufferBuilder $builder, $offset)\n"; - code += Indent + "{\n"; + code += Indent + "{\n"; code += Indent + Indent + "$builder->addOffsetX("; code += NumToString(offset) + ", $offset, 0);\n"; code += Indent + "}\n\n"; @@ -815,7 +813,7 @@ namespace php { code += Indent + ");\n\n"; code += Indent + "public static function Name($e)\n"; - code += Indent + "{\n"; + code += Indent + "{\n"; code += Indent + Indent + "if (!isset(self::$names[$e])) {\n"; code += Indent + Indent + Indent + "throw new \\Exception();\n"; code += Indent + Indent + "}\n"; @@ -943,7 +941,7 @@ namespace php { code += "(FlatBufferBuilder $builder"; StructBuilderArgs(struct_def, "", code_ptr); code += ")\n"; - code += Indent + "{\n"; + code += Indent + "{\n"; StructBuilderBody(struct_def, "", code_ptr); @@ -955,8 +953,7 @@ namespace php { bool GeneratePhp(const Parser &parser, const std::string &path, - const std::string & /*file_name*/, - const GeneratorOptions & /*opts*/) { + const std::string & /*file_name*/) { for (auto it = parser.enums_.vec.begin(); it != parser.enums_.vec.end(); ++it) { std::string enumcode; diff --git a/src/idl_gen_python.cpp b/src/idl_gen_python.cpp index de47a99c..7cd09cfc 100644 --- a/src/idl_gen_python.cpp +++ b/src/idl_gen_python.cpp @@ -638,8 +638,7 @@ static void GenStructBuilder(const StructDef &struct_def, bool GeneratePython(const Parser &parser, const std::string &path, - const std::string & /*file_name*/, - const GeneratorOptions & /*opts*/) { + const std::string & /*file_name*/) { for (auto it = parser.enums_.vec.begin(); it != parser.enums_.vec.end(); ++it) { std::string enumcode; diff --git a/src/idl_gen_text.cpp b/src/idl_gen_text.cpp index 18bebc32..dd96912c 100644 --- a/src/idl_gen_text.cpp +++ b/src/idl_gen_text.cpp @@ -23,21 +23,21 @@ namespace flatbuffers { static void GenStruct(const StructDef &struct_def, const Table *table, - int indent, const GeneratorOptions &opts, + int indent, const IDLOptions &opts, std::string *_text); // If indentation is less than 0, that indicates we don't want any newlines // either. -const char *NewLine(const GeneratorOptions &opts) { +const char *NewLine(const IDLOptions &opts) { return opts.indent_step >= 0 ? "\n" : ""; } -int Indent(const GeneratorOptions &opts) { +int Indent(const IDLOptions &opts) { return std::max(opts.indent_step, 0); } // Output an identifier with or without quotes depending on strictness. -void OutputIdentifier(const std::string &name, const GeneratorOptions &opts, +void OutputIdentifier(const std::string &name, const IDLOptions &opts, std::string *_text) { std::string &text = *_text; if (opts.strict_json) text += "\""; @@ -50,7 +50,7 @@ void OutputIdentifier(const std::string &name, const GeneratorOptions &opts, // The general case for scalars: template<typename T> void Print(T val, Type type, int /*indent*/, StructDef * /*union_sd*/, - const GeneratorOptions &opts, + const IDLOptions &opts, std::string *_text) { std::string &text = *_text; if (type.enum_def && opts.output_enum_identifiers) { @@ -70,7 +70,7 @@ template<typename T> void Print(T val, Type type, int /*indent*/, // Print a vector a sequence of JSON values, comma separated, wrapped in "[]". template<typename T> void PrintVector(const Vector<T> &v, Type type, - int indent, const GeneratorOptions &opts, + int indent, const IDLOptions &opts, std::string *_text) { std::string &text = *_text; text += "["; @@ -136,7 +136,7 @@ static void EscapeString(const String &s, std::string *_text) { template<> void Print<const void *>(const void *val, Type type, int indent, StructDef *union_sd, - const GeneratorOptions &opts, + const IDLOptions &opts, std::string *_text) { switch (type.base_type) { case BASE_TYPE_UNION: @@ -181,7 +181,7 @@ template<> void Print<const void *>(const void *val, // Generate text for a scalar field. template<typename T> static void GenField(const FieldDef &fd, const Table *table, bool fixed, - const GeneratorOptions &opts, + const IDLOptions &opts, int indent, std::string *_text) { Print(fixed ? @@ -193,7 +193,7 @@ template<typename T> static void GenField(const FieldDef &fd, // Generate text for non-scalar field. static void GenFieldOffset(const FieldDef &fd, const Table *table, bool fixed, int indent, StructDef *union_sd, - const GeneratorOptions &opts, std::string *_text) { + const IDLOptions &opts, std::string *_text) { const void *val = nullptr; if (fixed) { // The only non-scalar fields in structs are structs. @@ -211,7 +211,7 @@ static void GenFieldOffset(const FieldDef &fd, const Table *table, bool fixed, // Generate text for a struct or table, values separated by commas, indented, // and bracketed by "{}" static void GenStruct(const StructDef &struct_def, const Table *table, - int indent, const GeneratorOptions &opts, + int indent, const IDLOptions &opts, std::string *_text) { std::string &text = *_text; text += "{"; @@ -273,16 +273,16 @@ static void GenStruct(const StructDef &struct_def, const Table *table, // Generate a text representation of a flatbuffer in JSON format. void GenerateText(const Parser &parser, const void *flatbuffer, - const GeneratorOptions &opts, std::string *_text) { + std::string *_text) { std::string &text = *_text; assert(parser.root_struct_def_); // call SetRootType() text.reserve(1024); // Reduce amount of inevitable reallocs. GenStruct(*parser.root_struct_def_, GetRoot<Table>(flatbuffer), 0, - opts, + parser.opts, _text); - text += NewLine(opts); + text += NewLine(parser.opts); } std::string TextFileName(const std::string &path, @@ -292,12 +292,10 @@ std::string TextFileName(const std::string &path, bool GenerateTextFile(const Parser &parser, const std::string &path, - const std::string &file_name, - const GeneratorOptions &opts) { + const std::string &file_name) { if (!parser.builder_.GetSize() || !parser.root_struct_def_) return true; std::string text; - GenerateText(parser, parser.builder_.GetBufferPointer(), opts, - &text); + GenerateText(parser, parser.builder_.GetBufferPointer(), &text); return flatbuffers::SaveFile(TextFileName(path, file_name).c_str(), text, false); @@ -305,8 +303,7 @@ bool GenerateTextFile(const Parser &parser, std::string TextMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name, - const GeneratorOptions & /*opts*/) { + const std::string &file_name) { if (!parser.builder_.GetSize() || !parser.root_struct_def_) return ""; std::string filebase = flatbuffers::StripPath( flatbuffers::StripExtension(file_name)); diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp index f2b7fc9c..663ccd1d 100644 --- a/src/idl_parser.cpp +++ b/src/idl_parser.cpp @@ -589,10 +589,10 @@ uoffset_t Parser::ParseTable(const StructDef &struct_def, std::string *value) { Expect('{'); size_t fieldn = 0; for (;;) { - if ((!strict_json_ || !fieldn) && IsNext('}')) break; + if ((!opts.strict_json || !fieldn) && IsNext('}')) break; std::string name = attribute_; if (!IsNext(kTokenStringConstant)) - Expect(strict_json_ ? kTokenStringConstant : kTokenIdentifier); + Expect(opts.strict_json ? kTokenStringConstant : kTokenIdentifier); auto field = struct_def.fields.Lookup(name); if (!field) Error("unknown field: " + name); Expect(':'); @@ -685,7 +685,7 @@ uoffset_t Parser::ParseTable(const StructDef &struct_def, std::string *value) { uoffset_t Parser::ParseVector(const Type &type) { int count = 0; for (;;) { - if ((!strict_json_ || !count) && IsNext(']')) break; + if ((!opts.strict_json || !count) && IsNext(']')) break; Value val; val.type = type; ParseAnyValue(val, nullptr, 0); @@ -903,7 +903,7 @@ EnumDef &Parser::ParseEnum(bool is_union) { enum_def.underlying_type.base_type = BASE_TYPE_UTYPE; enum_def.underlying_type.enum_def = &enum_def; } else { - if (proto_mode_) { + if (opts.proto_mode) { enum_def.underlying_type.base_type = BASE_TYPE_INT; } else { // Give specialized error message, since this type spec used to @@ -922,7 +922,7 @@ EnumDef &Parser::ParseEnum(bool is_union) { Expect('{'); if (is_union) enum_def.vals.Add("NONE", new EnumVal("NONE", 0)); do { - if (proto_mode_ && attribute_ == "option") { + if (opts.proto_mode && attribute_ == "option") { ParseProtoOption(); } else { auto value_name = attribute_; @@ -944,17 +944,17 @@ EnumDef &Parser::ParseEnum(bool is_union) { if (IsNext('=')) { ev.value = atoi(attribute_.c_str()); Expect(kTokenIntegerConstant); - if (!proto_mode_ && prevsize && + if (!opts.proto_mode && prevsize && enum_def.vals.vec[prevsize - 1]->value >= ev.value) Error("enum values must be specified in ascending order"); } - if (proto_mode_ && IsNext('[')) { + if (opts.proto_mode && IsNext('[')) { // ignore attributes on enums. while (token_ != ']') Next(); Next(); } } - } while (IsNext(proto_mode_ ? ';' : ',') && token_ != '}'); + } while (IsNext(opts.proto_mode ? ';' : ',') && token_ != '}'); Expect('}'); if (enum_def.attributes.Lookup("bit_flags")) { for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end(); @@ -1372,15 +1372,15 @@ bool Parser::Parse(const char *source, const char **include_paths, // Includes must come before type declarations: for (;;) { // Parse pre-include proto statements if any: - if (proto_mode_ && + if (opts.proto_mode && (attribute_ == "option" || attribute_ == "syntax" || attribute_ == "package")) { ParseProtoDecl(); } else if (IsNext(kTokenInclude) || - (proto_mode_ && + (opts.proto_mode && attribute_ == "import" && IsNext(kTokenIdentifier))) { - if (proto_mode_ && attribute_ == "public") Next(); + if (opts.proto_mode && attribute_ == "public") Next(); auto name = attribute_; Expect(kTokenStringConstant); // Look for the file in include_paths. @@ -1403,8 +1403,8 @@ bool Parser::Parse(const char *source, const char **include_paths, // Any errors, we're done. return false; } - // We do not want to output code for any included files: - MarkGenerated(); + // We generally do not want to output code for any included files: + if (!opts.generate_all) MarkGenerated(); // This is the easiest way to continue this file after an include: // instead of saving and restoring all the state, we simply start the // file anew. This will cause it to encounter the same include statement @@ -1421,7 +1421,7 @@ bool Parser::Parse(const char *source, const char **include_paths, } // Now parse all other kinds of declarations: while (token_ != kTokenEof) { - if (proto_mode_) { + if (opts.proto_mode) { ParseProtoDecl(); } else if (token_ == kTokenNameSpace) { ParseNamespace(); diff --git a/tests/test.cpp b/tests/test.cpp index d25fa135..be364d40 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -281,8 +281,7 @@ void ParseAndGenerateTextTest() { // to ensure it is correct, we now generate text back from the binary, // and compare the two: std::string jsongen; - flatbuffers::GeneratorOptions opts; - GenerateText(parser, parser.builder_.GetBufferPointer(), opts, &jsongen); + GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen); if (jsongen != jsonfile) { printf("%s----------------\n%s", jsongen.c_str(), jsonfile.c_str()); @@ -426,15 +425,17 @@ void ParseProtoTest() { TEST_EQ(flatbuffers::LoadFile( "tests/prototest/test.golden", false, &goldenfile), true); + flatbuffers::IDLOptions opts; + opts.include_dependence_headers = false; + opts.proto_mode = true; + // Parse proto. - flatbuffers::Parser parser(false, true); + flatbuffers::Parser parser(opts); const char *include_directories[] = { "tests/prototest", nullptr }; TEST_EQ(parser.Parse(protofile.c_str(), include_directories), true); // Generate fbs. - flatbuffers::GeneratorOptions opts; - opts.include_dependence_headers = false; - auto fbs = flatbuffers::GenerateFBS(parser, "test", opts); + auto fbs = flatbuffers::GenerateFBS(parser, "test"); // Ensure generated file is parsable. flatbuffers::Parser parser2; @@ -677,9 +678,8 @@ void FuzzTest2() { TEST_EQ(parser.Parse(json.c_str()), true); std::string jsongen; - flatbuffers::GeneratorOptions opts; - opts.indent_step = 0; - GenerateText(parser, parser.builder_.GetBufferPointer(), opts, &jsongen); + parser.opts.indent_step = 0; + GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen); if (jsongen != json) { // These strings are larger than a megabyte, so we show the bytes around @@ -706,7 +706,9 @@ void FuzzTest2() { // Test that parser errors are actually generated. void TestError(const char *src, const char *error_substr, bool strict_json = false) { - flatbuffers::Parser parser(strict_json); + flatbuffers::IDLOptions opts; + opts.strict_json = strict_json; + flatbuffers::Parser parser(opts); TEST_EQ(parser.Parse(src), false); // Must signal error // Must be the error we're expecting TEST_NOTNULL(strstr(parser.error_.c_str(), error_substr)); @@ -794,9 +796,8 @@ void UnicodeTest() { "{ F:\"\\u20AC\\u00A2\\u30E6\\u30FC\\u30B6\\u30FC" "\\u5225\\u30B5\\u30A4\\u30C8\\x01\\x80\" }"), true); std::string jsongen; - flatbuffers::GeneratorOptions opts; - opts.indent_step = -1; - GenerateText(parser, parser.builder_.GetBufferPointer(), opts, &jsongen); + parser.opts.indent_step = -1; + GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen); TEST_EQ(jsongen == "{F: \"\\u20AC\\u00A2\\u30E6\\u30FC\\u30B6\\u30FC" "\\u5225\\u30B5\\u30A4\\u30C8\\x01\\x80\"}", true); } -- GitLab