// Copyright 2023 Google LLC
//
// 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
//
//     https://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.

#ifndef MPACT_SIM_DECODER_INSTRUCTION_SET_VISITOR_H_
#define MPACT_SIM_DECODER_INSTRUCTION_SET_VISITOR_H_

#include <deque>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "absl/container/btree_set.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "antlr4-runtime/ParserRuleContext.h"
#include "mpact/sim/decoder/InstructionSetLexer.h"
#include "mpact/sim/decoder/InstructionSetParser.h"
#include "mpact/sim/decoder/antlr_parser_wrapper.h"
#include "mpact/sim/decoder/bundle.h"
#include "mpact/sim/decoder/decoder_error_listener.h"
#include "mpact/sim/decoder/instruction.h"
#include "mpact/sim/decoder/instruction_set.h"
#include "mpact/sim/decoder/opcode.h"
#include "mpact/sim/decoder/slot.h"
#include "mpact/sim/decoder/template_expression.h"

// This file declares the classes that interact with the antlr4 library
// to parse an input stream and generate the parse tree, then visiting the
// parse tree to build up the internal representation from which further
// processing and eventual c++ code generation is done.
namespace mpact {
namespace sim {
namespace machine_description {
namespace instruction_set {

using InstructionSetParser = ::sim::machine_description::instruction_set::
    generated::InstructionSetParser;
using ::sim::machine_description::instruction_set::generated::
    InstructionSetLexer;

using IsaAntlrParserWrapper =
    decoder::AntlrParserWrapper<InstructionSetParser, InstructionSetLexer>;

// Visitor class for the Antlr4 parse tree. It does not derive from Antlr4
// base classes so that the return types and method parameters could be
// customized.
class InstructionSetVisitor {
 public:
  InstructionSetVisitor();
  ~InstructionSetVisitor();

  // Entry point for processing a source_stream input, generating any output
  // files in the given directory. Returns OK if no errors were encountered.
  absl::Status Process(const std::vector<std::string> &file_names,
                       const std::string &prefix, const std::string &isa_name,
                       const std::vector<std::string> &include_roots,
                       absl::string_view directory);

  // Global const expressions.
  absl::Status AddConstant(absl::string_view name, absl::string_view type,
                           TemplateExpression *expr);
  TemplateExpression *GetConstExpression(absl::string_view name) const;
  // The current isa name.
  const std::string &isa_name() const { return isa_name_; }

 private:
  struct TemplateFunctionEvaluator {
    TemplateFunction::Evaluator function;
    size_t arity;
    TemplateFunctionEvaluator(TemplateFunction::Evaluator function_,
                              size_t arity_)
        : function(std::move(function_)), arity(arity_) {}
  };

  // Type aliases for antlr4 context types.
  using TopLevelCtx = InstructionSetParser::Top_levelContext;
  using NamespaceDeclCtx = InstructionSetParser::Namespace_declContext;
  using ConstantDefCtx = InstructionSetParser::Constant_defContext;
  using IncludeFileCtx = InstructionSetParser::Include_fileContext;
  using DeclarationCtx = InstructionSetParser::DeclarationContext;
  using IsaDeclCtx = InstructionSetParser::Isa_declarationContext;
  using BundleDeclCtx = InstructionSetParser::Bundle_declarationContext;
  using SlotDeclCtx = InstructionSetParser::Slot_declarationContext;
  using BaseItemListCtx = InstructionSetParser::Base_item_listContext;
  using ExpressionCtx = InstructionSetParser::ExpressionContext;
  using ArraySpecCtx = InstructionSetParser::Array_specContext;
  using OpcodeSpecCtx = InstructionSetParser::Opcode_specContext;
  using BundleListCtx = InstructionSetParser::Bundle_listContext;
  using SlotListCtx = InstructionSetParser::Slot_listContext;
  using OpcodeListCtx = InstructionSetParser::Opcode_listContext;
  using OpcodeOperandsCtx = InstructionSetParser::Opcode_operandsContext;
  using IdentListCtx = InstructionSetParser::Ident_listContext;
  using DisasmWidthsCtx = InstructionSetParser::Disasm_widthsContext;
  using ConstAndDefaultCtx =
      InstructionSetParser::Const_and_default_declContext;
  using OpcodeAttributeListCtx =
      InstructionSetParser::Opcode_attribute_listContext;
  using InstructionAttributeListCtx =
      InstructionSetParser::Instruction_attribute_listContext;
  using SemfuncSpecCtx = InstructionSetParser::Semfunc_specContext;
  using ResourceItemCtx = InstructionSetParser::Resource_itemContext;
  using ResourceDetailsCtx = InstructionSetParser::Resource_detailsContext;
  // Checks that any references to slots or bundles within a bundle
  // declaration are to valid slots/bundles.
  absl::Status PerformBundleReferenceChecks(InstructionSet *instruction_set,
                                            Bundle *bundle);
  // The following methods visits the parts of the parse tree indicated by
  // the method name and builds up the internal representation used for
  // decoder generation.
  void VisitTopLevel(TopLevelCtx *ctx);

  std::unique_ptr<InstructionSet> VisitIsaDeclaration(IsaDeclCtx *ctx);
  void VisitConstantDef(ConstantDefCtx *ctx);
  void VisitBundleList(BundleListCtx *ctx, Bundle *bundle);
  void VisitOpcodeList(OpcodeListCtx *ctx, Slot *slot);
  void VisitOpcodeOperands(OpcodeOperandsCtx *ctx, int op_spec_number,
                           Instruction *parent, Instruction *child, Slot *slot);
  void VisitSlotList(SlotListCtx *ctx, Bundle *);
  void VisitIncludeFile(IncludeFileCtx *ctx);
  void VisitSlotDeclaration(SlotDeclCtx *ctx, InstructionSet *instruction_set);
  void VisitConstAndDefaultDecls(ConstAndDefaultCtx *ctx, Slot *slot);
  TemplateExpression *VisitExpression(ExpressionCtx *ctx, Slot *slot,
                                      Instruction *inst);
  std::vector<int> VisitArraySpec(ArraySpecCtx *ctx);
  void VisitNamespaceDecl(NamespaceDeclCtx *ctx, InstructionSet *isa);
  void VisitBundleDeclaration(BundleDeclCtx *ctx,
                              InstructionSet *instruction_set);
  void VisitDisasmWidthsDecl(DisasmWidthsCtx *ctx);
  void VisitInstructionAttributeList(InstructionAttributeListCtx *ctx,
                                     Slot *slot, Instruction *inst);
  void VisitOpcodeAttributes(OpcodeAttributeListCtx *ctx, Instruction *inst,
                             Slot *slot);
  void VisitSemfuncSpec(SemfuncSpecCtx *semfunc_spec, Instruction *inst);
  void VisitResourceDetails(ResourceDetailsCtx *ctx, Instruction *inst,
                            Slot *slot);
  std::optional<ResourceReference *> ProcessResourceReference(
      Slot *slot, Instruction *inst, ResourceItemCtx *resource_item);
  void VisitResourceDetailsLists(ResourceDetailsCtx *ctx, Slot *slot,
                                 Instruction *inst, ResourceSpec *spec);
  std::unique_ptr<InstructionSet> ProcessTopLevel(absl::string_view isa_name);
  void ParseIncludeFile(antlr4::ParserRuleContext *ctx,
                        const std::string &file_name,
                        const std::vector<std::string> &dirs);
  DestinationOperand *FindDestinationOpInExpression(
      ExpressionCtx *ctx, const Slot *slot, const Instruction *inst) const;
  void PerformOpcodeOverrides(
      absl::flat_hash_set<OpcodeSpecCtx *> overridden_ops_set, Slot *slot);
  void PreProcessDeclarations(const std::vector<DeclarationCtx *> &ctx_vec);
  void ProcessOpcodeList(
      OpcodeListCtx *ctx, Slot *slot,
      std::vector<Instruction *> &instruction_vec,
      absl::flat_hash_set<std::string> &deleted_ops_set,
      absl::flat_hash_set<OpcodeSpecCtx *> &overridden_ops_set);

  // These methods parses the disassembly format string.
  absl::Status ParseDisasmFormat(std::string format, Instruction *inst);
  absl::StatusOr<std::string> ParseNumberFormat(std::string format);
  absl::StatusOr<FormatInfo *> ParseFormatExpression(std::string expr,
                                                     Opcode *op);

  // Generate file prologues/epilogues.
  std::string GenerateHdrFileProlog(absl::string_view file_name,
                                    absl::string_view opcode_file_name,
                                    absl::string_view guard_name,
                                    absl::string_view encoding_base_name,
                                    const std::vector<std::string> &namespaces);
  std::string GenerateHdrFileEpilog(absl::string_view guard_name,
                                    const std::vector<std::string> &namespaces);
  std::string GenerateCcFileProlog(absl::string_view hdr_file_name,
                                   const std::vector<std::string> &namespaces);
  std::string GenerateNamespaceEpilog(
      const std::vector<std::string> &namespaces);
  std::string GenerateSimpleHdrProlog(
      absl::string_view guard_name, const std::vector<std::string> &namespaces);

  // Error handler.
  decoder::DecoderErrorListener *error_listener() const {
    return error_listener_.get();
  }
  void set_error_listener(
      std::unique_ptr<decoder::DecoderErrorListener> listener) {
    error_listener_ = std::move(listener);
  }

  std::string isa_name_;

  // Slot and bundle maps - these point to the contexts for every slot and
  // bundle that have been declared.
  absl::flat_hash_map<std::string, SlotDeclCtx *> slot_decl_map_;
  absl::flat_hash_map<std::string, BundleDeclCtx *> bundle_decl_map_;
  absl::flat_hash_map<std::string, IsaDeclCtx *> isa_decl_map_;

  // Constant map
  absl::flat_hash_map<std::string, TemplateExpression *> constant_map_;
  // Include file strings.
  absl::btree_set<std::string> include_files_;

  // Include file roots.
  std::vector<std::string> include_dir_vec_;
  // Keep track of files that are included in case there is recursive includes.
  std::deque<std::string> include_file_stack_;
  // Error listening object passed to the parser.
  std::unique_ptr<decoder::DecoderErrorListener> error_listener_;
  // For template functions evaluators.
  absl::flat_hash_map<std::string, TemplateFunctionEvaluator>
      template_function_evaluators_;
  // Disassembler field widths.
  std::vector<TemplateExpression *> disasm_field_widths_;
  // AntlrParserWrapper vector.
  std::vector<IsaAntlrParserWrapper *> antlr_parser_wrappers_;
};

}  // namespace instruction_set
}  // namespace machine_description
}  // namespace sim
}  // namespace mpact

#endif  // MPACT_SIM_DECODER_INSTRUCTION_SET_VISITOR_H_
