//===- FrontendOptions.h ----------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_FLANG_FRONTEND_FRONTENDOPTIONS_H
#define LLVM_FLANG_FRONTEND_FRONTENDOPTIONS_H

#include "flang/Common/Fortran-features.h"
#include "flang/Parser/characters.h"
#include "flang/Parser/unparse.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/MemoryBuffer.h"

#include <cstdint>
#include <string>

namespace Fortran::frontend {

enum ActionKind {
  InvalidAction = 0,

  /// -test-io mode
  InputOutputTest,

  /// -E mode
  PrintPreprocessedInput,

  /// -fsyntax-only
  ParseSyntaxOnly,

  /// Emit a .o file.
  EmitObj,

  /// Parse, unparse the parse-tree and output a Fortran source file
  DebugUnparse,

  /// Parse, unparse the parse-tree and output a Fortran source file, skip the
  /// semantic checks
  DebugUnparseNoSema,

  /// Parse, resolve the sybmols, unparse the parse-tree and then output a
  /// Fortran source file
  DebugUnparseWithSymbols,

  /// Parse, run semantics and then output symbols from semantics
  DebugDumpSymbols,

  /// Parse, run semantics and then output the parse tree
  DebugDumpParseTree,

  /// Parse, run semantics and then output the parse tree and symbols
  DebugDumpAll,

  /// Parse and then output the parse tree, skip the semantic checks
  DebugDumpParseTreeNoSema,

  /// Dump provenance
  DebugDumpProvenance,

  /// Parse then output the parsing log
  DebugDumpParsingLog,

  /// Parse then output the number of objects in the parse tree and the overall
  /// size
  DebugMeasureParseTree,

  /// Parse, run semantics and then output the pre-FIR tree
  DebugPreFIRTree,

  /// `-fget-definition`
  GetDefinition,

  /// Parse, run semantics and then dump symbol sources map
  GetSymbolsSources,

  /// Only execute frontend initialization
  InitOnly,

  /// Run a plugin action
  PluginAction

  /// TODO: RunPreprocessor, EmitLLVM, EmitLLVMOnly,
  /// EmitCodeGenOnly, EmitAssembly, (...)
};

/// \param suffix The file extension
/// \return True if the file extension should be processed as fixed form
bool isFixedFormSuffix(llvm::StringRef suffix);

/// \param suffix The file extension
/// \return True if the file extension should be processed as free form
bool isFreeFormSuffix(llvm::StringRef suffix);

/// \param suffix The file extension
/// \return True if the file should be preprocessed
bool mustBePreprocessed(llvm::StringRef suffix);

enum class Language : uint8_t {
  Unknown,

  /// LLVM IR: we accept this so that we can run the optimizer on it,
  /// and compile it to assembly or object code.
  LLVM_IR,

  /// @{ Languages that the frontend can parse and compile.
  Fortran,
};

// Source file layout
enum class FortranForm {
  /// The user has not specified a form. Base the form off the file extension.
  Unknown,

  /// -ffree-form
  FixedForm,

  /// -ffixed-form
  FreeForm
};

/// The kind of a file that we've been handed as an input.
class InputKind {
private:
  Language lang_;

public:
  /// The input file format.
  enum Format { Source, ModuleMap, Precompiled };

  constexpr InputKind(Language l = Language::Unknown) : lang_(l) {}

  Language GetLanguage() const { return static_cast<Language>(lang_); }

  /// Is the input kind fully-unknown?
  bool IsUnknown() const { return lang_ == Language::Unknown; }
};

/// An input file for the front end.
class FrontendInputFile {
  /// The file name, or "-" to read from standard input.
  std::string file_;

  /// The input, if it comes from a buffer rather than a file. This object
  /// does not own the buffer, and the caller is responsible for ensuring
  /// that it outlives any users.
  const llvm::MemoryBuffer *buffer_ = nullptr;

  /// The kind of input, atm it contains language
  InputKind kind_;

  /// Is this input file in fixed-form format? This is simply derived from the
  /// file extension and should not be altered by consumers. For input from
  /// stdin this is never modified.
  bool isFixedForm_ = false;

  /// Must this file be preprocessed? Note that in Flang the preprocessor is
  /// always run. This flag is used to control whether predefined and command
  /// line preprocessor macros are enabled or not. In practice, this is
  /// sufficient to implement gfortran`s logic controlled with `-cpp/-nocpp`.
  unsigned mustBePreprocessed_ : 1;

public:
  FrontendInputFile() = default;
  FrontendInputFile(llvm::StringRef file, InputKind kind)
      : file_(file.str()), kind_(kind) {

    // Based on the extension, decide whether this is a fixed or free form
    // file.
    auto pathDotIndex{file.rfind(".")};
    std::string pathSuffix{file.substr(pathDotIndex + 1)};
    isFixedForm_ = isFixedFormSuffix(pathSuffix);
    mustBePreprocessed_ = mustBePreprocessed(pathSuffix);
  }

  FrontendInputFile(const llvm::MemoryBuffer *buffer, InputKind kind)
      : buffer_(buffer), kind_(kind) {}

  InputKind kind() const { return kind_; }

  bool IsEmpty() const { return file_.empty() && buffer_ == nullptr; }
  bool IsFile() const { return !IsBuffer(); }
  bool IsBuffer() const { return buffer_ != nullptr; }
  bool IsFixedForm() const { return isFixedForm_; }
  bool MustBePreprocessed() const { return mustBePreprocessed_; }

  llvm::StringRef file() const {
    assert(IsFile());
    return file_;
  }

  const llvm::MemoryBuffer *buffer() const {
    assert(IsBuffer() && "Requested buffer_, but it is empty!");
    return buffer_;
  }
};

/// FrontendOptions - Options for controlling the behavior of the frontend.
struct FrontendOptions {
  FrontendOptions()
      : showHelp(false), showVersion(false), instrumentedParse(false),
        needProvenanceRangeToCharBlockMappings(false) {}

  /// Show the -help text.
  unsigned showHelp : 1;

  /// Show the -version text.
  unsigned showVersion : 1;

  /// Instrument the parse to get a more verbose log
  unsigned instrumentedParse : 1;

  /// Enable Provenance to character-stream mapping. Allows e.g. IDEs to find
  /// symbols based on source-code location. This is not needed in regular
  /// compilation.
  unsigned needProvenanceRangeToCharBlockMappings : 1;

  /// Input values from `-fget-definition`
  struct GetDefinitionVals {
    unsigned line;
    unsigned startColumn;
    unsigned endColumn;
  };
  GetDefinitionVals getDefVals;

  /// The input files and their types.
  std::vector<FrontendInputFile> inputs;

  /// The output file, if any.
  std::string outputFile;

  /// The frontend action to perform.
  frontend::ActionKind programAction;

  // The form to process files in, if specified.
  FortranForm fortranForm = FortranForm::Unknown;

  // The column after which characters are ignored in fixed form lines in the
  // source file.
  int fixedFormColumns = 72;

  /// The input kind, either specified via -x argument or deduced from the input
  /// file name.
  InputKind dashX;

  // Language features
  common::LanguageFeatureControl features;

  // Source file encoding
  Fortran::parser::Encoding encoding{Fortran::parser::Encoding::UTF_8};

  /// The list of plugins to load.
  std::vector<std::string> plugins;

  /// The name of the action to run when using a plugin action.
  std::string ActionName;

  // Return the appropriate input kind for a file extension. For example,
  /// "*.f" would return Language::Fortran.
  ///
  /// \return The input kind for the extension, or Language::Unknown if the
  /// extension is not recognized.
  static InputKind GetInputKindForExtension(llvm::StringRef extension);
};
} // namespace Fortran::frontend

#endif // LLVM_FLANG_FRONTEND_FRONTENDOPTIONS_H
