// 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.

#include "fidl/parser.h"

namespace fidl {

#define TOKEN_PRIMITIVE_TYPE_CASES \
    case Token::Kind::Bool:        \
    case Token::Kind::Status:      \
    case Token::Kind::Int8:        \
    case Token::Kind::Int16:       \
    case Token::Kind::Int32:       \
    case Token::Kind::Int64:       \
    case Token::Kind::Uint8:       \
    case Token::Kind::Uint16:      \
    case Token::Kind::Uint32:      \
    case Token::Kind::Uint64:      \
    case Token::Kind::Float32:     \
    case Token::Kind::Float64

#define TOKEN_TYPE_CASES          \
    TOKEN_PRIMITIVE_TYPE_CASES:   \
    case Token::Kind::Identifier: \
    case Token::Kind::Array:      \
    case Token::Kind::Vector:     \
    case Token::Kind::String:     \
    case Token::Kind::Handle:     \
    case Token::Kind::Request

#define TOKEN_LITERAL_CASES           \
    case Token::Kind::Default:        \
    case Token::Kind::True:           \
    case Token::Kind::False:          \
    case Token::Kind::NumericLiteral: \
    case Token::Kind::StringLiteral

namespace {
enum {
    More,
    Done,
};
} // namespace

Parser::Parser(Lexer* lexer, ErrorReporter* error_reporter)
    : lexer_(lexer), error_reporter_(error_reporter) {
    handle_subtype_table_ = {
        {"process", types::HandleSubtype::Process},
        {"thread", types::HandleSubtype::Thread},
        {"vmo", types::HandleSubtype::Vmo},
        {"channel", types::HandleSubtype::Channel},
        {"event", types::HandleSubtype::Event},
        {"port", types::HandleSubtype::Port},
        {"interrupt", types::HandleSubtype::Interrupt},
        {"log", types::HandleSubtype::Log},
        {"socket", types::HandleSubtype::Socket},
        {"resource", types::HandleSubtype::Resource},
        {"eventpair", types::HandleSubtype::Eventpair},
        {"job", types::HandleSubtype::Job},
        {"vmar", types::HandleSubtype::Vmar},
        {"fifo", types::HandleSubtype::Fifo},
        {"guest", types::HandleSubtype::Guest},
        {"timer", types::HandleSubtype::Timer},
    };

    last_token_ = Lex();
}

bool Parser::LookupHandleSubtype(const raw::Identifier* identifier,
                                 types::HandleSubtype* subtype_out) {
    auto lookup = handle_subtype_table_.find(identifier->location.data());
    if (lookup == handle_subtype_table_.end()) {
        return false;
    }
    *subtype_out = lookup->second;
    return true;
}

decltype(nullptr) Parser::Fail() {
    if (ok_) {
        int line_number;
        auto surrounding_line = last_token_.location().SourceLine(&line_number);

        std::string error = "found unexpected token: ";
        error += last_token_.data();
        error += "\n";
        error += "on line #" + std::to_string(line_number) + ":\n\n";
        error += surrounding_line;
        error += "\n";

        error_reporter_->ReportError(error);
        ok_ = false;
    }
    return nullptr;
}

std::unique_ptr<raw::Identifier> Parser::ParseIdentifier() {
    auto identifier = ConsumeToken(Token::Kind::Identifier);
    if (!Ok())
        return Fail();

    return std::make_unique<raw::Identifier>(identifier.location());
}

std::unique_ptr<raw::CompoundIdentifier> Parser::ParseCompoundIdentifier() {
    std::vector<std::unique_ptr<raw::Identifier>> components;

    components.emplace_back(ParseIdentifier());
    if (!Ok())
        return Fail();

    auto parse_component = [&components, this]() {
        switch (Peek()) {
        default:
            return Done;

        case Token::Kind::Dot:
            ConsumeToken(Token::Kind::Dot);
            if (Ok())
                components.emplace_back(ParseIdentifier());
            return More;
        }
    };

    while (parse_component() == More) {
        if (!Ok())
            return Fail();
    }

    return std::make_unique<raw::CompoundIdentifier>(std::move(components));
}

std::unique_ptr<raw::StringLiteral> Parser::ParseStringLiteral() {
    auto string_literal = ConsumeToken(Token::Kind::StringLiteral);
    if (!Ok())
        return Fail();

    return std::make_unique<raw::StringLiteral>(string_literal.location());
}

std::unique_ptr<raw::NumericLiteral> Parser::ParseNumericLiteral() {
    auto numeric_literal = ConsumeToken(Token::Kind::NumericLiteral);
    if (!Ok())
        return Fail();

    return std::make_unique<raw::NumericLiteral>(numeric_literal.location());
}

std::unique_ptr<raw::TrueLiteral> Parser::ParseTrueLiteral() {
    ConsumeToken(Token::Kind::True);
    if (!Ok())
        return Fail();

    return std::make_unique<raw::TrueLiteral>();
}

std::unique_ptr<raw::FalseLiteral> Parser::ParseFalseLiteral() {
    ConsumeToken(Token::Kind::False);
    if (!Ok())
        return Fail();

    return std::make_unique<raw::FalseLiteral>();
}

std::unique_ptr<raw::DefaultLiteral> Parser::ParseDefaultLiteral() {
    ConsumeToken(Token::Kind::Default);
    if (!Ok())
        return Fail();

    return std::make_unique<raw::DefaultLiteral>();
}

std::unique_ptr<raw::Literal> Parser::ParseLiteral() {
    switch (Peek()) {
    case Token::Kind::StringLiteral:
        return ParseStringLiteral();

    case Token::Kind::NumericLiteral:
        return ParseNumericLiteral();

    case Token::Kind::True:
        return ParseTrueLiteral();

    case Token::Kind::False:
        return ParseFalseLiteral();

    case Token::Kind::Default:
        return ParseDefaultLiteral();

    default:
        return Fail();
    }
}

std::unique_ptr<raw::Attribute> Parser::ParseAttribute() {
    auto name = ParseIdentifier();
    if (!Ok())
        return Fail();
    std::unique_ptr<raw::StringLiteral> value;
    if (MaybeConsumeToken(Token::Kind::Equal)) {
        value = ParseStringLiteral();
        if (!Ok())
            return Fail();
    }
    return std::make_unique<raw::Attribute>(std::move(name), std::move(value));
}

std::unique_ptr<raw::AttributeList> Parser::ParseAttributeList() {
    ConsumeToken(Token::Kind::LeftSquare);
    if (!Ok())
        return Fail();
    std::vector<std::unique_ptr<raw::Attribute>> attribute_list;
    for (;;) {
        attribute_list.emplace_back(ParseAttribute());
        if (!Ok())
            return Fail();
        if (!MaybeConsumeToken(Token::Kind::Comma))
            break;
    }
    ConsumeToken(Token::Kind::RightSquare);
    if (!Ok())
        return Fail();
    return std::make_unique<raw::AttributeList>(std::move(attribute_list));
}

std::unique_ptr<raw::AttributeList> Parser::MaybeParseAttributeList() {
    if (Peek() == Token::Kind::LeftSquare)
        return ParseAttributeList();
    return nullptr;
}

std::unique_ptr<raw::Constant> Parser::ParseConstant() {
    switch (Peek()) {
    case Token::Kind::Identifier: {
        auto identifier = ParseCompoundIdentifier();
        if (!Ok())
            return Fail();
        return std::make_unique<raw::IdentifierConstant>(std::move(identifier));
    }

    TOKEN_LITERAL_CASES : {
        auto literal = ParseLiteral();
        if (!Ok())
            return Fail();
        return std::make_unique<raw::LiteralConstant>(std::move(literal));
    }

    default:
        return Fail();
    }
}

std::unique_ptr<raw::Using> Parser::ParseUsing() {
    ConsumeToken(Token::Kind::Using);
    if (!Ok())
        return Fail();
    auto using_path = ParseCompoundIdentifier();
    if (!Ok())
        return Fail();

    std::unique_ptr<raw::Identifier> maybe_alias;
    if (MaybeConsumeToken(Token::Kind::As)) {
        if (!Ok())
            return Fail();
        maybe_alias = ParseIdentifier();
        if (!Ok())
            return Fail();
    }

    return std::make_unique<raw::Using>(std::move(using_path), std::move(maybe_alias));
}

std::unique_ptr<raw::ArrayType> Parser::ParseArrayType() {
    ConsumeToken(Token::Kind::Array);
    if (!Ok())
        return Fail();
    ConsumeToken(Token::Kind::LeftAngle);
    if (!Ok())
        return Fail();
    auto element_type = ParseType();
    if (!Ok())
        return Fail();
    ConsumeToken(Token::Kind::RightAngle);
    if (!Ok())
        return Fail();
    ConsumeToken(Token::Kind::Colon);
    if (!Ok())
        return Fail();
    auto element_count = ParseConstant();
    if (!Ok())
        return Fail();

    return std::make_unique<raw::ArrayType>(std::move(element_type), std::move(element_count));
}

std::unique_ptr<raw::VectorType> Parser::ParseVectorType() {
    ConsumeToken(Token::Kind::Vector);
    if (!Ok())
        return Fail();
    ConsumeToken(Token::Kind::LeftAngle);
    if (!Ok())
        return Fail();
    auto element_type = ParseType();
    if (!Ok())
        return Fail();
    ConsumeToken(Token::Kind::RightAngle);
    if (!Ok())
        return Fail();

    std::unique_ptr<raw::Constant> maybe_element_count;
    if (MaybeConsumeToken(Token::Kind::Colon)) {
        if (!Ok())
            return Fail();
        maybe_element_count = ParseConstant();
        if (!Ok())
            return Fail();
    }

    auto nullability = types::Nullability::Nonnullable;
    if (MaybeConsumeToken(Token::Kind::Question)) {
        nullability = types::Nullability::Nullable;
    }

    return std::make_unique<raw::VectorType>(std::move(element_type),
                                             std::move(maybe_element_count), nullability);
}

std::unique_ptr<raw::StringType> Parser::ParseStringType() {
    ConsumeToken(Token::Kind::String);
    if (!Ok())
        return Fail();

    std::unique_ptr<raw::Constant> maybe_element_count;
    if (MaybeConsumeToken(Token::Kind::Colon)) {
        if (!Ok())
            return Fail();
        maybe_element_count = ParseConstant();
        if (!Ok())
            return Fail();
    }

    auto nullability = types::Nullability::Nonnullable;
    if (MaybeConsumeToken(Token::Kind::Question)) {
        nullability = types::Nullability::Nullable;
    }

    return std::make_unique<raw::StringType>(std::move(maybe_element_count), nullability);
}

std::unique_ptr<raw::HandleType> Parser::ParseHandleType() {
    ConsumeToken(Token::Kind::Handle);
    if (!Ok())
        return Fail();

    auto subtype = types::HandleSubtype::Handle;
    if (MaybeConsumeToken(Token::Kind::LeftAngle)) {
        if (!Ok())
            return Fail();
        auto identifier = ParseIdentifier();
        if (!Ok())
            return Fail();
        if (!LookupHandleSubtype(identifier.get(), &subtype))
            return Fail();
        ConsumeToken(Token::Kind::RightAngle);
        if (!Ok())
            return Fail();
    }

    auto nullability = types::Nullability::Nonnullable;
    if (MaybeConsumeToken(Token::Kind::Question)) {
        nullability = types::Nullability::Nullable;
    }

    return std::make_unique<raw::HandleType>(subtype, nullability);
}

std::unique_ptr<raw::PrimitiveType> Parser::ParsePrimitiveType() {
    types::PrimitiveSubtype subtype;

    switch (Peek()) {
    case Token::Kind::Bool:
        subtype = types::PrimitiveSubtype::Bool;
        break;
    case Token::Kind::Status:
        subtype = types::PrimitiveSubtype::Status;
        break;
    case Token::Kind::Int8:
        subtype = types::PrimitiveSubtype::Int8;
        break;
    case Token::Kind::Int16:
        subtype = types::PrimitiveSubtype::Int16;
        break;
    case Token::Kind::Int32:
        subtype = types::PrimitiveSubtype::Int32;
        break;
    case Token::Kind::Int64:
        subtype = types::PrimitiveSubtype::Int64;
        break;
    case Token::Kind::Uint8:
        subtype = types::PrimitiveSubtype::Uint8;
        break;
    case Token::Kind::Uint16:
        subtype = types::PrimitiveSubtype::Uint16;
        break;
    case Token::Kind::Uint32:
        subtype = types::PrimitiveSubtype::Uint32;
        break;
    case Token::Kind::Uint64:
        subtype = types::PrimitiveSubtype::Uint64;
        break;
    case Token::Kind::Float32:
        subtype = types::PrimitiveSubtype::Float32;
        break;
    case Token::Kind::Float64:
        subtype = types::PrimitiveSubtype::Float64;
        break;
    default:
        return Fail();
    }

    ConsumeToken(Peek());
    if (!Ok())
        return Fail();
    return std::make_unique<raw::PrimitiveType>(subtype);
}

std::unique_ptr<raw::RequestHandleType> Parser::ParseRequestHandleType() {
    ConsumeToken(Token::Kind::Request);
    if (!Ok())
        return Fail();
    ConsumeToken(Token::Kind::LeftAngle);
    if (!Ok())
        return Fail();
    auto identifier = ParseCompoundIdentifier();
    if (!Ok())
        return Fail();
    ConsumeToken(Token::Kind::RightAngle);
    if (!Ok())
        return Fail();

    auto nullability = types::Nullability::Nonnullable;
    if (MaybeConsumeToken(Token::Kind::Question)) {
        nullability = types::Nullability::Nullable;
    }

    return std::make_unique<raw::RequestHandleType>(std::move(identifier), nullability);
}

std::unique_ptr<raw::Type> Parser::ParseType() {
    switch (Peek()) {
    case Token::Kind::Identifier: {
        auto identifier = ParseCompoundIdentifier();
        if (!Ok())
            return Fail();
        auto nullability = types::Nullability::Nonnullable;
        if (MaybeConsumeToken(Token::Kind::Question)) {
            if (!Ok())
                return Fail();
            nullability = types::Nullability::Nullable;
        }
        return std::make_unique<raw::IdentifierType>(std::move(identifier), nullability);
    }

    case Token::Kind::Array: {
        auto type = ParseArrayType();
        if (!Ok())
            return Fail();
        return type;
    }

    case Token::Kind::Vector: {
        auto type = ParseVectorType();
        if (!Ok())
            return Fail();
        return type;
    }

    case Token::Kind::String: {
        auto type = ParseStringType();
        if (!Ok())
            return Fail();
        return type;
    }

    case Token::Kind::Handle: {
        auto type = ParseHandleType();
        if (!Ok())
            return Fail();
        return type;
    }

    case Token::Kind::Request: {
        auto type = ParseRequestHandleType();
        if (!Ok())
            return Fail();
        return type;
    }

    TOKEN_PRIMITIVE_TYPE_CASES : {
        auto type = ParsePrimitiveType();
        if (!Ok())
            return Fail();
        return type;
    }

    default:
        return Fail();
    }
}

std::unique_ptr<raw::ConstDeclaration> Parser::ParseConstDeclaration(std::unique_ptr<raw::AttributeList> attributes) {
    ConsumeToken(Token::Kind::Const);
    if (!Ok())
        return Fail();
    auto type = ParseType();
    if (!Ok())
        return Fail();
    auto identifier = ParseIdentifier();
    if (!Ok())
        return Fail();
    ConsumeToken(Token::Kind::Equal);
    if (!Ok())
        return Fail();
    auto constant = ParseConstant();
    if (!Ok())
        return Fail();

    return std::make_unique<raw::ConstDeclaration>(std::move(attributes), std::move(type),
                                                   std::move(identifier), std::move(constant));
}

std::unique_ptr<raw::EnumMember> Parser::ParseEnumMember() {
    auto identifier = ParseIdentifier();
    if (!Ok())
        return Fail();

    ConsumeToken(Token::Kind::Equal);
    if (!Ok())
        return Fail();

    auto member_value = ParseConstant();
    if (!Ok())
        return Fail();

    return std::make_unique<raw::EnumMember>(std::move(identifier), std::move(member_value));
}

std::unique_ptr<raw::EnumDeclaration> Parser::ParseEnumDeclaration(std::unique_ptr<raw::AttributeList> attributes) {
    std::vector<std::unique_ptr<raw::EnumMember>> members;

    ConsumeToken(Token::Kind::Enum);
    if (!Ok())
        return Fail();
    auto identifier = ParseIdentifier();
    if (!Ok())
        return Fail();
    std::unique_ptr<raw::PrimitiveType> subtype;
    if (MaybeConsumeToken(Token::Kind::Colon)) {
        if (!Ok())
            return Fail();
        subtype = ParsePrimitiveType();
        if (!Ok())
            return Fail();
    }
    ConsumeToken(Token::Kind::LeftCurly);
    if (!Ok())
        return Fail();

    auto parse_member = [&members, this]() {
        switch (Peek()) {
        default:
            ConsumeToken(Token::Kind::RightCurly);
            return Done;

        TOKEN_TYPE_CASES:
            members.emplace_back(ParseEnumMember());
            return More;
        }
    };

    while (parse_member() == More) {
        if (!Ok())
            Fail();
        ConsumeToken(Token::Kind::Semicolon);
        if (!Ok())
            return Fail();
    }
    if (!Ok())
        Fail();

    return std::make_unique<raw::EnumDeclaration>(std::move(attributes), std::move(identifier),
                                                  std::move(subtype), std::move(members));
}

std::unique_ptr<raw::Parameter> Parser::ParseParameter() {
    auto type = ParseType();
    if (!Ok())
        return Fail();
    auto identifier = ParseIdentifier();
    if (!Ok())
        return Fail();

    return std::make_unique<raw::Parameter>(std::move(type), std::move(identifier));
}

std::unique_ptr<raw::ParameterList> Parser::ParseParameterList() {
    std::vector<std::unique_ptr<raw::Parameter>> parameter_list;

    switch (Peek()) {
    default:
        break;

    TOKEN_TYPE_CASES:
        parameter_list.emplace_back(ParseParameter());
        if (!Ok())
            return Fail();
        while (Peek() == Token::Kind::Comma) {
            ConsumeToken(Token::Kind::Comma);
            if (!Ok())
                return Fail();
            switch (Peek()) {
            TOKEN_TYPE_CASES:
                parameter_list.emplace_back(ParseParameter());
                if (!Ok())
                    return Fail();
                break;

            default:
                return Fail();
            }
        }
    }

    return std::make_unique<raw::ParameterList>(std::move(parameter_list));
}

std::unique_ptr<raw::InterfaceMemberMethod> Parser::ParseInterfaceMemberMethod() {
    auto ordinal = ParseNumericLiteral();
    if (!Ok())
        return Fail();
    ConsumeToken(Token::Kind::Colon);
    if (!Ok())
        return Fail();

    std::unique_ptr<raw::Identifier> method_name;
    std::unique_ptr<raw::ParameterList> maybe_request;
    std::unique_ptr<raw::ParameterList> maybe_response;

    auto parse_params = [this](std::unique_ptr<raw::ParameterList>* params_out) {
        ConsumeToken(Token::Kind::LeftParen);
        if (!Ok())
            return false;
        *params_out = ParseParameterList();
        if (!Ok())
            return false;
        ConsumeToken(Token::Kind::RightParen);
        if (!Ok())
            return false;
        return true;
    };

    if (MaybeConsumeToken(Token::Kind::Arrow)) {
        method_name = ParseIdentifier();
        if (!Ok())
            return Fail();
        if (!parse_params(&maybe_response))
            return Fail();
    } else {
        method_name = ParseIdentifier();
        if (!Ok())
            return Fail();
        if (!parse_params(&maybe_request))
            return Fail();

        if (MaybeConsumeToken(Token::Kind::Arrow)) {
            if (!Ok())
                return Fail();
            if (!parse_params(&maybe_response))
                return Fail();
        }
    }

    assert(method_name);
    assert(maybe_request || maybe_response);

    return std::make_unique<raw::InterfaceMemberMethod>(std::move(ordinal),
                                                        std::move(method_name),
                                                        std::move(maybe_request),
                                                        std::move(maybe_response));
}

std::unique_ptr<raw::InterfaceDeclaration> Parser::ParseInterfaceDeclaration(std::unique_ptr<raw::AttributeList> attributes) {
    std::vector<std::unique_ptr<raw::CompoundIdentifier>> superinterfaces;
    std::vector<std::unique_ptr<raw::ConstDeclaration>> const_members;
    std::vector<std::unique_ptr<raw::EnumDeclaration>> enum_members;
    std::vector<std::unique_ptr<raw::InterfaceMemberMethod>> method_members;

    ConsumeToken(Token::Kind::Interface);
    if (!Ok())
        return Fail();

    auto identifier = ParseIdentifier();
    if (!Ok())
        return Fail();

    if (MaybeConsumeToken(Token::Kind::Colon)) {
        for (;;) {
            superinterfaces.emplace_back(ParseCompoundIdentifier());
            if (!Ok())
                return Fail();
            if (!MaybeConsumeToken(Token::Kind::Comma))
                break;
        }
    }

    ConsumeToken(Token::Kind::LeftCurly);
    if (!Ok())
        return Fail();

    auto parse_member = [&const_members, &enum_members, &method_members, this]() {
        std::unique_ptr<raw::AttributeList> attributes = MaybeParseAttributeList();
        if (!Ok())
            return More;

        switch (Peek()) {
        default:
            ConsumeToken(Token::Kind::RightCurly);
            return Done;

        case Token::Kind::Const:
            const_members.emplace_back(ParseConstDeclaration(std::move(attributes)));
            return More;

        case Token::Kind::Enum:
            enum_members.emplace_back(ParseEnumDeclaration(std::move(attributes)));
            return More;

        case Token::Kind::NumericLiteral:
            method_members.emplace_back(ParseInterfaceMemberMethod());
            return More;
        }
    };

    while (parse_member() == More) {
        if (!Ok())
            Fail();
        ConsumeToken(Token::Kind::Semicolon);
        if (!Ok())
            return Fail();
    }
    if (!Ok())
        Fail();

    return std::make_unique<raw::InterfaceDeclaration>(std::move(attributes), std::move(identifier),
                                                       std::move(superinterfaces), std::move(const_members),
                                                       std::move(enum_members), std::move(method_members));
}

std::unique_ptr<raw::StructMember> Parser::ParseStructMember() {
    auto type = ParseType();
    if (!Ok())
        return Fail();
    auto identifier = ParseIdentifier();
    if (!Ok())
        return Fail();

    std::unique_ptr<raw::Constant> maybe_default_value;
    if (MaybeConsumeToken(Token::Kind::Equal)) {
        if (!Ok())
            return Fail();
        maybe_default_value = ParseConstant();
        if (!Ok())
            return Fail();
    }

    return std::make_unique<raw::StructMember>(std::move(type), std::move(identifier),
                                               std::move(maybe_default_value));
}

std::unique_ptr<raw::StructDeclaration> Parser::ParseStructDeclaration(std::unique_ptr<raw::AttributeList> attributes) {
    std::vector<std::unique_ptr<raw::ConstDeclaration>> const_members;
    std::vector<std::unique_ptr<raw::EnumDeclaration>> enum_members;
    std::vector<std::unique_ptr<raw::StructMember>> members;

    ConsumeToken(Token::Kind::Struct);
    if (!Ok())
        return Fail();
    auto identifier = ParseIdentifier();
    if (!Ok())
        return Fail();
    ConsumeToken(Token::Kind::LeftCurly);
    if (!Ok())
        return Fail();

    auto parse_member = [&const_members, &enum_members, &members, this]() {
        std::unique_ptr<raw::AttributeList> attributes = MaybeParseAttributeList();
        if (!Ok())
            return More;

        switch (Peek()) {
        default:
            ConsumeToken(Token::Kind::RightCurly);
            return Done;

        case Token::Kind::Const:
            const_members.emplace_back(ParseConstDeclaration(std::move(attributes)));
            return More;

        case Token::Kind::Enum:
            enum_members.emplace_back(ParseEnumDeclaration(std::move(attributes)));
            return More;

        TOKEN_TYPE_CASES:
            members.emplace_back(ParseStructMember());
            return More;
        }
    };

    while (parse_member() == More) {
        if (!Ok())
            Fail();
        ConsumeToken(Token::Kind::Semicolon);
        if (!Ok())
            return Fail();
    }
    if (!Ok())
        Fail();

    if (members.empty())
        return Fail();

    return std::make_unique<raw::StructDeclaration>(std::move(attributes), std::move(identifier),
                                                    std::move(const_members), std::move(enum_members),
                                                    std::move(members));
}

std::unique_ptr<raw::UnionMember> Parser::ParseUnionMember() {
    auto type = ParseType();
    if (!Ok())
        return Fail();
    auto identifier = ParseIdentifier();
    if (!Ok())
        return Fail();

    return std::make_unique<raw::UnionMember>(std::move(type), std::move(identifier));
}

std::unique_ptr<raw::UnionDeclaration> Parser::ParseUnionDeclaration(std::unique_ptr<raw::AttributeList> attributes) {
    std::vector<std::unique_ptr<raw::ConstDeclaration>> const_members;
    std::vector<std::unique_ptr<raw::EnumDeclaration>> enum_members;
    std::vector<std::unique_ptr<raw::UnionMember>> members;

    ConsumeToken(Token::Kind::Union);
    if (!Ok())
        return Fail();
    auto identifier = ParseIdentifier();
    if (!Ok())
        return Fail();
    ConsumeToken(Token::Kind::LeftCurly);
    if (!Ok())
        return Fail();

    auto parse_member = [&const_members, &enum_members, &members, this]() {
        std::unique_ptr<raw::AttributeList> attributes = MaybeParseAttributeList();
        if (!Ok())
            return More;

        switch (Peek()) {
        default:
            ConsumeToken(Token::Kind::RightCurly);
            return Done;

        case Token::Kind::Const:
            const_members.emplace_back(ParseConstDeclaration(std::move(attributes)));
            return More;

        case Token::Kind::Enum:
            enum_members.emplace_back(ParseEnumDeclaration(std::move(attributes)));
            return More;

        TOKEN_TYPE_CASES:
            members.emplace_back(ParseUnionMember());
            return More;
        }
    };

    while (parse_member() == More) {
        if (!Ok())
            Fail();
        ConsumeToken(Token::Kind::Semicolon);
        if (!Ok())
            return Fail();
    }
    if (!Ok())
        Fail();

    if (members.empty())
        Fail();

    return std::make_unique<raw::UnionDeclaration>(std::move(attributes), std::move(identifier),
                                                   std::move(const_members), std::move(enum_members),
                                                   std::move(members));
}

std::unique_ptr<raw::File> Parser::ParseFile() {
    std::vector<std::unique_ptr<raw::Using>> using_list;
    std::vector<std::unique_ptr<raw::ConstDeclaration>> const_declaration_list;
    std::vector<std::unique_ptr<raw::EnumDeclaration>> enum_declaration_list;
    std::vector<std::unique_ptr<raw::InterfaceDeclaration>> interface_declaration_list;
    std::vector<std::unique_ptr<raw::StructDeclaration>> struct_declaration_list;
    std::vector<std::unique_ptr<raw::UnionDeclaration>> union_declaration_list;

    ConsumeToken(Token::Kind::Library);
    if (!Ok())
        return Fail();
    auto identifier = ParseCompoundIdentifier();
    if (!Ok())
        return Fail();
    ConsumeToken(Token::Kind::Semicolon);
    if (!Ok())
        return Fail();

    auto parse_using = [&using_list, this]() {
        switch (Peek()) {
        default:
            return Done;

        case Token::Kind::Using:
            using_list.emplace_back(ParseUsing());
            return More;
        }
    };

    while (parse_using() == More) {
        if (!Ok())
            return Fail();
        ConsumeToken(Token::Kind::Semicolon);
        if (!Ok())
            return Fail();
    }

    auto parse_declaration = [&const_declaration_list, &enum_declaration_list,
                              &interface_declaration_list, &struct_declaration_list,
                              &union_declaration_list, this]() {
        std::unique_ptr<raw::AttributeList> attributes = MaybeParseAttributeList();
        if (!Ok())
            return More;

        switch (Peek()) {
        default:
            return Done;

        case Token::Kind::Const:
            const_declaration_list.emplace_back(ParseConstDeclaration(std::move(attributes)));
            return More;

        case Token::Kind::Enum:
            enum_declaration_list.emplace_back(ParseEnumDeclaration(std::move(attributes)));
            return More;

        case Token::Kind::Interface:
            interface_declaration_list.emplace_back(ParseInterfaceDeclaration(std::move(attributes)));
            return More;

        case Token::Kind::Struct:
            struct_declaration_list.emplace_back(ParseStructDeclaration(std::move(attributes)));
            return More;

        case Token::Kind::Union:
            union_declaration_list.emplace_back(ParseUnionDeclaration(std::move(attributes)));
            return More;
        }
    };

    while (parse_declaration() == More) {
        if (!Ok())
            return Fail();
        ConsumeToken(Token::Kind::Semicolon);
        if (!Ok())
            return Fail();
    }

    ConsumeToken(Token::Kind::EndOfFile);
    if (!Ok())
        return Fail();

    return std::make_unique<raw::File>(
        std::move(identifier), std::move(using_list), std::move(const_declaration_list),
        std::move(enum_declaration_list), std::move(interface_declaration_list),
        std::move(struct_declaration_list), std::move(union_declaration_list));
}

} // namespace fidl
