/*
 * Copyright 2014 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "flatbuffers/flatc.h"

#include <list>

namespace flatbuffers {

const char *FLATC_VERSION() { return FLATBUFFERS_VERSION(); }

void FlatCompiler::ParseFile(
    flatbuffers::Parser &parser, const std::string &filename,
    const std::string &contents,
    std::vector<const char *> &include_directories) const {
  auto local_include_directory = flatbuffers::StripFileName(filename);
  include_directories.push_back(local_include_directory.c_str());
  include_directories.push_back(nullptr);
  if (!parser.Parse(contents.c_str(), &include_directories[0],
                    filename.c_str())) {
    Error(parser.error_, false, false);
  }
  if (!parser.error_.empty()) { Warn(parser.error_, false); }
  include_directories.pop_back();
  include_directories.pop_back();
}

void FlatCompiler::LoadBinarySchema(flatbuffers::Parser &parser,
                                    const std::string &filename,
                                    const std::string &contents) {
  if (!parser.Deserialize(reinterpret_cast<const uint8_t *>(contents.c_str()),
                          contents.size())) {
    Error("failed to load binary schema: " + filename, false, false);
  }
}

void FlatCompiler::Warn(const std::string &warn, bool show_exe_name) const {
  params_.warn_fn(this, warn, show_exe_name);
}

void FlatCompiler::Error(const std::string &err, bool usage,
                         bool show_exe_name) const {
  params_.error_fn(this, err, usage, show_exe_name);
}

std::string FlatCompiler::GetUsageString(const char *program_name) const {
  std::stringstream ss;
  ss << "Usage: " << program_name << " [OPTION]... FILE... [-- FILE...]\n";
  for (size_t i = 0; i < params_.num_generators; ++i) {
    const Generator &g = params_.generators[i];

    std::stringstream full_name;
    full_name << std::setw(16) << std::left << g.generator_opt_long;
    const char *name = g.generator_opt_short ? g.generator_opt_short : "  ";
    const char *help = g.generator_help;

    ss << "  " << full_name.str() << " " << name << "    " << help << ".\n";
  }
  // clang-format off

  // Output width
  // 12345678901234567890123456789012345678901234567890123456789012345678901234567890
  ss <<
    "  -o PATH                Prefix PATH to all generated files.\n"
    "  -I PATH                Search for includes in the specified path.\n"
    "  -M                     Print make rules for generated files.\n"
    "  --version              Print the version number of flatc and exit.\n"
    "  --strict-json          Strict JSON: field names must be / will be quoted,\n"
    "                         no trailing commas in tables/vectors.\n"
    "  --allow-non-utf8       Pass non-UTF-8 input through parser and emit nonstandard\n"
    "                         \\x escapes in JSON. (Default is to raise parse error on\n"
    "                         non-UTF-8 input.)\n"
    "  --natural-utf8         Output strings with UTF-8 as human-readable strings.\n"
    "                         By default, UTF-8 characters are printed as \\uXXXX escapes.\n"
    "  --defaults-json        Output fields whose value is the default when\n"
    "                         writing JSON\n"
    "  --unknown-json         Allow fields in JSON that are not defined in the\n"
    "                         schema. These fields will be discared when generating\n"
    "                         binaries.\n"
    "  --no-prefix            Don\'t prefix enum values with the enum type in C++.\n"
    "  --scoped-enums         Use C++11 style scoped and strongly typed enums.\n"
    "                         also implies --no-prefix.\n"
    "  --gen-includes         (deprecated), this is the default behavior.\n"
    "                         If the original behavior is required (no include\n"
    "                         statements) use --no-includes.\n"
    "  --no-includes          Don\'t generate include statements for included\n"
    "                         schemas the generated file depends on (C++ / Python).\n"
    "  --gen-mutable          Generate accessors that can mutate buffers in-place.\n"
    "  --gen-onefile          Generate single output file for C# and Go.\n"
    "  --gen-name-strings     Generate type name functions for C++ and Rust.\n"
    "  --gen-object-api       Generate an additional object-based API.\n"
    "  --gen-compare          Generate operator== for object-based API types.\n"
    "  --gen-nullable         Add Clang _Nullable for C++ pointer. or @Nullable for Java\n"
    "  --java-checkerframe    work Add @Pure for Java.\n"
    "  --gen-generated        Add @Generated annotation for Java\n"
    "  --gen-jvmstatic        Add @JvmStatic annotation for Kotlin methods\n"
    "                         in companion object for interop from Java to Kotlin.\n"
    "  --gen-all              Generate not just code for the current schema files,\n"
    "                         but for all files it includes as well.\n"
    "                         If the language uses a single file for output (by default\n"
    "                         the case for C++ and JS), all code will end up in this one\n"
    "                         file.\n"
    "  --cpp-include          Adds an #include in generated file.\n"
    "  --cpp-ptr-type T       Set object API pointer type (default std::unique_ptr).\n"
    "  --cpp-str-type T       Set object API string type (default std::string).\n"
    "                         T::c_str(), T::length() and T::empty() must be supported.\n"
    "                         The custom type also needs to be constructible from std::string\n"
    "                         (see the --cpp-str-flex-ctor option to change this behavior).\n"
    "  --cpp-str-flex-ctor    Don't construct custom string types by passing std::string\n"
    "                         from Flatbuffers, but (char* + length).\n"
    "  --cpp-field-case-style STYLE Generate C++ fields using selected case style.\n"
    "                         Supported STYLE values:\n"
    "                          * 'unchanged' - leave unchanged (default);\n"
    "                          * 'upper' - schema snake_case emits UpperCamel;\n"
    "                          * 'lower' - schema snake_case emits lowerCamel.\n"
    "  --cpp-std CPP_STD      Generate a C++ code using features of selected C++ standard.\n"
    "                         Supported CPP_STD values:\n"
    "                          * 'c++0x' - generate code compatible with old compilers;\n"
    "                          * 'c++11' - use C++11 code generator (default);\n"
    "                          * 'c++17' - use C++17 features in generated code (experimental).\n"
    "  --cpp-static-reflection When using C++17, generate extra code to provide compile-time\n"
    "                          (static) reflection of Flatbuffers types.  Requires --cpp-std\n"
    "                          to be \"c++17\" or higher.\n"
    "  --object-prefix        Customise class prefix for C++ object-based API.\n"
    "  --object-suffix        Customise class suffix for C++ object-based API.\n"
    "                         Default value is \"T\".\n"
    "  --go-namespace         Generate the overriding namespace in Golang.\n"
    "  --go-import            Generate the overriding import for flatbuffers in Golang\n"
    "                         (default is \"github.com/google/flatbuffers/go\").\n"
    "  --raw-binary           Allow binaries without file_identifier to be read.\n"
    "                         This may crash flatc given a mismatched schema.\n"
    "  --size-prefixed        Input binaries are size prefixed buffers.\n"
    "  --proto                Input is a .proto, translate to .fbs.\n"
    "  --proto-namespace-suffix Add this namespace to any flatbuffers generated\n"
    "    SUFFIX                 from protobufs.\n"
    "  --oneof-union          Translate .proto oneofs to flatbuffer unions.\n"
    "  --grpc                 Generate GRPC interfaces for the specified languages.\n"
    "  --schema               Serialize schemas instead of JSON (use with -b).\n"
    "  --bfbs-filenames PATH  Sets the root path where reflection filenames in \n"
    "                         reflection.fbs are relative to. The 'root' is denoted with \n"
    "                         `//`. E.g. if PATH=/a/b/c \n then /a/d/e.fbs will be serialized\n"
    "                         as //../d/e.fbs. (PATH defaults to the directory of the first\n"
    "                         provided schema file.)\n"
    "  --bfbs-comments        Add doc comments to the binary schema files.\n"
    "  --bfbs-builtins        Add builtin attributes to the binary schema files.\n"
    "  --bfbs-gen-embed       Generate code to embed the bfbs schema to the source.\n"
    "  --conform FILE         Specify a schema the following schemas should be\n"
    "                         an evolution of. Gives errors if not.\n"
    "  --conform-includes     Include path for the schema given with --conform PATH\n"
    "  --filename-suffix      The suffix appended to the generated file names.\n"
    "                         Default is '_generated'.\n"
    "  --filename-ext         The extension appended to the generated file names.\n"
    "                         Default is language-specific (e.g., '.h' for C++)\n"
    "  --include-prefix       Prefix this path to any generated include statements.\n"
    "    PATH\n"
    "  --keep-prefix          Keep original prefix of schema include statement.\n"
    "  --reflect-types        Add minimal type reflection to code generation.\n"
    "  --reflect-names        Add minimal type/name reflection.\n"
    "  --root-type T          Select or override the default root_type\n"
    "  --require-explicit-ids When parsing schemas, require explicit ids (id: x).\n"
    "  --force-defaults       Emit default values in binary output from JSON\n"
    "  --force-empty          When serializing from object API representation,\n"
    "                         force strings and vectors to empty rather than null.\n"
    "  --force-empty-vectors  When serializing from object API representation,\n"
    "                         force vectors to empty rather than null.\n"
    "  --flexbuffers          Used with \"binary\" and \"json\" options, it generates\n"
    "                         data using schema-less FlexBuffers.\n"
    "  --no-warnings          Inhibit all warning messages.\n"
    "FILEs may be schemas (must end in .fbs), binary schemas (must end in .bfbs),\n"
    "or JSON files (conforming to preceding schema). FILEs after the -- must be\n"
    "binary flatbuffer format files.\n"
    "Output files are named using the base file name of the input,\n"
    "and written to the current directory or the path given by -o.\n"
    "example: " << program_name << " -c -b schema1.fbs schema2.fbs data.json\n";
  // 12345678901234567890123456789012345678901234567890123456789012345678901234567890
  // clang-format on
  return ss.str();
}

int FlatCompiler::Compile(int argc, const char **argv) {
  if (params_.generators == nullptr || params_.num_generators == 0) {
    return 0;
  }

  flatbuffers::IDLOptions opts;
  std::string output_path;

  bool any_generator = false;
  bool print_make_rules = false;
  bool raw_binary = false;
  bool schema_binary = false;
  bool grpc_enabled = false;
  std::vector<std::string> filenames;
  std::list<std::string> include_directories_storage;
  std::vector<const char *> include_directories;
  std::vector<const char *> conform_include_directories;
  std::vector<bool> generator_enabled(params_.num_generators, false);
  size_t binary_files_from = std::numeric_limits<size_t>::max();
  std::string conform_to_schema;

  for (int argi = 0; argi < argc; argi++) {
    std::string arg = argv[argi];
    if (arg[0] == '-') {
      if (filenames.size() && arg[1] != '-')
        Error("invalid option location: " + arg, true);
      if (arg == "-o") {
        if (++argi >= argc) Error("missing path following: " + arg, true);
        output_path = flatbuffers::ConCatPathFileName(
            flatbuffers::PosixPath(argv[argi]), "");
      } else if (arg == "-I") {
        if (++argi >= argc) Error("missing path following: " + arg, true);
        include_directories_storage.push_back(
            flatbuffers::PosixPath(argv[argi]));
        include_directories.push_back(
            include_directories_storage.back().c_str());
      } else if (arg == "--bfbs-filenames") {
        if (++argi > argc) Error("missing path following: " + arg, true);
        opts.project_root = argv[argi];
        if (!DirExists(opts.project_root.c_str()))
          Error(arg + " is not a directory: " + opts.project_root);
      } else if (arg == "--conform") {
        if (++argi >= argc) Error("missing path following: " + arg, true);
        conform_to_schema = flatbuffers::PosixPath(argv[argi]);
      } else if (arg == "--conform-includes") {
        if (++argi >= argc) Error("missing path following: " + arg, true);
        include_directories_storage.push_back(
            flatbuffers::PosixPath(argv[argi]));
        conform_include_directories.push_back(
            include_directories_storage.back().c_str());
      } else if (arg == "--include-prefix") {
        if (++argi >= argc) Error("missing path following: " + arg, true);
        opts.include_prefix = flatbuffers::ConCatPathFileName(
            flatbuffers::PosixPath(argv[argi]), "");
      } else if (arg == "--keep-prefix") {
        opts.keep_include_path = true;
      } else if (arg == "--strict-json") {
        opts.strict_json = true;
      } else if (arg == "--allow-non-utf8") {
        opts.allow_non_utf8 = true;
      } else if (arg == "--natural-utf8") {
        opts.natural_utf8 = true;
      } else if (arg == "--go-namespace") {
        if (++argi >= argc) Error("missing golang namespace" + arg, true);
        opts.go_namespace = argv[argi];
      } else if (arg == "--go-import") {
        if (++argi >= argc) Error("missing golang import" + arg, true);
        opts.go_import = argv[argi];
      } else if (arg == "--defaults-json") {
        opts.output_default_scalars_in_json = true;
      } else if (arg == "--unknown-json") {
        opts.skip_unexpected_fields_in_json = true;
      } else if (arg == "--no-prefix") {
        opts.prefixed_enums = false;
      } else if (arg == "--scoped-enums") {
        opts.prefixed_enums = false;
        opts.scoped_enums = true;
      } else if (arg == "--no-union-value-namespacing") {
        opts.union_value_namespacing = false;
      } else if (arg == "--gen-mutable") {
        opts.mutable_buffer = true;
      } else if (arg == "--gen-name-strings") {
        opts.generate_name_strings = true;
      } else if (arg == "--gen-object-api") {
        opts.generate_object_based_api = true;
      } else if (arg == "--gen-compare") {
        opts.gen_compare = true;
      } else if (arg == "--cpp-include") {
        if (++argi >= argc) Error("missing include following: " + arg, true);
        opts.cpp_includes.push_back(argv[argi]);
      } else if (arg == "--cpp-ptr-type") {
        if (++argi >= argc) Error("missing type following: " + arg, true);
        opts.cpp_object_api_pointer_type = argv[argi];
      } else if (arg == "--cpp-str-type") {
        if (++argi >= argc) Error("missing type following: " + arg, true);
        opts.cpp_object_api_string_type = argv[argi];
      } else if (arg == "--cpp-str-flex-ctor") {
        opts.cpp_object_api_string_flexible_constructor = true;
      } else if (arg == "--no-cpp-direct-copy") {
        opts.cpp_direct_copy = false;
      } else if (arg == "--cpp-field-case-style") {
        if (++argi >= argc) Error("missing case style following: " + arg, true);
        if (!strcmp(argv[argi], "unchanged"))
          opts.cpp_object_api_field_case_style =
              IDLOptions::CaseStyle_Unchanged;
        else if (!strcmp(argv[argi], "upper"))
          opts.cpp_object_api_field_case_style = IDLOptions::CaseStyle_Upper;
        else if (!strcmp(argv[argi], "lower"))
          opts.cpp_object_api_field_case_style = IDLOptions::CaseStyle_Lower;
        else
          Error("unknown case style: " + std::string(argv[argi]), true);
      } else if (arg == "--gen-nullable") {
        opts.gen_nullable = true;
      } else if (arg == "--java-checkerframework") {
        opts.java_checkerframework = true;
      } else if (arg == "--gen-generated") {
        opts.gen_generated = true;
      } else if (arg == "--object-prefix") {
        if (++argi >= argc) Error("missing prefix following: " + arg, true);
        opts.object_prefix = argv[argi];
      } else if (arg == "--object-suffix") {
        if (++argi >= argc) Error("missing suffix following: " + arg, true);
        opts.object_suffix = argv[argi];
      } 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.
        Warn("warning: --gen-includes is deprecated (it is now default)\n");
      } else if (arg == "--no-includes") {
        opts.include_dependence_headers = false;
      } else if (arg == "--gen-onefile") {
        opts.one_file = true;
      } else if (arg == "--raw-binary") {
        raw_binary = true;
      } else if (arg == "--size-prefixed") {
        opts.size_prefixed = true;
      } else if (arg == "--") {  // Separator between text and binary inputs.
        binary_files_from = filenames.size();
      } else if (arg == "--proto") {
        opts.proto_mode = true;
      } else if (arg == "--proto-namespace-suffix") {
        if (++argi >= argc) Error("missing namespace suffix" + arg, true);
        opts.proto_namespace_suffix = argv[argi];
      } else if (arg == "--oneof-union") {
        opts.proto_oneof_union = true;
      } else if (arg == "--schema") {
        schema_binary = true;
      } else if (arg == "-M") {
        print_make_rules = true;
      } else if (arg == "--version") {
        printf("flatc version %s\n", FLATC_VERSION());
        exit(0);
      } else if (arg == "--grpc") {
        grpc_enabled = true;
      } else if (arg == "--bfbs-comments") {
        opts.binary_schema_comments = true;
      } else if (arg == "--bfbs-builtins") {
        opts.binary_schema_builtins = true;
      } else if (arg == "--bfbs-gen-embed") {
        opts.binary_schema_gen_embed = true;
      } else if (arg == "--reflect-types") {
        opts.mini_reflect = IDLOptions::kTypes;
      } else if (arg == "--reflect-names") {
        opts.mini_reflect = IDLOptions::kTypesAndNames;
      } else if (arg == "--require-explicit-ids") {
        opts.require_explicit_ids = true;
      } else if (arg == "--root-type") {
        if (++argi >= argc) Error("missing type following: " + arg, true);
        opts.root_type = argv[argi];
      } else if (arg == "--filename-suffix") {
        if (++argi >= argc) Error("missing filename suffix: " + arg, true);
        opts.filename_suffix = argv[argi];
      } else if (arg == "--filename-ext") {
        if (++argi >= argc) Error("missing filename extension: " + arg, true);
        opts.filename_extension = argv[argi];
      } else if (arg == "--force-defaults") {
        opts.force_defaults = true;
      } else if (arg == "--force-empty") {
        opts.set_empty_strings_to_null = false;
        opts.set_empty_vectors_to_null = false;
      } else if (arg == "--force-empty-vectors") {
        opts.set_empty_vectors_to_null = false;
      } else if (arg == "--java-primitive-has-method") {
        opts.java_primitive_has_method = true;
      } else if (arg == "--cs-gen-json-serializer") {
        opts.cs_gen_json_serializer = true;
      } else if (arg == "--flexbuffers") {
        opts.use_flexbuffers = true;
      } else if (arg == "--gen-jvmstatic") {
        opts.gen_jvmstatic = true;
      } else if (arg == "--no-warnings") {
        opts.no_warnings = true;
      } else if (arg == "--cpp-std") {
        if (++argi >= argc)
          Error("missing C++ standard specification" + arg, true);
        opts.cpp_std = argv[argi];
      } else if (arg.rfind("--cpp-std=", 0) == 0) {
        opts.cpp_std = arg.substr(std::string("--cpp-std=").size());
      } else if (arg == "--cpp-static-reflection") {
        opts.cpp_static_reflection = true;
      } else {
        for (size_t i = 0; i < params_.num_generators; ++i) {
          if (arg == params_.generators[i].generator_opt_long ||
              (params_.generators[i].generator_opt_short &&
               arg == params_.generators[i].generator_opt_short)) {
            generator_enabled[i] = true;
            any_generator = true;
            opts.lang_to_generate |= params_.generators[i].lang;
            goto found;
          }
        }
        Error("unknown commandline argument: " + arg, true);
      found:;
      }
    } else {
      filenames.push_back(flatbuffers::PosixPath(argv[argi]));
    }
  }

  if (!filenames.size()) Error("missing input files", false, true);

  if (opts.proto_mode) {
    if (any_generator)
      Error("cannot generate code directly from .proto files", true);
  } else if (!any_generator && conform_to_schema.empty()) {
    Error("no options: specify at least one generator.", true);
  }

  flatbuffers::Parser conform_parser;
  if (!conform_to_schema.empty()) {
    std::string contents;
    if (!flatbuffers::LoadFile(conform_to_schema.c_str(), true, &contents))
      Error("unable to load schema: " + conform_to_schema);

    if (flatbuffers::GetExtension(conform_to_schema) ==
        reflection::SchemaExtension()) {
      LoadBinarySchema(conform_parser, conform_to_schema, contents);
    } else {
      ParseFile(conform_parser, conform_to_schema, contents,
                conform_include_directories);
    }
  }

  std::unique_ptr<flatbuffers::Parser> parser(new flatbuffers::Parser(opts));

  for (auto file_it = filenames.begin(); file_it != filenames.end();
       ++file_it) {
    auto &filename = *file_it;
    std::string contents;
    if (!flatbuffers::LoadFile(filename.c_str(), true, &contents))
      Error("unable to load file: " + filename);

    bool is_binary =
        static_cast<size_t>(file_it - filenames.begin()) >= binary_files_from;
    auto ext = flatbuffers::GetExtension(filename);
    const bool is_schema = ext == "fbs" || ext == "proto";
    if (is_schema && opts.project_root.empty()) {
      opts.project_root = StripFileName(filename);
    }
    const bool is_binary_schema = ext == reflection::SchemaExtension();
    if (is_binary) {
      parser->builder_.Clear();
      parser->builder_.PushFlatBuffer(
          reinterpret_cast<const uint8_t *>(contents.c_str()),
          contents.length());
      if (!raw_binary) {
        // Generally reading binaries that do not correspond to the schema
        // will crash, and sadly there's no way around that when the binary
        // does not contain a file identifier.
        // We'd expect that typically any binary used as a file would have
        // such an identifier, so by default we require them to match.
        if (!parser->file_identifier_.length()) {
          Error("current schema has no file_identifier: cannot test if \"" +
                filename +
                "\" matches the schema, use --raw-binary to read this file"
                " anyway.");
        } else if (!flatbuffers::BufferHasIdentifier(
                       contents.c_str(), parser->file_identifier_.c_str(),
                       opts.size_prefixed)) {
          Error("binary \"" + filename +
                "\" does not have expected file_identifier \"" +
                parser->file_identifier_ +
                "\", use --raw-binary to read this file anyway.");
        }
      }
    } else {
      // Check if file contains 0 bytes.
      if (!opts.use_flexbuffers && !is_binary_schema &&
          contents.length() != strlen(contents.c_str())) {
        Error("input file appears to be binary: " + filename, true);
      }
      if (is_schema) {
        // If we're processing multiple schemas, make sure to start each
        // one from scratch. If it depends on previous schemas it must do
        // so explicitly using an include.
        parser.reset(new flatbuffers::Parser(opts));
      }
      if (is_binary_schema) {
        LoadBinarySchema(*parser.get(), filename, contents);
      }
      if (opts.use_flexbuffers) {
        if (opts.lang_to_generate == IDLOptions::kJson) {
          parser->flex_root_ = flexbuffers::GetRoot(
              reinterpret_cast<const uint8_t *>(contents.c_str()),
              contents.size());
        } else {
          parser->flex_builder_.Clear();
          ParseFile(*parser.get(), filename, contents, include_directories);
        }
      } else {
        ParseFile(*parser.get(), filename, contents, include_directories);
        if (!is_schema && !parser->builder_.GetSize()) {
          // If a file doesn't end in .fbs, it must be json/binary. Ensure we
          // didn't just parse a schema with a different extension.
          Error("input file is neither json nor a .fbs (schema) file: " +
                    filename,
                true);
        }
      }
      if ((is_schema || is_binary_schema) && !conform_to_schema.empty()) {
        auto err = parser->ConformTo(conform_parser);
        if (!err.empty()) Error("schemas don\'t conform: " + err);
      }
      if (schema_binary || opts.binary_schema_gen_embed) {
        parser->Serialize();
      }
      if (schema_binary) {
        parser->file_extension_ = reflection::SchemaExtension();
      }
    }

    std::string filebase =
        flatbuffers::StripPath(flatbuffers::StripExtension(filename));

    for (size_t i = 0; i < params_.num_generators; ++i) {
      parser->opts.lang = params_.generators[i].lang;
      if (generator_enabled[i]) {
        if (!print_make_rules) {
          flatbuffers::EnsureDirExists(output_path);
          if ((!params_.generators[i].schema_only ||
               (is_schema || is_binary_schema)) &&
              !params_.generators[i].generate(*parser.get(), output_path,
                                              filebase)) {
            Error(std::string("Unable to generate ") +
                  params_.generators[i].lang_name + " for " + filebase);
          }
        } else {
          if (params_.generators[i].make_rule == nullptr) {
            Error(std::string("Cannot generate make rule for ") +
                  params_.generators[i].lang_name);
          } else {
            std::string make_rule = params_.generators[i].make_rule(
                *parser.get(), output_path, filename);
            if (!make_rule.empty())
              printf("%s\n",
                     flatbuffers::WordWrap(make_rule, 80, " ", " \\").c_str());
          }
        }
        if (grpc_enabled) {
          if (params_.generators[i].generateGRPC != nullptr) {
            if (!params_.generators[i].generateGRPC(*parser.get(), output_path,
                                                    filebase)) {
              Error(std::string("Unable to generate GRPC interface for") +
                    params_.generators[i].lang_name);
            }
          } else {
            Warn(std::string("GRPC interface generator not implemented for ") +
                 params_.generators[i].lang_name);
          }
        }
      }
    }

    if (!opts.root_type.empty()) {
      if (!parser->SetRootType(opts.root_type.c_str()))
        Error("unknown root type: " + opts.root_type);
      else if (parser->root_struct_def_->fixed)
        Error("root type must be a table");
    }

    if (opts.proto_mode) GenerateFBS(*parser.get(), output_path, filebase);

    // We do not want to generate code for the definitions in this file
    // in any files coming up next.
    parser->MarkGenerated();
  }
  if (opts.lang_to_generate & IDLOptions::kRust && !parser->opts.one_file) {
    GenerateRustModuleRootFile(*parser, output_path);
  }
  return 0;
}

}  // namespace flatbuffers
