/*
 * 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 <algorithm>
#include <limits>
#include <list>
#include <memory>
#include <sstream>
#include <string>

#include "annotated_binary_text_gen.h"
#include "binary_annotator.h"
#include "flatbuffers/code_generator.h"
#include "flatbuffers/idl.h"
#include "flatbuffers/util.h"

namespace flatbuffers {

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

void FlatCompiler::ParseFile(
    flatbuffers::Parser& parser, const std::string& filename,
    const std::string& contents,
    const std::vector<const char*>& include_directories) const {
  auto local_include_directory = flatbuffers::StripFileName(filename);

  std::vector<const char*> inc_directories;
  inc_directories.insert(inc_directories.end(), include_directories.begin(),
                         include_directories.end());
  inc_directories.push_back(local_include_directory.c_str());
  inc_directories.push_back(nullptr);

  if (!parser.Parse(contents.c_str(), &inc_directories[0], filename.c_str())) {
    Error(parser.error_, false, false);
  }
  if (!parser.error_.empty()) {
    Warn(parser.error_, false);
  }
}

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);
}

const static FlatCOption flatc_options[] = {
    {"o", "", "PATH", "Prefix PATH to all generated files."},
    {"I", "", "PATH", "Search for includes in the specified path."},
    {"M", "", "", "Print make rules for generated files."},
    {"", "version", "", "Print the version number of flatc and exit."},
    {"h", "help", "", "Prints this help text and exit."},
    {"", "strict-json", "",
     "Strict JSON: field names must be / will be quoted, no trailing commas in "
     "tables/vectors."},
    {"", "allow-non-utf8", "",
     "Pass non-UTF-8 input through parser and emit nonstandard \\x escapes in "
     "JSON. (Default is to raise parse error on non-UTF-8 input.)"},
    {"", "natural-utf8", "",
     "Output strings with UTF-8 as human-readable strings. By default, UTF-8 "
     "characters are printed as \\uXXXX escapes."},
    {"", "defaults-json", "",
     "Output fields whose value is the default when writing JSON"},
    {"", "unknown-json", "",
     "Allow fields in JSON that are not defined in the schema. These fields "
     "will be discarded when generating binaries."},
    {"", "no-prefix", "",
     "Don't prefix enum values with the enum type in C++."},
    {"", "scoped-enums", "",
     "Use C++11 style scoped and strongly typed enums. Also implies "
     "--no-prefix."},
    {"", "no-emit-min-max-enum-values", "",
     "Disable generation of MIN and MAX enumerated values for scoped enums "
     "and prefixed enums."},
    {"", "swift-implementation-only", "",
     "Adds a @_implementationOnly to swift imports"},
    {"", "gen-includes", "",
     "(deprecated), this is the default behavior. If the original behavior is "
     "required (no include statements) use --no-includes."},
    {"", "no-includes", "",
     "Don't generate include statements for included schemas the generated "
     "file depends on (C++, Python, Proto-to-Fbs)."},
    {"", "gen-mutable", "",
     "Generate accessors that can mutate buffers in-place."},
    {"", "gen-onefile", "",
     "Generate a single output file for C#, Go, Java, Kotlin and Python. "
     "Implies --no-include."},
    {"", "gen-name-strings", "",
     "Generate type name functions for C++ and Rust."},
    {"", "gen-object-api", "", "Generate an additional object-based API."},
    {"", "gen-compare", "", "Generate operator== for object-based API types."},
    {"", "gen-nullable", "",
     "Add Clang _Nullable for C++ pointer. or @Nullable for Java"},
    {"", "java-package-prefix", "",
     "Add a prefix to the generated package name for Java."},
    {"", "java-checkerframework", "", "Add @Pure for Java."},
    {"", "gen-generated", "", "Add @Generated annotation for Java."},
    {"", "gen-jvmstatic", "",
     "Add @JvmStatic annotation for Kotlin methods in companion object for "
     "interop from Java to Kotlin."},
    {"", "gen-all", "",
     "Generate not just code for the current schema files, but for all files "
     "it "
     "includes as well. If the language uses a single file for output (by "
     "default the case for C++ and JS), all code will end up in this one "
     "file."},
    {"", "gen-json-emit", "",
     "Generates encoding code which emits Flatbuffers into JSON"},
    {"", "cpp-include", "", "Adds an #include in generated file."},
    {"", "cpp-ptr-type", "T",
     "Set object API pointer type (default std::unique_ptr)."},
    {"", "cpp-str-type", "T",
     "Set object API string type (default std::string). T::c_str(), "
     "T::length() "
     "and T::empty() must be supported. The custom type also needs to be "
     "constructible from std::string (see the --cpp-str-flex-ctor option to "
     "change this behavior)"},
    {"", "cpp-str-flex-ctor", "",
     "Don't construct custom string types by passing std::string from "
     "Flatbuffers, but (char* + length)."},
    {"", "cpp-field-case-style", "STYLE",
     "Generate C++ fields using selected case style. Supported STYLE values: * "
     "'unchanged' - leave unchanged (default) * 'upper' - schema snake_case "
     "emits UpperCamel; * 'lower' - schema snake_case emits lowerCamel."},
    {"", "cpp-std", "CPP_STD",
     "Generate a C++ code using features of selected C++ standard. Supported "
     "CPP_STD values: * 'c++0x' - generate code compatible with old compilers; "
     "'c++11' - use C++11 code generator (default); * 'c++17' - use C++17 "
     "features in generated code (experimental)."},
    {"", "cpp-static-reflection", "",
     "When using C++17, generate extra code to provide compile-time (static) "
     "reflection of Flatbuffers types. Requires --cpp-std to be \"c++17\" or "
     "higher."},
    {"", "object-prefix", "PREFIX",
     "Customize class prefix for C++ object-based API."},
    {"", "object-suffix", "SUFFIX",
     "Customize class suffix for C++ object-based API. Default Value is "
     "\"T\"."},
    {"", "go-namespace", "", "Generate the overriding namespace in Golang."},
    {"", "go-import", "IMPORT",
     "Generate the overriding import for flatbuffers in Golang (default is "
     "\"github.com/google/flatbuffers/go\")."},
    {"", "go-module-name", "",
     "Prefix local import paths of generated go code with the module name"},
    {"", "raw-binary", "",
     "Allow binaries without file_identifier to be read. This may crash flatc "
     "given a mismatched schema."},
    {"", "size-prefixed", "", "Input binaries are size prefixed buffers."},
    {"", "proto-namespace-suffix", "SUFFIX",
     "Add this namespace to any flatbuffers generated from protobufs."},
    {"", "oneof-union", "", "Translate .proto oneofs to flatbuffer unions."},
    {"", "keep-proto-id", "", "Keep protobuf field ids in generated fbs file."},
    {"", "proto-id-gap", "",
     "Action that should be taken when a gap between protobuf ids found. "
     "Supported values: * "
     "'nop' - do not care about gap * 'warn' - A warning message will be shown "
     "about the gap in protobuf ids"
     "(default) "
     "* 'error' - An error message will be shown and the fbs generation will "
     "be "
     "interrupted."},
    {"", "grpc", "", "Generate GRPC interfaces for the specified languages."},
    {"", "schema", "", "Serialize schemas instead of JSON (use with -b)."},
    {"", "bfbs-filenames", "PATH",
     "Sets the root path where reflection filenames in reflection.fbs are "
     "relative to. The 'root' is denoted with  `//`. E.g. if PATH=/a/b/c "
     "then /a/d/e.fbs will be serialized as //../d/e.fbs. (PATH defaults to "
     "the "
     "directory of the first provided schema file."},
    {"", "bfbs-absolute-paths", "",
     "Uses absolute paths instead of relative paths in the BFBS output."},
    {"", "bfbs-comments", "", "Add doc comments to the binary schema files."},
    {"", "bfbs-builtins", "",
     "Add builtin attributes to the binary schema files."},
    {"", "bfbs-gen-embed", "",
     "Generate code to embed the bfbs schema to the source."},
    {"", "conform", "FILE",
     "Specify a schema the following schemas should be an evolution of. Gives "
     "errors if not."},
    {"", "conform-includes", "PATH",
     "Include path for the schema given with --conform PATH"},
    {"", "filename-suffix", "SUFFIX",
     "The suffix appended to the generated file names (Default is "
     "'_generated')."},
    {"", "filename-ext", "EXT",
     "The extension appended to the generated file names. Default is "
     "language-specific (e.g., '.h' for C++)"},
    {"", "include-prefix", "PATH",
     "Prefix this PATH to any generated include statements."},
    {"", "keep-prefix", "",
     "Keep original prefix of schema include statement."},
    {"", "reflect-types", "",
     "Add minimal type reflection to code generation."},
    {"", "reflect-names", "", "Add minimal type/name reflection."},
    {"", "rust-serialize", "",
     "Implement serde::Serialize on generated Rust types."},
    {"", "rust-module-root-file", "",
     "Generate rust code in individual files with a module root file."},
    {"", "root-type", "T", "Select or override the default root_type."},
    {"", "require-explicit-ids", "",
     "When parsing schemas, require explicit ids (id: x)."},
    {"", "force-defaults", "",
     "Emit default values in binary output from JSON"},
    {"", "force-empty", "",
     "When serializing from object API representation, force strings and "
     "vectors to empty rather than null."},
    {"", "force-empty-vectors", "",
     "When serializing from object API representation, force vectors to empty "
     "rather than null."},
    {"", "flexbuffers", "",
     "Used with \"binary\" and \"json\" options, it generates data using "
     "schema-less FlexBuffers."},
    {"", "no-warnings", "", "Inhibit all warnings messages."},
    {"", "warnings-as-errors", "", "Treat all warnings as errors."},
    {"", "cs-global-alias", "",
     "Prepend \"global::\" to all user generated csharp classes and "
     "structs."},
    {"", "cs-gen-json-serializer", "",
     "Allows (de)serialization of JSON text in the Object API. (requires "
     "--gen-object-api)."},
    {"", "json-nested-bytes", "",
     "Allow a nested_flatbuffer field to be parsed as a vector of bytes "
     "in JSON, which is unsafe unless checked by a verifier afterwards."},
    {"", "ts-flat-files", "", "(deprecated) Alias for --gen-all."},
    {"", "ts-entry-points", "", "(deprecated) Alias for --gen-all."},
    {"", "annotate-sparse-vectors", "", "Don't annotate every vector element."},
    {"", "annotate", "SCHEMA",
     "Annotate the provided BINARY_FILE with the specified SCHEMA file."},
    {"", "no-leak-private-annotation", "",
     "Prevents multiple type of annotations within a Fbs SCHEMA file. "
     "Currently this is required to generate private types in Rust"},
    {"", "python-no-type-prefix-suffix", "",
     "Skip emission of Python functions that are prefixed with typenames"},
    {"", "python-typing", "", "Generate Python type annotations"},
    {"", "python-version", "", "Generate code for the given Python version."},
    {"", "python-decode-obj-api-strings", "",
     "Decode bytes to strings for the Python Object API"},
    {"", "python-gen-numpy", "", "Whether to generate numpy helpers."},
    {"", "ts-omit-entrypoint", "",
     "Omit emission of namespace entrypoint file"},
    {"", "ts-undefined-for-optionals", "",
     "Whether to generate undefined values instead of null values for missing "
     "optional keys"},
    {"", "file-names-only", "",
     "Print out generated file names without writing to the files"},
    {"", "grpc-filename-suffix", "SUFFIX",
     "The suffix for the generated file names (Default is '.fb')."},
    {"", "grpc-additional-header", "",
     "Additional headers to prepend to the generated files."},
    {"", "grpc-use-system-headers", "",
     "Use <> for headers included from the generated code."},
    {"", "grpc-search-path", "PATH", "Prefix to any gRPC includes."},
    {"", "grpc-python-typed-handlers", "",
     "The handlers will use the generated classes rather than raw bytes."},
    {"", "grpc-callback-api", "",
     "Generate gRPC code using the callback (reactor) API instead of legacy "
     "sync/async."},
};

auto cmp = [](FlatCOption a, FlatCOption b) { return a.long_opt < b.long_opt; };
static std::set<FlatCOption, decltype(cmp)> language_options(cmp);

static void AppendTextWrappedString(std::stringstream& ss, std::string& text,
                                    size_t max_col, size_t start_col) {
  size_t max_line_length = max_col - start_col;

  if (text.length() > max_line_length) {
    size_t ideal_break_location = text.rfind(' ', max_line_length);
    size_t length = std::min(max_line_length, ideal_break_location);
    ss << text.substr(0, length) << "\n";
    ss << std::string(start_col, ' ');
    std::string rest_of_description = text.substr(
        ((ideal_break_location < max_line_length || text.at(length) == ' ')
             ? length + 1
             : length));
    AppendTextWrappedString(ss, rest_of_description, max_col, start_col);
  } else {
    ss << text;
  }
}

static void AppendOption(std::stringstream& ss, const FlatCOption& option,
                         size_t max_col, size_t min_col_for_description) {
  size_t chars = 2;
  ss << "  ";
  if (!option.short_opt.empty()) {
    chars += 2 + option.short_opt.length();
    ss << "-" << option.short_opt;
    if (!option.long_opt.empty()) {
      chars++;
      ss << ",";
    }
    ss << " ";
  }
  if (!option.long_opt.empty()) {
    chars += 3 + option.long_opt.length();
    ss << "--" << option.long_opt << " ";
  }
  if (!option.parameter.empty()) {
    chars += 1 + option.parameter.length();
    ss << option.parameter << " ";
  }
  size_t start_of_description = chars;
  if (start_of_description > min_col_for_description) {
    ss << "\n";
    start_of_description = min_col_for_description;
    ss << std::string(start_of_description, ' ');
  } else {
    while (start_of_description < min_col_for_description) {
      ss << " ";
      start_of_description++;
    }
  }
  if (!option.description.empty()) {
    std::string description = option.description;
    AppendTextWrappedString(ss, description, max_col, start_of_description);
  }
  ss << "\n";
}

static void AppendShortOption(std::stringstream& ss,
                              const FlatCOption& option) {
  if (!option.short_opt.empty()) {
    ss << "-" << option.short_opt;
    if (!option.long_opt.empty()) {
      ss << "|";
    }
  }
  if (!option.long_opt.empty()) {
    ss << "--" << option.long_opt;
  }
}

std::string FlatCompiler::GetShortUsageString(
    const std::string& program_name) const {
  std::stringstream ss;
  ss << "Usage: " << program_name << " [";

  for (const FlatCOption& option : language_options) {
    AppendShortOption(ss, option);
    ss << ", ";
  }

  for (const FlatCOption& option : flatc_options) {
    AppendShortOption(ss, option);
    ss << ", ";
  }

  ss.seekp(-2, ss.cur);
  ss << "]... FILE... [-- BINARY_FILE...]";
  std::string help = ss.str();
  std::stringstream ss_textwrap;
  AppendTextWrappedString(ss_textwrap, help, 80, 0);
  return ss_textwrap.str();
}

std::string FlatCompiler::GetUsageString(
    const std::string& program_name) const {
  std::stringstream ss;
  ss << "Usage: " << program_name
     << " [OPTION]... FILE... [-- BINARY_FILE...]\n";

  for (const FlatCOption& option : language_options) {
    AppendOption(ss, option, 80, 25);
  }
  ss << "\n";

  for (const FlatCOption& option : flatc_options) {
    AppendOption(ss, option, 80, 25);
  }
  ss << "\n";

  std::string files_description =
      "FILEs may be schemas (must end in .fbs), binary schemas (must end in "
      ".bfbs) or JSON files (conforming to preceding schema). BINARY_FILEs "
      "after the -- must be binary flatbuffer format files. Output files are "
      "named using the base file name of the input, and written to the current "
      "directory or the path given by -o. example: " +
      program_name + " -c -b schema1.fbs schema2.fbs data.json";
  AppendTextWrappedString(ss, files_description, 80, 0);
  ss << "\n";
  return ss.str();
}

void FlatCompiler::AnnotateBinaries(const uint8_t* binary_schema,
                                    const uint64_t binary_schema_size,
                                    const FlatCOptions& options) {
  const std::string& schema_filename = options.annotate_schema;

  for (const std::string& filename : options.filenames) {
    std::string binary_contents;
    if (!flatbuffers::LoadFile(filename.c_str(), true, &binary_contents)) {
      Warn("unable to load binary file: " + filename);
      continue;
    }

    const uint8_t* binary =
        reinterpret_cast<const uint8_t*>(binary_contents.c_str());
    const size_t binary_size = binary_contents.size();
    const bool is_size_prefixed = options.opts.size_prefixed;

    flatbuffers::BinaryAnnotator binary_annotator(
        binary_schema, binary_schema_size, binary, binary_size,
        is_size_prefixed);

    auto annotations = binary_annotator.Annotate();

    flatbuffers::AnnotatedBinaryTextGenerator::Options text_gen_opts;
    text_gen_opts.include_vector_contents =
        options.annotate_include_vector_contents;

    // TODO(dbaileychess): Right now we just support a single text-based
    // output of the annotated binary schema, which we generate here. We
    // could output the raw annotations instead and have third-party tools
    // use them to generate their own output.
    flatbuffers::AnnotatedBinaryTextGenerator text_generator(
        text_gen_opts, annotations, binary, binary_size);

    text_generator.Generate(filename, schema_filename);
  }
}

FlatCOptions FlatCompiler::ParseFromCommandLineArguments(int argc,
                                                         const char** argv) {
  if (argc <= 1) {
    Error("Need to provide at least one argument.");
  }

  FlatCOptions options;

  options.program_name = std::string(argv[0]);

  IDLOptions& opts = options.opts;

  for (int argi = 1; argi < argc; argi++) {
    std::string arg = argv[argi];
    if (arg[0] == '-') {
      if (options.filenames.size() && arg[1] != '-')
        Error("invalid option location: " + arg, true);
      if (arg == "-o") {
        if (++argi >= argc) Error("missing path following: " + arg, true);
        options.output_path = flatbuffers::ConCatPathFileName(
            flatbuffers::PosixPath(argv[argi]), "");
      } else if (arg == "-I") {
        if (++argi >= argc) Error("missing path following: " + arg, true);
        options.include_directories_storage.push_back(
            flatbuffers::PosixPath(argv[argi]));
        options.include_directories.push_back(
            options.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);
        options.conform_to_schema = flatbuffers::PosixPath(argv[argi]);
      } else if (arg == "--conform-includes") {
        if (++argi >= argc) Error("missing path following: " + arg, true);
        options.include_directories_storage.push_back(
            flatbuffers::PosixPath(argv[argi]));
        options.conform_include_directories.push_back(
            options.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_prefix = 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 == "--go-module-name") {
        if (++argi >= argc) Error("missing golang module name" + arg, true);
        opts.go_module_name = 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 == "--cpp-minify-enums") {
        opts.cpp_minify_enums = true;
      } else if (arg == "--scoped-enums") {
        opts.prefixed_enums = false;
        opts.scoped_enums = true;
      } else if (arg == "--no-emit-min-max-enum-values") {
        opts.emit_min_max_enum_values = false;
      } 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 == "--gen-absl-hash") {
        opts.gen_absl_hash = 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-package-prefix") {
        if (++argi >= argc) Error("missing prefix following: " + arg, true);
        opts.java_package_prefix = argv[argi];
      } else if (arg == "--java-checkerframework") {
        opts.java_checkerframework = true;
      } else if (arg == "--gen-generated") {
        opts.gen_generated = true;
      } else if (arg == "--swift-implementation-only") {
        opts.swift_implementation_only = true;
      } else if (arg == "--gen-json-emit") {
        opts.gen_json_coders = 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;
        opts.include_dependence_headers = false;
      } else if (arg == "--raw-binary") {
        options.raw_binary = true;
      } else if (arg == "--size-prefixed") {
        opts.size_prefixed = true;
      } else if (arg == "--") {  // Separator between text and binary inputs.
        options.binary_files_from = options.filenames.size();
      } 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 == "--keep-proto-id") {
        opts.keep_proto_id = true;
      } else if (arg == "--proto-id-gap") {
        if (++argi >= argc) Error("missing case style following: " + arg, true);
        if (!strcmp(argv[argi], "nop"))
          opts.proto_id_gap_action = IDLOptions::ProtoIdGapAction::NO_OP;
        else if (!strcmp(argv[argi], "warn"))
          opts.proto_id_gap_action = IDLOptions::ProtoIdGapAction::WARNING;
        else if (!strcmp(argv[argi], "error"))
          opts.proto_id_gap_action = IDLOptions::ProtoIdGapAction::ERROR;
        else
          Error("unknown case style: " + std::string(argv[argi]), true);
      } else if (arg == "--schema") {
        options.schema_binary = true;
      } else if (arg == "-M") {
        options.print_make_rules = true;
      } else if (arg == "--version") {
        printf("flatc version %s\n", FLATC_VERSION());
        exit(0);
      } else if (arg == "--help" || arg == "-h") {
        printf("%s\n", GetUsageString(options.program_name).c_str());
        exit(0);
      } else if (arg == "--grpc") {
        options.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 == "--bfbs-absolute-paths") {
        opts.binary_schema_absolute_paths = true;
      } else if (arg == "--reflect-types") {
        opts.mini_reflect = IDLOptions::kTypes;
      } else if (arg == "--reflect-names") {
        opts.mini_reflect = IDLOptions::kTypesAndNames;
      } else if (arg == "--rust-serialize") {
        opts.rust_serialize = true;
      } else if (arg == "--rust-module-root-file") {
        opts.rust_module_root_file = true;
      } 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 == "--warnings-as-errors") {
        opts.warnings_as_errors = 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 if (arg == "--cs-global-alias") {
        opts.cs_global_alias = true;
      } else if (arg == "--json-nested-bytes") {
        opts.json_nested_legacy_flatbuffers = true;
      } else if (arg == "--ts-flat-files") {
        // deprecated -- just enables generate_all
        Warn("--ts-flat-files is deprecated; use --gen-all instead.\n");
        opts.generate_all = true;
      } else if (arg == "--ts-entry-points") {
        // deprecated -- just enables generate_all
        Warn("--ts-entry-points is deprecated; use --gen-all instead.\n");
        opts.generate_all = true;
      } else if (arg == "--ts-no-import-ext") {
        opts.ts_no_import_ext = true;
      } else if (arg == "--no-leak-private-annotation") {
        opts.no_leak_private_annotations = true;
      } else if (arg == "--python-no-type-prefix-suffix") {
        opts.python_no_type_prefix_suffix = true;
      } else if (arg == "--python-typing") {
        opts.python_typing = true;
      } else if (arg.rfind("--python-version=", 0) == 0) {
        opts.python_version =
            arg.substr(std::string("--python-version=").size());
      } else if (arg == "--python-version") {
        if (++argi >= argc) Error("missing value following: " + arg, true);
        opts.python_version = argv[argi];
      } else if (arg == "--python-decode-obj-api-strings") {
        opts.python_decode_obj_api_strings = true;
      } else if (arg == "--python-gen-numpy" ||
                 arg == "--python-gen-numpy=true") {
        opts.python_gen_numpy = true;
      } else if (arg == "--no-python-gen-numpy" ||
                 arg == "--python-gen-numpy=false") {
        opts.python_gen_numpy = false;
      } else if (arg == "--ts-omit-entrypoint") {
        opts.ts_omit_entrypoint = true;
      } else if (arg == "--ts-undefined-for-optionals") {
        opts.ts_undefined_for_optionals = true;
      } else if (arg == "--annotate-sparse-vectors") {
        options.annotate_include_vector_contents = false;
      } else if (arg == "--annotate") {
        if (++argi >= argc) Error("missing path following: " + arg, true);
        options.annotate_schema = flatbuffers::PosixPath(argv[argi]);
      } else if (arg == "--file-names-only") {
        options.file_names_only = true;
      } else if (arg == "--grpc-filename-suffix") {
        if (++argi >= argc) Error("missing gRPC filename suffix: " + arg, true);
        opts.grpc_filename_suffix = argv[argi];
      } else if (arg.rfind("--grpc-filename-suffix=", 0) == 0) {
        opts.grpc_filename_suffix =
            arg.substr(std::string("--grpc-filename-suffix=").size());
      } else if (arg == "--grpc-additional-header") {
        if (++argi >= argc) Error("missing include following: " + arg, true);
        opts.grpc_additional_headers.push_back(argv[argi]);
      } else if (arg.rfind("--grpc-additional-header=", 0) == 0) {
        opts.grpc_additional_headers.push_back(
            arg.substr(std::string("--grpc-additional-header=").size()));
      } else if (arg == "--grpc-search-path") {
        if (++argi >= argc) Error("missing gRPC search path: " + arg, true);
        opts.grpc_search_path = argv[argi];
      } else if (arg.rfind("--grpc-search-path=", 0) == 0) {
        opts.grpc_search_path =
            arg.substr(std::string("--grpc-search-path=").size());
      } else if (arg == "--grpc-use-system-headers" ||
                 arg == "--grpc-use-system-headers=true") {
        opts.grpc_use_system_headers = true;
      } else if (arg == "--no-grpc-use-system-headers" ||
                 arg == "--grpc-use-system-headers=false") {
        opts.grpc_use_system_headers = false;
      } else if (arg == "--grpc-python-typed-handlers" ||
                 arg == "--grpc-python-typed-handlers=true") {
        opts.grpc_python_typed_handlers = true;
      } else if (arg == "--no-grpc-python-typed-handlers" ||
                 arg == "--grpc-python-typed-handlers=false") {
        opts.grpc_python_typed_handlers = false;
      } else if (arg == "--grpc-callback-api" ||
                 arg == "--grpc-callback-api=true") {
        opts.grpc_callback_api = true;
      } else if (arg == "--no-grpc-callback-api" ||
                 arg == "--grpc-callback-api=false") {
        opts.grpc_callback_api = false;
      } else {
        if (arg == "--proto") {
          opts.proto_mode = true;
        }

        auto code_generator_it = code_generators_.find(arg);
        if (code_generator_it == code_generators_.end()) {
          Error("unknown commandline argument: " + arg, true);
          return options;
        }

        std::shared_ptr<CodeGenerator> code_generator =
            code_generator_it->second;

        // TODO(derekbailey): remove in favor of just checking if
        // generators.empty().
        options.any_generator = true;
        opts.lang_to_generate |= code_generator->Language();

        auto is_binary_schema = code_generator->SupportsBfbsGeneration();
        opts.binary_schema_comments = is_binary_schema;
        options.requires_bfbs = is_binary_schema;
        options.generators.push_back(std::move(code_generator));
      }
    } else {
      options.filenames.push_back(flatbuffers::PosixPath(argv[argi]));
    }
  }

  ValidateOptions(options);

  return options;
}

void FlatCompiler::ValidateOptions(const FlatCOptions& options) {
  const IDLOptions& opts = options.opts;

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

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

  if (opts.cs_gen_json_serializer && !opts.generate_object_based_api) {
    Error(
        "--cs-gen-json-serializer requires --gen-object-api to be set as "
        "well.");
  }
}

flatbuffers::Parser FlatCompiler::GetConformParser(
    const FlatCOptions& options) {
  flatbuffers::Parser conform_parser;

  // conform parser should check advanced options,
  // so, it have to have knowledge about languages:
  conform_parser.opts.lang_to_generate = options.opts.lang_to_generate;

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

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

std::unique_ptr<Parser> FlatCompiler::GenerateCode(const FlatCOptions& options,
                                                   Parser& conform_parser) {
  std::unique_ptr<Parser> parser =
      std::unique_ptr<Parser>(new Parser(options.opts));

  for (auto file_it = options.filenames.begin();
       file_it != options.filenames.end(); ++file_it) {
    IDLOptions opts = options.opts;

    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 - options.filenames.begin()) >=
                     options.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 (!options.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 || is_binary_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 Parser(opts));
      }
      // Try to parse the file contents (binary schema/flexbuffer/textual
      // schema)
      if (is_binary_schema) {
        LoadBinarySchema(*parser, filename, contents);
      } else if (opts.use_flexbuffers) {
        if (opts.lang_to_generate == IDLOptions::kJson) {
          auto data = reinterpret_cast<const uint8_t*>(contents.c_str());
          auto size = contents.size();
          std::vector<uint8_t> reuse_tracker;
          if (!flexbuffers::VerifyBuffer(data, size, &reuse_tracker))
            Error("flexbuffers file failed to verify: " + filename, false);
          parser->flex_root_ = flexbuffers::GetRoot(data, size);
        } else {
          parser->flex_builder_.Clear();
          ParseFile(*parser, filename, contents, options.include_directories);
        }
      } else {
        ParseFile(*parser, filename, contents, options.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) &&
          !options.conform_to_schema.empty()) {
        auto err = parser->ConformTo(conform_parser);
        if (!err.empty()) Error("schemas don\'t conform: " + err, false);
      }
      if (options.schema_binary || opts.binary_schema_gen_embed) {
        parser->Serialize();
      }
      if (options.schema_binary) {
        parser->file_extension_ = reflection::SchemaExtension();
      }
    }
    std::string filebase =
        flatbuffers::StripPath(flatbuffers::StripExtension(filename));

    // If one of the generators uses bfbs, serialize the parser and get
    // the serialized buffer and length.
    const uint8_t* bfbs_buffer = nullptr;
    int64_t bfbs_length = 0;
    if (options.requires_bfbs) {
      parser->Serialize();
      bfbs_buffer = parser->builder_.GetBufferPointer();
      bfbs_length = parser->builder_.GetSize();
    }

    for (const std::shared_ptr<CodeGenerator>& code_generator :
         options.generators) {
      if (options.print_make_rules) {
        std::string make_rule;
        const CodeGenerator::Status status = code_generator->GenerateMakeRule(
            *parser, options.output_path, filename, make_rule);
        if (status == CodeGenerator::Status::OK && !make_rule.empty()) {
          printf("%s\n",
                 flatbuffers::WordWrap(make_rule, 80, " ", " \\").c_str());
        } else {
          Error("Cannot generate make rule for " +
                code_generator->LanguageName());
        }
      } else {
        flatbuffers::EnsureDirExists(options.output_path);

        // Prefer bfbs generators if present.
        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);
          if (status != CodeGenerator::Status::OK) {
            Error("Unable to generate " + code_generator->LanguageName() +
                  " for " + filebase + code_generator->status_detail +
                  " using bfbs generator.");
          }
        } else {
          if ((!code_generator->IsSchemaOnly() ||
               (is_schema || is_binary_schema)) &&
              code_generator->GenerateCode(*parser, options.output_path,
                                           filebase) !=
                  CodeGenerator::Status::OK) {
            Error("Unable to generate " + code_generator->LanguageName() +
                  " for " + filebase + code_generator->status_detail);
          }
        }
      }

      if (options.grpc_enabled) {
        const CodeGenerator::Status status = code_generator->GenerateGrpcCode(
            *parser, options.output_path, filebase);

        if (status == CodeGenerator::Status::NOT_IMPLEMENTED) {
          Warn("GRPC interface generator not implemented for " +
               code_generator->LanguageName());
        } else if (status == CodeGenerator::Status::ERROR) {
          Error("Unable to generate GRPC interface for " +
                code_generator->LanguageName());
        }
      }
    }

    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");
    }

    // We do not want to generate code for the definitions in this file
    // in any files coming up next.
    parser->MarkGenerated();
  }

  return parser;
}

int FlatCompiler::Compile(const FlatCOptions& options) {
  // TODO(derekbailey): change to std::optional<Parser>
  Parser conform_parser = GetConformParser(options);

  // TODO(derekbailey): split to own method.
  if (!options.annotate_schema.empty()) {
    const std::string ext = flatbuffers::GetExtension(options.annotate_schema);
    if (!(ext == reflection::SchemaExtension() || ext == "fbs")) {
      Error("Expected a `.bfbs` or `.fbs` schema, got: " +
            options.annotate_schema);
    }

    const bool is_binary_schema = ext == reflection::SchemaExtension();

    std::string schema_contents;
    if (!flatbuffers::LoadFile(options.annotate_schema.c_str(),
                               /*binary=*/is_binary_schema, &schema_contents)) {
      Error("unable to load schema: " + options.annotate_schema);
    }

    const uint8_t* binary_schema = nullptr;
    uint64_t binary_schema_size = 0;

    IDLOptions binary_opts;
    binary_opts.lang_to_generate |= flatbuffers::IDLOptions::kBinary;
    Parser parser(binary_opts);

    if (is_binary_schema) {
      binary_schema = reinterpret_cast<const uint8_t*>(schema_contents.c_str());
      binary_schema_size = schema_contents.size();
    } else {
      // If we need to generate the .bfbs file from the provided schema file
      // (.fbs)
      ParseFile(parser, options.annotate_schema, schema_contents,
                options.include_directories);
      parser.Serialize();

      binary_schema = parser.builder_.GetBufferPointer();
      binary_schema_size = parser.builder_.GetSize();
    }

    if (binary_schema == nullptr || !binary_schema_size) {
      Error("could not parse a value binary schema from: " +
            options.annotate_schema);
    }

    // Annotate the provided files with the binary_schema.
    AnnotateBinaries(binary_schema, binary_schema_size, options);

    // We don't support doing anything else after annotating a binary.
    return 0;
  }

  if (options.generators.empty() && options.conform_to_schema.empty()) {
    Error("No generator registered");
    return -1;
  }

  std::unique_ptr<Parser> parser = GenerateCode(options, conform_parser);

  for (const auto& code_generator : options.generators) {
    if (code_generator->SupportsRootFileGeneration()) {
      code_generator->GenerateRootFile(*parser, options.output_path);
    }
  }

  return 0;
}

bool FlatCompiler::RegisterCodeGenerator(
    const FlatCOption& option, std::shared_ptr<CodeGenerator> code_generator) {
  if (!option.short_opt.empty() &&
      code_generators_.find("-" + option.short_opt) != code_generators_.end()) {
    Error("multiple generators registered under: -" + option.short_opt, false,
          false);
    return false;
  }

  if (!option.short_opt.empty()) {
    code_generators_["-" + option.short_opt] = code_generator;
  }

  if (!option.long_opt.empty() &&
      code_generators_.find("--" + option.long_opt) != code_generators_.end()) {
    Error("multiple generators registered under: --" + option.long_opt, false,
          false);
    return false;
  }

  if (!option.long_opt.empty()) {
    code_generators_["--" + option.long_opt] = code_generator;
  }

  language_options.insert(option);

  return true;
}

}  // namespace flatbuffers
