/*
 * 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", "",
    "Generate a single typescript file per .fbs file. Implies "
    "ts_entry_points." },
  { "", "ts-entry-points", "",
    "Generate entry point typescript per namespace. Implies 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" },
  { "", "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 == "--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") {
        opts.ts_flat_files = true;
        opts.ts_entry_points = true;
        opts.generate_all = true;
      } else if (arg == "--ts-entry-points") {
        opts.ts_entry_points = true;
        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 == "--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") {
        // TODO (khhn): Provide 2 implementation
        options.file_names_only = true;
      } else if (arg == "--grpc-filename-suffix") {
        if (++argi >= argc) Error("missing gRPC filename suffix: " + arg, true);
        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;

          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
