diff --git a/CMakeLists.txt b/CMakeLists.txt index 93dac0aaf..81b994ed5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -147,6 +147,8 @@ set(FlatBuffers_Library_SRCS include/flatbuffers/vector.h include/flatbuffers/vector_downward.h include/flatbuffers/verifier.h + src/file_manager.cpp + src/file_name_manager.cpp src/idl_parser.cpp src/idl_gen_text.cpp src/reflection.cpp @@ -173,9 +175,6 @@ set(FlatBuffers_Compiler_SRCS src/idl_gen_grpc.cpp src/idl_gen_json_schema.cpp src/idl_gen_swift.cpp - src/file_name_saving_file_manager.cpp - src/file_binary_writer.cpp - src/file_writer.cpp src/idl_namer.h src/namer.h src/flatc.cpp diff --git a/grpc/src/compiler/python_generator.cc b/grpc/src/compiler/python_generator.cc index f217c9d5e..7e5026635 100644 --- a/grpc/src/compiler/python_generator.cc +++ b/grpc/src/compiler/python_generator.cc @@ -76,31 +76,6 @@ void FormatImports(std::stringstream& ss, const Imports& imports) { ss << "\n\n"; } -bool SaveStub(const std::string& filename, const Imports& imports, - const std::string& content) { - std::stringstream ss; - ss << "# Generated by the gRPC FlatBuffers compiler. DO NOT EDIT!\n" - << '\n' - << "from __future__ import annotations\n" - << '\n'; - FormatImports(ss, imports); - ss << content << '\n'; - - EnsureDirExists(StripFileName(filename)); - return flatbuffers::SaveFile(filename.c_str(), ss.str(), false); -} - -bool SaveService(const std::string& filename, const Imports& imports, - const std::string& content) { - std::stringstream ss; - ss << "# Generated by the gRPC FlatBuffers compiler. DO NOT EDIT!\n" << '\n'; - FormatImports(ss, imports); - ss << content << '\n'; - - EnsureDirExists(StripFileName(filename)); - return flatbuffers::SaveFile(filename.c_str(), ss.str(), false); -} - class BaseGenerator { protected: BaseGenerator(const Parser& parser, const Namer::Config& config, @@ -175,6 +150,20 @@ class StubGenerator : public BaseGenerator { } private: + bool SaveStub(const std::string& filename, const Imports& imports, + const std::string& content) { + std::stringstream ss; + ss << "# Generated by the gRPC FlatBuffers compiler. DO NOT EDIT!\n" + << '\n' + << "from __future__ import annotations\n" + << '\n'; + FormatImports(ss, imports); + ss << content << '\n'; + + EnsureDirExists(StripFileName(filename)); + return parser_.opts.file_saver->SaveFile(filename.c_str(), ss.str(), false); + } + void Generate(std::stringstream& ss, const ServiceDef* service, Imports* imports) { imports->Import("grpc"); @@ -293,6 +282,18 @@ class ServiceGenerator : public BaseGenerator { } private: + bool SaveService(const std::string& filename, const Imports& imports, + const std::string& content) { + std::stringstream ss; + ss << "# Generated by the gRPC FlatBuffers compiler. DO NOT EDIT!\n" + << '\n'; + FormatImports(ss, imports); + ss << content << '\n'; + + EnsureDirExists(StripFileName(filename)); + return parser_.opts.file_saver->SaveFile(filename.c_str(), ss.str(), false); + } + void GenerateStub(std::stringstream& ss, const ServiceDef* service, Imports* imports) { ss << "class " << service->name << "Stub"; diff --git a/include/flatbuffers/code_generator.h b/include/flatbuffers/code_generator.h index cc4df7f1c..bfd771dae 100644 --- a/include/flatbuffers/code_generator.h +++ b/include/flatbuffers/code_generator.h @@ -19,12 +19,14 @@ #include +#include "flatbuffers/file_manager.h" #include "flatbuffers/idl.h" namespace flatbuffers { struct CodeGenOptions { std::string output_path; + FileSaver* file_saver{nullptr}; }; // A code generator interface for producing converting flatbuffer schema into diff --git a/include/flatbuffers/file_manager.h b/include/flatbuffers/file_manager.h index 0941faef6..bafe6f29b 100644 --- a/include/flatbuffers/file_manager.h +++ b/include/flatbuffers/file_manager.h @@ -17,30 +17,52 @@ #ifndef FLATBUFFERS_FILE_MANAGER_H_ #define FLATBUFFERS_FILE_MANAGER_H_ +#include #include #include -#include "flatbuffers/util.h" - namespace flatbuffers { // A File interface to write data to file by default or // save only file names -class FileManager { +class FileSaver { public: - FileManager() = default; - virtual ~FileManager() = default; + FileSaver() = default; + virtual ~FileSaver() = default; - virtual bool SaveFile(const std::string& absolute_file_name, - const std::string& content) = 0; + virtual bool SaveFile(const char* name, const char* buf, size_t len, + bool binary) = 0; - virtual bool LoadFile(const std::string& absolute_file_name, - std::string* buf) = 0; + bool SaveFile(const char* name, const std::string& buf, bool binary) { + return SaveFile(name, buf.c_str(), buf.size(), binary); + } + + virtual void Finish() {} private: // Copying is not supported. - FileManager(const FileManager&) = delete; - FileManager& operator=(const FileManager&) = delete; + FileSaver(const FileSaver&) = delete; + FileSaver& operator=(const FileSaver&) = delete; + // Rule of 5 + FileSaver(FileSaver&&) = default; + FileSaver& operator=(FileSaver&&) = default; +}; + +class RealFileSaver final : public FileSaver { + public: + bool SaveFile(const char* name, const char* buf, size_t len, + bool binary) final; +}; + +class FileNameSaver final : public FileSaver { + public: + bool SaveFile(const char* name, const char* buf, size_t len, + bool binary) final; + + void Finish() final; + + private: + std::set file_names_{}; }; } // namespace flatbuffers diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h index 1c551e999..4139529a1 100644 --- a/include/flatbuffers/idl.h +++ b/include/flatbuffers/idl.h @@ -25,6 +25,7 @@ #include #include "flatbuffers/base.h" +#include "flatbuffers/file_manager.h" #include "flatbuffers/flatbuffers.h" #include "flatbuffers/flexbuffers.h" #include "flatbuffers/hash.h" @@ -634,6 +635,10 @@ inline bool operator<(const IncludedFile& a, const IncludedFile& b) { // Container of options that may apply to any of the source/text generators. struct IDLOptions { + // file saver + // shared pointer since this object gets copied and modified. + FileSaver* file_saver = nullptr; + // field case style options for C++ enum CaseStyle { CaseStyle_Unchanged = 0, CaseStyle_Upper, CaseStyle_Lower }; enum class ProtoIdGapAction { NO_OP, WARNING, ERROR }; diff --git a/include/flatbuffers/util.h b/include/flatbuffers/util.h index 0313e74d8..d8387e175 100644 --- a/include/flatbuffers/util.h +++ b/include/flatbuffers/util.h @@ -448,12 +448,16 @@ bool LoadFile(const char* name, bool binary, std::string* buf); // If "binary" is false data is written using ifstream's // text mode, otherwise data is written with no // transcoding. +// NOTE: this function is deprecated in favor of FileSaver class, +// but left here for compatibility. bool SaveFile(const char* name, const char* buf, size_t len, bool binary); // Save data "buf" into file "name" returning true if // successful, false otherwise. If "binary" is false // data is written using ifstream's text mode, otherwise // data is written with no transcoding. +// NOTE: this function is deprecated in favor of FileSaver class, +// but left here for compatibility. inline bool SaveFile(const char* name, const std::string& buf, bool binary) { return SaveFile(name, buf.c_str(), buf.size(), binary); } diff --git a/src/BUILD.bazel b/src/BUILD.bazel index 4b9fb7a81..cefc0b8d8 100644 --- a/src/BUILD.bazel +++ b/src/BUILD.bazel @@ -103,9 +103,8 @@ cc_library( "bfbs_gen_nim.cpp", "bfbs_gen_nim.h", "bfbs_namer.h", - "file_binary_writer.cpp", - "file_name_saving_file_manager.cpp", - "file_writer.cpp", + "file_manager.cpp", + "file_name_manager.cpp", "flatc_main.cpp", "idl_gen_binary.cpp", "idl_gen_binary.h", diff --git a/src/bfbs_gen_lua.cpp b/src/bfbs_gen_lua.cpp index 01cd2d992..f21892953 100644 --- a/src/bfbs_gen_lua.cpp +++ b/src/bfbs_gen_lua.cpp @@ -703,7 +703,7 @@ class LuaBfbsGenerator : public BaseBfbsGenerator { EnsureDirExists(path); const std::string file_name = options_.output_path + path + "/" + namer_.File(name); - SaveFile(file_name.c_str(), code, false); + options_.file_saver->SaveFile(file_name.c_str(), code, false); } std::unordered_set keywords_; diff --git a/src/bfbs_gen_nim.cpp b/src/bfbs_gen_nim.cpp index ec72930e6..d5ec2bd34 100644 --- a/src/bfbs_gen_nim.cpp +++ b/src/bfbs_gen_nim.cpp @@ -718,7 +718,7 @@ class NimBfbsGenerator : public BaseBfbsGenerator { EnsureDirExists(path); const std::string file_name = options_.output_path + path + "/" + namer_.File(name); - SaveFile(file_name.c_str(), code, false); + options_.file_saver->SaveFile(file_name.c_str(), code, false); } std::unordered_set keywords_; diff --git a/src/file_binary_writer.cpp b/src/file_binary_writer.cpp deleted file mode 100644 index 6fc762f38..000000000 --- a/src/file_binary_writer.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2023 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. - */ - -#include -#include -#include - -#include "flatbuffers/file_manager.h" - -namespace flatbuffers { - -class FileBinaryWriter : public FileManager { - public: - bool SaveFile(const std::string& absolute_file_name, - const std::string& content) override { - std::ofstream ofs(absolute_file_name, std::ofstream::binary); - if (!ofs.is_open()) return false; - ofs.write(content.c_str(), content.size()); - return !ofs.bad(); - } - - bool Loadfile(const std::string& absolute_file_name, std::string* output) { - if (DirExists(absolute_file_name.c_str())) return false; - std::ifstream ifs(absolute_file_name, std::ifstream::binary); - if (!ifs.is_open()) return false; - // The fastest way to read a file into a string. - ifs.seekg(0, std::ios::end); - auto size = ifs.tellg(); - (*output).resize(static_cast(size)); - ifs.seekg(0, std::ios::beg); - ifs.read(&(*output)[0], (*output).size()); - return !ifs.bad(); - } -}; - -} // namespace flatbuffers diff --git a/src/file_name_saving_file_manager.cpp b/src/file_manager.cpp similarity index 53% rename from src/file_name_saving_file_manager.cpp rename to src/file_manager.cpp index f0a356c05..13b1580af 100644 --- a/src/file_name_saving_file_manager.cpp +++ b/src/file_manager.cpp @@ -22,28 +22,12 @@ namespace flatbuffers { -class FileNameSavingFileManager : public FileManager { - public: - FileNameSavingFileManager(std::set file_names) - : file_names_(file_names) {} - - bool SaveFile(const std::string& absolute_file_name, - const std::string& content) override { - (void)content; - auto pair = file_names_.insert(absolute_file_name); - // pair.second indicates whether the insertion is - // successful or not. - return pair.second; - } - - bool Loadfile(const std::string& absolute_file_name, std::string* content) { - (void)absolute_file_name; - (void)content; - return false; - } - - private: - std::set file_names_; -}; +bool RealFileSaver::SaveFile(const char* name, const char* buf, size_t len, + bool binary) { + std::ofstream ofs(name, binary ? std::ofstream::binary : std::ofstream::out); + if (!ofs.is_open()) return false; + ofs.write(buf, len); + return !ofs.bad(); +} } // namespace flatbuffers diff --git a/src/file_name_manager.cpp b/src/file_name_manager.cpp new file mode 100644 index 000000000..aad63de8c --- /dev/null +++ b/src/file_name_manager.cpp @@ -0,0 +1,44 @@ +/* + * Copyright 2023 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. + */ + +#include +#include + +#include "flatbuffers/file_manager.h" + +namespace flatbuffers { + +bool FileNameSaver::SaveFile(const char* name, const char* buf, size_t len, + bool binary) { + (void)buf; + (void)len; + (void)binary; + + std::ignore = file_names_.insert(name); + + // we want to simulate always successful save + return true; +} + +void FileNameSaver::Finish() { + for (const auto& file_name : file_names_) { + // Just print the file names to standard output. + // No actual file is created. + std::cout << file_name << "\n"; + } +} + +} // namespace flatbuffers diff --git a/src/file_writer.cpp b/src/file_writer.cpp deleted file mode 100644 index 5cba285e2..000000000 --- a/src/file_writer.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2023 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. - */ - -#include -#include -#include - -#include "flatbuffers/file_manager.h" - -namespace flatbuffers { - -class FileWriter : public FileManager { - public: - bool SaveFile(const std::string& absolute_file_name, - const std::string& content) override { - std::ofstream ofs(absolute_file_name, std::ofstream::out); - if (!ofs.is_open()) return false; - ofs.write(content.c_str(), content.size()); - return !ofs.bad(); - } - - bool Loadfile(const std::string& absolute_file_name, std::string* output) { - if (DirExists(absolute_file_name.c_str())) return false; - std::ifstream ifs(absolute_file_name, std::ifstream::in); - if (!ifs.is_open()) return false; - // This is slower, but works correctly on all platforms for text files. - std::ostringstream oss; - oss << ifs.rdbuf(); - *output = oss.str(); - return !ifs.bad(); - } -}; - -} // namespace flatbuffers diff --git a/src/flatc.cpp b/src/flatc.cpp index 612f797cc..cab0ee395 100644 --- a/src/flatc.cpp +++ b/src/flatc.cpp @@ -716,7 +716,6 @@ FlatCOptions FlatCompiler::ParseFromCommandLineArguments(int argc, if (++argi >= argc) Error("missing path following: " + arg, true); options.annotate_schema = flatbuffers::PosixPath(argv[argi]); } else if (arg == "--file-names-only") { - // TODO (khhn): Provide 2 implementation options.file_names_only = true; } else if (arg == "--grpc-filename-suffix") { if (++argi >= argc) Error("missing gRPC filename suffix: " + arg, true); @@ -963,6 +962,7 @@ std::unique_ptr FlatCompiler::GenerateCode(const FlatCOptions& options, if (code_generator->SupportsBfbsGeneration()) { CodeGenOptions code_gen_options; code_gen_options.output_path = options.output_path; + code_gen_options.file_saver = options.opts.file_saver; const CodeGenerator::Status status = code_generator->GenerateCode( bfbs_buffer, bfbs_length, code_gen_options); diff --git a/src/flatc_main.cpp b/src/flatc_main.cpp index bcbb55d83..ce9b8c4a4 100644 --- a/src/flatc_main.cpp +++ b/src/flatc_main.cpp @@ -181,9 +181,25 @@ int main(int argc, const char* argv[]) { flatbuffers::NewTsCodeGenerator()); // Create the FlatC options by parsing the command line arguments. - const flatbuffers::FlatCOptions& options = + flatbuffers::FlatCOptions options = flatc.ParseFromCommandLineArguments(argc, argv); + // this exists here to ensure file_saver outlives the compilation process + std::unique_ptr file_saver; + if (options.file_names_only) { + file_saver.reset(new flatbuffers::FileNameSaver{}); + } else { + file_saver.reset(new flatbuffers::RealFileSaver{}); + } + + options.opts.file_saver = file_saver.get(); + FLATBUFFERS_ASSERT(options.opts.file_saver); + // Compile with the extracted FlatC options. - return flatc.Compile(options); + int success = flatc.Compile(options); + + // print file names if file-names-only option is set + options.opts.file_saver->Finish(); + + return success; } diff --git a/src/idl_gen_binary.cpp b/src/idl_gen_binary.cpp index a02805516..2afc6f77c 100644 --- a/src/idl_gen_binary.cpp +++ b/src/idl_gen_binary.cpp @@ -45,12 +45,12 @@ static bool GenerateBinary(const Parser& parser, const std::string& path, auto data_vec = parser.flex_builder_.GetBuffer(); auto data_ptr = reinterpret_cast(data(data_vec)); return !parser.flex_builder_.GetSize() || - flatbuffers::SaveFile( + parser.opts.file_saver->SaveFile( BinaryFileName(parser, path, file_name).c_str(), data_ptr, parser.flex_builder_.GetSize(), true); } return !parser.builder_.GetSize() || - flatbuffers::SaveFile( + parser.opts.file_saver->SaveFile( BinaryFileName(parser, path, file_name).c_str(), reinterpret_cast(parser.builder_.GetBufferPointer()), parser.builder_.GetSize(), true); diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp index d3441db4c..6207071f3 100644 --- a/src/idl_gen_cpp.cpp +++ b/src/idl_gen_cpp.cpp @@ -433,7 +433,8 @@ class CppGenerator : public BaseGenerator { GeneratedFileName(path_, file_name_ + "_bfbs", opts_); const auto final_code = code_.ToString(); - return SaveFile(file_path.c_str(), final_code, false); + return parser_.opts.file_saver->SaveFile(file_path.c_str(), final_code, + false); } // Iterate through all definitions we haven't generate code for (enums, @@ -764,8 +765,9 @@ class CppGenerator : public BaseGenerator { const auto final_code = code_.ToString(); // Save the file and optionally generate the binary schema code. - return SaveFile(file_path.c_str(), final_code, false) && - (!parser_.opts.binary_schema_gen_embed || generate_bfbs_embed()); + return parser_.opts.file_saver->SaveFile( + file_path.c_str(), final_code, + (!parser_.opts.binary_schema_gen_embed || generate_bfbs_embed())); } private: diff --git a/src/idl_gen_csharp.cpp b/src/idl_gen_csharp.cpp index 223402f4c..f02a17fd2 100644 --- a/src/idl_gen_csharp.cpp +++ b/src/idl_gen_csharp.cpp @@ -241,7 +241,7 @@ class CSharpGenerator : public BaseGenerator { } filename += options.filename_extension.empty() ? ".cs" : options.filename_extension; - return SaveFile(filename.c_str(), code, false); + return options.file_saver->SaveFile(filename.c_str(), code, false); } const Namespace* CurrentNameSpace() const { return cur_name_space_; } diff --git a/src/idl_gen_dart.cpp b/src/idl_gen_dart.cpp index d0b093016..589e5d91f 100644 --- a/src/idl_gen_dart.cpp +++ b/src/idl_gen_dart.cpp @@ -163,7 +163,8 @@ class DartGenerator : public BaseGenerator { code += "\n"; code += kv->second; - if (!SaveFile(Filename(kv->first).c_str(), code, false)) { + if (!parser_.opts.file_saver->SaveFile(Filename(kv->first).c_str(), code, + false)) { return false; } } diff --git a/src/idl_gen_fbs.cpp b/src/idl_gen_fbs.cpp index 1d7fd9a43..da4289587 100644 --- a/src/idl_gen_fbs.cpp +++ b/src/idl_gen_fbs.cpp @@ -409,7 +409,8 @@ static bool GenerateFBS(const Parser& parser, const std::string& path, "When you use --proto, that you should check for conformity " "yourself, using the existing --conform"); } - return SaveFile((path + file_name + ".fbs").c_str(), fbs, false); + return parser.opts.file_saver->SaveFile((path + file_name + ".fbs").c_str(), + fbs, false); } class FBSCodeGenerator : public CodeGenerator { diff --git a/src/idl_gen_go.cpp b/src/idl_gen_go.cpp index 46585b3e6..9e743dd2d 100644 --- a/src/idl_gen_go.cpp +++ b/src/idl_gen_go.cpp @@ -113,7 +113,7 @@ class GoGenerator : public BaseGenerator { code += one_file_code; const std::string filename = GeneratedFileName(path_, file_name_, parser_.opts); - return SaveFile(filename.c_str(), code, false); + return parser_.opts.file_saver->SaveFile(filename.c_str(), code, false); } return true; @@ -1627,7 +1627,7 @@ class GoGenerator : public BaseGenerator { std::string file = namer_.File(def, SkipFile::Suffix); EnsureDirExists(directory); std::string filename = directory + file; - return SaveFile(filename.c_str(), code, false); + return parser_.opts.file_saver->SaveFile(filename.c_str(), code, false); } // Create the full name of the imported namespace (format: A__B__C). diff --git a/src/idl_gen_grpc.cpp b/src/idl_gen_grpc.cpp index dc5bed3f6..476fa5ffe 100644 --- a/src/idl_gen_grpc.cpp +++ b/src/idl_gen_grpc.cpp @@ -331,7 +331,8 @@ class GoGRPCGenerator : public flatbuffers::BaseGenerator { grpc_go_generator::GenerateServiceSource(&file, service.get(), &p); std::string filename = NamespaceDir(*def->defined_namespace) + def->name + "_grpc.go"; - if (!flatbuffers::SaveFile(filename.c_str(), output, false)) return false; + if (!parser_.opts.file_saver->SaveFile(filename.c_str(), output, false)) + return false; } return true; } @@ -393,11 +394,11 @@ bool GenerateCppGRPC(const Parser& parser, const std::string& path, grpc_cpp_generator::GetSourceServices(&fbfile, generator_parameters) + grpc_cpp_generator::GetSourceEpilogue(&fbfile, generator_parameters); - return flatbuffers::SaveFile( + return parser.opts.file_saver->SaveFile( (path + file_name + ".grpc" + opts.grpc_filename_suffix + ".h") .c_str(), header_code, false) && - flatbuffers::SaveFile( + parser.opts.file_saver->SaveFile( (path + file_name + ".grpc" + opts.grpc_filename_suffix + ".cc") .c_str(), source_code, false); @@ -421,7 +422,8 @@ class JavaGRPCGenerator : public flatbuffers::BaseGenerator { grpc_java_generator::GenerateServiceSource(&file, service.get(), &p); std::string filename = NamespaceDir(*def->defined_namespace) + def->name + "Grpc.java"; - if (!flatbuffers::SaveFile(filename.c_str(), output, false)) return false; + if (!parser_.opts.file_saver->SaveFile(filename.c_str(), output, false)) + return false; } return true; } @@ -479,7 +481,8 @@ class SwiftGRPCGenerator : public flatbuffers::BaseGenerator { } const auto final_code = code_.ToString(); const auto filename = GeneratedFileName(path_, file_name_); - return SaveFile(filename.c_str(), final_code, false); + return parser_.opts.file_saver->SaveFile(filename.c_str(), final_code, + false); } static std::string GeneratedFileName(const std::string& path, @@ -516,13 +519,16 @@ class TSGRPCGenerator : public flatbuffers::BaseGenerator { auto service = file.service(i); code_ += grpc_ts_generator::Generate(&file, service.get(), file_name_); const auto ts_name = GeneratedFileName(path_, file_name_); - if (!SaveFile(ts_name.c_str(), code_.ToString(), false)) return false; + if (!parser_.opts.file_saver->SaveFile(ts_name.c_str(), code_.ToString(), + false)) + return false; code_.Clear(); code_ += grpc_ts_generator::GenerateInterface(&file, service.get(), file_name_); const auto ts_interface_name = GeneratedFileName(path_, file_name_, true); - if (!SaveFile(ts_interface_name.c_str(), code_.ToString(), false)) + if (!parser_.opts.file_saver->SaveFile(ts_interface_name.c_str(), + code_.ToString(), false)) return false; } return true; diff --git a/src/idl_gen_java.cpp b/src/idl_gen_java.cpp index 143a361b3..32214e4e5 100644 --- a/src/idl_gen_java.cpp +++ b/src/idl_gen_java.cpp @@ -225,7 +225,7 @@ class JavaGenerator : public BaseGenerator { EnsureDirExists(dirs); const std::string filename = dirs + namer_.File(defname, /*skips=*/SkipFile::Suffix); - return SaveFile(filename.c_str(), code, false); + return parser_.opts.file_saver->SaveFile(filename.c_str(), code, false); } const Namespace* CurrentNameSpace() const { return cur_name_space_; } diff --git a/src/idl_gen_json_schema.cpp b/src/idl_gen_json_schema.cpp index 9ab290516..e24d6ce12 100644 --- a/src/idl_gen_json_schema.cpp +++ b/src/idl_gen_json_schema.cpp @@ -330,7 +330,7 @@ class JsonSchemaGenerator : public BaseGenerator { bool save() const { const auto file_path = GeneratedFileName(path_, file_name_, parser_.opts); - return SaveFile(file_path.c_str(), code_, false); + return parser_.opts.file_saver->SaveFile(file_path.c_str(), code_, false); } const std::string getJson() { return code_; } diff --git a/src/idl_gen_kotlin.cpp b/src/idl_gen_kotlin.cpp index cda07a809..2ed89d419 100644 --- a/src/idl_gen_kotlin.cpp +++ b/src/idl_gen_kotlin.cpp @@ -156,7 +156,7 @@ class KotlinGenerator : public BaseGenerator { EnsureDirExists(dirs); const std::string filename = dirs + namer_.File(defname, /*skips=*/SkipFile::Suffix); - return SaveFile(filename.c_str(), code, false); + return parser_.opts.file_saver->SaveFile(filename.c_str(), code, false); } static bool IsEnum(const Type& type) { diff --git a/src/idl_gen_kotlin_kmp.cpp b/src/idl_gen_kotlin_kmp.cpp index 89bee9447..571d452f0 100644 --- a/src/idl_gen_kotlin_kmp.cpp +++ b/src/idl_gen_kotlin_kmp.cpp @@ -161,7 +161,7 @@ class KotlinKMPGenerator : public BaseGenerator { EnsureDirExists(dirs); const std::string filename = dirs + namer_.File(defname, /*skips=*/SkipFile::Suffix); - return SaveFile(filename.c_str(), code, false); + return parser_.opts.file_saver->SaveFile(filename.c_str(), code, false); } static bool IsEnum(const Type& type) { diff --git a/src/idl_gen_lobster.cpp b/src/idl_gen_lobster.cpp index 33c1071ec..dfe3ac8e4 100644 --- a/src/idl_gen_lobster.cpp +++ b/src/idl_gen_lobster.cpp @@ -403,8 +403,9 @@ class LobsterGenerator : public BaseGenerator { auto& struct_def = **it; GenStruct(struct_def, &code); } - return SaveFile(GeneratedFileName(path_, file_name_, parser_.opts).c_str(), - code, false); + return parser_.opts.file_saver->SaveFile( + GeneratedFileName(path_, file_name_, parser_.opts).c_str(), code, + false); } private: diff --git a/src/idl_gen_php.cpp b/src/idl_gen_php.cpp index 48de73c52..4b05703e8 100644 --- a/src/idl_gen_php.cpp +++ b/src/idl_gen_php.cpp @@ -95,7 +95,7 @@ class PhpGenerator : public BaseGenerator { std::string filename = NamespaceDir(*def.defined_namespace) + def.name + ".php"; - return SaveFile(filename.c_str(), code, false); + return parser_.opts.file_saver->SaveFile(filename.c_str(), code, false); } // Begin a class declaration. diff --git a/src/idl_gen_python.cpp b/src/idl_gen_python.cpp index b034ec8c3..314c3c2d8 100644 --- a/src/idl_gen_python.cpp +++ b/src/idl_gen_python.cpp @@ -120,7 +120,7 @@ class PythonStubGenerator { ss << content.str() << '\n'; EnsureDirExists(StripFileName(filename)); - return flatbuffers::SaveFile(filename.c_str(), ss.str(), false); + return parser_.opts.file_saver->SaveFile(filename.c_str(), ss.str(), false); } static void DeclareUOffset(std::stringstream& stub, Imports* imports) { @@ -2889,11 +2889,11 @@ class PythonGenerator : public BaseGenerator { i = directories.find(kPathSeparator, i + 1)) { const std::string init_py = directories.substr(0, i) + kPathSeparator + "__init__.py"; - SaveFile(init_py.c_str(), "", false); + parser_.opts.file_saver->SaveFile(init_py.c_str(), "", false); } const std::string filename = directories + defname; - return SaveFile(filename.c_str(), code, false); + return parser_.opts.file_saver->SaveFile(filename.c_str(), code, false); } private: diff --git a/src/idl_gen_rust.cpp b/src/idl_gen_rust.cpp index 22df1dcf0..05a58e6bb 100644 --- a/src/idl_gen_rust.cpp +++ b/src/idl_gen_rust.cpp @@ -336,8 +336,8 @@ static bool GenerateRustModuleRootFile(const Parser& parser, "Do not modify."; code += "// @generated"; root_module.GenerateImports(code); - const bool success = - SaveFile((output_dir + "mod.rs").c_str(), code.ToString(), false); + const bool success = parser.opts.file_saver->SaveFile( + (output_dir + "mod.rs").c_str(), code.ToString(), false); code.Clear(); return success; } @@ -394,8 +394,8 @@ class RustGenerator : public BaseGenerator { namer_.Directories(*symbol.defined_namespace); EnsureDirExists(directories); const std::string file_path = directories + namer_.File(symbol); - const bool save_success = - SaveFile(file_path.c_str(), code_.ToString(), /*binary=*/false); + const bool save_success = parser_.opts.file_saver->SaveFile( + file_path.c_str(), code_.ToString(), /*binary=*/false); if (!save_success) return false; } return true; @@ -496,7 +496,8 @@ class RustGenerator : public BaseGenerator { const auto file_path = GeneratedFileName(path_, file_name_, parser_.opts); const auto final_code = code_.ToString(); - return SaveFile(file_path.c_str(), final_code, false); + return parser_.opts.file_saver->SaveFile(file_path.c_str(), final_code, + false); } private: diff --git a/src/idl_gen_swift.cpp b/src/idl_gen_swift.cpp index e0e231978..6e4910937 100644 --- a/src/idl_gen_swift.cpp +++ b/src/idl_gen_swift.cpp @@ -191,7 +191,8 @@ class SwiftGenerator : public BaseGenerator { const auto filename = GeneratedFileName(path_, file_name_, parser_.opts); const auto final_code = code_.ToString(); - return SaveFile(filename.c_str(), final_code, false); + return parser_.opts.file_saver->SaveFile(filename.c_str(), final_code, + false); } void GenerateCode() { diff --git a/src/idl_gen_text.cpp b/src/idl_gen_text.cpp index ea1738c71..690830553 100644 --- a/src/idl_gen_text.cpp +++ b/src/idl_gen_text.cpp @@ -440,8 +440,9 @@ const char* GenTextFile(const Parser& parser, const std::string& path, if (parser.opts.use_flexbuffers) { std::string json; parser.flex_root_.ToString(true, parser.opts.strict_json, json); - return flatbuffers::SaveFile(TextFileName(path, file_name).c_str(), - json.c_str(), json.size(), true) + return parser.opts.file_saver->SaveFile( + TextFileName(path, file_name).c_str(), json.c_str(), json.size(), + true) ? nullptr : "SaveFile failed"; } @@ -449,8 +450,8 @@ const char* GenTextFile(const Parser& parser, const std::string& path, std::string text; auto err = GenText(parser, parser.builder_.GetBufferPointer(), &text); if (err) return err; - return flatbuffers::SaveFile(TextFileName(path, file_name).c_str(), text, - false) + return parser.opts.file_saver->SaveFile(TextFileName(path, file_name).c_str(), + text, false) ? nullptr : "SaveFile failed"; } diff --git a/src/idl_gen_ts.cpp b/src/idl_gen_ts.cpp index aed7d59f8..446be30c4 100644 --- a/src/idl_gen_ts.cpp +++ b/src/idl_gen_ts.cpp @@ -178,7 +178,7 @@ class TsGenerator : public BaseGenerator { EnsureDirExists(dirs); auto basename = dirs + namer_.File(definition, SkipFile::Suffix); - return SaveFile(basename.c_str(), code, false); + return parser_.opts.file_saver->SaveFile(basename.c_str(), code, false); } void TrackNsDef(const Definition& definition, std::string type_name) { @@ -319,7 +319,9 @@ class TsGenerator : public BaseGenerator { export_counter++; } - if (export_counter > 0) SaveFile(it.second.filepath.c_str(), code, false); + if (export_counter > 0) + parser_.opts.file_saver->SaveFile(it.second.filepath.c_str(), code, + false); } } diff --git a/tests/fuzzer/CMakeLists.txt b/tests/fuzzer/CMakeLists.txt index 03a508628..272c121aa 100644 --- a/tests/fuzzer/CMakeLists.txt +++ b/tests/fuzzer/CMakeLists.txt @@ -110,6 +110,8 @@ set(FlatBuffers_Library_SRCS ${FLATBUFFERS_DIR}/include/flatbuffers/vector.h ${FLATBUFFERS_DIR}/include/flatbuffers/vector_downward.h ${FLATBUFFERS_DIR}/include/flatbuffers/verifier.h + ${FLATBUFFERS_DIR}/src/file_manager.cpp + ${FLATBUFFERS_DIR}/src/file_name_manager.cpp ${FLATBUFFERS_DIR}/src/idl_parser.cpp ${FLATBUFFERS_DIR}/src/idl_gen_text.cpp ${FLATBUFFERS_DIR}/src/reflection.cpp @@ -139,9 +141,8 @@ set(FlatBuffers_Compiler_SRCS ${FLATBUFFERS_DIR}/src/idl_gen_grpc.cpp ${FLATBUFFERS_DIR}/src/idl_gen_json_schema.cpp ${FLATBUFFERS_DIR}/src/idl_gen_swift.cpp - ${FLATBUFFERS_DIR}/src/file_name_saving_file_manager.cpp - ${FLATBUFFERS_DIR}/src/file_binary_writer.cpp - ${FLATBUFFERS_DIR}/src/file_writer.cpp + ${FLATBUFFERS_DIR}/src/file_manager.cpp + ${FLATBUFFERS_DIR}/src/file_name_manager.cpp ${FLATBUFFERS_DIR}/src/idl_namer.h ${FLATBUFFERS_DIR}/src/namer.h ${FLATBUFFERS_DIR}/src/flatc.cpp @@ -260,7 +261,7 @@ if(BUILD_DEBUGGER) > -fno-limit-debug-info ) - + target_link_libraries( flatbuffers_nonfuzz PUBLIC @@ -293,5 +294,5 @@ if(BUILD_DEBUGGER) COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../monster_test.bfbs ${CMAKE_CURRENT_BINARY_DIR}/monster_test.bfbs) - + endif(BUILD_DEBUGGER)