//===- Parser.h - Matcher expression parser ---------------------*- 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
//
//===----------------------------------------------------------------------===//
//
/// \file
/// Simple matcher expression parser.
///
/// The parser understands matcher expressions of the form:
///   MatcherName(Arg0, Arg1, ..., ArgN)
/// as well as simple types like strings.
/// The parser does not know how to process the matchers. It delegates this task
/// to a Sema object received as an argument.
///
/// \code
/// Grammar for the expressions supported:
/// <Expression>        := <Literal> | <NamedValue> | <MatcherExpression>
/// <Literal>           := <StringLiteral> | <Boolean> | <Double> | <Unsigned>
/// <StringLiteral>     := "quoted string"
/// <Boolean>           := true | false
/// <Double>            := [0-9]+.[0-9]* | [0-9]+.[0-9]*[eE][-+]?[0-9]+
/// <Unsigned>          := [0-9]+
/// <NamedValue>        := <Identifier>
/// <MatcherExpression> := <Identifier>(<ArgumentList>) |
///                        <Identifier>(<ArgumentList>).bind(<StringLiteral>)
/// <Identifier>        := [a-zA-Z]+
/// <ArgumentList>      := <Expression> | <Expression>,<ArgumentList>
/// \endcode
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_PARSER_H
#define LLVM_CLANG_ASTMATCHERS_DYNAMIC_PARSER_H

#include "clang/ASTMatchers/ASTMatchersInternal.h"
#include "clang/ASTMatchers/Dynamic/Registry.h"
#include "clang/ASTMatchers/Dynamic/VariantValue.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include <utility>
#include <vector>

namespace clang {
namespace ast_matchers {
namespace dynamic {

class Diagnostics;

/// Matcher expression parser.
class Parser {
public:
  /// Interface to connect the parser with the registry and more.
  ///
  /// The parser uses the Sema instance passed into
  /// parseMatcherExpression() to handle all matcher tokens. The simplest
  /// processor implementation would simply call into the registry to create
  /// the matchers.
  /// However, a more complex processor might decide to intercept the matcher
  /// creation and do some extra work. For example, it could apply some
  /// transformation to the matcher by adding some id() nodes, or could detect
  /// specific matcher nodes for more efficient lookup.
  class Sema {
  public:
    virtual ~Sema();

    /// Process a matcher expression.
    ///
    /// All the arguments passed here have already been processed.
    ///
    /// \param Ctor A matcher constructor looked up by lookupMatcherCtor.
    ///
    /// \param NameRange The location of the name in the matcher source.
    ///   Useful for error reporting.
    ///
    /// \param BindID The ID to use to bind the matcher, or a null \c StringRef
    ///   if no ID is specified.
    ///
    /// \param Args The argument list for the matcher.
    ///
    /// \return The matcher objects constructed by the processor, or a null
    ///   matcher if an error occurred. In that case, \c Error will contain a
    ///   description of the error.
    virtual VariantMatcher actOnMatcherExpression(MatcherCtor Ctor,
                                                  SourceRange NameRange,
                                                  StringRef BindID,
                                                  ArrayRef<ParserValue> Args,
                                                  Diagnostics *Error) = 0;

    /// Look up a matcher by name.
    ///
    /// \param MatcherName The matcher name found by the parser.
    ///
    /// \return The matcher constructor, or Optional<MatcherCtor>() if not
    /// found.
    virtual llvm::Optional<MatcherCtor>
    lookupMatcherCtor(StringRef MatcherName) = 0;

    virtual bool isBuilderMatcher(MatcherCtor) const = 0;

    virtual ASTNodeKind nodeMatcherType(MatcherCtor) const = 0;

    virtual internal::MatcherDescriptorPtr
    buildMatcherCtor(MatcherCtor, SourceRange NameRange,
                     ArrayRef<ParserValue> Args, Diagnostics *Error) const = 0;

    /// Compute the list of completion types for \p Context.
    ///
    /// Each element of \p Context represents a matcher invocation, going from
    /// outermost to innermost. Elements are pairs consisting of a reference to
    /// the matcher constructor and the index of the next element in the
    /// argument list of that matcher (or for the last element, the index of
    /// the completion point in the argument list). An empty list requests
    /// completion for the root matcher.
    virtual std::vector<ArgKind> getAcceptedCompletionTypes(
        llvm::ArrayRef<std::pair<MatcherCtor, unsigned>> Context);

    /// Compute the list of completions that match any of
    /// \p AcceptedTypes.
    ///
    /// \param AcceptedTypes All types accepted for this completion.
    ///
    /// \return All completions for the specified types.
    /// Completions should be valid when used in \c lookupMatcherCtor().
    /// The matcher constructed from the return of \c lookupMatcherCtor()
    /// should be convertible to some type in \p AcceptedTypes.
    virtual std::vector<MatcherCompletion>
    getMatcherCompletions(llvm::ArrayRef<ArgKind> AcceptedTypes);
  };

  /// Sema implementation that uses the matcher registry to process the
  ///   tokens.
  class RegistrySema : public Parser::Sema {
  public:
    ~RegistrySema() override;

    llvm::Optional<MatcherCtor>
    lookupMatcherCtor(StringRef MatcherName) override;

    VariantMatcher actOnMatcherExpression(MatcherCtor Ctor,
                                          SourceRange NameRange,
                                          StringRef BindID,
                                          ArrayRef<ParserValue> Args,
                                          Diagnostics *Error) override;

    std::vector<ArgKind> getAcceptedCompletionTypes(
        llvm::ArrayRef<std::pair<MatcherCtor, unsigned>> Context) override;

    bool isBuilderMatcher(MatcherCtor Ctor) const override;

    ASTNodeKind nodeMatcherType(MatcherCtor) const override;

    internal::MatcherDescriptorPtr
    buildMatcherCtor(MatcherCtor, SourceRange NameRange,
                     ArrayRef<ParserValue> Args,
                     Diagnostics *Error) const override;

    std::vector<MatcherCompletion>
    getMatcherCompletions(llvm::ArrayRef<ArgKind> AcceptedTypes) override;
  };

  using NamedValueMap = llvm::StringMap<VariantValue>;

  /// Parse a matcher expression.
  ///
  /// \param MatcherCode The matcher expression to parse.
  ///
  /// \param S The Sema instance that will help the parser
  ///   construct the matchers. If null, it uses the default registry.
  ///
  /// \param NamedValues A map of precomputed named values.  This provides
  ///   the dictionary for the <NamedValue> rule of the grammar.
  ///   If null, it is ignored.
  ///
  /// \return The matcher object constructed by the processor, or an empty
  ///   Optional if an error occurred. In that case, \c Error will contain a
  ///   description of the error.
  ///   The caller takes ownership of the DynTypedMatcher object returned.
  static llvm::Optional<DynTypedMatcher>
  parseMatcherExpression(StringRef &MatcherCode, Sema *S,
                         const NamedValueMap *NamedValues, Diagnostics *Error);
  static llvm::Optional<DynTypedMatcher>
  parseMatcherExpression(StringRef &MatcherCode, Sema *S, Diagnostics *Error) {
    return parseMatcherExpression(MatcherCode, S, nullptr, Error);
  }
  static llvm::Optional<DynTypedMatcher>
  parseMatcherExpression(StringRef &MatcherCode, Diagnostics *Error) {
    return parseMatcherExpression(MatcherCode, nullptr, Error);
  }

  /// Parse an expression.
  ///
  /// Parses any expression supported by this parser. In general, the
  /// \c parseMatcherExpression function is a better approach to get a matcher
  /// object.
  ///
  /// \param S The Sema instance that will help the parser
  ///   construct the matchers. If null, it uses the default registry.
  ///
  /// \param NamedValues A map of precomputed named values.  This provides
  ///   the dictionary for the <NamedValue> rule of the grammar.
  ///   If null, it is ignored.
  static bool parseExpression(StringRef &Code, Sema *S,
                              const NamedValueMap *NamedValues,
                              VariantValue *Value, Diagnostics *Error);
  static bool parseExpression(StringRef &Code, Sema *S, VariantValue *Value,
                              Diagnostics *Error) {
    return parseExpression(Code, S, nullptr, Value, Error);
  }
  static bool parseExpression(StringRef &Code, VariantValue *Value,
                              Diagnostics *Error) {
    return parseExpression(Code, nullptr, Value, Error);
  }

  /// Complete an expression at the given offset.
  ///
  /// \param S The Sema instance that will help the parser
  ///   construct the matchers. If null, it uses the default registry.
  ///
  /// \param NamedValues A map of precomputed named values.  This provides
  ///   the dictionary for the <NamedValue> rule of the grammar.
  ///   If null, it is ignored.
  ///
  /// \return The list of completions, which may be empty if there are no
  /// available completions or if an error occurred.
  static std::vector<MatcherCompletion>
  completeExpression(StringRef &Code, unsigned CompletionOffset, Sema *S,
                     const NamedValueMap *NamedValues);
  static std::vector<MatcherCompletion>
  completeExpression(StringRef &Code, unsigned CompletionOffset, Sema *S) {
    return completeExpression(Code, CompletionOffset, S, nullptr);
  }
  static std::vector<MatcherCompletion>
  completeExpression(StringRef &Code, unsigned CompletionOffset) {
    return completeExpression(Code, CompletionOffset, nullptr);
  }

private:
  class CodeTokenizer;
  struct ScopedContextEntry;
  struct TokenInfo;

  Parser(CodeTokenizer *Tokenizer, Sema *S,
         const NamedValueMap *NamedValues,
         Diagnostics *Error);

  bool parseBindID(std::string &BindID);
  bool parseExpressionImpl(VariantValue *Value);
  bool parseMatcherBuilder(MatcherCtor Ctor, const TokenInfo &NameToken,
                           const TokenInfo &OpenToken, VariantValue *Value);
  bool parseMatcherExpressionImpl(const TokenInfo &NameToken,
                                  const TokenInfo &OpenToken,
                                  llvm::Optional<MatcherCtor> Ctor,
                                  VariantValue *Value);
  bool parseIdentifierPrefixImpl(VariantValue *Value);

  void addCompletion(const TokenInfo &CompToken,
                     const MatcherCompletion &Completion);
  void addExpressionCompletions();

  std::vector<MatcherCompletion>
  getNamedValueCompletions(ArrayRef<ArgKind> AcceptedTypes);

  CodeTokenizer *const Tokenizer;
  Sema *const S;
  const NamedValueMap *const NamedValues;
  Diagnostics *const Error;

  using ContextStackTy = std::vector<std::pair<MatcherCtor, unsigned>>;

  ContextStackTy ContextStack;
  std::vector<MatcherCompletion> Completions;
};

} // namespace dynamic
} // namespace ast_matchers
} // namespace clang

#endif // LLVM_CLANG_ASTMATCHERS_DYNAMIC_PARSER_H
