// Copyright 2017 The Fuchsia 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 ZIRCON_SYSTEM_HOST_FIDL_INCLUDE_FIDL_PARSER_H_
#define ZIRCON_SYSTEM_HOST_FIDL_INCLUDE_FIDL_PARSER_H_

#include <memory>

#include "error_reporter.h"
#include "lexer.h"
#include "raw_ast.h"

namespace fidl {

class Parser {
public:
    Parser(Lexer* lexer, ErrorReporter* error_reporter);

    std::unique_ptr<raw::File> Parse() { return ParseFile(); }

    bool Ok() const { return error_reporter_->errors().size() == 0; }

private:
    Token Lex() { return lexer_->LexNoComments(); }

    Token::KindAndSubkind Peek() { return last_token_.kind_and_subkind(); }

    // ASTScope is a tool to track the start and end source location of each
    // node automatically.  The parser associates each node with the start and
    // end of its source location.  It also tracks the "gap" is between the the
    // start and the previous interesting source element.  As we walk the tree,
    // we create ASTScope objects that can track the beginning and end of the
    // text associated with the Node being built.  The ASTScope object then
    // colludes with the Parser to figure out where the beginning and end of
    // that node are.
    //
    // ASTScope should only be created on the stack, when starting to parse
    // something that will result in a new AST node.
    class ASTScope {
    public:
        explicit ASTScope(Parser* parser)
            : parser_(parser) {
            suppress_ = parser_->suppress_gap_checks_;
            parser_->suppress_gap_checks_ = false;
            parser_->active_ast_scopes_.push_back(raw::SourceElement(Token(), Token()));
        }
        // The suppress mechanism
        ASTScope(Parser* parser, bool suppress)
            : parser_(parser), suppress_(suppress) {
            parser_->active_ast_scopes_.push_back(raw::SourceElement(Token(), Token()));
            suppress_ = parser_->suppress_gap_checks_;
            parser_->suppress_gap_checks_ = suppress;
        }
        raw::SourceElement GetSourceElement() {
            parser_->active_ast_scopes_.back().end_ = parser_->previous_token_;
            if (!parser_->suppress_gap_checks_) {
                parser_->last_was_gap_start_ = true;
            }
            return raw::SourceElement(parser_->active_ast_scopes_.back());
        }
        ~ASTScope() {
            parser_->suppress_gap_checks_ = suppress_;
            parser_->active_ast_scopes_.pop_back();
        }

        ASTScope(const ASTScope&) = delete;
        ASTScope& operator=(const ASTScope&) = delete;

    private:
        Parser* parser_;
        bool suppress_;
    };

    void UpdateMarks(Token& token) {
        // There should always be at least one of these - the outermost.
        if (active_ast_scopes_.size() == 0) {
            Fail("Internal compiler error: unbalanced parse tree");
        }

        if (!suppress_gap_checks_) {
            // If the end of the last node was the start of a gap, record that.
            if (last_was_gap_start_ && previous_token_.kind() != Token::Kind::kNotAToken) {
                gap_start_ = token.previous_end();
                last_was_gap_start_ = false;
            }

            // If this is a start node, then the end of it will be the start of
            // a gap.
            if (active_ast_scopes_.back().start_.kind() == Token::Kind::kNotAToken) {
                last_was_gap_start_ = true;
            }
        }
        // Update the token to record the correct location of the beginning of
        // the gap prior to it.
        if (gap_start_.valid()) {
            token.set_previous_end(gap_start_);
        }

        for (auto& scope : active_ast_scopes_) {
            if (scope.start_.kind() == Token::Kind::kNotAToken) {
                scope.start_ = token;
            }
        }

        previous_token_ = token;
    }

    // ConsumeToken consumes a token, and matches using the predicate |p|.
    // See #OfKind, and #IdentifierOfSubkind for the two expected predicates.
    //
    // If the token is not retained on return, is_discarded should be true.
    // That allows the parser to track its source location, in case it should
    // become interesting to the AST.
    template <class Predicate>
    Token ConsumeToken(Predicate p, bool is_discarded = false) {
        std::unique_ptr<std::string> failure_message = p(Peek());
        if (failure_message) {
            Fail(*failure_message);
        }
        auto token = last_token_;
        last_token_ = Lex();
        UpdateMarks(token);

        return token;
    }

    // MaybeConsumeToken consumes a token if-and-only-if it matches the given
    // predicate |p|.
    // See #OfKind, and #IdentifierOfSubkind for the two expected predicates.
    template <class Predicate>
    bool MaybeConsumeToken(Predicate p) {
        std::unique_ptr<std::string> failure_message = p(Peek());
        if (failure_message) {
            return false;
        }
        previous_token_ = last_token_;
        UpdateMarks(last_token_);
        last_token_ = Lex();
        return true;
    }

    static auto OfKind(Token::Kind expected_kind) {
        return [expected_kind](Token::KindAndSubkind actual) -> std::unique_ptr<std::string> {
            if (actual.kind() != expected_kind) {
                auto message = std::make_unique<std::string>("unexpected token ");
                message->append(Token::Name(actual));
                message->append(", was expecting ");
                message->append(Token::Name(Token::KindAndSubkind(expected_kind, Token::Subkind::kNone)));
                return message;
            }
            return nullptr;
        };
    }

    static auto IdentifierOfSubkind(Token::Subkind expected_subkind) {
        return [expected_subkind](Token::KindAndSubkind actual) -> std::unique_ptr<std::string> {
            auto expected = Token::KindAndSubkind(Token::Kind::kIdentifier, expected_subkind);
            if (actual.combined() != expected.combined()) {
                auto message = std::make_unique<std::string>("unexpected identifier ");
                message->append(Token::Name(actual));
                message->append(", was expecting ");
                message->append(Token::Name(Token::KindAndSubkind(Token::Kind::kIdentifier, Token::Subkind::kNone)));
                return message;
            }
            return nullptr;
        };
    }

    bool LookupHandleSubtype(const raw::Identifier* identifier, types::HandleSubtype* subtype_out);

    decltype(nullptr) Fail();
    decltype(nullptr) Fail(StringView message);

    std::unique_ptr<raw::Identifier> ParseIdentifier(bool is_discarded = false);
    std::unique_ptr<raw::CompoundIdentifier> ParseCompoundIdentifier();

    std::unique_ptr<raw::StringLiteral> ParseStringLiteral();
    std::unique_ptr<raw::NumericLiteral> ParseNumericLiteral();
    std::unique_ptr<raw::TrueLiteral> ParseTrueLiteral();
    std::unique_ptr<raw::FalseLiteral> ParseFalseLiteral();
    std::unique_ptr<raw::Literal> ParseLiteral();
    std::unique_ptr<raw::Ordinal> MaybeParseOrdinal();

    std::unique_ptr<raw::Constant> ParseConstant();

    std::unique_ptr<raw::Attribute> ParseAttribute();
    std::unique_ptr<raw::Attribute> ParseDocComment();
    std::unique_ptr<raw::AttributeList> ParseAttributeList(std::unique_ptr<raw::Attribute>&& doc_comment, ASTScope& scope);
    std::unique_ptr<raw::AttributeList> MaybeParseAttributeList();

    std::unique_ptr<raw::Using> ParseUsing();

    std::unique_ptr<raw::IdentifierType> ParseIdentifierType();
    std::unique_ptr<raw::ArrayType> ParseArrayType();
    std::unique_ptr<raw::VectorType> ParseVectorType();
    std::unique_ptr<raw::StringType> ParseStringType();
    std::unique_ptr<raw::HandleType> ParseHandleType();
    std::unique_ptr<raw::RequestHandleType> ParseRequestHandleType();
    std::unique_ptr<raw::Type> ParseType();

    std::unique_ptr<raw::ConstDeclaration>
    ParseConstDeclaration(std::unique_ptr<raw::AttributeList> attributes, ASTScope&);

    std::unique_ptr<raw::EnumMember> ParseEnumMember();
    std::unique_ptr<raw::EnumDeclaration>
    ParseEnumDeclaration(std::unique_ptr<raw::AttributeList> attributes, ASTScope&);

    std::unique_ptr<raw::Parameter> ParseParameter();
    std::unique_ptr<raw::ParameterList> ParseParameterList();
    std::unique_ptr<raw::InterfaceMethod> ParseInterfaceMethod(
        std::unique_ptr<raw::AttributeList> attributes, ASTScope& scope);
    std::unique_ptr<raw::InterfaceDeclaration>
    ParseInterfaceDeclaration(std::unique_ptr<raw::AttributeList> attributes, ASTScope&);

    std::unique_ptr<raw::StructMember> ParseStructMember();
    std::unique_ptr<raw::StructDeclaration>
    ParseStructDeclaration(std::unique_ptr<raw::AttributeList> attributes, ASTScope&);

    std::unique_ptr<raw::TableMember>
    ParseTableMember();
    std::unique_ptr<raw::TableDeclaration>
    ParseTableDeclaration(std::unique_ptr<raw::AttributeList> attributes, ASTScope&);

    std::unique_ptr<raw::UnionMember> ParseUnionMember();
    std::unique_ptr<raw::UnionDeclaration>
    ParseUnionDeclaration(std::unique_ptr<raw::AttributeList> attributes, ASTScope&);

    std::unique_ptr<raw::XUnionMember> ParseXUnionMember();
    std::unique_ptr<raw::XUnionDeclaration>
    ParseXUnionDeclaration(std::unique_ptr<raw::AttributeList> attributes, ASTScope&);

    std::unique_ptr<raw::File> ParseFile();

    std::map<StringView, types::HandleSubtype> handle_subtype_table_;

    Lexer* lexer_;
    ErrorReporter* error_reporter_;

    // The stack of information interesting to the currently active ASTScope
    // objects.
    std::vector<raw::SourceElement> active_ast_scopes_;
    // The most recent start of a "gap" - the uninteresting source prior to the
    // beginning of a token (usually mostly containing whitespace).
    SourceLocation gap_start_;
    // Indicates that the last element was the start of a gap, and that the
    // scope should be updated accordingly.
    bool last_was_gap_start_ = false;
    // Suppress updating the gap for the current Scope.  Useful when
    // you don't know whether a scope is going to be interesting lexically, and
    // you have to decide at runtime.
    bool suppress_gap_checks_ = false;
    // The token before last_token_ (below).
    Token previous_token_;

    Token last_token_;
};

} // namespace fidl

#endif // ZIRCON_SYSTEM_HOST_FIDL_INCLUDE_FIDL_PARSER_H_
