%{
  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
  }
}

extension Syntax {
  /// 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.
  static func fromRaw(_ raw: RawSyntax) -> Syntax {
    let data = SyntaxData(raw: raw)
    return make(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.
  static func make(root: SyntaxData?, data: SyntaxData) -> Syntax {
    let root = root ?? data
    switch data.raw.kind {
    case .token: return TokenSyntax(root: root, data: data)
    case .unknown: return Syntax(root: root, data: data)
% for node in SYNTAX_NODES:
    case .${node.swift_syntax_kind}: return ${node.name}(root: root, data: data)
% end
    }
  }
}