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

#include "flatbuffers/flatc.h"

#include <list>

namespace flatbuffers {

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

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

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

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

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

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

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

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

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

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

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

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

  for (int argi = 0; argi < argc; argi++) {
    std::string arg = argv[argi];
    if (arg[0] == '-') {
      if (filenames.size() && arg[1] != '-')
        Error("invalid option location: " + arg, true);
      if (arg == "-o") {
        if (++argi >= argc) Error("missing path following: " + arg, true);
        output_path = flatbuffers::ConCatPathFileName(
            flatbuffers::PosixPath(argv[argi]), "");
      } else if (arg == "-I") {
        if (++argi >= argc) Error("missing path following: " + arg, true);
        include_directories_storage.push_back(
            flatbuffers::PosixPath(argv[argi]));
        include_directories.push_back(
            include_directories_storage.back().c_str());
      } else if (arg == "--conform") {
        if (++argi >= argc) Error("missing path following: " + arg, true);
        conform_to_schema = flatbuffers::PosixPath(argv[argi]);
      } else if (arg == "--conform-includes") {
        if (++argi >= argc) Error("missing path following: " + arg, true);
        include_directories_storage.push_back(
            flatbuffers::PosixPath(argv[argi]));
        conform_include_directories.push_back(
            include_directories_storage.back().c_str());
      } else if (arg == "--include-prefix") {
        if (++argi >= argc) Error("missing path following: " + arg, true);
        opts.include_prefix = flatbuffers::ConCatPathFileName(
            flatbuffers::PosixPath(argv[argi]), "");
      } else if (arg == "--keep-prefix") {
        opts.keep_include_path = true;
      } else if (arg == "--strict-json") {
        opts.strict_json = true;
      } else if (arg == "--allow-non-utf8") {
        opts.allow_non_utf8 = true;
      } else if (arg == "--natural-utf8") {
        opts.natural_utf8 = true;
      } else if (arg == "--no-js-exports") {
        opts.skip_js_exports = true;
      } else if (arg == "--goog-js-export") {
        opts.use_goog_js_export_format = true;
        opts.use_ES6_js_export_format = false;
      } else if (arg == "--es6-js-export") {
        opts.use_goog_js_export_format = false;
        opts.use_ES6_js_export_format = true;
      } else if (arg == "--go-namespace") {
        if (++argi >= argc) Error("missing golang namespace" + arg, true);
        opts.go_namespace = argv[argi];
      } else if (arg == "--go-import") {
        if (++argi >= argc) Error("missing golang import" + arg, true);
        opts.go_import = argv[argi];
      } else if (arg == "--defaults-json") {
        opts.output_default_scalars_in_json = true;
      } else if (arg == "--unknown-json") {
        opts.skip_unexpected_fields_in_json = true;
      } else if (arg == "--no-prefix") {
        opts.prefixed_enums = false;
      } else if (arg == "--scoped-enums") {
        opts.prefixed_enums = false;
        opts.scoped_enums = true;
      } else if (arg == "--no-union-value-namespacing") {
        opts.union_value_namespacing = false;
      } else if (arg == "--gen-mutable") {
        opts.mutable_buffer = true;
      } else if (arg == "--gen-name-strings") {
        opts.generate_name_strings = true;
      } else if (arg == "--gen-object-api") {
        opts.generate_object_based_api = true;
      } else if (arg == "--gen-compare") {
        opts.gen_compare = true;
      } else if (arg == "--cpp-include") {
        if (++argi >= argc) Error("missing include following: " + arg, true);
        opts.cpp_includes.push_back(argv[argi]);
      } else if (arg == "--cpp-ptr-type") {
        if (++argi >= argc) Error("missing type following: " + arg, true);
        opts.cpp_object_api_pointer_type = argv[argi];
      } else if (arg == "--cpp-str-type") {
        if (++argi >= argc) Error("missing type following: " + arg, true);
        opts.cpp_object_api_string_type = argv[argi];
      } else if (arg == "--cpp-str-flex-ctor") {
        opts.cpp_object_api_string_flexible_constructor = true;
      } else if (arg == "--no-cpp-direct-copy") {
        opts.cpp_direct_copy = false;
      } else if (arg == "--gen-nullable") {
        opts.gen_nullable = true;
      } else if (arg == "--java-checkerframework") {
        opts.java_checkerframework = true;
      } else if (arg == "--gen-generated") {
        opts.gen_generated = true;
      } else if (arg == "--object-prefix") {
        if (++argi >= argc) Error("missing prefix following: " + arg, true);
        opts.object_prefix = argv[argi];
      } else if (arg == "--object-suffix") {
        if (++argi >= argc) Error("missing suffix following: " + arg, true);
        opts.object_suffix = argv[argi];
      } else if (arg == "--gen-all") {
        opts.generate_all = true;
        opts.include_dependence_headers = false;
        opts.reexport_ts_modules = false;
      } else if (arg == "--gen-includes") {
        // Deprecated, remove this option some time in the future.
        Warn("warning: --gen-includes is deprecated (it is now default)\n");
      } else if (arg == "--no-includes") {
        opts.include_dependence_headers = false;
      } else if (arg == "--gen-onefile") {
        opts.one_file = true;
      } else if (arg == "--raw-binary") {
        raw_binary = true;
      } else if (arg == "--size-prefixed") {
        opts.size_prefixed = true;
      } else if (arg == "--") {  // Separator between text and binary inputs.
        binary_files_from = filenames.size();
      } else if (arg == "--proto") {
        opts.proto_mode = true;
      } else if (arg == "--proto-namespace-suffix") {
        if (++argi >= argc) Error("missing namespace suffix" + arg, true);
        opts.proto_namespace_suffix = argv[argi];
      } else if (arg == "--oneof-union") {
        opts.proto_oneof_union = true;
      } else if (arg == "--schema") {
        schema_binary = true;
      } else if (arg == "-M") {
        print_make_rules = true;
      } else if (arg == "--version") {
        printf("flatc version %s\n", FLATC_VERSION());
        exit(0);
      } else if (arg == "--grpc") {
        grpc_enabled = true;
      } else if (arg == "--bfbs-comments") {
        opts.binary_schema_comments = true;
      } else if (arg == "--bfbs-builtins") {
        opts.binary_schema_builtins = true;
      } else if (arg == "--bfbs-gen-embed") {
        opts.binary_schema_gen_embed = true;
      } else if (arg == "--no-fb-import") {
        opts.skip_flatbuffers_import = true;
      } else if (arg == "--no-ts-reexport") {
        opts.reexport_ts_modules = false;
      } else if (arg == "--short-names") {
        opts.js_ts_short_names = true;
      } else if (arg == "--reflect-types") {
        opts.mini_reflect = IDLOptions::kTypes;
      } else if (arg == "--reflect-names") {
        opts.mini_reflect = IDLOptions::kTypesAndNames;
      } 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 == "--cpp-std") {
        if (++argi >= argc)
          Error("missing C++ standard specification" + arg, true);
        opts.cpp_std = argv[argi];
      } else {
        for (size_t i = 0; i < params_.num_generators; ++i) {
          if (arg == params_.generators[i].generator_opt_long ||
              (params_.generators[i].generator_opt_short &&
               arg == params_.generators[i].generator_opt_short)) {
            generator_enabled[i] = true;
            any_generator = true;
            opts.lang_to_generate |= params_.generators[i].lang;
            goto found;
          }
        }
        Error("unknown commandline argument: " + arg, true);
      found:;
      }
    } else {
      filenames.push_back(flatbuffers::PosixPath(argv[argi]));
    }
  }

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

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

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

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

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

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

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

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

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

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

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

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

}  // namespace flatbuffers
