// 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 <iostream>
#include <istream>
#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 "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::string &file_name, 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.
  std::unique_ptr<InstructionSet> VisitTopLevel(TopLevelCtx *ctx,
                                                const std::string &isa_name);

  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);
  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_
