%{
  from gyb_syntax_support import *
  # -*- mode: Swift -*-
  # Ignore the following admonition it applies to the resulting .swift file only
}%
//// Automatically Generated From SyntaxCollections.swift.gyb.
//// Do Not Edit Directly!
//===------------ SyntaxCollections.swift.gyb - Syntax Collection ---------===//
//
// 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
//
//===----------------------------------------------------------------------===//

import Foundation

% for node in SYNTAX_NODES:
%   if node.collection_element:

/// `${node.name}` represents a collection of one or more
/// `${node.collection_element_type}` nodes. ${node.name} behaves
/// as a regular Swift collection, and has accessors that return new
/// versions of the collection with different children.
public struct ${node.name}: _SyntaxBase {
  let _root: SyntaxData
  unowned let _data: SyntaxData

  /// Creates a Syntax node from the provided root and data.
  internal init(root: SyntaxData, data: SyntaxData) {
    self._root = root
    self._data = data
#if DEBUG
    validate()
#endif
  }

  /// Creates a new `${node.name}` by replacing the underlying layout with
  /// a different set of raw syntax nodes.
  ///
  /// - Parameter layout: The new list of raw syntax nodes underlying this
  ///                     collection.
  /// - Returns: A new `${node.name}` with the new layout underlying it.
  internal func replacingLayout(
    _ layout: [RawSyntax?]) -> ${node.name} {
    let newRaw = data.raw.replacingLayout(layout)
    let (newRoot, newData) = data.replacingSelf(newRaw)
    return ${node.name}(root: newRoot, data: newData)
  }

  /// Creates a new `${node.name}` by appending the provided syntax element
  /// to the children.
  ///
  /// - Parameter syntax: The element to append.
  /// - Returns: A new `${node.name}` with that element appended to the end.
  public func appending(
    _ syntax: ${node.collection_element_type}) -> ${node.name} {
    var newLayout = data.raw.layout
    newLayout.append(syntax.raw)
    return replacingLayout(newLayout)
  }

  /// Creates a new `${node.name}` by prepending the provided syntax element
  /// to the children.
  ///
  /// - Parameter syntax: The element to prepend.
  /// - Returns: A new `${node.name}` with that element prepended to the
  ///            beginning.
  public func prepending(
    _ syntax: ${node.collection_element_type}) -> ${node.name} {
    return inserting(syntax, at: 0)
  }

  /// Creates a new `${node.name}` by inserting the provided syntax element
  /// at the provided index in the children.
  ///
  /// - Parameters:
  ///   - syntax: The element to insert.
  ///   - index: The index at which to insert the element in the collection.
  ///
  /// - Returns: A new `${node.name}` with that element appended to the end.
  public func inserting(_ syntax: ${node.collection_element_type},
                        at index: Int) -> ${node.name} {
    var newLayout = data.raw.layout
    /// Make sure the index is a valid insertion index (0 to 1 past the end)
    precondition((newLayout.startIndex...newLayout.endIndex).contains(index),
                 "inserting node at invalid index \(index)")
    newLayout.insert(syntax.raw, at: index)
    return replacingLayout(newLayout)
  }

  /// Creates a new `${node.name}` by removing the syntax element at the
  /// provided index.
  ///
  /// - Parameter index: The index of the element to remove from the collection.
  /// - Returns: A new `${node.name}` with the element at the provided index
  ///            removed.
  public func removing(childAt index: Int) -> ${node.name} {
    var newLayout = data.raw.layout
    newLayout.remove(at: index)
    return replacingLayout(newLayout)
  }

  /// Creates a new `${node.name}` by removing the first element.
  ///
  /// - Returns: A new `${node.name}` with the first element removed.
  public func removingFirst() -> ${node.name} {
    var newLayout = data.raw.layout
    newLayout.removeFirst()
    return replacingLayout(newLayout)
  }

  /// Creates a new `${node.name}` by removing the last element.
  ///
  /// - Returns: A new `${node.name}` with the last element removed.
  public func removingLast() -> ${node.name} {
    var newLayout = data.raw.layout
    newLayout.removeLast()
    return replacingLayout(newLayout)
  }

  /// Returns an iterator over the elements of this syntax collection.
  public func makeIterator() -> ${node.name}Iterator {
    return ${node.name}Iterator(collection: self)
  }
}

/// Conformance for `${node.name}`` to the Collection protocol.
extension ${node.name}: Collection {
  public var startIndex: Int {
    return data.childCaches.startIndex
  }

  public var endIndex: Int {
    return data.childCaches.endIndex
  }

  public func index(after i: Int) -> Int {
    return data.childCaches.index(after: i)
  }

  public subscript(_ index: Int) -> ${node.collection_element_type} {
%   cast = '' if node.collection_element_type == 'Syntax' \
%          else 'as! ' + node.collection_element_type
    return child(at: index)! ${cast}
  }
}

/// A type that iterates over a `${node.name}` using its indices.
public struct ${node.name}Iterator: IteratorProtocol {
  public typealias Element = ${node.collection_element_type}

  private let collection: ${node.name}
  private var index: ${node.name}.Index

  fileprivate init(collection: ${node.name}) {
    self.collection = collection
    self.index = collection.startIndex
  }

  public mutating func next() -> Element? {
    guard
      !(self.collection.isEmpty || self.index == self.collection.endIndex)
    else {
      return nil
    }

    let result = collection[index]
    collection.formIndex(after: &index)
    return result
  }
}

%   end
% end
