//===--- TypeSyntax.h - Swift Type Syntax Interface -------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file defines the interface for type syntax nodes,
// such as for type representations for tuple types (Int, Int), or
// function types () -> (), for example.
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_SYNTAX_TYPESYNTAX_H
#define SWIFT_SYNTAX_TYPESYNTAX_H

#include "swift/Syntax/References.h"
#include "swift/Syntax/Syntax.h"
#include "swift/Syntax/SyntaxData.h"
#include "swift/Syntax/TokenSyntax.h"

namespace swift {
namespace syntax {

class GenericArgumentClauseSyntax;
class GenericArgumentClauseSyntaxData;
class GenericParameterClauseSyntax;
class GenericParameterClauseSyntaxData;

#pragma mark - balanced-tokens Data

class BalancedTokensSyntaxData final : public SyntaxData {
  friend class SyntaxData;
  friend struct SyntaxFactory;

  BalancedTokensSyntaxData(RC<RawSyntax> Raw,
                           const SyntaxData *Parent = nullptr,
                           CursorIndex IndexInParent = 0);
  static RC<BalancedTokensSyntaxData> make(RC<RawSyntax> Raw,
                                           const SyntaxData *Parent = nullptr,
                                           CursorIndex IndexInParent = 0);
  static RC<BalancedTokensSyntaxData> makeBlank();
public:
  static bool classof(const SyntaxData *S) {
    return S->getKind() == SyntaxKind::BalancedTokens;
  }
};

#pragma mark - balanced-tokens API

/// balanced-tokens -> Any identifier, keyword, literal, or operator
///                  | Any punctuation except (, ), [, ], {, or }
class BalancedTokensSyntax final : public Syntax {
  friend struct SyntaxFactory;
  friend class SyntaxData;

  using DataType = BalancedTokensSyntaxData;

  BalancedTokensSyntax(RC<SyntaxData> Root,
                       const BalancedTokensSyntaxData *Data);

public:
  // TODO: TODO: BalancedTokensSyntax::getBalancedToken

  BalancedTokensSyntax
  addBalancedToken(RC<TokenSyntax> NewBalancedToken) const;

  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::BalancedTokens;
  }
};

#pragma mark - type-attribute Data

class TypeAttributeSyntaxData final : public SyntaxData {
  friend class SyntaxData;
  RC<BalancedTokensSyntaxData> CachedBalancedTokens;
  friend struct SyntaxFactory;

  TypeAttributeSyntaxData(RC<RawSyntax> Raw,
                          const SyntaxData *Parent = nullptr,
                          CursorIndex IndexInParent = 0);
  static RC<TypeAttributeSyntaxData> make(RC<RawSyntax> Raw,
                                          const SyntaxData *Parent = nullptr,
                                          CursorIndex IndexInParent = 0);
  static RC<TypeAttributeSyntaxData> makeBlank();

public:
  static bool classof(const SyntaxData *S) {
    return S->getKind() == SyntaxKind::TypeAttribute;
  }
};

#pragma mark - type-attribute API

/// type-attribute -> '@' identifier attribute-argument-clause?
/// attribute-argument-clause -> '(' balanced-tokens ')'
class TypeAttributeSyntax final : public Syntax {
  friend struct SyntaxFactory;
  friend class TypeAttributeSyntaxData;
  friend class SyntaxData;

  using DataType = TypeAttributeSyntaxData;

  enum class Cursor : CursorIndex {
    AtSignToken,
    Identifier,
    LeftParenToken,
    BalancedTokens,
    RightParenToken,
  };

  TypeAttributeSyntax(RC<SyntaxData> Root, const TypeAttributeSyntaxData *Data);

public:

  /// Return the '@' token associated with the type attribute.
  RC<TokenSyntax> getAtSignToken() const;

  /// Return a new TypeAttributeSyntax with the given '@' token.
  TypeAttributeSyntax withAtSignToken(RC<TokenSyntax> NewAtSignToken) const;

  /// Return the name of the type attribute.
  RC<TokenSyntax> getIdentifier() const;

  /// Return a new TypeAttributeSyntax with the given name.
  TypeAttributeSyntax withIdentifier(RC<TokenSyntax> NewIdentifier) const;

  /// Return the left parenthesis '(' token attached to the type attribute.
  RC<TokenSyntax> getLeftParenToken() const;

  /// Return a TypeAttributeSyntax with the given left parenthesis '(' token.
  TypeAttributeSyntax
  withLeftParenToken(RC<TokenSyntax> NewLeftParenToken) const;

  /// Return the "balanced tokens" of the type attributes; the arguments.
  BalancedTokensSyntax getBalancedTokens() const;

  /// Return a TypeAttributeSyntax with the given balanced tokens as arguments
  /// to the type attribute.
  TypeAttributeSyntax
  withBalancedTokens(BalancedTokensSyntax NewBalancedTokens) const;

  /// Return the right parenthesis ')' token attached to the type attribute.
  RC<TokenSyntax> getRightParenToken() const;

  /// Return a TypeAttributeSyntax with the given right parenthesis ')' token.
  TypeAttributeSyntax
  withRightParenToken(RC<TokenSyntax> NewRightParenToken) const;

  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::TypeAttribute;
  }
};

#pragma mark - type-attributes Data

class TypeAttributesSyntaxData final : public SyntaxData {
  friend class SyntaxData;
  friend class TypeAttributesSyntax;
  friend struct SyntaxFactory;

  TypeAttributesSyntaxData(RC<RawSyntax> Raw,
                           const SyntaxData *Parent = nullptr,
                           CursorIndex IndexInParent = 0);
  static RC<TypeAttributesSyntaxData> make(RC<RawSyntax> Raw,
                                           const SyntaxData *Parent = nullptr,
                                           CursorIndex IndexInParent = 0);
  static RC<TypeAttributesSyntaxData> makeBlank();
public:
  static bool classof(const SyntaxData *S) {
    return S->getKind() == SyntaxKind::TypeAttributes;
  }
};

#pragma mark - type-attributes API

/// type-attributes -> type-attribute
///                  | type-attribute type-attributes
class TypeAttributesSyntax final : public Syntax {
  friend struct SyntaxFactory;
  friend class TypeAttributesSyntaxData;
  friend class SyntaxData;
  friend class FunctionSignatureSyntax;
  friend class FunctionDeclSyntax;

  using DataType = TypeAttributesSyntaxData;

  TypeAttributesSyntax(RC<SyntaxData> Root,
                       const TypeAttributesSyntaxData *Data);
public:
  // TODO: Convert to SyntaxCollection
  // 

  TypeAttributesSyntax
  addTypeAttribute(TypeAttributeSyntax NewTypeAttribute) const;

  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::TypeAttributes;
  }
};

#pragma mark - type-syntax Data

class TypeSyntaxData : public SyntaxData {
  friend class SyntaxData;
  friend class TypeSyntax;

protected:
  TypeSyntaxData(RC<RawSyntax> Raw,
                 const SyntaxData *Parent = nullptr,
                 CursorIndex IndexInParent = 0);

public:
  static bool classof(const SyntaxData *S) {
    return S->isType();
  }
};

#pragma mark - type-syntax API

/// type -> array-type
///       | dictionary-type
///       | function-type
///       | type-identifier
///       | tuple-type
///       | optional-type
///       | implicitly-unwrapped-optional-type
///       | protocol-composition-type
///       | metatype-type
///       | 'Any'
///       | 'Self'
class TypeSyntax : public Syntax {
  using DataType = TypeSyntaxData;
  friend class SyntaxData;
  friend class FunctionParameterSyntax;
  friend class FunctionSignatureSyntax;
protected:
  TypeSyntax(const RC<SyntaxData> Root, const TypeSyntaxData *Data);
public:
  static bool classof(const Syntax *S) {
    return S->isType();
  }
};

#pragma mark - type-identifier Data

class TypeIdentifierSyntaxData final : public TypeSyntaxData {
  friend struct SyntaxFactory;
  friend class TypeIdentifierSyntax;
  friend class SyntaxData;
  
  RC<GenericArgumentClauseSyntaxData> CachedGenericArgumentClause;
  RC<TypeIdentifierSyntaxData> CachedChildTypeIdentifier;

  TypeIdentifierSyntaxData(RC<RawSyntax> Raw,
                           const SyntaxData *Parent = nullptr,
                           CursorIndex IndexInParent = 0);

  static RC<TypeIdentifierSyntaxData> make (RC<RawSyntax> Raw,
                                            const SyntaxData *Parent = nullptr,
                                            CursorIndex IndexInParent = 0);
  static RC<TypeIdentifierSyntaxData> makeBlank();
public:
  static bool classof(const SyntaxData *S) {
    return S->getKind() == SyntaxKind::TypeIdentifier;
  }
};

#pragma mark - type-identifier API

/// type-identifier -> type-name generic-argument-clause?
///                  | type-name generic-argument-clause '.' type-identifier
class TypeIdentifierSyntax final : public TypeSyntax {
  friend struct SyntaxFactory;
  friend class TypeIdentifierSyntaxData;
  friend class SyntaxData;

  using DataType = TypeIdentifierSyntaxData;

private:
  enum class Cursor {
    Identifier,
    GenericArgumentClause,
    DotToken,
    ChildTypeIdentifier,
  };

  TypeIdentifierSyntax(RC<SyntaxData> Root,
                       const TypeIdentifierSyntaxData *Data);

public:
  RC<TokenSyntax> getIdentifier() const;

  TypeIdentifierSyntax
  withIdentifier(RC<TokenSyntax> NewIdentifier) const;

  GenericArgumentClauseSyntax getGenericArgumentClause() const;
  TypeIdentifierSyntax
  withGenericArgumentClause(GenericArgumentClauseSyntax NewGenericArgs) const;

  RC<TokenSyntax> getDotToken() const;
  TypeIdentifierSyntax withDotToken(RC<TokenSyntax> NewIdentifier) const;

  TypeIdentifierSyntax getChildType() const;
  TypeIdentifierSyntax addChildType(TypeIdentifierSyntax ChildType) const;

  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::TypeIdentifier;
  }
};

#pragma mark - type-argument-list Data

class TypeArgumentListSyntaxData final : public SyntaxData {
  friend class SyntaxData;
  friend struct SyntaxFactory;

  TypeArgumentListSyntaxData(RC<RawSyntax> Raw,
                             const SyntaxData *Parent = nullptr,
                             CursorIndex IndexInParent = 0);

  static RC<TypeArgumentListSyntaxData> make(RC<RawSyntax> Raw,
                                             const SyntaxData *Parent = nullptr,
                                             CursorIndex IndexInParent = 0);
  static RC<TypeArgumentListSyntaxData> makeBlank();

public:
  static bool classof(const SyntaxData *S) {
    return S->getKind() == SyntaxKind::TypeArgumentList;
  }
};

#pragma mark - tuple-type-element Data

class TupleTypeElementSyntaxData final : public SyntaxData {
  friend class SyntaxData;
  friend struct SyntaxFactory;

  TupleTypeElementSyntaxData(RC<RawSyntax> Raw,
                             const SyntaxData *Parent = nullptr,
                             CursorIndex IndexInParent = 0);
  static RC<TupleTypeElementSyntaxData> make(RC<RawSyntax> Raw,
                                             const SyntaxData *Parent = nullptr,
                                             CursorIndex IndexInParent = 0);
  static RC<TupleTypeElementSyntaxData> makeBlank();
public:
  static bool classof(const SyntaxData *S) {
    return S->getKind() == SyntaxKind::TupleTypeElement;
  }
};

#pragma mark - tuple-type-element API

/// tuple-type-element -> (identifier ':')? type-attributes? 'inout'? type
///
/// Used for tuple elements and function argument types. This can simply be
/// a type without a label.
class TupleTypeElementSyntax final : public Syntax {
  friend struct SyntaxFactory;
  friend class TupleTypeElementSyntaxData;
  friend class SyntaxData;

  using DataType = TupleTypeElementSyntaxData;

  enum class Cursor : CursorIndex {
    Label,
    ColonToken,
    Attributes,
    InoutToken,
    Type,
  };

  TupleTypeElementSyntax(RC<SyntaxData> Root,
                         const TupleTypeElementSyntaxData *Data);
public:
  /// Return the label of the tuple type element.
  RC<TokenSyntax> getLabel() const;

  /// Return a new named tuple type element with the specified identifier.
  TupleTypeElementSyntax withLabel(RC<TokenSyntax> NewIdentifier) const;

  /// Return the colon token of the tuple type element.
  RC<TokenSyntax> getColonToken() const;

  /// Return a new named tuple type element with a colon token replacement
  /// using the specified leading and trailing trivia.
  TupleTypeElementSyntax
  withColonToken(RC<TokenSyntax> NewColonToken) const;

  /// Return the type attributes for the tuple type element.
  TypeAttributesSyntax getTypeAttributes() const;

  /// Return a new named tuple type element with the specified attributes.
  TupleTypeElementSyntax
  withTypeAttributes(TypeAttributesSyntax NewTypeAttributes) const;

  /// Return the 'inout' token of the tuple type element.
  RC<TokenSyntax> getInoutToken() const;

  /// Return a new named tuple type element with the 'inout' keyword added.
  TupleTypeElementSyntax withInoutToken(RC<TokenSyntax> NewInoutToken) const;

  TypeSyntax getTypeSyntax() const;

  /// Return a new named tuple type element with the specified type.
  TupleTypeElementSyntax withTypeSyntax(TypeSyntax NewType) const;

  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::TupleTypeElement;
  }
};


#pragma mark - type-argument-list API

/// type-argument-list
///   -> function-type-argument
///    | function-type-argument ',' function-type-argument-list
class TypeArgumentListSyntax final : public Syntax {
  friend struct SyntaxFactory;
  friend class SyntaxData;

  using DataType = TypeArgumentListSyntaxData;

  TypeArgumentListSyntax(RC<SyntaxData> Root,
                         const TypeArgumentListSyntaxData *Data);

public:
  // TODO: TODO: getType
  TypeArgumentListSyntax
  addType(llvm::Optional<RC<TokenSyntax>> MaybeComma,
          TupleTypeElementSyntax NewTypeArgument) const;

  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::TypeArgumentList;
  }
};

#pragma mark - tuple-type Data

class TupleTypeSyntaxData final : public TypeSyntaxData {
  friend class SyntaxData;
  friend struct SyntaxFactory;
  friend class TupleTypeSyntaxBuilder;
  TupleTypeSyntaxData(RC<RawSyntax> Raw,
                      const SyntaxData *Parent = nullptr,
                      CursorIndex IndexInParent = 0);

  static RC<TupleTypeSyntaxData> make(RC<RawSyntax> Raw,
                                      const SyntaxData *Parent = nullptr,
                                      CursorIndex IndexInParent = 0);
  static RC<TupleTypeSyntaxData> makeBlank();

public:
  static bool classof(const SyntaxData *S) {
    return S->getKind() == SyntaxKind::TupleType;
  }
};

#pragma mark - tuple-type API

/// tuple-type -> '(' tuple-type-element-list ')'
class TupleTypeSyntax final : public TypeSyntax {
  friend struct SyntaxFactory;
  friend class TupleTypeSyntaxData;
  friend class SyntaxData;
  friend class TupleTypeSyntaxBuilder;

  using DataType = TupleTypeSyntaxData;

  enum class Cursor : CursorIndex {
    LeftParenToken,
    TypeArgumentList,
    RightParenToken,
  };

  TupleTypeSyntax(RC<SyntaxData> Root, const TupleTypeSyntaxData *Data);

public:
  /// Return the left paren '(' token surrounding the tuple type syntax.
  RC<TokenSyntax> getLeftParen() const;
  TupleTypeSyntax withLeftParen(RC<TokenSyntax> NewLeftParen) const;

  /// Get the type argument list inside the tuple type syntax.
  TypeArgumentListSyntax getTypeArgumentList() const;

  /// Return a new tuple type syntax with the given type argument list.
  TupleTypeSyntax
  withTypeArgumentList(TypeArgumentListSyntax NewTypeArgumentList) const;

  /// Return the right paren ')' token surrounding the tuple type syntax.
  RC<TokenSyntax> getRightParen() const;
  TupleTypeSyntax withRightParen(RC<TokenSyntax> NewRightParen) const;

  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::TupleType;
  }
};

#pragma mark - tuple-type Builder

/// Incrementally builds tuple type syntax.
class TupleTypeSyntaxBuilder final {
  RC<RawSyntax> LeftParenToken;
  RawSyntax::LayoutList ElementTypeLayout;
  RC<RawSyntax> RightParenToken;

public:
  TupleTypeSyntaxBuilder();

  /// Use the given left paren '(' token when building the tuple type syntax.
  TupleTypeSyntaxBuilder &useLeftParen(RC<TokenSyntax> LeftParen);

  /// Add an element type to the eventual tuple type syntax.
  TupleTypeSyntaxBuilder &
  addElementTypeSyntax(llvm::Optional<RC<TokenSyntax>> MaybeComma,
                       TupleTypeElementSyntax ElementTypeSyntax);

  /// Use the given left paren '(' token when building the tuple type syntax.
  TupleTypeSyntaxBuilder &useRightParen(RC<TokenSyntax> RightParen);

  /// Build a TupleTypeSyntax from the elements seen so far.
  ///
  /// This method is stateless and can be called multiple times to get
  /// new tuple type syntax nodes.
  TupleTypeSyntax build() const;
};

#pragma mark - metatype-type Data

class MetatypeTypeSyntaxData final : public TypeSyntaxData {
  friend struct SyntaxFactory;
  friend class SyntaxData;
  MetatypeTypeSyntaxData(RC<RawSyntax> Raw,
                         const SyntaxData *Parent = nullptr,
                         CursorIndex IndexInParent = 0);
  static RC<MetatypeTypeSyntaxData> make(RC<RawSyntax> Raw,
                                         const SyntaxData *Parent = nullptr,
                                         CursorIndex IndexInParent = 0);
  static RC<MetatypeTypeSyntaxData> makeBlank();
public:
  static bool classof(const SyntaxData *S) {
    return S->getKind() == SyntaxKind::MetatypeType;
  }
};

#pragma mark - metatype-type API

/// metatype-type -> type '.' 'Type'
///                | type '.' 'Protocol'
class MetatypeTypeSyntax final : public TypeSyntax {
  friend struct SyntaxFactory;
  friend class MetatypeTypeSyntaxData;
  friend class SyntaxData;

  using DataType = MetatypeTypeSyntaxData;

  enum class Cursor : CursorIndex {
    BaseType,
    DotToken,
    TypeToken,
  };

  MetatypeTypeSyntax(RC<SyntaxData> Root, const MetatypeTypeSyntaxData *Data);

public:
  TypeSyntax getBaseTypeSyntax() const;
  /// Return a new metatype type with the given base type - the `A` in `A.Type`.
  MetatypeTypeSyntax withBaseTypeSyntax(TypeSyntax NewBaseType) const;

  /// Return the dot token.
  RC<TokenSyntax> getDotToken() const;

  /// Return a new metatype type with the given dot token.
  MetatypeTypeSyntax withDotToken(RC<TokenSyntax> NewDotToken) const;

  /// Return the child type - either the identifiers `Type` or `Protocol`.
  RC<TokenSyntax> getTypeToken() const;

  /// Return a new metatype type with the given child type - either the
  /// identifiers: `Type` or `Protocol`.
  MetatypeTypeSyntax withTypeToken(RC<TokenSyntax> NewTypeToken) const;

  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::MetatypeType;
  }
};

#pragma mark - optional-type Data

class OptionalTypeSyntaxData final : public TypeSyntaxData {
  friend class SyntaxData;
  friend struct SyntaxFactory;
  OptionalTypeSyntaxData(RC<RawSyntax> Raw,
                         const SyntaxData *Parent = nullptr,
                         CursorIndex IndexInParent = 0);
  static RC<OptionalTypeSyntaxData> make(RC<RawSyntax> Raw,
                                         const SyntaxData *Parent = nullptr,
                                         CursorIndex IndexInParent = 0);
  static RC<OptionalTypeSyntaxData> makeBlank();
public:
  static bool classof(const SyntaxData *S) {
    return S->getKind() == SyntaxKind::OptionalType;
  }
};

#pragma mark - optional-type API

/// optional-type -> type '?'
class OptionalTypeSyntax final : public TypeSyntax {
  friend struct SyntaxFactory;
  friend class OptionalTypeSyntaxData;
  friend class SyntaxData;

  using DataType = OptionalTypeSyntaxData;

  enum class Cursor : CursorIndex {
    BaseType,
    QuestionToken
  };

  OptionalTypeSyntax(RC<SyntaxData> Root, const OptionalTypeSyntaxData *Data);

public:
  /// Return the syntax of the type to which this optional type refers.
  TypeSyntax getBaseTypeSyntax() const;

  /// Return a new optional type with the given base type.
  OptionalTypeSyntax withBaseTypeSyntax(TypeSyntax NewBaseType) const;

  /// Return the question-mark '?' token attached to this optional type syntax.
  RC<TokenSyntax> getQuestionToken() const;

  /// Return a new optional type with the given question-mark token.
  OptionalTypeSyntax
  withQuestionToken(RC<TokenSyntax> NewQuestionToken) const;

  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::OptionalType;
  }
};

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

class ImplicitlyUnwrappedOptionalTypeSyntaxData final : public TypeSyntaxData {
  friend struct SyntaxFactory;
  friend class SyntaxData;
  ImplicitlyUnwrappedOptionalTypeSyntaxData(RC<RawSyntax> Raw,
                                            const SyntaxData *Parent = nullptr,
                                            CursorIndex IndexInParent = 0);

  static RC<ImplicitlyUnwrappedOptionalTypeSyntaxData>
  make(RC<RawSyntax> Raw,
       const SyntaxData *Parent = nullptr,
       CursorIndex IndexInParent = 0);
  static RC<ImplicitlyUnwrappedOptionalTypeSyntaxData> makeBlank();
public:
  static bool classof(const SyntaxData *S) {
    return S->getKind() == SyntaxKind::ImplicitlyUnwrappedOptionalType;
  }
};

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

/// implicitly-unwrapped-optional-type -> type '!'
class ImplicitlyUnwrappedOptionalTypeSyntax final : public TypeSyntax {
  friend struct SyntaxFactory;
  friend class ImplicitlyUnwrappedOptionalTypeSyntaxData;
  friend class SyntaxData;

  using DataType = ImplicitlyUnwrappedOptionalTypeSyntaxData;

  enum class Cursor : CursorIndex { Type, ExclaimToken };

  ImplicitlyUnwrappedOptionalTypeSyntax(RC<SyntaxData> Root,
      const ImplicitlyUnwrappedOptionalTypeSyntaxData *Data);

public:
  /// Return the syntax for the base type to which this implicitly unwrapped
  /// optional type refers.
  TypeSyntax getBaseTypeSyntax() const;

  /// Return a new implicitly unwrapped optional type syntax with the given base
  /// type syntax
  ImplicitlyUnwrappedOptionalTypeSyntax
  withBaseTypeSyntax(TypeSyntax NewBaseTypeSyntax) const;

  /// Return the exclamation-mark '!' token attached to the end of this
  /// implicitly unwrapped optional type syntax.
  RC<TokenSyntax> getExclaimToken() const;

  /// Return a new implicitly unwrapped optional type with the given
  /// exclamation-mark '!' token.
  ImplicitlyUnwrappedOptionalTypeSyntax
  withExclaimToken(RC<TokenSyntax> NewExclaimToken) const;

  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::OptionalType;
  }
};

#pragma mark - array-type Data

class ArrayTypeSyntaxData final : public TypeSyntaxData {
  friend class SyntaxData;
  friend struct SyntaxFactory;

  ArrayTypeSyntaxData(RC<RawSyntax> Raw,
                      const SyntaxData *Parent = nullptr,
                      CursorIndex IndexInParent = 0);

  static RC<ArrayTypeSyntaxData> make(RC<RawSyntax> Raw,
                                      const SyntaxData *Parent = nullptr,
                                      CursorIndex IndexInParent = 0);
  static RC<ArrayTypeSyntaxData> makeBlank();

public:
  static bool classof(const SyntaxData *S) {
    return S->getKind() == SyntaxKind::OptionalType;
  }
};

#pragma mark - array-type API

// array-type -> '[' type ']'
class ArrayTypeSyntax final : public TypeSyntax {
  friend struct SyntaxFactory;
  friend class ArrayTypeSyntaxData;
  friend class SyntaxData;

  using DataType = ArrayTypeSyntaxData;

  enum class Cursor : CursorIndex {
    LeftSquareBracketToken,
    Type,
    RightSquareBracketToken,
  };

  ArrayTypeSyntax(RC<SyntaxData> Root, const ArrayTypeSyntaxData *Data);

public:
  /// Return the left square bracket '[' token surrounding the array
  /// type syntax.
  RC<TokenSyntax> getLeftSquareBracketToken() const;

  /// Return a new array type with the given left square bracket token.
  ArrayTypeSyntax
  withLeftSquareBracketToken(RC<TokenSyntax> NewLeftSquareBracketToken) const;

  /// Return a new array type with the given element type.
  ArrayTypeSyntax withType(TypeSyntax NewType) const;

  /// Return the right square bracket ']' token surrounding the array
  /// type syntax.
  RC<TokenSyntax> getRightSquareBracketToken() const;

  /// Return a new array type with the given right square bracket token.
  ArrayTypeSyntax
  withRightSquareBracketToken(RC<TokenSyntax> NewRightSquareBracketToken) const;

  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::ArrayType;
  }
};

#pragma mark - dictionary-type Data

class DictionaryTypeSyntaxData final : public TypeSyntaxData {
  friend class SyntaxData;
  friend class DictionaryTypeSyntax;
  friend struct SyntaxFactory;

  RC<TypeSyntaxData> CachedKeyTypeSyntax;
  RC<TypeSyntaxData> CachedValueTypeSyntax;

  DictionaryTypeSyntaxData(RC<RawSyntax> Raw,
                           const SyntaxData *Parent = nullptr,
                           CursorIndex IndexInParent = 0);

  static RC<DictionaryTypeSyntaxData> make(RC<RawSyntax> Raw,
                                           const SyntaxData *Parent = nullptr,
                                           CursorIndex IndexInParent = 0);
  static RC<DictionaryTypeSyntaxData> makeBlank();
public:
  static bool classof(const SyntaxData *S) {
    return S->getKind() == SyntaxKind::ArrayType;
  }
};

#pragma mark - dictionary-type API

// dictionary-type -> '[' type ':' type ']'
class DictionaryTypeSyntax final : public TypeSyntax {
  friend struct SyntaxFactory;
  friend class DictionaryTypeSyntaxData;
  friend class SyntaxData;

  using DataType = DictionaryTypeSyntaxData;

  enum class Cursor : CursorIndex {
    LeftSquareBracketToken,
    KeyType,
    ColonToken,
    ValueType,
    RightSquareBracketToken,
  };

  DictionaryTypeSyntax(RC<SyntaxData> Root,
                       const DictionaryTypeSyntaxData *Data);

public:
  /// Return the left square bracket '[' token surrounding the dictionary
  /// type syntax.
  RC<TokenSyntax> getLeftSquareBracketToken() const;

  /// Return a new dictionary type with the given left square bracket token.
  DictionaryTypeSyntax
  withLeftSquareBracketToken(RC<TokenSyntax> NewLeftSquareBracketToken) const;

  /// Return the key type syntax for this dictionary type.
  TypeSyntax getKeyTypeSyntax() const;

  /// Return a new dictionary type with the given key type.
  DictionaryTypeSyntax withKeyTypeSyntax(TypeSyntax NewKeyType) const;

  /// Get the colon token in the dictionary type syntax.
  RC<TokenSyntax> getColonToken() const;

  /// Return a new dictionary type with the given colon token.
  DictionaryTypeSyntax withColon(RC<TokenSyntax> NewColonToken) const;

  /// Return the value type syntax for this dictionary type.
  TypeSyntax getValueTypeSyntax() const;

  /// Return a new dictionary type with the given value type.
  DictionaryTypeSyntax withValueTypeSyntax(TypeSyntax NewTypeSyntax) const;

  /// Return the right square bracket ']' token surrounding the dictionary
  /// type syntax.
  RC<TokenSyntax> getRightSquareBracketToken() const;

  /// Return a new dictionary type with the given right square bracket token.
  DictionaryTypeSyntax
  withRightSquareBracketToken(RC<TokenSyntax> NewRightSquareBracketToken) const;

  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::DictionaryType;
  }
};

#pragma mark - function-type-argument Data

class FunctionTypeArgumentSyntaxData final : public SyntaxData {
  friend class SyntaxData;
  friend struct SyntaxFactory;

  FunctionTypeArgumentSyntaxData(RC<RawSyntax> Raw,
                                 const SyntaxData *Parent = nullptr,
                                 CursorIndex IndexInParent = 0);

  static RC<FunctionTypeArgumentSyntaxData>
  make(RC<RawSyntax> Raw,
       const SyntaxData *Parent = nullptr,
       CursorIndex IndexInParent = 0);
  static RC<FunctionTypeArgumentSyntaxData> makeBlank();
public:
  static bool classof(const SyntaxData *SD) {
    return SD->getKind() == SyntaxKind::FunctionTypeArgument;
  }
};

#pragma mark - function-type-argument API

class FunctionTypeArgumentSyntax final : public Syntax {
  friend struct SyntaxFactory;
  friend class SyntaxData;

  using DataType = FunctionTypeArgumentSyntaxData;

  enum class Cursor : CursorIndex {
    ExternalParameterName,
    LocalParameterName,
    ColonToken,
    TypeAttributes,
    InoutKeyword,
    Type,
  };

  FunctionTypeArgumentSyntax(RC<SyntaxData> Root,
                             const FunctionTypeArgumentSyntaxData *Data);

public:
  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::FunctionTypeArgument;
  }
};


#pragma mark - function-type Data

class FunctionTypeSyntaxData final : public TypeSyntaxData {
  friend class SyntaxData;
  friend class FunctionTypeSyntax;
  friend class FunctionTypeSyntaxBuilder;
  friend struct SyntaxFactory;

  FunctionTypeSyntaxData(RC<RawSyntax> Raw,
                         const SyntaxData *Parent = nullptr,
                         CursorIndex IndexInParent = 0);
  static RC<FunctionTypeSyntaxData> make(RC<RawSyntax> Raw,
                                         const SyntaxData *Parent = nullptr,
                                         CursorIndex IndexInParent = 0);
  static RC<FunctionTypeSyntaxData> makeBlank();
public:
  static bool classof(const SyntaxData *S) {
    return S->getKind() == SyntaxKind::DictionaryType;
  }
};

#pragma mark - function-type API

/// function-type ->
///   type-attributes? function-type-argument-clause 'throws'? '->' type
/// | type-attributes? function-type-argument-clause 'rethrows' '->' type
class FunctionTypeSyntax final : public TypeSyntax {
  friend struct SyntaxFactory;
  friend class FunctionTypeSyntaxBuilder;
  friend class FunctionTypeSyntaxData;
  friend class SyntaxData;

  using DataType = FunctionTypeSyntaxData;

  enum class Cursor : CursorIndex {
    TypeAttributes,
    LeftParen,
    ArgumentList,
    RightParen,
    ThrowsOrRethrows,
    Arrow,
    ReturnType
  };

  FunctionTypeSyntax(RC<SyntaxData> Root,
                     const FunctionTypeSyntaxData *Data);

public:

  /// Return the type attributes for the function type.
  TypeAttributesSyntax getAttributes() const;

  /// Return a new function type with the given type attributes.
  FunctionTypeSyntax
  withTypeAttributes(TypeAttributesSyntax NewAttributes) const;

  /// Return the left parenthesis '(' token surrounding the argument type.
  RC<TokenSyntax> getLeftArgumentsParen() const;

  /// Return a new function type with the given left parenthesis on the type
  /// argument list.
  FunctionTypeSyntax
  withLeftArgumentsParen(RC<TokenSyntax> NewLeftParen) const;

  /// Return a new function type with the additional argument type and
  /// optionally a preceding comma token.
  FunctionTypeSyntax
  addTypeArgument(llvm::Optional<RC<TokenSyntax>> MaybeComma,
                  FunctionTypeArgumentSyntax NewArgument) const;

  /// Return the type arguments list for this function type syntax.
  TypeArgumentListSyntax getTypeArgumentList() const;

  /// Return a new function type with the given type argument list.
  ///
  /// This replaces all of the argument types.
  FunctionTypeSyntax
  withTypeArgumentList(TypeArgumentListSyntax NewArgumentList) const;

  /// Return the right parenthesis ')' token surrounding the argument type.
  RC<TokenSyntax> getRightArgumentsParen() const;

  /// Return a new function type with the given right parenthesis ')'
  /// on the type argument list.
  FunctionTypeSyntax
  withRightArgumentsParen(RC<TokenSyntax> NewRightParen) const;

  /// Return the 'throws' or 'rethrows' keyword on the function type syntax.
  RC<TokenSyntax> getThrowsOrRethrowsKeyword() const;

  /// Return a new function type with the given `throws` keyword.
  ///
  /// This fills the same slot held by the `rethrows` keyword.
  FunctionTypeSyntax withThrowsKeyword(RC<TokenSyntax> NewThrowsKeyword) const;

  /// Return a new function type with the given `rethrows` keyword.
  ///
  /// This fills the same slot held by the `throws` keyword.
  FunctionTypeSyntax
  withRethrowsKeyword(RC<TokenSyntax> NewThrowsKeyword) const;

  /// Return the arrow token in the function type syntax.
  RC<TokenSyntax> getArrow() const;

  /// Return a new function type with the given arrow token.
  FunctionTypeSyntax withArrow(RC<TokenSyntax> NewArrow) const;

  // Return the return type syntax for the function type.
  TypeSyntax getReturnTypeSyntax() const;

  /// Return a new function type with the given return type.
  FunctionTypeSyntax withReturnTypeSyntax(TypeSyntax NewReturnType) const;

  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::FunctionType;
  }
};

#pragma mark - function-type Builder

/// Incrementally builds function type syntax.
class FunctionTypeSyntaxBuilder final {
  RawSyntax::LayoutList FunctionTypeLayout;
public:
  FunctionTypeSyntaxBuilder();

  /// Use the given type attributes when building the eventual function
  /// syntax.
  FunctionTypeSyntaxBuilder &
  useTypeAttributes(TypeAttributeSyntax NewAttributes);

  /// Use the given left paren '(' token on the argument type syntax.
  FunctionTypeSyntaxBuilder &useLeftArgumentsParen(RC<TokenSyntax> LeftParen);

  FunctionTypeSyntaxBuilder &
  addArgumentTypeSyntax(llvm::Optional<RC<TokenSyntax>> MaybeComma,
                        FunctionTypeArgumentSyntax Argument);

  /// Use the given right paren ')' token on the argument type syntax.
  FunctionTypeSyntaxBuilder &useRightArgumentsParen(RC<TokenSyntax> RightParen);

  /// Use the given 'throws' keyword in the function type syntax.
  FunctionTypeSyntaxBuilder &useThrowsKeyword(RC<TokenSyntax> ThrowsKeyword);

  FunctionTypeSyntaxBuilder &
  useRethrowsKeyword(RC<TokenSyntax> RethrowsKeyword);

  FunctionTypeSyntaxBuilder &useArrow(RC<TokenSyntax> Arrow);
  FunctionTypeSyntaxBuilder &useReturnTypeSyntax(TypeSyntax ReturnType);

  FunctionTypeSyntax build() const;
};

} // end namespace syntax
} // end namespace swift

#endif // SWIFT_SYNTAX_TYPESYNTAX_H
