%{
  from gyb_syntax_support import *
  from gyb_syntax_support.kinds import SYNTAX_BASE_KINDS
  grouped_nodes = { kind: [] for kind in SYNTAX_BASE_KINDS }
  for node in SYNTAX_NODES:
    grouped_nodes[node.base_kind].append(node)
  # -*- mode: Swift -*-
  # Ignore the following admonition; it applies to the resulting .swift file only
}%
//// Automatically Generated From SyntaxKind.swift.gyb.
//// Do Not Edit Directly!
//===--------------- SyntaxKind.swift - Syntax Kind definitions -----------===//
//
// 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

/// Enumerates the known kinds of Syntax represented in the Syntax tree.
internal enum SyntaxKind: String, Codable {
  case token = "Token"
  case unknown = "Unknown"
% for node in SYNTAX_NODES:
  case ${node.swift_syntax_kind} = "${node.syntax_kind}"
% end

% for name, nodes in grouped_nodes.items():
%   if name not in ["Syntax", "SyntaxCollection"]:
  /// Whether the underlying kind is a sub-kind of ${name}Syntax.
  public var is${name}: Bool {
    switch self {
%     for node in nodes:
    case .${node.swift_syntax_kind}: return true
%     end
    default: return false
    }
  }
%   end
% end

  public init(from decoder: Decoder) throws {
    let container = try decoder.singleValueContainer()
    let kind = try container.decode(String.self)
    self = SyntaxKind(rawValue: kind) ?? .unknown
  }
}

/// Creates a Syntax node from the provided RawSyntax using the appropriate
/// Syntax type, as specified by its kind.
/// - Parameters:
///   - raw: The raw syntax with which to create this node.
///   - root: The root of this tree, or `nil` if the new node is the root.
internal func makeSyntax(_ raw: RawSyntax) -> Syntax {
  let data = SyntaxData(raw: raw)
  return makeSyntax(root: nil, data: data)
}

/// Creates a Syntax node from the provided SyntaxData using the appropriate
/// Syntax type, as specified by its kind.
/// - Parameters:
///   - root: The root of this tree, or `nil` if the new node is the root.
///   - data: The data for this new node.
internal func makeSyntax(root: SyntaxData?, data: SyntaxData) -> Syntax {
  let root = root ?? data
  switch data.raw.kind {
  case .token: return TokenSyntax(root: root, data: data)
  case .unknown: return UnknownSyntax(root: root, data: data)
% for node in SYNTAX_NODES:
  case .${node.swift_syntax_kind}:
%   if node.is_base():
    return Unknown${node.name}(root: root, data: data)
%   else:
    return ${node.name}(root: root, data: data)
%   end
% end
  }
}