%{
  # -*- mode: C++ -*-
  from gyb_syntax_support import *
  NODE_MAP = create_node_map()
  # Ignore the following admonition; it applies to the resulting .cpp file only
}%
//// Automatically Generated From ParsedSyntaxBuilders.cpp.gyb.
//// Do Not Edit Directly!
//===------------- ParsedSyntaxBuilders.cpp - Parsed Syntax Building ------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2019 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
//
//===----------------------------------------------------------------------===//

#include "swift/Parse/ParsedSyntaxBuilders.h"
#include "swift/Parse/ParsedRawSyntaxRecorder.h"
#include "swift/Parse/SyntaxParsingContext.h"
#include "swift/Syntax/SyntaxNodes.h"

using namespace swift;
using namespace swift::syntax;

% for node in SYNTAX_NODES + PARSEONLY_NODES:
%   if node.is_buildable():
%     for child in node.children:
%       child_elt = None
%       child_elt_type = None
%       child_node = NODE_MAP.get(child.syntax_kind)
%       if child_node and child_node.is_syntax_collection():
%         child_elt = child_node.collection_element_name
%         child_elt_type = child_node.collection_element_type
%         child_elt_name = child.name + 'Member'
%       end
Parsed${node.name}Builder &
Parsed${node.name}Builder::use${child.name}(Parsed${child.type_name} ${child.name}) {
%       if child_elt:
  assert(${child_elt_name}s.empty() && "use either 'use' function or 'add', not both");
%       end
  Layout[cursorIndex(${node.name}::Cursor::${child.name})] =
    ${child.name}.takeRaw();
  return *this;
}
%       if child_elt:
Parsed${node.name}Builder &
Parsed${node.name}Builder::add${child_elt_name}(Parsed${child_elt_type} ${child_elt}) {
  assert(Layout[cursorIndex(${node.name}::Cursor::${child.name})].isNull() && "use either 'use' function or 'add', not both");
  ${child_elt_name}s.push_back(${child_elt}.takeRaw());
  return *this;
}
%       end
%     end

Parsed${node.name}
Parsed${node.name}Builder::record() {
  finishLayout(/*deferred=*/false);
  auto &Rec = SPCtx.getRecorder();
  auto raw = Rec.recordRawSyntax(SyntaxKind::${node.syntax_kind}, Layout);
  return Parsed${node.name}(std::move(raw));
}

Parsed${node.name}
Parsed${node.name}Builder::makeDeferred() {
  finishLayout(/*deferred=*/true);
  auto raw = ParsedRawSyntaxNode::makeDeferred(SyntaxKind::${node.syntax_kind},
    Layout, SPCtx);
  return Parsed${node.name}(std::move(raw));
}

Parsed${node.name}
Parsed${node.name}Builder::build() {
  if (SPCtx.shouldDefer())
    return makeDeferred();
  return record();
}

void Parsed${node.name}Builder::finishLayout(bool deferred) {
  auto &Rec = SPCtx.getRecorder();
  (void)Rec;
% if node.children:
%   for (idx, child) in enumerate(node.children):
%     child_elt = None
%     child_node = NODE_MAP.get(child.syntax_kind)
%     if child_node and child_node.is_syntax_collection():
%       child_elt = child_node.collection_element_name
%       child_elt_type = child_node.collection_element_type
%       child_elt_name = child.name + 'Member'
%     if child_elt:
  if (!${child_elt_name}s.empty()) {
    if (deferred) {
      Layout[${idx}] = ParsedRawSyntaxNode::makeDeferred(SyntaxKind::${child_node.syntax_kind},
                          ${child_elt_name}s, SPCtx);
    } else {
      Layout[${idx}] = Rec.recordRawSyntax(SyntaxKind::${child_node.syntax_kind}, ${child_elt_name}s);
    }
  }
%     end
%     if not child.is_optional:
  if (Layout[${idx}].isNull()) {
%       if child.is_token():
%         token = child.main_token()
%         tok_kind = token.kind if token else "unknown"
    if (deferred) {
      Layout[${idx}] = ParsedRawSyntaxNode::makeDeferredMissing(tok::${tok_kind}, SourceLoc());
    } else {
      Layout[${idx}] = Rec.recordMissingToken(tok::${tok_kind}, SourceLoc());
    }
%       elif child_elt:
    if (deferred) {
      Layout[${idx}] = ParsedRawSyntaxNode::makeDeferred(SyntaxKind::${child_node.syntax_kind}, {}, SPCtx);
    } else {
      Layout[${idx}] = Rec.recordRawSyntax(SyntaxKind::${child_node.syntax_kind}, {});
    }
%       else:
    llvm_unreachable("need missing non-token nodes ?");
%       end
  }
%     end
%   end

#ifndef NDEBUG
  ParsedRawSyntaxRecorder::verifyElementRanges(Layout);
#endif
% end
}

%   end
% end
