ProjectionPathASTNode* findLastInnerNodeOnPath(ProjectionPathASTNode* root,
                                               const FieldPath& path,
                                               size_t componentIndex) {
    invariant(root);
    invariant(path.getPathLength() > componentIndex);

    auto child = exact_pointer_cast<ProjectionPathASTNode*>(
        root->getChild(path.getFieldName(componentIndex)));
    if (path.getPathLength() == componentIndex + 1) {
        return child;
    } else if (!child) {
        return nullptr;
    }

    return findLastInnerNodeOnPath(child, path, componentIndex + 1);
}
ProjectionPathASTNode* findLastInnerNodeOnPath(ProjectionPathASTNode* root,
                                               const FieldPath& path,
                                               size_t componentIndex) {
    invariant(root);
    invariant(path.getPathLength() > componentIndex);

    auto child = exact_pointer_cast<ProjectionPathASTNode*>(
        root->getChild(path.getFieldName(componentIndex)));
    if (path.getPathLength() == componentIndex + 1) {
        return child;
    } else if (!child) {
        return nullptr;
    }

    return findLastInnerNodeOnPath(child, path, componentIndex + 1);
}