// Generated by Cap'n Proto compiler, DO NOT EDIT
// source: rpc.capnp

#pragma once

#include <capnp/generated-header-support.h>
#include <kj/windows-sanity.h>

#if CAPNP_VERSION != 10000
#error "Version mismatch between generated code and library headers.  You must use the same version of the Cap'n Proto compiler and library."
#endif


CAPNP_BEGIN_HEADER

namespace capnp {
namespace schemas {

CAPNP_DECLARE_SCHEMA(91b79f1f808db032);
CAPNP_DECLARE_SCHEMA(e94ccf8031176ec4);
CAPNP_DECLARE_SCHEMA(836a53ce789d4cd4);
CAPNP_DECLARE_SCHEMA(dae8b0f61aab5f99);
CAPNP_DECLARE_SCHEMA(9e19b28d3db3573a);
CAPNP_DECLARE_SCHEMA(d37d2eb2c2f80e63);
CAPNP_DECLARE_SCHEMA(bbc29655fa89086e);
CAPNP_DECLARE_SCHEMA(ad1a6c0d7dd07497);
CAPNP_DECLARE_SCHEMA(f964368b0fbd3711);
CAPNP_DECLARE_SCHEMA(d562b4df655bdd4d);
CAPNP_DECLARE_SCHEMA(9c6a046bfbc1ac5a);
CAPNP_DECLARE_SCHEMA(d4c9b56290554016);
CAPNP_DECLARE_SCHEMA(fbe1980490e001af);
CAPNP_DECLARE_SCHEMA(95bc14545813fbc1);
CAPNP_DECLARE_SCHEMA(9a0e61223d96743b);
CAPNP_DECLARE_SCHEMA(8523ddc40b86b8b0);
CAPNP_DECLARE_SCHEMA(d800b1d6cd6f1ca0);
CAPNP_DECLARE_SCHEMA(f316944415569081);
CAPNP_DECLARE_SCHEMA(d37007fde1f0027d);
CAPNP_DECLARE_SCHEMA(d625b7063acf691a);
CAPNP_DECLARE_SCHEMA(b28c96e23f4cbd58);
enum class Type_b28c96e23f4cbd58: uint16_t {
  FAILED,
  OVERLOADED,
  DISCONNECTED,
  UNIMPLEMENTED,
};
CAPNP_DECLARE_ENUM(Type, b28c96e23f4cbd58);

}  // namespace schemas
}  // namespace capnp

namespace capnp {
namespace rpc {

struct Message {
  Message() = delete;

  class Reader;
  class Builder;
  class Pipeline;
  enum Which: uint16_t {
    UNIMPLEMENTED,
    ABORT,
    CALL,
    RETURN,
    FINISH,
    RESOLVE,
    RELEASE,
    OBSOLETE_SAVE,
    BOOTSTRAP,
    OBSOLETE_DELETE,
    PROVIDE,
    ACCEPT,
    JOIN,
    DISEMBARGO,
  };

  struct _capnpPrivate {
    CAPNP_DECLARE_STRUCT_HEADER(91b79f1f808db032, 1, 1)
    #if !CAPNP_LITE
    static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
    #endif  // !CAPNP_LITE
  };
};

struct Bootstrap {
  Bootstrap() = delete;

  class Reader;
  class Builder;
  class Pipeline;

  struct _capnpPrivate {
    CAPNP_DECLARE_STRUCT_HEADER(e94ccf8031176ec4, 1, 1)
    #if !CAPNP_LITE
    static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
    #endif  // !CAPNP_LITE
  };
};

struct Call {
  Call() = delete;

  class Reader;
  class Builder;
  class Pipeline;
  struct SendResultsTo;

  struct _capnpPrivate {
    CAPNP_DECLARE_STRUCT_HEADER(836a53ce789d4cd4, 3, 3)
    #if !CAPNP_LITE
    static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
    #endif  // !CAPNP_LITE
  };
};

struct Call::SendResultsTo {
  SendResultsTo() = delete;

  class Reader;
  class Builder;
  class Pipeline;
  enum Which: uint16_t {
    CALLER,
    YOURSELF,
    THIRD_PARTY,
  };

  struct _capnpPrivate {
    CAPNP_DECLARE_STRUCT_HEADER(dae8b0f61aab5f99, 3, 3)
    #if !CAPNP_LITE
    static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
    #endif  // !CAPNP_LITE
  };
};

struct Return {
  Return() = delete;

  class Reader;
  class Builder;
  class Pipeline;
  enum Which: uint16_t {
    RESULTS,
    EXCEPTION,
    CANCELED,
    RESULTS_SENT_ELSEWHERE,
    TAKE_FROM_OTHER_QUESTION,
    ACCEPT_FROM_THIRD_PARTY,
  };

  struct _capnpPrivate {
    CAPNP_DECLARE_STRUCT_HEADER(9e19b28d3db3573a, 2, 1)
    #if !CAPNP_LITE
    static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
    #endif  // !CAPNP_LITE
  };
};

struct Finish {
  Finish() = delete;

  class Reader;
  class Builder;
  class Pipeline;

  struct _capnpPrivate {
    CAPNP_DECLARE_STRUCT_HEADER(d37d2eb2c2f80e63, 1, 0)
    #if !CAPNP_LITE
    static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
    #endif  // !CAPNP_LITE
  };
};

struct Resolve {
  Resolve() = delete;

  class Reader;
  class Builder;
  class Pipeline;
  enum Which: uint16_t {
    CAP,
    EXCEPTION,
  };

  struct _capnpPrivate {
    CAPNP_DECLARE_STRUCT_HEADER(bbc29655fa89086e, 1, 1)
    #if !CAPNP_LITE
    static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
    #endif  // !CAPNP_LITE
  };
};

struct Release {
  Release() = delete;

  class Reader;
  class Builder;
  class Pipeline;

  struct _capnpPrivate {
    CAPNP_DECLARE_STRUCT_HEADER(ad1a6c0d7dd07497, 1, 0)
    #if !CAPNP_LITE
    static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
    #endif  // !CAPNP_LITE
  };
};

struct Disembargo {
  Disembargo() = delete;

  class Reader;
  class Builder;
  class Pipeline;
  struct Context;

  struct _capnpPrivate {
    CAPNP_DECLARE_STRUCT_HEADER(f964368b0fbd3711, 1, 1)
    #if !CAPNP_LITE
    static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
    #endif  // !CAPNP_LITE
  };
};

struct Disembargo::Context {
  Context() = delete;

  class Reader;
  class Builder;
  class Pipeline;
  enum Which: uint16_t {
    SENDER_LOOPBACK,
    RECEIVER_LOOPBACK,
    ACCEPT,
    PROVIDE,
  };

  struct _capnpPrivate {
    CAPNP_DECLARE_STRUCT_HEADER(d562b4df655bdd4d, 1, 1)
    #if !CAPNP_LITE
    static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
    #endif  // !CAPNP_LITE
  };
};

struct Provide {
  Provide() = delete;

  class Reader;
  class Builder;
  class Pipeline;

  struct _capnpPrivate {
    CAPNP_DECLARE_STRUCT_HEADER(9c6a046bfbc1ac5a, 1, 2)
    #if !CAPNP_LITE
    static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
    #endif  // !CAPNP_LITE
  };
};

struct Accept {
  Accept() = delete;

  class Reader;
  class Builder;
  class Pipeline;

  struct _capnpPrivate {
    CAPNP_DECLARE_STRUCT_HEADER(d4c9b56290554016, 1, 1)
    #if !CAPNP_LITE
    static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
    #endif  // !CAPNP_LITE
  };
};

struct Join {
  Join() = delete;

  class Reader;
  class Builder;
  class Pipeline;

  struct _capnpPrivate {
    CAPNP_DECLARE_STRUCT_HEADER(fbe1980490e001af, 1, 2)
    #if !CAPNP_LITE
    static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
    #endif  // !CAPNP_LITE
  };
};

struct MessageTarget {
  MessageTarget() = delete;

  class Reader;
  class Builder;
  class Pipeline;
  enum Which: uint16_t {
    IMPORTED_CAP,
    PROMISED_ANSWER,
  };

  struct _capnpPrivate {
    CAPNP_DECLARE_STRUCT_HEADER(95bc14545813fbc1, 1, 1)
    #if !CAPNP_LITE
    static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
    #endif  // !CAPNP_LITE
  };
};

struct Payload {
  Payload() = delete;

  class Reader;
  class Builder;
  class Pipeline;

  struct _capnpPrivate {
    CAPNP_DECLARE_STRUCT_HEADER(9a0e61223d96743b, 0, 2)
    #if !CAPNP_LITE
    static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
    #endif  // !CAPNP_LITE
  };
};

struct CapDescriptor {
  CapDescriptor() = delete;

  class Reader;
  class Builder;
  class Pipeline;
  enum Which: uint16_t {
    NONE,
    SENDER_HOSTED,
    SENDER_PROMISE,
    RECEIVER_HOSTED,
    RECEIVER_ANSWER,
    THIRD_PARTY_HOSTED,
  };

  struct _capnpPrivate {
    CAPNP_DECLARE_STRUCT_HEADER(8523ddc40b86b8b0, 1, 1)
    #if !CAPNP_LITE
    static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
    #endif  // !CAPNP_LITE
  };
};

struct PromisedAnswer {
  PromisedAnswer() = delete;

  class Reader;
  class Builder;
  class Pipeline;
  struct Op;

  struct _capnpPrivate {
    CAPNP_DECLARE_STRUCT_HEADER(d800b1d6cd6f1ca0, 1, 1)
    #if !CAPNP_LITE
    static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
    #endif  // !CAPNP_LITE
  };
};

struct PromisedAnswer::Op {
  Op() = delete;

  class Reader;
  class Builder;
  class Pipeline;
  enum Which: uint16_t {
    NOOP,
    GET_POINTER_FIELD,
  };

  struct _capnpPrivate {
    CAPNP_DECLARE_STRUCT_HEADER(f316944415569081, 1, 0)
    #if !CAPNP_LITE
    static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
    #endif  // !CAPNP_LITE
  };
};

struct ThirdPartyCapDescriptor {
  ThirdPartyCapDescriptor() = delete;

  class Reader;
  class Builder;
  class Pipeline;

  struct _capnpPrivate {
    CAPNP_DECLARE_STRUCT_HEADER(d37007fde1f0027d, 1, 1)
    #if !CAPNP_LITE
    static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
    #endif  // !CAPNP_LITE
  };
};

struct Exception {
  Exception() = delete;

  class Reader;
  class Builder;
  class Pipeline;
  typedef ::capnp::schemas::Type_b28c96e23f4cbd58 Type;


  struct _capnpPrivate {
    CAPNP_DECLARE_STRUCT_HEADER(d625b7063acf691a, 1, 2)
    #if !CAPNP_LITE
    static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
    #endif  // !CAPNP_LITE
  };
};

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

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

  Reader() = default;
  inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}

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

#if !CAPNP_LITE
  inline ::kj::StringTree toString() const {
    return ::capnp::_::structString(_reader, *_capnpPrivate::brand());
  }
#endif  // !CAPNP_LITE

  inline Which which() const;
  inline bool isUnimplemented() const;
  inline bool hasUnimplemented() const;
  inline  ::capnp::rpc::Message::Reader getUnimplemented() const;

  inline bool isAbort() const;
  inline bool hasAbort() const;
  inline  ::capnp::rpc::Exception::Reader getAbort() const;

  inline bool isCall() const;
  inline bool hasCall() const;
  inline  ::capnp::rpc::Call::Reader getCall() const;

  inline bool isReturn() const;
  inline bool hasReturn() const;
  inline  ::capnp::rpc::Return::Reader getReturn() const;

  inline bool isFinish() const;
  inline bool hasFinish() const;
  inline  ::capnp::rpc::Finish::Reader getFinish() const;

  inline bool isResolve() const;
  inline bool hasResolve() const;
  inline  ::capnp::rpc::Resolve::Reader getResolve() const;

  inline bool isRelease() const;
  inline bool hasRelease() const;
  inline  ::capnp::rpc::Release::Reader getRelease() const;

  inline bool isObsoleteSave() const;
  inline bool hasObsoleteSave() const;
  inline ::capnp::AnyPointer::Reader getObsoleteSave() const;

  inline bool isBootstrap() const;
  inline bool hasBootstrap() const;
  inline  ::capnp::rpc::Bootstrap::Reader getBootstrap() const;

  inline bool isObsoleteDelete() const;
  inline bool hasObsoleteDelete() const;
  inline ::capnp::AnyPointer::Reader getObsoleteDelete() const;

  inline bool isProvide() const;
  inline bool hasProvide() const;
  inline  ::capnp::rpc::Provide::Reader getProvide() const;

  inline bool isAccept() const;
  inline bool hasAccept() const;
  inline  ::capnp::rpc::Accept::Reader getAccept() const;

  inline bool isJoin() const;
  inline bool hasJoin() const;
  inline  ::capnp::rpc::Join::Reader getJoin() const;

  inline bool isDisembargo() const;
  inline bool hasDisembargo() const;
  inline  ::capnp::rpc::Disembargo::Reader getDisembargo() const;

private:
  ::capnp::_::StructReader _reader;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::List;
  friend class ::capnp::MessageBuilder;
  friend class ::capnp::Orphanage;
};

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

  Builder() = delete;  // Deleted to discourage incorrect usage.
                       // You can explicitly initialize to nullptr instead.
  inline Builder(decltype(nullptr)) {}
  inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
  inline operator Reader() const { return Reader(_builder.asReader()); }
  inline Reader asReader() const { return *this; }

  inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
#if !CAPNP_LITE
  inline ::kj::StringTree toString() const { return asReader().toString(); }
#endif  // !CAPNP_LITE

  inline Which which();
  inline bool isUnimplemented();
  inline bool hasUnimplemented();
  inline  ::capnp::rpc::Message::Builder getUnimplemented();
  inline void setUnimplemented( ::capnp::rpc::Message::Reader value);
  inline  ::capnp::rpc::Message::Builder initUnimplemented();
  inline void adoptUnimplemented(::capnp::Orphan< ::capnp::rpc::Message>&& value);
  inline ::capnp::Orphan< ::capnp::rpc::Message> disownUnimplemented();

  inline bool isAbort();
  inline bool hasAbort();
  inline  ::capnp::rpc::Exception::Builder getAbort();
  inline void setAbort( ::capnp::rpc::Exception::Reader value);
  inline  ::capnp::rpc::Exception::Builder initAbort();
  inline void adoptAbort(::capnp::Orphan< ::capnp::rpc::Exception>&& value);
  inline ::capnp::Orphan< ::capnp::rpc::Exception> disownAbort();

  inline bool isCall();
  inline bool hasCall();
  inline  ::capnp::rpc::Call::Builder getCall();
  inline void setCall( ::capnp::rpc::Call::Reader value);
  inline  ::capnp::rpc::Call::Builder initCall();
  inline void adoptCall(::capnp::Orphan< ::capnp::rpc::Call>&& value);
  inline ::capnp::Orphan< ::capnp::rpc::Call> disownCall();

  inline bool isReturn();
  inline bool hasReturn();
  inline  ::capnp::rpc::Return::Builder getReturn();
  inline void setReturn( ::capnp::rpc::Return::Reader value);
  inline  ::capnp::rpc::Return::Builder initReturn();
  inline void adoptReturn(::capnp::Orphan< ::capnp::rpc::Return>&& value);
  inline ::capnp::Orphan< ::capnp::rpc::Return> disownReturn();

  inline bool isFinish();
  inline bool hasFinish();
  inline  ::capnp::rpc::Finish::Builder getFinish();
  inline void setFinish( ::capnp::rpc::Finish::Reader value);
  inline  ::capnp::rpc::Finish::Builder initFinish();
  inline void adoptFinish(::capnp::Orphan< ::capnp::rpc::Finish>&& value);
  inline ::capnp::Orphan< ::capnp::rpc::Finish> disownFinish();

  inline bool isResolve();
  inline bool hasResolve();
  inline  ::capnp::rpc::Resolve::Builder getResolve();
  inline void setResolve( ::capnp::rpc::Resolve::Reader value);
  inline  ::capnp::rpc::Resolve::Builder initResolve();
  inline void adoptResolve(::capnp::Orphan< ::capnp::rpc::Resolve>&& value);
  inline ::capnp::Orphan< ::capnp::rpc::Resolve> disownResolve();

  inline bool isRelease();
  inline bool hasRelease();
  inline  ::capnp::rpc::Release::Builder getRelease();
  inline void setRelease( ::capnp::rpc::Release::Reader value);
  inline  ::capnp::rpc::Release::Builder initRelease();
  inline void adoptRelease(::capnp::Orphan< ::capnp::rpc::Release>&& value);
  inline ::capnp::Orphan< ::capnp::rpc::Release> disownRelease();

  inline bool isObsoleteSave();
  inline bool hasObsoleteSave();
  inline ::capnp::AnyPointer::Builder getObsoleteSave();
  inline ::capnp::AnyPointer::Builder initObsoleteSave();

  inline bool isBootstrap();
  inline bool hasBootstrap();
  inline  ::capnp::rpc::Bootstrap::Builder getBootstrap();
  inline void setBootstrap( ::capnp::rpc::Bootstrap::Reader value);
  inline  ::capnp::rpc::Bootstrap::Builder initBootstrap();
  inline void adoptBootstrap(::capnp::Orphan< ::capnp::rpc::Bootstrap>&& value);
  inline ::capnp::Orphan< ::capnp::rpc::Bootstrap> disownBootstrap();

  inline bool isObsoleteDelete();
  inline bool hasObsoleteDelete();
  inline ::capnp::AnyPointer::Builder getObsoleteDelete();
  inline ::capnp::AnyPointer::Builder initObsoleteDelete();

  inline bool isProvide();
  inline bool hasProvide();
  inline  ::capnp::rpc::Provide::Builder getProvide();
  inline void setProvide( ::capnp::rpc::Provide::Reader value);
  inline  ::capnp::rpc::Provide::Builder initProvide();
  inline void adoptProvide(::capnp::Orphan< ::capnp::rpc::Provide>&& value);
  inline ::capnp::Orphan< ::capnp::rpc::Provide> disownProvide();

  inline bool isAccept();
  inline bool hasAccept();
  inline  ::capnp::rpc::Accept::Builder getAccept();
  inline void setAccept( ::capnp::rpc::Accept::Reader value);
  inline  ::capnp::rpc::Accept::Builder initAccept();
  inline void adoptAccept(::capnp::Orphan< ::capnp::rpc::Accept>&& value);
  inline ::capnp::Orphan< ::capnp::rpc::Accept> disownAccept();

  inline bool isJoin();
  inline bool hasJoin();
  inline  ::capnp::rpc::Join::Builder getJoin();
  inline void setJoin( ::capnp::rpc::Join::Reader value);
  inline  ::capnp::rpc::Join::Builder initJoin();
  inline void adoptJoin(::capnp::Orphan< ::capnp::rpc::Join>&& value);
  inline ::capnp::Orphan< ::capnp::rpc::Join> disownJoin();

  inline bool isDisembargo();
  inline bool hasDisembargo();
  inline  ::capnp::rpc::Disembargo::Builder getDisembargo();
  inline void setDisembargo( ::capnp::rpc::Disembargo::Reader value);
  inline  ::capnp::rpc::Disembargo::Builder initDisembargo();
  inline void adoptDisembargo(::capnp::Orphan< ::capnp::rpc::Disembargo>&& value);
  inline ::capnp::Orphan< ::capnp::rpc::Disembargo> disownDisembargo();

private:
  ::capnp::_::StructBuilder _builder;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  friend class ::capnp::Orphanage;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
};

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

  inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
  inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
      : _typeless(kj::mv(typeless)) {}

private:
  ::capnp::AnyPointer::Pipeline _typeless;
  friend class ::capnp::PipelineHook;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
};
#endif  // !CAPNP_LITE

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

  Reader() = default;
  inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}

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

#if !CAPNP_LITE
  inline ::kj::StringTree toString() const {
    return ::capnp::_::structString(_reader, *_capnpPrivate::brand());
  }
#endif  // !CAPNP_LITE

  inline  ::uint32_t getQuestionId() const;

  inline bool hasDeprecatedObjectId() const;
  inline ::capnp::AnyPointer::Reader getDeprecatedObjectId() const;

private:
  ::capnp::_::StructReader _reader;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::List;
  friend class ::capnp::MessageBuilder;
  friend class ::capnp::Orphanage;
};

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

  Builder() = delete;  // Deleted to discourage incorrect usage.
                       // You can explicitly initialize to nullptr instead.
  inline Builder(decltype(nullptr)) {}
  inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
  inline operator Reader() const { return Reader(_builder.asReader()); }
  inline Reader asReader() const { return *this; }

  inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
#if !CAPNP_LITE
  inline ::kj::StringTree toString() const { return asReader().toString(); }
#endif  // !CAPNP_LITE

  inline  ::uint32_t getQuestionId();
  inline void setQuestionId( ::uint32_t value);

  inline bool hasDeprecatedObjectId();
  inline ::capnp::AnyPointer::Builder getDeprecatedObjectId();
  inline ::capnp::AnyPointer::Builder initDeprecatedObjectId();

private:
  ::capnp::_::StructBuilder _builder;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  friend class ::capnp::Orphanage;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
};

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

  inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
  inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
      : _typeless(kj::mv(typeless)) {}

private:
  ::capnp::AnyPointer::Pipeline _typeless;
  friend class ::capnp::PipelineHook;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
};
#endif  // !CAPNP_LITE

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

  Reader() = default;
  inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}

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

#if !CAPNP_LITE
  inline ::kj::StringTree toString() const {
    return ::capnp::_::structString(_reader, *_capnpPrivate::brand());
  }
#endif  // !CAPNP_LITE

  inline  ::uint32_t getQuestionId() const;

  inline bool hasTarget() const;
  inline  ::capnp::rpc::MessageTarget::Reader getTarget() const;

  inline  ::uint64_t getInterfaceId() const;

  inline  ::uint16_t getMethodId() const;

  inline bool hasParams() const;
  inline  ::capnp::rpc::Payload::Reader getParams() const;

  inline typename SendResultsTo::Reader getSendResultsTo() const;

  inline bool getAllowThirdPartyTailCall() const;

private:
  ::capnp::_::StructReader _reader;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::List;
  friend class ::capnp::MessageBuilder;
  friend class ::capnp::Orphanage;
};

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

  Builder() = delete;  // Deleted to discourage incorrect usage.
                       // You can explicitly initialize to nullptr instead.
  inline Builder(decltype(nullptr)) {}
  inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
  inline operator Reader() const { return Reader(_builder.asReader()); }
  inline Reader asReader() const { return *this; }

  inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
#if !CAPNP_LITE
  inline ::kj::StringTree toString() const { return asReader().toString(); }
#endif  // !CAPNP_LITE

  inline  ::uint32_t getQuestionId();
  inline void setQuestionId( ::uint32_t value);

  inline bool hasTarget();
  inline  ::capnp::rpc::MessageTarget::Builder getTarget();
  inline void setTarget( ::capnp::rpc::MessageTarget::Reader value);
  inline  ::capnp::rpc::MessageTarget::Builder initTarget();
  inline void adoptTarget(::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value);
  inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> disownTarget();

  inline  ::uint64_t getInterfaceId();
  inline void setInterfaceId( ::uint64_t value);

  inline  ::uint16_t getMethodId();
  inline void setMethodId( ::uint16_t value);

  inline bool hasParams();
  inline  ::capnp::rpc::Payload::Builder getParams();
  inline void setParams( ::capnp::rpc::Payload::Reader value);
  inline  ::capnp::rpc::Payload::Builder initParams();
  inline void adoptParams(::capnp::Orphan< ::capnp::rpc::Payload>&& value);
  inline ::capnp::Orphan< ::capnp::rpc::Payload> disownParams();

  inline typename SendResultsTo::Builder getSendResultsTo();
  inline typename SendResultsTo::Builder initSendResultsTo();

  inline bool getAllowThirdPartyTailCall();
  inline void setAllowThirdPartyTailCall(bool value);

private:
  ::capnp::_::StructBuilder _builder;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  friend class ::capnp::Orphanage;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
};

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

  inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
  inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
      : _typeless(kj::mv(typeless)) {}

  inline  ::capnp::rpc::MessageTarget::Pipeline getTarget();
  inline  ::capnp::rpc::Payload::Pipeline getParams();
  inline typename SendResultsTo::Pipeline getSendResultsTo();
private:
  ::capnp::AnyPointer::Pipeline _typeless;
  friend class ::capnp::PipelineHook;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
};
#endif  // !CAPNP_LITE

class Call::SendResultsTo::Reader {
public:
  typedef SendResultsTo Reads;

  Reader() = default;
  inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}

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

#if !CAPNP_LITE
  inline ::kj::StringTree toString() const {
    return ::capnp::_::structString(_reader, *_capnpPrivate::brand());
  }
#endif  // !CAPNP_LITE

  inline Which which() const;
  inline bool isCaller() const;
  inline  ::capnp::Void getCaller() const;

  inline bool isYourself() const;
  inline  ::capnp::Void getYourself() const;

  inline bool isThirdParty() const;
  inline bool hasThirdParty() const;
  inline ::capnp::AnyPointer::Reader getThirdParty() const;

private:
  ::capnp::_::StructReader _reader;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::List;
  friend class ::capnp::MessageBuilder;
  friend class ::capnp::Orphanage;
};

class Call::SendResultsTo::Builder {
public:
  typedef SendResultsTo Builds;

  Builder() = delete;  // Deleted to discourage incorrect usage.
                       // You can explicitly initialize to nullptr instead.
  inline Builder(decltype(nullptr)) {}
  inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
  inline operator Reader() const { return Reader(_builder.asReader()); }
  inline Reader asReader() const { return *this; }

  inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
#if !CAPNP_LITE
  inline ::kj::StringTree toString() const { return asReader().toString(); }
#endif  // !CAPNP_LITE

  inline Which which();
  inline bool isCaller();
  inline  ::capnp::Void getCaller();
  inline void setCaller( ::capnp::Void value = ::capnp::VOID);

  inline bool isYourself();
  inline  ::capnp::Void getYourself();
  inline void setYourself( ::capnp::Void value = ::capnp::VOID);

  inline bool isThirdParty();
  inline bool hasThirdParty();
  inline ::capnp::AnyPointer::Builder getThirdParty();
  inline ::capnp::AnyPointer::Builder initThirdParty();

private:
  ::capnp::_::StructBuilder _builder;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  friend class ::capnp::Orphanage;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
};

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

  inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
  inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
      : _typeless(kj::mv(typeless)) {}

private:
  ::capnp::AnyPointer::Pipeline _typeless;
  friend class ::capnp::PipelineHook;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
};
#endif  // !CAPNP_LITE

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

  Reader() = default;
  inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}

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

#if !CAPNP_LITE
  inline ::kj::StringTree toString() const {
    return ::capnp::_::structString(_reader, *_capnpPrivate::brand());
  }
#endif  // !CAPNP_LITE

  inline Which which() const;
  inline  ::uint32_t getAnswerId() const;

  inline bool getReleaseParamCaps() const;

  inline bool isResults() const;
  inline bool hasResults() const;
  inline  ::capnp::rpc::Payload::Reader getResults() const;

  inline bool isException() const;
  inline bool hasException() const;
  inline  ::capnp::rpc::Exception::Reader getException() const;

  inline bool isCanceled() const;
  inline  ::capnp::Void getCanceled() const;

  inline bool isResultsSentElsewhere() const;
  inline  ::capnp::Void getResultsSentElsewhere() const;

  inline bool isTakeFromOtherQuestion() const;
  inline  ::uint32_t getTakeFromOtherQuestion() const;

  inline bool isAcceptFromThirdParty() const;
  inline bool hasAcceptFromThirdParty() const;
  inline ::capnp::AnyPointer::Reader getAcceptFromThirdParty() const;

private:
  ::capnp::_::StructReader _reader;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::List;
  friend class ::capnp::MessageBuilder;
  friend class ::capnp::Orphanage;
};

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

  Builder() = delete;  // Deleted to discourage incorrect usage.
                       // You can explicitly initialize to nullptr instead.
  inline Builder(decltype(nullptr)) {}
  inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
  inline operator Reader() const { return Reader(_builder.asReader()); }
  inline Reader asReader() const { return *this; }

  inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
#if !CAPNP_LITE
  inline ::kj::StringTree toString() const { return asReader().toString(); }
#endif  // !CAPNP_LITE

  inline Which which();
  inline  ::uint32_t getAnswerId();
  inline void setAnswerId( ::uint32_t value);

  inline bool getReleaseParamCaps();
  inline void setReleaseParamCaps(bool value);

  inline bool isResults();
  inline bool hasResults();
  inline  ::capnp::rpc::Payload::Builder getResults();
  inline void setResults( ::capnp::rpc::Payload::Reader value);
  inline  ::capnp::rpc::Payload::Builder initResults();
  inline void adoptResults(::capnp::Orphan< ::capnp::rpc::Payload>&& value);
  inline ::capnp::Orphan< ::capnp::rpc::Payload> disownResults();

  inline bool isException();
  inline bool hasException();
  inline  ::capnp::rpc::Exception::Builder getException();
  inline void setException( ::capnp::rpc::Exception::Reader value);
  inline  ::capnp::rpc::Exception::Builder initException();
  inline void adoptException(::capnp::Orphan< ::capnp::rpc::Exception>&& value);
  inline ::capnp::Orphan< ::capnp::rpc::Exception> disownException();

  inline bool isCanceled();
  inline  ::capnp::Void getCanceled();
  inline void setCanceled( ::capnp::Void value = ::capnp::VOID);

  inline bool isResultsSentElsewhere();
  inline  ::capnp::Void getResultsSentElsewhere();
  inline void setResultsSentElsewhere( ::capnp::Void value = ::capnp::VOID);

  inline bool isTakeFromOtherQuestion();
  inline  ::uint32_t getTakeFromOtherQuestion();
  inline void setTakeFromOtherQuestion( ::uint32_t value);

  inline bool isAcceptFromThirdParty();
  inline bool hasAcceptFromThirdParty();
  inline ::capnp::AnyPointer::Builder getAcceptFromThirdParty();
  inline ::capnp::AnyPointer::Builder initAcceptFromThirdParty();

private:
  ::capnp::_::StructBuilder _builder;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  friend class ::capnp::Orphanage;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
};

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

  inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
  inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
      : _typeless(kj::mv(typeless)) {}

private:
  ::capnp::AnyPointer::Pipeline _typeless;
  friend class ::capnp::PipelineHook;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
};
#endif  // !CAPNP_LITE

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

  Reader() = default;
  inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}

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

#if !CAPNP_LITE
  inline ::kj::StringTree toString() const {
    return ::capnp::_::structString(_reader, *_capnpPrivate::brand());
  }
#endif  // !CAPNP_LITE

  inline  ::uint32_t getQuestionId() const;

  inline bool getReleaseResultCaps() const;

private:
  ::capnp::_::StructReader _reader;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::List;
  friend class ::capnp::MessageBuilder;
  friend class ::capnp::Orphanage;
};

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

  Builder() = delete;  // Deleted to discourage incorrect usage.
                       // You can explicitly initialize to nullptr instead.
  inline Builder(decltype(nullptr)) {}
  inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
  inline operator Reader() const { return Reader(_builder.asReader()); }
  inline Reader asReader() const { return *this; }

  inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
#if !CAPNP_LITE
  inline ::kj::StringTree toString() const { return asReader().toString(); }
#endif  // !CAPNP_LITE

  inline  ::uint32_t getQuestionId();
  inline void setQuestionId( ::uint32_t value);

  inline bool getReleaseResultCaps();
  inline void setReleaseResultCaps(bool value);

private:
  ::capnp::_::StructBuilder _builder;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  friend class ::capnp::Orphanage;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
};

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

  inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
  inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
      : _typeless(kj::mv(typeless)) {}

private:
  ::capnp::AnyPointer::Pipeline _typeless;
  friend class ::capnp::PipelineHook;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
};
#endif  // !CAPNP_LITE

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

  Reader() = default;
  inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}

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

#if !CAPNP_LITE
  inline ::kj::StringTree toString() const {
    return ::capnp::_::structString(_reader, *_capnpPrivate::brand());
  }
#endif  // !CAPNP_LITE

  inline Which which() const;
  inline  ::uint32_t getPromiseId() const;

  inline bool isCap() const;
  inline bool hasCap() const;
  inline  ::capnp::rpc::CapDescriptor::Reader getCap() const;

  inline bool isException() const;
  inline bool hasException() const;
  inline  ::capnp::rpc::Exception::Reader getException() const;

private:
  ::capnp::_::StructReader _reader;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::List;
  friend class ::capnp::MessageBuilder;
  friend class ::capnp::Orphanage;
};

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

  Builder() = delete;  // Deleted to discourage incorrect usage.
                       // You can explicitly initialize to nullptr instead.
  inline Builder(decltype(nullptr)) {}
  inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
  inline operator Reader() const { return Reader(_builder.asReader()); }
  inline Reader asReader() const { return *this; }

  inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
#if !CAPNP_LITE
  inline ::kj::StringTree toString() const { return asReader().toString(); }
#endif  // !CAPNP_LITE

  inline Which which();
  inline  ::uint32_t getPromiseId();
  inline void setPromiseId( ::uint32_t value);

  inline bool isCap();
  inline bool hasCap();
  inline  ::capnp::rpc::CapDescriptor::Builder getCap();
  inline void setCap( ::capnp::rpc::CapDescriptor::Reader value);
  inline  ::capnp::rpc::CapDescriptor::Builder initCap();
  inline void adoptCap(::capnp::Orphan< ::capnp::rpc::CapDescriptor>&& value);
  inline ::capnp::Orphan< ::capnp::rpc::CapDescriptor> disownCap();

  inline bool isException();
  inline bool hasException();
  inline  ::capnp::rpc::Exception::Builder getException();
  inline void setException( ::capnp::rpc::Exception::Reader value);
  inline  ::capnp::rpc::Exception::Builder initException();
  inline void adoptException(::capnp::Orphan< ::capnp::rpc::Exception>&& value);
  inline ::capnp::Orphan< ::capnp::rpc::Exception> disownException();

private:
  ::capnp::_::StructBuilder _builder;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  friend class ::capnp::Orphanage;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
};

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

  inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
  inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
      : _typeless(kj::mv(typeless)) {}

private:
  ::capnp::AnyPointer::Pipeline _typeless;
  friend class ::capnp::PipelineHook;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
};
#endif  // !CAPNP_LITE

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

  Reader() = default;
  inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}

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

#if !CAPNP_LITE
  inline ::kj::StringTree toString() const {
    return ::capnp::_::structString(_reader, *_capnpPrivate::brand());
  }
#endif  // !CAPNP_LITE

  inline  ::uint32_t getId() const;

  inline  ::uint32_t getReferenceCount() const;

private:
  ::capnp::_::StructReader _reader;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::List;
  friend class ::capnp::MessageBuilder;
  friend class ::capnp::Orphanage;
};

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

  Builder() = delete;  // Deleted to discourage incorrect usage.
                       // You can explicitly initialize to nullptr instead.
  inline Builder(decltype(nullptr)) {}
  inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
  inline operator Reader() const { return Reader(_builder.asReader()); }
  inline Reader asReader() const { return *this; }

  inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
#if !CAPNP_LITE
  inline ::kj::StringTree toString() const { return asReader().toString(); }
#endif  // !CAPNP_LITE

  inline  ::uint32_t getId();
  inline void setId( ::uint32_t value);

  inline  ::uint32_t getReferenceCount();
  inline void setReferenceCount( ::uint32_t value);

private:
  ::capnp::_::StructBuilder _builder;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  friend class ::capnp::Orphanage;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
};

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

  inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
  inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
      : _typeless(kj::mv(typeless)) {}

private:
  ::capnp::AnyPointer::Pipeline _typeless;
  friend class ::capnp::PipelineHook;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
};
#endif  // !CAPNP_LITE

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

  Reader() = default;
  inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}

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

#if !CAPNP_LITE
  inline ::kj::StringTree toString() const {
    return ::capnp::_::structString(_reader, *_capnpPrivate::brand());
  }
#endif  // !CAPNP_LITE

  inline bool hasTarget() const;
  inline  ::capnp::rpc::MessageTarget::Reader getTarget() const;

  inline typename Context::Reader getContext() const;

private:
  ::capnp::_::StructReader _reader;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::List;
  friend class ::capnp::MessageBuilder;
  friend class ::capnp::Orphanage;
};

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

  Builder() = delete;  // Deleted to discourage incorrect usage.
                       // You can explicitly initialize to nullptr instead.
  inline Builder(decltype(nullptr)) {}
  inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
  inline operator Reader() const { return Reader(_builder.asReader()); }
  inline Reader asReader() const { return *this; }

  inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
#if !CAPNP_LITE
  inline ::kj::StringTree toString() const { return asReader().toString(); }
#endif  // !CAPNP_LITE

  inline bool hasTarget();
  inline  ::capnp::rpc::MessageTarget::Builder getTarget();
  inline void setTarget( ::capnp::rpc::MessageTarget::Reader value);
  inline  ::capnp::rpc::MessageTarget::Builder initTarget();
  inline void adoptTarget(::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value);
  inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> disownTarget();

  inline typename Context::Builder getContext();
  inline typename Context::Builder initContext();

private:
  ::capnp::_::StructBuilder _builder;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  friend class ::capnp::Orphanage;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
};

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

  inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
  inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
      : _typeless(kj::mv(typeless)) {}

  inline  ::capnp::rpc::MessageTarget::Pipeline getTarget();
  inline typename Context::Pipeline getContext();
private:
  ::capnp::AnyPointer::Pipeline _typeless;
  friend class ::capnp::PipelineHook;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
};
#endif  // !CAPNP_LITE

class Disembargo::Context::Reader {
public:
  typedef Context Reads;

  Reader() = default;
  inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}

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

#if !CAPNP_LITE
  inline ::kj::StringTree toString() const {
    return ::capnp::_::structString(_reader, *_capnpPrivate::brand());
  }
#endif  // !CAPNP_LITE

  inline Which which() const;
  inline bool isSenderLoopback() const;
  inline  ::uint32_t getSenderLoopback() const;

  inline bool isReceiverLoopback() const;
  inline  ::uint32_t getReceiverLoopback() const;

  inline bool isAccept() const;
  inline  ::capnp::Void getAccept() const;

  inline bool isProvide() const;
  inline  ::uint32_t getProvide() const;

private:
  ::capnp::_::StructReader _reader;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::List;
  friend class ::capnp::MessageBuilder;
  friend class ::capnp::Orphanage;
};

class Disembargo::Context::Builder {
public:
  typedef Context Builds;

  Builder() = delete;  // Deleted to discourage incorrect usage.
                       // You can explicitly initialize to nullptr instead.
  inline Builder(decltype(nullptr)) {}
  inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
  inline operator Reader() const { return Reader(_builder.asReader()); }
  inline Reader asReader() const { return *this; }

  inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
#if !CAPNP_LITE
  inline ::kj::StringTree toString() const { return asReader().toString(); }
#endif  // !CAPNP_LITE

  inline Which which();
  inline bool isSenderLoopback();
  inline  ::uint32_t getSenderLoopback();
  inline void setSenderLoopback( ::uint32_t value);

  inline bool isReceiverLoopback();
  inline  ::uint32_t getReceiverLoopback();
  inline void setReceiverLoopback( ::uint32_t value);

  inline bool isAccept();
  inline  ::capnp::Void getAccept();
  inline void setAccept( ::capnp::Void value = ::capnp::VOID);

  inline bool isProvide();
  inline  ::uint32_t getProvide();
  inline void setProvide( ::uint32_t value);

private:
  ::capnp::_::StructBuilder _builder;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  friend class ::capnp::Orphanage;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
};

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

  inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
  inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
      : _typeless(kj::mv(typeless)) {}

private:
  ::capnp::AnyPointer::Pipeline _typeless;
  friend class ::capnp::PipelineHook;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
};
#endif  // !CAPNP_LITE

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

  Reader() = default;
  inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}

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

#if !CAPNP_LITE
  inline ::kj::StringTree toString() const {
    return ::capnp::_::structString(_reader, *_capnpPrivate::brand());
  }
#endif  // !CAPNP_LITE

  inline  ::uint32_t getQuestionId() const;

  inline bool hasTarget() const;
  inline  ::capnp::rpc::MessageTarget::Reader getTarget() const;

  inline bool hasRecipient() const;
  inline ::capnp::AnyPointer::Reader getRecipient() const;

private:
  ::capnp::_::StructReader _reader;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::List;
  friend class ::capnp::MessageBuilder;
  friend class ::capnp::Orphanage;
};

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

  Builder() = delete;  // Deleted to discourage incorrect usage.
                       // You can explicitly initialize to nullptr instead.
  inline Builder(decltype(nullptr)) {}
  inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
  inline operator Reader() const { return Reader(_builder.asReader()); }
  inline Reader asReader() const { return *this; }

  inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
#if !CAPNP_LITE
  inline ::kj::StringTree toString() const { return asReader().toString(); }
#endif  // !CAPNP_LITE

  inline  ::uint32_t getQuestionId();
  inline void setQuestionId( ::uint32_t value);

  inline bool hasTarget();
  inline  ::capnp::rpc::MessageTarget::Builder getTarget();
  inline void setTarget( ::capnp::rpc::MessageTarget::Reader value);
  inline  ::capnp::rpc::MessageTarget::Builder initTarget();
  inline void adoptTarget(::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value);
  inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> disownTarget();

  inline bool hasRecipient();
  inline ::capnp::AnyPointer::Builder getRecipient();
  inline ::capnp::AnyPointer::Builder initRecipient();

private:
  ::capnp::_::StructBuilder _builder;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  friend class ::capnp::Orphanage;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
};

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

  inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
  inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
      : _typeless(kj::mv(typeless)) {}

  inline  ::capnp::rpc::MessageTarget::Pipeline getTarget();
private:
  ::capnp::AnyPointer::Pipeline _typeless;
  friend class ::capnp::PipelineHook;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
};
#endif  // !CAPNP_LITE

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

  Reader() = default;
  inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}

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

#if !CAPNP_LITE
  inline ::kj::StringTree toString() const {
    return ::capnp::_::structString(_reader, *_capnpPrivate::brand());
  }
#endif  // !CAPNP_LITE

  inline  ::uint32_t getQuestionId() const;

  inline bool hasProvision() const;
  inline ::capnp::AnyPointer::Reader getProvision() const;

  inline bool getEmbargo() const;

private:
  ::capnp::_::StructReader _reader;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::List;
  friend class ::capnp::MessageBuilder;
  friend class ::capnp::Orphanage;
};

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

  Builder() = delete;  // Deleted to discourage incorrect usage.
                       // You can explicitly initialize to nullptr instead.
  inline Builder(decltype(nullptr)) {}
  inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
  inline operator Reader() const { return Reader(_builder.asReader()); }
  inline Reader asReader() const { return *this; }

  inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
#if !CAPNP_LITE
  inline ::kj::StringTree toString() const { return asReader().toString(); }
#endif  // !CAPNP_LITE

  inline  ::uint32_t getQuestionId();
  inline void setQuestionId( ::uint32_t value);

  inline bool hasProvision();
  inline ::capnp::AnyPointer::Builder getProvision();
  inline ::capnp::AnyPointer::Builder initProvision();

  inline bool getEmbargo();
  inline void setEmbargo(bool value);

private:
  ::capnp::_::StructBuilder _builder;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  friend class ::capnp::Orphanage;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
};

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

  inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
  inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
      : _typeless(kj::mv(typeless)) {}

private:
  ::capnp::AnyPointer::Pipeline _typeless;
  friend class ::capnp::PipelineHook;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
};
#endif  // !CAPNP_LITE

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

  Reader() = default;
  inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}

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

#if !CAPNP_LITE
  inline ::kj::StringTree toString() const {
    return ::capnp::_::structString(_reader, *_capnpPrivate::brand());
  }
#endif  // !CAPNP_LITE

  inline  ::uint32_t getQuestionId() const;

  inline bool hasTarget() const;
  inline  ::capnp::rpc::MessageTarget::Reader getTarget() const;

  inline bool hasKeyPart() const;
  inline ::capnp::AnyPointer::Reader getKeyPart() const;

private:
  ::capnp::_::StructReader _reader;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::List;
  friend class ::capnp::MessageBuilder;
  friend class ::capnp::Orphanage;
};

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

  Builder() = delete;  // Deleted to discourage incorrect usage.
                       // You can explicitly initialize to nullptr instead.
  inline Builder(decltype(nullptr)) {}
  inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
  inline operator Reader() const { return Reader(_builder.asReader()); }
  inline Reader asReader() const { return *this; }

  inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
#if !CAPNP_LITE
  inline ::kj::StringTree toString() const { return asReader().toString(); }
#endif  // !CAPNP_LITE

  inline  ::uint32_t getQuestionId();
  inline void setQuestionId( ::uint32_t value);

  inline bool hasTarget();
  inline  ::capnp::rpc::MessageTarget::Builder getTarget();
  inline void setTarget( ::capnp::rpc::MessageTarget::Reader value);
  inline  ::capnp::rpc::MessageTarget::Builder initTarget();
  inline void adoptTarget(::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value);
  inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> disownTarget();

  inline bool hasKeyPart();
  inline ::capnp::AnyPointer::Builder getKeyPart();
  inline ::capnp::AnyPointer::Builder initKeyPart();

private:
  ::capnp::_::StructBuilder _builder;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  friend class ::capnp::Orphanage;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
};

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

  inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
  inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
      : _typeless(kj::mv(typeless)) {}

  inline  ::capnp::rpc::MessageTarget::Pipeline getTarget();
private:
  ::capnp::AnyPointer::Pipeline _typeless;
  friend class ::capnp::PipelineHook;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
};
#endif  // !CAPNP_LITE

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

  Reader() = default;
  inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}

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

#if !CAPNP_LITE
  inline ::kj::StringTree toString() const {
    return ::capnp::_::structString(_reader, *_capnpPrivate::brand());
  }
#endif  // !CAPNP_LITE

  inline Which which() const;
  inline bool isImportedCap() const;
  inline  ::uint32_t getImportedCap() const;

  inline bool isPromisedAnswer() const;
  inline bool hasPromisedAnswer() const;
  inline  ::capnp::rpc::PromisedAnswer::Reader getPromisedAnswer() const;

private:
  ::capnp::_::StructReader _reader;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::List;
  friend class ::capnp::MessageBuilder;
  friend class ::capnp::Orphanage;
};

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

  Builder() = delete;  // Deleted to discourage incorrect usage.
                       // You can explicitly initialize to nullptr instead.
  inline Builder(decltype(nullptr)) {}
  inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
  inline operator Reader() const { return Reader(_builder.asReader()); }
  inline Reader asReader() const { return *this; }

  inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
#if !CAPNP_LITE
  inline ::kj::StringTree toString() const { return asReader().toString(); }
#endif  // !CAPNP_LITE

  inline Which which();
  inline bool isImportedCap();
  inline  ::uint32_t getImportedCap();
  inline void setImportedCap( ::uint32_t value);

  inline bool isPromisedAnswer();
  inline bool hasPromisedAnswer();
  inline  ::capnp::rpc::PromisedAnswer::Builder getPromisedAnswer();
  inline void setPromisedAnswer( ::capnp::rpc::PromisedAnswer::Reader value);
  inline  ::capnp::rpc::PromisedAnswer::Builder initPromisedAnswer();
  inline void adoptPromisedAnswer(::capnp::Orphan< ::capnp::rpc::PromisedAnswer>&& value);
  inline ::capnp::Orphan< ::capnp::rpc::PromisedAnswer> disownPromisedAnswer();

private:
  ::capnp::_::StructBuilder _builder;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  friend class ::capnp::Orphanage;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
};

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

  inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
  inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
      : _typeless(kj::mv(typeless)) {}

private:
  ::capnp::AnyPointer::Pipeline _typeless;
  friend class ::capnp::PipelineHook;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
};
#endif  // !CAPNP_LITE

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

  Reader() = default;
  inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}

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

#if !CAPNP_LITE
  inline ::kj::StringTree toString() const {
    return ::capnp::_::structString(_reader, *_capnpPrivate::brand());
  }
#endif  // !CAPNP_LITE

  inline bool hasContent() const;
  inline ::capnp::AnyPointer::Reader getContent() const;

  inline bool hasCapTable() const;
  inline  ::capnp::List< ::capnp::rpc::CapDescriptor,  ::capnp::Kind::STRUCT>::Reader getCapTable() const;

private:
  ::capnp::_::StructReader _reader;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::List;
  friend class ::capnp::MessageBuilder;
  friend class ::capnp::Orphanage;
};

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

  Builder() = delete;  // Deleted to discourage incorrect usage.
                       // You can explicitly initialize to nullptr instead.
  inline Builder(decltype(nullptr)) {}
  inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
  inline operator Reader() const { return Reader(_builder.asReader()); }
  inline Reader asReader() const { return *this; }

  inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
#if !CAPNP_LITE
  inline ::kj::StringTree toString() const { return asReader().toString(); }
#endif  // !CAPNP_LITE

  inline bool hasContent();
  inline ::capnp::AnyPointer::Builder getContent();
  inline ::capnp::AnyPointer::Builder initContent();

  inline bool hasCapTable();
  inline  ::capnp::List< ::capnp::rpc::CapDescriptor,  ::capnp::Kind::STRUCT>::Builder getCapTable();
  inline void setCapTable( ::capnp::List< ::capnp::rpc::CapDescriptor,  ::capnp::Kind::STRUCT>::Reader value);
  inline  ::capnp::List< ::capnp::rpc::CapDescriptor,  ::capnp::Kind::STRUCT>::Builder initCapTable(unsigned int size);
  inline void adoptCapTable(::capnp::Orphan< ::capnp::List< ::capnp::rpc::CapDescriptor,  ::capnp::Kind::STRUCT>>&& value);
  inline ::capnp::Orphan< ::capnp::List< ::capnp::rpc::CapDescriptor,  ::capnp::Kind::STRUCT>> disownCapTable();

private:
  ::capnp::_::StructBuilder _builder;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  friend class ::capnp::Orphanage;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
};

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

  inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
  inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
      : _typeless(kj::mv(typeless)) {}

private:
  ::capnp::AnyPointer::Pipeline _typeless;
  friend class ::capnp::PipelineHook;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
};
#endif  // !CAPNP_LITE

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

  Reader() = default;
  inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}

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

#if !CAPNP_LITE
  inline ::kj::StringTree toString() const {
    return ::capnp::_::structString(_reader, *_capnpPrivate::brand());
  }
#endif  // !CAPNP_LITE

  inline Which which() const;
  inline bool isNone() const;
  inline  ::capnp::Void getNone() const;

  inline bool isSenderHosted() const;
  inline  ::uint32_t getSenderHosted() const;

  inline bool isSenderPromise() const;
  inline  ::uint32_t getSenderPromise() const;

  inline bool isReceiverHosted() const;
  inline  ::uint32_t getReceiverHosted() const;

  inline bool isReceiverAnswer() const;
  inline bool hasReceiverAnswer() const;
  inline  ::capnp::rpc::PromisedAnswer::Reader getReceiverAnswer() const;

  inline bool isThirdPartyHosted() const;
  inline bool hasThirdPartyHosted() const;
  inline  ::capnp::rpc::ThirdPartyCapDescriptor::Reader getThirdPartyHosted() const;

  inline  ::uint8_t getAttachedFd() const;

private:
  ::capnp::_::StructReader _reader;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::List;
  friend class ::capnp::MessageBuilder;
  friend class ::capnp::Orphanage;
};

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

  Builder() = delete;  // Deleted to discourage incorrect usage.
                       // You can explicitly initialize to nullptr instead.
  inline Builder(decltype(nullptr)) {}
  inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
  inline operator Reader() const { return Reader(_builder.asReader()); }
  inline Reader asReader() const { return *this; }

  inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
#if !CAPNP_LITE
  inline ::kj::StringTree toString() const { return asReader().toString(); }
#endif  // !CAPNP_LITE

  inline Which which();
  inline bool isNone();
  inline  ::capnp::Void getNone();
  inline void setNone( ::capnp::Void value = ::capnp::VOID);

  inline bool isSenderHosted();
  inline  ::uint32_t getSenderHosted();
  inline void setSenderHosted( ::uint32_t value);

  inline bool isSenderPromise();
  inline  ::uint32_t getSenderPromise();
  inline void setSenderPromise( ::uint32_t value);

  inline bool isReceiverHosted();
  inline  ::uint32_t getReceiverHosted();
  inline void setReceiverHosted( ::uint32_t value);

  inline bool isReceiverAnswer();
  inline bool hasReceiverAnswer();
  inline  ::capnp::rpc::PromisedAnswer::Builder getReceiverAnswer();
  inline void setReceiverAnswer( ::capnp::rpc::PromisedAnswer::Reader value);
  inline  ::capnp::rpc::PromisedAnswer::Builder initReceiverAnswer();
  inline void adoptReceiverAnswer(::capnp::Orphan< ::capnp::rpc::PromisedAnswer>&& value);
  inline ::capnp::Orphan< ::capnp::rpc::PromisedAnswer> disownReceiverAnswer();

  inline bool isThirdPartyHosted();
  inline bool hasThirdPartyHosted();
  inline  ::capnp::rpc::ThirdPartyCapDescriptor::Builder getThirdPartyHosted();
  inline void setThirdPartyHosted( ::capnp::rpc::ThirdPartyCapDescriptor::Reader value);
  inline  ::capnp::rpc::ThirdPartyCapDescriptor::Builder initThirdPartyHosted();
  inline void adoptThirdPartyHosted(::capnp::Orphan< ::capnp::rpc::ThirdPartyCapDescriptor>&& value);
  inline ::capnp::Orphan< ::capnp::rpc::ThirdPartyCapDescriptor> disownThirdPartyHosted();

  inline  ::uint8_t getAttachedFd();
  inline void setAttachedFd( ::uint8_t value);

private:
  ::capnp::_::StructBuilder _builder;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  friend class ::capnp::Orphanage;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
};

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

  inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
  inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
      : _typeless(kj::mv(typeless)) {}

private:
  ::capnp::AnyPointer::Pipeline _typeless;
  friend class ::capnp::PipelineHook;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
};
#endif  // !CAPNP_LITE

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

  Reader() = default;
  inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}

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

#if !CAPNP_LITE
  inline ::kj::StringTree toString() const {
    return ::capnp::_::structString(_reader, *_capnpPrivate::brand());
  }
#endif  // !CAPNP_LITE

  inline  ::uint32_t getQuestionId() const;

  inline bool hasTransform() const;
  inline  ::capnp::List< ::capnp::rpc::PromisedAnswer::Op,  ::capnp::Kind::STRUCT>::Reader getTransform() const;

private:
  ::capnp::_::StructReader _reader;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::List;
  friend class ::capnp::MessageBuilder;
  friend class ::capnp::Orphanage;
};

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

  Builder() = delete;  // Deleted to discourage incorrect usage.
                       // You can explicitly initialize to nullptr instead.
  inline Builder(decltype(nullptr)) {}
  inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
  inline operator Reader() const { return Reader(_builder.asReader()); }
  inline Reader asReader() const { return *this; }

  inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
#if !CAPNP_LITE
  inline ::kj::StringTree toString() const { return asReader().toString(); }
#endif  // !CAPNP_LITE

  inline  ::uint32_t getQuestionId();
  inline void setQuestionId( ::uint32_t value);

  inline bool hasTransform();
  inline  ::capnp::List< ::capnp::rpc::PromisedAnswer::Op,  ::capnp::Kind::STRUCT>::Builder getTransform();
  inline void setTransform( ::capnp::List< ::capnp::rpc::PromisedAnswer::Op,  ::capnp::Kind::STRUCT>::Reader value);
  inline  ::capnp::List< ::capnp::rpc::PromisedAnswer::Op,  ::capnp::Kind::STRUCT>::Builder initTransform(unsigned int size);
  inline void adoptTransform(::capnp::Orphan< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op,  ::capnp::Kind::STRUCT>>&& value);
  inline ::capnp::Orphan< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op,  ::capnp::Kind::STRUCT>> disownTransform();

private:
  ::capnp::_::StructBuilder _builder;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  friend class ::capnp::Orphanage;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
};

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

  inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
  inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
      : _typeless(kj::mv(typeless)) {}

private:
  ::capnp::AnyPointer::Pipeline _typeless;
  friend class ::capnp::PipelineHook;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
};
#endif  // !CAPNP_LITE

class PromisedAnswer::Op::Reader {
public:
  typedef Op Reads;

  Reader() = default;
  inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}

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

#if !CAPNP_LITE
  inline ::kj::StringTree toString() const {
    return ::capnp::_::structString(_reader, *_capnpPrivate::brand());
  }
#endif  // !CAPNP_LITE

  inline Which which() const;
  inline bool isNoop() const;
  inline  ::capnp::Void getNoop() const;

  inline bool isGetPointerField() const;
  inline  ::uint16_t getGetPointerField() const;

private:
  ::capnp::_::StructReader _reader;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::List;
  friend class ::capnp::MessageBuilder;
  friend class ::capnp::Orphanage;
};

class PromisedAnswer::Op::Builder {
public:
  typedef Op Builds;

  Builder() = delete;  // Deleted to discourage incorrect usage.
                       // You can explicitly initialize to nullptr instead.
  inline Builder(decltype(nullptr)) {}
  inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
  inline operator Reader() const { return Reader(_builder.asReader()); }
  inline Reader asReader() const { return *this; }

  inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
#if !CAPNP_LITE
  inline ::kj::StringTree toString() const { return asReader().toString(); }
#endif  // !CAPNP_LITE

  inline Which which();
  inline bool isNoop();
  inline  ::capnp::Void getNoop();
  inline void setNoop( ::capnp::Void value = ::capnp::VOID);

  inline bool isGetPointerField();
  inline  ::uint16_t getGetPointerField();
  inline void setGetPointerField( ::uint16_t value);

private:
  ::capnp::_::StructBuilder _builder;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  friend class ::capnp::Orphanage;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
};

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

  inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
  inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
      : _typeless(kj::mv(typeless)) {}

private:
  ::capnp::AnyPointer::Pipeline _typeless;
  friend class ::capnp::PipelineHook;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
};
#endif  // !CAPNP_LITE

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

  Reader() = default;
  inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}

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

#if !CAPNP_LITE
  inline ::kj::StringTree toString() const {
    return ::capnp::_::structString(_reader, *_capnpPrivate::brand());
  }
#endif  // !CAPNP_LITE

  inline bool hasId() const;
  inline ::capnp::AnyPointer::Reader getId() const;

  inline  ::uint32_t getVineId() const;

private:
  ::capnp::_::StructReader _reader;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::List;
  friend class ::capnp::MessageBuilder;
  friend class ::capnp::Orphanage;
};

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

  Builder() = delete;  // Deleted to discourage incorrect usage.
                       // You can explicitly initialize to nullptr instead.
  inline Builder(decltype(nullptr)) {}
  inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
  inline operator Reader() const { return Reader(_builder.asReader()); }
  inline Reader asReader() const { return *this; }

  inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
#if !CAPNP_LITE
  inline ::kj::StringTree toString() const { return asReader().toString(); }
#endif  // !CAPNP_LITE

  inline bool hasId();
  inline ::capnp::AnyPointer::Builder getId();
  inline ::capnp::AnyPointer::Builder initId();

  inline  ::uint32_t getVineId();
  inline void setVineId( ::uint32_t value);

private:
  ::capnp::_::StructBuilder _builder;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  friend class ::capnp::Orphanage;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
};

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

  inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
  inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
      : _typeless(kj::mv(typeless)) {}

private:
  ::capnp::AnyPointer::Pipeline _typeless;
  friend class ::capnp::PipelineHook;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
};
#endif  // !CAPNP_LITE

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

  Reader() = default;
  inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}

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

#if !CAPNP_LITE
  inline ::kj::StringTree toString() const {
    return ::capnp::_::structString(_reader, *_capnpPrivate::brand());
  }
#endif  // !CAPNP_LITE

  inline bool hasReason() const;
  inline  ::capnp::Text::Reader getReason() const;

  inline bool getObsoleteIsCallersFault() const;

  inline  ::uint16_t getObsoleteDurability() const;

  inline  ::capnp::rpc::Exception::Type getType() const;

  inline bool hasTrace() const;
  inline  ::capnp::Text::Reader getTrace() const;

private:
  ::capnp::_::StructReader _reader;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::List;
  friend class ::capnp::MessageBuilder;
  friend class ::capnp::Orphanage;
};

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

  Builder() = delete;  // Deleted to discourage incorrect usage.
                       // You can explicitly initialize to nullptr instead.
  inline Builder(decltype(nullptr)) {}
  inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
  inline operator Reader() const { return Reader(_builder.asReader()); }
  inline Reader asReader() const { return *this; }

  inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
#if !CAPNP_LITE
  inline ::kj::StringTree toString() const { return asReader().toString(); }
#endif  // !CAPNP_LITE

  inline bool hasReason();
  inline  ::capnp::Text::Builder getReason();
  inline void setReason( ::capnp::Text::Reader value);
  inline  ::capnp::Text::Builder initReason(unsigned int size);
  inline void adoptReason(::capnp::Orphan< ::capnp::Text>&& value);
  inline ::capnp::Orphan< ::capnp::Text> disownReason();

  inline bool getObsoleteIsCallersFault();
  inline void setObsoleteIsCallersFault(bool value);

  inline  ::uint16_t getObsoleteDurability();
  inline void setObsoleteDurability( ::uint16_t value);

  inline  ::capnp::rpc::Exception::Type getType();
  inline void setType( ::capnp::rpc::Exception::Type value);

  inline bool hasTrace();
  inline  ::capnp::Text::Builder getTrace();
  inline void setTrace( ::capnp::Text::Reader value);
  inline  ::capnp::Text::Builder initTrace(unsigned int size);
  inline void adoptTrace(::capnp::Orphan< ::capnp::Text>&& value);
  inline ::capnp::Orphan< ::capnp::Text> disownTrace();

private:
  ::capnp::_::StructBuilder _builder;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  friend class ::capnp::Orphanage;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
};

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

  inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
  inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
      : _typeless(kj::mv(typeless)) {}

private:
  ::capnp::AnyPointer::Pipeline _typeless;
  friend class ::capnp::PipelineHook;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
};
#endif  // !CAPNP_LITE

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

inline  ::capnp::rpc::Message::Which Message::Reader::which() const {
  return _reader.getDataField<Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline  ::capnp::rpc::Message::Which Message::Builder::which() {
  return _builder.getDataField<Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}

inline bool Message::Reader::isUnimplemented() const {
  return which() == Message::UNIMPLEMENTED;
}
inline bool Message::Builder::isUnimplemented() {
  return which() == Message::UNIMPLEMENTED;
}
inline bool Message::Reader::hasUnimplemented() const {
  if (which() != Message::UNIMPLEMENTED) return false;
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Message::Builder::hasUnimplemented() {
  if (which() != Message::UNIMPLEMENTED) return false;
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::rpc::Message::Reader Message::Reader::getUnimplemented() const {
  KJ_IREQUIRE((which() == Message::UNIMPLEMENTED),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Message>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::rpc::Message::Builder Message::Builder::getUnimplemented() {
  KJ_IREQUIRE((which() == Message::UNIMPLEMENTED),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Message>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Message::Builder::setUnimplemented( ::capnp::rpc::Message::Reader value) {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::UNIMPLEMENTED);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Message>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::rpc::Message::Builder Message::Builder::initUnimplemented() {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::UNIMPLEMENTED);
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Message>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Message::Builder::adoptUnimplemented(
    ::capnp::Orphan< ::capnp::rpc::Message>&& value) {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::UNIMPLEMENTED);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Message>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::rpc::Message> Message::Builder::disownUnimplemented() {
  KJ_IREQUIRE((which() == Message::UNIMPLEMENTED),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Message>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline bool Message::Reader::isAbort() const {
  return which() == Message::ABORT;
}
inline bool Message::Builder::isAbort() {
  return which() == Message::ABORT;
}
inline bool Message::Reader::hasAbort() const {
  if (which() != Message::ABORT) return false;
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Message::Builder::hasAbort() {
  if (which() != Message::ABORT) return false;
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::rpc::Exception::Reader Message::Reader::getAbort() const {
  KJ_IREQUIRE((which() == Message::ABORT),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::rpc::Exception::Builder Message::Builder::getAbort() {
  KJ_IREQUIRE((which() == Message::ABORT),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Message::Builder::setAbort( ::capnp::rpc::Exception::Reader value) {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::ABORT);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::rpc::Exception::Builder Message::Builder::initAbort() {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::ABORT);
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Message::Builder::adoptAbort(
    ::capnp::Orphan< ::capnp::rpc::Exception>&& value) {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::ABORT);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::rpc::Exception> Message::Builder::disownAbort() {
  KJ_IREQUIRE((which() == Message::ABORT),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline bool Message::Reader::isCall() const {
  return which() == Message::CALL;
}
inline bool Message::Builder::isCall() {
  return which() == Message::CALL;
}
inline bool Message::Reader::hasCall() const {
  if (which() != Message::CALL) return false;
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Message::Builder::hasCall() {
  if (which() != Message::CALL) return false;
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::rpc::Call::Reader Message::Reader::getCall() const {
  KJ_IREQUIRE((which() == Message::CALL),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Call>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::rpc::Call::Builder Message::Builder::getCall() {
  KJ_IREQUIRE((which() == Message::CALL),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Call>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Message::Builder::setCall( ::capnp::rpc::Call::Reader value) {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::CALL);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Call>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::rpc::Call::Builder Message::Builder::initCall() {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::CALL);
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Call>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Message::Builder::adoptCall(
    ::capnp::Orphan< ::capnp::rpc::Call>&& value) {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::CALL);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Call>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::rpc::Call> Message::Builder::disownCall() {
  KJ_IREQUIRE((which() == Message::CALL),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Call>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline bool Message::Reader::isReturn() const {
  return which() == Message::RETURN;
}
inline bool Message::Builder::isReturn() {
  return which() == Message::RETURN;
}
inline bool Message::Reader::hasReturn() const {
  if (which() != Message::RETURN) return false;
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Message::Builder::hasReturn() {
  if (which() != Message::RETURN) return false;
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::rpc::Return::Reader Message::Reader::getReturn() const {
  KJ_IREQUIRE((which() == Message::RETURN),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Return>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::rpc::Return::Builder Message::Builder::getReturn() {
  KJ_IREQUIRE((which() == Message::RETURN),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Return>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Message::Builder::setReturn( ::capnp::rpc::Return::Reader value) {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::RETURN);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Return>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::rpc::Return::Builder Message::Builder::initReturn() {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::RETURN);
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Return>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Message::Builder::adoptReturn(
    ::capnp::Orphan< ::capnp::rpc::Return>&& value) {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::RETURN);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Return>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::rpc::Return> Message::Builder::disownReturn() {
  KJ_IREQUIRE((which() == Message::RETURN),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Return>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline bool Message::Reader::isFinish() const {
  return which() == Message::FINISH;
}
inline bool Message::Builder::isFinish() {
  return which() == Message::FINISH;
}
inline bool Message::Reader::hasFinish() const {
  if (which() != Message::FINISH) return false;
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Message::Builder::hasFinish() {
  if (which() != Message::FINISH) return false;
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::rpc::Finish::Reader Message::Reader::getFinish() const {
  KJ_IREQUIRE((which() == Message::FINISH),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Finish>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::rpc::Finish::Builder Message::Builder::getFinish() {
  KJ_IREQUIRE((which() == Message::FINISH),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Finish>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Message::Builder::setFinish( ::capnp::rpc::Finish::Reader value) {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::FINISH);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Finish>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::rpc::Finish::Builder Message::Builder::initFinish() {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::FINISH);
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Finish>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Message::Builder::adoptFinish(
    ::capnp::Orphan< ::capnp::rpc::Finish>&& value) {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::FINISH);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Finish>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::rpc::Finish> Message::Builder::disownFinish() {
  KJ_IREQUIRE((which() == Message::FINISH),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Finish>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline bool Message::Reader::isResolve() const {
  return which() == Message::RESOLVE;
}
inline bool Message::Builder::isResolve() {
  return which() == Message::RESOLVE;
}
inline bool Message::Reader::hasResolve() const {
  if (which() != Message::RESOLVE) return false;
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Message::Builder::hasResolve() {
  if (which() != Message::RESOLVE) return false;
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::rpc::Resolve::Reader Message::Reader::getResolve() const {
  KJ_IREQUIRE((which() == Message::RESOLVE),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Resolve>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::rpc::Resolve::Builder Message::Builder::getResolve() {
  KJ_IREQUIRE((which() == Message::RESOLVE),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Resolve>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Message::Builder::setResolve( ::capnp::rpc::Resolve::Reader value) {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::RESOLVE);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Resolve>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::rpc::Resolve::Builder Message::Builder::initResolve() {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::RESOLVE);
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Resolve>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Message::Builder::adoptResolve(
    ::capnp::Orphan< ::capnp::rpc::Resolve>&& value) {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::RESOLVE);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Resolve>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::rpc::Resolve> Message::Builder::disownResolve() {
  KJ_IREQUIRE((which() == Message::RESOLVE),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Resolve>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline bool Message::Reader::isRelease() const {
  return which() == Message::RELEASE;
}
inline bool Message::Builder::isRelease() {
  return which() == Message::RELEASE;
}
inline bool Message::Reader::hasRelease() const {
  if (which() != Message::RELEASE) return false;
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Message::Builder::hasRelease() {
  if (which() != Message::RELEASE) return false;
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::rpc::Release::Reader Message::Reader::getRelease() const {
  KJ_IREQUIRE((which() == Message::RELEASE),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Release>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::rpc::Release::Builder Message::Builder::getRelease() {
  KJ_IREQUIRE((which() == Message::RELEASE),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Release>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Message::Builder::setRelease( ::capnp::rpc::Release::Reader value) {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::RELEASE);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Release>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::rpc::Release::Builder Message::Builder::initRelease() {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::RELEASE);
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Release>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Message::Builder::adoptRelease(
    ::capnp::Orphan< ::capnp::rpc::Release>&& value) {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::RELEASE);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Release>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::rpc::Release> Message::Builder::disownRelease() {
  KJ_IREQUIRE((which() == Message::RELEASE),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Release>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline bool Message::Reader::isObsoleteSave() const {
  return which() == Message::OBSOLETE_SAVE;
}
inline bool Message::Builder::isObsoleteSave() {
  return which() == Message::OBSOLETE_SAVE;
}
inline bool Message::Reader::hasObsoleteSave() const {
  if (which() != Message::OBSOLETE_SAVE) return false;
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Message::Builder::hasObsoleteSave() {
  if (which() != Message::OBSOLETE_SAVE) return false;
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline ::capnp::AnyPointer::Reader Message::Reader::getObsoleteSave() const {
  KJ_IREQUIRE((which() == Message::OBSOLETE_SAVE),
              "Must check which() before get()ing a union member.");
  return ::capnp::AnyPointer::Reader(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline ::capnp::AnyPointer::Builder Message::Builder::getObsoleteSave() {
  KJ_IREQUIRE((which() == Message::OBSOLETE_SAVE),
              "Must check which() before get()ing a union member.");
  return ::capnp::AnyPointer::Builder(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline ::capnp::AnyPointer::Builder Message::Builder::initObsoleteSave() {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::OBSOLETE_SAVE);
  auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
  result.clear();
  return result;
}

inline bool Message::Reader::isBootstrap() const {
  return which() == Message::BOOTSTRAP;
}
inline bool Message::Builder::isBootstrap() {
  return which() == Message::BOOTSTRAP;
}
inline bool Message::Reader::hasBootstrap() const {
  if (which() != Message::BOOTSTRAP) return false;
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Message::Builder::hasBootstrap() {
  if (which() != Message::BOOTSTRAP) return false;
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::rpc::Bootstrap::Reader Message::Reader::getBootstrap() const {
  KJ_IREQUIRE((which() == Message::BOOTSTRAP),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Bootstrap>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::rpc::Bootstrap::Builder Message::Builder::getBootstrap() {
  KJ_IREQUIRE((which() == Message::BOOTSTRAP),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Bootstrap>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Message::Builder::setBootstrap( ::capnp::rpc::Bootstrap::Reader value) {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::BOOTSTRAP);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Bootstrap>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::rpc::Bootstrap::Builder Message::Builder::initBootstrap() {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::BOOTSTRAP);
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Bootstrap>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Message::Builder::adoptBootstrap(
    ::capnp::Orphan< ::capnp::rpc::Bootstrap>&& value) {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::BOOTSTRAP);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Bootstrap>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::rpc::Bootstrap> Message::Builder::disownBootstrap() {
  KJ_IREQUIRE((which() == Message::BOOTSTRAP),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Bootstrap>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline bool Message::Reader::isObsoleteDelete() const {
  return which() == Message::OBSOLETE_DELETE;
}
inline bool Message::Builder::isObsoleteDelete() {
  return which() == Message::OBSOLETE_DELETE;
}
inline bool Message::Reader::hasObsoleteDelete() const {
  if (which() != Message::OBSOLETE_DELETE) return false;
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Message::Builder::hasObsoleteDelete() {
  if (which() != Message::OBSOLETE_DELETE) return false;
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline ::capnp::AnyPointer::Reader Message::Reader::getObsoleteDelete() const {
  KJ_IREQUIRE((which() == Message::OBSOLETE_DELETE),
              "Must check which() before get()ing a union member.");
  return ::capnp::AnyPointer::Reader(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline ::capnp::AnyPointer::Builder Message::Builder::getObsoleteDelete() {
  KJ_IREQUIRE((which() == Message::OBSOLETE_DELETE),
              "Must check which() before get()ing a union member.");
  return ::capnp::AnyPointer::Builder(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline ::capnp::AnyPointer::Builder Message::Builder::initObsoleteDelete() {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::OBSOLETE_DELETE);
  auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
  result.clear();
  return result;
}

inline bool Message::Reader::isProvide() const {
  return which() == Message::PROVIDE;
}
inline bool Message::Builder::isProvide() {
  return which() == Message::PROVIDE;
}
inline bool Message::Reader::hasProvide() const {
  if (which() != Message::PROVIDE) return false;
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Message::Builder::hasProvide() {
  if (which() != Message::PROVIDE) return false;
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::rpc::Provide::Reader Message::Reader::getProvide() const {
  KJ_IREQUIRE((which() == Message::PROVIDE),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Provide>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::rpc::Provide::Builder Message::Builder::getProvide() {
  KJ_IREQUIRE((which() == Message::PROVIDE),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Provide>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Message::Builder::setProvide( ::capnp::rpc::Provide::Reader value) {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::PROVIDE);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Provide>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::rpc::Provide::Builder Message::Builder::initProvide() {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::PROVIDE);
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Provide>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Message::Builder::adoptProvide(
    ::capnp::Orphan< ::capnp::rpc::Provide>&& value) {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::PROVIDE);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Provide>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::rpc::Provide> Message::Builder::disownProvide() {
  KJ_IREQUIRE((which() == Message::PROVIDE),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Provide>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline bool Message::Reader::isAccept() const {
  return which() == Message::ACCEPT;
}
inline bool Message::Builder::isAccept() {
  return which() == Message::ACCEPT;
}
inline bool Message::Reader::hasAccept() const {
  if (which() != Message::ACCEPT) return false;
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Message::Builder::hasAccept() {
  if (which() != Message::ACCEPT) return false;
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::rpc::Accept::Reader Message::Reader::getAccept() const {
  KJ_IREQUIRE((which() == Message::ACCEPT),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Accept>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::rpc::Accept::Builder Message::Builder::getAccept() {
  KJ_IREQUIRE((which() == Message::ACCEPT),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Accept>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Message::Builder::setAccept( ::capnp::rpc::Accept::Reader value) {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::ACCEPT);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Accept>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::rpc::Accept::Builder Message::Builder::initAccept() {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::ACCEPT);
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Accept>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Message::Builder::adoptAccept(
    ::capnp::Orphan< ::capnp::rpc::Accept>&& value) {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::ACCEPT);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Accept>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::rpc::Accept> Message::Builder::disownAccept() {
  KJ_IREQUIRE((which() == Message::ACCEPT),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Accept>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline bool Message::Reader::isJoin() const {
  return which() == Message::JOIN;
}
inline bool Message::Builder::isJoin() {
  return which() == Message::JOIN;
}
inline bool Message::Reader::hasJoin() const {
  if (which() != Message::JOIN) return false;
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Message::Builder::hasJoin() {
  if (which() != Message::JOIN) return false;
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::rpc::Join::Reader Message::Reader::getJoin() const {
  KJ_IREQUIRE((which() == Message::JOIN),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Join>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::rpc::Join::Builder Message::Builder::getJoin() {
  KJ_IREQUIRE((which() == Message::JOIN),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Join>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Message::Builder::setJoin( ::capnp::rpc::Join::Reader value) {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::JOIN);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Join>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::rpc::Join::Builder Message::Builder::initJoin() {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::JOIN);
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Join>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Message::Builder::adoptJoin(
    ::capnp::Orphan< ::capnp::rpc::Join>&& value) {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::JOIN);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Join>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::rpc::Join> Message::Builder::disownJoin() {
  KJ_IREQUIRE((which() == Message::JOIN),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Join>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline bool Message::Reader::isDisembargo() const {
  return which() == Message::DISEMBARGO;
}
inline bool Message::Builder::isDisembargo() {
  return which() == Message::DISEMBARGO;
}
inline bool Message::Reader::hasDisembargo() const {
  if (which() != Message::DISEMBARGO) return false;
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Message::Builder::hasDisembargo() {
  if (which() != Message::DISEMBARGO) return false;
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::rpc::Disembargo::Reader Message::Reader::getDisembargo() const {
  KJ_IREQUIRE((which() == Message::DISEMBARGO),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Disembargo>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::rpc::Disembargo::Builder Message::Builder::getDisembargo() {
  KJ_IREQUIRE((which() == Message::DISEMBARGO),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Disembargo>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Message::Builder::setDisembargo( ::capnp::rpc::Disembargo::Reader value) {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::DISEMBARGO);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Disembargo>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::rpc::Disembargo::Builder Message::Builder::initDisembargo() {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::DISEMBARGO);
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Disembargo>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Message::Builder::adoptDisembargo(
    ::capnp::Orphan< ::capnp::rpc::Disembargo>&& value) {
  _builder.setDataField<Message::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::DISEMBARGO);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Disembargo>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::rpc::Disembargo> Message::Builder::disownDisembargo() {
  KJ_IREQUIRE((which() == Message::DISEMBARGO),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Disembargo>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline  ::uint32_t Bootstrap::Reader::getQuestionId() const {
  return _reader.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}

inline  ::uint32_t Bootstrap::Builder::getQuestionId() {
  return _builder.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline void Bootstrap::Builder::setQuestionId( ::uint32_t value) {
  _builder.setDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, value);
}

inline bool Bootstrap::Reader::hasDeprecatedObjectId() const {
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Bootstrap::Builder::hasDeprecatedObjectId() {
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline ::capnp::AnyPointer::Reader Bootstrap::Reader::getDeprecatedObjectId() const {
  return ::capnp::AnyPointer::Reader(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline ::capnp::AnyPointer::Builder Bootstrap::Builder::getDeprecatedObjectId() {
  return ::capnp::AnyPointer::Builder(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline ::capnp::AnyPointer::Builder Bootstrap::Builder::initDeprecatedObjectId() {
  auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
  result.clear();
  return result;
}

inline  ::uint32_t Call::Reader::getQuestionId() const {
  return _reader.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}

inline  ::uint32_t Call::Builder::getQuestionId() {
  return _builder.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline void Call::Builder::setQuestionId( ::uint32_t value) {
  _builder.setDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, value);
}

inline bool Call::Reader::hasTarget() const {
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Call::Builder::hasTarget() {
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::rpc::MessageTarget::Reader Call::Reader::getTarget() const {
  return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::rpc::MessageTarget::Builder Call::Builder::getTarget() {
  return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
#if !CAPNP_LITE
inline  ::capnp::rpc::MessageTarget::Pipeline Call::Pipeline::getTarget() {
  return  ::capnp::rpc::MessageTarget::Pipeline(_typeless.getPointerField(0));
}
#endif  // !CAPNP_LITE
inline void Call::Builder::setTarget( ::capnp::rpc::MessageTarget::Reader value) {
  ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::rpc::MessageTarget::Builder Call::Builder::initTarget() {
  return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Call::Builder::adoptTarget(
    ::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value) {
  ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> Call::Builder::disownTarget() {
  return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline  ::uint64_t Call::Reader::getInterfaceId() const {
  return _reader.getDataField< ::uint64_t>(
      ::capnp::bounded<1>() * ::capnp::ELEMENTS);
}

inline  ::uint64_t Call::Builder::getInterfaceId() {
  return _builder.getDataField< ::uint64_t>(
      ::capnp::bounded<1>() * ::capnp::ELEMENTS);
}
inline void Call::Builder::setInterfaceId( ::uint64_t value) {
  _builder.setDataField< ::uint64_t>(
      ::capnp::bounded<1>() * ::capnp::ELEMENTS, value);
}

inline  ::uint16_t Call::Reader::getMethodId() const {
  return _reader.getDataField< ::uint16_t>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS);
}

inline  ::uint16_t Call::Builder::getMethodId() {
  return _builder.getDataField< ::uint16_t>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS);
}
inline void Call::Builder::setMethodId( ::uint16_t value) {
  _builder.setDataField< ::uint16_t>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS, value);
}

inline bool Call::Reader::hasParams() const {
  return !_reader.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS).isNull();
}
inline bool Call::Builder::hasParams() {
  return !_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::rpc::Payload::Reader Call::Reader::getParams() const {
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::get(_reader.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS));
}
inline  ::capnp::rpc::Payload::Builder Call::Builder::getParams() {
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::get(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS));
}
#if !CAPNP_LITE
inline  ::capnp::rpc::Payload::Pipeline Call::Pipeline::getParams() {
  return  ::capnp::rpc::Payload::Pipeline(_typeless.getPointerField(1));
}
#endif  // !CAPNP_LITE
inline void Call::Builder::setParams( ::capnp::rpc::Payload::Reader value) {
  ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::set(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS), value);
}
inline  ::capnp::rpc::Payload::Builder Call::Builder::initParams() {
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::init(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS));
}
inline void Call::Builder::adoptParams(
    ::capnp::Orphan< ::capnp::rpc::Payload>&& value) {
  ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::adopt(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::rpc::Payload> Call::Builder::disownParams() {
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::disown(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS));
}

inline typename Call::SendResultsTo::Reader Call::Reader::getSendResultsTo() const {
  return typename Call::SendResultsTo::Reader(_reader);
}
inline typename Call::SendResultsTo::Builder Call::Builder::getSendResultsTo() {
  return typename Call::SendResultsTo::Builder(_builder);
}
#if !CAPNP_LITE
inline typename Call::SendResultsTo::Pipeline Call::Pipeline::getSendResultsTo() {
  return typename Call::SendResultsTo::Pipeline(_typeless.noop());
}
#endif  // !CAPNP_LITE
inline typename Call::SendResultsTo::Builder Call::Builder::initSendResultsTo() {
  _builder.setDataField< ::uint16_t>(::capnp::bounded<3>() * ::capnp::ELEMENTS, 0);
  _builder.getPointerField(::capnp::bounded<2>() * ::capnp::POINTERS).clear();
  return typename Call::SendResultsTo::Builder(_builder);
}
inline bool Call::Reader::getAllowThirdPartyTailCall() const {
  return _reader.getDataField<bool>(
      ::capnp::bounded<128>() * ::capnp::ELEMENTS);
}

inline bool Call::Builder::getAllowThirdPartyTailCall() {
  return _builder.getDataField<bool>(
      ::capnp::bounded<128>() * ::capnp::ELEMENTS);
}
inline void Call::Builder::setAllowThirdPartyTailCall(bool value) {
  _builder.setDataField<bool>(
      ::capnp::bounded<128>() * ::capnp::ELEMENTS, value);
}

inline  ::capnp::rpc::Call::SendResultsTo::Which Call::SendResultsTo::Reader::which() const {
  return _reader.getDataField<Which>(
      ::capnp::bounded<3>() * ::capnp::ELEMENTS);
}
inline  ::capnp::rpc::Call::SendResultsTo::Which Call::SendResultsTo::Builder::which() {
  return _builder.getDataField<Which>(
      ::capnp::bounded<3>() * ::capnp::ELEMENTS);
}

inline bool Call::SendResultsTo::Reader::isCaller() const {
  return which() == Call::SendResultsTo::CALLER;
}
inline bool Call::SendResultsTo::Builder::isCaller() {
  return which() == Call::SendResultsTo::CALLER;
}
inline  ::capnp::Void Call::SendResultsTo::Reader::getCaller() const {
  KJ_IREQUIRE((which() == Call::SendResultsTo::CALLER),
              "Must check which() before get()ing a union member.");
  return _reader.getDataField< ::capnp::Void>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}

inline  ::capnp::Void Call::SendResultsTo::Builder::getCaller() {
  KJ_IREQUIRE((which() == Call::SendResultsTo::CALLER),
              "Must check which() before get()ing a union member.");
  return _builder.getDataField< ::capnp::Void>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline void Call::SendResultsTo::Builder::setCaller( ::capnp::Void value) {
  _builder.setDataField<Call::SendResultsTo::Which>(
      ::capnp::bounded<3>() * ::capnp::ELEMENTS, Call::SendResultsTo::CALLER);
  _builder.setDataField< ::capnp::Void>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, value);
}

inline bool Call::SendResultsTo::Reader::isYourself() const {
  return which() == Call::SendResultsTo::YOURSELF;
}
inline bool Call::SendResultsTo::Builder::isYourself() {
  return which() == Call::SendResultsTo::YOURSELF;
}
inline  ::capnp::Void Call::SendResultsTo::Reader::getYourself() const {
  KJ_IREQUIRE((which() == Call::SendResultsTo::YOURSELF),
              "Must check which() before get()ing a union member.");
  return _reader.getDataField< ::capnp::Void>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}

inline  ::capnp::Void Call::SendResultsTo::Builder::getYourself() {
  KJ_IREQUIRE((which() == Call::SendResultsTo::YOURSELF),
              "Must check which() before get()ing a union member.");
  return _builder.getDataField< ::capnp::Void>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline void Call::SendResultsTo::Builder::setYourself( ::capnp::Void value) {
  _builder.setDataField<Call::SendResultsTo::Which>(
      ::capnp::bounded<3>() * ::capnp::ELEMENTS, Call::SendResultsTo::YOURSELF);
  _builder.setDataField< ::capnp::Void>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, value);
}

inline bool Call::SendResultsTo::Reader::isThirdParty() const {
  return which() == Call::SendResultsTo::THIRD_PARTY;
}
inline bool Call::SendResultsTo::Builder::isThirdParty() {
  return which() == Call::SendResultsTo::THIRD_PARTY;
}
inline bool Call::SendResultsTo::Reader::hasThirdParty() const {
  if (which() != Call::SendResultsTo::THIRD_PARTY) return false;
  return !_reader.getPointerField(
      ::capnp::bounded<2>() * ::capnp::POINTERS).isNull();
}
inline bool Call::SendResultsTo::Builder::hasThirdParty() {
  if (which() != Call::SendResultsTo::THIRD_PARTY) return false;
  return !_builder.getPointerField(
      ::capnp::bounded<2>() * ::capnp::POINTERS).isNull();
}
inline ::capnp::AnyPointer::Reader Call::SendResultsTo::Reader::getThirdParty() const {
  KJ_IREQUIRE((which() == Call::SendResultsTo::THIRD_PARTY),
              "Must check which() before get()ing a union member.");
  return ::capnp::AnyPointer::Reader(_reader.getPointerField(
      ::capnp::bounded<2>() * ::capnp::POINTERS));
}
inline ::capnp::AnyPointer::Builder Call::SendResultsTo::Builder::getThirdParty() {
  KJ_IREQUIRE((which() == Call::SendResultsTo::THIRD_PARTY),
              "Must check which() before get()ing a union member.");
  return ::capnp::AnyPointer::Builder(_builder.getPointerField(
      ::capnp::bounded<2>() * ::capnp::POINTERS));
}
inline ::capnp::AnyPointer::Builder Call::SendResultsTo::Builder::initThirdParty() {
  _builder.setDataField<Call::SendResultsTo::Which>(
      ::capnp::bounded<3>() * ::capnp::ELEMENTS, Call::SendResultsTo::THIRD_PARTY);
  auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField(
      ::capnp::bounded<2>() * ::capnp::POINTERS));
  result.clear();
  return result;
}

inline  ::capnp::rpc::Return::Which Return::Reader::which() const {
  return _reader.getDataField<Which>(
      ::capnp::bounded<3>() * ::capnp::ELEMENTS);
}
inline  ::capnp::rpc::Return::Which Return::Builder::which() {
  return _builder.getDataField<Which>(
      ::capnp::bounded<3>() * ::capnp::ELEMENTS);
}

inline  ::uint32_t Return::Reader::getAnswerId() const {
  return _reader.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}

inline  ::uint32_t Return::Builder::getAnswerId() {
  return _builder.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline void Return::Builder::setAnswerId( ::uint32_t value) {
  _builder.setDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, value);
}

inline bool Return::Reader::getReleaseParamCaps() const {
  return _reader.getDataField<bool>(
      ::capnp::bounded<32>() * ::capnp::ELEMENTS, true);
}

inline bool Return::Builder::getReleaseParamCaps() {
  return _builder.getDataField<bool>(
      ::capnp::bounded<32>() * ::capnp::ELEMENTS, true);
}
inline void Return::Builder::setReleaseParamCaps(bool value) {
  _builder.setDataField<bool>(
      ::capnp::bounded<32>() * ::capnp::ELEMENTS, value, true);
}

inline bool Return::Reader::isResults() const {
  return which() == Return::RESULTS;
}
inline bool Return::Builder::isResults() {
  return which() == Return::RESULTS;
}
inline bool Return::Reader::hasResults() const {
  if (which() != Return::RESULTS) return false;
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Return::Builder::hasResults() {
  if (which() != Return::RESULTS) return false;
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::rpc::Payload::Reader Return::Reader::getResults() const {
  KJ_IREQUIRE((which() == Return::RESULTS),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::rpc::Payload::Builder Return::Builder::getResults() {
  KJ_IREQUIRE((which() == Return::RESULTS),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Return::Builder::setResults( ::capnp::rpc::Payload::Reader value) {
  _builder.setDataField<Return::Which>(
      ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::RESULTS);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::rpc::Payload::Builder Return::Builder::initResults() {
  _builder.setDataField<Return::Which>(
      ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::RESULTS);
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Return::Builder::adoptResults(
    ::capnp::Orphan< ::capnp::rpc::Payload>&& value) {
  _builder.setDataField<Return::Which>(
      ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::RESULTS);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::rpc::Payload> Return::Builder::disownResults() {
  KJ_IREQUIRE((which() == Return::RESULTS),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline bool Return::Reader::isException() const {
  return which() == Return::EXCEPTION;
}
inline bool Return::Builder::isException() {
  return which() == Return::EXCEPTION;
}
inline bool Return::Reader::hasException() const {
  if (which() != Return::EXCEPTION) return false;
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Return::Builder::hasException() {
  if (which() != Return::EXCEPTION) return false;
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::rpc::Exception::Reader Return::Reader::getException() const {
  KJ_IREQUIRE((which() == Return::EXCEPTION),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::rpc::Exception::Builder Return::Builder::getException() {
  KJ_IREQUIRE((which() == Return::EXCEPTION),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Return::Builder::setException( ::capnp::rpc::Exception::Reader value) {
  _builder.setDataField<Return::Which>(
      ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::EXCEPTION);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::rpc::Exception::Builder Return::Builder::initException() {
  _builder.setDataField<Return::Which>(
      ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::EXCEPTION);
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Return::Builder::adoptException(
    ::capnp::Orphan< ::capnp::rpc::Exception>&& value) {
  _builder.setDataField<Return::Which>(
      ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::EXCEPTION);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::rpc::Exception> Return::Builder::disownException() {
  KJ_IREQUIRE((which() == Return::EXCEPTION),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline bool Return::Reader::isCanceled() const {
  return which() == Return::CANCELED;
}
inline bool Return::Builder::isCanceled() {
  return which() == Return::CANCELED;
}
inline  ::capnp::Void Return::Reader::getCanceled() const {
  KJ_IREQUIRE((which() == Return::CANCELED),
              "Must check which() before get()ing a union member.");
  return _reader.getDataField< ::capnp::Void>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}

inline  ::capnp::Void Return::Builder::getCanceled() {
  KJ_IREQUIRE((which() == Return::CANCELED),
              "Must check which() before get()ing a union member.");
  return _builder.getDataField< ::capnp::Void>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline void Return::Builder::setCanceled( ::capnp::Void value) {
  _builder.setDataField<Return::Which>(
      ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::CANCELED);
  _builder.setDataField< ::capnp::Void>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, value);
}

inline bool Return::Reader::isResultsSentElsewhere() const {
  return which() == Return::RESULTS_SENT_ELSEWHERE;
}
inline bool Return::Builder::isResultsSentElsewhere() {
  return which() == Return::RESULTS_SENT_ELSEWHERE;
}
inline  ::capnp::Void Return::Reader::getResultsSentElsewhere() const {
  KJ_IREQUIRE((which() == Return::RESULTS_SENT_ELSEWHERE),
              "Must check which() before get()ing a union member.");
  return _reader.getDataField< ::capnp::Void>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}

inline  ::capnp::Void Return::Builder::getResultsSentElsewhere() {
  KJ_IREQUIRE((which() == Return::RESULTS_SENT_ELSEWHERE),
              "Must check which() before get()ing a union member.");
  return _builder.getDataField< ::capnp::Void>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline void Return::Builder::setResultsSentElsewhere( ::capnp::Void value) {
  _builder.setDataField<Return::Which>(
      ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::RESULTS_SENT_ELSEWHERE);
  _builder.setDataField< ::capnp::Void>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, value);
}

inline bool Return::Reader::isTakeFromOtherQuestion() const {
  return which() == Return::TAKE_FROM_OTHER_QUESTION;
}
inline bool Return::Builder::isTakeFromOtherQuestion() {
  return which() == Return::TAKE_FROM_OTHER_QUESTION;
}
inline  ::uint32_t Return::Reader::getTakeFromOtherQuestion() const {
  KJ_IREQUIRE((which() == Return::TAKE_FROM_OTHER_QUESTION),
              "Must check which() before get()ing a union member.");
  return _reader.getDataField< ::uint32_t>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS);
}

inline  ::uint32_t Return::Builder::getTakeFromOtherQuestion() {
  KJ_IREQUIRE((which() == Return::TAKE_FROM_OTHER_QUESTION),
              "Must check which() before get()ing a union member.");
  return _builder.getDataField< ::uint32_t>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS);
}
inline void Return::Builder::setTakeFromOtherQuestion( ::uint32_t value) {
  _builder.setDataField<Return::Which>(
      ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::TAKE_FROM_OTHER_QUESTION);
  _builder.setDataField< ::uint32_t>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS, value);
}

inline bool Return::Reader::isAcceptFromThirdParty() const {
  return which() == Return::ACCEPT_FROM_THIRD_PARTY;
}
inline bool Return::Builder::isAcceptFromThirdParty() {
  return which() == Return::ACCEPT_FROM_THIRD_PARTY;
}
inline bool Return::Reader::hasAcceptFromThirdParty() const {
  if (which() != Return::ACCEPT_FROM_THIRD_PARTY) return false;
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Return::Builder::hasAcceptFromThirdParty() {
  if (which() != Return::ACCEPT_FROM_THIRD_PARTY) return false;
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline ::capnp::AnyPointer::Reader Return::Reader::getAcceptFromThirdParty() const {
  KJ_IREQUIRE((which() == Return::ACCEPT_FROM_THIRD_PARTY),
              "Must check which() before get()ing a union member.");
  return ::capnp::AnyPointer::Reader(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline ::capnp::AnyPointer::Builder Return::Builder::getAcceptFromThirdParty() {
  KJ_IREQUIRE((which() == Return::ACCEPT_FROM_THIRD_PARTY),
              "Must check which() before get()ing a union member.");
  return ::capnp::AnyPointer::Builder(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline ::capnp::AnyPointer::Builder Return::Builder::initAcceptFromThirdParty() {
  _builder.setDataField<Return::Which>(
      ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::ACCEPT_FROM_THIRD_PARTY);
  auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
  result.clear();
  return result;
}

inline  ::uint32_t Finish::Reader::getQuestionId() const {
  return _reader.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}

inline  ::uint32_t Finish::Builder::getQuestionId() {
  return _builder.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline void Finish::Builder::setQuestionId( ::uint32_t value) {
  _builder.setDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, value);
}

inline bool Finish::Reader::getReleaseResultCaps() const {
  return _reader.getDataField<bool>(
      ::capnp::bounded<32>() * ::capnp::ELEMENTS, true);
}

inline bool Finish::Builder::getReleaseResultCaps() {
  return _builder.getDataField<bool>(
      ::capnp::bounded<32>() * ::capnp::ELEMENTS, true);
}
inline void Finish::Builder::setReleaseResultCaps(bool value) {
  _builder.setDataField<bool>(
      ::capnp::bounded<32>() * ::capnp::ELEMENTS, value, true);
}

inline  ::capnp::rpc::Resolve::Which Resolve::Reader::which() const {
  return _reader.getDataField<Which>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS);
}
inline  ::capnp::rpc::Resolve::Which Resolve::Builder::which() {
  return _builder.getDataField<Which>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS);
}

inline  ::uint32_t Resolve::Reader::getPromiseId() const {
  return _reader.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}

inline  ::uint32_t Resolve::Builder::getPromiseId() {
  return _builder.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline void Resolve::Builder::setPromiseId( ::uint32_t value) {
  _builder.setDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, value);
}

inline bool Resolve::Reader::isCap() const {
  return which() == Resolve::CAP;
}
inline bool Resolve::Builder::isCap() {
  return which() == Resolve::CAP;
}
inline bool Resolve::Reader::hasCap() const {
  if (which() != Resolve::CAP) return false;
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Resolve::Builder::hasCap() {
  if (which() != Resolve::CAP) return false;
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::rpc::CapDescriptor::Reader Resolve::Reader::getCap() const {
  KJ_IREQUIRE((which() == Resolve::CAP),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::CapDescriptor>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::rpc::CapDescriptor::Builder Resolve::Builder::getCap() {
  KJ_IREQUIRE((which() == Resolve::CAP),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::CapDescriptor>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Resolve::Builder::setCap( ::capnp::rpc::CapDescriptor::Reader value) {
  _builder.setDataField<Resolve::Which>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS, Resolve::CAP);
  ::capnp::_::PointerHelpers< ::capnp::rpc::CapDescriptor>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::rpc::CapDescriptor::Builder Resolve::Builder::initCap() {
  _builder.setDataField<Resolve::Which>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS, Resolve::CAP);
  return ::capnp::_::PointerHelpers< ::capnp::rpc::CapDescriptor>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Resolve::Builder::adoptCap(
    ::capnp::Orphan< ::capnp::rpc::CapDescriptor>&& value) {
  _builder.setDataField<Resolve::Which>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS, Resolve::CAP);
  ::capnp::_::PointerHelpers< ::capnp::rpc::CapDescriptor>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::rpc::CapDescriptor> Resolve::Builder::disownCap() {
  KJ_IREQUIRE((which() == Resolve::CAP),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::CapDescriptor>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline bool Resolve::Reader::isException() const {
  return which() == Resolve::EXCEPTION;
}
inline bool Resolve::Builder::isException() {
  return which() == Resolve::EXCEPTION;
}
inline bool Resolve::Reader::hasException() const {
  if (which() != Resolve::EXCEPTION) return false;
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Resolve::Builder::hasException() {
  if (which() != Resolve::EXCEPTION) return false;
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::rpc::Exception::Reader Resolve::Reader::getException() const {
  KJ_IREQUIRE((which() == Resolve::EXCEPTION),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::rpc::Exception::Builder Resolve::Builder::getException() {
  KJ_IREQUIRE((which() == Resolve::EXCEPTION),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Resolve::Builder::setException( ::capnp::rpc::Exception::Reader value) {
  _builder.setDataField<Resolve::Which>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS, Resolve::EXCEPTION);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::rpc::Exception::Builder Resolve::Builder::initException() {
  _builder.setDataField<Resolve::Which>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS, Resolve::EXCEPTION);
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Resolve::Builder::adoptException(
    ::capnp::Orphan< ::capnp::rpc::Exception>&& value) {
  _builder.setDataField<Resolve::Which>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS, Resolve::EXCEPTION);
  ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::rpc::Exception> Resolve::Builder::disownException() {
  KJ_IREQUIRE((which() == Resolve::EXCEPTION),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline  ::uint32_t Release::Reader::getId() const {
  return _reader.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}

inline  ::uint32_t Release::Builder::getId() {
  return _builder.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline void Release::Builder::setId( ::uint32_t value) {
  _builder.setDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, value);
}

inline  ::uint32_t Release::Reader::getReferenceCount() const {
  return _reader.getDataField< ::uint32_t>(
      ::capnp::bounded<1>() * ::capnp::ELEMENTS);
}

inline  ::uint32_t Release::Builder::getReferenceCount() {
  return _builder.getDataField< ::uint32_t>(
      ::capnp::bounded<1>() * ::capnp::ELEMENTS);
}
inline void Release::Builder::setReferenceCount( ::uint32_t value) {
  _builder.setDataField< ::uint32_t>(
      ::capnp::bounded<1>() * ::capnp::ELEMENTS, value);
}

inline bool Disembargo::Reader::hasTarget() const {
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Disembargo::Builder::hasTarget() {
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::rpc::MessageTarget::Reader Disembargo::Reader::getTarget() const {
  return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::rpc::MessageTarget::Builder Disembargo::Builder::getTarget() {
  return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
#if !CAPNP_LITE
inline  ::capnp::rpc::MessageTarget::Pipeline Disembargo::Pipeline::getTarget() {
  return  ::capnp::rpc::MessageTarget::Pipeline(_typeless.getPointerField(0));
}
#endif  // !CAPNP_LITE
inline void Disembargo::Builder::setTarget( ::capnp::rpc::MessageTarget::Reader value) {
  ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::rpc::MessageTarget::Builder Disembargo::Builder::initTarget() {
  return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Disembargo::Builder::adoptTarget(
    ::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value) {
  ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> Disembargo::Builder::disownTarget() {
  return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline typename Disembargo::Context::Reader Disembargo::Reader::getContext() const {
  return typename Disembargo::Context::Reader(_reader);
}
inline typename Disembargo::Context::Builder Disembargo::Builder::getContext() {
  return typename Disembargo::Context::Builder(_builder);
}
#if !CAPNP_LITE
inline typename Disembargo::Context::Pipeline Disembargo::Pipeline::getContext() {
  return typename Disembargo::Context::Pipeline(_typeless.noop());
}
#endif  // !CAPNP_LITE
inline typename Disembargo::Context::Builder Disembargo::Builder::initContext() {
  _builder.setDataField< ::uint32_t>(::capnp::bounded<0>() * ::capnp::ELEMENTS, 0);
  _builder.setDataField< ::uint16_t>(::capnp::bounded<2>() * ::capnp::ELEMENTS, 0);
  return typename Disembargo::Context::Builder(_builder);
}
inline  ::capnp::rpc::Disembargo::Context::Which Disembargo::Context::Reader::which() const {
  return _reader.getDataField<Which>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS);
}
inline  ::capnp::rpc::Disembargo::Context::Which Disembargo::Context::Builder::which() {
  return _builder.getDataField<Which>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS);
}

inline bool Disembargo::Context::Reader::isSenderLoopback() const {
  return which() == Disembargo::Context::SENDER_LOOPBACK;
}
inline bool Disembargo::Context::Builder::isSenderLoopback() {
  return which() == Disembargo::Context::SENDER_LOOPBACK;
}
inline  ::uint32_t Disembargo::Context::Reader::getSenderLoopback() const {
  KJ_IREQUIRE((which() == Disembargo::Context::SENDER_LOOPBACK),
              "Must check which() before get()ing a union member.");
  return _reader.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}

inline  ::uint32_t Disembargo::Context::Builder::getSenderLoopback() {
  KJ_IREQUIRE((which() == Disembargo::Context::SENDER_LOOPBACK),
              "Must check which() before get()ing a union member.");
  return _builder.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline void Disembargo::Context::Builder::setSenderLoopback( ::uint32_t value) {
  _builder.setDataField<Disembargo::Context::Which>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS, Disembargo::Context::SENDER_LOOPBACK);
  _builder.setDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, value);
}

inline bool Disembargo::Context::Reader::isReceiverLoopback() const {
  return which() == Disembargo::Context::RECEIVER_LOOPBACK;
}
inline bool Disembargo::Context::Builder::isReceiverLoopback() {
  return which() == Disembargo::Context::RECEIVER_LOOPBACK;
}
inline  ::uint32_t Disembargo::Context::Reader::getReceiverLoopback() const {
  KJ_IREQUIRE((which() == Disembargo::Context::RECEIVER_LOOPBACK),
              "Must check which() before get()ing a union member.");
  return _reader.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}

inline  ::uint32_t Disembargo::Context::Builder::getReceiverLoopback() {
  KJ_IREQUIRE((which() == Disembargo::Context::RECEIVER_LOOPBACK),
              "Must check which() before get()ing a union member.");
  return _builder.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline void Disembargo::Context::Builder::setReceiverLoopback( ::uint32_t value) {
  _builder.setDataField<Disembargo::Context::Which>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS, Disembargo::Context::RECEIVER_LOOPBACK);
  _builder.setDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, value);
}

inline bool Disembargo::Context::Reader::isAccept() const {
  return which() == Disembargo::Context::ACCEPT;
}
inline bool Disembargo::Context::Builder::isAccept() {
  return which() == Disembargo::Context::ACCEPT;
}
inline  ::capnp::Void Disembargo::Context::Reader::getAccept() const {
  KJ_IREQUIRE((which() == Disembargo::Context::ACCEPT),
              "Must check which() before get()ing a union member.");
  return _reader.getDataField< ::capnp::Void>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}

inline  ::capnp::Void Disembargo::Context::Builder::getAccept() {
  KJ_IREQUIRE((which() == Disembargo::Context::ACCEPT),
              "Must check which() before get()ing a union member.");
  return _builder.getDataField< ::capnp::Void>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline void Disembargo::Context::Builder::setAccept( ::capnp::Void value) {
  _builder.setDataField<Disembargo::Context::Which>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS, Disembargo::Context::ACCEPT);
  _builder.setDataField< ::capnp::Void>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, value);
}

inline bool Disembargo::Context::Reader::isProvide() const {
  return which() == Disembargo::Context::PROVIDE;
}
inline bool Disembargo::Context::Builder::isProvide() {
  return which() == Disembargo::Context::PROVIDE;
}
inline  ::uint32_t Disembargo::Context::Reader::getProvide() const {
  KJ_IREQUIRE((which() == Disembargo::Context::PROVIDE),
              "Must check which() before get()ing a union member.");
  return _reader.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}

inline  ::uint32_t Disembargo::Context::Builder::getProvide() {
  KJ_IREQUIRE((which() == Disembargo::Context::PROVIDE),
              "Must check which() before get()ing a union member.");
  return _builder.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline void Disembargo::Context::Builder::setProvide( ::uint32_t value) {
  _builder.setDataField<Disembargo::Context::Which>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS, Disembargo::Context::PROVIDE);
  _builder.setDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, value);
}

inline  ::uint32_t Provide::Reader::getQuestionId() const {
  return _reader.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}

inline  ::uint32_t Provide::Builder::getQuestionId() {
  return _builder.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline void Provide::Builder::setQuestionId( ::uint32_t value) {
  _builder.setDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, value);
}

inline bool Provide::Reader::hasTarget() const {
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Provide::Builder::hasTarget() {
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::rpc::MessageTarget::Reader Provide::Reader::getTarget() const {
  return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::rpc::MessageTarget::Builder Provide::Builder::getTarget() {
  return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
#if !CAPNP_LITE
inline  ::capnp::rpc::MessageTarget::Pipeline Provide::Pipeline::getTarget() {
  return  ::capnp::rpc::MessageTarget::Pipeline(_typeless.getPointerField(0));
}
#endif  // !CAPNP_LITE
inline void Provide::Builder::setTarget( ::capnp::rpc::MessageTarget::Reader value) {
  ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::rpc::MessageTarget::Builder Provide::Builder::initTarget() {
  return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Provide::Builder::adoptTarget(
    ::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value) {
  ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> Provide::Builder::disownTarget() {
  return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline bool Provide::Reader::hasRecipient() const {
  return !_reader.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS).isNull();
}
inline bool Provide::Builder::hasRecipient() {
  return !_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS).isNull();
}
inline ::capnp::AnyPointer::Reader Provide::Reader::getRecipient() const {
  return ::capnp::AnyPointer::Reader(_reader.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS));
}
inline ::capnp::AnyPointer::Builder Provide::Builder::getRecipient() {
  return ::capnp::AnyPointer::Builder(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS));
}
inline ::capnp::AnyPointer::Builder Provide::Builder::initRecipient() {
  auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS));
  result.clear();
  return result;
}

inline  ::uint32_t Accept::Reader::getQuestionId() const {
  return _reader.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}

inline  ::uint32_t Accept::Builder::getQuestionId() {
  return _builder.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline void Accept::Builder::setQuestionId( ::uint32_t value) {
  _builder.setDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, value);
}

inline bool Accept::Reader::hasProvision() const {
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Accept::Builder::hasProvision() {
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline ::capnp::AnyPointer::Reader Accept::Reader::getProvision() const {
  return ::capnp::AnyPointer::Reader(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline ::capnp::AnyPointer::Builder Accept::Builder::getProvision() {
  return ::capnp::AnyPointer::Builder(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline ::capnp::AnyPointer::Builder Accept::Builder::initProvision() {
  auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
  result.clear();
  return result;
}

inline bool Accept::Reader::getEmbargo() const {
  return _reader.getDataField<bool>(
      ::capnp::bounded<32>() * ::capnp::ELEMENTS);
}

inline bool Accept::Builder::getEmbargo() {
  return _builder.getDataField<bool>(
      ::capnp::bounded<32>() * ::capnp::ELEMENTS);
}
inline void Accept::Builder::setEmbargo(bool value) {
  _builder.setDataField<bool>(
      ::capnp::bounded<32>() * ::capnp::ELEMENTS, value);
}

inline  ::uint32_t Join::Reader::getQuestionId() const {
  return _reader.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}

inline  ::uint32_t Join::Builder::getQuestionId() {
  return _builder.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline void Join::Builder::setQuestionId( ::uint32_t value) {
  _builder.setDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, value);
}

inline bool Join::Reader::hasTarget() const {
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Join::Builder::hasTarget() {
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::rpc::MessageTarget::Reader Join::Reader::getTarget() const {
  return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::rpc::MessageTarget::Builder Join::Builder::getTarget() {
  return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
#if !CAPNP_LITE
inline  ::capnp::rpc::MessageTarget::Pipeline Join::Pipeline::getTarget() {
  return  ::capnp::rpc::MessageTarget::Pipeline(_typeless.getPointerField(0));
}
#endif  // !CAPNP_LITE
inline void Join::Builder::setTarget( ::capnp::rpc::MessageTarget::Reader value) {
  ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::rpc::MessageTarget::Builder Join::Builder::initTarget() {
  return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Join::Builder::adoptTarget(
    ::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value) {
  ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> Join::Builder::disownTarget() {
  return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline bool Join::Reader::hasKeyPart() const {
  return !_reader.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS).isNull();
}
inline bool Join::Builder::hasKeyPart() {
  return !_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS).isNull();
}
inline ::capnp::AnyPointer::Reader Join::Reader::getKeyPart() const {
  return ::capnp::AnyPointer::Reader(_reader.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS));
}
inline ::capnp::AnyPointer::Builder Join::Builder::getKeyPart() {
  return ::capnp::AnyPointer::Builder(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS));
}
inline ::capnp::AnyPointer::Builder Join::Builder::initKeyPart() {
  auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS));
  result.clear();
  return result;
}

inline  ::capnp::rpc::MessageTarget::Which MessageTarget::Reader::which() const {
  return _reader.getDataField<Which>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS);
}
inline  ::capnp::rpc::MessageTarget::Which MessageTarget::Builder::which() {
  return _builder.getDataField<Which>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS);
}

inline bool MessageTarget::Reader::isImportedCap() const {
  return which() == MessageTarget::IMPORTED_CAP;
}
inline bool MessageTarget::Builder::isImportedCap() {
  return which() == MessageTarget::IMPORTED_CAP;
}
inline  ::uint32_t MessageTarget::Reader::getImportedCap() const {
  KJ_IREQUIRE((which() == MessageTarget::IMPORTED_CAP),
              "Must check which() before get()ing a union member.");
  return _reader.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}

inline  ::uint32_t MessageTarget::Builder::getImportedCap() {
  KJ_IREQUIRE((which() == MessageTarget::IMPORTED_CAP),
              "Must check which() before get()ing a union member.");
  return _builder.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline void MessageTarget::Builder::setImportedCap( ::uint32_t value) {
  _builder.setDataField<MessageTarget::Which>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS, MessageTarget::IMPORTED_CAP);
  _builder.setDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, value);
}

inline bool MessageTarget::Reader::isPromisedAnswer() const {
  return which() == MessageTarget::PROMISED_ANSWER;
}
inline bool MessageTarget::Builder::isPromisedAnswer() {
  return which() == MessageTarget::PROMISED_ANSWER;
}
inline bool MessageTarget::Reader::hasPromisedAnswer() const {
  if (which() != MessageTarget::PROMISED_ANSWER) return false;
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool MessageTarget::Builder::hasPromisedAnswer() {
  if (which() != MessageTarget::PROMISED_ANSWER) return false;
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::rpc::PromisedAnswer::Reader MessageTarget::Reader::getPromisedAnswer() const {
  KJ_IREQUIRE((which() == MessageTarget::PROMISED_ANSWER),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::rpc::PromisedAnswer::Builder MessageTarget::Builder::getPromisedAnswer() {
  KJ_IREQUIRE((which() == MessageTarget::PROMISED_ANSWER),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void MessageTarget::Builder::setPromisedAnswer( ::capnp::rpc::PromisedAnswer::Reader value) {
  _builder.setDataField<MessageTarget::Which>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS, MessageTarget::PROMISED_ANSWER);
  ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::rpc::PromisedAnswer::Builder MessageTarget::Builder::initPromisedAnswer() {
  _builder.setDataField<MessageTarget::Which>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS, MessageTarget::PROMISED_ANSWER);
  return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void MessageTarget::Builder::adoptPromisedAnswer(
    ::capnp::Orphan< ::capnp::rpc::PromisedAnswer>&& value) {
  _builder.setDataField<MessageTarget::Which>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS, MessageTarget::PROMISED_ANSWER);
  ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::rpc::PromisedAnswer> MessageTarget::Builder::disownPromisedAnswer() {
  KJ_IREQUIRE((which() == MessageTarget::PROMISED_ANSWER),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline bool Payload::Reader::hasContent() const {
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Payload::Builder::hasContent() {
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline ::capnp::AnyPointer::Reader Payload::Reader::getContent() const {
  return ::capnp::AnyPointer::Reader(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline ::capnp::AnyPointer::Builder Payload::Builder::getContent() {
  return ::capnp::AnyPointer::Builder(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline ::capnp::AnyPointer::Builder Payload::Builder::initContent() {
  auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
  result.clear();
  return result;
}

inline bool Payload::Reader::hasCapTable() const {
  return !_reader.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS).isNull();
}
inline bool Payload::Builder::hasCapTable() {
  return !_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::List< ::capnp::rpc::CapDescriptor,  ::capnp::Kind::STRUCT>::Reader Payload::Reader::getCapTable() const {
  return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor,  ::capnp::Kind::STRUCT>>::get(_reader.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS));
}
inline  ::capnp::List< ::capnp::rpc::CapDescriptor,  ::capnp::Kind::STRUCT>::Builder Payload::Builder::getCapTable() {
  return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor,  ::capnp::Kind::STRUCT>>::get(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS));
}
inline void Payload::Builder::setCapTable( ::capnp::List< ::capnp::rpc::CapDescriptor,  ::capnp::Kind::STRUCT>::Reader value) {
  ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor,  ::capnp::Kind::STRUCT>>::set(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS), value);
}
inline  ::capnp::List< ::capnp::rpc::CapDescriptor,  ::capnp::Kind::STRUCT>::Builder Payload::Builder::initCapTable(unsigned int size) {
  return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor,  ::capnp::Kind::STRUCT>>::init(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS), size);
}
inline void Payload::Builder::adoptCapTable(
    ::capnp::Orphan< ::capnp::List< ::capnp::rpc::CapDescriptor,  ::capnp::Kind::STRUCT>>&& value) {
  ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor,  ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::List< ::capnp::rpc::CapDescriptor,  ::capnp::Kind::STRUCT>> Payload::Builder::disownCapTable() {
  return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor,  ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS));
}

inline  ::capnp::rpc::CapDescriptor::Which CapDescriptor::Reader::which() const {
  return _reader.getDataField<Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline  ::capnp::rpc::CapDescriptor::Which CapDescriptor::Builder::which() {
  return _builder.getDataField<Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}

inline bool CapDescriptor::Reader::isNone() const {
  return which() == CapDescriptor::NONE;
}
inline bool CapDescriptor::Builder::isNone() {
  return which() == CapDescriptor::NONE;
}
inline  ::capnp::Void CapDescriptor::Reader::getNone() const {
  KJ_IREQUIRE((which() == CapDescriptor::NONE),
              "Must check which() before get()ing a union member.");
  return _reader.getDataField< ::capnp::Void>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}

inline  ::capnp::Void CapDescriptor::Builder::getNone() {
  KJ_IREQUIRE((which() == CapDescriptor::NONE),
              "Must check which() before get()ing a union member.");
  return _builder.getDataField< ::capnp::Void>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline void CapDescriptor::Builder::setNone( ::capnp::Void value) {
  _builder.setDataField<CapDescriptor::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::NONE);
  _builder.setDataField< ::capnp::Void>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, value);
}

inline bool CapDescriptor::Reader::isSenderHosted() const {
  return which() == CapDescriptor::SENDER_HOSTED;
}
inline bool CapDescriptor::Builder::isSenderHosted() {
  return which() == CapDescriptor::SENDER_HOSTED;
}
inline  ::uint32_t CapDescriptor::Reader::getSenderHosted() const {
  KJ_IREQUIRE((which() == CapDescriptor::SENDER_HOSTED),
              "Must check which() before get()ing a union member.");
  return _reader.getDataField< ::uint32_t>(
      ::capnp::bounded<1>() * ::capnp::ELEMENTS);
}

inline  ::uint32_t CapDescriptor::Builder::getSenderHosted() {
  KJ_IREQUIRE((which() == CapDescriptor::SENDER_HOSTED),
              "Must check which() before get()ing a union member.");
  return _builder.getDataField< ::uint32_t>(
      ::capnp::bounded<1>() * ::capnp::ELEMENTS);
}
inline void CapDescriptor::Builder::setSenderHosted( ::uint32_t value) {
  _builder.setDataField<CapDescriptor::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::SENDER_HOSTED);
  _builder.setDataField< ::uint32_t>(
      ::capnp::bounded<1>() * ::capnp::ELEMENTS, value);
}

inline bool CapDescriptor::Reader::isSenderPromise() const {
  return which() == CapDescriptor::SENDER_PROMISE;
}
inline bool CapDescriptor::Builder::isSenderPromise() {
  return which() == CapDescriptor::SENDER_PROMISE;
}
inline  ::uint32_t CapDescriptor::Reader::getSenderPromise() const {
  KJ_IREQUIRE((which() == CapDescriptor::SENDER_PROMISE),
              "Must check which() before get()ing a union member.");
  return _reader.getDataField< ::uint32_t>(
      ::capnp::bounded<1>() * ::capnp::ELEMENTS);
}

inline  ::uint32_t CapDescriptor::Builder::getSenderPromise() {
  KJ_IREQUIRE((which() == CapDescriptor::SENDER_PROMISE),
              "Must check which() before get()ing a union member.");
  return _builder.getDataField< ::uint32_t>(
      ::capnp::bounded<1>() * ::capnp::ELEMENTS);
}
inline void CapDescriptor::Builder::setSenderPromise( ::uint32_t value) {
  _builder.setDataField<CapDescriptor::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::SENDER_PROMISE);
  _builder.setDataField< ::uint32_t>(
      ::capnp::bounded<1>() * ::capnp::ELEMENTS, value);
}

inline bool CapDescriptor::Reader::isReceiverHosted() const {
  return which() == CapDescriptor::RECEIVER_HOSTED;
}
inline bool CapDescriptor::Builder::isReceiverHosted() {
  return which() == CapDescriptor::RECEIVER_HOSTED;
}
inline  ::uint32_t CapDescriptor::Reader::getReceiverHosted() const {
  KJ_IREQUIRE((which() == CapDescriptor::RECEIVER_HOSTED),
              "Must check which() before get()ing a union member.");
  return _reader.getDataField< ::uint32_t>(
      ::capnp::bounded<1>() * ::capnp::ELEMENTS);
}

inline  ::uint32_t CapDescriptor::Builder::getReceiverHosted() {
  KJ_IREQUIRE((which() == CapDescriptor::RECEIVER_HOSTED),
              "Must check which() before get()ing a union member.");
  return _builder.getDataField< ::uint32_t>(
      ::capnp::bounded<1>() * ::capnp::ELEMENTS);
}
inline void CapDescriptor::Builder::setReceiverHosted( ::uint32_t value) {
  _builder.setDataField<CapDescriptor::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::RECEIVER_HOSTED);
  _builder.setDataField< ::uint32_t>(
      ::capnp::bounded<1>() * ::capnp::ELEMENTS, value);
}

inline bool CapDescriptor::Reader::isReceiverAnswer() const {
  return which() == CapDescriptor::RECEIVER_ANSWER;
}
inline bool CapDescriptor::Builder::isReceiverAnswer() {
  return which() == CapDescriptor::RECEIVER_ANSWER;
}
inline bool CapDescriptor::Reader::hasReceiverAnswer() const {
  if (which() != CapDescriptor::RECEIVER_ANSWER) return false;
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool CapDescriptor::Builder::hasReceiverAnswer() {
  if (which() != CapDescriptor::RECEIVER_ANSWER) return false;
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::rpc::PromisedAnswer::Reader CapDescriptor::Reader::getReceiverAnswer() const {
  KJ_IREQUIRE((which() == CapDescriptor::RECEIVER_ANSWER),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::rpc::PromisedAnswer::Builder CapDescriptor::Builder::getReceiverAnswer() {
  KJ_IREQUIRE((which() == CapDescriptor::RECEIVER_ANSWER),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void CapDescriptor::Builder::setReceiverAnswer( ::capnp::rpc::PromisedAnswer::Reader value) {
  _builder.setDataField<CapDescriptor::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::RECEIVER_ANSWER);
  ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::rpc::PromisedAnswer::Builder CapDescriptor::Builder::initReceiverAnswer() {
  _builder.setDataField<CapDescriptor::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::RECEIVER_ANSWER);
  return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void CapDescriptor::Builder::adoptReceiverAnswer(
    ::capnp::Orphan< ::capnp::rpc::PromisedAnswer>&& value) {
  _builder.setDataField<CapDescriptor::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::RECEIVER_ANSWER);
  ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::rpc::PromisedAnswer> CapDescriptor::Builder::disownReceiverAnswer() {
  KJ_IREQUIRE((which() == CapDescriptor::RECEIVER_ANSWER),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline bool CapDescriptor::Reader::isThirdPartyHosted() const {
  return which() == CapDescriptor::THIRD_PARTY_HOSTED;
}
inline bool CapDescriptor::Builder::isThirdPartyHosted() {
  return which() == CapDescriptor::THIRD_PARTY_HOSTED;
}
inline bool CapDescriptor::Reader::hasThirdPartyHosted() const {
  if (which() != CapDescriptor::THIRD_PARTY_HOSTED) return false;
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool CapDescriptor::Builder::hasThirdPartyHosted() {
  if (which() != CapDescriptor::THIRD_PARTY_HOSTED) return false;
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::rpc::ThirdPartyCapDescriptor::Reader CapDescriptor::Reader::getThirdPartyHosted() const {
  KJ_IREQUIRE((which() == CapDescriptor::THIRD_PARTY_HOSTED),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::ThirdPartyCapDescriptor>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::rpc::ThirdPartyCapDescriptor::Builder CapDescriptor::Builder::getThirdPartyHosted() {
  KJ_IREQUIRE((which() == CapDescriptor::THIRD_PARTY_HOSTED),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::ThirdPartyCapDescriptor>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void CapDescriptor::Builder::setThirdPartyHosted( ::capnp::rpc::ThirdPartyCapDescriptor::Reader value) {
  _builder.setDataField<CapDescriptor::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::THIRD_PARTY_HOSTED);
  ::capnp::_::PointerHelpers< ::capnp::rpc::ThirdPartyCapDescriptor>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::rpc::ThirdPartyCapDescriptor::Builder CapDescriptor::Builder::initThirdPartyHosted() {
  _builder.setDataField<CapDescriptor::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::THIRD_PARTY_HOSTED);
  return ::capnp::_::PointerHelpers< ::capnp::rpc::ThirdPartyCapDescriptor>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void CapDescriptor::Builder::adoptThirdPartyHosted(
    ::capnp::Orphan< ::capnp::rpc::ThirdPartyCapDescriptor>&& value) {
  _builder.setDataField<CapDescriptor::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::THIRD_PARTY_HOSTED);
  ::capnp::_::PointerHelpers< ::capnp::rpc::ThirdPartyCapDescriptor>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::rpc::ThirdPartyCapDescriptor> CapDescriptor::Builder::disownThirdPartyHosted() {
  KJ_IREQUIRE((which() == CapDescriptor::THIRD_PARTY_HOSTED),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::rpc::ThirdPartyCapDescriptor>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline  ::uint8_t CapDescriptor::Reader::getAttachedFd() const {
  return _reader.getDataField< ::uint8_t>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS, 255u);
}

inline  ::uint8_t CapDescriptor::Builder::getAttachedFd() {
  return _builder.getDataField< ::uint8_t>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS, 255u);
}
inline void CapDescriptor::Builder::setAttachedFd( ::uint8_t value) {
  _builder.setDataField< ::uint8_t>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS, value, 255u);
}

inline  ::uint32_t PromisedAnswer::Reader::getQuestionId() const {
  return _reader.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}

inline  ::uint32_t PromisedAnswer::Builder::getQuestionId() {
  return _builder.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline void PromisedAnswer::Builder::setQuestionId( ::uint32_t value) {
  _builder.setDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, value);
}

inline bool PromisedAnswer::Reader::hasTransform() const {
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool PromisedAnswer::Builder::hasTransform() {
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::List< ::capnp::rpc::PromisedAnswer::Op,  ::capnp::Kind::STRUCT>::Reader PromisedAnswer::Reader::getTransform() const {
  return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op,  ::capnp::Kind::STRUCT>>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::List< ::capnp::rpc::PromisedAnswer::Op,  ::capnp::Kind::STRUCT>::Builder PromisedAnswer::Builder::getTransform() {
  return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op,  ::capnp::Kind::STRUCT>>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void PromisedAnswer::Builder::setTransform( ::capnp::List< ::capnp::rpc::PromisedAnswer::Op,  ::capnp::Kind::STRUCT>::Reader value) {
  ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op,  ::capnp::Kind::STRUCT>>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::List< ::capnp::rpc::PromisedAnswer::Op,  ::capnp::Kind::STRUCT>::Builder PromisedAnswer::Builder::initTransform(unsigned int size) {
  return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op,  ::capnp::Kind::STRUCT>>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), size);
}
inline void PromisedAnswer::Builder::adoptTransform(
    ::capnp::Orphan< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op,  ::capnp::Kind::STRUCT>>&& value) {
  ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op,  ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op,  ::capnp::Kind::STRUCT>> PromisedAnswer::Builder::disownTransform() {
  return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op,  ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline  ::capnp::rpc::PromisedAnswer::Op::Which PromisedAnswer::Op::Reader::which() const {
  return _reader.getDataField<Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline  ::capnp::rpc::PromisedAnswer::Op::Which PromisedAnswer::Op::Builder::which() {
  return _builder.getDataField<Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}

inline bool PromisedAnswer::Op::Reader::isNoop() const {
  return which() == PromisedAnswer::Op::NOOP;
}
inline bool PromisedAnswer::Op::Builder::isNoop() {
  return which() == PromisedAnswer::Op::NOOP;
}
inline  ::capnp::Void PromisedAnswer::Op::Reader::getNoop() const {
  KJ_IREQUIRE((which() == PromisedAnswer::Op::NOOP),
              "Must check which() before get()ing a union member.");
  return _reader.getDataField< ::capnp::Void>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}

inline  ::capnp::Void PromisedAnswer::Op::Builder::getNoop() {
  KJ_IREQUIRE((which() == PromisedAnswer::Op::NOOP),
              "Must check which() before get()ing a union member.");
  return _builder.getDataField< ::capnp::Void>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline void PromisedAnswer::Op::Builder::setNoop( ::capnp::Void value) {
  _builder.setDataField<PromisedAnswer::Op::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, PromisedAnswer::Op::NOOP);
  _builder.setDataField< ::capnp::Void>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, value);
}

inline bool PromisedAnswer::Op::Reader::isGetPointerField() const {
  return which() == PromisedAnswer::Op::GET_POINTER_FIELD;
}
inline bool PromisedAnswer::Op::Builder::isGetPointerField() {
  return which() == PromisedAnswer::Op::GET_POINTER_FIELD;
}
inline  ::uint16_t PromisedAnswer::Op::Reader::getGetPointerField() const {
  KJ_IREQUIRE((which() == PromisedAnswer::Op::GET_POINTER_FIELD),
              "Must check which() before get()ing a union member.");
  return _reader.getDataField< ::uint16_t>(
      ::capnp::bounded<1>() * ::capnp::ELEMENTS);
}

inline  ::uint16_t PromisedAnswer::Op::Builder::getGetPointerField() {
  KJ_IREQUIRE((which() == PromisedAnswer::Op::GET_POINTER_FIELD),
              "Must check which() before get()ing a union member.");
  return _builder.getDataField< ::uint16_t>(
      ::capnp::bounded<1>() * ::capnp::ELEMENTS);
}
inline void PromisedAnswer::Op::Builder::setGetPointerField( ::uint16_t value) {
  _builder.setDataField<PromisedAnswer::Op::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, PromisedAnswer::Op::GET_POINTER_FIELD);
  _builder.setDataField< ::uint16_t>(
      ::capnp::bounded<1>() * ::capnp::ELEMENTS, value);
}

inline bool ThirdPartyCapDescriptor::Reader::hasId() const {
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool ThirdPartyCapDescriptor::Builder::hasId() {
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline ::capnp::AnyPointer::Reader ThirdPartyCapDescriptor::Reader::getId() const {
  return ::capnp::AnyPointer::Reader(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline ::capnp::AnyPointer::Builder ThirdPartyCapDescriptor::Builder::getId() {
  return ::capnp::AnyPointer::Builder(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline ::capnp::AnyPointer::Builder ThirdPartyCapDescriptor::Builder::initId() {
  auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
  result.clear();
  return result;
}

inline  ::uint32_t ThirdPartyCapDescriptor::Reader::getVineId() const {
  return _reader.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}

inline  ::uint32_t ThirdPartyCapDescriptor::Builder::getVineId() {
  return _builder.getDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline void ThirdPartyCapDescriptor::Builder::setVineId( ::uint32_t value) {
  _builder.setDataField< ::uint32_t>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, value);
}

inline bool Exception::Reader::hasReason() const {
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Exception::Builder::hasReason() {
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::Text::Reader Exception::Reader::getReason() const {
  return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::Text::Builder Exception::Builder::getReason() {
  return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Exception::Builder::setReason( ::capnp::Text::Reader value) {
  ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::Text::Builder Exception::Builder::initReason(unsigned int size) {
  return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), size);
}
inline void Exception::Builder::adoptReason(
    ::capnp::Orphan< ::capnp::Text>&& value) {
  ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::Text> Exception::Builder::disownReason() {
  return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline bool Exception::Reader::getObsoleteIsCallersFault() const {
  return _reader.getDataField<bool>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}

inline bool Exception::Builder::getObsoleteIsCallersFault() {
  return _builder.getDataField<bool>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline void Exception::Builder::setObsoleteIsCallersFault(bool value) {
  _builder.setDataField<bool>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, value);
}

inline  ::uint16_t Exception::Reader::getObsoleteDurability() const {
  return _reader.getDataField< ::uint16_t>(
      ::capnp::bounded<1>() * ::capnp::ELEMENTS);
}

inline  ::uint16_t Exception::Builder::getObsoleteDurability() {
  return _builder.getDataField< ::uint16_t>(
      ::capnp::bounded<1>() * ::capnp::ELEMENTS);
}
inline void Exception::Builder::setObsoleteDurability( ::uint16_t value) {
  _builder.setDataField< ::uint16_t>(
      ::capnp::bounded<1>() * ::capnp::ELEMENTS, value);
}

inline  ::capnp::rpc::Exception::Type Exception::Reader::getType() const {
  return _reader.getDataField< ::capnp::rpc::Exception::Type>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS);
}

inline  ::capnp::rpc::Exception::Type Exception::Builder::getType() {
  return _builder.getDataField< ::capnp::rpc::Exception::Type>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS);
}
inline void Exception::Builder::setType( ::capnp::rpc::Exception::Type value) {
  _builder.setDataField< ::capnp::rpc::Exception::Type>(
      ::capnp::bounded<2>() * ::capnp::ELEMENTS, value);
}

inline bool Exception::Reader::hasTrace() const {
  return !_reader.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS).isNull();
}
inline bool Exception::Builder::hasTrace() {
  return !_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::Text::Reader Exception::Reader::getTrace() const {
  return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS));
}
inline  ::capnp::Text::Builder Exception::Builder::getTrace() {
  return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS));
}
inline void Exception::Builder::setTrace( ::capnp::Text::Reader value) {
  ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS), value);
}
inline  ::capnp::Text::Builder Exception::Builder::initTrace(unsigned int size) {
  return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS), size);
}
inline void Exception::Builder::adoptTrace(
    ::capnp::Orphan< ::capnp::Text>&& value) {
  ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::Text> Exception::Builder::disownTrace() {
  return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS));
}

}  // namespace
}  // namespace

CAPNP_END_HEADER

