// 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_RAW_AST_H_
#define ZIRCON_SYSTEM_HOST_FIDL_INCLUDE_FIDL_RAW_AST_H_

#include <memory>
#include <utility>
#include <vector>

#include "source_location.h"
#include "token.h"
#include "types.h"

// ASTs fresh out of the oven. This is a tree-shaped bunch of nodes
// pretty much exactly corresponding to the grammar of a single fidl
// file. File is the root of the tree, and consists of lists of
// Declarations, and so on down to individual SourceLocations.

// Each node owns its children via unique_ptr and vector. All tokens
// here, like everywhere in the fidl compiler, are backed by a string
// view whose contents are owned by a SourceManager.

// This class has a tight coupling with the TreeVisitor class.  Each node has a
// corresponding method in that class.  Each node type also has an Accept()
// method to help visitors visit the node.  When you add a new node, or add a
// field to an existing node, you must ensure the Accept method works.

// A raw::File is produced by parsing a token stream. All of the
// Files in a library are then flattened out into a Library.

namespace fidl {
namespace raw {

// In order to be able to associate AST nodes with their original source, each
// node is a SourceElement, which contains information about the original
// source.  The AST has a start token, whose previous_end field points to the
// end of the previous AST node, and an end token, which points to the end of
// this syntactic element.
//
// Note: The file may have a tail of whitespace / comment text not explicitly
// associated with any node.  In order to reconstruct that text, raw::File
// contains an end token; the previous_end field of that token points to the end
// of the last interesting token.
class TreeVisitor;

class SourceElement {
public:
    explicit SourceElement(SourceElement const& element)
        : start_(element.start_), end_(element.end_) {}

    explicit SourceElement(Token start, Token end)
        : start_(start), end_(end) {}

    SourceLocation location() const { return start_.location(); }

    virtual ~SourceElement() {}

    Token start_;
    Token end_;
};

class SourceElementMark {
public:
    SourceElementMark(TreeVisitor& tv,
                      const SourceElement& element);

    ~SourceElementMark();

private:
    TreeVisitor& tv_;
    const SourceElement& element_;
};

class Identifier : public SourceElement {
public:
    explicit Identifier(SourceElement const& element)
        : SourceElement(element) {}

    virtual ~Identifier() {}

    void Accept(TreeVisitor& visitor) {
        SourceElementMark sem(visitor, *this);
    }
};

class CompoundIdentifier : public SourceElement {
public:
    CompoundIdentifier(SourceElement const& element, std::vector<std::unique_ptr<Identifier>> components)
        : SourceElement(element), components(std::move(components)) {}

    virtual ~CompoundIdentifier() {}

    std::vector<std::unique_ptr<Identifier>> components;

    void Accept(TreeVisitor& visitor);
};

class Literal : public SourceElement {
public:
    enum struct Kind {
        kString,
        kNumeric,
        // TODO(pascallouis): should have kBool instead.
        kTrue,
        kFalse,
    };

    explicit Literal(SourceElement const& element, Kind kind)
        : SourceElement(element), kind(kind) {}

    virtual ~Literal() {}

    const Kind kind;
};

class StringLiteral : public Literal {
public:
    explicit StringLiteral(SourceElement const& element)
        : Literal(element, Kind::kString) {}

    void Accept(TreeVisitor& visitor);
};

class NumericLiteral : public Literal {
public:
    NumericLiteral(SourceElement const& element)
        : Literal(element, Kind::kNumeric) {}

    void Accept(TreeVisitor& visitor);
};

class Ordinal : public SourceElement {
public:
    Ordinal(SourceElement const& element, uint32_t value)
        : SourceElement(element), value(value) {}

    void Accept(TreeVisitor& visitor);

    const uint32_t value;
};

class TrueLiteral : public Literal {
public:
    TrueLiteral(SourceElement const& element)
        : Literal(element, Kind::kTrue) {}

    void Accept(TreeVisitor& visitor);
};

class FalseLiteral : public Literal {
public:
    FalseLiteral(SourceElement const& element)
        : Literal(element, Kind::kFalse) {}

    void Accept(TreeVisitor& visitor);
};

class Constant : public SourceElement {
public:
    enum class Kind {
        kIdentifier,
        kLiteral,
    };

    explicit Constant(Token token, Kind kind)
        : SourceElement(token, token), kind(kind) {}

    virtual ~Constant() {}

    const Kind kind;
};

class IdentifierConstant : public Constant {
public:
    explicit IdentifierConstant(std::unique_ptr<CompoundIdentifier> identifier)
        : Constant(identifier->start_, Kind::kIdentifier), identifier(std::move(identifier)) {}

    std::unique_ptr<CompoundIdentifier> identifier;

    void Accept(TreeVisitor& visitor);
};

class LiteralConstant : public Constant {
public:
    explicit LiteralConstant(std::unique_ptr<Literal> literal)
        : Constant(literal->start_, Kind::kLiteral), literal(std::move(literal)) {}

    std::unique_ptr<Literal> literal;

    void Accept(TreeVisitor& visitor);
};

class Attribute : public SourceElement {
public:
    Attribute(SourceElement const& element, std::string name, std::string value)
        : SourceElement(element), name(std::move(name)), value(std::move(value)) {}

    void Accept(TreeVisitor& visitor);

    const std::string name;
    const std::string value;
};

class AttributeList : public SourceElement {
public:
    AttributeList(SourceElement const& element, std::vector<std::unique_ptr<Attribute>> attributes)
        : SourceElement(element), attributes(std::move(attributes)) {}

    bool HasAttribute(std::string name) const {
        for (const auto& attribute : attributes) {
            if (attribute->name == name)
                return true;
        }
        return false;
    }

    void Accept(TreeVisitor& visitor);

    std::vector<std::unique_ptr<Attribute>> attributes;
};

class Type : public SourceElement {
public:
    virtual ~Type() {}

    enum struct Kind {
        kArray,
        kVector,
        kString,
        kHandle,
        kRequestHandle,
        kIdentifier,
    };

    explicit Type(Token start, Token end, Kind kind)
        : SourceElement(start, end), kind(kind) {}

    const Kind kind;
};

class ArrayType : public Type {
public:
    ArrayType(SourceElement const& element, std::unique_ptr<Type> element_type, std::unique_ptr<Constant> element_count)
        : Type(element.start_, element.end_, Kind::kArray), element_type(std::move(element_type)),
          element_count(std::move(element_count)) {}

    void Accept(TreeVisitor& visitor);
    std::unique_ptr<Type> element_type;
    std::unique_ptr<Constant> element_count;
};

class VectorType : public Type {
public:
    VectorType(SourceElement const& element, std::unique_ptr<Type> element_type, std::unique_ptr<Constant> maybe_element_count,
               types::Nullability nullability)
        : Type(element.start_, element.end_, Kind::kVector), element_type(std::move(element_type)),
          maybe_element_count(std::move(maybe_element_count)), nullability(nullability) {}

    void Accept(TreeVisitor& visitor);

    std::unique_ptr<Type> element_type;
    std::unique_ptr<Constant> maybe_element_count;
    types::Nullability nullability;
};

class StringType : public Type {
public:
    StringType(SourceElement const& element, std::unique_ptr<Constant> maybe_element_count, types::Nullability nullability)
        : Type(element.start_, element.end_, Kind::kString), maybe_element_count(std::move(maybe_element_count)),
          nullability(nullability) {}

    void Accept(TreeVisitor& visitor);

    std::unique_ptr<Constant> maybe_element_count;
    types::Nullability nullability;
};

class HandleType : public Type {
public:
    HandleType(SourceElement const& element, types::HandleSubtype subtype, types::Nullability nullability)
        : Type(element.start_, element.end_, Kind::kHandle), subtype(subtype), nullability(nullability) {}

    void Accept(TreeVisitor& visitor);

    types::HandleSubtype subtype;
    types::Nullability nullability;
};

class RequestHandleType : public Type {
public:
    RequestHandleType(SourceElement const& element, std::unique_ptr<CompoundIdentifier> identifier,
                      types::Nullability nullability)
        : Type(element.start_, element.end_, Kind::kRequestHandle), identifier(std::move(identifier)), nullability(nullability) {}

    void Accept(TreeVisitor& visitor);

    std::unique_ptr<CompoundIdentifier> identifier;
    types::Nullability nullability;
};

class IdentifierType : public Type {
public:
    IdentifierType(SourceElement const& element, std::unique_ptr<CompoundIdentifier> identifier, types::Nullability nullability)
        : Type(element.start_, element.end_, Kind::kIdentifier), identifier(std::move(identifier)), nullability(nullability) {}

    void Accept(TreeVisitor& visitor);

    std::unique_ptr<CompoundIdentifier> identifier;
    types::Nullability nullability;
};

class Using : public SourceElement {
public:
    Using(SourceElement const& element, std::unique_ptr<CompoundIdentifier> using_path, std::unique_ptr<Identifier> maybe_alias, std::unique_ptr<IdentifierType> maybe_type)
        : SourceElement(element), using_path(std::move(using_path)), maybe_alias(std::move(maybe_alias)), maybe_type(std::move(maybe_type)) {}

    void Accept(TreeVisitor& visitor);

    std::unique_ptr<CompoundIdentifier> using_path;
    std::unique_ptr<Identifier> maybe_alias;
    // TODO(pascal): We should be more explicit for type aliases such as
    // `using foo = int8;` and use a special purpose AST element.
    std::unique_ptr<IdentifierType> maybe_type;
};

class ConstDeclaration : public SourceElement {
public:
    ConstDeclaration(SourceElement const& element, std::unique_ptr<AttributeList> attributes, std::unique_ptr<Type> type,
                     std::unique_ptr<Identifier> identifier, std::unique_ptr<Constant> constant)
        : SourceElement(element), attributes(std::move(attributes)), type(std::move(type)),
          identifier(std::move(identifier)), constant(std::move(constant)) {}

    void Accept(TreeVisitor& visitor);

    std::unique_ptr<AttributeList> attributes;
    std::unique_ptr<Type> type;
    std::unique_ptr<Identifier> identifier;
    std::unique_ptr<Constant> constant;
};

class EnumMember : public SourceElement {
public:
    EnumMember(SourceElement const& element, std::unique_ptr<Identifier> identifier, std::unique_ptr<Constant> value, std::unique_ptr<AttributeList> attributes)
        : SourceElement(element), identifier(std::move(identifier)), value(std::move(value)), attributes(std::move(attributes)) {}

    void Accept(TreeVisitor& visitor);

    std::unique_ptr<Identifier> identifier;
    std::unique_ptr<Constant> value;
    std::unique_ptr<AttributeList> attributes;
};

class EnumDeclaration : public SourceElement {
public:
    EnumDeclaration(SourceElement const& element, std::unique_ptr<AttributeList> attributes,
                    std::unique_ptr<Identifier> identifier,
                    std::unique_ptr<IdentifierType> maybe_subtype,
                    std::vector<std::unique_ptr<EnumMember>> members)
        : SourceElement(element), attributes(std::move(attributes)), identifier(std::move(identifier)),
          maybe_subtype(std::move(maybe_subtype)), members(std::move(members)) {}

    void Accept(TreeVisitor& visitor);

    std::unique_ptr<AttributeList> attributes;
    std::unique_ptr<Identifier> identifier;
    std::unique_ptr<IdentifierType> maybe_subtype;
    std::vector<std::unique_ptr<EnumMember>> members;
};

class Parameter : public SourceElement {
public:
    Parameter(SourceElement const& element, std::unique_ptr<Type> type, std::unique_ptr<Identifier> identifier)
        : SourceElement(element), type(std::move(type)), identifier(std::move(identifier)) {}

    void Accept(TreeVisitor& visitor);

    std::unique_ptr<Type> type;
    std::unique_ptr<Identifier> identifier;
};

class ParameterList : public SourceElement {
public:
    ParameterList(SourceElement const& element, std::vector<std::unique_ptr<Parameter>> parameter_list)
        : SourceElement(element), parameter_list(std::move(parameter_list)) {}

    void Accept(TreeVisitor& visitor);

    std::vector<std::unique_ptr<Parameter>> parameter_list;
};

class InterfaceMethod : public SourceElement {
public:
    InterfaceMethod(SourceElement const& element, std::unique_ptr<AttributeList> attributes,
                    std::unique_ptr<Ordinal> ordinal,
                    std::unique_ptr<Identifier> identifier,
                    std::unique_ptr<ParameterList> maybe_request,
                    std::unique_ptr<ParameterList> maybe_response)
        : SourceElement(element), attributes(std::move(attributes)),
          ordinal(std::move(ordinal)), identifier(std::move(identifier)),
          maybe_request(std::move(maybe_request)), maybe_response(std::move(maybe_response)) {}

    void Accept(TreeVisitor& visitor);

    std::unique_ptr<AttributeList> attributes;
    std::unique_ptr<Ordinal> ordinal;
    std::unique_ptr<Identifier> identifier;
    std::unique_ptr<ParameterList> maybe_request;
    std::unique_ptr<ParameterList> maybe_response;
};

class InterfaceDeclaration : public SourceElement {
public:
    InterfaceDeclaration(SourceElement const& element, std::unique_ptr<AttributeList> attributes,
                         std::unique_ptr<Identifier> identifier,
                         std::vector<std::unique_ptr<CompoundIdentifier>> superinterfaces,
                         std::vector<std::unique_ptr<InterfaceMethod>> methods)
        : SourceElement(element), attributes(std::move(attributes)), identifier(std::move(identifier)),
          superinterfaces(std::move(superinterfaces)), methods(std::move(methods)) {}

    void Accept(TreeVisitor& visitor);

    std::unique_ptr<AttributeList> attributes;
    std::unique_ptr<Identifier> identifier;
    std::vector<std::unique_ptr<CompoundIdentifier>> superinterfaces;
    std::vector<std::unique_ptr<InterfaceMethod>> methods;
};

class StructMember : public SourceElement {
public:
    StructMember(SourceElement const& element, std::unique_ptr<Type> type, std::unique_ptr<Identifier> identifier,
                 std::unique_ptr<Constant> maybe_default_value,
                 std::unique_ptr<AttributeList> attributes)
        : SourceElement(element), type(std::move(type)), identifier(std::move(identifier)),
          maybe_default_value(std::move(maybe_default_value)), attributes(std::move(attributes)) {}

    void Accept(TreeVisitor& visitor);

    std::unique_ptr<Type> type;
    std::unique_ptr<Identifier> identifier;
    std::unique_ptr<Constant> maybe_default_value;
    std::unique_ptr<AttributeList> attributes;
};

class StructDeclaration : public SourceElement {
public:
    // Note: A nullptr passed to attributes means an empty attribute list.
    StructDeclaration(SourceElement const& element, std::unique_ptr<AttributeList> attributes,
                      std::unique_ptr<Identifier> identifier,
                      std::vector<std::unique_ptr<StructMember>> members)
        : SourceElement(element), attributes(std::move(attributes)), identifier(std::move(identifier)),
          members(std::move(members)) {}

    void Accept(TreeVisitor& visitor);

    std::unique_ptr<AttributeList> attributes;
    std::unique_ptr<Identifier> identifier;
    std::vector<std::unique_ptr<StructMember>> members;
};

struct TableMember : public SourceElement {
    TableMember(SourceElement const& element, std::unique_ptr<Ordinal> ordinal,
                std::unique_ptr<Type> type,
                std::unique_ptr<Identifier> identifier,
                std::unique_ptr<Constant> maybe_default_value,
                std::unique_ptr<AttributeList> attributes)
        : SourceElement(element), ordinal(std::move(ordinal)),
          maybe_used(std::make_unique<Used>(std::move(type), std::move(identifier),
                                            std::move(maybe_default_value), std::move(attributes))) {}

    TableMember(SourceElement const& element, std::unique_ptr<Ordinal> ordinal)
        : SourceElement(element), ordinal(std::move(ordinal)) {}

    void Accept(TreeVisitor& visitor);

    std::unique_ptr<Ordinal> ordinal;
    // A used member is not 'reserved'
    struct Used {
        Used(std::unique_ptr<Type> type,
             std::unique_ptr<Identifier> identifier,
             std::unique_ptr<Constant> maybe_default_value,
             std::unique_ptr<AttributeList> attributes)
            : type(std::move(type)), identifier(std::move(identifier)),
              maybe_default_value(std::move(maybe_default_value)), attributes(std::move(attributes)) {}
        std::unique_ptr<Type> type;
        std::unique_ptr<Identifier> identifier;
        std::unique_ptr<Constant> maybe_default_value;
        std::unique_ptr<AttributeList> attributes;
    };
    std::unique_ptr<Used> maybe_used;
};

struct TableDeclaration : public SourceElement {
    TableDeclaration(SourceElement const& element, std::unique_ptr<AttributeList> attributes,
                     std::unique_ptr<Identifier> identifier,
                     std::vector<std::unique_ptr<TableMember>> members)
        : SourceElement(element), attributes(std::move(attributes)), identifier(std::move(identifier)),
          members(std::move(members)) {}

    void Accept(TreeVisitor& visitor);

    std::unique_ptr<AttributeList> attributes;
    std::unique_ptr<Identifier> identifier;
    std::vector<std::unique_ptr<TableMember>> members;
};

class UnionMember : public SourceElement {
public:
    UnionMember(SourceElement const& element, std::unique_ptr<Type> type, std::unique_ptr<Identifier> identifier,
                std::unique_ptr<AttributeList> attributes)
        : SourceElement(element), type(std::move(type)), identifier(std::move(identifier)), attributes(std::move(attributes)) {}

    void Accept(TreeVisitor& visitor);

    std::unique_ptr<Type> type;
    std::unique_ptr<Identifier> identifier;
    std::unique_ptr<AttributeList> attributes;
};

class UnionDeclaration : public SourceElement {
public:
    UnionDeclaration(SourceElement const& element, std::unique_ptr<AttributeList> attributes,
                     std::unique_ptr<Identifier> identifier,
                     std::vector<std::unique_ptr<UnionMember>> members)
        : SourceElement(element), attributes(std::move(attributes)), identifier(std::move(identifier)),
          members(std::move(members)) {}

    void Accept(TreeVisitor& visitor);

    std::unique_ptr<AttributeList> attributes;
    std::unique_ptr<Identifier> identifier;
    std::vector<std::unique_ptr<UnionMember>> members;
};

class XUnionMember : public SourceElement {
public:
    XUnionMember(SourceElement const& element, std::unique_ptr<Type> type, std::unique_ptr<Identifier> identifier,
                 std::unique_ptr<AttributeList> attributes)
        : SourceElement(element), type(std::move(type)), identifier(std::move(identifier)), attributes(std::move(attributes)) {}

    void Accept(TreeVisitor& visitor);

    std::unique_ptr<Type> type;
    std::unique_ptr<Identifier> identifier;
    std::unique_ptr<AttributeList> attributes;
};

class XUnionDeclaration : public SourceElement {
public:
    XUnionDeclaration(SourceElement const& element, std::unique_ptr<AttributeList> attributes,
                      std::unique_ptr<Identifier> identifier,
                      std::vector<std::unique_ptr<XUnionMember>> members)
        : SourceElement(element), attributes(std::move(attributes)), identifier(std::move(identifier)),
          members(std::move(members)) {}

    void Accept(TreeVisitor& visitor);

    std::unique_ptr<AttributeList> attributes;
    std::unique_ptr<Identifier> identifier;
    std::vector<std::unique_ptr<XUnionMember>> members;
};

class File : public SourceElement {
public:
    File(SourceElement const& element, Token end,
         std::unique_ptr<AttributeList> attributes,
         std::unique_ptr<CompoundIdentifier> library_name,
         std::vector<std::unique_ptr<Using>> using_list,
         std::vector<std::unique_ptr<ConstDeclaration>> const_declaration_list,
         std::vector<std::unique_ptr<EnumDeclaration>> enum_declaration_list,
         std::vector<std::unique_ptr<InterfaceDeclaration>> interface_declaration_list,
         std::vector<std::unique_ptr<StructDeclaration>> struct_declaration_list,
         std::vector<std::unique_ptr<TableDeclaration>> table_declaration_list,
         std::vector<std::unique_ptr<UnionDeclaration>> union_declaration_list,
         std::vector<std::unique_ptr<XUnionDeclaration>> xunion_declaration_list)
        : SourceElement(element),
          attributes(std::move(attributes)),
          library_name(std::move(library_name)),
          using_list(std::move(using_list)),
          const_declaration_list(std::move(const_declaration_list)),
          enum_declaration_list(std::move(enum_declaration_list)),
          interface_declaration_list(std::move(interface_declaration_list)),
          struct_declaration_list(std::move(struct_declaration_list)),
          table_declaration_list(std::move(table_declaration_list)),
          union_declaration_list(std::move(union_declaration_list)),
          xunion_declaration_list(std::move(xunion_declaration_list)),
          end_(end) {}

    void Accept(TreeVisitor& visitor);

    std::unique_ptr<AttributeList> attributes;
    std::unique_ptr<CompoundIdentifier> library_name;
    std::vector<std::unique_ptr<Using>> using_list;
    std::vector<std::unique_ptr<ConstDeclaration>> const_declaration_list;
    std::vector<std::unique_ptr<EnumDeclaration>> enum_declaration_list;
    std::vector<std::unique_ptr<InterfaceDeclaration>> interface_declaration_list;
    std::vector<std::unique_ptr<StructDeclaration>> struct_declaration_list;
    std::vector<std::unique_ptr<TableDeclaration>> table_declaration_list;
    std::vector<std::unique_ptr<UnionDeclaration>> union_declaration_list;
    std::vector<std::unique_ptr<XUnionDeclaration>> xunion_declaration_list;
    Token end_;
};

} // namespace raw
} // namespace fidl

#endif // ZIRCON_SYSTEM_HOST_FIDL_INCLUDE_FIDL_RAW_AST_H_
