/*
 * 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"},
    {"", "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") {
        // 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 == "--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
