Implement --file-names-only (#8788)

* flatc builds and seems to work, some of the extra targets are having linker errors

* fix build system

* pipeline failures

* un-rename files

* refactor to use unique_ptr

* typo

* rm make_unique, add comments

* fix cmake

---------

Co-authored-by: Wouter van Oortmerssen <aardappel@gmail.com>
This commit is contained in:
Justin Davis
2025-12-02 23:37:06 -05:00
committed by GitHub
parent 0b60686e3d
commit a1e125af11
34 changed files with 207 additions and 210 deletions

View File

@@ -147,6 +147,8 @@ set(FlatBuffers_Library_SRCS
include/flatbuffers/vector.h include/flatbuffers/vector.h
include/flatbuffers/vector_downward.h include/flatbuffers/vector_downward.h
include/flatbuffers/verifier.h include/flatbuffers/verifier.h
src/file_manager.cpp
src/file_name_manager.cpp
src/idl_parser.cpp src/idl_parser.cpp
src/idl_gen_text.cpp src/idl_gen_text.cpp
src/reflection.cpp src/reflection.cpp
@@ -173,9 +175,6 @@ set(FlatBuffers_Compiler_SRCS
src/idl_gen_grpc.cpp src/idl_gen_grpc.cpp
src/idl_gen_json_schema.cpp src/idl_gen_json_schema.cpp
src/idl_gen_swift.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/idl_namer.h
src/namer.h src/namer.h
src/flatc.cpp src/flatc.cpp

View File

@@ -76,31 +76,6 @@ void FormatImports(std::stringstream& ss, const Imports& imports) {
ss << "\n\n"; 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 { class BaseGenerator {
protected: protected:
BaseGenerator(const Parser& parser, const Namer::Config& config, BaseGenerator(const Parser& parser, const Namer::Config& config,
@@ -175,6 +150,20 @@ class StubGenerator : public BaseGenerator {
} }
private: 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, void Generate(std::stringstream& ss, const ServiceDef* service,
Imports* imports) { Imports* imports) {
imports->Import("grpc"); imports->Import("grpc");
@@ -293,6 +282,18 @@ class ServiceGenerator : public BaseGenerator {
} }
private: 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, void GenerateStub(std::stringstream& ss, const ServiceDef* service,
Imports* imports) { Imports* imports) {
ss << "class " << service->name << "Stub"; ss << "class " << service->name << "Stub";

View File

@@ -19,12 +19,14 @@
#include <string> #include <string>
#include "flatbuffers/file_manager.h"
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
namespace flatbuffers { namespace flatbuffers {
struct CodeGenOptions { struct CodeGenOptions {
std::string output_path; std::string output_path;
FileSaver* file_saver{nullptr};
}; };
// A code generator interface for producing converting flatbuffer schema into // A code generator interface for producing converting flatbuffer schema into

View File

@@ -17,30 +17,52 @@
#ifndef FLATBUFFERS_FILE_MANAGER_H_ #ifndef FLATBUFFERS_FILE_MANAGER_H_
#define FLATBUFFERS_FILE_MANAGER_H_ #define FLATBUFFERS_FILE_MANAGER_H_
#include <cstddef>
#include <set> #include <set>
#include <string> #include <string>
#include "flatbuffers/util.h"
namespace flatbuffers { namespace flatbuffers {
// A File interface to write data to file by default or // A File interface to write data to file by default or
// save only file names // save only file names
class FileManager { class FileSaver {
public: public:
FileManager() = default; FileSaver() = default;
virtual ~FileManager() = default; virtual ~FileSaver() = default;
virtual bool SaveFile(const std::string& absolute_file_name, virtual bool SaveFile(const char* name, const char* buf, size_t len,
const std::string& content) = 0; bool binary) = 0;
virtual bool LoadFile(const std::string& absolute_file_name, bool SaveFile(const char* name, const std::string& buf, bool binary) {
std::string* buf) = 0; return SaveFile(name, buf.c_str(), buf.size(), binary);
}
virtual void Finish() {}
private: private:
// Copying is not supported. // Copying is not supported.
FileManager(const FileManager&) = delete; FileSaver(const FileSaver&) = delete;
FileManager& operator=(const FileManager&) = 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<std::string> file_names_{};
}; };
} // namespace flatbuffers } // namespace flatbuffers

View File

@@ -25,6 +25,7 @@
#include <vector> #include <vector>
#include "flatbuffers/base.h" #include "flatbuffers/base.h"
#include "flatbuffers/file_manager.h"
#include "flatbuffers/flatbuffers.h" #include "flatbuffers/flatbuffers.h"
#include "flatbuffers/flexbuffers.h" #include "flatbuffers/flexbuffers.h"
#include "flatbuffers/hash.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. // Container of options that may apply to any of the source/text generators.
struct IDLOptions { struct IDLOptions {
// file saver
// shared pointer since this object gets copied and modified.
FileSaver* file_saver = nullptr;
// field case style options for C++ // field case style options for C++
enum CaseStyle { CaseStyle_Unchanged = 0, CaseStyle_Upper, CaseStyle_Lower }; enum CaseStyle { CaseStyle_Unchanged = 0, CaseStyle_Upper, CaseStyle_Lower };
enum class ProtoIdGapAction { NO_OP, WARNING, ERROR }; enum class ProtoIdGapAction { NO_OP, WARNING, ERROR };

View File

@@ -448,12 +448,16 @@ bool LoadFile(const char* name, bool binary, std::string* buf);
// If "binary" is false data is written using ifstream's // If "binary" is false data is written using ifstream's
// text mode, otherwise data is written with no // text mode, otherwise data is written with no
// transcoding. // 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); bool SaveFile(const char* name, const char* buf, size_t len, bool binary);
// Save data "buf" into file "name" returning true if // Save data "buf" into file "name" returning true if
// successful, false otherwise. If "binary" is false // successful, false otherwise. If "binary" is false
// data is written using ifstream's text mode, otherwise // data is written using ifstream's text mode, otherwise
// data is written with no transcoding. // 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) { inline bool SaveFile(const char* name, const std::string& buf, bool binary) {
return SaveFile(name, buf.c_str(), buf.size(), binary); return SaveFile(name, buf.c_str(), buf.size(), binary);
} }

View File

@@ -103,9 +103,8 @@ cc_library(
"bfbs_gen_nim.cpp", "bfbs_gen_nim.cpp",
"bfbs_gen_nim.h", "bfbs_gen_nim.h",
"bfbs_namer.h", "bfbs_namer.h",
"file_binary_writer.cpp", "file_manager.cpp",
"file_name_saving_file_manager.cpp", "file_name_manager.cpp",
"file_writer.cpp",
"flatc_main.cpp", "flatc_main.cpp",
"idl_gen_binary.cpp", "idl_gen_binary.cpp",
"idl_gen_binary.h", "idl_gen_binary.h",

View File

@@ -703,7 +703,7 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
EnsureDirExists(path); EnsureDirExists(path);
const std::string file_name = const std::string file_name =
options_.output_path + path + "/" + namer_.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<std::string> keywords_; std::unordered_set<std::string> keywords_;

View File

@@ -718,7 +718,7 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
EnsureDirExists(path); EnsureDirExists(path);
const std::string file_name = const std::string file_name =
options_.output_path + path + "/" + namer_.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<std::string> keywords_; std::unordered_set<std::string> keywords_;

View File

@@ -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 <fstream>
#include <set>
#include <string>
#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_t>(size));
ifs.seekg(0, std::ios::beg);
ifs.read(&(*output)[0], (*output).size());
return !ifs.bad();
}
};
} // namespace flatbuffers

View File

@@ -22,28 +22,12 @@
namespace flatbuffers { namespace flatbuffers {
class FileNameSavingFileManager : public FileManager { bool RealFileSaver::SaveFile(const char* name, const char* buf, size_t len,
public: bool binary) {
FileNameSavingFileManager(std::set<std::string> file_names) std::ofstream ofs(name, binary ? std::ofstream::binary : std::ofstream::out);
: file_names_(file_names) {} if (!ofs.is_open()) return false;
ofs.write(buf, len);
bool SaveFile(const std::string& absolute_file_name, return !ofs.bad();
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<std::string> file_names_;
};
} // namespace flatbuffers } // namespace flatbuffers

44
src/file_name_manager.cpp Normal file
View File

@@ -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 <iostream>
#include <tuple>
#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

View File

@@ -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 <fstream>
#include <set>
#include <string>
#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

View File

@@ -716,7 +716,6 @@ FlatCOptions FlatCompiler::ParseFromCommandLineArguments(int argc,
if (++argi >= argc) Error("missing path following: " + arg, true); if (++argi >= argc) Error("missing path following: " + arg, true);
options.annotate_schema = flatbuffers::PosixPath(argv[argi]); options.annotate_schema = flatbuffers::PosixPath(argv[argi]);
} else if (arg == "--file-names-only") { } else if (arg == "--file-names-only") {
// TODO (khhn): Provide 2 implementation
options.file_names_only = true; options.file_names_only = true;
} else if (arg == "--grpc-filename-suffix") { } else if (arg == "--grpc-filename-suffix") {
if (++argi >= argc) Error("missing gRPC filename suffix: " + arg, true); if (++argi >= argc) Error("missing gRPC filename suffix: " + arg, true);
@@ -963,6 +962,7 @@ std::unique_ptr<Parser> FlatCompiler::GenerateCode(const FlatCOptions& options,
if (code_generator->SupportsBfbsGeneration()) { if (code_generator->SupportsBfbsGeneration()) {
CodeGenOptions code_gen_options; CodeGenOptions code_gen_options;
code_gen_options.output_path = options.output_path; code_gen_options.output_path = options.output_path;
code_gen_options.file_saver = options.opts.file_saver;
const CodeGenerator::Status status = code_generator->GenerateCode( const CodeGenerator::Status status = code_generator->GenerateCode(
bfbs_buffer, bfbs_length, code_gen_options); bfbs_buffer, bfbs_length, code_gen_options);

View File

@@ -181,9 +181,25 @@ int main(int argc, const char* argv[]) {
flatbuffers::NewTsCodeGenerator()); flatbuffers::NewTsCodeGenerator());
// Create the FlatC options by parsing the command line arguments. // Create the FlatC options by parsing the command line arguments.
const flatbuffers::FlatCOptions& options = flatbuffers::FlatCOptions options =
flatc.ParseFromCommandLineArguments(argc, argv); flatc.ParseFromCommandLineArguments(argc, argv);
// this exists here to ensure file_saver outlives the compilation process
std::unique_ptr<flatbuffers::FileSaver> 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. // 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;
} }

View File

@@ -45,12 +45,12 @@ static bool GenerateBinary(const Parser& parser, const std::string& path,
auto data_vec = parser.flex_builder_.GetBuffer(); auto data_vec = parser.flex_builder_.GetBuffer();
auto data_ptr = reinterpret_cast<char*>(data(data_vec)); auto data_ptr = reinterpret_cast<char*>(data(data_vec));
return !parser.flex_builder_.GetSize() || return !parser.flex_builder_.GetSize() ||
flatbuffers::SaveFile( parser.opts.file_saver->SaveFile(
BinaryFileName(parser, path, file_name).c_str(), data_ptr, BinaryFileName(parser, path, file_name).c_str(), data_ptr,
parser.flex_builder_.GetSize(), true); parser.flex_builder_.GetSize(), true);
} }
return !parser.builder_.GetSize() || return !parser.builder_.GetSize() ||
flatbuffers::SaveFile( parser.opts.file_saver->SaveFile(
BinaryFileName(parser, path, file_name).c_str(), BinaryFileName(parser, path, file_name).c_str(),
reinterpret_cast<char*>(parser.builder_.GetBufferPointer()), reinterpret_cast<char*>(parser.builder_.GetBufferPointer()),
parser.builder_.GetSize(), true); parser.builder_.GetSize(), true);

View File

@@ -433,7 +433,8 @@ class CppGenerator : public BaseGenerator {
GeneratedFileName(path_, file_name_ + "_bfbs", opts_); GeneratedFileName(path_, file_name_ + "_bfbs", opts_);
const auto final_code = code_.ToString(); 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, // 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(); const auto final_code = code_.ToString();
// Save the file and optionally generate the binary schema code. // Save the file and optionally generate the binary schema code.
return SaveFile(file_path.c_str(), final_code, false) && return parser_.opts.file_saver->SaveFile(
(!parser_.opts.binary_schema_gen_embed || generate_bfbs_embed()); file_path.c_str(), final_code,
(!parser_.opts.binary_schema_gen_embed || generate_bfbs_embed()));
} }
private: private:

View File

@@ -241,7 +241,7 @@ class CSharpGenerator : public BaseGenerator {
} }
filename += filename +=
options.filename_extension.empty() ? ".cs" : options.filename_extension; 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_; } const Namespace* CurrentNameSpace() const { return cur_name_space_; }

View File

@@ -163,7 +163,8 @@ class DartGenerator : public BaseGenerator {
code += "\n"; code += "\n";
code += kv->second; 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; return false;
} }
} }

View File

@@ -409,7 +409,8 @@ static bool GenerateFBS(const Parser& parser, const std::string& path,
"When you use --proto, that you should check for conformity " "When you use --proto, that you should check for conformity "
"yourself, using the existing --conform"); "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 { class FBSCodeGenerator : public CodeGenerator {

View File

@@ -113,7 +113,7 @@ class GoGenerator : public BaseGenerator {
code += one_file_code; code += one_file_code;
const std::string filename = const std::string filename =
GeneratedFileName(path_, file_name_, parser_.opts); 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; return true;
@@ -1627,7 +1627,7 @@ class GoGenerator : public BaseGenerator {
std::string file = namer_.File(def, SkipFile::Suffix); std::string file = namer_.File(def, SkipFile::Suffix);
EnsureDirExists(directory); EnsureDirExists(directory);
std::string filename = directory + file; 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). // Create the full name of the imported namespace (format: A__B__C).

View File

@@ -331,7 +331,8 @@ class GoGRPCGenerator : public flatbuffers::BaseGenerator {
grpc_go_generator::GenerateServiceSource(&file, service.get(), &p); grpc_go_generator::GenerateServiceSource(&file, service.get(), &p);
std::string filename = std::string filename =
NamespaceDir(*def->defined_namespace) + def->name + "_grpc.go"; 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; 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::GetSourceServices(&fbfile, generator_parameters) +
grpc_cpp_generator::GetSourceEpilogue(&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") (path + file_name + ".grpc" + opts.grpc_filename_suffix + ".h")
.c_str(), .c_str(),
header_code, false) && header_code, false) &&
flatbuffers::SaveFile( parser.opts.file_saver->SaveFile(
(path + file_name + ".grpc" + opts.grpc_filename_suffix + ".cc") (path + file_name + ".grpc" + opts.grpc_filename_suffix + ".cc")
.c_str(), .c_str(),
source_code, false); source_code, false);
@@ -421,7 +422,8 @@ class JavaGRPCGenerator : public flatbuffers::BaseGenerator {
grpc_java_generator::GenerateServiceSource(&file, service.get(), &p); grpc_java_generator::GenerateServiceSource(&file, service.get(), &p);
std::string filename = std::string filename =
NamespaceDir(*def->defined_namespace) + def->name + "Grpc.java"; 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; return true;
} }
@@ -479,7 +481,8 @@ class SwiftGRPCGenerator : public flatbuffers::BaseGenerator {
} }
const auto final_code = code_.ToString(); const auto final_code = code_.ToString();
const auto filename = GeneratedFileName(path_, file_name_); 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, static std::string GeneratedFileName(const std::string& path,
@@ -516,13 +519,16 @@ class TSGRPCGenerator : public flatbuffers::BaseGenerator {
auto service = file.service(i); auto service = file.service(i);
code_ += grpc_ts_generator::Generate(&file, service.get(), file_name_); code_ += grpc_ts_generator::Generate(&file, service.get(), file_name_);
const auto ts_name = GeneratedFileName(path_, 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_.Clear();
code_ += grpc_ts_generator::GenerateInterface(&file, service.get(), code_ += grpc_ts_generator::GenerateInterface(&file, service.get(),
file_name_); file_name_);
const auto ts_interface_name = GeneratedFileName(path_, file_name_, true); 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 false;
} }
return true; return true;

View File

@@ -225,7 +225,7 @@ class JavaGenerator : public BaseGenerator {
EnsureDirExists(dirs); EnsureDirExists(dirs);
const std::string filename = const std::string filename =
dirs + namer_.File(defname, /*skips=*/SkipFile::Suffix); 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_; } const Namespace* CurrentNameSpace() const { return cur_name_space_; }

View File

@@ -330,7 +330,7 @@ class JsonSchemaGenerator : public BaseGenerator {
bool save() const { bool save() const {
const auto file_path = GeneratedFileName(path_, file_name_, parser_.opts); 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_; } const std::string getJson() { return code_; }

View File

@@ -156,7 +156,7 @@ class KotlinGenerator : public BaseGenerator {
EnsureDirExists(dirs); EnsureDirExists(dirs);
const std::string filename = const std::string filename =
dirs + namer_.File(defname, /*skips=*/SkipFile::Suffix); 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) { static bool IsEnum(const Type& type) {

View File

@@ -161,7 +161,7 @@ class KotlinKMPGenerator : public BaseGenerator {
EnsureDirExists(dirs); EnsureDirExists(dirs);
const std::string filename = const std::string filename =
dirs + namer_.File(defname, /*skips=*/SkipFile::Suffix); 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) { static bool IsEnum(const Type& type) {

View File

@@ -403,8 +403,9 @@ class LobsterGenerator : public BaseGenerator {
auto& struct_def = **it; auto& struct_def = **it;
GenStruct(struct_def, &code); GenStruct(struct_def, &code);
} }
return SaveFile(GeneratedFileName(path_, file_name_, parser_.opts).c_str(), return parser_.opts.file_saver->SaveFile(
code, false); GeneratedFileName(path_, file_name_, parser_.opts).c_str(), code,
false);
} }
private: private:

View File

@@ -95,7 +95,7 @@ class PhpGenerator : public BaseGenerator {
std::string filename = std::string filename =
NamespaceDir(*def.defined_namespace) + def.name + ".php"; 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. // Begin a class declaration.

View File

@@ -120,7 +120,7 @@ class PythonStubGenerator {
ss << content.str() << '\n'; ss << content.str() << '\n';
EnsureDirExists(StripFileName(filename)); 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) { static void DeclareUOffset(std::stringstream& stub, Imports* imports) {
@@ -2889,11 +2889,11 @@ class PythonGenerator : public BaseGenerator {
i = directories.find(kPathSeparator, i + 1)) { i = directories.find(kPathSeparator, i + 1)) {
const std::string init_py = const std::string init_py =
directories.substr(0, i) + kPathSeparator + "__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; 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: private:

View File

@@ -336,8 +336,8 @@ static bool GenerateRustModuleRootFile(const Parser& parser,
"Do not modify."; "Do not modify.";
code += "// @generated"; code += "// @generated";
root_module.GenerateImports(code); root_module.GenerateImports(code);
const bool success = const bool success = parser.opts.file_saver->SaveFile(
SaveFile((output_dir + "mod.rs").c_str(), code.ToString(), false); (output_dir + "mod.rs").c_str(), code.ToString(), false);
code.Clear(); code.Clear();
return success; return success;
} }
@@ -394,8 +394,8 @@ class RustGenerator : public BaseGenerator {
namer_.Directories(*symbol.defined_namespace); namer_.Directories(*symbol.defined_namespace);
EnsureDirExists(directories); EnsureDirExists(directories);
const std::string file_path = directories + namer_.File(symbol); const std::string file_path = directories + namer_.File(symbol);
const bool save_success = const bool save_success = parser_.opts.file_saver->SaveFile(
SaveFile(file_path.c_str(), code_.ToString(), /*binary=*/false); file_path.c_str(), code_.ToString(), /*binary=*/false);
if (!save_success) return false; if (!save_success) return false;
} }
return true; return true;
@@ -496,7 +496,8 @@ class RustGenerator : public BaseGenerator {
const auto file_path = GeneratedFileName(path_, file_name_, parser_.opts); const auto file_path = GeneratedFileName(path_, file_name_, parser_.opts);
const auto final_code = code_.ToString(); 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: private:

View File

@@ -191,7 +191,8 @@ class SwiftGenerator : public BaseGenerator {
const auto filename = GeneratedFileName(path_, file_name_, parser_.opts); const auto filename = GeneratedFileName(path_, file_name_, parser_.opts);
const auto final_code = code_.ToString(); 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() { void GenerateCode() {

View File

@@ -440,8 +440,9 @@ const char* GenTextFile(const Parser& parser, const std::string& path,
if (parser.opts.use_flexbuffers) { if (parser.opts.use_flexbuffers) {
std::string json; std::string json;
parser.flex_root_.ToString(true, parser.opts.strict_json, json); parser.flex_root_.ToString(true, parser.opts.strict_json, json);
return flatbuffers::SaveFile(TextFileName(path, file_name).c_str(), return parser.opts.file_saver->SaveFile(
json.c_str(), json.size(), true) TextFileName(path, file_name).c_str(), json.c_str(), json.size(),
true)
? nullptr ? nullptr
: "SaveFile failed"; : "SaveFile failed";
} }
@@ -449,8 +450,8 @@ const char* GenTextFile(const Parser& parser, const std::string& path,
std::string text; std::string text;
auto err = GenText(parser, parser.builder_.GetBufferPointer(), &text); auto err = GenText(parser, parser.builder_.GetBufferPointer(), &text);
if (err) return err; if (err) return err;
return flatbuffers::SaveFile(TextFileName(path, file_name).c_str(), text, return parser.opts.file_saver->SaveFile(TextFileName(path, file_name).c_str(),
false) text, false)
? nullptr ? nullptr
: "SaveFile failed"; : "SaveFile failed";
} }

View File

@@ -178,7 +178,7 @@ class TsGenerator : public BaseGenerator {
EnsureDirExists(dirs); EnsureDirExists(dirs);
auto basename = dirs + namer_.File(definition, SkipFile::Suffix); 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) { void TrackNsDef(const Definition& definition, std::string type_name) {
@@ -319,7 +319,9 @@ class TsGenerator : public BaseGenerator {
export_counter++; 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);
} }
} }

View File

@@ -110,6 +110,8 @@ set(FlatBuffers_Library_SRCS
${FLATBUFFERS_DIR}/include/flatbuffers/vector.h ${FLATBUFFERS_DIR}/include/flatbuffers/vector.h
${FLATBUFFERS_DIR}/include/flatbuffers/vector_downward.h ${FLATBUFFERS_DIR}/include/flatbuffers/vector_downward.h
${FLATBUFFERS_DIR}/include/flatbuffers/verifier.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_parser.cpp
${FLATBUFFERS_DIR}/src/idl_gen_text.cpp ${FLATBUFFERS_DIR}/src/idl_gen_text.cpp
${FLATBUFFERS_DIR}/src/reflection.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_grpc.cpp
${FLATBUFFERS_DIR}/src/idl_gen_json_schema.cpp ${FLATBUFFERS_DIR}/src/idl_gen_json_schema.cpp
${FLATBUFFERS_DIR}/src/idl_gen_swift.cpp ${FLATBUFFERS_DIR}/src/idl_gen_swift.cpp
${FLATBUFFERS_DIR}/src/file_name_saving_file_manager.cpp ${FLATBUFFERS_DIR}/src/file_manager.cpp
${FLATBUFFERS_DIR}/src/file_binary_writer.cpp ${FLATBUFFERS_DIR}/src/file_name_manager.cpp
${FLATBUFFERS_DIR}/src/file_writer.cpp
${FLATBUFFERS_DIR}/src/idl_namer.h ${FLATBUFFERS_DIR}/src/idl_namer.h
${FLATBUFFERS_DIR}/src/namer.h ${FLATBUFFERS_DIR}/src/namer.h
${FLATBUFFERS_DIR}/src/flatc.cpp ${FLATBUFFERS_DIR}/src/flatc.cpp
@@ -260,7 +261,7 @@ if(BUILD_DEBUGGER)
> >
-fno-limit-debug-info -fno-limit-debug-info
) )
target_link_libraries( target_link_libraries(
flatbuffers_nonfuzz flatbuffers_nonfuzz
PUBLIC PUBLIC
@@ -293,5 +294,5 @@ if(BUILD_DEBUGGER)
COMMAND ${CMAKE_COMMAND} -E copy COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_SOURCE_DIR}/../monster_test.bfbs ${CMAKE_SOURCE_DIR}/../monster_test.bfbs
${CMAKE_CURRENT_BINARY_DIR}/monster_test.bfbs) ${CMAKE_CURRENT_BINARY_DIR}/monster_test.bfbs)
endif(BUILD_DEBUGGER) endif(BUILD_DEBUGGER)