// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

// Parser combinator framework!
//
// This file declares several functions which construct parsers, usually taking other parsers as
// input, thus making them parser combinators.
//
// A valid parser is any functor which takes a reference to an input cursor (defined below) as its
// input and returns a Maybe.  The parser returns null on parse failure, or returns the parsed
// result on success.
//
// An "input cursor" is any type which implements the same interface as IteratorInput, below.  Such
// a type acts as a pointer to the current input location.  When a parser returns successfully, it
// will have updated the input cursor to point to the position just past the end of what was parsed.
// On failure, the cursor position is unspecified.

#pragma once

#include "../common.h"
#include "../memory.h"
#include "../array.h"
#include "../tuple.h"
#include "../vector.h"

#if _MSC_VER && _MSC_VER < 1920 && !__clang__
#define KJ_MSVC_BROKEN_DECLTYPE 1
#endif

#if KJ_MSVC_BROKEN_DECLTYPE
#include <type_traits>  // result_of_t
#endif

KJ_BEGIN_HEADER

namespace kj {
namespace parse {

template <typename Element, typename Iterator>
class IteratorInput {
  // A parser input implementation based on an iterator range.

public:
  IteratorInput(Iterator begin, Iterator end)
      : parent(nullptr), pos(begin), end(end), best(begin) {}
  explicit IteratorInput(IteratorInput& parent)
      : parent(&parent), pos(parent.pos), end(parent.end), best(parent.pos) {}
  ~IteratorInput() {
    if (parent != nullptr) {
      parent->best = kj::max(kj::max(pos, best), parent->best);
    }
  }
  KJ_DISALLOW_COPY(IteratorInput);

  void advanceParent() {
    parent->pos = pos;
  }
  void forgetParent() {
    parent = nullptr;
  }

  bool atEnd() { return pos == end; }
  auto current() -> decltype(*instance<Iterator>()) {
    KJ_IREQUIRE(!atEnd());
    return *pos;
  }
  auto consume() -> decltype(*instance<Iterator>()) {
    KJ_IREQUIRE(!atEnd());
    return *pos++;
  }
  void next() {
    KJ_IREQUIRE(!atEnd());
    ++pos;
  }

  Iterator getBest() { return kj::max(pos, best); }

  Iterator getPosition() { return pos; }

private:
  IteratorInput* parent;
  Iterator pos;
  Iterator end;
  Iterator best;  // furthest we got with any sub-input
};

template <typename T> struct OutputType_;
template <typename T> struct OutputType_<Maybe<T>> { typedef T Type; };
template <typename Parser, typename Input>
using OutputType = typename OutputType_<
#if KJ_MSVC_BROKEN_DECLTYPE
    std::result_of_t<Parser(Input)>
    // The instance<T&>() based version below results in many compiler errors on MSVC2017.
#else
    decltype(instance<Parser&>()(instance<Input&>()))
#endif
    >::Type;
// Synonym for the output type of a parser, given the parser type and the input type.

// =======================================================================================

template <typename Input, typename Output>
class ParserRef {
  // Acts as a reference to some other parser, with simplified type.  The referenced parser
  // is polymorphic by virtual call rather than templates.  For grammars of non-trivial size,
  // it is important to inject refs into the grammar here and there to prevent the parser types
  // from becoming ridiculous.  Using too many of them can hurt performance, though.

public:
  ParserRef(): parser(nullptr), wrapper(nullptr) {}
  ParserRef(const ParserRef&) = default;
  ParserRef(ParserRef&&) = default;
  ParserRef& operator=(const ParserRef& other) = default;
  ParserRef& operator=(ParserRef&& other) = default;

  template <typename Other>
  constexpr ParserRef(Other&& other)
      : parser(&other), wrapper(&WrapperImplInstance<Decay<Other>>::instance) {
    static_assert(kj::isReference<Other>(), "ParserRef should not be assigned to a temporary.");
  }

  template <typename Other>
  inline ParserRef& operator=(Other&& other) {
    static_assert(kj::isReference<Other>(), "ParserRef should not be assigned to a temporary.");
    parser = &other;
    wrapper = &WrapperImplInstance<Decay<Other>>::instance;
    return *this;
  }

  KJ_ALWAYS_INLINE(Maybe<Output> operator()(Input& input) const) {
    // Always inline in the hopes that this allows branch prediction to kick in so the virtual call
    // doesn't hurt so much.
    return wrapper->parse(parser, input);
  }

private:
  struct Wrapper {
    virtual Maybe<Output> parse(const void* parser, Input& input) const = 0;
  };
  template <typename ParserImpl>
  struct WrapperImpl: public Wrapper {
    Maybe<Output> parse(const void* parser, Input& input) const override {
      return (*reinterpret_cast<const ParserImpl*>(parser))(input);
    }
  };
  template <typename ParserImpl>
  struct WrapperImplInstance {
#if _MSC_VER && !__clang__
    // TODO(msvc): MSVC currently fails to initialize vtable pointers for constexpr values so
    //   we have to make this just const instead.
    static const WrapperImpl<ParserImpl> instance;
#else
    static constexpr WrapperImpl<ParserImpl> instance = WrapperImpl<ParserImpl>();
#endif
  };

  const void* parser;
  const Wrapper* wrapper;
};

template <typename Input, typename Output>
template <typename ParserImpl>
#if _MSC_VER && !__clang__
const typename ParserRef<Input, Output>::template WrapperImpl<ParserImpl>
ParserRef<Input, Output>::WrapperImplInstance<ParserImpl>::instance = WrapperImpl<ParserImpl>();
#else
constexpr typename ParserRef<Input, Output>::template WrapperImpl<ParserImpl>
ParserRef<Input, Output>::WrapperImplInstance<ParserImpl>::instance;
#endif

template <typename Input, typename ParserImpl>
constexpr ParserRef<Input, OutputType<ParserImpl, Input>> ref(ParserImpl& impl) {
  // Constructs a ParserRef.  You must specify the input type explicitly, e.g.
  // `ref<MyInput>(myParser)`.

  return ParserRef<Input, OutputType<ParserImpl, Input>>(impl);
}

// -------------------------------------------------------------------
// any
// Output = one token

class Any_ {
public:
  template <typename Input>
  Maybe<Decay<decltype(instance<Input>().consume())>> operator()(Input& input) const {
    if (input.atEnd()) {
      return nullptr;
    } else {
      return input.consume();
    }
  }
};

constexpr Any_ any = Any_();
// A parser which matches any token and simply returns it.

// -------------------------------------------------------------------
// exactly()
// Output = Tuple<>

template <typename T>
class Exactly_ {
public:
  explicit constexpr Exactly_(T&& expected): expected(expected) {}

  template <typename Input>
  Maybe<Tuple<>> operator()(Input& input) const {
    if (input.atEnd() || input.current() != expected) {
      return nullptr;
    } else {
      input.next();
      return Tuple<>();
    }
  }

private:
  T expected;
};

template <typename T>
constexpr Exactly_<T> exactly(T&& expected) {
  // Constructs a parser which succeeds when the input is exactly the token specified.  The
  // result is always the empty tuple.

  return Exactly_<T>(kj::fwd<T>(expected));
}

// -------------------------------------------------------------------
// exactlyConst()
// Output = Tuple<>

template <typename T, T expected>
class ExactlyConst_ {
public:
  explicit constexpr ExactlyConst_() {}

  template <typename Input>
  Maybe<Tuple<>> operator()(Input& input) const {
    if (input.atEnd() || input.current() != expected) {
      return nullptr;
    } else {
      input.next();
      return Tuple<>();
    }
  }
};

template <typename T, T expected>
constexpr ExactlyConst_<T, expected> exactlyConst() {
  // Constructs a parser which succeeds when the input is exactly the token specified.  The
  // result is always the empty tuple.  This parser is templated on the token value which may cause
  // it to perform better -- or worse.  Be sure to measure.

  return ExactlyConst_<T, expected>();
}

// -------------------------------------------------------------------
// constResult()

template <typename SubParser, typename Result>
class ConstResult_ {
public:
  explicit constexpr ConstResult_(SubParser&& subParser, Result&& result)
      : subParser(kj::fwd<SubParser>(subParser)), result(kj::fwd<Result>(result)) {}

  template <typename Input>
  Maybe<Result> operator()(Input& input) const {
    if (subParser(input) == nullptr) {
      return nullptr;
    } else {
      return result;
    }
  }

private:
  SubParser subParser;
  Result result;
};

template <typename SubParser, typename Result>
constexpr ConstResult_<SubParser, Result> constResult(SubParser&& subParser, Result&& result) {
  // Constructs a parser which returns exactly `result` if `subParser` is successful.
  return ConstResult_<SubParser, Result>(kj::fwd<SubParser>(subParser), kj::fwd<Result>(result));
}

template <typename SubParser>
constexpr ConstResult_<SubParser, Tuple<>> discard(SubParser&& subParser) {
  // Constructs a parser which wraps `subParser` but discards the result.
  return constResult(kj::fwd<SubParser>(subParser), Tuple<>());
}

// -------------------------------------------------------------------
// sequence()
// Output = Flattened Tuple of outputs of sub-parsers.

template <typename... SubParsers> class Sequence_;

template <typename FirstSubParser, typename... SubParsers>
class Sequence_<FirstSubParser, SubParsers...> {
public:
  template <typename T, typename... U>
  explicit constexpr Sequence_(T&& firstSubParser, U&&... rest)
      : first(kj::fwd<T>(firstSubParser)), rest(kj::fwd<U>(rest)...) {}

  // TODO(msvc): The trailing return types on `operator()` and `parseNext()` expose at least two
  //   bugs in MSVC:
  //
  //     1. An ICE.
  //     2. 'error C2672: 'operator __surrogate_func': no matching overloaded function found)',
  //        which crops up in numerous places when trying to build the capnp command line tools.
  //
  //   The only workaround I found for both bugs is to omit the trailing return types and instead
  //   rely on C++14's return type deduction.

  template <typename Input>
  auto operator()(Input& input) const
#if !_MSC_VER || __clang__
      -> Maybe<decltype(tuple(
          instance<OutputType<FirstSubParser, Input>>(),
          instance<OutputType<SubParsers, Input>>()...))>
#endif
  {
    return parseNext(input);
  }

  template <typename Input, typename... InitialParams>
  auto parseNext(Input& input, InitialParams&&... initialParams) const
#if !_MSC_VER || __clang__
      -> Maybe<decltype(tuple(
          kj::fwd<InitialParams>(initialParams)...,
          instance<OutputType<FirstSubParser, Input>>(),
          instance<OutputType<SubParsers, Input>>()...))>
#endif
  {
    KJ_IF_MAYBE(firstResult, first(input)) {
      return rest.parseNext(input, kj::fwd<InitialParams>(initialParams)...,
                            kj::mv(*firstResult));
    } else {
      // TODO(msvc): MSVC depends on return type deduction to compile this function, so we need to
      //   help it deduce the right type on this code path.
      return Maybe<decltype(tuple(
          kj::fwd<InitialParams>(initialParams)...,
          instance<OutputType<FirstSubParser, Input>>(),
          instance<OutputType<SubParsers, Input>>()...))>{nullptr};
    }
  }

private:
  FirstSubParser first;
  Sequence_<SubParsers...> rest;
};

template <>
class Sequence_<> {
public:
  template <typename Input>
  Maybe<Tuple<>> operator()(Input& input) const {
    return parseNext(input);
  }

  template <typename Input, typename... Params>
  auto parseNext(Input& input, Params&&... params) const ->
      Maybe<decltype(tuple(kj::fwd<Params>(params)...))> {
    return tuple(kj::fwd<Params>(params)...);
  }
};

template <typename... SubParsers>
constexpr Sequence_<SubParsers...> sequence(SubParsers&&... subParsers) {
  // Constructs a parser that executes each of the parameter parsers in sequence and returns a
  // tuple of their results.

  return Sequence_<SubParsers...>(kj::fwd<SubParsers>(subParsers)...);
}

// -------------------------------------------------------------------
// many()
// Output = Array of output of sub-parser, or just a uint count if the sub-parser returns Tuple<>.

template <typename SubParser, bool atLeastOne>
class Many_ {
  template <typename Input, typename Output = OutputType<SubParser, Input>>
  struct Impl;
public:
  explicit constexpr Many_(SubParser&& subParser)
      : subParser(kj::fwd<SubParser>(subParser)) {}

  template <typename Input>
  auto operator()(Input& input) const
      -> decltype(Impl<Input>::apply(instance<const SubParser&>(), input));

private:
  SubParser subParser;
};

template <typename SubParser, bool atLeastOne>
template <typename Input, typename Output>
struct Many_<SubParser, atLeastOne>::Impl {
  static Maybe<Array<Output>> apply(const SubParser& subParser, Input& input) {
    typedef Vector<OutputType<SubParser, Input>> Results;
    Results results;

    while (!input.atEnd()) {
      Input subInput(input);

      KJ_IF_MAYBE(subResult, subParser(subInput)) {
        subInput.advanceParent();
        results.add(kj::mv(*subResult));
      } else {
        break;
      }
    }

    if (atLeastOne && results.empty()) {
      return nullptr;
    }

    return results.releaseAsArray();
  }
};

template <typename SubParser, bool atLeastOne>
template <typename Input>
struct Many_<SubParser, atLeastOne>::Impl<Input, Tuple<>> {
  // If the sub-parser output is Tuple<>, just return a count.

  static Maybe<uint> apply(const SubParser& subParser, Input& input) {
    uint count = 0;

    while (!input.atEnd()) {
      Input subInput(input);

      KJ_IF_MAYBE(subResult, subParser(subInput)) {
        subInput.advanceParent();
        ++count;
      } else {
        break;
      }
    }

    if (atLeastOne && count == 0) {
      return nullptr;
    }

    return count;
  }
};

template <typename SubParser, bool atLeastOne>
template <typename Input>
auto Many_<SubParser, atLeastOne>::operator()(Input& input) const
    -> decltype(Impl<Input>::apply(instance<const SubParser&>(), input)) {
  return Impl<Input, OutputType<SubParser, Input>>::apply(subParser, input);
}

template <typename SubParser>
constexpr Many_<SubParser, false> many(SubParser&& subParser) {
  // Constructs a parser that repeatedly executes the given parser until it fails, returning an
  // Array of the results (or a uint count if `subParser` returns an empty tuple).
  return Many_<SubParser, false>(kj::fwd<SubParser>(subParser));
}

template <typename SubParser>
constexpr Many_<SubParser, true> oneOrMore(SubParser&& subParser) {
  // Like `many()` but the parser must parse at least one item to be successful.
  return Many_<SubParser, true>(kj::fwd<SubParser>(subParser));
}

// -------------------------------------------------------------------
// times()
// Output = Array of output of sub-parser, or Tuple<> if sub-parser returns Tuple<>.

template <typename SubParser>
class Times_ {
  template <typename Input, typename Output = OutputType<SubParser, Input>>
  struct Impl;
public:
  explicit constexpr Times_(SubParser&& subParser, uint count)
      : subParser(kj::fwd<SubParser>(subParser)), count(count) {}

  template <typename Input>
  auto operator()(Input& input) const
      -> decltype(Impl<Input>::apply(instance<const SubParser&>(), instance<uint>(), input));

private:
  SubParser subParser;
  uint count;
};

template <typename SubParser>
template <typename Input, typename Output>
struct Times_<SubParser>::Impl {
  static Maybe<Array<Output>> apply(const SubParser& subParser, uint count, Input& input) {
    auto results = heapArrayBuilder<OutputType<SubParser, Input>>(count);

    while (results.size() < count) {
      if (input.atEnd()) {
        return nullptr;
      } else KJ_IF_MAYBE(subResult, subParser(input)) {
        results.add(kj::mv(*subResult));
      } else {
        return nullptr;
      }
    }

    return results.finish();
  }
};

template <typename SubParser>
template <typename Input>
struct Times_<SubParser>::Impl<Input, Tuple<>> {
  // If the sub-parser output is Tuple<>, just return a count.

  static Maybe<Tuple<>> apply(const SubParser& subParser, uint count, Input& input) {
    uint actualCount = 0;

    while (actualCount < count) {
      if (input.atEnd()) {
        return nullptr;
      } else KJ_IF_MAYBE(subResult, subParser(input)) {
        ++actualCount;
      } else {
        return nullptr;
      }
    }

    return tuple();
  }
};

template <typename SubParser>
template <typename Input>
auto Times_<SubParser>::operator()(Input& input) const
    -> decltype(Impl<Input>::apply(instance<const SubParser&>(), instance<uint>(), input)) {
  return Impl<Input, OutputType<SubParser, Input>>::apply(subParser, count, input);
}

template <typename SubParser>
constexpr Times_<SubParser> times(SubParser&& subParser, uint count) {
  // Constructs a parser that repeats the subParser exactly `count` times.
  return Times_<SubParser>(kj::fwd<SubParser>(subParser), count);
}

// -------------------------------------------------------------------
// optional()
// Output = Maybe<output of sub-parser>

template <typename SubParser>
class Optional_ {
public:
  explicit constexpr Optional_(SubParser&& subParser)
      : subParser(kj::fwd<SubParser>(subParser)) {}

  template <typename Input>
  Maybe<Maybe<OutputType<SubParser, Input>>> operator()(Input& input) const {
    typedef Maybe<OutputType<SubParser, Input>> Result;

    Input subInput(input);
    KJ_IF_MAYBE(subResult, subParser(subInput)) {
      subInput.advanceParent();
      return Result(kj::mv(*subResult));
    } else {
      return Result(nullptr);
    }
  }

private:
  SubParser subParser;
};

template <typename SubParser>
constexpr Optional_<SubParser> optional(SubParser&& subParser) {
  // Constructs a parser that accepts zero or one of the given sub-parser, returning a Maybe
  // of the sub-parser's result.
  return Optional_<SubParser>(kj::fwd<SubParser>(subParser));
}

// -------------------------------------------------------------------
// oneOf()
// All SubParsers must have same output type, which becomes the output type of the
// OneOfParser.

template <typename... SubParsers>
class OneOf_;

template <typename FirstSubParser, typename... SubParsers>
class OneOf_<FirstSubParser, SubParsers...> {
public:
  explicit constexpr OneOf_(FirstSubParser&& firstSubParser, SubParsers&&... rest)
      : first(kj::fwd<FirstSubParser>(firstSubParser)), rest(kj::fwd<SubParsers>(rest)...) {}

  template <typename Input>
  Maybe<OutputType<FirstSubParser, Input>> operator()(Input& input) const {
    {
      Input subInput(input);
      Maybe<OutputType<FirstSubParser, Input>> firstResult = first(subInput);

      if (firstResult != nullptr) {
        subInput.advanceParent();
        return kj::mv(firstResult);
      }
    }

    // Hoping for some tail recursion here...
    return rest(input);
  }

private:
  FirstSubParser first;
  OneOf_<SubParsers...> rest;
};

template <>
class OneOf_<> {
public:
  template <typename Input>
  decltype(nullptr) operator()(Input& input) const {
    return nullptr;
  }
};

template <typename... SubParsers>
constexpr OneOf_<SubParsers...> oneOf(SubParsers&&... parsers) {
  // Constructs a parser that accepts one of a set of options.  The parser behaves as the first
  // sub-parser in the list which returns successfully.  All of the sub-parsers must return the
  // same type.
  return OneOf_<SubParsers...>(kj::fwd<SubParsers>(parsers)...);
}

// -------------------------------------------------------------------
// transform()
// Output = Result of applying transform functor to input value.  If input is a tuple, it is
// unpacked to form the transformation parameters.

template <typename Position>
struct Span {
public:
  inline const Position& begin() const { return begin_; }
  inline const Position& end() const { return end_; }

  Span() = default;
  inline constexpr Span(Position&& begin, Position&& end): begin_(mv(begin)), end_(mv(end)) {}

private:
  Position begin_;
  Position end_;
};

template <typename Position>
constexpr Span<Decay<Position>> span(Position&& start, Position&& end) {
  return Span<Decay<Position>>(kj::fwd<Position>(start), kj::fwd<Position>(end));
}

template <typename SubParser, typename TransformFunc>
class Transform_ {
public:
  explicit constexpr Transform_(SubParser&& subParser, TransformFunc&& transform)
      : subParser(kj::fwd<SubParser>(subParser)), transform(kj::fwd<TransformFunc>(transform)) {}

  template <typename Input>
  Maybe<decltype(kj::apply(instance<TransformFunc&>(),
                           instance<OutputType<SubParser, Input>&&>()))>
      operator()(Input& input) const {
    KJ_IF_MAYBE(subResult, subParser(input)) {
      return kj::apply(transform, kj::mv(*subResult));
    } else {
      return nullptr;
    }
  }

private:
  SubParser subParser;
  TransformFunc transform;
};

template <typename SubParser, typename TransformFunc>
class TransformOrReject_ {
public:
  explicit constexpr TransformOrReject_(SubParser&& subParser, TransformFunc&& transform)
      : subParser(kj::fwd<SubParser>(subParser)), transform(kj::fwd<TransformFunc>(transform)) {}

  template <typename Input>
  decltype(kj::apply(instance<TransformFunc&>(), instance<OutputType<SubParser, Input>&&>()))
      operator()(Input& input) const {
    KJ_IF_MAYBE(subResult, subParser(input)) {
      return kj::apply(transform, kj::mv(*subResult));
    } else {
      return nullptr;
    }
  }

private:
  SubParser subParser;
  TransformFunc transform;
};

template <typename SubParser, typename TransformFunc>
class TransformWithLocation_ {
public:
  explicit constexpr TransformWithLocation_(SubParser&& subParser, TransformFunc&& transform)
      : subParser(kj::fwd<SubParser>(subParser)), transform(kj::fwd<TransformFunc>(transform)) {}

  template <typename Input>
  Maybe<decltype(kj::apply(instance<TransformFunc&>(),
                           instance<Span<Decay<decltype(instance<Input&>().getPosition())>>>(),
                           instance<OutputType<SubParser, Input>&&>()))>
      operator()(Input& input) const {
    auto start = input.getPosition();
    KJ_IF_MAYBE(subResult, subParser(input)) {
      return kj::apply(transform, Span<decltype(start)>(kj::mv(start), input.getPosition()),
                       kj::mv(*subResult));
    } else {
      return nullptr;
    }
  }

private:
  SubParser subParser;
  TransformFunc transform;
};

template <typename SubParser, typename TransformFunc>
constexpr Transform_<SubParser, TransformFunc> transform(
    SubParser&& subParser, TransformFunc&& functor) {
  // Constructs a parser which executes some other parser and then transforms the result by invoking
  // `functor` on it.  Typically `functor` is a lambda.  It is invoked using `kj::apply`,
  // meaning tuples will be unpacked as arguments.
  return Transform_<SubParser, TransformFunc>(
      kj::fwd<SubParser>(subParser), kj::fwd<TransformFunc>(functor));
}

template <typename SubParser, typename TransformFunc>
constexpr TransformOrReject_<SubParser, TransformFunc> transformOrReject(
    SubParser&& subParser, TransformFunc&& functor) {
  // Like `transform()` except that `functor` returns a `Maybe`.  If it returns null, parsing fails,
  // otherwise the parser's result is the content of the `Maybe`.
  return TransformOrReject_<SubParser, TransformFunc>(
      kj::fwd<SubParser>(subParser), kj::fwd<TransformFunc>(functor));
}

template <typename SubParser, typename TransformFunc>
constexpr TransformWithLocation_<SubParser, TransformFunc> transformWithLocation(
    SubParser&& subParser, TransformFunc&& functor) {
  // Like `transform` except that `functor` also takes a `Span` as its first parameter specifying
  // the location of the parsed content.  The span's position type is whatever the parser input's
  // getPosition() returns.
  return TransformWithLocation_<SubParser, TransformFunc>(
      kj::fwd<SubParser>(subParser), kj::fwd<TransformFunc>(functor));
}

// -------------------------------------------------------------------
// notLookingAt()
// Fails if the given parser succeeds at the current location.

template <typename SubParser>
class NotLookingAt_ {
public:
  explicit constexpr NotLookingAt_(SubParser&& subParser)
      : subParser(kj::fwd<SubParser>(subParser)) {}

  template <typename Input>
  Maybe<Tuple<>> operator()(Input& input) const {
    Input subInput(input);
    subInput.forgetParent();
    if (subParser(subInput) == nullptr) {
      return Tuple<>();
    } else {
      return nullptr;
    }
  }

private:
  SubParser subParser;
};

template <typename SubParser>
constexpr NotLookingAt_<SubParser> notLookingAt(SubParser&& subParser) {
  // Constructs a parser which fails at any position where the given parser succeeds.  Otherwise,
  // it succeeds without consuming any input and returns an empty tuple.
  return NotLookingAt_<SubParser>(kj::fwd<SubParser>(subParser));
}

// -------------------------------------------------------------------
// endOfInput()
// Output = Tuple<>, only succeeds if at end-of-input

class EndOfInput_ {
public:
  template <typename Input>
  Maybe<Tuple<>> operator()(Input& input) const {
    if (input.atEnd()) {
      return Tuple<>();
    } else {
      return nullptr;
    }
  }
};

constexpr EndOfInput_ endOfInput = EndOfInput_();
// A parser that succeeds only if it is called with no input.

}  // namespace parse
}  // namespace kj

KJ_END_HEADER
