//===--- TypeSyntax.cpp - Swift Type Syntax Implementation ----------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/Syntax/RawSyntax.h"
#include "swift/Syntax/SyntaxFactory.h"
#include "swift/Syntax/TypeSyntax.h"

using namespace swift;
using namespace swift::syntax;

using llvm::None;
using llvm::Optional;

TypeSyntaxData::TypeSyntaxData(RC<RawSyntax> Raw, const SyntaxData *Parent,
                               CursorIndex IndexInParent)
  : SyntaxData(Raw, Parent, IndexInParent) {}

TypeSyntax::TypeSyntax(RC<SyntaxData> Root, const TypeSyntaxData *Data)
  : Syntax(Root, Data) {}

#pragma mark - balanced-tokens Data

BalancedTokensSyntaxData::BalancedTokensSyntaxData(RC<RawSyntax> Raw,
                                                   const SyntaxData *Parent,
                                                   CursorIndex IndexInParent)
  : SyntaxData(Raw, Parent, IndexInParent) {
  assert(Raw->Kind == SyntaxKind::BalancedTokens);
  // TODO: Add some checks here that each element of raw syntax
  // matches the grammar rules in the doc comment of
  // this class.
}

RC<BalancedTokensSyntaxData>
BalancedTokensSyntaxData::make(RC<RawSyntax> Raw,
                               const SyntaxData *Parent,
                               CursorIndex IndexInParent) {
  return RC<BalancedTokensSyntaxData> {
    new BalancedTokensSyntaxData { Raw, Parent, IndexInParent }
  };
}

RC<BalancedTokensSyntaxData> BalancedTokensSyntaxData::makeBlank() {
  return make(RawSyntax::make(SyntaxKind::BalancedTokens, {},
                              SourcePresence::Present));
}

#pragma mark - balanced-tokens API

BalancedTokensSyntax::BalancedTokensSyntax(RC<SyntaxData> Root,
                                           const BalancedTokensSyntaxData *Data)
  : Syntax(Root, Data) {}

BalancedTokensSyntax
BalancedTokensSyntax::addBalancedToken(RC<TokenSyntax> NewBalancedToken) const {
#ifndef NDEBUG
  assert(NewBalancedToken->getTokenKind() != tok::l_paren);
  assert(NewBalancedToken->getTokenKind() != tok::r_paren);
  assert(NewBalancedToken->getTokenKind() != tok::l_square);
  assert(NewBalancedToken->getTokenKind() != tok::r_square);
  assert(NewBalancedToken->getTokenKind() != tok::l_brace);
  assert(NewBalancedToken->getTokenKind() != tok::r_brace);
  auto IsIdentifier = NewBalancedToken->getTokenKind() == tok::identifier;
  auto IsKeyword = NewBalancedToken->isKeyword();
  auto IsLiteral = NewBalancedToken->isLiteral();
  auto IsOperator = NewBalancedToken->isOperator();
  auto IsPunctuation = NewBalancedToken->isPunctuation();
  assert(IsIdentifier || IsKeyword || IsLiteral || IsOperator ||
         IsPunctuation);
#endif
  auto Layout = getRaw()->Layout;
  Layout.push_back(NewBalancedToken);

  auto NewRaw = RawSyntax::make(SyntaxKind::BalancedTokens, Layout,
                                SourcePresence::Present);
  return Data->replaceSelf<BalancedTokensSyntax>(NewRaw);
}

#pragma mark - type-attribute Data

TypeAttributeSyntaxData::TypeAttributeSyntaxData(RC<RawSyntax> Raw,
                                                 const SyntaxData *Parent,
                                                 CursorIndex IndexInParent)
    : SyntaxData(Raw, Parent, IndexInParent) {
  assert(Raw->Kind == SyntaxKind::TypeAttribute);
  assert(Raw->Layout.size() == 5);
  syntax_assert_child_token_text(Raw,
                                 TypeAttributeSyntax::Cursor::AtSignToken,
                                 tok::at_sign, "@");
  syntax_assert_child_token(Raw, TypeAttributeSyntax::Cursor::Identifier,
                            tok::identifier);
  syntax_assert_child_token_text(Raw,
                                 TypeAttributeSyntax::Cursor::LeftParenToken,
                                 tok::l_paren,
                                 "(");
  syntax_assert_child_kind(Raw, TypeAttributeSyntax::Cursor::BalancedTokens,
                           SyntaxKind::BalancedTokens);
  syntax_assert_child_token_text(Raw,
                                 TypeAttributeSyntax::Cursor::RightParenToken,
                                 tok::r_paren,
                                 ")");
}

RC<TypeAttributeSyntaxData>
TypeAttributeSyntaxData::make(RC<RawSyntax> Raw,
                              const SyntaxData *Parent,
                              CursorIndex IndexInParent) {
  return RC<TypeAttributeSyntaxData> {
    new TypeAttributeSyntaxData { Raw, Parent, IndexInParent }
  };
}

RC<TypeAttributeSyntaxData> TypeAttributeSyntaxData::makeBlank() {
  auto Raw = RawSyntax::make(SyntaxKind::TypeAttribute,
                             {
                               TokenSyntax::missingToken(tok::at_sign, "@"),
                               TokenSyntax::missingToken(tok::identifier, ""),
                               TokenSyntax::missingToken(tok::l_paren, "("),
                               RawSyntax::missing(SyntaxKind::BalancedTokens),
                               TokenSyntax::missingToken(tok::r_paren, ")"),
                             },
                             SourcePresence::Present);
  return make(Raw);
}

#pragma mark - type-attribute API

TypeAttributeSyntax::TypeAttributeSyntax(RC<SyntaxData> Root,
                                         const TypeAttributeSyntaxData *Data)
  : Syntax(Root, Data) {}

TypeAttributeSyntax
TypeAttributeSyntax::withAtSignToken(RC<TokenSyntax> NewAtSignToken) const {
  syntax_assert_token_is(NewAtSignToken, tok::at_sign, "@");
  return Data->replaceChild<TypeAttributeSyntax>(NewAtSignToken,
                                                 Cursor::AtSignToken);
}

TypeAttributeSyntax
TypeAttributeSyntax::withIdentifier(RC<TokenSyntax> NewIdentifier) const {
  assert(NewIdentifier->getTokenKind() == tok::identifier);
  return Data->replaceChild<TypeAttributeSyntax>(NewIdentifier,
                                                 Cursor::Identifier);
};

TypeAttributeSyntax TypeAttributeSyntax::
withLeftParenToken(RC<TokenSyntax> NewLeftParenToken) const {
  assert(NewLeftParenToken->getTokenKind() == tok::l_paren);
  return Data->replaceChild<TypeAttributeSyntax>(NewLeftParenToken,
                                                 Cursor::LeftParenToken);
};

TypeAttributeSyntax TypeAttributeSyntax::
withBalancedTokens(BalancedTokensSyntax NewBalancedTokens) const {
  return Data->replaceChild<TypeAttributeSyntax>(NewBalancedTokens.getRaw(),
                                                 Cursor::BalancedTokens);
}

TypeAttributeSyntax TypeAttributeSyntax::
withRightParenToken(RC<TokenSyntax> NewRightParenToken) const {
  assert(NewRightParenToken->getTokenKind() == tok::r_paren);
  return Data->replaceChild<TypeAttributeSyntax>(NewRightParenToken,
                                                 Cursor::RightParenToken);
};

#pragma mark - type-attributes Data

TypeAttributesSyntaxData::TypeAttributesSyntaxData(RC<RawSyntax> Raw,
                                                   const SyntaxData *Parent,
                                                   CursorIndex IndexInParent)
  : SyntaxData(Raw, Parent, IndexInParent) {
  // TODO: kind assertions
}

RC<TypeAttributesSyntaxData>
TypeAttributesSyntaxData::make(RC<RawSyntax> Raw,
                               const SyntaxData *Parent,
                               CursorIndex IndexInParent) {
  return RC<TypeAttributesSyntaxData> {
    new TypeAttributesSyntaxData { Raw, Parent, IndexInParent }
  };
}

RC<TypeAttributesSyntaxData> TypeAttributesSyntaxData::makeBlank() {
  return make(RawSyntax::make(SyntaxKind::TypeAttributes, {},
                              SourcePresence::Present));
}

#pragma mark - type-attributes API

TypeAttributesSyntax::
TypeAttributesSyntax(RC<SyntaxData> Root, const TypeAttributesSyntaxData *Data)
  : Syntax(Root, Data) {}

TypeAttributesSyntax TypeAttributesSyntax::
addTypeAttribute(TypeAttributeSyntax NewTypeAttribute) const {
  auto Layout = getRaw()->Layout;
  Layout.push_back(NewTypeAttribute.getRaw());
  auto NewRaw = RawSyntax::make(SyntaxKind::TypeAttributes, Layout,
                                SourcePresence::Present);
  return Data->replaceSelf<TypeAttributesSyntax>(NewRaw);
}

#pragma mark - type-identifier Data

TypeIdentifierSyntaxData::TypeIdentifierSyntaxData(RC<RawSyntax> Raw,
                                                   const SyntaxData *Parent,
                                                   CursorIndex IndexInParent)
    : TypeSyntaxData(Raw, Parent, IndexInParent) {
  assert(Raw->Kind == SyntaxKind::TypeIdentifier);
  assert(Raw->Layout.size() == 4);
  syntax_assert_child_token(Raw, TypeIdentifierSyntax::Cursor::Identifier,
                            tok::identifier);
  syntax_assert_child_kind(Raw,
    TypeIdentifierSyntax::Cursor::GenericArgumentClause,
    SyntaxKind::GenericArgumentClause);
  syntax_assert_child_token_text(Raw, TypeIdentifierSyntax::Cursor::DotToken,
                                 tok::period, ".");
  syntax_assert_child_kind(Raw,
                           TypeIdentifierSyntax::Cursor::ChildTypeIdentifier,
                           SyntaxKind::TypeIdentifier);
}

RC<TypeIdentifierSyntaxData>
TypeIdentifierSyntaxData::make(RC<RawSyntax> Raw,
                               const SyntaxData *Parent,
                               CursorIndex IndexInParent) {
  return RC<TypeIdentifierSyntaxData> {
    new TypeIdentifierSyntaxData { Raw, Parent, IndexInParent }
  };
}

RC<TypeIdentifierSyntaxData>
TypeIdentifierSyntaxData::makeBlank() {
  return make(RawSyntax::make(
    SyntaxKind::TypeIdentifier,
    {
      TokenSyntax::missingToken(tok::identifier, ""),
      RawSyntax::missing(SyntaxKind::GenericArgumentClause),
      TokenSyntax::missingToken(tok::period, "."),
      RawSyntax::missing(SyntaxKind::TypeIdentifier),
    },
    SourcePresence::Present));
}

#pragma mark - type-identifier API

TypeIdentifierSyntax::TypeIdentifierSyntax(RC<SyntaxData> Root,
                                           const TypeIdentifierSyntaxData *Data)
  : TypeSyntax(Root, Data) {}

TypeIdentifierSyntax
TypeIdentifierSyntax::addChildType(TypeIdentifierSyntax ChildType) const {
  auto MaybeChild = getRaw()->getChild(Cursor::ChildTypeIdentifier);

  if (MaybeChild->isMissing()) {
    auto NewRaw =
        getRaw()->replaceChild(Cursor::DotToken,
                               SyntaxFactory::makeDotToken({}, {}))
            ->replaceChild(Cursor::ChildTypeIdentifier, ChildType.getRaw());

    return Data->replaceSelf<TypeIdentifierSyntax>(NewRaw);
  } else {
    auto NewRawChild = MaybeChild->replaceChild(Cursor::ChildTypeIdentifier,
                                                ChildType.getRaw());
    auto NewRaw = getRaw()->replaceChild(Cursor::ChildTypeIdentifier,
                                         NewRawChild);
    return Data->replaceSelf<TypeIdentifierSyntax>(NewRaw);
  }
}

TypeIdentifierSyntax
TypeIdentifierSyntax::withIdentifier(RC<TokenSyntax> NewIdentifier) const {
  assert(NewIdentifier->getTokenKind() == tok::identifier);
  auto NewRaw = getRaw()->replaceChild(Cursor::Identifier,
                                               NewIdentifier);
  return Data->replaceSelf<TypeIdentifierSyntax>(NewRaw);
}

TypeIdentifierSyntax
TypeIdentifierSyntax::withDotToken(RC<TokenSyntax> NewDotToken) const {
  syntax_assert_token_is(NewDotToken, tok::period, ".");
  auto NewRaw = getRaw()->replaceChild(Cursor::DotToken, NewDotToken);
  return Data->replaceSelf<TypeIdentifierSyntax>(NewRaw);
}

#pragma mark - type-argument-list Data

TypeArgumentListSyntaxData::
TypeArgumentListSyntaxData(RC<RawSyntax> Raw,
                           const SyntaxData *Parent,
                           CursorIndex IndexInParent)
    : SyntaxData(Raw, Parent, IndexInParent) {
  assert(Raw->Kind == SyntaxKind::TypeArgumentList);
#ifndef NDEBUG
  for (size_t i = 0; i < Raw->Layout.size(); ++i) {
    if (i % 2 == 0) {
      assert(Raw->getChild(i)->Kind == SyntaxKind::TupleTypeElement);
    } else {
      syntax_assert_token_is(cast<TokenSyntax>(Raw->getChild(i)), tok::comma,
                             ",");
    }
  }
#endif
}

RC<TypeArgumentListSyntaxData>
TypeArgumentListSyntaxData::make(RC<RawSyntax> Raw,
                                 const SyntaxData *Parent,
                                 CursorIndex IndexInParent) {
  return RC<TypeArgumentListSyntaxData> {
    new TypeArgumentListSyntaxData { Raw, Parent, IndexInParent }
  };
}

RC<TypeArgumentListSyntaxData>
TypeArgumentListSyntaxData::makeBlank() {
  return make(RawSyntax::make(SyntaxKind::TypeArgumentList, {},
                              SourcePresence::Present));
}

#pragma mark - type-argument-list API

TypeArgumentListSyntax::
TypeArgumentListSyntax(RC<SyntaxData> Root,
                       const TypeArgumentListSyntaxData *Data)
  : Syntax(Root, Data) {}

TypeArgumentListSyntax TypeArgumentListSyntax::addType(
    Optional<RC<TokenSyntax>> MaybeComma,
    TupleTypeElementSyntax NewTypeArgument) const {
  auto Layout = getRaw()->Layout;

  if (MaybeComma.hasValue()) {
    syntax_assert_token_is(MaybeComma.getValue(), tok::comma, ",");
    Layout.push_back(MaybeComma.getValue());
  }

  Layout.push_back(NewTypeArgument.getRaw());

  auto NewRaw = RawSyntax::make(SyntaxKind::TypeArgumentList, Layout,
                                SourcePresence::Present);
  return Data->replaceSelf<TypeArgumentListSyntax>(NewRaw);
}

#pragma mark - tuple-type Data

TupleTypeSyntaxData::TupleTypeSyntaxData(RC<RawSyntax> Raw,
                                         const SyntaxData *Parent,
                                         CursorIndex IndexInParent)
    : TypeSyntaxData(Raw, Parent, IndexInParent) {
  assert(Raw->Kind == SyntaxKind::TupleType);
  assert(Raw->Layout.size() == 3);
  syntax_assert_child_token_text(Raw, TupleTypeSyntax::Cursor::LeftParenToken,
                                 tok::l_paren,
                                 "(");
  syntax_assert_child_kind(Raw, TupleTypeSyntax::Cursor::TypeArgumentList,
                           SyntaxKind::TypeArgumentList);
  syntax_assert_child_token_text(Raw, TupleTypeSyntax::Cursor::RightParenToken,
                                 tok::r_paren,
                                 ")");
}

RC<TupleTypeSyntaxData>
TupleTypeSyntaxData::make(RC<RawSyntax> Raw,
                          const SyntaxData *Parent,
                          CursorIndex IndexInParent) {
  return RC<TupleTypeSyntaxData> {
    new TupleTypeSyntaxData { Raw, Parent, IndexInParent }
  };
}

RC<TupleTypeSyntaxData>
TupleTypeSyntaxData::makeBlank() {
  return make(
      RawSyntax::make(SyntaxKind::TupleType,
                      {
                        TokenSyntax::missingToken(tok::l_paren, "("),
                        RawSyntax::missing(SyntaxKind::TypeArgumentList),
                        TokenSyntax::missingToken(tok::r_paren, ")"),
                      },
                      SourcePresence::Present));
}

#pragma mark - tuple-type API

TupleTypeSyntax::TupleTypeSyntax(RC<SyntaxData> Root,
                                 const TupleTypeSyntaxData *Data)
  : TypeSyntax(Root, Data) {}

TupleTypeSyntax
TupleTypeSyntax::withLeftParen(RC<TokenSyntax> NewLeftParen) const {
  syntax_assert_token_is(NewLeftParen, tok::l_paren, "(");
  auto NewRaw = getRaw()->replaceChild(Cursor::LeftParenToken, NewLeftParen);
  return Data->replaceSelf<TupleTypeSyntax>(NewRaw);
}

TupleTypeSyntax TupleTypeSyntax::
withTypeArgumentList(TypeArgumentListSyntax NewTypeArgumentList) const {
  auto NewRaw = getRaw()->replaceChild(Cursor::TypeArgumentList,
                                       NewTypeArgumentList.getRaw());
  return Data->replaceSelf<TupleTypeSyntax>(NewRaw);
}

TupleTypeSyntax TupleTypeSyntax::
withRightParen(RC<TokenSyntax> NewRightParen) const {
  syntax_assert_token_is(NewRightParen, tok::r_paren, ")");
  auto NewRaw = getRaw()->replaceChild(Cursor::RightParenToken, NewRightParen);
  return Data->replaceSelf<TupleTypeSyntax>(NewRaw);
}

#pragma mark - tuple-type Builder

TupleTypeSyntaxBuilder::TupleTypeSyntaxBuilder()
  : ElementTypeLayout(
      SyntaxFactory::makeBlankTypeArgumentList().getRaw()->Layout) {}

TupleTypeSyntaxBuilder &TupleTypeSyntaxBuilder::
addElementTypeSyntax(llvm::Optional<RC<TokenSyntax>> MaybeComma,
                     TupleTypeElementSyntax ElementTypeSyntax) {
  if (MaybeComma.hasValue()) {
    syntax_assert_token_is(MaybeComma.getValue(), tok::comma, ",");
    ElementTypeLayout.push_back(MaybeComma.getValue());
  } else {
    ElementTypeLayout.push_back(TokenSyntax::missingToken(tok::comma, ","));
  }
  ElementTypeLayout.push_back(ElementTypeSyntax.getRaw());
  return *this;
}

TupleTypeSyntaxBuilder &
TupleTypeSyntaxBuilder::useLeftParen(RC<TokenSyntax> LeftParen) {
  LeftParenToken = LeftParen;
  return *this;
}

TupleTypeSyntaxBuilder &
TupleTypeSyntaxBuilder::useRightParen(RC<TokenSyntax> RightParen) {
  RightParenToken = RightParen;
  return *this;
}

TupleTypeSyntax TupleTypeSyntaxBuilder::build() const {
  auto ElementsRaw = RawSyntax::make(SyntaxKind::TypeArgumentList,
                                     { ElementTypeLayout },
                                     SourcePresence::Present);
  auto Raw = RawSyntax::make(SyntaxKind::TupleType,
                             {
                               LeftParenToken,
                               ElementsRaw,
                               RightParenToken,
                             },
                             SourcePresence::Present);
  auto Data = TupleTypeSyntaxData::make(Raw);
  return { Data, Data.get() };
}

#pragma mark - tuple-type-element Data

TupleTypeElementSyntaxData::
TupleTypeElementSyntaxData(RC<RawSyntax> Raw,
                           const SyntaxData *Parent,
                           CursorIndex IndexInParent)
  : SyntaxData(Raw, Parent, IndexInParent) {
  assert(Raw->Kind == SyntaxKind::TupleTypeElement);
  assert(Raw->Layout.size() == 5);
  syntax_assert_child_token(Raw, TupleTypeElementSyntax::Cursor::Label,
                            tok::identifier);
  syntax_assert_child_token_text(Raw,
                                 TupleTypeElementSyntax::Cursor::ColonToken,
                                 tok::colon, ":");
  syntax_assert_child_kind(Raw, TupleTypeElementSyntax::Cursor::Attributes,
                           SyntaxKind::TypeAttributes);
  syntax_assert_child_token_text(Raw,
                                 TupleTypeElementSyntax::Cursor::InoutToken,
                                 tok::kw_inout,
                                 "inout");
  assert(Raw->getChild(TupleTypeElementSyntax::Cursor::Type)->isType());
}

RC<TupleTypeElementSyntaxData>
TupleTypeElementSyntaxData::make(RC<RawSyntax> Raw,
                                 const SyntaxData *Parent,
                                 CursorIndex IndexInParent) {
  return RC<TupleTypeElementSyntaxData> {
    new TupleTypeElementSyntaxData { Raw, Parent, IndexInParent }
  };
}

RC<TupleTypeElementSyntaxData>
TupleTypeElementSyntaxData::makeBlank() {
  return make(
      RawSyntax::make(SyntaxKind::TupleTypeElement,
                      {
                        TokenSyntax::missingToken(tok::identifier, ""),
                        TokenSyntax::missingToken(tok::colon, ":"),
                        RawSyntax::missing(SyntaxKind::TypeAttributes),
                        TokenSyntax::missingToken(tok::kw_inout, "inout"),
                        RawSyntax::missing(SyntaxKind::MissingType),
                      },
                      SourcePresence::Present));
}

#pragma mark - tuple-type-element API

TupleTypeElementSyntax::
TupleTypeElementSyntax(RC<SyntaxData> Root,
                       const TupleTypeElementSyntaxData *Data)
  : Syntax(Root, Data) {}

TupleTypeElementSyntax
TupleTypeElementSyntax::withLabel(RC<TokenSyntax> NewLabel) const {
  assert(NewLabel->getTokenKind() == tok::identifier);
  auto NewRaw = getRaw()->replaceChild(Cursor::Label, NewLabel);
  return Data->replaceSelf<TupleTypeElementSyntax>(NewRaw);
}

TupleTypeElementSyntax
TupleTypeElementSyntax::withColonToken(RC<TokenSyntax> NewColonToken) const {
  syntax_assert_token_is(NewColonToken, tok::colon, ":")
  auto NewRaw = getRaw()->replaceChild(Cursor::ColonToken, NewColonToken);
  return Data->replaceSelf<TupleTypeElementSyntax>(NewRaw);
}

TupleTypeElementSyntax TupleTypeElementSyntax::
withTypeAttributes(TypeAttributesSyntax NewTypeAttributes) const {
  auto NewRaw = getRaw()->replaceChild(Cursor::Attributes,
                                       NewTypeAttributes.getRaw());
  return Data->replaceSelf<TupleTypeElementSyntax>(NewRaw);
}

TupleTypeElementSyntax TupleTypeElementSyntax::
withInoutToken(RC<TokenSyntax> NewInoutToken) const {
  syntax_assert_token_is(NewInoutToken, tok::kw_inout, "inout");
  auto NewRaw = getRaw()->replaceChild(Cursor::InoutToken, NewInoutToken);
  return Data->replaceSelf<TupleTypeElementSyntax>(NewRaw);
}

TupleTypeElementSyntax
TupleTypeElementSyntax::withTypeSyntax(TypeSyntax NewTypeSyntax) const {
  auto NewRaw = getRaw()->replaceChild(Cursor::Type, NewTypeSyntax.getRaw());
  return Data->replaceSelf<TupleTypeElementSyntax>(NewRaw);
}

#pragma mark - metatype-type Data

MetatypeTypeSyntaxData::MetatypeTypeSyntaxData(RC<RawSyntax> Raw,
                                               const SyntaxData *Parent,
                                               CursorIndex IndexInParent)
    : TypeSyntaxData(Raw, Parent, IndexInParent) {
  assert(Raw->Kind == SyntaxKind::MetatypeType);
  assert(Raw->Layout.size() == 3);
  assert(Raw->getChild(MetatypeTypeSyntax::Cursor::BaseType)->isType());
  syntax_assert_child_token_text(Raw, MetatypeTypeSyntax::Cursor::DotToken,
                                 tok::period, ".");
  syntax_assert_child_token(Raw, MetatypeTypeSyntax::Cursor::TypeToken,
                            tok::identifier);
}

RC<MetatypeTypeSyntaxData>
MetatypeTypeSyntaxData::make(RC<RawSyntax> Raw,
                             const SyntaxData *Parent,
                             CursorIndex IndexInParent) {
  return RC<MetatypeTypeSyntaxData> {
    new MetatypeTypeSyntaxData { Raw, Parent, IndexInParent }
  };
}

RC<MetatypeTypeSyntaxData> MetatypeTypeSyntaxData::makeBlank() {
  return make(RawSyntax::make(SyntaxKind::MetatypeType,
                              {
                                RawSyntax::missing(SyntaxKind::MissingType),
                                TokenSyntax::missingToken(tok::period, "."),
                                TokenSyntax::missingToken(tok::identifier, ""),
                              },
                              SourcePresence::Present));
}

#pragma mark - metatype-type API

MetatypeTypeSyntax::MetatypeTypeSyntax(RC<SyntaxData> Root,
                                       const MetatypeTypeSyntaxData *Data)
  : TypeSyntax(Root, Data) {}

MetatypeTypeSyntax
MetatypeTypeSyntax::withBaseTypeSyntax(TypeSyntax NewBaseTypeSyntax) const {
  auto NewRaw = getRaw()->replaceChild(Cursor::BaseType,
                                       NewBaseTypeSyntax.getRaw());
  return Data->replaceSelf<MetatypeTypeSyntax>(NewRaw);
}

MetatypeTypeSyntax
MetatypeTypeSyntax::withDotToken(RC<TokenSyntax> NewDotToken) const {
  syntax_assert_token_is(NewDotToken, tok::period, ".");
  auto NewRaw = getRaw()->replaceChild(Cursor::DotToken, NewDotToken);
  return Data->replaceSelf<MetatypeTypeSyntax>(NewRaw);
}

MetatypeTypeSyntax
MetatypeTypeSyntax::withTypeToken(RC<TokenSyntax> NewTypeToken) const {
  assert(NewTypeToken->getTokenKind() == tok::identifier);
  assert(NewTypeToken->getText() == "Type" ||
         NewTypeToken->getText() == "Protocol");
  auto NewRaw = getRaw()->replaceChild(Cursor::TypeToken, NewTypeToken);
  return Data->replaceSelf<MetatypeTypeSyntax>(NewRaw);
}

#pragma mark - optional-type Data

OptionalTypeSyntaxData::OptionalTypeSyntaxData(RC<RawSyntax> Raw,
                                               const SyntaxData *Parent,
                                               CursorIndex IndexInParent)
    : TypeSyntaxData(Raw, Parent, IndexInParent) {
  assert(Raw->Kind == SyntaxKind::OptionalType);
  assert(Raw->Layout.size() == 2);
  assert(Raw->getChild(OptionalTypeSyntax::Cursor::BaseType)->isType());
  syntax_assert_child_token_text(Raw, OptionalTypeSyntax::Cursor::QuestionToken,
                                 tok::question_postfix, "?");
}

RC<OptionalTypeSyntaxData>
OptionalTypeSyntaxData::make(RC<RawSyntax> Raw,
                             const SyntaxData *Parent,
                             CursorIndex IndexInParent) {
  return RC<OptionalTypeSyntaxData> {
    new OptionalTypeSyntaxData { Raw, Parent, IndexInParent }
  };
}

RC<OptionalTypeSyntaxData> OptionalTypeSyntaxData::makeBlank() {
  return make(RawSyntax::make(SyntaxKind::OptionalType,
    {
      RawSyntax::missing(SyntaxKind::MissingType),
      TokenSyntax::missingToken(tok::question_postfix, "?"),
    },
    SourcePresence::Present));
}

#pragma mark - optional-type API

OptionalTypeSyntax::OptionalTypeSyntax(RC<SyntaxData> Root,
                                       const OptionalTypeSyntaxData *Data)
  : TypeSyntax(Root, Data) {}

OptionalTypeSyntax
OptionalTypeSyntax::withBaseTypeSyntax(TypeSyntax NewTypeSyntax) const {
  auto NewRaw = getRaw()->replaceChild(Cursor::BaseType, NewTypeSyntax.getRaw());
  return Data->replaceSelf<OptionalTypeSyntax>(NewRaw);
}

OptionalTypeSyntax
OptionalTypeSyntax::withQuestionToken(RC<TokenSyntax> NewQuestionToken) const {
  syntax_assert_token_is(NewQuestionToken, tok::question_postfix, "?");
  auto NewRaw = getRaw()->replaceChild(Cursor::QuestionToken, NewQuestionToken);
  return Data->replaceSelf<OptionalTypeSyntax>(NewRaw);
}

#pragma mark - implicitly-unwrapped-optional-type Data

ImplicitlyUnwrappedOptionalTypeSyntaxData::
ImplicitlyUnwrappedOptionalTypeSyntaxData(RC<RawSyntax> Raw,
                                          const SyntaxData *Parent,
                                          CursorIndex IndexInParent)
    : TypeSyntaxData(Raw, Parent, IndexInParent) {
  assert(Raw->Kind == SyntaxKind::ImplicitlyUnwrappedOptionalType);
  assert(Raw->Layout.size() == 2);
  assert(Raw->getChild(ImplicitlyUnwrappedOptionalTypeSyntax::Cursor::Type)
           ->isType());
  syntax_assert_child_token_text(Raw,
    ImplicitlyUnwrappedOptionalTypeSyntax::Cursor::ExclaimToken,
    tok::exclaim_postfix, "!");
}

RC<ImplicitlyUnwrappedOptionalTypeSyntaxData>
ImplicitlyUnwrappedOptionalTypeSyntaxData::make(RC<RawSyntax> Raw,
                                                const SyntaxData *Parent,
                                                CursorIndex IndexInParent) {
  return RC<ImplicitlyUnwrappedOptionalTypeSyntaxData> {
    new ImplicitlyUnwrappedOptionalTypeSyntaxData { Raw, Parent, IndexInParent }
  };
}

RC<ImplicitlyUnwrappedOptionalTypeSyntaxData>
ImplicitlyUnwrappedOptionalTypeSyntaxData::makeBlank() {
  return make(RawSyntax::make(SyntaxKind::ImplicitlyUnwrappedOptionalType,
    {
      RawSyntax::missing(SyntaxKind::MissingType),
      TokenSyntax::missingToken(tok::exclaim_postfix, "!"),
    },
    SourcePresence::Present));
}

#pragma mark - implicitly-unwrapped-optional-type API

ImplicitlyUnwrappedOptionalTypeSyntax::
ImplicitlyUnwrappedOptionalTypeSyntax(RC<SyntaxData> Root,
    const ImplicitlyUnwrappedOptionalTypeSyntaxData *Data)
  : TypeSyntax(Root, Data) {}

ImplicitlyUnwrappedOptionalTypeSyntax ImplicitlyUnwrappedOptionalTypeSyntax::
withBaseTypeSyntax(TypeSyntax NewTypeSyntax) const {
  auto NewRaw = getRaw()->replaceChild(Cursor::Type, NewTypeSyntax.getRaw());
  return Data->replaceSelf<ImplicitlyUnwrappedOptionalTypeSyntax>(NewRaw);
}

ImplicitlyUnwrappedOptionalTypeSyntax ImplicitlyUnwrappedOptionalTypeSyntax::
withExclaimToken(RC<TokenSyntax> NewExclaimToken) const {
  syntax_assert_token_is(NewExclaimToken, tok::exclaim_postfix, "!");
  auto NewRaw = getRaw()->replaceChild(Cursor::ExclaimToken, NewExclaimToken);
  return Data->replaceSelf<ImplicitlyUnwrappedOptionalTypeSyntax>(NewRaw);
}

#pragma mark - array-type Data

ArrayTypeSyntaxData::ArrayTypeSyntaxData(RC<RawSyntax> Raw,
                                         const SyntaxData *Parent,
                                         CursorIndex IndexInParent)
    : TypeSyntaxData(Raw, Parent, IndexInParent) {
  assert(Raw->Kind == SyntaxKind::ArrayType);
  assert(Raw->Layout.size() == 3);
  syntax_assert_child_token_text(Raw,
    ArrayTypeSyntax::Cursor::LeftSquareBracketToken,
    tok::l_square, "[");
  assert(Raw->getChild(ArrayTypeSyntax::Cursor::Type)->isType());
  syntax_assert_child_token_text(Raw,
    ArrayTypeSyntax::Cursor::RightSquareBracketToken,
    tok::r_square, "]");
}

RC<ArrayTypeSyntaxData> ArrayTypeSyntaxData::make(RC<RawSyntax> Raw,
                                                  const SyntaxData *Parent,
                                                  CursorIndex IndexInParent) {
  return RC<ArrayTypeSyntaxData> {
    new ArrayTypeSyntaxData { Raw, Parent, IndexInParent }
  };
}

RC<ArrayTypeSyntaxData> ArrayTypeSyntaxData::makeBlank() {
  return make(RawSyntax::make(SyntaxKind::ArrayType,
                              {
                                TokenSyntax::missingToken(tok::l_square, "["),
                                RawSyntax::missing(SyntaxKind::MissingType),
                                TokenSyntax::missingToken(tok::r_square, "]"),
                              },
                              SourcePresence::Present));
}

#pragma mark - array-type API

ArrayTypeSyntax::ArrayTypeSyntax(RC<SyntaxData> Root,
                                 const ArrayTypeSyntaxData *Data)
  : TypeSyntax(Root, Data) {}

ArrayTypeSyntax ArrayTypeSyntax::
withLeftSquareBracketToken(RC<TokenSyntax> NewLeftSquareBracketToken) const {
  syntax_assert_token_is(NewLeftSquareBracketToken, tok::l_square, "[");
  auto NewRaw = getRaw()->replaceChild(Cursor::LeftSquareBracketToken,
                                     NewLeftSquareBracketToken);
  return Data->replaceSelf<ArrayTypeSyntax>(NewRaw);
}

ArrayTypeSyntax ArrayTypeSyntax::withType(TypeSyntax NewType) const {
  auto NewRaw = getRaw()->replaceChild(Cursor::Type, NewType.getRaw());
  return Data->replaceSelf<ArrayTypeSyntax>(NewRaw);
}

ArrayTypeSyntax ArrayTypeSyntax::
withRightSquareBracketToken(RC<TokenSyntax> NewRightSquareBracketToken) const {
  syntax_assert_token_is(NewRightSquareBracketToken, tok::r_square, "]");
  auto NewRaw = getRaw()->replaceChild(Cursor::RightSquareBracketToken,
                                       NewRightSquareBracketToken);
  return Data->replaceSelf<ArrayTypeSyntax>(NewRaw);
}

#pragma mark - dictionary-type Data

DictionaryTypeSyntaxData::DictionaryTypeSyntaxData(RC<RawSyntax> Raw,
                                                   const SyntaxData *Parent,
                                                   CursorIndex IndexInParent)
    : TypeSyntaxData(Raw, Parent, IndexInParent) {
  assert(Raw->Kind == SyntaxKind::DictionaryType);
  assert(Raw->Layout.size() == 5);

  syntax_assert_child_token_text(Raw,
    DictionaryTypeSyntax::Cursor::LeftSquareBracketToken,
    tok::l_square, "[");
  assert(Raw->getChild(DictionaryTypeSyntax::Cursor::KeyType)->isType());
  syntax_assert_child_token_text(Raw, DictionaryTypeSyntax::Cursor::ColonToken,
                                 tok::colon, ":");
  assert(Raw->getChild(DictionaryTypeSyntax::Cursor::ValueType)->isType());
  syntax_assert_child_token_text(Raw,
    DictionaryTypeSyntax::Cursor::RightSquareBracketToken,
    tok::r_square, "]");
}

RC<DictionaryTypeSyntaxData>
DictionaryTypeSyntaxData::make(RC<RawSyntax> Raw,
                               const SyntaxData *Parent,
                               CursorIndex IndexInParent) {
  return RC<DictionaryTypeSyntaxData> {
    new DictionaryTypeSyntaxData { Raw, Parent, IndexInParent }
  };
}

RC<DictionaryTypeSyntaxData>
DictionaryTypeSyntaxData::makeBlank() {
  return make(RawSyntax::make(SyntaxKind::DictionaryType,
                              {
                                TokenSyntax::missingToken(tok::l_square, "["),
                                RawSyntax::missing(SyntaxKind::MissingType),
                                TokenSyntax::missingToken(tok::colon, ":"),
                                RawSyntax::missing(SyntaxKind::MissingType),
                                TokenSyntax::missingToken(tok::r_square, "]"),
                              },
                              SourcePresence::Present));
}

#pragma mark - dictionary-type API

DictionaryTypeSyntax::DictionaryTypeSyntax(RC<SyntaxData> Root,
                                           const DictionaryTypeSyntaxData *Data)
  : TypeSyntax(Root, Data) {}

DictionaryTypeSyntax DictionaryTypeSyntax::
withLeftSquareBracketToken(RC<TokenSyntax> NewLeftSquareBracketToken) const {
  syntax_assert_token_is(NewLeftSquareBracketToken, tok::l_square, "[");
  auto NewRaw = getRaw()->replaceChild(Cursor::LeftSquareBracketToken,
                                       NewLeftSquareBracketToken);
  return Data->replaceSelf<DictionaryTypeSyntax>(NewRaw);
}

DictionaryTypeSyntax
DictionaryTypeSyntax::withKeyTypeSyntax(TypeSyntax NewTypeSyntax) const {
  auto NewRaw = getRaw()->replaceChild(Cursor::KeyType, NewTypeSyntax.getRaw());
  return Data->replaceSelf<DictionaryTypeSyntax>(NewRaw);
}

DictionaryTypeSyntax
DictionaryTypeSyntax::withColon(RC<TokenSyntax> NewColonToken) const {
  syntax_assert_token_is(NewColonToken, tok::colon, ":");
  auto NewRaw = getRaw()->replaceChild(Cursor::ColonToken, NewColonToken);
  return Data->replaceSelf<DictionaryTypeSyntax>(NewRaw);
}

DictionaryTypeSyntax
DictionaryTypeSyntax::withValueTypeSyntax(TypeSyntax NewTypeSyntax) const {
  auto NewRaw = getRaw()->replaceChild(Cursor::ValueType,
                                       NewTypeSyntax.getRaw());
  return Data->replaceSelf<DictionaryTypeSyntax>(NewRaw);
}

DictionaryTypeSyntax DictionaryTypeSyntax::
withRightSquareBracketToken(RC<TokenSyntax> NewRightSquareBracketToken) const {
  syntax_assert_token_is(NewRightSquareBracketToken, tok::r_square, "]");
  auto NewRaw = getRaw()->replaceChild(Cursor::RightSquareBracketToken,
                                       NewRightSquareBracketToken);
  return Data->replaceSelf<DictionaryTypeSyntax>(NewRaw);
}

#pragma mark - function-type-argument Data

FunctionTypeArgumentSyntaxData::
FunctionTypeArgumentSyntaxData(RC<RawSyntax> Raw,
                               const SyntaxData *Parent,
                               CursorIndex IndexInParent)
  : SyntaxData(Raw, Parent, IndexInParent) {}

RC<FunctionTypeArgumentSyntaxData>
FunctionTypeArgumentSyntaxData::make(RC<RawSyntax> Raw,
                                     const SyntaxData *Parent,
                                     CursorIndex IndexInParent) {
  return RC<FunctionTypeArgumentSyntaxData> {
    new FunctionTypeArgumentSyntaxData { Raw, Parent, IndexInParent }
  };
}

RC<FunctionTypeArgumentSyntaxData>
FunctionTypeArgumentSyntaxData::makeBlank() {
  auto Raw = RawSyntax::make(SyntaxKind::FunctionTypeArgument,
                             {
                               TokenSyntax::missingToken(tok::identifier, ""),
                               TokenSyntax::missingToken(tok::identifier, ""),
                               TokenSyntax::missingToken(tok::colon, ","),
                             },
                             SourcePresence::Present);
  return make(Raw);
}

#pragma mark - function-type-argument API

FunctionTypeArgumentSyntax::
FunctionTypeArgumentSyntax(RC<SyntaxData> Root,
                           const FunctionTypeArgumentSyntaxData *Data)
  : Syntax(Root, Data) {}

#pragma mark - function-type Data

FunctionTypeSyntaxData::FunctionTypeSyntaxData(RC<RawSyntax> Raw,
                                               const SyntaxData *Parent,
                                               CursorIndex IndexInParent)
  : TypeSyntaxData(Raw, Parent, IndexInParent) {
  assert(Raw->Kind == SyntaxKind::FunctionType);
  syntax_assert_child_kind(Raw, FunctionTypeSyntax::Cursor::TypeAttributes,
                           SyntaxKind::TypeAttributes);
  syntax_assert_child_token_text(Raw, FunctionTypeSyntax::Cursor::LeftParen,
                                 tok::l_paren, "(");
  syntax_assert_child_kind(Raw, FunctionTypeSyntax::Cursor::ArgumentList,
                           SyntaxKind::TypeArgumentList);
  syntax_assert_child_token_text(Raw, FunctionTypeSyntax::Cursor::RightParen,
                                 tok::r_paren, ")");
#ifndef NDEBUG
  auto ThrowsOrRethrows =
    cast<TokenSyntax>(
      Raw->getChild(FunctionTypeSyntax::Cursor::ThrowsOrRethrows));
  assert(ThrowsOrRethrows->is(tok::kw_throws, "throws") ||
         ThrowsOrRethrows->is(tok::kw_rethrows, "rethrows"));
#endif
  syntax_assert_child_token_text(Raw, FunctionTypeSyntax::Cursor::Arrow,
                                 tok::arrow, "->");
  assert(Raw->getChild(FunctionTypeSyntax::Cursor::ReturnType)->isType());
}

RC<FunctionTypeSyntaxData>
FunctionTypeSyntaxData::make(RC<RawSyntax> Raw,
                             const SyntaxData *Parent,
                             CursorIndex IndexInParent) {
  return RC<FunctionTypeSyntaxData> {
    new FunctionTypeSyntaxData { Raw, Parent, IndexInParent }
  };
}

RC<FunctionTypeSyntaxData> FunctionTypeSyntaxData::makeBlank() {
  return make(RawSyntax::make(SyntaxKind::FunctionType,
    {
      RawSyntax::missing(SyntaxKind::TypeAttributes),
      TokenSyntax::missingToken(tok::l_paren, "("),
      RawSyntax::missing(SyntaxKind::TypeArgumentList),
      TokenSyntax::missingToken(tok::r_paren, ")"),
      TokenSyntax::missingToken(tok::kw_throws, "throws"),
      TokenSyntax::missingToken(tok::arrow, "->"),
      RawSyntax::missing(SyntaxKind::MissingType),
    },
    SourcePresence::Present));
}

#pragma mark - function-type API

FunctionTypeSyntax::FunctionTypeSyntax(RC<SyntaxData> Root,
                                       const FunctionTypeSyntaxData *Data)
  : TypeSyntax(Root, Data) {}

FunctionTypeSyntax FunctionTypeSyntax::
withTypeAttributes(TypeAttributesSyntax NewAttributes) const {
  auto NewRaw = getRaw()->replaceChild(Cursor::TypeAttributes,
                                     NewAttributes.getRaw());
  return Data->replaceSelf<FunctionTypeSyntax>(NewRaw);
}

FunctionTypeSyntax
FunctionTypeSyntax::withLeftArgumentsParen(RC<TokenSyntax> NewLeftParen) const {
  syntax_assert_token_is(NewLeftParen, tok::l_paren, "(");
  auto NewRaw = getRaw()->replaceChild(Cursor::LeftParen, NewLeftParen);
  return Data->replaceSelf<FunctionTypeSyntax>(NewRaw);
}

FunctionTypeSyntax FunctionTypeSyntax::
addTypeArgument(llvm::Optional<RC<TokenSyntax>> MaybeComma,
                FunctionTypeArgumentSyntax NewArgument) const {
  auto ArgList = getRaw()->getChild(Cursor::ArgumentList);

  if (MaybeComma.hasValue()) {
    syntax_assert_token_is(MaybeComma.getValue(), tok::comma, ",");
    ArgList = ArgList->append(MaybeComma.getValue());
  } else {
    if (!ArgList->Layout.empty()) {
      ArgList = ArgList->append(TokenSyntax::missingToken(tok::comma, ","));
    }
  }
  ArgList = ArgList->append(NewArgument.getRaw());
  auto NewRaw = getRaw()->replaceChild(Cursor::ArgumentList, ArgList);
  return Data->replaceSelf<FunctionTypeSyntax>(NewRaw);
}

FunctionTypeSyntax FunctionTypeSyntax::
withRightArgumentsParen(RC<TokenSyntax> NewLeftParen) const {
  syntax_assert_token_is(NewLeftParen, tok::r_paren, ")");
  auto NewRaw = getRaw()->replaceChild(Cursor::RightParen, NewLeftParen);
  return Data->replaceSelf<FunctionTypeSyntax>(NewRaw);
}

FunctionTypeSyntax
FunctionTypeSyntax::withThrowsKeyword(RC<TokenSyntax> NewThrowsKeyword) const {
  syntax_assert_token_is(NewThrowsKeyword, tok::kw_throws, "throws");
  auto NewRaw = getRaw()->replaceChild(Cursor::ThrowsOrRethrows,
                                       NewThrowsKeyword);
  return Data->replaceSelf<FunctionTypeSyntax>(NewRaw);
}

FunctionTypeSyntax FunctionTypeSyntax::
withRethrowsKeyword(RC<TokenSyntax> NewThrowsKeyword) const {
  syntax_assert_token_is(NewThrowsKeyword, tok::kw_rethrows, "rethrows");
  auto NewRaw = getRaw()->replaceChild(Cursor::ThrowsOrRethrows,
                                       NewThrowsKeyword);
  return Data->replaceSelf<FunctionTypeSyntax>(NewRaw);
}

FunctionTypeSyntax
FunctionTypeSyntax::withArrow(RC<TokenSyntax> NewArrow) const {
  syntax_assert_token_is(NewArrow, tok::arrow, "->");
  auto NewRaw = getRaw()->replaceChild(Cursor::Arrow, NewArrow);
  return Data->replaceSelf<FunctionTypeSyntax>(NewRaw);
}

FunctionTypeSyntax
FunctionTypeSyntax::withReturnTypeSyntax(TypeSyntax NewReturnTypeSyntax) const {
  auto NewRaw = getRaw()->replaceChild(Cursor::ReturnType,
                                       NewReturnTypeSyntax.getRaw());
  return Data->replaceSelf<FunctionTypeSyntax>(NewRaw);
}

#pragma mark - function-type Builder

FunctionTypeSyntaxBuilder::FunctionTypeSyntaxBuilder()
    : FunctionTypeLayout(
          SyntaxFactory::makeBlankFunctionType().getRaw()->Layout) {}

FunctionTypeSyntaxBuilder &FunctionTypeSyntaxBuilder::useTypeAttributes(
    TypeAttributeSyntax NewAttributes) {
  auto Index = cursorIndex(FunctionTypeSyntax::Cursor::TypeAttributes);
  FunctionTypeLayout[Index] = NewAttributes.getRaw();
  return *this;
}

FunctionTypeSyntaxBuilder &
FunctionTypeSyntaxBuilder::useLeftArgumentsParen(RC<TokenSyntax> NewLeftParen) {
  syntax_assert_token_is(NewLeftParen, tok::l_paren, "(");
  auto Index = cursorIndex(FunctionTypeSyntax::Cursor::LeftParen);
  FunctionTypeLayout[Index] = NewLeftParen;
  return *this;
}

FunctionTypeSyntaxBuilder &FunctionTypeSyntaxBuilder::
useRightArgumentsParen(RC<TokenSyntax> NewRightParen) {
  syntax_assert_token_is(NewRightParen, tok::r_paren, ")");
  auto Index = cursorIndex(FunctionTypeSyntax::Cursor::RightParen);
  FunctionTypeLayout[Index] = NewRightParen;
  return *this;
}

FunctionTypeSyntaxBuilder &FunctionTypeSyntaxBuilder::
addArgumentTypeSyntax(Optional<RC<TokenSyntax>> MaybeComma,
                      FunctionTypeArgumentSyntax NewTypeArgument) {
  auto Index = cursorIndex(FunctionTypeSyntax::Cursor::ArgumentList);
  auto TypeArgumentsLayout = FunctionTypeLayout[Index]->Layout;

  if (MaybeComma.hasValue()) {
    syntax_assert_token_is(MaybeComma.getValue(), tok::comma, ",");
    TypeArgumentsLayout.push_back(MaybeComma.getValue());
  } else {
    if (TypeArgumentsLayout.empty()) {
      TypeArgumentsLayout.push_back(TokenSyntax::missingToken(tok::comma, ","));
    }
  }

  TypeArgumentsLayout.push_back(NewTypeArgument.getRaw());

  FunctionTypeLayout[Index] = RawSyntax::make(SyntaxKind::TypeArgumentList,
                                              TypeArgumentsLayout,
                                              SourcePresence::Present);
  return *this;
}

FunctionTypeSyntaxBuilder &
FunctionTypeSyntaxBuilder::useThrowsKeyword(RC<TokenSyntax> NewThrowsKeyword) {
  syntax_assert_token_is(NewThrowsKeyword, tok::kw_throws, "throws");
  auto Index = cursorIndex(FunctionTypeSyntax::Cursor::ThrowsOrRethrows);
  FunctionTypeLayout[Index] = NewThrowsKeyword;
  return *this;
}

FunctionTypeSyntaxBuilder &
FunctionTypeSyntaxBuilder::useRethrowsKeyword(RC<TokenSyntax> NewRethrowsKeyword) {
  syntax_assert_token_is(NewRethrowsKeyword, tok::kw_rethrows, "rethrows");
  auto Index = cursorIndex(FunctionTypeSyntax::Cursor::ThrowsOrRethrows);
  FunctionTypeLayout[Index] = NewRethrowsKeyword;
  return *this;
}

FunctionTypeSyntaxBuilder &
FunctionTypeSyntaxBuilder::useArrow(RC<TokenSyntax> NewArrow) {
  syntax_assert_token_is(NewArrow, tok::arrow, "->");
  auto Index = cursorIndex(FunctionTypeSyntax::Cursor::Arrow);
  FunctionTypeLayout[Index] = NewArrow;
  return *this;
}

FunctionTypeSyntaxBuilder &
FunctionTypeSyntaxBuilder::useReturnTypeSyntax(TypeSyntax NewReturnType) {
  auto Index = cursorIndex(FunctionTypeSyntax::Cursor::ReturnType);
  FunctionTypeLayout[Index] = NewReturnType.getRaw();
  return *this;
}

FunctionTypeSyntax FunctionTypeSyntaxBuilder::build() const {
  auto Raw = RawSyntax::make(SyntaxKind::FunctionType, FunctionTypeLayout,
                             SourcePresence::Present);
  auto Data = FunctionTypeSyntaxData::make(Raw);
  return { Data, Data.get() };
}
