// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef TOOLS_GN_PARSER_H_
#define TOOLS_GN_PARSER_H_

#include <stddef.h>

#include <map>
#include <memory>
#include <vector>

#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "gn/err.h"
#include "gn/parse_tree.h"

extern const char kGrammar_Help[];

struct ParserHelper;

// Parses a series of tokens. The resulting AST will refer to the tokens passed
// to the input, so the tokens an the file data they refer to must outlive your
// use of the ParseNode.
class Parser {
 public:
  // Will return a null pointer and set the err on error.
  static std::unique_ptr<ParseNode> Parse(const std::vector<Token>& tokens,
                                          Err* err);

  // Alternative to parsing that assumes the input is an expression.
  static std::unique_ptr<ParseNode> ParseExpression(
      const std::vector<Token>& tokens,
      Err* err);

  // Alternative to parsing that assumes the input is a literal value.
  static std::unique_ptr<ParseNode> ParseValue(const std::vector<Token>& tokens,
                                               Err* err);

 private:
  // Vector must be valid for lifetime of call.
  Parser(const std::vector<Token>& tokens, Err* err);
  ~Parser();

  std::unique_ptr<ParseNode> ParseExpression();

  // Parses an expression with the given precedence or higher.
  std::unique_ptr<ParseNode> ParseExpression(int precedence);

  // |PrefixFunc|s used in parsing expressions.
  std::unique_ptr<ParseNode> Block(const Token& token);
  std::unique_ptr<ParseNode> Literal(const Token& token);
  std::unique_ptr<ParseNode> Name(const Token& token);
  std::unique_ptr<ParseNode> Group(const Token& token);
  std::unique_ptr<ParseNode> Not(const Token& token);
  std::unique_ptr<ParseNode> List(const Token& token);
  std::unique_ptr<ParseNode> BlockComment(const Token& token);

  // |InfixFunc|s used in parsing expressions.
  std::unique_ptr<ParseNode> BinaryOperator(std::unique_ptr<ParseNode> left,
                                            const Token& token);
  std::unique_ptr<ParseNode> IdentifierOrCall(std::unique_ptr<ParseNode> left,
                                              const Token& token);
  std::unique_ptr<ParseNode> Assignment(std::unique_ptr<ParseNode> left,
                                        const Token& token);
  std::unique_ptr<ParseNode> Subscript(std::unique_ptr<ParseNode> left,
                                       const Token& token);
  std::unique_ptr<ParseNode> DotOperator(std::unique_ptr<ParseNode> left,
                                         const Token& token);

  // Helper to parse a comma separated list, optionally allowing trailing
  // commas (allowed in [] lists, not in function calls).
  std::unique_ptr<ListNode> ParseList(const Token& start_token,
                                      Token::Type stop_before,
                                      bool allow_trailing_comma);

  std::unique_ptr<ParseNode> ParseFile();
  std::unique_ptr<ParseNode> ParseStatement();
  // Expects to be passed the token corresponding to the '{' and that the
  // current token is the one following the '{'.
  std::unique_ptr<BlockNode> ParseBlock(const Token& begin_brace,
                                        BlockNode::ResultMode result_mode);
  std::unique_ptr<ParseNode> ParseCondition();

  // Generates a pre- and post-order traversal of the tree.
  void TraverseOrder(const ParseNode* root,
                     std::vector<const ParseNode*>* pre,
                     std::vector<const ParseNode*>* post);

  // Attach comments to nearby syntax.
  void AssignComments(ParseNode* file);

  bool IsAssignment(const ParseNode* node) const;
  bool IsStatementBreak(Token::Type token_type) const;

  bool LookAhead(Token::Type type);
  bool Match(Token::Type type);
  const Token& Consume(Token::Type type, const char* error_message);
  const Token& Consume(Token::Type* types,
                       size_t num_types,
                       const char* error_message);
  const Token& Consume();

  // Call this only if !at_end().
  const Token& cur_token() const { return tokens_[cur_]; }

  const Token& cur_or_last_token() const {
    return at_end() ? tokens_[tokens_.size() - 1] : cur_token();
  }

  bool done() const { return at_end() || has_error(); }
  bool at_end() const { return cur_ >= tokens_.size(); }
  bool has_error() const { return err_->has_error(); }

  std::vector<Token> tokens_;
  std::vector<Token> line_comment_tokens_;
  std::vector<Token> suffix_comment_tokens_;

  static ParserHelper expressions_[Token::NUM_TYPES];

  Token invalid_token_;
  Err* err_;

  // Current index into the tokens.
  size_t cur_;

  FRIEND_TEST_ALL_PREFIXES(Parser, BinaryOp);
  FRIEND_TEST_ALL_PREFIXES(Parser, Block);
  FRIEND_TEST_ALL_PREFIXES(Parser, Condition);
  FRIEND_TEST_ALL_PREFIXES(Parser, Expression);
  FRIEND_TEST_ALL_PREFIXES(Parser, FunctionCall);
  FRIEND_TEST_ALL_PREFIXES(Parser, List);
  FRIEND_TEST_ALL_PREFIXES(Parser, ParenExpression);
  FRIEND_TEST_ALL_PREFIXES(Parser, UnaryOp);

  DISALLOW_COPY_AND_ASSIGN(Parser);
};

using PrefixFunc = std::unique_ptr<ParseNode> (Parser::*)(const Token& token);
using InfixFunc = std::unique_ptr<ParseNode> (
    Parser::*)(std::unique_ptr<ParseNode> left, const Token& token);

struct ParserHelper {
  PrefixFunc prefix;
  InfixFunc infix;

  // Used only for infix operators.
  int precedence;
};

// Renders parse subtree as a formatted text, indenting by the given number of
// spaces.
void RenderToText(const base::Value& node,
                  int indent_level,
                  std::ostringstream& os);

#endif  // TOOLS_GN_PARSER_H_
