// 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.

#pragma once

#include "layout.h"
#include "pointer-helpers.h"
#include "orphan.h"
#include "list.h"
#include <kj/windows-sanity.h>  // work-around macro conflict with `VOID`
#include <kj/hash.h>

CAPNP_BEGIN_HEADER

namespace capnp {

class StructSchema;
class ListSchema;
class InterfaceSchema;
class Orphanage;
class ClientHook;
class PipelineHook;
struct PipelineOp;
struct AnyPointer;

struct AnyList {
  AnyList() = delete;

  class Reader;
  class Builder;
};

struct AnyStruct {
  AnyStruct() = delete;

  class Reader;
  class Builder;
  class Pipeline;
};

template<>
struct List<AnyStruct, Kind::OTHER> {
  List() = delete;

  class Reader;
  class Builder;
};

namespace _ {  // private
template <> struct Kind_<AnyPointer> { static constexpr Kind kind = Kind::OTHER; };
template <> struct Kind_<AnyStruct> { static constexpr Kind kind = Kind::OTHER; };
template <> struct Kind_<AnyList> { static constexpr Kind kind = Kind::OTHER; };
}  // namespace _ (private)

// =======================================================================================
// AnyPointer!

enum class Equality {
  NOT_EQUAL,
  EQUAL,
  UNKNOWN_CONTAINS_CAPS
};

kj::StringPtr KJ_STRINGIFY(Equality res);

struct AnyPointer {
  // Reader/Builder for the `AnyPointer` field type, i.e. a pointer that can point to an arbitrary
  // object.

  AnyPointer() = delete;

  class Reader {
  public:
    typedef AnyPointer Reads;

    Reader() = default;
    inline Reader(_::PointerReader reader): reader(reader) {}

    inline MessageSize targetSize() const;
    // Get the total size of the target object and all its children.

    inline PointerType getPointerType() const;

    inline bool isNull() const { return getPointerType() == PointerType::NULL_; }
    inline bool isStruct() const { return getPointerType() == PointerType::STRUCT; }
    inline bool isList() const { return getPointerType() == PointerType::LIST; }
    inline bool isCapability() const { return getPointerType() == PointerType::CAPABILITY; }

    Equality equals(AnyPointer::Reader right) const;
    bool operator==(AnyPointer::Reader right) const;
    inline bool operator!=(AnyPointer::Reader right) const {
      return !(*this == right);
    }

    template <typename T>
    inline ReaderFor<T> getAs() const;
    // Valid for T = any generated struct type, interface type, List<U>, Text, or Data.

    template <typename T>
    inline ReaderFor<T> getAs(StructSchema schema) const;
    // Only valid for T = DynamicStruct.  Requires `#include <capnp/dynamic.h>`.

    template <typename T>
    inline ReaderFor<T> getAs(ListSchema schema) const;
    // Only valid for T = DynamicList.  Requires `#include <capnp/dynamic.h>`.

    template <typename T>
    inline ReaderFor<T> getAs(InterfaceSchema schema) const;
    // Only valid for T = DynamicCapability.  Requires `#include <capnp/dynamic.h>`.

#if !CAPNP_LITE
    kj::Own<ClientHook> getPipelinedCap(kj::ArrayPtr<const PipelineOp> ops) const;
    // Used by RPC system to implement pipelining.  Applications generally shouldn't use this
    // directly.
#endif  // !CAPNP_LITE

  private:
    _::PointerReader reader;
    friend struct AnyPointer;
    friend class Orphanage;
    friend class CapReaderContext;
    friend struct _::PointerHelpers<AnyPointer>;
  };

  class Builder {
  public:
    typedef AnyPointer Builds;

    Builder() = delete;
    inline Builder(decltype(nullptr)) {}
    inline Builder(_::PointerBuilder builder): builder(builder) {}

    inline MessageSize targetSize() const;
    // Get the total size of the target object and all its children.

    inline PointerType getPointerType();

    inline bool isNull() { return getPointerType() == PointerType::NULL_; }
    inline bool isStruct() { return getPointerType() == PointerType::STRUCT; }
    inline bool isList() { return getPointerType() == PointerType::LIST; }
    inline bool isCapability() { return getPointerType() == PointerType::CAPABILITY; }

    inline Equality equals(AnyPointer::Reader right) const {
      return asReader().equals(right);
    }
    inline bool operator==(AnyPointer::Reader right) const {
      return asReader() == right;
    }
    inline bool operator!=(AnyPointer::Reader right) const {
      return !(*this == right);
    }

    inline void clear();
    // Set to null.

    template <typename T>
    inline BuilderFor<T> getAs();
    // Valid for T = any generated struct type, List<U>, Text, or Data.

    template <typename T>
    inline BuilderFor<T> getAs(StructSchema schema);
    // Only valid for T = DynamicStruct.  Requires `#include <capnp/dynamic.h>`.

    template <typename T>
    inline BuilderFor<T> getAs(ListSchema schema);
    // Only valid for T = DynamicList.  Requires `#include <capnp/dynamic.h>`.

    template <typename T>
    inline BuilderFor<T> getAs(InterfaceSchema schema);
    // Only valid for T = DynamicCapability.  Requires `#include <capnp/dynamic.h>`.

    template <typename T>
    inline BuilderFor<T> initAs();
    // Valid for T = any generated struct type.

    template <typename T>
    inline BuilderFor<T> initAs(uint elementCount);
    // Valid for T = List<U>, Text, or Data.

    template <typename T>
    inline BuilderFor<T> initAs(StructSchema schema);
    // Only valid for T = DynamicStruct.  Requires `#include <capnp/dynamic.h>`.

    template <typename T>
    inline BuilderFor<T> initAs(ListSchema schema, uint elementCount);
    // Only valid for T = DynamicList.  Requires `#include <capnp/dynamic.h>`.

    inline AnyList::Builder initAsAnyList(ElementSize elementSize, uint elementCount);
    // Note: Does not accept INLINE_COMPOSITE for elementSize.

    inline List<AnyStruct>::Builder initAsListOfAnyStruct(
        uint16_t dataWordCount, uint16_t pointerCount, uint elementCount);

    inline AnyStruct::Builder initAsAnyStruct(uint16_t dataWordCount, uint16_t pointerCount);

    template <typename T>
    inline void setAs(ReaderFor<T> value);
    // Valid for ReaderType = T::Reader for T = any generated struct type, List<U>, Text, Data,
    // DynamicStruct, or DynamicList (the dynamic types require `#include <capnp/dynamic.h>`).

    template <typename T>
    inline void setAs(std::initializer_list<ReaderFor<ListElementType<T>>> list);
    // Valid for T = List<?>.

    template <typename T>
    inline void setCanonicalAs(ReaderFor<T> value);

    inline void set(Reader value) { builder.copyFrom(value.reader); }
    // Set to a copy of another AnyPointer.

    inline void setCanonical(Reader value) { builder.copyFrom(value.reader, true); }

    template <typename T>
    inline void adopt(Orphan<T>&& orphan);
    // Valid for T = any generated struct type, List<U>, Text, Data, DynamicList, DynamicStruct,
    // or DynamicValue (the dynamic types require `#include <capnp/dynamic.h>`).

    template <typename T>
    inline Orphan<T> disownAs();
    // Valid for T = any generated struct type, List<U>, Text, Data.

    template <typename T>
    inline Orphan<T> disownAs(StructSchema schema);
    // Only valid for T = DynamicStruct.  Requires `#include <capnp/dynamic.h>`.

    template <typename T>
    inline Orphan<T> disownAs(ListSchema schema);
    // Only valid for T = DynamicList.  Requires `#include <capnp/dynamic.h>`.

    template <typename T>
    inline Orphan<T> disownAs(InterfaceSchema schema);
    // Only valid for T = DynamicCapability.  Requires `#include <capnp/dynamic.h>`.

    inline Orphan<AnyPointer> disown();
    // Disown without a type.

    inline Reader asReader() const { return Reader(builder.asReader()); }
    inline operator Reader() const { return Reader(builder.asReader()); }

  private:
    _::PointerBuilder builder;
    friend class Orphanage;
    friend class CapBuilderContext;
    friend struct _::PointerHelpers<AnyPointer>;
  };

#if !CAPNP_LITE
  class Pipeline {
  public:
    typedef AnyPointer Pipelines;

    inline Pipeline(decltype(nullptr)) {}
    inline explicit Pipeline(kj::Own<PipelineHook>&& hook): hook(kj::mv(hook)) {}

    Pipeline noop();
    // Just make a copy.

    Pipeline getPointerField(uint16_t pointerIndex);
    // Deprecated. In the future, we should use .asAnyStruct.getPointerField.

    inline AnyStruct::Pipeline asAnyStruct();

    kj::Own<ClientHook> asCap();
    // Expect that the result is a capability and construct a pipelined version of it now.

    inline kj::Own<PipelineHook> releasePipelineHook() { return kj::mv(hook); }
    // For use by RPC implementations.

    template <typename T, typename = kj::EnableIf<CAPNP_KIND(FromClient<T>) == Kind::INTERFACE>>
    inline operator T() { return T(asCap()); }

  private:
    kj::Own<PipelineHook> hook;
    kj::Array<PipelineOp> ops;

    inline Pipeline(kj::Own<PipelineHook>&& hook, kj::Array<PipelineOp>&& ops)
        : hook(kj::mv(hook)), ops(kj::mv(ops)) {}

    friend class LocalClient;
    friend class PipelineHook;
    friend class AnyStruct::Pipeline;
  };
#endif  // !CAPNP_LITE
};

template <>
class Orphan<AnyPointer> {
  // An orphaned object of unknown type.

public:
  Orphan() = default;
  KJ_DISALLOW_COPY(Orphan);
  Orphan(Orphan&&) = default;
  inline Orphan(_::OrphanBuilder&& builder)
      : builder(kj::mv(builder)) {}

  Orphan& operator=(Orphan&&) = default;

  template <typename T>
  inline Orphan(Orphan<T>&& other): builder(kj::mv(other.builder)) {}
  template <typename T>
  inline Orphan& operator=(Orphan<T>&& other) { builder = kj::mv(other.builder); return *this; }
  // Cast from typed orphan.

  // It's not possible to get an AnyPointer::{Reader,Builder} directly since there is no
  // underlying pointer (the pointer would normally live in the parent, but this object is
  // orphaned).  It is possible, however, to request typed readers/builders.

  template <typename T>
  inline BuilderFor<T> getAs();
  template <typename T>
  inline BuilderFor<T> getAs(StructSchema schema);
  template <typename T>
  inline BuilderFor<T> getAs(ListSchema schema);
  template <typename T>
  inline typename T::Client getAs(InterfaceSchema schema);
  template <typename T>
  inline ReaderFor<T> getAsReader() const;
  template <typename T>
  inline ReaderFor<T> getAsReader(StructSchema schema) const;
  template <typename T>
  inline ReaderFor<T> getAsReader(ListSchema schema) const;
  template <typename T>
  inline typename T::Client getAsReader(InterfaceSchema schema) const;

  template <typename T>
  inline Orphan<T> releaseAs();
  template <typename T>
  inline Orphan<T> releaseAs(StructSchema schema);
  template <typename T>
  inline Orphan<T> releaseAs(ListSchema schema);
  template <typename T>
  inline Orphan<T> releaseAs(InterfaceSchema schema);
  // Down-cast the orphan to a specific type.

  inline bool operator==(decltype(nullptr)) const { return builder == nullptr; }
  inline bool operator!=(decltype(nullptr)) const { return builder != nullptr; }

private:
  _::OrphanBuilder builder;

  template <typename, Kind>
  friend struct _::PointerHelpers;
  friend class Orphanage;
  template <typename U>
  friend class Orphan;
  friend class AnyPointer::Builder;
};

template <Kind k> struct AnyTypeFor_;
template <> struct AnyTypeFor_<Kind::STRUCT> { typedef AnyStruct Type; };
template <> struct AnyTypeFor_<Kind::LIST> { typedef AnyList Type; };

template <typename T>
using AnyTypeFor = typename AnyTypeFor_<CAPNP_KIND(T)>::Type;

template <typename T>
inline ReaderFor<AnyTypeFor<FromReader<T>>> toAny(T&& value) {
  return ReaderFor<AnyTypeFor<FromReader<T>>>(
      _::PointerHelpers<FromReader<T>>::getInternalReader(value));
}
template <typename T>
inline BuilderFor<AnyTypeFor<FromBuilder<T>>> toAny(T&& value) {
  return BuilderFor<AnyTypeFor<FromBuilder<T>>>(
      _::PointerHelpers<FromBuilder<T>>::getInternalBuilder(kj::mv(value)));
}

template <>
struct List<AnyPointer, Kind::OTHER> {
  // Note: This cannot be used for a list of structs, since such lists are not encoded as pointer
  //   lists! Use List<AnyStruct>.

  List() = delete;

  class Reader {
  public:
    typedef List<AnyPointer> Reads;

    inline Reader(): reader(ElementSize::POINTER) {}
    inline explicit Reader(_::ListReader reader): reader(reader) {}

    inline uint size() const { return unbound(reader.size() / ELEMENTS); }
    inline AnyPointer::Reader operator[](uint index) const {
      KJ_IREQUIRE(index < size());
      return AnyPointer::Reader(reader.getPointerElement(bounded(index) * ELEMENTS));
    }

    typedef _::IndexingIterator<const Reader, typename AnyPointer::Reader> Iterator;
    inline Iterator begin() const { return Iterator(this, 0); }
    inline Iterator end() const { return Iterator(this, size()); }

    inline MessageSize totalSize() const {
      return reader.totalSize().asPublic();
    }

  private:
    _::ListReader reader;
    template <typename U, Kind K>
    friend struct _::PointerHelpers;
    template <typename U, Kind K>
    friend struct List;
    friend class Orphanage;
    template <typename U, Kind K>
    friend struct ToDynamic_;
  };

  class Builder {
  public:
    typedef List<AnyPointer> Builds;

    Builder() = delete;
    inline Builder(decltype(nullptr)): builder(ElementSize::POINTER) {}
    inline explicit Builder(_::ListBuilder builder): builder(builder) {}

    inline operator Reader() const { return Reader(builder.asReader()); }
    inline Reader asReader() const { return Reader(builder.asReader()); }

    inline uint size() const { return unbound(builder.size() / ELEMENTS); }
    inline AnyPointer::Builder operator[](uint index) {
      KJ_IREQUIRE(index < size());
      return AnyPointer::Builder(builder.getPointerElement(bounded(index) * ELEMENTS));
    }

    typedef _::IndexingIterator<Builder, typename AnyPointer::Builder> Iterator;
    inline Iterator begin() { return Iterator(this, 0); }
    inline Iterator end() { return Iterator(this, size()); }

  private:
    _::ListBuilder builder;
    template <typename, Kind>
    friend struct _::PointerHelpers;
    friend class Orphanage;
    template <typename, Kind>
    friend struct ToDynamic_;
  };
};

class AnyStruct::Reader {
public:
  typedef AnyStruct Reads;

  Reader() = default;
  inline Reader(_::StructReader reader): _reader(reader) {}

  template <typename T, typename = kj::EnableIf<CAPNP_KIND(FromReader<T>) == Kind::STRUCT>>
  inline Reader(T&& value)
      : _reader(_::PointerHelpers<FromReader<T>>::getInternalReader(kj::fwd<T>(value))) {}

  inline MessageSize totalSize() const { return _reader.totalSize().asPublic(); }

  kj::ArrayPtr<const byte> getDataSection() const {
    return _reader.getDataSectionAsBlob();
  }
  List<AnyPointer>::Reader getPointerSection() const {
    return List<AnyPointer>::Reader(_reader.getPointerSectionAsList());
  }

  kj::Array<word> canonicalize() {
    return _reader.canonicalize();
  }

  Equality equals(AnyStruct::Reader right) const;
  bool operator==(AnyStruct::Reader right) const;
  inline bool operator!=(AnyStruct::Reader right) const {
    return !(*this == right);
  }

  template <typename T>
  ReaderFor<T> as() const {
    // T must be a struct type.
    return typename T::Reader(_reader);
  }

  template <typename T>
  ReaderFor<T> as(StructSchema schema) const;
  // T must be DynamicStruct. Defined in dynamic.h.

private:
  _::StructReader _reader;

  template <typename, Kind>
  friend struct _::PointerHelpers;
  friend class Orphanage;
};

class AnyStruct::Builder {
public:
  typedef AnyStruct Builds;

  inline Builder(decltype(nullptr)) {}
  inline Builder(_::StructBuilder builder): _builder(builder) {}

#if !_MSC_VER || defined(__clang__) // TODO(msvc): MSVC ICEs on this. Try restoring when compiler improves.
  template <typename T, typename = kj::EnableIf<CAPNP_KIND(FromBuilder<T>) == Kind::STRUCT>>
  inline Builder(T&& value)
      : _builder(_::PointerHelpers<FromBuilder<T>>::getInternalBuilder(kj::fwd<T>(value))) {}
#endif

  inline kj::ArrayPtr<byte> getDataSection() {
    return _builder.getDataSectionAsBlob();
  }
  List<AnyPointer>::Builder getPointerSection() {
    return List<AnyPointer>::Builder(_builder.getPointerSectionAsList());
  }

  inline Equality equals(AnyStruct::Reader right) const {
    return asReader().equals(right);
  }
  inline bool operator==(AnyStruct::Reader right) const {
    return asReader() == right;
  }
  inline bool operator!=(AnyStruct::Reader right) const {
    return !(*this == right);
  }

  inline operator Reader() const { return Reader(_builder.asReader()); }
  inline Reader asReader() const { return Reader(_builder.asReader()); }

  template <typename T>
  BuilderFor<T> as() {
    // T must be a struct type.
    return typename T::Builder(_builder);
  }

  template <typename T>
  BuilderFor<T> as(StructSchema schema);
  // T must be DynamicStruct. Defined in dynamic.h.

private:
  _::StructBuilder _builder;
  friend class Orphanage;
  friend class CapBuilderContext;
};

#if !CAPNP_LITE
class AnyStruct::Pipeline {
public:
  inline Pipeline(decltype(nullptr)): typeless(nullptr) {}
  inline explicit Pipeline(AnyPointer::Pipeline&& typeless)
      : typeless(kj::mv(typeless)) {}

  inline AnyPointer::Pipeline getPointerField(uint16_t pointerIndex) {
    // Return a new Promise representing a sub-object of the result.  `pointerIndex` is the index
    // of the sub-object within the pointer section of the result (the result must be a struct).
    //
    // TODO(perf):  On GCC 4.8 / Clang 3.3, use rvalue qualifiers to avoid the need for copies.
    //   Also make `ops` into a Vector to optimize this.
    return typeless.getPointerField(pointerIndex);
  }

private:
  AnyPointer::Pipeline typeless;
};
#endif  // !CAPNP_LITE

class List<AnyStruct, Kind::OTHER>::Reader {
public:
  typedef List<AnyStruct> Reads;

  inline Reader(): reader(ElementSize::INLINE_COMPOSITE) {}
  inline explicit Reader(_::ListReader reader): reader(reader) {}

  inline uint size() const { return unbound(reader.size() / ELEMENTS); }
  inline AnyStruct::Reader operator[](uint index) const {
    KJ_IREQUIRE(index < size());
    return AnyStruct::Reader(reader.getStructElement(bounded(index) * ELEMENTS));
  }

  typedef _::IndexingIterator<const Reader, typename AnyStruct::Reader> Iterator;
  inline Iterator begin() const { return Iterator(this, 0); }
  inline Iterator end() const { return Iterator(this, size()); }

  inline MessageSize totalSize() const {
    return reader.totalSize().asPublic();
  }

private:
  _::ListReader reader;
  template <typename U, Kind K>
  friend struct _::PointerHelpers;
  template <typename U, Kind K>
  friend struct List;
  friend class Orphanage;
  template <typename U, Kind K>
  friend struct ToDynamic_;
};

class List<AnyStruct, Kind::OTHER>::Builder {
public:
  typedef List<AnyStruct> Builds;

  Builder() = delete;
  inline Builder(decltype(nullptr)): builder(ElementSize::INLINE_COMPOSITE) {}
  inline explicit Builder(_::ListBuilder builder): builder(builder) {}

  inline operator Reader() const { return Reader(builder.asReader()); }
  inline Reader asReader() const { return Reader(builder.asReader()); }

  inline uint size() const { return unbound(builder.size() / ELEMENTS); }
  inline AnyStruct::Builder operator[](uint index) {
    KJ_IREQUIRE(index < size());
    return AnyStruct::Builder(builder.getStructElement(bounded(index) * ELEMENTS));
  }

  typedef _::IndexingIterator<Builder, typename AnyStruct::Builder> Iterator;
  inline Iterator begin() { return Iterator(this, 0); }
  inline Iterator end() { return Iterator(this, size()); }

private:
  _::ListBuilder builder;
  template <typename U, Kind K>
  friend struct _::PointerHelpers;
  friend class Orphanage;
  template <typename U, Kind K>
  friend struct ToDynamic_;
};

class AnyList::Reader {
public:
  typedef AnyList Reads;

  inline Reader(): _reader(ElementSize::VOID) {}
  inline Reader(_::ListReader reader): _reader(reader) {}

#if !_MSC_VER || defined(__clang__) // TODO(msvc): MSVC ICEs on this. Try restoring when compiler improves.
  template <typename T, typename = kj::EnableIf<CAPNP_KIND(FromReader<T>) == Kind::LIST>>
  inline Reader(T&& value)
      : _reader(_::PointerHelpers<FromReader<T>>::getInternalReader(kj::fwd<T>(value))) {}
#endif

  inline ElementSize getElementSize() const { return _reader.getElementSize(); }
  inline uint size() const { return unbound(_reader.size() / ELEMENTS); }

  inline kj::ArrayPtr<const byte> getRawBytes() const { return _reader.asRawBytes(); }

  Equality equals(AnyList::Reader right) const;
  bool operator==(AnyList::Reader right) const;
  inline bool operator!=(AnyList::Reader right) const {
    return !(*this == right);
  }

  inline MessageSize totalSize() const {
    return _reader.totalSize().asPublic();
  }

  template <typename T> ReaderFor<T> as() const {
    // T must be List<U>.
    return ReaderFor<T>(_reader);
  }
private:
  _::ListReader _reader;

  template <typename, Kind>
  friend struct _::PointerHelpers;
  friend class Orphanage;
};

class AnyList::Builder {
public:
  typedef AnyList Builds;

  inline Builder(decltype(nullptr)): _builder(ElementSize::VOID) {}
  inline Builder(_::ListBuilder builder): _builder(builder) {}

#if !_MSC_VER || defined(__clang__) // TODO(msvc): MSVC ICEs on this. Try restoring when compiler improves.
  template <typename T, typename = kj::EnableIf<CAPNP_KIND(FromBuilder<T>) == Kind::LIST>>
  inline Builder(T&& value)
      : _builder(_::PointerHelpers<FromBuilder<T>>::getInternalBuilder(kj::fwd<T>(value))) {}
#endif

  inline ElementSize getElementSize() { return _builder.getElementSize(); }
  inline uint size() { return unbound(_builder.size() / ELEMENTS); }

  Equality equals(AnyList::Reader right) const;
  inline bool operator==(AnyList::Reader right) const{
    return asReader() == right;
  }
  inline bool operator!=(AnyList::Reader right) const{
    return !(*this == right);
  }

  template <typename T> BuilderFor<T> as() {
    // T must be List<U>.
    return BuilderFor<T>(_builder);
  }

  inline operator Reader() const { return Reader(_builder.asReader()); }
  inline Reader asReader() const { return Reader(_builder.asReader()); }

private:
  _::ListBuilder _builder;

  friend class Orphanage;
};

// =======================================================================================
// Pipeline helpers
//
// These relate to capabilities, but we don't declare them in capability.h because generated code
// for structs needs to know about these, even in files that contain no interfaces.

#if !CAPNP_LITE

struct PipelineOp {
  // Corresponds to rpc.capnp's PromisedAnswer.Op.

  enum Type {
    NOOP,  // for convenience

    GET_POINTER_FIELD

    // There may be other types in the future...
  };

  Type type;
  union {
    uint16_t pointerIndex;  // for GET_POINTER_FIELD
  };
};

inline uint KJ_HASHCODE(const PipelineOp& op) {
  switch (op.type) {
    case PipelineOp::NOOP: return kj::hashCode(op.type);
    case PipelineOp::GET_POINTER_FIELD: return kj::hashCode(op.type, op.pointerIndex);
  }
  KJ_CLANG_KNOWS_THIS_IS_UNREACHABLE_BUT_GCC_DOESNT
}

inline bool operator==(const PipelineOp& a, const PipelineOp& b) {
  if (a.type != b.type) return false;
  switch (a.type) {
    case PipelineOp::NOOP: return true;
    case PipelineOp::GET_POINTER_FIELD: return a.pointerIndex == b.pointerIndex;
  }
  KJ_CLANG_KNOWS_THIS_IS_UNREACHABLE_BUT_GCC_DOESNT
}

inline bool operator!=(const PipelineOp& a, const PipelineOp& b) {
  return !(a == b);
}

class PipelineHook {
  // Represents a currently-running call, and implements pipelined requests on its result.

public:
  virtual kj::Own<PipelineHook> addRef() = 0;
  // Increment this object's reference count.

  virtual kj::Own<ClientHook> getPipelinedCap(kj::ArrayPtr<const PipelineOp> ops) = 0;
  // Extract a promised Capability from the results.

  virtual kj::Own<ClientHook> getPipelinedCap(kj::Array<PipelineOp>&& ops);
  // Version of getPipelinedCap() passing the array by move.  May avoid a copy in some cases.
  // Default implementation just calls the other version.

  template <typename Pipeline, typename = FromPipeline<Pipeline>>
  static inline kj::Own<PipelineHook> from(Pipeline&& pipeline);

  template <typename Pipeline, typename = FromPipeline<Pipeline>>
  static inline PipelineHook& from(Pipeline& pipeline);

private:
  template <typename T> struct FromImpl;
};

#endif  // !CAPNP_LITE

// =======================================================================================
// Inline implementation details

inline MessageSize AnyPointer::Reader::targetSize() const {
  return reader.targetSize().asPublic();
}

inline PointerType AnyPointer::Reader::getPointerType() const {
  return reader.getPointerType();
}

template <typename T>
inline ReaderFor<T> AnyPointer::Reader::getAs() const {
  return _::PointerHelpers<T>::get(reader);
}

inline MessageSize AnyPointer::Builder::targetSize() const {
  return asReader().targetSize();
}

inline PointerType AnyPointer::Builder::getPointerType() {
  return builder.getPointerType();
}

inline void AnyPointer::Builder::clear() {
  return builder.clear();
}

template <typename T>
inline BuilderFor<T> AnyPointer::Builder::getAs() {
  return _::PointerHelpers<T>::get(builder);
}

template <typename T>
inline BuilderFor<T> AnyPointer::Builder::initAs() {
  return _::PointerHelpers<T>::init(builder);
}

template <typename T>
inline BuilderFor<T> AnyPointer::Builder::initAs(uint elementCount) {
  return _::PointerHelpers<T>::init(builder, elementCount);
}

inline AnyList::Builder AnyPointer::Builder::initAsAnyList(
    ElementSize elementSize, uint elementCount) {
  return AnyList::Builder(builder.initList(elementSize, bounded(elementCount) * ELEMENTS));
}

inline List<AnyStruct>::Builder AnyPointer::Builder::initAsListOfAnyStruct(
    uint16_t dataWordCount, uint16_t pointerCount, uint elementCount) {
  return List<AnyStruct>::Builder(builder.initStructList(bounded(elementCount) * ELEMENTS,
      _::StructSize(bounded(dataWordCount) * WORDS,
                    bounded(pointerCount) * POINTERS)));
}

inline AnyStruct::Builder AnyPointer::Builder::initAsAnyStruct(
    uint16_t dataWordCount, uint16_t pointerCount) {
  return AnyStruct::Builder(builder.initStruct(
      _::StructSize(bounded(dataWordCount) * WORDS,
                    bounded(pointerCount) * POINTERS)));
}

template <typename T>
inline void AnyPointer::Builder::setAs(ReaderFor<T> value) {
  return _::PointerHelpers<T>::set(builder, value);
}

template <typename T>
inline void AnyPointer::Builder::setCanonicalAs(ReaderFor<T> value) {
  return _::PointerHelpers<T>::setCanonical(builder, value);
}

template <typename T>
inline void AnyPointer::Builder::setAs(
    std::initializer_list<ReaderFor<ListElementType<T>>> list) {
  return _::PointerHelpers<T>::set(builder, list);
}

template <typename T>
inline void AnyPointer::Builder::adopt(Orphan<T>&& orphan) {
  _::PointerHelpers<T>::adopt(builder, kj::mv(orphan));
}

template <typename T>
inline Orphan<T> AnyPointer::Builder::disownAs() {
  return _::PointerHelpers<T>::disown(builder);
}

inline Orphan<AnyPointer> AnyPointer::Builder::disown() {
  return Orphan<AnyPointer>(builder.disown());
}

template <> struct ReaderFor_ <AnyPointer, Kind::OTHER> { typedef AnyPointer::Reader Type; };
template <> struct BuilderFor_<AnyPointer, Kind::OTHER> { typedef AnyPointer::Builder Type; };
template <> struct ReaderFor_ <AnyStruct, Kind::OTHER> { typedef AnyStruct::Reader Type; };
template <> struct BuilderFor_<AnyStruct, Kind::OTHER> { typedef AnyStruct::Builder Type; };

template <>
struct Orphanage::GetInnerReader<AnyPointer, Kind::OTHER> {
  static inline _::PointerReader apply(const AnyPointer::Reader& t) {
    return t.reader;
  }
};

template <>
struct Orphanage::GetInnerBuilder<AnyPointer, Kind::OTHER> {
  static inline _::PointerBuilder apply(AnyPointer::Builder& t) {
    return t.builder;
  }
};

template <>
struct Orphanage::GetInnerReader<AnyStruct, Kind::OTHER> {
  static inline _::StructReader apply(const AnyStruct::Reader& t) {
    return t._reader;
  }
};

template <>
struct Orphanage::GetInnerBuilder<AnyStruct, Kind::OTHER> {
  static inline _::StructBuilder apply(AnyStruct::Builder& t) {
    return t._builder;
  }
};

template <>
struct Orphanage::GetInnerReader<AnyList, Kind::OTHER> {
  static inline _::ListReader apply(const AnyList::Reader& t) {
    return t._reader;
  }
};

template <>
struct Orphanage::GetInnerBuilder<AnyList, Kind::OTHER> {
  static inline _::ListBuilder apply(AnyList::Builder& t) {
    return t._builder;
  }
};

template <typename T>
inline BuilderFor<T> Orphan<AnyPointer>::getAs() {
  return _::OrphanGetImpl<T>::apply(builder);
}
template <typename T>
inline ReaderFor<T> Orphan<AnyPointer>::getAsReader() const {
  return _::OrphanGetImpl<T>::applyReader(builder);
}
template <typename T>
inline Orphan<T> Orphan<AnyPointer>::releaseAs() {
  return Orphan<T>(kj::mv(builder));
}

// Using AnyPointer as the template type should work...

template <>
inline typename AnyPointer::Reader AnyPointer::Reader::getAs<AnyPointer>() const {
  return *this;
}
template <>
inline typename AnyPointer::Builder AnyPointer::Builder::getAs<AnyPointer>() {
  return *this;
}
template <>
inline typename AnyPointer::Builder AnyPointer::Builder::initAs<AnyPointer>() {
  clear();
  return *this;
}
template <>
inline void AnyPointer::Builder::setAs<AnyPointer>(AnyPointer::Reader value) {
  return builder.copyFrom(value.reader);
}
template <>
inline void AnyPointer::Builder::adopt<AnyPointer>(Orphan<AnyPointer>&& orphan) {
  builder.adopt(kj::mv(orphan.builder));
}
template <>
inline Orphan<AnyPointer> AnyPointer::Builder::disownAs<AnyPointer>() {
  return Orphan<AnyPointer>(builder.disown());
}
template <>
inline Orphan<AnyPointer> Orphan<AnyPointer>::releaseAs() {
  return kj::mv(*this);
}

namespace _ {  // private

// Specialize PointerHelpers for AnyPointer.

template <>
struct PointerHelpers<AnyPointer, Kind::OTHER> {
  static inline AnyPointer::Reader get(PointerReader reader,
                                       const void* defaultValue = nullptr,
                                       uint defaultBytes = 0) {
    return AnyPointer::Reader(reader);
  }
  static inline AnyPointer::Builder get(PointerBuilder builder,
                                        const void* defaultValue = nullptr,
                                        uint defaultBytes = 0) {
    return AnyPointer::Builder(builder);
  }
  static inline void set(PointerBuilder builder, AnyPointer::Reader value) {
    AnyPointer::Builder(builder).set(value);
  }
  static inline void adopt(PointerBuilder builder, Orphan<AnyPointer>&& value) {
    builder.adopt(kj::mv(value.builder));
  }
  static inline Orphan<AnyPointer> disown(PointerBuilder builder) {
    return Orphan<AnyPointer>(builder.disown());
  }
  static inline _::PointerReader getInternalReader(const AnyPointer::Reader& reader) {
    return reader.reader;
  }
  static inline _::PointerBuilder getInternalBuilder(AnyPointer::Builder&& builder) {
    return builder.builder;
  }
};

template <>
struct PointerHelpers<AnyStruct, Kind::OTHER> {
  static inline AnyStruct::Reader get(
      PointerReader reader, const word* defaultValue = nullptr) {
    return AnyStruct::Reader(reader.getStruct(defaultValue));
  }
  static inline AnyStruct::Builder get(
      PointerBuilder builder, const word* defaultValue = nullptr) {
    // TODO(someday): Allow specifying the size somehow?
    return AnyStruct::Builder(builder.getStruct(
        _::StructSize(ZERO * WORDS, ZERO * POINTERS), defaultValue));
  }
  static inline void set(PointerBuilder builder, AnyStruct::Reader value) {
    builder.setStruct(value._reader);
  }
  static inline AnyStruct::Builder init(
      PointerBuilder builder, uint16_t dataWordCount, uint16_t pointerCount) {
    return AnyStruct::Builder(builder.initStruct(
        StructSize(bounded(dataWordCount) * WORDS,
                   bounded(pointerCount) * POINTERS)));
  }

  static void adopt(PointerBuilder builder, Orphan<AnyStruct>&& value) {
    builder.adopt(kj::mv(value.builder));
  }
  static Orphan<AnyStruct> disown(PointerBuilder builder) {
    return Orphan<AnyStruct>(builder.disown());
  }
};

template <>
struct PointerHelpers<AnyList, Kind::OTHER> {
  static inline AnyList::Reader get(
      PointerReader reader, const word* defaultValue = nullptr) {
    return AnyList::Reader(reader.getListAnySize(defaultValue));
  }
  static inline AnyList::Builder get(
      PointerBuilder builder, const word* defaultValue = nullptr) {
    return AnyList::Builder(builder.getListAnySize(defaultValue));
  }
  static inline void set(PointerBuilder builder, AnyList::Reader value) {
    builder.setList(value._reader);
  }
  static inline AnyList::Builder init(
      PointerBuilder builder, ElementSize elementSize, uint elementCount) {
    return AnyList::Builder(builder.initList(
        elementSize, bounded(elementCount) * ELEMENTS));
  }
  static inline AnyList::Builder init(
      PointerBuilder builder, uint16_t dataWordCount, uint16_t pointerCount, uint elementCount) {
    return AnyList::Builder(builder.initStructList(
        bounded(elementCount) * ELEMENTS,
        StructSize(bounded(dataWordCount) * WORDS,
                   bounded(pointerCount) * POINTERS)));
  }

  static void adopt(PointerBuilder builder, Orphan<AnyList>&& value) {
    builder.adopt(kj::mv(value.builder));
  }
  static Orphan<AnyList> disown(PointerBuilder builder) {
    return Orphan<AnyList>(builder.disown());
  }
};

template <>
struct OrphanGetImpl<AnyStruct, Kind::OTHER> {
  static inline AnyStruct::Builder apply(_::OrphanBuilder& builder) {
    return AnyStruct::Builder(builder.asStruct(_::StructSize(ZERO * WORDS, ZERO * POINTERS)));
  }
  static inline AnyStruct::Reader applyReader(const _::OrphanBuilder& builder) {
    return AnyStruct::Reader(builder.asStructReader(_::StructSize(ZERO * WORDS, ZERO * POINTERS)));
  }
  static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) {
    builder.truncate(size, _::StructSize(ZERO * WORDS, ZERO * POINTERS));
  }
};

template <>
struct OrphanGetImpl<AnyList, Kind::OTHER> {
  static inline AnyList::Builder apply(_::OrphanBuilder& builder) {
    return AnyList::Builder(builder.asListAnySize());
  }
  static inline AnyList::Reader applyReader(const _::OrphanBuilder& builder) {
    return AnyList::Reader(builder.asListReaderAnySize());
  }
  static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) {
    builder.truncate(size, ElementSize::POINTER);
  }
};

}  // namespace _ (private)

#if !CAPNP_LITE

template <typename T>
struct PipelineHook::FromImpl {
  static inline kj::Own<PipelineHook> apply(typename T::Pipeline&& pipeline) {
    return from(kj::mv(pipeline._typeless));
  }
  static inline PipelineHook& apply(typename T::Pipeline& pipeline) {
    return from(pipeline._typeless);
  }
};

template <>
struct PipelineHook::FromImpl<AnyPointer> {
  static inline kj::Own<PipelineHook> apply(AnyPointer::Pipeline&& pipeline) {
    return kj::mv(pipeline.hook);
  }
  static inline PipelineHook& apply(AnyPointer::Pipeline& pipeline) {
    return *pipeline.hook;
  }
};

template <typename Pipeline, typename T>
inline kj::Own<PipelineHook> PipelineHook::from(Pipeline&& pipeline) {
  return FromImpl<T>::apply(kj::fwd<Pipeline>(pipeline));
}

template <typename Pipeline, typename T>
inline PipelineHook& PipelineHook::from(Pipeline& pipeline) {
  return FromImpl<T>::apply(pipeline);
}

#endif  // !CAPNP_LITE

}  // namespace capnp

CAPNP_END_HEADER
