%{
  from gyb_syntax_support import *
  # -*- mode: C++ -*-
  # Ignore the following admonition; it applies to the resulting .cpp file only
}%
//// Automatically Generated From SyntaxFactory.cpp.gyb.
//// Do Not Edit Directly!
//===--------- SyntaxFactory.cpp - Syntax Factory implementations ---------===//
//
// 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 SyntaxFactory, one of the most important client-facing
// types in lib/Syntax and likely to be very commonly used.
//
// Effectively a namespace, SyntaxFactory is never instantiated, but is *the*
// one-stop shop for making new Syntax nodes. Putting all of these into a
// collection of static methods provides a single point of API lookup for
// clients' convenience and also allows the library to hide all of the
// constructors for all Syntax nodes, as the SyntaxFactory is friend to all.
//
//===----------------------------------------------------------------------===//

#include "swift/Syntax/SyntaxFactory.h"
#include "swift/Syntax/SyntaxNodes.h"
#include "swift/Syntax/Trivia.h"
#include "llvm/ADT/ArrayRef.h"

#include <vector>

using namespace swift;
using namespace swift::syntax;

TokenSyntax SyntaxFactory::makeToken(tok Kind, OwnedString Text,
                                     const Trivia &LeadingTrivia,
                                     const Trivia &TrailingTrivia,
                                     SourcePresence Presence,
                                     SyntaxArena *Arena) {
  return make<TokenSyntax>(RawSyntax::make(Kind, Text, LeadingTrivia.Pieces,
                                           TrailingTrivia.Pieces, Presence,
                                           Arena));
}

UnknownSyntax
SyntaxFactory::makeUnknownSyntax(llvm::ArrayRef<TokenSyntax> Tokens,
                                 SyntaxArena *Arena) {
  std::vector<RC<RawSyntax>> Layout;
  Layout.reserve(Tokens.size());
  for (auto &Token : Tokens) {
    Layout.push_back(Token.getRaw());
  }
  auto Raw = RawSyntax::make(SyntaxKind::Unknown, Layout,
                             SourcePresence::Present, Arena);
  return make<UnknownSyntax>(Raw);
}

Syntax SyntaxFactory::makeBlankCollectionSyntax(SyntaxKind Kind) {
  switch(Kind) {
% for node in SYNTAX_NODES:
%   if node.is_syntax_collection():
  case SyntaxKind::${node.syntax_kind}: return makeBlank${node.syntax_kind}();
%   end
% end
  default: break;
  }
  llvm_unreachable("not collection kind.");
}

std::pair<unsigned, unsigned>
SyntaxFactory::countChildren(SyntaxKind Kind){
  switch(Kind) {
% for node in SYNTAX_NODES:
%   if not node.is_syntax_collection():
  case SyntaxKind::${node.syntax_kind}:
%     child_count = len(node.children)
%     non_optional_child_count = sum(0 if child.is_optional else 1 for child in node.children)
    return {${non_optional_child_count}, ${child_count}};
%   end
% end
  default:
  llvm_unreachable("bad syntax kind.");
  }
}

bool SyntaxFactory::canServeAsCollectionMemberRaw(SyntaxKind CollectionKind,
                                                  const RC<RawSyntax> &Member) {
  switch (CollectionKind) {
% for node in SYNTAX_NODES:
%   if node.is_syntax_collection():
  case SyntaxKind::${node.syntax_kind}:
%     if node.collection_element_choices:
%       element_checks = []
%       for choice in node.collection_element_choices:
%         element_checks.append("" + choice + "Syntax::kindof(Member->getKind())")
%       end
    return ${' || '.join(element_checks)};
%     else:
    return ${node.collection_element_type}::kindof(Member->getKind());
%     end
%   end
% end
  default:
    llvm_unreachable("Not collection kind.");
  }
}

bool SyntaxFactory::
canServeAsCollectionMember(SyntaxKind CollectionKind, Syntax Member) {
  return canServeAsCollectionMemberRaw(CollectionKind, Member.getRaw());
}

RC<RawSyntax> SyntaxFactory::createRaw(SyntaxKind Kind,
                                       llvm::ArrayRef<RC<RawSyntax>> Elements,
                                       SyntaxArena *Arena) {
  switch (Kind) {
% for node in SYNTAX_NODES:
  case SyntaxKind::${node.syntax_kind}: {
% if node.children:
%   child_count = len(node.children)
    RC<RawSyntax> Layout[${child_count}];
    unsigned I = 0;
%   for (child_idx, child) in enumerate(node.children):
    // child[${child_idx}] ${child.name}
    if (I == Elements.size() ||
        !${check_child_condition_raw(child)}(Elements[I])) {
%     if child.is_optional:
      Layout[${child_idx}] = nullptr;
%     else:
      return nullptr;
%     end
    } else {
      Layout[${child_idx}] = Elements[I];
      ++I;
    }
%   end
    if (I != Elements.size())
      return nullptr;
    return RawSyntax::make(Kind, Layout, SourcePresence::Present, Arena);
% elif node.is_syntax_collection():
    for (auto &E : Elements) {
      if (!canServeAsCollectionMemberRaw(SyntaxKind::${node.syntax_kind}, E))
        return nullptr;
    }
    return RawSyntax::make(Kind, Elements, SourcePresence::Present, Arena);
% else:
    return nullptr;
% end
  }
% end
  default:
    return nullptr;
  }
}

Optional<Syntax> SyntaxFactory::createSyntax(SyntaxKind Kind,
                                             llvm::ArrayRef<Syntax> Elements,
                                             SyntaxArena *Arena) {
  std::vector<RC<RawSyntax>> Layout;
  Layout.reserve(Elements.size());
  for (auto &E : Elements)
    Layout.emplace_back(E.getRaw());

  if (auto Raw = createRaw(Kind, Layout, Arena))
    return make<Syntax>(Raw);
  else
    return None;
}

% for node in SYNTAX_NODES:
%   if node.children:
%     child_params = []
%     for child in node.children:
%         param_type = child.type_name
%         if child.is_optional:
%            param_type = "llvm::Optional<%s>" % param_type
%         child_params.append("%s %s" % (param_type, child.name))
%     child_params = ', '.join(child_params)
${node.name}
SyntaxFactory::make${node.syntax_kind}(${child_params},
                                       SyntaxArena *Arena) {
  auto Raw = RawSyntax::make(SyntaxKind::${node.syntax_kind}, {
%     for child in node.children:
%       if child.is_optional:
    ${child.name}.hasValue() ? ${child.name}->getRaw() : nullptr,
%       else:
    ${child.name}.getRaw(),
%       end
%     end
  }, SourcePresence::Present, Arena);
  return make<${node.name}>(Raw);
}
%   elif node.is_syntax_collection():
${node.name}
SyntaxFactory::make${node.syntax_kind}(
    const std::vector<${node.collection_element_type}> &elements,
    SyntaxArena *Arena) {
  std::vector<RC<RawSyntax>> layout;
  layout.reserve(elements.size());
  for (auto &element : elements) {
    layout.push_back(element.getRaw());
  }
  auto raw = RawSyntax::make(SyntaxKind::${node.syntax_kind},
                             layout, SourcePresence::Present, Arena);
  return make<${node.name}>(raw);
}
%   end

${node.name}
SyntaxFactory::makeBlank${node.syntax_kind}(SyntaxArena *Arena) {
  auto raw = RawSyntax::make(SyntaxKind::${node.syntax_kind}, {
%   for child in node.children:
%       if child.is_optional:
    nullptr,
%       else:
    ${make_missing_child(child)},
%       end
%   end
  }, SourcePresence::Present, Arena);
  return make<${node.name}>(raw);
}
% end

% for token in SYNTAX_TOKENS:
%   if token.is_keyword:
  TokenSyntax
  SyntaxFactory::make${token.name}Keyword(const Trivia &LeadingTrivia,
                                          const Trivia &TrailingTrivia,
                                          SyntaxArena *Arena) {
    return makeToken(tok::${token.kind}, "${token.text}",
                     LeadingTrivia, TrailingTrivia,
                     SourcePresence::Present, Arena);
  }
%   elif token.text:
  TokenSyntax
  SyntaxFactory::make${token.name}Token(const Trivia &LeadingTrivia,
                                        const Trivia &TrailingTrivia,
                                        SyntaxArena *Arena) {
    return makeToken(tok::${token.kind}, "${token.text}",
                     LeadingTrivia, TrailingTrivia,
                     SourcePresence::Present, Arena);
  }
%   else:
  TokenSyntax
  SyntaxFactory::make${token.name}(OwnedString Text,
                                   const Trivia &LeadingTrivia,
                                   const Trivia &TrailingTrivia,
                                   SyntaxArena *Arena) {
    return makeToken(tok::${token.kind}, Text,
                     LeadingTrivia, TrailingTrivia,
                     SourcePresence::Present, Arena);
  }
%   end
% end

TupleTypeSyntax SyntaxFactory::makeVoidTupleType(SyntaxArena *Arena) {
  return makeTupleType(makeLeftParenToken({}, {}, Arena),
                       makeBlankTupleTypeElementList(Arena),
                       makeRightParenToken({}, {}, Arena),
                       Arena);
}

TupleTypeElementSyntax
SyntaxFactory::makeTupleTypeElement(llvm::Optional<TokenSyntax> Label,
                                    llvm::Optional<TokenSyntax> Colon,
                                    TypeSyntax Type,
                                    llvm::Optional<TokenSyntax> TrailingComma,
                                    SyntaxArena *Arena) {
  return makeTupleTypeElement(None, Label, None, Colon, Type, None, None,
                              TrailingComma, Arena);
}

TupleTypeElementSyntax
SyntaxFactory::makeTupleTypeElement(TypeSyntax Type,
                                    llvm::Optional<TokenSyntax> TrailingComma,
                                    SyntaxArena *Arena) {
  return makeTupleTypeElement(None, None, None, None, Type, None, None,
                              TrailingComma, Arena);
}

GenericParameterSyntax
SyntaxFactory::makeGenericParameter(TokenSyntax Name,
                                    llvm::Optional<TokenSyntax> TrailingComma,
                                    SyntaxArena *Arena) {
  return makeGenericParameter(None, Name, None, None, TrailingComma, Arena);
}

TypeSyntax SyntaxFactory::makeTypeIdentifier(OwnedString TypeName,
                                             const Trivia &LeadingTrivia,
                                             const Trivia &TrailingTrivia,
                                             SyntaxArena *Arena) {
  auto identifier =
      makeIdentifier(TypeName, LeadingTrivia, TrailingTrivia, Arena);
  return makeSimpleTypeIdentifier(identifier, None, Arena);
}

TypeSyntax SyntaxFactory::makeAnyTypeIdentifier(const Trivia &LeadingTrivia,
                                                const Trivia &TrailingTrivia,
                                                SyntaxArena *Arena) {
  return makeTypeIdentifier("Any", LeadingTrivia, TrailingTrivia, Arena);
}

TypeSyntax SyntaxFactory::makeSelfTypeIdentifier(const Trivia &LeadingTrivia,
                                                 const Trivia &TrailingTrivia,
                                                 SyntaxArena *Arena) {
  return makeTypeIdentifier("Self", LeadingTrivia, TrailingTrivia, Arena);
}

TokenSyntax SyntaxFactory::makeTypeToken(const Trivia &LeadingTrivia,
                                         const Trivia &TrailingTrivia,
                                         SyntaxArena *Arena) {
  return makeIdentifier("Type", LeadingTrivia, TrailingTrivia, Arena);
}

TokenSyntax SyntaxFactory::makeProtocolToken(const Trivia &LeadingTrivia,
                                             const Trivia &TrailingTrivia,
                                             SyntaxArena *Arena) {
  return makeIdentifier("Protocol", LeadingTrivia, TrailingTrivia, Arena);
}

TokenSyntax SyntaxFactory::makeEqualityOperator(const Trivia &LeadingTrivia,
                                                const Trivia &TrailingTrivia,
                                                SyntaxArena *Arena) {
  return makeToken(tok::oper_binary_spaced, "==", LeadingTrivia, TrailingTrivia,
                   SourcePresence::Present, Arena);
}
