Mercurial > hg > sv-dependency-builds
changeset 135:38d1c0e7850b
Headers for KJ/Capnp Win32
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/any.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,1047 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef CAPNP_ANY_H_ +#define CAPNP_ANY_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "layout.h" +#include "pointer-helpers.h" +#include "orphan.h" +#include "list.h" + +namespace capnp { + +class StructSchema; +class ListSchema; +class InterfaceSchema; +class Orphanage; +class ClientHook; +class PipelineHook; +struct PipelineOp; +struct AnyPointer; + +struct AnyList { + AnyList() = delete; + + class Reader; + class Builder; +}; + +struct AnyStruct { + AnyStruct() = delete; + + class Reader; + class Builder; + class Pipeline; +}; + +template<> +struct List<AnyStruct, Kind::OTHER> { + List() = delete; + + class Reader; + class Builder; +}; + +namespace _ { // private +template <> struct Kind_<AnyPointer> { static constexpr Kind kind = Kind::OTHER; }; +template <> struct Kind_<AnyStruct> { static constexpr Kind kind = Kind::OTHER; }; +template <> struct Kind_<AnyList> { static constexpr Kind kind = Kind::OTHER; }; +} // namespace _ (private) + +// ======================================================================================= +// AnyPointer! + +enum class Equality { + NOT_EQUAL, + EQUAL, + UNKNOWN_CONTAINS_CAPS +}; + +kj::StringPtr KJ_STRINGIFY(Equality res); + +struct AnyPointer { + // Reader/Builder for the `AnyPointer` field type, i.e. a pointer that can point to an arbitrary + // object. + + AnyPointer() = delete; + + class Reader { + public: + typedef AnyPointer Reads; + + Reader() = default; + inline Reader(_::PointerReader reader): reader(reader) {} + + inline MessageSize targetSize() const; + // Get the total size of the target object and all its children. + + inline PointerType getPointerType() const; + + inline bool isNull() const { return getPointerType() == PointerType::NULL_; } + inline bool isStruct() const { return getPointerType() == PointerType::STRUCT; } + inline bool isList() const { return getPointerType() == PointerType::LIST; } + inline bool isCapability() const { return getPointerType() == PointerType::CAPABILITY; } + + Equality equals(AnyPointer::Reader right); + bool operator==(AnyPointer::Reader right); + inline bool operator!=(AnyPointer::Reader right) { + return !(*this == right); + } + + template <typename T> + inline ReaderFor<T> getAs() const; + // Valid for T = any generated struct type, interface type, List<U>, Text, or Data. + + template <typename T> + inline ReaderFor<T> getAs(StructSchema schema) const; + // Only valid for T = DynamicStruct. Requires `#include <capnp/dynamic.h>`. + + template <typename T> + inline ReaderFor<T> getAs(ListSchema schema) const; + // Only valid for T = DynamicList. Requires `#include <capnp/dynamic.h>`. + + template <typename T> + inline ReaderFor<T> getAs(InterfaceSchema schema) const; + // Only valid for T = DynamicCapability. Requires `#include <capnp/dynamic.h>`. + +#if !CAPNP_LITE + kj::Own<ClientHook> getPipelinedCap(kj::ArrayPtr<const PipelineOp> ops) const; + // Used by RPC system to implement pipelining. Applications generally shouldn't use this + // directly. +#endif // !CAPNP_LITE + + private: + _::PointerReader reader; + friend struct AnyPointer; + friend class Orphanage; + friend class CapReaderContext; + friend struct _::PointerHelpers<AnyPointer>; + }; + + class Builder { + public: + typedef AnyPointer Builds; + + Builder() = delete; + inline Builder(decltype(nullptr)) {} + inline Builder(_::PointerBuilder builder): builder(builder) {} + + inline MessageSize targetSize() const; + // Get the total size of the target object and all its children. + + inline PointerType getPointerType(); + + inline bool isNull() { return getPointerType() == PointerType::NULL_; } + inline bool isStruct() { return getPointerType() == PointerType::STRUCT; } + inline bool isList() { return getPointerType() == PointerType::LIST; } + inline bool isCapability() { return getPointerType() == PointerType::CAPABILITY; } + + inline Equality equals(AnyPointer::Reader right) { + return asReader().equals(right); + } + inline bool operator==(AnyPointer::Reader right) { + return asReader() == right; + } + inline bool operator!=(AnyPointer::Reader right) { + return !(*this == right); + } + + inline void clear(); + // Set to null. + + template <typename T> + inline BuilderFor<T> getAs(); + // Valid for T = any generated struct type, List<U>, Text, or Data. + + template <typename T> + inline BuilderFor<T> getAs(StructSchema schema); + // Only valid for T = DynamicStruct. Requires `#include <capnp/dynamic.h>`. + + template <typename T> + inline BuilderFor<T> getAs(ListSchema schema); + // Only valid for T = DynamicList. Requires `#include <capnp/dynamic.h>`. + + template <typename T> + inline BuilderFor<T> getAs(InterfaceSchema schema); + // Only valid for T = DynamicCapability. Requires `#include <capnp/dynamic.h>`. + + template <typename T> + inline BuilderFor<T> initAs(); + // Valid for T = any generated struct type. + + template <typename T> + inline BuilderFor<T> initAs(uint elementCount); + // Valid for T = List<U>, Text, or Data. + + template <typename T> + inline BuilderFor<T> initAs(StructSchema schema); + // Only valid for T = DynamicStruct. Requires `#include <capnp/dynamic.h>`. + + template <typename T> + inline BuilderFor<T> initAs(ListSchema schema, uint elementCount); + // Only valid for T = DynamicList. Requires `#include <capnp/dynamic.h>`. + + inline AnyList::Builder initAsAnyList(ElementSize elementSize, uint elementCount); + // Note: Does not accept INLINE_COMPOSITE for elementSize. + + inline List<AnyStruct>::Builder initAsListOfAnyStruct( + uint dataWordCount, uint pointerCount, uint elementCount); + + inline AnyStruct::Builder initAsAnyStruct(uint dataWordCount, uint pointerCount); + + template <typename T> + inline void setAs(ReaderFor<T> value); + // Valid for ReaderType = T::Reader for T = any generated struct type, List<U>, Text, Data, + // DynamicStruct, or DynamicList (the dynamic types require `#include <capnp/dynamic.h>`). + + template <typename T> + inline void setAs(std::initializer_list<ReaderFor<ListElementType<T>>> list); + // Valid for T = List<?>. + + template <typename T> + inline void setCanonicalAs(ReaderFor<T> value); + + inline void set(Reader value) { builder.copyFrom(value.reader); } + // Set to a copy of another AnyPointer. + + inline void setCanonical(Reader value) { builder.copyFrom(value.reader, true); } + + template <typename T> + inline void adopt(Orphan<T>&& orphan); + // Valid for T = any generated struct type, List<U>, Text, Data, DynamicList, DynamicStruct, + // or DynamicValue (the dynamic types require `#include <capnp/dynamic.h>`). + + template <typename T> + inline Orphan<T> disownAs(); + // Valid for T = any generated struct type, List<U>, Text, Data. + + template <typename T> + inline Orphan<T> disownAs(StructSchema schema); + // Only valid for T = DynamicStruct. Requires `#include <capnp/dynamic.h>`. + + template <typename T> + inline Orphan<T> disownAs(ListSchema schema); + // Only valid for T = DynamicList. Requires `#include <capnp/dynamic.h>`. + + template <typename T> + inline Orphan<T> disownAs(InterfaceSchema schema); + // Only valid for T = DynamicCapability. Requires `#include <capnp/dynamic.h>`. + + inline Orphan<AnyPointer> disown(); + // Disown without a type. + + inline Reader asReader() const { return Reader(builder.asReader()); } + inline operator Reader() const { return Reader(builder.asReader()); } + + private: + _::PointerBuilder builder; + friend class Orphanage; + friend class CapBuilderContext; + friend struct _::PointerHelpers<AnyPointer>; + }; + +#if !CAPNP_LITE + class Pipeline { + public: + typedef AnyPointer Pipelines; + + inline Pipeline(decltype(nullptr)) {} + inline explicit Pipeline(kj::Own<PipelineHook>&& hook): hook(kj::mv(hook)) {} + + Pipeline noop(); + // Just make a copy. + + Pipeline getPointerField(uint16_t pointerIndex); + // Deprecated. In the future, we should use .asAnyStruct.getPointerField. + + inline AnyStruct::Pipeline asAnyStruct(); + + kj::Own<ClientHook> asCap(); + // Expect that the result is a capability and construct a pipelined version of it now. + + inline kj::Own<PipelineHook> releasePipelineHook() { return kj::mv(hook); } + // For use by RPC implementations. + + template <typename T, typename = kj::EnableIf<CAPNP_KIND(FromClient<T>) == Kind::INTERFACE>> + inline operator T() { return T(asCap()); } + + private: + kj::Own<PipelineHook> hook; + kj::Array<PipelineOp> ops; + + inline Pipeline(kj::Own<PipelineHook>&& hook, kj::Array<PipelineOp>&& ops) + : hook(kj::mv(hook)), ops(kj::mv(ops)) {} + + friend class LocalClient; + friend class PipelineHook; + friend class AnyStruct::Pipeline; + }; +#endif // !CAPNP_LITE +}; + +template <> +class Orphan<AnyPointer> { + // An orphaned object of unknown type. + +public: + Orphan() = default; + KJ_DISALLOW_COPY(Orphan); + Orphan(Orphan&&) = default; + inline Orphan(_::OrphanBuilder&& builder) + : builder(kj::mv(builder)) {} + + Orphan& operator=(Orphan&&) = default; + + template <typename T> + inline Orphan(Orphan<T>&& other): builder(kj::mv(other.builder)) {} + template <typename T> + inline Orphan& operator=(Orphan<T>&& other) { builder = kj::mv(other.builder); return *this; } + // Cast from typed orphan. + + // It's not possible to get an AnyPointer::{Reader,Builder} directly since there is no + // underlying pointer (the pointer would normally live in the parent, but this object is + // orphaned). It is possible, however, to request typed readers/builders. + + template <typename T> + inline BuilderFor<T> getAs(); + template <typename T> + inline BuilderFor<T> getAs(StructSchema schema); + template <typename T> + inline BuilderFor<T> getAs(ListSchema schema); + template <typename T> + inline typename T::Client getAs(InterfaceSchema schema); + template <typename T> + inline ReaderFor<T> getAsReader() const; + template <typename T> + inline ReaderFor<T> getAsReader(StructSchema schema) const; + template <typename T> + inline ReaderFor<T> getAsReader(ListSchema schema) const; + template <typename T> + inline typename T::Client getAsReader(InterfaceSchema schema) const; + + template <typename T> + inline Orphan<T> releaseAs(); + template <typename T> + inline Orphan<T> releaseAs(StructSchema schema); + template <typename T> + inline Orphan<T> releaseAs(ListSchema schema); + template <typename T> + inline Orphan<T> releaseAs(InterfaceSchema schema); + // Down-cast the orphan to a specific type. + + inline bool operator==(decltype(nullptr)) const { return builder == nullptr; } + inline bool operator!=(decltype(nullptr)) const { return builder != nullptr; } + +private: + _::OrphanBuilder builder; + + template <typename, Kind> + friend struct _::PointerHelpers; + friend class Orphanage; + template <typename U> + friend class Orphan; + friend class AnyPointer::Builder; +}; + +template <Kind k> struct AnyTypeFor_; +template <> struct AnyTypeFor_<Kind::STRUCT> { typedef AnyStruct Type; }; +template <> struct AnyTypeFor_<Kind::LIST> { typedef AnyList Type; }; + +template <typename T> +using AnyTypeFor = typename AnyTypeFor_<CAPNP_KIND(T)>::Type; + +template <typename T> +inline ReaderFor<AnyTypeFor<FromReader<T>>> toAny(T&& value) { + return ReaderFor<AnyTypeFor<FromReader<T>>>( + _::PointerHelpers<FromReader<T>>::getInternalReader(value)); +} +template <typename T> +inline BuilderFor<AnyTypeFor<FromBuilder<T>>> toAny(T&& value) { + return BuilderFor<AnyTypeFor<FromBuilder<T>>>( + _::PointerHelpers<FromBuilder<T>>::getInternalBuilder(kj::mv(value))); +} + +template <> +struct List<AnyPointer, Kind::OTHER> { + // Note: This cannot be used for a list of structs, since such lists are not encoded as pointer + // lists! Use List<AnyStruct>. + + List() = delete; + + class Reader { + public: + typedef List<AnyPointer> Reads; + + inline Reader(): reader(ElementSize::POINTER) {} + inline explicit Reader(_::ListReader reader): reader(reader) {} + + inline uint size() const { return reader.size() / ELEMENTS; } + inline AnyPointer::Reader operator[](uint index) const { + KJ_IREQUIRE(index < size()); + return AnyPointer::Reader(reader.getPointerElement(index * ELEMENTS)); + } + + typedef _::IndexingIterator<const Reader, typename AnyPointer::Reader> Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + + private: + _::ListReader reader; + template <typename U, Kind K> + friend struct _::PointerHelpers; + template <typename U, Kind K> + friend struct List; + friend class Orphanage; + template <typename U, Kind K> + friend struct ToDynamic_; + }; + + class Builder { + public: + typedef List<AnyPointer> Builds; + + Builder() = delete; + inline Builder(decltype(nullptr)): builder(ElementSize::POINTER) {} + inline explicit Builder(_::ListBuilder builder): builder(builder) {} + + inline operator Reader() const { return Reader(builder.asReader()); } + inline Reader asReader() const { return Reader(builder.asReader()); } + + inline uint size() const { return builder.size() / ELEMENTS; } + inline AnyPointer::Builder operator[](uint index) { + KJ_IREQUIRE(index < size()); + return AnyPointer::Builder(builder.getPointerElement(index * ELEMENTS)); + } + + typedef _::IndexingIterator<Builder, typename AnyPointer::Builder> Iterator; + inline Iterator begin() { return Iterator(this, 0); } + inline Iterator end() { return Iterator(this, size()); } + + private: + _::ListBuilder builder; + template <typename, Kind> + friend struct _::PointerHelpers; + friend class Orphanage; + template <typename, Kind> + friend struct ToDynamic_; + }; +}; + +class AnyStruct::Reader { +public: + typedef AnyStruct Reads; + + Reader() = default; + inline Reader(_::StructReader reader): _reader(reader) {} + + template <typename T, typename = kj::EnableIf<CAPNP_KIND(FromReader<T>) == Kind::STRUCT>> + inline Reader(T&& value) + : _reader(_::PointerHelpers<FromReader<T>>::getInternalReader(kj::fwd<T>(value))) {} + + kj::ArrayPtr<const byte> getDataSection() { + return _reader.getDataSectionAsBlob(); + } + List<AnyPointer>::Reader getPointerSection() { + return List<AnyPointer>::Reader(_reader.getPointerSectionAsList()); + } + + kj::Array<word> canonicalize() { + return _reader.canonicalize(); + } + + Equality equals(AnyStruct::Reader right); + bool operator==(AnyStruct::Reader right); + inline bool operator!=(AnyStruct::Reader right) { + return !(*this == right); + } + + template <typename T> + ReaderFor<T> as() const { + // T must be a struct type. + return typename T::Reader(_reader); + } +private: + _::StructReader _reader; + + template <typename, Kind> + friend struct _::PointerHelpers; + friend class Orphanage; +}; + +class AnyStruct::Builder { +public: + typedef AnyStruct Builds; + + inline Builder(decltype(nullptr)) {} + inline Builder(_::StructBuilder builder): _builder(builder) {} + +#if !_MSC_VER // TODO(msvc): MSVC ICEs on this. Try restoring when compiler improves. + template <typename T, typename = kj::EnableIf<CAPNP_KIND(FromBuilder<T>) == Kind::STRUCT>> + inline Builder(T&& value) + : _builder(_::PointerHelpers<FromBuilder<T>>::getInternalBuilder(kj::fwd<T>(value))) {} +#endif + + inline kj::ArrayPtr<byte> getDataSection() { + return _builder.getDataSectionAsBlob(); + } + List<AnyPointer>::Builder getPointerSection() { + return List<AnyPointer>::Builder(_builder.getPointerSectionAsList()); + } + + inline Equality equals(AnyStruct::Reader right) { + return asReader().equals(right); + } + inline bool operator==(AnyStruct::Reader right) { + return asReader() == right; + } + inline bool operator!=(AnyStruct::Reader right) { + return !(*this == right); + } + + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return Reader(_builder.asReader()); } + + template <typename T> + BuilderFor<T> as() { + // T must be a struct type. + return typename T::Builder(_builder); + } +private: + _::StructBuilder _builder; + friend class Orphanage; + friend class CapBuilderContext; +}; + +#if !CAPNP_LITE +class AnyStruct::Pipeline { +public: + inline Pipeline(decltype(nullptr)): typeless(nullptr) {} + inline explicit Pipeline(AnyPointer::Pipeline&& typeless) + : typeless(kj::mv(typeless)) {} + + inline AnyPointer::Pipeline getPointerField(uint16_t pointerIndex) { + // Return a new Promise representing a sub-object of the result. `pointerIndex` is the index + // of the sub-object within the pointer section of the result (the result must be a struct). + // + // TODO(perf): On GCC 4.8 / Clang 3.3, use rvalue qualifiers to avoid the need for copies. + // Also make `ops` into a Vector to optimize this. + return typeless.getPointerField(pointerIndex); + } + +private: + AnyPointer::Pipeline typeless; +}; +#endif // !CAPNP_LITE + +class List<AnyStruct, Kind::OTHER>::Reader { +public: + typedef List<AnyStruct> Reads; + + inline Reader(): reader(ElementSize::INLINE_COMPOSITE) {} + inline explicit Reader(_::ListReader reader): reader(reader) {} + + inline uint size() const { return reader.size() / ELEMENTS; } + inline AnyStruct::Reader operator[](uint index) const { + KJ_IREQUIRE(index < size()); + return AnyStruct::Reader(reader.getStructElement(index * ELEMENTS)); + } + + typedef _::IndexingIterator<const Reader, typename AnyStruct::Reader> Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + +private: + _::ListReader reader; + template <typename U, Kind K> + friend struct _::PointerHelpers; + template <typename U, Kind K> + friend struct List; + friend class Orphanage; + template <typename U, Kind K> + friend struct ToDynamic_; +}; + +class List<AnyStruct, Kind::OTHER>::Builder { +public: + typedef List<AnyStruct> Builds; + + Builder() = delete; + inline Builder(decltype(nullptr)): builder(ElementSize::INLINE_COMPOSITE) {} + inline explicit Builder(_::ListBuilder builder): builder(builder) {} + + inline operator Reader() const { return Reader(builder.asReader()); } + inline Reader asReader() const { return Reader(builder.asReader()); } + + inline uint size() const { return builder.size() / ELEMENTS; } + inline AnyStruct::Builder operator[](uint index) { + KJ_IREQUIRE(index < size()); + return AnyStruct::Builder(builder.getStructElement(index * ELEMENTS)); + } + + typedef _::IndexingIterator<Builder, typename AnyStruct::Builder> Iterator; + inline Iterator begin() { return Iterator(this, 0); } + inline Iterator end() { return Iterator(this, size()); } + +private: + _::ListBuilder builder; + template <typename U, Kind K> + friend struct _::PointerHelpers; + friend class Orphanage; + template <typename U, Kind K> + friend struct ToDynamic_; +}; + +class AnyList::Reader { +public: + typedef AnyList Reads; + + inline Reader(): _reader(ElementSize::VOID) {} + inline Reader(_::ListReader reader): _reader(reader) {} + +#if !_MSC_VER // TODO(msvc): MSVC ICEs on this. Try restoring when compiler improves. + template <typename T, typename = kj::EnableIf<CAPNP_KIND(FromReader<T>) == Kind::LIST>> + inline Reader(T&& value) + : _reader(_::PointerHelpers<FromReader<T>>::getInternalReader(kj::fwd<T>(value))) {} +#endif + + inline ElementSize getElementSize() { return _reader.getElementSize(); } + inline uint size() { return _reader.size() / ELEMENTS; } + + inline kj::ArrayPtr<const byte> getRawBytes() { return _reader.asRawBytes(); } + + Equality equals(AnyList::Reader right); + bool operator==(AnyList::Reader right); + inline bool operator!=(AnyList::Reader right) { + return !(*this == right); + } + + template <typename T> ReaderFor<T> as() { + // T must be List<U>. + return ReaderFor<T>(_reader); + } +private: + _::ListReader _reader; + + template <typename, Kind> + friend struct _::PointerHelpers; + friend class Orphanage; +}; + +class AnyList::Builder { +public: + typedef AnyList Builds; + + inline Builder(decltype(nullptr)): _builder(ElementSize::VOID) {} + inline Builder(_::ListBuilder builder): _builder(builder) {} + +#if !_MSC_VER // TODO(msvc): MSVC ICEs on this. Try restoring when compiler improves. + template <typename T, typename = kj::EnableIf<CAPNP_KIND(FromBuilder<T>) == Kind::LIST>> + inline Builder(T&& value) + : _builder(_::PointerHelpers<FromBuilder<T>>::getInternalBuilder(kj::fwd<T>(value))) {} +#endif + + inline ElementSize getElementSize() { return _builder.getElementSize(); } + inline uint size() { return _builder.size() / ELEMENTS; } + + Equality equals(AnyList::Reader right); + inline bool operator==(AnyList::Reader right) { + return asReader() == right; + } + inline bool operator!=(AnyList::Reader right) { + return !(*this == right); + } + + template <typename T> BuilderFor<T> as() { + // T must be List<U>. + return BuilderFor<T>(_builder); + } + + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return Reader(_builder.asReader()); } + +private: + _::ListBuilder _builder; + + friend class Orphanage; +}; + +// ======================================================================================= +// Pipeline helpers +// +// These relate to capabilities, but we don't declare them in capability.h because generated code +// for structs needs to know about these, even in files that contain no interfaces. + +#if !CAPNP_LITE + +struct PipelineOp { + // Corresponds to rpc.capnp's PromisedAnswer.Op. + + enum Type { + NOOP, // for convenience + + GET_POINTER_FIELD + + // There may be other types in the future... + }; + + Type type; + union { + uint16_t pointerIndex; // for GET_POINTER_FIELD + }; +}; + +class PipelineHook { + // Represents a currently-running call, and implements pipelined requests on its result. + +public: + virtual kj::Own<PipelineHook> addRef() = 0; + // Increment this object's reference count. + + virtual kj::Own<ClientHook> getPipelinedCap(kj::ArrayPtr<const PipelineOp> ops) = 0; + // Extract a promised Capability from the results. + + virtual kj::Own<ClientHook> getPipelinedCap(kj::Array<PipelineOp>&& ops); + // Version of getPipelinedCap() passing the array by move. May avoid a copy in some cases. + // Default implementation just calls the other version. + + template <typename Pipeline, typename = FromPipeline<Pipeline>> + static inline kj::Own<PipelineHook> from(Pipeline&& pipeline); + +private: + template <typename T> struct FromImpl; +}; + +#endif // !CAPNP_LITE + +// ======================================================================================= +// Inline implementation details + +inline MessageSize AnyPointer::Reader::targetSize() const { + return reader.targetSize().asPublic(); +} + +inline PointerType AnyPointer::Reader::getPointerType() const { + return reader.getPointerType(); +} + +template <typename T> +inline ReaderFor<T> AnyPointer::Reader::getAs() const { + return _::PointerHelpers<T>::get(reader); +} + +inline MessageSize AnyPointer::Builder::targetSize() const { + return asReader().targetSize(); +} + +inline PointerType AnyPointer::Builder::getPointerType() { + return builder.getPointerType(); +} + +inline void AnyPointer::Builder::clear() { + return builder.clear(); +} + +template <typename T> +inline BuilderFor<T> AnyPointer::Builder::getAs() { + return _::PointerHelpers<T>::get(builder); +} + +template <typename T> +inline BuilderFor<T> AnyPointer::Builder::initAs() { + return _::PointerHelpers<T>::init(builder); +} + +template <typename T> +inline BuilderFor<T> AnyPointer::Builder::initAs(uint elementCount) { + return _::PointerHelpers<T>::init(builder, elementCount); +} + +inline AnyList::Builder AnyPointer::Builder::initAsAnyList( + ElementSize elementSize, uint elementCount) { + return AnyList::Builder(builder.initList(elementSize, elementCount * ELEMENTS)); +} + +inline List<AnyStruct>::Builder AnyPointer::Builder::initAsListOfAnyStruct( + uint dataWordCount, uint pointerCount, uint elementCount) { + return List<AnyStruct>::Builder(builder.initStructList(elementCount * ELEMENTS, + _::StructSize(dataWordCount * WORDS, pointerCount * POINTERS))); +} + +inline AnyStruct::Builder AnyPointer::Builder::initAsAnyStruct(uint dataWordCount, uint pointerCount) { + return AnyStruct::Builder(builder.initStruct( + _::StructSize(dataWordCount * WORDS, pointerCount * POINTERS))); +} + +template <typename T> +inline void AnyPointer::Builder::setAs(ReaderFor<T> value) { + return _::PointerHelpers<T>::set(builder, value); +} + +template <typename T> +inline void AnyPointer::Builder::setCanonicalAs(ReaderFor<T> value) { + return _::PointerHelpers<T>::setCanonical(builder, value); +} + +template <typename T> +inline void AnyPointer::Builder::setAs( + std::initializer_list<ReaderFor<ListElementType<T>>> list) { + return _::PointerHelpers<T>::set(builder, list); +} + +template <typename T> +inline void AnyPointer::Builder::adopt(Orphan<T>&& orphan) { + _::PointerHelpers<T>::adopt(builder, kj::mv(orphan)); +} + +template <typename T> +inline Orphan<T> AnyPointer::Builder::disownAs() { + return _::PointerHelpers<T>::disown(builder); +} + +inline Orphan<AnyPointer> AnyPointer::Builder::disown() { + return Orphan<AnyPointer>(builder.disown()); +} + +template <> struct ReaderFor_ <AnyPointer, Kind::OTHER> { typedef AnyPointer::Reader Type; }; +template <> struct BuilderFor_<AnyPointer, Kind::OTHER> { typedef AnyPointer::Builder Type; }; +template <> struct ReaderFor_ <AnyStruct, Kind::OTHER> { typedef AnyStruct::Reader Type; }; +template <> struct BuilderFor_<AnyStruct, Kind::OTHER> { typedef AnyStruct::Builder Type; }; + +template <> +struct Orphanage::GetInnerReader<AnyPointer, Kind::OTHER> { + static inline _::PointerReader apply(const AnyPointer::Reader& t) { + return t.reader; + } +}; + +template <> +struct Orphanage::GetInnerBuilder<AnyPointer, Kind::OTHER> { + static inline _::PointerBuilder apply(AnyPointer::Builder& t) { + return t.builder; + } +}; + +template <> +struct Orphanage::GetInnerReader<AnyStruct, Kind::OTHER> { + static inline _::StructReader apply(const AnyStruct::Reader& t) { + return t._reader; + } +}; + +template <> +struct Orphanage::GetInnerBuilder<AnyStruct, Kind::OTHER> { + static inline _::StructBuilder apply(AnyStruct::Builder& t) { + return t._builder; + } +}; + +template <> +struct Orphanage::GetInnerReader<AnyList, Kind::OTHER> { + static inline _::ListReader apply(const AnyList::Reader& t) { + return t._reader; + } +}; + +template <> +struct Orphanage::GetInnerBuilder<AnyList, Kind::OTHER> { + static inline _::ListBuilder apply(AnyList::Builder& t) { + return t._builder; + } +}; + +template <typename T> +inline BuilderFor<T> Orphan<AnyPointer>::getAs() { + return _::OrphanGetImpl<T>::apply(builder); +} +template <typename T> +inline ReaderFor<T> Orphan<AnyPointer>::getAsReader() const { + return _::OrphanGetImpl<T>::applyReader(builder); +} +template <typename T> +inline Orphan<T> Orphan<AnyPointer>::releaseAs() { + return Orphan<T>(kj::mv(builder)); +} + +// Using AnyPointer as the template type should work... + +template <> +inline typename AnyPointer::Reader AnyPointer::Reader::getAs<AnyPointer>() const { + return *this; +} +template <> +inline typename AnyPointer::Builder AnyPointer::Builder::getAs<AnyPointer>() { + return *this; +} +template <> +inline typename AnyPointer::Builder AnyPointer::Builder::initAs<AnyPointer>() { + clear(); + return *this; +} +template <> +inline void AnyPointer::Builder::setAs<AnyPointer>(AnyPointer::Reader value) { + return builder.copyFrom(value.reader); +} +template <> +inline void AnyPointer::Builder::adopt<AnyPointer>(Orphan<AnyPointer>&& orphan) { + builder.adopt(kj::mv(orphan.builder)); +} +template <> +inline Orphan<AnyPointer> AnyPointer::Builder::disownAs<AnyPointer>() { + return Orphan<AnyPointer>(builder.disown()); +} +template <> +inline Orphan<AnyPointer> Orphan<AnyPointer>::releaseAs() { + return kj::mv(*this); +} + +namespace _ { // private + +// Specialize PointerHelpers for AnyPointer. + +template <> +struct PointerHelpers<AnyPointer, Kind::OTHER> { + static inline AnyPointer::Reader get(PointerReader reader, + const void* defaultValue = nullptr, + uint defaultBytes = 0) { + return AnyPointer::Reader(reader); + } + static inline AnyPointer::Builder get(PointerBuilder builder, + const void* defaultValue = nullptr, + uint defaultBytes = 0) { + return AnyPointer::Builder(builder); + } + static inline void set(PointerBuilder builder, AnyPointer::Reader value) { + AnyPointer::Builder(builder).set(value); + } + static inline void adopt(PointerBuilder builder, Orphan<AnyPointer>&& value) { + builder.adopt(kj::mv(value.builder)); + } + static inline Orphan<AnyPointer> disown(PointerBuilder builder) { + return Orphan<AnyPointer>(builder.disown()); + } + static inline _::PointerReader getInternalReader(const AnyPointer::Reader& reader) { + return reader.reader; + } + static inline _::PointerBuilder getInternalBuilder(AnyPointer::Builder&& builder) { + return builder.builder; + } +}; + +template <> +struct PointerHelpers<AnyStruct, Kind::OTHER> { + static inline AnyStruct::Reader get( + PointerReader reader, const word* defaultValue = nullptr) { + return AnyStruct::Reader(reader.getStruct(defaultValue)); + } + static inline AnyStruct::Builder get( + PointerBuilder builder, const word* defaultValue = nullptr) { + // TODO(someday): Allow specifying the size somehow? + return AnyStruct::Builder(builder.getStruct( + _::StructSize(0 * WORDS, 0 * POINTERS), defaultValue)); + } + static inline void set(PointerBuilder builder, AnyStruct::Reader value) { + builder.setStruct(value._reader); + } + static inline AnyStruct::Builder init( + PointerBuilder builder, uint dataWordCount, uint pointerCount) { + return AnyStruct::Builder(builder.initStruct( + StructSize(dataWordCount * WORDS, pointerCount * POINTERS))); + } + + // TODO(soon): implement these + static void adopt(PointerBuilder builder, Orphan<AnyStruct>&& value); + static Orphan<AnyStruct> disown(PointerBuilder builder); +}; + +template <> +struct PointerHelpers<AnyList, Kind::OTHER> { + static inline AnyList::Reader get( + PointerReader reader, const word* defaultValue = nullptr) { + return AnyList::Reader(reader.getListAnySize(defaultValue)); + } + static inline AnyList::Builder get( + PointerBuilder builder, const word* defaultValue = nullptr) { + return AnyList::Builder(builder.getListAnySize(defaultValue)); + } + static inline void set(PointerBuilder builder, AnyList::Reader value) { + builder.setList(value._reader); + } + static inline AnyList::Builder init( + PointerBuilder builder, ElementSize elementSize, uint elementCount) { + return AnyList::Builder(builder.initList(elementSize, elementCount * ELEMENTS)); + } + static inline AnyList::Builder init( + PointerBuilder builder, uint dataWordCount, uint pointerCount, uint elementCount) { + return AnyList::Builder(builder.initStructList( + elementCount * ELEMENTS, StructSize(dataWordCount * WORDS, pointerCount * POINTERS))); + } + + // TODO(soon): implement these + static void adopt(PointerBuilder builder, Orphan<AnyList>&& value); + static Orphan<AnyList> disown(PointerBuilder builder); +}; + +template <> +struct OrphanGetImpl<AnyStruct, Kind::OTHER> { + static inline AnyStruct::Builder apply(_::OrphanBuilder& builder) { + return AnyStruct::Builder(builder.asStruct(_::StructSize(0 * WORDS, 0 * POINTERS))); + } + static inline AnyStruct::Reader applyReader(const _::OrphanBuilder& builder) { + return AnyStruct::Reader(builder.asStructReader(_::StructSize(0 * WORDS, 0 * POINTERS))); + } + static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { + builder.truncate(size, _::StructSize(0 * WORDS, 0 * POINTERS)); + } +}; + +} // namespace _ (private) + +#if !CAPNP_LITE + +template <typename T> +struct PipelineHook::FromImpl { + static inline kj::Own<PipelineHook> apply(typename T::Pipeline&& pipeline) { + return from(kj::mv(pipeline._typeless)); + } +}; + +template <> +struct PipelineHook::FromImpl<AnyPointer> { + static inline kj::Own<PipelineHook> apply(AnyPointer::Pipeline&& pipeline) { + return kj::mv(pipeline.hook); + } +}; + +template <typename Pipeline, typename T> +inline kj::Own<PipelineHook> PipelineHook::from(Pipeline&& pipeline) { + return FromImpl<T>::apply(kj::fwd<Pipeline>(pipeline)); +} + +#endif // !CAPNP_LITE + +} // namespace capnp + +#endif // CAPNP_ANY_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/arena.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,457 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef CAPNP_ARENA_H_ +#define CAPNP_ARENA_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#ifndef CAPNP_PRIVATE +#error "This header is only meant to be included by Cap'n Proto's own source code." +#endif + +#include <kj/common.h> +#include <kj/mutex.h> +#include <kj/exception.h> +#include <kj/vector.h> +#include "common.h" +#include "message.h" +#include "layout.h" +#include <unordered_map> + +#if !CAPNP_LITE +#include "capability.h" +#endif // !CAPNP_LITE + +namespace capnp { + +#if !CAPNP_LITE +class ClientHook; +#endif // !CAPNP_LITE + +namespace _ { // private + +class SegmentReader; +class SegmentBuilder; +class Arena; +class BuilderArena; +class ReadLimiter; + +class Segment; +typedef kj::Id<uint32_t, Segment> SegmentId; + +class ReadLimiter { + // Used to keep track of how much data has been processed from a message, and cut off further + // processing if and when a particular limit is reached. This is primarily intended to guard + // against maliciously-crafted messages which contain cycles or overlapping structures. Cycles + // and overlapping are not permitted by the Cap'n Proto format because in many cases they could + // be used to craft a deceptively small message which could consume excessive server resources to + // process, perhaps even sending it into an infinite loop. Actually detecting overlaps would be + // time-consuming, so instead we just keep track of how many words worth of data structures the + // receiver has actually dereferenced and error out if this gets too high. + // + // This counting takes place as you call getters (for non-primitive values) on the message + // readers. If you call the same getter twice, the data it returns may be double-counted. This + // should not be a big deal in most cases -- just set the read limit high enough that it will + // only trigger in unreasonable cases. + // + // This class is "safe" to use from multiple threads for its intended use case. Threads may + // overwrite each others' changes to the counter, but this is OK because it only means that the + // limit is enforced a bit less strictly -- it will still kick in eventually. + +public: + inline explicit ReadLimiter(); // No limit. + inline explicit ReadLimiter(WordCount64 limit); // Limit to the given number of words. + + inline void reset(WordCount64 limit); + + KJ_ALWAYS_INLINE(bool canRead(WordCount amount, Arena* arena)); + + void unread(WordCount64 amount); + // Adds back some words to the limit. Useful when the caller knows they are double-reading + // some data. + +private: + volatile uint64_t limit; + // Current limit, decremented each time catRead() is called. Volatile because multiple threads + // could be trying to modify it at once. (This is not real thread-safety, but good enough for + // the purpose of this class. See class comment.) + + KJ_DISALLOW_COPY(ReadLimiter); +}; + +#if !CAPNP_LITE +class BrokenCapFactory { + // Callback for constructing broken caps. We use this so that we can avoid arena.c++ having a + // link-time dependency on capability code that lives in libcapnp-rpc. + +public: + virtual kj::Own<ClientHook> newBrokenCap(kj::StringPtr description) = 0; + virtual kj::Own<ClientHook> newNullCap() = 0; +}; +#endif // !CAPNP_LITE + +class SegmentReader { +public: + inline SegmentReader(Arena* arena, SegmentId id, kj::ArrayPtr<const word> ptr, + ReadLimiter* readLimiter); + + KJ_ALWAYS_INLINE(bool containsInterval(const void* from, const void* to)); + + KJ_ALWAYS_INLINE(bool amplifiedRead(WordCount virtualAmount)); + // Indicates that the reader should pretend that `virtualAmount` additional data was read even + // though no actual pointer was traversed. This is used e.g. when reading a struct list pointer + // where the element sizes are zero -- the sender could set the list size arbitrarily high and + // cause the receiver to iterate over this list even though the message itself is small, so we + // need to defend against DoS attacks based on this. + + inline Arena* getArena(); + inline SegmentId getSegmentId(); + + inline const word* getStartPtr(); + inline WordCount getOffsetTo(const word* ptr); + inline WordCount getSize(); + + inline kj::ArrayPtr<const word> getArray(); + + inline void unread(WordCount64 amount); + // Add back some words to the ReadLimiter. + +private: + Arena* arena; + SegmentId id; + kj::ArrayPtr<const word> ptr; + ReadLimiter* readLimiter; + + KJ_DISALLOW_COPY(SegmentReader); + + friend class SegmentBuilder; +}; + +class SegmentBuilder: public SegmentReader { +public: + inline SegmentBuilder(BuilderArena* arena, SegmentId id, kj::ArrayPtr<word> ptr, + ReadLimiter* readLimiter, size_t wordsUsed = 0); + inline SegmentBuilder(BuilderArena* arena, SegmentId id, kj::ArrayPtr<const word> ptr, + ReadLimiter* readLimiter); + inline SegmentBuilder(BuilderArena* arena, SegmentId id, decltype(nullptr), + ReadLimiter* readLimiter); + + KJ_ALWAYS_INLINE(word* allocate(WordCount amount)); + + KJ_ALWAYS_INLINE(void checkWritable()); + // Throw an exception if the segment is read-only (meaning it is a reference to external data). + + KJ_ALWAYS_INLINE(word* getPtrUnchecked(WordCount offset)); + // Get a writable pointer into the segment. Throws an exception if the segment is read-only (i.e. + // a reference to external immutable data). + + inline BuilderArena* getArena(); + + inline kj::ArrayPtr<const word> currentlyAllocated(); + + inline void reset(); + + inline bool isWritable() { return !readOnly; } + + inline void tryTruncate(word* from, word* to); + // If `from` points just past the current end of the segment, then move the end back to `to`. + // Otherwise, do nothing. + + inline bool tryExtend(word* from, word* to); + // If `from` points just past the current end of the segment, and `to` is within the segment + // boundaries, then move the end up to `to` and return true. Otherwise, do nothing and return + // false. + +private: + word* pos; + // Pointer to a pointer to the current end point of the segment, i.e. the location where the + // next object should be allocated. + + bool readOnly; + + void throwNotWritable(); + + KJ_DISALLOW_COPY(SegmentBuilder); +}; + +class Arena { +public: + virtual ~Arena() noexcept(false); + + virtual SegmentReader* tryGetSegment(SegmentId id) = 0; + // Gets the segment with the given ID, or return nullptr if no such segment exists. + + virtual void reportReadLimitReached() = 0; + // Called to report that the read limit has been reached. See ReadLimiter, below. This invokes + // the VALIDATE_INPUT() macro which may throw an exception; if it returns normally, the caller + // will need to continue with default values. +}; + +class ReaderArena final: public Arena { +public: + ReaderArena(MessageReader* message); + ~ReaderArena() noexcept(false); + KJ_DISALLOW_COPY(ReaderArena); + + // implements Arena ------------------------------------------------ + SegmentReader* tryGetSegment(SegmentId id) override; + void reportReadLimitReached() override; + +private: + MessageReader* message; + ReadLimiter readLimiter; + + // Optimize for single-segment messages so that small messages are handled quickly. + SegmentReader segment0; + + typedef std::unordered_map<uint, kj::Own<SegmentReader>> SegmentMap; + kj::MutexGuarded<kj::Maybe<kj::Own<SegmentMap>>> moreSegments; + // We need to mutex-guard the segment map because we lazily initialize segments when they are + // first requested, but a Reader is allowed to be used concurrently in multiple threads. Luckily + // this only applies to large messages. + // + // TODO(perf): Thread-local thing instead? Some kind of lockless map? Or do sharing of data + // in a different way, where you have to construct a new MessageReader in each thread (but + // possibly backed by the same data)? +}; + +class BuilderArena final: public Arena { + // A BuilderArena that does not allow the injection of capabilities. + +public: + explicit BuilderArena(MessageBuilder* message); + BuilderArena(MessageBuilder* message, kj::ArrayPtr<MessageBuilder::SegmentInit> segments); + ~BuilderArena() noexcept(false); + KJ_DISALLOW_COPY(BuilderArena); + + inline SegmentBuilder* getRootSegment() { return &segment0; } + + kj::ArrayPtr<const kj::ArrayPtr<const word>> getSegmentsForOutput(); + // Get an array of all the segments, suitable for writing out. This only returns the allocated + // portion of each segment, whereas tryGetSegment() returns something that includes + // not-yet-allocated space. + + inline CapTableBuilder* getLocalCapTable() { + // Return a CapTableBuilder that merely implements local loopback. That is, you can set + // capabilities, then read the same capabilities back, but there is no intent ever to transmit + // these capabilities. A MessageBuilder that isn't imbued with some other CapTable uses this + // by default. + // + // TODO(cleanup): It's sort of a hack that this exists. In theory, perhaps, unimbued + // MessageBuilders should throw exceptions on any attempt to access capability fields, like + // unimbued MessageReaders do. However, lots of code exists which uses MallocMessageBuilder + // as a temporary holder for data to be copied in and out (without being serialized), and it + // is expected that such data can include capabilities, which is admittedly reasonable. + // Therefore, all MessageBuilders must have a cap table by default. Arguably we should + // deprecate this usage and instead define a new helper type for this exact purpose. + + return &localCapTable; + } + + SegmentBuilder* getSegment(SegmentId id); + // Get the segment with the given id. Crashes or throws an exception if no such segment exists. + + struct AllocateResult { + SegmentBuilder* segment; + word* words; + }; + + AllocateResult allocate(WordCount amount); + // Find a segment with at least the given amount of space available and allocate the space. + // Note that allocating directly from a particular segment is much faster, but allocating from + // the arena is guaranteed to succeed. Therefore callers should try to allocate from a specific + // segment first if there is one, then fall back to the arena. + + SegmentBuilder* addExternalSegment(kj::ArrayPtr<const word> content); + // Add a new segment to the arena which points to some existing memory region. The segment is + // assumed to be completley full; the arena will never allocate from it. In fact, the segment + // is considered read-only. Any attempt to get a Builder pointing into this segment will throw + // an exception. Readers are allowed, however. + // + // This can be used to inject some external data into a message without a copy, e.g. embedding a + // large mmap'd file into a message as `Data` without forcing that data to actually be read in + // from disk (until the message itself is written out). `Orphanage` provides the public API for + // this feature. + + // implements Arena ------------------------------------------------ + SegmentReader* tryGetSegment(SegmentId id) override; + void reportReadLimitReached() override; + +private: + MessageBuilder* message; + ReadLimiter dummyLimiter; + + class LocalCapTable: public CapTableBuilder { +#if !CAPNP_LITE + public: + kj::Maybe<kj::Own<ClientHook>> extractCap(uint index) override; + uint injectCap(kj::Own<ClientHook>&& cap) override; + void dropCap(uint index) override; + + private: + kj::Vector<kj::Maybe<kj::Own<ClientHook>>> capTable; +#endif // ! CAPNP_LITE + }; + + LocalCapTable localCapTable; + + SegmentBuilder segment0; + kj::ArrayPtr<const word> segment0ForOutput; + + struct MultiSegmentState { + kj::Vector<kj::Own<SegmentBuilder>> builders; + kj::Vector<kj::ArrayPtr<const word>> forOutput; + }; + kj::Maybe<kj::Own<MultiSegmentState>> moreSegments; + + SegmentBuilder* segmentWithSpace = nullptr; + // When allocating, look for space in this segment first before resorting to allocating a new + // segment. This is not necessarily the last segment because addExternalSegment() may add a + // segment that is already-full, in which case we don't update this pointer. + + template <typename T> // Can be `word` or `const word`. + SegmentBuilder* addSegmentInternal(kj::ArrayPtr<T> content); +}; + +// ======================================================================================= + +inline ReadLimiter::ReadLimiter() + : limit(kj::maxValue) {} + +inline ReadLimiter::ReadLimiter(WordCount64 limit): limit(limit / WORDS) {} + +inline void ReadLimiter::reset(WordCount64 limit) { this->limit = limit / WORDS; } + +inline bool ReadLimiter::canRead(WordCount amount, Arena* arena) { + // Be careful not to store an underflowed value into `limit`, even if multiple threads are + // decrementing it. + uint64_t current = limit; + if (KJ_UNLIKELY(amount / WORDS > current)) { + arena->reportReadLimitReached(); + return false; + } else { + limit = current - amount / WORDS; + return true; + } +} + +// ------------------------------------------------------------------- + +inline SegmentReader::SegmentReader(Arena* arena, SegmentId id, kj::ArrayPtr<const word> ptr, + ReadLimiter* readLimiter) + : arena(arena), id(id), ptr(ptr), readLimiter(readLimiter) {} + +inline bool SegmentReader::containsInterval(const void* from, const void* to) { + return from >= this->ptr.begin() && to <= this->ptr.end() && from <= to && + readLimiter->canRead( + intervalLength(reinterpret_cast<const byte*>(from), + reinterpret_cast<const byte*>(to)) / BYTES_PER_WORD, + arena); +} + +inline bool SegmentReader::amplifiedRead(WordCount virtualAmount) { + return readLimiter->canRead(virtualAmount, arena); +} + +inline Arena* SegmentReader::getArena() { return arena; } +inline SegmentId SegmentReader::getSegmentId() { return id; } +inline const word* SegmentReader::getStartPtr() { return ptr.begin(); } +inline WordCount SegmentReader::getOffsetTo(const word* ptr) { + return intervalLength(this->ptr.begin(), ptr); +} +inline WordCount SegmentReader::getSize() { return ptr.size() * WORDS; } +inline kj::ArrayPtr<const word> SegmentReader::getArray() { return ptr; } +inline void SegmentReader::unread(WordCount64 amount) { readLimiter->unread(amount); } + +// ------------------------------------------------------------------- + +inline SegmentBuilder::SegmentBuilder( + BuilderArena* arena, SegmentId id, kj::ArrayPtr<word> ptr, ReadLimiter* readLimiter, + size_t wordsUsed) + : SegmentReader(arena, id, ptr, readLimiter), pos(ptr.begin() + wordsUsed), readOnly(false) {} +inline SegmentBuilder::SegmentBuilder( + BuilderArena* arena, SegmentId id, kj::ArrayPtr<const word> ptr, ReadLimiter* readLimiter) + : SegmentReader(arena, id, ptr, readLimiter), + // const_cast is safe here because the member won't ever be dereferenced because it appears + // to point to the end of the segment anyway. + pos(const_cast<word*>(ptr.end())), + readOnly(true) {} +inline SegmentBuilder::SegmentBuilder(BuilderArena* arena, SegmentId id, decltype(nullptr), + ReadLimiter* readLimiter) + : SegmentReader(arena, id, nullptr, readLimiter), pos(nullptr), readOnly(false) {} + +inline word* SegmentBuilder::allocate(WordCount amount) { + if (intervalLength(pos, ptr.end()) < amount) { + // Not enough space in the segment for this allocation. + return nullptr; + } else { + // Success. + word* result = pos; + pos = pos + amount; + return result; + } +} + +inline void SegmentBuilder::checkWritable() { + if (KJ_UNLIKELY(readOnly)) throwNotWritable(); +} + +inline word* SegmentBuilder::getPtrUnchecked(WordCount offset) { + return const_cast<word*>(ptr.begin() + offset); +} + +inline BuilderArena* SegmentBuilder::getArena() { + // Down-cast safe because SegmentBuilder's constructor always initializes its SegmentReader base + // class with an Arena pointer that actually points to a BuilderArena. + return static_cast<BuilderArena*>(arena); +} + +inline kj::ArrayPtr<const word> SegmentBuilder::currentlyAllocated() { + return kj::arrayPtr(ptr.begin(), pos - ptr.begin()); +} + +inline void SegmentBuilder::reset() { + word* start = getPtrUnchecked(0 * WORDS); + memset(start, 0, (pos - start) * sizeof(word)); + pos = start; +} + +inline void SegmentBuilder::tryTruncate(word* from, word* to) { + if (pos == from) pos = to; +} + +inline bool SegmentBuilder::tryExtend(word* from, word* to) { + // Careful about overflow. + if (pos == from && to <= ptr.end() && to >= from) { + pos = to; + return true; + } else { + return false; + } +} + +} // namespace _ (private) +} // namespace capnp + +#endif // CAPNP_ARENA_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/blob.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,220 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef CAPNP_BLOB_H_ +#define CAPNP_BLOB_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include <kj/common.h> +#include <kj/string.h> +#include "common.h" +#include <string.h> + +namespace capnp { + +struct Data { + Data() = delete; + class Reader; + class Builder; + class Pipeline {}; +}; + +struct Text { + Text() = delete; + class Reader; + class Builder; + class Pipeline {}; +}; + +class Data::Reader: public kj::ArrayPtr<const byte> { + // Points to a blob of bytes. The usual Reader rules apply -- Data::Reader behaves like a simple + // pointer which does not own its target, can be passed by value, etc. + +public: + typedef Data Reads; + + Reader() = default; + inline Reader(decltype(nullptr)): ArrayPtr<const byte>(nullptr) {} + inline Reader(const byte* value, size_t size): ArrayPtr<const byte>(value, size) {} + inline Reader(const kj::Array<const byte>& value): ArrayPtr<const byte>(value) {} + inline Reader(const ArrayPtr<const byte>& value): ArrayPtr<const byte>(value) {} + inline Reader(const kj::Array<byte>& value): ArrayPtr<const byte>(value) {} + inline Reader(const ArrayPtr<byte>& value): ArrayPtr<const byte>(value) {} +}; + +class Text::Reader: public kj::StringPtr { + // Like Data::Reader, but points at NUL-terminated UTF-8 text. The NUL terminator is not counted + // in the size but must be present immediately after the last byte. + // + // Text::Reader's interface contract is that its data MUST be NUL-terminated. The producer of + // the Text::Reader must guarantee this, so that the consumer need not check. The data SHOULD + // also be valid UTF-8, but this is NOT guaranteed -- the consumer must verify if it cares. + +public: + typedef Text Reads; + + Reader() = default; + inline Reader(decltype(nullptr)): StringPtr(nullptr) {} + inline Reader(const char* value): StringPtr(value) {} + inline Reader(const char* value, size_t size): StringPtr(value, size) {} + inline Reader(const kj::String& value): StringPtr(value) {} + inline Reader(const StringPtr& value): StringPtr(value) {} + +#if KJ_COMPILER_SUPPORTS_STL_STRING_INTEROP + template <typename T, typename = decltype(kj::instance<T>().c_str())> + inline Reader(const T& t): StringPtr(t) {} + // Allow implicit conversion from any class that has a c_str() method (namely, std::string). + // We use a template trick to detect std::string in order to avoid including the header for + // those who don't want it. +#endif +}; + +class Data::Builder: public kj::ArrayPtr<byte> { + // Like Data::Reader except the pointers aren't const. + +public: + typedef Data Builds; + + Builder() = default; + inline Builder(decltype(nullptr)): ArrayPtr<byte>(nullptr) {} + inline Builder(byte* value, size_t size): ArrayPtr<byte>(value, size) {} + inline Builder(kj::Array<byte>& value): ArrayPtr<byte>(value) {} + inline Builder(ArrayPtr<byte> value): ArrayPtr<byte>(value) {} + + inline Data::Reader asReader() const { return Data::Reader(*this); } + inline operator Reader() const { return asReader(); } +}; + +class Text::Builder: public kj::DisallowConstCopy { + // Basically identical to kj::StringPtr, except that the contents are non-const. + +public: + inline Builder(): content(nulstr, 1) {} + inline Builder(decltype(nullptr)): content(nulstr, 1) {} + inline Builder(char* value): content(value, strlen(value) + 1) {} + inline Builder(char* value, size_t size): content(value, size + 1) { + KJ_IREQUIRE(value[size] == '\0', "StringPtr must be NUL-terminated."); + } + + inline Reader asReader() const { return Reader(content.begin(), content.size() - 1); } + inline operator Reader() const { return asReader(); } + + inline operator kj::ArrayPtr<char>(); + inline kj::ArrayPtr<char> asArray(); + inline operator kj::ArrayPtr<const char>() const; + inline kj::ArrayPtr<const char> asArray() const; + inline kj::ArrayPtr<byte> asBytes() { return asArray().asBytes(); } + inline kj::ArrayPtr<const byte> asBytes() const { return asArray().asBytes(); } + // Result does not include NUL terminator. + + inline operator kj::StringPtr() const; + inline kj::StringPtr asString() const; + + inline const char* cStr() const { return content.begin(); } + // Returns NUL-terminated string. + + inline size_t size() const { return content.size() - 1; } + // Result does not include NUL terminator. + + inline char operator[](size_t index) const { return content[index]; } + inline char& operator[](size_t index) { return content[index]; } + + inline char* begin() { return content.begin(); } + inline char* end() { return content.end() - 1; } + inline const char* begin() const { return content.begin(); } + inline const char* end() const { return content.end() - 1; } + + inline bool operator==(decltype(nullptr)) const { return content.size() <= 1; } + inline bool operator!=(decltype(nullptr)) const { return content.size() > 1; } + + inline bool operator==(Builder other) const { return asString() == other.asString(); } + inline bool operator!=(Builder other) const { return asString() != other.asString(); } + inline bool operator< (Builder other) const { return asString() < other.asString(); } + inline bool operator> (Builder other) const { return asString() > other.asString(); } + inline bool operator<=(Builder other) const { return asString() <= other.asString(); } + inline bool operator>=(Builder other) const { return asString() >= other.asString(); } + + inline kj::StringPtr slice(size_t start) const; + inline kj::ArrayPtr<const char> slice(size_t start, size_t end) const; + inline Builder slice(size_t start); + inline kj::ArrayPtr<char> slice(size_t start, size_t end); + // A string slice is only NUL-terminated if it is a suffix, so slice() has a one-parameter + // version that assumes end = size(). + +private: + inline explicit Builder(kj::ArrayPtr<char> content): content(content) {} + + kj::ArrayPtr<char> content; + + static char nulstr[1]; +}; + +inline kj::StringPtr KJ_STRINGIFY(Text::Builder builder) { + return builder.asString(); +} + +inline bool operator==(const char* a, const Text::Builder& b) { return a == b.asString(); } +inline bool operator!=(const char* a, const Text::Builder& b) { return a != b.asString(); } + +inline Text::Builder::operator kj::StringPtr() const { + return kj::StringPtr(content.begin(), content.size() - 1); +} + +inline kj::StringPtr Text::Builder::asString() const { + return kj::StringPtr(content.begin(), content.size() - 1); +} + +inline Text::Builder::operator kj::ArrayPtr<char>() { + return content.slice(0, content.size() - 1); +} + +inline kj::ArrayPtr<char> Text::Builder::asArray() { + return content.slice(0, content.size() - 1); +} + +inline Text::Builder::operator kj::ArrayPtr<const char>() const { + return content.slice(0, content.size() - 1); +} + +inline kj::ArrayPtr<const char> Text::Builder::asArray() const { + return content.slice(0, content.size() - 1); +} + +inline kj::StringPtr Text::Builder::slice(size_t start) const { + return asReader().slice(start); +} +inline kj::ArrayPtr<const char> Text::Builder::slice(size_t start, size_t end) const { + return content.slice(start, end); +} + +inline Text::Builder Text::Builder::slice(size_t start) { + return Text::Builder(content.slice(start, content.size())); +} +inline kj::ArrayPtr<char> Text::Builder::slice(size_t start, size_t end) { + return content.slice(start, end); +} + +} // namespace capnp + +#endif // CAPNP_BLOB_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/c++.capnp Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,26 @@ +# Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +# Licensed under the MIT License: +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +@0xbdf87d7bb8304e81; +$namespace("capnp::annotations"); + +annotation namespace(file): Text; +annotation name(field, enumerant, struct, enum, interface, method, param, group, union): Text;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/c++.capnp.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,33 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: c++.capnp + +#ifndef CAPNP_INCLUDED_bdf87d7bb8304e81_ +#define CAPNP_INCLUDED_bdf87d7bb8304e81_ + +#include <capnp/generated-header-support.h> + +#if CAPNP_VERSION != 6000 +#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." +#endif + + +namespace capnp { +namespace schemas { + +CAPNP_DECLARE_SCHEMA(b9c6f99ebf805f2c); +CAPNP_DECLARE_SCHEMA(f264a779fef191ce); + +} // namespace schemas +} // namespace capnp + +namespace capnp { +namespace annotations { + +// ======================================================================================= + +// ======================================================================================= + +} // namespace +} // namespace + +#endif // CAPNP_INCLUDED_bdf87d7bb8304e81_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/capability.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,885 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef CAPNP_CAPABILITY_H_ +#define CAPNP_CAPABILITY_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#if CAPNP_LITE +#error "RPC APIs, including this header, are not available in lite mode." +#endif + +#include <kj/async.h> +#include <kj/vector.h> +#include "any.h" +#include "pointer-helpers.h" + +namespace capnp { + +template <typename Results> +class Response; + +template <typename T> +class RemotePromise: public kj::Promise<Response<T>>, public T::Pipeline { + // A Promise which supports pipelined calls. T is typically a struct type. T must declare + // an inner "mix-in" type "Pipeline" which implements pipelining; RemotePromise simply + // multiply-inherits that type along with Promise<Response<T>>. T::Pipeline must be movable, + // but does not need to be copyable (i.e. just like Promise<T>). + // + // The promise is for an owned pointer so that the RPC system can allocate the MessageReader + // itself. + +public: + inline RemotePromise(kj::Promise<Response<T>>&& promise, typename T::Pipeline&& pipeline) + : kj::Promise<Response<T>>(kj::mv(promise)), + T::Pipeline(kj::mv(pipeline)) {} + inline RemotePromise(decltype(nullptr)) + : kj::Promise<Response<T>>(nullptr), + T::Pipeline(nullptr) {} + KJ_DISALLOW_COPY(RemotePromise); + RemotePromise(RemotePromise&& other) = default; + RemotePromise& operator=(RemotePromise&& other) = default; +}; + +class LocalClient; +namespace _ { // private +struct RawSchema; +struct RawBrandedSchema; +extern const RawSchema NULL_INTERFACE_SCHEMA; // defined in schema.c++ +class CapabilityServerSetBase; +} // namespace _ (private) + +struct Capability { + // A capability without type-safe methods. Typed capability clients wrap `Client` and typed + // capability servers subclass `Server` to dispatch to the regular, typed methods. + + class Client; + class Server; + + struct _capnpPrivate { + struct IsInterface; + static constexpr uint64_t typeId = 0x3; + static constexpr Kind kind = Kind::INTERFACE; + static constexpr _::RawSchema const* schema = &_::NULL_INTERFACE_SCHEMA; + + static const _::RawBrandedSchema* const brand; + // Can't quite declare this one inline without including generated-header-support.h. Avoiding + // for now by declaring out-of-line. + // TODO(cleanup): Split RawSchema stuff into its own header that can be included here, or + // something. + }; +}; + +// ======================================================================================= +// Capability clients + +class RequestHook; +class ResponseHook; +class PipelineHook; +class ClientHook; + +template <typename Params, typename Results> +class Request: public Params::Builder { + // A call that hasn't been sent yet. This class extends a Builder for the call's "Params" + // structure with a method send() that actually sends it. + // + // Given a Cap'n Proto method `foo(a :A, b :B): C`, the generated client interface will have + // a method `Request<FooParams, C> fooRequest()` (as well as a convenience method + // `RemotePromise<C> foo(A::Reader a, B::Reader b)`). + +public: + inline Request(typename Params::Builder builder, kj::Own<RequestHook>&& hook) + : Params::Builder(builder), hook(kj::mv(hook)) {} + inline Request(decltype(nullptr)): Params::Builder(nullptr) {} + + RemotePromise<Results> send() KJ_WARN_UNUSED_RESULT; + // Send the call and return a promise for the results. + +private: + kj::Own<RequestHook> hook; + + friend class Capability::Client; + friend struct DynamicCapability; + template <typename, typename> + friend class CallContext; + friend class RequestHook; +}; + +template <typename Results> +class Response: public Results::Reader { + // A completed call. This class extends a Reader for the call's answer structure. The Response + // is move-only -- once it goes out-of-scope, the underlying message will be freed. + +public: + inline Response(typename Results::Reader reader, kj::Own<ResponseHook>&& hook) + : Results::Reader(reader), hook(kj::mv(hook)) {} + +private: + kj::Own<ResponseHook> hook; + + template <typename, typename> + friend class Request; + friend class ResponseHook; +}; + +class Capability::Client { + // Base type for capability clients. + +public: + typedef Capability Reads; + typedef Capability Calls; + + Client(decltype(nullptr)); + // If you need to declare a Client before you have anything to assign to it (perhaps because + // the assignment is going to occur in an if/else scope), you can start by initializing it to + // `nullptr`. The resulting client is not meant to be called and throws exceptions from all + // methods. + + template <typename T, typename = kj::EnableIf<kj::canConvert<T*, Capability::Server*>()>> + Client(kj::Own<T>&& server); + // Make a client capability that wraps the given server capability. The server's methods will + // only be executed in the given EventLoop, regardless of what thread calls the client's methods. + + template <typename T, typename = kj::EnableIf<kj::canConvert<T*, Client*>()>> + Client(kj::Promise<T>&& promise); + // Make a client from a promise for a future client. The resulting client queues calls until the + // promise resolves. + + Client(kj::Exception&& exception); + // Make a broken client that throws the given exception from all calls. + + Client(Client& other); + Client& operator=(Client& other); + // Copies by reference counting. Warning: This refcounting is not thread-safe. All copies of + // the client must remain in one thread. + + Client(Client&&) = default; + Client& operator=(Client&&) = default; + // Move constructor avoids reference counting. + + explicit Client(kj::Own<ClientHook>&& hook); + // For use by the RPC implementation: Wrap a ClientHook. + + template <typename T> + typename T::Client castAs(); + // Reinterpret the capability as implementing the given interface. Note that no error will occur + // here if the capability does not actually implement this interface, but later method calls will + // fail. It's up to the application to decide how indicate that additional interfaces are + // supported. + // + // TODO(perf): GCC 4.8 / Clang 3.3: rvalue-qualified version for better performance. + + template <typename T> + typename T::Client castAs(InterfaceSchema schema); + // Dynamic version. `T` must be `DynamicCapability`, and you must `#include <capnp/dynamic.h>`. + + kj::Promise<void> whenResolved(); + // If the capability is actually only a promise, the returned promise resolves once the + // capability itself has resolved to its final destination (or propagates the exception if + // the capability promise is rejected). This is mainly useful for error-checking in the case + // where no calls are being made. There is no reason to wait for this before making calls; if + // the capability does not resolve, the call results will propagate the error. + + Request<AnyPointer, AnyPointer> typelessRequest( + uint64_t interfaceId, uint16_t methodId, + kj::Maybe<MessageSize> sizeHint); + // Make a request without knowing the types of the params or results. You specify the type ID + // and method number manually. + + // TODO(someday): method(s) for Join + +protected: + Client() = default; + + template <typename Params, typename Results> + Request<Params, Results> newCall(uint64_t interfaceId, uint16_t methodId, + kj::Maybe<MessageSize> sizeHint); + +private: + kj::Own<ClientHook> hook; + + static kj::Own<ClientHook> makeLocalClient(kj::Own<Capability::Server>&& server); + + template <typename, Kind> + friend struct _::PointerHelpers; + friend struct DynamicCapability; + friend class Orphanage; + friend struct DynamicStruct; + friend struct DynamicList; + template <typename, Kind> + friend struct List; + friend class _::CapabilityServerSetBase; + friend class ClientHook; +}; + +// ======================================================================================= +// Capability servers + +class CallContextHook; + +template <typename Params, typename Results> +class CallContext: public kj::DisallowConstCopy { + // Wrapper around CallContextHook with a specific return type. + // + // Methods of this class may only be called from within the server's event loop, not from other + // threads. + // + // The CallContext becomes invalid as soon as the call reports completion. + +public: + explicit CallContext(CallContextHook& hook); + + typename Params::Reader getParams(); + // Get the params payload. + + void releaseParams(); + // Release the params payload. getParams() will throw an exception after this is called. + // Releasing the params may allow the RPC system to free up buffer space to handle other + // requests. Long-running asynchronous methods should try to call this as early as is + // convenient. + + typename Results::Builder getResults(kj::Maybe<MessageSize> sizeHint = nullptr); + typename Results::Builder initResults(kj::Maybe<MessageSize> sizeHint = nullptr); + void setResults(typename Results::Reader value); + void adoptResults(Orphan<Results>&& value); + Orphanage getResultsOrphanage(kj::Maybe<MessageSize> sizeHint = nullptr); + // Manipulate the results payload. The "Return" message (part of the RPC protocol) will + // typically be allocated the first time one of these is called. Some RPC systems may + // allocate these messages in a limited space (such as a shared memory segment), therefore the + // application should delay calling these as long as is convenient to do so (but don't delay + // if doing so would require extra copies later). + // + // `sizeHint` indicates a guess at the message size. This will usually be used to decide how + // much space to allocate for the first message segment (don't worry: only space that is actually + // used will be sent on the wire). If omitted, the system decides. The message root pointer + // should not be included in the size. So, if you are simply going to copy some existing message + // directly into the results, just call `.totalSize()` and pass that in. + + template <typename SubParams> + kj::Promise<void> tailCall(Request<SubParams, Results>&& tailRequest); + // Resolve the call by making a tail call. `tailRequest` is a request that has been filled in + // but not yet sent. The context will send the call, then fill in the results with the result + // of the call. If tailCall() is used, {get,init,set,adopt}Results (above) *must not* be called. + // + // The RPC implementation may be able to optimize a tail call to another machine such that the + // results never actually pass through this machine. Even if no such optimization is possible, + // `tailCall()` may allow pipelined calls to be forwarded optimistically to the new call site. + // + // In general, this should be the last thing a method implementation calls, and the promise + // returned from `tailCall()` should then be returned by the method implementation. + + void allowCancellation(); + // Indicate that it is OK for the RPC system to discard its Promise for this call's result if + // the caller cancels the call, thereby transitively canceling any asynchronous operations the + // call implementation was performing. This is not done by default because it could represent a + // security risk: applications must be carefully written to ensure that they do not end up in + // a bad state if an operation is canceled at an arbitrary point. However, for long-running + // method calls that hold significant resources, prompt cancellation is often useful. + // + // Keep in mind that asynchronous cancellation cannot occur while the method is synchronously + // executing on a local thread. The method must perform an asynchronous operation or call + // `EventLoop::current().evalLater()` to yield control. + // + // Note: You might think that we should offer `onCancel()` and/or `isCanceled()` methods that + // provide notification when the caller cancels the request without forcefully killing off the + // promise chain. Unfortunately, this composes poorly with promise forking: the canceled + // path may be just one branch of a fork of the result promise. The other branches still want + // the call to continue. Promise forking is used within the Cap'n Proto implementation -- in + // particular each pipelined call forks the result promise. So, if a caller made a pipelined + // call and then dropped the original object, the call should not be canceled, but it would be + // excessively complicated for the framework to avoid notififying of cancellation as long as + // pipelined calls still exist. + +private: + CallContextHook* hook; + + friend class Capability::Server; + friend struct DynamicCapability; +}; + +class Capability::Server { + // Objects implementing a Cap'n Proto interface must subclass this. Typically, such objects + // will instead subclass a typed Server interface which will take care of implementing + // dispatchCall(). + +public: + typedef Capability Serves; + + virtual kj::Promise<void> dispatchCall(uint64_t interfaceId, uint16_t methodId, + CallContext<AnyPointer, AnyPointer> context) = 0; + // Call the given method. `params` is the input struct, and should be released as soon as it + // is no longer needed. `context` may be used to allocate the output struct and deal with + // cancellation. + + // TODO(someday): Method which can optionally be overridden to implement Join when the object is + // a proxy. + +protected: + inline Capability::Client thisCap(); + // Get a capability pointing to this object, much like the `this` keyword. + // + // The effect of this method is undefined if: + // - No capability client has been created pointing to this object. (This is always the case in + // the server's constructor.) + // - The capability client pointing at this object has been destroyed. (This is always the case + // in the server's destructor.) + // - Multiple capability clients have been created around the same server (possible if the server + // is refcounted, which is not recommended since the client itself provides refcounting). + + template <typename Params, typename Results> + CallContext<Params, Results> internalGetTypedContext( + CallContext<AnyPointer, AnyPointer> typeless); + kj::Promise<void> internalUnimplemented(const char* actualInterfaceName, + uint64_t requestedTypeId); + kj::Promise<void> internalUnimplemented(const char* interfaceName, + uint64_t typeId, uint16_t methodId); + kj::Promise<void> internalUnimplemented(const char* interfaceName, const char* methodName, + uint64_t typeId, uint16_t methodId); + +private: + ClientHook* thisHook = nullptr; + friend class LocalClient; +}; + +// ======================================================================================= + +class ReaderCapabilityTable: private _::CapTableReader { + // Class which imbues Readers with the ability to read capabilities. + // + // In Cap'n Proto format, the encoding of a capability pointer is simply an integer index into + // an external table. Since these pointers fundamentally point outside the message, a + // MessageReader by default has no idea what they point at, and therefore reading capabilities + // from such a reader will throw exceptions. + // + // In order to be able to read capabilities, you must first attach a capability table, using + // this class. By "imbuing" a Reader, you get a new Reader which will interpret capability + // pointers by treating them as indexes into the ReaderCapabilityTable. + // + // Note that when using Cap'n Proto's RPC system, this is handled automatically. + +public: + explicit ReaderCapabilityTable(kj::Array<kj::Maybe<kj::Own<ClientHook>>> table); + KJ_DISALLOW_COPY(ReaderCapabilityTable); + + template <typename T> + T imbue(T reader); + // Return a reader equivalent to `reader` except that when reading capability-valued fields, + // the capabilities are looked up in this table. + +private: + kj::Array<kj::Maybe<kj::Own<ClientHook>>> table; + + kj::Maybe<kj::Own<ClientHook>> extractCap(uint index) override; +}; + +class BuilderCapabilityTable: private _::CapTableBuilder { + // Class which imbues Builders with the ability to read and write capabilities. + // + // This is much like ReaderCapabilityTable, except for builders. The table starts out empty, + // but capabilities can be added to it over time. + +public: + BuilderCapabilityTable(); + KJ_DISALLOW_COPY(BuilderCapabilityTable); + + inline kj::ArrayPtr<kj::Maybe<kj::Own<ClientHook>>> getTable() { return table; } + + template <typename T> + T imbue(T builder); + // Return a builder equivalent to `builder` except that when reading capability-valued fields, + // the capabilities are looked up in this table. + +private: + kj::Vector<kj::Maybe<kj::Own<ClientHook>>> table; + + kj::Maybe<kj::Own<ClientHook>> extractCap(uint index) override; + uint injectCap(kj::Own<ClientHook>&& cap) override; + void dropCap(uint index) override; +}; + +// ======================================================================================= + +namespace _ { // private + +class CapabilityServerSetBase { +public: + Capability::Client addInternal(kj::Own<Capability::Server>&& server, void* ptr); + kj::Promise<void*> getLocalServerInternal(Capability::Client& client); +}; + +} // namespace _ (private) + +template <typename T> +class CapabilityServerSet: private _::CapabilityServerSetBase { + // Allows a server to recognize its own capabilities when passed back to it, and obtain the + // underlying Server objects associated with them. + // + // All objects in the set must have the same interface type T. The objects may implement various + // interfaces derived from T (and in fact T can be `capnp::Capability` to accept all objects), + // but note that if you compile with RTTI disabled then you will not be able to down-cast through + // virtual inheritance, and all inheritance between server interfaces is virtual. So, with RTTI + // disabled, you will likely need to set T to be the most-derived Cap'n Proto interface type, + // and you server class will need to be directly derived from that, so that you can use + // static_cast (or kj::downcast) to cast to it after calling getLocalServer(). (If you compile + // with RTTI, then you can freely dynamic_cast and ignore this issue!) + +public: + CapabilityServerSet() = default; + KJ_DISALLOW_COPY(CapabilityServerSet); + + typename T::Client add(kj::Own<typename T::Server>&& server); + // Create a new capability Client for the given Server and also add this server to the set. + + kj::Promise<kj::Maybe<typename T::Server&>> getLocalServer(typename T::Client& client); + // Given a Client pointing to a server previously passed to add(), return the corresponding + // Server. This returns a promise because if the input client is itself a promise, this must + // wait for it to resolve. Keep in mind that the server will be deleted when all clients are + // gone, so the caller should make sure to keep the client alive (hence why this method only + // accepts an lvalue input). +}; + +// ======================================================================================= +// Hook interfaces which must be implemented by the RPC system. Applications never call these +// directly; the RPC system implements them and the types defined earlier in this file wrap them. + +class RequestHook { + // Hook interface implemented by RPC system representing a request being built. + +public: + virtual RemotePromise<AnyPointer> send() = 0; + // Send the call and return a promise for the result. + + virtual const void* getBrand() = 0; + // Returns a void* that identifies who made this request. This can be used by an RPC adapter to + // discover when tail call is going to be sent over its own connection and therefore can be + // optimized into a remote tail call. + + template <typename T, typename U> + inline static kj::Own<RequestHook> from(Request<T, U>&& request) { + return kj::mv(request.hook); + } +}; + +class ResponseHook { + // Hook interface implemented by RPC system representing a response. + // + // At present this class has no methods. It exists only for garbage collection -- when the + // ResponseHook is destroyed, the results can be freed. + +public: + virtual ~ResponseHook() noexcept(false); + // Just here to make sure the type is dynamic. + + template <typename T> + inline static kj::Own<ResponseHook> from(Response<T>&& response) { + return kj::mv(response.hook); + } +}; + +// class PipelineHook is declared in any.h because it is needed there. + +class ClientHook { +public: + ClientHook(); + + virtual Request<AnyPointer, AnyPointer> newCall( + uint64_t interfaceId, uint16_t methodId, kj::Maybe<MessageSize> sizeHint) = 0; + // Start a new call, allowing the client to allocate request/response objects as it sees fit. + // This version is used when calls are made from application code in the local process. + + struct VoidPromiseAndPipeline { + kj::Promise<void> promise; + kj::Own<PipelineHook> pipeline; + }; + + virtual VoidPromiseAndPipeline call(uint64_t interfaceId, uint16_t methodId, + kj::Own<CallContextHook>&& context) = 0; + // Call the object, but the caller controls allocation of the request/response objects. If the + // callee insists on allocating these objects itself, it must make a copy. This version is used + // when calls come in over the network via an RPC system. Note that even if the returned + // `Promise<void>` is discarded, the call may continue executing if any pipelined calls are + // waiting for it. + // + // Since the caller of this method chooses the CallContext implementation, it is the caller's + // responsibility to ensure that the returned promise is not canceled unless allowed via + // the context's `allowCancellation()`. + // + // The call must not begin synchronously; the callee must arrange for the call to begin in a + // later turn of the event loop. Otherwise, application code may call back and affect the + // callee's state in an unexpected way. + + virtual kj::Maybe<ClientHook&> getResolved() = 0; + // If this ClientHook is a promise that has already resolved, returns the inner, resolved version + // of the capability. The caller may permanently replace this client with the resolved one if + // desired. Returns null if the client isn't a promise or hasn't resolved yet -- use + // `whenMoreResolved()` to distinguish between them. + + virtual kj::Maybe<kj::Promise<kj::Own<ClientHook>>> whenMoreResolved() = 0; + // If this client is a settled reference (not a promise), return nullptr. Otherwise, return a + // promise that eventually resolves to a new client that is closer to being the final, settled + // client (i.e. the value eventually returned by `getResolved()`). Calling this repeatedly + // should eventually produce a settled client. + + kj::Promise<void> whenResolved(); + // Repeatedly calls whenMoreResolved() until it returns nullptr. + + virtual kj::Own<ClientHook> addRef() = 0; + // Return a new reference to the same capability. + + virtual const void* getBrand() = 0; + // Returns a void* that identifies who made this client. This can be used by an RPC adapter to + // discover when a capability it needs to marshal is one that it created in the first place, and + // therefore it can transfer the capability without proxying. + + static const uint NULL_CAPABILITY_BRAND; + // Value is irrelevant; used for pointer. + + inline bool isNull() { return getBrand() == &NULL_CAPABILITY_BRAND; } + // Returns true if the capability was created as a result of assigning a Client to null or by + // reading a null pointer out of a Cap'n Proto message. + + virtual void* getLocalServer(_::CapabilityServerSetBase& capServerSet); + // If this is a local capability created through `capServerSet`, return the underlying Server. + // Otherwise, return nullptr. Default implementation (which everyone except LocalClient should + // use) always returns nullptr. + + static kj::Own<ClientHook> from(Capability::Client client) { return kj::mv(client.hook); } +}; + +class CallContextHook { + // Hook interface implemented by RPC system to manage a call on the server side. See + // CallContext<T>. + +public: + virtual AnyPointer::Reader getParams() = 0; + virtual void releaseParams() = 0; + virtual AnyPointer::Builder getResults(kj::Maybe<MessageSize> sizeHint) = 0; + virtual kj::Promise<void> tailCall(kj::Own<RequestHook>&& request) = 0; + virtual void allowCancellation() = 0; + + virtual kj::Promise<AnyPointer::Pipeline> onTailCall() = 0; + // If `tailCall()` is called, resolves to the PipelineHook from the tail call. An + // implementation of `ClientHook::call()` is allowed to call this at most once. + + virtual ClientHook::VoidPromiseAndPipeline directTailCall(kj::Own<RequestHook>&& request) = 0; + // Call this when you would otherwise call onTailCall() immediately followed by tailCall(). + // Implementations of tailCall() should typically call directTailCall() and then fulfill the + // promise fulfiller for onTailCall() with the returned pipeline. + + virtual kj::Own<CallContextHook> addRef() = 0; +}; + +kj::Own<ClientHook> newLocalPromiseClient(kj::Promise<kj::Own<ClientHook>>&& promise); +// Returns a ClientHook that queues up calls until `promise` resolves, then forwards them to +// the new client. This hook's `getResolved()` and `whenMoreResolved()` methods will reflect the +// redirection to the eventual replacement client. + +kj::Own<PipelineHook> newLocalPromisePipeline(kj::Promise<kj::Own<PipelineHook>>&& promise); +// Returns a PipelineHook that queues up calls until `promise` resolves, then forwards them to +// the new pipeline. + +kj::Own<ClientHook> newBrokenCap(kj::StringPtr reason); +kj::Own<ClientHook> newBrokenCap(kj::Exception&& reason); +// Helper function that creates a capability which simply throws exceptions when called. + +kj::Own<PipelineHook> newBrokenPipeline(kj::Exception&& reason); +// Helper function that creates a pipeline which simply throws exceptions when called. + +Request<AnyPointer, AnyPointer> newBrokenRequest( + kj::Exception&& reason, kj::Maybe<MessageSize> sizeHint); +// Helper function that creates a Request object that simply throws exceptions when sent. + +// ======================================================================================= +// Extend PointerHelpers for interfaces + +namespace _ { // private + +template <typename T> +struct PointerHelpers<T, Kind::INTERFACE> { + static inline typename T::Client get(PointerReader reader) { + return typename T::Client(reader.getCapability()); + } + static inline typename T::Client get(PointerBuilder builder) { + return typename T::Client(builder.getCapability()); + } + static inline void set(PointerBuilder builder, typename T::Client&& value) { + builder.setCapability(kj::mv(value.Capability::Client::hook)); + } + static inline void set(PointerBuilder builder, typename T::Client& value) { + builder.setCapability(value.Capability::Client::hook->addRef()); + } + static inline void adopt(PointerBuilder builder, Orphan<T>&& value) { + builder.adopt(kj::mv(value.builder)); + } + static inline Orphan<T> disown(PointerBuilder builder) { + return Orphan<T>(builder.disown()); + } +}; + +} // namespace _ (private) + +// ======================================================================================= +// Extend List for interfaces + +template <typename T> +struct List<T, Kind::INTERFACE> { + List() = delete; + + class Reader { + public: + typedef List<T> Reads; + + Reader() = default; + inline explicit Reader(_::ListReader reader): reader(reader) {} + + inline uint size() const { return reader.size() / ELEMENTS; } + inline typename T::Client operator[](uint index) const { + KJ_IREQUIRE(index < size()); + return typename T::Client(reader.getPointerElement(index * ELEMENTS).getCapability()); + } + + typedef _::IndexingIterator<const Reader, typename T::Client> Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + + private: + _::ListReader reader; + template <typename U, Kind K> + friend struct _::PointerHelpers; + template <typename U, Kind K> + friend struct List; + friend class Orphanage; + template <typename U, Kind K> + friend struct ToDynamic_; + }; + + class Builder { + public: + typedef List<T> Builds; + + Builder() = delete; + inline Builder(decltype(nullptr)) {} + inline explicit Builder(_::ListBuilder builder): builder(builder) {} + + inline operator Reader() const { return Reader(builder.asReader()); } + inline Reader asReader() const { return Reader(builder.asReader()); } + + inline uint size() const { return builder.size() / ELEMENTS; } + inline typename T::Client operator[](uint index) { + KJ_IREQUIRE(index < size()); + return typename T::Client(builder.getPointerElement(index * ELEMENTS).getCapability()); + } + inline void set(uint index, typename T::Client value) { + KJ_IREQUIRE(index < size()); + builder.getPointerElement(index * ELEMENTS).setCapability(kj::mv(value.hook)); + } + inline void adopt(uint index, Orphan<T>&& value) { + KJ_IREQUIRE(index < size()); + builder.getPointerElement(index * ELEMENTS).adopt(kj::mv(value)); + } + inline Orphan<T> disown(uint index) { + KJ_IREQUIRE(index < size()); + return Orphan<T>(builder.getPointerElement(index * ELEMENTS).disown()); + } + + typedef _::IndexingIterator<Builder, typename T::Client> Iterator; + inline Iterator begin() { return Iterator(this, 0); } + inline Iterator end() { return Iterator(this, size()); } + + private: + _::ListBuilder builder; + friend class Orphanage; + template <typename U, Kind K> + friend struct ToDynamic_; + }; + +private: + inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) { + return builder.initList(ElementSize::POINTER, size * ELEMENTS); + } + inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) { + return builder.getList(ElementSize::POINTER, defaultValue); + } + inline static _::ListReader getFromPointer( + const _::PointerReader& reader, const word* defaultValue) { + return reader.getList(ElementSize::POINTER, defaultValue); + } + + template <typename U, Kind k> + friend struct List; + template <typename U, Kind K> + friend struct _::PointerHelpers; +}; + +// ======================================================================================= +// Inline implementation details + +template <typename Params, typename Results> +RemotePromise<Results> Request<Params, Results>::send() { + auto typelessPromise = hook->send(); + hook = nullptr; // prevent reuse + + // Convert the Promise to return the correct response type. + // Explicitly upcast to kj::Promise to make clear that calling .then() doesn't invalidate the + // Pipeline part of the RemotePromise. + auto typedPromise = kj::implicitCast<kj::Promise<Response<AnyPointer>>&>(typelessPromise) + .then([](Response<AnyPointer>&& response) -> Response<Results> { + return Response<Results>(response.getAs<Results>(), kj::mv(response.hook)); + }); + + // Wrap the typeless pipeline in a typed wrapper. + typename Results::Pipeline typedPipeline( + kj::mv(kj::implicitCast<AnyPointer::Pipeline&>(typelessPromise))); + + return RemotePromise<Results>(kj::mv(typedPromise), kj::mv(typedPipeline)); +} + +inline Capability::Client::Client(kj::Own<ClientHook>&& hook): hook(kj::mv(hook)) {} +template <typename T, typename> +inline Capability::Client::Client(kj::Own<T>&& server) + : hook(makeLocalClient(kj::mv(server))) {} +template <typename T, typename> +inline Capability::Client::Client(kj::Promise<T>&& promise) + : hook(newLocalPromiseClient(promise.then([](T&& t) { return kj::mv(t.hook); }))) {} +inline Capability::Client::Client(Client& other): hook(other.hook->addRef()) {} +inline Capability::Client& Capability::Client::operator=(Client& other) { + hook = other.hook->addRef(); + return *this; +} +template <typename T> +inline typename T::Client Capability::Client::castAs() { + return typename T::Client(hook->addRef()); +} +inline kj::Promise<void> Capability::Client::whenResolved() { + return hook->whenResolved(); +} +inline Request<AnyPointer, AnyPointer> Capability::Client::typelessRequest( + uint64_t interfaceId, uint16_t methodId, + kj::Maybe<MessageSize> sizeHint) { + return newCall<AnyPointer, AnyPointer>(interfaceId, methodId, sizeHint); +} +template <typename Params, typename Results> +inline Request<Params, Results> Capability::Client::newCall( + uint64_t interfaceId, uint16_t methodId, kj::Maybe<MessageSize> sizeHint) { + auto typeless = hook->newCall(interfaceId, methodId, sizeHint); + return Request<Params, Results>(typeless.template getAs<Params>(), kj::mv(typeless.hook)); +} + +template <typename Params, typename Results> +inline CallContext<Params, Results>::CallContext(CallContextHook& hook): hook(&hook) {} +template <typename Params, typename Results> +inline typename Params::Reader CallContext<Params, Results>::getParams() { + return hook->getParams().template getAs<Params>(); +} +template <typename Params, typename Results> +inline void CallContext<Params, Results>::releaseParams() { + hook->releaseParams(); +} +template <typename Params, typename Results> +inline typename Results::Builder CallContext<Params, Results>::getResults( + kj::Maybe<MessageSize> sizeHint) { + // `template` keyword needed due to: http://llvm.org/bugs/show_bug.cgi?id=17401 + return hook->getResults(sizeHint).template getAs<Results>(); +} +template <typename Params, typename Results> +inline typename Results::Builder CallContext<Params, Results>::initResults( + kj::Maybe<MessageSize> sizeHint) { + // `template` keyword needed due to: http://llvm.org/bugs/show_bug.cgi?id=17401 + return hook->getResults(sizeHint).template initAs<Results>(); +} +template <typename Params, typename Results> +inline void CallContext<Params, Results>::setResults(typename Results::Reader value) { + hook->getResults(value.totalSize()).template setAs<Results>(value); +} +template <typename Params, typename Results> +inline void CallContext<Params, Results>::adoptResults(Orphan<Results>&& value) { + hook->getResults(nullptr).adopt(kj::mv(value)); +} +template <typename Params, typename Results> +inline Orphanage CallContext<Params, Results>::getResultsOrphanage( + kj::Maybe<MessageSize> sizeHint) { + return Orphanage::getForMessageContaining(hook->getResults(sizeHint)); +} +template <typename Params, typename Results> +template <typename SubParams> +inline kj::Promise<void> CallContext<Params, Results>::tailCall( + Request<SubParams, Results>&& tailRequest) { + return hook->tailCall(kj::mv(tailRequest.hook)); +} +template <typename Params, typename Results> +inline void CallContext<Params, Results>::allowCancellation() { + hook->allowCancellation(); +} + +template <typename Params, typename Results> +CallContext<Params, Results> Capability::Server::internalGetTypedContext( + CallContext<AnyPointer, AnyPointer> typeless) { + return CallContext<Params, Results>(*typeless.hook); +} + +Capability::Client Capability::Server::thisCap() { + return Client(thisHook->addRef()); +} + +template <typename T> +T ReaderCapabilityTable::imbue(T reader) { + return T(_::PointerHelpers<FromReader<T>>::getInternalReader(reader).imbue(this)); +} + +template <typename T> +T BuilderCapabilityTable::imbue(T builder) { + return T(_::PointerHelpers<FromBuilder<T>>::getInternalBuilder(kj::mv(builder)).imbue(this)); +} + +template <typename T> +typename T::Client CapabilityServerSet<T>::add(kj::Own<typename T::Server>&& server) { + void* ptr = reinterpret_cast<void*>(server.get()); + // Clang insists that `castAs` is a template-dependent member and therefore we need the + // `template` keyword here, but AFAICT this is wrong: addImpl() is not a template. + return addInternal(kj::mv(server), ptr).template castAs<T>(); +} + +template <typename T> +kj::Promise<kj::Maybe<typename T::Server&>> CapabilityServerSet<T>::getLocalServer( + typename T::Client& client) { + return getLocalServerInternal(client) + .then([](void* server) -> kj::Maybe<typename T::Server&> { + if (server == nullptr) { + return nullptr; + } else { + return *reinterpret_cast<typename T::Server*>(server); + } + }); +} + +template <typename T> +struct Orphanage::GetInnerReader<T, Kind::INTERFACE> { + static inline kj::Own<ClientHook> apply(typename T::Client t) { + return ClientHook::from(kj::mv(t)); + } +}; + +} // namespace capnp + +#endif // CAPNP_CAPABILITY_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/common.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,487 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// This file contains types which are intended to help detect incorrect usage at compile +// time, but should then be optimized down to basic primitives (usually, integers) by the +// compiler. + +#ifndef CAPNP_COMMON_H_ +#define CAPNP_COMMON_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include <kj/units.h> +#include <inttypes.h> +#include <kj/string.h> +#include <kj/memory.h> + +namespace capnp { + +#define CAPNP_VERSION_MAJOR 0 +#define CAPNP_VERSION_MINOR 6 +#define CAPNP_VERSION_MICRO 0 + +#define CAPNP_VERSION \ + (CAPNP_VERSION_MAJOR * 1000000 + CAPNP_VERSION_MINOR * 1000 + CAPNP_VERSION_MICRO) + +#ifdef _MSC_VER +#define CAPNP_LITE 1 +// MSVC only supports "lite" mode for now, due to missing C++11 features. +#endif + +#ifndef CAPNP_LITE +#define CAPNP_LITE 0 +#endif + +typedef unsigned int uint; + +struct Void { + // Type used for Void fields. Using C++'s "void" type creates a bunch of issues since it behaves + // differently from other types. + + inline constexpr bool operator==(Void other) const { return true; } + inline constexpr bool operator!=(Void other) const { return false; } +}; + +static constexpr Void VOID = Void(); +// Constant value for `Void`, which is an empty struct. + +inline kj::StringPtr KJ_STRINGIFY(Void) { return "void"; } + +struct Text; +struct Data; + +enum class Kind: uint8_t { + PRIMITIVE, + BLOB, + ENUM, + STRUCT, + UNION, + INTERFACE, + LIST, + + OTHER + // Some other type which is often a type parameter to Cap'n Proto templates, but which needs + // special handling. This includes types like AnyPointer, Dynamic*, etc. +}; + +enum class Style: uint8_t { + PRIMITIVE, + POINTER, // other than struct + STRUCT, + CAPABILITY +}; + +enum class ElementSize: uint8_t { + // Size of a list element. + + VOID = 0, + BIT = 1, + BYTE = 2, + TWO_BYTES = 3, + FOUR_BYTES = 4, + EIGHT_BYTES = 5, + + POINTER = 6, + + INLINE_COMPOSITE = 7 +}; + +enum class PointerType { + // Various wire types a pointer field can take + + NULL_, + // Should be NULL, but that's #defined in stddef.h + + STRUCT, + LIST, + CAPABILITY +}; + +namespace schemas { + +template <typename T> +struct EnumInfo; + +} // namespace schemas + +namespace _ { // private + +template <typename T, typename = void> struct Kind_; + +template <> struct Kind_<Void> { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_<bool> { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_<int8_t> { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_<int16_t> { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_<int32_t> { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_<int64_t> { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_<uint8_t> { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_<uint16_t> { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_<uint32_t> { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_<uint64_t> { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_<float> { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_<double> { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_<Text> { static constexpr Kind kind = Kind::BLOB; }; +template <> struct Kind_<Data> { static constexpr Kind kind = Kind::BLOB; }; + +template <typename T> struct Kind_<T, kj::VoidSfinae<typename T::_capnpPrivate::IsStruct>> { + static constexpr Kind kind = Kind::STRUCT; +}; +template <typename T> struct Kind_<T, kj::VoidSfinae<typename T::_capnpPrivate::IsInterface>> { + static constexpr Kind kind = Kind::INTERFACE; +}; +template <typename T> struct Kind_<T, kj::VoidSfinae<typename schemas::EnumInfo<T>::IsEnum>> { + static constexpr Kind kind = Kind::ENUM; +}; + +} // namespace _ (private) + +template <typename T, Kind k = _::Kind_<T>::kind> +inline constexpr Kind kind() { + // This overload of kind() matches types which have a Kind_ specialization. + + return k; +} + +#if CAPNP_LITE + +#define CAPNP_KIND(T) ::capnp::_::Kind_<T>::kind +// Avoid constexpr methods in lite mode (MSVC is bad at constexpr). + +#else // CAPNP_LITE + +#define CAPNP_KIND(T) ::capnp::kind<T>() +// Use this macro rather than kind<T>() in any code which must work in lite mode. + +template <typename T, Kind k = kind<T>()> +inline constexpr Style style() { + return k == Kind::PRIMITIVE || k == Kind::ENUM ? Style::PRIMITIVE + : k == Kind::STRUCT ? Style::STRUCT + : k == Kind::INTERFACE ? Style::CAPABILITY : Style::POINTER; +} + +#endif // CAPNP_LITE, else + +template <typename T, Kind k = CAPNP_KIND(T)> +struct List; + +#if _MSC_VER + +template <typename T, Kind k> +struct List {}; +// For some reason, without this declaration, MSVC will error out on some uses of List +// claiming that "T" -- as used in the default initializer for the second template param, "k" -- +// is not defined. I do not understand this error, but adding this empty default declaration fixes +// it. + +#endif + +template <typename T> struct ListElementType_; +template <typename T> struct ListElementType_<List<T>> { typedef T Type; }; +template <typename T> using ListElementType = typename ListElementType_<T>::Type; + +namespace _ { // private +template <typename T, Kind k> struct Kind_<List<T, k>> { + static constexpr Kind kind = Kind::LIST; +}; +} // namespace _ (private) + +template <typename T, Kind k = CAPNP_KIND(T)> struct ReaderFor_ { typedef typename T::Reader Type; }; +template <typename T> struct ReaderFor_<T, Kind::PRIMITIVE> { typedef T Type; }; +template <typename T> struct ReaderFor_<T, Kind::ENUM> { typedef T Type; }; +template <typename T> struct ReaderFor_<T, Kind::INTERFACE> { typedef typename T::Client Type; }; +template <typename T> using ReaderFor = typename ReaderFor_<T>::Type; +// The type returned by List<T>::Reader::operator[]. + +template <typename T, Kind k = CAPNP_KIND(T)> struct BuilderFor_ { typedef typename T::Builder Type; }; +template <typename T> struct BuilderFor_<T, Kind::PRIMITIVE> { typedef T Type; }; +template <typename T> struct BuilderFor_<T, Kind::ENUM> { typedef T Type; }; +template <typename T> struct BuilderFor_<T, Kind::INTERFACE> { typedef typename T::Client Type; }; +template <typename T> using BuilderFor = typename BuilderFor_<T>::Type; +// The type returned by List<T>::Builder::operator[]. + +template <typename T, Kind k = CAPNP_KIND(T)> struct PipelineFor_ { typedef typename T::Pipeline Type;}; +template <typename T> struct PipelineFor_<T, Kind::INTERFACE> { typedef typename T::Client Type; }; +template <typename T> using PipelineFor = typename PipelineFor_<T>::Type; + +template <typename T, Kind k = CAPNP_KIND(T)> struct TypeIfEnum_; +template <typename T> struct TypeIfEnum_<T, Kind::ENUM> { typedef T Type; }; + +template <typename T> +using TypeIfEnum = typename TypeIfEnum_<kj::Decay<T>>::Type; + +template <typename T> +using FromReader = typename kj::Decay<T>::Reads; +// FromReader<MyType::Reader> = MyType (for any Cap'n Proto type). + +template <typename T> +using FromBuilder = typename kj::Decay<T>::Builds; +// FromBuilder<MyType::Builder> = MyType (for any Cap'n Proto type). + +template <typename T> +using FromPipeline = typename kj::Decay<T>::Pipelines; +// FromBuilder<MyType::Pipeline> = MyType (for any Cap'n Proto type). + +template <typename T> +using FromClient = typename kj::Decay<T>::Calls; +// FromReader<MyType::Client> = MyType (for any Cap'n Proto interface type). + +template <typename T> +using FromServer = typename kj::Decay<T>::Serves; +// FromBuilder<MyType::Server> = MyType (for any Cap'n Proto interface type). + +template <typename T, typename = void> +struct FromAny_; + +template <typename T> +struct FromAny_<T, kj::VoidSfinae<FromReader<T>>> { + using Type = FromReader<T>; +}; + +template <typename T> +struct FromAny_<T, kj::VoidSfinae<FromBuilder<T>>> { + using Type = FromBuilder<T>; +}; + +template <typename T> +struct FromAny_<T, kj::VoidSfinae<FromPipeline<T>>> { + using Type = FromPipeline<T>; +}; + +// Note that T::Client is covered by FromReader + +template <typename T> +struct FromAny_<kj::Own<T>, kj::VoidSfinae<FromServer<T>>> { + using Type = FromServer<T>; +}; + +template <typename T> +struct FromAny_<T, + kj::EnableIf<_::Kind_<T>::kind == Kind::PRIMITIVE || _::Kind_<T>::kind == Kind::ENUM>> { + // TODO(msvc): Ideally the EnableIf condition would be `style<T>() == Style::PRIMITIVE`, but MSVC + // cannot yet use style<T>() in this constexpr context. + + using Type = kj::Decay<T>; +}; + +template <typename T> +using FromAny = typename FromAny_<T>::Type; +// Given any Cap'n Proto value type as an input, return the Cap'n Proto base type. That is: +// +// Foo::Reader -> Foo +// Foo::Builder -> Foo +// Foo::Pipeline -> Foo +// Foo::Client -> Foo +// Own<Foo::Server> -> Foo +// uint32_t -> uint32_t + +namespace _ { // private + +template <typename T, Kind k = CAPNP_KIND(T)> +struct PointerHelpers; + +#if _MSC_VER + +template <typename T, Kind k> +struct PointerHelpers {}; +// For some reason, without this declaration, MSVC will error out on some uses of PointerHelpers +// claiming that "T" -- as used in the default initializer for the second template param, "k" -- +// is not defined. I do not understand this error, but adding this empty default declaration fixes +// it. + +#endif + +} // namespace _ (private) + +struct MessageSize { + // Size of a message. Every struct type has a method `.totalSize()` that returns this. + uint64_t wordCount; + uint capCount; +}; + +// ======================================================================================= +// Raw memory types and measures + +using kj::byte; + +class word { uint64_t content KJ_UNUSED_MEMBER; KJ_DISALLOW_COPY(word); public: word() = default; }; +// word is an opaque type with size of 64 bits. This type is useful only to make pointer +// arithmetic clearer. Since the contents are private, the only way to access them is to first +// reinterpret_cast to some other pointer type. +// +// Copying is disallowed because you should always use memcpy(). Otherwise, you may run afoul of +// aliasing rules. +// +// A pointer of type word* should always be word-aligned even if won't actually be dereferenced as +// that type. + +static_assert(sizeof(byte) == 1, "uint8_t is not one byte?"); +static_assert(sizeof(word) == 8, "uint64_t is not 8 bytes?"); + +#if CAPNP_DEBUG_TYPES +// Set CAPNP_DEBUG_TYPES to 1 to use kj::Quantity for "count" types. Otherwise, plain integers are +// used. All the code should still operate exactly the same, we just lose compile-time checking. +// Note that this will also change symbol names, so it's important that the library and any clients +// be compiled with the same setting here. +// +// We disable this by default to reduce symbol name size and avoid any possibility of the compiler +// failing to fully-optimize the types, but anyone modifying Cap'n Proto itself should enable this +// during development and testing. + +namespace _ { class BitLabel; class ElementLabel; struct WirePointer; } + +typedef kj::Quantity<uint, _::BitLabel> BitCount; +typedef kj::Quantity<uint8_t, _::BitLabel> BitCount8; +typedef kj::Quantity<uint16_t, _::BitLabel> BitCount16; +typedef kj::Quantity<uint32_t, _::BitLabel> BitCount32; +typedef kj::Quantity<uint64_t, _::BitLabel> BitCount64; + +typedef kj::Quantity<uint, byte> ByteCount; +typedef kj::Quantity<uint8_t, byte> ByteCount8; +typedef kj::Quantity<uint16_t, byte> ByteCount16; +typedef kj::Quantity<uint32_t, byte> ByteCount32; +typedef kj::Quantity<uint64_t, byte> ByteCount64; + +typedef kj::Quantity<uint, word> WordCount; +typedef kj::Quantity<uint8_t, word> WordCount8; +typedef kj::Quantity<uint16_t, word> WordCount16; +typedef kj::Quantity<uint32_t, word> WordCount32; +typedef kj::Quantity<uint64_t, word> WordCount64; + +typedef kj::Quantity<uint, _::ElementLabel> ElementCount; +typedef kj::Quantity<uint8_t, _::ElementLabel> ElementCount8; +typedef kj::Quantity<uint16_t, _::ElementLabel> ElementCount16; +typedef kj::Quantity<uint32_t, _::ElementLabel> ElementCount32; +typedef kj::Quantity<uint64_t, _::ElementLabel> ElementCount64; + +typedef kj::Quantity<uint, _::WirePointer> WirePointerCount; +typedef kj::Quantity<uint8_t, _::WirePointer> WirePointerCount8; +typedef kj::Quantity<uint16_t, _::WirePointer> WirePointerCount16; +typedef kj::Quantity<uint32_t, _::WirePointer> WirePointerCount32; +typedef kj::Quantity<uint64_t, _::WirePointer> WirePointerCount64; + +template <typename T, typename U> +inline constexpr U* operator+(U* ptr, kj::Quantity<T, U> offset) { + return ptr + offset / kj::unit<kj::Quantity<T, U>>(); +} +template <typename T, typename U> +inline constexpr const U* operator+(const U* ptr, kj::Quantity<T, U> offset) { + return ptr + offset / kj::unit<kj::Quantity<T, U>>(); +} +template <typename T, typename U> +inline constexpr U* operator+=(U*& ptr, kj::Quantity<T, U> offset) { + return ptr = ptr + offset / kj::unit<kj::Quantity<T, U>>(); +} +template <typename T, typename U> +inline constexpr const U* operator+=(const U*& ptr, kj::Quantity<T, U> offset) { + return ptr = ptr + offset / kj::unit<kj::Quantity<T, U>>(); +} + +template <typename T, typename U> +inline constexpr U* operator-(U* ptr, kj::Quantity<T, U> offset) { + return ptr - offset / kj::unit<kj::Quantity<T, U>>(); +} +template <typename T, typename U> +inline constexpr const U* operator-(const U* ptr, kj::Quantity<T, U> offset) { + return ptr - offset / kj::unit<kj::Quantity<T, U>>(); +} +template <typename T, typename U> +inline constexpr U* operator-=(U*& ptr, kj::Quantity<T, U> offset) { + return ptr = ptr - offset / kj::unit<kj::Quantity<T, U>>(); +} +template <typename T, typename U> +inline constexpr const U* operator-=(const U*& ptr, kj::Quantity<T, U> offset) { + return ptr = ptr - offset / kj::unit<kj::Quantity<T, U>>(); +} + +#else + +typedef uint BitCount; +typedef uint8_t BitCount8; +typedef uint16_t BitCount16; +typedef uint32_t BitCount32; +typedef uint64_t BitCount64; + +typedef uint ByteCount; +typedef uint8_t ByteCount8; +typedef uint16_t ByteCount16; +typedef uint32_t ByteCount32; +typedef uint64_t ByteCount64; + +typedef uint WordCount; +typedef uint8_t WordCount8; +typedef uint16_t WordCount16; +typedef uint32_t WordCount32; +typedef uint64_t WordCount64; + +typedef uint ElementCount; +typedef uint8_t ElementCount8; +typedef uint16_t ElementCount16; +typedef uint32_t ElementCount32; +typedef uint64_t ElementCount64; + +typedef uint WirePointerCount; +typedef uint8_t WirePointerCount8; +typedef uint16_t WirePointerCount16; +typedef uint32_t WirePointerCount32; +typedef uint64_t WirePointerCount64; + +#endif + +constexpr BitCount BITS = kj::unit<BitCount>(); +constexpr ByteCount BYTES = kj::unit<ByteCount>(); +constexpr WordCount WORDS = kj::unit<WordCount>(); +constexpr ElementCount ELEMENTS = kj::unit<ElementCount>(); +constexpr WirePointerCount POINTERS = kj::unit<WirePointerCount>(); + +// GCC 4.7 actually gives unused warnings on these constants in opt mode... +constexpr auto BITS_PER_BYTE KJ_UNUSED = 8 * BITS / BYTES; +constexpr auto BITS_PER_WORD KJ_UNUSED = 64 * BITS / WORDS; +constexpr auto BYTES_PER_WORD KJ_UNUSED = 8 * BYTES / WORDS; + +constexpr auto BITS_PER_POINTER KJ_UNUSED = 64 * BITS / POINTERS; +constexpr auto BYTES_PER_POINTER KJ_UNUSED = 8 * BYTES / POINTERS; +constexpr auto WORDS_PER_POINTER KJ_UNUSED = 1 * WORDS / POINTERS; + +constexpr WordCount POINTER_SIZE_IN_WORDS = 1 * POINTERS * WORDS_PER_POINTER; + +template <typename T> +inline KJ_CONSTEXPR() decltype(BYTES / ELEMENTS) bytesPerElement() { + return sizeof(T) * BYTES / ELEMENTS; +} + +template <typename T> +inline KJ_CONSTEXPR() decltype(BITS / ELEMENTS) bitsPerElement() { + return sizeof(T) * 8 * BITS / ELEMENTS; +} + +inline constexpr ByteCount intervalLength(const byte* a, const byte* b) { + return uint(b - a) * BYTES; +} +inline constexpr WordCount intervalLength(const word* a, const word* b) { + return uint(b - a) * WORDS; +} + +} // namespace capnp + +#endif // CAPNP_COMMON_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/dynamic.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,1593 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// This file defines classes that can be used to manipulate messages based on schemas that are not +// known until runtime. This is also useful for writing generic code that uses schemas to handle +// arbitrary types in a generic way. +// +// Each of the classes defined here has a to() template method which converts an instance back to a +// native type. This method will throw an exception if the requested type does not match the +// schema. To convert native types to dynamic, use DynamicFactory. +// +// As always, underlying data is validated lazily, so you have to actually traverse the whole +// message if you want to validate all content. + +#ifndef CAPNP_DYNAMIC_H_ +#define CAPNP_DYNAMIC_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "schema.h" +#include "layout.h" +#include "message.h" +#include "any.h" +#include "capability.h" + +namespace capnp { + +class MessageReader; +class MessageBuilder; + +struct DynamicValue { + DynamicValue() = delete; + + enum Type { + UNKNOWN, + // Means that the value has unknown type and content because it comes from a newer version of + // the schema, or from a newer version of Cap'n Proto that has new features that this version + // doesn't understand. + + VOID, + BOOL, + INT, + UINT, + FLOAT, + TEXT, + DATA, + LIST, + ENUM, + STRUCT, + CAPABILITY, + ANY_POINTER + }; + + class Reader; + class Builder; + class Pipeline; +}; +class DynamicEnum; +struct DynamicStruct { + DynamicStruct() = delete; + class Reader; + class Builder; + class Pipeline; +}; +struct DynamicList { + DynamicList() = delete; + class Reader; + class Builder; +}; +struct DynamicCapability { + DynamicCapability() = delete; + class Client; + class Server; +}; +template <> class Orphan<DynamicValue>; + +template <Kind k> struct DynamicTypeFor_; +template <> struct DynamicTypeFor_<Kind::ENUM> { typedef DynamicEnum Type; }; +template <> struct DynamicTypeFor_<Kind::STRUCT> { typedef DynamicStruct Type; }; +template <> struct DynamicTypeFor_<Kind::LIST> { typedef DynamicList Type; }; +template <> struct DynamicTypeFor_<Kind::INTERFACE> { typedef DynamicCapability Type; }; + +template <typename T> +using DynamicTypeFor = typename DynamicTypeFor_<kind<T>()>::Type; + +template <typename T> +ReaderFor<DynamicTypeFor<FromReader<T>>> toDynamic(T&& value); +template <typename T> +BuilderFor<DynamicTypeFor<FromBuilder<T>>> toDynamic(T&& value); +template <typename T> +DynamicTypeFor<TypeIfEnum<T>> toDynamic(T&& value); +template <typename T> +typename DynamicTypeFor<FromServer<T>>::Client toDynamic(kj::Own<T>&& value); + +namespace _ { // private + +template <> struct Kind_<DynamicValue > { static constexpr Kind kind = Kind::OTHER; }; +template <> struct Kind_<DynamicEnum > { static constexpr Kind kind = Kind::OTHER; }; +template <> struct Kind_<DynamicStruct > { static constexpr Kind kind = Kind::OTHER; }; +template <> struct Kind_<DynamicList > { static constexpr Kind kind = Kind::OTHER; }; +template <> struct Kind_<DynamicCapability> { static constexpr Kind kind = Kind::OTHER; }; + +} // namespace _ (private) + +template <> inline constexpr Style style<DynamicValue >() { return Style::POINTER; } +template <> inline constexpr Style style<DynamicEnum >() { return Style::PRIMITIVE; } +template <> inline constexpr Style style<DynamicStruct >() { return Style::STRUCT; } +template <> inline constexpr Style style<DynamicList >() { return Style::POINTER; } +template <> inline constexpr Style style<DynamicCapability>() { return Style::CAPABILITY; } + +// ------------------------------------------------------------------- + +class DynamicEnum { +public: + DynamicEnum() = default; + inline DynamicEnum(EnumSchema::Enumerant enumerant) + : schema(enumerant.getContainingEnum()), value(enumerant.getOrdinal()) {} + inline DynamicEnum(EnumSchema schema, uint16_t value) + : schema(schema), value(value) {} + + template <typename T, typename = kj::EnableIf<kind<T>() == Kind::ENUM>> + inline DynamicEnum(T&& value): DynamicEnum(toDynamic(value)) {} + + template <typename T> + inline T as() const { return static_cast<T>(asImpl(typeId<T>())); } + // Cast to a native enum type. + + inline EnumSchema getSchema() const { return schema; } + + kj::Maybe<EnumSchema::Enumerant> getEnumerant() const; + // Get which enumerant this enum value represents. Returns nullptr if the numeric value does not + // correspond to any enumerant in the schema -- this can happen if the data was built using a + // newer schema that has more values defined. + + inline uint16_t getRaw() const { return value; } + // Returns the raw underlying enum value. + +private: + EnumSchema schema; + uint16_t value; + + uint16_t asImpl(uint64_t requestedTypeId) const; + + friend struct DynamicStruct; + friend struct DynamicList; + friend struct DynamicValue; + template <typename T> + friend DynamicTypeFor<TypeIfEnum<T>> toDynamic(T&& value); +}; + +// ------------------------------------------------------------------- + +class DynamicStruct::Reader { +public: + typedef DynamicStruct Reads; + + Reader() = default; + + template <typename T, typename = kj::EnableIf<kind<FromReader<T>>() == Kind::STRUCT>> + inline Reader(T&& value): Reader(toDynamic(value)) {} + + inline MessageSize totalSize() const { return reader.totalSize().asPublic(); } + + template <typename T> + typename T::Reader as() const; + // Convert the dynamic struct to its compiled-in type. + + inline StructSchema getSchema() const { return schema; } + + DynamicValue::Reader get(StructSchema::Field field) const; + // Read the given field value. + + bool has(StructSchema::Field field) const; + // Tests whether the given field is set to its default value. For pointer values, this does + // not actually traverse the value comparing it with the default, but simply returns true if the + // pointer is non-null. For members of unions, has() returns false if the union member is not + // active, but does not necessarily return true if the member is active (depends on the field's + // value). + + kj::Maybe<StructSchema::Field> which() const; + // If the struct contains an (unnamed) union, and the currently-active field within that union + // is known, this returns that field. Otherwise, it returns null. In other words, this returns + // null if there is no union present _or_ if the union's discriminant is set to an unrecognized + // value. This could happen in particular when receiving a message from a sender who has a + // newer version of the protocol and is using a field of the union that you don't know about yet. + + DynamicValue::Reader get(kj::StringPtr name) const; + bool has(kj::StringPtr name) const; + // Shortcuts to access fields by name. These throw exceptions if no such field exists. + +private: + StructSchema schema; + _::StructReader reader; + + inline Reader(StructSchema schema, _::StructReader reader) + : schema(schema), reader(reader) {} + + bool isSetInUnion(StructSchema::Field field) const; + void verifySetInUnion(StructSchema::Field field) const; + static DynamicValue::Reader getImpl(_::StructReader reader, StructSchema::Field field); + + template <typename T, Kind K> + friend struct _::PointerHelpers; + friend class DynamicStruct::Builder; + friend struct DynamicList; + friend class MessageReader; + friend class MessageBuilder; + template <typename T, ::capnp::Kind k> + friend struct ::capnp::ToDynamic_; + friend kj::StringTree _::structString( + _::StructReader reader, const _::RawBrandedSchema& schema); + friend class Orphanage; + friend class Orphan<DynamicStruct>; + friend class Orphan<DynamicValue>; + friend class Orphan<AnyPointer>; +}; + +class DynamicStruct::Builder { +public: + typedef DynamicStruct Builds; + + Builder() = default; + inline Builder(decltype(nullptr)) {} + + template <typename T, typename = kj::EnableIf<kind<FromBuilder<T>>() == Kind::STRUCT>> + inline Builder(T&& value): Builder(toDynamic(value)) {} + + inline MessageSize totalSize() const { return asReader().totalSize(); } + + template <typename T> + typename T::Builder as(); + // Cast to a particular struct type. + + inline StructSchema getSchema() const { return schema; } + + DynamicValue::Builder get(StructSchema::Field field); + // Read the given field value. + + inline bool has(StructSchema::Field field) { return asReader().has(field); } + // Tests whether the given field is set to its default value. For pointer values, this does + // not actually traverse the value comparing it with the default, but simply returns true if the + // pointer is non-null. For members of unions, has() returns whether the field is currently + // active and the union as a whole is non-default -- so, the only time has() will return false + // for an active union field is if it is the default active field and it has its default value. + + kj::Maybe<StructSchema::Field> which(); + // If the struct contains an (unnamed) union, and the currently-active field within that union + // is known, this returns that field. Otherwise, it returns null. In other words, this returns + // null if there is no union present _or_ if the union's discriminant is set to an unrecognized + // value. This could happen in particular when receiving a message from a sender who has a + // newer version of the protocol and is using a field of the union that you don't know about yet. + + void set(StructSchema::Field field, const DynamicValue::Reader& value); + // Set the given field value. + + DynamicValue::Builder init(StructSchema::Field field); + DynamicValue::Builder init(StructSchema::Field field, uint size); + // Init a struct, list, or blob field. + + void adopt(StructSchema::Field field, Orphan<DynamicValue>&& orphan); + Orphan<DynamicValue> disown(StructSchema::Field field); + // Adopt/disown. This works even for non-pointer fields: adopt() becomes equivalent to set() + // and disown() becomes like get() followed by clear(). + + void clear(StructSchema::Field field); + // Clear a field, setting it to its default value. For pointer fields, this actually makes the + // field null. + + DynamicValue::Builder get(kj::StringPtr name); + bool has(kj::StringPtr name); + void set(kj::StringPtr name, const DynamicValue::Reader& value); + void set(kj::StringPtr name, std::initializer_list<DynamicValue::Reader> value); + DynamicValue::Builder init(kj::StringPtr name); + DynamicValue::Builder init(kj::StringPtr name, uint size); + void adopt(kj::StringPtr name, Orphan<DynamicValue>&& orphan); + Orphan<DynamicValue> disown(kj::StringPtr name); + void clear(kj::StringPtr name); + // Shortcuts to access fields by name. These throw exceptions if no such field exists. + + Reader asReader() const; + +private: + StructSchema schema; + _::StructBuilder builder; + + inline Builder(StructSchema schema, _::StructBuilder builder) + : schema(schema), builder(builder) {} + + bool isSetInUnion(StructSchema::Field field); + void verifySetInUnion(StructSchema::Field field); + void setInUnion(StructSchema::Field field); + + template <typename T, Kind k> + friend struct _::PointerHelpers; + friend struct DynamicList; + friend class MessageReader; + friend class MessageBuilder; + template <typename T, ::capnp::Kind k> + friend struct ::capnp::ToDynamic_; + friend class Orphanage; + friend class Orphan<DynamicStruct>; + friend class Orphan<DynamicValue>; + friend class Orphan<AnyPointer>; +}; + +class DynamicStruct::Pipeline { +public: + typedef DynamicStruct Pipelines; + + inline Pipeline(decltype(nullptr)): typeless(nullptr) {} + + template <typename T> + typename T::Pipeline releaseAs(); + // Convert the dynamic pipeline to its compiled-in type. + + inline StructSchema getSchema() { return schema; } + + DynamicValue::Pipeline get(StructSchema::Field field); + // Read the given field value. + + DynamicValue::Pipeline get(kj::StringPtr name); + // Get by string name. + +private: + StructSchema schema; + AnyPointer::Pipeline typeless; + + inline explicit Pipeline(StructSchema schema, AnyPointer::Pipeline&& typeless) + : schema(schema), typeless(kj::mv(typeless)) {} + + friend class Request<DynamicStruct, DynamicStruct>; +}; + +// ------------------------------------------------------------------- + +class DynamicList::Reader { +public: + typedef DynamicList Reads; + + inline Reader(): reader(ElementSize::VOID) {} + + template <typename T, typename = kj::EnableIf<kind<FromReader<T>>() == Kind::LIST>> + inline Reader(T&& value): Reader(toDynamic(value)) {} + + template <typename T> + typename T::Reader as() const; + // Try to convert to any List<T>, Data, or Text. Throws an exception if the underlying data + // can't possibly represent the requested type. + + inline ListSchema getSchema() const { return schema; } + + inline uint size() const { return reader.size() / ELEMENTS; } + DynamicValue::Reader operator[](uint index) const; + + typedef _::IndexingIterator<const Reader, DynamicValue::Reader> Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + +private: + ListSchema schema; + _::ListReader reader; + + Reader(ListSchema schema, _::ListReader reader): schema(schema), reader(reader) {} + + template <typename T, Kind k> + friend struct _::PointerHelpers; + friend struct DynamicStruct; + friend class DynamicList::Builder; + template <typename T, ::capnp::Kind k> + friend struct ::capnp::ToDynamic_; + friend class Orphanage; + friend class Orphan<DynamicList>; + friend class Orphan<DynamicValue>; + friend class Orphan<AnyPointer>; +}; + +class DynamicList::Builder { +public: + typedef DynamicList Builds; + + inline Builder(): builder(ElementSize::VOID) {} + inline Builder(decltype(nullptr)): builder(ElementSize::VOID) {} + + template <typename T, typename = kj::EnableIf<kind<FromBuilder<T>>() == Kind::LIST>> + inline Builder(T&& value): Builder(toDynamic(value)) {} + + template <typename T> + typename T::Builder as(); + // Try to convert to any List<T>, Data, or Text. Throws an exception if the underlying data + // can't possibly represent the requested type. + + inline ListSchema getSchema() const { return schema; } + + inline uint size() const { return builder.size() / ELEMENTS; } + DynamicValue::Builder operator[](uint index); + void set(uint index, const DynamicValue::Reader& value); + DynamicValue::Builder init(uint index, uint size); + void adopt(uint index, Orphan<DynamicValue>&& orphan); + Orphan<DynamicValue> disown(uint index); + + typedef _::IndexingIterator<Builder, DynamicStruct::Builder> Iterator; + inline Iterator begin() { return Iterator(this, 0); } + inline Iterator end() { return Iterator(this, size()); } + + void copyFrom(std::initializer_list<DynamicValue::Reader> value); + + Reader asReader() const; + +private: + ListSchema schema; + _::ListBuilder builder; + + Builder(ListSchema schema, _::ListBuilder builder): schema(schema), builder(builder) {} + + template <typename T, Kind k> + friend struct _::PointerHelpers; + friend struct DynamicStruct; + template <typename T, ::capnp::Kind k> + friend struct ::capnp::ToDynamic_; + friend class Orphanage; + template <typename T, Kind k> + friend struct _::OrphanGetImpl; + friend class Orphan<DynamicList>; + friend class Orphan<DynamicValue>; + friend class Orphan<AnyPointer>; +}; + +// ------------------------------------------------------------------- + +class DynamicCapability::Client: public Capability::Client { +public: + typedef DynamicCapability Calls; + typedef DynamicCapability Reads; + + Client() = default; + + template <typename T, typename = kj::EnableIf<kind<FromClient<T>>() == Kind::INTERFACE>> + inline Client(T&& client); + + template <typename T, typename = kj::EnableIf<kj::canConvert<T*, DynamicCapability::Server*>()>> + inline Client(kj::Own<T>&& server); + + template <typename T, typename = kj::EnableIf<kind<T>() == Kind::INTERFACE>> + typename T::Client as(); + template <typename T, typename = kj::EnableIf<kind<T>() == Kind::INTERFACE>> + typename T::Client releaseAs(); + // Convert to any client type. + + Client upcast(InterfaceSchema requestedSchema); + // Upcast to a superclass. Throws an exception if `schema` is not a superclass. + + inline InterfaceSchema getSchema() { return schema; } + + Request<DynamicStruct, DynamicStruct> newRequest( + InterfaceSchema::Method method, kj::Maybe<MessageSize> sizeHint = nullptr); + Request<DynamicStruct, DynamicStruct> newRequest( + kj::StringPtr methodName, kj::Maybe<MessageSize> sizeHint = nullptr); + +private: + InterfaceSchema schema; + + Client(InterfaceSchema schema, kj::Own<ClientHook>&& hook) + : Capability::Client(kj::mv(hook)), schema(schema) {} + + template <typename T> + inline Client(InterfaceSchema schema, kj::Own<T>&& server); + + friend struct Capability; + friend struct DynamicStruct; + friend struct DynamicList; + friend struct DynamicValue; + friend class Orphan<DynamicCapability>; + friend class Orphan<DynamicValue>; + friend class Orphan<AnyPointer>; + template <typename T, Kind k> + friend struct _::PointerHelpers; +}; + +class DynamicCapability::Server: public Capability::Server { +public: + typedef DynamicCapability Serves; + + Server(InterfaceSchema schema): schema(schema) {} + + virtual kj::Promise<void> call(InterfaceSchema::Method method, + CallContext<DynamicStruct, DynamicStruct> context) = 0; + + kj::Promise<void> dispatchCall(uint64_t interfaceId, uint16_t methodId, + CallContext<AnyPointer, AnyPointer> context) override final; + + inline InterfaceSchema getSchema() const { return schema; } + +private: + InterfaceSchema schema; +}; + +template <> +class Request<DynamicStruct, DynamicStruct>: public DynamicStruct::Builder { + // Specialization of `Request<T, U>` for DynamicStruct. + +public: + inline Request(DynamicStruct::Builder builder, kj::Own<RequestHook>&& hook, + StructSchema resultSchema) + : DynamicStruct::Builder(builder), hook(kj::mv(hook)), resultSchema(resultSchema) {} + + RemotePromise<DynamicStruct> send(); + // Send the call and return a promise for the results. + +private: + kj::Own<RequestHook> hook; + StructSchema resultSchema; + + friend class Capability::Client; + friend struct DynamicCapability; + template <typename, typename> + friend class CallContext; + friend class RequestHook; +}; + +template <> +class CallContext<DynamicStruct, DynamicStruct>: public kj::DisallowConstCopy { + // Wrapper around CallContextHook with a specific return type. + // + // Methods of this class may only be called from within the server's event loop, not from other + // threads. + +public: + explicit CallContext(CallContextHook& hook, StructSchema paramType, StructSchema resultType); + + DynamicStruct::Reader getParams(); + void releaseParams(); + DynamicStruct::Builder getResults(kj::Maybe<MessageSize> sizeHint = nullptr); + DynamicStruct::Builder initResults(kj::Maybe<MessageSize> sizeHint = nullptr); + void setResults(DynamicStruct::Reader value); + void adoptResults(Orphan<DynamicStruct>&& value); + Orphanage getResultsOrphanage(kj::Maybe<MessageSize> sizeHint = nullptr); + template <typename SubParams> + kj::Promise<void> tailCall(Request<SubParams, DynamicStruct>&& tailRequest); + void allowCancellation(); + +private: + CallContextHook* hook; + StructSchema paramType; + StructSchema resultType; + + friend class DynamicCapability::Server; +}; + +// ------------------------------------------------------------------- + +// Make sure ReaderFor<T> and BuilderFor<T> work for DynamicEnum, DynamicStruct, and +// DynamicList, so that we can define DynamicValue::as(). + +template <> struct ReaderFor_ <DynamicEnum, Kind::OTHER> { typedef DynamicEnum Type; }; +template <> struct BuilderFor_<DynamicEnum, Kind::OTHER> { typedef DynamicEnum Type; }; +template <> struct ReaderFor_ <DynamicStruct, Kind::OTHER> { typedef DynamicStruct::Reader Type; }; +template <> struct BuilderFor_<DynamicStruct, Kind::OTHER> { typedef DynamicStruct::Builder Type; }; +template <> struct ReaderFor_ <DynamicList, Kind::OTHER> { typedef DynamicList::Reader Type; }; +template <> struct BuilderFor_<DynamicList, Kind::OTHER> { typedef DynamicList::Builder Type; }; +template <> struct ReaderFor_ <DynamicCapability, Kind::OTHER> { typedef DynamicCapability::Client Type; }; +template <> struct BuilderFor_<DynamicCapability, Kind::OTHER> { typedef DynamicCapability::Client Type; }; +template <> struct PipelineFor_<DynamicCapability, Kind::OTHER> { typedef DynamicCapability::Client Type; }; + +class DynamicValue::Reader { +public: + typedef DynamicValue Reads; + + inline Reader(decltype(nullptr) n = nullptr); // UNKNOWN + inline Reader(Void value); + inline Reader(bool value); + inline Reader(char value); + inline Reader(signed char value); + inline Reader(short value); + inline Reader(int value); + inline Reader(long value); + inline Reader(long long value); + inline Reader(unsigned char value); + inline Reader(unsigned short value); + inline Reader(unsigned int value); + inline Reader(unsigned long value); + inline Reader(unsigned long long value); + inline Reader(float value); + inline Reader(double value); + inline Reader(const char* value); // Text + inline Reader(const Text::Reader& value); + inline Reader(const Data::Reader& value); + inline Reader(const DynamicList::Reader& value); + inline Reader(DynamicEnum value); + inline Reader(const DynamicStruct::Reader& value); + inline Reader(const AnyPointer::Reader& value); + inline Reader(DynamicCapability::Client& value); + inline Reader(DynamicCapability::Client&& value); + template <typename T, typename = kj::EnableIf<kj::canConvert<T*, DynamicCapability::Server*>()>> + inline Reader(kj::Own<T>&& value); + Reader(ConstSchema constant); + + template <typename T, typename = decltype(toDynamic(kj::instance<T>()))> + inline Reader(T&& value): Reader(toDynamic(kj::mv(value))) {} + + Reader(const Reader& other); + Reader(Reader&& other) noexcept; + ~Reader() noexcept(false); + Reader& operator=(const Reader& other); + Reader& operator=(Reader&& other); + // Unfortunately, we cannot use the implicit definitions of these since DynamicCapability is not + // trivially copyable. + + template <typename T> + inline ReaderFor<T> as() const { return AsImpl<T>::apply(*this); } + // Use to interpret the value as some Cap'n Proto type. Allowed types are: + // - Void, bool, [u]int{8,16,32,64}_t, float, double, any enum: Returns the raw value. + // - Text, Data, AnyPointer, any struct type: Returns the corresponding Reader. + // - List<T> for any T listed above: Returns List<T>::Reader. + // - DynamicEnum: Returns the corresponding type. + // - DynamicStruct, DynamicList: Returns the corresponding Reader. + // - Any capability type, including DynamicCapability: Returns the corresponding Client. + // (TODO(perf): On GCC 4.8 / Clang 3.3, provide rvalue-qualified version that avoids + // refcounting.) + // + // DynamicValue allows various implicit conversions, mostly just to make the interface friendlier. + // - Any integer can be converted to any other integer type so long as the actual value is within + // the new type's range. + // - Floating-point types can be converted to integers as long as no information would be lost + // in the conversion. + // - Integers can be converted to floating points. This may lose information, but won't throw. + // - Float32/Float64 can be converted between each other. Converting Float64 -> Float32 may lose + // information, but won't throw. + // - Text can be converted to an enum, if the Text matches one of the enumerant names (but not + // vice-versa). + // - Capabilities can be upcast (cast to a supertype), but not downcast. + // + // Any other conversion attempt will throw an exception. + + inline Type getType() const { return type; } + // Get the type of this value. + +private: + Type type; + + union { + Void voidValue; + bool boolValue; + int64_t intValue; + uint64_t uintValue; + double floatValue; + Text::Reader textValue; + Data::Reader dataValue; + DynamicList::Reader listValue; + DynamicEnum enumValue; + DynamicStruct::Reader structValue; + AnyPointer::Reader anyPointerValue; + + mutable DynamicCapability::Client capabilityValue; + // Declared mutable because `Client`s normally cannot be const. + + // Warning: Copy/move constructors assume all these types are trivially copyable except + // Capability. + }; + + template <typename T, Kind kind = kind<T>()> struct AsImpl; + // Implementation backing the as() method. Needs to be a struct to allow partial + // specialization. Has a method apply() which does the work. + + friend class Orphanage; // to speed up newOrphanCopy(DynamicValue::Reader) +}; + +class DynamicValue::Builder { +public: + typedef DynamicValue Builds; + + inline Builder(decltype(nullptr) n = nullptr); // UNKNOWN + inline Builder(Void value); + inline Builder(bool value); + inline Builder(char value); + inline Builder(signed char value); + inline Builder(short value); + inline Builder(int value); + inline Builder(long value); + inline Builder(long long value); + inline Builder(unsigned char value); + inline Builder(unsigned short value); + inline Builder(unsigned int value); + inline Builder(unsigned long value); + inline Builder(unsigned long long value); + inline Builder(float value); + inline Builder(double value); + inline Builder(Text::Builder value); + inline Builder(Data::Builder value); + inline Builder(DynamicList::Builder value); + inline Builder(DynamicEnum value); + inline Builder(DynamicStruct::Builder value); + inline Builder(AnyPointer::Builder value); + inline Builder(DynamicCapability::Client& value); + inline Builder(DynamicCapability::Client&& value); + + template <typename T, typename = decltype(toDynamic(kj::instance<T>()))> + inline Builder(T value): Builder(toDynamic(value)) {} + + Builder(Builder& other); + Builder(Builder&& other) noexcept; + ~Builder() noexcept(false); + Builder& operator=(Builder& other); + Builder& operator=(Builder&& other); + // Unfortunately, we cannot use the implicit definitions of these since DynamicCapability is not + // trivially copyable. + + template <typename T> + inline BuilderFor<T> as() { return AsImpl<T>::apply(*this); } + // See DynamicValue::Reader::as(). + + inline Type getType() { return type; } + // Get the type of this value. + + Reader asReader() const; + +private: + Type type; + + union { + Void voidValue; + bool boolValue; + int64_t intValue; + uint64_t uintValue; + double floatValue; + Text::Builder textValue; + Data::Builder dataValue; + DynamicList::Builder listValue; + DynamicEnum enumValue; + DynamicStruct::Builder structValue; + AnyPointer::Builder anyPointerValue; + + mutable DynamicCapability::Client capabilityValue; + // Declared mutable because `Client`s normally cannot be const. + }; + + template <typename T, Kind kind = kind<T>()> struct AsImpl; + // Implementation backing the as() method. Needs to be a struct to allow partial + // specialization. Has a method apply() which does the work. + + friend class Orphan<DynamicValue>; +}; + +class DynamicValue::Pipeline { +public: + typedef DynamicValue Pipelines; + + inline Pipeline(decltype(nullptr) n = nullptr); + inline Pipeline(DynamicStruct::Pipeline&& value); + inline Pipeline(DynamicCapability::Client&& value); + + Pipeline(Pipeline&& other) noexcept; + Pipeline& operator=(Pipeline&& other); + ~Pipeline() noexcept(false); + + template <typename T> + inline PipelineFor<T> releaseAs() { return AsImpl<T>::apply(*this); } + + inline Type getType() { return type; } + // Get the type of this value. + +private: + Type type; + union { + DynamicStruct::Pipeline structValue; + DynamicCapability::Client capabilityValue; + }; + + template <typename T, Kind kind = kind<T>()> struct AsImpl; + // Implementation backing the releaseAs() method. Needs to be a struct to allow partial + // specialization. Has a method apply() which does the work. +}; + +kj::StringTree KJ_STRINGIFY(const DynamicValue::Reader& value); +kj::StringTree KJ_STRINGIFY(const DynamicValue::Builder& value); +kj::StringTree KJ_STRINGIFY(DynamicEnum value); +kj::StringTree KJ_STRINGIFY(const DynamicStruct::Reader& value); +kj::StringTree KJ_STRINGIFY(const DynamicStruct::Builder& value); +kj::StringTree KJ_STRINGIFY(const DynamicList::Reader& value); +kj::StringTree KJ_STRINGIFY(const DynamicList::Builder& value); + +// ------------------------------------------------------------------- +// Orphan <-> Dynamic glue + +template <> +class Orphan<DynamicStruct> { +public: + Orphan() = default; + KJ_DISALLOW_COPY(Orphan); + Orphan(Orphan&&) = default; + Orphan& operator=(Orphan&&) = default; + + template <typename T, typename = kj::EnableIf<kind<T>() == Kind::STRUCT>> + inline Orphan(Orphan<T>&& other): schema(Schema::from<T>()), builder(kj::mv(other.builder)) {} + + DynamicStruct::Builder get(); + DynamicStruct::Reader getReader() const; + + template <typename T> + Orphan<T> releaseAs(); + // Like DynamicStruct::Builder::as(), but coerces the Orphan type. Since Orphans are move-only, + // the original Orphan<DynamicStruct> is no longer valid after this call; ownership is + // transferred to the returned Orphan<T>. + + inline bool operator==(decltype(nullptr)) const { return builder == nullptr; } + inline bool operator!=(decltype(nullptr)) const { return builder != nullptr; } + +private: + StructSchema schema; + _::OrphanBuilder builder; + + inline Orphan(StructSchema schema, _::OrphanBuilder&& builder) + : schema(schema), builder(kj::mv(builder)) {} + + template <typename, Kind> + friend struct _::PointerHelpers; + friend struct DynamicList; + friend class Orphanage; + friend class Orphan<DynamicValue>; + friend class Orphan<AnyPointer>; + friend class MessageBuilder; +}; + +template <> +class Orphan<DynamicList> { +public: + Orphan() = default; + KJ_DISALLOW_COPY(Orphan); + Orphan(Orphan&&) = default; + Orphan& operator=(Orphan&&) = default; + + template <typename T, typename = kj::EnableIf<kind<T>() == Kind::LIST>> + inline Orphan(Orphan<T>&& other): schema(Schema::from<T>()), builder(kj::mv(other.builder)) {} + + DynamicList::Builder get(); + DynamicList::Reader getReader() const; + + template <typename T> + Orphan<T> releaseAs(); + // Like DynamicList::Builder::as(), but coerces the Orphan type. Since Orphans are move-only, + // the original Orphan<DynamicStruct> is no longer valid after this call; ownership is + // transferred to the returned Orphan<T>. + + // TODO(someday): Support truncate(). + + inline bool operator==(decltype(nullptr)) const { return builder == nullptr; } + inline bool operator!=(decltype(nullptr)) const { return builder != nullptr; } + +private: + ListSchema schema; + _::OrphanBuilder builder; + + inline Orphan(ListSchema schema, _::OrphanBuilder&& builder) + : schema(schema), builder(kj::mv(builder)) {} + + template <typename, Kind> + friend struct _::PointerHelpers; + friend struct DynamicList; + friend class Orphanage; + friend class Orphan<DynamicValue>; + friend class Orphan<AnyPointer>; +}; + +template <> +class Orphan<DynamicCapability> { +public: + Orphan() = default; + KJ_DISALLOW_COPY(Orphan); + Orphan(Orphan&&) = default; + Orphan& operator=(Orphan&&) = default; + + template <typename T, typename = kj::EnableIf<kind<T>() == Kind::INTERFACE>> + inline Orphan(Orphan<T>&& other): schema(Schema::from<T>()), builder(kj::mv(other.builder)) {} + + DynamicCapability::Client get(); + DynamicCapability::Client getReader() const; + + template <typename T> + Orphan<T> releaseAs(); + // Like DynamicCapability::Client::as(), but coerces the Orphan type. Since Orphans are move-only, + // the original Orphan<DynamicCapability> is no longer valid after this call; ownership is + // transferred to the returned Orphan<T>. + + inline bool operator==(decltype(nullptr)) const { return builder == nullptr; } + inline bool operator!=(decltype(nullptr)) const { return builder != nullptr; } + +private: + InterfaceSchema schema; + _::OrphanBuilder builder; + + inline Orphan(InterfaceSchema schema, _::OrphanBuilder&& builder) + : schema(schema), builder(kj::mv(builder)) {} + + template <typename, Kind> + friend struct _::PointerHelpers; + friend struct DynamicList; + friend class Orphanage; + friend class Orphan<DynamicValue>; + friend class Orphan<AnyPointer>; +}; + +template <> +class Orphan<DynamicValue> { +public: + inline Orphan(decltype(nullptr) n = nullptr): type(DynamicValue::UNKNOWN) {} + inline Orphan(Void value); + inline Orphan(bool value); + inline Orphan(char value); + inline Orphan(signed char value); + inline Orphan(short value); + inline Orphan(int value); + inline Orphan(long value); + inline Orphan(long long value); + inline Orphan(unsigned char value); + inline Orphan(unsigned short value); + inline Orphan(unsigned int value); + inline Orphan(unsigned long value); + inline Orphan(unsigned long long value); + inline Orphan(float value); + inline Orphan(double value); + inline Orphan(DynamicEnum value); + Orphan(Orphan&&) = default; + template <typename T> + Orphan(Orphan<T>&&); + Orphan(Orphan<AnyPointer>&&); + Orphan(void*) = delete; // So Orphan(bool) doesn't accept pointers. + KJ_DISALLOW_COPY(Orphan); + + Orphan& operator=(Orphan&&) = default; + + inline DynamicValue::Type getType() { return type; } + + DynamicValue::Builder get(); + DynamicValue::Reader getReader() const; + + template <typename T> + Orphan<T> releaseAs(); + // Like DynamicValue::Builder::as(), but coerces the Orphan type. Since Orphans are move-only, + // the original Orphan<DynamicStruct> is no longer valid after this call; ownership is + // transferred to the returned Orphan<T>. + +private: + DynamicValue::Type type; + union { + Void voidValue; + bool boolValue; + int64_t intValue; + uint64_t uintValue; + double floatValue; + DynamicEnum enumValue; + StructSchema structSchema; + ListSchema listSchema; + InterfaceSchema interfaceSchema; + }; + + _::OrphanBuilder builder; + // Only used if `type` is a pointer type. + + Orphan(DynamicValue::Builder value, _::OrphanBuilder&& builder); + Orphan(DynamicValue::Type type, _::OrphanBuilder&& builder) + : type(type), builder(kj::mv(builder)) {} + Orphan(StructSchema structSchema, _::OrphanBuilder&& builder) + : type(DynamicValue::STRUCT), structSchema(structSchema), builder(kj::mv(builder)) {} + Orphan(ListSchema listSchema, _::OrphanBuilder&& builder) + : type(DynamicValue::LIST), listSchema(listSchema), builder(kj::mv(builder)) {} + + template <typename, Kind> + friend struct _::PointerHelpers; + friend struct DynamicStruct; + friend struct DynamicList; + friend struct AnyPointer; + friend class Orphanage; +}; + +template <typename T> +inline Orphan<DynamicValue>::Orphan(Orphan<T>&& other) + : Orphan(other.get(), kj::mv(other.builder)) {} + +inline Orphan<DynamicValue>::Orphan(Orphan<AnyPointer>&& other) + : type(DynamicValue::ANY_POINTER), builder(kj::mv(other.builder)) {} + +template <typename T> +Orphan<T> Orphan<DynamicStruct>::releaseAs() { + get().as<T>(); // type check + return Orphan<T>(kj::mv(builder)); +} + +template <typename T> +Orphan<T> Orphan<DynamicList>::releaseAs() { + get().as<T>(); // type check + return Orphan<T>(kj::mv(builder)); +} + +template <typename T> +Orphan<T> Orphan<DynamicCapability>::releaseAs() { + get().as<T>(); // type check + return Orphan<T>(kj::mv(builder)); +} + +template <typename T> +Orphan<T> Orphan<DynamicValue>::releaseAs() { + get().as<T>(); // type check + type = DynamicValue::UNKNOWN; + return Orphan<T>(kj::mv(builder)); +} + +template <> +Orphan<AnyPointer> Orphan<DynamicValue>::releaseAs<AnyPointer>(); +template <> +Orphan<DynamicStruct> Orphan<DynamicValue>::releaseAs<DynamicStruct>(); +template <> +Orphan<DynamicList> Orphan<DynamicValue>::releaseAs<DynamicList>(); +template <> +Orphan<DynamicCapability> Orphan<DynamicValue>::releaseAs<DynamicCapability>(); + +template <> +struct Orphanage::GetInnerBuilder<DynamicStruct, Kind::OTHER> { + static inline _::StructBuilder apply(DynamicStruct::Builder& t) { + return t.builder; + } +}; + +template <> +struct Orphanage::GetInnerBuilder<DynamicList, Kind::OTHER> { + static inline _::ListBuilder apply(DynamicList::Builder& t) { + return t.builder; + } +}; + +template <> +inline Orphan<DynamicStruct> Orphanage::newOrphanCopy<DynamicStruct::Reader>( + DynamicStruct::Reader copyFrom) const { + return Orphan<DynamicStruct>( + copyFrom.getSchema(), _::OrphanBuilder::copy(arena, capTable, copyFrom.reader)); +} + +template <> +inline Orphan<DynamicList> Orphanage::newOrphanCopy<DynamicList::Reader>( + DynamicList::Reader copyFrom) const { + return Orphan<DynamicList>(copyFrom.getSchema(), + _::OrphanBuilder::copy(arena, capTable, copyFrom.reader)); +} + +template <> +inline Orphan<DynamicCapability> Orphanage::newOrphanCopy<DynamicCapability::Client>( + DynamicCapability::Client copyFrom) const { + return Orphan<DynamicCapability>( + copyFrom.getSchema(), _::OrphanBuilder::copy(arena, capTable, copyFrom.hook->addRef())); +} + +template <> +Orphan<DynamicValue> Orphanage::newOrphanCopy<DynamicValue::Reader>( + DynamicValue::Reader copyFrom) const; + +namespace _ { // private + +template <> +struct PointerHelpers<DynamicStruct, Kind::OTHER> { + // getDynamic() is used when an AnyPointer's get() accessor is passed arguments, because for + // non-dynamic types PointerHelpers::get() takes a default value as the third argument, and we + // don't want people to accidentally be able to provide their own default value. + static DynamicStruct::Reader getDynamic(PointerReader reader, StructSchema schema); + static DynamicStruct::Builder getDynamic(PointerBuilder builder, StructSchema schema); + static void set(PointerBuilder builder, const DynamicStruct::Reader& value); + static DynamicStruct::Builder init(PointerBuilder builder, StructSchema schema); + static inline void adopt(PointerBuilder builder, Orphan<DynamicStruct>&& value) { + builder.adopt(kj::mv(value.builder)); + } + static inline Orphan<DynamicStruct> disown(PointerBuilder builder, StructSchema schema) { + return Orphan<DynamicStruct>(schema, builder.disown()); + } +}; + +template <> +struct PointerHelpers<DynamicList, Kind::OTHER> { + // getDynamic() is used when an AnyPointer's get() accessor is passed arguments, because for + // non-dynamic types PointerHelpers::get() takes a default value as the third argument, and we + // don't want people to accidentally be able to provide their own default value. + static DynamicList::Reader getDynamic(PointerReader reader, ListSchema schema); + static DynamicList::Builder getDynamic(PointerBuilder builder, ListSchema schema); + static void set(PointerBuilder builder, const DynamicList::Reader& value); + static DynamicList::Builder init(PointerBuilder builder, ListSchema schema, uint size); + static inline void adopt(PointerBuilder builder, Orphan<DynamicList>&& value) { + builder.adopt(kj::mv(value.builder)); + } + static inline Orphan<DynamicList> disown(PointerBuilder builder, ListSchema schema) { + return Orphan<DynamicList>(schema, builder.disown()); + } +}; + +template <> +struct PointerHelpers<DynamicCapability, Kind::OTHER> { + // getDynamic() is used when an AnyPointer's get() accessor is passed arguments, because for + // non-dynamic types PointerHelpers::get() takes a default value as the third argument, and we + // don't want people to accidentally be able to provide their own default value. + static DynamicCapability::Client getDynamic(PointerReader reader, InterfaceSchema schema); + static DynamicCapability::Client getDynamic(PointerBuilder builder, InterfaceSchema schema); + static void set(PointerBuilder builder, DynamicCapability::Client& value); + static void set(PointerBuilder builder, DynamicCapability::Client&& value); + static inline void adopt(PointerBuilder builder, Orphan<DynamicCapability>&& value) { + builder.adopt(kj::mv(value.builder)); + } + static inline Orphan<DynamicCapability> disown(PointerBuilder builder, InterfaceSchema schema) { + return Orphan<DynamicCapability>(schema, builder.disown()); + } +}; + +} // namespace _ (private) + +template <typename T> +inline ReaderFor<T> AnyPointer::Reader::getAs(StructSchema schema) const { + return _::PointerHelpers<T>::getDynamic(reader, schema); +} +template <typename T> +inline ReaderFor<T> AnyPointer::Reader::getAs(ListSchema schema) const { + return _::PointerHelpers<T>::getDynamic(reader, schema); +} +template <typename T> +inline ReaderFor<T> AnyPointer::Reader::getAs(InterfaceSchema schema) const { + return _::PointerHelpers<T>::getDynamic(reader, schema); +} +template <typename T> +inline BuilderFor<T> AnyPointer::Builder::getAs(StructSchema schema) { + return _::PointerHelpers<T>::getDynamic(builder, schema); +} +template <typename T> +inline BuilderFor<T> AnyPointer::Builder::getAs(ListSchema schema) { + return _::PointerHelpers<T>::getDynamic(builder, schema); +} +template <typename T> +inline BuilderFor<T> AnyPointer::Builder::getAs(InterfaceSchema schema) { + return _::PointerHelpers<T>::getDynamic(builder, schema); +} +template <typename T> +inline BuilderFor<T> AnyPointer::Builder::initAs(StructSchema schema) { + return _::PointerHelpers<T>::init(builder, schema); +} +template <typename T> +inline BuilderFor<T> AnyPointer::Builder::initAs(ListSchema schema, uint elementCount) { + return _::PointerHelpers<T>::init(builder, schema, elementCount); +} +template <> +inline void AnyPointer::Builder::setAs<DynamicStruct>(DynamicStruct::Reader value) { + return _::PointerHelpers<DynamicStruct>::set(builder, value); +} +template <> +inline void AnyPointer::Builder::setAs<DynamicList>(DynamicList::Reader value) { + return _::PointerHelpers<DynamicList>::set(builder, value); +} +template <> +inline void AnyPointer::Builder::setAs<DynamicCapability>(DynamicCapability::Client value) { + return _::PointerHelpers<DynamicCapability>::set(builder, kj::mv(value)); +} +template <> +void AnyPointer::Builder::adopt<DynamicValue>(Orphan<DynamicValue>&& orphan); +template <typename T> +inline Orphan<T> AnyPointer::Builder::disownAs(StructSchema schema) { + return _::PointerHelpers<T>::disown(builder, schema); +} +template <typename T> +inline Orphan<T> AnyPointer::Builder::disownAs(ListSchema schema) { + return _::PointerHelpers<T>::disown(builder, schema); +} +template <typename T> +inline Orphan<T> AnyPointer::Builder::disownAs(InterfaceSchema schema) { + return _::PointerHelpers<T>::disown(builder, schema); +} + +template <> +DynamicStruct::Builder Orphan<AnyPointer>::getAs<DynamicStruct>(StructSchema schema); +template <> +DynamicList::Builder Orphan<AnyPointer>::getAs<DynamicList>(ListSchema schema); +template <> +DynamicCapability::Client Orphan<AnyPointer>::getAs<DynamicCapability>(InterfaceSchema schema); +template <> +DynamicStruct::Reader Orphan<AnyPointer>::getAsReader<DynamicStruct>(StructSchema schema) const; +template <> +DynamicList::Reader Orphan<AnyPointer>::getAsReader<DynamicList>(ListSchema schema) const; +template <> +DynamicCapability::Client Orphan<AnyPointer>::getAsReader<DynamicCapability>( + InterfaceSchema schema) const; +template <> +Orphan<DynamicStruct> Orphan<AnyPointer>::releaseAs<DynamicStruct>(StructSchema schema); +template <> +Orphan<DynamicList> Orphan<AnyPointer>::releaseAs<DynamicList>(ListSchema schema); +template <> +Orphan<DynamicCapability> Orphan<AnyPointer>::releaseAs<DynamicCapability>( + InterfaceSchema schema); + +// ======================================================================================= +// Inline implementation details. + +template <typename T> +struct ToDynamic_<T, Kind::STRUCT> { + static inline DynamicStruct::Reader apply(const typename T::Reader& value) { + return DynamicStruct::Reader(Schema::from<T>(), value._reader); + } + static inline DynamicStruct::Builder apply(typename T::Builder& value) { + return DynamicStruct::Builder(Schema::from<T>(), value._builder); + } +}; + +template <typename T> +struct ToDynamic_<T, Kind::LIST> { + static inline DynamicList::Reader apply(const typename T::Reader& value) { + return DynamicList::Reader(Schema::from<T>(), value.reader); + } + static inline DynamicList::Builder apply(typename T::Builder& value) { + return DynamicList::Builder(Schema::from<T>(), value.builder); + } +}; + +template <typename T> +struct ToDynamic_<T, Kind::INTERFACE> { + static inline DynamicCapability::Client apply(typename T::Client value) { + return DynamicCapability::Client(kj::mv(value)); + } + static inline DynamicCapability::Client apply(typename T::Client&& value) { + return DynamicCapability::Client(kj::mv(value)); + } +}; + +template <typename T> +ReaderFor<DynamicTypeFor<FromReader<T>>> toDynamic(T&& value) { + return ToDynamic_<FromReader<T>>::apply(value); +} +template <typename T> +BuilderFor<DynamicTypeFor<FromBuilder<T>>> toDynamic(T&& value) { + return ToDynamic_<FromBuilder<T>>::apply(value); +} +template <typename T> +DynamicTypeFor<TypeIfEnum<T>> toDynamic(T&& value) { + return DynamicEnum(Schema::from<kj::Decay<T>>(), static_cast<uint16_t>(value)); +} +template <typename T> +typename DynamicTypeFor<FromServer<T>>::Client toDynamic(kj::Own<T>&& value) { + return typename FromServer<T>::Client(kj::mv(value)); +} + +inline DynamicValue::Reader::Reader(std::nullptr_t n): type(UNKNOWN) {} +inline DynamicValue::Builder::Builder(std::nullptr_t n): type(UNKNOWN) {} + +#define CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(cppType, typeTag, fieldName) \ +inline DynamicValue::Reader::Reader(cppType value) \ + : type(typeTag), fieldName##Value(value) {} \ +inline DynamicValue::Builder::Builder(cppType value) \ + : type(typeTag), fieldName##Value(value) {} \ +inline Orphan<DynamicValue>::Orphan(cppType value) \ + : type(DynamicValue::typeTag), fieldName##Value(value) {} + +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(Void, VOID, void); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(bool, BOOL, bool); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(char, INT, int); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(signed char, INT, int); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(short, INT, int); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(int, INT, int); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(long, INT, int); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(long long, INT, int); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(unsigned char, UINT, uint); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(unsigned short, UINT, uint); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(unsigned int, UINT, uint); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(unsigned long, UINT, uint); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(unsigned long long, UINT, uint); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(float, FLOAT, float); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(double, FLOAT, float); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(DynamicEnum, ENUM, enum); +#undef CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR + +#define CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(cppType, typeTag, fieldName) \ +inline DynamicValue::Reader::Reader(const cppType::Reader& value) \ + : type(typeTag), fieldName##Value(value) {} \ +inline DynamicValue::Builder::Builder(cppType::Builder value) \ + : type(typeTag), fieldName##Value(value) {} + +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(Text, TEXT, text); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(Data, DATA, data); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(DynamicList, LIST, list); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(DynamicStruct, STRUCT, struct); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(AnyPointer, ANY_POINTER, anyPointer); + +#undef CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR + +inline DynamicValue::Reader::Reader(DynamicCapability::Client& value) + : type(CAPABILITY), capabilityValue(value) {} +inline DynamicValue::Reader::Reader(DynamicCapability::Client&& value) + : type(CAPABILITY), capabilityValue(kj::mv(value)) {} +template <typename T, typename> +inline DynamicValue::Reader::Reader(kj::Own<T>&& value) + : type(CAPABILITY), capabilityValue(kj::mv(value)) {} +inline DynamicValue::Builder::Builder(DynamicCapability::Client& value) + : type(CAPABILITY), capabilityValue(value) {} +inline DynamicValue::Builder::Builder(DynamicCapability::Client&& value) + : type(CAPABILITY), capabilityValue(kj::mv(value)) {} + +inline DynamicValue::Reader::Reader(const char* value): Reader(Text::Reader(value)) {} + +#define CAPNP_DECLARE_TYPE(discrim, typeName) \ +template <> \ +struct DynamicValue::Reader::AsImpl<typeName> { \ + static ReaderFor<typeName> apply(const Reader& reader); \ +}; \ +template <> \ +struct DynamicValue::Builder::AsImpl<typeName> { \ + static BuilderFor<typeName> apply(Builder& builder); \ +}; + +//CAPNP_DECLARE_TYPE(VOID, Void) +CAPNP_DECLARE_TYPE(BOOL, bool) +CAPNP_DECLARE_TYPE(INT8, int8_t) +CAPNP_DECLARE_TYPE(INT16, int16_t) +CAPNP_DECLARE_TYPE(INT32, int32_t) +CAPNP_DECLARE_TYPE(INT64, int64_t) +CAPNP_DECLARE_TYPE(UINT8, uint8_t) +CAPNP_DECLARE_TYPE(UINT16, uint16_t) +CAPNP_DECLARE_TYPE(UINT32, uint32_t) +CAPNP_DECLARE_TYPE(UINT64, uint64_t) +CAPNP_DECLARE_TYPE(FLOAT32, float) +CAPNP_DECLARE_TYPE(FLOAT64, double) + +CAPNP_DECLARE_TYPE(TEXT, Text) +CAPNP_DECLARE_TYPE(DATA, Data) +CAPNP_DECLARE_TYPE(LIST, DynamicList) +CAPNP_DECLARE_TYPE(STRUCT, DynamicStruct) +CAPNP_DECLARE_TYPE(INTERFACE, DynamicCapability) +CAPNP_DECLARE_TYPE(ENUM, DynamicEnum) +CAPNP_DECLARE_TYPE(ANY_POINTER, AnyPointer) +#undef CAPNP_DECLARE_TYPE + +// CAPNP_DECLARE_TYPE(Void) causes gcc 4.7 to segfault. If I do it manually and remove the +// ReaderFor<> and BuilderFor<> wrappers, it works. +template <> +struct DynamicValue::Reader::AsImpl<Void> { + static Void apply(const Reader& reader); +}; +template <> +struct DynamicValue::Builder::AsImpl<Void> { + static Void apply(Builder& builder); +}; + +template <typename T> +struct DynamicValue::Reader::AsImpl<T, Kind::ENUM> { + static T apply(const Reader& reader) { + return reader.as<DynamicEnum>().as<T>(); + } +}; +template <typename T> +struct DynamicValue::Builder::AsImpl<T, Kind::ENUM> { + static T apply(Builder& builder) { + return builder.as<DynamicEnum>().as<T>(); + } +}; + +template <typename T> +struct DynamicValue::Reader::AsImpl<T, Kind::STRUCT> { + static typename T::Reader apply(const Reader& reader) { + return reader.as<DynamicStruct>().as<T>(); + } +}; +template <typename T> +struct DynamicValue::Builder::AsImpl<T, Kind::STRUCT> { + static typename T::Builder apply(Builder& builder) { + return builder.as<DynamicStruct>().as<T>(); + } +}; + +template <typename T> +struct DynamicValue::Reader::AsImpl<T, Kind::LIST> { + static typename T::Reader apply(const Reader& reader) { + return reader.as<DynamicList>().as<T>(); + } +}; +template <typename T> +struct DynamicValue::Builder::AsImpl<T, Kind::LIST> { + static typename T::Builder apply(Builder& builder) { + return builder.as<DynamicList>().as<T>(); + } +}; + +template <typename T> +struct DynamicValue::Reader::AsImpl<T, Kind::INTERFACE> { + static typename T::Client apply(const Reader& reader) { + return reader.as<DynamicCapability>().as<T>(); + } +}; +template <typename T> +struct DynamicValue::Builder::AsImpl<T, Kind::INTERFACE> { + static typename T::Client apply(Builder& builder) { + return builder.as<DynamicCapability>().as<T>(); + } +}; + +inline DynamicValue::Pipeline::Pipeline(std::nullptr_t n): type(UNKNOWN) {} +inline DynamicValue::Pipeline::Pipeline(DynamicStruct::Pipeline&& value) + : type(STRUCT), structValue(kj::mv(value)) {} +inline DynamicValue::Pipeline::Pipeline(DynamicCapability::Client&& value) + : type(CAPABILITY), capabilityValue(kj::mv(value)) {} + +template <typename T> +struct DynamicValue::Pipeline::AsImpl<T, Kind::STRUCT> { + static typename T::Pipeline apply(Pipeline& pipeline) { + return pipeline.releaseAs<DynamicStruct>().releaseAs<T>(); + } +}; +template <typename T> +struct DynamicValue::Pipeline::AsImpl<T, Kind::INTERFACE> { + static typename T::Client apply(Pipeline& pipeline) { + return pipeline.releaseAs<DynamicCapability>().releaseAs<T>(); + } +}; +template <> +struct DynamicValue::Pipeline::AsImpl<DynamicStruct, Kind::OTHER> { + static PipelineFor<DynamicStruct> apply(Pipeline& pipeline); +}; +template <> +struct DynamicValue::Pipeline::AsImpl<DynamicCapability, Kind::OTHER> { + static PipelineFor<DynamicCapability> apply(Pipeline& pipeline); +}; + +// ------------------------------------------------------------------- + +template <typename T> +typename T::Reader DynamicStruct::Reader::as() const { + static_assert(kind<T>() == Kind::STRUCT, + "DynamicStruct::Reader::as<T>() can only convert to struct types."); + schema.requireUsableAs<T>(); + return typename T::Reader(reader); +} + +template <typename T> +typename T::Builder DynamicStruct::Builder::as() { + static_assert(kind<T>() == Kind::STRUCT, + "DynamicStruct::Builder::as<T>() can only convert to struct types."); + schema.requireUsableAs<T>(); + return typename T::Builder(builder); +} + +template <> +inline DynamicStruct::Reader DynamicStruct::Reader::as<DynamicStruct>() const { + return *this; +} +template <> +inline DynamicStruct::Builder DynamicStruct::Builder::as<DynamicStruct>() { + return *this; +} + +inline DynamicStruct::Reader DynamicStruct::Builder::asReader() const { + return DynamicStruct::Reader(schema, builder.asReader()); +} + +template <> +inline AnyStruct::Reader DynamicStruct::Reader::as<AnyStruct>() const { + return AnyStruct::Reader(reader); +} + +template <> +inline AnyStruct::Builder DynamicStruct::Builder::as<AnyStruct>() { + return AnyStruct::Builder(builder); +} + +template <typename T> +typename T::Pipeline DynamicStruct::Pipeline::releaseAs() { + static_assert(kind<T>() == Kind::STRUCT, + "DynamicStruct::Pipeline::releaseAs<T>() can only convert to struct types."); + schema.requireUsableAs<T>(); + return typename T::Pipeline(kj::mv(typeless)); +} + +// ------------------------------------------------------------------- + +template <typename T> +typename T::Reader DynamicList::Reader::as() const { + static_assert(kind<T>() == Kind::LIST, + "DynamicStruct::Reader::as<T>() can only convert to list types."); + schema.requireUsableAs<T>(); + return typename T::Reader(reader); +} +template <typename T> +typename T::Builder DynamicList::Builder::as() { + static_assert(kind<T>() == Kind::LIST, + "DynamicStruct::Builder::as<T>() can only convert to list types."); + schema.requireUsableAs<T>(); + return typename T::Builder(builder); +} + +template <> +inline DynamicList::Reader DynamicList::Reader::as<DynamicList>() const { + return *this; +} +template <> +inline DynamicList::Builder DynamicList::Builder::as<DynamicList>() { + return *this; +} + +// ------------------------------------------------------------------- + +template <typename T, typename> +inline DynamicCapability::Client::Client(T&& client) + : Capability::Client(kj::mv(client)), schema(Schema::from<FromClient<T>>()) {} + +template <typename T, typename> +inline DynamicCapability::Client::Client(kj::Own<T>&& server) + : Client(server->getSchema(), kj::mv(server)) {} +template <typename T> +inline DynamicCapability::Client::Client(InterfaceSchema schema, kj::Own<T>&& server) + : Capability::Client(kj::mv(server)), schema(schema) {} + +template <typename T, typename> +typename T::Client DynamicCapability::Client::as() { + static_assert(kind<T>() == Kind::INTERFACE, + "DynamicCapability::Client::as<T>() can only convert to interface types."); + schema.requireUsableAs<T>(); + return typename T::Client(hook->addRef()); +} + +template <typename T, typename> +typename T::Client DynamicCapability::Client::releaseAs() { + static_assert(kind<T>() == Kind::INTERFACE, + "DynamicCapability::Client::as<T>() can only convert to interface types."); + schema.requireUsableAs<T>(); + return typename T::Client(kj::mv(hook)); +} + +inline CallContext<DynamicStruct, DynamicStruct>::CallContext( + CallContextHook& hook, StructSchema paramType, StructSchema resultType) + : hook(&hook), paramType(paramType), resultType(resultType) {} +inline DynamicStruct::Reader CallContext<DynamicStruct, DynamicStruct>::getParams() { + return hook->getParams().getAs<DynamicStruct>(paramType); +} +inline void CallContext<DynamicStruct, DynamicStruct>::releaseParams() { + hook->releaseParams(); +} +inline DynamicStruct::Builder CallContext<DynamicStruct, DynamicStruct>::getResults( + kj::Maybe<MessageSize> sizeHint) { + return hook->getResults(sizeHint).getAs<DynamicStruct>(resultType); +} +inline DynamicStruct::Builder CallContext<DynamicStruct, DynamicStruct>::initResults( + kj::Maybe<MessageSize> sizeHint) { + return hook->getResults(sizeHint).initAs<DynamicStruct>(resultType); +} +inline void CallContext<DynamicStruct, DynamicStruct>::setResults(DynamicStruct::Reader value) { + hook->getResults(value.totalSize()).setAs<DynamicStruct>(value); +} +inline void CallContext<DynamicStruct, DynamicStruct>::adoptResults(Orphan<DynamicStruct>&& value) { + hook->getResults(MessageSize { 0, 0 }).adopt(kj::mv(value)); +} +inline Orphanage CallContext<DynamicStruct, DynamicStruct>::getResultsOrphanage( + kj::Maybe<MessageSize> sizeHint) { + return Orphanage::getForMessageContaining(hook->getResults(sizeHint)); +} +template <typename SubParams> +inline kj::Promise<void> CallContext<DynamicStruct, DynamicStruct>::tailCall( + Request<SubParams, DynamicStruct>&& tailRequest) { + return hook->tailCall(kj::mv(tailRequest.hook)); +} +inline void CallContext<DynamicStruct, DynamicStruct>::allowCancellation() { + hook->allowCancellation(); +} + +template <> +inline DynamicCapability::Client Capability::Client::castAs<DynamicCapability>( + InterfaceSchema schema) { + return DynamicCapability::Client(schema, hook->addRef()); +} + +// ------------------------------------------------------------------- + +template <typename T> +ReaderFor<T> ConstSchema::as() const { + return DynamicValue::Reader(*this).as<T>(); +} + +} // namespace capnp + +#endif // CAPNP_DYNAMIC_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/endian.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,309 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef CAPNP_ENDIAN_H_ +#define CAPNP_ENDIAN_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "common.h" +#include <inttypes.h> +#include <string.h> // memcpy + +namespace capnp { +namespace _ { // private + +// WireValue +// +// Wraps a primitive value as it appears on the wire. Namely, values are little-endian on the +// wire, because little-endian is the most common endianness in modern CPUs. +// +// Note: In general, code that depends cares about byte ordering is bad. See: +// http://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html +// Cap'n Proto is special because it is essentially doing compiler-like things, fussing over +// allocation and layout of memory, in order to squeeze out every last drop of performance. + +#if _MSC_VER +// Assume Windows is little-endian. +// +// TODO(msvc): This is ugly. Maybe refactor later checks to be based on CAPNP_BYTE_ORDER or +// CAPNP_SWAP_BYTES or something, and define that in turn based on _MSC_VER or the GCC +// intrinsics. + +#ifndef __ORDER_BIG_ENDIAN__ +#define __ORDER_BIG_ENDIAN__ 4321 +#endif +#ifndef __ORDER_LITTLE_ENDIAN__ +#define __ORDER_LITTLE_ENDIAN__ 1234 +#endif +#ifndef __BYTE_ORDER__ +#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ +#endif +#endif + +#if CAPNP_REVERSE_ENDIAN +#define CAPNP_WIRE_BYTE_ORDER __ORDER_BIG_ENDIAN__ +#define CAPNP_OPPOSITE_OF_WIRE_BYTE_ORDER __ORDER_LITTLE_ENDIAN__ +#else +#define CAPNP_WIRE_BYTE_ORDER __ORDER_LITTLE_ENDIAN__ +#define CAPNP_OPPOSITE_OF_WIRE_BYTE_ORDER __ORDER_BIG_ENDIAN__ +#endif + +#if defined(__BYTE_ORDER__) && \ + __BYTE_ORDER__ == CAPNP_WIRE_BYTE_ORDER && \ + !CAPNP_DISABLE_ENDIAN_DETECTION +// CPU is little-endian. We can just read/write the memory directly. + +template <typename T> +class DirectWireValue { +public: + KJ_ALWAYS_INLINE(T get() const) { return value; } + KJ_ALWAYS_INLINE(void set(T newValue)) { value = newValue; } + +private: + T value; +}; + +template <typename T> +using WireValue = DirectWireValue<T>; +// To prevent ODR problems when endian-test, endian-reverse-test, and endian-fallback-test are +// linked together, we define each implementation with a different name and define an alias to the +// one we want to use. + +#elif defined(__BYTE_ORDER__) && \ + __BYTE_ORDER__ == CAPNP_OPPOSITE_OF_WIRE_BYTE_ORDER && \ + defined(__GNUC__) && !CAPNP_DISABLE_ENDIAN_DETECTION +// Big-endian, but GCC's __builtin_bswap() is available. + +// TODO(perf): Use dedicated instructions to read little-endian data on big-endian CPUs that have +// them. + +// TODO(perf): Verify that this code optimizes reasonably. In particular, ensure that the +// compiler optimizes away the memcpy()s and keeps everything in registers. + +template <typename T, size_t size = sizeof(T)> +class SwappingWireValue; + +template <typename T> +class SwappingWireValue<T, 1> { +public: + KJ_ALWAYS_INLINE(T get() const) { return value; } + KJ_ALWAYS_INLINE(void set(T newValue)) { value = newValue; } + +private: + T value; +}; + +template <typename T> +class SwappingWireValue<T, 2> { +public: + KJ_ALWAYS_INLINE(T get() const) { + // Not all platforms have __builtin_bswap16() for some reason. In particular, it is missing + // on gcc-4.7.3-cygwin32 (but present on gcc-4.8.1-cygwin64). + uint16_t swapped = (value << 8) | (value >> 8); + T result; + memcpy(&result, &swapped, sizeof(T)); + return result; + } + KJ_ALWAYS_INLINE(void set(T newValue)) { + uint16_t raw; + memcpy(&raw, &newValue, sizeof(T)); + // Not all platforms have __builtin_bswap16() for some reason. In particular, it is missing + // on gcc-4.7.3-cygwin32 (but present on gcc-4.8.1-cygwin64). + value = (raw << 8) | (raw >> 8); + } + +private: + uint16_t value; +}; + +template <typename T> +class SwappingWireValue<T, 4> { +public: + KJ_ALWAYS_INLINE(T get() const) { + uint32_t swapped = __builtin_bswap32(value); + T result; + memcpy(&result, &swapped, sizeof(T)); + return result; + } + KJ_ALWAYS_INLINE(void set(T newValue)) { + uint32_t raw; + memcpy(&raw, &newValue, sizeof(T)); + value = __builtin_bswap32(raw); + } + +private: + uint32_t value; +}; + +template <typename T> +class SwappingWireValue<T, 8> { +public: + KJ_ALWAYS_INLINE(T get() const) { + uint64_t swapped = __builtin_bswap64(value); + T result; + memcpy(&result, &swapped, sizeof(T)); + return result; + } + KJ_ALWAYS_INLINE(void set(T newValue)) { + uint64_t raw; + memcpy(&raw, &newValue, sizeof(T)); + value = __builtin_bswap64(raw); + } + +private: + uint64_t value; +}; + +template <typename T> +using WireValue = SwappingWireValue<T>; +// To prevent ODR problems when endian-test, endian-reverse-test, and endian-fallback-test are +// linked together, we define each implementation with a different name and define an alias to the +// one we want to use. + +#else +// Unknown endianness. Fall back to bit shifts. + +#if !CAPNP_DISABLE_ENDIAN_DETECTION +#if _MSC_VER +#pragma message("Couldn't detect endianness of your platform. Using unoptimized fallback implementation.") +#pragma message("Consider changing this code to detect your platform and send us a patch!") +#else +#warning "Couldn't detect endianness of your platform. Using unoptimized fallback implementation." +#warning "Consider changing this code to detect your platform and send us a patch!" +#endif +#endif // !CAPNP_DISABLE_ENDIAN_DETECTION + +template <typename T, size_t size = sizeof(T)> +class ShiftingWireValue; + +template <typename T> +class ShiftingWireValue<T, 1> { +public: + KJ_ALWAYS_INLINE(T get() const) { return value; } + KJ_ALWAYS_INLINE(void set(T newValue)) { value = newValue; } + +private: + T value; +}; + +template <typename T> +class ShiftingWireValue<T, 2> { +public: + KJ_ALWAYS_INLINE(T get() const) { + uint16_t raw = (static_cast<uint16_t>(bytes[0]) ) | + (static_cast<uint16_t>(bytes[1]) << 8); + T result; + memcpy(&result, &raw, sizeof(T)); + return result; + } + KJ_ALWAYS_INLINE(void set(T newValue)) { + uint16_t raw; + memcpy(&raw, &newValue, sizeof(T)); + bytes[0] = raw; + bytes[1] = raw >> 8; + } + +private: + union { + byte bytes[2]; + uint16_t align; + }; +}; + +template <typename T> +class ShiftingWireValue<T, 4> { +public: + KJ_ALWAYS_INLINE(T get() const) { + uint32_t raw = (static_cast<uint32_t>(bytes[0]) ) | + (static_cast<uint32_t>(bytes[1]) << 8) | + (static_cast<uint32_t>(bytes[2]) << 16) | + (static_cast<uint32_t>(bytes[3]) << 24); + T result; + memcpy(&result, &raw, sizeof(T)); + return result; + } + KJ_ALWAYS_INLINE(void set(T newValue)) { + uint32_t raw; + memcpy(&raw, &newValue, sizeof(T)); + bytes[0] = raw; + bytes[1] = raw >> 8; + bytes[2] = raw >> 16; + bytes[3] = raw >> 24; + } + +private: + union { + byte bytes[4]; + uint32_t align; + }; +}; + +template <typename T> +class ShiftingWireValue<T, 8> { +public: + KJ_ALWAYS_INLINE(T get() const) { + uint64_t raw = (static_cast<uint64_t>(bytes[0]) ) | + (static_cast<uint64_t>(bytes[1]) << 8) | + (static_cast<uint64_t>(bytes[2]) << 16) | + (static_cast<uint64_t>(bytes[3]) << 24) | + (static_cast<uint64_t>(bytes[4]) << 32) | + (static_cast<uint64_t>(bytes[5]) << 40) | + (static_cast<uint64_t>(bytes[6]) << 48) | + (static_cast<uint64_t>(bytes[7]) << 56); + T result; + memcpy(&result, &raw, sizeof(T)); + return result; + } + KJ_ALWAYS_INLINE(void set(T newValue)) { + uint64_t raw; + memcpy(&raw, &newValue, sizeof(T)); + bytes[0] = raw; + bytes[1] = raw >> 8; + bytes[2] = raw >> 16; + bytes[3] = raw >> 24; + bytes[4] = raw >> 32; + bytes[5] = raw >> 40; + bytes[6] = raw >> 48; + bytes[7] = raw >> 56; + } + +private: + union { + byte bytes[8]; + uint64_t align; + }; +}; + +template <typename T> +using WireValue = ShiftingWireValue<T>; +// To prevent ODR problems when endian-test, endian-reverse-test, and endian-fallback-test are +// linked together, we define each implementation with a different name and define an alias to the +// one we want to use. + +#endif + +} // namespace _ (private) +} // namespace capnp + +#endif // CAPNP_ENDIAN_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/ez-rpc.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,254 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef CAPNP_EZ_RPC_H_ +#define CAPNP_EZ_RPC_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "rpc.h" +#include "message.h" + +struct sockaddr; + +namespace kj { class AsyncIoProvider; class LowLevelAsyncIoProvider; } + +namespace capnp { + +class EzRpcContext; + +class EzRpcClient { + // Super-simple interface for setting up a Cap'n Proto RPC client. Example: + // + // # Cap'n Proto schema + // interface Adder { + // add @0 (left :Int32, right :Int32) -> (value :Int32); + // } + // + // // C++ client + // int main() { + // capnp::EzRpcClient client("localhost:3456"); + // Adder::Client adder = client.getMain<Adder>(); + // auto request = adder.addRequest(); + // request.setLeft(12); + // request.setRight(34); + // auto response = request.send().wait(client.getWaitScope()); + // assert(response.getValue() == 46); + // return 0; + // } + // + // // C++ server + // class AdderImpl final: public Adder::Server { + // public: + // kj::Promise<void> add(AddContext context) override { + // auto params = context.getParams(); + // context.getResults().setValue(params.getLeft() + params.getRight()); + // return kj::READY_NOW; + // } + // }; + // + // int main() { + // capnp::EzRpcServer server(kj::heap<AdderImpl>(), "*:3456"); + // kj::NEVER_DONE.wait(server.getWaitScope()); + // } + // + // This interface is easy, but it hides a lot of useful features available from the lower-level + // classes: + // - The server can only export a small set of public, singleton capabilities under well-known + // string names. This is fine for transient services where no state needs to be kept between + // connections, but hides the power of Cap'n Proto when it comes to long-lived resources. + // - EzRpcClient/EzRpcServer automatically set up a `kj::EventLoop` and make it current for the + // thread. Only one `kj::EventLoop` can exist per thread, so you cannot use these interfaces + // if you wish to set up your own event loop. (However, you can safely create multiple + // EzRpcClient / EzRpcServer objects in a single thread; they will make sure to make no more + // than one EventLoop.) + // - These classes only support simple two-party connections, not multilateral VatNetworks. + // - These classes only support communication over a raw, unencrypted socket. If you want to + // build on an abstract stream (perhaps one which supports encryption), you must use the + // lower-level interfaces. + // + // Some of these restrictions will probably be lifted in future versions, but some things will + // always require using the low-level interfaces directly. If you are interested in working + // at a lower level, start by looking at these interfaces: + // - `kj::setupAsyncIo()` in `kj/async-io.h`. + // - `RpcSystem` in `capnp/rpc.h`. + // - `TwoPartyVatNetwork` in `capnp/rpc-twoparty.h`. + +public: + explicit EzRpcClient(kj::StringPtr serverAddress, uint defaultPort = 0, + ReaderOptions readerOpts = ReaderOptions()); + // Construct a new EzRpcClient and connect to the given address. The connection is formed in + // the background -- if it fails, calls to capabilities returned by importCap() will fail with an + // appropriate exception. + // + // `defaultPort` is the IP port number to use if `serverAddress` does not include it explicitly. + // If unspecified, the port is required in `serverAddress`. + // + // The address is parsed by `kj::Network` in `kj/async-io.h`. See that interface for more info + // on the address format, but basically it's what you'd expect. + // + // `readerOpts` is the ReaderOptions structure used to read each incoming message on the + // connection. Setting this may be necessary if you need to receive very large individual + // messages or messages. However, it is recommended that you instead think about how to change + // your protocol to send large data blobs in multiple small chunks -- this is much better for + // both security and performance. See `ReaderOptions` in `message.h` for more details. + + EzRpcClient(const struct sockaddr* serverAddress, uint addrSize, + ReaderOptions readerOpts = ReaderOptions()); + // Like the above constructor, but connects to an already-resolved socket address. Any address + // format supported by `kj::Network` in `kj/async-io.h` is accepted. + + explicit EzRpcClient(int socketFd, ReaderOptions readerOpts = ReaderOptions()); + // Create a client on top of an already-connected socket. + // `readerOpts` acts as in the first constructor. + + ~EzRpcClient() noexcept(false); + + template <typename Type> + typename Type::Client getMain(); + Capability::Client getMain(); + // Get the server's main (aka "bootstrap") interface. + + template <typename Type> + typename Type::Client importCap(kj::StringPtr name) + KJ_DEPRECATED("Change your server to export a main interface, then use getMain() instead."); + Capability::Client importCap(kj::StringPtr name) + KJ_DEPRECATED("Change your server to export a main interface, then use getMain() instead."); + // ** DEPRECATED ** + // + // Ask the sever for the capability with the given name. You may specify a type to automatically + // down-cast to that type. It is up to you to specify the correct expected type. + // + // Named interfaces are deprecated. The new preferred usage pattern is for the server to export + // a "main" interface which itself has methods for getting any other interfaces. + + kj::WaitScope& getWaitScope(); + // Get the `WaitScope` for the client's `EventLoop`, which allows you to synchronously wait on + // promises. + + kj::AsyncIoProvider& getIoProvider(); + // Get the underlying AsyncIoProvider set up by the RPC system. This is useful if you want + // to do some non-RPC I/O in asynchronous fashion. + + kj::LowLevelAsyncIoProvider& getLowLevelIoProvider(); + // Get the underlying LowLevelAsyncIoProvider set up by the RPC system. This is useful if you + // want to do some non-RPC I/O in asynchronous fashion. + +private: + struct Impl; + kj::Own<Impl> impl; +}; + +class EzRpcServer { + // The server counterpart to `EzRpcClient`. See `EzRpcClient` for an example. + +public: + explicit EzRpcServer(Capability::Client mainInterface, kj::StringPtr bindAddress, + uint defaultPort = 0, ReaderOptions readerOpts = ReaderOptions()); + // Construct a new `EzRpcServer` that binds to the given address. An address of "*" means to + // bind to all local addresses. + // + // `defaultPort` is the IP port number to use if `serverAddress` does not include it explicitly. + // If unspecified, a port is chosen automatically, and you must call getPort() to find out what + // it is. + // + // The address is parsed by `kj::Network` in `kj/async-io.h`. See that interface for more info + // on the address format, but basically it's what you'd expect. + // + // The server might not begin listening immediately, especially if `bindAddress` needs to be + // resolved. If you need to wait until the server is definitely up, wait on the promise returned + // by `getPort()`. + // + // `readerOpts` is the ReaderOptions structure used to read each incoming message on the + // connection. Setting this may be necessary if you need to receive very large individual + // messages or messages. However, it is recommended that you instead think about how to change + // your protocol to send large data blobs in multiple small chunks -- this is much better for + // both security and performance. See `ReaderOptions` in `message.h` for more details. + + EzRpcServer(Capability::Client mainInterface, struct sockaddr* bindAddress, uint addrSize, + ReaderOptions readerOpts = ReaderOptions()); + // Like the above constructor, but binds to an already-resolved socket address. Any address + // format supported by `kj::Network` in `kj/async-io.h` is accepted. + + EzRpcServer(Capability::Client mainInterface, int socketFd, uint port, + ReaderOptions readerOpts = ReaderOptions()); + // Create a server on top of an already-listening socket (i.e. one on which accept() may be + // called). `port` is returned by `getPort()` -- it serves no other purpose. + // `readerOpts` acts as in the other two above constructors. + + explicit EzRpcServer(kj::StringPtr bindAddress, uint defaultPort = 0, + ReaderOptions readerOpts = ReaderOptions()) + KJ_DEPRECATED("Please specify a main interface for your server."); + EzRpcServer(struct sockaddr* bindAddress, uint addrSize, + ReaderOptions readerOpts = ReaderOptions()) + KJ_DEPRECATED("Please specify a main interface for your server."); + EzRpcServer(int socketFd, uint port, ReaderOptions readerOpts = ReaderOptions()) + KJ_DEPRECATED("Please specify a main interface for your server."); + + ~EzRpcServer() noexcept(false); + + void exportCap(kj::StringPtr name, Capability::Client cap); + // Export a capability publicly under the given name, so that clients can import it. + // + // Keep in mind that you can implicitly convert `kj::Own<MyType::Server>&&` to + // `Capability::Client`, so it's typical to pass something like + // `kj::heap<MyImplementation>(<constructor params>)` as the second parameter. + + kj::Promise<uint> getPort(); + // Get the IP port number on which this server is listening. This promise won't resolve until + // the server is actually listening. If the address was not an IP address (e.g. it was a Unix + // domain socket) then getPort() resolves to zero. + + kj::WaitScope& getWaitScope(); + // Get the `WaitScope` for the client's `EventLoop`, which allows you to synchronously wait on + // promises. + + kj::AsyncIoProvider& getIoProvider(); + // Get the underlying AsyncIoProvider set up by the RPC system. This is useful if you want + // to do some non-RPC I/O in asynchronous fashion. + + kj::LowLevelAsyncIoProvider& getLowLevelIoProvider(); + // Get the underlying LowLevelAsyncIoProvider set up by the RPC system. This is useful if you + // want to do some non-RPC I/O in asynchronous fashion. + +private: + struct Impl; + kj::Own<Impl> impl; +}; + +// ======================================================================================= +// inline implementation details + +template <typename Type> +inline typename Type::Client EzRpcClient::getMain() { + return getMain().castAs<Type>(); +} + +template <typename Type> +inline typename Type::Client EzRpcClient::importCap(kj::StringPtr name) { + return importCap(name).castAs<Type>(); +} + +} // namespace capnp + +#endif // CAPNP_EZ_RPC_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/generated-header-support.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,585 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// This file is included form all generated headers. + +#ifndef CAPNP_GENERATED_HEADER_SUPPORT_H_ +#define CAPNP_GENERATED_HEADER_SUPPORT_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "layout.h" +#include "list.h" +#include "orphan.h" +#include "pointer-helpers.h" +#include "any.h" +#include <kj/string.h> +#include <kj/string-tree.h> + +namespace capnp { + +class MessageBuilder; // So that it can be declared a friend. + +template <typename T, Kind k = CAPNP_KIND(T)> +struct ToDynamic_; // Defined in dynamic.h, needs to be declared as everyone's friend. + +struct DynamicStruct; // So that it can be declared a friend. + +struct Capability; // To declare brandBindingFor<Capability>() + +namespace _ { // private + +#if !CAPNP_LITE + +struct RawSchema; + +struct RawBrandedSchema { + // Represents a combination of a schema and bindings for its generic parameters. + // + // Note that while we generate one `RawSchema` per type, we generate a `RawBrandedSchema` for + // every _instance_ of a generic type -- or, at least, every instance that is actually used. For + // generated-code types, we use template magic to initialize these. + + const RawSchema* generic; + // Generic type which we're branding. + + struct Binding { + uint8_t which; // Numeric value of one of schema::Type::Which. + + bool isImplicitParameter; + // For AnyPointer, true if it's an implicit method parameter. + + uint16_t listDepth; // Number of times to wrap the base type in List(). + + uint16_t paramIndex; + // For AnyPointer. If it's a type parameter (scopeId is non-zero) or it's an implicit parameter + // (isImplicitParameter is true), then this is the parameter index. Otherwise this is a numeric + // value of one of schema::Type::AnyPointer::Unconstrained::Which. + + union { + const RawBrandedSchema* schema; // for struct, enum, interface + uint64_t scopeId; // for AnyPointer, if it's a type parameter + }; + + Binding() = default; + inline constexpr Binding(uint8_t which, uint16_t listDepth, const RawBrandedSchema* schema) + : which(which), isImplicitParameter(false), listDepth(listDepth), paramIndex(0), + schema(schema) {} + inline constexpr Binding(uint8_t which, uint16_t listDepth, + uint64_t scopeId, uint16_t paramIndex) + : which(which), isImplicitParameter(false), listDepth(listDepth), paramIndex(paramIndex), + scopeId(scopeId) {} + inline constexpr Binding(uint8_t which, uint16_t listDepth, uint16_t implicitParamIndex) + : which(which), isImplicitParameter(true), listDepth(listDepth), + paramIndex(implicitParamIndex), scopeId(0) {} + }; + + struct Scope { + uint64_t typeId; + // Type ID whose parameters are being bound. + + const Binding* bindings; + uint bindingCount; + // Bindings for those parameters. + + bool isUnbound; + // This scope is unbound, in the sense of SchemaLoader::getUnbound(). + }; + + const Scope* scopes; + // Array of enclosing scopes for which generic variables have been bound, sorted by type ID. + + struct Dependency { + uint location; + const RawBrandedSchema* schema; + }; + + const Dependency* dependencies; + // Map of branded schemas for dependencies of this type, given our brand. Only dependencies that + // are branded are included in this map; if a dependency is missing, use its `defaultBrand`. + + uint32_t scopeCount; + uint32_t dependencyCount; + + enum class DepKind { + // Component of a Dependency::location. Specifies what sort of dependency this is. + + INVALID, + // Mostly defined to ensure that zero is not a valid location. + + FIELD, + // Binding needed for a field's type. The index is the field index (NOT ordinal!). + + METHOD_PARAMS, + // Bindings needed for a method's params type. The index is the method number. + + METHOD_RESULTS, + // Bindings needed for a method's results type. The index is the method ordinal. + + SUPERCLASS, + // Bindings needed for a superclass type. The index is the superclass's index in the + // "extends" list. + + CONST_TYPE + // Bindings needed for the type of a constant. The index is zero. + }; + + static inline uint makeDepLocation(DepKind kind, uint index) { + // Make a number representing the location of a particular dependency within its parent + // schema. + + return (static_cast<uint>(kind) << 24) | index; + } + + class Initializer { + public: + virtual void init(const RawBrandedSchema* generic) const = 0; + }; + + const Initializer* lazyInitializer; + // Lazy initializer, invoked by ensureInitialized(). + + inline void ensureInitialized() const { + // Lazy initialization support. Invoke to ensure that initialization has taken place. This + // is required in particular when traversing the dependency list. RawSchemas for compiled-in + // types are always initialized; only dynamically-loaded schemas may be lazy. + + const Initializer* i = __atomic_load_n(&lazyInitializer, __ATOMIC_ACQUIRE); + if (i != nullptr) i->init(this); + } + + inline bool isUnbound() const; + // Checks if this schema is the result of calling SchemaLoader::getUnbound(), in which case + // binding lookups need to be handled specially. +}; + +struct RawSchema { + // The generated code defines a constant RawSchema for every compiled declaration. + // + // This is an internal structure which could change in the future. + + uint64_t id; + + const word* encodedNode; + // Encoded SchemaNode, readable via readMessageUnchecked<schema::Node>(encodedNode). + + uint32_t encodedSize; + // Size of encodedNode, in words. + + const RawSchema* const* dependencies; + // Pointers to other types on which this one depends, sorted by ID. The schemas in this table + // may be uninitialized -- you must call ensureInitialized() on the one you wish to use before + // using it. + // + // TODO(someday): Make this a hashtable. + + const uint16_t* membersByName; + // Indexes of members sorted by name. Used to implement name lookup. + // TODO(someday): Make this a hashtable. + + uint32_t dependencyCount; + uint32_t memberCount; + // Sizes of above tables. + + const uint16_t* membersByDiscriminant; + // List of all member indexes ordered by discriminant value. Those which don't have a + // discriminant value are listed at the end, in order by ordinal. + + const RawSchema* canCastTo; + // Points to the RawSchema of a compiled-in type to which it is safe to cast any DynamicValue + // with this schema. This is null for all compiled-in types; it is only set by SchemaLoader on + // dynamically-loaded types. + + class Initializer { + public: + virtual void init(const RawSchema* schema) const = 0; + }; + + const Initializer* lazyInitializer; + // Lazy initializer, invoked by ensureInitialized(). + + inline void ensureInitialized() const { + // Lazy initialization support. Invoke to ensure that initialization has taken place. This + // is required in particular when traversing the dependency list. RawSchemas for compiled-in + // types are always initialized; only dynamically-loaded schemas may be lazy. + + const Initializer* i = __atomic_load_n(&lazyInitializer, __ATOMIC_ACQUIRE); + if (i != nullptr) i->init(this); + } + + RawBrandedSchema defaultBrand; + // Specifies the brand to use for this schema if no generic parameters have been bound to + // anything. Generally, in the default brand, all generic parameters are treated as if they were + // bound to `AnyPointer`. +}; + +inline bool RawBrandedSchema::isUnbound() const { + // The unbound schema is the only one that has no scopes but is not the default schema. + return scopeCount == 0 && this != &generic->defaultBrand; +} + +template <typename T, typename CapnpPrivate = typename T::_capnpPrivate, bool = false> +inline const RawSchema& rawSchema() { + return *CapnpPrivate::schema; +} +template <typename T, uint64_t id = schemas::EnumInfo<T>::typeId> +inline const RawSchema& rawSchema() { + return *schemas::EnumInfo<T>::schema; +} + +template <typename T, typename CapnpPrivate = typename T::_capnpPrivate> +inline const RawBrandedSchema& rawBrandedSchema() { + return *CapnpPrivate::brand; +} +template <typename T, uint64_t id = schemas::EnumInfo<T>::typeId> +inline const RawBrandedSchema& rawBrandedSchema() { + return schemas::EnumInfo<T>::schema->defaultBrand; +} + +template <typename TypeTag, typename... Params> +struct ChooseBrand; +// If all of `Params` are `AnyPointer`, return the type's default brand. Otherwise, return a +// specific brand instance. TypeTag is the _capnpPrivate struct for the type in question. + +template <typename TypeTag> +struct ChooseBrand<TypeTag> { + // All params were AnyPointer. No specific brand needed. + static constexpr _::RawBrandedSchema const* brand = &TypeTag::schema->defaultBrand; +}; + +template <typename TypeTag, typename... Rest> +struct ChooseBrand<TypeTag, AnyPointer, Rest...>: public ChooseBrand<TypeTag, Rest...> {}; +// The first parameter is AnyPointer, so recurse to check the rest. + +template <typename TypeTag, typename First, typename... Rest> +struct ChooseBrand<TypeTag, First, Rest...> { + // At least one parameter is not AnyPointer, so use the specificBrand constant. + static constexpr _::RawBrandedSchema const* brand = &TypeTag::specificBrand; +}; + +template <typename T, Kind k = kind<T>()> +struct BrandBindingFor_; + +#define HANDLE_TYPE(Type, which) \ + template <> \ + struct BrandBindingFor_<Type, Kind::PRIMITIVE> { \ + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { \ + return { which, listDepth, nullptr }; \ + } \ + } +HANDLE_TYPE(Void, 0); +HANDLE_TYPE(bool, 1); +HANDLE_TYPE(int8_t, 2); +HANDLE_TYPE(int16_t, 3); +HANDLE_TYPE(int32_t, 4); +HANDLE_TYPE(int64_t, 5); +HANDLE_TYPE(uint8_t, 6); +HANDLE_TYPE(uint16_t, 7); +HANDLE_TYPE(uint32_t, 8); +HANDLE_TYPE(uint64_t, 9); +HANDLE_TYPE(float, 10); +HANDLE_TYPE(double, 11); +#undef HANDLE_TYPE + +template <> +struct BrandBindingFor_<Text, Kind::BLOB> { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return { 12, listDepth, nullptr }; + } +}; + +template <> +struct BrandBindingFor_<Data, Kind::BLOB> { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return { 13, listDepth, nullptr }; + } +}; + +template <typename T> +struct BrandBindingFor_<List<T>, Kind::LIST> { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return BrandBindingFor_<T>::get(listDepth + 1); + } +}; + +template <typename T> +struct BrandBindingFor_<T, Kind::ENUM> { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return { 15, listDepth, nullptr }; + } +}; + +template <typename T> +struct BrandBindingFor_<T, Kind::STRUCT> { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return { 16, listDepth, T::_capnpPrivate::brand }; + } +}; + +template <typename T> +struct BrandBindingFor_<T, Kind::INTERFACE> { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return { 17, listDepth, T::_capnpPrivate::brand }; + } +}; + +template <> +struct BrandBindingFor_<AnyPointer, Kind::OTHER> { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return { 18, listDepth, 0, 0 }; + } +}; + +template <> +struct BrandBindingFor_<AnyStruct, Kind::OTHER> { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return { 18, listDepth, 0, 1 }; + } +}; + +template <> +struct BrandBindingFor_<AnyList, Kind::OTHER> { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return { 18, listDepth, 0, 2 }; + } +}; + +template <> +struct BrandBindingFor_<Capability, Kind::OTHER> { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return { 18, listDepth, 0, 3 }; + } +}; + +template <typename T> +constexpr RawBrandedSchema::Binding brandBindingFor() { + return BrandBindingFor_<T>::get(0); +} + +kj::StringTree structString(StructReader reader, const RawBrandedSchema& schema); +kj::String enumString(uint16_t value, const RawBrandedSchema& schema); +// Declared here so that we can declare inline stringify methods on generated types. +// Defined in stringify.c++, which depends on dynamic.c++, which is allowed not to be linked in. + +template <typename T> +inline kj::StringTree structString(StructReader reader) { + return structString(reader, rawBrandedSchema<T>()); +} +template <typename T> +inline kj::String enumString(T value) { + return enumString(static_cast<uint16_t>(value), rawBrandedSchema<T>()); +} + +#endif // !CAPNP_LITE + +// TODO(cleanup): Unify ConstStruct and ConstList. +template <typename T> +class ConstStruct { +public: + ConstStruct() = delete; + KJ_DISALLOW_COPY(ConstStruct); + inline explicit constexpr ConstStruct(const word* ptr): ptr(ptr) {} + + inline typename T::Reader get() const { + return AnyPointer::Reader(PointerReader::getRootUnchecked(ptr)).getAs<T>(); + } + + inline operator typename T::Reader() const { return get(); } + inline typename T::Reader operator*() const { return get(); } + inline TemporaryPointer<typename T::Reader> operator->() const { return get(); } + +private: + const word* ptr; +}; + +template <typename T> +class ConstList { +public: + ConstList() = delete; + KJ_DISALLOW_COPY(ConstList); + inline explicit constexpr ConstList(const word* ptr): ptr(ptr) {} + + inline typename List<T>::Reader get() const { + return AnyPointer::Reader(PointerReader::getRootUnchecked(ptr)).getAs<List<T>>(); + } + + inline operator typename List<T>::Reader() const { return get(); } + inline typename List<T>::Reader operator*() const { return get(); } + inline TemporaryPointer<typename List<T>::Reader> operator->() const { return get(); } + +private: + const word* ptr; +}; + +template <size_t size> +class ConstText { +public: + ConstText() = delete; + KJ_DISALLOW_COPY(ConstText); + inline explicit constexpr ConstText(const word* ptr): ptr(ptr) {} + + inline Text::Reader get() const { + return Text::Reader(reinterpret_cast<const char*>(ptr), size); + } + + inline operator Text::Reader() const { return get(); } + inline Text::Reader operator*() const { return get(); } + inline TemporaryPointer<Text::Reader> operator->() const { return get(); } + + inline kj::StringPtr toString() const { + return get(); + } + +private: + const word* ptr; +}; + +template <size_t size> +inline kj::StringPtr KJ_STRINGIFY(const ConstText<size>& s) { + return s.get(); +} + +template <size_t size> +class ConstData { +public: + ConstData() = delete; + KJ_DISALLOW_COPY(ConstData); + inline explicit constexpr ConstData(const word* ptr): ptr(ptr) {} + + inline Data::Reader get() const { + return Data::Reader(reinterpret_cast<const byte*>(ptr), size); + } + + inline operator Data::Reader() const { return get(); } + inline Data::Reader operator*() const { return get(); } + inline TemporaryPointer<Data::Reader> operator->() const { return get(); } + +private: + const word* ptr; +}; + +template <size_t size> +inline auto KJ_STRINGIFY(const ConstData<size>& s) -> decltype(kj::toCharSequence(s.get())) { + return kj::toCharSequence(s.get()); +} + +} // namespace _ (private) + +template <typename T, typename CapnpPrivate = typename T::_capnpPrivate> +inline constexpr uint64_t typeId() { return CapnpPrivate::typeId; } +template <typename T, uint64_t id = schemas::EnumInfo<T>::typeId> +inline constexpr uint64_t typeId() { return id; } +// typeId<MyType>() returns the type ID as defined in the schema. Works with structs, enums, and +// interfaces. + +template <typename T> +inline constexpr uint sizeInWords() { + // Return the size, in words, of a Struct type, if allocated free-standing (not in a list). + // May be useful for pre-computing space needed in order to precisely allocate messages. + + return (WordCount32(_::structSize<T>().data) + + _::structSize<T>().pointers * WORDS_PER_POINTER) / WORDS; +} + +} // namespace capnp + +#if _MSC_VER +// MSVC doesn't understand floating-point constexpr yet. +// +// TODO(msvc): Remove this hack when MSVC is fixed. +#define CAPNP_NON_INT_CONSTEXPR_DECL_INIT(value) +#define CAPNP_NON_INT_CONSTEXPR_DEF_INIT(value) = value +#else +#define CAPNP_NON_INT_CONSTEXPR_DECL_INIT(value) = value +#define CAPNP_NON_INT_CONSTEXPR_DEF_INIT(value) +#endif + +#if CAPNP_LITE + +#define CAPNP_DECLARE_SCHEMA(id) \ + extern ::capnp::word const* const bp_##id + +#define CAPNP_DECLARE_ENUM(type, id) \ + inline ::kj::String KJ_STRINGIFY(type##_##id value) { \ + return ::kj::str(static_cast<uint16_t>(value)); \ + } \ + template <> struct EnumInfo<type##_##id> { \ + struct IsEnum; \ + static constexpr uint64_t typeId = 0x##id; \ + static inline ::capnp::word const* encodedSchema() { return bp_##id; } \ + } + +#if _MSC_VER +// TODO(msvc): MSVC dosen't expect constexprs to have definitions. +#define CAPNP_DEFINE_ENUM(type, id) +#else +#define CAPNP_DEFINE_ENUM(type, id) \ + constexpr uint64_t EnumInfo<type>::typeId +#endif + +#define CAPNP_DECLARE_STRUCT_HEADER(id, dataWordSize_, pointerCount_) \ + struct IsStruct; \ + static constexpr uint64_t typeId = 0x##id; \ + static constexpr uint16_t dataWordSize = dataWordSize_; \ + static constexpr uint16_t pointerCount = pointerCount_; \ + static inline ::capnp::word const* encodedSchema() { return ::capnp::schemas::bp_##id; } + +#else // CAPNP_LITE + +#define CAPNP_DECLARE_SCHEMA(id) \ + extern ::capnp::word const* const bp_##id; \ + extern const ::capnp::_::RawSchema s_##id + +#define CAPNP_DECLARE_ENUM(type, id) \ + inline ::kj::String KJ_STRINGIFY(type##_##id value) { \ + return ::capnp::_::enumString(value); \ + } \ + template <> struct EnumInfo<type##_##id> { \ + struct IsEnum; \ + static constexpr uint64_t typeId = 0x##id; \ + static inline ::capnp::word const* encodedSchema() { return bp_##id; } \ + static constexpr ::capnp::_::RawSchema const* schema = &s_##id; \ + } +#define CAPNP_DEFINE_ENUM(type, id) \ + constexpr uint64_t EnumInfo<type>::typeId; \ + constexpr ::capnp::_::RawSchema const* EnumInfo<type>::schema + +#define CAPNP_DECLARE_STRUCT_HEADER(id, dataWordSize_, pointerCount_) \ + struct IsStruct; \ + static constexpr uint64_t typeId = 0x##id; \ + static constexpr ::capnp::Kind kind = ::capnp::Kind::STRUCT; \ + static constexpr uint16_t dataWordSize = dataWordSize_; \ + static constexpr uint16_t pointerCount = pointerCount_; \ + static inline ::capnp::word const* encodedSchema() { return ::capnp::schemas::bp_##id; } \ + static constexpr ::capnp::_::RawSchema const* schema = &::capnp::schemas::s_##id; + +#define CAPNP_DECLARE_INTERFACE_HEADER(id) \ + struct IsInterface; \ + static constexpr uint64_t typeId = 0x##id; \ + static constexpr ::capnp::Kind kind = ::capnp::Kind::INTERFACE; \ + static inline ::capnp::word const* encodedSchema() { return ::capnp::schemas::bp_##id; } \ + static constexpr ::capnp::_::RawSchema const* schema = &::capnp::schemas::s_##id; + +#endif // CAPNP_LITE, else + +#endif // CAPNP_GENERATED_HEADER_SUPPORT_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/layout.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,1225 @@ +// Copyright (c) 2013-2016 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// This file is NOT intended for use by clients, except in generated code. +// +// This file defines low-level, non-type-safe classes for traversing the Cap'n Proto memory layout +// (which is also its wire format). Code generated by the Cap'n Proto compiler uses these classes, +// as does other parts of the Cap'n proto library which provide a higher-level interface for +// dynamic introspection. + +#ifndef CAPNP_LAYOUT_H_ +#define CAPNP_LAYOUT_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include <kj/common.h> +#include <kj/memory.h> +#include "common.h" +#include "blob.h" +#include "endian.h" + +#if (defined(__mips__) || defined(__hppa__)) && !defined(CAPNP_CANONICALIZE_NAN) +#define CAPNP_CANONICALIZE_NAN 1 +// Explicitly detect NaNs and canonicalize them to the quiet NaN value as would be returned by +// __builtin_nan("") on systems implementing the IEEE-754 recommended (but not required) NaN +// signalling/quiet differentiation (such as x86). Unfortunately, some architectures -- in +// particular, MIPS -- represent quiet vs. signalling nans differently than the rest of the world. +// Canonicalizing them makes output consistent (which is important!), but hurts performance +// slightly. +// +// Note that trying to convert MIPS NaNs to standard NaNs without losing data doesn't work. +// Signaling vs. quiet is indicated by a bit, with the meaning being the opposite on MIPS vs. +// everyone else. It would be great if we could just flip that bit, but we can't, because if the +// significand is all-zero, then the value is infinity rather than NaN. This means that on most +// machines, where the bit indicates quietness, there is one more quiet NaN value than signalling +// NaN value, whereas on MIPS there is one more sNaN than qNaN, and thus there is no isomorphic +// mapping that properly preserves quietness. Instead of doing something hacky, we just give up +// and blow away NaN payloads, because no one uses them anyway. +#endif + +namespace capnp { + +#if !CAPNP_LITE +class ClientHook; +#endif // !CAPNP_LITE + +namespace _ { // private + +class PointerBuilder; +class PointerReader; +class StructBuilder; +class StructReader; +class ListBuilder; +class ListReader; +class OrphanBuilder; +struct WirePointer; +struct WireHelpers; +class SegmentReader; +class SegmentBuilder; +class Arena; +class BuilderArena; + +// ============================================================================= + +typedef decltype(BITS / ELEMENTS) BitsPerElement; +typedef decltype(POINTERS / ELEMENTS) PointersPerElement; + +static constexpr BitsPerElement BITS_PER_ELEMENT_TABLE[8] = { + 0 * BITS / ELEMENTS, + 1 * BITS / ELEMENTS, + 8 * BITS / ELEMENTS, + 16 * BITS / ELEMENTS, + 32 * BITS / ELEMENTS, + 64 * BITS / ELEMENTS, + 0 * BITS / ELEMENTS, + 0 * BITS / ELEMENTS +}; + +inline KJ_CONSTEXPR() BitsPerElement dataBitsPerElement(ElementSize size) { + return _::BITS_PER_ELEMENT_TABLE[static_cast<int>(size)]; +} + +inline constexpr PointersPerElement pointersPerElement(ElementSize size) { + return size == ElementSize::POINTER ? 1 * POINTERS / ELEMENTS : 0 * POINTERS / ELEMENTS; +} + +template <size_t size> struct ElementSizeForByteSize; +template <> struct ElementSizeForByteSize<1> { static constexpr ElementSize value = ElementSize::BYTE; }; +template <> struct ElementSizeForByteSize<2> { static constexpr ElementSize value = ElementSize::TWO_BYTES; }; +template <> struct ElementSizeForByteSize<4> { static constexpr ElementSize value = ElementSize::FOUR_BYTES; }; +template <> struct ElementSizeForByteSize<8> { static constexpr ElementSize value = ElementSize::EIGHT_BYTES; }; + +template <typename T> struct ElementSizeForType { + static constexpr ElementSize value = + // Primitive types that aren't special-cased below can be determined from sizeof(). + CAPNP_KIND(T) == Kind::PRIMITIVE ? ElementSizeForByteSize<sizeof(T)>::value : + CAPNP_KIND(T) == Kind::ENUM ? ElementSize::TWO_BYTES : + CAPNP_KIND(T) == Kind::STRUCT ? ElementSize::INLINE_COMPOSITE : + + // Everything else is a pointer. + ElementSize::POINTER; +}; + +// Void and bool are special. +template <> struct ElementSizeForType<Void> { static constexpr ElementSize value = ElementSize::VOID; }; +template <> struct ElementSizeForType<bool> { static constexpr ElementSize value = ElementSize::BIT; }; + +// Lists and blobs are pointers, not structs. +template <typename T, bool b> struct ElementSizeForType<List<T, b>> { + static constexpr ElementSize value = ElementSize::POINTER; +}; +template <> struct ElementSizeForType<Text> { + static constexpr ElementSize value = ElementSize::POINTER; +}; +template <> struct ElementSizeForType<Data> { + static constexpr ElementSize value = ElementSize::POINTER; +}; + +template <typename T> +inline constexpr ElementSize elementSizeForType() { + return ElementSizeForType<T>::value; +} + +struct MessageSizeCounts { + WordCount64 wordCount; + uint capCount; + + MessageSizeCounts& operator+=(const MessageSizeCounts& other) { + wordCount += other.wordCount; + capCount += other.capCount; + return *this; + } + + MessageSize asPublic() { + return MessageSize { wordCount / WORDS, capCount }; + } +}; + +// ============================================================================= + +template <int wordCount> +union AlignedData { + // Useful for declaring static constant data blobs as an array of bytes, but forcing those + // bytes to be word-aligned. + + uint8_t bytes[wordCount * sizeof(word)]; + word words[wordCount]; +}; + +struct StructSize { + WordCount16 data; + WirePointerCount16 pointers; + + inline constexpr WordCount total() const { return data + pointers * WORDS_PER_POINTER; } + + StructSize() = default; + inline constexpr StructSize(WordCount data, WirePointerCount pointers) + : data(data), pointers(pointers) {} +}; + +template <typename T, typename CapnpPrivate = typename T::_capnpPrivate> +inline constexpr StructSize structSize() { + return StructSize(CapnpPrivate::dataWordSize * WORDS, CapnpPrivate::pointerCount * POINTERS); +} + +template <typename T, typename CapnpPrivate = typename T::_capnpPrivate, + typename = kj::EnableIf<CAPNP_KIND(T) == Kind::STRUCT>> +inline constexpr StructSize minStructSizeForElement() { + // If T is a struct, return its struct size. Otherwise return the minimum struct size big enough + // to hold a T. + + return StructSize(CapnpPrivate::dataWordSize * WORDS, CapnpPrivate::pointerCount * POINTERS); +} + +template <typename T, typename = kj::EnableIf<CAPNP_KIND(T) != Kind::STRUCT>> +inline constexpr StructSize minStructSizeForElement() { + // If T is a struct, return its struct size. Otherwise return the minimum struct size big enough + // to hold a T. + + return StructSize( + dataBitsPerElement(elementSizeForType<T>()) * ELEMENTS > 0 * BITS ? 1 * WORDS : 0 * WORDS, + pointersPerElement(elementSizeForType<T>()) * ELEMENTS); +} + +// ------------------------------------------------------------------- +// Masking of default values + +template <typename T, Kind kind = CAPNP_KIND(T)> struct Mask_; +template <typename T> struct Mask_<T, Kind::PRIMITIVE> { typedef T Type; }; +template <typename T> struct Mask_<T, Kind::ENUM> { typedef uint16_t Type; }; +template <> struct Mask_<float, Kind::PRIMITIVE> { typedef uint32_t Type; }; +template <> struct Mask_<double, Kind::PRIMITIVE> { typedef uint64_t Type; }; + +template <typename T> struct Mask_<T, Kind::OTHER> { + // Union discriminants end up here. + static_assert(sizeof(T) == 2, "Don't know how to mask this type."); + typedef uint16_t Type; +}; + +template <typename T> +using Mask = typename Mask_<T>::Type; + +template <typename T> +KJ_ALWAYS_INLINE(Mask<T> mask(T value, Mask<T> mask)); +template <typename T> +KJ_ALWAYS_INLINE(T unmask(Mask<T> value, Mask<T> mask)); + +template <typename T> +inline Mask<T> mask(T value, Mask<T> mask) { + return static_cast<Mask<T> >(value) ^ mask; +} + +template <> +inline uint32_t mask<float>(float value, uint32_t mask) { +#if CAPNP_CANONICALIZE_NAN + if (value != value) { + return 0x7fc00000u ^ mask; + } +#endif + + uint32_t i; + static_assert(sizeof(i) == sizeof(value), "float is not 32 bits?"); + memcpy(&i, &value, sizeof(value)); + return i ^ mask; +} + +template <> +inline uint64_t mask<double>(double value, uint64_t mask) { +#if CAPNP_CANONICALIZE_NAN + if (value != value) { + return 0x7ff8000000000000ull ^ mask; + } +#endif + + uint64_t i; + static_assert(sizeof(i) == sizeof(value), "double is not 64 bits?"); + memcpy(&i, &value, sizeof(value)); + return i ^ mask; +} + +template <typename T> +inline T unmask(Mask<T> value, Mask<T> mask) { + return static_cast<T>(value ^ mask); +} + +template <> +inline float unmask<float>(uint32_t value, uint32_t mask) { + value ^= mask; + float result; + static_assert(sizeof(result) == sizeof(value), "float is not 32 bits?"); + memcpy(&result, &value, sizeof(value)); + return result; +} + +template <> +inline double unmask<double>(uint64_t value, uint64_t mask) { + value ^= mask; + double result; + static_assert(sizeof(result) == sizeof(value), "double is not 64 bits?"); + memcpy(&result, &value, sizeof(value)); + return result; +} + +// ------------------------------------------------------------------- + +class CapTableReader { +public: +#if !CAPNP_LITE + virtual kj::Maybe<kj::Own<ClientHook>> extractCap(uint index) = 0; + // Extract the capability at the given index. If the index is invalid, returns null. +#endif // !CAPNP_LITE +}; + +class CapTableBuilder: public CapTableReader { +public: +#if !CAPNP_LITE + virtual uint injectCap(kj::Own<ClientHook>&& cap) = 0; + // Add the capability to the message and return its index. If the same ClientHook is injected + // twice, this may return the same index both times, but in this case dropCap() needs to be + // called an equal number of times to actually remove the cap. + + virtual void dropCap(uint index) = 0; + // Remove a capability injected earlier. Called when the pointer is overwritten or zero'd out. +#endif // !CAPNP_LITE +}; + +// ------------------------------------------------------------------- + +class PointerBuilder: public kj::DisallowConstCopy { + // Represents a single pointer, usually embedded in a struct or a list. + +public: + inline PointerBuilder(): segment(nullptr), capTable(nullptr), pointer(nullptr) {} + + static inline PointerBuilder getRoot( + SegmentBuilder* segment, CapTableBuilder* capTable, word* location); + // Get a PointerBuilder representing a message root located in the given segment at the given + // location. + + inline bool isNull() { return getPointerType() == PointerType::NULL_; } + PointerType getPointerType(); + + StructBuilder getStruct(StructSize size, const word* defaultValue); + ListBuilder getList(ElementSize elementSize, const word* defaultValue); + ListBuilder getStructList(StructSize elementSize, const word* defaultValue); + ListBuilder getListAnySize(const word* defaultValue); + template <typename T> typename T::Builder getBlob(const void* defaultValue,ByteCount defaultSize); +#if !CAPNP_LITE + kj::Own<ClientHook> getCapability(); +#endif // !CAPNP_LITE + // Get methods: Get the value. If it is null, initialize it to a copy of the default value. + // The default value is encoded as an "unchecked message" for structs, lists, and objects, or a + // simple byte array for blobs. + + StructBuilder initStruct(StructSize size); + ListBuilder initList(ElementSize elementSize, ElementCount elementCount); + ListBuilder initStructList(ElementCount elementCount, StructSize size); + template <typename T> typename T::Builder initBlob(ByteCount size); + // Init methods: Initialize the pointer to a newly-allocated object, discarding the existing + // object. + + void setStruct(const StructReader& value, bool canonical = false); + void setList(const ListReader& value, bool canonical = false); + template <typename T> void setBlob(typename T::Reader value); +#if !CAPNP_LITE + void setCapability(kj::Own<ClientHook>&& cap); +#endif // !CAPNP_LITE + // Set methods: Initialize the pointer to a newly-allocated copy of the given value, discarding + // the existing object. + + void adopt(OrphanBuilder&& orphan); + // Set the pointer to point at the given orphaned value. + + OrphanBuilder disown(); + // Set the pointer to null and return its previous value as an orphan. + + void clear(); + // Clear the pointer to null, discarding its previous value. + + void transferFrom(PointerBuilder other); + // Equivalent to `adopt(other.disown())`. + + void copyFrom(PointerReader other, bool canonical = false); + // Equivalent to `set(other.get())`. + // If you set the canonical flag, it will attempt to lay the target out + // canonically, provided enough space is available. + + PointerReader asReader() const; + + BuilderArena* getArena() const; + // Get the arena containing this pointer. + + CapTableBuilder* getCapTable(); + // Gets the capability context in which this object is operating. + + PointerBuilder imbue(CapTableBuilder* capTable); + // Return a copy of this builder except using the given capability context. + +private: + SegmentBuilder* segment; // Memory segment in which the pointer resides. + CapTableBuilder* capTable; // Table of capability indexes. + WirePointer* pointer; // Pointer to the pointer. + + inline PointerBuilder(SegmentBuilder* segment, CapTableBuilder* capTable, WirePointer* pointer) + : segment(segment), capTable(capTable), pointer(pointer) {} + + friend class StructBuilder; + friend class ListBuilder; + friend class OrphanBuilder; +}; + +class PointerReader { +public: + inline PointerReader() + : segment(nullptr), capTable(nullptr), pointer(nullptr), nestingLimit(0x7fffffff) {} + + static PointerReader getRoot(SegmentReader* segment, CapTableReader* capTable, + const word* location, int nestingLimit); + // Get a PointerReader representing a message root located in the given segment at the given + // location. + + static inline PointerReader getRootUnchecked(const word* location); + // Get a PointerReader for an unchecked message. + + MessageSizeCounts targetSize() const; + // Return the total size of the target object and everything to which it points. Does not count + // far pointer overhead. This is useful for deciding how much space is needed to copy the object + // into a flat array. However, the caller is advised NOT to treat this value as secure. Instead, + // use the result as a hint for allocating the first segment, do the copy, and then throw an + // exception if it overruns. + + inline bool isNull() const { return getPointerType() == PointerType::NULL_; } + PointerType getPointerType() const; + + StructReader getStruct(const word* defaultValue) const; + ListReader getList(ElementSize expectedElementSize, const word* defaultValue) const; + ListReader getListAnySize(const word* defaultValue) const; + template <typename T> + typename T::Reader getBlob(const void* defaultValue, ByteCount defaultSize) const; +#if !CAPNP_LITE + kj::Own<ClientHook> getCapability() const; +#endif // !CAPNP_LITE + // Get methods: Get the value. If it is null, return the default value instead. + // The default value is encoded as an "unchecked message" for structs, lists, and objects, or a + // simple byte array for blobs. + + const word* getUnchecked() const; + // If this is an unchecked message, get a word* pointing at the location of the pointer. This + // word* can actually be passed to readUnchecked() to read the designated sub-object later. If + // this isn't an unchecked message, throws an exception. + + kj::Maybe<Arena&> getArena() const; + // Get the arena containing this pointer. + + CapTableReader* getCapTable(); + // Gets the capability context in which this object is operating. + + PointerReader imbue(CapTableReader* capTable) const; + // Return a copy of this reader except using the given capability context. + + bool isCanonical(const word **readHead); + // Validate this pointer's canonicity, subject to the conditions: + // * All data to the left of readHead has been read thus far (for pointer + // ordering) + // * All pointers in preorder have already been checked + // * This pointer is in the first and only segment of the message + +private: + SegmentReader* segment; // Memory segment in which the pointer resides. + CapTableReader* capTable; // Table of capability indexes. + const WirePointer* pointer; // Pointer to the pointer. null = treat as null pointer. + + int nestingLimit; + // Limits the depth of message structures to guard against stack-overflow-based DoS attacks. + // Once this reaches zero, further pointers will be pruned. + + inline PointerReader(SegmentReader* segment, CapTableReader* capTable, + const WirePointer* pointer, int nestingLimit) + : segment(segment), capTable(capTable), pointer(pointer), nestingLimit(nestingLimit) {} + + friend class StructReader; + friend class ListReader; + friend class PointerBuilder; + friend class OrphanBuilder; +}; + +// ------------------------------------------------------------------- + +class StructBuilder: public kj::DisallowConstCopy { +public: + inline StructBuilder(): segment(nullptr), capTable(nullptr), data(nullptr), pointers(nullptr) {} + + inline word* getLocation() { return reinterpret_cast<word*>(data); } + // Get the object's location. Only valid for independently-allocated objects (i.e. not list + // elements). + + inline BitCount getDataSectionSize() const { return dataSize; } + inline WirePointerCount getPointerSectionSize() const { return pointerCount; } + inline kj::ArrayPtr<byte> getDataSectionAsBlob(); + inline _::ListBuilder getPointerSectionAsList(); + + template <typename T> + KJ_ALWAYS_INLINE(bool hasDataField(ElementCount offset)); + // Return true if the field is set to something other than its default value. + + template <typename T> + KJ_ALWAYS_INLINE(T getDataField(ElementCount offset)); + // Gets the data field value of the given type at the given offset. The offset is measured in + // multiples of the field size, determined by the type. + + template <typename T> + KJ_ALWAYS_INLINE(T getDataField(ElementCount offset, Mask<T> mask)); + // Like getDataField() but applies the given XOR mask to the data on load. Used for reading + // fields with non-zero default values. + + template <typename T> + KJ_ALWAYS_INLINE(void setDataField( + ElementCount offset, kj::NoInfer<T> value)); + // Sets the data field value at the given offset. + + template <typename T> + KJ_ALWAYS_INLINE(void setDataField( + ElementCount offset, kj::NoInfer<T> value, Mask<T> mask)); + // Like setDataField() but applies the given XOR mask before storing. Used for writing fields + // with non-zero default values. + + KJ_ALWAYS_INLINE(PointerBuilder getPointerField(WirePointerCount ptrIndex)); + // Get a builder for a pointer field given the index within the pointer section. + + void clearAll(); + // Clear all pointers and data. + + void transferContentFrom(StructBuilder other); + // Adopt all pointers from `other`, and also copy all data. If `other`'s sections are larger + // than this, the extra data is not transferred, meaning there is a risk of data loss when + // transferring from messages built with future versions of the protocol. + + void copyContentFrom(StructReader other); + // Copy content from `other`. If `other`'s sections are larger than this, the extra data is not + // copied, meaning there is a risk of data loss when copying from messages built with future + // versions of the protocol. + + StructReader asReader() const; + // Gets a StructReader pointing at the same memory. + + BuilderArena* getArena(); + // Gets the arena in which this object is allocated. + + CapTableBuilder* getCapTable(); + // Gets the capability context in which this object is operating. + + StructBuilder imbue(CapTableBuilder* capTable); + // Return a copy of this builder except using the given capability context. + +private: + SegmentBuilder* segment; // Memory segment in which the struct resides. + CapTableBuilder* capTable; // Table of capability indexes. + void* data; // Pointer to the encoded data. + WirePointer* pointers; // Pointer to the encoded pointers. + + BitCount32 dataSize; + // Size of data section. We use a bit count rather than a word count to more easily handle the + // case of struct lists encoded with less than a word per element. + + WirePointerCount16 pointerCount; // Size of the pointer section. + + inline StructBuilder(SegmentBuilder* segment, CapTableBuilder* capTable, + void* data, WirePointer* pointers, + BitCount dataSize, WirePointerCount pointerCount) + : segment(segment), capTable(capTable), data(data), pointers(pointers), + dataSize(dataSize), pointerCount(pointerCount) {} + + friend class ListBuilder; + friend struct WireHelpers; + friend class OrphanBuilder; +}; + +class StructReader { +public: + inline StructReader() + : segment(nullptr), capTable(nullptr), data(nullptr), pointers(nullptr), dataSize(0), + pointerCount(0), nestingLimit(0x7fffffff) {} + inline StructReader(kj::ArrayPtr<const word> data) + : segment(nullptr), capTable(nullptr), data(data.begin()), pointers(nullptr), + dataSize(data.size() * WORDS * BITS_PER_WORD), pointerCount(0), nestingLimit(0x7fffffff) {} + + const void* getLocation() const { return data; } + + inline BitCount getDataSectionSize() const { return dataSize; } + inline WirePointerCount getPointerSectionSize() const { return pointerCount; } + inline kj::ArrayPtr<const byte> getDataSectionAsBlob(); + inline _::ListReader getPointerSectionAsList(); + + kj::Array<word> canonicalize(); + + template <typename T> + KJ_ALWAYS_INLINE(bool hasDataField(ElementCount offset) const); + // Return true if the field is set to something other than its default value. + + template <typename T> + KJ_ALWAYS_INLINE(T getDataField(ElementCount offset) const); + // Get the data field value of the given type at the given offset. The offset is measured in + // multiples of the field size, determined by the type. Returns zero if the offset is past the + // end of the struct's data section. + + template <typename T> + KJ_ALWAYS_INLINE( + T getDataField(ElementCount offset, Mask<T> mask) const); + // Like getDataField(offset), but applies the given XOR mask to the result. Used for reading + // fields with non-zero default values. + + KJ_ALWAYS_INLINE(PointerReader getPointerField(WirePointerCount ptrIndex) const); + // Get a reader for a pointer field given the index within the pointer section. If the index + // is out-of-bounds, returns a null pointer. + + MessageSizeCounts totalSize() const; + // Return the total size of the struct and everything to which it points. Does not count far + // pointer overhead. This is useful for deciding how much space is needed to copy the struct + // into a flat array. However, the caller is advised NOT to treat this value as secure. Instead, + // use the result as a hint for allocating the first segment, do the copy, and then throw an + // exception if it overruns. + + CapTableReader* getCapTable(); + // Gets the capability context in which this object is operating. + + StructReader imbue(CapTableReader* capTable) const; + // Return a copy of this reader except using the given capability context. + + bool isCanonical(const word **readHead, const word **ptrHead, + bool *dataTrunc, bool *ptrTrunc); + // Validate this pointer's canonicity, subject to the conditions: + // * All data to the left of readHead has been read thus far (for pointer + // ordering) + // * All pointers in preorder have already been checked + // * This pointer is in the first and only segment of the message + // + // If this function returns false, the struct is non-canonical. If it + // returns true, then: + // * If it is a composite in a list, it is canonical if at least one struct + // in the list outputs dataTrunc = 1, and at least one outputs ptrTrunc = 1 + // * If it is derived from a struct pointer, it is canonical if + // dataTrunc = 1 AND ptrTrunc = 1 + +private: + SegmentReader* segment; // Memory segment in which the struct resides. + CapTableReader* capTable; // Table of capability indexes. + + const void* data; + const WirePointer* pointers; + + BitCount32 dataSize; + // Size of data section. We use a bit count rather than a word count to more easily handle the + // case of struct lists encoded with less than a word per element. + + WirePointerCount16 pointerCount; // Size of the pointer section. + + int nestingLimit; + // Limits the depth of message structures to guard against stack-overflow-based DoS attacks. + // Once this reaches zero, further pointers will be pruned. + // TODO(perf): Limit to 16 bits for better packing? + + inline StructReader(SegmentReader* segment, CapTableReader* capTable, + const void* data, const WirePointer* pointers, + BitCount dataSize, WirePointerCount pointerCount, int nestingLimit) + : segment(segment), capTable(capTable), data(data), pointers(pointers), + dataSize(dataSize), pointerCount(pointerCount), + nestingLimit(nestingLimit) {} + + friend class ListReader; + friend class StructBuilder; + friend struct WireHelpers; +}; + +// ------------------------------------------------------------------- + +class ListBuilder: public kj::DisallowConstCopy { +public: + inline explicit ListBuilder(ElementSize elementSize) + : segment(nullptr), capTable(nullptr), ptr(nullptr), elementCount(0 * ELEMENTS), + step(0 * BITS / ELEMENTS), structDataSize(0 * BITS), structPointerCount(0 * POINTERS), + elementSize(elementSize) {} + + inline word* getLocation() { + // Get the object's location. + + if (elementSize == ElementSize::INLINE_COMPOSITE && ptr != nullptr) { + return reinterpret_cast<word*>(ptr) - POINTER_SIZE_IN_WORDS; + } else { + return reinterpret_cast<word*>(ptr); + } + } + + inline ElementSize getElementSize() const { return elementSize; } + + inline ElementCount size() const; + // The number of elements in the list. + + Text::Builder asText(); + Data::Builder asData(); + // Reinterpret the list as a blob. Throws an exception if the elements are not byte-sized. + + template <typename T> + KJ_ALWAYS_INLINE(T getDataElement(ElementCount index)); + // Get the element of the given type at the given index. + + template <typename T> + KJ_ALWAYS_INLINE(void setDataElement( + ElementCount index, kj::NoInfer<T> value)); + // Set the element at the given index. + + KJ_ALWAYS_INLINE(PointerBuilder getPointerElement(ElementCount index)); + + StructBuilder getStructElement(ElementCount index); + + ListReader asReader() const; + // Get a ListReader pointing at the same memory. + + BuilderArena* getArena(); + // Gets the arena in which this object is allocated. + + CapTableBuilder* getCapTable(); + // Gets the capability context in which this object is operating. + + ListBuilder imbue(CapTableBuilder* capTable); + // Return a copy of this builder except using the given capability context. + +private: + SegmentBuilder* segment; // Memory segment in which the list resides. + CapTableBuilder* capTable; // Table of capability indexes. + + byte* ptr; // Pointer to list content. + + ElementCount elementCount; // Number of elements in the list. + + decltype(BITS / ELEMENTS) step; + // The distance between elements. + + BitCount32 structDataSize; + WirePointerCount16 structPointerCount; + // The struct properties to use when interpreting the elements as structs. All lists can be + // interpreted as struct lists, so these are always filled in. + + ElementSize elementSize; + // The element size as a ElementSize. This is only really needed to disambiguate INLINE_COMPOSITE + // from other types when the overall size is exactly zero or one words. + + inline ListBuilder(SegmentBuilder* segment, CapTableBuilder* capTable, void* ptr, + decltype(BITS / ELEMENTS) step, ElementCount size, + BitCount structDataSize, WirePointerCount structPointerCount, + ElementSize elementSize) + : segment(segment), capTable(capTable), ptr(reinterpret_cast<byte*>(ptr)), + elementCount(size), step(step), structDataSize(structDataSize), + structPointerCount(structPointerCount), elementSize(elementSize) {} + + friend class StructBuilder; + friend struct WireHelpers; + friend class OrphanBuilder; +}; + +class ListReader { +public: + inline explicit ListReader(ElementSize elementSize) + : segment(nullptr), capTable(nullptr), ptr(nullptr), elementCount(0), + step(0 * BITS / ELEMENTS), structDataSize(0), structPointerCount(0), + elementSize(elementSize), nestingLimit(0x7fffffff) {} + + inline ElementCount size() const; + // The number of elements in the list. + + inline ElementSize getElementSize() const { return elementSize; } + + Text::Reader asText(); + Data::Reader asData(); + // Reinterpret the list as a blob. Throws an exception if the elements are not byte-sized. + + kj::ArrayPtr<const byte> asRawBytes(); + + template <typename T> + KJ_ALWAYS_INLINE(T getDataElement(ElementCount index) const); + // Get the element of the given type at the given index. + + KJ_ALWAYS_INLINE(PointerReader getPointerElement(ElementCount index) const); + + StructReader getStructElement(ElementCount index) const; + + CapTableReader* getCapTable(); + // Gets the capability context in which this object is operating. + + ListReader imbue(CapTableReader* capTable) const; + // Return a copy of this reader except using the given capability context. + + bool isCanonical(const word **readHead); + // Validate this pointer's canonicity, subject to the conditions: + // * All data to the left of readHead has been read thus far (for pointer + // ordering) + // * All pointers in preorder have already been checked + // * This pointer is in the first and only segment of the message + +private: + SegmentReader* segment; // Memory segment in which the list resides. + CapTableReader* capTable; // Table of capability indexes. + + const byte* ptr; // Pointer to list content. + + ElementCount elementCount; // Number of elements in the list. + + decltype(BITS / ELEMENTS) step; + // The distance between elements. + + BitCount32 structDataSize; + WirePointerCount16 structPointerCount; + // The struct properties to use when interpreting the elements as structs. All lists can be + // interpreted as struct lists, so these are always filled in. + + ElementSize elementSize; + // The element size as a ElementSize. This is only really needed to disambiguate INLINE_COMPOSITE + // from other types when the overall size is exactly zero or one words. + + int nestingLimit; + // Limits the depth of message structures to guard against stack-overflow-based DoS attacks. + // Once this reaches zero, further pointers will be pruned. + + inline ListReader(SegmentReader* segment, CapTableReader* capTable, const void* ptr, + ElementCount elementCount, decltype(BITS / ELEMENTS) step, + BitCount structDataSize, WirePointerCount structPointerCount, + ElementSize elementSize, int nestingLimit) + : segment(segment), capTable(capTable), ptr(reinterpret_cast<const byte*>(ptr)), + elementCount(elementCount), step(step), structDataSize(structDataSize), + structPointerCount(structPointerCount), elementSize(elementSize), + nestingLimit(nestingLimit) {} + + friend class StructReader; + friend class ListBuilder; + friend struct WireHelpers; + friend class OrphanBuilder; +}; + +// ------------------------------------------------------------------- + +class OrphanBuilder { +public: + inline OrphanBuilder(): segment(nullptr), capTable(nullptr), location(nullptr) { + memset(&tag, 0, sizeof(tag)); + } + OrphanBuilder(const OrphanBuilder& other) = delete; + inline OrphanBuilder(OrphanBuilder&& other) noexcept; + inline ~OrphanBuilder() noexcept(false); + + static OrphanBuilder initStruct(BuilderArena* arena, CapTableBuilder* capTable, StructSize size); + static OrphanBuilder initList(BuilderArena* arena, CapTableBuilder* capTable, + ElementCount elementCount, ElementSize elementSize); + static OrphanBuilder initStructList(BuilderArena* arena, CapTableBuilder* capTable, + ElementCount elementCount, StructSize elementSize); + static OrphanBuilder initText(BuilderArena* arena, CapTableBuilder* capTable, ByteCount size); + static OrphanBuilder initData(BuilderArena* arena, CapTableBuilder* capTable, ByteCount size); + + static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, StructReader copyFrom); + static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, ListReader copyFrom); + static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, PointerReader copyFrom); + static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, Text::Reader copyFrom); + static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, Data::Reader copyFrom); +#if !CAPNP_LITE + static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, + kj::Own<ClientHook> copyFrom); +#endif // !CAPNP_LITE + + static OrphanBuilder concat(BuilderArena* arena, CapTableBuilder* capTable, + ElementSize expectedElementSize, StructSize expectedStructSize, + kj::ArrayPtr<const ListReader> lists); + + static OrphanBuilder referenceExternalData(BuilderArena* arena, Data::Reader data); + + OrphanBuilder& operator=(const OrphanBuilder& other) = delete; + inline OrphanBuilder& operator=(OrphanBuilder&& other); + + inline bool operator==(decltype(nullptr)) const { return location == nullptr; } + inline bool operator!=(decltype(nullptr)) const { return location != nullptr; } + + StructBuilder asStruct(StructSize size); + // Interpret as a struct, or throw an exception if not a struct. + + ListBuilder asList(ElementSize elementSize); + // Interpret as a list, or throw an exception if not a list. elementSize cannot be + // INLINE_COMPOSITE -- use asStructList() instead. + + ListBuilder asStructList(StructSize elementSize); + // Interpret as a struct list, or throw an exception if not a list. + + Text::Builder asText(); + Data::Builder asData(); + // Interpret as a blob, or throw an exception if not a blob. + + StructReader asStructReader(StructSize size) const; + ListReader asListReader(ElementSize elementSize) const; +#if !CAPNP_LITE + kj::Own<ClientHook> asCapability() const; +#endif // !CAPNP_LITE + Text::Reader asTextReader() const; + Data::Reader asDataReader() const; + + bool truncate(ElementCount size, bool isText) KJ_WARN_UNUSED_RESULT; + // Resize the orphan list to the given size. Returns false if the list is currently empty but + // the requested size is non-zero, in which case the caller will need to allocate a new list. + + void truncate(ElementCount size, ElementSize elementSize); + void truncate(ElementCount size, StructSize elementSize); + void truncateText(ElementCount size); + // Versions of truncate() that know how to allocate a new list if needed. + +private: + static_assert(1 * POINTERS * WORDS_PER_POINTER == 1 * WORDS, + "This struct assumes a pointer is one word."); + word tag; + // Contains an encoded WirePointer representing this object. WirePointer is defined in + // layout.c++, but fits in a word. + // + // This may be a FAR pointer. Even in that case, `location` points to the eventual destination + // of that far pointer. The reason we keep the far pointer around rather than just making `tag` + // represent the final destination is because if the eventual adopter of the pointer is not in + // the target's segment then it may be useful to reuse the far pointer landing pad. + // + // If `tag` is not a far pointer, its offset is garbage; only `location` points to the actual + // target. + + SegmentBuilder* segment; + // Segment in which the object resides. + + CapTableBuilder* capTable; + // Table of capability indexes. + + word* location; + // Pointer to the object, or nullptr if the pointer is null. For capabilities, we make this + // 0x1 just so that it is non-null for operator==, but it is never used. + + inline OrphanBuilder(const void* tagPtr, SegmentBuilder* segment, + CapTableBuilder* capTable, word* location) + : segment(segment), capTable(capTable), location(location) { + memcpy(&tag, tagPtr, sizeof(tag)); + } + + inline WirePointer* tagAsPtr() { return reinterpret_cast<WirePointer*>(&tag); } + inline const WirePointer* tagAsPtr() const { return reinterpret_cast<const WirePointer*>(&tag); } + + void euthanize(); + // Erase the target object, zeroing it out and possibly reclaiming the memory. Called when + // the OrphanBuilder is being destroyed or overwritten and it is non-null. + + friend struct WireHelpers; +}; + +// ======================================================================================= +// Internal implementation details... + +// These are defined in the source file. +template <> typename Text::Builder PointerBuilder::initBlob<Text>(ByteCount size); +template <> void PointerBuilder::setBlob<Text>(typename Text::Reader value); +template <> typename Text::Builder PointerBuilder::getBlob<Text>(const void* defaultValue, ByteCount defaultSize); +template <> typename Text::Reader PointerReader::getBlob<Text>(const void* defaultValue, ByteCount defaultSize) const; + +template <> typename Data::Builder PointerBuilder::initBlob<Data>(ByteCount size); +template <> void PointerBuilder::setBlob<Data>(typename Data::Reader value); +template <> typename Data::Builder PointerBuilder::getBlob<Data>(const void* defaultValue, ByteCount defaultSize); +template <> typename Data::Reader PointerReader::getBlob<Data>(const void* defaultValue, ByteCount defaultSize) const; + +inline PointerBuilder PointerBuilder::getRoot( + SegmentBuilder* segment, CapTableBuilder* capTable, word* location) { + return PointerBuilder(segment, capTable, reinterpret_cast<WirePointer*>(location)); +} + +inline PointerReader PointerReader::getRootUnchecked(const word* location) { + return PointerReader(nullptr, nullptr, + reinterpret_cast<const WirePointer*>(location), 0x7fffffff); +} + +// ------------------------------------------------------------------- + +inline kj::ArrayPtr<byte> StructBuilder::getDataSectionAsBlob() { + return kj::ArrayPtr<byte>(reinterpret_cast<byte*>(data), dataSize / BITS_PER_BYTE / BYTES); +} + +inline _::ListBuilder StructBuilder::getPointerSectionAsList() { + return _::ListBuilder(segment, capTable, pointers, 1 * POINTERS * BITS_PER_POINTER / ELEMENTS, + pointerCount * (1 * ELEMENTS / POINTERS), + 0 * BITS, 1 * POINTERS, ElementSize::POINTER); +} + +template <typename T> +inline bool StructBuilder::hasDataField(ElementCount offset) { + return getDataField<Mask<T>>(offset) != 0; +} + +template <> +inline bool StructBuilder::hasDataField<Void>(ElementCount offset) { + return false; +} + +template <typename T> +inline T StructBuilder::getDataField(ElementCount offset) { + return reinterpret_cast<WireValue<T>*>(data)[offset / ELEMENTS].get(); +} + +template <> +inline bool StructBuilder::getDataField<bool>(ElementCount offset) { + BitCount boffset = offset * (1 * BITS / ELEMENTS); + byte* b = reinterpret_cast<byte*>(data) + boffset / BITS_PER_BYTE; + return (*reinterpret_cast<uint8_t*>(b) & (1 << (boffset % BITS_PER_BYTE / BITS))) != 0; +} + +template <> +inline Void StructBuilder::getDataField<Void>(ElementCount offset) { + return VOID; +} + +template <typename T> +inline T StructBuilder::getDataField(ElementCount offset, Mask<T> mask) { + return unmask<T>(getDataField<Mask<T> >(offset), mask); +} + +template <typename T> +inline void StructBuilder::setDataField(ElementCount offset, kj::NoInfer<T> value) { + reinterpret_cast<WireValue<T>*>(data)[offset / ELEMENTS].set(value); +} + +#if CAPNP_CANONICALIZE_NAN +// Use mask() on floats and doubles to make sure we canonicalize NaNs. +template <> +inline void StructBuilder::setDataField<float>(ElementCount offset, float value) { + setDataField<uint32_t>(offset, mask<float>(value, 0)); +} +template <> +inline void StructBuilder::setDataField<double>(ElementCount offset, double value) { + setDataField<uint64_t>(offset, mask<double>(value, 0)); +} +#endif + +template <> +inline void StructBuilder::setDataField<bool>(ElementCount offset, bool value) { + BitCount boffset = offset * (1 * BITS / ELEMENTS); + byte* b = reinterpret_cast<byte*>(data) + boffset / BITS_PER_BYTE; + uint bitnum = boffset % BITS_PER_BYTE / BITS; + *reinterpret_cast<uint8_t*>(b) = (*reinterpret_cast<uint8_t*>(b) & ~(1 << bitnum)) + | (static_cast<uint8_t>(value) << bitnum); +} + +template <> +inline void StructBuilder::setDataField<Void>(ElementCount offset, Void value) {} + +template <typename T> +inline void StructBuilder::setDataField(ElementCount offset, kj::NoInfer<T> value, Mask<T> m) { + setDataField<Mask<T> >(offset, mask<T>(value, m)); +} + +inline PointerBuilder StructBuilder::getPointerField(WirePointerCount ptrIndex) { + // Hacky because WirePointer is defined in the .c++ file (so is incomplete here). + return PointerBuilder(segment, capTable, reinterpret_cast<WirePointer*>( + reinterpret_cast<word*>(pointers) + ptrIndex * WORDS_PER_POINTER)); +} + +// ------------------------------------------------------------------- + +inline kj::ArrayPtr<const byte> StructReader::getDataSectionAsBlob() { + return kj::ArrayPtr<const byte>(reinterpret_cast<const byte*>(data), dataSize / BITS_PER_BYTE / BYTES); +} + +inline _::ListReader StructReader::getPointerSectionAsList() { + return _::ListReader(segment, capTable, pointers, pointerCount * (1 * ELEMENTS / POINTERS), + 1 * POINTERS * BITS_PER_POINTER / ELEMENTS, 0 * BITS, 1 * POINTERS, + ElementSize::POINTER, nestingLimit); +} + +template <typename T> +inline bool StructReader::hasDataField(ElementCount offset) const { + return getDataField<Mask<T>>(offset) != 0; +} + +template <> +inline bool StructReader::hasDataField<Void>(ElementCount offset) const { + return false; +} + +template <typename T> +inline T StructReader::getDataField(ElementCount offset) const { + if ((offset + 1 * ELEMENTS) * capnp::bitsPerElement<T>() <= dataSize) { + return reinterpret_cast<const WireValue<T>*>(data)[offset / ELEMENTS].get(); + } else { + return static_cast<T>(0); + } +} + +template <> +inline bool StructReader::getDataField<bool>(ElementCount offset) const { + BitCount boffset = offset * (1 * BITS / ELEMENTS); + if (boffset < dataSize) { + const byte* b = reinterpret_cast<const byte*>(data) + boffset / BITS_PER_BYTE; + return (*reinterpret_cast<const uint8_t*>(b) & (1 << (boffset % BITS_PER_BYTE / BITS))) != 0; + } else { + return false; + } +} + +template <> +inline Void StructReader::getDataField<Void>(ElementCount offset) const { + return VOID; +} + +template <typename T> +T StructReader::getDataField(ElementCount offset, Mask<T> mask) const { + return unmask<T>(getDataField<Mask<T> >(offset), mask); +} + +inline PointerReader StructReader::getPointerField(WirePointerCount ptrIndex) const { + if (ptrIndex < pointerCount) { + // Hacky because WirePointer is defined in the .c++ file (so is incomplete here). + return PointerReader(segment, capTable, reinterpret_cast<const WirePointer*>( + reinterpret_cast<const word*>(pointers) + ptrIndex * WORDS_PER_POINTER), nestingLimit); + } else{ + return PointerReader(); + } +} + +// ------------------------------------------------------------------- + +inline ElementCount ListBuilder::size() const { return elementCount; } + +template <typename T> +inline T ListBuilder::getDataElement(ElementCount index) { + return reinterpret_cast<WireValue<T>*>(ptr + index * step / BITS_PER_BYTE)->get(); + + // TODO(perf): Benchmark this alternate implementation, which I suspect may make better use of + // the x86 SIB byte. Also use it for all the other getData/setData implementations below, and + // the various non-inline methods that look up pointers. + // Also if using this, consider changing ptr back to void* instead of byte*. +// return reinterpret_cast<WireValue<T>*>(ptr)[ +// index / ELEMENTS * (step / capnp::bitsPerElement<T>())].get(); +} + +template <> +inline bool ListBuilder::getDataElement<bool>(ElementCount index) { + // Ignore step for bit lists because bit lists cannot be upgraded to struct lists. + BitCount bindex = index * (1 * BITS / ELEMENTS); + byte* b = ptr + bindex / BITS_PER_BYTE; + return (*reinterpret_cast<uint8_t*>(b) & (1 << (bindex % BITS_PER_BYTE / BITS))) != 0; +} + +template <> +inline Void ListBuilder::getDataElement<Void>(ElementCount index) { + return VOID; +} + +template <typename T> +inline void ListBuilder::setDataElement(ElementCount index, kj::NoInfer<T> value) { + reinterpret_cast<WireValue<T>*>(ptr + index * step / BITS_PER_BYTE)->set(value); +} + +#if CAPNP_CANONICALIZE_NAN +// Use mask() on floats and doubles to make sure we canonicalize NaNs. +template <> +inline void ListBuilder::setDataElement<float>(ElementCount index, float value) { + setDataElement<uint32_t>(index, mask<float>(value, 0)); +} +template <> +inline void ListBuilder::setDataElement<double>(ElementCount index, double value) { + setDataElement<uint64_t>(index, mask<double>(value, 0)); +} +#endif + +template <> +inline void ListBuilder::setDataElement<bool>(ElementCount index, bool value) { + // Ignore stepBytes for bit lists because bit lists cannot be upgraded to struct lists. + BitCount bindex = index * (1 * BITS / ELEMENTS); + byte* b = ptr + bindex / BITS_PER_BYTE; + uint bitnum = bindex % BITS_PER_BYTE / BITS; + *reinterpret_cast<uint8_t*>(b) = (*reinterpret_cast<uint8_t*>(b) & ~(1 << bitnum)) + | (static_cast<uint8_t>(value) << bitnum); +} + +template <> +inline void ListBuilder::setDataElement<Void>(ElementCount index, Void value) {} + +inline PointerBuilder ListBuilder::getPointerElement(ElementCount index) { + return PointerBuilder(segment, capTable, + reinterpret_cast<WirePointer*>(ptr + index * step / BITS_PER_BYTE)); +} + +// ------------------------------------------------------------------- + +inline ElementCount ListReader::size() const { return elementCount; } + +template <typename T> +inline T ListReader::getDataElement(ElementCount index) const { + return reinterpret_cast<const WireValue<T>*>(ptr + index * step / BITS_PER_BYTE)->get(); +} + +template <> +inline bool ListReader::getDataElement<bool>(ElementCount index) const { + // Ignore step for bit lists because bit lists cannot be upgraded to struct lists. + BitCount bindex = index * (1 * BITS / ELEMENTS); + const byte* b = ptr + bindex / BITS_PER_BYTE; + return (*reinterpret_cast<const uint8_t*>(b) & (1 << (bindex % BITS_PER_BYTE / BITS))) != 0; +} + +template <> +inline Void ListReader::getDataElement<Void>(ElementCount index) const { + return VOID; +} + +inline PointerReader ListReader::getPointerElement(ElementCount index) const { + return PointerReader(segment, capTable, + reinterpret_cast<const WirePointer*>(ptr + index * step / BITS_PER_BYTE), nestingLimit); +} + +// ------------------------------------------------------------------- + +inline OrphanBuilder::OrphanBuilder(OrphanBuilder&& other) noexcept + : segment(other.segment), capTable(other.capTable), location(other.location) { + memcpy(&tag, &other.tag, sizeof(tag)); // Needs memcpy to comply with aliasing rules. + other.segment = nullptr; + other.location = nullptr; +} + +inline OrphanBuilder::~OrphanBuilder() noexcept(false) { + if (segment != nullptr) euthanize(); +} + +inline OrphanBuilder& OrphanBuilder::operator=(OrphanBuilder&& other) { + // With normal smart pointers, it's important to handle the case where the incoming pointer + // is actually transitively owned by this one. In this case, euthanize() would destroy `other` + // before we copied it. This isn't possible in the case of `OrphanBuilder` because it only + // owns message objects, and `other` is not itself a message object, therefore cannot possibly + // be transitively owned by `this`. + + if (segment != nullptr) euthanize(); + segment = other.segment; + capTable = other.capTable; + location = other.location; + memcpy(&tag, &other.tag, sizeof(tag)); // Needs memcpy to comply with aliasing rules. + other.segment = nullptr; + other.location = nullptr; + return *this; +} + +} // namespace _ (private) +} // namespace capnp + +#endif // CAPNP_LAYOUT_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/list.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,543 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef CAPNP_LIST_H_ +#define CAPNP_LIST_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "layout.h" +#include "orphan.h" +#include <initializer_list> +#ifdef KJ_STD_COMPAT +#include <iterator> +#endif // KJ_STD_COMPAT + +namespace capnp { +namespace _ { // private + +template <typename T> +class TemporaryPointer { + // This class is a little hack which lets us define operator->() in cases where it needs to + // return a pointer to a temporary value. We instead construct a TemporaryPointer and return that + // (by value). The compiler then invokes operator->() on the TemporaryPointer, which itself is + // able to return a real pointer to its member. + +public: + TemporaryPointer(T&& value): value(kj::mv(value)) {} + TemporaryPointer(const T& value): value(value) {} + + inline T* operator->() { return &value; } +private: + T value; +}; + +template <typename Container, typename Element> +class IndexingIterator { +public: + IndexingIterator() = default; + + inline Element operator*() const { return (*container)[index]; } + inline TemporaryPointer<Element> operator->() const { + return TemporaryPointer<Element>((*container)[index]); + } + inline Element operator[]( int off) const { return (*container)[index]; } + inline Element operator[](uint off) const { return (*container)[index]; } + + inline IndexingIterator& operator++() { ++index; return *this; } + inline IndexingIterator operator++(int) { IndexingIterator other = *this; ++index; return other; } + inline IndexingIterator& operator--() { --index; return *this; } + inline IndexingIterator operator--(int) { IndexingIterator other = *this; --index; return other; } + + inline IndexingIterator operator+(uint amount) const { return IndexingIterator(container, index + amount); } + inline IndexingIterator operator-(uint amount) const { return IndexingIterator(container, index - amount); } + inline IndexingIterator operator+( int amount) const { return IndexingIterator(container, index + amount); } + inline IndexingIterator operator-( int amount) const { return IndexingIterator(container, index - amount); } + + inline int operator-(const IndexingIterator& other) const { return index - other.index; } + + inline IndexingIterator& operator+=(uint amount) { index += amount; return *this; } + inline IndexingIterator& operator-=(uint amount) { index -= amount; return *this; } + inline IndexingIterator& operator+=( int amount) { index += amount; return *this; } + inline IndexingIterator& operator-=( int amount) { index -= amount; return *this; } + + // STL says comparing iterators of different containers is not allowed, so we only compare + // indices here. + inline bool operator==(const IndexingIterator& other) const { return index == other.index; } + inline bool operator!=(const IndexingIterator& other) const { return index != other.index; } + inline bool operator<=(const IndexingIterator& other) const { return index <= other.index; } + inline bool operator>=(const IndexingIterator& other) const { return index >= other.index; } + inline bool operator< (const IndexingIterator& other) const { return index < other.index; } + inline bool operator> (const IndexingIterator& other) const { return index > other.index; } + +private: + Container* container; + uint index; + + friend Container; + inline IndexingIterator(Container* container, uint index) + : container(container), index(index) {} +}; + +} // namespace _ (private) + +template <typename T> +struct List<T, Kind::PRIMITIVE> { + // List of primitives. + + List() = delete; + + class Reader { + public: + typedef List<T> Reads; + + inline Reader(): reader(_::elementSizeForType<T>()) {} + inline explicit Reader(_::ListReader reader): reader(reader) {} + + inline uint size() const { return reader.size() / ELEMENTS; } + inline T operator[](uint index) const { + KJ_IREQUIRE(index < size()); + return reader.template getDataElement<T>(index * ELEMENTS); + } + + typedef _::IndexingIterator<const Reader, T> Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + + private: + _::ListReader reader; + template <typename U, Kind K> + friend struct _::PointerHelpers; + template <typename U, Kind K> + friend struct List; + friend class Orphanage; + template <typename U, Kind K> + friend struct ToDynamic_; + }; + + class Builder { + public: + typedef List<T> Builds; + + inline Builder(): builder(_::elementSizeForType<T>()) {} + inline Builder(decltype(nullptr)) {} + inline explicit Builder(_::ListBuilder builder): builder(builder) {} + + inline operator Reader() const { return Reader(builder.asReader()); } + inline Reader asReader() const { return Reader(builder.asReader()); } + + inline uint size() const { return builder.size() / ELEMENTS; } + inline T operator[](uint index) { + KJ_IREQUIRE(index < size()); + return builder.template getDataElement<T>(index * ELEMENTS); + } + inline void set(uint index, T value) { + // Alas, it is not possible to make operator[] return a reference to which you can assign, + // since the encoded representation does not necessarily match the compiler's representation + // of the type. We can't even return a clever class that implements operator T() and + // operator=() because it will lead to surprising behavior when using type inference (e.g. + // calling a template function with inferred argument types, or using "auto" or "decltype"). + + builder.template setDataElement<T>(index * ELEMENTS, value); + } + + typedef _::IndexingIterator<Builder, T> Iterator; + inline Iterator begin() { return Iterator(this, 0); } + inline Iterator end() { return Iterator(this, size()); } + + private: + _::ListBuilder builder; + template <typename U, Kind K> + friend struct _::PointerHelpers; + friend class Orphanage; + template <typename U, Kind K> + friend struct ToDynamic_; + }; + + class Pipeline {}; + +private: + inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) { + return builder.initList(_::elementSizeForType<T>(), size * ELEMENTS); + } + inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) { + return builder.getList(_::elementSizeForType<T>(), defaultValue); + } + inline static _::ListReader getFromPointer( + const _::PointerReader& reader, const word* defaultValue) { + return reader.getList(_::elementSizeForType<T>(), defaultValue); + } + + template <typename U, Kind k> + friend struct List; + template <typename U, Kind K> + friend struct _::PointerHelpers; +}; + +template <typename T> +struct List<T, Kind::ENUM>: public List<T, Kind::PRIMITIVE> {}; + +template <typename T> +struct List<T, Kind::STRUCT> { + // List of structs. + + List() = delete; + + class Reader { + public: + typedef List<T> Reads; + + inline Reader(): reader(ElementSize::INLINE_COMPOSITE) {} + inline explicit Reader(_::ListReader reader): reader(reader) {} + + inline uint size() const { return reader.size() / ELEMENTS; } + inline typename T::Reader operator[](uint index) const { + KJ_IREQUIRE(index < size()); + return typename T::Reader(reader.getStructElement(index * ELEMENTS)); + } + + typedef _::IndexingIterator<const Reader, typename T::Reader> Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + + private: + _::ListReader reader; + template <typename U, Kind K> + friend struct _::PointerHelpers; + template <typename U, Kind K> + friend struct List; + friend class Orphanage; + template <typename U, Kind K> + friend struct ToDynamic_; + }; + + class Builder { + public: + typedef List<T> Builds; + + inline Builder(): builder(ElementSize::INLINE_COMPOSITE) {} + inline Builder(decltype(nullptr)) {} + inline explicit Builder(_::ListBuilder builder): builder(builder) {} + + inline operator Reader() const { return Reader(builder.asReader()); } + inline Reader asReader() const { return Reader(builder.asReader()); } + + inline uint size() const { return builder.size() / ELEMENTS; } + inline typename T::Builder operator[](uint index) { + KJ_IREQUIRE(index < size()); + return typename T::Builder(builder.getStructElement(index * ELEMENTS)); + } + + inline void adoptWithCaveats(uint index, Orphan<T>&& orphan) { + // Mostly behaves like you'd expect `adopt` to behave, but with two caveats originating from + // the fact that structs in a struct list are allocated inline rather than by pointer: + // * This actually performs a shallow copy, effectively adopting each of the orphan's + // children rather than adopting the orphan itself. The orphan ends up being discarded, + // possibly wasting space in the message object. + // * If the orphan is larger than the target struct -- say, because the orphan was built + // using a newer version of the schema that has additional fields -- it will be truncated, + // losing data. + + KJ_IREQUIRE(index < size()); + + // We pass a zero-valued StructSize to asStruct() because we do not want the struct to be + // expanded under any circumstances. We're just going to throw it away anyway, and + // transferContentFrom() already carefully compares the struct sizes before transferring. + builder.getStructElement(index * ELEMENTS).transferContentFrom( + orphan.builder.asStruct(_::StructSize(0 * WORDS, 0 * POINTERS))); + } + inline void setWithCaveats(uint index, const typename T::Reader& reader) { + // Mostly behaves like you'd expect `set` to behave, but with a caveat originating from + // the fact that structs in a struct list are allocated inline rather than by pointer: + // If the source struct is larger than the target struct -- say, because the source was built + // using a newer version of the schema that has additional fields -- it will be truncated, + // losing data. + // + // Note: If you are trying to concatenate some lists, use Orphanage::newOrphanConcat() to + // do it without losing any data in case the source lists come from a newer version of the + // protocol. (Plus, it's easier to use anyhow.) + + KJ_IREQUIRE(index < size()); + builder.getStructElement(index * ELEMENTS).copyContentFrom(reader._reader); + } + + // There are no init(), set(), adopt(), or disown() methods for lists of structs because the + // elements of the list are inlined and are initialized when the list is initialized. This + // means that init() would be redundant, and set() would risk data loss if the input struct + // were from a newer version of the protocol. + + typedef _::IndexingIterator<Builder, typename T::Builder> Iterator; + inline Iterator begin() { return Iterator(this, 0); } + inline Iterator end() { return Iterator(this, size()); } + + private: + _::ListBuilder builder; + template <typename U, Kind K> + friend struct _::PointerHelpers; + friend class Orphanage; + template <typename U, Kind K> + friend struct ToDynamic_; + }; + + class Pipeline {}; + +private: + inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) { + return builder.initStructList(size * ELEMENTS, _::structSize<T>()); + } + inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) { + return builder.getStructList(_::structSize<T>(), defaultValue); + } + inline static _::ListReader getFromPointer( + const _::PointerReader& reader, const word* defaultValue) { + return reader.getList(ElementSize::INLINE_COMPOSITE, defaultValue); + } + + template <typename U, Kind k> + friend struct List; + template <typename U, Kind K> + friend struct _::PointerHelpers; +}; + +template <typename T> +struct List<List<T>, Kind::LIST> { + // List of lists. + + List() = delete; + + class Reader { + public: + typedef List<List<T>> Reads; + + inline Reader(): reader(ElementSize::POINTER) {} + inline explicit Reader(_::ListReader reader): reader(reader) {} + + inline uint size() const { return reader.size() / ELEMENTS; } + inline typename List<T>::Reader operator[](uint index) const { + KJ_IREQUIRE(index < size()); + return typename List<T>::Reader( + _::PointerHelpers<List<T>>::get(reader.getPointerElement(index * ELEMENTS))); + } + + typedef _::IndexingIterator<const Reader, typename List<T>::Reader> Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + + private: + _::ListReader reader; + template <typename U, Kind K> + friend struct _::PointerHelpers; + template <typename U, Kind K> + friend struct List; + friend class Orphanage; + template <typename U, Kind K> + friend struct ToDynamic_; + }; + + class Builder { + public: + typedef List<List<T>> Builds; + + inline Builder(): builder(ElementSize::POINTER) {} + inline Builder(decltype(nullptr)) {} + inline explicit Builder(_::ListBuilder builder): builder(builder) {} + + inline operator Reader() const { return Reader(builder.asReader()); } + inline Reader asReader() const { return Reader(builder.asReader()); } + + inline uint size() const { return builder.size() / ELEMENTS; } + inline typename List<T>::Builder operator[](uint index) { + KJ_IREQUIRE(index < size()); + return typename List<T>::Builder( + _::PointerHelpers<List<T>>::get(builder.getPointerElement(index * ELEMENTS))); + } + inline typename List<T>::Builder init(uint index, uint size) { + KJ_IREQUIRE(index < this->size()); + return typename List<T>::Builder( + _::PointerHelpers<List<T>>::init(builder.getPointerElement(index * ELEMENTS), size)); + } + inline void set(uint index, typename List<T>::Reader value) { + KJ_IREQUIRE(index < size()); + builder.getPointerElement(index * ELEMENTS).setList(value.reader); + } + void set(uint index, std::initializer_list<ReaderFor<T>> value) { + KJ_IREQUIRE(index < size()); + auto l = init(index, value.size()); + uint i = 0; + for (auto& element: value) { + l.set(i++, element); + } + } + inline void adopt(uint index, Orphan<T>&& value) { + KJ_IREQUIRE(index < size()); + builder.getPointerElement(index * ELEMENTS).adopt(kj::mv(value.builder)); + } + inline Orphan<T> disown(uint index) { + KJ_IREQUIRE(index < size()); + return Orphan<T>(builder.getPointerElement(index * ELEMENTS).disown()); + } + + typedef _::IndexingIterator<Builder, typename List<T>::Builder> Iterator; + inline Iterator begin() { return Iterator(this, 0); } + inline Iterator end() { return Iterator(this, size()); } + + private: + _::ListBuilder builder; + template <typename U, Kind K> + friend struct _::PointerHelpers; + friend class Orphanage; + template <typename U, Kind K> + friend struct ToDynamic_; + }; + + class Pipeline {}; + +private: + inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) { + return builder.initList(ElementSize::POINTER, size * ELEMENTS); + } + inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) { + return builder.getList(ElementSize::POINTER, defaultValue); + } + inline static _::ListReader getFromPointer( + const _::PointerReader& reader, const word* defaultValue) { + return reader.getList(ElementSize::POINTER, defaultValue); + } + + template <typename U, Kind k> + friend struct List; + template <typename U, Kind K> + friend struct _::PointerHelpers; +}; + +template <typename T> +struct List<T, Kind::BLOB> { + List() = delete; + + class Reader { + public: + typedef List<T> Reads; + + inline Reader(): reader(ElementSize::POINTER) {} + inline explicit Reader(_::ListReader reader): reader(reader) {} + + inline uint size() const { return reader.size() / ELEMENTS; } + inline typename T::Reader operator[](uint index) const { + KJ_IREQUIRE(index < size()); + return reader.getPointerElement(index * ELEMENTS).template getBlob<T>(nullptr, 0 * BYTES); + } + + typedef _::IndexingIterator<const Reader, typename T::Reader> Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + + private: + _::ListReader reader; + template <typename U, Kind K> + friend struct _::PointerHelpers; + template <typename U, Kind K> + friend struct List; + friend class Orphanage; + template <typename U, Kind K> + friend struct ToDynamic_; + }; + + class Builder { + public: + typedef List<T> Builds; + + inline Builder(): builder(ElementSize::POINTER) {} + inline Builder(decltype(nullptr)) {} + inline explicit Builder(_::ListBuilder builder): builder(builder) {} + + inline operator Reader() const { return Reader(builder.asReader()); } + inline Reader asReader() const { return Reader(builder.asReader()); } + + inline uint size() const { return builder.size() / ELEMENTS; } + inline typename T::Builder operator[](uint index) { + KJ_IREQUIRE(index < size()); + return builder.getPointerElement(index * ELEMENTS).template getBlob<T>(nullptr, 0 * BYTES); + } + inline void set(uint index, typename T::Reader value) { + KJ_IREQUIRE(index < size()); + builder.getPointerElement(index * ELEMENTS).template setBlob<T>(value); + } + inline typename T::Builder init(uint index, uint size) { + KJ_IREQUIRE(index < this->size()); + return builder.getPointerElement(index * ELEMENTS).template initBlob<T>(size * BYTES); + } + inline void adopt(uint index, Orphan<T>&& value) { + KJ_IREQUIRE(index < size()); + builder.getPointerElement(index * ELEMENTS).adopt(kj::mv(value.builder)); + } + inline Orphan<T> disown(uint index) { + KJ_IREQUIRE(index < size()); + return Orphan<T>(builder.getPointerElement(index * ELEMENTS).disown()); + } + + typedef _::IndexingIterator<Builder, typename T::Builder> Iterator; + inline Iterator begin() { return Iterator(this, 0); } + inline Iterator end() { return Iterator(this, size()); } + + private: + _::ListBuilder builder; + template <typename U, Kind K> + friend struct _::PointerHelpers; + friend class Orphanage; + template <typename U, Kind K> + friend struct ToDynamic_; + }; + + class Pipeline {}; + +private: + inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) { + return builder.initList(ElementSize::POINTER, size * ELEMENTS); + } + inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) { + return builder.getList(ElementSize::POINTER, defaultValue); + } + inline static _::ListReader getFromPointer( + const _::PointerReader& reader, const word* defaultValue) { + return reader.getList(ElementSize::POINTER, defaultValue); + } + + template <typename U, Kind k> + friend struct List; + template <typename U, Kind K> + friend struct _::PointerHelpers; +}; + +} // namespace capnp + +#ifdef KJ_STD_COMPAT +namespace std { + +template <typename Container, typename Element> +struct iterator_traits<capnp::_::IndexingIterator<Container, Element>> + : public std::iterator<std::random_access_iterator_tag, Element, int> {}; + +} // namespace std +#endif // KJ_STD_COMPAT + +#endif // CAPNP_LIST_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/membrane.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,202 @@ +// Copyright (c) 2015 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef CAPNP_MEMBRANE_H_ +#define CAPNP_MEMBRANE_H_ +// In capability theory, a "membrane" is a wrapper around a capability which (usually) forwards +// calls but recursively wraps capabilities in those calls in the same membrane. The purpose of a +// membrane is to enforce a barrier between two capabilities that cannot be bypassed by merely +// introducing new objects. +// +// The most common use case for a membrane is revocation: Say Alice wants to give Bob a capability +// to access Carol, but wants to be able to revoke this capability later. Alice can accomplish this +// by wrapping Carol in a revokable wrapper which passes through calls until such a time as Alice +// indicates it should be revoked, after which all calls through the wrapper will throw exceptions. +// However, a naive wrapper approach has a problem: if Bob makes a call to Carol and sends a new +// capability in that call, or if Carol returns a capability to Bob in the response to a call, then +// the two are now able to communicate using this new capability, which Alice cannot revoke. In +// order to avoid this problem, Alice must use not just a wrapper but a "membrane", which +// recursively wraps all objects that pass through it in either direction. Thus, all connections +// formed between Bob and Carol (originating from Alice's original introduction) can be revoked +// together by revoking the membrane. +// +// Note that when a capability is passed into a membrane and then passed back out, the result is +// the original capability, not a double-membraned capability. This means that in our revocation +// example, if Bob uses his capability to Carol to obtain another capability from her, then send +// it back to her, the capability Carol receives back will NOT be revoked when Bob's access to +// Carol is revoked. Thus Bob can create long-term irrevocable connections. In most practical use +// cases, this is what you want. APIs commonly rely on the fact that a capability obtained and then +// passed back can be recognized as the original capability. +// +// Mark Miller on membranes: http://www.eros-os.org/pipermail/e-lang/2003-January/008434.html + +#include "capability.h" + +namespace capnp { + +class MembranePolicy { + // Applications may implement this interface to define a membrane policy, which allows some + // calls crossing the membrane to be blocked or redirected. + +public: + virtual kj::Maybe<Capability::Client> inboundCall( + uint64_t interfaceId, uint16_t methodId, Capability::Client target) = 0; + // Given an inbound call (a call originating "outside" the membrane destined for an object + // "inside" the membrane), decides what to do with it. The policy may: + // + // - Return null to indicate that the call should proceed to the destination. All capabilities + // in the parameters or result will be properly wrapped in the same membrane. + // - Return a capability to have the call redirected to that capability. Note that the redirect + // capability will be treated as outside the membrane, so the params and results will not be + // auto-wrapped; however, the callee can easily wrap the returned capability in the membrane + // itself before returning to achieve this effect. + // - Throw an exception to cause the call to fail with that exception. + // + // `target` is the underlying capability (*inside* the membrane) for which the call is destined. + // Generally, the only way you should use `target` is to wrap it in some capability which you + // return as a redirect. The redirect capability may modify the call in some way and send it to + // `target`. Be careful to use `copyIntoMembrane()` and `copyOutOfMembrane()` as appropriate when + // copying parameters or results across the membrane. + // + // Note that since `target` is inside the capability, if you were to directly return it (rather + // than return null), the effect would be that the membrane would be broken: the call would + // proceed directly and any new capabilities introduced through it would not be membraned. You + // generally should not do that. + + virtual kj::Maybe<Capability::Client> outboundCall( + uint64_t interfaceId, uint16_t methodId, Capability::Client target) = 0; + // Like `inboundCall()`, but applies to calls originating *inside* the membrane and terminating + // outside. + // + // Note: It is strongly recommended that `outboundCall()` returns null in exactly the same cases + // that `inboundCall()` return null. Conversely, for any case where `inboundCall()` would + // redirect or throw, `outboundCall()` should also redirect or throw. Otherwise, you can run + // into inconsistent behavion when a promise is returned across a membrane, and that promise + // later resolves to a capability on the other side of the membrane: calls on the promise + // will enter and then exit the membrane, but calls on the eventual resolution will not cross + // the membrane at all, so it is important that these two cases behave the same. + + virtual kj::Own<MembranePolicy> addRef() = 0; + // Return a new owned pointer to the same policy. + // + // Typically an implementation of MembranePolicy should also inherit kj::Refcounted and implement + // `addRef()` as `return kj::addRef(*this);`. + // + // Note that the membraning system considers two membranes created with the same MembranePolicy + // object actually to be the *same* membrane. This is relevant when an object passes into the + // membrane and then back out (or out and then back in): instead of double-wrapping the object, + // the wrapping will be removed. +}; + +Capability::Client membrane(Capability::Client inner, kj::Own<MembranePolicy> policy); +// Wrap `inner` in a membrane specified by `policy`. `inner` is considered "inside" the membrane, +// while the returned capability should only be called from outside the membrane. + +Capability::Client reverseMembrane(Capability::Client outer, kj::Own<MembranePolicy> policy); +// Like `membrane` but treat the input capability as "outside" the membrane, and return a +// capability appropriate for use inside. +// +// Applications typically won't use this directly; the membraning code automatically sets up +// reverse membranes where needed. + +template <typename ClientType> +ClientType membrane(ClientType inner, kj::Own<MembranePolicy> policy); +template <typename ClientType> +ClientType reverseMembrane(ClientType inner, kj::Own<MembranePolicy> policy); +// Convenience templates which return the same interface type as the input. + +template <typename ServerType> +typename ServerType::Serves::Client membrane( + kj::Own<ServerType> inner, kj::Own<MembranePolicy> policy); +template <typename ServerType> +typename ServerType::Serves::Client reverseMembrane( + kj::Own<ServerType> inner, kj::Own<MembranePolicy> policy); +// Convenience templates which input a capability server type and return the appropriate client +// type. + +template <typename Reader> +Orphan<typename kj::Decay<Reader>::Reads> copyIntoMembrane( + Reader&& from, Orphanage to, kj::Own<MembranePolicy> policy); +// Copy a Cap'n Proto object (e.g. struct or list), adding the given membrane to any capabilities +// found within it. `from` is interpreted as "outside" the membrane while `to` is "inside". + +template <typename Reader> +Orphan<typename kj::Decay<Reader>::Reads> copyOutOfMembrane( + Reader&& from, Orphanage to, kj::Own<MembranePolicy> policy); +// Like copyIntoMembrane() except that `from` is "inside" the membrane and `to` is "outside". + +// ======================================================================================= +// inline implementation details + +template <typename ClientType> +ClientType membrane(ClientType inner, kj::Own<MembranePolicy> policy) { + return membrane(Capability::Client(kj::mv(inner)), kj::mv(policy)) + .castAs<typename ClientType::Calls>(); +} +template <typename ClientType> +ClientType reverseMembrane(ClientType inner, kj::Own<MembranePolicy> policy) { + return reverseMembrane(Capability::Client(kj::mv(inner)), kj::mv(policy)) + .castAs<typename ClientType::Calls>(); +} + +template <typename ServerType> +typename ServerType::Serves::Client membrane( + kj::Own<ServerType> inner, kj::Own<MembranePolicy> policy) { + return membrane(Capability::Client(kj::mv(inner)), kj::mv(policy)) + .castAs<typename ServerType::Serves::Client>(); +} +template <typename ServerType> +typename ServerType::Serves::Client reverseMembrane( + kj::Own<ServerType> inner, kj::Own<MembranePolicy> policy) { + return reverseMembrane(Capability::Client(kj::mv(inner)), kj::mv(policy)) + .castAs<typename ServerType::Serves::Client>(); +} + +namespace _ { // private + +OrphanBuilder copyOutOfMembrane(PointerReader from, Orphanage to, + kj::Own<MembranePolicy> policy, bool reverse); +OrphanBuilder copyOutOfMembrane(StructReader from, Orphanage to, + kj::Own<MembranePolicy> policy, bool reverse); +OrphanBuilder copyOutOfMembrane(ListReader from, Orphanage to, + kj::Own<MembranePolicy> policy, bool reverse); + +} // namespace _ (private) + +template <typename Reader> +Orphan<typename kj::Decay<Reader>::Reads> copyIntoMembrane( + Reader&& from, Orphanage to, kj::Own<MembranePolicy> policy) { + return _::copyOutOfMembrane( + _::PointerHelpers<typename kj::Decay<Reader>::Reads>::getInternalReader(from), + to, kj::mv(policy), true); +} + +template <typename Reader> +Orphan<typename kj::Decay<Reader>::Reads> copyOutOfMembrane( + Reader&& from, Orphanage to, kj::Own<MembranePolicy> policy) { + return _::copyOutOfMembrane( + _::PointerHelpers<typename kj::Decay<Reader>::Reads>::getInternalReader(from), + to, kj::mv(policy), false); +} + +} // namespace capnp + +#endif // CAPNP_MEMBRANE_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/message.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,508 @@ +// Copyright (c) 2013-2016 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include <kj/common.h> +#include <kj/memory.h> +#include <kj/mutex.h> +#include <kj/debug.h> +#include "common.h" +#include "layout.h" +#include "any.h" + +#ifndef CAPNP_MESSAGE_H_ +#define CAPNP_MESSAGE_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +namespace capnp { + +namespace _ { // private + class ReaderArena; + class BuilderArena; +} + +class StructSchema; +class Orphanage; +template <typename T> +class Orphan; + +// ======================================================================================= + +struct ReaderOptions { + // Options controlling how data is read. + + uint64_t traversalLimitInWords = 8 * 1024 * 1024; + // Limits how many total words of data are allowed to be traversed. Traversal is counted when + // a new struct or list builder is obtained, e.g. from a get() accessor. This means that calling + // the getter for the same sub-struct multiple times will cause it to be double-counted. Once + // the traversal limit is reached, an error will be reported. + // + // This limit exists for security reasons. It is possible for an attacker to construct a message + // in which multiple pointers point at the same location. This is technically invalid, but hard + // to detect. Using such a message, an attacker could cause a message which is small on the wire + // to appear much larger when actually traversed, possibly exhausting server resources leading to + // denial-of-service. + // + // It makes sense to set a traversal limit that is much larger than the underlying message. + // Together with sensible coding practices (e.g. trying to avoid calling sub-object getters + // multiple times, which is expensive anyway), this should provide adequate protection without + // inconvenience. + // + // The default limit is 64 MiB. This may or may not be a sensible number for any given use case, + // but probably at least prevents easy exploitation while also avoiding causing problems in most + // typical cases. + + int nestingLimit = 64; + // Limits how deeply-nested a message structure can be, e.g. structs containing other structs or + // lists of structs. + // + // Like the traversal limit, this limit exists for security reasons. Since it is common to use + // recursive code to traverse recursive data structures, an attacker could easily cause a stack + // overflow by sending a very-deeply-nested (or even cyclic) message, without the message even + // being very large. The default limit of 64 is probably low enough to prevent any chance of + // stack overflow, yet high enough that it is never a problem in practice. +}; + +class MessageReader { + // Abstract interface for an object used to read a Cap'n Proto message. Subclasses of + // MessageReader are responsible for reading the raw, flat message content. Callers should + // usually call `messageReader.getRoot<MyStructType>()` to get a `MyStructType::Reader` + // representing the root of the message, then use that to traverse the message content. + // + // Some common subclasses of `MessageReader` include `SegmentArrayMessageReader`, whose + // constructor accepts pointers to the raw data, and `StreamFdMessageReader` (from + // `serialize.h`), which reads the message from a file descriptor. One might implement other + // subclasses to handle things like reading from shared memory segments, mmap()ed files, etc. + +public: + MessageReader(ReaderOptions options); + // It is suggested that subclasses take ReaderOptions as a constructor parameter, but give it a + // default value of "ReaderOptions()". The base class constructor doesn't have a default value + // in order to remind subclasses that they really need to give the user a way to provide this. + + virtual ~MessageReader() noexcept(false); + + virtual kj::ArrayPtr<const word> getSegment(uint id) = 0; + // Gets the segment with the given ID, or returns null if no such segment exists. This method + // will be called at most once for each segment ID. + + inline const ReaderOptions& getOptions(); + // Get the options passed to the constructor. + + template <typename RootType> + typename RootType::Reader getRoot(); + // Get the root struct of the message, interpreting it as the given struct type. + + template <typename RootType, typename SchemaType> + typename RootType::Reader getRoot(SchemaType schema); + // Dynamically interpret the root struct of the message using the given schema (a StructSchema). + // RootType in this case must be DynamicStruct, and you must #include <capnp/dynamic.h> to + // use this. + + bool isCanonical(); + // Returns whether the message encoded in the reader is in canonical form. + +private: + ReaderOptions options; + + // Space in which we can construct a ReaderArena. We don't use ReaderArena directly here + // because we don't want clients to have to #include arena.h, which itself includes a bunch of + // big STL headers. We don't use a pointer to a ReaderArena because that would require an + // extra malloc on every message which could be expensive when processing small messages. + void* arenaSpace[15 + sizeof(kj::MutexGuarded<void*>) / sizeof(void*)]; + bool allocatedArena; + + _::ReaderArena* arena() { return reinterpret_cast<_::ReaderArena*>(arenaSpace); } + AnyPointer::Reader getRootInternal(); +}; + +class MessageBuilder { + // Abstract interface for an object used to allocate and build a message. Subclasses of + // MessageBuilder are responsible for allocating the space in which the message will be written. + // The most common subclass is `MallocMessageBuilder`, but other subclasses may be used to do + // tricky things like allocate messages in shared memory or mmap()ed files. + // + // Creating a new message ususually means allocating a new MessageBuilder (ideally on the stack) + // and then calling `messageBuilder.initRoot<MyStructType>()` to get a `MyStructType::Builder`. + // That, in turn, can be used to fill in the message content. When done, you can call + // `messageBuilder.getSegmentsForOutput()` to get a list of flat data arrays containing the + // message. + +public: + MessageBuilder(); + virtual ~MessageBuilder() noexcept(false); + KJ_DISALLOW_COPY(MessageBuilder); + + struct SegmentInit { + kj::ArrayPtr<word> space; + + size_t wordsUsed; + // Number of words in `space` which are used; the rest are free space in which additional + // objects may be allocated. + }; + + explicit MessageBuilder(kj::ArrayPtr<SegmentInit> segments); + // Create a MessageBuilder backed by existing memory. This is an advanced interface that most + // people should not use. THIS METHOD IS INSECURE; see below. + // + // This allows a MessageBuilder to be constructed to modify an in-memory message without first + // making a copy of the content. This is especially useful in conjunction with mmap(). + // + // The contents of each segment must outlive the MessageBuilder, but the SegmentInit array itself + // only need outlive the constructor. + // + // SECURITY: Do not use this in conjunction with untrusted data. This constructor assumes that + // the input message is valid. This constructor is designed to be used with data you control, + // e.g. an mmap'd file which is owned and accessed by only one program. When reading data you + // do not trust, you *must* load it into a Reader and then copy into a Builder as a means of + // validating the content. + // + // WARNING: It is NOT safe to initialize a MessageBuilder in this way from memory that is + // currently in use by another MessageBuilder or MessageReader. Other readers/builders will + // not observe changes to the segment sizes nor newly-allocated segments caused by allocating + // new objects in this message. + + virtual kj::ArrayPtr<word> allocateSegment(uint minimumSize) = 0; + // Allocates an array of at least the given number of words, throwing an exception or crashing if + // this is not possible. It is expected that this method will usually return more space than + // requested, and the caller should use that extra space as much as possible before allocating + // more. The returned space remains valid at least until the MessageBuilder is destroyed. + // + // Cap'n Proto will only call this once at a time, so the subclass need not worry about + // thread-safety. + + template <typename RootType> + typename RootType::Builder initRoot(); + // Initialize the root struct of the message as the given struct type. + + template <typename Reader> + void setRoot(Reader&& value); + // Set the root struct to a deep copy of the given struct. + + template <typename RootType> + typename RootType::Builder getRoot(); + // Get the root struct of the message, interpreting it as the given struct type. + + template <typename RootType, typename SchemaType> + typename RootType::Builder getRoot(SchemaType schema); + // Dynamically interpret the root struct of the message using the given schema (a StructSchema). + // RootType in this case must be DynamicStruct, and you must #include <capnp/dynamic.h> to + // use this. + + template <typename RootType, typename SchemaType> + typename RootType::Builder initRoot(SchemaType schema); + // Dynamically init the root struct of the message using the given schema (a StructSchema). + // RootType in this case must be DynamicStruct, and you must #include <capnp/dynamic.h> to + // use this. + + template <typename T> + void adoptRoot(Orphan<T>&& orphan); + // Like setRoot() but adopts the orphan without copying. + + kj::ArrayPtr<const kj::ArrayPtr<const word>> getSegmentsForOutput(); + // Get the raw data that makes up the message. + + Orphanage getOrphanage(); + + bool isCanonical(); + // Check whether the message builder is in canonical form + +private: + void* arenaSpace[22]; + // Space in which we can construct a BuilderArena. We don't use BuilderArena directly here + // because we don't want clients to have to #include arena.h, which itself includes a bunch of + // big STL headers. We don't use a pointer to a BuilderArena because that would require an + // extra malloc on every message which could be expensive when processing small messages. + + bool allocatedArena = false; + // We have to initialize the arena lazily because when we do so we want to allocate the root + // pointer immediately, and this will allocate a segment, which requires a virtual function + // call on the MessageBuilder. We can't do such a call in the constructor since the subclass + // isn't constructed yet. This is kind of annoying because it means that getOrphanage() is + // not thread-safe, but that shouldn't be a huge deal... + + _::BuilderArena* arena() { return reinterpret_cast<_::BuilderArena*>(arenaSpace); } + _::SegmentBuilder* getRootSegment(); + AnyPointer::Builder getRootInternal(); +}; + +template <typename RootType> +typename RootType::Reader readMessageUnchecked(const word* data); +// IF THE INPUT IS INVALID, THIS MAY CRASH, CORRUPT MEMORY, CREATE A SECURITY HOLE IN YOUR APP, +// MURDER YOUR FIRST-BORN CHILD, AND/OR BRING ABOUT ETERNAL DAMNATION ON ALL OF HUMANITY. DO NOT +// USE UNLESS YOU UNDERSTAND THE CONSEQUENCES. +// +// Given a pointer to a known-valid message located in a single contiguous memory segment, +// returns a reader for that message. No bounds-checking will be done while traversing this +// message. Use this only if you have already verified that all pointers are valid and in-bounds, +// and there are no far pointers in the message. +// +// To create a message that can be passed to this function, build a message using a MallocAllocator +// whose preferred segment size is larger than the message size. This guarantees that the message +// will be allocated as a single segment, meaning getSegmentsForOutput() returns a single word +// array. That word array is your message; you may pass a pointer to its first word into +// readMessageUnchecked() to read the message. +// +// This can be particularly handy for embedding messages in generated code: you can +// embed the raw bytes (using AlignedData) then make a Reader for it using this. This is the way +// default values are embedded in code generated by the Cap'n Proto compiler. E.g., if you have +// a message MyMessage, you can read its default value like so: +// MyMessage::Reader reader = Message<MyMessage>::readMessageUnchecked(MyMessage::DEFAULT.words); +// +// To sanitize a message from an untrusted source such that it can be safely passed to +// readMessageUnchecked(), use copyToUnchecked(). + +template <typename Reader> +void copyToUnchecked(Reader&& reader, kj::ArrayPtr<word> uncheckedBuffer); +// Copy the content of the given reader into the given buffer, such that it can safely be passed to +// readMessageUnchecked(). The buffer's size must be exactly reader.totalSizeInWords() + 1, +// otherwise an exception will be thrown. The buffer must be zero'd before calling. + +template <typename RootType> +typename RootType::Reader readDataStruct(kj::ArrayPtr<const word> data); +// Interprets the given data as a single, data-only struct. Only primitive fields (booleans, +// numbers, and enums) will be readable; all pointers will be null. This is useful if you want +// to use Cap'n Proto as a language/platform-neutral way to pack some bits. +// +// The input is a word array rather than a byte array to enforce alignment. If you have a byte +// array which you know is word-aligned (or if your platform supports unaligned reads and you don't +// mind the performance penalty), then you can use `reinterpret_cast` to convert a byte array into +// a word array: +// +// kj::arrayPtr(reinterpret_cast<const word*>(bytes.begin()), +// reinterpret_cast<const word*>(bytes.end())) + +template <typename BuilderType> +typename kj::ArrayPtr<const word> writeDataStruct(BuilderType builder); +// Given a struct builder, get the underlying data section as a word array, suitable for passing +// to `readDataStruct()`. +// +// Note that you may call `.toBytes()` on the returned value to convert to `ArrayPtr<const byte>`. + +template <typename Type> +static typename Type::Reader defaultValue(); +// Get a default instance of the given struct or list type. +// +// TODO(cleanup): Find a better home for this function? + +// ======================================================================================= + +class SegmentArrayMessageReader: public MessageReader { + // A simple MessageReader that reads from an array of word arrays representing all segments. + // In particular you can read directly from the output of MessageBuilder::getSegmentsForOutput() + // (although it would probably make more sense to call builder.getRoot().asReader() in that case). + +public: + SegmentArrayMessageReader(kj::ArrayPtr<const kj::ArrayPtr<const word>> segments, + ReaderOptions options = ReaderOptions()); + // Creates a message pointing at the given segment array, without taking ownership of the + // segments. All arrays passed in must remain valid until the MessageReader is destroyed. + + KJ_DISALLOW_COPY(SegmentArrayMessageReader); + ~SegmentArrayMessageReader() noexcept(false); + + virtual kj::ArrayPtr<const word> getSegment(uint id) override; + +private: + kj::ArrayPtr<const kj::ArrayPtr<const word>> segments; +}; + +enum class AllocationStrategy: uint8_t { + FIXED_SIZE, + // The builder will prefer to allocate the same amount of space for each segment with no + // heuristic growth. It will still allocate larger segments when the preferred size is too small + // for some single object. This mode is generally not recommended, but can be particularly useful + // for testing in order to force a message to allocate a predictable number of segments. Note + // that you can force every single object in the message to be located in a separate segment by + // using this mode with firstSegmentWords = 0. + + GROW_HEURISTICALLY + // The builder will heuristically decide how much space to allocate for each segment. Each + // allocated segment will be progressively larger than the previous segments on the assumption + // that message sizes are exponentially distributed. The total number of segments that will be + // allocated for a message of size n is O(log n). +}; + +constexpr uint SUGGESTED_FIRST_SEGMENT_WORDS = 1024; +constexpr AllocationStrategy SUGGESTED_ALLOCATION_STRATEGY = AllocationStrategy::GROW_HEURISTICALLY; + +class MallocMessageBuilder: public MessageBuilder { + // A simple MessageBuilder that uses malloc() (actually, calloc()) to allocate segments. This + // implementation should be reasonable for any case that doesn't require writing the message to + // a specific location in memory. + +public: + explicit MallocMessageBuilder(uint firstSegmentWords = SUGGESTED_FIRST_SEGMENT_WORDS, + AllocationStrategy allocationStrategy = SUGGESTED_ALLOCATION_STRATEGY); + // Creates a BuilderContext which allocates at least the given number of words for the first + // segment, and then uses the given strategy to decide how much to allocate for subsequent + // segments. When choosing a value for firstSegmentWords, consider that: + // 1) Reading and writing messages gets slower when multiple segments are involved, so it's good + // if most messages fit in a single segment. + // 2) Unused bytes will not be written to the wire, so generally it is not a big deal to allocate + // more space than you need. It only becomes problematic if you are allocating many messages + // in parallel and thus use lots of memory, or if you allocate so much extra space that just + // zeroing it out becomes a bottleneck. + // The defaults have been chosen to be reasonable for most people, so don't change them unless you + // have reason to believe you need to. + + explicit MallocMessageBuilder(kj::ArrayPtr<word> firstSegment, + AllocationStrategy allocationStrategy = SUGGESTED_ALLOCATION_STRATEGY); + // This version always returns the given array for the first segment, and then proceeds with the + // allocation strategy. This is useful for optimization when building lots of small messages in + // a tight loop: you can reuse the space for the first segment. + // + // firstSegment MUST be zero-initialized. MallocMessageBuilder's destructor will write new zeros + // over any space that was used so that it can be reused. + + KJ_DISALLOW_COPY(MallocMessageBuilder); + virtual ~MallocMessageBuilder() noexcept(false); + + virtual kj::ArrayPtr<word> allocateSegment(uint minimumSize) override; + +private: + uint nextSize; + AllocationStrategy allocationStrategy; + + bool ownFirstSegment; + bool returnedFirstSegment; + + void* firstSegment; + + struct MoreSegments; + kj::Maybe<kj::Own<MoreSegments>> moreSegments; +}; + +class FlatMessageBuilder: public MessageBuilder { + // THIS IS NOT THE CLASS YOU'RE LOOKING FOR. + // + // If you want to write a message into already-existing scratch space, use `MallocMessageBuilder` + // and pass the scratch space to its constructor. It will then only fall back to malloc() if + // the scratch space is not large enough. + // + // Do NOT use this class unless you really know what you're doing. This class is problematic + // because it requires advance knowledge of the size of your message, which is usually impossible + // to determine without actually building the message. The class was created primarily to + // implement `copyToUnchecked()`, which itself exists only to support other internal parts of + // the Cap'n Proto implementation. + +public: + explicit FlatMessageBuilder(kj::ArrayPtr<word> array); + KJ_DISALLOW_COPY(FlatMessageBuilder); + virtual ~FlatMessageBuilder() noexcept(false); + + void requireFilled(); + // Throws an exception if the flat array is not exactly full. + + virtual kj::ArrayPtr<word> allocateSegment(uint minimumSize) override; + +private: + kj::ArrayPtr<word> array; + bool allocated; +}; + +// ======================================================================================= +// implementation details + +inline const ReaderOptions& MessageReader::getOptions() { + return options; +} + +template <typename RootType> +inline typename RootType::Reader MessageReader::getRoot() { + return getRootInternal().getAs<RootType>(); +} + +template <typename RootType> +inline typename RootType::Builder MessageBuilder::initRoot() { + return getRootInternal().initAs<RootType>(); +} + +template <typename Reader> +inline void MessageBuilder::setRoot(Reader&& value) { + getRootInternal().setAs<FromReader<Reader>>(value); +} + +template <typename RootType> +inline typename RootType::Builder MessageBuilder::getRoot() { + return getRootInternal().getAs<RootType>(); +} + +template <typename T> +void MessageBuilder::adoptRoot(Orphan<T>&& orphan) { + return getRootInternal().adopt(kj::mv(orphan)); +} + +template <typename RootType, typename SchemaType> +typename RootType::Reader MessageReader::getRoot(SchemaType schema) { + return getRootInternal().getAs<RootType>(schema); +} + +template <typename RootType, typename SchemaType> +typename RootType::Builder MessageBuilder::getRoot(SchemaType schema) { + return getRootInternal().getAs<RootType>(schema); +} + +template <typename RootType, typename SchemaType> +typename RootType::Builder MessageBuilder::initRoot(SchemaType schema) { + return getRootInternal().initAs<RootType>(schema); +} + +template <typename RootType> +typename RootType::Reader readMessageUnchecked(const word* data) { + return AnyPointer::Reader(_::PointerReader::getRootUnchecked(data)).getAs<RootType>(); +} + +template <typename Reader> +void copyToUnchecked(Reader&& reader, kj::ArrayPtr<word> uncheckedBuffer) { + FlatMessageBuilder builder(uncheckedBuffer); + builder.setRoot(kj::fwd<Reader>(reader)); + builder.requireFilled(); +} + +template <typename RootType> +typename RootType::Reader readDataStruct(kj::ArrayPtr<const word> data) { + return typename RootType::Reader(_::StructReader(data)); +} + +template <typename BuilderType> +typename kj::ArrayPtr<const word> writeDataStruct(BuilderType builder) { + auto bytes = _::PointerHelpers<FromBuilder<BuilderType>>::getInternalBuilder(kj::mv(builder)) + .getDataSectionAsBlob(); + return kj::arrayPtr(reinterpret_cast<word*>(bytes.begin()), + reinterpret_cast<word*>(bytes.end())); +} + +template <typename Type> +static typename Type::Reader defaultValue() { + return typename Type::Reader(_::StructReader()); +} + +template <typename T> +kj::Array<word> canonicalize(T&& reader) { + return _::PointerHelpers<FromReader<T>>::getInternalReader(reader).canonicalize(); +} + +} // namespace capnp + +#endif // CAPNP_MESSAGE_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/orphan.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,440 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef CAPNP_ORPHAN_H_ +#define CAPNP_ORPHAN_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "layout.h" + +namespace capnp { + +class StructSchema; +class ListSchema; +struct DynamicStruct; +struct DynamicList; +namespace _ { struct OrphanageInternal; } + +template <typename T> +class Orphan { + // Represents an object which is allocated within some message builder but has no pointers + // pointing at it. An Orphan can later be "adopted" by some other object as one of that object's + // fields, without having to copy the orphan. For a field `foo` of pointer type, the generated + // code will define builder methods `void adoptFoo(Orphan<T>)` and `Orphan<T> disownFoo()`. + // Orphans can also be created independently of any parent using an Orphanage. + // + // `Orphan<T>` can be moved but not copied, like `Own<T>`, so that it is impossible for one + // orphan to be adopted multiple times. If an orphan is destroyed without being adopted, its + // contents are zero'd out (and possibly reused, if we ever implement the ability to reuse space + // in a message arena). + +public: + Orphan() = default; + KJ_DISALLOW_COPY(Orphan); + Orphan(Orphan&&) = default; + Orphan& operator=(Orphan&&) = default; + inline Orphan(_::OrphanBuilder&& builder): builder(kj::mv(builder)) {} + + inline BuilderFor<T> get(); + // Get the underlying builder. If the orphan is null, this will allocate and return a default + // object rather than crash. This is done for security -- otherwise, you might enable a DoS + // attack any time you disown a field and fail to check if it is null. In the case of structs, + // this means that the orphan is no longer null after get() returns. In the case of lists, + // no actual object is allocated since a simple empty ListBuilder can be returned. + + inline ReaderFor<T> getReader() const; + + inline bool operator==(decltype(nullptr)) const { return builder == nullptr; } + inline bool operator!=(decltype(nullptr)) const { return builder != nullptr; } + + inline void truncate(uint size); + // Resize an object (which must be a list or a blob) to the given size. + // + // If the new size is less than the original, the remaining elements will be discarded. The + // list is never moved in this case. If the list happens to be located at the end of its segment + // (which is always true if the list was the last thing allocated), the removed memory will be + // reclaimed (reducing the messag size), otherwise it is simply zeroed. The reclaiming behavior + // is particularly useful for allocating buffer space when you aren't sure how much space you + // actually need: you can pre-allocate, say, a 4k byte array, read() from a file into it, and + // then truncate it back to the amount of space actually used. + // + // If the new size is greater than the original, the list is extended with default values. If + // the list is the last object in its segment *and* there is enough space left in the segment to + // extend it to cover the new values, then the list is extended in-place. Otherwise, it must be + // moved to a new location, leaving a zero'd hole in the previous space that won't be filled. + // This copy is shallow; sub-objects will simply be reparented, not copied. + // + // Any existing readers or builders pointing at the object are invalidated by this call (even if + // it doesn't move). You must call `get()` or `getReader()` again to get the new, valid pointer. + +private: + _::OrphanBuilder builder; + + template <typename, Kind> + friend struct _::PointerHelpers; + template <typename, Kind> + friend struct List; + template <typename U> + friend class Orphan; + friend class Orphanage; + friend class MessageBuilder; +}; + +class Orphanage: private kj::DisallowConstCopy { + // Use to directly allocate Orphan objects, without having a parent object allocate and then + // disown the object. + +public: + inline Orphanage(): arena(nullptr) {} + + template <typename BuilderType> + static Orphanage getForMessageContaining(BuilderType builder); + // Construct an Orphanage that allocates within the message containing the given Builder. This + // allows the constructed Orphans to be adopted by objects within said message. + // + // This constructor takes the builder rather than having the builder have a getOrphanage() method + // because this is an advanced feature and we don't want to pollute the builder APIs with it. + // + // Note that if you have a direct pointer to the `MessageBuilder`, you can simply call its + // `getOrphanage()` method. + + template <typename RootType> + Orphan<RootType> newOrphan() const; + // Allocate a new orphaned struct. + + template <typename RootType> + Orphan<RootType> newOrphan(uint size) const; + // Allocate a new orphaned list or blob. + + Orphan<DynamicStruct> newOrphan(StructSchema schema) const; + // Dynamically create an orphan struct with the given schema. You must + // #include <capnp/dynamic.h> to use this. + + Orphan<DynamicList> newOrphan(ListSchema schema, uint size) const; + // Dynamically create an orphan list with the given schema. You must #include <capnp/dynamic.h> + // to use this. + + template <typename Reader> + Orphan<FromReader<Reader>> newOrphanCopy(Reader copyFrom) const; + // Allocate a new orphaned object (struct, list, or blob) and initialize it as a copy of the + // given object. + + template <typename T> + Orphan<List<ListElementType<FromReader<T>>>> newOrphanConcat(kj::ArrayPtr<T> lists) const; + template <typename T> + Orphan<List<ListElementType<FromReader<T>>>> newOrphanConcat(kj::ArrayPtr<const T> lists) const; + // Given an array of List readers, copy and concatenate the lists, creating a new Orphan. + // + // Note that compared to allocating the list yourself and using `setWithCaveats()` to set each + // item, this method avoids the "caveats": the new list will be allocated with the element size + // being the maximum of that from all the input lists. This is particularly important when + // concatenating struct lists: if the lists were created using a newer version of the protocol + // in which some new fields had been added to the struct, using `setWithCaveats()` would + // truncate off those new fields. + + Orphan<Data> referenceExternalData(Data::Reader data) const; + // Creates an Orphan<Data> that points at an existing region of memory (e.g. from another message) + // without copying it. There are some SEVERE restrictions on how this can be used: + // - The memory must remain valid until the `MessageBuilder` is destroyed (even if the orphan is + // abandoned). + // - Because the data is const, you will not be allowed to obtain a `Data::Builder` + // for this blob. Any call which would return such a builder will throw an exception. You + // can, however, obtain a Reader, e.g. via orphan.getReader() or from a parent Reader (once + // the orphan is adopted). It is your responsibility to make sure your code can deal with + // these problems when using this optimization; if you can't, allocate a copy instead. + // - `data.begin()` must be aligned to a machine word boundary (32-bit or 64-bit depending on + // the CPU). Any pointer returned by malloc() as well as any data blob obtained from another + // Cap'n Proto message satisfies this. + // - If `data.size()` is not a multiple of 8, extra bytes past data.end() up until the next 8-byte + // boundary will be visible in the raw message when it is written out. Thus, there must be no + // secrets in these bytes. Data blobs obtained from other Cap'n Proto messages should be safe + // as these bytes should be zero (unless the sender had the same problem). + // + // The array will actually become one of the message's segments. The data can thus be adopted + // into the message tree without copying it. This is particularly useful when referencing very + // large blobs, such as whole mmap'd files. + +private: + _::BuilderArena* arena; + _::CapTableBuilder* capTable; + + inline explicit Orphanage(_::BuilderArena* arena, _::CapTableBuilder* capTable) + : arena(arena), capTable(capTable) {} + + template <typename T, Kind = CAPNP_KIND(T)> + struct GetInnerBuilder; + template <typename T, Kind = CAPNP_KIND(T)> + struct GetInnerReader; + template <typename T> + struct NewOrphanListImpl; + + friend class MessageBuilder; + friend struct _::OrphanageInternal; +}; + +// ======================================================================================= +// Inline implementation details. + +namespace _ { // private + +template <typename T, Kind = CAPNP_KIND(T)> +struct OrphanGetImpl; + +template <typename T> +struct OrphanGetImpl<T, Kind::PRIMITIVE> { + static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { + builder.truncate(size, _::elementSizeForType<T>()); + } +}; + +template <typename T> +struct OrphanGetImpl<T, Kind::STRUCT> { + static inline typename T::Builder apply(_::OrphanBuilder& builder) { + return typename T::Builder(builder.asStruct(_::structSize<T>())); + } + static inline typename T::Reader applyReader(const _::OrphanBuilder& builder) { + return typename T::Reader(builder.asStructReader(_::structSize<T>())); + } + static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { + builder.truncate(size, _::structSize<T>()); + } +}; + +#if !CAPNP_LITE +template <typename T> +struct OrphanGetImpl<T, Kind::INTERFACE> { + static inline typename T::Client apply(_::OrphanBuilder& builder) { + return typename T::Client(builder.asCapability()); + } + static inline typename T::Client applyReader(const _::OrphanBuilder& builder) { + return typename T::Client(builder.asCapability()); + } + static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { + builder.truncate(size, ElementSize::POINTER); + } +}; +#endif // !CAPNP_LITE + +template <typename T, Kind k> +struct OrphanGetImpl<List<T, k>, Kind::LIST> { + static inline typename List<T>::Builder apply(_::OrphanBuilder& builder) { + return typename List<T>::Builder(builder.asList(_::ElementSizeForType<T>::value)); + } + static inline typename List<T>::Reader applyReader(const _::OrphanBuilder& builder) { + return typename List<T>::Reader(builder.asListReader(_::ElementSizeForType<T>::value)); + } + static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { + builder.truncate(size, ElementSize::POINTER); + } +}; + +template <typename T> +struct OrphanGetImpl<List<T, Kind::STRUCT>, Kind::LIST> { + static inline typename List<T>::Builder apply(_::OrphanBuilder& builder) { + return typename List<T>::Builder(builder.asStructList(_::structSize<T>())); + } + static inline typename List<T>::Reader applyReader(const _::OrphanBuilder& builder) { + return typename List<T>::Reader(builder.asListReader(_::ElementSizeForType<T>::value)); + } + static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { + builder.truncate(size, ElementSize::POINTER); + } +}; + +template <> +struct OrphanGetImpl<Text, Kind::BLOB> { + static inline Text::Builder apply(_::OrphanBuilder& builder) { + return Text::Builder(builder.asText()); + } + static inline Text::Reader applyReader(const _::OrphanBuilder& builder) { + return Text::Reader(builder.asTextReader()); + } + static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { + builder.truncate(size, ElementSize::POINTER); + } +}; + +template <> +struct OrphanGetImpl<Data, Kind::BLOB> { + static inline Data::Builder apply(_::OrphanBuilder& builder) { + return Data::Builder(builder.asData()); + } + static inline Data::Reader applyReader(const _::OrphanBuilder& builder) { + return Data::Reader(builder.asDataReader()); + } + static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { + builder.truncate(size, ElementSize::POINTER); + } +}; + +struct OrphanageInternal { + static inline _::BuilderArena* getArena(Orphanage orphanage) { return orphanage.arena; } + static inline _::CapTableBuilder* getCapTable(Orphanage orphanage) { return orphanage.capTable; } +}; + +} // namespace _ (private) + +template <typename T> +inline BuilderFor<T> Orphan<T>::get() { + return _::OrphanGetImpl<T>::apply(builder); +} + +template <typename T> +inline ReaderFor<T> Orphan<T>::getReader() const { + return _::OrphanGetImpl<T>::applyReader(builder); +} + +template <typename T> +inline void Orphan<T>::truncate(uint size) { + _::OrphanGetImpl<ListElementType<T>>::truncateListOf(builder, size * ELEMENTS); +} + +template <> +inline void Orphan<Text>::truncate(uint size) { + builder.truncateText(size * ELEMENTS); +} + +template <> +inline void Orphan<Data>::truncate(uint size) { + builder.truncate(size * ELEMENTS, ElementSize::BYTE); +} + +template <typename T> +struct Orphanage::GetInnerBuilder<T, Kind::STRUCT> { + static inline _::StructBuilder apply(typename T::Builder& t) { + return t._builder; + } +}; + +template <typename T> +struct Orphanage::GetInnerBuilder<T, Kind::LIST> { + static inline _::ListBuilder apply(typename T::Builder& t) { + return t.builder; + } +}; + +template <typename BuilderType> +Orphanage Orphanage::getForMessageContaining(BuilderType builder) { + auto inner = GetInnerBuilder<FromBuilder<BuilderType>>::apply(builder); + return Orphanage(inner.getArena(), inner.getCapTable()); +} + +template <typename RootType> +Orphan<RootType> Orphanage::newOrphan() const { + return Orphan<RootType>(_::OrphanBuilder::initStruct(arena, capTable, _::structSize<RootType>())); +} + +template <typename T, Kind k> +struct Orphanage::NewOrphanListImpl<List<T, k>> { + static inline _::OrphanBuilder apply( + _::BuilderArena* arena, _::CapTableBuilder* capTable, uint size) { + return _::OrphanBuilder::initList( + arena, capTable, size * ELEMENTS, _::ElementSizeForType<T>::value); + } +}; + +template <typename T> +struct Orphanage::NewOrphanListImpl<List<T, Kind::STRUCT>> { + static inline _::OrphanBuilder apply( + _::BuilderArena* arena, _::CapTableBuilder* capTable, uint size) { + return _::OrphanBuilder::initStructList( + arena, capTable, size * ELEMENTS, _::structSize<T>()); + } +}; + +template <> +struct Orphanage::NewOrphanListImpl<Text> { + static inline _::OrphanBuilder apply( + _::BuilderArena* arena, _::CapTableBuilder* capTable, uint size) { + return _::OrphanBuilder::initText(arena, capTable, size * BYTES); + } +}; + +template <> +struct Orphanage::NewOrphanListImpl<Data> { + static inline _::OrphanBuilder apply( + _::BuilderArena* arena, _::CapTableBuilder* capTable, uint size) { + return _::OrphanBuilder::initData(arena, capTable, size * BYTES); + } +}; + +template <typename RootType> +Orphan<RootType> Orphanage::newOrphan(uint size) const { + return Orphan<RootType>(NewOrphanListImpl<RootType>::apply(arena, capTable, size)); +} + +template <typename T> +struct Orphanage::GetInnerReader<T, Kind::STRUCT> { + static inline _::StructReader apply(const typename T::Reader& t) { + return t._reader; + } +}; + +template <typename T> +struct Orphanage::GetInnerReader<T, Kind::LIST> { + static inline _::ListReader apply(const typename T::Reader& t) { + return t.reader; + } +}; + +template <typename T> +struct Orphanage::GetInnerReader<T, Kind::BLOB> { + static inline const typename T::Reader& apply(const typename T::Reader& t) { + return t; + } +}; + +template <typename Reader> +inline Orphan<FromReader<Reader>> Orphanage::newOrphanCopy(Reader copyFrom) const { + return Orphan<FromReader<Reader>>(_::OrphanBuilder::copy( + arena, capTable, GetInnerReader<FromReader<Reader>>::apply(copyFrom))); +} + +template <typename T> +inline Orphan<List<ListElementType<FromReader<T>>>> +Orphanage::newOrphanConcat(kj::ArrayPtr<T> lists) const { + return newOrphanConcat(kj::implicitCast<kj::ArrayPtr<const T>>(lists)); +} +template <typename T> +inline Orphan<List<ListElementType<FromReader<T>>>> +Orphanage::newOrphanConcat(kj::ArrayPtr<const T> lists) const { + // Optimization / simplification: Rely on List<T>::Reader containing nothing except a + // _::ListReader. + static_assert(sizeof(T) == sizeof(_::ListReader), "lists are not bare readers?"); + kj::ArrayPtr<const _::ListReader> raw( + reinterpret_cast<const _::ListReader*>(lists.begin()), lists.size()); + typedef ListElementType<FromReader<T>> Element; + return Orphan<List<Element>>( + _::OrphanBuilder::concat(arena, capTable, + _::elementSizeForType<Element>(), + _::minStructSizeForElement<Element>(), raw)); +} + +inline Orphan<Data> Orphanage::referenceExternalData(Data::Reader data) const { + return Orphan<Data>(_::OrphanBuilder::referenceExternalData(arena, data)); +} + +} // namespace capnp + +#endif // CAPNP_ORPHAN_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/persistent.capnp Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,139 @@ +# Copyright (c) 2014 Sandstorm Development Group, Inc. and contributors +# Licensed under the MIT License: +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +@0xb8630836983feed7; + +$import "/capnp/c++.capnp".namespace("capnp"); + +interface Persistent@0xc8cb212fcd9f5691(SturdyRef, Owner) { + # Interface implemented by capabilities that outlive a single connection. A client may save() + # the capability, producing a SturdyRef. The SturdyRef can be stored to disk, then later used to + # obtain a new reference to the capability on a future connection. + # + # The exact format of SturdyRef depends on the "realm" in which the SturdyRef appears. A "realm" + # is an abstract space in which all SturdyRefs have the same format and refer to the same set of + # resources. Every vat is in exactly one realm. All capability clients within that vat must + # produce SturdyRefs of the format appropriate for the realm. + # + # Similarly, every VatNetwork also resides in a particular realm. Usually, a vat's "realm" + # corresponds to the realm of its main VatNetwork. However, a Vat can in fact communicate over + # a VatNetwork in a different realm -- in this case, all SturdyRefs need to be transformed when + # coming or going through said VatNetwork. The RPC system has hooks for registering + # transformation callbacks for this purpose. + # + # Since the format of SturdyRef is realm-dependent, it is not defined here. An application should + # choose an appropriate realm for itself as part of its design. Note that under Sandstorm, every + # application exists in its own realm and is therefore free to define its own SturdyRef format; + # the Sandstorm platform handles translating between realms. + # + # Note that whether a capability is persistent is often orthogonal to its type. In these cases, + # the capability's interface should NOT inherit `Persistent`; instead, just perform a cast at + # runtime. It's not type-safe, but trying to be type-safe in these cases will likely lead to + # tears. In cases where a particular interface only makes sense on persistent capabilities, it + # still should not explicitly inherit Persistent because the `SturdyRef` and `Owner` types will + # vary between realms (they may even be different at the call site than they are on the + # implementation). Instead, mark persistent interfaces with the $persistent annotation (defined + # below). + # + # Sealing + # ------- + # + # As an added security measure, SturdyRefs may be "sealed" to a particular owner, such that + # if the SturdyRef itself leaks to a third party, that party cannot actually restore it because + # they are not the owner. To restore a sealed capability, you must first prove to its host that + # you are the rightful owner. The precise mechanism for this authentication is defined by the + # realm. + # + # Sealing is a defense-in-depth mechanism meant to mitigate damage in the case of catastrophic + # attacks. For example, say an attacker temporarily gains read access to a database full of + # SturdyRefs: it would be unfortunate if it were then necessary to revoke every single reference + # in the database to prevent the attacker from using them. + # + # In general, an "owner" is a course-grained identity. Because capability-based security is still + # the primary mechanism of security, it is not necessary nor desirable to have a separate "owner" + # identity for every single process or object; that is exactly what capabilities are supposed to + # avoid! Instead, it makes sense for an "owner" to literally identify the owner of the machines + # where the capability is stored. If untrusted third parties are able to run arbitrary code on + # said machines, then the sandbox for that code should be designed using Distributed Confinement + # such that the third-party code never sees the bits of the SturdyRefs and cannot directly + # exercise the owner's power to restore refs. See: + # + # http://www.erights.org/elib/capability/dist-confine.html + # + # Resist the urge to represent an Owner as a simple public key. The whole point of sealing is to + # defend against leaked-storage attacks. Such attacks can easily result in the owner's private + # key being stolen as well. A better solution is for `Owner` to contain a simple globally unique + # identifier for the owner, and for everyone to separately maintain a mapping of owner IDs to + # public keys. If an owner's private key is compromised, then humans will need to communicate + # and agree on a replacement public key, then update the mapping. + # + # As a concrete example, an `Owner` could simply contain a domain name, and restoring a SturdyRef + # would require signing a request using the domain's private key. Authenticating this key could + # be accomplished through certificate authorities or web-of-trust techniques. + + save @0 SaveParams -> SaveResults; + # Save a capability persistently so that it can be restored by a future connection. Not all + # capabilities can be saved -- application interfaces should define which capabilities support + # this and which do not. + + struct SaveParams { + sealFor @0 :Owner; + # Seal the SturdyRef so that it can only be restored by the specified Owner. This is meant + # to mitigate damage when a SturdyRef is leaked. See comments above. + # + # Leaving this value null may or may not be allowed; it is up to the realm to decide. If a + # realm does allow a null owner, this should indicate that anyone is allowed to restore the + # ref. + } + struct SaveResults { + sturdyRef @0 :SturdyRef; + } +} + +interface RealmGateway(InternalRef, ExternalRef, InternalOwner, ExternalOwner) { + # Interface invoked when a SturdyRef is about to cross realms. The RPC system supports providing + # a RealmGateway as a callback hook when setting up RPC over some VatNetwork. + + import @0 (cap :Persistent(ExternalRef, ExternalOwner), + params :Persistent(InternalRef, InternalOwner).SaveParams) + -> Persistent(InternalRef, InternalOwner).SaveResults; + # Given an external capability, save it and return an internal reference. Used when someone + # inside the realm tries to save a capability from outside the realm. + + export @1 (cap :Persistent(InternalRef, InternalOwner), + params :Persistent(ExternalRef, ExternalOwner).SaveParams) + -> Persistent(ExternalRef, ExternalOwner).SaveResults; + # Given an internal capability, save it and return an external reference. Used when someone + # outside the realm tries to save a capability from inside the realm. +} + +annotation persistent(interface, field) :Void; +# Apply this annotation to interfaces for objects that will always be persistent, instead of +# extending the Persistent capability, since the correct type parameters to Persistent depend on +# the realm, which is orthogonal to the interface type and therefore should not be defined +# along-side it. +# +# You may also apply this annotation to a capability-typed field which will always contain a +# persistent capability, but where the capability's interface itself is not already marked +# persistent. +# +# Note that absence of the $persistent annotation doesn't mean a capability of that type isn't +# persistent; it just means not *all* such capabilities are persistent.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/persistent.capnp.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,1328 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: persistent.capnp + +#ifndef CAPNP_INCLUDED_b8630836983feed7_ +#define CAPNP_INCLUDED_b8630836983feed7_ + +#include <capnp/generated-header-support.h> +#if !CAPNP_LITE +#include <capnp/capability.h> +#endif // !CAPNP_LITE + +#if CAPNP_VERSION != 6000 +#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." +#endif + + +namespace capnp { +namespace schemas { + +CAPNP_DECLARE_SCHEMA(c8cb212fcd9f5691); +CAPNP_DECLARE_SCHEMA(f76fba59183073a5); +CAPNP_DECLARE_SCHEMA(b76848c18c40efbf); +CAPNP_DECLARE_SCHEMA(84ff286cd00a3ed4); +CAPNP_DECLARE_SCHEMA(f0c2cc1d3909574d); +CAPNP_DECLARE_SCHEMA(ecafa18b482da3aa); +CAPNP_DECLARE_SCHEMA(f622595091cafb67); + +} // namespace schemas +} // namespace capnp + +namespace capnp { + +template <typename SturdyRef = ::capnp::AnyPointer, typename Owner = ::capnp::AnyPointer> +struct Persistent { + Persistent() = delete; + +#if !CAPNP_LITE + class Client; + class Server; +#endif // !CAPNP_LITE + + struct SaveParams; + struct SaveResults; + + #if !CAPNP_LITE + struct _capnpPrivate { + CAPNP_DECLARE_INTERFACE_HEADER(c8cb212fcd9f5691) + static const ::capnp::_::RawBrandedSchema::Scope brandScopes[]; + static const ::capnp::_::RawBrandedSchema::Binding brandBindings[]; + static const ::capnp::_::RawBrandedSchema::Dependency brandDependencies[]; + static const ::capnp::_::RawBrandedSchema specificBrand; + static constexpr ::capnp::_::RawBrandedSchema const* brand = ::capnp::_::ChooseBrand<_capnpPrivate, SturdyRef, Owner>::brand; + }; + #endif // !CAPNP_LITE +}; + +template <typename SturdyRef, typename Owner> +struct Persistent<SturdyRef, Owner>::SaveParams { + SaveParams() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(f76fba59183073a5, 0, 1) + #if !CAPNP_LITE + static const ::capnp::_::RawBrandedSchema::Scope brandScopes[]; + static const ::capnp::_::RawBrandedSchema::Binding brandBindings[]; + static const ::capnp::_::RawBrandedSchema specificBrand; + static constexpr ::capnp::_::RawBrandedSchema const* brand = ::capnp::_::ChooseBrand<_capnpPrivate, SturdyRef, Owner>::brand; + #endif // !CAPNP_LITE + }; +}; + +template <typename SturdyRef, typename Owner> +struct Persistent<SturdyRef, Owner>::SaveResults { + SaveResults() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(b76848c18c40efbf, 0, 1) + #if !CAPNP_LITE + static const ::capnp::_::RawBrandedSchema::Scope brandScopes[]; + static const ::capnp::_::RawBrandedSchema::Binding brandBindings[]; + static const ::capnp::_::RawBrandedSchema specificBrand; + static constexpr ::capnp::_::RawBrandedSchema const* brand = ::capnp::_::ChooseBrand<_capnpPrivate, SturdyRef, Owner>::brand; + #endif // !CAPNP_LITE + }; +}; + +template <typename InternalRef = ::capnp::AnyPointer, typename ExternalRef = ::capnp::AnyPointer, typename InternalOwner = ::capnp::AnyPointer, typename ExternalOwner = ::capnp::AnyPointer> +struct RealmGateway { + RealmGateway() = delete; + +#if !CAPNP_LITE + class Client; + class Server; +#endif // !CAPNP_LITE + + struct ImportParams; + struct ExportParams; + + #if !CAPNP_LITE + struct _capnpPrivate { + CAPNP_DECLARE_INTERFACE_HEADER(84ff286cd00a3ed4) + static const ::capnp::_::RawBrandedSchema::Scope brandScopes[]; + static const ::capnp::_::RawBrandedSchema::Binding brandBindings[]; + static const ::capnp::_::RawBrandedSchema::Dependency brandDependencies[]; + static const ::capnp::_::RawBrandedSchema specificBrand; + static constexpr ::capnp::_::RawBrandedSchema const* brand = ::capnp::_::ChooseBrand<_capnpPrivate, InternalRef, ExternalRef, InternalOwner, ExternalOwner>::brand; + }; + #endif // !CAPNP_LITE +}; + +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +struct RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams { + ImportParams() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(f0c2cc1d3909574d, 0, 2) + #if !CAPNP_LITE + static const ::capnp::_::RawBrandedSchema::Scope brandScopes[]; + static const ::capnp::_::RawBrandedSchema::Binding brandBindings[]; + static const ::capnp::_::RawBrandedSchema::Dependency brandDependencies[]; + static const ::capnp::_::RawBrandedSchema specificBrand; + static constexpr ::capnp::_::RawBrandedSchema const* brand = ::capnp::_::ChooseBrand<_capnpPrivate, InternalRef, ExternalRef, InternalOwner, ExternalOwner>::brand; + #endif // !CAPNP_LITE + }; +}; + +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +struct RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams { + ExportParams() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(ecafa18b482da3aa, 0, 2) + #if !CAPNP_LITE + static const ::capnp::_::RawBrandedSchema::Scope brandScopes[]; + static const ::capnp::_::RawBrandedSchema::Binding brandBindings[]; + static const ::capnp::_::RawBrandedSchema::Dependency brandDependencies[]; + static const ::capnp::_::RawBrandedSchema specificBrand; + static constexpr ::capnp::_::RawBrandedSchema const* brand = ::capnp::_::ChooseBrand<_capnpPrivate, InternalRef, ExternalRef, InternalOwner, ExternalOwner>::brand; + #endif // !CAPNP_LITE + }; +}; + +// ======================================================================================= + +#if !CAPNP_LITE +template <typename SturdyRef, typename Owner> +class Persistent<SturdyRef, Owner>::Client + : public virtual ::capnp::Capability::Client { +public: + typedef Persistent<SturdyRef, Owner> Calls; + typedef Persistent<SturdyRef, Owner> Reads; + + Client(decltype(nullptr)); + explicit Client(::kj::Own< ::capnp::ClientHook>&& hook); + template <typename _t, typename = ::kj::EnableIf< ::kj::canConvert<_t*, Server*>()>> + Client(::kj::Own<_t>&& server); + template <typename _t, typename = ::kj::EnableIf< ::kj::canConvert<_t*, Client*>()>> + Client(::kj::Promise<_t>&& promise); + Client(::kj::Exception&& exception); + Client(Client&) = default; + Client(Client&&) = default; + Client& operator=(Client& other); + Client& operator=(Client&& other); + + template <typename SturdyRef2 = ::capnp::AnyPointer, typename Owner2 = ::capnp::AnyPointer> + typename Persistent<SturdyRef2, Owner2>::Client asGeneric() { + return castAs<Persistent<SturdyRef2, Owner2>>(); + } + + ::capnp::Request<typename ::capnp::Persistent<SturdyRef, Owner>::SaveParams, typename ::capnp::Persistent<SturdyRef, Owner>::SaveResults> saveRequest( + ::kj::Maybe< ::capnp::MessageSize> sizeHint = nullptr); + +protected: + Client() = default; +}; + +template <typename SturdyRef, typename Owner> +class Persistent<SturdyRef, Owner>::Server + : public virtual ::capnp::Capability::Server { +public: + typedef Persistent<SturdyRef, Owner> Serves; + + ::kj::Promise<void> dispatchCall(uint64_t interfaceId, uint16_t methodId, + ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context) + override; + +protected: + typedef ::capnp::CallContext<typename ::capnp::Persistent<SturdyRef, Owner>::SaveParams, typename ::capnp::Persistent<SturdyRef, Owner>::SaveResults> SaveContext; + virtual ::kj::Promise<void> save(SaveContext context); + + inline typename ::capnp::Persistent<SturdyRef, Owner>::Client thisCap() { + return ::capnp::Capability::Server::thisCap() + .template castAs< ::capnp::Persistent<SturdyRef, Owner>>(); + } + + ::kj::Promise<void> dispatchCallInternal(uint16_t methodId, + ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context); +}; +#endif // !CAPNP_LITE + +template <typename SturdyRef, typename Owner> +class Persistent<SturdyRef, Owner>::SaveParams::Reader { +public: + typedef SaveParams 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 + + template <typename SturdyRef2 = ::capnp::AnyPointer, typename Owner2 = ::capnp::AnyPointer> + typename Persistent<SturdyRef2, Owner2>::SaveParams::Reader asPersistentGeneric() { + return typename Persistent<SturdyRef2, Owner2>::SaveParams::Reader(_reader); + } + + inline bool hasSealFor() const; + inline ::capnp::ReaderFor<Owner> getSealFor() 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; +}; + +template <typename SturdyRef, typename Owner> +class Persistent<SturdyRef, Owner>::SaveParams::Builder { +public: + typedef SaveParams 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 + + template <typename SturdyRef2 = ::capnp::AnyPointer, typename Owner2 = ::capnp::AnyPointer> + typename Persistent<SturdyRef2, Owner2>::SaveParams::Builder asPersistentGeneric() { + return typename Persistent<SturdyRef2, Owner2>::SaveParams::Builder(_builder); + } + + inline bool hasSealFor(); + inline ::capnp::BuilderFor<Owner> getSealFor(); + inline void setSealFor( ::capnp::ReaderFor<Owner> value); + inline ::capnp::BuilderFor<Owner> initSealFor(); + inline ::capnp::BuilderFor<Owner> initSealFor(unsigned int size); + inline void adoptSealFor(::capnp::Orphan<Owner>&& value); + inline ::capnp::Orphan<Owner> disownSealFor(); + +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 +template <typename SturdyRef, typename Owner> +class Persistent<SturdyRef, Owner>::SaveParams::Pipeline { +public: + typedef SaveParams Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::PipelineFor<Owner> getSealFor(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template <typename, ::capnp::Kind> + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +template <typename SturdyRef, typename Owner> +class Persistent<SturdyRef, Owner>::SaveResults::Reader { +public: + typedef SaveResults 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 + + template <typename SturdyRef2 = ::capnp::AnyPointer, typename Owner2 = ::capnp::AnyPointer> + typename Persistent<SturdyRef2, Owner2>::SaveResults::Reader asPersistentGeneric() { + return typename Persistent<SturdyRef2, Owner2>::SaveResults::Reader(_reader); + } + + inline bool hasSturdyRef() const; + inline ::capnp::ReaderFor<SturdyRef> getSturdyRef() 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; +}; + +template <typename SturdyRef, typename Owner> +class Persistent<SturdyRef, Owner>::SaveResults::Builder { +public: + typedef SaveResults 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 + + template <typename SturdyRef2 = ::capnp::AnyPointer, typename Owner2 = ::capnp::AnyPointer> + typename Persistent<SturdyRef2, Owner2>::SaveResults::Builder asPersistentGeneric() { + return typename Persistent<SturdyRef2, Owner2>::SaveResults::Builder(_builder); + } + + inline bool hasSturdyRef(); + inline ::capnp::BuilderFor<SturdyRef> getSturdyRef(); + inline void setSturdyRef( ::capnp::ReaderFor<SturdyRef> value); + inline ::capnp::BuilderFor<SturdyRef> initSturdyRef(); + inline ::capnp::BuilderFor<SturdyRef> initSturdyRef(unsigned int size); + inline void adoptSturdyRef(::capnp::Orphan<SturdyRef>&& value); + inline ::capnp::Orphan<SturdyRef> disownSturdyRef(); + +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 +template <typename SturdyRef, typename Owner> +class Persistent<SturdyRef, Owner>::SaveResults::Pipeline { +public: + typedef SaveResults Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::PipelineFor<SturdyRef> getSturdyRef(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template <typename, ::capnp::Kind> + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +#if !CAPNP_LITE +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +class RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::Client + : public virtual ::capnp::Capability::Client { +public: + typedef RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner> Calls; + typedef RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner> Reads; + + Client(decltype(nullptr)); + explicit Client(::kj::Own< ::capnp::ClientHook>&& hook); + template <typename _t, typename = ::kj::EnableIf< ::kj::canConvert<_t*, Server*>()>> + Client(::kj::Own<_t>&& server); + template <typename _t, typename = ::kj::EnableIf< ::kj::canConvert<_t*, Client*>()>> + Client(::kj::Promise<_t>&& promise); + Client(::kj::Exception&& exception); + Client(Client&) = default; + Client(Client&&) = default; + Client& operator=(Client& other); + Client& operator=(Client&& other); + + template <typename InternalRef2 = ::capnp::AnyPointer, typename ExternalRef2 = ::capnp::AnyPointer, typename InternalOwner2 = ::capnp::AnyPointer, typename ExternalOwner2 = ::capnp::AnyPointer> + typename RealmGateway<InternalRef2, ExternalRef2, InternalOwner2, ExternalOwner2>::Client asGeneric() { + return castAs<RealmGateway<InternalRef2, ExternalRef2, InternalOwner2, ExternalOwner2>>(); + } + + ::capnp::Request<typename ::capnp::RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams, typename ::capnp::Persistent<InternalRef, InternalOwner>::SaveResults> importRequest( + ::kj::Maybe< ::capnp::MessageSize> sizeHint = nullptr); + ::capnp::Request<typename ::capnp::RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams, typename ::capnp::Persistent<ExternalRef, ExternalOwner>::SaveResults> exportRequest( + ::kj::Maybe< ::capnp::MessageSize> sizeHint = nullptr); + +protected: + Client() = default; +}; + +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +class RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::Server + : public virtual ::capnp::Capability::Server { +public: + typedef RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner> Serves; + + ::kj::Promise<void> dispatchCall(uint64_t interfaceId, uint16_t methodId, + ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context) + override; + +protected: + typedef typename ::capnp::RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams ImportParams; + typedef ::capnp::CallContext<ImportParams, typename ::capnp::Persistent<InternalRef, InternalOwner>::SaveResults> ImportContext; + virtual ::kj::Promise<void> import(ImportContext context); + typedef typename ::capnp::RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams ExportParams; + typedef ::capnp::CallContext<ExportParams, typename ::capnp::Persistent<ExternalRef, ExternalOwner>::SaveResults> ExportContext; + virtual ::kj::Promise<void> export_(ExportContext context); + + inline typename ::capnp::RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::Client thisCap() { + return ::capnp::Capability::Server::thisCap() + .template castAs< ::capnp::RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>>(); + } + + ::kj::Promise<void> dispatchCallInternal(uint16_t methodId, + ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context); +}; +#endif // !CAPNP_LITE + +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +class RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::Reader { +public: + typedef ImportParams 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 + + template <typename InternalRef2 = ::capnp::AnyPointer, typename ExternalRef2 = ::capnp::AnyPointer, typename InternalOwner2 = ::capnp::AnyPointer, typename ExternalOwner2 = ::capnp::AnyPointer> + typename RealmGateway<InternalRef2, ExternalRef2, InternalOwner2, ExternalOwner2>::ImportParams::Reader asRealmGatewayGeneric() { + return typename RealmGateway<InternalRef2, ExternalRef2, InternalOwner2, ExternalOwner2>::ImportParams::Reader(_reader); + } + + inline bool hasCap() const; +#if !CAPNP_LITE + inline typename ::capnp::Persistent<ExternalRef, ExternalOwner>::Client getCap() const; +#endif // !CAPNP_LITE + + inline bool hasParams() const; + inline typename ::capnp::Persistent<InternalRef, InternalOwner>::SaveParams::Reader getParams() 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; +}; + +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +class RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::Builder { +public: + typedef ImportParams 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 + + template <typename InternalRef2 = ::capnp::AnyPointer, typename ExternalRef2 = ::capnp::AnyPointer, typename InternalOwner2 = ::capnp::AnyPointer, typename ExternalOwner2 = ::capnp::AnyPointer> + typename RealmGateway<InternalRef2, ExternalRef2, InternalOwner2, ExternalOwner2>::ImportParams::Builder asRealmGatewayGeneric() { + return typename RealmGateway<InternalRef2, ExternalRef2, InternalOwner2, ExternalOwner2>::ImportParams::Builder(_builder); + } + + inline bool hasCap(); +#if !CAPNP_LITE + inline typename ::capnp::Persistent<ExternalRef, ExternalOwner>::Client getCap(); + inline void setCap(typename ::capnp::Persistent<ExternalRef, ExternalOwner>::Client&& value); + inline void setCap(typename ::capnp::Persistent<ExternalRef, ExternalOwner>::Client& value); + inline void adoptCap(::capnp::Orphan< ::capnp::Persistent<ExternalRef, ExternalOwner>>&& value); + inline ::capnp::Orphan< ::capnp::Persistent<ExternalRef, ExternalOwner>> disownCap(); +#endif // !CAPNP_LITE + + inline bool hasParams(); + inline typename ::capnp::Persistent<InternalRef, InternalOwner>::SaveParams::Builder getParams(); + inline void setParams(typename ::capnp::Persistent<InternalRef, InternalOwner>::SaveParams::Reader value); + inline typename ::capnp::Persistent<InternalRef, InternalOwner>::SaveParams::Builder initParams(); + inline void adoptParams(::capnp::Orphan<typename ::capnp::Persistent<InternalRef, InternalOwner>::SaveParams>&& value); + inline ::capnp::Orphan<typename ::capnp::Persistent<InternalRef, InternalOwner>::SaveParams> disownParams(); + +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 +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +class RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::Pipeline { +public: + typedef ImportParams Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline typename ::capnp::Persistent<ExternalRef, ExternalOwner>::Client getCap(); + inline typename ::capnp::Persistent<InternalRef, InternalOwner>::SaveParams::Pipeline getParams(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template <typename, ::capnp::Kind> + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +class RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::Reader { +public: + typedef ExportParams 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 + + template <typename InternalRef2 = ::capnp::AnyPointer, typename ExternalRef2 = ::capnp::AnyPointer, typename InternalOwner2 = ::capnp::AnyPointer, typename ExternalOwner2 = ::capnp::AnyPointer> + typename RealmGateway<InternalRef2, ExternalRef2, InternalOwner2, ExternalOwner2>::ExportParams::Reader asRealmGatewayGeneric() { + return typename RealmGateway<InternalRef2, ExternalRef2, InternalOwner2, ExternalOwner2>::ExportParams::Reader(_reader); + } + + inline bool hasCap() const; +#if !CAPNP_LITE + inline typename ::capnp::Persistent<InternalRef, InternalOwner>::Client getCap() const; +#endif // !CAPNP_LITE + + inline bool hasParams() const; + inline typename ::capnp::Persistent<ExternalRef, ExternalOwner>::SaveParams::Reader getParams() 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; +}; + +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +class RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::Builder { +public: + typedef ExportParams 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 + + template <typename InternalRef2 = ::capnp::AnyPointer, typename ExternalRef2 = ::capnp::AnyPointer, typename InternalOwner2 = ::capnp::AnyPointer, typename ExternalOwner2 = ::capnp::AnyPointer> + typename RealmGateway<InternalRef2, ExternalRef2, InternalOwner2, ExternalOwner2>::ExportParams::Builder asRealmGatewayGeneric() { + return typename RealmGateway<InternalRef2, ExternalRef2, InternalOwner2, ExternalOwner2>::ExportParams::Builder(_builder); + } + + inline bool hasCap(); +#if !CAPNP_LITE + inline typename ::capnp::Persistent<InternalRef, InternalOwner>::Client getCap(); + inline void setCap(typename ::capnp::Persistent<InternalRef, InternalOwner>::Client&& value); + inline void setCap(typename ::capnp::Persistent<InternalRef, InternalOwner>::Client& value); + inline void adoptCap(::capnp::Orphan< ::capnp::Persistent<InternalRef, InternalOwner>>&& value); + inline ::capnp::Orphan< ::capnp::Persistent<InternalRef, InternalOwner>> disownCap(); +#endif // !CAPNP_LITE + + inline bool hasParams(); + inline typename ::capnp::Persistent<ExternalRef, ExternalOwner>::SaveParams::Builder getParams(); + inline void setParams(typename ::capnp::Persistent<ExternalRef, ExternalOwner>::SaveParams::Reader value); + inline typename ::capnp::Persistent<ExternalRef, ExternalOwner>::SaveParams::Builder initParams(); + inline void adoptParams(::capnp::Orphan<typename ::capnp::Persistent<ExternalRef, ExternalOwner>::SaveParams>&& value); + inline ::capnp::Orphan<typename ::capnp::Persistent<ExternalRef, ExternalOwner>::SaveParams> disownParams(); + +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 +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +class RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::Pipeline { +public: + typedef ExportParams Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline typename ::capnp::Persistent<InternalRef, InternalOwner>::Client getCap(); + inline typename ::capnp::Persistent<ExternalRef, ExternalOwner>::SaveParams::Pipeline getParams(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template <typename, ::capnp::Kind> + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +// ======================================================================================= + +#if !CAPNP_LITE +template <typename SturdyRef, typename Owner> +inline Persistent<SturdyRef, Owner>::Client::Client(decltype(nullptr)) + : ::capnp::Capability::Client(nullptr) {} +template <typename SturdyRef, typename Owner> +inline Persistent<SturdyRef, Owner>::Client::Client( + ::kj::Own< ::capnp::ClientHook>&& hook) + : ::capnp::Capability::Client(::kj::mv(hook)) {} +template <typename SturdyRef, typename Owner> +template <typename _t, typename> +inline Persistent<SturdyRef, Owner>::Client::Client(::kj::Own<_t>&& server) + : ::capnp::Capability::Client(::kj::mv(server)) {} +template <typename SturdyRef, typename Owner> +template <typename _t, typename> +inline Persistent<SturdyRef, Owner>::Client::Client(::kj::Promise<_t>&& promise) + : ::capnp::Capability::Client(::kj::mv(promise)) {} +template <typename SturdyRef, typename Owner> +inline Persistent<SturdyRef, Owner>::Client::Client(::kj::Exception&& exception) + : ::capnp::Capability::Client(::kj::mv(exception)) {} +template <typename SturdyRef, typename Owner> +inline typename ::capnp::Persistent<SturdyRef, Owner>::Client& Persistent<SturdyRef, Owner>::Client::operator=(Client& other) { + ::capnp::Capability::Client::operator=(other); + return *this; +} +template <typename SturdyRef, typename Owner> +inline typename ::capnp::Persistent<SturdyRef, Owner>::Client& Persistent<SturdyRef, Owner>::Client::operator=(Client&& other) { + ::capnp::Capability::Client::operator=(kj::mv(other)); + return *this; +} + +#endif // !CAPNP_LITE +template <typename SturdyRef, typename Owner> +inline bool Persistent<SturdyRef, Owner>::SaveParams::Reader::hasSealFor() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +template <typename SturdyRef, typename Owner> +inline bool Persistent<SturdyRef, Owner>::SaveParams::Builder::hasSealFor() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +template <typename SturdyRef, typename Owner> +inline ::capnp::ReaderFor<Owner> Persistent<SturdyRef, Owner>::SaveParams::Reader::getSealFor() const { + return ::capnp::_::PointerHelpers<Owner>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +template <typename SturdyRef, typename Owner> +inline ::capnp::BuilderFor<Owner> Persistent<SturdyRef, Owner>::SaveParams::Builder::getSealFor() { + return ::capnp::_::PointerHelpers<Owner>::get( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +template <typename SturdyRef, typename Owner> +inline ::capnp::PipelineFor<Owner> Persistent<SturdyRef, Owner>::SaveParams::Pipeline::getSealFor() { + return ::capnp::PipelineFor<Owner>(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +template <typename SturdyRef, typename Owner> +inline void Persistent<SturdyRef, Owner>::SaveParams::Builder::setSealFor( ::capnp::ReaderFor<Owner> value) { + ::capnp::_::PointerHelpers<Owner>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +template <typename SturdyRef, typename Owner> +inline ::capnp::BuilderFor<Owner> Persistent<SturdyRef, Owner>::SaveParams::Builder::initSealFor() { + return ::capnp::_::PointerHelpers<Owner>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +template <typename SturdyRef, typename Owner> +inline ::capnp::BuilderFor<Owner> Persistent<SturdyRef, Owner>::SaveParams::Builder::initSealFor(unsigned int size) { + return ::capnp::_::PointerHelpers<Owner>::init( + _builder.getPointerField(0 * ::capnp::POINTERS), size); +} +template <typename SturdyRef, typename Owner> +inline void Persistent<SturdyRef, Owner>::SaveParams::Builder::adoptSealFor( + ::capnp::Orphan<Owner>&& value) { + ::capnp::_::PointerHelpers<Owner>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +template <typename SturdyRef, typename Owner> +inline ::capnp::Orphan<Owner> Persistent<SturdyRef, Owner>::SaveParams::Builder::disownSealFor() { + return ::capnp::_::PointerHelpers<Owner>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} + +// Persistent<SturdyRef, Owner>::SaveParams +template <typename SturdyRef, typename Owner> +constexpr uint16_t Persistent<SturdyRef, Owner>::SaveParams::_capnpPrivate::dataWordSize; +template <typename SturdyRef, typename Owner> +constexpr uint16_t Persistent<SturdyRef, Owner>::SaveParams::_capnpPrivate::pointerCount; +#if !CAPNP_LITE +template <typename SturdyRef, typename Owner> +constexpr ::capnp::Kind Persistent<SturdyRef, Owner>::SaveParams::_capnpPrivate::kind; +template <typename SturdyRef, typename Owner> +constexpr ::capnp::_::RawSchema const* Persistent<SturdyRef, Owner>::SaveParams::_capnpPrivate::schema; +template <typename SturdyRef, typename Owner> +constexpr ::capnp::_::RawBrandedSchema const* Persistent<SturdyRef, Owner>::SaveParams::_capnpPrivate::brand; +template <typename SturdyRef, typename Owner> +const ::capnp::_::RawBrandedSchema::Scope Persistent<SturdyRef, Owner>::SaveParams::_capnpPrivate::brandScopes[] = { + { 0xc8cb212fcd9f5691, brandBindings + 0, 2, false}, +}; +template <typename SturdyRef, typename Owner> +const ::capnp::_::RawBrandedSchema::Binding Persistent<SturdyRef, Owner>::SaveParams::_capnpPrivate::brandBindings[] = { + ::capnp::_::brandBindingFor<SturdyRef>(), + ::capnp::_::brandBindingFor<Owner>(), +}; +template <typename SturdyRef, typename Owner> +const ::capnp::_::RawBrandedSchema Persistent<SturdyRef, Owner>::SaveParams::_capnpPrivate::specificBrand = { + &::capnp::schemas::s_f76fba59183073a5, brandScopes, nullptr, + sizeof(brandScopes) / sizeof(brandScopes[0]), 0, nullptr +}; +#endif // !CAPNP_LITE + +template <typename SturdyRef, typename Owner> +inline bool Persistent<SturdyRef, Owner>::SaveResults::Reader::hasSturdyRef() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +template <typename SturdyRef, typename Owner> +inline bool Persistent<SturdyRef, Owner>::SaveResults::Builder::hasSturdyRef() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +template <typename SturdyRef, typename Owner> +inline ::capnp::ReaderFor<SturdyRef> Persistent<SturdyRef, Owner>::SaveResults::Reader::getSturdyRef() const { + return ::capnp::_::PointerHelpers<SturdyRef>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +template <typename SturdyRef, typename Owner> +inline ::capnp::BuilderFor<SturdyRef> Persistent<SturdyRef, Owner>::SaveResults::Builder::getSturdyRef() { + return ::capnp::_::PointerHelpers<SturdyRef>::get( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +template <typename SturdyRef, typename Owner> +inline ::capnp::PipelineFor<SturdyRef> Persistent<SturdyRef, Owner>::SaveResults::Pipeline::getSturdyRef() { + return ::capnp::PipelineFor<SturdyRef>(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +template <typename SturdyRef, typename Owner> +inline void Persistent<SturdyRef, Owner>::SaveResults::Builder::setSturdyRef( ::capnp::ReaderFor<SturdyRef> value) { + ::capnp::_::PointerHelpers<SturdyRef>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +template <typename SturdyRef, typename Owner> +inline ::capnp::BuilderFor<SturdyRef> Persistent<SturdyRef, Owner>::SaveResults::Builder::initSturdyRef() { + return ::capnp::_::PointerHelpers<SturdyRef>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +template <typename SturdyRef, typename Owner> +inline ::capnp::BuilderFor<SturdyRef> Persistent<SturdyRef, Owner>::SaveResults::Builder::initSturdyRef(unsigned int size) { + return ::capnp::_::PointerHelpers<SturdyRef>::init( + _builder.getPointerField(0 * ::capnp::POINTERS), size); +} +template <typename SturdyRef, typename Owner> +inline void Persistent<SturdyRef, Owner>::SaveResults::Builder::adoptSturdyRef( + ::capnp::Orphan<SturdyRef>&& value) { + ::capnp::_::PointerHelpers<SturdyRef>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +template <typename SturdyRef, typename Owner> +inline ::capnp::Orphan<SturdyRef> Persistent<SturdyRef, Owner>::SaveResults::Builder::disownSturdyRef() { + return ::capnp::_::PointerHelpers<SturdyRef>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} + +// Persistent<SturdyRef, Owner>::SaveResults +template <typename SturdyRef, typename Owner> +constexpr uint16_t Persistent<SturdyRef, Owner>::SaveResults::_capnpPrivate::dataWordSize; +template <typename SturdyRef, typename Owner> +constexpr uint16_t Persistent<SturdyRef, Owner>::SaveResults::_capnpPrivate::pointerCount; +#if !CAPNP_LITE +template <typename SturdyRef, typename Owner> +constexpr ::capnp::Kind Persistent<SturdyRef, Owner>::SaveResults::_capnpPrivate::kind; +template <typename SturdyRef, typename Owner> +constexpr ::capnp::_::RawSchema const* Persistent<SturdyRef, Owner>::SaveResults::_capnpPrivate::schema; +template <typename SturdyRef, typename Owner> +constexpr ::capnp::_::RawBrandedSchema const* Persistent<SturdyRef, Owner>::SaveResults::_capnpPrivate::brand; +template <typename SturdyRef, typename Owner> +const ::capnp::_::RawBrandedSchema::Scope Persistent<SturdyRef, Owner>::SaveResults::_capnpPrivate::brandScopes[] = { + { 0xc8cb212fcd9f5691, brandBindings + 0, 2, false}, +}; +template <typename SturdyRef, typename Owner> +const ::capnp::_::RawBrandedSchema::Binding Persistent<SturdyRef, Owner>::SaveResults::_capnpPrivate::brandBindings[] = { + ::capnp::_::brandBindingFor<SturdyRef>(), + ::capnp::_::brandBindingFor<Owner>(), +}; +template <typename SturdyRef, typename Owner> +const ::capnp::_::RawBrandedSchema Persistent<SturdyRef, Owner>::SaveResults::_capnpPrivate::specificBrand = { + &::capnp::schemas::s_b76848c18c40efbf, brandScopes, nullptr, + sizeof(brandScopes) / sizeof(brandScopes[0]), 0, nullptr +}; +#endif // !CAPNP_LITE + +#if !CAPNP_LITE +template <typename SturdyRef, typename Owner> +::capnp::Request<typename ::capnp::Persistent<SturdyRef, Owner>::SaveParams, typename ::capnp::Persistent<SturdyRef, Owner>::SaveResults> +Persistent<SturdyRef, Owner>::Client::saveRequest(::kj::Maybe< ::capnp::MessageSize> sizeHint) { + return newCall<typename ::capnp::Persistent<SturdyRef, Owner>::SaveParams, typename ::capnp::Persistent<SturdyRef, Owner>::SaveResults>( + 0xc8cb212fcd9f5691ull, 0, sizeHint); +} +template <typename SturdyRef, typename Owner> +::kj::Promise<void> Persistent<SturdyRef, Owner>::Server::save(SaveContext) { + return ::capnp::Capability::Server::internalUnimplemented( + "capnp/persistent.capnp:Persistent", "save", + 0xc8cb212fcd9f5691ull, 0); +} +template <typename SturdyRef, typename Owner> +::kj::Promise<void> Persistent<SturdyRef, Owner>::Server::dispatchCall( + uint64_t interfaceId, uint16_t methodId, + ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context) { + switch (interfaceId) { + case 0xc8cb212fcd9f5691ull: + return dispatchCallInternal(methodId, context); + default: + return internalUnimplemented("capnp/persistent.capnp:Persistent", interfaceId); + } +} +template <typename SturdyRef, typename Owner> +::kj::Promise<void> Persistent<SturdyRef, Owner>::Server::dispatchCallInternal( + uint16_t methodId, + ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context) { + switch (methodId) { + case 0: + return save(::capnp::Capability::Server::internalGetTypedContext< + typename ::capnp::Persistent<SturdyRef, Owner>::SaveParams, typename ::capnp::Persistent<SturdyRef, Owner>::SaveResults>(context)); + default: + (void)context; + return ::capnp::Capability::Server::internalUnimplemented( + "capnp/persistent.capnp:Persistent", + 0xc8cb212fcd9f5691ull, methodId); + } +} +#endif // !CAPNP_LITE + +// Persistent<SturdyRef, Owner> +#if !CAPNP_LITE +template <typename SturdyRef, typename Owner> +constexpr ::capnp::Kind Persistent<SturdyRef, Owner>::_capnpPrivate::kind; +template <typename SturdyRef, typename Owner> +constexpr ::capnp::_::RawSchema const* Persistent<SturdyRef, Owner>::_capnpPrivate::schema; +template <typename SturdyRef, typename Owner> +constexpr ::capnp::_::RawBrandedSchema const* Persistent<SturdyRef, Owner>::_capnpPrivate::brand; +template <typename SturdyRef, typename Owner> +const ::capnp::_::RawBrandedSchema::Scope Persistent<SturdyRef, Owner>::_capnpPrivate::brandScopes[] = { + { 0xc8cb212fcd9f5691, brandBindings + 0, 2, false}, +}; +template <typename SturdyRef, typename Owner> +const ::capnp::_::RawBrandedSchema::Binding Persistent<SturdyRef, Owner>::_capnpPrivate::brandBindings[] = { + ::capnp::_::brandBindingFor<SturdyRef>(), + ::capnp::_::brandBindingFor<Owner>(), +}; +template <typename SturdyRef, typename Owner> +const ::capnp::_::RawBrandedSchema::Dependency Persistent<SturdyRef, Owner>::_capnpPrivate::brandDependencies[] = { + { 33554432, ::capnp::Persistent<SturdyRef, Owner>::SaveParams::_capnpPrivate::brand }, + { 50331648, ::capnp::Persistent<SturdyRef, Owner>::SaveResults::_capnpPrivate::brand }, +}; +template <typename SturdyRef, typename Owner> +const ::capnp::_::RawBrandedSchema Persistent<SturdyRef, Owner>::_capnpPrivate::specificBrand = { + &::capnp::schemas::s_c8cb212fcd9f5691, brandScopes, brandDependencies, + sizeof(brandScopes) / sizeof(brandScopes[0]), sizeof(brandDependencies) / sizeof(brandDependencies[0]), nullptr +}; +#endif // !CAPNP_LITE + +#if !CAPNP_LITE +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::Client::Client(decltype(nullptr)) + : ::capnp::Capability::Client(nullptr) {} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::Client::Client( + ::kj::Own< ::capnp::ClientHook>&& hook) + : ::capnp::Capability::Client(::kj::mv(hook)) {} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +template <typename _t, typename> +inline RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::Client::Client(::kj::Own<_t>&& server) + : ::capnp::Capability::Client(::kj::mv(server)) {} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +template <typename _t, typename> +inline RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::Client::Client(::kj::Promise<_t>&& promise) + : ::capnp::Capability::Client(::kj::mv(promise)) {} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::Client::Client(::kj::Exception&& exception) + : ::capnp::Capability::Client(::kj::mv(exception)) {} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline typename ::capnp::RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::Client& RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::Client::operator=(Client& other) { + ::capnp::Capability::Client::operator=(other); + return *this; +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline typename ::capnp::RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::Client& RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::Client::operator=(Client&& other) { + ::capnp::Capability::Client::operator=(kj::mv(other)); + return *this; +} + +#endif // !CAPNP_LITE +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline bool RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::Reader::hasCap() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline bool RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::Builder::hasCap() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +#if !CAPNP_LITE +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline typename ::capnp::Persistent<ExternalRef, ExternalOwner>::Client RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::Reader::getCap() const { + return ::capnp::_::PointerHelpers< ::capnp::Persistent<ExternalRef, ExternalOwner>>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline typename ::capnp::Persistent<ExternalRef, ExternalOwner>::Client RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::Builder::getCap() { + return ::capnp::_::PointerHelpers< ::capnp::Persistent<ExternalRef, ExternalOwner>>::get( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline typename ::capnp::Persistent<ExternalRef, ExternalOwner>::Client RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::Pipeline::getCap() { + return typename ::capnp::Persistent<ExternalRef, ExternalOwner>::Client(_typeless.getPointerField(0).asCap()); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline void RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::Builder::setCap(typename ::capnp::Persistent<ExternalRef, ExternalOwner>::Client&& cap) { + ::capnp::_::PointerHelpers< ::capnp::Persistent<ExternalRef, ExternalOwner>>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(cap)); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline void RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::Builder::setCap(typename ::capnp::Persistent<ExternalRef, ExternalOwner>::Client& cap) { + ::capnp::_::PointerHelpers< ::capnp::Persistent<ExternalRef, ExternalOwner>>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), cap); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline void RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::Builder::adoptCap( + ::capnp::Orphan< ::capnp::Persistent<ExternalRef, ExternalOwner>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Persistent<ExternalRef, ExternalOwner>>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline ::capnp::Orphan< ::capnp::Persistent<ExternalRef, ExternalOwner>> RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::Builder::disownCap() { + return ::capnp::_::PointerHelpers< ::capnp::Persistent<ExternalRef, ExternalOwner>>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +#endif // !CAPNP_LITE + +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline bool RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::Reader::hasParams() const { + return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull(); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline bool RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::Builder::hasParams() { + return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull(); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline typename ::capnp::Persistent<InternalRef, InternalOwner>::SaveParams::Reader RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::Reader::getParams() const { + return ::capnp::_::PointerHelpers<typename ::capnp::Persistent<InternalRef, InternalOwner>::SaveParams>::get( + _reader.getPointerField(1 * ::capnp::POINTERS)); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline typename ::capnp::Persistent<InternalRef, InternalOwner>::SaveParams::Builder RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::Builder::getParams() { + return ::capnp::_::PointerHelpers<typename ::capnp::Persistent<InternalRef, InternalOwner>::SaveParams>::get( + _builder.getPointerField(1 * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline typename ::capnp::Persistent<InternalRef, InternalOwner>::SaveParams::Pipeline RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::Pipeline::getParams() { + return typename ::capnp::Persistent<InternalRef, InternalOwner>::SaveParams::Pipeline(_typeless.getPointerField(1)); +} +#endif // !CAPNP_LITE +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline void RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::Builder::setParams(typename ::capnp::Persistent<InternalRef, InternalOwner>::SaveParams::Reader value) { + ::capnp::_::PointerHelpers<typename ::capnp::Persistent<InternalRef, InternalOwner>::SaveParams>::set( + _builder.getPointerField(1 * ::capnp::POINTERS), value); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline typename ::capnp::Persistent<InternalRef, InternalOwner>::SaveParams::Builder RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::Builder::initParams() { + return ::capnp::_::PointerHelpers<typename ::capnp::Persistent<InternalRef, InternalOwner>::SaveParams>::init( + _builder.getPointerField(1 * ::capnp::POINTERS)); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline void RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::Builder::adoptParams( + ::capnp::Orphan<typename ::capnp::Persistent<InternalRef, InternalOwner>::SaveParams>&& value) { + ::capnp::_::PointerHelpers<typename ::capnp::Persistent<InternalRef, InternalOwner>::SaveParams>::adopt( + _builder.getPointerField(1 * ::capnp::POINTERS), kj::mv(value)); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline ::capnp::Orphan<typename ::capnp::Persistent<InternalRef, InternalOwner>::SaveParams> RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::Builder::disownParams() { + return ::capnp::_::PointerHelpers<typename ::capnp::Persistent<InternalRef, InternalOwner>::SaveParams>::disown( + _builder.getPointerField(1 * ::capnp::POINTERS)); +} + +// RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +constexpr uint16_t RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::_capnpPrivate::dataWordSize; +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +constexpr uint16_t RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::_capnpPrivate::pointerCount; +#if !CAPNP_LITE +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +constexpr ::capnp::Kind RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::_capnpPrivate::kind; +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +constexpr ::capnp::_::RawSchema const* RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::_capnpPrivate::schema; +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +constexpr ::capnp::_::RawBrandedSchema const* RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::_capnpPrivate::brand; +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +const ::capnp::_::RawBrandedSchema::Scope RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::_capnpPrivate::brandScopes[] = { + { 0x84ff286cd00a3ed4, brandBindings + 0, 4, false}, +}; +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +const ::capnp::_::RawBrandedSchema::Binding RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::_capnpPrivate::brandBindings[] = { + ::capnp::_::brandBindingFor<InternalRef>(), + ::capnp::_::brandBindingFor<ExternalRef>(), + ::capnp::_::brandBindingFor<InternalOwner>(), + ::capnp::_::brandBindingFor<ExternalOwner>(), +}; +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +const ::capnp::_::RawBrandedSchema::Dependency RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::_capnpPrivate::brandDependencies[] = { + { 16777216, ::capnp::Persistent<ExternalRef, ExternalOwner>::_capnpPrivate::brand }, + { 16777217, ::capnp::Persistent<InternalRef, InternalOwner>::SaveParams::_capnpPrivate::brand }, +}; +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +const ::capnp::_::RawBrandedSchema RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::_capnpPrivate::specificBrand = { + &::capnp::schemas::s_f0c2cc1d3909574d, brandScopes, brandDependencies, + sizeof(brandScopes) / sizeof(brandScopes[0]), sizeof(brandDependencies) / sizeof(brandDependencies[0]), nullptr +}; +#endif // !CAPNP_LITE + +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline bool RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::Reader::hasCap() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline bool RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::Builder::hasCap() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +#if !CAPNP_LITE +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline typename ::capnp::Persistent<InternalRef, InternalOwner>::Client RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::Reader::getCap() const { + return ::capnp::_::PointerHelpers< ::capnp::Persistent<InternalRef, InternalOwner>>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline typename ::capnp::Persistent<InternalRef, InternalOwner>::Client RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::Builder::getCap() { + return ::capnp::_::PointerHelpers< ::capnp::Persistent<InternalRef, InternalOwner>>::get( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline typename ::capnp::Persistent<InternalRef, InternalOwner>::Client RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::Pipeline::getCap() { + return typename ::capnp::Persistent<InternalRef, InternalOwner>::Client(_typeless.getPointerField(0).asCap()); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline void RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::Builder::setCap(typename ::capnp::Persistent<InternalRef, InternalOwner>::Client&& cap) { + ::capnp::_::PointerHelpers< ::capnp::Persistent<InternalRef, InternalOwner>>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(cap)); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline void RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::Builder::setCap(typename ::capnp::Persistent<InternalRef, InternalOwner>::Client& cap) { + ::capnp::_::PointerHelpers< ::capnp::Persistent<InternalRef, InternalOwner>>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), cap); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline void RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::Builder::adoptCap( + ::capnp::Orphan< ::capnp::Persistent<InternalRef, InternalOwner>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Persistent<InternalRef, InternalOwner>>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline ::capnp::Orphan< ::capnp::Persistent<InternalRef, InternalOwner>> RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::Builder::disownCap() { + return ::capnp::_::PointerHelpers< ::capnp::Persistent<InternalRef, InternalOwner>>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +#endif // !CAPNP_LITE + +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline bool RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::Reader::hasParams() const { + return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull(); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline bool RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::Builder::hasParams() { + return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull(); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline typename ::capnp::Persistent<ExternalRef, ExternalOwner>::SaveParams::Reader RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::Reader::getParams() const { + return ::capnp::_::PointerHelpers<typename ::capnp::Persistent<ExternalRef, ExternalOwner>::SaveParams>::get( + _reader.getPointerField(1 * ::capnp::POINTERS)); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline typename ::capnp::Persistent<ExternalRef, ExternalOwner>::SaveParams::Builder RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::Builder::getParams() { + return ::capnp::_::PointerHelpers<typename ::capnp::Persistent<ExternalRef, ExternalOwner>::SaveParams>::get( + _builder.getPointerField(1 * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline typename ::capnp::Persistent<ExternalRef, ExternalOwner>::SaveParams::Pipeline RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::Pipeline::getParams() { + return typename ::capnp::Persistent<ExternalRef, ExternalOwner>::SaveParams::Pipeline(_typeless.getPointerField(1)); +} +#endif // !CAPNP_LITE +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline void RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::Builder::setParams(typename ::capnp::Persistent<ExternalRef, ExternalOwner>::SaveParams::Reader value) { + ::capnp::_::PointerHelpers<typename ::capnp::Persistent<ExternalRef, ExternalOwner>::SaveParams>::set( + _builder.getPointerField(1 * ::capnp::POINTERS), value); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline typename ::capnp::Persistent<ExternalRef, ExternalOwner>::SaveParams::Builder RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::Builder::initParams() { + return ::capnp::_::PointerHelpers<typename ::capnp::Persistent<ExternalRef, ExternalOwner>::SaveParams>::init( + _builder.getPointerField(1 * ::capnp::POINTERS)); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline void RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::Builder::adoptParams( + ::capnp::Orphan<typename ::capnp::Persistent<ExternalRef, ExternalOwner>::SaveParams>&& value) { + ::capnp::_::PointerHelpers<typename ::capnp::Persistent<ExternalRef, ExternalOwner>::SaveParams>::adopt( + _builder.getPointerField(1 * ::capnp::POINTERS), kj::mv(value)); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +inline ::capnp::Orphan<typename ::capnp::Persistent<ExternalRef, ExternalOwner>::SaveParams> RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::Builder::disownParams() { + return ::capnp::_::PointerHelpers<typename ::capnp::Persistent<ExternalRef, ExternalOwner>::SaveParams>::disown( + _builder.getPointerField(1 * ::capnp::POINTERS)); +} + +// RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +constexpr uint16_t RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::_capnpPrivate::dataWordSize; +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +constexpr uint16_t RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::_capnpPrivate::pointerCount; +#if !CAPNP_LITE +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +constexpr ::capnp::Kind RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::_capnpPrivate::kind; +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +constexpr ::capnp::_::RawSchema const* RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::_capnpPrivate::schema; +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +constexpr ::capnp::_::RawBrandedSchema const* RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::_capnpPrivate::brand; +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +const ::capnp::_::RawBrandedSchema::Scope RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::_capnpPrivate::brandScopes[] = { + { 0x84ff286cd00a3ed4, brandBindings + 0, 4, false}, +}; +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +const ::capnp::_::RawBrandedSchema::Binding RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::_capnpPrivate::brandBindings[] = { + ::capnp::_::brandBindingFor<InternalRef>(), + ::capnp::_::brandBindingFor<ExternalRef>(), + ::capnp::_::brandBindingFor<InternalOwner>(), + ::capnp::_::brandBindingFor<ExternalOwner>(), +}; +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +const ::capnp::_::RawBrandedSchema::Dependency RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::_capnpPrivate::brandDependencies[] = { + { 16777216, ::capnp::Persistent<InternalRef, InternalOwner>::_capnpPrivate::brand }, + { 16777217, ::capnp::Persistent<ExternalRef, ExternalOwner>::SaveParams::_capnpPrivate::brand }, +}; +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +const ::capnp::_::RawBrandedSchema RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::_capnpPrivate::specificBrand = { + &::capnp::schemas::s_ecafa18b482da3aa, brandScopes, brandDependencies, + sizeof(brandScopes) / sizeof(brandScopes[0]), sizeof(brandDependencies) / sizeof(brandDependencies[0]), nullptr +}; +#endif // !CAPNP_LITE + +#if !CAPNP_LITE +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +::capnp::Request<typename ::capnp::RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams, typename ::capnp::Persistent<InternalRef, InternalOwner>::SaveResults> +RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::Client::importRequest(::kj::Maybe< ::capnp::MessageSize> sizeHint) { + return newCall<typename ::capnp::RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams, typename ::capnp::Persistent<InternalRef, InternalOwner>::SaveResults>( + 0x84ff286cd00a3ed4ull, 0, sizeHint); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +::kj::Promise<void> RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::Server::import(ImportContext) { + return ::capnp::Capability::Server::internalUnimplemented( + "capnp/persistent.capnp:RealmGateway", "import", + 0x84ff286cd00a3ed4ull, 0); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +::capnp::Request<typename ::capnp::RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams, typename ::capnp::Persistent<ExternalRef, ExternalOwner>::SaveResults> +RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::Client::exportRequest(::kj::Maybe< ::capnp::MessageSize> sizeHint) { + return newCall<typename ::capnp::RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams, typename ::capnp::Persistent<ExternalRef, ExternalOwner>::SaveResults>( + 0x84ff286cd00a3ed4ull, 1, sizeHint); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +::kj::Promise<void> RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::Server::export_(ExportContext) { + return ::capnp::Capability::Server::internalUnimplemented( + "capnp/persistent.capnp:RealmGateway", "export", + 0x84ff286cd00a3ed4ull, 1); +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +::kj::Promise<void> RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::Server::dispatchCall( + uint64_t interfaceId, uint16_t methodId, + ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context) { + switch (interfaceId) { + case 0x84ff286cd00a3ed4ull: + return dispatchCallInternal(methodId, context); + default: + return internalUnimplemented("capnp/persistent.capnp:RealmGateway", interfaceId); + } +} +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +::kj::Promise<void> RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::Server::dispatchCallInternal( + uint16_t methodId, + ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context) { + switch (methodId) { + case 0: + return import(::capnp::Capability::Server::internalGetTypedContext< + typename ::capnp::RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams, typename ::capnp::Persistent<InternalRef, InternalOwner>::SaveResults>(context)); + case 1: + return export_(::capnp::Capability::Server::internalGetTypedContext< + typename ::capnp::RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams, typename ::capnp::Persistent<ExternalRef, ExternalOwner>::SaveResults>(context)); + default: + (void)context; + return ::capnp::Capability::Server::internalUnimplemented( + "capnp/persistent.capnp:RealmGateway", + 0x84ff286cd00a3ed4ull, methodId); + } +} +#endif // !CAPNP_LITE + +// RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner> +#if !CAPNP_LITE +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +constexpr ::capnp::Kind RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::_capnpPrivate::kind; +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +constexpr ::capnp::_::RawSchema const* RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::_capnpPrivate::schema; +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +constexpr ::capnp::_::RawBrandedSchema const* RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::_capnpPrivate::brand; +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +const ::capnp::_::RawBrandedSchema::Scope RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::_capnpPrivate::brandScopes[] = { + { 0x84ff286cd00a3ed4, brandBindings + 0, 4, false}, +}; +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +const ::capnp::_::RawBrandedSchema::Binding RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::_capnpPrivate::brandBindings[] = { + ::capnp::_::brandBindingFor<InternalRef>(), + ::capnp::_::brandBindingFor<ExternalRef>(), + ::capnp::_::brandBindingFor<InternalOwner>(), + ::capnp::_::brandBindingFor<ExternalOwner>(), +}; +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +const ::capnp::_::RawBrandedSchema::Dependency RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::_capnpPrivate::brandDependencies[] = { + { 33554432, ::capnp::RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ImportParams::_capnpPrivate::brand }, + { 33554433, ::capnp::RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::ExportParams::_capnpPrivate::brand }, + { 50331648, ::capnp::Persistent<InternalRef, InternalOwner>::SaveResults::_capnpPrivate::brand }, + { 50331649, ::capnp::Persistent<ExternalRef, ExternalOwner>::SaveResults::_capnpPrivate::brand }, +}; +template <typename InternalRef, typename ExternalRef, typename InternalOwner, typename ExternalOwner> +const ::capnp::_::RawBrandedSchema RealmGateway<InternalRef, ExternalRef, InternalOwner, ExternalOwner>::_capnpPrivate::specificBrand = { + &::capnp::schemas::s_84ff286cd00a3ed4, brandScopes, brandDependencies, + sizeof(brandScopes) / sizeof(brandScopes[0]), sizeof(brandDependencies) / sizeof(brandDependencies[0]), nullptr +}; +#endif // !CAPNP_LITE + +} // namespace + +#endif // CAPNP_INCLUDED_b8630836983feed7_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/pointer-helpers.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,160 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef CAPNP_POINTER_HELPERS_H_ +#define CAPNP_POINTER_HELPERS_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "layout.h" +#include "list.h" + +namespace capnp { +namespace _ { // private + +// PointerHelpers is a template class that assists in wrapping/unwrapping the low-level types in +// layout.h with the high-level public API and generated types. This way, the code generator +// and other templates do not have to specialize on each kind of pointer. + +template <typename T> +struct PointerHelpers<T, Kind::STRUCT> { + static inline typename T::Reader get(PointerReader reader, const word* defaultValue = nullptr) { + return typename T::Reader(reader.getStruct(defaultValue)); + } + static inline typename T::Builder get(PointerBuilder builder, + const word* defaultValue = nullptr) { + return typename T::Builder(builder.getStruct(structSize<T>(), defaultValue)); + } + static inline void set(PointerBuilder builder, typename T::Reader value) { + builder.setStruct(value._reader); + } + static inline void setCanonical(PointerBuilder builder, typename T::Reader value) { + builder.setStruct(value._reader, true); + } + static inline typename T::Builder init(PointerBuilder builder) { + return typename T::Builder(builder.initStruct(structSize<T>())); + } + static inline void adopt(PointerBuilder builder, Orphan<T>&& value) { + builder.adopt(kj::mv(value.builder)); + } + static inline Orphan<T> disown(PointerBuilder builder) { + return Orphan<T>(builder.disown()); + } + static inline _::StructReader getInternalReader(const typename T::Reader& reader) { + return reader._reader; + } + static inline _::StructBuilder getInternalBuilder(typename T::Builder&& builder) { + return builder._builder; + } +}; + +template <typename T> +struct PointerHelpers<List<T>, Kind::LIST> { + static inline typename List<T>::Reader get(PointerReader reader, + const word* defaultValue = nullptr) { + return typename List<T>::Reader(List<T>::getFromPointer(reader, defaultValue)); + } + static inline typename List<T>::Builder get(PointerBuilder builder, + const word* defaultValue = nullptr) { + return typename List<T>::Builder(List<T>::getFromPointer(builder, defaultValue)); + } + static inline void set(PointerBuilder builder, typename List<T>::Reader value) { + builder.setList(value.reader); + } + static inline void setCanonical(PointerBuilder builder, typename List<T>::Reader value) { + builder.setList(value.reader, true); + } + static void set(PointerBuilder builder, kj::ArrayPtr<const ReaderFor<T>> value) { + auto l = init(builder, value.size()); + uint i = 0; + for (auto& element: value) { + l.set(i++, element); + } + } + static inline typename List<T>::Builder init(PointerBuilder builder, uint size) { + return typename List<T>::Builder(List<T>::initPointer(builder, size)); + } + static inline void adopt(PointerBuilder builder, Orphan<List<T>>&& value) { + builder.adopt(kj::mv(value.builder)); + } + static inline Orphan<List<T>> disown(PointerBuilder builder) { + return Orphan<List<T>>(builder.disown()); + } + static inline _::ListReader getInternalReader(const typename List<T>::Reader& reader) { + return reader.reader; + } + static inline _::ListBuilder getInternalBuilder(typename List<T>::Builder&& builder) { + return builder.builder; + } +}; + +template <typename T> +struct PointerHelpers<T, Kind::BLOB> { + static inline typename T::Reader get(PointerReader reader, + const void* defaultValue = nullptr, + uint defaultBytes = 0) { + return reader.getBlob<T>(defaultValue, defaultBytes * BYTES); + } + static inline typename T::Builder get(PointerBuilder builder, + const void* defaultValue = nullptr, + uint defaultBytes = 0) { + return builder.getBlob<T>(defaultValue, defaultBytes * BYTES); + } + static inline void set(PointerBuilder builder, typename T::Reader value) { + builder.setBlob<T>(value); + } + static inline void setCanonical(PointerBuilder builder, typename T::Reader value) { + builder.setBlob<T>(value); + } + static inline typename T::Builder init(PointerBuilder builder, uint size) { + return builder.initBlob<T>(size * BYTES); + } + static inline void adopt(PointerBuilder builder, Orphan<T>&& value) { + builder.adopt(kj::mv(value.builder)); + } + static inline Orphan<T> disown(PointerBuilder builder) { + return Orphan<T>(builder.disown()); + } +}; + +struct UncheckedMessage { + typedef const word* Reader; +}; + +template <> struct Kind_<UncheckedMessage> { static constexpr Kind kind = Kind::OTHER; }; + +template <> +struct PointerHelpers<UncheckedMessage> { + // Reads an AnyPointer field as an unchecked message pointer. Requires that the containing + // message is itself unchecked. This hack is currently private. It is used to locate default + // values within encoded schemas. + + static inline const word* get(PointerReader reader) { + return reader.getUnchecked(); + } +}; + +} // namespace _ (private) +} // namespace capnp + +#endif // CAPNP_POINTER_HELPERS_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/pretty-print.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,47 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef CAPNP_PRETTY_PRINT_H_ +#define CAPNP_PRETTY_PRINT_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "dynamic.h" +#include <kj/string-tree.h> + +namespace capnp { + +kj::StringTree prettyPrint(DynamicStruct::Reader value); +kj::StringTree prettyPrint(DynamicStruct::Builder value); +kj::StringTree prettyPrint(DynamicList::Reader value); +kj::StringTree prettyPrint(DynamicList::Builder value); +// Print the given Cap'n Proto struct or list with nice indentation. Note that you can pass any +// struct or list reader or builder type to this method, since they can be implicitly converted +// to one of the dynamic types. +// +// If you don't want indentation, just use the value's KJ stringifier (e.g. pass it to kj::str(), +// any of the KJ debug macros, etc.). + +} // namespace capnp + +#endif // PRETTY_PRINT_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/rpc-prelude.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,130 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// This file contains a bunch of internal declarations that must appear before rpc.h can start. +// We don't define these directly in rpc.h because it makes the file hard to read. + +#ifndef CAPNP_RPC_PRELUDE_H_ +#define CAPNP_RPC_PRELUDE_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "capability.h" +#include "persistent.capnp.h" + +namespace capnp { + +class OutgoingRpcMessage; +class IncomingRpcMessage; + +template <typename SturdyRefHostId> +class RpcSystem; + +namespace _ { // private + +class VatNetworkBase { + // Non-template version of VatNetwork. Ignore this class; see VatNetwork in rpc.h. + +public: + class Connection; + + struct ConnectionAndProvisionId { + kj::Own<Connection> connection; + kj::Own<OutgoingRpcMessage> firstMessage; + Orphan<AnyPointer> provisionId; + }; + + class Connection { + public: + virtual kj::Own<OutgoingRpcMessage> newOutgoingMessage(uint firstSegmentWordSize) = 0; + virtual kj::Promise<kj::Maybe<kj::Own<IncomingRpcMessage>>> receiveIncomingMessage() = 0; + virtual kj::Promise<void> shutdown() = 0; + virtual AnyStruct::Reader baseGetPeerVatId() = 0; + }; + virtual kj::Maybe<kj::Own<Connection>> baseConnect(AnyStruct::Reader vatId) = 0; + virtual kj::Promise<kj::Own<Connection>> baseAccept() = 0; +}; + +class SturdyRefRestorerBase { +public: + virtual Capability::Client baseRestore(AnyPointer::Reader ref) = 0; +}; + +class BootstrapFactoryBase { + // Non-template version of BootstrapFactory. Ignore this class; see BootstrapFactory in rpc.h. +public: + virtual Capability::Client baseCreateFor(AnyStruct::Reader clientId) = 0; +}; + +class RpcSystemBase { + // Non-template version of RpcSystem. Ignore this class; see RpcSystem in rpc.h. + +public: + RpcSystemBase(VatNetworkBase& network, kj::Maybe<Capability::Client> bootstrapInterface, + kj::Maybe<RealmGateway<>::Client> gateway); + RpcSystemBase(VatNetworkBase& network, BootstrapFactoryBase& bootstrapFactory, + kj::Maybe<RealmGateway<>::Client> gateway); + RpcSystemBase(VatNetworkBase& network, SturdyRefRestorerBase& restorer); + RpcSystemBase(RpcSystemBase&& other) noexcept; + ~RpcSystemBase() noexcept(false); + +private: + class Impl; + kj::Own<Impl> impl; + + Capability::Client baseBootstrap(AnyStruct::Reader vatId); + Capability::Client baseRestore(AnyStruct::Reader vatId, AnyPointer::Reader objectId); + void baseSetFlowLimit(size_t words); + + template <typename> + friend class capnp::RpcSystem; +}; + +template <typename T> struct InternalRefFromRealmGateway_; +template <typename InternalRef, typename ExternalRef, typename InternalOwner, + typename ExternalOwner> +struct InternalRefFromRealmGateway_<RealmGateway<InternalRef, ExternalRef, InternalOwner, + ExternalOwner>> { + typedef InternalRef Type; +}; +template <typename T> +using InternalRefFromRealmGateway = typename InternalRefFromRealmGateway_<T>::Type; +template <typename T> +using InternalRefFromRealmGatewayClient = InternalRefFromRealmGateway<typename T::Calls>; + +template <typename T> struct ExternalRefFromRealmGateway_; +template <typename InternalRef, typename ExternalRef, typename InternalOwner, + typename ExternalOwner> +struct ExternalRefFromRealmGateway_<RealmGateway<InternalRef, ExternalRef, InternalOwner, + ExternalOwner>> { + typedef ExternalRef Type; +}; +template <typename T> +using ExternalRefFromRealmGateway = typename ExternalRefFromRealmGateway_<T>::Type; +template <typename T> +using ExternalRefFromRealmGatewayClient = ExternalRefFromRealmGateway<typename T::Calls>; + +} // namespace _ (private) +} // namespace capnp + +#endif // CAPNP_RPC_PRELUDE_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/rpc-twoparty.capnp Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,169 @@ +# Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +# Licensed under the MIT License: +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +@0xa184c7885cdaf2a1; +# This file defines the "network-specific parameters" in rpc.capnp to support a network consisting +# of two vats. Each of these vats may in fact be in communication with other vats, but any +# capabilities they forward must be proxied. Thus, to each end of the connection, all capabilities +# received from the other end appear to live in a single vat. +# +# Two notable use cases for this model include: +# - Regular client-server communications, where a remote client machine (perhaps living on an end +# user's personal device) connects to a server. The server may be part of a cluster, and may +# call on other servers in the cluster to help service the user's request. It may even obtain +# capabilities from these other servers which it passes on to the user. To simplify network +# common traversal problems (e.g. if the user is behind a firewall), it is probably desirable to +# multiplex all communications between the server cluster and the client over the original +# connection rather than form new ones. This connection should use the two-party protocol, as +# the client has no interest in knowing about additional servers. +# - Applications running in a sandbox. A supervisor process may execute a confined application +# such that all of the confined app's communications with the outside world must pass through +# the supervisor. In this case, the connection between the confined app and the supervisor might +# as well use the two-party protocol, because the confined app is intentionally prevented from +# talking to any other vat anyway. Any external resources will be proxied through the supervisor, +# and so to the contained app will appear as if they were hosted by the supervisor itself. +# +# Since there are only two vats in this network, there is never a need for three-way introductions, +# so level 3 is free. Moreover, because it is never necessary to form new connections, the +# two-party protocol can be used easily anywhere where a two-way byte stream exists, without regard +# to where that byte stream goes or how it was initiated. This makes the two-party runtime library +# highly reusable. +# +# Joins (level 4) _could_ be needed in cases where one or both vats are participating in other +# networks that use joins. For instance, if Alice and Bob are speaking through the two-party +# protocol, and Bob is also participating on another network, Bob may send Alice two or more +# proxied capabilities which, unbeknownst to Bob at the time, are in fact pointing at the same +# remote object. Alice may then request to join these capabilities, at which point Bob will have +# to forward the join to the other network. Note, however, that if Alice is _not_ participating on +# any other network, then Alice will never need to _receive_ a Join, because Alice would always +# know when two locally-hosted capabilities are the same and would never export a redundant alias +# to Bob. So, Alice can respond to all incoming joins with an error, and only needs to implement +# outgoing joins if she herself desires to use this feature. Also, outgoing joins are relatively +# easy to implement in this scenario. +# +# What all this means is that a level 4 implementation of the confined network is barely more +# complicated than a level 2 implementation. However, such an implementation allows the "client" +# or "confined" app to access the server's/supervisor's network with equal functionality to any +# native participant. In other words, an application which implements only the two-party protocol +# can be paired with a proxy app in order to participate in any network. +# +# So, when implementing Cap'n Proto in a new language, it makes sense to implement only the +# two-party protocol initially, and then pair applications with an appropriate proxy written in +# C++, rather than implement other parameterizations of the RPC protocol directly. + +using Cxx = import "/capnp/c++.capnp"; +$Cxx.namespace("capnp::rpc::twoparty"); + +# Note: SturdyRef is not specified here. It is up to the application to define semantics of +# SturdyRefs if desired. + +enum Side { + server @0; + # The object lives on the "server" or "supervisor" end of the connection. Only the + # server/supervisor knows how to interpret the ref; to the client, it is opaque. + # + # Note that containers intending to implement strong confinement should rewrite SturdyRefs + # received from the external network before passing them on to the confined app. The confined + # app thus does not ever receive the raw bits of the SturdyRef (which it could perhaps + # maliciously leak), but instead receives only a thing that it can pass back to the container + # later to restore the ref. See: + # http://www.erights.org/elib/capability/dist-confine.html + + client @1; + # The object lives on the "client" or "confined app" end of the connection. Only the client + # knows how to interpret the ref; to the server/supervisor, it is opaque. Most clients do not + # actually know how to persist capabilities at all, so use of this is unusual. +} + +struct VatId { + side @0 :Side; +} + +struct ProvisionId { + # Only used for joins, since three-way introductions never happen on a two-party network. + + joinId @0 :UInt32; + # The ID from `JoinKeyPart`. +} + +struct RecipientId {} +# Never used, because there are only two parties. + +struct ThirdPartyCapId {} +# Never used, because there is no third party. + +struct JoinKeyPart { + # Joins in the two-party case are simplified by a few observations. + # + # First, on a two-party network, a Join only ever makes sense if the receiving end is also + # connected to other networks. A vat which is not connected to any other network can safely + # reject all joins. + # + # Second, since a two-party connection bisects the network -- there can be no other connections + # between the networks at either end of the connection -- if one part of a join crosses the + # connection, then _all_ parts must cross it. Therefore, a vat which is receiving a Join request + # off some other network which needs to be forwarded across the two-party connection can + # collect all the parts on its end and only forward them across the two-party connection when all + # have been received. + # + # For example, imagine that Alice and Bob are vats connected over a two-party connection, and + # each is also connected to other networks. At some point, Alice receives one part of a Join + # request off her network. The request is addressed to a capability that Alice received from + # Bob and is proxying to her other network. Alice goes ahead and responds to the Join part as + # if she hosted the capability locally (this is important so that if not all the Join parts end + # up at Alice, the original sender can detect the failed Join without hanging). As other parts + # trickle in, Alice verifies that each part is addressed to a capability from Bob and continues + # to respond to each one. Once the complete set of join parts is received, Alice checks if they + # were all for the exact same capability. If so, she doesn't need to send anything to Bob at + # all. Otherwise, she collects the set of capabilities (from Bob) to which the join parts were + # addressed and essentially initiates a _new_ Join request on those capabilities to Bob. Alice + # does not forward the Join parts she received herself, but essentially forwards the Join as a + # whole. + # + # On Bob's end, since he knows that Alice will always send all parts of a Join together, he + # simply waits until he's received them all, then performs a join on the respective capabilities + # as if it had been requested locally. + + joinId @0 :UInt32; + # A number identifying this join, chosen by the sender. May be reused once `Finish` messages are + # sent corresponding to all of the `Join` messages. + + partCount @1 :UInt16; + # The number of capabilities to be joined. + + partNum @2 :UInt16; + # Which part this request targets -- a number in the range [0, partCount). +} + +struct JoinResult { + joinId @0 :UInt32; + # Matches `JoinKeyPart`. + + succeeded @1 :Bool; + # All JoinResults in the set will have the same value for `succeeded`. The receiver actually + # implements the join by waiting for all the `JoinKeyParts` and then performing its own join on + # them, then going back and answering all the join requests afterwards. + + cap @2 :AnyPointer; + # One of the JoinResults will have a non-null `cap` which is the joined capability. + # + # TODO(cleanup): Change `AnyPointer` to `Capability` when that is supported. +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/rpc-twoparty.capnp.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,724 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: rpc-twoparty.capnp + +#ifndef CAPNP_INCLUDED_a184c7885cdaf2a1_ +#define CAPNP_INCLUDED_a184c7885cdaf2a1_ + +#include <capnp/generated-header-support.h> + +#if CAPNP_VERSION != 6000 +#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." +#endif + + +namespace capnp { +namespace schemas { + +CAPNP_DECLARE_SCHEMA(9fd69ebc87b9719c); +enum class Side_9fd69ebc87b9719c: uint16_t { + SERVER, + CLIENT, +}; +CAPNP_DECLARE_ENUM(Side, 9fd69ebc87b9719c); +CAPNP_DECLARE_SCHEMA(d20b909fee733a8e); +CAPNP_DECLARE_SCHEMA(b88d09a9c5f39817); +CAPNP_DECLARE_SCHEMA(89f389b6fd4082c1); +CAPNP_DECLARE_SCHEMA(b47f4979672cb59d); +CAPNP_DECLARE_SCHEMA(95b29059097fca83); +CAPNP_DECLARE_SCHEMA(9d263a3630b7ebee); + +} // namespace schemas +} // namespace capnp + +namespace capnp { +namespace rpc { +namespace twoparty { + +typedef ::capnp::schemas::Side_9fd69ebc87b9719c Side; + +struct VatId { + VatId() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(d20b909fee733a8e, 1, 0) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct ProvisionId { + ProvisionId() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(b88d09a9c5f39817, 1, 0) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct RecipientId { + RecipientId() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(89f389b6fd4082c1, 0, 0) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct ThirdPartyCapId { + ThirdPartyCapId() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(b47f4979672cb59d, 0, 0) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct JoinKeyPart { + JoinKeyPart() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(95b29059097fca83, 1, 0) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct JoinResult { + JoinResult() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(9d263a3630b7ebee, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +// ======================================================================================= + +class VatId::Reader { +public: + typedef VatId 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 ::capnp::rpc::twoparty::Side getSide() 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 VatId::Builder { +public: + typedef VatId 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 ::capnp::rpc::twoparty::Side getSide(); + inline void setSide( ::capnp::rpc::twoparty::Side 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 VatId::Pipeline { +public: + typedef VatId 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 ProvisionId::Reader { +public: + typedef ProvisionId 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 getJoinId() 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 ProvisionId::Builder { +public: + typedef ProvisionId 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 getJoinId(); + inline void setJoinId( ::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 ProvisionId::Pipeline { +public: + typedef ProvisionId 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 RecipientId::Reader { +public: + typedef RecipientId 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 + +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 RecipientId::Builder { +public: + typedef RecipientId 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 + +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 RecipientId::Pipeline { +public: + typedef RecipientId 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 ThirdPartyCapId::Reader { +public: + typedef ThirdPartyCapId 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 + +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 ThirdPartyCapId::Builder { +public: + typedef ThirdPartyCapId 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 + +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 ThirdPartyCapId::Pipeline { +public: + typedef ThirdPartyCapId 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 JoinKeyPart::Reader { +public: + typedef JoinKeyPart 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 getJoinId() const; + + inline ::uint16_t getPartCount() const; + + inline ::uint16_t getPartNum() 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 JoinKeyPart::Builder { +public: + typedef JoinKeyPart 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 getJoinId(); + inline void setJoinId( ::uint32_t value); + + inline ::uint16_t getPartCount(); + inline void setPartCount( ::uint16_t value); + + inline ::uint16_t getPartNum(); + inline void setPartNum( ::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 JoinKeyPart::Pipeline { +public: + typedef JoinKeyPart 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 JoinResult::Reader { +public: + typedef JoinResult 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 getJoinId() const; + + inline bool getSucceeded() const; + + inline bool hasCap() const; + inline ::capnp::AnyPointer::Reader getCap() 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 JoinResult::Builder { +public: + typedef JoinResult 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 getJoinId(); + inline void setJoinId( ::uint32_t value); + + inline bool getSucceeded(); + inline void setSucceeded(bool value); + + inline bool hasCap(); + inline ::capnp::AnyPointer::Builder getCap(); + inline ::capnp::AnyPointer::Builder initCap(); + +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 JoinResult::Pipeline { +public: + typedef JoinResult 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::twoparty::Side VatId::Reader::getSide() const { + return _reader.getDataField< ::capnp::rpc::twoparty::Side>( + 0 * ::capnp::ELEMENTS); +} + +inline ::capnp::rpc::twoparty::Side VatId::Builder::getSide() { + return _builder.getDataField< ::capnp::rpc::twoparty::Side>( + 0 * ::capnp::ELEMENTS); +} +inline void VatId::Builder::setSide( ::capnp::rpc::twoparty::Side value) { + _builder.setDataField< ::capnp::rpc::twoparty::Side>( + 0 * ::capnp::ELEMENTS, value); +} + +inline ::uint32_t ProvisionId::Reader::getJoinId() const { + return _reader.getDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS); +} + +inline ::uint32_t ProvisionId::Builder::getJoinId() { + return _builder.getDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS); +} +inline void ProvisionId::Builder::setJoinId( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS, value); +} + +inline ::uint32_t JoinKeyPart::Reader::getJoinId() const { + return _reader.getDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS); +} + +inline ::uint32_t JoinKeyPart::Builder::getJoinId() { + return _builder.getDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS); +} +inline void JoinKeyPart::Builder::setJoinId( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS, value); +} + +inline ::uint16_t JoinKeyPart::Reader::getPartCount() const { + return _reader.getDataField< ::uint16_t>( + 2 * ::capnp::ELEMENTS); +} + +inline ::uint16_t JoinKeyPart::Builder::getPartCount() { + return _builder.getDataField< ::uint16_t>( + 2 * ::capnp::ELEMENTS); +} +inline void JoinKeyPart::Builder::setPartCount( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + 2 * ::capnp::ELEMENTS, value); +} + +inline ::uint16_t JoinKeyPart::Reader::getPartNum() const { + return _reader.getDataField< ::uint16_t>( + 3 * ::capnp::ELEMENTS); +} + +inline ::uint16_t JoinKeyPart::Builder::getPartNum() { + return _builder.getDataField< ::uint16_t>( + 3 * ::capnp::ELEMENTS); +} +inline void JoinKeyPart::Builder::setPartNum( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + 3 * ::capnp::ELEMENTS, value); +} + +inline ::uint32_t JoinResult::Reader::getJoinId() const { + return _reader.getDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS); +} + +inline ::uint32_t JoinResult::Builder::getJoinId() { + return _builder.getDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS); +} +inline void JoinResult::Builder::setJoinId( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool JoinResult::Reader::getSucceeded() const { + return _reader.getDataField<bool>( + 32 * ::capnp::ELEMENTS); +} + +inline bool JoinResult::Builder::getSucceeded() { + return _builder.getDataField<bool>( + 32 * ::capnp::ELEMENTS); +} +inline void JoinResult::Builder::setSucceeded(bool value) { + _builder.setDataField<bool>( + 32 * ::capnp::ELEMENTS, value); +} + +inline bool JoinResult::Reader::hasCap() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool JoinResult::Builder::hasCap() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::AnyPointer::Reader JoinResult::Reader::getCap() const { + return ::capnp::AnyPointer::Reader( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder JoinResult::Builder::getCap() { + return ::capnp::AnyPointer::Builder( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder JoinResult::Builder::initCap() { + auto result = ::capnp::AnyPointer::Builder( + _builder.getPointerField(0 * ::capnp::POINTERS)); + result.clear(); + return result; +} + +} // namespace +} // namespace +} // namespace + +#endif // CAPNP_INCLUDED_a184c7885cdaf2a1_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/rpc-twoparty.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,160 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef CAPNP_RPC_TWOPARTY_H_ +#define CAPNP_RPC_TWOPARTY_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "rpc.h" +#include "message.h" +#include <kj/async-io.h> +#include <capnp/rpc-twoparty.capnp.h> + +namespace capnp { + +namespace rpc { + namespace twoparty { + typedef VatId SturdyRefHostId; // For backwards-compatibility with version 0.4. + } +} + +typedef VatNetwork<rpc::twoparty::VatId, rpc::twoparty::ProvisionId, + rpc::twoparty::RecipientId, rpc::twoparty::ThirdPartyCapId, rpc::twoparty::JoinResult> + TwoPartyVatNetworkBase; + +class TwoPartyVatNetwork: public TwoPartyVatNetworkBase, + private TwoPartyVatNetworkBase::Connection { + // A `VatNetwork` that consists of exactly two parties communicating over an arbitrary byte + // stream. This is used to implement the common case of a client/server network. + // + // See `ez-rpc.h` for a simple interface for setting up two-party clients and servers. + // Use `TwoPartyVatNetwork` only if you need the advanced features. + +public: + TwoPartyVatNetwork(kj::AsyncIoStream& stream, rpc::twoparty::Side side, + ReaderOptions receiveOptions = ReaderOptions()); + KJ_DISALLOW_COPY(TwoPartyVatNetwork); + + kj::Promise<void> onDisconnect() { return disconnectPromise.addBranch(); } + // Returns a promise that resolves when the peer disconnects. + + rpc::twoparty::Side getSide() { return side; } + + // implements VatNetwork ----------------------------------------------------- + + kj::Maybe<kj::Own<TwoPartyVatNetworkBase::Connection>> connect( + rpc::twoparty::VatId::Reader ref) override; + kj::Promise<kj::Own<TwoPartyVatNetworkBase::Connection>> accept() override; + +private: + class OutgoingMessageImpl; + class IncomingMessageImpl; + + kj::AsyncIoStream& stream; + rpc::twoparty::Side side; + MallocMessageBuilder peerVatId; + ReaderOptions receiveOptions; + bool accepted = false; + + kj::Maybe<kj::Promise<void>> previousWrite; + // Resolves when the previous write completes. This effectively serves as the write queue. + // Becomes null when shutdown() is called. + + kj::Own<kj::PromiseFulfiller<kj::Own<TwoPartyVatNetworkBase::Connection>>> acceptFulfiller; + // Fulfiller for the promise returned by acceptConnectionAsRefHost() on the client side, or the + // second call on the server side. Never fulfilled, because there is only one connection. + + kj::ForkedPromise<void> disconnectPromise = nullptr; + + class FulfillerDisposer: public kj::Disposer { + // Hack: TwoPartyVatNetwork is both a VatNetwork and a VatNetwork::Connection. When the RPC + // system detects (or initiates) a disconnection, it drops its reference to the Connection. + // When all references have been dropped, then we want disconnectPromise to be fulfilled. + // So we hand out Own<Connection>s with this disposer attached, so that we can detect when + // they are dropped. + + public: + mutable kj::Own<kj::PromiseFulfiller<void>> fulfiller; + mutable uint refcount = 0; + + void disposeImpl(void* pointer) const override; + }; + FulfillerDisposer disconnectFulfiller; + + kj::Own<TwoPartyVatNetworkBase::Connection> asConnection(); + // Returns a pointer to this with the disposer set to disconnectFulfiller. + + // implements Connection ----------------------------------------------------- + + rpc::twoparty::VatId::Reader getPeerVatId() override; + kj::Own<OutgoingRpcMessage> newOutgoingMessage(uint firstSegmentWordSize) override; + kj::Promise<kj::Maybe<kj::Own<IncomingRpcMessage>>> receiveIncomingMessage() override; + kj::Promise<void> shutdown() override; +}; + +class TwoPartyServer: private kj::TaskSet::ErrorHandler { + // Convenience class which implements a simple server which accepts connections on a listener + // socket and serices them as two-party connections. + +public: + explicit TwoPartyServer(Capability::Client bootstrapInterface); + + void accept(kj::Own<kj::AsyncIoStream>&& connection); + // Accepts the connection for servicing. + + kj::Promise<void> listen(kj::ConnectionReceiver& listener); + // Listens for connections on the given listener. The returned promise never resolves unless an + // exception is thrown while trying to accept. You may discard the returned promise to cancel + // listening. + +private: + Capability::Client bootstrapInterface; + kj::TaskSet tasks; + + struct AcceptedConnection; + + void taskFailed(kj::Exception&& exception) override; +}; + +class TwoPartyClient { + // Convenience class which implements a simple client. + +public: + explicit TwoPartyClient(kj::AsyncIoStream& connection); + TwoPartyClient(kj::AsyncIoStream& connection, Capability::Client bootstrapInterface, + rpc::twoparty::Side side = rpc::twoparty::Side::CLIENT); + + Capability::Client bootstrap(); + // Get the server's bootstrap interface. + + inline kj::Promise<void> onDisconnect() { return network.onDisconnect(); } + +private: + TwoPartyVatNetwork network; + RpcSystem<rpc::twoparty::VatId> rpcSystem; +}; + +} // namespace capnp + +#endif // CAPNP_RPC_TWOPARTY_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/rpc.capnp Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,1399 @@ +# Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +# Licensed under the MIT License: +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +@0xb312981b2552a250; +# Recall that Cap'n Proto RPC allows messages to contain references to remote objects that +# implement interfaces. These references are called "capabilities", because they both designate +# the remote object to use and confer permission to use it. +# +# Recall also that Cap'n Proto RPC has the feature that when a method call itself returns a +# capability, the caller can begin calling methods on that capability _before the first call has +# returned_. The caller essentially sends a message saying "Hey server, as soon as you finish +# that previous call, do this with the result!". Cap'n Proto's RPC protocol makes this possible. +# +# The protocol is significantly more complicated than most RPC protocols. However, this is +# implementation complexity that underlies an easy-to-grasp higher-level model of object oriented +# programming. That is, just like TCP is a surprisingly complicated protocol that implements a +# conceptually-simple byte stream abstraction, Cap'n Proto is a surprisingly complicated protocol +# that implements a conceptually-simple object abstraction. +# +# Cap'n Proto RPC is based heavily on CapTP, the object-capability protocol used by the E +# programming language: +# http://www.erights.org/elib/distrib/captp/index.html +# +# Cap'n Proto RPC takes place between "vats". A vat hosts some set of objects and talks to other +# vats through direct bilateral connections. Typically, there is a 1:1 correspondence between vats +# and processes (in the unix sense of the word), although this is not strictly always true (one +# process could run multiple vats, or a distributed virtual vat might live across many processes). +# +# Cap'n Proto does not distinguish between "clients" and "servers" -- this is up to the application. +# Either end of any connection can potentially hold capabilities pointing to the other end, and +# can call methods on those capabilities. In the doc comments below, we use the words "sender" +# and "receiver". These refer to the sender and receiver of an instance of the struct or field +# being documented. Sometimes we refer to a "third-party" that is neither the sender nor the +# receiver. Documentation is generally written from the point of view of the sender. +# +# It is generally up to the vat network implementation to securely verify that connections are made +# to the intended vat as well as to encrypt transmitted data for privacy and integrity. See the +# `VatNetwork` example interface near the end of this file. +# +# When a new connection is formed, the only interesting things that can be done are to send a +# `Bootstrap` (level 0) or `Accept` (level 3) message. +# +# Unless otherwise specified, messages must be delivered to the receiving application in the same +# order in which they were initiated by the sending application. The goal is to support "E-Order", +# which states that two calls made on the same reference must be delivered in the order which they +# were made: +# http://erights.org/elib/concurrency/partial-order.html +# +# Since the full protocol is complicated, we define multiple levels of support that an +# implementation may target. For many applications, level 1 support will be sufficient. +# Comments in this file indicate which level requires the corresponding feature to be +# implemented. +# +# * **Level 0:** The implementation does not support object references. Only the bootstrap interface +# can be called. At this level, the implementation does not support object-oriented protocols and +# is similar in complexity to JSON-RPC or Protobuf services. This level should be considered only +# a temporary stepping-stone toward level 1 as the lack of object references drastically changes +# how protocols are designed. Applications _should not_ attempt to design their protocols around +# the limitations of level 0 implementations. +# +# * **Level 1:** The implementation supports simple bilateral interaction with object references +# and promise pipelining, but interactions between three or more parties are supported only via +# proxying of objects. E.g. if Alice (in Vat A) wants to send Bob (in Vat B) a capability +# pointing to Carol (in Vat C), Alice must create a proxy of Carol within Vat A and send Bob a +# reference to that; Bob cannot form a direct connection to Carol. Level 1 implementations do +# not support checking if two capabilities received from different vats actually point to the +# same object ("join"), although they should be able to do this check on capabilities received +# from the same vat. +# +# * **Level 2:** The implementation supports saving persistent capabilities -- i.e. capabilities +# that remain valid even after disconnect, and can be restored on a future connection. When a +# capability is saved, the requester receives a `SturdyRef`, which is a token that can be used +# to restore the capability later. +# +# * **Level 3:** The implementation supports three-way interactions. That is, if Alice (in Vat A) +# sends Bob (in Vat B) a capability pointing to Carol (in Vat C), then Vat B will automatically +# form a direct connection to Vat C rather than have requests be proxied through Vat A. +# +# * **Level 4:** The entire protocol is implemented, including joins (checking if two capabilities +# are equivalent). +# +# Note that an implementation must also support specific networks (transports), as described in +# the "Network-specific Parameters" section below. An implementation might have different levels +# depending on the network used. +# +# New implementations of Cap'n Proto should start out targeting the simplistic two-party network +# type as defined in `rpc-twoparty.capnp`. With this network type, level 3 is irrelevant and +# levels 2 and 4 are much easier than usual to implement. When such an implementation is paired +# with a container proxy, the contained app effectively gets to make full use of the proxy's +# network at level 4. And since Cap'n Proto IPC is extremely fast, it may never make sense to +# bother implementing any other vat network protocol -- just use the correct container type and get +# it for free. + +using Cxx = import "/capnp/c++.capnp"; +$Cxx.namespace("capnp::rpc"); + +# ======================================================================================== +# The Four Tables +# +# Cap'n Proto RPC connections are stateful (although an application built on Cap'n Proto could +# export a stateless interface). As in CapTP, for each open connection, a vat maintains four state +# tables: questions, answers, imports, and exports. See the diagram at: +# http://www.erights.org/elib/distrib/captp/4tables.html +# +# The question table corresponds to the other end's answer table, and the imports table corresponds +# to the other end's exports table. +# +# The entries in each table are identified by ID numbers (defined below as 32-bit integers). These +# numbers are always specific to the connection; a newly-established connection starts with no +# valid IDs. Since low-numbered IDs will pack better, it is suggested that IDs be assigned like +# Unix file descriptors -- prefer the lowest-number ID that is currently available. +# +# IDs in the questions/answers tables are chosen by the questioner and generally represent method +# calls that are in progress. +# +# IDs in the imports/exports tables are chosen by the exporter and generally represent objects on +# which methods may be called. Exports may be "settled", meaning the exported object is an actual +# object living in the exporter's vat, or they may be "promises", meaning the exported object is +# the as-yet-unknown result of an ongoing operation and will eventually be resolved to some other +# object once that operation completes. Calls made to a promise will be forwarded to the eventual +# target once it is known. The eventual replacement object does *not* get the same ID as the +# promise, as it may turn out to be an object that is already exported (so already has an ID) or +# may even live in a completely different vat (and so won't get an ID on the same export table +# at all). +# +# IDs can be reused over time. To make this safe, we carefully define the lifetime of IDs. Since +# messages using the ID could be traveling in both directions simultaneously, we must define the +# end of life of each ID _in each direction_. The ID is only safe to reuse once it has been +# released by both sides. +# +# When a Cap'n Proto connection is lost, everything on the four tables is lost. All questions are +# canceled and throw exceptions. All imports become broken (all future calls to them throw +# exceptions). All exports and answers are implicitly released. The only things not lost are +# persistent capabilities (`SturdyRef`s). The application must plan for this and should respond by +# establishing a new connection and restoring from these persistent capabilities. + +using QuestionId = UInt32; +# **(level 0)** +# +# Identifies a question in the sender's question table (which corresponds to the receiver's answer +# table). The questioner (caller) chooses an ID when making a call. The ID remains valid in +# caller -> callee messages until a Finish message is sent, and remains valid in callee -> caller +# messages until a Return message is sent. + +using AnswerId = QuestionId; +# **(level 0)** +# +# Identifies an answer in the sender's answer table (which corresponds to the receiver's question +# table). +# +# AnswerId is physically equivalent to QuestionId, since the question and answer tables correspond, +# but we define a separate type for documentation purposes: we always use the type representing +# the sender's point of view. + +using ExportId = UInt32; +# **(level 1)** +# +# Identifies an exported capability or promise in the sender's export table (which corresponds +# to the receiver's import table). The exporter chooses an ID before sending a capability over the +# wire. If the capability is already in the table, the exporter should reuse the same ID. If the +# ID is a promise (as opposed to a settled capability), this must be indicated at the time the ID +# is introduced (e.g. by using `senderPromise` instead of `senderHosted` in `CapDescriptor`); in +# this case, the importer shall expect a later `Resolve` message that replaces the promise. +# +# ExportId/ImportIds are subject to reference counting. Whenever an `ExportId` is sent over the +# wire (from the exporter to the importer), the export's reference count is incremented (unless +# otherwise specified). The reference count is later decremented by a `Release` message. Since +# the `Release` message can specify an arbitrary number by which to reduce the reference count, the +# importer should usually batch reference decrements and only send a `Release` when it believes the +# reference count has hit zero. Of course, it is possible that a new reference to the export is +# in-flight at the time that the `Release` message is sent, so it is necessary for the exporter to +# keep track of the reference count on its end as well to avoid race conditions. +# +# When a connection is lost, all exports are implicitly released. It is not possible to restore +# a connection state after disconnect (although a transport layer could implement a concept of +# persistent connections if it is transparent to the RPC layer). + +using ImportId = ExportId; +# **(level 1)** +# +# Identifies an imported capability or promise in the sender's import table (which corresponds to +# the receiver's export table). +# +# ImportId is physically equivalent to ExportId, since the export and import tables correspond, +# but we define a separate type for documentation purposes: we always use the type representing +# the sender's point of view. +# +# An `ImportId` remains valid in importer -> exporter messages until the importer has sent +# `Release` messages that (it believes) have reduced the reference count to zero. + +# ======================================================================================== +# Messages + +struct Message { + # An RPC connection is a bi-directional stream of Messages. + + union { + unimplemented @0 :Message; + # The sender previously received this message from the peer but didn't understand it or doesn't + # yet implement the functionality that was requested. So, the sender is echoing the message + # back. In some cases, the receiver may be able to recover from this by pretending the sender + # had taken some appropriate "null" action. + # + # For example, say `resolve` is received by a level 0 implementation (because a previous call + # or return happened to contain a promise). The level 0 implementation will echo it back as + # `unimplemented`. The original sender can then simply release the cap to which the promise + # had resolved, thus avoiding a leak. + # + # For any message type that introduces a question, if the message comes back unimplemented, + # the original sender may simply treat it as if the question failed with an exception. + # + # In cases where there is no sensible way to react to an `unimplemented` message (without + # resource leaks or other serious problems), the connection may need to be aborted. This is + # a gray area; different implementations may take different approaches. + + abort @1 :Exception; + # Sent when a connection is being aborted due to an unrecoverable error. This could be e.g. + # because the sender received an invalid or nonsensical message (`isCallersFault` is true) or + # because the sender had an internal error (`isCallersFault` is false). The sender will shut + # down the outgoing half of the connection after `abort` and will completely close the + # connection shortly thereafter (it's up to the sender how much of a time buffer they want to + # offer for the client to receive the `abort` before the connection is reset). + + # Level 0 features ----------------------------------------------- + + bootstrap @8 :Bootstrap; # Request the peer's bootstrap interface. + call @2 :Call; # Begin a method call. + return @3 :Return; # Complete a method call. + finish @4 :Finish; # Release a returned answer / cancel a call. + + # Level 1 features ----------------------------------------------- + + resolve @5 :Resolve; # Resolve a previously-sent promise. + release @6 :Release; # Release a capability so that the remote object can be deallocated. + disembargo @13 :Disembargo; # Lift an embargo used to enforce E-order over promise resolution. + + # Level 2 features ----------------------------------------------- + + obsoleteSave @7 :AnyPointer; + # Obsolete request to save a capability, resulting in a SturdyRef. This has been replaced + # by the `Persistent` interface defined in `persistent.capnp`. This operation was never + # implemented. + + obsoleteDelete @9 :AnyPointer; + # Obsolete way to delete a SturdyRef. This operation was never implemented. + + # Level 3 features ----------------------------------------------- + + provide @10 :Provide; # Provide a capability to a third party. + accept @11 :Accept; # Accept a capability provided by a third party. + + # Level 4 features ----------------------------------------------- + + join @12 :Join; # Directly connect to the common root of two or more proxied caps. + } +} + +# Level 0 message types ---------------------------------------------- + +struct Bootstrap { + # **(level 0)** + # + # Get the "bootstrap" interface exported by the remote vat. + # + # For level 0, 1, and 2 implementations, the "bootstrap" interface is simply the main interface + # exported by a vat. If the vat acts as a server fielding connections from clients, then the + # bootstrap interface defines the basic functionality available to a client when it connects. + # The exact interface definition obviously depends on the application. + # + # We call this a "bootstrap" because in an ideal Cap'n Proto world, bootstrap interfaces would + # never be used. In such a world, any time you connect to a new vat, you do so because you + # received an introduction from some other vat (see `ThirdPartyCapId`). Thus, the first message + # you send is `Accept`, and further communications derive from there. `Bootstrap` is not used. + # + # In such an ideal world, DNS itself would support Cap'n Proto -- performing a DNS lookup would + # actually return a new Cap'n Proto capability, thus introducing you to the target system via + # level 3 RPC. Applications would receive the capability to talk to DNS in the first place as + # an initial endowment or part of a Powerbox interaction. Therefore, an app can form arbitrary + # connections without ever using `Bootstrap`. + # + # Of course, in the real world, DNS is not Cap'n-Proto-based, and we don't want Cap'n Proto to + # require a whole new internet infrastructure to be useful. Therefore, we offer bootstrap + # interfaces as a way to get up and running without a level 3 introduction. Thus, bootstrap + # interfaces are used to "bootstrap" from other, non-Cap'n-Proto-based means of service discovery, + # such as legacy DNS. + # + # Note that a vat need not provide a bootstrap interface, and in fact many vats (especially those + # acting as clients) do not. In this case, the vat should either reply to `Bootstrap` with a + # `Return` indicating an exception, or should return a dummy capability with no methods. + + questionId @0 :QuestionId; + # A new question ID identifying this request, which will eventually receive a Return message + # containing the restored capability. + + deprecatedObjectId @1 :AnyPointer; + # ** DEPRECATED ** + # + # A Vat may export multiple bootstrap interfaces. In this case, `deprecatedObjectId` specifies + # which one to return. If this pointer is null, then the default bootstrap interface is returned. + # + # As of verison 0.5, use of this field is deprecated. If a service wants to export multiple + # bootstrap interfaces, it should instead define a single bootstarp interface that has methods + # that return each of the other interfaces. + # + # **History** + # + # In the first version of Cap'n Proto RPC (0.4.x) the `Bootstrap` message was called `Restore`. + # At the time, it was thought that this would eventually serve as the way to restore SturdyRefs + # (level 2). Meanwhile, an application could offer its "main" interface on a well-known + # (non-secret) SturdyRef. + # + # Since level 2 RPC was not implemented at the time, the `Restore` message was in practice only + # used to obtain the main interface. Since most applications had only one main interface that + # they wanted to restore, they tended to designate this with a null `objectId`. + # + # Unfortunately, the earliest version of the EZ RPC interfaces set a precedent of exporting + # multiple main interfaces by allowing them to be exported under string names. In this case, + # `objectId` was a Text value specifying the name. + # + # All of this proved problematic for several reasons: + # + # - The arrangement assumed that a client wishing to restore a SturdyRef would know exactly what + # machine to connect to and would be able to immediately restore a SturdyRef on connection. + # However, in practice, the ability to restore SturdyRefs is itself a capability that may + # require going through an authentication process to obtain. Thus, it makes more sense to + # define a "restorer service" as a full Cap'n Proto interface. If this restorer interface is + # offered as the vat's bootstrap interface, then this is equivalent to the old arrangement. + # + # - Overloading "Restore" for the purpose of obtaining well-known capabilities encouraged the + # practice of exporting singleton services with string names. If singleton services are desired, + # it is better to have one main interface that has methods that can be used to obtain each + # service, in order to get all the usual benefits of schemas and type checking. + # + # - Overloading "Restore" also had a security problem: Often, "main" or "well-known" + # capabilities exported by a vat are in fact not public: they are intended to be accessed only + # by clients who are capable of forming a connection to the vat. This can lead to trouble if + # the client itself has other clients and wishes to foward some `Restore` requests from those + # external clients -- it has to be very careful not to allow through `Restore` requests + # addressing the default capability. + # + # For example, consider the case of a sandboxed Sandstorm application and its supervisor. The + # application exports a default capability to its supervisor that provides access to + # functionality that only the supervisor is supposed to access. Meanwhile, though, applications + # may publish other capabilities that may be persistent, in which case the application needs + # to field `Restore` requests that could come from anywhere. These requests of course have to + # pass through the supervisor, as all communications with the outside world must. But, the + # supervisor has to be careful not to honor an external request addressing the application's + # default capability, since this capability is privileged. Unfortunately, the default + # capability cannot be given an unguessable name, because then the supervisor itself would not + # be able to address it! + # + # As of Cap'n Proto 0.5, `Restore` has been renamed to `Bootstrap` and is no longer planned for + # use in restoring SturdyRefs. + # + # Note that 0.4 also defined a message type called `Delete` that, like `Restore`, addressed a + # SturdyRef, but indicated that the client would not restore the ref again in the future. This + # operation was never implemented, so it was removed entirely. If a "delete" operation is desired, + # it should exist as a method on the same interface that handles restoring SturdyRefs. However, + # the utility of such an operation is questionable. You wouldn't be able to rely on it for + # garbage collection since a client could always disappear permanently without remembering to + # delete all its SturdyRefs, thus leaving them dangling forever. Therefore, it is advisable to + # design systems such that SturdyRefs never represent "owned" pointers. + # + # For example, say a SturdyRef points to an image file hosted on some server. That image file + # should also live inside a collection (a gallery, perhaps) hosted on the same server, owned by + # a user who can delete the image at any time. If the user deletes the image, the SturdyRef + # stops working. On the other hand, if the SturdyRef is discarded, this has no effect on the + # existence of the image in its collection. +} + +struct Call { + # **(level 0)** + # + # Message type initiating a method call on a capability. + + questionId @0 :QuestionId; + # A number, chosen by the caller, that identifies this call in future messages. This number + # must be different from all other calls originating from the same end of the connection (but + # may overlap with question IDs originating from the opposite end). A fine strategy is to use + # sequential question IDs, but the recipient should not assume this. + # + # A question ID can be reused once both: + # - A matching Return has been received from the callee. + # - A matching Finish has been sent from the caller. + + target @1 :MessageTarget; + # The object that should receive this call. + + interfaceId @2 :UInt64; + # The type ID of the interface being called. Each capability may implement multiple interfaces. + + methodId @3 :UInt16; + # The ordinal number of the method to call within the requested interface. + + allowThirdPartyTailCall @8 :Bool = false; + # Indicates whether or not the receiver is allowed to send a `Return` containing + # `acceptFromThirdParty`. Level 3 implementations should set this true. Otherwise, the callee + # will have to proxy the return in the case of a tail call to a third-party vat. + + params @4 :Payload; + # The call parameters. `params.content` is a struct whose fields correspond to the parameters of + # the method. + + sendResultsTo :union { + # Where should the return message be sent? + + caller @5 :Void; + # Send the return message back to the caller (the usual). + + yourself @6 :Void; + # **(level 1)** + # + # Don't actually return the results to the sender. Instead, hold on to them and await + # instructions from the sender regarding what to do with them. In particular, the sender + # may subsequently send a `Return` for some other call (which the receiver had previously made + # to the sender) with `takeFromOtherQuestion` set. The results from this call are then used + # as the results of the other call. + # + # When `yourself` is used, the receiver must still send a `Return` for the call, but sets the + # field `resultsSentElsewhere` in that `Return` rather than including the results. + # + # This feature can be used to implement tail calls in which a call from Vat A to Vat B ends up + # returning the result of a call from Vat B back to Vat A. + # + # In particular, the most common use case for this feature is when Vat A makes a call to a + # promise in Vat B, and then that promise ends up resolving to a capability back in Vat A. + # Vat B must forward all the queued calls on that promise back to Vat A, but can set `yourself` + # in the calls so that the results need not pass back through Vat B. + # + # For example: + # - Alice, in Vat A, call foo() on Bob in Vat B. + # - Alice makes a pipelined call bar() on the promise returned by foo(). + # - Later on, Bob resolves the promise from foo() to point at Carol, who lives in Vat A (next + # to Alice). + # - Vat B dutifully forwards the bar() call to Carol. Let us call this forwarded call bar'(). + # Notice that bar() and bar'() are travelling in opposite directions on the same network + # link. + # - The `Call` for bar'() has `sendResultsTo` set to `yourself`, with the value being the + # question ID originally assigned to the bar() call. + # - Vat A receives bar'() and delivers it to Carol. + # - When bar'() returns, Vat A immediately takes the results and returns them from bar(). + # - Meanwhile, Vat A sends a `Return` for bar'() to Vat B, with `resultsSentElsewhere` set in + # place of results. + # - Vat A sends a `Finish` for that call to Vat B. + # - Vat B receives the `Return` for bar'() and sends a `Return` for bar(), with + # `receivedFromYourself` set in place of the results. + # - Vat B receives the `Finish` for bar() and sends a `Finish` to bar'(). + + thirdParty @7 :RecipientId; + # **(level 3)** + # + # The call's result should be returned to a different vat. The receiver (the callee) expects + # to receive an `Accept` message from the indicated vat, and should return the call's result + # to it, rather than to the sender of the `Call`. + # + # This operates much like `yourself`, above, except that Carol is in a separate Vat C. `Call` + # messages are sent from Vat A -> Vat B and Vat B -> Vat C. A `Return` message is sent from + # Vat B -> Vat A that contains `acceptFromThirdParty` in place of results. When Vat A sends + # an `Accept` to Vat C, it receives back a `Return` containing the call's actual result. Vat C + # also sends a `Return` to Vat B with `resultsSentElsewhere`. + } +} + +struct Return { + # **(level 0)** + # + # Message type sent from callee to caller indicating that the call has completed. + + answerId @0 :AnswerId; + # Equal to the QuestionId of the corresponding `Call` message. + + releaseParamCaps @1 :Bool = true; + # If true, all capabilities that were in the params should be considered released. The sender + # must not send separate `Release` messages for them. Level 0 implementations in particular + # should always set this true. This defaults true because if level 0 implementations forget to + # set it they'll never notice (just silently leak caps), but if level >=1 implementations forget + # to set it to false they'll quickly get errors. + + union { + results @2 :Payload; + # The result. + # + # For regular method calls, `results.content` points to the result struct. + # + # For a `Return` in response to an `Accept`, `results` contains a single capability (rather + # than a struct), and `results.content` is just a capability pointer with index 0. A `Finish` + # is still required in this case. + + exception @3 :Exception; + # Indicates that the call failed and explains why. + + canceled @4 :Void; + # Indicates that the call was canceled due to the caller sending a Finish message + # before the call had completed. + + resultsSentElsewhere @5 :Void; + # This is set when returning from a `Call` that had `sendResultsTo` set to something other + # than `caller`. + + takeFromOtherQuestion @6 :QuestionId; + # The sender has also sent (before this message) a `Call` with the given question ID and with + # `sendResultsTo.yourself` set, and the results of that other call should be used as the + # results here. + + acceptFromThirdParty @7 :ThirdPartyCapId; + # **(level 3)** + # + # The caller should contact a third-party vat to pick up the results. An `Accept` message + # sent to the vat will return the result. This pairs with `Call.sendResultsTo.thirdParty`. + # It should only be used if the corresponding `Call` had `allowThirdPartyTailCall` set. + } +} + +struct Finish { + # **(level 0)** + # + # Message type sent from the caller to the callee to indicate: + # 1) The questionId will no longer be used in any messages sent by the callee (no further + # pipelined requests). + # 2) If the call has not returned yet, the caller no longer cares about the result. If nothing + # else cares about the result either (e.g. there are no other outstanding calls pipelined on + # the result of this one) then the callee may wish to immediately cancel the operation and + # send back a Return message with "canceled" set. However, implementations are not required + # to support premature cancellation -- instead, the implementation may wait until the call + # actually completes and send a normal `Return` message. + # + # TODO(someday): Should we separate (1) and implicitly releasing result capabilities? It would be + # possible and useful to notify the server that it doesn't need to keep around the response to + # service pipeline requests even though the caller still wants to receive it / hasn't yet + # finished processing it. It could also be useful to notify the server that it need not marshal + # the results because the caller doesn't want them anyway, even if the caller is still sending + # pipelined calls, although this seems less useful (just saving some bytes on the wire). + + questionId @0 :QuestionId; + # ID of the call whose result is to be released. + + releaseResultCaps @1 :Bool = true; + # If true, all capabilities that were in the results should be considered released. The sender + # must not send separate `Release` messages for them. Level 0 implementations in particular + # should always set this true. This defaults true because if level 0 implementations forget to + # set it they'll never notice (just silently leak caps), but if level >=1 implementations forget + # set it false they'll quickly get errors. +} + +# Level 1 message types ---------------------------------------------- + +struct Resolve { + # **(level 1)** + # + # Message type sent to indicate that a previously-sent promise has now been resolved to some other + # object (possibly another promise) -- or broken, or canceled. + # + # Keep in mind that it's possible for a `Resolve` to be sent to a level 0 implementation that + # doesn't implement it. For example, a method call or return might contain a capability in the + # payload. Normally this is fine even if the receiver is level 0, because they will implicitly + # release all such capabilities on return / finish. But if the cap happens to be a promise, then + # a follow-up `Resolve` may be sent regardless of this release. The level 0 receiver will reply + # with an `unimplemented` message, and the sender (of the `Resolve`) can respond to this as if the + # receiver had immediately released any capability to which the promise resolved. + # + # When implementing promise resolution, it's important to understand how embargos work and the + # tricky case of the Tribble 4-way race condition. See the comments for the Disembargo message, + # below. + + promiseId @0 :ExportId; + # The ID of the promise to be resolved. + # + # Unlike all other instances of `ExportId` sent from the exporter, the `Resolve` message does + # _not_ increase the reference count of `promiseId`. In fact, it is expected that the receiver + # will release the export soon after receiving `Resolve`, and the sender will not send this + # `ExportId` again until it has been released and recycled. + # + # When an export ID sent over the wire (e.g. in a `CapDescriptor`) is indicated to be a promise, + # this indicates that the sender will follow up at some point with a `Resolve` message. If the + # same `promiseId` is sent again before `Resolve`, still only one `Resolve` is sent. If the + # same ID is sent again later _after_ a `Resolve`, it can only be because the export's + # reference count hit zero in the meantime and the ID was re-assigned to a new export, therefore + # this later promise does _not_ correspond to the earlier `Resolve`. + # + # If a promise ID's reference count reaches zero before a `Resolve` is sent, the `Resolve` + # message may or may not still be sent (the `Resolve` may have already been in-flight when + # `Release` was sent, but if the `Release` is received before `Resolve` then there is no longer + # any reason to send a `Resolve`). Thus a `Resolve` may be received for a promise of which + # the receiver has no knowledge, because it already released it earlier. In this case, the + # receiver should simply release the capability to which the promise resolved. + + union { + cap @1 :CapDescriptor; + # The object to which the promise resolved. + # + # The sender promises that from this point forth, until `promiseId` is released, it shall + # simply forward all messages to the capability designated by `cap`. This is true even if + # `cap` itself happens to desigate another promise, and that other promise later resolves -- + # messages sent to `promiseId` shall still go to that other promise, not to its resolution. + # This is important in the case that the receiver of the `Resolve` ends up sending a + # `Disembargo` message towards `promiseId` in order to control message ordering -- that + # `Disembargo` really needs to reflect back to exactly the object designated by `cap` even + # if that object is itself a promise. + + exception @2 :Exception; + # Indicates that the promise was broken. + } +} + +struct Release { + # **(level 1)** + # + # Message type sent to indicate that the sender is done with the given capability and the receiver + # can free resources allocated to it. + + id @0 :ImportId; + # What to release. + + referenceCount @1 :UInt32; + # The amount by which to decrement the reference count. The export is only actually released + # when the reference count reaches zero. +} + +struct Disembargo { + # **(level 1)** + # + # Message sent to indicate that an embargo on a recently-resolved promise may now be lifted. + # + # Embargos are used to enforce E-order in the presence of promise resolution. That is, if an + # application makes two calls foo() and bar() on the same capability reference, in that order, + # the calls should be delivered in the order in which they were made. But if foo() is called + # on a promise, and that promise happens to resolve before bar() is called, then the two calls + # may travel different paths over the network, and thus could arrive in the wrong order. In + # this case, the call to `bar()` must be embargoed, and a `Disembargo` message must be sent along + # the same path as `foo()` to ensure that the `Disembargo` arrives after `foo()`. Once the + # `Disembargo` arrives, `bar()` can then be delivered. + # + # There are two particular cases where embargos are important. Consider object Alice, in Vat A, + # who holds a promise P, pointing towards Vat B, that eventually resolves to Carol. The two + # cases are: + # - Carol lives in Vat A, i.e. next to Alice. In this case, Vat A needs to send a `Disembargo` + # message that echos through Vat B and back, to ensure that all pipelined calls on the promise + # have been delivered. + # - Carol lives in a different Vat C. When the promise resolves, a three-party handoff occurs + # (see `Provide` and `Accept`, which constitute level 3 of the protocol). In this case, we + # piggyback on the state that has already been set up to handle the handoff: the `Accept` + # message (from Vat A to Vat C) is embargoed, as are all pipelined messages sent to it, while + # a `Disembargo` message is sent from Vat A through Vat B to Vat C. See `Accept.embargo` for + # an example. + # + # Note that in the case where Carol actually lives in Vat B (i.e., the same vat that the promise + # already pointed at), no embargo is needed, because the pipelined calls are delivered over the + # same path as the later direct calls. + # + # Keep in mind that promise resolution happens both in the form of Resolve messages as well as + # Return messages (which resolve PromisedAnswers). Embargos apply in both cases. + # + # An alternative strategy for enforcing E-order over promise resolution could be for Vat A to + # implement the embargo internally. When Vat A is notified of promise resolution, it could + # send a dummy no-op call to promise P and wait for it to complete. Until that call completes, + # all calls to the capability are queued locally. This strategy works, but is pessimistic: + # in the three-party case, it requires an A -> B -> C -> B -> A round trip before calls can start + # being delivered directly to from Vat A to Vat C. The `Disembargo` message allows latency to be + # reduced. (In the two-party loopback case, the `Disembargo` message is just a more explicit way + # of accomplishing the same thing as a no-op call, but isn't any faster.) + # + # *The Tribble 4-way Race Condition* + # + # Any implementation of promise resolution and embargos must be aware of what we call the + # "Tribble 4-way race condition", after Dean Tribble, who explained the problem in a lively + # Friam meeting. + # + # Embargos are designed to work in the case where a two-hop path is being shortened to one hop. + # But sometimes there are more hops. Imagine that Alice has a reference to a remote promise P1 + # that eventually resolves to _another_ remote promise P2 (in a third vat), which _at the same + # time_ happens to resolve to Bob (in a fourth vat). In this case, we're shortening from a 3-hop + # path (with four parties) to a 1-hop path (Alice -> Bob). + # + # Extending the embargo/disembargo protocol to be able to shorted multiple hops at once seems + # difficult. Instead, we make a rule that prevents this case from coming up: + # + # One a promise P has been resolved to a remove object reference R, then all further messages + # received addressed to P will be forwarded strictly to R. Even if it turns out later that R is + # itself a promise, and has resolved to some other object Q, messages sent to P will still be + # forwarded to R, not directly to Q (R will of course further forward the messages to Q). + # + # This rule does not cause a significant performance burden because once P has resolved to R, it + # is expected that people sending messages to P will shortly start sending them to R instead and + # drop P. P is at end-of-life anyway, so it doesn't matter if it ignores chances to further + # optimize its path. + + target @0 :MessageTarget; + # What is to be disembargoed. + + using EmbargoId = UInt32; + # Used in `senderLoopback` and `receiverLoopback`, below. + + context :union { + senderLoopback @1 :EmbargoId; + # The sender is requesting a disembargo on a promise that is known to resolve back to a + # capability hosted by the sender. As soon as the receiver has echoed back all pipelined calls + # on this promise, it will deliver the Disembargo back to the sender with `receiverLoopback` + # set to the same value as `senderLoopback`. This value is chosen by the sender, and since + # it is also consumed be the sender, the sender can use whatever strategy it wants to make sure + # the value is unambiguous. + # + # The receiver must verify that the target capability actually resolves back to the sender's + # vat. Otherwise, the sender has committed a protocol error and should be disconnected. + + receiverLoopback @2 :EmbargoId; + # The receiver previously sent a `senderLoopback` Disembargo towards a promise resolving to + # this capability, and that Disembargo is now being echoed back. + + accept @3 :Void; + # **(level 3)** + # + # The sender is requesting a disembargo on a promise that is known to resolve to a third-party + # capability that the sender is currently in the process of accepting (using `Accept`). + # The receiver of this `Disembargo` has an outstanding `Provide` on said capability. The + # receiver should now send a `Disembargo` with `provide` set to the question ID of that + # `Provide` message. + # + # See `Accept.embargo` for an example. + + provide @4 :QuestionId; + # **(level 3)** + # + # The sender is requesting a disembargo on a capability currently being provided to a third + # party. The question ID identifies the `Provide` message previously sent by the sender to + # this capability. On receipt, the receiver (the capability host) shall release the embargo + # on the `Accept` message that it has received from the third party. See `Accept.embargo` for + # an example. + } +} + +# Level 2 message types ---------------------------------------------- + +# See persistent.capnp. + +# Level 3 message types ---------------------------------------------- + +struct Provide { + # **(level 3)** + # + # Message type sent to indicate that the sender wishes to make a particular capability implemented + # by the receiver available to a third party for direct access (without the need for the third + # party to proxy through the sender). + # + # (In CapTP, `Provide` and `Accept` are methods of the global `NonceLocator` object exported by + # every vat. In Cap'n Proto, we bake this into the core protocol.) + + questionId @0 :QuestionId; + # Question ID to be held open until the recipient has received the capability. A result will be + # returned once the third party has successfully received the capability. The sender must at some + # point send a `Finish` message as with any other call, and that message can be used to cancel the + # whole operation. + + target @1 :MessageTarget; + # What is to be provided to the third party. + + recipient @2 :RecipientId; + # Identity of the third party that is expected to pick up the capability. +} + +struct Accept { + # **(level 3)** + # + # Message type sent to pick up a capability hosted by the receiving vat and provided by a third + # party. The third party previously designated the capability using `Provide`. + # + # This message is also used to pick up a redirected return -- see `Return.redirect`. + + questionId @0 :QuestionId; + # A new question ID identifying this accept message, which will eventually receive a Return + # message containing the provided capability (or the call result in the case of a redirected + # return). + + provision @1 :ProvisionId; + # Identifies the provided object to be picked up. + + embargo @2 :Bool; + # If true, this accept shall be temporarily embargoed. The resulting `Return` will not be sent, + # and any pipelined calls will not be delivered, until the embargo is released. The receiver + # (the capability host) will expect the provider (the vat that sent the `Provide` message) to + # eventually send a `Disembargo` message with the field `context.provide` set to the question ID + # of the original `Provide` message. At that point, the embargo is released and the queued + # messages are delivered. + # + # For example: + # - Alice, in Vat A, holds a promise P, which currently points toward Vat B. + # - Alice calls foo() on P. The `Call` message is sent to Vat B. + # - The promise P in Vat B ends up resolving to Carol, in Vat C. + # - Vat B sends a `Provide` message to Vat C, identifying Vat A as the recipient. + # - Vat B sends a `Resolve` message to Vat A, indicating that the promise has resolved to a + # `ThirdPartyCapId` identifying Carol in Vat C. + # - Vat A sends an `Accept` message to Vat C to pick up the capability. Since Vat A knows that + # it has an outstanding call to the promise, it sets `embargo` to `true` in the `Accept` + # message. + # - Vat A sends a `Disembargo` message to Vat B on promise P, with `context.accept` set. + # - Alice makes a call bar() to promise P, which is now pointing towards Vat C. Alice doesn't + # know anything about the mechanics of promise resolution happening under the hood, but she + # expects that bar() will be delivered after foo() because that is the order in which she + # initiated the calls. + # - Vat A sends the bar() call to Vat C, as a pipelined call on the result of the `Accept` (which + # hasn't returned yet, due to the embargo). Since calls to the newly-accepted capability + # are embargoed, Vat C does not deliver the call yet. + # - At some point, Vat B forwards the foo() call from the beginning of this example on to Vat C. + # - Vat B forwards the `Disembargo` from Vat A on to vat C. It sets `context.provide` to the + # question ID of the `Provide` message it had sent previously. + # - Vat C receives foo() before `Disembargo`, thus allowing it to correctly deliver foo() + # before delivering bar(). + # - Vat C receives `Disembargo` from Vat B. It can now send a `Return` for the `Accept` from + # Vat A, as well as deliver bar(). +} + +# Level 4 message types ---------------------------------------------- + +struct Join { + # **(level 4)** + # + # Message type sent to implement E.join(), which, given a number of capabilities that are + # expected to be equivalent, finds the underlying object upon which they all agree and forms a + # direct connection to it, skipping any proxies that may have been constructed by other vats + # while transmitting the capability. See: + # http://erights.org/elib/equality/index.html + # + # Note that this should only serve to bypass fully-transparent proxies -- proxies that were + # created merely for convenience, without any intention of hiding the underlying object. + # + # For example, say Bob holds two capabilities hosted by Alice and Carol, but he expects that both + # are simply proxies for a capability hosted elsewhere. He then issues a join request, which + # operates as follows: + # - Bob issues Join requests on both Alice and Carol. Each request contains a different piece + # of the JoinKey. + # - Alice is proxying a capability hosted by Dana, so forwards the request to Dana's cap. + # - Dana receives the first request and sees that the JoinKeyPart is one of two. She notes that + # she doesn't have the other part yet, so she records the request and responds with a + # JoinResult. + # - Alice relays the JoinAswer back to Bob. + # - Carol is also proxying a capability from Dana, and so forwards her Join request to Dana as + # well. + # - Dana receives Carol's request and notes that she now has both parts of a JoinKey. She + # combines them in order to form information needed to form a secure connection to Bob. She + # also responds with another JoinResult. + # - Bob receives the responses from Alice and Carol. He uses the returned JoinResults to + # determine how to connect to Dana and attempts to form the connection. Since Bob and Dana now + # agree on a secret key that neither Alice nor Carol ever saw, this connection can be made + # securely even if Alice or Carol is conspiring against the other. (If Alice and Carol are + # conspiring _together_, they can obviously reproduce the key, but this doesn't matter because + # the whole point of the join is to verify that Alice and Carol agree on what capability they + # are proxying.) + # + # If the two capabilities aren't actually proxies of the same object, then the join requests + # will come back with conflicting `hostId`s and the join will fail before attempting to form any + # connection. + + questionId @0 :QuestionId; + # Question ID used to respond to this Join. (Note that this ID only identifies one part of the + # request for one hop; each part has a different ID and relayed copies of the request have + # (probably) different IDs still.) + # + # The receiver will reply with a `Return` whose `results` is a JoinResult. This `JoinResult` + # is relayed from the joined object's host, possibly with transformation applied as needed + # by the network. + # + # Like any return, the result must be released using a `Finish`. However, this release + # should not occur until the joiner has either successfully connected to the joined object. + # Vats relaying a `Join` message similarly must not release the result they receive until the + # return they relayed back towards the joiner has itself been released. This allows the + # joined object's host to detect when the Join operation is canceled before completing -- if + # it receives a `Finish` for one of the join results before the joiner successfully + # connects. It can then free any resources it had allocated as part of the join. + + target @1 :MessageTarget; + # The capability to join. + + keyPart @2 :JoinKeyPart; + # A part of the join key. These combine to form the complete join key, which is used to establish + # a direct connection. + + # TODO(before implementing): Change this so that multiple parts can be sent in a single Join + # message, so that if multiple join parts are going to cross the same connection they can be sent + # together, so that the receive can potentially optimize its handling of them. In the case where + # all parts are bundled together, should the recipient be expected to simply return a cap, so + # that the caller can immediately start pipelining to it? +} + +# ======================================================================================== +# Common structures used in messages + +struct MessageTarget { + # The target of a `Call` or other messages that target a capability. + + union { + importedCap @0 :ImportId; + # This message is to a capability or promise previously imported by the caller (exported by + # the receiver). + + promisedAnswer @1 :PromisedAnswer; + # This message is to a capability that is expected to be returned by another call that has not + # yet been completed. + # + # At level 0, this is supported only for addressing the result of a previous `Bootstrap`, so + # that initial startup doesn't require a round trip. + } +} + +struct Payload { + # Represents some data structure that might contain capabilities. + + content @0 :AnyPointer; + # Some Cap'n Proto data structure. Capability pointers embedded in this structure index into + # `capTable`. + + capTable @1 :List(CapDescriptor); + # Descriptors corresponding to the cap pointers in `content`. +} + +struct CapDescriptor { + # **(level 1)** + # + # When an application-defined type contains an interface pointer, that pointer contains an index + # into the message's capability table -- i.e. the `capTable` part of the `Payload`. Each + # capability in the table is represented as a `CapDescriptor`. The runtime API should not reveal + # the CapDescriptor directly to the application, but should instead wrap it in some kind of + # callable object with methods corresponding to the interface that the capability implements. + # + # Keep in mind that `ExportIds` in a `CapDescriptor` are subject to reference counting. See the + # description of `ExportId`. + + union { + none @0 :Void; + # There is no capability here. This `CapDescriptor` should not appear in the payload content. + # A `none` CapDescriptor can be generated when an application inserts a capability into a + # message and then later changes its mind and removes it -- rewriting all of the other + # capability pointers may be hard, so instead a tombstone is left, similar to the way a removed + # struct or list instance is zeroed out of the message but the space is not reclaimed. + # Hopefully this is unusual. + + senderHosted @1 :ExportId; + # A capability newly exported by the sender. This is the ID of the new capability in the + # sender's export table (receiver's import table). + + senderPromise @2 :ExportId; + # A promise that the sender will resolve later. The sender will send exactly one Resolve + # message at a future point in time to replace this promise. Note that even if the same + # `senderPromise` is received multiple times, only one `Resolve` is sent to cover all of + # them. If `senderPromise` is released before the `Resolve` is sent, the sender (of this + # `CapDescriptor`) may choose not to send the `Resolve` at all. + + receiverHosted @3 :ImportId; + # A capability (or promise) previously exported by the receiver (imported by the sender). + + receiverAnswer @4 :PromisedAnswer; + # A capability expected to be returned in the results of a currently-outstanding call posed + # by the sender. + + thirdPartyHosted @5 :ThirdPartyCapDescriptor; + # **(level 3)** + # + # A capability that lives in neither the sender's nor the receiver's vat. The sender needs + # to form a direct connection to a third party to pick up the capability. + # + # Level 1 and 2 implementations that receive a `thirdPartyHosted` may simply send calls to its + # `vine` instead. + } +} + +struct PromisedAnswer { + # **(mostly level 1)** + # + # Specifies how to derive a promise from an unanswered question, by specifying the path of fields + # to follow from the root of the eventual result struct to get to the desired capability. Used + # to address method calls to a not-yet-returned capability or to pass such a capability as an + # input to some other method call. + # + # Level 0 implementations must support `PromisedAnswer` only for the case where the answer is + # to a `Bootstrap` message. In this case, `path` is always empty since `Bootstrap` always returns + # a raw capability. + + questionId @0 :QuestionId; + # ID of the question (in the sender's question table / receiver's answer table) whose answer is + # expected to contain the capability. + + transform @1 :List(Op); + # Operations / transformations to apply to the result in order to get the capability actually + # being addressed. E.g. if the result is a struct and you want to call a method on a capability + # pointed to by a field of the struct, you need a `getPointerField` op. + + struct Op { + union { + noop @0 :Void; + # Does nothing. This member is mostly defined so that we can make `Op` a union even + # though (as of this writing) only one real operation is defined. + + getPointerField @1 :UInt16; + # Get a pointer field within a struct. The number is an index into the pointer section, NOT + # a field ordinal, so that the receiver does not need to understand the schema. + + # TODO(someday): We could add: + # - For lists, the ability to address every member of the list, or a slice of the list, the + # result of which would be another list. This is useful for implementing the equivalent of + # a SQL table join (not to be confused with the `Join` message type). + # - Maybe some ability to test a union. + # - Probably not a good idea: the ability to specify an arbitrary script to run on the + # result. We could define a little stack-based language where `Op` specifies one + # "instruction" or transformation to apply. Although this is not a good idea + # (over-engineered), any narrower additions to `Op` should be designed as if this + # were the eventual goal. + } + } +} + +struct ThirdPartyCapDescriptor { + # **(level 3)** + # + # Identifies a capability in a third-party vat that the sender wants the receiver to pick up. + + id @0 :ThirdPartyCapId; + # Identifies the third-party host and the specific capability to accept from it. + + vineId @1 :ExportId; + # A proxy for the third-party object exported by the sender. In CapTP terminology this is called + # a "vine", because it is an indirect reference to the third-party object that snakes through the + # sender vat. This serves two purposes: + # + # * Level 1 and 2 implementations that don't understand how to connect to a third party may + # simply send calls to the vine. Such calls will be forwarded to the third-party by the + # sender. + # + # * Level 3 implementations must release the vine once they have successfully picked up the + # object from the third party. This ensures that the capability is not released by the sender + # prematurely. + # + # The sender will close the `Provide` request that it has sent to the third party as soon as + # it receives either a `Call` or a `Release` message directed at the vine. +} + +struct Exception { + # **(level 0)** + # + # Describes an arbitrary error that prevented an operation (e.g. a call) from completing. + # + # Cap'n Proto exceptions always indicate that something went wrong. In other words, in a fantasy + # world where everything always works as expected, no exceptions would ever be thrown. Clients + # should only ever catch exceptions as a means to implement fault-tolerance, where "fault" can + # mean: + # - Bugs. + # - Invalid input. + # - Configuration errors. + # - Network problems. + # - Insufficient resources. + # - Version skew (unimplemented functionality). + # - Other logistical problems. + # + # Exceptions should NOT be used to flag application-specific conditions that a client is expected + # to handle in an application-specific way. Put another way, in the Cap'n Proto world, + # "checked exceptions" (where an interface explicitly defines the exceptions it throws and + # clients are forced by the type system to handle those exceptions) do NOT make sense. + + reason @0 :Text; + # Human-readable failure description. + + type @3 :Type; + # The type of the error. The purpose of this enum is not to describe the error itself, but + # rather to describe how the client might want to respond to the error. + + enum Type { + failed @0; + # A generic problem occurred, and it is believed that if the operation were repeated without + # any change in the state of the world, the problem would occur again. + # + # A client might respond to this error by logging it for investigation by the developer and/or + # displaying it to the user. + + overloaded @1; + # The request was rejected due to a temporary lack of resources. + # + # Examples include: + # - There's not enough CPU time to keep up with incoming requests, so some are rejected. + # - The server ran out of RAM or disk space during the request. + # - The operation timed out (took significantly longer than it should have). + # + # A client might respond to this error by scheduling to retry the operation much later. The + # client should NOT retry again immediately since this would likely exacerbate the problem. + + disconnected @2; + # The method failed because a connection to some necessary capability was lost. + # + # Examples include: + # - The client introduced the server to a third-party capability, the connection to that third + # party was subsequently lost, and then the client requested that the server use the dead + # capability for something. + # - The client previously requested that the server obtain a capability from some third party. + # The server returned a capability to an object wrapping the third-party capability. Later, + # the server's connection to the third party was lost. + # - The capability has been revoked. Revocation does not necessarily mean that the client is + # no longer authorized to use the capability; it is often used simply as a way to force the + # client to repeat the setup process, perhaps to efficiently move them to a new back-end or + # get them to recognize some other change that has occurred. + # + # A client should normally respond to this error by releasing all capabilities it is currently + # holding related to the one it called and then re-creating them by restoring SturdyRefs and/or + # repeating the method calls used to create them originally. In other words, disconnect and + # start over. This should in turn cause the server to obtain a new copy of the capability that + # it lost, thus making everything work. + # + # If the client receives another `disconnencted` error in the process of rebuilding the + # capability and retrying the call, it should treat this as an `overloaded` error: the network + # is currently unreliable, possibly due to load or other temporary issues. + + unimplemented @3; + # The server doesn't implement the requested method. If there is some other method that the + # client could call (perhaps an older and/or slower interface), it should try that instead. + # Otherwise, this should be treated like `failed`. + } + + obsoleteIsCallersFault @1 :Bool; + # OBSOLETE. Ignore. + + obsoleteDurability @2 :UInt16; + # OBSOLETE. See `type` instead. +} + +# ======================================================================================== +# Network-specific Parameters +# +# Some parts of the Cap'n Proto RPC protocol are not specified here because different vat networks +# may wish to use different approaches to solving them. For example, on the public internet, you +# may want to authenticate vats using public-key cryptography, but on a local intranet with trusted +# infrastructure, you may be happy to authenticate based on network address only, or some other +# lightweight mechanism. +# +# To accommodate this, we specify several "parameter" types. Each type is defined here as an +# alias for `AnyPointer`, but a specific network will want to define a specific set of types to use. +# All vats in a vat network must agree on these parameters in order to be able to communicate. +# Inter-network communication can be accomplished through "gateways" that perform translation +# between the primitives used on each network; these gateways may need to be deeply stateful, +# depending on the translations they perform. +# +# For interaction over the global internet between parties with no other prior arrangement, a +# particular set of bindings for these types is defined elsewhere. (TODO(someday): Specify where +# these common definitions live.) +# +# Another common network type is the two-party network, in which one of the parties typically +# interacts with the outside world entirely through the other party. In such a connection between +# Alice and Bob, all objects that exist on Bob's other networks appear to Alice as if they were +# hosted by Bob himself, and similarly all objects on Alice's network (if she even has one) appear +# to Bob as if they were hosted by Alice. This network type is interesting because from the point +# of view of a simple application that communicates with only one other party via the two-party +# protocol, there are no three-party interactions at all, and joins are unusually simple to +# implement, so implementing at level 4 is barely more complicated than implementing at level 1. +# Moreover, if you pair an app implementing the two-party network with a container that implements +# some other network, the app can then participate on the container's network just as if it +# implemented that network directly. The types used by the two-party network are defined in +# `rpc-twoparty.capnp`. +# +# The things that we need to parameterize are: +# - How to store capabilities long-term without holding a connection open (mostly level 2). +# - How to authenticate vats in three-party introductions (level 3). +# - How to implement `Join` (level 4). +# +# Persistent references +# --------------------- +# +# **(mostly level 2)** +# +# We want to allow some capabilities to be stored long-term, even if a connection is lost and later +# recreated. ExportId is a short-term identifier that is specific to a connection, so it doesn't +# help here. We need a way to specify long-term identifiers, as well as a strategy for +# reconnecting to a referenced capability later. +# +# Three-party interactions +# ------------------------ +# +# **(level 3)** +# +# In cases where more than two vats are interacting, we have situations where VatA holds a +# capability hosted by VatB and wants to send that capability to VatC. This can be accomplished +# by VatA proxying requests on the new capability, but doing so has two big problems: +# - It's inefficient, requiring an extra network hop. +# - If VatC receives another capability to the same object from VatD, it is difficult for VatC to +# detect that the two capabilities are really the same and to implement the E "join" operation, +# which is necessary for certain four-or-more-party interactions, such as the escrow pattern. +# See: http://www.erights.org/elib/equality/grant-matcher/index.html +# +# Instead, we want a way for VatC to form a direct, authenticated connection to VatB. +# +# Join +# ---- +# +# **(level 4)** +# +# The `Join` message type and corresponding operation arranges for a direct connection to be formed +# between the joiner and the host of the joined object, and this connection must be authenticated. +# Thus, the details are network-dependent. + +using SturdyRef = AnyPointer; +# **(level 2)** +# +# Identifies a persisted capability that can be restored in the future. How exactly a SturdyRef +# is restored to a live object is specified along with the SturdyRef definition (i.e. not by +# rpc.capnp). +# +# Generally a SturdyRef needs to specify three things: +# - How to reach the vat that can restore the ref (e.g. a hostname or IP address). +# - How to authenticate the vat after connecting (e.g. a public key fingerprint). +# - The identity of a specific object hosted by the vat. Generally, this is an opaque pointer whose +# format is defined by the specific vat -- the client has no need to inspect the object ID. +# It is important that the objec ID be unguessable if the object is not public (and objects +# should almost never be public). +# +# The above are only suggestions. Some networks might work differently. For example, a private +# network might employ a special restorer service whose sole purpose is to restore SturdyRefs. +# In this case, the entire contents of SturdyRef might be opaque, because they are intended only +# to be forwarded to the restorer service. + +using ProvisionId = AnyPointer; +# **(level 3)** +# +# The information that must be sent in an `Accept` message to identify the object being accepted. +# +# In a network where each vat has a public/private key pair, this could simply be the public key +# fingerprint of the provider vat along with the question ID used in the `Provide` message sent from +# that provider. + +using RecipientId = AnyPointer; +# **(level 3)** +# +# The information that must be sent in a `Provide` message to identify the recipient of the +# capability. +# +# In a network where each vat has a public/private key pair, this could simply be the public key +# fingerprint of the recipient. (CapTP also calls for a nonce to identify the object. In our +# case, the `Provide` message's `questionId` can serve as the nonce.) + +using ThirdPartyCapId = AnyPointer; +# **(level 3)** +# +# The information needed to connect to a third party and accept a capability from it. +# +# In a network where each vat has a public/private key pair, this could be a combination of the +# third party's public key fingerprint, hints on how to connect to the third party (e.g. an IP +# address), and the question ID used in the corresponding `Provide` message sent to that third party +# (used to identify which capability to pick up). + +using JoinKeyPart = AnyPointer; +# **(level 4)** +# +# A piece of a secret key. One piece is sent along each path that is expected to lead to the same +# place. Once the pieces are combined, a direct connection may be formed between the sender and +# the receiver, bypassing any men-in-the-middle along the paths. See the `Join` message type. +# +# The motivation for Joins is discussed under "Supporting Equality" in the "Unibus" protocol +# sketch: http://www.erights.org/elib/distrib/captp/unibus.html +# +# In a network where each vat has a public/private key pair and each vat forms no more than one +# connection to each other vat, Joins will rarely -- perhaps never -- be needed, as objects never +# need to be transparently proxied and references to the same object sent over the same connection +# have the same export ID. Thus, a successful join requires only checking that the two objects +# come from the same connection and have the same ID, and then completes immediately. +# +# However, in networks where two vats may form more than one connection between each other, or +# where proxying of objects occurs, joins are necessary. +# +# Typically, each JoinKeyPart would include a fixed-length data value such that all value parts +# XOR'd together forms a shared secret that can be used to form an encrypted connection between +# the joiner and the joined object's host. Each JoinKeyPart should also include an indication of +# how many parts to expect and a hash of the shared secret (used to match up parts). + +using JoinResult = AnyPointer; +# **(level 4)** +# +# Information returned as the result to a `Join` message, needed by the joiner in order to form a +# direct connection to a joined object. This might simply be the address of the joined object's +# host vat, since the `JoinKey` has already been communicated so the two vats already have a shared +# secret to use to authenticate each other. +# +# The `JoinResult` should also contain information that can be used to detect when the Join +# requests ended up reaching different objects, so that this situation can be detected easily. +# This could be a simple matter of including a sequence number -- if the joiner receives two +# `JoinResult`s with sequence number 0, then they must have come from different objects and the +# whole join is a failure. + +# ======================================================================================== +# Network interface sketch +# +# The interfaces below are meant to be pseudo-code to illustrate how the details of a particular +# vat network might be abstracted away. They are written like Cap'n Proto interfaces, but in +# practice you'd probably define these interfaces manually in the target programming language. A +# Cap'n Proto RPC implementation should be able to use these interfaces without knowing the +# definitions of the various network-specific parameters defined above. + +# interface VatNetwork { +# # Represents a vat network, with the ability to connect to particular vats and receive +# # connections from vats. +# # +# # Note that methods returning a `Connection` may return a pre-existing `Connection`, and the +# # caller is expected to find and share state with existing users of the connection. +# +# # Level 0 features ----------------------------------------------- +# +# connect(vatId :VatId) :Connection; +# # Connect to the given vat. The transport should return a promise that does not +# # resolve until authentication has completed, but allows messages to be pipelined in before +# # that; the transport either queues these messages until authenticated, or sends them encrypted +# # such that only the authentic vat would be able to decrypt them. The latter approach avoids a +# # round trip for authentication. +# +# accept() :Connection; +# # Wait for the next incoming connection and return it. Only connections formed by +# # connect() are returned by this method. +# +# # Level 4 features ----------------------------------------------- +# +# newJoiner(count :UInt32) :NewJoinerResponse; +# # Prepare a new Join operation, which will eventually lead to forming a new direct connection +# # to the host of the joined capability. `count` is the number of capabilities to join. +# +# struct NewJoinerResponse { +# joinKeyParts :List(JoinKeyPart); +# # Key parts to send in Join messages to each capability. +# +# joiner :Joiner; +# # Used to establish the final connection. +# } +# +# interface Joiner { +# addJoinResult(result :JoinResult) :Void; +# # Add a JoinResult received in response to one of the `Join` messages. All `JoinResult`s +# # returned from all paths must be added before trying to connect. +# +# connect() :ConnectionAndProvisionId; +# # Try to form a connection to the joined capability's host, verifying that it has received +# # all of the JoinKeyParts. Once the connection is formed, the caller should send an `Accept` +# # message on it with the specified `ProvisionId` in order to receive the final capability. +# } +# +# acceptConnectionFromJoiner(parts :List(JoinKeyPart), paths :List(VatPath)) +# :ConnectionAndProvisionId; +# # Called on a joined capability's host to receive the connection from the joiner, once all +# # key parts have arrived. The caller should expect to receive an `Accept` message over the +# # connection with the given ProvisionId. +# } +# +# interface Connection { +# # Level 0 features ----------------------------------------------- +# +# send(message :Message) :Void; +# # Send the message. Returns successfully when the message (and all preceding messages) has +# # been acknowledged by the recipient. +# +# receive() :Message; +# # Receive the next message, and acknowledges receipt to the sender. Messages are received in +# # the order in which they are sent. +# +# # Level 3 features ----------------------------------------------- +# +# introduceTo(recipient :Connection) :IntroductionInfo; +# # Call before starting a three-way introduction, assuming a `Provide` message is to be sent on +# # this connection and a `ThirdPartyCapId` is to be sent to `recipient`. +# +# struct IntroductionInfo { +# sendToRecipient :ThirdPartyCapId; +# sendToTarget :RecipientId; +# } +# +# connectToIntroduced(capId :ThirdPartyCapId) :ConnectionAndProvisionId; +# # Given a ThirdPartyCapId received over this connection, connect to the third party. The +# # caller should then send an `Accept` message over the new connection. +# +# acceptIntroducedConnection(recipientId :RecipientId) :Connection; +# # Given a RecipientId received in a `Provide` message on this `Connection`, wait for the +# # recipient to connect, and return the connection formed. Usually, the first message received +# # on the new connection will be an `Accept` message. +# } +# +# struct ConnectionAndProvisionId { +# # **(level 3)** +# +# connection :Connection; +# # Connection on which to issue `Accept` message. +# +# provision :ProvisionId; +# # `ProvisionId` to send in the `Accept` message. +# }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/rpc.capnp.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,4808 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: rpc.capnp + +#ifndef CAPNP_INCLUDED_b312981b2552a250_ +#define CAPNP_INCLUDED_b312981b2552a250_ + +#include <capnp/generated-header-support.h> + +#if CAPNP_VERSION != 6000 +#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." +#endif + + +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 = &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 = &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 = &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 = &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 = &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 = &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 = &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 = &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 = &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 = &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 = &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 = &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 = &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 = &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 = &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 = &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 = &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 = &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 = &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, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &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>::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>::Builder getCapTable(); + inline void setCapTable( ::capnp::List< ::capnp::rpc::CapDescriptor>::Reader value); + inline ::capnp::List< ::capnp::rpc::CapDescriptor>::Builder initCapTable(unsigned int size); + inline void adoptCapTable(::capnp::Orphan< ::capnp::List< ::capnp::rpc::CapDescriptor>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::rpc::CapDescriptor>> 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; + +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(); + +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>::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>::Builder getTransform(); + inline void setTransform( ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Reader value); + inline ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Builder initTransform(unsigned int size); + inline void adoptTransform(::capnp::Orphan< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>> 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; + +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); + +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>(0 * ::capnp::ELEMENTS); +} +inline ::capnp::rpc::Message::Which Message::Builder::which() { + return _builder.getDataField<Which>(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(0 * ::capnp::POINTERS).isNull(); +} +inline bool Message::Builder::hasUnimplemented() { + if (which() != Message::UNIMPLEMENTED) return false; + return !_builder.getPointerField(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(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(0 * ::capnp::POINTERS)); +} +inline void Message::Builder::setUnimplemented( ::capnp::rpc::Message::Reader value) { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::UNIMPLEMENTED); + ::capnp::_::PointerHelpers< ::capnp::rpc::Message>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Message::Builder Message::Builder::initUnimplemented() { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::UNIMPLEMENTED); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Message>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Message::Builder::adoptUnimplemented( + ::capnp::Orphan< ::capnp::rpc::Message>&& value) { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::UNIMPLEMENTED); + ::capnp::_::PointerHelpers< ::capnp::rpc::Message>::adopt( + _builder.getPointerField(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(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(0 * ::capnp::POINTERS).isNull(); +} +inline bool Message::Builder::hasAbort() { + if (which() != Message::ABORT) return false; + return !_builder.getPointerField(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(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(0 * ::capnp::POINTERS)); +} +inline void Message::Builder::setAbort( ::capnp::rpc::Exception::Reader value) { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::ABORT); + ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Exception::Builder Message::Builder::initAbort() { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::ABORT); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Message::Builder::adoptAbort( + ::capnp::Orphan< ::capnp::rpc::Exception>&& value) { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::ABORT); + ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::adopt( + _builder.getPointerField(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(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(0 * ::capnp::POINTERS).isNull(); +} +inline bool Message::Builder::hasCall() { + if (which() != Message::CALL) return false; + return !_builder.getPointerField(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(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(0 * ::capnp::POINTERS)); +} +inline void Message::Builder::setCall( ::capnp::rpc::Call::Reader value) { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::CALL); + ::capnp::_::PointerHelpers< ::capnp::rpc::Call>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Call::Builder Message::Builder::initCall() { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::CALL); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Call>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Message::Builder::adoptCall( + ::capnp::Orphan< ::capnp::rpc::Call>&& value) { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::CALL); + ::capnp::_::PointerHelpers< ::capnp::rpc::Call>::adopt( + _builder.getPointerField(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(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(0 * ::capnp::POINTERS).isNull(); +} +inline bool Message::Builder::hasReturn() { + if (which() != Message::RETURN) return false; + return !_builder.getPointerField(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(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(0 * ::capnp::POINTERS)); +} +inline void Message::Builder::setReturn( ::capnp::rpc::Return::Reader value) { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::RETURN); + ::capnp::_::PointerHelpers< ::capnp::rpc::Return>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Return::Builder Message::Builder::initReturn() { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::RETURN); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Return>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Message::Builder::adoptReturn( + ::capnp::Orphan< ::capnp::rpc::Return>&& value) { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::RETURN); + ::capnp::_::PointerHelpers< ::capnp::rpc::Return>::adopt( + _builder.getPointerField(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(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(0 * ::capnp::POINTERS).isNull(); +} +inline bool Message::Builder::hasFinish() { + if (which() != Message::FINISH) return false; + return !_builder.getPointerField(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(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(0 * ::capnp::POINTERS)); +} +inline void Message::Builder::setFinish( ::capnp::rpc::Finish::Reader value) { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::FINISH); + ::capnp::_::PointerHelpers< ::capnp::rpc::Finish>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Finish::Builder Message::Builder::initFinish() { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::FINISH); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Finish>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Message::Builder::adoptFinish( + ::capnp::Orphan< ::capnp::rpc::Finish>&& value) { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::FINISH); + ::capnp::_::PointerHelpers< ::capnp::rpc::Finish>::adopt( + _builder.getPointerField(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(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(0 * ::capnp::POINTERS).isNull(); +} +inline bool Message::Builder::hasResolve() { + if (which() != Message::RESOLVE) return false; + return !_builder.getPointerField(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(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(0 * ::capnp::POINTERS)); +} +inline void Message::Builder::setResolve( ::capnp::rpc::Resolve::Reader value) { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::RESOLVE); + ::capnp::_::PointerHelpers< ::capnp::rpc::Resolve>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Resolve::Builder Message::Builder::initResolve() { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::RESOLVE); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Resolve>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Message::Builder::adoptResolve( + ::capnp::Orphan< ::capnp::rpc::Resolve>&& value) { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::RESOLVE); + ::capnp::_::PointerHelpers< ::capnp::rpc::Resolve>::adopt( + _builder.getPointerField(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(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(0 * ::capnp::POINTERS).isNull(); +} +inline bool Message::Builder::hasRelease() { + if (which() != Message::RELEASE) return false; + return !_builder.getPointerField(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(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(0 * ::capnp::POINTERS)); +} +inline void Message::Builder::setRelease( ::capnp::rpc::Release::Reader value) { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::RELEASE); + ::capnp::_::PointerHelpers< ::capnp::rpc::Release>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Release::Builder Message::Builder::initRelease() { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::RELEASE); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Release>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Message::Builder::adoptRelease( + ::capnp::Orphan< ::capnp::rpc::Release>&& value) { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::RELEASE); + ::capnp::_::PointerHelpers< ::capnp::rpc::Release>::adopt( + _builder.getPointerField(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(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(0 * ::capnp::POINTERS).isNull(); +} +inline bool Message::Builder::hasObsoleteSave() { + if (which() != Message::OBSOLETE_SAVE) return false; + return !_builder.getPointerField(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(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(0 * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Message::Builder::initObsoleteSave() { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::OBSOLETE_SAVE); + auto result = ::capnp::AnyPointer::Builder( + _builder.getPointerField(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(0 * ::capnp::POINTERS).isNull(); +} +inline bool Message::Builder::hasBootstrap() { + if (which() != Message::BOOTSTRAP) return false; + return !_builder.getPointerField(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(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(0 * ::capnp::POINTERS)); +} +inline void Message::Builder::setBootstrap( ::capnp::rpc::Bootstrap::Reader value) { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::BOOTSTRAP); + ::capnp::_::PointerHelpers< ::capnp::rpc::Bootstrap>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Bootstrap::Builder Message::Builder::initBootstrap() { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::BOOTSTRAP); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Bootstrap>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Message::Builder::adoptBootstrap( + ::capnp::Orphan< ::capnp::rpc::Bootstrap>&& value) { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::BOOTSTRAP); + ::capnp::_::PointerHelpers< ::capnp::rpc::Bootstrap>::adopt( + _builder.getPointerField(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(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(0 * ::capnp::POINTERS).isNull(); +} +inline bool Message::Builder::hasObsoleteDelete() { + if (which() != Message::OBSOLETE_DELETE) return false; + return !_builder.getPointerField(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(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(0 * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Message::Builder::initObsoleteDelete() { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::OBSOLETE_DELETE); + auto result = ::capnp::AnyPointer::Builder( + _builder.getPointerField(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(0 * ::capnp::POINTERS).isNull(); +} +inline bool Message::Builder::hasProvide() { + if (which() != Message::PROVIDE) return false; + return !_builder.getPointerField(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(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(0 * ::capnp::POINTERS)); +} +inline void Message::Builder::setProvide( ::capnp::rpc::Provide::Reader value) { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::PROVIDE); + ::capnp::_::PointerHelpers< ::capnp::rpc::Provide>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Provide::Builder Message::Builder::initProvide() { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::PROVIDE); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Provide>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Message::Builder::adoptProvide( + ::capnp::Orphan< ::capnp::rpc::Provide>&& value) { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::PROVIDE); + ::capnp::_::PointerHelpers< ::capnp::rpc::Provide>::adopt( + _builder.getPointerField(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(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(0 * ::capnp::POINTERS).isNull(); +} +inline bool Message::Builder::hasAccept() { + if (which() != Message::ACCEPT) return false; + return !_builder.getPointerField(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(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(0 * ::capnp::POINTERS)); +} +inline void Message::Builder::setAccept( ::capnp::rpc::Accept::Reader value) { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::ACCEPT); + ::capnp::_::PointerHelpers< ::capnp::rpc::Accept>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Accept::Builder Message::Builder::initAccept() { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::ACCEPT); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Accept>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Message::Builder::adoptAccept( + ::capnp::Orphan< ::capnp::rpc::Accept>&& value) { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::ACCEPT); + ::capnp::_::PointerHelpers< ::capnp::rpc::Accept>::adopt( + _builder.getPointerField(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(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(0 * ::capnp::POINTERS).isNull(); +} +inline bool Message::Builder::hasJoin() { + if (which() != Message::JOIN) return false; + return !_builder.getPointerField(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(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(0 * ::capnp::POINTERS)); +} +inline void Message::Builder::setJoin( ::capnp::rpc::Join::Reader value) { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::JOIN); + ::capnp::_::PointerHelpers< ::capnp::rpc::Join>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Join::Builder Message::Builder::initJoin() { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::JOIN); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Join>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Message::Builder::adoptJoin( + ::capnp::Orphan< ::capnp::rpc::Join>&& value) { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::JOIN); + ::capnp::_::PointerHelpers< ::capnp::rpc::Join>::adopt( + _builder.getPointerField(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(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(0 * ::capnp::POINTERS).isNull(); +} +inline bool Message::Builder::hasDisembargo() { + if (which() != Message::DISEMBARGO) return false; + return !_builder.getPointerField(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(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(0 * ::capnp::POINTERS)); +} +inline void Message::Builder::setDisembargo( ::capnp::rpc::Disembargo::Reader value) { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::DISEMBARGO); + ::capnp::_::PointerHelpers< ::capnp::rpc::Disembargo>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Disembargo::Builder Message::Builder::initDisembargo() { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::DISEMBARGO); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Disembargo>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Message::Builder::adoptDisembargo( + ::capnp::Orphan< ::capnp::rpc::Disembargo>&& value) { + _builder.setDataField<Message::Which>( + 0 * ::capnp::ELEMENTS, Message::DISEMBARGO); + ::capnp::_::PointerHelpers< ::capnp::rpc::Disembargo>::adopt( + _builder.getPointerField(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(0 * ::capnp::POINTERS)); +} + +inline ::uint32_t Bootstrap::Reader::getQuestionId() const { + return _reader.getDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS); +} + +inline ::uint32_t Bootstrap::Builder::getQuestionId() { + return _builder.getDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS); +} +inline void Bootstrap::Builder::setQuestionId( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Bootstrap::Reader::hasDeprecatedObjectId() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool Bootstrap::Builder::hasDeprecatedObjectId() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::AnyPointer::Reader Bootstrap::Reader::getDeprecatedObjectId() const { + return ::capnp::AnyPointer::Reader( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Bootstrap::Builder::getDeprecatedObjectId() { + return ::capnp::AnyPointer::Builder( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Bootstrap::Builder::initDeprecatedObjectId() { + auto result = ::capnp::AnyPointer::Builder( + _builder.getPointerField(0 * ::capnp::POINTERS)); + result.clear(); + return result; +} + +inline ::uint32_t Call::Reader::getQuestionId() const { + return _reader.getDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS); +} + +inline ::uint32_t Call::Builder::getQuestionId() { + return _builder.getDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS); +} +inline void Call::Builder::setQuestionId( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Call::Reader::hasTarget() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool Call::Builder::hasTarget() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::MessageTarget::Reader Call::Reader::getTarget() const { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::rpc::MessageTarget::Builder Call::Builder::getTarget() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get( + _builder.getPointerField(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(0 * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::MessageTarget::Builder Call::Builder::initTarget() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Call::Builder::adoptTarget( + ::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value) { + ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> Call::Builder::disownTarget() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} + +inline ::uint64_t Call::Reader::getInterfaceId() const { + return _reader.getDataField< ::uint64_t>( + 1 * ::capnp::ELEMENTS); +} + +inline ::uint64_t Call::Builder::getInterfaceId() { + return _builder.getDataField< ::uint64_t>( + 1 * ::capnp::ELEMENTS); +} +inline void Call::Builder::setInterfaceId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + 1 * ::capnp::ELEMENTS, value); +} + +inline ::uint16_t Call::Reader::getMethodId() const { + return _reader.getDataField< ::uint16_t>( + 2 * ::capnp::ELEMENTS); +} + +inline ::uint16_t Call::Builder::getMethodId() { + return _builder.getDataField< ::uint16_t>( + 2 * ::capnp::ELEMENTS); +} +inline void Call::Builder::setMethodId( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + 2 * ::capnp::ELEMENTS, value); +} + +inline bool Call::Reader::hasParams() const { + return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull(); +} +inline bool Call::Builder::hasParams() { + return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::Payload::Reader Call::Reader::getParams() const { + return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::get( + _reader.getPointerField(1 * ::capnp::POINTERS)); +} +inline ::capnp::rpc::Payload::Builder Call::Builder::getParams() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::get( + _builder.getPointerField(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(1 * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Payload::Builder Call::Builder::initParams() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::init( + _builder.getPointerField(1 * ::capnp::POINTERS)); +} +inline void Call::Builder::adoptParams( + ::capnp::Orphan< ::capnp::rpc::Payload>&& value) { + ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::adopt( + _builder.getPointerField(1 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::Payload> Call::Builder::disownParams() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::disown( + _builder.getPointerField(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>(3 * ::capnp::ELEMENTS, 0); + _builder.getPointerField(2 * ::capnp::POINTERS).clear(); + return typename Call::SendResultsTo::Builder(_builder); +} +inline bool Call::Reader::getAllowThirdPartyTailCall() const { + return _reader.getDataField<bool>( + 128 * ::capnp::ELEMENTS); +} + +inline bool Call::Builder::getAllowThirdPartyTailCall() { + return _builder.getDataField<bool>( + 128 * ::capnp::ELEMENTS); +} +inline void Call::Builder::setAllowThirdPartyTailCall(bool value) { + _builder.setDataField<bool>( + 128 * ::capnp::ELEMENTS, value); +} + +inline ::capnp::rpc::Call::SendResultsTo::Which Call::SendResultsTo::Reader::which() const { + return _reader.getDataField<Which>(3 * ::capnp::ELEMENTS); +} +inline ::capnp::rpc::Call::SendResultsTo::Which Call::SendResultsTo::Builder::which() { + return _builder.getDataField<Which>(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>( + 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>( + 0 * ::capnp::ELEMENTS); +} +inline void Call::SendResultsTo::Builder::setCaller( ::capnp::Void value) { + _builder.setDataField<Call::SendResultsTo::Which>( + 3 * ::capnp::ELEMENTS, Call::SendResultsTo::CALLER); + _builder.setDataField< ::capnp::Void>( + 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>( + 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>( + 0 * ::capnp::ELEMENTS); +} +inline void Call::SendResultsTo::Builder::setYourself( ::capnp::Void value) { + _builder.setDataField<Call::SendResultsTo::Which>( + 3 * ::capnp::ELEMENTS, Call::SendResultsTo::YOURSELF); + _builder.setDataField< ::capnp::Void>( + 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(2 * ::capnp::POINTERS).isNull(); +} +inline bool Call::SendResultsTo::Builder::hasThirdParty() { + if (which() != Call::SendResultsTo::THIRD_PARTY) return false; + return !_builder.getPointerField(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(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(2 * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Call::SendResultsTo::Builder::initThirdParty() { + _builder.setDataField<Call::SendResultsTo::Which>( + 3 * ::capnp::ELEMENTS, Call::SendResultsTo::THIRD_PARTY); + auto result = ::capnp::AnyPointer::Builder( + _builder.getPointerField(2 * ::capnp::POINTERS)); + result.clear(); + return result; +} + +inline ::capnp::rpc::Return::Which Return::Reader::which() const { + return _reader.getDataField<Which>(3 * ::capnp::ELEMENTS); +} +inline ::capnp::rpc::Return::Which Return::Builder::which() { + return _builder.getDataField<Which>(3 * ::capnp::ELEMENTS); +} + +inline ::uint32_t Return::Reader::getAnswerId() const { + return _reader.getDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS); +} + +inline ::uint32_t Return::Builder::getAnswerId() { + return _builder.getDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS); +} +inline void Return::Builder::setAnswerId( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Return::Reader::getReleaseParamCaps() const { + return _reader.getDataField<bool>( + 32 * ::capnp::ELEMENTS, true); +} + +inline bool Return::Builder::getReleaseParamCaps() { + return _builder.getDataField<bool>( + 32 * ::capnp::ELEMENTS, true); +} +inline void Return::Builder::setReleaseParamCaps(bool value) { + _builder.setDataField<bool>( + 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(0 * ::capnp::POINTERS).isNull(); +} +inline bool Return::Builder::hasResults() { + if (which() != Return::RESULTS) return false; + return !_builder.getPointerField(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(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(0 * ::capnp::POINTERS)); +} +inline void Return::Builder::setResults( ::capnp::rpc::Payload::Reader value) { + _builder.setDataField<Return::Which>( + 3 * ::capnp::ELEMENTS, Return::RESULTS); + ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Payload::Builder Return::Builder::initResults() { + _builder.setDataField<Return::Which>( + 3 * ::capnp::ELEMENTS, Return::RESULTS); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Return::Builder::adoptResults( + ::capnp::Orphan< ::capnp::rpc::Payload>&& value) { + _builder.setDataField<Return::Which>( + 3 * ::capnp::ELEMENTS, Return::RESULTS); + ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::adopt( + _builder.getPointerField(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(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(0 * ::capnp::POINTERS).isNull(); +} +inline bool Return::Builder::hasException() { + if (which() != Return::EXCEPTION) return false; + return !_builder.getPointerField(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(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(0 * ::capnp::POINTERS)); +} +inline void Return::Builder::setException( ::capnp::rpc::Exception::Reader value) { + _builder.setDataField<Return::Which>( + 3 * ::capnp::ELEMENTS, Return::EXCEPTION); + ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Exception::Builder Return::Builder::initException() { + _builder.setDataField<Return::Which>( + 3 * ::capnp::ELEMENTS, Return::EXCEPTION); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Return::Builder::adoptException( + ::capnp::Orphan< ::capnp::rpc::Exception>&& value) { + _builder.setDataField<Return::Which>( + 3 * ::capnp::ELEMENTS, Return::EXCEPTION); + ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::adopt( + _builder.getPointerField(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(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>( + 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>( + 0 * ::capnp::ELEMENTS); +} +inline void Return::Builder::setCanceled( ::capnp::Void value) { + _builder.setDataField<Return::Which>( + 3 * ::capnp::ELEMENTS, Return::CANCELED); + _builder.setDataField< ::capnp::Void>( + 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>( + 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>( + 0 * ::capnp::ELEMENTS); +} +inline void Return::Builder::setResultsSentElsewhere( ::capnp::Void value) { + _builder.setDataField<Return::Which>( + 3 * ::capnp::ELEMENTS, Return::RESULTS_SENT_ELSEWHERE); + _builder.setDataField< ::capnp::Void>( + 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>( + 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>( + 2 * ::capnp::ELEMENTS); +} +inline void Return::Builder::setTakeFromOtherQuestion( ::uint32_t value) { + _builder.setDataField<Return::Which>( + 3 * ::capnp::ELEMENTS, Return::TAKE_FROM_OTHER_QUESTION); + _builder.setDataField< ::uint32_t>( + 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(0 * ::capnp::POINTERS).isNull(); +} +inline bool Return::Builder::hasAcceptFromThirdParty() { + if (which() != Return::ACCEPT_FROM_THIRD_PARTY) return false; + return !_builder.getPointerField(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(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(0 * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Return::Builder::initAcceptFromThirdParty() { + _builder.setDataField<Return::Which>( + 3 * ::capnp::ELEMENTS, Return::ACCEPT_FROM_THIRD_PARTY); + auto result = ::capnp::AnyPointer::Builder( + _builder.getPointerField(0 * ::capnp::POINTERS)); + result.clear(); + return result; +} + +inline ::uint32_t Finish::Reader::getQuestionId() const { + return _reader.getDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS); +} + +inline ::uint32_t Finish::Builder::getQuestionId() { + return _builder.getDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS); +} +inline void Finish::Builder::setQuestionId( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Finish::Reader::getReleaseResultCaps() const { + return _reader.getDataField<bool>( + 32 * ::capnp::ELEMENTS, true); +} + +inline bool Finish::Builder::getReleaseResultCaps() { + return _builder.getDataField<bool>( + 32 * ::capnp::ELEMENTS, true); +} +inline void Finish::Builder::setReleaseResultCaps(bool value) { + _builder.setDataField<bool>( + 32 * ::capnp::ELEMENTS, value, true); +} + +inline ::capnp::rpc::Resolve::Which Resolve::Reader::which() const { + return _reader.getDataField<Which>(2 * ::capnp::ELEMENTS); +} +inline ::capnp::rpc::Resolve::Which Resolve::Builder::which() { + return _builder.getDataField<Which>(2 * ::capnp::ELEMENTS); +} + +inline ::uint32_t Resolve::Reader::getPromiseId() const { + return _reader.getDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS); +} + +inline ::uint32_t Resolve::Builder::getPromiseId() { + return _builder.getDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS); +} +inline void Resolve::Builder::setPromiseId( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + 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(0 * ::capnp::POINTERS).isNull(); +} +inline bool Resolve::Builder::hasCap() { + if (which() != Resolve::CAP) return false; + return !_builder.getPointerField(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(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(0 * ::capnp::POINTERS)); +} +inline void Resolve::Builder::setCap( ::capnp::rpc::CapDescriptor::Reader value) { + _builder.setDataField<Resolve::Which>( + 2 * ::capnp::ELEMENTS, Resolve::CAP); + ::capnp::_::PointerHelpers< ::capnp::rpc::CapDescriptor>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::CapDescriptor::Builder Resolve::Builder::initCap() { + _builder.setDataField<Resolve::Which>( + 2 * ::capnp::ELEMENTS, Resolve::CAP); + return ::capnp::_::PointerHelpers< ::capnp::rpc::CapDescriptor>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Resolve::Builder::adoptCap( + ::capnp::Orphan< ::capnp::rpc::CapDescriptor>&& value) { + _builder.setDataField<Resolve::Which>( + 2 * ::capnp::ELEMENTS, Resolve::CAP); + ::capnp::_::PointerHelpers< ::capnp::rpc::CapDescriptor>::adopt( + _builder.getPointerField(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(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(0 * ::capnp::POINTERS).isNull(); +} +inline bool Resolve::Builder::hasException() { + if (which() != Resolve::EXCEPTION) return false; + return !_builder.getPointerField(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(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(0 * ::capnp::POINTERS)); +} +inline void Resolve::Builder::setException( ::capnp::rpc::Exception::Reader value) { + _builder.setDataField<Resolve::Which>( + 2 * ::capnp::ELEMENTS, Resolve::EXCEPTION); + ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::Exception::Builder Resolve::Builder::initException() { + _builder.setDataField<Resolve::Which>( + 2 * ::capnp::ELEMENTS, Resolve::EXCEPTION); + return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Resolve::Builder::adoptException( + ::capnp::Orphan< ::capnp::rpc::Exception>&& value) { + _builder.setDataField<Resolve::Which>( + 2 * ::capnp::ELEMENTS, Resolve::EXCEPTION); + ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::adopt( + _builder.getPointerField(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(0 * ::capnp::POINTERS)); +} + +inline ::uint32_t Release::Reader::getId() const { + return _reader.getDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS); +} + +inline ::uint32_t Release::Builder::getId() { + return _builder.getDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS); +} +inline void Release::Builder::setId( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS, value); +} + +inline ::uint32_t Release::Reader::getReferenceCount() const { + return _reader.getDataField< ::uint32_t>( + 1 * ::capnp::ELEMENTS); +} + +inline ::uint32_t Release::Builder::getReferenceCount() { + return _builder.getDataField< ::uint32_t>( + 1 * ::capnp::ELEMENTS); +} +inline void Release::Builder::setReferenceCount( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + 1 * ::capnp::ELEMENTS, value); +} + +inline bool Disembargo::Reader::hasTarget() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool Disembargo::Builder::hasTarget() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::MessageTarget::Reader Disembargo::Reader::getTarget() const { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::rpc::MessageTarget::Builder Disembargo::Builder::getTarget() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get( + _builder.getPointerField(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(0 * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::MessageTarget::Builder Disembargo::Builder::initTarget() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Disembargo::Builder::adoptTarget( + ::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value) { + ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> Disembargo::Builder::disownTarget() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::disown( + _builder.getPointerField(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>(0 * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint16_t>(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>(2 * ::capnp::ELEMENTS); +} +inline ::capnp::rpc::Disembargo::Context::Which Disembargo::Context::Builder::which() { + return _builder.getDataField<Which>(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>( + 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>( + 0 * ::capnp::ELEMENTS); +} +inline void Disembargo::Context::Builder::setSenderLoopback( ::uint32_t value) { + _builder.setDataField<Disembargo::Context::Which>( + 2 * ::capnp::ELEMENTS, Disembargo::Context::SENDER_LOOPBACK); + _builder.setDataField< ::uint32_t>( + 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>( + 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>( + 0 * ::capnp::ELEMENTS); +} +inline void Disembargo::Context::Builder::setReceiverLoopback( ::uint32_t value) { + _builder.setDataField<Disembargo::Context::Which>( + 2 * ::capnp::ELEMENTS, Disembargo::Context::RECEIVER_LOOPBACK); + _builder.setDataField< ::uint32_t>( + 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>( + 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>( + 0 * ::capnp::ELEMENTS); +} +inline void Disembargo::Context::Builder::setAccept( ::capnp::Void value) { + _builder.setDataField<Disembargo::Context::Which>( + 2 * ::capnp::ELEMENTS, Disembargo::Context::ACCEPT); + _builder.setDataField< ::capnp::Void>( + 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>( + 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>( + 0 * ::capnp::ELEMENTS); +} +inline void Disembargo::Context::Builder::setProvide( ::uint32_t value) { + _builder.setDataField<Disembargo::Context::Which>( + 2 * ::capnp::ELEMENTS, Disembargo::Context::PROVIDE); + _builder.setDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS, value); +} + +inline ::uint32_t Provide::Reader::getQuestionId() const { + return _reader.getDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS); +} + +inline ::uint32_t Provide::Builder::getQuestionId() { + return _builder.getDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS); +} +inline void Provide::Builder::setQuestionId( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Provide::Reader::hasTarget() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool Provide::Builder::hasTarget() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::MessageTarget::Reader Provide::Reader::getTarget() const { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::rpc::MessageTarget::Builder Provide::Builder::getTarget() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get( + _builder.getPointerField(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(0 * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::MessageTarget::Builder Provide::Builder::initTarget() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Provide::Builder::adoptTarget( + ::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value) { + ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> Provide::Builder::disownTarget() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} + +inline bool Provide::Reader::hasRecipient() const { + return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull(); +} +inline bool Provide::Builder::hasRecipient() { + return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::AnyPointer::Reader Provide::Reader::getRecipient() const { + return ::capnp::AnyPointer::Reader( + _reader.getPointerField(1 * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Provide::Builder::getRecipient() { + return ::capnp::AnyPointer::Builder( + _builder.getPointerField(1 * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Provide::Builder::initRecipient() { + auto result = ::capnp::AnyPointer::Builder( + _builder.getPointerField(1 * ::capnp::POINTERS)); + result.clear(); + return result; +} + +inline ::uint32_t Accept::Reader::getQuestionId() const { + return _reader.getDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS); +} + +inline ::uint32_t Accept::Builder::getQuestionId() { + return _builder.getDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS); +} +inline void Accept::Builder::setQuestionId( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Accept::Reader::hasProvision() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool Accept::Builder::hasProvision() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::AnyPointer::Reader Accept::Reader::getProvision() const { + return ::capnp::AnyPointer::Reader( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Accept::Builder::getProvision() { + return ::capnp::AnyPointer::Builder( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Accept::Builder::initProvision() { + auto result = ::capnp::AnyPointer::Builder( + _builder.getPointerField(0 * ::capnp::POINTERS)); + result.clear(); + return result; +} + +inline bool Accept::Reader::getEmbargo() const { + return _reader.getDataField<bool>( + 32 * ::capnp::ELEMENTS); +} + +inline bool Accept::Builder::getEmbargo() { + return _builder.getDataField<bool>( + 32 * ::capnp::ELEMENTS); +} +inline void Accept::Builder::setEmbargo(bool value) { + _builder.setDataField<bool>( + 32 * ::capnp::ELEMENTS, value); +} + +inline ::uint32_t Join::Reader::getQuestionId() const { + return _reader.getDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS); +} + +inline ::uint32_t Join::Builder::getQuestionId() { + return _builder.getDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS); +} +inline void Join::Builder::setQuestionId( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Join::Reader::hasTarget() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool Join::Builder::hasTarget() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::rpc::MessageTarget::Reader Join::Reader::getTarget() const { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::rpc::MessageTarget::Builder Join::Builder::getTarget() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get( + _builder.getPointerField(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(0 * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::MessageTarget::Builder Join::Builder::initTarget() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Join::Builder::adoptTarget( + ::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value) { + ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> Join::Builder::disownTarget() { + return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} + +inline bool Join::Reader::hasKeyPart() const { + return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull(); +} +inline bool Join::Builder::hasKeyPart() { + return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::AnyPointer::Reader Join::Reader::getKeyPart() const { + return ::capnp::AnyPointer::Reader( + _reader.getPointerField(1 * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Join::Builder::getKeyPart() { + return ::capnp::AnyPointer::Builder( + _builder.getPointerField(1 * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Join::Builder::initKeyPart() { + auto result = ::capnp::AnyPointer::Builder( + _builder.getPointerField(1 * ::capnp::POINTERS)); + result.clear(); + return result; +} + +inline ::capnp::rpc::MessageTarget::Which MessageTarget::Reader::which() const { + return _reader.getDataField<Which>(2 * ::capnp::ELEMENTS); +} +inline ::capnp::rpc::MessageTarget::Which MessageTarget::Builder::which() { + return _builder.getDataField<Which>(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>( + 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>( + 0 * ::capnp::ELEMENTS); +} +inline void MessageTarget::Builder::setImportedCap( ::uint32_t value) { + _builder.setDataField<MessageTarget::Which>( + 2 * ::capnp::ELEMENTS, MessageTarget::IMPORTED_CAP); + _builder.setDataField< ::uint32_t>( + 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(0 * ::capnp::POINTERS).isNull(); +} +inline bool MessageTarget::Builder::hasPromisedAnswer() { + if (which() != MessageTarget::PROMISED_ANSWER) return false; + return !_builder.getPointerField(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(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(0 * ::capnp::POINTERS)); +} +inline void MessageTarget::Builder::setPromisedAnswer( ::capnp::rpc::PromisedAnswer::Reader value) { + _builder.setDataField<MessageTarget::Which>( + 2 * ::capnp::ELEMENTS, MessageTarget::PROMISED_ANSWER); + ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::PromisedAnswer::Builder MessageTarget::Builder::initPromisedAnswer() { + _builder.setDataField<MessageTarget::Which>( + 2 * ::capnp::ELEMENTS, MessageTarget::PROMISED_ANSWER); + return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void MessageTarget::Builder::adoptPromisedAnswer( + ::capnp::Orphan< ::capnp::rpc::PromisedAnswer>&& value) { + _builder.setDataField<MessageTarget::Which>( + 2 * ::capnp::ELEMENTS, MessageTarget::PROMISED_ANSWER); + ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::adopt( + _builder.getPointerField(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(0 * ::capnp::POINTERS)); +} + +inline bool Payload::Reader::hasContent() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool Payload::Builder::hasContent() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::AnyPointer::Reader Payload::Reader::getContent() const { + return ::capnp::AnyPointer::Reader( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Payload::Builder::getContent() { + return ::capnp::AnyPointer::Builder( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Payload::Builder::initContent() { + auto result = ::capnp::AnyPointer::Builder( + _builder.getPointerField(0 * ::capnp::POINTERS)); + result.clear(); + return result; +} + +inline bool Payload::Reader::hasCapTable() const { + return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull(); +} +inline bool Payload::Builder::hasCapTable() { + return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::rpc::CapDescriptor>::Reader Payload::Reader::getCapTable() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor>>::get( + _reader.getPointerField(1 * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::rpc::CapDescriptor>::Builder Payload::Builder::getCapTable() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor>>::get( + _builder.getPointerField(1 * ::capnp::POINTERS)); +} +inline void Payload::Builder::setCapTable( ::capnp::List< ::capnp::rpc::CapDescriptor>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor>>::set( + _builder.getPointerField(1 * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::rpc::CapDescriptor>::Builder Payload::Builder::initCapTable(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor>>::init( + _builder.getPointerField(1 * ::capnp::POINTERS), size); +} +inline void Payload::Builder::adoptCapTable( + ::capnp::Orphan< ::capnp::List< ::capnp::rpc::CapDescriptor>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor>>::adopt( + _builder.getPointerField(1 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::rpc::CapDescriptor>> Payload::Builder::disownCapTable() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor>>::disown( + _builder.getPointerField(1 * ::capnp::POINTERS)); +} + +inline ::capnp::rpc::CapDescriptor::Which CapDescriptor::Reader::which() const { + return _reader.getDataField<Which>(0 * ::capnp::ELEMENTS); +} +inline ::capnp::rpc::CapDescriptor::Which CapDescriptor::Builder::which() { + return _builder.getDataField<Which>(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>( + 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>( + 0 * ::capnp::ELEMENTS); +} +inline void CapDescriptor::Builder::setNone( ::capnp::Void value) { + _builder.setDataField<CapDescriptor::Which>( + 0 * ::capnp::ELEMENTS, CapDescriptor::NONE); + _builder.setDataField< ::capnp::Void>( + 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>( + 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>( + 1 * ::capnp::ELEMENTS); +} +inline void CapDescriptor::Builder::setSenderHosted( ::uint32_t value) { + _builder.setDataField<CapDescriptor::Which>( + 0 * ::capnp::ELEMENTS, CapDescriptor::SENDER_HOSTED); + _builder.setDataField< ::uint32_t>( + 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>( + 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>( + 1 * ::capnp::ELEMENTS); +} +inline void CapDescriptor::Builder::setSenderPromise( ::uint32_t value) { + _builder.setDataField<CapDescriptor::Which>( + 0 * ::capnp::ELEMENTS, CapDescriptor::SENDER_PROMISE); + _builder.setDataField< ::uint32_t>( + 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>( + 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>( + 1 * ::capnp::ELEMENTS); +} +inline void CapDescriptor::Builder::setReceiverHosted( ::uint32_t value) { + _builder.setDataField<CapDescriptor::Which>( + 0 * ::capnp::ELEMENTS, CapDescriptor::RECEIVER_HOSTED); + _builder.setDataField< ::uint32_t>( + 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(0 * ::capnp::POINTERS).isNull(); +} +inline bool CapDescriptor::Builder::hasReceiverAnswer() { + if (which() != CapDescriptor::RECEIVER_ANSWER) return false; + return !_builder.getPointerField(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(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(0 * ::capnp::POINTERS)); +} +inline void CapDescriptor::Builder::setReceiverAnswer( ::capnp::rpc::PromisedAnswer::Reader value) { + _builder.setDataField<CapDescriptor::Which>( + 0 * ::capnp::ELEMENTS, CapDescriptor::RECEIVER_ANSWER); + ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::PromisedAnswer::Builder CapDescriptor::Builder::initReceiverAnswer() { + _builder.setDataField<CapDescriptor::Which>( + 0 * ::capnp::ELEMENTS, CapDescriptor::RECEIVER_ANSWER); + return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void CapDescriptor::Builder::adoptReceiverAnswer( + ::capnp::Orphan< ::capnp::rpc::PromisedAnswer>&& value) { + _builder.setDataField<CapDescriptor::Which>( + 0 * ::capnp::ELEMENTS, CapDescriptor::RECEIVER_ANSWER); + ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::adopt( + _builder.getPointerField(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(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(0 * ::capnp::POINTERS).isNull(); +} +inline bool CapDescriptor::Builder::hasThirdPartyHosted() { + if (which() != CapDescriptor::THIRD_PARTY_HOSTED) return false; + return !_builder.getPointerField(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(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(0 * ::capnp::POINTERS)); +} +inline void CapDescriptor::Builder::setThirdPartyHosted( ::capnp::rpc::ThirdPartyCapDescriptor::Reader value) { + _builder.setDataField<CapDescriptor::Which>( + 0 * ::capnp::ELEMENTS, CapDescriptor::THIRD_PARTY_HOSTED); + ::capnp::_::PointerHelpers< ::capnp::rpc::ThirdPartyCapDescriptor>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::rpc::ThirdPartyCapDescriptor::Builder CapDescriptor::Builder::initThirdPartyHosted() { + _builder.setDataField<CapDescriptor::Which>( + 0 * ::capnp::ELEMENTS, CapDescriptor::THIRD_PARTY_HOSTED); + return ::capnp::_::PointerHelpers< ::capnp::rpc::ThirdPartyCapDescriptor>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void CapDescriptor::Builder::adoptThirdPartyHosted( + ::capnp::Orphan< ::capnp::rpc::ThirdPartyCapDescriptor>&& value) { + _builder.setDataField<CapDescriptor::Which>( + 0 * ::capnp::ELEMENTS, CapDescriptor::THIRD_PARTY_HOSTED); + ::capnp::_::PointerHelpers< ::capnp::rpc::ThirdPartyCapDescriptor>::adopt( + _builder.getPointerField(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(0 * ::capnp::POINTERS)); +} + +inline ::uint32_t PromisedAnswer::Reader::getQuestionId() const { + return _reader.getDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS); +} + +inline ::uint32_t PromisedAnswer::Builder::getQuestionId() { + return _builder.getDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS); +} +inline void PromisedAnswer::Builder::setQuestionId( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool PromisedAnswer::Reader::hasTransform() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool PromisedAnswer::Builder::hasTransform() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Reader PromisedAnswer::Reader::getTransform() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Builder PromisedAnswer::Builder::getTransform() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>::get( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void PromisedAnswer::Builder::setTransform( ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Builder PromisedAnswer::Builder::initTransform(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>::init( + _builder.getPointerField(0 * ::capnp::POINTERS), size); +} +inline void PromisedAnswer::Builder::adoptTransform( + ::capnp::Orphan< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>> PromisedAnswer::Builder::disownTransform() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} + +inline ::capnp::rpc::PromisedAnswer::Op::Which PromisedAnswer::Op::Reader::which() const { + return _reader.getDataField<Which>(0 * ::capnp::ELEMENTS); +} +inline ::capnp::rpc::PromisedAnswer::Op::Which PromisedAnswer::Op::Builder::which() { + return _builder.getDataField<Which>(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>( + 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>( + 0 * ::capnp::ELEMENTS); +} +inline void PromisedAnswer::Op::Builder::setNoop( ::capnp::Void value) { + _builder.setDataField<PromisedAnswer::Op::Which>( + 0 * ::capnp::ELEMENTS, PromisedAnswer::Op::NOOP); + _builder.setDataField< ::capnp::Void>( + 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>( + 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>( + 1 * ::capnp::ELEMENTS); +} +inline void PromisedAnswer::Op::Builder::setGetPointerField( ::uint16_t value) { + _builder.setDataField<PromisedAnswer::Op::Which>( + 0 * ::capnp::ELEMENTS, PromisedAnswer::Op::GET_POINTER_FIELD); + _builder.setDataField< ::uint16_t>( + 1 * ::capnp::ELEMENTS, value); +} + +inline bool ThirdPartyCapDescriptor::Reader::hasId() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool ThirdPartyCapDescriptor::Builder::hasId() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::AnyPointer::Reader ThirdPartyCapDescriptor::Reader::getId() const { + return ::capnp::AnyPointer::Reader( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder ThirdPartyCapDescriptor::Builder::getId() { + return ::capnp::AnyPointer::Builder( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder ThirdPartyCapDescriptor::Builder::initId() { + auto result = ::capnp::AnyPointer::Builder( + _builder.getPointerField(0 * ::capnp::POINTERS)); + result.clear(); + return result; +} + +inline ::uint32_t ThirdPartyCapDescriptor::Reader::getVineId() const { + return _reader.getDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS); +} + +inline ::uint32_t ThirdPartyCapDescriptor::Builder::getVineId() { + return _builder.getDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS); +} +inline void ThirdPartyCapDescriptor::Builder::setVineId( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Exception::Reader::hasReason() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool Exception::Builder::hasReason() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Exception::Reader::getReason() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Exception::Builder::getReason() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Exception::Builder::setReason( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Exception::Builder::initReason(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init( + _builder.getPointerField(0 * ::capnp::POINTERS), size); +} +inline void Exception::Builder::adoptReason( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Exception::Builder::disownReason() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} + +inline bool Exception::Reader::getObsoleteIsCallersFault() const { + return _reader.getDataField<bool>( + 0 * ::capnp::ELEMENTS); +} + +inline bool Exception::Builder::getObsoleteIsCallersFault() { + return _builder.getDataField<bool>( + 0 * ::capnp::ELEMENTS); +} +inline void Exception::Builder::setObsoleteIsCallersFault(bool value) { + _builder.setDataField<bool>( + 0 * ::capnp::ELEMENTS, value); +} + +inline ::uint16_t Exception::Reader::getObsoleteDurability() const { + return _reader.getDataField< ::uint16_t>( + 1 * ::capnp::ELEMENTS); +} + +inline ::uint16_t Exception::Builder::getObsoleteDurability() { + return _builder.getDataField< ::uint16_t>( + 1 * ::capnp::ELEMENTS); +} +inline void Exception::Builder::setObsoleteDurability( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + 1 * ::capnp::ELEMENTS, value); +} + +inline ::capnp::rpc::Exception::Type Exception::Reader::getType() const { + return _reader.getDataField< ::capnp::rpc::Exception::Type>( + 2 * ::capnp::ELEMENTS); +} + +inline ::capnp::rpc::Exception::Type Exception::Builder::getType() { + return _builder.getDataField< ::capnp::rpc::Exception::Type>( + 2 * ::capnp::ELEMENTS); +} +inline void Exception::Builder::setType( ::capnp::rpc::Exception::Type value) { + _builder.setDataField< ::capnp::rpc::Exception::Type>( + 2 * ::capnp::ELEMENTS, value); +} + +} // namespace +} // namespace + +#endif // CAPNP_INCLUDED_b312981b2552a250_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/rpc.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,537 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef CAPNP_RPC_H_ +#define CAPNP_RPC_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "capability.h" +#include "rpc-prelude.h" + +namespace capnp { + +template <typename VatId, typename ProvisionId, typename RecipientId, + typename ThirdPartyCapId, typename JoinResult> +class VatNetwork; +template <typename SturdyRefObjectId> +class SturdyRefRestorer; + +template <typename VatId> +class BootstrapFactory: public _::BootstrapFactoryBase { + // Interface that constructs per-client bootstrap interfaces. Use this if you want each client + // who connects to see a different bootstrap interface based on their (authenticated) VatId. + // This allows an application to bootstrap off of the authentication performed at the VatNetwork + // level. (Typically VatId is some sort of public key.) + // + // This is only useful for multi-party networks. For TwoPartyVatNetwork, there's no reason to + // use a BootstrapFactory; just specify a single bootstrap capability in this case. + +public: + virtual Capability::Client createFor(typename VatId::Reader clientId) = 0; + // Create a bootstrap capability appropriate for exposing to the given client. VatNetwork will + // have authenticated the client VatId before this is called. + +private: + Capability::Client baseCreateFor(AnyStruct::Reader clientId) override; +}; + +template <typename VatId> +class RpcSystem: public _::RpcSystemBase { + // Represents the RPC system, which is the portal to objects available on the network. + // + // The RPC implementation sits on top of an implementation of `VatNetwork`. The `VatNetwork` + // determines how to form connections between vats -- specifically, two-way, private, reliable, + // sequenced datagram connections. The RPC implementation determines how to use such connections + // to manage object references and make method calls. + // + // See `makeRpcServer()` and `makeRpcClient()` below for convenient syntax for setting up an + // `RpcSystem` given a `VatNetwork`. + // + // See `ez-rpc.h` for an even simpler interface for setting up RPC in a typical two-party + // client/server scenario. + +public: + template <typename ProvisionId, typename RecipientId, + typename ThirdPartyCapId, typename JoinResult> + RpcSystem( + VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network, + kj::Maybe<Capability::Client> bootstrapInterface, + kj::Maybe<RealmGateway<>::Client> gateway = nullptr); + + template <typename ProvisionId, typename RecipientId, + typename ThirdPartyCapId, typename JoinResult> + RpcSystem( + VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network, + BootstrapFactory<VatId>& bootstrapFactory, + kj::Maybe<RealmGateway<>::Client> gateway = nullptr); + + template <typename ProvisionId, typename RecipientId, + typename ThirdPartyCapId, typename JoinResult, + typename LocalSturdyRefObjectId> + RpcSystem( + VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network, + SturdyRefRestorer<LocalSturdyRefObjectId>& restorer); + + RpcSystem(RpcSystem&& other) = default; + + Capability::Client bootstrap(typename VatId::Reader vatId); + // Connect to the given vat and return its bootstrap interface. + + Capability::Client restore(typename VatId::Reader hostId, AnyPointer::Reader objectId) + KJ_DEPRECATED("Please transition to using a bootstrap interface instead."); + // ** DEPRECATED ** + // + // Restores the given SturdyRef from the network and return the capability representing it. + // + // `hostId` identifies the host from which to request the ref, in the format specified by the + // `VatNetwork` in use. `objectId` is the object ID in whatever format is expected by said host. + // + // This method will be removed in a future version of Cap'n Proto. Instead, please transition + // to using bootstrap(), which is equivalent to calling restore() with a null `objectId`. + // You may emulate the old concept of object IDs by exporting a bootstrap interface which has + // methods that can be used to obtain other capabilities by ID. + + void setFlowLimit(size_t words); + // Sets the incoming call flow limit. If more than `words` worth of call messages have not yet + // received responses, the RpcSystem will not read further messages from the stream. This can be + // used as a crude way to prevent a resource exhaustion attack (or bug) in which a peer makes an + // excessive number of simultaneous calls that consume the receiver's RAM. + // + // There are some caveats. When over the flow limit, all messages are blocked, including returns. + // If the outstanding calls are themselves waiting on calls going in the opposite direction, the + // flow limit may prevent those calls from completing, leading to deadlock. However, a + // sufficiently high limit should make this unlikely. + // + // Note that a call's parameter size counts against the flow limit until the call returns, even + // if the recipient calls releaseParams() to free the parameter memory early. This is because + // releaseParams() may simply indicate that the parameters have been forwarded to another + // machine, but are still in-memory there. For illustration, say that Alice made a call to Bob + // who forwarded the call to Carol. Bob has imposed a flow limit on Alice. Alice's calls are + // being forwarded to Carol, so Bob never keeps the parameters in-memory for more than a brief + // period. However, the flow limit counts all calls that haven't returned, even if Bob has + // already freed the memory they consumed. You might argue that the right solution here is + // instead for Carol to impose her own flow limit on Bob. This has a serious problem, though: + // Bob might be forwarding requests to Carol on behalf of many different parties, not just Alice. + // If Alice can pump enough data to hit the Bob -> Carol flow limit, then those other parties + // will be disrupted. Thus, we can only really impose the limit on the Alice -> Bob link, which + // only affects Alice. We need that one flow limit to limit Alice's impact on the whole system, + // so it has to count all in-flight calls. + // + // In Sandstorm, flow limits are imposed by the supervisor on calls coming out of a grain, in + // order to prevent a grain from inundating the system with in-flight calls. In practice, the + // main time this happens is when a grain is pushing a large file download and doesn't implement + // proper cooperative flow control. +}; + +template <typename VatId, typename ProvisionId, typename RecipientId, + typename ThirdPartyCapId, typename JoinResult> +RpcSystem<VatId> makeRpcServer( + VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network, + Capability::Client bootstrapInterface); +// Make an RPC server. Typical usage (e.g. in a main() function): +// +// MyEventLoop eventLoop; +// kj::WaitScope waitScope(eventLoop); +// MyNetwork network; +// MyMainInterface::Client bootstrap = makeMain(); +// auto server = makeRpcServer(network, bootstrap); +// kj::NEVER_DONE.wait(waitScope); // run forever +// +// See also ez-rpc.h, which has simpler instructions for the common case of a two-party +// client-server RPC connection. + +template <typename VatId, typename ProvisionId, typename RecipientId, + typename ThirdPartyCapId, typename JoinResult, typename RealmGatewayClient, + typename InternalRef = _::InternalRefFromRealmGatewayClient<RealmGatewayClient>, + typename ExternalRef = _::ExternalRefFromRealmGatewayClient<RealmGatewayClient>> +RpcSystem<VatId> makeRpcServer( + VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network, + Capability::Client bootstrapInterface, RealmGatewayClient gateway); +// Make an RPC server for a VatNetwork that resides in a different realm from the application. +// The given RealmGateway is used to translate SturdyRefs between the app's ("internal") format +// and the network's ("external") format. + +template <typename VatId, typename ProvisionId, typename RecipientId, + typename ThirdPartyCapId, typename JoinResult> +RpcSystem<VatId> makeRpcServer( + VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network, + BootstrapFactory<VatId>& bootstrapFactory); +// Make an RPC server that can serve different bootstrap interfaces to different clients via a +// BootstrapInterface. + +template <typename VatId, typename ProvisionId, typename RecipientId, + typename ThirdPartyCapId, typename JoinResult, typename RealmGatewayClient, + typename InternalRef = _::InternalRefFromRealmGatewayClient<RealmGatewayClient>, + typename ExternalRef = _::ExternalRefFromRealmGatewayClient<RealmGatewayClient>> +RpcSystem<VatId> makeRpcServer( + VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network, + BootstrapFactory<VatId>& bootstrapFactory, RealmGatewayClient gateway); +// Make an RPC server that can serve different bootstrap interfaces to different clients via a +// BootstrapInterface and communicates with a different realm than the application is in via a +// RealmGateway. + +template <typename VatId, typename LocalSturdyRefObjectId, + typename ProvisionId, typename RecipientId, typename ThirdPartyCapId, typename JoinResult> +RpcSystem<VatId> makeRpcServer( + VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network, + SturdyRefRestorer<LocalSturdyRefObjectId>& restorer) + KJ_DEPRECATED("Please transition to using a bootstrap interface instead."); +// ** DEPRECATED ** +// +// Create an RPC server which exports multiple main interfaces by object ID. The `restorer` object +// can be used to look up objects by ID. +// +// Please transition to exporting only one interface, which is known as the "bootstrap" interface. +// For backwards-compatibility with old clients, continue to implement SturdyRefRestorer, but +// return the new bootstrap interface when the request object ID is null. When new clients connect +// and request the bootstrap interface, they will get that interface. Eventually, once all clients +// are updated to request only the bootstrap interface, stop implementing SturdyRefRestorer and +// switch to passing the bootstrap capability itself as the second parameter to `makeRpcServer()`. + +template <typename VatId, typename ProvisionId, + typename RecipientId, typename ThirdPartyCapId, typename JoinResult> +RpcSystem<VatId> makeRpcClient( + VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network); +// Make an RPC client. Typical usage (e.g. in a main() function): +// +// MyEventLoop eventLoop; +// kj::WaitScope waitScope(eventLoop); +// MyNetwork network; +// auto client = makeRpcClient(network); +// MyCapability::Client cap = client.restore(hostId, objId).castAs<MyCapability>(); +// auto response = cap.fooRequest().send().wait(waitScope); +// handleMyResponse(response); +// +// See also ez-rpc.h, which has simpler instructions for the common case of a two-party +// client-server RPC connection. + +template <typename VatId, typename ProvisionId, typename RecipientId, + typename ThirdPartyCapId, typename JoinResult, typename RealmGatewayClient, + typename InternalRef = _::InternalRefFromRealmGatewayClient<RealmGatewayClient>, + typename ExternalRef = _::ExternalRefFromRealmGatewayClient<RealmGatewayClient>> +RpcSystem<VatId> makeRpcClient( + VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network, + RealmGatewayClient gateway); +// Make an RPC client for a VatNetwork that resides in a different realm from the application. +// The given RealmGateway is used to translate SturdyRefs between the app's ("internal") format +// and the network's ("external") format. + +template <typename SturdyRefObjectId> +class SturdyRefRestorer: public _::SturdyRefRestorerBase { + // ** DEPRECATED ** + // + // In Cap'n Proto 0.4.x, applications could export multiple main interfaces identified by + // object IDs. The callback used to map object IDs to objects was `SturdyRefRestorer`, as we + // imagined this would eventually be used for restoring SturdyRefs as well. In practice, it was + // never used for real SturdyRefs, only for exporting singleton objects under well-known names. + // + // The new preferred strategy is to export only a _single_ such interface, called the + // "bootstrap interface". That interface can itself have methods for obtaining other objects, of + // course, but that is up to the app. `SturdyRefRestorer` exists for backwards-compatibility. + // + // Hint: Use SturdyRefRestorer<capnp::Text> to define a server that exports services under + // string names. + +public: + virtual Capability::Client restore(typename SturdyRefObjectId::Reader ref) + KJ_DEPRECATED( + "Please transition to using bootstrap interfaces instead of SturdyRefRestorer.") = 0; + // Restore the given object, returning a capability representing it. + +private: + Capability::Client baseRestore(AnyPointer::Reader ref) override final; +}; + +// ======================================================================================= +// VatNetwork + +class OutgoingRpcMessage { + // A message to be sent by a `VatNetwork`. + +public: + virtual AnyPointer::Builder getBody() = 0; + // Get the message body, which the caller may fill in any way it wants. (The standard RPC + // implementation initializes it as a Message as defined in rpc.capnp.) + + virtual void send() = 0; + // Send the message, or at least put it in a queue to be sent later. Note that the builder + // returned by `getBody()` remains valid at least until the `OutgoingRpcMessage` is destroyed. +}; + +class IncomingRpcMessage { + // A message received from a `VatNetwork`. + +public: + virtual AnyPointer::Reader getBody() = 0; + // Get the message body, to be interpreted by the caller. (The standard RPC implementation + // interprets it as a Message as defined in rpc.capnp.) +}; + +template <typename VatId, typename ProvisionId, typename RecipientId, + typename ThirdPartyCapId, typename JoinResult> +class VatNetwork: public _::VatNetworkBase { + // Cap'n Proto RPC operates between vats, where a "vat" is some sort of host of objects. + // Typically one Cap'n Proto process (in the Unix sense) is one vat. The RPC system is what + // allows calls between objects hosted in different vats. + // + // The RPC implementation sits on top of an implementation of `VatNetwork`. The `VatNetwork` + // determines how to form connections between vats -- specifically, two-way, private, reliable, + // sequenced datagram connections. The RPC implementation determines how to use such connections + // to manage object references and make method calls. + // + // The most common implementation of VatNetwork is TwoPartyVatNetwork (rpc-twoparty.h). Most + // simple client-server apps will want to use it. (You may even want to use the EZ RPC + // interfaces in `ez-rpc.h` and avoid all of this.) + // + // TODO(someday): Provide a standard implementation for the public internet. + +public: + class Connection; + + struct ConnectionAndProvisionId { + // Result of connecting to a vat introduced by another vat. + + kj::Own<Connection> connection; + // Connection to the new vat. + + kj::Own<OutgoingRpcMessage> firstMessage; + // An already-allocated `OutgoingRpcMessage` associated with `connection`. The RPC system will + // construct this as an `Accept` message and send it. + + Orphan<ProvisionId> provisionId; + // A `ProvisionId` already allocated inside `firstMessage`, which the RPC system will use to + // build the `Accept` message. + }; + + class Connection: public _::VatNetworkBase::Connection { + // A two-way RPC connection. + // + // This object may represent a connection that doesn't exist yet, but is expected to exist + // in the future. In this case, sent messages will automatically be queued and sent once the + // connection is ready, so that the caller doesn't need to know the difference. + + public: + // Level 0 features ---------------------------------------------- + + virtual typename VatId::Reader getPeerVatId() = 0; + // Returns the connected vat's authenticated VatId. It is the VatNetwork's responsibility to + // authenticate this, so that the caller can be assured that they are really talking to the + // identified vat and not an imposter. + + virtual kj::Own<OutgoingRpcMessage> newOutgoingMessage(uint firstSegmentWordSize) override = 0; + // Allocate a new message to be sent on this connection. + // + // If `firstSegmentWordSize` is non-zero, it should be treated as a hint suggesting how large + // to make the first segment. This is entirely a hint and the connection may adjust it up or + // down. If it is zero, the connection should choose the size itself. + + virtual kj::Promise<kj::Maybe<kj::Own<IncomingRpcMessage>>> receiveIncomingMessage() override = 0; + // Wait for a message to be received and return it. If the read stream cleanly terminates, + // return null. If any other problem occurs, throw an exception. + + virtual kj::Promise<void> shutdown() override KJ_WARN_UNUSED_RESULT = 0; + // Waits until all outgoing messages have been sent, then shuts down the outgoing stream. The + // returned promise resolves after shutdown is complete. + + private: + AnyStruct::Reader baseGetPeerVatId() override; + }; + + // Level 0 features ------------------------------------------------ + + virtual kj::Maybe<kj::Own<Connection>> connect(typename VatId::Reader hostId) = 0; + // Connect to a VatId. Note that this method immediately returns a `Connection`, even + // if the network connection has not yet been established. Messages can be queued to this + // connection and will be delivered once it is open. The caller must attempt to read from the + // connection to verify that it actually succeeded; the read will fail if the connection + // couldn't be opened. Some network implementations may actually start sending messages before + // hearing back from the server at all, to avoid a round trip. + // + // Returns nullptr if `hostId` refers to the local host. + + virtual kj::Promise<kj::Own<Connection>> accept() = 0; + // Wait for the next incoming connection and return it. + + // Level 4 features ------------------------------------------------ + // TODO(someday) + +private: + kj::Maybe<kj::Own<_::VatNetworkBase::Connection>> + baseConnect(AnyStruct::Reader hostId) override final; + kj::Promise<kj::Own<_::VatNetworkBase::Connection>> baseAccept() override final; +}; + +// ======================================================================================= +// *************************************************************************************** +// Inline implementation details start here +// *************************************************************************************** +// ======================================================================================= + +template <typename VatId> +Capability::Client BootstrapFactory<VatId>::baseCreateFor(AnyStruct::Reader clientId) { + return createFor(clientId.as<VatId>()); +} + +template <typename SturdyRef, typename ProvisionId, typename RecipientId, + typename ThirdPartyCapId, typename JoinResult> +kj::Maybe<kj::Own<_::VatNetworkBase::Connection>> + VatNetwork<SturdyRef, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>:: + baseConnect(AnyStruct::Reader ref) { + auto maybe = connect(ref.as<SturdyRef>()); + return maybe.map([](kj::Own<Connection>& conn) -> kj::Own<_::VatNetworkBase::Connection> { + return kj::mv(conn); + }); +} + +template <typename SturdyRef, typename ProvisionId, typename RecipientId, + typename ThirdPartyCapId, typename JoinResult> +kj::Promise<kj::Own<_::VatNetworkBase::Connection>> + VatNetwork<SturdyRef, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>::baseAccept() { + return accept().then( + [](kj::Own<Connection>&& connection) -> kj::Own<_::VatNetworkBase::Connection> { + return kj::mv(connection); + }); +} + +template <typename SturdyRef, typename ProvisionId, typename RecipientId, + typename ThirdPartyCapId, typename JoinResult> +AnyStruct::Reader VatNetwork< + SturdyRef, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>:: + Connection::baseGetPeerVatId() { + return getPeerVatId(); +} + +template <typename SturdyRef> +Capability::Client SturdyRefRestorer<SturdyRef>::baseRestore(AnyPointer::Reader ref) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + return restore(ref.getAs<SturdyRef>()); +#pragma GCC diagnostic pop +} + +template <typename VatId> +template <typename ProvisionId, typename RecipientId, + typename ThirdPartyCapId, typename JoinResult> +RpcSystem<VatId>::RpcSystem( + VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network, + kj::Maybe<Capability::Client> bootstrap, + kj::Maybe<RealmGateway<>::Client> gateway) + : _::RpcSystemBase(network, kj::mv(bootstrap), kj::mv(gateway)) {} + +template <typename VatId> +template <typename ProvisionId, typename RecipientId, + typename ThirdPartyCapId, typename JoinResult> +RpcSystem<VatId>::RpcSystem( + VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network, + BootstrapFactory<VatId>& bootstrapFactory, + kj::Maybe<RealmGateway<>::Client> gateway) + : _::RpcSystemBase(network, bootstrapFactory, kj::mv(gateway)) {} + +template <typename VatId> +template <typename ProvisionId, typename RecipientId, + typename ThirdPartyCapId, typename JoinResult, + typename LocalSturdyRefObjectId> +RpcSystem<VatId>::RpcSystem( + VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network, + SturdyRefRestorer<LocalSturdyRefObjectId>& restorer) + : _::RpcSystemBase(network, restorer) {} + +template <typename VatId> +Capability::Client RpcSystem<VatId>::bootstrap(typename VatId::Reader vatId) { + return baseBootstrap(_::PointerHelpers<VatId>::getInternalReader(vatId)); +} + +template <typename VatId> +Capability::Client RpcSystem<VatId>::restore( + typename VatId::Reader hostId, AnyPointer::Reader objectId) { + return baseRestore(_::PointerHelpers<VatId>::getInternalReader(hostId), objectId); +} + +template <typename VatId> +inline void RpcSystem<VatId>::setFlowLimit(size_t words) { + baseSetFlowLimit(words); +} + +template <typename VatId, typename ProvisionId, typename RecipientId, + typename ThirdPartyCapId, typename JoinResult> +RpcSystem<VatId> makeRpcServer( + VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network, + Capability::Client bootstrapInterface) { + return RpcSystem<VatId>(network, kj::mv(bootstrapInterface)); +} + +template <typename VatId, typename ProvisionId, typename RecipientId, + typename ThirdPartyCapId, typename JoinResult, + typename RealmGatewayClient, typename InternalRef, typename ExternalRef> +RpcSystem<VatId> makeRpcServer( + VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network, + Capability::Client bootstrapInterface, RealmGatewayClient gateway) { + return RpcSystem<VatId>(network, kj::mv(bootstrapInterface), + gateway.template castAs<RealmGateway<>>()); +} + +template <typename VatId, typename ProvisionId, typename RecipientId, + typename ThirdPartyCapId, typename JoinResult> +RpcSystem<VatId> makeRpcServer( + VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network, + BootstrapFactory<VatId>& bootstrapFactory) { + return RpcSystem<VatId>(network, bootstrapFactory); +} + +template <typename VatId, typename ProvisionId, typename RecipientId, + typename ThirdPartyCapId, typename JoinResult, + typename RealmGatewayClient, typename InternalRef, typename ExternalRef> +RpcSystem<VatId> makeRpcServer( + VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network, + BootstrapFactory<VatId>& bootstrapFactory, RealmGatewayClient gateway) { + return RpcSystem<VatId>(network, bootstrapFactory, gateway.template castAs<RealmGateway<>>()); +} + +template <typename VatId, typename LocalSturdyRefObjectId, + typename ProvisionId, typename RecipientId, typename ThirdPartyCapId, typename JoinResult> +RpcSystem<VatId> makeRpcServer( + VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network, + SturdyRefRestorer<LocalSturdyRefObjectId>& restorer) { + return RpcSystem<VatId>(network, restorer); +} + +template <typename VatId, typename ProvisionId, + typename RecipientId, typename ThirdPartyCapId, typename JoinResult> +RpcSystem<VatId> makeRpcClient( + VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network) { + return RpcSystem<VatId>(network, nullptr); +} + +template <typename VatId, typename ProvisionId, + typename RecipientId, typename ThirdPartyCapId, typename JoinResult, + typename RealmGatewayClient, typename InternalRef, typename ExternalRef> +RpcSystem<VatId> makeRpcClient( + VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network, + RealmGatewayClient gateway) { + return RpcSystem<VatId>(network, nullptr, gateway.template castAs<RealmGateway<>>()); +} + +} // namespace capnp + +#endif // CAPNP_RPC_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/schema-lite.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,48 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef CAPNP_SCHEMA_LITE_H_ +#define CAPNP_SCHEMA_LITE_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include <capnp/schema.capnp.h> +#include "message.h" + +namespace capnp { + +template <typename T, typename CapnpPrivate = typename T::_capnpPrivate> +inline schema::Node::Reader schemaProto() { + // Get the schema::Node for this type's schema. This function works even in lite mode. + return readMessageUnchecked<schema::Node>(CapnpPrivate::encodedSchema()); +} + +template <typename T, uint64_t id = schemas::EnumInfo<T>::typeId> +inline schema::Node::Reader schemaProto() { + // Get the schema::Node for this type's schema. This function works even in lite mode. + return readMessageUnchecked<schema::Node>(schemas::EnumInfo<T>::encodedSchema()); +} + +} // namespace capnp + +#endif // CAPNP_SCHEMA_LITE_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/schema-loader.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,173 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef CAPNP_SCHEMA_LOADER_H_ +#define CAPNP_SCHEMA_LOADER_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "schema.h" +#include <kj/memory.h> +#include <kj/mutex.h> + +namespace capnp { + +class SchemaLoader { + // Class which can be used to construct Schema objects from schema::Nodes as defined in + // schema.capnp. + // + // It is a bad idea to use this class on untrusted input with exceptions disabled -- you may + // be exposing yourself to denial-of-service attacks, as attackers can easily construct schemas + // that are subtly inconsistent in a way that causes exceptions to be thrown either by + // SchemaLoader or by the dynamic API when the schemas are subsequently used. If you enable and + // properly catch exceptions, you should be OK -- assuming no bugs in the Cap'n Proto + // implementation, of course. + +public: + class LazyLoadCallback { + public: + virtual void load(const SchemaLoader& loader, uint64_t id) const = 0; + // Request that the schema node with the given ID be loaded into the given SchemaLoader. If + // the callback is able to find a schema for this ID, it should invoke `loadOnce()` on + // `loader` to load it. If no such node exists, it should simply do nothing and return. + // + // The callback is allowed to load schema nodes other than the one requested, e.g. because it + // expects they will be needed soon. + // + // If the `SchemaLoader` is used from multiple threads, the callback must be thread-safe. + // In particular, it's possible for multiple threads to invoke `load()` with the same ID. + // If the callback performs a large amount of work to look up IDs, it should be sure to + // de-dup these requests. + }; + + SchemaLoader(); + + SchemaLoader(const LazyLoadCallback& callback); + // Construct a SchemaLoader which will invoke the given callback when a schema node is requested + // that isn't already loaded. + + ~SchemaLoader() noexcept(false); + KJ_DISALLOW_COPY(SchemaLoader); + + Schema get(uint64_t id, schema::Brand::Reader brand = schema::Brand::Reader(), + Schema scope = Schema()) const; + // Gets the schema for the given ID, throwing an exception if it isn't present. + // + // The returned schema may be invalidated if load() is called with a new schema for the same ID. + // In general, you should not call load() while a schema from this loader is in-use. + // + // `brand` and `scope` are used to determine brand bindings where relevant. `brand` gives + // parameter bindings for the target type's brand parameters that were specified at the reference + // site. `scope` specifies the scope in which the type ID appeared -- if `brand` itself contains + // parameter references or indicates that some parameters will be inherited, these will be + // interpreted within / inherited from `scope`. + + kj::Maybe<Schema> tryGet(uint64_t id, schema::Brand::Reader bindings = schema::Brand::Reader(), + Schema scope = Schema()) const; + // Like get() but doesn't throw. + + Schema getUnbound(uint64_t id) const; + // Gets a special version of the schema in which all brand parameters are "unbound". This means + // that if you look up a type via the Schema API, and it resolves to a brand parameter, the + // returned Type's getBrandParameter() method will return info about that parameter. Otherwise, + // normally, all brand parameters that aren't otherwise bound are assumed to simply be + // "AnyPointer". + + Type getType(schema::Type::Reader type, Schema scope = Schema()) const; + // Convenience method which interprets a schema::Type to produce a Type object. Implemented in + // terms of get(). + + Schema load(const schema::Node::Reader& reader); + // Loads the given schema node. Validates the node and throws an exception if invalid. This + // makes a copy of the schema, so the object passed in can be destroyed after this returns. + // + // If the node has any dependencies which are not already loaded, they will be initialized as + // stubs -- empty schemas of whichever kind is expected. + // + // If another schema for the given reader has already been seen, the loader will inspect both + // schemas to determine which one is newer, and use that that one. If the two versions are + // found to be incompatible, an exception is thrown. If the two versions differ but are + // compatible and the loader cannot determine which is newer (e.g., the only changes are renames), + // the existing schema will be preferred. Note that in any case, the loader will end up keeping + // around copies of both schemas, so you shouldn't repeatedly reload schemas into the same loader. + // + // The following properties of the schema node are validated: + // - Struct size and preferred list encoding are valid and consistent. + // - Struct members are fields or unions. + // - Union members are fields. + // - Field offsets are in-bounds. + // - Ordinals and codeOrders are sequential starting from zero. + // - Values are of the right union case to match their types. + // + // You should assume anything not listed above is NOT validated. In particular, things that are + // not validated now, but could be in the future, include but are not limited to: + // - Names. + // - Annotation values. (This is hard because the annotation declaration is not always + // available.) + // - Content of default/constant values of pointer type. (Validating these would require knowing + // their schema, but even if the schemas are available at validation time, they could be + // updated by a subsequent load(), invalidating existing values. Instead, these values are + // validated at the time they are used, as usual for Cap'n Proto objects.) + // + // Also note that unknown types are not considered invalid. Instead, the dynamic API returns + // a DynamicValue with type UNKNOWN for these. + + Schema loadOnce(const schema::Node::Reader& reader) const; + // Like `load()` but does nothing if a schema with the same ID is already loaded. In contrast, + // `load()` would attempt to compare the schemas and take the newer one. `loadOnce()` is safe + // to call even while concurrently using schemas from this loader. It should be considered an + // error to call `loadOnce()` with two non-identical schemas that share the same ID, although + // this error may or may not actually be detected by the implementation. + + template <typename T> + void loadCompiledTypeAndDependencies(); + // Load the schema for the given compiled-in type and all of its dependencies. + // + // If you want to be able to cast a DynamicValue built from this SchemaLoader to the compiled-in + // type using as<T>(), you must call this method before constructing the DynamicValue. Otherwise, + // as<T>() will throw an exception complaining about type mismatch. + + kj::Array<Schema> getAllLoaded() const; + // Get a complete list of all loaded schema nodes. It is particularly useful to call this after + // loadCompiledTypeAndDependencies<T>() in order to get a flat list of all of T's transitive + // dependencies. + +private: + class Validator; + class CompatibilityChecker; + class Impl; + class InitializerImpl; + class BrandedInitializerImpl; + kj::MutexGuarded<kj::Own<Impl>> impl; + + void loadNative(const _::RawSchema* nativeSchema); +}; + +template <typename T> +inline void SchemaLoader::loadCompiledTypeAndDependencies() { + loadNative(&_::rawSchema<T>()); +} + +} // namespace capnp + +#endif // CAPNP_SCHEMA_LOADER_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/schema-parser.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,207 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef CAPNP_SCHEMA_PARSER_H_ +#define CAPNP_SCHEMA_PARSER_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "schema-loader.h" +#include <kj/string.h> + +namespace capnp { + +class ParsedSchema; +class SchemaFile; + +class SchemaParser { + // Parses `.capnp` files to produce `Schema` objects. + // + // This class is thread-safe, hence all its methods are const. + +public: + SchemaParser(); + ~SchemaParser() noexcept(false); + + ParsedSchema parseDiskFile(kj::StringPtr displayName, kj::StringPtr diskPath, + kj::ArrayPtr<const kj::StringPtr> importPath) const; + // Parse a file located on disk. Throws an exception if the file dosen't exist. + // + // Parameters: + // * `displayName`: The name that will appear in the file's schema node. (If the file has + // already been parsed, this will be ignored and the display name from the first time it was + // parsed will be kept.) + // * `diskPath`: The path to the file on disk. + // * `importPath`: Directories to search when resolving absolute imports within this file + // (imports that start with a `/`). Must remain valid until the SchemaParser is destroyed. + // (If the file has already been parsed, this will be ignored and the import path from the + // first time it was parsed will be kept.) + // + // This method is a shortcut, equivalent to: + // parser.parseFile(SchemaFile::newDiskFile(displayName, diskPath, importPath))`; + // + // This method throws an exception if any errors are encountered in the file or in anything the + // file depends on. Note that merely importing another file does not count as a dependency on + // anything in the imported file -- only the imported types which are actually used are + // "dependencies". + + ParsedSchema parseFile(kj::Own<SchemaFile>&& file) const; + // Advanced interface for parsing a file that may or may not be located in any global namespace. + // Most users will prefer `parseDiskFile()`. + // + // If the file has already been parsed (that is, a SchemaFile that compares equal to this one + // was parsed previously), the existing schema will be returned again. + // + // This method reports errors by calling SchemaFile::reportError() on the file where the error + // is located. If that call does not throw an exception, `parseFile()` may in fact return + // normally. In this case, the result is a best-effort attempt to compile the schema, but it + // may be invalid or corrupt, and using it for anything may cause exceptions to be thrown. + + template <typename T> + inline void loadCompiledTypeAndDependencies() { + // See SchemaLoader::loadCompiledTypeAndDependencies(). + getLoader().loadCompiledTypeAndDependencies<T>(); + } + +private: + struct Impl; + class ModuleImpl; + kj::Own<Impl> impl; + mutable bool hadErrors = false; + + ModuleImpl& getModuleImpl(kj::Own<SchemaFile>&& file) const; + SchemaLoader& getLoader(); + + friend class ParsedSchema; +}; + +class ParsedSchema: public Schema { + // ParsedSchema is an extension of Schema which also has the ability to look up nested nodes + // by name. See `SchemaParser`. + +public: + inline ParsedSchema(): parser(nullptr) {} + + kj::Maybe<ParsedSchema> findNested(kj::StringPtr name) const; + // Gets the nested node with the given name, or returns null if there is no such nested + // declaration. + + ParsedSchema getNested(kj::StringPtr name) const; + // Gets the nested node with the given name, or throws an exception if there is no such nested + // declaration. + +private: + inline ParsedSchema(Schema inner, const SchemaParser& parser): Schema(inner), parser(&parser) {} + + const SchemaParser* parser; + friend class SchemaParser; +}; + +// ======================================================================================= +// Advanced API + +class SchemaFile { + // Abstract interface representing a schema file. You can implement this yourself in order to + // gain more control over how the compiler resolves imports and reads files. For the + // common case of files on disk or other global filesystem-like namespaces, use + // `SchemaFile::newDiskFile()`. + +public: + class FileReader { + public: + virtual bool exists(kj::StringPtr path) const = 0; + virtual kj::Array<const char> read(kj::StringPtr path) const = 0; + }; + + class DiskFileReader final: public FileReader { + // Implementation of FileReader that uses the local disk. Files are read using mmap() if + // possible. + + public: + static const DiskFileReader instance; + + bool exists(kj::StringPtr path) const override; + kj::Array<const char> read(kj::StringPtr path) const override; + }; + + static kj::Own<SchemaFile> newDiskFile( + kj::StringPtr displayName, kj::StringPtr diskPath, + kj::ArrayPtr<const kj::StringPtr> importPath, + const FileReader& fileReader = DiskFileReader::instance); + // Construct a SchemaFile representing a file on disk (or located in the filesystem-like + // namespace represented by `fileReader`). + // + // Parameters: + // * `displayName`: The name that will appear in the file's schema node. + // * `diskPath`: The path to the file on disk. + // * `importPath`: Directories to search when resolving absolute imports within this file + // (imports that start with a `/`). The array content must remain valid as long as the + // SchemaFile exists (which is at least as long as the SchemaParser that parses it exists). + // * `fileReader`: Allows you to use a filesystem other than the actual local disk. Although, + // if you find yourself using this, it may make more sense for you to implement SchemaFile + // yourself. + // + // The SchemaFile compares equal to any other SchemaFile that has exactly the same disk path, + // after canonicalization. + // + // The SchemaFile will throw an exception if any errors are reported. + + // ----------------------------------------------------------------- + // For more control, you can implement this interface. + + virtual kj::StringPtr getDisplayName() const = 0; + // Get the file's name, as it should appear in the schema. + + virtual kj::Array<const char> readContent() const = 0; + // Read the file's entire content and return it as a byte array. + + virtual kj::Maybe<kj::Own<SchemaFile>> import(kj::StringPtr path) const = 0; + // Resolve an import, relative to this file. + // + // `path` is exactly what appears between quotes after the `import` keyword in the source code. + // It is entirely up to the `SchemaFile` to decide how to map this to another file. Typically, + // a leading '/' means that the file is an "absolute" path and is searched for in some list of + // schema file repositories. On the other hand, a path that doesn't start with '/' is relative + // to the importing file. + + virtual bool operator==(const SchemaFile& other) const = 0; + virtual bool operator!=(const SchemaFile& other) const = 0; + virtual size_t hashCode() const = 0; + // Compare two SchemaFiles to see if they refer to the same underlying file. This is an + // optimization used to avoid the need to re-parse a file to check its ID. + + struct SourcePos { + uint byte; + uint line; + uint column; + }; + virtual void reportError(SourcePos start, SourcePos end, kj::StringPtr message) const = 0; + // Report that the file contains an error at the given interval. + +private: + class DiskSchemaFile; +}; + +} // namespace capnp + +#endif // CAPNP_SCHEMA_PARSER_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/schema.capnp Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,484 @@ +# Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +# Licensed under the MIT License: +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +using Cxx = import "/capnp/c++.capnp"; + +@0xa93fc509624c72d9; +$Cxx.namespace("capnp::schema"); + +using Id = UInt64; +# The globally-unique ID of a file, type, or annotation. + +struct Node { + id @0 :Id; + + displayName @1 :Text; + # Name to present to humans to identify this Node. You should not attempt to parse this. Its + # format could change. It is not guaranteed to be unique. + # + # (On Zooko's triangle, this is the node's nickname.) + + displayNamePrefixLength @2 :UInt32; + # If you want a shorter version of `displayName` (just naming this node, without its surrounding + # scope), chop off this many characters from the beginning of `displayName`. + + scopeId @3 :Id; + # ID of the lexical parent node. Typically, the scope node will have a NestedNode pointing back + # at this node, but robust code should avoid relying on this (and, in fact, group nodes are not + # listed in the outer struct's nestedNodes, since they are listed in the fields). `scopeId` is + # zero if the node has no parent, which is normally only the case with files, but should be + # allowed for any kind of node (in order to make runtime type generation easier). + + parameters @32 :List(Parameter); + # If this node is parameterized (generic), the list of parameters. Empty for non-generic types. + + isGeneric @33 :Bool; + # True if this node is generic, meaning that it or one of its parent scopes has a non-empty + # `parameters`. + + struct Parameter { + # Information about one of the node's parameters. + + name @0 :Text; + } + + nestedNodes @4 :List(NestedNode); + # List of nodes nested within this node, along with the names under which they were declared. + + struct NestedNode { + name @0 :Text; + # Unqualified symbol name. Unlike Node.displayName, this *can* be used programmatically. + # + # (On Zooko's triangle, this is the node's petname according to its parent scope.) + + id @1 :Id; + # ID of the nested node. Typically, the target node's scopeId points back to this node, but + # robust code should avoid relying on this. + } + + annotations @5 :List(Annotation); + # Annotations applied to this node. + + union { + # Info specific to each kind of node. + + file @6 :Void; + + struct :group { + dataWordCount @7 :UInt16; + # Size of the data section, in words. + + pointerCount @8 :UInt16; + # Size of the pointer section, in pointers (which are one word each). + + preferredListEncoding @9 :ElementSize; + # The preferred element size to use when encoding a list of this struct. If this is anything + # other than `inlineComposite` then the struct is one word or less in size and is a candidate + # for list packing optimization. + + isGroup @10 :Bool; + # If true, then this "struct" node is actually not an independent node, but merely represents + # some named union or group within a particular parent struct. This node's scopeId refers + # to the parent struct, which may itself be a union/group in yet another struct. + # + # All group nodes share the same dataWordCount and pointerCount as the top-level + # struct, and their fields live in the same ordinal and offset spaces as all other fields in + # the struct. + # + # Note that a named union is considered a special kind of group -- in fact, a named union + # is exactly equivalent to a group that contains nothing but an unnamed union. + + discriminantCount @11 :UInt16; + # Number of fields in this struct which are members of an anonymous union, and thus may + # overlap. If this is non-zero, then a 16-bit discriminant is present indicating which + # of the overlapping fields is active. This can never be 1 -- if it is non-zero, it must be + # two or more. + # + # Note that the fields of an unnamed union are considered fields of the scope containing the + # union -- an unnamed union is not its own group. So, a top-level struct may contain a + # non-zero discriminant count. Named unions, on the other hand, are equivalent to groups + # containing unnamed unions. So, a named union has its own independent schema node, with + # `isGroup` = true. + + discriminantOffset @12 :UInt32; + # If `discriminantCount` is non-zero, this is the offset of the union discriminant, in + # multiples of 16 bits. + + fields @13 :List(Field); + # Fields defined within this scope (either the struct's top-level fields, or the fields of + # a particular group; see `isGroup`). + # + # The fields are sorted by ordinal number, but note that because groups share the same + # ordinal space, the field's index in this list is not necessarily exactly its ordinal. + # On the other hand, the field's position in this list does remain the same even as the + # protocol evolves, since it is not possible to insert or remove an earlier ordinal. + # Therefore, for most use cases, if you want to identify a field by number, it may make the + # most sense to use the field's index in this list rather than its ordinal. + } + + enum :group { + enumerants@14 :List(Enumerant); + # Enumerants ordered by numeric value (ordinal). + } + + interface :group { + methods @15 :List(Method); + # Methods ordered by ordinal. + + superclasses @31 :List(Superclass); + # Superclasses of this interface. + } + + const :group { + type @16 :Type; + value @17 :Value; + } + + annotation :group { + type @18 :Type; + + targetsFile @19 :Bool; + targetsConst @20 :Bool; + targetsEnum @21 :Bool; + targetsEnumerant @22 :Bool; + targetsStruct @23 :Bool; + targetsField @24 :Bool; + targetsUnion @25 :Bool; + targetsGroup @26 :Bool; + targetsInterface @27 :Bool; + targetsMethod @28 :Bool; + targetsParam @29 :Bool; + targetsAnnotation @30 :Bool; + } + } +} + +struct Field { + # Schema for a field of a struct. + + name @0 :Text; + + codeOrder @1 :UInt16; + # Indicates where this member appeared in the code, relative to other members. + # Code ordering may have semantic relevance -- programmers tend to place related fields + # together. So, using code ordering makes sense in human-readable formats where ordering is + # otherwise irrelevant, like JSON. The values of codeOrder are tightly-packed, so the maximum + # value is count(members) - 1. Fields that are members of a union are only ordered relative to + # the other members of that union, so the maximum value there is count(union.members). + + annotations @2 :List(Annotation); + + const noDiscriminant :UInt16 = 0xffff; + + discriminantValue @3 :UInt16 = Field.noDiscriminant; + # If the field is in a union, this is the value which the union's discriminant should take when + # the field is active. If the field is not in a union, this is 0xffff. + + union { + slot :group { + # A regular, non-group, non-fixed-list field. + + offset @4 :UInt32; + # Offset, in units of the field's size, from the beginning of the section in which the field + # resides. E.g. for a UInt32 field, multiply this by 4 to get the byte offset from the + # beginning of the data section. + + type @5 :Type; + defaultValue @6 :Value; + + hadExplicitDefault @10 :Bool; + # Whether the default value was specified explicitly. Non-explicit default values are always + # zero or empty values. Usually, whether the default value was explicit shouldn't matter. + # The main use case for this flag is for structs representing method parameters: + # explicitly-defaulted parameters may be allowed to be omitted when calling the method. + } + + group :group { + # A group. + + typeId @7 :Id; + # The ID of the group's node. + } + } + + ordinal :union { + implicit @8 :Void; + explicit @9 :UInt16; + # The original ordinal number given to the field. You probably should NOT use this; if you need + # a numeric identifier for a field, use its position within the field array for its scope. + # The ordinal is given here mainly just so that the original schema text can be reproduced given + # the compiled version -- i.e. so that `capnp compile -ocapnp` can do its job. + } +} + +struct Enumerant { + # Schema for member of an enum. + + name @0 :Text; + + codeOrder @1 :UInt16; + # Specifies order in which the enumerants were declared in the code. + # Like Struct.Field.codeOrder. + + annotations @2 :List(Annotation); +} + +struct Superclass { + id @0 :Id; + brand @1 :Brand; +} + +struct Method { + # Schema for method of an interface. + + name @0 :Text; + + codeOrder @1 :UInt16; + # Specifies order in which the methods were declared in the code. + # Like Struct.Field.codeOrder. + + implicitParameters @7 :List(Node.Parameter); + # The parameters listed in [] (typically, type / generic parameters), whose bindings are intended + # to be inferred rather than specified explicitly, although not all languages support this. + + paramStructType @2 :Id; + # ID of the parameter struct type. If a named parameter list was specified in the method + # declaration (rather than a single struct parameter type) then a corresponding struct type is + # auto-generated. Such an auto-generated type will not be listed in the interface's + # `nestedNodes` and its `scopeId` will be zero -- it is completely detached from the namespace. + # (Awkwardly, it does of course inherit generic parameters from the method's scope, which makes + # this a situation where you can't just climb the scope chain to find where a particular + # generic parameter was introduced. Making the `scopeId` zero was a mistake.) + + paramBrand @5 :Brand; + # Brand of param struct type. + + resultStructType @3 :Id; + # ID of the return struct type; similar to `paramStructType`. + + resultBrand @6 :Brand; + # Brand of result struct type. + + annotations @4 :List(Annotation); +} + +struct Type { + # Represents a type expression. + + union { + # The ordinals intentionally match those of Value. + + void @0 :Void; + bool @1 :Void; + int8 @2 :Void; + int16 @3 :Void; + int32 @4 :Void; + int64 @5 :Void; + uint8 @6 :Void; + uint16 @7 :Void; + uint32 @8 :Void; + uint64 @9 :Void; + float32 @10 :Void; + float64 @11 :Void; + text @12 :Void; + data @13 :Void; + + list :group { + elementType @14 :Type; + } + + enum :group { + typeId @15 :Id; + brand @21 :Brand; + } + struct :group { + typeId @16 :Id; + brand @22 :Brand; + } + interface :group { + typeId @17 :Id; + brand @23 :Brand; + } + + anyPointer :union { + unconstrained :union { + # A regular AnyPointer. + # + # The name "unconstained" means as opposed to constraining it to match a type parameter. + # In retrospect this name is probably a poor choice given that it may still be constrained + # to be a struct, list, or capability. + + anyKind @18 :Void; # truly AnyPointer + struct @25 :Void; # AnyStruct + list @26 :Void; # AnyList + capability @27 :Void; # Capability + } + + parameter :group { + # This is actually a reference to a type parameter defined within this scope. + + scopeId @19 :Id; + # ID of the generic type whose parameter we're referencing. This should be a parent of the + # current scope. + + parameterIndex @20 :UInt16; + # Index of the parameter within the generic type's parameter list. + } + + implicitMethodParameter :group { + # This is actually a reference to an implicit (generic) parameter of a method. The only + # legal context for this type to appear is inside Method.paramBrand or Method.resultBrand. + + parameterIndex @24 :UInt16; + } + } + } +} + +struct Brand { + # Specifies bindings for parameters of generics. Since these bindings turn a generic into a + # non-generic, we call it the "brand". + + scopes @0 :List(Scope); + # For each of the target type and each of its parent scopes, a parameterization may be included + # in this list. If no parameterization is included for a particular relevant scope, then either + # that scope has no parameters or all parameters should be considered to be `AnyPointer`. + + struct Scope { + scopeId @0 :Id; + # ID of the scope to which these params apply. + + union { + bind @1 :List(Binding); + # List of parameter bindings. + + inherit @2 :Void; + # The place where this Brand appears is actually within this scope or a sub-scope, + # and the bindings for this scope should be inherited from the reference point. + } + } + + struct Binding { + union { + unbound @0 :Void; + type @1 :Type; + + # TODO(someday): Allow non-type parameters? Unsure if useful. + } + } +} + +struct Value { + # Represents a value, e.g. a field default value, constant value, or annotation value. + + union { + # The ordinals intentionally match those of Type. + + void @0 :Void; + bool @1 :Bool; + int8 @2 :Int8; + int16 @3 :Int16; + int32 @4 :Int32; + int64 @5 :Int64; + uint8 @6 :UInt8; + uint16 @7 :UInt16; + uint32 @8 :UInt32; + uint64 @9 :UInt64; + float32 @10 :Float32; + float64 @11 :Float64; + text @12 :Text; + data @13 :Data; + + list @14 :AnyPointer; + + enum @15 :UInt16; + struct @16 :AnyPointer; + + interface @17 :Void; + # The only interface value that can be represented statically is "null", whose methods always + # throw exceptions. + + anyPointer @18 :AnyPointer; + } +} + +struct Annotation { + # Describes an annotation applied to a declaration. Note AnnotationNode describes the + # annotation's declaration, while this describes a use of the annotation. + + id @0 :Id; + # ID of the annotation node. + + brand @2 :Brand; + # Brand of the annotation. + # + # Note that the annotation itself is not allowed to be parameterized, but its scope might be. + + value @1 :Value; +} + +enum ElementSize { + # Possible element sizes for encoded lists. These correspond exactly to the possible values of + # the 3-bit element size component of a list pointer. + + empty @0; # aka "void", but that's a keyword. + bit @1; + byte @2; + twoBytes @3; + fourBytes @4; + eightBytes @5; + pointer @6; + inlineComposite @7; +} + +struct CodeGeneratorRequest { + nodes @0 :List(Node); + # All nodes parsed by the compiler, including for the files on the command line and their + # imports. + + requestedFiles @1 :List(RequestedFile); + # Files which were listed on the command line. + + struct RequestedFile { + id @0 :Id; + # ID of the file. + + filename @1 :Text; + # Name of the file as it appeared on the command-line (minus the src-prefix). You may use + # this to decide where to write the output. + + imports @2 :List(Import); + # List of all imported paths seen in this file. + + struct Import { + id @0 :Id; + # ID of the imported file. + + name @1 :Text; + # Name which *this* file used to refer to the foreign file. This may be a relative name. + # This information is provided because it might be useful for code generation, e.g. to + # generate #include directives in C++. We don't put this in Node.file because this + # information is only meaningful at compile time anyway. + # + # (On Zooko's triangle, this is the import's petname according to the importing file.) + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/schema.capnp.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,7561 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: schema.capnp + +#ifndef CAPNP_INCLUDED_a93fc509624c72d9_ +#define CAPNP_INCLUDED_a93fc509624c72d9_ + +#include <capnp/generated-header-support.h> + +#if CAPNP_VERSION != 6000 +#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." +#endif + + +namespace capnp { +namespace schemas { + +CAPNP_DECLARE_SCHEMA(e682ab4cf923a417); +CAPNP_DECLARE_SCHEMA(b9521bccf10fa3b1); +CAPNP_DECLARE_SCHEMA(debf55bbfa0fc242); +CAPNP_DECLARE_SCHEMA(9ea0b19b37fb4435); +CAPNP_DECLARE_SCHEMA(b54ab3364333f598); +CAPNP_DECLARE_SCHEMA(e82753cff0c2218f); +CAPNP_DECLARE_SCHEMA(b18aa5ac7a0d9420); +CAPNP_DECLARE_SCHEMA(ec1619d4400a0290); +CAPNP_DECLARE_SCHEMA(9aad50a41f4af45f); +CAPNP_DECLARE_SCHEMA(97b14cbe7cfec712); +CAPNP_DECLARE_SCHEMA(c42305476bb4746f); +CAPNP_DECLARE_SCHEMA(cafccddb68db1d11); +CAPNP_DECLARE_SCHEMA(bb90d5c287870be6); +CAPNP_DECLARE_SCHEMA(978a7cebdc549a4d); +CAPNP_DECLARE_SCHEMA(a9962a9ed0a4d7f8); +CAPNP_DECLARE_SCHEMA(9500cce23b334d80); +CAPNP_DECLARE_SCHEMA(d07378ede1f9cc60); +CAPNP_DECLARE_SCHEMA(87e739250a60ea97); +CAPNP_DECLARE_SCHEMA(9e0e78711a7f87a9); +CAPNP_DECLARE_SCHEMA(ac3a6f60ef4cc6d3); +CAPNP_DECLARE_SCHEMA(ed8bca69f7fb0cbf); +CAPNP_DECLARE_SCHEMA(c2573fe8a23e49f1); +CAPNP_DECLARE_SCHEMA(8e3b5f79fe593656); +CAPNP_DECLARE_SCHEMA(9dd1f724f4614a85); +CAPNP_DECLARE_SCHEMA(baefc9120c56e274); +CAPNP_DECLARE_SCHEMA(903455f06065422b); +CAPNP_DECLARE_SCHEMA(abd73485a9636bc9); +CAPNP_DECLARE_SCHEMA(c863cd16969ee7fc); +CAPNP_DECLARE_SCHEMA(ce23dcd2d7b00c9b); +CAPNP_DECLARE_SCHEMA(f1c8950dab257542); +CAPNP_DECLARE_SCHEMA(d1958f7dba521926); +enum class ElementSize_d1958f7dba521926: uint16_t { + EMPTY, + BIT, + BYTE, + TWO_BYTES, + FOUR_BYTES, + EIGHT_BYTES, + POINTER, + INLINE_COMPOSITE, +}; +CAPNP_DECLARE_ENUM(ElementSize, d1958f7dba521926); +CAPNP_DECLARE_SCHEMA(bfc546f6210ad7ce); +CAPNP_DECLARE_SCHEMA(cfea0eb02e810062); +CAPNP_DECLARE_SCHEMA(ae504193122357e5); + +} // namespace schemas +} // namespace capnp + +namespace capnp { +namespace schema { + +struct Node { + Node() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + FILE, + STRUCT, + ENUM, + INTERFACE, + CONST, + ANNOTATION, + }; + struct Parameter; + struct NestedNode; + struct Struct; + struct Enum; + struct Interface; + struct Const; + struct Annotation; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(e682ab4cf923a417, 5, 6) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct Node::Parameter { + Parameter() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(b9521bccf10fa3b1, 0, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct Node::NestedNode { + NestedNode() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(debf55bbfa0fc242, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct Node::Struct { + Struct() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(9ea0b19b37fb4435, 5, 6) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct Node::Enum { + Enum() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(b54ab3364333f598, 5, 6) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct Node::Interface { + Interface() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(e82753cff0c2218f, 5, 6) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct Node::Const { + Const() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(b18aa5ac7a0d9420, 5, 6) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct Node::Annotation { + Annotation() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(ec1619d4400a0290, 5, 6) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct Field { + Field() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + SLOT, + GROUP, + }; + static constexpr ::uint16_t NO_DISCRIMINANT = 65535u; + struct Slot; + struct Group; + struct Ordinal; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(9aad50a41f4af45f, 3, 4) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct Field::Slot { + Slot() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(c42305476bb4746f, 3, 4) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct Field::Group { + Group() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(cafccddb68db1d11, 3, 4) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct Field::Ordinal { + Ordinal() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + IMPLICIT, + EXPLICIT, + }; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(bb90d5c287870be6, 3, 4) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct Enumerant { + Enumerant() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(978a7cebdc549a4d, 1, 2) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct Superclass { + Superclass() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(a9962a9ed0a4d7f8, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct Method { + Method() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(9500cce23b334d80, 3, 5) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct Type { + Type() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + VOID, + BOOL, + INT8, + INT16, + INT32, + INT64, + UINT8, + UINT16, + UINT32, + UINT64, + FLOAT32, + FLOAT64, + TEXT, + DATA, + LIST, + ENUM, + STRUCT, + INTERFACE, + ANY_POINTER, + }; + struct List; + struct Enum; + struct Struct; + struct Interface; + struct AnyPointer; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(d07378ede1f9cc60, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct Type::List { + List() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(87e739250a60ea97, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct Type::Enum { + Enum() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(9e0e78711a7f87a9, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct Type::Struct { + Struct() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(ac3a6f60ef4cc6d3, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct Type::Interface { + Interface() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(ed8bca69f7fb0cbf, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct Type::AnyPointer { + AnyPointer() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + UNCONSTRAINED, + PARAMETER, + IMPLICIT_METHOD_PARAMETER, + }; + struct Unconstrained; + struct Parameter; + struct ImplicitMethodParameter; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(c2573fe8a23e49f1, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct Type::AnyPointer::Unconstrained { + Unconstrained() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + ANY_KIND, + STRUCT, + LIST, + CAPABILITY, + }; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(8e3b5f79fe593656, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct Type::AnyPointer::Parameter { + Parameter() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(9dd1f724f4614a85, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct Type::AnyPointer::ImplicitMethodParameter { + ImplicitMethodParameter() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(baefc9120c56e274, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct Brand { + Brand() = delete; + + class Reader; + class Builder; + class Pipeline; + struct Scope; + struct Binding; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(903455f06065422b, 0, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct Brand::Scope { + Scope() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + BIND, + INHERIT, + }; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(abd73485a9636bc9, 2, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct Brand::Binding { + Binding() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + UNBOUND, + TYPE, + }; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(c863cd16969ee7fc, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct Value { + Value() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + VOID, + BOOL, + INT8, + INT16, + INT32, + INT64, + UINT8, + UINT16, + UINT32, + UINT64, + FLOAT32, + FLOAT64, + TEXT, + DATA, + LIST, + ENUM, + STRUCT, + INTERFACE, + ANY_POINTER, + }; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(ce23dcd2d7b00c9b, 2, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct Annotation { + Annotation() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(f1c8950dab257542, 1, 2) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +typedef ::capnp::schemas::ElementSize_d1958f7dba521926 ElementSize; + +struct CodeGeneratorRequest { + CodeGeneratorRequest() = delete; + + class Reader; + class Builder; + class Pipeline; + struct RequestedFile; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(bfc546f6210ad7ce, 0, 2) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct CodeGeneratorRequest::RequestedFile { + RequestedFile() = delete; + + class Reader; + class Builder; + class Pipeline; + struct Import; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(cfea0eb02e810062, 1, 2) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +struct CodeGeneratorRequest::RequestedFile::Import { + Import() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(ae504193122357e5, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand = &schema->defaultBrand; + #endif // !CAPNP_LITE + }; +}; + +// ======================================================================================= + +class Node::Reader { +public: + typedef Node 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 ::uint64_t getId() const; + + inline bool hasDisplayName() const; + inline ::capnp::Text::Reader getDisplayName() const; + + inline ::uint32_t getDisplayNamePrefixLength() const; + + inline ::uint64_t getScopeId() const; + + inline bool hasNestedNodes() const; + inline ::capnp::List< ::capnp::schema::Node::NestedNode>::Reader getNestedNodes() const; + + inline bool hasAnnotations() const; + inline ::capnp::List< ::capnp::schema::Annotation>::Reader getAnnotations() const; + + inline bool isFile() const; + inline ::capnp::Void getFile() const; + + inline bool isStruct() const; + inline typename Struct::Reader getStruct() const; + + inline bool isEnum() const; + inline typename Enum::Reader getEnum() const; + + inline bool isInterface() const; + inline typename Interface::Reader getInterface() const; + + inline bool isConst() const; + inline typename Const::Reader getConst() const; + + inline bool isAnnotation() const; + inline typename Annotation::Reader getAnnotation() const; + + inline bool hasParameters() const; + inline ::capnp::List< ::capnp::schema::Node::Parameter>::Reader getParameters() const; + + inline bool getIsGeneric() 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 Node::Builder { +public: + typedef Node 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 ::uint64_t getId(); + inline void setId( ::uint64_t value); + + inline bool hasDisplayName(); + inline ::capnp::Text::Builder getDisplayName(); + inline void setDisplayName( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initDisplayName(unsigned int size); + inline void adoptDisplayName(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownDisplayName(); + + inline ::uint32_t getDisplayNamePrefixLength(); + inline void setDisplayNamePrefixLength( ::uint32_t value); + + inline ::uint64_t getScopeId(); + inline void setScopeId( ::uint64_t value); + + inline bool hasNestedNodes(); + inline ::capnp::List< ::capnp::schema::Node::NestedNode>::Builder getNestedNodes(); + inline void setNestedNodes( ::capnp::List< ::capnp::schema::Node::NestedNode>::Reader value); + inline ::capnp::List< ::capnp::schema::Node::NestedNode>::Builder initNestedNodes(unsigned int size); + inline void adoptNestedNodes(::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::NestedNode>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::NestedNode>> disownNestedNodes(); + + inline bool hasAnnotations(); + inline ::capnp::List< ::capnp::schema::Annotation>::Builder getAnnotations(); + inline void setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value); + inline ::capnp::List< ::capnp::schema::Annotation>::Builder initAnnotations(unsigned int size); + inline void adoptAnnotations(::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> disownAnnotations(); + + inline bool isFile(); + inline ::capnp::Void getFile(); + inline void setFile( ::capnp::Void value = ::capnp::VOID); + + inline bool isStruct(); + inline typename Struct::Builder getStruct(); + inline typename Struct::Builder initStruct(); + + inline bool isEnum(); + inline typename Enum::Builder getEnum(); + inline typename Enum::Builder initEnum(); + + inline bool isInterface(); + inline typename Interface::Builder getInterface(); + inline typename Interface::Builder initInterface(); + + inline bool isConst(); + inline typename Const::Builder getConst(); + inline typename Const::Builder initConst(); + + inline bool isAnnotation(); + inline typename Annotation::Builder getAnnotation(); + inline typename Annotation::Builder initAnnotation(); + + inline bool hasParameters(); + inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder getParameters(); + inline void setParameters( ::capnp::List< ::capnp::schema::Node::Parameter>::Reader value); + inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder initParameters(unsigned int size); + inline void adoptParameters(::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>> disownParameters(); + + inline bool getIsGeneric(); + inline void setIsGeneric(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 Node::Pipeline { +public: + typedef Node 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 Node::Parameter::Reader { +public: + typedef Parameter 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 hasName() const; + inline ::capnp::Text::Reader getName() 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 Node::Parameter::Builder { +public: + typedef Parameter 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 hasName(); + inline ::capnp::Text::Builder getName(); + inline void setName( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initName(unsigned int size); + inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownName(); + +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 Node::Parameter::Pipeline { +public: + typedef Parameter 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 Node::NestedNode::Reader { +public: + typedef NestedNode 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 hasName() const; + inline ::capnp::Text::Reader getName() const; + + inline ::uint64_t getId() 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 Node::NestedNode::Builder { +public: + typedef NestedNode 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 hasName(); + inline ::capnp::Text::Builder getName(); + inline void setName( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initName(unsigned int size); + inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownName(); + + inline ::uint64_t getId(); + inline void setId( ::uint64_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 Node::NestedNode::Pipeline { +public: + typedef NestedNode 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 Node::Struct::Reader { +public: + typedef Struct 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 ::uint16_t getDataWordCount() const; + + inline ::uint16_t getPointerCount() const; + + inline ::capnp::schema::ElementSize getPreferredListEncoding() const; + + inline bool getIsGroup() const; + + inline ::uint16_t getDiscriminantCount() const; + + inline ::uint32_t getDiscriminantOffset() const; + + inline bool hasFields() const; + inline ::capnp::List< ::capnp::schema::Field>::Reader getFields() 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 Node::Struct::Builder { +public: + typedef Struct 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 ::uint16_t getDataWordCount(); + inline void setDataWordCount( ::uint16_t value); + + inline ::uint16_t getPointerCount(); + inline void setPointerCount( ::uint16_t value); + + inline ::capnp::schema::ElementSize getPreferredListEncoding(); + inline void setPreferredListEncoding( ::capnp::schema::ElementSize value); + + inline bool getIsGroup(); + inline void setIsGroup(bool value); + + inline ::uint16_t getDiscriminantCount(); + inline void setDiscriminantCount( ::uint16_t value); + + inline ::uint32_t getDiscriminantOffset(); + inline void setDiscriminantOffset( ::uint32_t value); + + inline bool hasFields(); + inline ::capnp::List< ::capnp::schema::Field>::Builder getFields(); + inline void setFields( ::capnp::List< ::capnp::schema::Field>::Reader value); + inline ::capnp::List< ::capnp::schema::Field>::Builder initFields(unsigned int size); + inline void adoptFields(::capnp::Orphan< ::capnp::List< ::capnp::schema::Field>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Field>> disownFields(); + +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 Node::Struct::Pipeline { +public: + typedef Struct 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 Node::Enum::Reader { +public: + typedef Enum 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 hasEnumerants() const; + inline ::capnp::List< ::capnp::schema::Enumerant>::Reader getEnumerants() 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 Node::Enum::Builder { +public: + typedef Enum 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 hasEnumerants(); + inline ::capnp::List< ::capnp::schema::Enumerant>::Builder getEnumerants(); + inline void setEnumerants( ::capnp::List< ::capnp::schema::Enumerant>::Reader value); + inline ::capnp::List< ::capnp::schema::Enumerant>::Builder initEnumerants(unsigned int size); + inline void adoptEnumerants(::capnp::Orphan< ::capnp::List< ::capnp::schema::Enumerant>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Enumerant>> disownEnumerants(); + +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 Node::Enum::Pipeline { +public: + typedef Enum 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 Node::Interface::Reader { +public: + typedef Interface 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 hasMethods() const; + inline ::capnp::List< ::capnp::schema::Method>::Reader getMethods() const; + + inline bool hasSuperclasses() const; + inline ::capnp::List< ::capnp::schema::Superclass>::Reader getSuperclasses() 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 Node::Interface::Builder { +public: + typedef Interface 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 hasMethods(); + inline ::capnp::List< ::capnp::schema::Method>::Builder getMethods(); + inline void setMethods( ::capnp::List< ::capnp::schema::Method>::Reader value); + inline ::capnp::List< ::capnp::schema::Method>::Builder initMethods(unsigned int size); + inline void adoptMethods(::capnp::Orphan< ::capnp::List< ::capnp::schema::Method>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Method>> disownMethods(); + + inline bool hasSuperclasses(); + inline ::capnp::List< ::capnp::schema::Superclass>::Builder getSuperclasses(); + inline void setSuperclasses( ::capnp::List< ::capnp::schema::Superclass>::Reader value); + inline ::capnp::List< ::capnp::schema::Superclass>::Builder initSuperclasses(unsigned int size); + inline void adoptSuperclasses(::capnp::Orphan< ::capnp::List< ::capnp::schema::Superclass>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Superclass>> disownSuperclasses(); + +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 Node::Interface::Pipeline { +public: + typedef Interface 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 Node::Const::Reader { +public: + typedef Const 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 hasType() const; + inline ::capnp::schema::Type::Reader getType() const; + + inline bool hasValue() const; + inline ::capnp::schema::Value::Reader getValue() 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 Node::Const::Builder { +public: + typedef Const 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 hasType(); + inline ::capnp::schema::Type::Builder getType(); + inline void setType( ::capnp::schema::Type::Reader value); + inline ::capnp::schema::Type::Builder initType(); + inline void adoptType(::capnp::Orphan< ::capnp::schema::Type>&& value); + inline ::capnp::Orphan< ::capnp::schema::Type> disownType(); + + inline bool hasValue(); + inline ::capnp::schema::Value::Builder getValue(); + inline void setValue( ::capnp::schema::Value::Reader value); + inline ::capnp::schema::Value::Builder initValue(); + inline void adoptValue(::capnp::Orphan< ::capnp::schema::Value>&& value); + inline ::capnp::Orphan< ::capnp::schema::Value> disownValue(); + +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 Node::Const::Pipeline { +public: + typedef Const Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Type::Pipeline getType(); + inline ::capnp::schema::Value::Pipeline getValue(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template <typename, ::capnp::Kind> + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Node::Annotation::Reader { +public: + typedef Annotation 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 hasType() const; + inline ::capnp::schema::Type::Reader getType() const; + + inline bool getTargetsFile() const; + + inline bool getTargetsConst() const; + + inline bool getTargetsEnum() const; + + inline bool getTargetsEnumerant() const; + + inline bool getTargetsStruct() const; + + inline bool getTargetsField() const; + + inline bool getTargetsUnion() const; + + inline bool getTargetsGroup() const; + + inline bool getTargetsInterface() const; + + inline bool getTargetsMethod() const; + + inline bool getTargetsParam() const; + + inline bool getTargetsAnnotation() 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 Node::Annotation::Builder { +public: + typedef Annotation 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 hasType(); + inline ::capnp::schema::Type::Builder getType(); + inline void setType( ::capnp::schema::Type::Reader value); + inline ::capnp::schema::Type::Builder initType(); + inline void adoptType(::capnp::Orphan< ::capnp::schema::Type>&& value); + inline ::capnp::Orphan< ::capnp::schema::Type> disownType(); + + inline bool getTargetsFile(); + inline void setTargetsFile(bool value); + + inline bool getTargetsConst(); + inline void setTargetsConst(bool value); + + inline bool getTargetsEnum(); + inline void setTargetsEnum(bool value); + + inline bool getTargetsEnumerant(); + inline void setTargetsEnumerant(bool value); + + inline bool getTargetsStruct(); + inline void setTargetsStruct(bool value); + + inline bool getTargetsField(); + inline void setTargetsField(bool value); + + inline bool getTargetsUnion(); + inline void setTargetsUnion(bool value); + + inline bool getTargetsGroup(); + inline void setTargetsGroup(bool value); + + inline bool getTargetsInterface(); + inline void setTargetsInterface(bool value); + + inline bool getTargetsMethod(); + inline void setTargetsMethod(bool value); + + inline bool getTargetsParam(); + inline void setTargetsParam(bool value); + + inline bool getTargetsAnnotation(); + inline void setTargetsAnnotation(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 Node::Annotation::Pipeline { +public: + typedef Annotation Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Type::Pipeline getType(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template <typename, ::capnp::Kind> + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Field::Reader { +public: + typedef Field 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 hasName() const; + inline ::capnp::Text::Reader getName() const; + + inline ::uint16_t getCodeOrder() const; + + inline bool hasAnnotations() const; + inline ::capnp::List< ::capnp::schema::Annotation>::Reader getAnnotations() const; + + inline ::uint16_t getDiscriminantValue() const; + + inline bool isSlot() const; + inline typename Slot::Reader getSlot() const; + + inline bool isGroup() const; + inline typename Group::Reader getGroup() const; + + inline typename Ordinal::Reader getOrdinal() 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 Field::Builder { +public: + typedef Field 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 hasName(); + inline ::capnp::Text::Builder getName(); + inline void setName( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initName(unsigned int size); + inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownName(); + + inline ::uint16_t getCodeOrder(); + inline void setCodeOrder( ::uint16_t value); + + inline bool hasAnnotations(); + inline ::capnp::List< ::capnp::schema::Annotation>::Builder getAnnotations(); + inline void setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value); + inline ::capnp::List< ::capnp::schema::Annotation>::Builder initAnnotations(unsigned int size); + inline void adoptAnnotations(::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> disownAnnotations(); + + inline ::uint16_t getDiscriminantValue(); + inline void setDiscriminantValue( ::uint16_t value); + + inline bool isSlot(); + inline typename Slot::Builder getSlot(); + inline typename Slot::Builder initSlot(); + + inline bool isGroup(); + inline typename Group::Builder getGroup(); + inline typename Group::Builder initGroup(); + + inline typename Ordinal::Builder getOrdinal(); + inline typename Ordinal::Builder initOrdinal(); + +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 Field::Pipeline { +public: + typedef Field Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline typename Ordinal::Pipeline getOrdinal(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template <typename, ::capnp::Kind> + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Field::Slot::Reader { +public: + typedef Slot 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 getOffset() const; + + inline bool hasType() const; + inline ::capnp::schema::Type::Reader getType() const; + + inline bool hasDefaultValue() const; + inline ::capnp::schema::Value::Reader getDefaultValue() const; + + inline bool getHadExplicitDefault() 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 Field::Slot::Builder { +public: + typedef Slot 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 getOffset(); + inline void setOffset( ::uint32_t value); + + inline bool hasType(); + inline ::capnp::schema::Type::Builder getType(); + inline void setType( ::capnp::schema::Type::Reader value); + inline ::capnp::schema::Type::Builder initType(); + inline void adoptType(::capnp::Orphan< ::capnp::schema::Type>&& value); + inline ::capnp::Orphan< ::capnp::schema::Type> disownType(); + + inline bool hasDefaultValue(); + inline ::capnp::schema::Value::Builder getDefaultValue(); + inline void setDefaultValue( ::capnp::schema::Value::Reader value); + inline ::capnp::schema::Value::Builder initDefaultValue(); + inline void adoptDefaultValue(::capnp::Orphan< ::capnp::schema::Value>&& value); + inline ::capnp::Orphan< ::capnp::schema::Value> disownDefaultValue(); + + inline bool getHadExplicitDefault(); + inline void setHadExplicitDefault(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 Field::Slot::Pipeline { +public: + typedef Slot Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Type::Pipeline getType(); + inline ::capnp::schema::Value::Pipeline getDefaultValue(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template <typename, ::capnp::Kind> + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Field::Group::Reader { +public: + typedef Group 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 ::uint64_t getTypeId() 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 Field::Group::Builder { +public: + typedef Group 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 ::uint64_t getTypeId(); + inline void setTypeId( ::uint64_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 Field::Group::Pipeline { +public: + typedef Group 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 Field::Ordinal::Reader { +public: + typedef Ordinal 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 isImplicit() const; + inline ::capnp::Void getImplicit() const; + + inline bool isExplicit() const; + inline ::uint16_t getExplicit() 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 Field::Ordinal::Builder { +public: + typedef Ordinal 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 isImplicit(); + inline ::capnp::Void getImplicit(); + inline void setImplicit( ::capnp::Void value = ::capnp::VOID); + + inline bool isExplicit(); + inline ::uint16_t getExplicit(); + inline void setExplicit( ::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 Field::Ordinal::Pipeline { +public: + typedef Ordinal 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 Enumerant::Reader { +public: + typedef Enumerant 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 hasName() const; + inline ::capnp::Text::Reader getName() const; + + inline ::uint16_t getCodeOrder() const; + + inline bool hasAnnotations() const; + inline ::capnp::List< ::capnp::schema::Annotation>::Reader getAnnotations() 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 Enumerant::Builder { +public: + typedef Enumerant 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 hasName(); + inline ::capnp::Text::Builder getName(); + inline void setName( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initName(unsigned int size); + inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownName(); + + inline ::uint16_t getCodeOrder(); + inline void setCodeOrder( ::uint16_t value); + + inline bool hasAnnotations(); + inline ::capnp::List< ::capnp::schema::Annotation>::Builder getAnnotations(); + inline void setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value); + inline ::capnp::List< ::capnp::schema::Annotation>::Builder initAnnotations(unsigned int size); + inline void adoptAnnotations(::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> disownAnnotations(); + +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 Enumerant::Pipeline { +public: + typedef Enumerant 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 Superclass::Reader { +public: + typedef Superclass 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 ::uint64_t getId() const; + + inline bool hasBrand() const; + inline ::capnp::schema::Brand::Reader getBrand() 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 Superclass::Builder { +public: + typedef Superclass 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 ::uint64_t getId(); + inline void setId( ::uint64_t value); + + inline bool hasBrand(); + inline ::capnp::schema::Brand::Builder getBrand(); + inline void setBrand( ::capnp::schema::Brand::Reader value); + inline ::capnp::schema::Brand::Builder initBrand(); + inline void adoptBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); + inline ::capnp::Orphan< ::capnp::schema::Brand> disownBrand(); + +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 Superclass::Pipeline { +public: + typedef Superclass Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Brand::Pipeline getBrand(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template <typename, ::capnp::Kind> + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Method::Reader { +public: + typedef Method 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 hasName() const; + inline ::capnp::Text::Reader getName() const; + + inline ::uint16_t getCodeOrder() const; + + inline ::uint64_t getParamStructType() const; + + inline ::uint64_t getResultStructType() const; + + inline bool hasAnnotations() const; + inline ::capnp::List< ::capnp::schema::Annotation>::Reader getAnnotations() const; + + inline bool hasParamBrand() const; + inline ::capnp::schema::Brand::Reader getParamBrand() const; + + inline bool hasResultBrand() const; + inline ::capnp::schema::Brand::Reader getResultBrand() const; + + inline bool hasImplicitParameters() const; + inline ::capnp::List< ::capnp::schema::Node::Parameter>::Reader getImplicitParameters() 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 Method::Builder { +public: + typedef Method 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 hasName(); + inline ::capnp::Text::Builder getName(); + inline void setName( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initName(unsigned int size); + inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownName(); + + inline ::uint16_t getCodeOrder(); + inline void setCodeOrder( ::uint16_t value); + + inline ::uint64_t getParamStructType(); + inline void setParamStructType( ::uint64_t value); + + inline ::uint64_t getResultStructType(); + inline void setResultStructType( ::uint64_t value); + + inline bool hasAnnotations(); + inline ::capnp::List< ::capnp::schema::Annotation>::Builder getAnnotations(); + inline void setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value); + inline ::capnp::List< ::capnp::schema::Annotation>::Builder initAnnotations(unsigned int size); + inline void adoptAnnotations(::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> disownAnnotations(); + + inline bool hasParamBrand(); + inline ::capnp::schema::Brand::Builder getParamBrand(); + inline void setParamBrand( ::capnp::schema::Brand::Reader value); + inline ::capnp::schema::Brand::Builder initParamBrand(); + inline void adoptParamBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); + inline ::capnp::Orphan< ::capnp::schema::Brand> disownParamBrand(); + + inline bool hasResultBrand(); + inline ::capnp::schema::Brand::Builder getResultBrand(); + inline void setResultBrand( ::capnp::schema::Brand::Reader value); + inline ::capnp::schema::Brand::Builder initResultBrand(); + inline void adoptResultBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); + inline ::capnp::Orphan< ::capnp::schema::Brand> disownResultBrand(); + + inline bool hasImplicitParameters(); + inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder getImplicitParameters(); + inline void setImplicitParameters( ::capnp::List< ::capnp::schema::Node::Parameter>::Reader value); + inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder initImplicitParameters(unsigned int size); + inline void adoptImplicitParameters(::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>> disownImplicitParameters(); + +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 Method::Pipeline { +public: + typedef Method Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Brand::Pipeline getParamBrand(); + inline ::capnp::schema::Brand::Pipeline getResultBrand(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template <typename, ::capnp::Kind> + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Type::Reader { +public: + typedef Type 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 isVoid() const; + inline ::capnp::Void getVoid() const; + + inline bool isBool() const; + inline ::capnp::Void getBool() const; + + inline bool isInt8() const; + inline ::capnp::Void getInt8() const; + + inline bool isInt16() const; + inline ::capnp::Void getInt16() const; + + inline bool isInt32() const; + inline ::capnp::Void getInt32() const; + + inline bool isInt64() const; + inline ::capnp::Void getInt64() const; + + inline bool isUint8() const; + inline ::capnp::Void getUint8() const; + + inline bool isUint16() const; + inline ::capnp::Void getUint16() const; + + inline bool isUint32() const; + inline ::capnp::Void getUint32() const; + + inline bool isUint64() const; + inline ::capnp::Void getUint64() const; + + inline bool isFloat32() const; + inline ::capnp::Void getFloat32() const; + + inline bool isFloat64() const; + inline ::capnp::Void getFloat64() const; + + inline bool isText() const; + inline ::capnp::Void getText() const; + + inline bool isData() const; + inline ::capnp::Void getData() const; + + inline bool isList() const; + inline typename List::Reader getList() const; + + inline bool isEnum() const; + inline typename Enum::Reader getEnum() const; + + inline bool isStruct() const; + inline typename Struct::Reader getStruct() const; + + inline bool isInterface() const; + inline typename Interface::Reader getInterface() const; + + inline bool isAnyPointer() const; + inline typename AnyPointer::Reader getAnyPointer() 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 Type::Builder { +public: + typedef Type 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 isVoid(); + inline ::capnp::Void getVoid(); + inline void setVoid( ::capnp::Void value = ::capnp::VOID); + + inline bool isBool(); + inline ::capnp::Void getBool(); + inline void setBool( ::capnp::Void value = ::capnp::VOID); + + inline bool isInt8(); + inline ::capnp::Void getInt8(); + inline void setInt8( ::capnp::Void value = ::capnp::VOID); + + inline bool isInt16(); + inline ::capnp::Void getInt16(); + inline void setInt16( ::capnp::Void value = ::capnp::VOID); + + inline bool isInt32(); + inline ::capnp::Void getInt32(); + inline void setInt32( ::capnp::Void value = ::capnp::VOID); + + inline bool isInt64(); + inline ::capnp::Void getInt64(); + inline void setInt64( ::capnp::Void value = ::capnp::VOID); + + inline bool isUint8(); + inline ::capnp::Void getUint8(); + inline void setUint8( ::capnp::Void value = ::capnp::VOID); + + inline bool isUint16(); + inline ::capnp::Void getUint16(); + inline void setUint16( ::capnp::Void value = ::capnp::VOID); + + inline bool isUint32(); + inline ::capnp::Void getUint32(); + inline void setUint32( ::capnp::Void value = ::capnp::VOID); + + inline bool isUint64(); + inline ::capnp::Void getUint64(); + inline void setUint64( ::capnp::Void value = ::capnp::VOID); + + inline bool isFloat32(); + inline ::capnp::Void getFloat32(); + inline void setFloat32( ::capnp::Void value = ::capnp::VOID); + + inline bool isFloat64(); + inline ::capnp::Void getFloat64(); + inline void setFloat64( ::capnp::Void value = ::capnp::VOID); + + inline bool isText(); + inline ::capnp::Void getText(); + inline void setText( ::capnp::Void value = ::capnp::VOID); + + inline bool isData(); + inline ::capnp::Void getData(); + inline void setData( ::capnp::Void value = ::capnp::VOID); + + inline bool isList(); + inline typename List::Builder getList(); + inline typename List::Builder initList(); + + inline bool isEnum(); + inline typename Enum::Builder getEnum(); + inline typename Enum::Builder initEnum(); + + inline bool isStruct(); + inline typename Struct::Builder getStruct(); + inline typename Struct::Builder initStruct(); + + inline bool isInterface(); + inline typename Interface::Builder getInterface(); + inline typename Interface::Builder initInterface(); + + inline bool isAnyPointer(); + inline typename AnyPointer::Builder getAnyPointer(); + inline typename AnyPointer::Builder initAnyPointer(); + +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 Type::Pipeline { +public: + typedef Type 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 Type::List::Reader { +public: + typedef List 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 hasElementType() const; + inline ::capnp::schema::Type::Reader getElementType() 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 Type::List::Builder { +public: + typedef List 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 hasElementType(); + inline ::capnp::schema::Type::Builder getElementType(); + inline void setElementType( ::capnp::schema::Type::Reader value); + inline ::capnp::schema::Type::Builder initElementType(); + inline void adoptElementType(::capnp::Orphan< ::capnp::schema::Type>&& value); + inline ::capnp::Orphan< ::capnp::schema::Type> disownElementType(); + +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 Type::List::Pipeline { +public: + typedef List Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Type::Pipeline getElementType(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template <typename, ::capnp::Kind> + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Type::Enum::Reader { +public: + typedef Enum 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 ::uint64_t getTypeId() const; + + inline bool hasBrand() const; + inline ::capnp::schema::Brand::Reader getBrand() 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 Type::Enum::Builder { +public: + typedef Enum 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 ::uint64_t getTypeId(); + inline void setTypeId( ::uint64_t value); + + inline bool hasBrand(); + inline ::capnp::schema::Brand::Builder getBrand(); + inline void setBrand( ::capnp::schema::Brand::Reader value); + inline ::capnp::schema::Brand::Builder initBrand(); + inline void adoptBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); + inline ::capnp::Orphan< ::capnp::schema::Brand> disownBrand(); + +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 Type::Enum::Pipeline { +public: + typedef Enum Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Brand::Pipeline getBrand(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template <typename, ::capnp::Kind> + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Type::Struct::Reader { +public: + typedef Struct 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 ::uint64_t getTypeId() const; + + inline bool hasBrand() const; + inline ::capnp::schema::Brand::Reader getBrand() 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 Type::Struct::Builder { +public: + typedef Struct 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 ::uint64_t getTypeId(); + inline void setTypeId( ::uint64_t value); + + inline bool hasBrand(); + inline ::capnp::schema::Brand::Builder getBrand(); + inline void setBrand( ::capnp::schema::Brand::Reader value); + inline ::capnp::schema::Brand::Builder initBrand(); + inline void adoptBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); + inline ::capnp::Orphan< ::capnp::schema::Brand> disownBrand(); + +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 Type::Struct::Pipeline { +public: + typedef Struct Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Brand::Pipeline getBrand(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template <typename, ::capnp::Kind> + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Type::Interface::Reader { +public: + typedef Interface 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 ::uint64_t getTypeId() const; + + inline bool hasBrand() const; + inline ::capnp::schema::Brand::Reader getBrand() 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 Type::Interface::Builder { +public: + typedef Interface 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 ::uint64_t getTypeId(); + inline void setTypeId( ::uint64_t value); + + inline bool hasBrand(); + inline ::capnp::schema::Brand::Builder getBrand(); + inline void setBrand( ::capnp::schema::Brand::Reader value); + inline ::capnp::schema::Brand::Builder initBrand(); + inline void adoptBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); + inline ::capnp::Orphan< ::capnp::schema::Brand> disownBrand(); + +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 Type::Interface::Pipeline { +public: + typedef Interface Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Brand::Pipeline getBrand(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template <typename, ::capnp::Kind> + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Type::AnyPointer::Reader { +public: + typedef AnyPointer 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 isUnconstrained() const; + inline typename Unconstrained::Reader getUnconstrained() const; + + inline bool isParameter() const; + inline typename Parameter::Reader getParameter() const; + + inline bool isImplicitMethodParameter() const; + inline typename ImplicitMethodParameter::Reader getImplicitMethodParameter() 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 Type::AnyPointer::Builder { +public: + typedef AnyPointer 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 isUnconstrained(); + inline typename Unconstrained::Builder getUnconstrained(); + inline typename Unconstrained::Builder initUnconstrained(); + + inline bool isParameter(); + inline typename Parameter::Builder getParameter(); + inline typename Parameter::Builder initParameter(); + + inline bool isImplicitMethodParameter(); + inline typename ImplicitMethodParameter::Builder getImplicitMethodParameter(); + inline typename ImplicitMethodParameter::Builder initImplicitMethodParameter(); + +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 Type::AnyPointer::Pipeline { +public: + typedef AnyPointer 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 Type::AnyPointer::Unconstrained::Reader { +public: + typedef Unconstrained 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 isAnyKind() const; + inline ::capnp::Void getAnyKind() const; + + inline bool isStruct() const; + inline ::capnp::Void getStruct() const; + + inline bool isList() const; + inline ::capnp::Void getList() const; + + inline bool isCapability() const; + inline ::capnp::Void getCapability() 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 Type::AnyPointer::Unconstrained::Builder { +public: + typedef Unconstrained 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 isAnyKind(); + inline ::capnp::Void getAnyKind(); + inline void setAnyKind( ::capnp::Void value = ::capnp::VOID); + + inline bool isStruct(); + inline ::capnp::Void getStruct(); + inline void setStruct( ::capnp::Void value = ::capnp::VOID); + + inline bool isList(); + inline ::capnp::Void getList(); + inline void setList( ::capnp::Void value = ::capnp::VOID); + + inline bool isCapability(); + inline ::capnp::Void getCapability(); + inline void setCapability( ::capnp::Void value = ::capnp::VOID); + +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 Type::AnyPointer::Unconstrained::Pipeline { +public: + typedef Unconstrained 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 Type::AnyPointer::Parameter::Reader { +public: + typedef Parameter 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 ::uint64_t getScopeId() const; + + inline ::uint16_t getParameterIndex() 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 Type::AnyPointer::Parameter::Builder { +public: + typedef Parameter 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 ::uint64_t getScopeId(); + inline void setScopeId( ::uint64_t value); + + inline ::uint16_t getParameterIndex(); + inline void setParameterIndex( ::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 Type::AnyPointer::Parameter::Pipeline { +public: + typedef Parameter 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 Type::AnyPointer::ImplicitMethodParameter::Reader { +public: + typedef ImplicitMethodParameter 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 ::uint16_t getParameterIndex() 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 Type::AnyPointer::ImplicitMethodParameter::Builder { +public: + typedef ImplicitMethodParameter 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 ::uint16_t getParameterIndex(); + inline void setParameterIndex( ::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 Type::AnyPointer::ImplicitMethodParameter::Pipeline { +public: + typedef ImplicitMethodParameter 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 Brand::Reader { +public: + typedef Brand 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 hasScopes() const; + inline ::capnp::List< ::capnp::schema::Brand::Scope>::Reader getScopes() 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 Brand::Builder { +public: + typedef Brand 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 hasScopes(); + inline ::capnp::List< ::capnp::schema::Brand::Scope>::Builder getScopes(); + inline void setScopes( ::capnp::List< ::capnp::schema::Brand::Scope>::Reader value); + inline ::capnp::List< ::capnp::schema::Brand::Scope>::Builder initScopes(unsigned int size); + inline void adoptScopes(::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Scope>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Scope>> disownScopes(); + +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 Brand::Pipeline { +public: + typedef Brand 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 Brand::Scope::Reader { +public: + typedef Scope 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 ::uint64_t getScopeId() const; + + inline bool isBind() const; + inline bool hasBind() const; + inline ::capnp::List< ::capnp::schema::Brand::Binding>::Reader getBind() const; + + inline bool isInherit() const; + inline ::capnp::Void getInherit() 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 Brand::Scope::Builder { +public: + typedef Scope 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 ::uint64_t getScopeId(); + inline void setScopeId( ::uint64_t value); + + inline bool isBind(); + inline bool hasBind(); + inline ::capnp::List< ::capnp::schema::Brand::Binding>::Builder getBind(); + inline void setBind( ::capnp::List< ::capnp::schema::Brand::Binding>::Reader value); + inline ::capnp::List< ::capnp::schema::Brand::Binding>::Builder initBind(unsigned int size); + inline void adoptBind(::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Binding>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Binding>> disownBind(); + + inline bool isInherit(); + inline ::capnp::Void getInherit(); + inline void setInherit( ::capnp::Void value = ::capnp::VOID); + +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 Brand::Scope::Pipeline { +public: + typedef Scope 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 Brand::Binding::Reader { +public: + typedef Binding 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 isUnbound() const; + inline ::capnp::Void getUnbound() const; + + inline bool isType() const; + inline bool hasType() const; + inline ::capnp::schema::Type::Reader getType() 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 Brand::Binding::Builder { +public: + typedef Binding 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 isUnbound(); + inline ::capnp::Void getUnbound(); + inline void setUnbound( ::capnp::Void value = ::capnp::VOID); + + inline bool isType(); + inline bool hasType(); + inline ::capnp::schema::Type::Builder getType(); + inline void setType( ::capnp::schema::Type::Reader value); + inline ::capnp::schema::Type::Builder initType(); + inline void adoptType(::capnp::Orphan< ::capnp::schema::Type>&& value); + inline ::capnp::Orphan< ::capnp::schema::Type> disownType(); + +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 Brand::Binding::Pipeline { +public: + typedef Binding 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 Value::Reader { +public: + typedef Value 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 isVoid() const; + inline ::capnp::Void getVoid() const; + + inline bool isBool() const; + inline bool getBool() const; + + inline bool isInt8() const; + inline ::int8_t getInt8() const; + + inline bool isInt16() const; + inline ::int16_t getInt16() const; + + inline bool isInt32() const; + inline ::int32_t getInt32() const; + + inline bool isInt64() const; + inline ::int64_t getInt64() const; + + inline bool isUint8() const; + inline ::uint8_t getUint8() const; + + inline bool isUint16() const; + inline ::uint16_t getUint16() const; + + inline bool isUint32() const; + inline ::uint32_t getUint32() const; + + inline bool isUint64() const; + inline ::uint64_t getUint64() const; + + inline bool isFloat32() const; + inline float getFloat32() const; + + inline bool isFloat64() const; + inline double getFloat64() const; + + inline bool isText() const; + inline bool hasText() const; + inline ::capnp::Text::Reader getText() const; + + inline bool isData() const; + inline bool hasData() const; + inline ::capnp::Data::Reader getData() const; + + inline bool isList() const; + inline bool hasList() const; + inline ::capnp::AnyPointer::Reader getList() const; + + inline bool isEnum() const; + inline ::uint16_t getEnum() const; + + inline bool isStruct() const; + inline bool hasStruct() const; + inline ::capnp::AnyPointer::Reader getStruct() const; + + inline bool isInterface() const; + inline ::capnp::Void getInterface() const; + + inline bool isAnyPointer() const; + inline bool hasAnyPointer() const; + inline ::capnp::AnyPointer::Reader getAnyPointer() 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 Value::Builder { +public: + typedef Value 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 isVoid(); + inline ::capnp::Void getVoid(); + inline void setVoid( ::capnp::Void value = ::capnp::VOID); + + inline bool isBool(); + inline bool getBool(); + inline void setBool(bool value); + + inline bool isInt8(); + inline ::int8_t getInt8(); + inline void setInt8( ::int8_t value); + + inline bool isInt16(); + inline ::int16_t getInt16(); + inline void setInt16( ::int16_t value); + + inline bool isInt32(); + inline ::int32_t getInt32(); + inline void setInt32( ::int32_t value); + + inline bool isInt64(); + inline ::int64_t getInt64(); + inline void setInt64( ::int64_t value); + + inline bool isUint8(); + inline ::uint8_t getUint8(); + inline void setUint8( ::uint8_t value); + + inline bool isUint16(); + inline ::uint16_t getUint16(); + inline void setUint16( ::uint16_t value); + + inline bool isUint32(); + inline ::uint32_t getUint32(); + inline void setUint32( ::uint32_t value); + + inline bool isUint64(); + inline ::uint64_t getUint64(); + inline void setUint64( ::uint64_t value); + + inline bool isFloat32(); + inline float getFloat32(); + inline void setFloat32(float value); + + inline bool isFloat64(); + inline double getFloat64(); + inline void setFloat64(double value); + + inline bool isText(); + inline bool hasText(); + inline ::capnp::Text::Builder getText(); + inline void setText( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initText(unsigned int size); + inline void adoptText(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownText(); + + inline bool isData(); + inline bool hasData(); + inline ::capnp::Data::Builder getData(); + inline void setData( ::capnp::Data::Reader value); + inline ::capnp::Data::Builder initData(unsigned int size); + inline void adoptData(::capnp::Orphan< ::capnp::Data>&& value); + inline ::capnp::Orphan< ::capnp::Data> disownData(); + + inline bool isList(); + inline bool hasList(); + inline ::capnp::AnyPointer::Builder getList(); + inline ::capnp::AnyPointer::Builder initList(); + + inline bool isEnum(); + inline ::uint16_t getEnum(); + inline void setEnum( ::uint16_t value); + + inline bool isStruct(); + inline bool hasStruct(); + inline ::capnp::AnyPointer::Builder getStruct(); + inline ::capnp::AnyPointer::Builder initStruct(); + + inline bool isInterface(); + inline ::capnp::Void getInterface(); + inline void setInterface( ::capnp::Void value = ::capnp::VOID); + + inline bool isAnyPointer(); + inline bool hasAnyPointer(); + inline ::capnp::AnyPointer::Builder getAnyPointer(); + inline ::capnp::AnyPointer::Builder initAnyPointer(); + +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 Value::Pipeline { +public: + typedef Value 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 Annotation::Reader { +public: + typedef Annotation 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 ::uint64_t getId() const; + + inline bool hasValue() const; + inline ::capnp::schema::Value::Reader getValue() const; + + inline bool hasBrand() const; + inline ::capnp::schema::Brand::Reader getBrand() 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 Annotation::Builder { +public: + typedef Annotation 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 ::uint64_t getId(); + inline void setId( ::uint64_t value); + + inline bool hasValue(); + inline ::capnp::schema::Value::Builder getValue(); + inline void setValue( ::capnp::schema::Value::Reader value); + inline ::capnp::schema::Value::Builder initValue(); + inline void adoptValue(::capnp::Orphan< ::capnp::schema::Value>&& value); + inline ::capnp::Orphan< ::capnp::schema::Value> disownValue(); + + inline bool hasBrand(); + inline ::capnp::schema::Brand::Builder getBrand(); + inline void setBrand( ::capnp::schema::Brand::Reader value); + inline ::capnp::schema::Brand::Builder initBrand(); + inline void adoptBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); + inline ::capnp::Orphan< ::capnp::schema::Brand> disownBrand(); + +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 Annotation::Pipeline { +public: + typedef Annotation Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Value::Pipeline getValue(); + inline ::capnp::schema::Brand::Pipeline getBrand(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template <typename, ::capnp::Kind> + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class CodeGeneratorRequest::Reader { +public: + typedef CodeGeneratorRequest 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 hasNodes() const; + inline ::capnp::List< ::capnp::schema::Node>::Reader getNodes() const; + + inline bool hasRequestedFiles() const; + inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Reader getRequestedFiles() 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 CodeGeneratorRequest::Builder { +public: + typedef CodeGeneratorRequest 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 hasNodes(); + inline ::capnp::List< ::capnp::schema::Node>::Builder getNodes(); + inline void setNodes( ::capnp::List< ::capnp::schema::Node>::Reader value); + inline ::capnp::List< ::capnp::schema::Node>::Builder initNodes(unsigned int size); + inline void adoptNodes(::capnp::Orphan< ::capnp::List< ::capnp::schema::Node>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node>> disownNodes(); + + inline bool hasRequestedFiles(); + inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Builder getRequestedFiles(); + inline void setRequestedFiles( ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Reader value); + inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Builder initRequestedFiles(unsigned int size); + inline void adoptRequestedFiles(::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>> disownRequestedFiles(); + +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 CodeGeneratorRequest::Pipeline { +public: + typedef CodeGeneratorRequest 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 CodeGeneratorRequest::RequestedFile::Reader { +public: + typedef RequestedFile 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 ::uint64_t getId() const; + + inline bool hasFilename() const; + inline ::capnp::Text::Reader getFilename() const; + + inline bool hasImports() const; + inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Reader getImports() 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 CodeGeneratorRequest::RequestedFile::Builder { +public: + typedef RequestedFile 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 ::uint64_t getId(); + inline void setId( ::uint64_t value); + + inline bool hasFilename(); + inline ::capnp::Text::Builder getFilename(); + inline void setFilename( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initFilename(unsigned int size); + inline void adoptFilename(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownFilename(); + + inline bool hasImports(); + inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Builder getImports(); + inline void setImports( ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Reader value); + inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Builder initImports(unsigned int size); + inline void adoptImports(::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>> disownImports(); + +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 CodeGeneratorRequest::RequestedFile::Pipeline { +public: + typedef RequestedFile 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 CodeGeneratorRequest::RequestedFile::Import::Reader { +public: + typedef Import 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 ::uint64_t getId() const; + + inline bool hasName() const; + inline ::capnp::Text::Reader getName() 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 CodeGeneratorRequest::RequestedFile::Import::Builder { +public: + typedef Import 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 ::uint64_t getId(); + inline void setId( ::uint64_t value); + + inline bool hasName(); + inline ::capnp::Text::Builder getName(); + inline void setName( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initName(unsigned int size); + inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownName(); + +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 CodeGeneratorRequest::RequestedFile::Import::Pipeline { +public: + typedef Import 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::schema::Node::Which Node::Reader::which() const { + return _reader.getDataField<Which>(6 * ::capnp::ELEMENTS); +} +inline ::capnp::schema::Node::Which Node::Builder::which() { + return _builder.getDataField<Which>(6 * ::capnp::ELEMENTS); +} + +inline ::uint64_t Node::Reader::getId() const { + return _reader.getDataField< ::uint64_t>( + 0 * ::capnp::ELEMENTS); +} + +inline ::uint64_t Node::Builder::getId() { + return _builder.getDataField< ::uint64_t>( + 0 * ::capnp::ELEMENTS); +} +inline void Node::Builder::setId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Node::Reader::hasDisplayName() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool Node::Builder::hasDisplayName() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Node::Reader::getDisplayName() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Node::Builder::getDisplayName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Node::Builder::setDisplayName( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Node::Builder::initDisplayName(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init( + _builder.getPointerField(0 * ::capnp::POINTERS), size); +} +inline void Node::Builder::adoptDisplayName( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Node::Builder::disownDisplayName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} + +inline ::uint32_t Node::Reader::getDisplayNamePrefixLength() const { + return _reader.getDataField< ::uint32_t>( + 2 * ::capnp::ELEMENTS); +} + +inline ::uint32_t Node::Builder::getDisplayNamePrefixLength() { + return _builder.getDataField< ::uint32_t>( + 2 * ::capnp::ELEMENTS); +} +inline void Node::Builder::setDisplayNamePrefixLength( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + 2 * ::capnp::ELEMENTS, value); +} + +inline ::uint64_t Node::Reader::getScopeId() const { + return _reader.getDataField< ::uint64_t>( + 2 * ::capnp::ELEMENTS); +} + +inline ::uint64_t Node::Builder::getScopeId() { + return _builder.getDataField< ::uint64_t>( + 2 * ::capnp::ELEMENTS); +} +inline void Node::Builder::setScopeId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + 2 * ::capnp::ELEMENTS, value); +} + +inline bool Node::Reader::hasNestedNodes() const { + return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull(); +} +inline bool Node::Builder::hasNestedNodes() { + return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Node::NestedNode>::Reader Node::Reader::getNestedNodes() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode>>::get( + _reader.getPointerField(1 * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Node::NestedNode>::Builder Node::Builder::getNestedNodes() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode>>::get( + _builder.getPointerField(1 * ::capnp::POINTERS)); +} +inline void Node::Builder::setNestedNodes( ::capnp::List< ::capnp::schema::Node::NestedNode>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode>>::set( + _builder.getPointerField(1 * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Node::NestedNode>::Builder Node::Builder::initNestedNodes(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode>>::init( + _builder.getPointerField(1 * ::capnp::POINTERS), size); +} +inline void Node::Builder::adoptNestedNodes( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::NestedNode>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode>>::adopt( + _builder.getPointerField(1 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::NestedNode>> Node::Builder::disownNestedNodes() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode>>::disown( + _builder.getPointerField(1 * ::capnp::POINTERS)); +} + +inline bool Node::Reader::hasAnnotations() const { + return !_reader.getPointerField(2 * ::capnp::POINTERS).isNull(); +} +inline bool Node::Builder::hasAnnotations() { + return !_builder.getPointerField(2 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Annotation>::Reader Node::Reader::getAnnotations() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get( + _reader.getPointerField(2 * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Annotation>::Builder Node::Builder::getAnnotations() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get( + _builder.getPointerField(2 * ::capnp::POINTERS)); +} +inline void Node::Builder::setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::set( + _builder.getPointerField(2 * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Annotation>::Builder Node::Builder::initAnnotations(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::init( + _builder.getPointerField(2 * ::capnp::POINTERS), size); +} +inline void Node::Builder::adoptAnnotations( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::adopt( + _builder.getPointerField(2 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> Node::Builder::disownAnnotations() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::disown( + _builder.getPointerField(2 * ::capnp::POINTERS)); +} + +inline bool Node::Reader::isFile() const { + return which() == Node::FILE; +} +inline bool Node::Builder::isFile() { + return which() == Node::FILE; +} +inline ::capnp::Void Node::Reader::getFile() const { + KJ_IREQUIRE((which() == Node::FILE), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Node::Builder::getFile() { + KJ_IREQUIRE((which() == Node::FILE), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} +inline void Node::Builder::setFile( ::capnp::Void value) { + _builder.setDataField<Node::Which>( + 6 * ::capnp::ELEMENTS, Node::FILE); + _builder.setDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Node::Reader::isStruct() const { + return which() == Node::STRUCT; +} +inline bool Node::Builder::isStruct() { + return which() == Node::STRUCT; +} +inline typename Node::Struct::Reader Node::Reader::getStruct() const { + KJ_IREQUIRE((which() == Node::STRUCT), + "Must check which() before get()ing a union member."); + return typename Node::Struct::Reader(_reader); +} +inline typename Node::Struct::Builder Node::Builder::getStruct() { + KJ_IREQUIRE((which() == Node::STRUCT), + "Must check which() before get()ing a union member."); + return typename Node::Struct::Builder(_builder); +} +inline typename Node::Struct::Builder Node::Builder::initStruct() { + _builder.setDataField<Node::Which>( + 6 * ::capnp::ELEMENTS, Node::STRUCT); + _builder.setDataField< ::uint16_t>(7 * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint16_t>(12 * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint16_t>(13 * ::capnp::ELEMENTS, 0); + _builder.setDataField<bool>(224 * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint16_t>(15 * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint32_t>(8 * ::capnp::ELEMENTS, 0); + _builder.getPointerField(3 * ::capnp::POINTERS).clear(); + return typename Node::Struct::Builder(_builder); +} +inline bool Node::Reader::isEnum() const { + return which() == Node::ENUM; +} +inline bool Node::Builder::isEnum() { + return which() == Node::ENUM; +} +inline typename Node::Enum::Reader Node::Reader::getEnum() const { + KJ_IREQUIRE((which() == Node::ENUM), + "Must check which() before get()ing a union member."); + return typename Node::Enum::Reader(_reader); +} +inline typename Node::Enum::Builder Node::Builder::getEnum() { + KJ_IREQUIRE((which() == Node::ENUM), + "Must check which() before get()ing a union member."); + return typename Node::Enum::Builder(_builder); +} +inline typename Node::Enum::Builder Node::Builder::initEnum() { + _builder.setDataField<Node::Which>( + 6 * ::capnp::ELEMENTS, Node::ENUM); + _builder.getPointerField(3 * ::capnp::POINTERS).clear(); + return typename Node::Enum::Builder(_builder); +} +inline bool Node::Reader::isInterface() const { + return which() == Node::INTERFACE; +} +inline bool Node::Builder::isInterface() { + return which() == Node::INTERFACE; +} +inline typename Node::Interface::Reader Node::Reader::getInterface() const { + KJ_IREQUIRE((which() == Node::INTERFACE), + "Must check which() before get()ing a union member."); + return typename Node::Interface::Reader(_reader); +} +inline typename Node::Interface::Builder Node::Builder::getInterface() { + KJ_IREQUIRE((which() == Node::INTERFACE), + "Must check which() before get()ing a union member."); + return typename Node::Interface::Builder(_builder); +} +inline typename Node::Interface::Builder Node::Builder::initInterface() { + _builder.setDataField<Node::Which>( + 6 * ::capnp::ELEMENTS, Node::INTERFACE); + _builder.getPointerField(3 * ::capnp::POINTERS).clear(); + _builder.getPointerField(4 * ::capnp::POINTERS).clear(); + return typename Node::Interface::Builder(_builder); +} +inline bool Node::Reader::isConst() const { + return which() == Node::CONST; +} +inline bool Node::Builder::isConst() { + return which() == Node::CONST; +} +inline typename Node::Const::Reader Node::Reader::getConst() const { + KJ_IREQUIRE((which() == Node::CONST), + "Must check which() before get()ing a union member."); + return typename Node::Const::Reader(_reader); +} +inline typename Node::Const::Builder Node::Builder::getConst() { + KJ_IREQUIRE((which() == Node::CONST), + "Must check which() before get()ing a union member."); + return typename Node::Const::Builder(_builder); +} +inline typename Node::Const::Builder Node::Builder::initConst() { + _builder.setDataField<Node::Which>( + 6 * ::capnp::ELEMENTS, Node::CONST); + _builder.getPointerField(3 * ::capnp::POINTERS).clear(); + _builder.getPointerField(4 * ::capnp::POINTERS).clear(); + return typename Node::Const::Builder(_builder); +} +inline bool Node::Reader::isAnnotation() const { + return which() == Node::ANNOTATION; +} +inline bool Node::Builder::isAnnotation() { + return which() == Node::ANNOTATION; +} +inline typename Node::Annotation::Reader Node::Reader::getAnnotation() const { + KJ_IREQUIRE((which() == Node::ANNOTATION), + "Must check which() before get()ing a union member."); + return typename Node::Annotation::Reader(_reader); +} +inline typename Node::Annotation::Builder Node::Builder::getAnnotation() { + KJ_IREQUIRE((which() == Node::ANNOTATION), + "Must check which() before get()ing a union member."); + return typename Node::Annotation::Builder(_builder); +} +inline typename Node::Annotation::Builder Node::Builder::initAnnotation() { + _builder.setDataField<Node::Which>( + 6 * ::capnp::ELEMENTS, Node::ANNOTATION); + _builder.setDataField<bool>(112 * ::capnp::ELEMENTS, 0); + _builder.setDataField<bool>(113 * ::capnp::ELEMENTS, 0); + _builder.setDataField<bool>(114 * ::capnp::ELEMENTS, 0); + _builder.setDataField<bool>(115 * ::capnp::ELEMENTS, 0); + _builder.setDataField<bool>(116 * ::capnp::ELEMENTS, 0); + _builder.setDataField<bool>(117 * ::capnp::ELEMENTS, 0); + _builder.setDataField<bool>(118 * ::capnp::ELEMENTS, 0); + _builder.setDataField<bool>(119 * ::capnp::ELEMENTS, 0); + _builder.setDataField<bool>(120 * ::capnp::ELEMENTS, 0); + _builder.setDataField<bool>(121 * ::capnp::ELEMENTS, 0); + _builder.setDataField<bool>(122 * ::capnp::ELEMENTS, 0); + _builder.setDataField<bool>(123 * ::capnp::ELEMENTS, 0); + _builder.getPointerField(3 * ::capnp::POINTERS).clear(); + return typename Node::Annotation::Builder(_builder); +} +inline bool Node::Reader::hasParameters() const { + return !_reader.getPointerField(5 * ::capnp::POINTERS).isNull(); +} +inline bool Node::Builder::hasParameters() { + return !_builder.getPointerField(5 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Node::Parameter>::Reader Node::Reader::getParameters() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::get( + _reader.getPointerField(5 * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder Node::Builder::getParameters() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::get( + _builder.getPointerField(5 * ::capnp::POINTERS)); +} +inline void Node::Builder::setParameters( ::capnp::List< ::capnp::schema::Node::Parameter>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::set( + _builder.getPointerField(5 * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder Node::Builder::initParameters(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::init( + _builder.getPointerField(5 * ::capnp::POINTERS), size); +} +inline void Node::Builder::adoptParameters( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::adopt( + _builder.getPointerField(5 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>> Node::Builder::disownParameters() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::disown( + _builder.getPointerField(5 * ::capnp::POINTERS)); +} + +inline bool Node::Reader::getIsGeneric() const { + return _reader.getDataField<bool>( + 288 * ::capnp::ELEMENTS); +} + +inline bool Node::Builder::getIsGeneric() { + return _builder.getDataField<bool>( + 288 * ::capnp::ELEMENTS); +} +inline void Node::Builder::setIsGeneric(bool value) { + _builder.setDataField<bool>( + 288 * ::capnp::ELEMENTS, value); +} + +inline bool Node::Parameter::Reader::hasName() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool Node::Parameter::Builder::hasName() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Node::Parameter::Reader::getName() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Node::Parameter::Builder::getName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Node::Parameter::Builder::setName( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Node::Parameter::Builder::initName(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init( + _builder.getPointerField(0 * ::capnp::POINTERS), size); +} +inline void Node::Parameter::Builder::adoptName( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Node::Parameter::Builder::disownName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} + +inline bool Node::NestedNode::Reader::hasName() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool Node::NestedNode::Builder::hasName() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Node::NestedNode::Reader::getName() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Node::NestedNode::Builder::getName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Node::NestedNode::Builder::setName( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Node::NestedNode::Builder::initName(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init( + _builder.getPointerField(0 * ::capnp::POINTERS), size); +} +inline void Node::NestedNode::Builder::adoptName( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Node::NestedNode::Builder::disownName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} + +inline ::uint64_t Node::NestedNode::Reader::getId() const { + return _reader.getDataField< ::uint64_t>( + 0 * ::capnp::ELEMENTS); +} + +inline ::uint64_t Node::NestedNode::Builder::getId() { + return _builder.getDataField< ::uint64_t>( + 0 * ::capnp::ELEMENTS); +} +inline void Node::NestedNode::Builder::setId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + 0 * ::capnp::ELEMENTS, value); +} + +inline ::uint16_t Node::Struct::Reader::getDataWordCount() const { + return _reader.getDataField< ::uint16_t>( + 7 * ::capnp::ELEMENTS); +} + +inline ::uint16_t Node::Struct::Builder::getDataWordCount() { + return _builder.getDataField< ::uint16_t>( + 7 * ::capnp::ELEMENTS); +} +inline void Node::Struct::Builder::setDataWordCount( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + 7 * ::capnp::ELEMENTS, value); +} + +inline ::uint16_t Node::Struct::Reader::getPointerCount() const { + return _reader.getDataField< ::uint16_t>( + 12 * ::capnp::ELEMENTS); +} + +inline ::uint16_t Node::Struct::Builder::getPointerCount() { + return _builder.getDataField< ::uint16_t>( + 12 * ::capnp::ELEMENTS); +} +inline void Node::Struct::Builder::setPointerCount( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + 12 * ::capnp::ELEMENTS, value); +} + +inline ::capnp::schema::ElementSize Node::Struct::Reader::getPreferredListEncoding() const { + return _reader.getDataField< ::capnp::schema::ElementSize>( + 13 * ::capnp::ELEMENTS); +} + +inline ::capnp::schema::ElementSize Node::Struct::Builder::getPreferredListEncoding() { + return _builder.getDataField< ::capnp::schema::ElementSize>( + 13 * ::capnp::ELEMENTS); +} +inline void Node::Struct::Builder::setPreferredListEncoding( ::capnp::schema::ElementSize value) { + _builder.setDataField< ::capnp::schema::ElementSize>( + 13 * ::capnp::ELEMENTS, value); +} + +inline bool Node::Struct::Reader::getIsGroup() const { + return _reader.getDataField<bool>( + 224 * ::capnp::ELEMENTS); +} + +inline bool Node::Struct::Builder::getIsGroup() { + return _builder.getDataField<bool>( + 224 * ::capnp::ELEMENTS); +} +inline void Node::Struct::Builder::setIsGroup(bool value) { + _builder.setDataField<bool>( + 224 * ::capnp::ELEMENTS, value); +} + +inline ::uint16_t Node::Struct::Reader::getDiscriminantCount() const { + return _reader.getDataField< ::uint16_t>( + 15 * ::capnp::ELEMENTS); +} + +inline ::uint16_t Node::Struct::Builder::getDiscriminantCount() { + return _builder.getDataField< ::uint16_t>( + 15 * ::capnp::ELEMENTS); +} +inline void Node::Struct::Builder::setDiscriminantCount( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + 15 * ::capnp::ELEMENTS, value); +} + +inline ::uint32_t Node::Struct::Reader::getDiscriminantOffset() const { + return _reader.getDataField< ::uint32_t>( + 8 * ::capnp::ELEMENTS); +} + +inline ::uint32_t Node::Struct::Builder::getDiscriminantOffset() { + return _builder.getDataField< ::uint32_t>( + 8 * ::capnp::ELEMENTS); +} +inline void Node::Struct::Builder::setDiscriminantOffset( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + 8 * ::capnp::ELEMENTS, value); +} + +inline bool Node::Struct::Reader::hasFields() const { + return !_reader.getPointerField(3 * ::capnp::POINTERS).isNull(); +} +inline bool Node::Struct::Builder::hasFields() { + return !_builder.getPointerField(3 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Field>::Reader Node::Struct::Reader::getFields() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field>>::get( + _reader.getPointerField(3 * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Field>::Builder Node::Struct::Builder::getFields() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field>>::get( + _builder.getPointerField(3 * ::capnp::POINTERS)); +} +inline void Node::Struct::Builder::setFields( ::capnp::List< ::capnp::schema::Field>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field>>::set( + _builder.getPointerField(3 * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Field>::Builder Node::Struct::Builder::initFields(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field>>::init( + _builder.getPointerField(3 * ::capnp::POINTERS), size); +} +inline void Node::Struct::Builder::adoptFields( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Field>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field>>::adopt( + _builder.getPointerField(3 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Field>> Node::Struct::Builder::disownFields() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field>>::disown( + _builder.getPointerField(3 * ::capnp::POINTERS)); +} + +inline bool Node::Enum::Reader::hasEnumerants() const { + return !_reader.getPointerField(3 * ::capnp::POINTERS).isNull(); +} +inline bool Node::Enum::Builder::hasEnumerants() { + return !_builder.getPointerField(3 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Enumerant>::Reader Node::Enum::Reader::getEnumerants() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant>>::get( + _reader.getPointerField(3 * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Enumerant>::Builder Node::Enum::Builder::getEnumerants() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant>>::get( + _builder.getPointerField(3 * ::capnp::POINTERS)); +} +inline void Node::Enum::Builder::setEnumerants( ::capnp::List< ::capnp::schema::Enumerant>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant>>::set( + _builder.getPointerField(3 * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Enumerant>::Builder Node::Enum::Builder::initEnumerants(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant>>::init( + _builder.getPointerField(3 * ::capnp::POINTERS), size); +} +inline void Node::Enum::Builder::adoptEnumerants( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Enumerant>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant>>::adopt( + _builder.getPointerField(3 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Enumerant>> Node::Enum::Builder::disownEnumerants() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant>>::disown( + _builder.getPointerField(3 * ::capnp::POINTERS)); +} + +inline bool Node::Interface::Reader::hasMethods() const { + return !_reader.getPointerField(3 * ::capnp::POINTERS).isNull(); +} +inline bool Node::Interface::Builder::hasMethods() { + return !_builder.getPointerField(3 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Method>::Reader Node::Interface::Reader::getMethods() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method>>::get( + _reader.getPointerField(3 * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Method>::Builder Node::Interface::Builder::getMethods() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method>>::get( + _builder.getPointerField(3 * ::capnp::POINTERS)); +} +inline void Node::Interface::Builder::setMethods( ::capnp::List< ::capnp::schema::Method>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method>>::set( + _builder.getPointerField(3 * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Method>::Builder Node::Interface::Builder::initMethods(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method>>::init( + _builder.getPointerField(3 * ::capnp::POINTERS), size); +} +inline void Node::Interface::Builder::adoptMethods( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Method>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method>>::adopt( + _builder.getPointerField(3 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Method>> Node::Interface::Builder::disownMethods() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method>>::disown( + _builder.getPointerField(3 * ::capnp::POINTERS)); +} + +inline bool Node::Interface::Reader::hasSuperclasses() const { + return !_reader.getPointerField(4 * ::capnp::POINTERS).isNull(); +} +inline bool Node::Interface::Builder::hasSuperclasses() { + return !_builder.getPointerField(4 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Superclass>::Reader Node::Interface::Reader::getSuperclasses() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass>>::get( + _reader.getPointerField(4 * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Superclass>::Builder Node::Interface::Builder::getSuperclasses() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass>>::get( + _builder.getPointerField(4 * ::capnp::POINTERS)); +} +inline void Node::Interface::Builder::setSuperclasses( ::capnp::List< ::capnp::schema::Superclass>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass>>::set( + _builder.getPointerField(4 * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Superclass>::Builder Node::Interface::Builder::initSuperclasses(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass>>::init( + _builder.getPointerField(4 * ::capnp::POINTERS), size); +} +inline void Node::Interface::Builder::adoptSuperclasses( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Superclass>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass>>::adopt( + _builder.getPointerField(4 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Superclass>> Node::Interface::Builder::disownSuperclasses() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass>>::disown( + _builder.getPointerField(4 * ::capnp::POINTERS)); +} + +inline bool Node::Const::Reader::hasType() const { + return !_reader.getPointerField(3 * ::capnp::POINTERS).isNull(); +} +inline bool Node::Const::Builder::hasType() { + return !_builder.getPointerField(3 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Type::Reader Node::Const::Reader::getType() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get( + _reader.getPointerField(3 * ::capnp::POINTERS)); +} +inline ::capnp::schema::Type::Builder Node::Const::Builder::getType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get( + _builder.getPointerField(3 * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Type::Pipeline Node::Const::Pipeline::getType() { + return ::capnp::schema::Type::Pipeline(_typeless.getPointerField(3)); +} +#endif // !CAPNP_LITE +inline void Node::Const::Builder::setType( ::capnp::schema::Type::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::set( + _builder.getPointerField(3 * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Type::Builder Node::Const::Builder::initType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::init( + _builder.getPointerField(3 * ::capnp::POINTERS)); +} +inline void Node::Const::Builder::adoptType( + ::capnp::Orphan< ::capnp::schema::Type>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::adopt( + _builder.getPointerField(3 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Type> Node::Const::Builder::disownType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::disown( + _builder.getPointerField(3 * ::capnp::POINTERS)); +} + +inline bool Node::Const::Reader::hasValue() const { + return !_reader.getPointerField(4 * ::capnp::POINTERS).isNull(); +} +inline bool Node::Const::Builder::hasValue() { + return !_builder.getPointerField(4 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Value::Reader Node::Const::Reader::getValue() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get( + _reader.getPointerField(4 * ::capnp::POINTERS)); +} +inline ::capnp::schema::Value::Builder Node::Const::Builder::getValue() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get( + _builder.getPointerField(4 * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Value::Pipeline Node::Const::Pipeline::getValue() { + return ::capnp::schema::Value::Pipeline(_typeless.getPointerField(4)); +} +#endif // !CAPNP_LITE +inline void Node::Const::Builder::setValue( ::capnp::schema::Value::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Value>::set( + _builder.getPointerField(4 * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Value::Builder Node::Const::Builder::initValue() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::init( + _builder.getPointerField(4 * ::capnp::POINTERS)); +} +inline void Node::Const::Builder::adoptValue( + ::capnp::Orphan< ::capnp::schema::Value>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Value>::adopt( + _builder.getPointerField(4 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Value> Node::Const::Builder::disownValue() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::disown( + _builder.getPointerField(4 * ::capnp::POINTERS)); +} + +inline bool Node::Annotation::Reader::hasType() const { + return !_reader.getPointerField(3 * ::capnp::POINTERS).isNull(); +} +inline bool Node::Annotation::Builder::hasType() { + return !_builder.getPointerField(3 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Type::Reader Node::Annotation::Reader::getType() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get( + _reader.getPointerField(3 * ::capnp::POINTERS)); +} +inline ::capnp::schema::Type::Builder Node::Annotation::Builder::getType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get( + _builder.getPointerField(3 * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Type::Pipeline Node::Annotation::Pipeline::getType() { + return ::capnp::schema::Type::Pipeline(_typeless.getPointerField(3)); +} +#endif // !CAPNP_LITE +inline void Node::Annotation::Builder::setType( ::capnp::schema::Type::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::set( + _builder.getPointerField(3 * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Type::Builder Node::Annotation::Builder::initType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::init( + _builder.getPointerField(3 * ::capnp::POINTERS)); +} +inline void Node::Annotation::Builder::adoptType( + ::capnp::Orphan< ::capnp::schema::Type>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::adopt( + _builder.getPointerField(3 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Type> Node::Annotation::Builder::disownType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::disown( + _builder.getPointerField(3 * ::capnp::POINTERS)); +} + +inline bool Node::Annotation::Reader::getTargetsFile() const { + return _reader.getDataField<bool>( + 112 * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsFile() { + return _builder.getDataField<bool>( + 112 * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsFile(bool value) { + _builder.setDataField<bool>( + 112 * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsConst() const { + return _reader.getDataField<bool>( + 113 * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsConst() { + return _builder.getDataField<bool>( + 113 * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsConst(bool value) { + _builder.setDataField<bool>( + 113 * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsEnum() const { + return _reader.getDataField<bool>( + 114 * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsEnum() { + return _builder.getDataField<bool>( + 114 * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsEnum(bool value) { + _builder.setDataField<bool>( + 114 * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsEnumerant() const { + return _reader.getDataField<bool>( + 115 * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsEnumerant() { + return _builder.getDataField<bool>( + 115 * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsEnumerant(bool value) { + _builder.setDataField<bool>( + 115 * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsStruct() const { + return _reader.getDataField<bool>( + 116 * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsStruct() { + return _builder.getDataField<bool>( + 116 * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsStruct(bool value) { + _builder.setDataField<bool>( + 116 * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsField() const { + return _reader.getDataField<bool>( + 117 * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsField() { + return _builder.getDataField<bool>( + 117 * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsField(bool value) { + _builder.setDataField<bool>( + 117 * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsUnion() const { + return _reader.getDataField<bool>( + 118 * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsUnion() { + return _builder.getDataField<bool>( + 118 * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsUnion(bool value) { + _builder.setDataField<bool>( + 118 * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsGroup() const { + return _reader.getDataField<bool>( + 119 * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsGroup() { + return _builder.getDataField<bool>( + 119 * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsGroup(bool value) { + _builder.setDataField<bool>( + 119 * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsInterface() const { + return _reader.getDataField<bool>( + 120 * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsInterface() { + return _builder.getDataField<bool>( + 120 * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsInterface(bool value) { + _builder.setDataField<bool>( + 120 * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsMethod() const { + return _reader.getDataField<bool>( + 121 * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsMethod() { + return _builder.getDataField<bool>( + 121 * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsMethod(bool value) { + _builder.setDataField<bool>( + 121 * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsParam() const { + return _reader.getDataField<bool>( + 122 * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsParam() { + return _builder.getDataField<bool>( + 122 * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsParam(bool value) { + _builder.setDataField<bool>( + 122 * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsAnnotation() const { + return _reader.getDataField<bool>( + 123 * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsAnnotation() { + return _builder.getDataField<bool>( + 123 * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsAnnotation(bool value) { + _builder.setDataField<bool>( + 123 * ::capnp::ELEMENTS, value); +} + +inline ::capnp::schema::Field::Which Field::Reader::which() const { + return _reader.getDataField<Which>(4 * ::capnp::ELEMENTS); +} +inline ::capnp::schema::Field::Which Field::Builder::which() { + return _builder.getDataField<Which>(4 * ::capnp::ELEMENTS); +} + +inline bool Field::Reader::hasName() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool Field::Builder::hasName() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Field::Reader::getName() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Field::Builder::getName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Field::Builder::setName( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Field::Builder::initName(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init( + _builder.getPointerField(0 * ::capnp::POINTERS), size); +} +inline void Field::Builder::adoptName( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Field::Builder::disownName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} + +inline ::uint16_t Field::Reader::getCodeOrder() const { + return _reader.getDataField< ::uint16_t>( + 0 * ::capnp::ELEMENTS); +} + +inline ::uint16_t Field::Builder::getCodeOrder() { + return _builder.getDataField< ::uint16_t>( + 0 * ::capnp::ELEMENTS); +} +inline void Field::Builder::setCodeOrder( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Field::Reader::hasAnnotations() const { + return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull(); +} +inline bool Field::Builder::hasAnnotations() { + return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Annotation>::Reader Field::Reader::getAnnotations() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get( + _reader.getPointerField(1 * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Annotation>::Builder Field::Builder::getAnnotations() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get( + _builder.getPointerField(1 * ::capnp::POINTERS)); +} +inline void Field::Builder::setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::set( + _builder.getPointerField(1 * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Annotation>::Builder Field::Builder::initAnnotations(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::init( + _builder.getPointerField(1 * ::capnp::POINTERS), size); +} +inline void Field::Builder::adoptAnnotations( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::adopt( + _builder.getPointerField(1 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> Field::Builder::disownAnnotations() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::disown( + _builder.getPointerField(1 * ::capnp::POINTERS)); +} + +inline ::uint16_t Field::Reader::getDiscriminantValue() const { + return _reader.getDataField< ::uint16_t>( + 1 * ::capnp::ELEMENTS, 65535u); +} + +inline ::uint16_t Field::Builder::getDiscriminantValue() { + return _builder.getDataField< ::uint16_t>( + 1 * ::capnp::ELEMENTS, 65535u); +} +inline void Field::Builder::setDiscriminantValue( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + 1 * ::capnp::ELEMENTS, value, 65535u); +} + +inline bool Field::Reader::isSlot() const { + return which() == Field::SLOT; +} +inline bool Field::Builder::isSlot() { + return which() == Field::SLOT; +} +inline typename Field::Slot::Reader Field::Reader::getSlot() const { + KJ_IREQUIRE((which() == Field::SLOT), + "Must check which() before get()ing a union member."); + return typename Field::Slot::Reader(_reader); +} +inline typename Field::Slot::Builder Field::Builder::getSlot() { + KJ_IREQUIRE((which() == Field::SLOT), + "Must check which() before get()ing a union member."); + return typename Field::Slot::Builder(_builder); +} +inline typename Field::Slot::Builder Field::Builder::initSlot() { + _builder.setDataField<Field::Which>( + 4 * ::capnp::ELEMENTS, Field::SLOT); + _builder.setDataField< ::uint32_t>(1 * ::capnp::ELEMENTS, 0); + _builder.setDataField<bool>(128 * ::capnp::ELEMENTS, 0); + _builder.getPointerField(2 * ::capnp::POINTERS).clear(); + _builder.getPointerField(3 * ::capnp::POINTERS).clear(); + return typename Field::Slot::Builder(_builder); +} +inline bool Field::Reader::isGroup() const { + return which() == Field::GROUP; +} +inline bool Field::Builder::isGroup() { + return which() == Field::GROUP; +} +inline typename Field::Group::Reader Field::Reader::getGroup() const { + KJ_IREQUIRE((which() == Field::GROUP), + "Must check which() before get()ing a union member."); + return typename Field::Group::Reader(_reader); +} +inline typename Field::Group::Builder Field::Builder::getGroup() { + KJ_IREQUIRE((which() == Field::GROUP), + "Must check which() before get()ing a union member."); + return typename Field::Group::Builder(_builder); +} +inline typename Field::Group::Builder Field::Builder::initGroup() { + _builder.setDataField<Field::Which>( + 4 * ::capnp::ELEMENTS, Field::GROUP); + _builder.setDataField< ::uint64_t>(2 * ::capnp::ELEMENTS, 0); + return typename Field::Group::Builder(_builder); +} +inline typename Field::Ordinal::Reader Field::Reader::getOrdinal() const { + return typename Field::Ordinal::Reader(_reader); +} +inline typename Field::Ordinal::Builder Field::Builder::getOrdinal() { + return typename Field::Ordinal::Builder(_builder); +} +#if !CAPNP_LITE +inline typename Field::Ordinal::Pipeline Field::Pipeline::getOrdinal() { + return typename Field::Ordinal::Pipeline(_typeless.noop()); +} +#endif // !CAPNP_LITE +inline typename Field::Ordinal::Builder Field::Builder::initOrdinal() { + _builder.setDataField< ::uint16_t>(5 * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint16_t>(6 * ::capnp::ELEMENTS, 0); + return typename Field::Ordinal::Builder(_builder); +} +inline ::uint32_t Field::Slot::Reader::getOffset() const { + return _reader.getDataField< ::uint32_t>( + 1 * ::capnp::ELEMENTS); +} + +inline ::uint32_t Field::Slot::Builder::getOffset() { + return _builder.getDataField< ::uint32_t>( + 1 * ::capnp::ELEMENTS); +} +inline void Field::Slot::Builder::setOffset( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + 1 * ::capnp::ELEMENTS, value); +} + +inline bool Field::Slot::Reader::hasType() const { + return !_reader.getPointerField(2 * ::capnp::POINTERS).isNull(); +} +inline bool Field::Slot::Builder::hasType() { + return !_builder.getPointerField(2 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Type::Reader Field::Slot::Reader::getType() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get( + _reader.getPointerField(2 * ::capnp::POINTERS)); +} +inline ::capnp::schema::Type::Builder Field::Slot::Builder::getType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get( + _builder.getPointerField(2 * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Type::Pipeline Field::Slot::Pipeline::getType() { + return ::capnp::schema::Type::Pipeline(_typeless.getPointerField(2)); +} +#endif // !CAPNP_LITE +inline void Field::Slot::Builder::setType( ::capnp::schema::Type::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::set( + _builder.getPointerField(2 * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Type::Builder Field::Slot::Builder::initType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::init( + _builder.getPointerField(2 * ::capnp::POINTERS)); +} +inline void Field::Slot::Builder::adoptType( + ::capnp::Orphan< ::capnp::schema::Type>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::adopt( + _builder.getPointerField(2 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Type> Field::Slot::Builder::disownType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::disown( + _builder.getPointerField(2 * ::capnp::POINTERS)); +} + +inline bool Field::Slot::Reader::hasDefaultValue() const { + return !_reader.getPointerField(3 * ::capnp::POINTERS).isNull(); +} +inline bool Field::Slot::Builder::hasDefaultValue() { + return !_builder.getPointerField(3 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Value::Reader Field::Slot::Reader::getDefaultValue() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get( + _reader.getPointerField(3 * ::capnp::POINTERS)); +} +inline ::capnp::schema::Value::Builder Field::Slot::Builder::getDefaultValue() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get( + _builder.getPointerField(3 * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Value::Pipeline Field::Slot::Pipeline::getDefaultValue() { + return ::capnp::schema::Value::Pipeline(_typeless.getPointerField(3)); +} +#endif // !CAPNP_LITE +inline void Field::Slot::Builder::setDefaultValue( ::capnp::schema::Value::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Value>::set( + _builder.getPointerField(3 * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Value::Builder Field::Slot::Builder::initDefaultValue() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::init( + _builder.getPointerField(3 * ::capnp::POINTERS)); +} +inline void Field::Slot::Builder::adoptDefaultValue( + ::capnp::Orphan< ::capnp::schema::Value>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Value>::adopt( + _builder.getPointerField(3 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Value> Field::Slot::Builder::disownDefaultValue() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::disown( + _builder.getPointerField(3 * ::capnp::POINTERS)); +} + +inline bool Field::Slot::Reader::getHadExplicitDefault() const { + return _reader.getDataField<bool>( + 128 * ::capnp::ELEMENTS); +} + +inline bool Field::Slot::Builder::getHadExplicitDefault() { + return _builder.getDataField<bool>( + 128 * ::capnp::ELEMENTS); +} +inline void Field::Slot::Builder::setHadExplicitDefault(bool value) { + _builder.setDataField<bool>( + 128 * ::capnp::ELEMENTS, value); +} + +inline ::uint64_t Field::Group::Reader::getTypeId() const { + return _reader.getDataField< ::uint64_t>( + 2 * ::capnp::ELEMENTS); +} + +inline ::uint64_t Field::Group::Builder::getTypeId() { + return _builder.getDataField< ::uint64_t>( + 2 * ::capnp::ELEMENTS); +} +inline void Field::Group::Builder::setTypeId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + 2 * ::capnp::ELEMENTS, value); +} + +inline ::capnp::schema::Field::Ordinal::Which Field::Ordinal::Reader::which() const { + return _reader.getDataField<Which>(5 * ::capnp::ELEMENTS); +} +inline ::capnp::schema::Field::Ordinal::Which Field::Ordinal::Builder::which() { + return _builder.getDataField<Which>(5 * ::capnp::ELEMENTS); +} + +inline bool Field::Ordinal::Reader::isImplicit() const { + return which() == Field::Ordinal::IMPLICIT; +} +inline bool Field::Ordinal::Builder::isImplicit() { + return which() == Field::Ordinal::IMPLICIT; +} +inline ::capnp::Void Field::Ordinal::Reader::getImplicit() const { + KJ_IREQUIRE((which() == Field::Ordinal::IMPLICIT), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Field::Ordinal::Builder::getImplicit() { + KJ_IREQUIRE((which() == Field::Ordinal::IMPLICIT), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} +inline void Field::Ordinal::Builder::setImplicit( ::capnp::Void value) { + _builder.setDataField<Field::Ordinal::Which>( + 5 * ::capnp::ELEMENTS, Field::Ordinal::IMPLICIT); + _builder.setDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Field::Ordinal::Reader::isExplicit() const { + return which() == Field::Ordinal::EXPLICIT; +} +inline bool Field::Ordinal::Builder::isExplicit() { + return which() == Field::Ordinal::EXPLICIT; +} +inline ::uint16_t Field::Ordinal::Reader::getExplicit() const { + KJ_IREQUIRE((which() == Field::Ordinal::EXPLICIT), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::uint16_t>( + 6 * ::capnp::ELEMENTS); +} + +inline ::uint16_t Field::Ordinal::Builder::getExplicit() { + KJ_IREQUIRE((which() == Field::Ordinal::EXPLICIT), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::uint16_t>( + 6 * ::capnp::ELEMENTS); +} +inline void Field::Ordinal::Builder::setExplicit( ::uint16_t value) { + _builder.setDataField<Field::Ordinal::Which>( + 5 * ::capnp::ELEMENTS, Field::Ordinal::EXPLICIT); + _builder.setDataField< ::uint16_t>( + 6 * ::capnp::ELEMENTS, value); +} + +inline bool Enumerant::Reader::hasName() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool Enumerant::Builder::hasName() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Enumerant::Reader::getName() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Enumerant::Builder::getName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Enumerant::Builder::setName( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Enumerant::Builder::initName(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init( + _builder.getPointerField(0 * ::capnp::POINTERS), size); +} +inline void Enumerant::Builder::adoptName( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Enumerant::Builder::disownName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} + +inline ::uint16_t Enumerant::Reader::getCodeOrder() const { + return _reader.getDataField< ::uint16_t>( + 0 * ::capnp::ELEMENTS); +} + +inline ::uint16_t Enumerant::Builder::getCodeOrder() { + return _builder.getDataField< ::uint16_t>( + 0 * ::capnp::ELEMENTS); +} +inline void Enumerant::Builder::setCodeOrder( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Enumerant::Reader::hasAnnotations() const { + return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull(); +} +inline bool Enumerant::Builder::hasAnnotations() { + return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Annotation>::Reader Enumerant::Reader::getAnnotations() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get( + _reader.getPointerField(1 * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Annotation>::Builder Enumerant::Builder::getAnnotations() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get( + _builder.getPointerField(1 * ::capnp::POINTERS)); +} +inline void Enumerant::Builder::setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::set( + _builder.getPointerField(1 * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Annotation>::Builder Enumerant::Builder::initAnnotations(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::init( + _builder.getPointerField(1 * ::capnp::POINTERS), size); +} +inline void Enumerant::Builder::adoptAnnotations( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::adopt( + _builder.getPointerField(1 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> Enumerant::Builder::disownAnnotations() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::disown( + _builder.getPointerField(1 * ::capnp::POINTERS)); +} + +inline ::uint64_t Superclass::Reader::getId() const { + return _reader.getDataField< ::uint64_t>( + 0 * ::capnp::ELEMENTS); +} + +inline ::uint64_t Superclass::Builder::getId() { + return _builder.getDataField< ::uint64_t>( + 0 * ::capnp::ELEMENTS); +} +inline void Superclass::Builder::setId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Superclass::Reader::hasBrand() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool Superclass::Builder::hasBrand() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Brand::Reader Superclass::Reader::getBrand() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::schema::Brand::Builder Superclass::Builder::getBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Brand::Pipeline Superclass::Pipeline::getBrand() { + return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Superclass::Builder::setBrand( ::capnp::schema::Brand::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Brand::Builder Superclass::Builder::initBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Superclass::Builder::adoptBrand( + ::capnp::Orphan< ::capnp::schema::Brand>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Brand> Superclass::Builder::disownBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} + +inline bool Method::Reader::hasName() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool Method::Builder::hasName() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Method::Reader::getName() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Method::Builder::getName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Method::Builder::setName( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Method::Builder::initName(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init( + _builder.getPointerField(0 * ::capnp::POINTERS), size); +} +inline void Method::Builder::adoptName( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Method::Builder::disownName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} + +inline ::uint16_t Method::Reader::getCodeOrder() const { + return _reader.getDataField< ::uint16_t>( + 0 * ::capnp::ELEMENTS); +} + +inline ::uint16_t Method::Builder::getCodeOrder() { + return _builder.getDataField< ::uint16_t>( + 0 * ::capnp::ELEMENTS); +} +inline void Method::Builder::setCodeOrder( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + 0 * ::capnp::ELEMENTS, value); +} + +inline ::uint64_t Method::Reader::getParamStructType() const { + return _reader.getDataField< ::uint64_t>( + 1 * ::capnp::ELEMENTS); +} + +inline ::uint64_t Method::Builder::getParamStructType() { + return _builder.getDataField< ::uint64_t>( + 1 * ::capnp::ELEMENTS); +} +inline void Method::Builder::setParamStructType( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + 1 * ::capnp::ELEMENTS, value); +} + +inline ::uint64_t Method::Reader::getResultStructType() const { + return _reader.getDataField< ::uint64_t>( + 2 * ::capnp::ELEMENTS); +} + +inline ::uint64_t Method::Builder::getResultStructType() { + return _builder.getDataField< ::uint64_t>( + 2 * ::capnp::ELEMENTS); +} +inline void Method::Builder::setResultStructType( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + 2 * ::capnp::ELEMENTS, value); +} + +inline bool Method::Reader::hasAnnotations() const { + return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull(); +} +inline bool Method::Builder::hasAnnotations() { + return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Annotation>::Reader Method::Reader::getAnnotations() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get( + _reader.getPointerField(1 * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Annotation>::Builder Method::Builder::getAnnotations() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get( + _builder.getPointerField(1 * ::capnp::POINTERS)); +} +inline void Method::Builder::setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::set( + _builder.getPointerField(1 * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Annotation>::Builder Method::Builder::initAnnotations(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::init( + _builder.getPointerField(1 * ::capnp::POINTERS), size); +} +inline void Method::Builder::adoptAnnotations( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::adopt( + _builder.getPointerField(1 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> Method::Builder::disownAnnotations() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::disown( + _builder.getPointerField(1 * ::capnp::POINTERS)); +} + +inline bool Method::Reader::hasParamBrand() const { + return !_reader.getPointerField(2 * ::capnp::POINTERS).isNull(); +} +inline bool Method::Builder::hasParamBrand() { + return !_builder.getPointerField(2 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Brand::Reader Method::Reader::getParamBrand() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get( + _reader.getPointerField(2 * ::capnp::POINTERS)); +} +inline ::capnp::schema::Brand::Builder Method::Builder::getParamBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get( + _builder.getPointerField(2 * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Brand::Pipeline Method::Pipeline::getParamBrand() { + return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(2)); +} +#endif // !CAPNP_LITE +inline void Method::Builder::setParamBrand( ::capnp::schema::Brand::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set( + _builder.getPointerField(2 * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Brand::Builder Method::Builder::initParamBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init( + _builder.getPointerField(2 * ::capnp::POINTERS)); +} +inline void Method::Builder::adoptParamBrand( + ::capnp::Orphan< ::capnp::schema::Brand>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt( + _builder.getPointerField(2 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Brand> Method::Builder::disownParamBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown( + _builder.getPointerField(2 * ::capnp::POINTERS)); +} + +inline bool Method::Reader::hasResultBrand() const { + return !_reader.getPointerField(3 * ::capnp::POINTERS).isNull(); +} +inline bool Method::Builder::hasResultBrand() { + return !_builder.getPointerField(3 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Brand::Reader Method::Reader::getResultBrand() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get( + _reader.getPointerField(3 * ::capnp::POINTERS)); +} +inline ::capnp::schema::Brand::Builder Method::Builder::getResultBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get( + _builder.getPointerField(3 * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Brand::Pipeline Method::Pipeline::getResultBrand() { + return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(3)); +} +#endif // !CAPNP_LITE +inline void Method::Builder::setResultBrand( ::capnp::schema::Brand::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set( + _builder.getPointerField(3 * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Brand::Builder Method::Builder::initResultBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init( + _builder.getPointerField(3 * ::capnp::POINTERS)); +} +inline void Method::Builder::adoptResultBrand( + ::capnp::Orphan< ::capnp::schema::Brand>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt( + _builder.getPointerField(3 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Brand> Method::Builder::disownResultBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown( + _builder.getPointerField(3 * ::capnp::POINTERS)); +} + +inline bool Method::Reader::hasImplicitParameters() const { + return !_reader.getPointerField(4 * ::capnp::POINTERS).isNull(); +} +inline bool Method::Builder::hasImplicitParameters() { + return !_builder.getPointerField(4 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Node::Parameter>::Reader Method::Reader::getImplicitParameters() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::get( + _reader.getPointerField(4 * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder Method::Builder::getImplicitParameters() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::get( + _builder.getPointerField(4 * ::capnp::POINTERS)); +} +inline void Method::Builder::setImplicitParameters( ::capnp::List< ::capnp::schema::Node::Parameter>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::set( + _builder.getPointerField(4 * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder Method::Builder::initImplicitParameters(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::init( + _builder.getPointerField(4 * ::capnp::POINTERS), size); +} +inline void Method::Builder::adoptImplicitParameters( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::adopt( + _builder.getPointerField(4 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>> Method::Builder::disownImplicitParameters() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::disown( + _builder.getPointerField(4 * ::capnp::POINTERS)); +} + +inline ::capnp::schema::Type::Which Type::Reader::which() const { + return _reader.getDataField<Which>(0 * ::capnp::ELEMENTS); +} +inline ::capnp::schema::Type::Which Type::Builder::which() { + return _builder.getDataField<Which>(0 * ::capnp::ELEMENTS); +} + +inline bool Type::Reader::isVoid() const { + return which() == Type::VOID; +} +inline bool Type::Builder::isVoid() { + return which() == Type::VOID; +} +inline ::capnp::Void Type::Reader::getVoid() const { + KJ_IREQUIRE((which() == Type::VOID), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getVoid() { + KJ_IREQUIRE((which() == Type::VOID), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} +inline void Type::Builder::setVoid( ::capnp::Void value) { + _builder.setDataField<Type::Which>( + 0 * ::capnp::ELEMENTS, Type::VOID); + _builder.setDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isBool() const { + return which() == Type::BOOL; +} +inline bool Type::Builder::isBool() { + return which() == Type::BOOL; +} +inline ::capnp::Void Type::Reader::getBool() const { + KJ_IREQUIRE((which() == Type::BOOL), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getBool() { + KJ_IREQUIRE((which() == Type::BOOL), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} +inline void Type::Builder::setBool( ::capnp::Void value) { + _builder.setDataField<Type::Which>( + 0 * ::capnp::ELEMENTS, Type::BOOL); + _builder.setDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isInt8() const { + return which() == Type::INT8; +} +inline bool Type::Builder::isInt8() { + return which() == Type::INT8; +} +inline ::capnp::Void Type::Reader::getInt8() const { + KJ_IREQUIRE((which() == Type::INT8), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getInt8() { + KJ_IREQUIRE((which() == Type::INT8), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} +inline void Type::Builder::setInt8( ::capnp::Void value) { + _builder.setDataField<Type::Which>( + 0 * ::capnp::ELEMENTS, Type::INT8); + _builder.setDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isInt16() const { + return which() == Type::INT16; +} +inline bool Type::Builder::isInt16() { + return which() == Type::INT16; +} +inline ::capnp::Void Type::Reader::getInt16() const { + KJ_IREQUIRE((which() == Type::INT16), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getInt16() { + KJ_IREQUIRE((which() == Type::INT16), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} +inline void Type::Builder::setInt16( ::capnp::Void value) { + _builder.setDataField<Type::Which>( + 0 * ::capnp::ELEMENTS, Type::INT16); + _builder.setDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isInt32() const { + return which() == Type::INT32; +} +inline bool Type::Builder::isInt32() { + return which() == Type::INT32; +} +inline ::capnp::Void Type::Reader::getInt32() const { + KJ_IREQUIRE((which() == Type::INT32), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getInt32() { + KJ_IREQUIRE((which() == Type::INT32), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} +inline void Type::Builder::setInt32( ::capnp::Void value) { + _builder.setDataField<Type::Which>( + 0 * ::capnp::ELEMENTS, Type::INT32); + _builder.setDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isInt64() const { + return which() == Type::INT64; +} +inline bool Type::Builder::isInt64() { + return which() == Type::INT64; +} +inline ::capnp::Void Type::Reader::getInt64() const { + KJ_IREQUIRE((which() == Type::INT64), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getInt64() { + KJ_IREQUIRE((which() == Type::INT64), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} +inline void Type::Builder::setInt64( ::capnp::Void value) { + _builder.setDataField<Type::Which>( + 0 * ::capnp::ELEMENTS, Type::INT64); + _builder.setDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isUint8() const { + return which() == Type::UINT8; +} +inline bool Type::Builder::isUint8() { + return which() == Type::UINT8; +} +inline ::capnp::Void Type::Reader::getUint8() const { + KJ_IREQUIRE((which() == Type::UINT8), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getUint8() { + KJ_IREQUIRE((which() == Type::UINT8), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} +inline void Type::Builder::setUint8( ::capnp::Void value) { + _builder.setDataField<Type::Which>( + 0 * ::capnp::ELEMENTS, Type::UINT8); + _builder.setDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isUint16() const { + return which() == Type::UINT16; +} +inline bool Type::Builder::isUint16() { + return which() == Type::UINT16; +} +inline ::capnp::Void Type::Reader::getUint16() const { + KJ_IREQUIRE((which() == Type::UINT16), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getUint16() { + KJ_IREQUIRE((which() == Type::UINT16), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} +inline void Type::Builder::setUint16( ::capnp::Void value) { + _builder.setDataField<Type::Which>( + 0 * ::capnp::ELEMENTS, Type::UINT16); + _builder.setDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isUint32() const { + return which() == Type::UINT32; +} +inline bool Type::Builder::isUint32() { + return which() == Type::UINT32; +} +inline ::capnp::Void Type::Reader::getUint32() const { + KJ_IREQUIRE((which() == Type::UINT32), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getUint32() { + KJ_IREQUIRE((which() == Type::UINT32), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} +inline void Type::Builder::setUint32( ::capnp::Void value) { + _builder.setDataField<Type::Which>( + 0 * ::capnp::ELEMENTS, Type::UINT32); + _builder.setDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isUint64() const { + return which() == Type::UINT64; +} +inline bool Type::Builder::isUint64() { + return which() == Type::UINT64; +} +inline ::capnp::Void Type::Reader::getUint64() const { + KJ_IREQUIRE((which() == Type::UINT64), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getUint64() { + KJ_IREQUIRE((which() == Type::UINT64), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} +inline void Type::Builder::setUint64( ::capnp::Void value) { + _builder.setDataField<Type::Which>( + 0 * ::capnp::ELEMENTS, Type::UINT64); + _builder.setDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isFloat32() const { + return which() == Type::FLOAT32; +} +inline bool Type::Builder::isFloat32() { + return which() == Type::FLOAT32; +} +inline ::capnp::Void Type::Reader::getFloat32() const { + KJ_IREQUIRE((which() == Type::FLOAT32), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getFloat32() { + KJ_IREQUIRE((which() == Type::FLOAT32), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} +inline void Type::Builder::setFloat32( ::capnp::Void value) { + _builder.setDataField<Type::Which>( + 0 * ::capnp::ELEMENTS, Type::FLOAT32); + _builder.setDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isFloat64() const { + return which() == Type::FLOAT64; +} +inline bool Type::Builder::isFloat64() { + return which() == Type::FLOAT64; +} +inline ::capnp::Void Type::Reader::getFloat64() const { + KJ_IREQUIRE((which() == Type::FLOAT64), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getFloat64() { + KJ_IREQUIRE((which() == Type::FLOAT64), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} +inline void Type::Builder::setFloat64( ::capnp::Void value) { + _builder.setDataField<Type::Which>( + 0 * ::capnp::ELEMENTS, Type::FLOAT64); + _builder.setDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isText() const { + return which() == Type::TEXT; +} +inline bool Type::Builder::isText() { + return which() == Type::TEXT; +} +inline ::capnp::Void Type::Reader::getText() const { + KJ_IREQUIRE((which() == Type::TEXT), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getText() { + KJ_IREQUIRE((which() == Type::TEXT), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} +inline void Type::Builder::setText( ::capnp::Void value) { + _builder.setDataField<Type::Which>( + 0 * ::capnp::ELEMENTS, Type::TEXT); + _builder.setDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isData() const { + return which() == Type::DATA; +} +inline bool Type::Builder::isData() { + return which() == Type::DATA; +} +inline ::capnp::Void Type::Reader::getData() const { + KJ_IREQUIRE((which() == Type::DATA), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getData() { + KJ_IREQUIRE((which() == Type::DATA), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} +inline void Type::Builder::setData( ::capnp::Void value) { + _builder.setDataField<Type::Which>( + 0 * ::capnp::ELEMENTS, Type::DATA); + _builder.setDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isList() const { + return which() == Type::LIST; +} +inline bool Type::Builder::isList() { + return which() == Type::LIST; +} +inline typename Type::List::Reader Type::Reader::getList() const { + KJ_IREQUIRE((which() == Type::LIST), + "Must check which() before get()ing a union member."); + return typename Type::List::Reader(_reader); +} +inline typename Type::List::Builder Type::Builder::getList() { + KJ_IREQUIRE((which() == Type::LIST), + "Must check which() before get()ing a union member."); + return typename Type::List::Builder(_builder); +} +inline typename Type::List::Builder Type::Builder::initList() { + _builder.setDataField<Type::Which>( + 0 * ::capnp::ELEMENTS, Type::LIST); + _builder.getPointerField(0 * ::capnp::POINTERS).clear(); + return typename Type::List::Builder(_builder); +} +inline bool Type::Reader::isEnum() const { + return which() == Type::ENUM; +} +inline bool Type::Builder::isEnum() { + return which() == Type::ENUM; +} +inline typename Type::Enum::Reader Type::Reader::getEnum() const { + KJ_IREQUIRE((which() == Type::ENUM), + "Must check which() before get()ing a union member."); + return typename Type::Enum::Reader(_reader); +} +inline typename Type::Enum::Builder Type::Builder::getEnum() { + KJ_IREQUIRE((which() == Type::ENUM), + "Must check which() before get()ing a union member."); + return typename Type::Enum::Builder(_builder); +} +inline typename Type::Enum::Builder Type::Builder::initEnum() { + _builder.setDataField<Type::Which>( + 0 * ::capnp::ELEMENTS, Type::ENUM); + _builder.setDataField< ::uint64_t>(1 * ::capnp::ELEMENTS, 0); + _builder.getPointerField(0 * ::capnp::POINTERS).clear(); + return typename Type::Enum::Builder(_builder); +} +inline bool Type::Reader::isStruct() const { + return which() == Type::STRUCT; +} +inline bool Type::Builder::isStruct() { + return which() == Type::STRUCT; +} +inline typename Type::Struct::Reader Type::Reader::getStruct() const { + KJ_IREQUIRE((which() == Type::STRUCT), + "Must check which() before get()ing a union member."); + return typename Type::Struct::Reader(_reader); +} +inline typename Type::Struct::Builder Type::Builder::getStruct() { + KJ_IREQUIRE((which() == Type::STRUCT), + "Must check which() before get()ing a union member."); + return typename Type::Struct::Builder(_builder); +} +inline typename Type::Struct::Builder Type::Builder::initStruct() { + _builder.setDataField<Type::Which>( + 0 * ::capnp::ELEMENTS, Type::STRUCT); + _builder.setDataField< ::uint64_t>(1 * ::capnp::ELEMENTS, 0); + _builder.getPointerField(0 * ::capnp::POINTERS).clear(); + return typename Type::Struct::Builder(_builder); +} +inline bool Type::Reader::isInterface() const { + return which() == Type::INTERFACE; +} +inline bool Type::Builder::isInterface() { + return which() == Type::INTERFACE; +} +inline typename Type::Interface::Reader Type::Reader::getInterface() const { + KJ_IREQUIRE((which() == Type::INTERFACE), + "Must check which() before get()ing a union member."); + return typename Type::Interface::Reader(_reader); +} +inline typename Type::Interface::Builder Type::Builder::getInterface() { + KJ_IREQUIRE((which() == Type::INTERFACE), + "Must check which() before get()ing a union member."); + return typename Type::Interface::Builder(_builder); +} +inline typename Type::Interface::Builder Type::Builder::initInterface() { + _builder.setDataField<Type::Which>( + 0 * ::capnp::ELEMENTS, Type::INTERFACE); + _builder.setDataField< ::uint64_t>(1 * ::capnp::ELEMENTS, 0); + _builder.getPointerField(0 * ::capnp::POINTERS).clear(); + return typename Type::Interface::Builder(_builder); +} +inline bool Type::Reader::isAnyPointer() const { + return which() == Type::ANY_POINTER; +} +inline bool Type::Builder::isAnyPointer() { + return which() == Type::ANY_POINTER; +} +inline typename Type::AnyPointer::Reader Type::Reader::getAnyPointer() const { + KJ_IREQUIRE((which() == Type::ANY_POINTER), + "Must check which() before get()ing a union member."); + return typename Type::AnyPointer::Reader(_reader); +} +inline typename Type::AnyPointer::Builder Type::Builder::getAnyPointer() { + KJ_IREQUIRE((which() == Type::ANY_POINTER), + "Must check which() before get()ing a union member."); + return typename Type::AnyPointer::Builder(_builder); +} +inline typename Type::AnyPointer::Builder Type::Builder::initAnyPointer() { + _builder.setDataField<Type::Which>( + 0 * ::capnp::ELEMENTS, Type::ANY_POINTER); + _builder.setDataField< ::uint16_t>(4 * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint16_t>(5 * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint64_t>(2 * ::capnp::ELEMENTS, 0); + return typename Type::AnyPointer::Builder(_builder); +} +inline bool Type::List::Reader::hasElementType() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool Type::List::Builder::hasElementType() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Type::Reader Type::List::Reader::getElementType() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::schema::Type::Builder Type::List::Builder::getElementType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Type::Pipeline Type::List::Pipeline::getElementType() { + return ::capnp::schema::Type::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Type::List::Builder::setElementType( ::capnp::schema::Type::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Type::Builder Type::List::Builder::initElementType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Type::List::Builder::adoptElementType( + ::capnp::Orphan< ::capnp::schema::Type>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Type> Type::List::Builder::disownElementType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} + +inline ::uint64_t Type::Enum::Reader::getTypeId() const { + return _reader.getDataField< ::uint64_t>( + 1 * ::capnp::ELEMENTS); +} + +inline ::uint64_t Type::Enum::Builder::getTypeId() { + return _builder.getDataField< ::uint64_t>( + 1 * ::capnp::ELEMENTS); +} +inline void Type::Enum::Builder::setTypeId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + 1 * ::capnp::ELEMENTS, value); +} + +inline bool Type::Enum::Reader::hasBrand() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool Type::Enum::Builder::hasBrand() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Brand::Reader Type::Enum::Reader::getBrand() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::schema::Brand::Builder Type::Enum::Builder::getBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Brand::Pipeline Type::Enum::Pipeline::getBrand() { + return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Type::Enum::Builder::setBrand( ::capnp::schema::Brand::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Brand::Builder Type::Enum::Builder::initBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Type::Enum::Builder::adoptBrand( + ::capnp::Orphan< ::capnp::schema::Brand>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Brand> Type::Enum::Builder::disownBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} + +inline ::uint64_t Type::Struct::Reader::getTypeId() const { + return _reader.getDataField< ::uint64_t>( + 1 * ::capnp::ELEMENTS); +} + +inline ::uint64_t Type::Struct::Builder::getTypeId() { + return _builder.getDataField< ::uint64_t>( + 1 * ::capnp::ELEMENTS); +} +inline void Type::Struct::Builder::setTypeId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + 1 * ::capnp::ELEMENTS, value); +} + +inline bool Type::Struct::Reader::hasBrand() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool Type::Struct::Builder::hasBrand() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Brand::Reader Type::Struct::Reader::getBrand() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::schema::Brand::Builder Type::Struct::Builder::getBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Brand::Pipeline Type::Struct::Pipeline::getBrand() { + return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Type::Struct::Builder::setBrand( ::capnp::schema::Brand::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Brand::Builder Type::Struct::Builder::initBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Type::Struct::Builder::adoptBrand( + ::capnp::Orphan< ::capnp::schema::Brand>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Brand> Type::Struct::Builder::disownBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} + +inline ::uint64_t Type::Interface::Reader::getTypeId() const { + return _reader.getDataField< ::uint64_t>( + 1 * ::capnp::ELEMENTS); +} + +inline ::uint64_t Type::Interface::Builder::getTypeId() { + return _builder.getDataField< ::uint64_t>( + 1 * ::capnp::ELEMENTS); +} +inline void Type::Interface::Builder::setTypeId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + 1 * ::capnp::ELEMENTS, value); +} + +inline bool Type::Interface::Reader::hasBrand() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool Type::Interface::Builder::hasBrand() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Brand::Reader Type::Interface::Reader::getBrand() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::schema::Brand::Builder Type::Interface::Builder::getBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Brand::Pipeline Type::Interface::Pipeline::getBrand() { + return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Type::Interface::Builder::setBrand( ::capnp::schema::Brand::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Brand::Builder Type::Interface::Builder::initBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Type::Interface::Builder::adoptBrand( + ::capnp::Orphan< ::capnp::schema::Brand>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Brand> Type::Interface::Builder::disownBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} + +inline ::capnp::schema::Type::AnyPointer::Which Type::AnyPointer::Reader::which() const { + return _reader.getDataField<Which>(4 * ::capnp::ELEMENTS); +} +inline ::capnp::schema::Type::AnyPointer::Which Type::AnyPointer::Builder::which() { + return _builder.getDataField<Which>(4 * ::capnp::ELEMENTS); +} + +inline bool Type::AnyPointer::Reader::isUnconstrained() const { + return which() == Type::AnyPointer::UNCONSTRAINED; +} +inline bool Type::AnyPointer::Builder::isUnconstrained() { + return which() == Type::AnyPointer::UNCONSTRAINED; +} +inline typename Type::AnyPointer::Unconstrained::Reader Type::AnyPointer::Reader::getUnconstrained() const { + KJ_IREQUIRE((which() == Type::AnyPointer::UNCONSTRAINED), + "Must check which() before get()ing a union member."); + return typename Type::AnyPointer::Unconstrained::Reader(_reader); +} +inline typename Type::AnyPointer::Unconstrained::Builder Type::AnyPointer::Builder::getUnconstrained() { + KJ_IREQUIRE((which() == Type::AnyPointer::UNCONSTRAINED), + "Must check which() before get()ing a union member."); + return typename Type::AnyPointer::Unconstrained::Builder(_builder); +} +inline typename Type::AnyPointer::Unconstrained::Builder Type::AnyPointer::Builder::initUnconstrained() { + _builder.setDataField<Type::AnyPointer::Which>( + 4 * ::capnp::ELEMENTS, Type::AnyPointer::UNCONSTRAINED); + _builder.setDataField< ::uint16_t>(5 * ::capnp::ELEMENTS, 0); + return typename Type::AnyPointer::Unconstrained::Builder(_builder); +} +inline bool Type::AnyPointer::Reader::isParameter() const { + return which() == Type::AnyPointer::PARAMETER; +} +inline bool Type::AnyPointer::Builder::isParameter() { + return which() == Type::AnyPointer::PARAMETER; +} +inline typename Type::AnyPointer::Parameter::Reader Type::AnyPointer::Reader::getParameter() const { + KJ_IREQUIRE((which() == Type::AnyPointer::PARAMETER), + "Must check which() before get()ing a union member."); + return typename Type::AnyPointer::Parameter::Reader(_reader); +} +inline typename Type::AnyPointer::Parameter::Builder Type::AnyPointer::Builder::getParameter() { + KJ_IREQUIRE((which() == Type::AnyPointer::PARAMETER), + "Must check which() before get()ing a union member."); + return typename Type::AnyPointer::Parameter::Builder(_builder); +} +inline typename Type::AnyPointer::Parameter::Builder Type::AnyPointer::Builder::initParameter() { + _builder.setDataField<Type::AnyPointer::Which>( + 4 * ::capnp::ELEMENTS, Type::AnyPointer::PARAMETER); + _builder.setDataField< ::uint16_t>(5 * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint64_t>(2 * ::capnp::ELEMENTS, 0); + return typename Type::AnyPointer::Parameter::Builder(_builder); +} +inline bool Type::AnyPointer::Reader::isImplicitMethodParameter() const { + return which() == Type::AnyPointer::IMPLICIT_METHOD_PARAMETER; +} +inline bool Type::AnyPointer::Builder::isImplicitMethodParameter() { + return which() == Type::AnyPointer::IMPLICIT_METHOD_PARAMETER; +} +inline typename Type::AnyPointer::ImplicitMethodParameter::Reader Type::AnyPointer::Reader::getImplicitMethodParameter() const { + KJ_IREQUIRE((which() == Type::AnyPointer::IMPLICIT_METHOD_PARAMETER), + "Must check which() before get()ing a union member."); + return typename Type::AnyPointer::ImplicitMethodParameter::Reader(_reader); +} +inline typename Type::AnyPointer::ImplicitMethodParameter::Builder Type::AnyPointer::Builder::getImplicitMethodParameter() { + KJ_IREQUIRE((which() == Type::AnyPointer::IMPLICIT_METHOD_PARAMETER), + "Must check which() before get()ing a union member."); + return typename Type::AnyPointer::ImplicitMethodParameter::Builder(_builder); +} +inline typename Type::AnyPointer::ImplicitMethodParameter::Builder Type::AnyPointer::Builder::initImplicitMethodParameter() { + _builder.setDataField<Type::AnyPointer::Which>( + 4 * ::capnp::ELEMENTS, Type::AnyPointer::IMPLICIT_METHOD_PARAMETER); + _builder.setDataField< ::uint16_t>(5 * ::capnp::ELEMENTS, 0); + return typename Type::AnyPointer::ImplicitMethodParameter::Builder(_builder); +} +inline ::capnp::schema::Type::AnyPointer::Unconstrained::Which Type::AnyPointer::Unconstrained::Reader::which() const { + return _reader.getDataField<Which>(5 * ::capnp::ELEMENTS); +} +inline ::capnp::schema::Type::AnyPointer::Unconstrained::Which Type::AnyPointer::Unconstrained::Builder::which() { + return _builder.getDataField<Which>(5 * ::capnp::ELEMENTS); +} + +inline bool Type::AnyPointer::Unconstrained::Reader::isAnyKind() const { + return which() == Type::AnyPointer::Unconstrained::ANY_KIND; +} +inline bool Type::AnyPointer::Unconstrained::Builder::isAnyKind() { + return which() == Type::AnyPointer::Unconstrained::ANY_KIND; +} +inline ::capnp::Void Type::AnyPointer::Unconstrained::Reader::getAnyKind() const { + KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::ANY_KIND), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::AnyPointer::Unconstrained::Builder::getAnyKind() { + KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::ANY_KIND), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} +inline void Type::AnyPointer::Unconstrained::Builder::setAnyKind( ::capnp::Void value) { + _builder.setDataField<Type::AnyPointer::Unconstrained::Which>( + 5 * ::capnp::ELEMENTS, Type::AnyPointer::Unconstrained::ANY_KIND); + _builder.setDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Type::AnyPointer::Unconstrained::Reader::isStruct() const { + return which() == Type::AnyPointer::Unconstrained::STRUCT; +} +inline bool Type::AnyPointer::Unconstrained::Builder::isStruct() { + return which() == Type::AnyPointer::Unconstrained::STRUCT; +} +inline ::capnp::Void Type::AnyPointer::Unconstrained::Reader::getStruct() const { + KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::STRUCT), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::AnyPointer::Unconstrained::Builder::getStruct() { + KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::STRUCT), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} +inline void Type::AnyPointer::Unconstrained::Builder::setStruct( ::capnp::Void value) { + _builder.setDataField<Type::AnyPointer::Unconstrained::Which>( + 5 * ::capnp::ELEMENTS, Type::AnyPointer::Unconstrained::STRUCT); + _builder.setDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Type::AnyPointer::Unconstrained::Reader::isList() const { + return which() == Type::AnyPointer::Unconstrained::LIST; +} +inline bool Type::AnyPointer::Unconstrained::Builder::isList() { + return which() == Type::AnyPointer::Unconstrained::LIST; +} +inline ::capnp::Void Type::AnyPointer::Unconstrained::Reader::getList() const { + KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::LIST), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::AnyPointer::Unconstrained::Builder::getList() { + KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::LIST), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} +inline void Type::AnyPointer::Unconstrained::Builder::setList( ::capnp::Void value) { + _builder.setDataField<Type::AnyPointer::Unconstrained::Which>( + 5 * ::capnp::ELEMENTS, Type::AnyPointer::Unconstrained::LIST); + _builder.setDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Type::AnyPointer::Unconstrained::Reader::isCapability() const { + return which() == Type::AnyPointer::Unconstrained::CAPABILITY; +} +inline bool Type::AnyPointer::Unconstrained::Builder::isCapability() { + return which() == Type::AnyPointer::Unconstrained::CAPABILITY; +} +inline ::capnp::Void Type::AnyPointer::Unconstrained::Reader::getCapability() const { + KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::CAPABILITY), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::AnyPointer::Unconstrained::Builder::getCapability() { + KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::CAPABILITY), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} +inline void Type::AnyPointer::Unconstrained::Builder::setCapability( ::capnp::Void value) { + _builder.setDataField<Type::AnyPointer::Unconstrained::Which>( + 5 * ::capnp::ELEMENTS, Type::AnyPointer::Unconstrained::CAPABILITY); + _builder.setDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS, value); +} + +inline ::uint64_t Type::AnyPointer::Parameter::Reader::getScopeId() const { + return _reader.getDataField< ::uint64_t>( + 2 * ::capnp::ELEMENTS); +} + +inline ::uint64_t Type::AnyPointer::Parameter::Builder::getScopeId() { + return _builder.getDataField< ::uint64_t>( + 2 * ::capnp::ELEMENTS); +} +inline void Type::AnyPointer::Parameter::Builder::setScopeId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + 2 * ::capnp::ELEMENTS, value); +} + +inline ::uint16_t Type::AnyPointer::Parameter::Reader::getParameterIndex() const { + return _reader.getDataField< ::uint16_t>( + 5 * ::capnp::ELEMENTS); +} + +inline ::uint16_t Type::AnyPointer::Parameter::Builder::getParameterIndex() { + return _builder.getDataField< ::uint16_t>( + 5 * ::capnp::ELEMENTS); +} +inline void Type::AnyPointer::Parameter::Builder::setParameterIndex( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + 5 * ::capnp::ELEMENTS, value); +} + +inline ::uint16_t Type::AnyPointer::ImplicitMethodParameter::Reader::getParameterIndex() const { + return _reader.getDataField< ::uint16_t>( + 5 * ::capnp::ELEMENTS); +} + +inline ::uint16_t Type::AnyPointer::ImplicitMethodParameter::Builder::getParameterIndex() { + return _builder.getDataField< ::uint16_t>( + 5 * ::capnp::ELEMENTS); +} +inline void Type::AnyPointer::ImplicitMethodParameter::Builder::setParameterIndex( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + 5 * ::capnp::ELEMENTS, value); +} + +inline bool Brand::Reader::hasScopes() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool Brand::Builder::hasScopes() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Brand::Scope>::Reader Brand::Reader::getScopes() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope>>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Brand::Scope>::Builder Brand::Builder::getScopes() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope>>::get( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Brand::Builder::setScopes( ::capnp::List< ::capnp::schema::Brand::Scope>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope>>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Brand::Scope>::Builder Brand::Builder::initScopes(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope>>::init( + _builder.getPointerField(0 * ::capnp::POINTERS), size); +} +inline void Brand::Builder::adoptScopes( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Scope>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope>>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Scope>> Brand::Builder::disownScopes() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope>>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} + +inline ::capnp::schema::Brand::Scope::Which Brand::Scope::Reader::which() const { + return _reader.getDataField<Which>(4 * ::capnp::ELEMENTS); +} +inline ::capnp::schema::Brand::Scope::Which Brand::Scope::Builder::which() { + return _builder.getDataField<Which>(4 * ::capnp::ELEMENTS); +} + +inline ::uint64_t Brand::Scope::Reader::getScopeId() const { + return _reader.getDataField< ::uint64_t>( + 0 * ::capnp::ELEMENTS); +} + +inline ::uint64_t Brand::Scope::Builder::getScopeId() { + return _builder.getDataField< ::uint64_t>( + 0 * ::capnp::ELEMENTS); +} +inline void Brand::Scope::Builder::setScopeId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Brand::Scope::Reader::isBind() const { + return which() == Brand::Scope::BIND; +} +inline bool Brand::Scope::Builder::isBind() { + return which() == Brand::Scope::BIND; +} +inline bool Brand::Scope::Reader::hasBind() const { + if (which() != Brand::Scope::BIND) return false; + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool Brand::Scope::Builder::hasBind() { + if (which() != Brand::Scope::BIND) return false; + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Brand::Binding>::Reader Brand::Scope::Reader::getBind() const { + KJ_IREQUIRE((which() == Brand::Scope::BIND), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding>>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Brand::Binding>::Builder Brand::Scope::Builder::getBind() { + KJ_IREQUIRE((which() == Brand::Scope::BIND), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding>>::get( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Brand::Scope::Builder::setBind( ::capnp::List< ::capnp::schema::Brand::Binding>::Reader value) { + _builder.setDataField<Brand::Scope::Which>( + 4 * ::capnp::ELEMENTS, Brand::Scope::BIND); + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding>>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Brand::Binding>::Builder Brand::Scope::Builder::initBind(unsigned int size) { + _builder.setDataField<Brand::Scope::Which>( + 4 * ::capnp::ELEMENTS, Brand::Scope::BIND); + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding>>::init( + _builder.getPointerField(0 * ::capnp::POINTERS), size); +} +inline void Brand::Scope::Builder::adoptBind( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Binding>>&& value) { + _builder.setDataField<Brand::Scope::Which>( + 4 * ::capnp::ELEMENTS, Brand::Scope::BIND); + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding>>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Binding>> Brand::Scope::Builder::disownBind() { + KJ_IREQUIRE((which() == Brand::Scope::BIND), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding>>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} + +inline bool Brand::Scope::Reader::isInherit() const { + return which() == Brand::Scope::INHERIT; +} +inline bool Brand::Scope::Builder::isInherit() { + return which() == Brand::Scope::INHERIT; +} +inline ::capnp::Void Brand::Scope::Reader::getInherit() const { + KJ_IREQUIRE((which() == Brand::Scope::INHERIT), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Brand::Scope::Builder::getInherit() { + KJ_IREQUIRE((which() == Brand::Scope::INHERIT), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} +inline void Brand::Scope::Builder::setInherit( ::capnp::Void value) { + _builder.setDataField<Brand::Scope::Which>( + 4 * ::capnp::ELEMENTS, Brand::Scope::INHERIT); + _builder.setDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS, value); +} + +inline ::capnp::schema::Brand::Binding::Which Brand::Binding::Reader::which() const { + return _reader.getDataField<Which>(0 * ::capnp::ELEMENTS); +} +inline ::capnp::schema::Brand::Binding::Which Brand::Binding::Builder::which() { + return _builder.getDataField<Which>(0 * ::capnp::ELEMENTS); +} + +inline bool Brand::Binding::Reader::isUnbound() const { + return which() == Brand::Binding::UNBOUND; +} +inline bool Brand::Binding::Builder::isUnbound() { + return which() == Brand::Binding::UNBOUND; +} +inline ::capnp::Void Brand::Binding::Reader::getUnbound() const { + KJ_IREQUIRE((which() == Brand::Binding::UNBOUND), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Brand::Binding::Builder::getUnbound() { + KJ_IREQUIRE((which() == Brand::Binding::UNBOUND), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} +inline void Brand::Binding::Builder::setUnbound( ::capnp::Void value) { + _builder.setDataField<Brand::Binding::Which>( + 0 * ::capnp::ELEMENTS, Brand::Binding::UNBOUND); + _builder.setDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Brand::Binding::Reader::isType() const { + return which() == Brand::Binding::TYPE; +} +inline bool Brand::Binding::Builder::isType() { + return which() == Brand::Binding::TYPE; +} +inline bool Brand::Binding::Reader::hasType() const { + if (which() != Brand::Binding::TYPE) return false; + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool Brand::Binding::Builder::hasType() { + if (which() != Brand::Binding::TYPE) return false; + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Type::Reader Brand::Binding::Reader::getType() const { + KJ_IREQUIRE((which() == Brand::Binding::TYPE), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::schema::Type::Builder Brand::Binding::Builder::getType() { + KJ_IREQUIRE((which() == Brand::Binding::TYPE), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Brand::Binding::Builder::setType( ::capnp::schema::Type::Reader value) { + _builder.setDataField<Brand::Binding::Which>( + 0 * ::capnp::ELEMENTS, Brand::Binding::TYPE); + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Type::Builder Brand::Binding::Builder::initType() { + _builder.setDataField<Brand::Binding::Which>( + 0 * ::capnp::ELEMENTS, Brand::Binding::TYPE); + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Brand::Binding::Builder::adoptType( + ::capnp::Orphan< ::capnp::schema::Type>&& value) { + _builder.setDataField<Brand::Binding::Which>( + 0 * ::capnp::ELEMENTS, Brand::Binding::TYPE); + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Type> Brand::Binding::Builder::disownType() { + KJ_IREQUIRE((which() == Brand::Binding::TYPE), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} + +inline ::capnp::schema::Value::Which Value::Reader::which() const { + return _reader.getDataField<Which>(0 * ::capnp::ELEMENTS); +} +inline ::capnp::schema::Value::Which Value::Builder::which() { + return _builder.getDataField<Which>(0 * ::capnp::ELEMENTS); +} + +inline bool Value::Reader::isVoid() const { + return which() == Value::VOID; +} +inline bool Value::Builder::isVoid() { + return which() == Value::VOID; +} +inline ::capnp::Void Value::Reader::getVoid() const { + KJ_IREQUIRE((which() == Value::VOID), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Value::Builder::getVoid() { + KJ_IREQUIRE((which() == Value::VOID), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} +inline void Value::Builder::setVoid( ::capnp::Void value) { + _builder.setDataField<Value::Which>( + 0 * ::capnp::ELEMENTS, Value::VOID); + _builder.setDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isBool() const { + return which() == Value::BOOL; +} +inline bool Value::Builder::isBool() { + return which() == Value::BOOL; +} +inline bool Value::Reader::getBool() const { + KJ_IREQUIRE((which() == Value::BOOL), + "Must check which() before get()ing a union member."); + return _reader.getDataField<bool>( + 16 * ::capnp::ELEMENTS); +} + +inline bool Value::Builder::getBool() { + KJ_IREQUIRE((which() == Value::BOOL), + "Must check which() before get()ing a union member."); + return _builder.getDataField<bool>( + 16 * ::capnp::ELEMENTS); +} +inline void Value::Builder::setBool(bool value) { + _builder.setDataField<Value::Which>( + 0 * ::capnp::ELEMENTS, Value::BOOL); + _builder.setDataField<bool>( + 16 * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isInt8() const { + return which() == Value::INT8; +} +inline bool Value::Builder::isInt8() { + return which() == Value::INT8; +} +inline ::int8_t Value::Reader::getInt8() const { + KJ_IREQUIRE((which() == Value::INT8), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::int8_t>( + 2 * ::capnp::ELEMENTS); +} + +inline ::int8_t Value::Builder::getInt8() { + KJ_IREQUIRE((which() == Value::INT8), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::int8_t>( + 2 * ::capnp::ELEMENTS); +} +inline void Value::Builder::setInt8( ::int8_t value) { + _builder.setDataField<Value::Which>( + 0 * ::capnp::ELEMENTS, Value::INT8); + _builder.setDataField< ::int8_t>( + 2 * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isInt16() const { + return which() == Value::INT16; +} +inline bool Value::Builder::isInt16() { + return which() == Value::INT16; +} +inline ::int16_t Value::Reader::getInt16() const { + KJ_IREQUIRE((which() == Value::INT16), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::int16_t>( + 1 * ::capnp::ELEMENTS); +} + +inline ::int16_t Value::Builder::getInt16() { + KJ_IREQUIRE((which() == Value::INT16), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::int16_t>( + 1 * ::capnp::ELEMENTS); +} +inline void Value::Builder::setInt16( ::int16_t value) { + _builder.setDataField<Value::Which>( + 0 * ::capnp::ELEMENTS, Value::INT16); + _builder.setDataField< ::int16_t>( + 1 * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isInt32() const { + return which() == Value::INT32; +} +inline bool Value::Builder::isInt32() { + return which() == Value::INT32; +} +inline ::int32_t Value::Reader::getInt32() const { + KJ_IREQUIRE((which() == Value::INT32), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::int32_t>( + 1 * ::capnp::ELEMENTS); +} + +inline ::int32_t Value::Builder::getInt32() { + KJ_IREQUIRE((which() == Value::INT32), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::int32_t>( + 1 * ::capnp::ELEMENTS); +} +inline void Value::Builder::setInt32( ::int32_t value) { + _builder.setDataField<Value::Which>( + 0 * ::capnp::ELEMENTS, Value::INT32); + _builder.setDataField< ::int32_t>( + 1 * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isInt64() const { + return which() == Value::INT64; +} +inline bool Value::Builder::isInt64() { + return which() == Value::INT64; +} +inline ::int64_t Value::Reader::getInt64() const { + KJ_IREQUIRE((which() == Value::INT64), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::int64_t>( + 1 * ::capnp::ELEMENTS); +} + +inline ::int64_t Value::Builder::getInt64() { + KJ_IREQUIRE((which() == Value::INT64), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::int64_t>( + 1 * ::capnp::ELEMENTS); +} +inline void Value::Builder::setInt64( ::int64_t value) { + _builder.setDataField<Value::Which>( + 0 * ::capnp::ELEMENTS, Value::INT64); + _builder.setDataField< ::int64_t>( + 1 * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isUint8() const { + return which() == Value::UINT8; +} +inline bool Value::Builder::isUint8() { + return which() == Value::UINT8; +} +inline ::uint8_t Value::Reader::getUint8() const { + KJ_IREQUIRE((which() == Value::UINT8), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::uint8_t>( + 2 * ::capnp::ELEMENTS); +} + +inline ::uint8_t Value::Builder::getUint8() { + KJ_IREQUIRE((which() == Value::UINT8), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::uint8_t>( + 2 * ::capnp::ELEMENTS); +} +inline void Value::Builder::setUint8( ::uint8_t value) { + _builder.setDataField<Value::Which>( + 0 * ::capnp::ELEMENTS, Value::UINT8); + _builder.setDataField< ::uint8_t>( + 2 * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isUint16() const { + return which() == Value::UINT16; +} +inline bool Value::Builder::isUint16() { + return which() == Value::UINT16; +} +inline ::uint16_t Value::Reader::getUint16() const { + KJ_IREQUIRE((which() == Value::UINT16), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::uint16_t>( + 1 * ::capnp::ELEMENTS); +} + +inline ::uint16_t Value::Builder::getUint16() { + KJ_IREQUIRE((which() == Value::UINT16), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::uint16_t>( + 1 * ::capnp::ELEMENTS); +} +inline void Value::Builder::setUint16( ::uint16_t value) { + _builder.setDataField<Value::Which>( + 0 * ::capnp::ELEMENTS, Value::UINT16); + _builder.setDataField< ::uint16_t>( + 1 * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isUint32() const { + return which() == Value::UINT32; +} +inline bool Value::Builder::isUint32() { + return which() == Value::UINT32; +} +inline ::uint32_t Value::Reader::getUint32() const { + KJ_IREQUIRE((which() == Value::UINT32), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::uint32_t>( + 1 * ::capnp::ELEMENTS); +} + +inline ::uint32_t Value::Builder::getUint32() { + KJ_IREQUIRE((which() == Value::UINT32), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::uint32_t>( + 1 * ::capnp::ELEMENTS); +} +inline void Value::Builder::setUint32( ::uint32_t value) { + _builder.setDataField<Value::Which>( + 0 * ::capnp::ELEMENTS, Value::UINT32); + _builder.setDataField< ::uint32_t>( + 1 * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isUint64() const { + return which() == Value::UINT64; +} +inline bool Value::Builder::isUint64() { + return which() == Value::UINT64; +} +inline ::uint64_t Value::Reader::getUint64() const { + KJ_IREQUIRE((which() == Value::UINT64), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::uint64_t>( + 1 * ::capnp::ELEMENTS); +} + +inline ::uint64_t Value::Builder::getUint64() { + KJ_IREQUIRE((which() == Value::UINT64), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::uint64_t>( + 1 * ::capnp::ELEMENTS); +} +inline void Value::Builder::setUint64( ::uint64_t value) { + _builder.setDataField<Value::Which>( + 0 * ::capnp::ELEMENTS, Value::UINT64); + _builder.setDataField< ::uint64_t>( + 1 * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isFloat32() const { + return which() == Value::FLOAT32; +} +inline bool Value::Builder::isFloat32() { + return which() == Value::FLOAT32; +} +inline float Value::Reader::getFloat32() const { + KJ_IREQUIRE((which() == Value::FLOAT32), + "Must check which() before get()ing a union member."); + return _reader.getDataField<float>( + 1 * ::capnp::ELEMENTS); +} + +inline float Value::Builder::getFloat32() { + KJ_IREQUIRE((which() == Value::FLOAT32), + "Must check which() before get()ing a union member."); + return _builder.getDataField<float>( + 1 * ::capnp::ELEMENTS); +} +inline void Value::Builder::setFloat32(float value) { + _builder.setDataField<Value::Which>( + 0 * ::capnp::ELEMENTS, Value::FLOAT32); + _builder.setDataField<float>( + 1 * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isFloat64() const { + return which() == Value::FLOAT64; +} +inline bool Value::Builder::isFloat64() { + return which() == Value::FLOAT64; +} +inline double Value::Reader::getFloat64() const { + KJ_IREQUIRE((which() == Value::FLOAT64), + "Must check which() before get()ing a union member."); + return _reader.getDataField<double>( + 1 * ::capnp::ELEMENTS); +} + +inline double Value::Builder::getFloat64() { + KJ_IREQUIRE((which() == Value::FLOAT64), + "Must check which() before get()ing a union member."); + return _builder.getDataField<double>( + 1 * ::capnp::ELEMENTS); +} +inline void Value::Builder::setFloat64(double value) { + _builder.setDataField<Value::Which>( + 0 * ::capnp::ELEMENTS, Value::FLOAT64); + _builder.setDataField<double>( + 1 * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isText() const { + return which() == Value::TEXT; +} +inline bool Value::Builder::isText() { + return which() == Value::TEXT; +} +inline bool Value::Reader::hasText() const { + if (which() != Value::TEXT) return false; + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool Value::Builder::hasText() { + if (which() != Value::TEXT) return false; + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Value::Reader::getText() const { + KJ_IREQUIRE((which() == Value::TEXT), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::Text>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Value::Builder::getText() { + KJ_IREQUIRE((which() == Value::TEXT), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::Text>::get( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Value::Builder::setText( ::capnp::Text::Reader value) { + _builder.setDataField<Value::Which>( + 0 * ::capnp::ELEMENTS, Value::TEXT); + ::capnp::_::PointerHelpers< ::capnp::Text>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Value::Builder::initText(unsigned int size) { + _builder.setDataField<Value::Which>( + 0 * ::capnp::ELEMENTS, Value::TEXT); + return ::capnp::_::PointerHelpers< ::capnp::Text>::init( + _builder.getPointerField(0 * ::capnp::POINTERS), size); +} +inline void Value::Builder::adoptText( + ::capnp::Orphan< ::capnp::Text>&& value) { + _builder.setDataField<Value::Which>( + 0 * ::capnp::ELEMENTS, Value::TEXT); + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Value::Builder::disownText() { + KJ_IREQUIRE((which() == Value::TEXT), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} + +inline bool Value::Reader::isData() const { + return which() == Value::DATA; +} +inline bool Value::Builder::isData() { + return which() == Value::DATA; +} +inline bool Value::Reader::hasData() const { + if (which() != Value::DATA) return false; + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool Value::Builder::hasData() { + if (which() != Value::DATA) return false; + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Data::Reader Value::Reader::getData() const { + KJ_IREQUIRE((which() == Value::DATA), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::Data>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::Data::Builder Value::Builder::getData() { + KJ_IREQUIRE((which() == Value::DATA), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::Data>::get( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Value::Builder::setData( ::capnp::Data::Reader value) { + _builder.setDataField<Value::Which>( + 0 * ::capnp::ELEMENTS, Value::DATA); + ::capnp::_::PointerHelpers< ::capnp::Data>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::Data::Builder Value::Builder::initData(unsigned int size) { + _builder.setDataField<Value::Which>( + 0 * ::capnp::ELEMENTS, Value::DATA); + return ::capnp::_::PointerHelpers< ::capnp::Data>::init( + _builder.getPointerField(0 * ::capnp::POINTERS), size); +} +inline void Value::Builder::adoptData( + ::capnp::Orphan< ::capnp::Data>&& value) { + _builder.setDataField<Value::Which>( + 0 * ::capnp::ELEMENTS, Value::DATA); + ::capnp::_::PointerHelpers< ::capnp::Data>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Data> Value::Builder::disownData() { + KJ_IREQUIRE((which() == Value::DATA), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::Data>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} + +inline bool Value::Reader::isList() const { + return which() == Value::LIST; +} +inline bool Value::Builder::isList() { + return which() == Value::LIST; +} +inline bool Value::Reader::hasList() const { + if (which() != Value::LIST) return false; + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool Value::Builder::hasList() { + if (which() != Value::LIST) return false; + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::AnyPointer::Reader Value::Reader::getList() const { + KJ_IREQUIRE((which() == Value::LIST), + "Must check which() before get()ing a union member."); + return ::capnp::AnyPointer::Reader( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Value::Builder::getList() { + KJ_IREQUIRE((which() == Value::LIST), + "Must check which() before get()ing a union member."); + return ::capnp::AnyPointer::Builder( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Value::Builder::initList() { + _builder.setDataField<Value::Which>( + 0 * ::capnp::ELEMENTS, Value::LIST); + auto result = ::capnp::AnyPointer::Builder( + _builder.getPointerField(0 * ::capnp::POINTERS)); + result.clear(); + return result; +} + +inline bool Value::Reader::isEnum() const { + return which() == Value::ENUM; +} +inline bool Value::Builder::isEnum() { + return which() == Value::ENUM; +} +inline ::uint16_t Value::Reader::getEnum() const { + KJ_IREQUIRE((which() == Value::ENUM), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::uint16_t>( + 1 * ::capnp::ELEMENTS); +} + +inline ::uint16_t Value::Builder::getEnum() { + KJ_IREQUIRE((which() == Value::ENUM), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::uint16_t>( + 1 * ::capnp::ELEMENTS); +} +inline void Value::Builder::setEnum( ::uint16_t value) { + _builder.setDataField<Value::Which>( + 0 * ::capnp::ELEMENTS, Value::ENUM); + _builder.setDataField< ::uint16_t>( + 1 * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isStruct() const { + return which() == Value::STRUCT; +} +inline bool Value::Builder::isStruct() { + return which() == Value::STRUCT; +} +inline bool Value::Reader::hasStruct() const { + if (which() != Value::STRUCT) return false; + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool Value::Builder::hasStruct() { + if (which() != Value::STRUCT) return false; + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::AnyPointer::Reader Value::Reader::getStruct() const { + KJ_IREQUIRE((which() == Value::STRUCT), + "Must check which() before get()ing a union member."); + return ::capnp::AnyPointer::Reader( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Value::Builder::getStruct() { + KJ_IREQUIRE((which() == Value::STRUCT), + "Must check which() before get()ing a union member."); + return ::capnp::AnyPointer::Builder( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Value::Builder::initStruct() { + _builder.setDataField<Value::Which>( + 0 * ::capnp::ELEMENTS, Value::STRUCT); + auto result = ::capnp::AnyPointer::Builder( + _builder.getPointerField(0 * ::capnp::POINTERS)); + result.clear(); + return result; +} + +inline bool Value::Reader::isInterface() const { + return which() == Value::INTERFACE; +} +inline bool Value::Builder::isInterface() { + return which() == Value::INTERFACE; +} +inline ::capnp::Void Value::Reader::getInterface() const { + KJ_IREQUIRE((which() == Value::INTERFACE), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Value::Builder::getInterface() { + KJ_IREQUIRE((which() == Value::INTERFACE), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS); +} +inline void Value::Builder::setInterface( ::capnp::Void value) { + _builder.setDataField<Value::Which>( + 0 * ::capnp::ELEMENTS, Value::INTERFACE); + _builder.setDataField< ::capnp::Void>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isAnyPointer() const { + return which() == Value::ANY_POINTER; +} +inline bool Value::Builder::isAnyPointer() { + return which() == Value::ANY_POINTER; +} +inline bool Value::Reader::hasAnyPointer() const { + if (which() != Value::ANY_POINTER) return false; + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool Value::Builder::hasAnyPointer() { + if (which() != Value::ANY_POINTER) return false; + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::AnyPointer::Reader Value::Reader::getAnyPointer() const { + KJ_IREQUIRE((which() == Value::ANY_POINTER), + "Must check which() before get()ing a union member."); + return ::capnp::AnyPointer::Reader( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Value::Builder::getAnyPointer() { + KJ_IREQUIRE((which() == Value::ANY_POINTER), + "Must check which() before get()ing a union member."); + return ::capnp::AnyPointer::Builder( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Value::Builder::initAnyPointer() { + _builder.setDataField<Value::Which>( + 0 * ::capnp::ELEMENTS, Value::ANY_POINTER); + auto result = ::capnp::AnyPointer::Builder( + _builder.getPointerField(0 * ::capnp::POINTERS)); + result.clear(); + return result; +} + +inline ::uint64_t Annotation::Reader::getId() const { + return _reader.getDataField< ::uint64_t>( + 0 * ::capnp::ELEMENTS); +} + +inline ::uint64_t Annotation::Builder::getId() { + return _builder.getDataField< ::uint64_t>( + 0 * ::capnp::ELEMENTS); +} +inline void Annotation::Builder::setId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool Annotation::Reader::hasValue() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool Annotation::Builder::hasValue() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Value::Reader Annotation::Reader::getValue() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::schema::Value::Builder Annotation::Builder::getValue() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Value::Pipeline Annotation::Pipeline::getValue() { + return ::capnp::schema::Value::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Annotation::Builder::setValue( ::capnp::schema::Value::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Value>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Value::Builder Annotation::Builder::initValue() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::init( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void Annotation::Builder::adoptValue( + ::capnp::Orphan< ::capnp::schema::Value>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Value>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Value> Annotation::Builder::disownValue() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} + +inline bool Annotation::Reader::hasBrand() const { + return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull(); +} +inline bool Annotation::Builder::hasBrand() { + return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Brand::Reader Annotation::Reader::getBrand() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get( + _reader.getPointerField(1 * ::capnp::POINTERS)); +} +inline ::capnp::schema::Brand::Builder Annotation::Builder::getBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get( + _builder.getPointerField(1 * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Brand::Pipeline Annotation::Pipeline::getBrand() { + return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(1)); +} +#endif // !CAPNP_LITE +inline void Annotation::Builder::setBrand( ::capnp::schema::Brand::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set( + _builder.getPointerField(1 * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Brand::Builder Annotation::Builder::initBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init( + _builder.getPointerField(1 * ::capnp::POINTERS)); +} +inline void Annotation::Builder::adoptBrand( + ::capnp::Orphan< ::capnp::schema::Brand>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt( + _builder.getPointerField(1 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Brand> Annotation::Builder::disownBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown( + _builder.getPointerField(1 * ::capnp::POINTERS)); +} + +inline bool CodeGeneratorRequest::Reader::hasNodes() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool CodeGeneratorRequest::Builder::hasNodes() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Node>::Reader CodeGeneratorRequest::Reader::getNodes() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node>>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Node>::Builder CodeGeneratorRequest::Builder::getNodes() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node>>::get( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void CodeGeneratorRequest::Builder::setNodes( ::capnp::List< ::capnp::schema::Node>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node>>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Node>::Builder CodeGeneratorRequest::Builder::initNodes(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node>>::init( + _builder.getPointerField(0 * ::capnp::POINTERS), size); +} +inline void CodeGeneratorRequest::Builder::adoptNodes( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node>>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node>> CodeGeneratorRequest::Builder::disownNodes() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node>>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} + +inline bool CodeGeneratorRequest::Reader::hasRequestedFiles() const { + return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull(); +} +inline bool CodeGeneratorRequest::Builder::hasRequestedFiles() { + return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Reader CodeGeneratorRequest::Reader::getRequestedFiles() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>::get( + _reader.getPointerField(1 * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Builder CodeGeneratorRequest::Builder::getRequestedFiles() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>::get( + _builder.getPointerField(1 * ::capnp::POINTERS)); +} +inline void CodeGeneratorRequest::Builder::setRequestedFiles( ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>::set( + _builder.getPointerField(1 * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Builder CodeGeneratorRequest::Builder::initRequestedFiles(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>::init( + _builder.getPointerField(1 * ::capnp::POINTERS), size); +} +inline void CodeGeneratorRequest::Builder::adoptRequestedFiles( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>::adopt( + _builder.getPointerField(1 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>> CodeGeneratorRequest::Builder::disownRequestedFiles() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>::disown( + _builder.getPointerField(1 * ::capnp::POINTERS)); +} + +inline ::uint64_t CodeGeneratorRequest::RequestedFile::Reader::getId() const { + return _reader.getDataField< ::uint64_t>( + 0 * ::capnp::ELEMENTS); +} + +inline ::uint64_t CodeGeneratorRequest::RequestedFile::Builder::getId() { + return _builder.getDataField< ::uint64_t>( + 0 * ::capnp::ELEMENTS); +} +inline void CodeGeneratorRequest::RequestedFile::Builder::setId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool CodeGeneratorRequest::RequestedFile::Reader::hasFilename() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool CodeGeneratorRequest::RequestedFile::Builder::hasFilename() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader CodeGeneratorRequest::RequestedFile::Reader::getFilename() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder CodeGeneratorRequest::RequestedFile::Builder::getFilename() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void CodeGeneratorRequest::RequestedFile::Builder::setFilename( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder CodeGeneratorRequest::RequestedFile::Builder::initFilename(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init( + _builder.getPointerField(0 * ::capnp::POINTERS), size); +} +inline void CodeGeneratorRequest::RequestedFile::Builder::adoptFilename( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> CodeGeneratorRequest::RequestedFile::Builder::disownFilename() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} + +inline bool CodeGeneratorRequest::RequestedFile::Reader::hasImports() const { + return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull(); +} +inline bool CodeGeneratorRequest::RequestedFile::Builder::hasImports() { + return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Reader CodeGeneratorRequest::RequestedFile::Reader::getImports() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>::get( + _reader.getPointerField(1 * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Builder CodeGeneratorRequest::RequestedFile::Builder::getImports() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>::get( + _builder.getPointerField(1 * ::capnp::POINTERS)); +} +inline void CodeGeneratorRequest::RequestedFile::Builder::setImports( ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>::set( + _builder.getPointerField(1 * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Builder CodeGeneratorRequest::RequestedFile::Builder::initImports(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>::init( + _builder.getPointerField(1 * ::capnp::POINTERS), size); +} +inline void CodeGeneratorRequest::RequestedFile::Builder::adoptImports( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>::adopt( + _builder.getPointerField(1 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>> CodeGeneratorRequest::RequestedFile::Builder::disownImports() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>::disown( + _builder.getPointerField(1 * ::capnp::POINTERS)); +} + +inline ::uint64_t CodeGeneratorRequest::RequestedFile::Import::Reader::getId() const { + return _reader.getDataField< ::uint64_t>( + 0 * ::capnp::ELEMENTS); +} + +inline ::uint64_t CodeGeneratorRequest::RequestedFile::Import::Builder::getId() { + return _builder.getDataField< ::uint64_t>( + 0 * ::capnp::ELEMENTS); +} +inline void CodeGeneratorRequest::RequestedFile::Import::Builder::setId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + 0 * ::capnp::ELEMENTS, value); +} + +inline bool CodeGeneratorRequest::RequestedFile::Import::Reader::hasName() const { + return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline bool CodeGeneratorRequest::RequestedFile::Import::Builder::hasName() { + return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader CodeGeneratorRequest::RequestedFile::Import::Reader::getName() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get( + _reader.getPointerField(0 * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder CodeGeneratorRequest::RequestedFile::Import::Builder::getName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} +inline void CodeGeneratorRequest::RequestedFile::Import::Builder::setName( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set( + _builder.getPointerField(0 * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder CodeGeneratorRequest::RequestedFile::Import::Builder::initName(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init( + _builder.getPointerField(0 * ::capnp::POINTERS), size); +} +inline void CodeGeneratorRequest::RequestedFile::Import::Builder::adoptName( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt( + _builder.getPointerField(0 * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> CodeGeneratorRequest::RequestedFile::Import::Builder::disownName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown( + _builder.getPointerField(0 * ::capnp::POINTERS)); +} + +} // namespace +} // namespace + +#endif // CAPNP_INCLUDED_a93fc509624c72d9_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/schema.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,934 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef CAPNP_SCHEMA_H_ +#define CAPNP_SCHEMA_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#if CAPNP_LITE +#error "Reflection APIs, including this header, are not available in lite mode." +#endif + +#include <capnp/schema.capnp.h> + +namespace capnp { + +class Schema; +class StructSchema; +class EnumSchema; +class InterfaceSchema; +class ConstSchema; +class ListSchema; +class Type; + +template <typename T, Kind k = kind<T>()> struct SchemaType_ { typedef Schema Type; }; +template <typename T> struct SchemaType_<T, Kind::PRIMITIVE> { typedef schema::Type::Which Type; }; +template <typename T> struct SchemaType_<T, Kind::BLOB> { typedef schema::Type::Which Type; }; +template <typename T> struct SchemaType_<T, Kind::ENUM> { typedef EnumSchema Type; }; +template <typename T> struct SchemaType_<T, Kind::STRUCT> { typedef StructSchema Type; }; +template <typename T> struct SchemaType_<T, Kind::INTERFACE> { typedef InterfaceSchema Type; }; +template <typename T> struct SchemaType_<T, Kind::LIST> { typedef ListSchema Type; }; + +template <typename T> +using SchemaType = typename SchemaType_<T>::Type; +// SchemaType<T> is the type of T's schema, e.g. StructSchema if T is a struct. + +namespace _ { // private +extern const RawSchema NULL_SCHEMA; +extern const RawSchema NULL_STRUCT_SCHEMA; +extern const RawSchema NULL_ENUM_SCHEMA; +extern const RawSchema NULL_INTERFACE_SCHEMA; +extern const RawSchema NULL_CONST_SCHEMA; +// The schema types default to these null (empty) schemas in case of error, especially when +// exceptions are disabled. +} // namespace _ (private) + +class Schema { + // Convenience wrapper around capnp::schema::Node. + +public: + inline Schema(): raw(&_::NULL_SCHEMA.defaultBrand) {} + + template <typename T> + static inline SchemaType<T> from() { return SchemaType<T>::template fromImpl<T>(); } + // Get the Schema for a particular compiled-in type. + + schema::Node::Reader getProto() const; + // Get the underlying Cap'n Proto representation of the schema node. (Note that this accessor + // has performance comparable to accessors of struct-typed fields on Reader classes.) + + kj::ArrayPtr<const word> asUncheckedMessage() const; + // Get the encoded schema node content as a single message segment. It is safe to read as an + // unchecked message. + + Schema getDependency(uint64_t id) const KJ_DEPRECATED("Does not handle generics correctly."); + // DEPRECATED: This method cannot correctly account for generic type parameter bindings that + // may apply to the dependency. Instead of using this method, use a method of the Schema API + // that corresponds to the exact kind of dependency. For example, to get a field type, use + // StructSchema::Field::getType(). + // + // Gets the Schema for one of this Schema's dependencies. For example, if this Schema is for a + // struct, you could look up the schema for one of its fields' types. Throws an exception if this + // schema doesn't actually depend on the given id. + // + // Note that not all type IDs found in the schema node are considered "dependencies" -- only the + // ones that are needed to implement the dynamic API are. That includes: + // - Field types. + // - Group types. + // - scopeId for group nodes, but NOT otherwise. + // - Method parameter and return types. + // + // The following are NOT considered dependencies: + // - Nested nodes. + // - scopeId for a non-group node. + // - Annotations. + // + // To obtain schemas for those, you would need a SchemaLoader. + + bool isBranded() const; + // Returns true if this schema represents a non-default parameterization of this type. + + Schema getGeneric() const; + // Get the version of this schema with any brands removed. + + class BrandArgumentList; + BrandArgumentList getBrandArgumentsAtScope(uint64_t scopeId) const; + // Gets the values bound to the brand parameters at the given scope. + + StructSchema asStruct() const; + EnumSchema asEnum() const; + InterfaceSchema asInterface() const; + ConstSchema asConst() const; + // Cast the Schema to a specific type. Throws an exception if the type doesn't match. Use + // getProto() to determine type, e.g. getProto().isStruct(). + + inline bool operator==(const Schema& other) const { return raw == other.raw; } + inline bool operator!=(const Schema& other) const { return raw != other.raw; } + // Determine whether two Schemas are wrapping the exact same underlying data, by identity. If + // you want to check if two Schemas represent the same type (but possibly different versions of + // it), compare their IDs instead. + + template <typename T> + void requireUsableAs() const; + // Throws an exception if a value with this Schema cannot safely be cast to a native value of + // the given type. This passes if either: + // - *this == from<T>() + // - This schema was loaded with SchemaLoader, the type ID matches typeId<T>(), and + // loadCompiledTypeAndDependencies<T>() was called on the SchemaLoader. + + kj::StringPtr getShortDisplayName() const; + // Get the short version of the node's display name. + +private: + const _::RawBrandedSchema* raw; + + inline explicit Schema(const _::RawBrandedSchema* raw): raw(raw) { + KJ_IREQUIRE(raw->lazyInitializer == nullptr, + "Must call ensureInitialized() on RawSchema before constructing Schema."); + } + + template <typename T> static inline Schema fromImpl() { + return Schema(&_::rawSchema<T>()); + } + + void requireUsableAs(const _::RawSchema* expected) const; + + uint32_t getSchemaOffset(const schema::Value::Reader& value) const; + + Type getBrandBinding(uint64_t scopeId, uint index) const; + // Look up the binding for a brand parameter used by this Schema. Returns `AnyPointer` if the + // parameter is not bound. + // + // TODO(someday): Public interface for iterating over all bindings? + + Schema getDependency(uint64_t id, uint location) const; + // Look up schema for a particular dependency of this schema. `location` is the dependency + // location number as defined in _::RawBrandedSchema. + + Type interpretType(schema::Type::Reader proto, uint location) const; + // Interpret a schema::Type in the given location within the schema, compiling it into a + // Type object. + + friend class StructSchema; + friend class EnumSchema; + friend class InterfaceSchema; + friend class ConstSchema; + friend class ListSchema; + friend class SchemaLoader; + friend class Type; + friend kj::StringTree _::structString( + _::StructReader reader, const _::RawBrandedSchema& schema); + friend kj::String _::enumString(uint16_t value, const _::RawBrandedSchema& schema); +}; + +kj::StringPtr KJ_STRINGIFY(const Schema& schema); + +class Schema::BrandArgumentList { + // A list of generic parameter bindings for parameters of some particular type. Note that since + // parameters on an outer type apply to all inner types as well, a deeply-nested type can have + // multiple BrandArgumentLists that apply to it. + // + // A BrandArgumentList only represents the arguments that the client of the type specified. Since + // new parameters can be added over time, this list may not cover all defined parameters for the + // type. Missing parameters should be treated as AnyPointer. This class's implementation of + // operator[] already does this for you; out-of-bounds access will safely return AnyPointer. + +public: + inline BrandArgumentList(): scopeId(0), size_(0), bindings(nullptr) {} + + inline uint size() const { return size_; } + Type operator[](uint index) const; + + typedef _::IndexingIterator<const BrandArgumentList, Type> Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + +private: + uint64_t scopeId; + uint size_; + bool isUnbound; + const _::RawBrandedSchema::Binding* bindings; + + inline BrandArgumentList(uint64_t scopeId, bool isUnbound) + : scopeId(scopeId), size_(0), isUnbound(isUnbound), bindings(nullptr) {} + inline BrandArgumentList(uint64_t scopeId, uint size, + const _::RawBrandedSchema::Binding* bindings) + : scopeId(scopeId), size_(size), isUnbound(false), bindings(bindings) {} + + friend class Schema; +}; + +// ------------------------------------------------------------------- + +class StructSchema: public Schema { +public: + inline StructSchema(): Schema(&_::NULL_STRUCT_SCHEMA.defaultBrand) {} + + class Field; + class FieldList; + class FieldSubset; + + FieldList getFields() const; + // List top-level fields of this struct. This list will contain top-level groups (including + // named unions) but not the members of those groups. The list does, however, contain the + // members of the unnamed union, if there is one. + + FieldSubset getUnionFields() const; + // If the field contains an unnamed union, get a list of fields in the union, ordered by + // ordinal. Since discriminant values are assigned sequentially by ordinal, you may index this + // list by discriminant value. + + FieldSubset getNonUnionFields() const; + // Get the fields of this struct which are not in an unnamed union, ordered by ordinal. + + kj::Maybe<Field> findFieldByName(kj::StringPtr name) const; + // Find the field with the given name, or return null if there is no such field. If the struct + // contains an unnamed union, then this will find fields of that union in addition to fields + // of the outer struct, since they exist in the same namespace. It will not, however, find + // members of groups (including named unions) -- you must first look up the group itself, + // then dig into its type. + + Field getFieldByName(kj::StringPtr name) const; + // Like findFieldByName() but throws an exception on failure. + + kj::Maybe<Field> getFieldByDiscriminant(uint16_t discriminant) const; + // Finds the field whose `discriminantValue` is equal to the given value, or returns null if + // there is no such field. (If the schema does not represent a union or a struct containing + // an unnamed union, then this always returns null.) + +private: + StructSchema(Schema base): Schema(base) {} + template <typename T> static inline StructSchema fromImpl() { + return StructSchema(Schema(&_::rawBrandedSchema<T>())); + } + friend class Schema; + friend class Type; +}; + +class StructSchema::Field { +public: + Field() = default; + + inline schema::Field::Reader getProto() const { return proto; } + inline StructSchema getContainingStruct() const { return parent; } + + inline uint getIndex() const { return index; } + // Get the index of this field within the containing struct or union. + + Type getType() const; + // Get the type of this field. Note that this is preferred over getProto().getType() as this + // method will apply generics. + + uint32_t getDefaultValueSchemaOffset() const; + // For struct, list, and object fields, returns the offset, in words, within the first segment of + // the struct's schema, where this field's default value pointer is located. The schema is + // always stored as a single-segment unchecked message, which in turn means that the default + // value pointer itself can be treated as the root of an unchecked message -- if you know where + // to find it, which is what this method helps you with. + // + // For blobs, returns the offset of the beginning of the blob's content within the first segment + // of the struct's schema. + // + // This is primarily useful for code generators. The C++ code generator, for example, embeds + // the entire schema as a raw word array within the generated code. Of course, to implement + // field accessors, it needs access to those fields' default values. Embedding separate copies + // of those default values would be redundant since they are already included in the schema, but + // seeking through the schema at runtime to find the default values would be ugly. Instead, + // the code generator can use getDefaultValueSchemaOffset() to find the offset of the default + // value within the schema, and can simply apply that offset at runtime. + // + // If the above does not make sense, you probably don't need this method. + + inline bool operator==(const Field& other) const; + inline bool operator!=(const Field& other) const { return !(*this == other); } + +private: + StructSchema parent; + uint index; + schema::Field::Reader proto; + + inline Field(StructSchema parent, uint index, schema::Field::Reader proto) + : parent(parent), index(index), proto(proto) {} + + friend class StructSchema; +}; + +kj::StringPtr KJ_STRINGIFY(const StructSchema::Field& field); + +class StructSchema::FieldList { +public: + FieldList() = default; // empty list + + inline uint size() const { return list.size(); } + inline Field operator[](uint index) const { return Field(parent, index, list[index]); } + + typedef _::IndexingIterator<const FieldList, Field> Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + +private: + StructSchema parent; + List<schema::Field>::Reader list; + + inline FieldList(StructSchema parent, List<schema::Field>::Reader list) + : parent(parent), list(list) {} + + friend class StructSchema; +}; + +class StructSchema::FieldSubset { +public: + FieldSubset() = default; // empty list + + inline uint size() const { return size_; } + inline Field operator[](uint index) const { + return Field(parent, indices[index], list[indices[index]]); + } + + typedef _::IndexingIterator<const FieldSubset, Field> Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + +private: + StructSchema parent; + List<schema::Field>::Reader list; + const uint16_t* indices; + uint size_; + + inline FieldSubset(StructSchema parent, List<schema::Field>::Reader list, + const uint16_t* indices, uint size) + : parent(parent), list(list), indices(indices), size_(size) {} + + friend class StructSchema; +}; + +// ------------------------------------------------------------------- + +class EnumSchema: public Schema { +public: + inline EnumSchema(): Schema(&_::NULL_ENUM_SCHEMA.defaultBrand) {} + + class Enumerant; + class EnumerantList; + + EnumerantList getEnumerants() const; + + kj::Maybe<Enumerant> findEnumerantByName(kj::StringPtr name) const; + + Enumerant getEnumerantByName(kj::StringPtr name) const; + // Like findEnumerantByName() but throws an exception on failure. + +private: + EnumSchema(Schema base): Schema(base) {} + template <typename T> static inline EnumSchema fromImpl() { + return EnumSchema(Schema(&_::rawBrandedSchema<T>())); + } + friend class Schema; + friend class Type; +}; + +class EnumSchema::Enumerant { +public: + Enumerant() = default; + + inline schema::Enumerant::Reader getProto() const { return proto; } + inline EnumSchema getContainingEnum() const { return parent; } + + inline uint16_t getOrdinal() const { return ordinal; } + inline uint getIndex() const { return ordinal; } + + inline bool operator==(const Enumerant& other) const; + inline bool operator!=(const Enumerant& other) const { return !(*this == other); } + +private: + EnumSchema parent; + uint16_t ordinal; + schema::Enumerant::Reader proto; + + inline Enumerant(EnumSchema parent, uint16_t ordinal, schema::Enumerant::Reader proto) + : parent(parent), ordinal(ordinal), proto(proto) {} + + friend class EnumSchema; +}; + +class EnumSchema::EnumerantList { +public: + EnumerantList() = default; // empty list + + inline uint size() const { return list.size(); } + inline Enumerant operator[](uint index) const { return Enumerant(parent, index, list[index]); } + + typedef _::IndexingIterator<const EnumerantList, Enumerant> Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + +private: + EnumSchema parent; + List<schema::Enumerant>::Reader list; + + inline EnumerantList(EnumSchema parent, List<schema::Enumerant>::Reader list) + : parent(parent), list(list) {} + + friend class EnumSchema; +}; + +// ------------------------------------------------------------------- + +class InterfaceSchema: public Schema { +public: + inline InterfaceSchema(): Schema(&_::NULL_INTERFACE_SCHEMA.defaultBrand) {} + + class Method; + class MethodList; + + MethodList getMethods() const; + + kj::Maybe<Method> findMethodByName(kj::StringPtr name) const; + + Method getMethodByName(kj::StringPtr name) const; + // Like findMethodByName() but throws an exception on failure. + + class SuperclassList; + + SuperclassList getSuperclasses() const; + // Get the immediate superclasses of this type, after applying generics. + + bool extends(InterfaceSchema other) const; + // Returns true if `other` is a superclass of this interface (including if `other == *this`). + + kj::Maybe<InterfaceSchema> findSuperclass(uint64_t typeId) const; + // Find the superclass of this interface with the given type ID. Returns null if the interface + // extends no such type. + +private: + InterfaceSchema(Schema base): Schema(base) {} + template <typename T> static inline InterfaceSchema fromImpl() { + return InterfaceSchema(Schema(&_::rawBrandedSchema<T>())); + } + friend class Schema; + friend class Type; + + kj::Maybe<Method> findMethodByName(kj::StringPtr name, uint& counter) const; + bool extends(InterfaceSchema other, uint& counter) const; + kj::Maybe<InterfaceSchema> findSuperclass(uint64_t typeId, uint& counter) const; + // We protect against malicious schemas with large or cyclic hierarchies by cutting off the + // search when the counter reaches a threshold. +}; + +class InterfaceSchema::Method { +public: + Method() = default; + + inline schema::Method::Reader getProto() const { return proto; } + inline InterfaceSchema getContainingInterface() const { return parent; } + + inline uint16_t getOrdinal() const { return ordinal; } + inline uint getIndex() const { return ordinal; } + + StructSchema getParamType() const; + StructSchema getResultType() const; + // Get the parameter and result types, including substituting generic parameters. + + inline bool operator==(const Method& other) const; + inline bool operator!=(const Method& other) const { return !(*this == other); } + +private: + InterfaceSchema parent; + uint16_t ordinal; + schema::Method::Reader proto; + + inline Method(InterfaceSchema parent, uint16_t ordinal, + schema::Method::Reader proto) + : parent(parent), ordinal(ordinal), proto(proto) {} + + friend class InterfaceSchema; +}; + +class InterfaceSchema::MethodList { +public: + MethodList() = default; // empty list + + inline uint size() const { return list.size(); } + inline Method operator[](uint index) const { return Method(parent, index, list[index]); } + + typedef _::IndexingIterator<const MethodList, Method> Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + +private: + InterfaceSchema parent; + List<schema::Method>::Reader list; + + inline MethodList(InterfaceSchema parent, List<schema::Method>::Reader list) + : parent(parent), list(list) {} + + friend class InterfaceSchema; +}; + +class InterfaceSchema::SuperclassList { +public: + SuperclassList() = default; // empty list + + inline uint size() const { return list.size(); } + InterfaceSchema operator[](uint index) const; + + typedef _::IndexingIterator<const SuperclassList, InterfaceSchema> Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + +private: + InterfaceSchema parent; + List<schema::Superclass>::Reader list; + + inline SuperclassList(InterfaceSchema parent, List<schema::Superclass>::Reader list) + : parent(parent), list(list) {} + + friend class InterfaceSchema; +}; + +// ------------------------------------------------------------------- + +class ConstSchema: public Schema { + // Represents a constant declaration. + // + // `ConstSchema` can be implicitly cast to DynamicValue to read its value. + +public: + inline ConstSchema(): Schema(&_::NULL_CONST_SCHEMA.defaultBrand) {} + + template <typename T> + ReaderFor<T> as() const; + // Read the constant's value. This is a convenience method equivalent to casting the ConstSchema + // to a DynamicValue and then calling its `as<T>()` method. For dependency reasons, this method + // is defined in <capnp/dynamic.h>, which you must #include explicitly. + + uint32_t getValueSchemaOffset() const; + // Much like StructSchema::Field::getDefaultValueSchemaOffset(), if the constant has pointer + // type, this gets the offset from the beginning of the constant's schema node to a pointer + // representing the constant value. + + Type getType() const; + +private: + ConstSchema(Schema base): Schema(base) {} + friend class Schema; +}; + +// ------------------------------------------------------------------- + +class Type { +public: + struct BrandParameter { + uint64_t scopeId; + uint index; + }; + struct ImplicitParameter { + uint index; + }; + + inline Type(); + inline Type(schema::Type::Which primitive); + inline Type(StructSchema schema); + inline Type(EnumSchema schema); + inline Type(InterfaceSchema schema); + inline Type(ListSchema schema); + inline Type(schema::Type::AnyPointer::Unconstrained::Which anyPointerKind); + inline Type(BrandParameter param); + inline Type(ImplicitParameter param); + + template <typename T> + inline static Type from(); + + inline schema::Type::Which which() const; + + StructSchema asStruct() const; + EnumSchema asEnum() const; + InterfaceSchema asInterface() const; + ListSchema asList() const; + // Each of these methods may only be called if which() returns the corresponding type. + + kj::Maybe<BrandParameter> getBrandParameter() const; + // Only callable if which() returns ANY_POINTER. Returns null if the type is just a regular + // AnyPointer and not a parameter. + + kj::Maybe<ImplicitParameter> getImplicitParameter() const; + // Only callable if which() returns ANY_POINTER. Returns null if the type is just a regular + // AnyPointer and not a parameter. "Implicit parameters" refer to type parameters on methods. + + inline schema::Type::AnyPointer::Unconstrained::Which whichAnyPointerKind() const; + // Only callable if which() returns ANY_POINTER. + + inline bool isVoid() const; + inline bool isBool() const; + inline bool isInt8() const; + inline bool isInt16() const; + inline bool isInt32() const; + inline bool isInt64() const; + inline bool isUInt8() const; + inline bool isUInt16() const; + inline bool isUInt32() const; + inline bool isUInt64() const; + inline bool isFloat32() const; + inline bool isFloat64() const; + inline bool isText() const; + inline bool isData() const; + inline bool isList() const; + inline bool isEnum() const; + inline bool isStruct() const; + inline bool isInterface() const; + inline bool isAnyPointer() const; + + bool operator==(const Type& other) const; + inline bool operator!=(const Type& other) const { return !(*this == other); } + + size_t hashCode() const; + + inline Type wrapInList(uint depth = 1) const; + // Return the Type formed by wrapping this type in List() `depth` times. + + inline Type(schema::Type::Which derived, const _::RawBrandedSchema* schema); + // For internal use. + +private: + schema::Type::Which baseType; // type not including applications of List() + uint8_t listDepth; // 0 for T, 1 for List(T), 2 for List(List(T)), ... + + bool isImplicitParam; + // If true, this refers to an implicit method parameter. baseType must be ANY_POINTER, scopeId + // must be zero, and paramIndex indicates the parameter index. + + union { + uint16_t paramIndex; + // If baseType is ANY_POINTER but this Type actually refers to a type parameter, this is the + // index of the parameter among the parameters at its scope, and `scopeId` below is the type ID + // of the scope where the parameter was defined. + + schema::Type::AnyPointer::Unconstrained::Which anyPointerKind; + // If scopeId is zero and isImplicitParam is false. + }; + + union { + const _::RawBrandedSchema* schema; // if type is struct, enum, interface... + uint64_t scopeId; // if type is AnyPointer but it's actually a type parameter... + }; + + Type(schema::Type::Which baseType, uint8_t listDepth, const _::RawBrandedSchema* schema) + : baseType(baseType), listDepth(listDepth), schema(schema) { + KJ_IREQUIRE(baseType != schema::Type::ANY_POINTER); + } + + void requireUsableAs(Type expected) const; + + friend class ListSchema; // only for requireUsableAs() +}; + +// ------------------------------------------------------------------- + +class ListSchema { + // ListSchema is a little different because list types are not described by schema nodes. So, + // ListSchema doesn't subclass Schema. + +public: + ListSchema() = default; + + static ListSchema of(schema::Type::Which primitiveType); + static ListSchema of(StructSchema elementType); + static ListSchema of(EnumSchema elementType); + static ListSchema of(InterfaceSchema elementType); + static ListSchema of(ListSchema elementType); + static ListSchema of(Type elementType); + // Construct the schema for a list of the given type. + + static ListSchema of(schema::Type::Reader elementType, Schema context) + KJ_DEPRECATED("Does not handle generics correctly."); + // DEPRECATED: This method cannot correctly account for generic type parameter bindings that + // may apply to the input type. Instead of using this method, use a method of the Schema API + // that corresponds to the exact kind of dependency. For example, to get a field type, use + // StructSchema::Field::getType(). + // + // Construct from an element type schema. Requires a context which can handle getDependency() + // requests for any type ID found in the schema. + + Type getElementType() const; + + inline schema::Type::Which whichElementType() const; + // Get the element type's "which()". ListSchema does not actually store a schema::Type::Reader + // describing the element type, but if it did, this would be equivalent to calling + // .getBody().which() on that type. + + StructSchema getStructElementType() const; + EnumSchema getEnumElementType() const; + InterfaceSchema getInterfaceElementType() const; + ListSchema getListElementType() const; + // Get the schema for complex element types. Each of these throws an exception if the element + // type is not of the requested kind. + + inline bool operator==(const ListSchema& other) const { return elementType == other.elementType; } + inline bool operator!=(const ListSchema& other) const { return elementType != other.elementType; } + + template <typename T> + void requireUsableAs() const; + +private: + Type elementType; + + inline explicit ListSchema(Type elementType): elementType(elementType) {} + + template <typename T> + struct FromImpl; + template <typename T> static inline ListSchema fromImpl() { + return FromImpl<T>::get(); + } + + void requireUsableAs(ListSchema expected) const; + + friend class Schema; +}; + +// ======================================================================================= +// inline implementation + +template <> inline schema::Type::Which Schema::from<Void>() { return schema::Type::VOID; } +template <> inline schema::Type::Which Schema::from<bool>() { return schema::Type::BOOL; } +template <> inline schema::Type::Which Schema::from<int8_t>() { return schema::Type::INT8; } +template <> inline schema::Type::Which Schema::from<int16_t>() { return schema::Type::INT16; } +template <> inline schema::Type::Which Schema::from<int32_t>() { return schema::Type::INT32; } +template <> inline schema::Type::Which Schema::from<int64_t>() { return schema::Type::INT64; } +template <> inline schema::Type::Which Schema::from<uint8_t>() { return schema::Type::UINT8; } +template <> inline schema::Type::Which Schema::from<uint16_t>() { return schema::Type::UINT16; } +template <> inline schema::Type::Which Schema::from<uint32_t>() { return schema::Type::UINT32; } +template <> inline schema::Type::Which Schema::from<uint64_t>() { return schema::Type::UINT64; } +template <> inline schema::Type::Which Schema::from<float>() { return schema::Type::FLOAT32; } +template <> inline schema::Type::Which Schema::from<double>() { return schema::Type::FLOAT64; } +template <> inline schema::Type::Which Schema::from<Text>() { return schema::Type::TEXT; } +template <> inline schema::Type::Which Schema::from<Data>() { return schema::Type::DATA; } + +inline Schema Schema::getDependency(uint64_t id) const { + return getDependency(id, 0); +} + +inline bool Schema::isBranded() const { + return raw != &raw->generic->defaultBrand; +} + +inline Schema Schema::getGeneric() const { + return Schema(&raw->generic->defaultBrand); +} + +template <typename T> +inline void Schema::requireUsableAs() const { + requireUsableAs(&_::rawSchema<T>()); +} + +inline bool StructSchema::Field::operator==(const Field& other) const { + return parent == other.parent && index == other.index; +} +inline bool EnumSchema::Enumerant::operator==(const Enumerant& other) const { + return parent == other.parent && ordinal == other.ordinal; +} +inline bool InterfaceSchema::Method::operator==(const Method& other) const { + return parent == other.parent && ordinal == other.ordinal; +} + +inline ListSchema ListSchema::of(StructSchema elementType) { + return ListSchema(Type(elementType)); +} +inline ListSchema ListSchema::of(EnumSchema elementType) { + return ListSchema(Type(elementType)); +} +inline ListSchema ListSchema::of(InterfaceSchema elementType) { + return ListSchema(Type(elementType)); +} +inline ListSchema ListSchema::of(ListSchema elementType) { + return ListSchema(Type(elementType)); +} +inline ListSchema ListSchema::of(Type elementType) { + return ListSchema(elementType); +} + +inline Type ListSchema::getElementType() const { + return elementType; +} + +inline schema::Type::Which ListSchema::whichElementType() const { + return elementType.which(); +} + +inline StructSchema ListSchema::getStructElementType() const { + return elementType.asStruct(); +} + +inline EnumSchema ListSchema::getEnumElementType() const { + return elementType.asEnum(); +} + +inline InterfaceSchema ListSchema::getInterfaceElementType() const { + return elementType.asInterface(); +} + +inline ListSchema ListSchema::getListElementType() const { + return elementType.asList(); +} + +template <typename T> +inline void ListSchema::requireUsableAs() const { + static_assert(kind<T>() == Kind::LIST, + "ListSchema::requireUsableAs<T>() requires T is a list type."); + requireUsableAs(Schema::from<T>()); +} + +inline void ListSchema::requireUsableAs(ListSchema expected) const { + elementType.requireUsableAs(expected.elementType); +} + +template <typename T> +struct ListSchema::FromImpl<List<T>> { + static inline ListSchema get() { return of(Schema::from<T>()); } +}; + +inline Type::Type(): baseType(schema::Type::VOID), listDepth(0), schema(nullptr) {} +inline Type::Type(schema::Type::Which primitive) + : baseType(primitive), listDepth(0), isImplicitParam(false) { + KJ_IREQUIRE(primitive != schema::Type::STRUCT && + primitive != schema::Type::ENUM && + primitive != schema::Type::INTERFACE && + primitive != schema::Type::LIST); + if (primitive == schema::Type::ANY_POINTER) { + scopeId = 0; + anyPointerKind = schema::Type::AnyPointer::Unconstrained::ANY_KIND; + } else { + schema = nullptr; + } +} +inline Type::Type(schema::Type::Which derived, const _::RawBrandedSchema* schema) + : baseType(derived), listDepth(0), isImplicitParam(false), schema(schema) { + KJ_IREQUIRE(derived == schema::Type::STRUCT || + derived == schema::Type::ENUM || + derived == schema::Type::INTERFACE); +} + +inline Type::Type(StructSchema schema) + : baseType(schema::Type::STRUCT), listDepth(0), schema(schema.raw) {} +inline Type::Type(EnumSchema schema) + : baseType(schema::Type::ENUM), listDepth(0), schema(schema.raw) {} +inline Type::Type(InterfaceSchema schema) + : baseType(schema::Type::INTERFACE), listDepth(0), schema(schema.raw) {} +inline Type::Type(ListSchema schema) + : Type(schema.getElementType()) { ++listDepth; } +inline Type::Type(schema::Type::AnyPointer::Unconstrained::Which anyPointerKind) + : baseType(schema::Type::ANY_POINTER), listDepth(0), isImplicitParam(false), + anyPointerKind(anyPointerKind), scopeId(0) {} +inline Type::Type(BrandParameter param) + : baseType(schema::Type::ANY_POINTER), listDepth(0), isImplicitParam(false), + paramIndex(param.index), scopeId(param.scopeId) {} +inline Type::Type(ImplicitParameter param) + : baseType(schema::Type::ANY_POINTER), listDepth(0), isImplicitParam(true), + paramIndex(param.index), scopeId(0) {} + +inline schema::Type::Which Type::which() const { + return listDepth > 0 ? schema::Type::LIST : baseType; +} + +inline schema::Type::AnyPointer::Unconstrained::Which Type::whichAnyPointerKind() const { + KJ_IREQUIRE(baseType == schema::Type::ANY_POINTER); + return !isImplicitParam && scopeId == 0 ? anyPointerKind + : schema::Type::AnyPointer::Unconstrained::ANY_KIND; +} + +template <typename T> +inline Type Type::from() { return Type(Schema::from<T>()); } + +inline bool Type::isVoid () const { return baseType == schema::Type::VOID && listDepth == 0; } +inline bool Type::isBool () const { return baseType == schema::Type::BOOL && listDepth == 0; } +inline bool Type::isInt8 () const { return baseType == schema::Type::INT8 && listDepth == 0; } +inline bool Type::isInt16 () const { return baseType == schema::Type::INT16 && listDepth == 0; } +inline bool Type::isInt32 () const { return baseType == schema::Type::INT32 && listDepth == 0; } +inline bool Type::isInt64 () const { return baseType == schema::Type::INT64 && listDepth == 0; } +inline bool Type::isUInt8 () const { return baseType == schema::Type::UINT8 && listDepth == 0; } +inline bool Type::isUInt16 () const { return baseType == schema::Type::UINT16 && listDepth == 0; } +inline bool Type::isUInt32 () const { return baseType == schema::Type::UINT32 && listDepth == 0; } +inline bool Type::isUInt64 () const { return baseType == schema::Type::UINT64 && listDepth == 0; } +inline bool Type::isFloat32() const { return baseType == schema::Type::FLOAT32 && listDepth == 0; } +inline bool Type::isFloat64() const { return baseType == schema::Type::FLOAT64 && listDepth == 0; } +inline bool Type::isText () const { return baseType == schema::Type::TEXT && listDepth == 0; } +inline bool Type::isData () const { return baseType == schema::Type::DATA && listDepth == 0; } +inline bool Type::isList () const { return listDepth > 0; } +inline bool Type::isEnum () const { return baseType == schema::Type::ENUM && listDepth == 0; } +inline bool Type::isStruct () const { return baseType == schema::Type::STRUCT && listDepth == 0; } +inline bool Type::isInterface() const { + return baseType == schema::Type::INTERFACE && listDepth == 0; +} +inline bool Type::isAnyPointer() const { + return baseType == schema::Type::ANY_POINTER && listDepth == 0; +} + +inline Type Type::wrapInList(uint depth) const { + Type result = *this; + result.listDepth += depth; + return result; +} + +} // namespace capnp + +#endif // CAPNP_SCHEMA_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/serialize-async.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,64 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef CAPNP_SERIALIZE_ASYNC_H_ +#define CAPNP_SERIALIZE_ASYNC_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include <kj/async-io.h> +#include "message.h" + +namespace capnp { + +kj::Promise<kj::Own<MessageReader>> readMessage( + kj::AsyncInputStream& input, ReaderOptions options = ReaderOptions(), + kj::ArrayPtr<word> scratchSpace = nullptr); +// Read a message asynchronously. +// +// `input` must remain valid until the returned promise resolves (or is canceled). +// +// `scratchSpace`, if provided, must remain valid until the returned MessageReader is destroyed. + +kj::Promise<kj::Maybe<kj::Own<MessageReader>>> tryReadMessage( + kj::AsyncInputStream& input, ReaderOptions options = ReaderOptions(), + kj::ArrayPtr<word> scratchSpace = nullptr); +// Like `readMessage` but returns null on EOF. + +kj::Promise<void> writeMessage(kj::AsyncOutputStream& output, + kj::ArrayPtr<const kj::ArrayPtr<const word>> segments) + KJ_WARN_UNUSED_RESULT; +kj::Promise<void> writeMessage(kj::AsyncOutputStream& output, MessageBuilder& builder) + KJ_WARN_UNUSED_RESULT; +// Write asynchronously. The parameters must remain valid until the returned promise resolves. + +// ======================================================================================= +// inline implementation details + +inline kj::Promise<void> writeMessage(kj::AsyncOutputStream& output, MessageBuilder& builder) { + return writeMessage(output, builder.getSegmentsForOutput()); +} + +} // namespace capnp + +#endif // CAPNP_SERIALIZE_ASYNC_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/serialize-packed.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,130 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef CAPNP_SERIALIZE_PACKED_H_ +#define CAPNP_SERIALIZE_PACKED_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "serialize.h" + +namespace capnp { + +namespace _ { // private + +class PackedInputStream: public kj::InputStream { + // An input stream that unpacks packed data with a picky constraint: The caller must read data + // in the exact same size and sequence as the data was written to PackedOutputStream. + +public: + explicit PackedInputStream(kj::BufferedInputStream& inner); + KJ_DISALLOW_COPY(PackedInputStream); + ~PackedInputStream() noexcept(false); + + // implements InputStream ------------------------------------------ + size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; + void skip(size_t bytes) override; + +private: + kj::BufferedInputStream& inner; +}; + +class PackedOutputStream: public kj::OutputStream { +public: + explicit PackedOutputStream(kj::BufferedOutputStream& inner); + KJ_DISALLOW_COPY(PackedOutputStream); + ~PackedOutputStream() noexcept(false); + + // implements OutputStream ----------------------------------------- + void write(const void* buffer, size_t bytes) override; + +private: + kj::BufferedOutputStream& inner; +}; + +} // namespace _ (private) + +class PackedMessageReader: private _::PackedInputStream, public InputStreamMessageReader { +public: + PackedMessageReader(kj::BufferedInputStream& inputStream, ReaderOptions options = ReaderOptions(), + kj::ArrayPtr<word> scratchSpace = nullptr); + KJ_DISALLOW_COPY(PackedMessageReader); + ~PackedMessageReader() noexcept(false); +}; + +class PackedFdMessageReader: private kj::FdInputStream, private kj::BufferedInputStreamWrapper, + public PackedMessageReader { +public: + PackedFdMessageReader(int fd, ReaderOptions options = ReaderOptions(), + kj::ArrayPtr<word> scratchSpace = nullptr); + // Read message from a file descriptor, without taking ownership of the descriptor. + // Note that if you want to reuse the descriptor after the reader is destroyed, you'll need to + // seek it, since otherwise the position is unspecified. + + PackedFdMessageReader(kj::AutoCloseFd fd, ReaderOptions options = ReaderOptions(), + kj::ArrayPtr<word> scratchSpace = nullptr); + // Read a message from a file descriptor, taking ownership of the descriptor. + + KJ_DISALLOW_COPY(PackedFdMessageReader); + + ~PackedFdMessageReader() noexcept(false); +}; + +void writePackedMessage(kj::BufferedOutputStream& output, MessageBuilder& builder); +void writePackedMessage(kj::BufferedOutputStream& output, + kj::ArrayPtr<const kj::ArrayPtr<const word>> segments); +// Write a packed message to a buffered output stream. + +void writePackedMessage(kj::OutputStream& output, MessageBuilder& builder); +void writePackedMessage(kj::OutputStream& output, + kj::ArrayPtr<const kj::ArrayPtr<const word>> segments); +// Write a packed message to an unbuffered output stream. If you intend to write multiple messages +// in succession, consider wrapping your output in a buffered stream in order to reduce system +// call overhead. + +void writePackedMessageToFd(int fd, MessageBuilder& builder); +void writePackedMessageToFd(int fd, kj::ArrayPtr<const kj::ArrayPtr<const word>> segments); +// Write a single packed message to the file descriptor. + +size_t computeUnpackedSizeInWords(kj::ArrayPtr<const byte> packedBytes); +// Computes the number of words to which the given packed bytes will unpack. Not intended for use +// in performance-sensitive situations. + +// ======================================================================================= +// inline stuff + +inline void writePackedMessage(kj::BufferedOutputStream& output, MessageBuilder& builder) { + writePackedMessage(output, builder.getSegmentsForOutput()); +} + +inline void writePackedMessage(kj::OutputStream& output, MessageBuilder& builder) { + writePackedMessage(output, builder.getSegmentsForOutput()); +} + +inline void writePackedMessageToFd(int fd, MessageBuilder& builder) { + writePackedMessageToFd(fd, builder.getSegmentsForOutput()); +} + +} // namespace capnp + +#endif // CAPNP_SERIALIZE_PACKED_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/serialize-text.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,96 @@ +// Copyright (c) 2015 Philip Quinn. +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef CAPNP_SERIALIZE_TEXT_H_ +#define CAPNP_SERIALIZE_TEXT_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include <kj/string.h> +#include "dynamic.h" +#include "orphan.h" +#include "schema.h" + +namespace capnp { + +class TextCodec { + // Reads and writes Cap'n Proto objects in a plain text format (as used in the schema + // language for constants, and read/written by the 'decode' and 'encode' commands of + // the capnp tool). + // + // This format is useful for debugging or human input, but it is not a robust alternative + // to the binary format. Changes to a schema's types or names that are permitted in a + // schema's binary evolution will likely break messages stored in this format. + // + // Note that definitions or references (to constants, other fields, or files) are not + // permitted in this format. To evaluate declarations with the full expressiveness of the + // schema language, see `capnp::SchemaParser`. + // + // Requires linking with the capnpc library. + +public: + TextCodec(); + ~TextCodec() noexcept(true); + + void setPrettyPrint(bool enabled); + // If enabled, pads the output of `encode()` with spaces and newlines to make it more + // human-readable. + + template <typename T> + kj::String encode(T&& value) const; + kj::String encode(DynamicValue::Reader value) const; + // Encode any Cap'n Proto value. + + template <typename T> + Orphan<T> decode(kj::StringPtr input, Orphanage orphanage) const; + // Decode a text message into a Cap'n Proto object of type T, allocated in the given + // orphanage. Any errors parsing the input or assigning the fields of T are thrown as + // exceptions. + + void decode(kj::StringPtr input, DynamicStruct::Builder output) const; + // Decode a text message for a struct into the given builder. Any errors parsing the + // input or assigning the fields of the output are thrown as exceptions. + + // TODO(someday): expose some control over the error handling? +private: + Orphan<DynamicValue> decode(kj::StringPtr input, Type type, Orphanage orphanage) const; + + bool prettyPrint; +}; + +// ======================================================================================= +// inline stuff + +template <typename T> +inline kj::String TextCodec::encode(T&& value) const { + return encode(DynamicValue::Reader(ReaderFor<FromAny<T>>(kj::fwd<T>(value)))); +} + +template <typename T> +inline Orphan<T> TextCodec::decode(kj::StringPtr input, Orphanage orphanage) const { + return decode(input, Type::from<T>(), orphanage).template releaseAs<T>(); +} + +} // namespace capnp + +#endif // CAPNP_SERIALIZE_TEXT_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/serialize.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,237 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// This file implements a simple serialization format for Cap'n Proto messages. The format +// is as follows: +// +// * 32-bit little-endian segment count (4 bytes). +// * 32-bit little-endian size of each segment (4*(segment count) bytes). +// * Padding so that subsequent data is 64-bit-aligned (0 or 4 bytes). (I.e., if there are an even +// number of segments, there are 4 bytes of zeros here, otherwise there is no padding.) +// * Data from each segment, in order (8*sum(segment sizes) bytes) +// +// This format has some important properties: +// - It is self-delimiting, so multiple messages may be written to a stream without any external +// delimiter. +// - The total size and position of each segment can be determined by reading only the first part +// of the message, allowing lazy and random-access reading of the segment data. +// - A message is always at least 8 bytes. +// - A single-segment message can be read entirely in two system calls with no buffering. +// - A multi-segment message can be read entirely in three system calls with no buffering. +// - The format is appropriate for mmap()ing since all data is aligned. + +#ifndef CAPNP_SERIALIZE_H_ +#define CAPNP_SERIALIZE_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include "message.h" +#include <kj/io.h> + +namespace capnp { + +class FlatArrayMessageReader: public MessageReader { + // Parses a message from a flat array. Note that it makes sense to use this together with mmap() + // for extremely fast parsing. + +public: + FlatArrayMessageReader(kj::ArrayPtr<const word> array, ReaderOptions options = ReaderOptions()); + // The array must remain valid until the MessageReader is destroyed. + + kj::ArrayPtr<const word> getSegment(uint id) override; + + const word* getEnd() const { return end; } + // Get a pointer just past the end of the message as determined by reading the message header. + // This could actually be before the end of the input array. This pointer is useful e.g. if + // you know that the input array has extra stuff appended after the message and you want to + // get at it. + +private: + // Optimize for single-segment case. + kj::ArrayPtr<const word> segment0; + kj::Array<kj::ArrayPtr<const word>> moreSegments; + const word* end; +}; + +kj::ArrayPtr<const word> initMessageBuilderFromFlatArrayCopy( + kj::ArrayPtr<const word> array, MessageBuilder& target, + ReaderOptions options = ReaderOptions()); +// Convenience function which reads a message using `FlatArrayMessageReader` then copies the +// content into the target `MessageBuilder`, verifying that the message structure is valid +// (although not necessarily that it matches the desired schema). +// +// Returns an ArrayPtr containing any words left over in the array after consuming the whole +// message. This is useful when reading multiple messages that have been concatenated. See also +// FlatArrayMessageReader::getEnd(). +// +// (Note that it's also possible to initialize a `MessageBuilder` directly without a copy using one +// of `MessageBuilder`'s constructors. However, this approach skips the validation step and is not +// safe to use on untrusted input. Therefore, we do not provide a convenience method for it.) + +kj::Array<word> messageToFlatArray(MessageBuilder& builder); +// Constructs a flat array containing the entire content of the given message. +// +// To output the message as bytes, use `.asBytes()` on the returned word array. Keep in mind that +// `asBytes()` returns an ArrayPtr, so you have to save the Array as well to prevent it from being +// deleted. For example: +// +// kj::Array<capnp::word> words = messageToFlatArray(myMessage); +// kj::ArrayPtr<kj::byte> bytes = words.asBytes(); +// write(fd, bytes.begin(), bytes.size()); + +kj::Array<word> messageToFlatArray(kj::ArrayPtr<const kj::ArrayPtr<const word>> segments); +// Version of messageToFlatArray that takes a raw segment array. + +size_t computeSerializedSizeInWords(MessageBuilder& builder); +// Returns the size, in words, that will be needed to serialize the message, including the header. + +size_t computeSerializedSizeInWords(kj::ArrayPtr<const kj::ArrayPtr<const word>> segments); +// Version of computeSerializedSizeInWords that takes a raw segment array. + +size_t expectedSizeInWordsFromPrefix(kj::ArrayPtr<const word> messagePrefix); +// Given a prefix of a serialized message, try to determine the expected total size of the message, +// in words. The returned size is based on the information known so far; it may be an underestimate +// if the prefix doesn't contain the full segment table. +// +// If the returned value is greater than `messagePrefix.size()`, then the message is not yet +// complete and the app cannot parse it yet. If the returned value is less than or equal to +// `messagePrefix.size()`, then the returned value is the exact total size of the message; any +// remaining bytes are part of the next message. +// +// This function is useful when reading messages from a stream in an asynchronous way, but when +// using the full KJ async infrastructure would be too difficult. Each time bytes are received, +// use this function to determine if an entire message is ready to be parsed. + +// ======================================================================================= + +class InputStreamMessageReader: public MessageReader { + // A MessageReader that reads from an abstract kj::InputStream. See also StreamFdMessageReader + // for a subclass specific to file descriptors. + +public: + InputStreamMessageReader(kj::InputStream& inputStream, + ReaderOptions options = ReaderOptions(), + kj::ArrayPtr<word> scratchSpace = nullptr); + ~InputStreamMessageReader() noexcept(false); + + // implements MessageReader ---------------------------------------- + kj::ArrayPtr<const word> getSegment(uint id) override; + +private: + kj::InputStream& inputStream; + byte* readPos; + + // Optimize for single-segment case. + kj::ArrayPtr<const word> segment0; + kj::Array<kj::ArrayPtr<const word>> moreSegments; + + kj::Array<word> ownedSpace; + // Only if scratchSpace wasn't big enough. + + kj::UnwindDetector unwindDetector; +}; + +void readMessageCopy(kj::InputStream& input, MessageBuilder& target, + ReaderOptions options = ReaderOptions(), + kj::ArrayPtr<word> scratchSpace = nullptr); +// Convenience function which reads a message using `InputStreamMessageReader` then copies the +// content into the target `MessageBuilder`, verifying that the message structure is valid +// (although not necessarily that it matches the desired schema). +// +// (Note that it's also possible to initialize a `MessageBuilder` directly without a copy using one +// of `MessageBuilder`'s constructors. However, this approach skips the validation step and is not +// safe to use on untrusted input. Therefore, we do not provide a convenience method for it.) + +void writeMessage(kj::OutputStream& output, MessageBuilder& builder); +// Write the message to the given output stream. + +void writeMessage(kj::OutputStream& output, kj::ArrayPtr<const kj::ArrayPtr<const word>> segments); +// Write the segment array to the given output stream. + +// ======================================================================================= +// Specializations for reading from / writing to file descriptors. + +class StreamFdMessageReader: private kj::FdInputStream, public InputStreamMessageReader { + // A MessageReader that reads from a steam-based file descriptor. + +public: + StreamFdMessageReader(int fd, ReaderOptions options = ReaderOptions(), + kj::ArrayPtr<word> scratchSpace = nullptr) + : FdInputStream(fd), InputStreamMessageReader(*this, options, scratchSpace) {} + // Read message from a file descriptor, without taking ownership of the descriptor. + + StreamFdMessageReader(kj::AutoCloseFd fd, ReaderOptions options = ReaderOptions(), + kj::ArrayPtr<word> scratchSpace = nullptr) + : FdInputStream(kj::mv(fd)), InputStreamMessageReader(*this, options, scratchSpace) {} + // Read a message from a file descriptor, taking ownership of the descriptor. + + ~StreamFdMessageReader() noexcept(false); +}; + +void readMessageCopyFromFd(int fd, MessageBuilder& target, + ReaderOptions options = ReaderOptions(), + kj::ArrayPtr<word> scratchSpace = nullptr); +// Convenience function which reads a message using `StreamFdMessageReader` then copies the +// content into the target `MessageBuilder`, verifying that the message structure is valid +// (although not necessarily that it matches the desired schema). +// +// (Note that it's also possible to initialize a `MessageBuilder` directly without a copy using one +// of `MessageBuilder`'s constructors. However, this approach skips the validation step and is not +// safe to use on untrusted input. Therefore, we do not provide a convenience method for it.) + +void writeMessageToFd(int fd, MessageBuilder& builder); +// Write the message to the given file descriptor. +// +// This function throws an exception on any I/O error. If your code is not exception-safe, be sure +// you catch this exception at the call site. If throwing an exception is not acceptable, you +// can implement your own OutputStream with arbitrary error handling and then use writeMessage(). + +void writeMessageToFd(int fd, kj::ArrayPtr<const kj::ArrayPtr<const word>> segments); +// Write the segment array to the given file descriptor. +// +// This function throws an exception on any I/O error. If your code is not exception-safe, be sure +// you catch this exception at the call site. If throwing an exception is not acceptable, you +// can implement your own OutputStream with arbitrary error handling and then use writeMessage(). + +// ======================================================================================= +// inline stuff + +inline kj::Array<word> messageToFlatArray(MessageBuilder& builder) { + return messageToFlatArray(builder.getSegmentsForOutput()); +} + +inline size_t computeSerializedSizeInWords(MessageBuilder& builder) { + return computeSerializedSizeInWords(builder.getSegmentsForOutput()); +} + +inline void writeMessage(kj::OutputStream& output, MessageBuilder& builder) { + writeMessage(output, builder.getSegmentsForOutput()); +} + +inline void writeMessageToFd(int fd, MessageBuilder& builder) { + writeMessageToFd(fd, builder.getSegmentsForOutput()); +} + +} // namespace capnp + +#endif // SERIALIZE_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/test-import.capnp Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,28 @@ +# Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +# Licensed under the MIT License: +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +@0xf36d7b330303c66e; + +using Test = import "test.capnp"; + +struct TestImport { + field @0 :Test.TestAllTypes; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/test-import2.capnp Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,32 @@ +# Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +# Licensed under the MIT License: +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +@0xc64a3bf0338a124a; + +using Import1 = import "/capnp/schema.capnp"; +using Import2 = import "test-import.capnp"; +using Import3 = import "test.capnp"; + +struct TestImport2 { + foo @0 :Import3.TestAllTypes; + bar @1 :Import1.Node; + baz @2 :Import2.TestImport; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/test-util.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,323 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef CAPNP_TEST_UTIL_H_ +#define CAPNP_TEST_UTIL_H_ + +#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) +#pragma GCC system_header +#endif + +#include <capnp/test.capnp.h> +#include <iostream> +#include "blob.h" +#include <kj/compat/gtest.h> + +#if !CAPNP_LITE +#include "dynamic.h" +#endif // !CAPNP_LITE + +#if KJ_NO_EXCEPTIONS +#undef EXPECT_ANY_THROW +#define EXPECT_ANY_THROW(code) EXPECT_DEATH(code, ".") +#endif + +#define EXPECT_NONFATAL_FAILURE(code) \ + EXPECT_TRUE(kj::runCatchingExceptions([&]() { code; }) != nullptr); + +#ifdef KJ_DEBUG +#define EXPECT_DEBUG_ANY_THROW EXPECT_ANY_THROW +#else +#define EXPECT_DEBUG_ANY_THROW(EXP) +#endif + +// TODO(cleanup): Auto-generate stringification functions for union discriminants. +namespace capnproto_test { +namespace capnp { +namespace test { +inline kj::String KJ_STRINGIFY(TestUnion::Union0::Which which) { + return kj::str(static_cast<uint16_t>(which)); +} +inline kj::String KJ_STRINGIFY(TestUnion::Union1::Which which) { + return kj::str(static_cast<uint16_t>(which)); +} +inline kj::String KJ_STRINGIFY(TestUnion::Union2::Which which) { + return kj::str(static_cast<uint16_t>(which)); +} +inline kj::String KJ_STRINGIFY(TestUnion::Union3::Which which) { + return kj::str(static_cast<uint16_t>(which)); +} +inline kj::String KJ_STRINGIFY(TestUnnamedUnion::Which which) { + return kj::str(static_cast<uint16_t>(which)); +} +inline kj::String KJ_STRINGIFY(TestGroups::Groups::Which which) { + return kj::str(static_cast<uint16_t>(which)); +} +inline kj::String KJ_STRINGIFY(TestInterleavedGroups::Group1::Which which) { + return kj::str(static_cast<uint16_t>(which)); +} +} // namespace test +} // namespace capnp +} // namespace capnproto_test + +namespace capnp { +namespace _ { // private + +inline Data::Reader data(const char* str) { + return Data::Reader(reinterpret_cast<const byte*>(str), strlen(str)); +} + +namespace test = capnproto_test::capnp::test; + +// We don't use "using namespace" to pull these in because then things would still compile +// correctly if they were generated in the global namespace. +using ::capnproto_test::capnp::test::TestAllTypes; +using ::capnproto_test::capnp::test::TestDefaults; +using ::capnproto_test::capnp::test::TestEnum; +using ::capnproto_test::capnp::test::TestUnion; +using ::capnproto_test::capnp::test::TestUnionDefaults; +using ::capnproto_test::capnp::test::TestNestedTypes; +using ::capnproto_test::capnp::test::TestUsing; +using ::capnproto_test::capnp::test::TestListDefaults; + +void initTestMessage(TestAllTypes::Builder builder); +void initTestMessage(TestDefaults::Builder builder); +void initTestMessage(TestListDefaults::Builder builder); + +void checkTestMessage(TestAllTypes::Builder builder); +void checkTestMessage(TestDefaults::Builder builder); +void checkTestMessage(TestListDefaults::Builder builder); + +void checkTestMessage(TestAllTypes::Reader reader); +void checkTestMessage(TestDefaults::Reader reader); +void checkTestMessage(TestListDefaults::Reader reader); + +void checkTestMessageAllZero(TestAllTypes::Builder builder); +void checkTestMessageAllZero(TestAllTypes::Reader reader); + +#if !CAPNP_LITE +void initDynamicTestMessage(DynamicStruct::Builder builder); +void initDynamicTestLists(DynamicStruct::Builder builder); +void checkDynamicTestMessage(DynamicStruct::Builder builder); +void checkDynamicTestLists(DynamicStruct::Builder builder); +void checkDynamicTestMessage(DynamicStruct::Reader reader); +void checkDynamicTestLists(DynamicStruct::Reader reader); +void checkDynamicTestMessageAllZero(DynamicStruct::Builder builder); +void checkDynamicTestMessageAllZero(DynamicStruct::Reader reader); +#endif // !CAPNP_LITE + +template <typename T> +inline void checkElement(T a, T b) { + EXPECT_EQ(a, b); +} + +template <> +inline void checkElement<float>(float a, float b) { + EXPECT_FLOAT_EQ(a, b); +} + +template <> +inline void checkElement<double>(double a, double b) { + EXPECT_DOUBLE_EQ(a, b); +} + +template <typename T, typename L = typename T::Reads> +void checkList(T reader, std::initializer_list<decltype(reader[0])> expected) { + ASSERT_EQ(expected.size(), reader.size()); + for (uint i = 0; i < expected.size(); i++) { + checkElement<decltype(reader[0])>(expected.begin()[i], reader[i]); + } +} + +template <typename T, typename L = typename T::Builds, bool = false> +void checkList(T reader, std::initializer_list<decltype(typename L::Reader()[0])> expected) { + ASSERT_EQ(expected.size(), reader.size()); + for (uint i = 0; i < expected.size(); i++) { + checkElement<decltype(typename L::Reader()[0])>(expected.begin()[i], reader[i]); + } +} + +inline void checkList(List<test::TestOldVersion>::Reader reader, + std::initializer_list<int64_t> expectedData, + std::initializer_list<Text::Reader> expectedPointers) { + ASSERT_EQ(expectedData.size(), reader.size()); + for (uint i = 0; i < expectedData.size(); i++) { + EXPECT_EQ(expectedData.begin()[i], reader[i].getOld1()); + EXPECT_EQ(expectedPointers.begin()[i], reader[i].getOld2()); + } +} + +// Hack because as<>() is a template-parameter-dependent lookup everywhere below... +#define as template as + +template <typename T> void expectPrimitiveEq(T a, T b) { EXPECT_EQ(a, b); } +inline void expectPrimitiveEq(float a, float b) { EXPECT_FLOAT_EQ(a, b); } +inline void expectPrimitiveEq(double a, double b) { EXPECT_DOUBLE_EQ(a, b); } +inline void expectPrimitiveEq(Text::Reader a, Text::Builder b) { EXPECT_EQ(a, b); } +inline void expectPrimitiveEq(Data::Reader a, Data::Builder b) { EXPECT_EQ(a, b); } + +#if !CAPNP_LITE +template <typename Element, typename T> +void checkList(T reader, std::initializer_list<ReaderFor<Element>> expected) { + auto list = reader.as<DynamicList>(); + ASSERT_EQ(expected.size(), list.size()); + for (uint i = 0; i < expected.size(); i++) { + expectPrimitiveEq(expected.begin()[i], list[i].as<Element>()); + } + + auto typed = reader.as<List<Element>>(); + ASSERT_EQ(expected.size(), typed.size()); + for (uint i = 0; i < expected.size(); i++) { + expectPrimitiveEq(expected.begin()[i], typed[i]); + } +} +#endif // !CAPNP_LITE + +#undef as + +// ======================================================================================= +// Interface implementations. + +#if !CAPNP_LITE + +class TestInterfaceImpl final: public test::TestInterface::Server { +public: + TestInterfaceImpl(int& callCount); + + kj::Promise<void> foo(FooContext context) override; + + kj::Promise<void> baz(BazContext context) override; + +private: + int& callCount; +}; + +class TestExtendsImpl final: public test::TestExtends2::Server { +public: + TestExtendsImpl(int& callCount); + + kj::Promise<void> foo(FooContext context) override; + + kj::Promise<void> grault(GraultContext context) override; + +private: + int& callCount; +}; + +class TestPipelineImpl final: public test::TestPipeline::Server { +public: + TestPipelineImpl(int& callCount); + + kj::Promise<void> getCap(GetCapContext context) override; + +private: + int& callCount; +}; + +class TestCallOrderImpl final: public test::TestCallOrder::Server { +public: + kj::Promise<void> getCallSequence(GetCallSequenceContext context) override; + +private: + uint count = 0; +}; + +class TestTailCallerImpl final: public test::TestTailCaller::Server { +public: + TestTailCallerImpl(int& callCount); + + kj::Promise<void> foo(FooContext context) override; + +private: + int& callCount; +}; + +class TestTailCalleeImpl final: public test::TestTailCallee::Server { +public: + TestTailCalleeImpl(int& callCount); + + kj::Promise<void> foo(FooContext context) override; + +private: + int& callCount; +}; + +class TestMoreStuffImpl final: public test::TestMoreStuff::Server { +public: + TestMoreStuffImpl(int& callCount, int& handleCount); + + kj::Promise<void> getCallSequence(GetCallSequenceContext context) override; + + kj::Promise<void> callFoo(CallFooContext context) override; + + kj::Promise<void> callFooWhenResolved(CallFooWhenResolvedContext context) override; + + kj::Promise<void> neverReturn(NeverReturnContext context) override; + + kj::Promise<void> hold(HoldContext context) override; + + kj::Promise<void> callHeld(CallHeldContext context) override; + + kj::Promise<void> getHeld(GetHeldContext context) override; + + kj::Promise<void> echo(EchoContext context) override; + + kj::Promise<void> expectCancel(ExpectCancelContext context) override; + + kj::Promise<void> getHandle(GetHandleContext context) override; + + kj::Promise<void> getNull(GetNullContext context) override; + +private: + int& callCount; + int& handleCount; + test::TestInterface::Client clientToHold = nullptr; + + kj::Promise<void> loop(uint depth, test::TestInterface::Client cap, ExpectCancelContext context); +}; + +class TestCapDestructor final: public test::TestInterface::Server { + // Implementation of TestInterface that notifies when it is destroyed. + +public: + TestCapDestructor(kj::Own<kj::PromiseFulfiller<void>>&& fulfiller) + : fulfiller(kj::mv(fulfiller)), impl(dummy) {} + + ~TestCapDestructor() { + fulfiller->fulfill(); + } + + kj::Promise<void> foo(FooContext context) { + return impl.foo(context); + } + +private: + kj::Own<kj::PromiseFulfiller<void>> fulfiller; + int dummy = 0; + TestInterfaceImpl impl; +}; + +#endif // !CAPNP_LITE + +} // namespace _ (private) +} // namespace capnp + +#endif // TEST_UTIL_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/capnp/test.capnp Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,931 @@ +# Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +# Licensed under the MIT License: +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +@0xd508eebdc2dc42b8; + +using Cxx = import "c++.capnp"; + +# Use a namespace likely to cause trouble if the generated code doesn't use fully-qualified +# names for stuff in the capnproto namespace. +$Cxx.namespace("capnproto_test::capnp::test"); + +enum TestEnum { + foo @0; + bar @1; + baz @2; + qux @3; + quux @4; + corge @5; + grault @6; + garply @7; +} + +struct TestAllTypes { + voidField @0 : Void; + boolField @1 : Bool; + int8Field @2 : Int8; + int16Field @3 : Int16; + int32Field @4 : Int32; + int64Field @5 : Int64; + uInt8Field @6 : UInt8; + uInt16Field @7 : UInt16; + uInt32Field @8 : UInt32; + uInt64Field @9 : UInt64; + float32Field @10 : Float32; + float64Field @11 : Float64; + textField @12 : Text; + dataField @13 : Data; + structField @14 : TestAllTypes; + enumField @15 : TestEnum; + interfaceField @16 : Void; # TODO + + voidList @17 : List(Void); + boolList @18 : List(Bool); + int8List @19 : List(Int8); + int16List @20 : List(Int16); + int32List @21 : List(Int32); + int64List @22 : List(Int64); + uInt8List @23 : List(UInt8); + uInt16List @24 : List(UInt16); + uInt32List @25 : List(UInt32); + uInt64List @26 : List(UInt64); + float32List @27 : List(Float32); + float64List @28 : List(Float64); + textList @29 : List(Text); + dataList @30 : List(Data); + structList @31 : List(TestAllTypes); + enumList @32 : List(TestEnum); + interfaceList @33 : List(Void); # TODO +} + +struct TestDefaults { + voidField @0 : Void = void; + boolField @1 : Bool = true; + int8Field @2 : Int8 = -123; + int16Field @3 : Int16 = -12345; + int32Field @4 : Int32 = -12345678; + int64Field @5 : Int64 = -123456789012345; + uInt8Field @6 : UInt8 = 234; + uInt16Field @7 : UInt16 = 45678; + uInt32Field @8 : UInt32 = 3456789012; + uInt64Field @9 : UInt64 = 12345678901234567890; + float32Field @10 : Float32 = 1234.5; + float64Field @11 : Float64 = -123e45; + textField @12 : Text = "foo"; + dataField @13 : Data = 0x"62 61 72"; # "bar" + structField @14 : TestAllTypes = ( + voidField = void, + boolField = true, + int8Field = -12, + int16Field = 3456, + int32Field = -78901234, + int64Field = 56789012345678, + uInt8Field = 90, + uInt16Field = 1234, + uInt32Field = 56789012, + uInt64Field = 345678901234567890, + float32Field = -1.25e-10, + float64Field = 345, + textField = "baz", + dataField = "qux", + structField = ( + textField = "nested", + structField = (textField = "really nested")), + enumField = baz, + # interfaceField can't have a default + + voidList = [void, void, void], + boolList = [false, true, false, true, true], + int8List = [12, -34, -0x80, 0x7f], + int16List = [1234, -5678, -0x8000, 0x7fff], + int32List = [12345678, -90123456, -0x80000000, 0x7fffffff], + int64List = [123456789012345, -678901234567890, -0x8000000000000000, 0x7fffffffffffffff], + uInt8List = [12, 34, 0, 0xff], + uInt16List = [1234, 5678, 0, 0xffff], + uInt32List = [12345678, 90123456, 0, 0xffffffff], + uInt64List = [123456789012345, 678901234567890, 0, 0xffffffffffffffff], + float32List = [0, 1234567, 1e37, -1e37, 1e-37, -1e-37], + float64List = [0, 123456789012345, 1e306, -1e306, 1e-306, -1e-306], + textList = ["quux", "corge", "grault"], + dataList = ["garply", "waldo", "fred"], + structList = [ + (textField = "x structlist 1"), + (textField = "x structlist 2"), + (textField = "x structlist 3")], + enumList = [qux, bar, grault] + # interfaceList can't have a default + ); + enumField @15 : TestEnum = corge; + interfaceField @16 : Void; # TODO + + voidList @17 : List(Void) = [void, void, void, void, void, void]; + boolList @18 : List(Bool) = [true, false, false, true]; + int8List @19 : List(Int8) = [111, -111]; + int16List @20 : List(Int16) = [11111, -11111]; + int32List @21 : List(Int32) = [111111111, -111111111]; + int64List @22 : List(Int64) = [1111111111111111111, -1111111111111111111]; + uInt8List @23 : List(UInt8) = [111, 222] ; + uInt16List @24 : List(UInt16) = [33333, 44444]; + uInt32List @25 : List(UInt32) = [3333333333]; + uInt64List @26 : List(UInt64) = [11111111111111111111]; + float32List @27 : List(Float32) = [5555.5, inf, -inf, nan]; + float64List @28 : List(Float64) = [7777.75, inf, -inf, nan]; + textList @29 : List(Text) = ["plugh", "xyzzy", "thud"]; + dataList @30 : List(Data) = ["oops", "exhausted", "rfc3092"]; + structList @31 : List(TestAllTypes) = [ + (textField = "structlist 1"), + (textField = "structlist 2"), + (textField = "structlist 3")]; + enumList @32 : List(TestEnum) = [foo, garply]; + interfaceList @33 : List(Void); # TODO +} + +struct TestAnyPointer { + anyPointerField @0 :AnyPointer; + + # Do not add any other fields here! Some tests rely on anyPointerField being the last pointer + # in the struct. +} + +struct TestAnyOthers { + anyStructField @0 :AnyStruct; + anyListField @1 :AnyList; + capabilityField @2 :Capability; +} + +struct TestOutOfOrder { + foo @3 :Text; + bar @2 :Text; + baz @8 :Text; + qux @0 :Text; + quux @6 :Text; + corge @4 :Text; + grault @1 :Text; + garply @7 :Text; + waldo @5 :Text; +} + +struct TestUnion { + union0 @0! :union { + # Pack union 0 under ideal conditions: there is no unused padding space prior to it. + u0f0s0 @4: Void; + u0f0s1 @5: Bool; + u0f0s8 @6: Int8; + u0f0s16 @7: Int16; + u0f0s32 @8: Int32; + u0f0s64 @9: Int64; + u0f0sp @10: Text; + + # Pack more stuff into union0 -- should go in same space. + u0f1s0 @11: Void; + u0f1s1 @12: Bool; + u0f1s8 @13: Int8; + u0f1s16 @14: Int16; + u0f1s32 @15: Int32; + u0f1s64 @16: Int64; + u0f1sp @17: Text; + } + + # Pack one bit in order to make pathological situation for union1. + bit0 @18: Bool; + + union1 @1! :union { + # Pack pathologically bad case. Each field takes up new space. + u1f0s0 @19: Void; + u1f0s1 @20: Bool; + u1f1s1 @21: Bool; + u1f0s8 @22: Int8; + u1f1s8 @23: Int8; + u1f0s16 @24: Int16; + u1f1s16 @25: Int16; + u1f0s32 @26: Int32; + u1f1s32 @27: Int32; + u1f0s64 @28: Int64; + u1f1s64 @29: Int64; + u1f0sp @30: Text; + u1f1sp @31: Text; + + # Pack more stuff into union1 -- each should go into the same space as corresponding u1f0s*. + u1f2s0 @32: Void; + u1f2s1 @33: Bool; + u1f2s8 @34: Int8; + u1f2s16 @35: Int16; + u1f2s32 @36: Int32; + u1f2s64 @37: Int64; + u1f2sp @38: Text; + } + + # Fill in the rest of that bitfield from earlier. + bit2 @39: Bool; + bit3 @40: Bool; + bit4 @41: Bool; + bit5 @42: Bool; + bit6 @43: Bool; + bit7 @44: Bool; + + # Interleave two unions to be really annoying. + # Also declare in reverse order to make sure union discriminant values are sorted by field number + # and not by declaration order. + union2 @2! :union { + u2f0s64 @54: Int64; + u2f0s32 @52: Int32; + u2f0s16 @50: Int16; + u2f0s8 @47: Int8; + u2f0s1 @45: Bool; + } + + union3 @3! :union { + u3f0s64 @55: Int64; + u3f0s32 @53: Int32; + u3f0s16 @51: Int16; + u3f0s8 @48: Int8; + u3f0s1 @46: Bool; + } + + byte0 @49: UInt8; +} + +struct TestUnnamedUnion { + before @0 :Text; + + union { + foo @1 :UInt16; + bar @3 :UInt32; + } + + middle @2 :UInt16; + + after @4 :Text; +} + +struct TestUnionInUnion { + # There is no reason to ever do this. + outer :union { + inner :union { + foo @0 :Int32; + bar @1 :Int32; + } + baz @2 :Int32; + } +} + +struct TestGroups { + groups :union { + foo :group { + corge @0 :Int32; + grault @2 :Int64; + garply @8 :Text; + } + bar :group { + corge @3 :Int32; + grault @4 :Text; + garply @5 :Int64; + } + baz :group { + corge @1 :Int32; + grault @6 :Text; + garply @7 :Text; + } + } +} + +struct TestInterleavedGroups { + group1 :group { + foo @0 :UInt32; + bar @2 :UInt64; + union { + qux @4 :UInt16; + corge :group { + grault @6 :UInt64; + garply @8 :UInt16; + plugh @14 :Text; + xyzzy @16 :Text; + } + + fred @12 :Text; + } + + waldo @10 :Text; + } + + group2 :group { + foo @1 :UInt32; + bar @3 :UInt64; + union { + qux @5 :UInt16; + corge :group { + grault @7 :UInt64; + garply @9 :UInt16; + plugh @15 :Text; + xyzzy @17 :Text; + } + + fred @13 :Text; + } + + waldo @11 :Text; + } +} + +struct TestUnionDefaults { + s16s8s64s8Set @0 :TestUnion = + (union0 = (u0f0s16 = 321), union1 = (u1f0s8 = 123), union2 = (u2f0s64 = 12345678901234567), + union3 = (u3f0s8 = 55)); + s0sps1s32Set @1 :TestUnion = + (union0 = (u0f1s0 = void), union1 = (u1f0sp = "foo"), union2 = (u2f0s1 = true), + union3 = (u3f0s32 = 12345678)); + + unnamed1 @2 :TestUnnamedUnion = (foo = 123); + unnamed2 @3 :TestUnnamedUnion = (bar = 321, before = "foo", after = "bar"); +} + +struct TestNestedTypes { + enum NestedEnum { + foo @0; + bar @1; + } + + struct NestedStruct { + enum NestedEnum { + baz @0; + qux @1; + quux @2; + } + + outerNestedEnum @0 :TestNestedTypes.NestedEnum = bar; + innerNestedEnum @1 :NestedEnum = quux; + } + + nestedStruct @0 :NestedStruct; + + outerNestedEnum @1 :NestedEnum = bar; + innerNestedEnum @2 :NestedStruct.NestedEnum = quux; +} + +struct TestUsing { + using OuterNestedEnum = TestNestedTypes.NestedEnum; + using TestNestedTypes.NestedStruct.NestedEnum; + + outerNestedEnum @1 :OuterNestedEnum = bar; + innerNestedEnum @0 :NestedEnum = quux; +} + +struct TestLists { + # Small structs, when encoded as list, will be encoded as primitive lists rather than struct + # lists, to save space. + struct Struct0 { f @0 :Void; } + struct Struct1 { f @0 :Bool; } + struct Struct8 { f @0 :UInt8; } + struct Struct16 { f @0 :UInt16; } + struct Struct32 { f @0 :UInt32; } + struct Struct64 { f @0 :UInt64; } + struct StructP { f @0 :Text; } + + # Versions of the above which cannot be encoded as primitive lists. + struct Struct0c { f @0 :Void; pad @1 :Text; } + struct Struct1c { f @0 :Bool; pad @1 :Text; } + struct Struct8c { f @0 :UInt8; pad @1 :Text; } + struct Struct16c { f @0 :UInt16; pad @1 :Text; } + struct Struct32c { f @0 :UInt32; pad @1 :Text; } + struct Struct64c { f @0 :UInt64; pad @1 :Text; } + struct StructPc { f @0 :Text; pad @1 :UInt64; } + + list0 @0 :List(Struct0); + list1 @1 :List(Struct1); + list8 @2 :List(Struct8); + list16 @3 :List(Struct16); + list32 @4 :List(Struct32); + list64 @5 :List(Struct64); + listP @6 :List(StructP); + + int32ListList @7 :List(List(Int32)); + textListList @8 :List(List(Text)); + structListList @9 :List(List(TestAllTypes)); +} + +struct TestFieldZeroIsBit { + bit @0 :Bool; + secondBit @1 :Bool = true; + thirdField @2 :UInt8 = 123; +} + +struct TestListDefaults { + lists @0 :TestLists = ( + list0 = [(f = void), (f = void)], + list1 = [(f = true), (f = false), (f = true), (f = true)], + list8 = [(f = 123), (f = 45)], + list16 = [(f = 12345), (f = 6789)], + list32 = [(f = 123456789), (f = 234567890)], + list64 = [(f = 1234567890123456), (f = 2345678901234567)], + listP = [(f = "foo"), (f = "bar")], + int32ListList = [[1, 2, 3], [4, 5], [12341234]], + textListList = [["foo", "bar"], ["baz"], ["qux", "corge"]], + structListList = [[(int32Field = 123), (int32Field = 456)], [(int32Field = 789)]]); +} + +struct TestLateUnion { + # Test what happens if the unions are not the first ordinals in the struct. At one point this + # was broken for the dynamic API. + + foo @0 :Int32; + bar @1 :Text; + baz @2 :Int16; + + theUnion @3! :union { + qux @4 :Text; + corge @5 :List(Int32); + grault @6 :Float32; + } + + anotherUnion @7! :union { + qux @8 :Text; + corge @9 :List(Int32); + grault @10 :Float32; + } +} + +struct TestOldVersion { + # A subset of TestNewVersion. + old1 @0 :Int64; + old2 @1 :Text; + old3 @2 :TestOldVersion; +} + +struct TestNewVersion { + # A superset of TestOldVersion. + old1 @0 :Int64; + old2 @1 :Text; + old3 @2 :TestNewVersion; + new1 @3 :Int64 = 987; + new2 @4 :Text = "baz"; +} + +struct TestOldUnionVersion { + union { + a @0 :Void; + b @1 :UInt64; + } +} + +struct TestNewUnionVersion { + union { + a :union { + a0 @0 :Void; + a1 @2 :UInt64; + } + b @1 :UInt64; + } +} + +struct TestStructUnion { + un @0! :union { + struct @1 :SomeStruct; + object @2 :TestAnyPointer; + } + + struct SomeStruct { + someText @0 :Text; + moreText @1 :Text; + } +} + +struct TestPrintInlineStructs { + someText @0 :Text; + + structList @1 :List(InlineStruct); + struct InlineStruct { + int32Field @0 :Int32; + textField @1 :Text; + } +} + +struct TestWholeFloatDefault { + # At one point, these failed to compile in C++ because it would produce literals like "123f", + # which is not valid; it needs to be "123.0f". + field @0 :Float32 = 123; + bigField @1 :Float32 = 2e30; + const constant :Float32 = 456; + const bigConstant :Float32 = 4e30; +} + +struct TestGenerics(Foo, Bar) { + foo @0 :Foo; + rev @1 :TestGenerics(Bar, Foo); + + union { + uv @2:Void; + ug :group { + ugfoo @3:Int32; + } + } + + struct Inner { + foo @0 :Foo; + bar @1 :Bar; + } + + struct Inner2(Baz) { + bar @0 :Bar; + baz @1 :Baz; + innerBound @2 :Inner; + innerUnbound @3 :TestGenerics.Inner; + + struct DeepNest(Qux) { + foo @0 :Foo; + bar @1 :Bar; + baz @2 :Baz; + qux @3 :Qux; + } + } + + interface Interface(Qux) { + call @0 Inner2(Text) -> (qux :Qux, gen :TestGenerics(TestAllTypes, TestAnyPointer)); + } + + annotation ann(struct) :Foo; + + using AliasFoo = Foo; + using AliasInner = Inner; + using AliasInner2 = Inner2; + using AliasInner2Text = Inner2(Text); + using AliasRev = TestGenerics(Bar, Foo); + + struct UseAliases { + foo @0 :AliasFoo; + inner @1 :AliasInner; + inner2 @2 :AliasInner2; + inner2Bind @3 :AliasInner2(Text); + inner2Text @4 :AliasInner2Text; + revFoo @5 :AliasRev.AliasFoo; + } +} + +struct TestGenericsWrapper(Foo, Bar) { + value @0 :TestGenerics(Foo, Bar); +} + +struct TestGenericsWrapper2 { + value @0 :TestGenericsWrapper(Text, TestAllTypes); +} + +interface TestImplicitMethodParams { + call @0 [T, U] (foo :T, bar :U) -> TestGenerics(T, U); +} + +interface TestImplicitMethodParamsInGeneric(V) { + call @0 [T, U] (foo :T, bar :U) -> TestGenerics(T, U); +} + +struct TestGenericsUnion(Foo, Bar) { + # At one point this failed to compile. + + union { + foo @0 :Foo; + bar @1 :Bar; + } +} + +struct TestUseGenerics $TestGenerics(Text, Data).ann("foo") { + basic @0 :TestGenerics(TestAllTypes, TestAnyPointer); + inner @1 :TestGenerics(TestAllTypes, TestAnyPointer).Inner; + inner2 @2 :TestGenerics(TestAllTypes, TestAnyPointer).Inner2(Text); + unspecified @3 :TestGenerics; + unspecifiedInner @4 :TestGenerics.Inner2(Text); + wrapper @8 :TestGenericsWrapper(TestAllTypes, TestAnyPointer); + cap @18 :TestGenerics(TestInterface, Text); + genericCap @19 :TestGenerics(TestAllTypes, List(UInt32)).Interface(Data); + + default @5 :TestGenerics(TestAllTypes, Text) = + (foo = (int16Field = 123), rev = (foo = "text", rev = (foo = (int16Field = 321)))); + defaultInner @6 :TestGenerics(TestAllTypes, Text).Inner = + (foo = (int16Field = 123), bar = "text"); + defaultUser @7 :TestUseGenerics = (basic = (foo = (int16Field = 123))); + defaultWrapper @9 :TestGenericsWrapper(Text, TestAllTypes) = + (value = (foo = "text", rev = (foo = (int16Field = 321)))); + defaultWrapper2 @10 :TestGenericsWrapper2 = + (value = (value = (foo = "text", rev = (foo = (int16Field = 321))))); + + aliasFoo @11 :TestGenerics(TestAllTypes, TestAnyPointer).AliasFoo = (int16Field = 123); + aliasInner @12 :TestGenerics(TestAllTypes, TestAnyPointer).AliasInner + = (foo = (int16Field = 123)); + aliasInner2 @13 :TestGenerics(TestAllTypes, TestAnyPointer).AliasInner2 + = (innerBound = (foo = (int16Field = 123))); + aliasInner2Bind @14 :TestGenerics(TestAllTypes, TestAnyPointer).AliasInner2(List(UInt32)) + = (baz = [12, 34], innerBound = (foo = (int16Field = 123))); + aliasInner2Text @15 :TestGenerics(TestAllTypes, TestAnyPointer).AliasInner2Text + = (baz = "text", innerBound = (foo = (int16Field = 123))); + aliasRev @16 :TestGenerics(TestAnyPointer, Text).AliasRev.AliasFoo = "text"; + + useAliases @17 :TestGenerics(TestAllTypes, List(UInt32)).UseAliases = ( + foo = (int16Field = 123), + inner = (foo = (int16Field = 123)), + inner2 = (innerBound = (foo = (int16Field = 123))), + inner2Bind = (baz = "text", innerBound = (foo = (int16Field = 123))), + inner2Text = (baz = "text", innerBound = (foo = (int16Field = 123))), + revFoo = [12, 34, 56]); +} + +struct TestEmptyStruct {} + +struct TestConstants { + const voidConst :Void = void; + const boolConst :Bool = true; + const int8Const :Int8 = -123; + const int16Const :Int16 = -12345; + const int32Const :Int32 = -12345678; + const int64Const :Int64 = -123456789012345; + const uint8Const :UInt8 = 234; + const uint16Const :UInt16 = 45678; + const uint32Const :UInt32 = 3456789012; + const uint64Const :UInt64 = 12345678901234567890; + const float32Const :Float32 = 1234.5; + const float64Const :Float64 = -123e45; + const textConst :Text = "foo"; + const dataConst :Data = "bar"; + const structConst :TestAllTypes = ( + voidField = void, + boolField = true, + int8Field = -12, + int16Field = 3456, + int32Field = -78901234, + int64Field = 56789012345678, + uInt8Field = 90, + uInt16Field = 1234, + uInt32Field = 56789012, + uInt64Field = 345678901234567890, + float32Field = -1.25e-10, + float64Field = 345, + textField = "baz", + dataField = "qux", + structField = ( + textField = "nested", + structField = (textField = "really nested")), + enumField = baz, + # interfaceField can't have a default + + voidList = [void, void, void], + boolList = [false, true, false, true, true], + int8List = [12, -34, -0x80, 0x7f], + int16List = [1234, -5678, -0x8000, 0x7fff], + int32List = [12345678, -90123456, -0x80000000, 0x7fffffff], + int64List = [123456789012345, -678901234567890, -0x8000000000000000, 0x7fffffffffffffff], + uInt8List = [12, 34, 0, 0xff], + uInt16List = [1234, 5678, 0, 0xffff], + uInt32List = [12345678, 90123456, 0, 0xffffffff], + uInt64List = [123456789012345, 678901234567890, 0, 0xffffffffffffffff], + float32List = [0, 1234567, 1e37, -1e37, 1e-37, -1e-37], + float64List = [0, 123456789012345, 1e306, -1e306, 1e-306, -1e-306], + textList = ["quux", "corge", "grault"], + dataList = ["garply", "waldo", "fred"], + structList = [ + (textField = "x structlist 1"), + (textField = "x structlist 2"), + (textField = "x structlist 3")], + enumList = [qux, bar, grault] + # interfaceList can't have a default + ); + const enumConst :TestEnum = corge; + + const voidListConst :List(Void) = [void, void, void, void, void, void]; + const boolListConst :List(Bool) = [true, false, false, true]; + const int8ListConst :List(Int8) = [111, -111]; + const int16ListConst :List(Int16) = [11111, -11111]; + const int32ListConst :List(Int32) = [111111111, -111111111]; + const int64ListConst :List(Int64) = [1111111111111111111, -1111111111111111111]; + const uint8ListConst :List(UInt8) = [111, 222] ; + const uint16ListConst :List(UInt16) = [33333, 44444]; + const uint32ListConst :List(UInt32) = [3333333333]; + const uint64ListConst :List(UInt64) = [11111111111111111111]; + const float32ListConst :List(Float32) = [5555.5, inf, -inf, nan]; + const float64ListConst :List(Float64) = [7777.75, inf, -inf, nan]; + const textListConst :List(Text) = ["plugh", "xyzzy", "thud"]; + const dataListConst :List(Data) = ["oops", "exhausted", "rfc3092"]; + const structListConst :List(TestAllTypes) = [ + (textField = "structlist 1"), + (textField = "structlist 2"), + (textField = "structlist 3")]; + const enumListConst :List(TestEnum) = [foo, garply]; +} + +const globalInt :UInt32 = 12345; +const globalText :Text = "foobar"; +const globalStruct :TestAllTypes = (int32Field = 54321); +const globalPrintableStruct :TestPrintInlineStructs = (someText = "foo"); +const derivedConstant :TestAllTypes = ( + uInt32Field = .globalInt, + textField = TestConstants.textConst, + structField = TestConstants.structConst, + int16List = TestConstants.int16ListConst, + structList = TestConstants.structListConst); + +const genericConstant :TestGenerics(TestAllTypes, Text) = + (foo = (int16Field = 123), rev = (foo = "text", rev = (foo = (int16Field = 321)))); + +const embeddedData :Data = embed "testdata/packed"; +const embeddedText :Text = embed "testdata/short.txt"; +const embeddedStruct :TestAllTypes = embed "testdata/binary"; + +interface TestInterface { + foo @0 (i :UInt32, j :Bool) -> (x :Text); + bar @1 () -> (); + baz @2 (s: TestAllTypes); +} + +interface TestExtends extends(TestInterface) { + qux @0 (); + corge @1 TestAllTypes -> (); + grault @2 () -> TestAllTypes; +} + +interface TestExtends2 extends(TestExtends) {} + +interface TestPipeline { + getCap @0 (n: UInt32, inCap :TestInterface) -> (s: Text, outBox :Box); + testPointers @1 (cap :TestInterface, obj :AnyPointer, list :List(TestInterface)) -> (); + + struct Box { + cap @0 :TestInterface; + } +} + +interface TestCallOrder { + getCallSequence @0 (expected: UInt32) -> (n: UInt32); + # First call returns 0, next returns 1, ... + # + # The input `expected` is ignored but useful for disambiguating debug logs. +} + +interface TestTailCallee { + struct TailResult { + i @0 :UInt32; + t @1 :Text; + c @2 :TestCallOrder; + } + + foo @0 (i :Int32, t :Text) -> TailResult; +} + +interface TestTailCaller { + foo @0 (i :Int32, callee :TestTailCallee) -> TestTailCallee.TailResult; +} + +interface TestHandle {} + +interface TestMoreStuff extends(TestCallOrder) { + # Catch-all type that contains lots of testing methods. + + callFoo @0 (cap :TestInterface) -> (s: Text); + # Call `cap.foo()`, check the result, and return "bar". + + callFooWhenResolved @1 (cap :TestInterface) -> (s: Text); + # Like callFoo but waits for `cap` to resolve first. + + neverReturn @2 (cap :TestInterface) -> (capCopy :TestInterface); + # Doesn't return. You should cancel it. + + hold @3 (cap :TestInterface) -> (); + # Returns immediately but holds on to the capability. + + callHeld @4 () -> (s: Text); + # Calls the capability previously held using `hold` (and keeps holding it). + + getHeld @5 () -> (cap :TestInterface); + # Returns the capability previously held using `hold` (and keeps holding it). + + echo @6 (cap :TestCallOrder) -> (cap :TestCallOrder); + # Just returns the input cap. + + expectCancel @7 (cap :TestInterface) -> (); + # evalLater()-loops forever, holding `cap`. Must be canceled. + + methodWithDefaults @8 (a :Text, b :UInt32 = 123, c :Text = "foo") -> (d :Text, e :Text = "bar"); + + getHandle @9 () -> (handle :TestHandle); + # Get a new handle. Tests have an out-of-band way to check the current number of live handles, so + # this can be used to test garbage collection. + + getNull @10 () -> (nullCap :TestMoreStuff); + # Always returns a null capability. +} + +interface TestMembrane { + makeThing @0 () -> (thing :Thing); + callPassThrough @1 (thing :Thing, tailCall :Bool) -> Result; + callIntercept @2 (thing :Thing, tailCall :Bool) -> Result; + loopback @3 (thing :Thing) -> (thing :Thing); + + interface Thing { + passThrough @0 () -> Result; + intercept @1 () -> Result; + } + + struct Result { + text @0 :Text; + } +} + +struct TestContainMembrane { + cap @0 :TestMembrane.Thing; + list @1 :List(TestMembrane.Thing); +} + +struct TestTransferCap { + list @0 :List(Element); + struct Element { + text @0 :Text; + cap @1 :TestInterface; + } +} + +interface TestKeywordMethods { + delete @0 (); + class @1 (); + void @2 (); + return @3 (); +} + +interface TestAuthenticatedBootstrap(VatId) { + getCallerId @0 () -> (caller :VatId); +} + +struct TestSturdyRef { + hostId @0 :TestSturdyRefHostId; + objectId @1 :AnyPointer; +} + +struct TestSturdyRefHostId { + host @0 :Text; +} + +struct TestSturdyRefObjectId { + tag @0 :Tag; + enum Tag { + testInterface @0; + testExtends @1; + testPipeline @2; + testTailCallee @3; + testTailCaller @4; + testMoreStuff @5; + } +} + +struct TestProvisionId {} +struct TestRecipientId {} +struct TestThirdPartyCapId {} +struct TestJoinResult {} + +struct TestNameAnnotation $Cxx.name("RenamedStruct") { + union { + badFieldName @0 :Bool $Cxx.name("goodFieldName"); + bar @1 :Int8; + } + + enum BadlyNamedEnum $Cxx.name("RenamedEnum") { + foo @0; + bar @1; + baz @2 $Cxx.name("qux"); + } + + anotherBadFieldName @2 :BadlyNamedEnum $Cxx.name("anotherGoodFieldName"); + + struct NestedStruct $Cxx.name("RenamedNestedStruct") { + badNestedFieldName @0 :Bool $Cxx.name("goodNestedFieldName"); + anotherBadNestedFieldName @1 :NestedStruct $Cxx.name("anotherGoodNestedFieldName"); + + enum DeeplyNestedEnum $Cxx.name("RenamedDeeplyNestedEnum") { + quux @0; + corge @1; + grault @2 $Cxx.name("garply"); + } + } + + badlyNamedUnion :union $Cxx.name("renamedUnion") { + badlyNamedGroup :group $Cxx.name("renamedGroup") { + foo @3 :Void; + bar @4 :Void; + } + baz @5 :NestedStruct $Cxx.name("qux"); + } +} + +interface TestNameAnnotationInterface $Cxx.name("RenamedInterface") { + badlyNamedMethod @0 (badlyNamedParam :UInt8 $Cxx.name("renamedParam")) $Cxx.name("renamedMethod"); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/arena.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,213 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef KJ_ARENA_H_ +#define KJ_ARENA_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "memory.h" +#include "array.h" +#include "string.h" + +namespace kj { + +class Arena { + // A class which allows several objects to be allocated in contiguous chunks of memory, then + // frees them all at once. + // + // Allocating from the same Arena in multiple threads concurrently is NOT safe, because making + // it safe would require atomic operations that would slow down allocation even when + // single-threaded. If you need to use arena allocation in a multithreaded context, consider + // allocating thread-local arenas. + +public: + explicit Arena(size_t chunkSizeHint = 1024); + // Create an Arena. `chunkSizeHint` hints at where to start when allocating chunks, but is only + // a hint -- the Arena will, for example, allocate progressively larger chunks as time goes on, + // in order to reduce overall allocation overhead. + + explicit Arena(ArrayPtr<byte> scratch); + // Allocates from the given scratch space first, only resorting to the heap when it runs out. + + KJ_DISALLOW_COPY(Arena); + ~Arena() noexcept(false); + + template <typename T, typename... Params> + T& allocate(Params&&... params); + template <typename T> + ArrayPtr<T> allocateArray(size_t size); + // Allocate an object or array of type T. If T has a non-trivial destructor, that destructor + // will be run during the Arena's destructor. Such destructors are run in opposite order of + // allocation. Note that these methods must maintain a list of destructors to call, which has + // overhead, but this overhead only applies if T has a non-trivial destructor. + + template <typename T, typename... Params> + Own<T> allocateOwn(Params&&... params); + template <typename T> + Array<T> allocateOwnArray(size_t size); + template <typename T> + ArrayBuilder<T> allocateOwnArrayBuilder(size_t capacity); + // Allocate an object or array of type T. Destructors are executed when the returned Own<T> + // or Array<T> goes out-of-scope, which must happen before the Arena is destroyed. This variant + // is useful when you need to control when the destructor is called. This variant also avoids + // the need for the Arena itself to keep track of destructors to call later, which may make it + // slightly more efficient. + + template <typename T> + inline T& copy(T&& value) { return allocate<Decay<T>>(kj::fwd<T>(value)); } + // Allocate a copy of the given value in the arena. This is just a shortcut for calling the + // type's copy (or move) constructor. + + StringPtr copyString(StringPtr content); + // Make a copy of the given string inside the arena, and return a pointer to the copy. + +private: + struct ChunkHeader { + ChunkHeader* next; + byte* pos; // first unallocated byte in this chunk + byte* end; // end of this chunk + }; + struct ObjectHeader { + void (*destructor)(void*); + ObjectHeader* next; + }; + + size_t nextChunkSize; + ChunkHeader* chunkList = nullptr; + ObjectHeader* objectList = nullptr; + + ChunkHeader* currentChunk = nullptr; + + void cleanup(); + // Run all destructors, leaving the above pointers null. If a destructor throws, the State is + // left in a consistent state, such that if cleanup() is called again, it will pick up where + // it left off. + + void* allocateBytes(size_t amount, uint alignment, bool hasDisposer); + // Allocate the given number of bytes. `hasDisposer` must be true if `setDisposer()` may be + // called on this pointer later. + + void* allocateBytesInternal(size_t amount, uint alignment); + // Try to allocate the given number of bytes without taking a lock. Fails if and only if there + // is no space left in the current chunk. + + void setDestructor(void* ptr, void (*destructor)(void*)); + // Schedule the given destructor to be executed when the Arena is destroyed. `ptr` must be a + // pointer previously returned by an `allocateBytes()` call for which `hasDisposer` was true. + + template <typename T> + static void destroyArray(void* pointer) { + size_t elementCount = *reinterpret_cast<size_t*>(pointer); + constexpr size_t prefixSize = kj::max(alignof(T), sizeof(size_t)); + DestructorOnlyArrayDisposer::instance.disposeImpl( + reinterpret_cast<byte*>(pointer) + prefixSize, + sizeof(T), elementCount, elementCount, &destroyObject<T>); + } + + template <typename T> + static void destroyObject(void* pointer) { + dtor(*reinterpret_cast<T*>(pointer)); + } +}; + +// ======================================================================================= +// Inline implementation details + +template <typename T, typename... Params> +T& Arena::allocate(Params&&... params) { + T& result = *reinterpret_cast<T*>(allocateBytes( + sizeof(T), alignof(T), !__has_trivial_destructor(T))); + if (!__has_trivial_constructor(T) || sizeof...(Params) > 0) { + ctor(result, kj::fwd<Params>(params)...); + } + if (!__has_trivial_destructor(T)) { + setDestructor(&result, &destroyObject<T>); + } + return result; +} + +template <typename T> +ArrayPtr<T> Arena::allocateArray(size_t size) { + if (__has_trivial_destructor(T)) { + ArrayPtr<T> result = + arrayPtr(reinterpret_cast<T*>(allocateBytes( + sizeof(T) * size, alignof(T), false)), size); + if (!__has_trivial_constructor(T)) { + for (size_t i = 0; i < size; i++) { + ctor(result[i]); + } + } + return result; + } else { + // Allocate with a 64-bit prefix in which we store the array size. + constexpr size_t prefixSize = kj::max(alignof(T), sizeof(size_t)); + void* base = allocateBytes(sizeof(T) * size + prefixSize, alignof(T), true); + size_t& tag = *reinterpret_cast<size_t*>(base); + ArrayPtr<T> result = + arrayPtr(reinterpret_cast<T*>(reinterpret_cast<byte*>(base) + prefixSize), size); + setDestructor(base, &destroyArray<T>); + + if (__has_trivial_constructor(T)) { + tag = size; + } else { + // In case of constructor exceptions, we need the tag to end up storing the number of objects + // that were successfully constructed, so that they'll be properly destroyed. + tag = 0; + for (size_t i = 0; i < size; i++) { + ctor(result[i]); + tag = i + 1; + } + } + return result; + } +} + +template <typename T, typename... Params> +Own<T> Arena::allocateOwn(Params&&... params) { + T& result = *reinterpret_cast<T*>(allocateBytes(sizeof(T), alignof(T), false)); + if (!__has_trivial_constructor(T) || sizeof...(Params) > 0) { + ctor(result, kj::fwd<Params>(params)...); + } + return Own<T>(&result, DestructorOnlyDisposer<T>::instance); +} + +template <typename T> +Array<T> Arena::allocateOwnArray(size_t size) { + ArrayBuilder<T> result = allocateOwnArrayBuilder<T>(size); + for (size_t i = 0; i < size; i++) { + result.add(); + } + return result.finish(); +} + +template <typename T> +ArrayBuilder<T> Arena::allocateOwnArrayBuilder(size_t capacity) { + return ArrayBuilder<T>( + reinterpret_cast<T*>(allocateBytes(sizeof(T) * capacity, alignof(T), false)), + capacity, DestructorOnlyArrayDisposer::instance); +} + +} // namespace kj + +#endif // KJ_ARENA_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/array.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,723 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef KJ_ARRAY_H_ +#define KJ_ARRAY_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "common.h" +#include <string.h> +#include <initializer_list> + +namespace kj { + +// ======================================================================================= +// ArrayDisposer -- Implementation details. + +class ArrayDisposer { + // Much like Disposer from memory.h. + +protected: + // Do not declare a destructor, as doing so will force a global initializer for + // HeapArrayDisposer::instance. + + virtual void disposeImpl(void* firstElement, size_t elementSize, size_t elementCount, + size_t capacity, void (*destroyElement)(void*)) const = 0; + // Disposes of the array. `destroyElement` invokes the destructor of each element, or is nullptr + // if the elements have trivial destructors. `capacity` is the amount of space that was + // allocated while `elementCount` is the number of elements that were actually constructed; + // these are always the same number for Array<T> but may be different when using ArrayBuilder<T>. + +public: + + template <typename T> + void dispose(T* firstElement, size_t elementCount, size_t capacity) const; + // Helper wrapper around disposeImpl(). + // + // Callers must not call dispose() on the same array twice, even if the first call throws + // an exception. + +private: + template <typename T, bool hasTrivialDestructor = __has_trivial_destructor(T)> + struct Dispose_; +}; + +class ExceptionSafeArrayUtil { + // Utility class that assists in constructing or destroying elements of an array, where the + // constructor or destructor could throw exceptions. In case of an exception, + // ExceptionSafeArrayUtil's destructor will call destructors on all elements that have been + // constructed but not destroyed. Remember that destructors that throw exceptions are required + // to use UnwindDetector to detect unwind and avoid exceptions in this case. Therefore, no more + // than one exception will be thrown (and the program will not terminate). + +public: + inline ExceptionSafeArrayUtil(void* ptr, size_t elementSize, size_t constructedElementCount, + void (*destroyElement)(void*)) + : pos(reinterpret_cast<byte*>(ptr) + elementSize * constructedElementCount), + elementSize(elementSize), constructedElementCount(constructedElementCount), + destroyElement(destroyElement) {} + KJ_DISALLOW_COPY(ExceptionSafeArrayUtil); + + inline ~ExceptionSafeArrayUtil() noexcept(false) { + if (constructedElementCount > 0) destroyAll(); + } + + void construct(size_t count, void (*constructElement)(void*)); + // Construct the given number of elements. + + void destroyAll(); + // Destroy all elements. Call this immediately before ExceptionSafeArrayUtil goes out-of-scope + // to ensure that one element throwing an exception does not prevent the others from being + // destroyed. + + void release() { constructedElementCount = 0; } + // Prevent ExceptionSafeArrayUtil's destructor from destroying the constructed elements. + // Call this after you've successfully finished constructing. + +private: + byte* pos; + size_t elementSize; + size_t constructedElementCount; + void (*destroyElement)(void*); +}; + +class DestructorOnlyArrayDisposer: public ArrayDisposer { +public: + static const DestructorOnlyArrayDisposer instance; + + void disposeImpl(void* firstElement, size_t elementSize, size_t elementCount, + size_t capacity, void (*destroyElement)(void*)) const override; +}; + +class NullArrayDisposer: public ArrayDisposer { + // An ArrayDisposer that does nothing. Can be used to construct a fake Arrays that doesn't + // actually own its content. + +public: + static const NullArrayDisposer instance; + + void disposeImpl(void* firstElement, size_t elementSize, size_t elementCount, + size_t capacity, void (*destroyElement)(void*)) const override; +}; + +// ======================================================================================= +// Array + +template <typename T> +class Array { + // An owned array which will automatically be disposed of (using an ArrayDisposer) in the + // destructor. Can be moved, but not copied. Much like Own<T>, but for arrays rather than + // single objects. + +public: + inline Array(): ptr(nullptr), size_(0), disposer(nullptr) {} + inline Array(decltype(nullptr)): ptr(nullptr), size_(0), disposer(nullptr) {} + inline Array(Array&& other) noexcept + : ptr(other.ptr), size_(other.size_), disposer(other.disposer) { + other.ptr = nullptr; + other.size_ = 0; + } + inline Array(Array<RemoveConstOrDisable<T>>&& other) noexcept + : ptr(other.ptr), size_(other.size_), disposer(other.disposer) { + other.ptr = nullptr; + other.size_ = 0; + } + inline Array(T* firstElement, size_t size, const ArrayDisposer& disposer) + : ptr(firstElement), size_(size), disposer(&disposer) {} + + KJ_DISALLOW_COPY(Array); + inline ~Array() noexcept { dispose(); } + + inline operator ArrayPtr<T>() { + return ArrayPtr<T>(ptr, size_); + } + inline operator ArrayPtr<const T>() const { + return ArrayPtr<T>(ptr, size_); + } + inline ArrayPtr<T> asPtr() { + return ArrayPtr<T>(ptr, size_); + } + inline ArrayPtr<const T> asPtr() const { + return ArrayPtr<T>(ptr, size_); + } + + inline size_t size() const { return size_; } + inline T& operator[](size_t index) const { + KJ_IREQUIRE(index < size_, "Out-of-bounds Array access."); + return ptr[index]; + } + + inline const T* begin() const { return ptr; } + inline const T* end() const { return ptr + size_; } + inline const T& front() const { return *ptr; } + inline const T& back() const { return *(ptr + size_ - 1); } + inline T* begin() { return ptr; } + inline T* end() { return ptr + size_; } + inline T& front() { return *ptr; } + inline T& back() { return *(ptr + size_ - 1); } + + inline ArrayPtr<T> slice(size_t start, size_t end) { + KJ_IREQUIRE(start <= end && end <= size_, "Out-of-bounds Array::slice()."); + return ArrayPtr<T>(ptr + start, end - start); + } + inline ArrayPtr<const T> slice(size_t start, size_t end) const { + KJ_IREQUIRE(start <= end && end <= size_, "Out-of-bounds Array::slice()."); + return ArrayPtr<const T>(ptr + start, end - start); + } + + inline ArrayPtr<const byte> asBytes() const { return asPtr().asBytes(); } + inline ArrayPtr<PropagateConst<T, byte>> asBytes() { return asPtr().asBytes(); } + inline ArrayPtr<const char> asChars() const { return asPtr().asChars(); } + inline ArrayPtr<PropagateConst<T, char>> asChars() { return asPtr().asChars(); } + + inline Array<PropagateConst<T, byte>> releaseAsBytes() { + // Like asBytes() but transfers ownership. + static_assert(sizeof(T) == sizeof(byte), + "releaseAsBytes() only possible on arrays with byte-size elements (e.g. chars)."); + Array<PropagateConst<T, byte>> result( + reinterpret_cast<PropagateConst<T, byte>*>(ptr), size_, *disposer); + ptr = nullptr; + size_ = 0; + return result; + } + inline Array<PropagateConst<T, char>> releaseAsChars() { + // Like asChars() but transfers ownership. + static_assert(sizeof(T) == sizeof(PropagateConst<T, char>), + "releaseAsChars() only possible on arrays with char-size elements (e.g. bytes)."); + Array<PropagateConst<T, char>> result( + reinterpret_cast<PropagateConst<T, char>*>(ptr), size_, *disposer); + ptr = nullptr; + size_ = 0; + return result; + } + + inline bool operator==(decltype(nullptr)) const { return size_ == 0; } + inline bool operator!=(decltype(nullptr)) const { return size_ != 0; } + + inline Array& operator=(decltype(nullptr)) { + dispose(); + return *this; + } + + inline Array& operator=(Array&& other) { + dispose(); + ptr = other.ptr; + size_ = other.size_; + disposer = other.disposer; + other.ptr = nullptr; + other.size_ = 0; + return *this; + } + +private: + T* ptr; + size_t size_; + const ArrayDisposer* disposer; + + inline void dispose() { + // Make sure that if an exception is thrown, we are left with a null ptr, so we won't possibly + // dispose again. + T* ptrCopy = ptr; + size_t sizeCopy = size_; + if (ptrCopy != nullptr) { + ptr = nullptr; + size_ = 0; + disposer->dispose(ptrCopy, sizeCopy, sizeCopy); + } + } + + template <typename U> + friend class Array; +}; + +namespace _ { // private + +class HeapArrayDisposer final: public ArrayDisposer { +public: + template <typename T> + static T* allocate(size_t count); + template <typename T> + static T* allocateUninitialized(size_t count); + + static const HeapArrayDisposer instance; + +private: + static void* allocateImpl(size_t elementSize, size_t elementCount, size_t capacity, + void (*constructElement)(void*), void (*destroyElement)(void*)); + // Allocates and constructs the array. Both function pointers are null if the constructor is + // trivial, otherwise destroyElement is null if the constructor doesn't throw. + + virtual void disposeImpl(void* firstElement, size_t elementSize, size_t elementCount, + size_t capacity, void (*destroyElement)(void*)) const override; + + template <typename T, bool hasTrivialConstructor = __has_trivial_constructor(T), + bool hasNothrowConstructor = __has_nothrow_constructor(T)> + struct Allocate_; +}; + +} // namespace _ (private) + +template <typename T> +inline Array<T> heapArray(size_t size) { + // Much like `heap<T>()` from memory.h, allocates a new array on the heap. + + return Array<T>(_::HeapArrayDisposer::allocate<T>(size), size, + _::HeapArrayDisposer::instance); +} + +template <typename T> Array<T> heapArray(const T* content, size_t size); +template <typename T> Array<T> heapArray(ArrayPtr<T> content); +template <typename T> Array<T> heapArray(ArrayPtr<const T> content); +template <typename T, typename Iterator> Array<T> heapArray(Iterator begin, Iterator end); +template <typename T> Array<T> heapArray(std::initializer_list<T> init); +// Allocate a heap array containing a copy of the given content. + +template <typename T, typename Container> +Array<T> heapArrayFromIterable(Container&& a) { return heapArray(a.begin(), a.end()); } +template <typename T> +Array<T> heapArrayFromIterable(Array<T>&& a) { return mv(a); } + +// ======================================================================================= +// ArrayBuilder + +template <typename T> +class ArrayBuilder { + // Class which lets you build an Array<T> specifying the exact constructor arguments for each + // element, rather than starting by default-constructing them. + +public: + ArrayBuilder(): ptr(nullptr), pos(nullptr), endPtr(nullptr) {} + ArrayBuilder(decltype(nullptr)): ptr(nullptr), pos(nullptr), endPtr(nullptr) {} + explicit ArrayBuilder(RemoveConst<T>* firstElement, size_t capacity, + const ArrayDisposer& disposer) + : ptr(firstElement), pos(firstElement), endPtr(firstElement + capacity), + disposer(&disposer) {} + ArrayBuilder(ArrayBuilder&& other) + : ptr(other.ptr), pos(other.pos), endPtr(other.endPtr), disposer(other.disposer) { + other.ptr = nullptr; + other.pos = nullptr; + other.endPtr = nullptr; + } + KJ_DISALLOW_COPY(ArrayBuilder); + inline ~ArrayBuilder() noexcept(false) { dispose(); } + + inline operator ArrayPtr<T>() { + return arrayPtr(ptr, pos); + } + inline operator ArrayPtr<const T>() const { + return arrayPtr(ptr, pos); + } + inline ArrayPtr<T> asPtr() { + return arrayPtr(ptr, pos); + } + inline ArrayPtr<const T> asPtr() const { + return arrayPtr(ptr, pos); + } + + inline size_t size() const { return pos - ptr; } + inline size_t capacity() const { return endPtr - ptr; } + inline T& operator[](size_t index) const { + KJ_IREQUIRE(index < implicitCast<size_t>(pos - ptr), "Out-of-bounds Array access."); + return ptr[index]; + } + + inline const T* begin() const { return ptr; } + inline const T* end() const { return pos; } + inline const T& front() const { return *ptr; } + inline const T& back() const { return *(pos - 1); } + inline T* begin() { return ptr; } + inline T* end() { return pos; } + inline T& front() { return *ptr; } + inline T& back() { return *(pos - 1); } + + ArrayBuilder& operator=(ArrayBuilder&& other) { + dispose(); + ptr = other.ptr; + pos = other.pos; + endPtr = other.endPtr; + disposer = other.disposer; + other.ptr = nullptr; + other.pos = nullptr; + other.endPtr = nullptr; + return *this; + } + ArrayBuilder& operator=(decltype(nullptr)) { + dispose(); + return *this; + } + + template <typename... Params> + T& add(Params&&... params) { + KJ_IREQUIRE(pos < endPtr, "Added too many elements to ArrayBuilder."); + ctor(*pos, kj::fwd<Params>(params)...); + return *pos++; + } + + template <typename Container> + void addAll(Container&& container) { + addAll(container.begin(), container.end()); + } + + template <typename Iterator> + void addAll(Iterator start, Iterator end); + + void removeLast() { + KJ_IREQUIRE(pos > ptr, "No elements present to remove."); + kj::dtor(*--pos); + } + + Array<T> finish() { + // We could safely remove this check if we assume that the disposer implementation doesn't + // need to know the original capacity, as is thes case with HeapArrayDisposer since it uses + // operator new() or if we created a custom disposer for ArrayBuilder which stores the capacity + // in a prefix. But that would make it hard to write cleverer heap allocators, and anyway this + // check might catch bugs. Probably people should use Vector if they want to build arrays + // without knowing the final size in advance. + KJ_IREQUIRE(pos == endPtr, "ArrayBuilder::finish() called prematurely."); + Array<T> result(reinterpret_cast<T*>(ptr), pos - ptr, *disposer); + ptr = nullptr; + pos = nullptr; + endPtr = nullptr; + return result; + } + + inline bool isFull() const { + return pos == endPtr; + } + +private: + T* ptr; + RemoveConst<T>* pos; + T* endPtr; + const ArrayDisposer* disposer; + + inline void dispose() { + // Make sure that if an exception is thrown, we are left with a null ptr, so we won't possibly + // dispose again. + T* ptrCopy = ptr; + T* posCopy = pos; + T* endCopy = endPtr; + if (ptrCopy != nullptr) { + ptr = nullptr; + pos = nullptr; + endPtr = nullptr; + disposer->dispose(ptrCopy, posCopy - ptrCopy, endCopy - ptrCopy); + } + } +}; + +template <typename T> +inline ArrayBuilder<T> heapArrayBuilder(size_t size) { + // Like `heapArray<T>()` but does not default-construct the elements. You must construct them + // manually by calling `add()`. + + return ArrayBuilder<T>(_::HeapArrayDisposer::allocateUninitialized<RemoveConst<T>>(size), + size, _::HeapArrayDisposer::instance); +} + +// ======================================================================================= +// Inline Arrays + +template <typename T, size_t fixedSize> +class FixedArray { + // A fixed-width array whose storage is allocated inline rather than on the heap. + +public: + inline size_t size() const { return fixedSize; } + inline T* begin() { return content; } + inline T* end() { return content + fixedSize; } + inline const T* begin() const { return content; } + inline const T* end() const { return content + fixedSize; } + + inline operator ArrayPtr<T>() { + return arrayPtr(content, fixedSize); + } + inline operator ArrayPtr<const T>() const { + return arrayPtr(content, fixedSize); + } + + inline T& operator[](size_t index) { return content[index]; } + inline const T& operator[](size_t index) const { return content[index]; } + +private: + T content[fixedSize]; +}; + +template <typename T, size_t fixedSize> +class CappedArray { + // Like `FixedArray` but can be dynamically resized as long as the size does not exceed the limit + // specified by the template parameter. + // + // TODO(someday): Don't construct elements past currentSize? + +public: + inline KJ_CONSTEXPR() CappedArray(): currentSize(fixedSize) {} + inline explicit constexpr CappedArray(size_t s): currentSize(s) {} + + inline size_t size() const { return currentSize; } + inline void setSize(size_t s) { KJ_IREQUIRE(s <= fixedSize); currentSize = s; } + inline T* begin() { return content; } + inline T* end() { return content + currentSize; } + inline const T* begin() const { return content; } + inline const T* end() const { return content + currentSize; } + + inline operator ArrayPtr<T>() { + return arrayPtr(content, currentSize); + } + inline operator ArrayPtr<const T>() const { + return arrayPtr(content, currentSize); + } + + inline T& operator[](size_t index) { return content[index]; } + inline const T& operator[](size_t index) const { return content[index]; } + +private: + size_t currentSize; + T content[fixedSize]; +}; + +// ======================================================================================= +// KJ_MAP + +#define KJ_MAP(elementName, array) \ + ::kj::_::Mapper<KJ_DECLTYPE_REF(array)>(array) * [&](decltype(*(array).begin()) elementName) +// Applies some function to every element of an array, returning an Array of the results, with +// nice syntax. Example: +// +// StringPtr foo = "abcd"; +// Array<char> bar = KJ_MAP(c, foo) -> char { return c + 1; }; +// KJ_ASSERT(str(bar) == "bcde"); + +namespace _ { // private + +template <typename T> +struct Mapper { + T array; + Mapper(T&& array): array(kj::fwd<T>(array)) {} + template <typename Func> + auto operator*(Func&& func) -> Array<decltype(func(*array.begin()))> { + auto builder = heapArrayBuilder<decltype(func(*array.begin()))>(array.size()); + for (auto iter = array.begin(); iter != array.end(); ++iter) { + builder.add(func(*iter)); + } + return builder.finish(); + } +}; + +} // namespace _ (private) + +// ======================================================================================= +// Inline implementation details + +template <typename T> +struct ArrayDisposer::Dispose_<T, true> { + static void dispose(T* firstElement, size_t elementCount, size_t capacity, + const ArrayDisposer& disposer) { + disposer.disposeImpl(const_cast<RemoveConst<T>*>(firstElement), + sizeof(T), elementCount, capacity, nullptr); + } +}; +template <typename T> +struct ArrayDisposer::Dispose_<T, false> { + static void destruct(void* ptr) { + kj::dtor(*reinterpret_cast<T*>(ptr)); + } + + static void dispose(T* firstElement, size_t elementCount, size_t capacity, + const ArrayDisposer& disposer) { + disposer.disposeImpl(firstElement, sizeof(T), elementCount, capacity, &destruct); + } +}; + +template <typename T> +void ArrayDisposer::dispose(T* firstElement, size_t elementCount, size_t capacity) const { + Dispose_<T>::dispose(firstElement, elementCount, capacity, *this); +} + +namespace _ { // private + +template <typename T> +struct HeapArrayDisposer::Allocate_<T, true, true> { + static T* allocate(size_t elementCount, size_t capacity) { + return reinterpret_cast<T*>(allocateImpl( + sizeof(T), elementCount, capacity, nullptr, nullptr)); + } +}; +template <typename T> +struct HeapArrayDisposer::Allocate_<T, false, true> { + static void construct(void* ptr) { + kj::ctor(*reinterpret_cast<T*>(ptr)); + } + static T* allocate(size_t elementCount, size_t capacity) { + return reinterpret_cast<T*>(allocateImpl( + sizeof(T), elementCount, capacity, &construct, nullptr)); + } +}; +template <typename T> +struct HeapArrayDisposer::Allocate_<T, false, false> { + static void construct(void* ptr) { + kj::ctor(*reinterpret_cast<T*>(ptr)); + } + static void destruct(void* ptr) { + kj::dtor(*reinterpret_cast<T*>(ptr)); + } + static T* allocate(size_t elementCount, size_t capacity) { + return reinterpret_cast<T*>(allocateImpl( + sizeof(T), elementCount, capacity, &construct, &destruct)); + } +}; + +template <typename T> +T* HeapArrayDisposer::allocate(size_t count) { + return Allocate_<T>::allocate(count, count); +} + +template <typename T> +T* HeapArrayDisposer::allocateUninitialized(size_t count) { + return Allocate_<T, true, true>::allocate(0, count); +} + +template <typename Element, typename Iterator, bool = canMemcpy<Element>()> +struct CopyConstructArray_; + +template <typename T> +struct CopyConstructArray_<T, T*, true> { + static inline T* apply(T* __restrict__ pos, T* start, T* end) { + memcpy(pos, start, reinterpret_cast<byte*>(end) - reinterpret_cast<byte*>(start)); + return pos + (end - start); + } +}; + +template <typename T> +struct CopyConstructArray_<T, const T*, true> { + static inline T* apply(T* __restrict__ pos, const T* start, const T* end) { + memcpy(pos, start, reinterpret_cast<const byte*>(end) - reinterpret_cast<const byte*>(start)); + return pos + (end - start); + } +}; + +template <typename T, typename Iterator> +struct CopyConstructArray_<T, Iterator, true> { + static inline T* apply(T* __restrict__ pos, Iterator start, Iterator end) { + // Since both the copy constructor and assignment operator are trivial, we know that assignment + // is equivalent to copy-constructing. So we can make this case somewhat easier for the + // compiler to optimize. + while (start != end) { + *pos++ = *start++; + } + return pos; + } +}; + +template <typename T, typename Iterator> +struct CopyConstructArray_<T, Iterator, false> { + struct ExceptionGuard { + T* start; + T* pos; + inline explicit ExceptionGuard(T* pos): start(pos), pos(pos) {} + ~ExceptionGuard() noexcept(false) { + while (pos > start) { + dtor(*--pos); + } + } + }; + + static T* apply(T* __restrict__ pos, Iterator start, Iterator end) { + // Verify that T can be *implicitly* constructed from the source values. + if (false) implicitCast<T>(*start); + + if (noexcept(T(*start))) { + while (start != end) { + ctor(*pos++, *start++); + } + return pos; + } else { + // Crap. This is complicated. + ExceptionGuard guard(pos); + while (start != end) { + ctor(*guard.pos, *start++); + ++guard.pos; + } + guard.start = guard.pos; + return guard.pos; + } + } +}; + +template <typename T, typename Iterator> +inline T* copyConstructArray(T* dst, Iterator start, Iterator end) { + return CopyConstructArray_<T, Decay<Iterator>>::apply(dst, start, end); +} + +} // namespace _ (private) + +template <typename T> +template <typename Iterator> +void ArrayBuilder<T>::addAll(Iterator start, Iterator end) { + pos = _::copyConstructArray(pos, start, end); +} + +template <typename T> +Array<T> heapArray(const T* content, size_t size) { + ArrayBuilder<T> builder = heapArrayBuilder<T>(size); + builder.addAll(content, content + size); + return builder.finish(); +} + +template <typename T> +Array<T> heapArray(T* content, size_t size) { + ArrayBuilder<T> builder = heapArrayBuilder<T>(size); + builder.addAll(content, content + size); + return builder.finish(); +} + +template <typename T> +Array<T> heapArray(ArrayPtr<T> content) { + ArrayBuilder<T> builder = heapArrayBuilder<T>(content.size()); + builder.addAll(content); + return builder.finish(); +} + +template <typename T> +Array<T> heapArray(ArrayPtr<const T> content) { + ArrayBuilder<T> builder = heapArrayBuilder<T>(content.size()); + builder.addAll(content); + return builder.finish(); +} + +template <typename T, typename Iterator> Array<T> +heapArray(Iterator begin, Iterator end) { + ArrayBuilder<T> builder = heapArrayBuilder<T>(end - begin); + builder.addAll(begin, end); + return builder.finish(); +} + +template <typename T> +inline Array<T> heapArray(std::initializer_list<T> init) { + return heapArray<T>(init.begin(), init.end()); +} + +} // namespace kj + +#endif // KJ_ARRAY_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/async-inl.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,1085 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// This file contains extended inline implementation details that are required along with async.h. +// We move this all into a separate file to make async.h more readable. +// +// Non-inline declarations here are defined in async.c++. + +#ifndef KJ_ASYNC_H_ +#error "Do not include this directly; include kj/async.h." +#include "async.h" // help IDE parse this file +#endif + +#ifndef KJ_ASYNC_INL_H_ +#define KJ_ASYNC_INL_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +namespace kj { +namespace _ { // private + +template <typename T> +class ExceptionOr; + +class ExceptionOrValue { +public: + ExceptionOrValue(bool, Exception&& exception): exception(kj::mv(exception)) {} + KJ_DISALLOW_COPY(ExceptionOrValue); + + void addException(Exception&& exception) { + if (this->exception == nullptr) { + this->exception = kj::mv(exception); + } + } + + template <typename T> + ExceptionOr<T>& as() { return *static_cast<ExceptionOr<T>*>(this); } + template <typename T> + const ExceptionOr<T>& as() const { return *static_cast<const ExceptionOr<T>*>(this); } + + Maybe<Exception> exception; + +protected: + // Allow subclasses to have move constructor / assignment. + ExceptionOrValue() = default; + ExceptionOrValue(ExceptionOrValue&& other) = default; + ExceptionOrValue& operator=(ExceptionOrValue&& other) = default; +}; + +template <typename T> +class ExceptionOr: public ExceptionOrValue { +public: + ExceptionOr() = default; + ExceptionOr(T&& value): value(kj::mv(value)) {} + ExceptionOr(bool, Exception&& exception): ExceptionOrValue(false, kj::mv(exception)) {} + ExceptionOr(ExceptionOr&&) = default; + ExceptionOr& operator=(ExceptionOr&&) = default; + + Maybe<T> value; +}; + +class Event { + // An event waiting to be executed. Not for direct use by applications -- promises use this + // internally. + +public: + Event(); + ~Event() noexcept(false); + KJ_DISALLOW_COPY(Event); + + void armDepthFirst(); + // Enqueue this event so that `fire()` will be called from the event loop soon. + // + // Events scheduled in this way are executed in depth-first order: if an event callback arms + // more events, those events are placed at the front of the queue (in the order in which they + // were armed), so that they run immediately after the first event's callback returns. + // + // Depth-first event scheduling is appropriate for events that represent simple continuations + // of a previous event that should be globbed together for performance. Depth-first scheduling + // can lead to starvation, so any long-running task must occasionally yield with + // `armBreadthFirst()`. (Promise::then() uses depth-first whereas evalLater() uses + // breadth-first.) + // + // To use breadth-first scheduling instead, use `armBreadthFirst()`. + + void armBreadthFirst(); + // Like `armDepthFirst()` except that the event is placed at the end of the queue. + + kj::String trace(); + // Dump debug info about this event. + + virtual _::PromiseNode* getInnerForTrace(); + // If this event wraps a PromiseNode, get that node. Used for debug tracing. + // Default implementation returns nullptr. + +protected: + virtual Maybe<Own<Event>> fire() = 0; + // Fire the event. Possibly returns a pointer to itself, which will be discarded by the + // caller. This is the only way that an event can delete itself as a result of firing, as + // doing so from within fire() will throw an exception. + +private: + friend class kj::EventLoop; + EventLoop& loop; + Event* next; + Event** prev; + bool firing = false; +}; + +class PromiseNode { + // A Promise<T> contains a chain of PromiseNodes tracking the pending transformations. + // + // To reduce generated code bloat, PromiseNode is not a template. Instead, it makes very hacky + // use of pointers to ExceptionOrValue which actually point to ExceptionOr<T>, but are only + // so down-cast in the few places that really need to be templated. Luckily this is all + // internal implementation details. + +public: + virtual void onReady(Event& event) noexcept = 0; + // Arms the given event when ready. + + virtual void setSelfPointer(Own<PromiseNode>* selfPtr) noexcept; + // Tells the node that `selfPtr` is the pointer that owns this node, and will continue to own + // this node until it is destroyed or setSelfPointer() is called again. ChainPromiseNode uses + // this to shorten redundant chains. The default implementation does nothing; only + // ChainPromiseNode should implement this. + + virtual void get(ExceptionOrValue& output) noexcept = 0; + // Get the result. `output` points to an ExceptionOr<T> into which the result will be written. + // Can only be called once, and only after the node is ready. Must be called directly from the + // event loop, with no application code on the stack. + + virtual PromiseNode* getInnerForTrace(); + // If this node wraps some other PromiseNode, get the wrapped node. Used for debug tracing. + // Default implementation returns nullptr. + +protected: + class OnReadyEvent { + // Helper class for implementing onReady(). + + public: + void init(Event& newEvent); + // Returns true if arm() was already called. + + void arm(); + // Arms the event if init() has already been called and makes future calls to init() return + // true. + + private: + Event* event = nullptr; + }; +}; + +// ------------------------------------------------------------------- + +class ImmediatePromiseNodeBase: public PromiseNode { +public: + ImmediatePromiseNodeBase(); + ~ImmediatePromiseNodeBase() noexcept(false); + + void onReady(Event& event) noexcept override; +}; + +template <typename T> +class ImmediatePromiseNode final: public ImmediatePromiseNodeBase { + // A promise that has already been resolved to an immediate value or exception. + +public: + ImmediatePromiseNode(ExceptionOr<T>&& result): result(kj::mv(result)) {} + + void get(ExceptionOrValue& output) noexcept override { + output.as<T>() = kj::mv(result); + } + +private: + ExceptionOr<T> result; +}; + +class ImmediateBrokenPromiseNode final: public ImmediatePromiseNodeBase { +public: + ImmediateBrokenPromiseNode(Exception&& exception); + + void get(ExceptionOrValue& output) noexcept override; + +private: + Exception exception; +}; + +// ------------------------------------------------------------------- + +class AttachmentPromiseNodeBase: public PromiseNode { +public: + AttachmentPromiseNodeBase(Own<PromiseNode>&& dependency); + + void onReady(Event& event) noexcept override; + void get(ExceptionOrValue& output) noexcept override; + PromiseNode* getInnerForTrace() override; + +private: + Own<PromiseNode> dependency; + + void dropDependency(); + + template <typename> + friend class AttachmentPromiseNode; +}; + +template <typename Attachment> +class AttachmentPromiseNode final: public AttachmentPromiseNodeBase { + // A PromiseNode that holds on to some object (usually, an Own<T>, but could be any movable + // object) until the promise resolves. + +public: + AttachmentPromiseNode(Own<PromiseNode>&& dependency, Attachment&& attachment) + : AttachmentPromiseNodeBase(kj::mv(dependency)), + attachment(kj::mv<Attachment>(attachment)) {} + + ~AttachmentPromiseNode() noexcept(false) { + // We need to make sure the dependency is deleted before we delete the attachment because the + // dependency may be using the attachment. + dropDependency(); + } + +private: + Attachment attachment; +}; + +// ------------------------------------------------------------------- + +class PtmfHelper { + // This class is a private helper for GetFunctorStartAddress. The class represents the internal + // representation of a pointer-to-member-function. + + template <typename... ParamTypes> + friend struct GetFunctorStartAddress; + +#if __GNUG__ + void* ptr; + ptrdiff_t adj; + // Layout of a pointer-to-member-function used by GCC and compatible compilers. +#else +#error "TODO(port): PTMF instruction address extraction" +#endif + +#define BODY \ + PtmfHelper result; \ + static_assert(sizeof(p) == sizeof(result), "unknown ptmf layout"); \ + memcpy(&result, &p, sizeof(result)); \ + return result + + template <typename R, typename C, typename... P, typename F> + static PtmfHelper from(F p) { BODY; } + // Create a PtmfHelper from some arbitrary pointer-to-member-function which is not + // overloaded nor a template. In this case the compiler is able to deduce the full function + // signature directly given the name since there is only one function with that name. + + template <typename R, typename C, typename... P> + static PtmfHelper from(R (C::*p)(NoInfer<P>...)) { BODY; } + template <typename R, typename C, typename... P> + static PtmfHelper from(R (C::*p)(NoInfer<P>...) const) { BODY; } + // Create a PtmfHelper from some poniter-to-member-function which is a template. In this case + // the function must match exactly the containing type C, return type R, and parameter types P... + // GetFunctorStartAddress normally specifies exactly the correct C and R, but can only make a + // guess at P. Luckily, if the function parameters are template parameters then it's not + // necessary to be precise about P. +#undef BODY + + void* apply(void* obj) { +#if defined(__arm__) || defined(__mips__) || defined(__aarch64__) + if (adj & 1) { + ptrdiff_t voff = (ptrdiff_t)ptr; +#else + ptrdiff_t voff = (ptrdiff_t)ptr; + if (voff & 1) { + voff &= ~1; +#endif + return *(void**)(*(char**)obj + voff); + } else { + return ptr; + } + } +}; + +template <typename... ParamTypes> +struct GetFunctorStartAddress { + // Given a functor (any object defining operator()), return the start address of the function, + // suitable for passing to addr2line to obtain a source file/line for debugging purposes. + // + // This turns out to be incredibly hard to implement in the presence of overloaded or templated + // functors. Therefore, we impose these specific restrictions, specific to our use case: + // - Overloading is not allowed, but templating is. (Generally we only intend to support lambdas + // anyway.) + // - The template parameters to GetFunctorStartAddress specify a hint as to the expected + // parameter types. If the functor is templated, its parameters must match exactly these types. + // (If it's not templated, ParamTypes are ignored.) + + template <typename Func> + static void* apply(Func&& func) { + typedef decltype(func(instance<ParamTypes>()...)) ReturnType; + return PtmfHelper::from<ReturnType, Decay<Func>, ParamTypes...>( + &Decay<Func>::operator()).apply(&func); + } +}; + +template <> +struct GetFunctorStartAddress<Void&&>: public GetFunctorStartAddress<> {}; +// Hack for TransformPromiseNode use case: an input type of `Void` indicates that the function +// actually has no parameters. + +class TransformPromiseNodeBase: public PromiseNode { +public: + TransformPromiseNodeBase(Own<PromiseNode>&& dependency, void* continuationTracePtr); + + void onReady(Event& event) noexcept override; + void get(ExceptionOrValue& output) noexcept override; + PromiseNode* getInnerForTrace() override; + +private: + Own<PromiseNode> dependency; + void* continuationTracePtr; + + void dropDependency(); + void getDepResult(ExceptionOrValue& output); + + virtual void getImpl(ExceptionOrValue& output) = 0; + + template <typename, typename, typename, typename> + friend class TransformPromiseNode; +}; + +template <typename T, typename DepT, typename Func, typename ErrorFunc> +class TransformPromiseNode final: public TransformPromiseNodeBase { + // A PromiseNode that transforms the result of another PromiseNode through an application-provided + // function (implements `then()`). + +public: + TransformPromiseNode(Own<PromiseNode>&& dependency, Func&& func, ErrorFunc&& errorHandler) + : TransformPromiseNodeBase(kj::mv(dependency), + GetFunctorStartAddress<DepT&&>::apply(func)), + func(kj::fwd<Func>(func)), errorHandler(kj::fwd<ErrorFunc>(errorHandler)) {} + + ~TransformPromiseNode() noexcept(false) { + // We need to make sure the dependency is deleted before we delete the continuations because it + // is a common pattern for the continuations to hold ownership of objects that might be in-use + // by the dependency. + dropDependency(); + } + +private: + Func func; + ErrorFunc errorHandler; + + void getImpl(ExceptionOrValue& output) override { + ExceptionOr<DepT> depResult; + getDepResult(depResult); + KJ_IF_MAYBE(depException, depResult.exception) { + output.as<T>() = handle( + MaybeVoidCaller<Exception, FixVoid<ReturnType<ErrorFunc, Exception>>>::apply( + errorHandler, kj::mv(*depException))); + } else KJ_IF_MAYBE(depValue, depResult.value) { + output.as<T>() = handle(MaybeVoidCaller<DepT, T>::apply(func, kj::mv(*depValue))); + } + } + + ExceptionOr<T> handle(T&& value) { + return kj::mv(value); + } + ExceptionOr<T> handle(PropagateException::Bottom&& value) { + return ExceptionOr<T>(false, value.asException()); + } +}; + +// ------------------------------------------------------------------- + +class ForkHubBase; + +class ForkBranchBase: public PromiseNode { +public: + ForkBranchBase(Own<ForkHubBase>&& hub); + ~ForkBranchBase() noexcept(false); + + void hubReady() noexcept; + // Called by the hub to indicate that it is ready. + + // implements PromiseNode ------------------------------------------ + void onReady(Event& event) noexcept override; + PromiseNode* getInnerForTrace() override; + +protected: + inline ExceptionOrValue& getHubResultRef(); + + void releaseHub(ExceptionOrValue& output); + // Release the hub. If an exception is thrown, add it to `output`. + +private: + OnReadyEvent onReadyEvent; + + Own<ForkHubBase> hub; + ForkBranchBase* next = nullptr; + ForkBranchBase** prevPtr = nullptr; + + friend class ForkHubBase; +}; + +template <typename T> T copyOrAddRef(T& t) { return t; } +template <typename T> Own<T> copyOrAddRef(Own<T>& t) { return t->addRef(); } + +template <typename T> +class ForkBranch final: public ForkBranchBase { + // A PromiseNode that implements one branch of a fork -- i.e. one of the branches that receives + // a const reference. + +public: + ForkBranch(Own<ForkHubBase>&& hub): ForkBranchBase(kj::mv(hub)) {} + + void get(ExceptionOrValue& output) noexcept override { + ExceptionOr<T>& hubResult = getHubResultRef().template as<T>(); + KJ_IF_MAYBE(value, hubResult.value) { + output.as<T>().value = copyOrAddRef(*value); + } else { + output.as<T>().value = nullptr; + } + output.exception = hubResult.exception; + releaseHub(output); + } +}; + +template <typename T, size_t index> +class SplitBranch final: public ForkBranchBase { + // A PromiseNode that implements one branch of a fork -- i.e. one of the branches that receives + // a const reference. + +public: + SplitBranch(Own<ForkHubBase>&& hub): ForkBranchBase(kj::mv(hub)) {} + + typedef kj::Decay<decltype(kj::get<index>(kj::instance<T>()))> Element; + + void get(ExceptionOrValue& output) noexcept override { + ExceptionOr<T>& hubResult = getHubResultRef().template as<T>(); + KJ_IF_MAYBE(value, hubResult.value) { + output.as<Element>().value = kj::mv(kj::get<index>(*value)); + } else { + output.as<Element>().value = nullptr; + } + output.exception = hubResult.exception; + releaseHub(output); + } +}; + +// ------------------------------------------------------------------- + +class ForkHubBase: public Refcounted, protected Event { +public: + ForkHubBase(Own<PromiseNode>&& inner, ExceptionOrValue& resultRef); + + inline ExceptionOrValue& getResultRef() { return resultRef; } + +private: + Own<PromiseNode> inner; + ExceptionOrValue& resultRef; + + ForkBranchBase* headBranch = nullptr; + ForkBranchBase** tailBranch = &headBranch; + // Tail becomes null once the inner promise is ready and all branches have been notified. + + Maybe<Own<Event>> fire() override; + _::PromiseNode* getInnerForTrace() override; + + friend class ForkBranchBase; +}; + +template <typename T> +class ForkHub final: public ForkHubBase { + // A PromiseNode that implements the hub of a fork. The first call to Promise::fork() replaces + // the promise's outer node with a ForkHub, and subsequent calls add branches to that hub (if + // possible). + +public: + ForkHub(Own<PromiseNode>&& inner): ForkHubBase(kj::mv(inner), result) {} + + Promise<_::UnfixVoid<T>> addBranch() { + return Promise<_::UnfixVoid<T>>(false, kj::heap<ForkBranch<T>>(addRef(*this))); + } + + _::SplitTuplePromise<T> split() { + return splitImpl(MakeIndexes<tupleSize<T>()>()); + } + +private: + ExceptionOr<T> result; + + template <size_t... indexes> + _::SplitTuplePromise<T> splitImpl(Indexes<indexes...>) { + return kj::tuple(addSplit<indexes>()...); + } + + template <size_t index> + Promise<JoinPromises<typename SplitBranch<T, index>::Element>> addSplit() { + return Promise<JoinPromises<typename SplitBranch<T, index>::Element>>( + false, maybeChain(kj::heap<SplitBranch<T, index>>(addRef(*this)), + implicitCast<typename SplitBranch<T, index>::Element*>(nullptr))); + } +}; + +inline ExceptionOrValue& ForkBranchBase::getHubResultRef() { + return hub->getResultRef(); +} + +// ------------------------------------------------------------------- + +class ChainPromiseNode final: public PromiseNode, public Event { + // Promise node which reduces Promise<Promise<T>> to Promise<T>. + // + // `Event` is only a public base class because otherwise we can't cast Own<ChainPromiseNode> to + // Own<Event>. Ugh, templates and private... + +public: + explicit ChainPromiseNode(Own<PromiseNode> inner); + ~ChainPromiseNode() noexcept(false); + + void onReady(Event& event) noexcept override; + void setSelfPointer(Own<PromiseNode>* selfPtr) noexcept override; + void get(ExceptionOrValue& output) noexcept override; + PromiseNode* getInnerForTrace() override; + +private: + enum State { + STEP1, + STEP2 + }; + + State state; + + Own<PromiseNode> inner; + // In STEP1, a PromiseNode for a Promise<T>. + // In STEP2, a PromiseNode for a T. + + Event* onReadyEvent = nullptr; + Own<PromiseNode>* selfPtr = nullptr; + + Maybe<Own<Event>> fire() override; +}; + +template <typename T> +Own<PromiseNode> maybeChain(Own<PromiseNode>&& node, Promise<T>*) { + return heap<ChainPromiseNode>(kj::mv(node)); +} + +template <typename T> +Own<PromiseNode>&& maybeChain(Own<PromiseNode>&& node, T*) { + return kj::mv(node); +} + +// ------------------------------------------------------------------- + +class ExclusiveJoinPromiseNode final: public PromiseNode { +public: + ExclusiveJoinPromiseNode(Own<PromiseNode> left, Own<PromiseNode> right); + ~ExclusiveJoinPromiseNode() noexcept(false); + + void onReady(Event& event) noexcept override; + void get(ExceptionOrValue& output) noexcept override; + PromiseNode* getInnerForTrace() override; + +private: + class Branch: public Event { + public: + Branch(ExclusiveJoinPromiseNode& joinNode, Own<PromiseNode> dependency); + ~Branch() noexcept(false); + + bool get(ExceptionOrValue& output); + // Returns true if this is the side that finished. + + Maybe<Own<Event>> fire() override; + _::PromiseNode* getInnerForTrace() override; + + private: + ExclusiveJoinPromiseNode& joinNode; + Own<PromiseNode> dependency; + }; + + Branch left; + Branch right; + OnReadyEvent onReadyEvent; +}; + +// ------------------------------------------------------------------- + +class ArrayJoinPromiseNodeBase: public PromiseNode { +public: + ArrayJoinPromiseNodeBase(Array<Own<PromiseNode>> promises, + ExceptionOrValue* resultParts, size_t partSize); + ~ArrayJoinPromiseNodeBase() noexcept(false); + + void onReady(Event& event) noexcept override final; + void get(ExceptionOrValue& output) noexcept override final; + PromiseNode* getInnerForTrace() override final; + +protected: + virtual void getNoError(ExceptionOrValue& output) noexcept = 0; + // Called to compile the result only in the case where there were no errors. + +private: + uint countLeft; + OnReadyEvent onReadyEvent; + + class Branch final: public Event { + public: + Branch(ArrayJoinPromiseNodeBase& joinNode, Own<PromiseNode> dependency, + ExceptionOrValue& output); + ~Branch() noexcept(false); + + Maybe<Own<Event>> fire() override; + _::PromiseNode* getInnerForTrace() override; + + Maybe<Exception> getPart(); + // Calls dependency->get(output). If there was an exception, return it. + + private: + ArrayJoinPromiseNodeBase& joinNode; + Own<PromiseNode> dependency; + ExceptionOrValue& output; + }; + + Array<Branch> branches; +}; + +template <typename T> +class ArrayJoinPromiseNode final: public ArrayJoinPromiseNodeBase { +public: + ArrayJoinPromiseNode(Array<Own<PromiseNode>> promises, + Array<ExceptionOr<T>> resultParts) + : ArrayJoinPromiseNodeBase(kj::mv(promises), resultParts.begin(), sizeof(ExceptionOr<T>)), + resultParts(kj::mv(resultParts)) {} + +protected: + void getNoError(ExceptionOrValue& output) noexcept override { + auto builder = heapArrayBuilder<T>(resultParts.size()); + for (auto& part: resultParts) { + KJ_IASSERT(part.value != nullptr, + "Bug in KJ promise framework: Promise result had neither value no exception."); + builder.add(kj::mv(*_::readMaybe(part.value))); + } + output.as<Array<T>>() = builder.finish(); + } + +private: + Array<ExceptionOr<T>> resultParts; +}; + +template <> +class ArrayJoinPromiseNode<void> final: public ArrayJoinPromiseNodeBase { +public: + ArrayJoinPromiseNode(Array<Own<PromiseNode>> promises, + Array<ExceptionOr<_::Void>> resultParts); + ~ArrayJoinPromiseNode(); + +protected: + void getNoError(ExceptionOrValue& output) noexcept override; + +private: + Array<ExceptionOr<_::Void>> resultParts; +}; + +// ------------------------------------------------------------------- + +class EagerPromiseNodeBase: public PromiseNode, protected Event { + // A PromiseNode that eagerly evaluates its dependency even if its dependent does not eagerly + // evaluate it. + +public: + EagerPromiseNodeBase(Own<PromiseNode>&& dependency, ExceptionOrValue& resultRef); + + void onReady(Event& event) noexcept override; + PromiseNode* getInnerForTrace() override; + +private: + Own<PromiseNode> dependency; + OnReadyEvent onReadyEvent; + + ExceptionOrValue& resultRef; + + Maybe<Own<Event>> fire() override; +}; + +template <typename T> +class EagerPromiseNode final: public EagerPromiseNodeBase { +public: + EagerPromiseNode(Own<PromiseNode>&& dependency) + : EagerPromiseNodeBase(kj::mv(dependency), result) {} + + void get(ExceptionOrValue& output) noexcept override { + output.as<T>() = kj::mv(result); + } + +private: + ExceptionOr<T> result; +}; + +template <typename T> +Own<PromiseNode> spark(Own<PromiseNode>&& node) { + // Forces evaluation of the given node to begin as soon as possible, even if no one is waiting + // on it. + return heap<EagerPromiseNode<T>>(kj::mv(node)); +} + +// ------------------------------------------------------------------- + +class AdapterPromiseNodeBase: public PromiseNode { +public: + void onReady(Event& event) noexcept override; + +protected: + inline void setReady() { + onReadyEvent.arm(); + } + +private: + OnReadyEvent onReadyEvent; +}; + +template <typename T, typename Adapter> +class AdapterPromiseNode final: public AdapterPromiseNodeBase, + private PromiseFulfiller<UnfixVoid<T>> { + // A PromiseNode that wraps a PromiseAdapter. + +public: + template <typename... Params> + AdapterPromiseNode(Params&&... params) + : adapter(static_cast<PromiseFulfiller<UnfixVoid<T>>&>(*this), kj::fwd<Params>(params)...) {} + + void get(ExceptionOrValue& output) noexcept override { + KJ_IREQUIRE(!isWaiting()); + output.as<T>() = kj::mv(result); + } + +private: + ExceptionOr<T> result; + bool waiting = true; + Adapter adapter; + + void fulfill(T&& value) override { + if (waiting) { + waiting = false; + result = ExceptionOr<T>(kj::mv(value)); + setReady(); + } + } + + void reject(Exception&& exception) override { + if (waiting) { + waiting = false; + result = ExceptionOr<T>(false, kj::mv(exception)); + setReady(); + } + } + + bool isWaiting() override { + return waiting; + } +}; + +} // namespace _ (private) + +// ======================================================================================= + +template <typename T> +Promise<T>::Promise(_::FixVoid<T> value) + : PromiseBase(heap<_::ImmediatePromiseNode<_::FixVoid<T>>>(kj::mv(value))) {} + +template <typename T> +Promise<T>::Promise(kj::Exception&& exception) + : PromiseBase(heap<_::ImmediateBrokenPromiseNode>(kj::mv(exception))) {} + +template <typename T> +template <typename Func, typename ErrorFunc> +PromiseForResult<Func, T> Promise<T>::then(Func&& func, ErrorFunc&& errorHandler) { + typedef _::FixVoid<_::ReturnType<Func, T>> ResultT; + + Own<_::PromiseNode> intermediate = + heap<_::TransformPromiseNode<ResultT, _::FixVoid<T>, Func, ErrorFunc>>( + kj::mv(node), kj::fwd<Func>(func), kj::fwd<ErrorFunc>(errorHandler)); + return PromiseForResult<Func, T>(false, + _::maybeChain(kj::mv(intermediate), implicitCast<ResultT*>(nullptr))); +} + +namespace _ { // private + +template <typename T> +struct IdentityFunc { + inline T operator()(T&& value) const { + return kj::mv(value); + } +}; +template <typename T> +struct IdentityFunc<Promise<T>> { + inline Promise<T> operator()(T&& value) const { + return kj::mv(value); + } +}; +template <> +struct IdentityFunc<void> { + inline void operator()() const {} +}; +template <> +struct IdentityFunc<Promise<void>> { + Promise<void> operator()() const; + // This can't be inline because it will make the translation unit depend on kj-async. Awkwardly, + // Cap'n Proto relies on being able to include this header without creating such a link-time + // dependency. +}; + +} // namespace _ (private) + +template <typename T> +template <typename ErrorFunc> +Promise<T> Promise<T>::catch_(ErrorFunc&& errorHandler) { + // then()'s ErrorFunc can only return a Promise if Func also returns a Promise. In this case, + // Func is being filled in automatically. We want to make sure ErrorFunc can return a Promise, + // but we don't want the extra overhead of promise chaining if ErrorFunc doesn't actually + // return a promise. So we make our Func return match ErrorFunc. + return then(_::IdentityFunc<decltype(errorHandler(instance<Exception&&>()))>(), + kj::fwd<ErrorFunc>(errorHandler)); +} + +template <typename T> +T Promise<T>::wait(WaitScope& waitScope) { + _::ExceptionOr<_::FixVoid<T>> result; + + waitImpl(kj::mv(node), result, waitScope); + + KJ_IF_MAYBE(value, result.value) { + KJ_IF_MAYBE(exception, result.exception) { + throwRecoverableException(kj::mv(*exception)); + } + return _::returnMaybeVoid(kj::mv(*value)); + } else KJ_IF_MAYBE(exception, result.exception) { + throwFatalException(kj::mv(*exception)); + } else { + // Result contained neither a value nor an exception? + KJ_UNREACHABLE; + } +} + +template <typename T> +ForkedPromise<T> Promise<T>::fork() { + return ForkedPromise<T>(false, refcounted<_::ForkHub<_::FixVoid<T>>>(kj::mv(node))); +} + +template <typename T> +Promise<T> ForkedPromise<T>::addBranch() { + return hub->addBranch(); +} + +template <typename T> +_::SplitTuplePromise<T> Promise<T>::split() { + return refcounted<_::ForkHub<_::FixVoid<T>>>(kj::mv(node))->split(); +} + +template <typename T> +Promise<T> Promise<T>::exclusiveJoin(Promise<T>&& other) { + return Promise(false, heap<_::ExclusiveJoinPromiseNode>(kj::mv(node), kj::mv(other.node))); +} + +template <typename T> +template <typename... Attachments> +Promise<T> Promise<T>::attach(Attachments&&... attachments) { + return Promise(false, kj::heap<_::AttachmentPromiseNode<Tuple<Attachments...>>>( + kj::mv(node), kj::tuple(kj::fwd<Attachments>(attachments)...))); +} + +template <typename T> +template <typename ErrorFunc> +Promise<T> Promise<T>::eagerlyEvaluate(ErrorFunc&& errorHandler) { + // See catch_() for commentary. + return Promise(false, _::spark<_::FixVoid<T>>(then( + _::IdentityFunc<decltype(errorHandler(instance<Exception&&>()))>(), + kj::fwd<ErrorFunc>(errorHandler)).node)); +} + +template <typename T> +Promise<T> Promise<T>::eagerlyEvaluate(decltype(nullptr)) { + return Promise(false, _::spark<_::FixVoid<T>>(kj::mv(node))); +} + +template <typename T> +kj::String Promise<T>::trace() { + return PromiseBase::trace(); +} + +template <typename Func> +inline PromiseForResult<Func, void> evalLater(Func&& func) { + return _::yield().then(kj::fwd<Func>(func), _::PropagateException()); +} + +template <typename Func> +inline PromiseForResult<Func, void> evalNow(Func&& func) { + PromiseForResult<Func, void> result = nullptr; + KJ_IF_MAYBE(e, kj::runCatchingExceptions([&]() { + result = func(); + })) { + result = kj::mv(*e); + } + return result; +} + +template <typename T> +template <typename ErrorFunc> +void Promise<T>::detach(ErrorFunc&& errorHandler) { + return _::detach(then([](T&&) {}, kj::fwd<ErrorFunc>(errorHandler))); +} + +template <> +template <typename ErrorFunc> +void Promise<void>::detach(ErrorFunc&& errorHandler) { + return _::detach(then([]() {}, kj::fwd<ErrorFunc>(errorHandler))); +} + +template <typename T> +Promise<Array<T>> joinPromises(Array<Promise<T>>&& promises) { + return Promise<Array<T>>(false, kj::heap<_::ArrayJoinPromiseNode<T>>( + KJ_MAP(p, promises) { return kj::mv(p.node); }, + heapArray<_::ExceptionOr<T>>(promises.size()))); +} + +// ======================================================================================= + +namespace _ { // private + +template <typename T> +class WeakFulfiller final: public PromiseFulfiller<T>, private kj::Disposer { + // A wrapper around PromiseFulfiller which can be detached. + // + // There are a couple non-trivialities here: + // - If the WeakFulfiller is discarded, we want the promise it fulfills to be implicitly + // rejected. + // - We cannot destroy the WeakFulfiller until the application has discarded it *and* it has been + // detached from the underlying fulfiller, because otherwise the later detach() call will go + // to a dangling pointer. Essentially, WeakFulfiller is reference counted, although the + // refcount never goes over 2 and we manually implement the refcounting because we need to do + // other special things when each side detaches anyway. To this end, WeakFulfiller is its own + // Disposer -- dispose() is called when the application discards its owned pointer to the + // fulfiller and detach() is called when the promise is destroyed. + +public: + KJ_DISALLOW_COPY(WeakFulfiller); + + static kj::Own<WeakFulfiller> make() { + WeakFulfiller* ptr = new WeakFulfiller; + return Own<WeakFulfiller>(ptr, *ptr); + } + + void fulfill(FixVoid<T>&& value) override { + if (inner != nullptr) { + inner->fulfill(kj::mv(value)); + } + } + + void reject(Exception&& exception) override { + if (inner != nullptr) { + inner->reject(kj::mv(exception)); + } + } + + bool isWaiting() override { + return inner != nullptr && inner->isWaiting(); + } + + void attach(PromiseFulfiller<T>& newInner) { + inner = &newInner; + } + + void detach(PromiseFulfiller<T>& from) { + if (inner == nullptr) { + // Already disposed. + delete this; + } else { + KJ_IREQUIRE(inner == &from); + inner = nullptr; + } + } + +private: + mutable PromiseFulfiller<T>* inner; + + WeakFulfiller(): inner(nullptr) {} + + void disposeImpl(void* pointer) const override { + // TODO(perf): Factor some of this out so it isn't regenerated for every fulfiller type? + + if (inner == nullptr) { + // Already detached. + delete this; + } else { + if (inner->isWaiting()) { + inner->reject(kj::Exception(kj::Exception::Type::FAILED, __FILE__, __LINE__, + kj::heapString("PromiseFulfiller was destroyed without fulfilling the promise."))); + } + inner = nullptr; + } + } +}; + +template <typename T> +class PromiseAndFulfillerAdapter { +public: + PromiseAndFulfillerAdapter(PromiseFulfiller<T>& fulfiller, + WeakFulfiller<T>& wrapper) + : fulfiller(fulfiller), wrapper(wrapper) { + wrapper.attach(fulfiller); + } + + ~PromiseAndFulfillerAdapter() noexcept(false) { + wrapper.detach(fulfiller); + } + +private: + PromiseFulfiller<T>& fulfiller; + WeakFulfiller<T>& wrapper; +}; + +} // namespace _ (private) + +template <typename T> +template <typename Func> +bool PromiseFulfiller<T>::rejectIfThrows(Func&& func) { + KJ_IF_MAYBE(exception, kj::runCatchingExceptions(kj::mv(func))) { + reject(kj::mv(*exception)); + return false; + } else { + return true; + } +} + +template <typename Func> +bool PromiseFulfiller<void>::rejectIfThrows(Func&& func) { + KJ_IF_MAYBE(exception, kj::runCatchingExceptions(kj::mv(func))) { + reject(kj::mv(*exception)); + return false; + } else { + return true; + } +} + +template <typename T, typename Adapter, typename... Params> +Promise<T> newAdaptedPromise(Params&&... adapterConstructorParams) { + return Promise<T>(false, heap<_::AdapterPromiseNode<_::FixVoid<T>, Adapter>>( + kj::fwd<Params>(adapterConstructorParams)...)); +} + +template <typename T> +PromiseFulfillerPair<T> newPromiseAndFulfiller() { + auto wrapper = _::WeakFulfiller<T>::make(); + + Own<_::PromiseNode> intermediate( + heap<_::AdapterPromiseNode<_::FixVoid<T>, _::PromiseAndFulfillerAdapter<T>>>(*wrapper)); + Promise<_::JoinPromises<T>> promise(false, + _::maybeChain(kj::mv(intermediate), implicitCast<T*>(nullptr))); + + return PromiseFulfillerPair<T> { kj::mv(promise), kj::mv(wrapper) }; +} + +} // namespace kj + +#endif // KJ_ASYNC_INL_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/async-io.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,502 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef KJ_ASYNC_IO_H_ +#define KJ_ASYNC_IO_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "async.h" +#include "function.h" +#include "thread.h" +#include "time.h" + +struct sockaddr; + +namespace kj { + +class UnixEventPort; +class NetworkAddress; + +// ======================================================================================= +// Streaming I/O + +class AsyncInputStream { + // Asynchronous equivalent of InputStream (from io.h). + +public: + virtual Promise<size_t> read(void* buffer, size_t minBytes, size_t maxBytes) = 0; + virtual Promise<size_t> tryRead(void* buffer, size_t minBytes, size_t maxBytes) = 0; + + Promise<void> read(void* buffer, size_t bytes); +}; + +class AsyncOutputStream { + // Asynchronous equivalent of OutputStream (from io.h). + +public: + virtual Promise<void> write(const void* buffer, size_t size) = 0; + virtual Promise<void> write(ArrayPtr<const ArrayPtr<const byte>> pieces) = 0; +}; + +class AsyncIoStream: public AsyncInputStream, public AsyncOutputStream { + // A combination input and output stream. + +public: + virtual void shutdownWrite() = 0; + // Cleanly shut down just the write end of the stream, while keeping the read end open. + + virtual void abortRead() {} + // Similar to shutdownWrite, but this will shut down the read end of the stream, and should only + // be called when an error has occurred. + + virtual void getsockopt(int level, int option, void* value, uint* length); + virtual void setsockopt(int level, int option, const void* value, uint length); + // Corresponds to getsockopt() and setsockopt() syscalls. Will throw an "unimplemented" exception + // if the stream is not a socket or the option is not appropriate for the socket type. The + // default implementations always throw "unimplemented". + + virtual void getsockname(struct sockaddr* addr, uint* length); + virtual void getpeername(struct sockaddr* addr, uint* length); + // Corresponds to getsockname() and getpeername() syscalls. Will throw an "unimplemented" + // exception if the stream is not a socket. The default implementations always throw + // "unimplemented". + // + // Note that we don't provide methods that return NetworkAddress because it usually wouldn't + // be useful. You can't connect() to or listen() on these addresses, obviously, because they are + // ephemeral addresses for a single connection. +}; + +struct OneWayPipe { + // A data pipe with an input end and an output end. (Typically backed by pipe() system call.) + + Own<AsyncInputStream> in; + Own<AsyncOutputStream> out; +}; + +struct TwoWayPipe { + // A data pipe that supports sending in both directions. Each end's output sends data to the + // other end's input. (Typically backed by socketpair() system call.) + + Own<AsyncIoStream> ends[2]; +}; + +class ConnectionReceiver { + // Represents a server socket listening on a port. + +public: + virtual Promise<Own<AsyncIoStream>> accept() = 0; + // Accept the next incoming connection. + + virtual uint getPort() = 0; + // Gets the port number, if applicable (i.e. if listening on IP). This is useful if you didn't + // specify a port when constructing the NetworkAddress -- one will have been assigned + // automatically. + + virtual void getsockopt(int level, int option, void* value, uint* length); + virtual void setsockopt(int level, int option, const void* value, uint length); + // Same as the methods of AsyncIoStream. +}; + +// ======================================================================================= +// Datagram I/O + +class AncillaryMessage { + // Represents an ancillary message (aka control message) received using the recvmsg() system + // call (or equivalent). Most apps will not use this. + +public: + inline AncillaryMessage(int level, int type, ArrayPtr<const byte> data); + AncillaryMessage() = default; + + inline int getLevel() const; + // Originating protocol / socket level. + + inline int getType() const; + // Protocol-specific message type. + + template <typename T> + inline Maybe<const T&> as(); + // Interpret the ancillary message as the given struct type. Most ancillary messages are some + // sort of struct, so this is a convenient way to access it. Returns nullptr if the message + // is smaller than the struct -- this can happen if the message was truncated due to + // insufficient ancillary buffer space. + + template <typename T> + inline ArrayPtr<const T> asArray(); + // Interpret the ancillary message as an array of items. If the message size does not evenly + // divide into elements of type T, the remainder is discarded -- this can happen if the message + // was truncated due to insufficient ancillary buffer space. + +private: + int level; + int type; + ArrayPtr<const byte> data; + // Message data. In most cases you should use `as()` or `asArray()`. +}; + +class DatagramReceiver { + // Class encapsulating the recvmsg() system call. You must specify the DatagramReceiver's + // capacity in advance; if a received packet is larger than the capacity, it will be truncated. + +public: + virtual Promise<void> receive() = 0; + // Receive a new message, overwriting this object's content. + // + // receive() may reuse the same buffers for content and ancillary data with each call. + + template <typename T> + struct MaybeTruncated { + T value; + + bool isTruncated; + // True if the Receiver's capacity was insufficient to receive the value and therefore the + // value is truncated. + }; + + virtual MaybeTruncated<ArrayPtr<const byte>> getContent() = 0; + // Get the content of the datagram. + + virtual MaybeTruncated<ArrayPtr<const AncillaryMessage>> getAncillary() = 0; + // Ancilarry messages received with the datagram. See the recvmsg() system call and the cmsghdr + // struct. Most apps don't need this. + // + // If the returned value is truncated, then the last message in the array may itself be + // truncated, meaning its as<T>() method will return nullptr or its asArray<T>() method will + // return fewer elements than expected. Truncation can also mean that additional messages were + // available but discarded. + + virtual NetworkAddress& getSource() = 0; + // Get the datagram sender's address. + + struct Capacity { + size_t content = 8192; + // How much space to allocate for the datagram content. If a datagram is received that is + // larger than this, it will be truncated, with no way to recover the tail. + + size_t ancillary = 0; + // How much space to allocate for ancillary messages. As with content, if the ancillary data + // is larger than this, it will be truncated. + }; +}; + +class DatagramPort { +public: + virtual Promise<size_t> send(const void* buffer, size_t size, NetworkAddress& destination) = 0; + virtual Promise<size_t> send(ArrayPtr<const ArrayPtr<const byte>> pieces, + NetworkAddress& destination) = 0; + + virtual Own<DatagramReceiver> makeReceiver( + DatagramReceiver::Capacity capacity = DatagramReceiver::Capacity()) = 0; + // Create a new `Receiver` that can be used to receive datagrams. `capacity` specifies how much + // space to allocate for the received message. The `DatagramPort` must outlive the `Receiver`. + + virtual uint getPort() = 0; + // Gets the port number, if applicable (i.e. if listening on IP). This is useful if you didn't + // specify a port when constructing the NetworkAddress -- one will have been assigned + // automatically. + + virtual void getsockopt(int level, int option, void* value, uint* length); + virtual void setsockopt(int level, int option, const void* value, uint length); + // Same as the methods of AsyncIoStream. +}; + +// ======================================================================================= +// Networks + +class NetworkAddress { + // Represents a remote address to which the application can connect. + +public: + virtual Promise<Own<AsyncIoStream>> connect() = 0; + // Make a new connection to this address. + // + // The address must not be a wildcard ("*"). If it is an IP address, it must have a port number. + + virtual Own<ConnectionReceiver> listen() = 0; + // Listen for incoming connections on this address. + // + // The address must be local. + + virtual Own<DatagramPort> bindDatagramPort(); + // Open this address as a datagram (e.g. UDP) port. + // + // The address must be local. + + virtual Own<NetworkAddress> clone() = 0; + // Returns an equivalent copy of this NetworkAddress. + + virtual String toString() = 0; + // Produce a human-readable string which hopefully can be passed to Network::parseAddress() + // to reproduce this address, although whether or not that works of course depends on the Network + // implementation. This should be called only to display the address to human users, who will + // hopefully know what they are able to do with it. +}; + +class Network { + // Factory for NetworkAddress instances, representing the network services offered by the + // operating system. + // + // This interface typically represents broad authority, and well-designed code should limit its + // use to high-level startup code and user interaction. Low-level APIs should accept + // NetworkAddress instances directly and work from there, if at all possible. + +public: + virtual Promise<Own<NetworkAddress>> parseAddress(StringPtr addr, uint portHint = 0) = 0; + // Construct a network address from a user-provided string. The format of the address + // strings is not specified at the API level, and application code should make no assumptions + // about them. These strings should always be provided by humans, and said humans will know + // what format to use in their particular context. + // + // `portHint`, if provided, specifies the "standard" IP port number for the application-level + // service in play. If the address turns out to be an IP address (v4 or v6), and it lacks a + // port number, this port will be used. If `addr` lacks a port number *and* `portHint` is + // omitted, then the returned address will only support listen() and bindDatagramPort() + // (not connect()), and an unused port will be chosen each time one of those methods is called. + + virtual Own<NetworkAddress> getSockaddr(const void* sockaddr, uint len) = 0; + // Construct a network address from a legacy struct sockaddr. +}; + +// ======================================================================================= +// I/O Provider + +class AsyncIoProvider { + // Class which constructs asynchronous wrappers around the operating system's I/O facilities. + // + // Generally, the implementation of this interface must integrate closely with a particular + // `EventLoop` implementation. Typically, the EventLoop implementation itself will provide + // an AsyncIoProvider. + +public: + virtual OneWayPipe newOneWayPipe() = 0; + // Creates an input/output stream pair representing the ends of a one-way pipe (e.g. created with + // the pipe(2) system call). + + virtual TwoWayPipe newTwoWayPipe() = 0; + // Creates two AsyncIoStreams representing the two ends of a two-way pipe (e.g. created with + // socketpair(2) system call). Data written to one end can be read from the other. + + virtual Network& getNetwork() = 0; + // Creates a new `Network` instance representing the networks exposed by the operating system. + // + // DO NOT CALL THIS except at the highest levels of your code, ideally in the main() function. If + // you call this from low-level code, then you are preventing higher-level code from injecting an + // alternative implementation. Instead, if your code needs to use network functionality, it + // should ask for a `Network` as a constructor or method parameter, so that higher-level code can + // chose what implementation to use. The system network is essentially a singleton. See: + // http://www.object-oriented-security.org/lets-argue/singletons + // + // Code that uses the system network should not make any assumptions about what kinds of + // addresses it will parse, as this could differ across platforms. String addresses should come + // strictly from the user, who will know how to write them correctly for their system. + // + // With that said, KJ currently supports the following string address formats: + // - IPv4: "1.2.3.4", "1.2.3.4:80" + // - IPv6: "1234:5678::abcd", "[1234:5678::abcd]:80" + // - Local IP wildcard (covers both v4 and v6): "*", "*:80" + // - Symbolic names: "example.com", "example.com:80", "example.com:http", "1.2.3.4:http" + // - Unix domain: "unix:/path/to/socket" + + struct PipeThread { + // A combination of a thread and a two-way pipe that communicates with that thread. + // + // The fields are intentionally ordered so that the pipe will be destroyed (and therefore + // disconnected) before the thread is destroyed (and therefore joined). Thus if the thread + // arranges to exit when it detects disconnect, destruction should be clean. + + Own<Thread> thread; + Own<AsyncIoStream> pipe; + }; + + virtual PipeThread newPipeThread( + Function<void(AsyncIoProvider&, AsyncIoStream&, WaitScope&)> startFunc) = 0; + // Create a new thread and set up a two-way pipe (socketpair) which can be used to communicate + // with it. One end of the pipe is passed to the thread's start function and the other end of + // the pipe is returned. The new thread also gets its own `AsyncIoProvider` instance and will + // already have an active `EventLoop` when `startFunc` is called. + // + // TODO(someday): I'm not entirely comfortable with this interface. It seems to be doing too + // much at once but I'm not sure how to cleanly break it down. + + virtual Timer& getTimer() = 0; + // Returns a `Timer` based on real time. Time does not pass while event handlers are running -- + // it only updates when the event loop polls for system events. This means that calling `now()` + // on this timer does not require a system call. + // + // This timer is not affected by changes to the system date. It is unspecified whether the timer + // continues to count while the system is suspended. +}; + +class LowLevelAsyncIoProvider { + // Similar to `AsyncIoProvider`, but represents a lower-level interface that may differ on + // different operating systems. You should prefer to use `AsyncIoProvider` over this interface + // whenever possible, as `AsyncIoProvider` is portable and friendlier to dependency-injection. + // + // On Unix, this interface can be used to import native file descriptors into the async framework. + // Different implementations of this interface might work on top of different event handling + // primitives, such as poll vs. epoll vs. kqueue vs. some higher-level event library. + // + // On Windows, this interface can be used to import native HANDLEs into the async framework. + // Different implementations of this interface might work on top of different event handling + // primitives, such as I/O completion ports vs. completion routines. + // + // TODO(port): Actually implement Windows support. + +public: + // --------------------------------------------------------------------------- + // Unix-specific stuff + + enum Flags { + // Flags controlling how to wrap a file descriptor. + + TAKE_OWNERSHIP = 1 << 0, + // The returned object should own the file descriptor, automatically closing it when destroyed. + // The close-on-exec flag will be set on the descriptor if it is not already. + // + // If this flag is not used, then the file descriptor is not automatically closed and the + // close-on-exec flag is not modified. + + ALREADY_CLOEXEC = 1 << 1, + // Indicates that the close-on-exec flag is known already to be set, so need not be set again. + // Only relevant when combined with TAKE_OWNERSHIP. + // + // On Linux, all system calls which yield new file descriptors have flags or variants which + // set the close-on-exec flag immediately. Unfortunately, other OS's do not. + + ALREADY_NONBLOCK = 1 << 2 + // Indicates that the file descriptor is known already to be in non-blocking mode, so the flag + // need not be set again. Otherwise, all wrap*Fd() methods will enable non-blocking mode + // automatically. + // + // On Linux, all system calls which yield new file descriptors have flags or variants which + // enable non-blocking mode immediately. Unfortunately, other OS's do not. + }; + + virtual Own<AsyncInputStream> wrapInputFd(int fd, uint flags = 0) = 0; + // Create an AsyncInputStream wrapping a file descriptor. + // + // `flags` is a bitwise-OR of the values of the `Flags` enum. + + virtual Own<AsyncOutputStream> wrapOutputFd(int fd, uint flags = 0) = 0; + // Create an AsyncOutputStream wrapping a file descriptor. + // + // `flags` is a bitwise-OR of the values of the `Flags` enum. + + virtual Own<AsyncIoStream> wrapSocketFd(int fd, uint flags = 0) = 0; + // Create an AsyncIoStream wrapping a socket file descriptor. + // + // `flags` is a bitwise-OR of the values of the `Flags` enum. + + virtual Promise<Own<AsyncIoStream>> wrapConnectingSocketFd(int fd, uint flags = 0) = 0; + // Create an AsyncIoStream wrapping a socket that is in the process of connecting. The returned + // promise should not resolve until connection has completed -- traditionally indicated by the + // descriptor becoming writable. + // + // `flags` is a bitwise-OR of the values of the `Flags` enum. + + virtual Own<ConnectionReceiver> wrapListenSocketFd(int fd, uint flags = 0) = 0; + // Create an AsyncIoStream wrapping a listen socket file descriptor. This socket should already + // have had `bind()` and `listen()` called on it, so it's ready for `accept()`. + // + // `flags` is a bitwise-OR of the values of the `Flags` enum. + + virtual Own<DatagramPort> wrapDatagramSocketFd(int fd, uint flags = 0); + + virtual Timer& getTimer() = 0; + // Returns a `Timer` based on real time. Time does not pass while event handlers are running -- + // it only updates when the event loop polls for system events. This means that calling `now()` + // on this timer does not require a system call. + // + // This timer is not affected by changes to the system date. It is unspecified whether the timer + // continues to count while the system is suspended. +}; + +Own<AsyncIoProvider> newAsyncIoProvider(LowLevelAsyncIoProvider& lowLevel); +// Make a new AsyncIoProvider wrapping a `LowLevelAsyncIoProvider`. + +struct AsyncIoContext { + Own<LowLevelAsyncIoProvider> lowLevelProvider; + Own<AsyncIoProvider> provider; + WaitScope& waitScope; + + UnixEventPort& unixEventPort; + // TEMPORARY: Direct access to underlying UnixEventPort, mainly for waiting on signals. This + // field will go away at some point when we have a chance to improve these interfaces. +}; + +AsyncIoContext setupAsyncIo(); +// Convenience method which sets up the current thread with everything it needs to do async I/O. +// The returned objects contain an `EventLoop` which is wrapping an appropriate `EventPort` for +// doing I/O on the host system, so everything is ready for the thread to start making async calls +// and waiting on promises. +// +// You would typically call this in your main() loop or in the start function of a thread. +// Example: +// +// int main() { +// auto ioContext = kj::setupAsyncIo(); +// +// // Now we can call an async function. +// Promise<String> textPromise = getHttp(*ioContext.provider, "http://example.com"); +// +// // And we can wait for the promise to complete. Note that you can only use `wait()` +// // from the top level, not from inside a promise callback. +// String text = textPromise.wait(ioContext.waitScope); +// print(text); +// return 0; +// } +// +// WARNING: An AsyncIoContext can only be used in the thread and process that created it. In +// particular, note that after a fork(), an AsyncIoContext created in the parent process will +// not work correctly in the child, even if the parent ceases to use its copy. In particular +// note that this means that server processes which daemonize themselves at startup must wait +// until after daemonization to create an AsyncIoContext. + +// ======================================================================================= +// inline implementation details + +inline AncillaryMessage::AncillaryMessage( + int level, int type, ArrayPtr<const byte> data) + : level(level), type(type), data(data) {} + +inline int AncillaryMessage::getLevel() const { return level; } +inline int AncillaryMessage::getType() const { return type; } + +template <typename T> +inline Maybe<const T&> AncillaryMessage::as() { + if (data.size() >= sizeof(T)) { + return *reinterpret_cast<const T*>(data.begin()); + } else { + return nullptr; + } +} + +template <typename T> +inline ArrayPtr<const T> AncillaryMessage::asArray() { + return arrayPtr(reinterpret_cast<const T*>(data.begin()), data.size() / sizeof(T)); +} + +} // namespace kj + +#endif // KJ_ASYNC_IO_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/async-prelude.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,218 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// This file contains a bunch of internal declarations that must appear before async.h can start. +// We don't define these directly in async.h because it makes the file hard to read. + +#ifndef KJ_ASYNC_PRELUDE_H_ +#define KJ_ASYNC_PRELUDE_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "exception.h" +#include "tuple.h" + +namespace kj { + +class EventLoop; +template <typename T> +class Promise; +class WaitScope; + +template <typename T> +Promise<Array<T>> joinPromises(Array<Promise<T>>&& promises); +Promise<void> joinPromises(Array<Promise<void>>&& promises); + +namespace _ { // private + +template <typename T> struct JoinPromises_ { typedef T Type; }; +template <typename T> struct JoinPromises_<Promise<T>> { typedef T Type; }; + +template <typename T> +using JoinPromises = typename JoinPromises_<T>::Type; +// If T is Promise<U>, resolves to U, otherwise resolves to T. +// +// TODO(cleanup): Rename to avoid confusion with joinPromises() call which is completely +// unrelated. + +class PropagateException { + // A functor which accepts a kj::Exception as a parameter and returns a broken promise of + // arbitrary type which simply propagates the exception. +public: + class Bottom { + public: + Bottom(Exception&& exception): exception(kj::mv(exception)) {} + + Exception asException() { return kj::mv(exception); } + + private: + Exception exception; + }; + + Bottom operator()(Exception&& e) { + return Bottom(kj::mv(e)); + } + Bottom operator()(const Exception& e) { + return Bottom(kj::cp(e)); + } +}; + +template <typename Func, typename T> +struct ReturnType_ { typedef decltype(instance<Func>()(instance<T>())) Type; }; +template <typename Func> +struct ReturnType_<Func, void> { typedef decltype(instance<Func>()()) Type; }; + +template <typename Func, typename T> +using ReturnType = typename ReturnType_<Func, T>::Type; +// The return type of functor Func given a parameter of type T, with the special exception that if +// T is void, this is the return type of Func called with no arguments. + +template <typename T> struct SplitTuplePromise_ { typedef Promise<T> Type; }; +template <typename... T> +struct SplitTuplePromise_<kj::_::Tuple<T...>> { + typedef kj::Tuple<Promise<JoinPromises<T>>...> Type; +}; + +template <typename T> +using SplitTuplePromise = typename SplitTuplePromise_<T>::Type; +// T -> Promise<T> +// Tuple<T> -> Tuple<Promise<T>> + +struct Void {}; +// Application code should NOT refer to this! See `kj::READY_NOW` instead. + +template <typename T> struct FixVoid_ { typedef T Type; }; +template <> struct FixVoid_<void> { typedef Void Type; }; +template <typename T> using FixVoid = typename FixVoid_<T>::Type; +// FixVoid<T> is just T unless T is void in which case it is _::Void (an empty struct). + +template <typename T> struct UnfixVoid_ { typedef T Type; }; +template <> struct UnfixVoid_<Void> { typedef void Type; }; +template <typename T> using UnfixVoid = typename UnfixVoid_<T>::Type; +// UnfixVoid is the opposite of FixVoid. + +template <typename In, typename Out> +struct MaybeVoidCaller { + // Calls the function converting a Void input to an empty parameter list and a void return + // value to a Void output. + + template <typename Func> + static inline Out apply(Func& func, In&& in) { + return func(kj::mv(in)); + } +}; +template <typename In, typename Out> +struct MaybeVoidCaller<In&, Out> { + template <typename Func> + static inline Out apply(Func& func, In& in) { + return func(in); + } +}; +template <typename Out> +struct MaybeVoidCaller<Void, Out> { + template <typename Func> + static inline Out apply(Func& func, Void&& in) { + return func(); + } +}; +template <typename In> +struct MaybeVoidCaller<In, Void> { + template <typename Func> + static inline Void apply(Func& func, In&& in) { + func(kj::mv(in)); + return Void(); + } +}; +template <typename In> +struct MaybeVoidCaller<In&, Void> { + template <typename Func> + static inline Void apply(Func& func, In& in) { + func(in); + return Void(); + } +}; +template <> +struct MaybeVoidCaller<Void, Void> { + template <typename Func> + static inline Void apply(Func& func, Void&& in) { + func(); + return Void(); + } +}; + +template <typename T> +inline T&& returnMaybeVoid(T&& t) { + return kj::fwd<T>(t); +} +inline void returnMaybeVoid(Void&& v) {} + +class ExceptionOrValue; +class PromiseNode; +class ChainPromiseNode; +template <typename T> +class ForkHub; + +class TaskSetImpl; + +class Event; + +class PromiseBase { +public: + kj::String trace(); + // Dump debug info about this promise. + +private: + Own<PromiseNode> node; + + PromiseBase() = default; + PromiseBase(Own<PromiseNode>&& node): node(kj::mv(node)) {} + + friend class kj::EventLoop; + friend class ChainPromiseNode; + template <typename> + friend class kj::Promise; + friend class TaskSetImpl; + template <typename U> + friend Promise<Array<U>> kj::joinPromises(Array<Promise<U>>&& promises); + friend Promise<void> kj::joinPromises(Array<Promise<void>>&& promises); +}; + +void detach(kj::Promise<void>&& promise); +void waitImpl(Own<_::PromiseNode>&& node, _::ExceptionOrValue& result, WaitScope& waitScope); +Promise<void> yield(); +Own<PromiseNode> neverDone(); + +class NeverDone { +public: + template <typename T> + operator Promise<T>() const { + return Promise<T>(false, neverDone()); + } + + KJ_NORETURN(void wait(WaitScope& waitScope) const); +}; + +} // namespace _ (private) +} // namespace kj + +#endif // KJ_ASYNC_PRELUDE_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/async-unix.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,273 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef KJ_ASYNC_UNIX_H_ +#define KJ_ASYNC_UNIX_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "async.h" +#include "time.h" +#include "vector.h" +#include "io.h" +#include <signal.h> + +#if __linux__ && !__BIONIC__ && !defined(KJ_USE_EPOLL) +// Default to epoll on Linux, except on Bionic (Android) which doesn't have signalfd.h. +#define KJ_USE_EPOLL 1 +#endif + +namespace kj { + +class UnixEventPort: public EventPort { + // An EventPort implementation which can wait for events on file descriptors as well as signals. + // This API only makes sense on Unix. + // + // The implementation uses `poll()` or possibly a platform-specific API (e.g. epoll, kqueue). + // To also wait on signals without race conditions, the implementation may block signals until + // just before `poll()` while using a signal handler which `siglongjmp()`s back to just before + // the signal was unblocked, or it may use a nicer platform-specific API like signalfd. + // + // The implementation reserves a signal for internal use. By default, it uses SIGUSR1. If you + // need to use SIGUSR1 for something else, you must offer a different signal by calling + // setReservedSignal() at startup. + // + // WARNING: A UnixEventPort can only be used in the thread and process that created it. In + // particular, note that after a fork(), a UnixEventPort created in the parent process will + // not work correctly in the child, even if the parent ceases to use its copy. In particular + // note that this means that server processes which daemonize themselves at startup must wait + // until after daemonization to create a UnixEventPort. + +public: + UnixEventPort(); + ~UnixEventPort() noexcept(false); + + class FdObserver; + // Class that watches an fd for readability or writability. See definition below. + + Promise<siginfo_t> onSignal(int signum); + // When the given signal is delivered to this thread, return the corresponding siginfo_t. + // The signal must have been captured using `captureSignal()`. + // + // If `onSignal()` has not been called, the signal will remain blocked in this thread. + // Therefore, a signal which arrives before `onSignal()` was called will not be "missed" -- the + // next call to 'onSignal()' will receive it. Also, you can control which thread receives a + // process-wide signal by only calling `onSignal()` on that thread's event loop. + // + // The result of waiting on the same signal twice at once is undefined. + + static void captureSignal(int signum); + // Arranges for the given signal to be captured and handled via UnixEventPort, so that you may + // then pass it to `onSignal()`. This method is static because it registers a signal handler + // which applies process-wide. If any other threads exist in the process when `captureSignal()` + // is called, you *must* set the signal mask in those threads to block this signal, otherwise + // terrible things will happen if the signal happens to be delivered to those threads. If at + // all possible, call `captureSignal()` *before* creating threads, so that threads you create in + // the future will inherit the proper signal mask. + // + // To un-capture a signal, simply install a different signal handler and then un-block it from + // the signal mask. + + static void setReservedSignal(int signum); + // Sets the signal number which `UnixEventPort` reserves for internal use. If your application + // needs to use SIGUSR1, call this at startup (before any calls to `captureSignal()` and before + // constructing an `UnixEventPort`) to offer a different signal. + + TimePoint steadyTime() { return frozenSteadyTime; } + Promise<void> atSteadyTime(TimePoint time); + + // implements EventPort ------------------------------------------------------ + bool wait() override; + bool poll() override; + void wake() const override; + +private: + struct TimerSet; // Defined in source file to avoid STL include. + class TimerPromiseAdapter; + class SignalPromiseAdapter; + + Own<TimerSet> timers; + TimePoint frozenSteadyTime; + + SignalPromiseAdapter* signalHead = nullptr; + SignalPromiseAdapter** signalTail = &signalHead; + + TimePoint currentSteadyTime(); + void processTimers(); + void gotSignal(const siginfo_t& siginfo); + + friend class TimerPromiseAdapter; + +#if KJ_USE_EPOLL + AutoCloseFd epollFd; + AutoCloseFd signalFd; + AutoCloseFd eventFd; // Used for cross-thread wakeups. + + sigset_t signalFdSigset; + // Signal mask as currently set on the signalFd. Tracked so we can detect whether or not it + // needs updating. + + bool doEpollWait(int timeout); + +#else + class PollContext; + + FdObserver* observersHead = nullptr; + FdObserver** observersTail = &observersHead; + + unsigned long long threadId; // actually pthread_t +#endif +}; + +class UnixEventPort::FdObserver { + // Object which watches a file descriptor to determine when it is readable or writable. + // + // For listen sockets, "readable" means that there is a connection to accept(). For everything + // else, it means that read() (or recv()) will return data. + // + // The presence of out-of-band data should NOT fire this event. However, the event may + // occasionally fire spuriously (when there is actually no data to read), and one thing that can + // cause such spurious events is the arrival of OOB data on certain platforms whose event + // interfaces fail to distinguish between regular and OOB data (e.g. Mac OSX). + // + // WARNING: The exact behavior of this class differs across systems, since event interfaces + // vary wildly. Be sure to read the documentation carefully and avoid depending on unspecified + // behavior. If at all possible, use the higher-level AsyncInputStream interface instead. + +public: + enum Flags { + OBSERVE_READ = 1, + OBSERVE_WRITE = 2, + OBSERVE_URGENT = 4, + OBSERVE_READ_WRITE = OBSERVE_READ | OBSERVE_WRITE + }; + + FdObserver(UnixEventPort& eventPort, int fd, uint flags); + // Begin watching the given file descriptor for readability. Only one ReadObserver may exist + // for a given file descriptor at a time. + + ~FdObserver() noexcept(false); + + KJ_DISALLOW_COPY(FdObserver); + + Promise<void> whenBecomesReadable(); + // Resolves the next time the file descriptor transitions from having no data to read to having + // some data to read. + // + // KJ uses "edge-triggered" event notification whenever possible. As a result, it is an error + // to call this method when there is already data in the read buffer which has been there since + // prior to the last turn of the event loop or prior to creation FdWatcher. In this case, it is + // unspecified whether the promise will ever resolve -- it depends on the underlying event + // mechanism being used. + // + // In order to avoid this problem, make sure that you only call `whenBecomesReadable()` + // only at times when you know the buffer is empty. You know this for sure when one of the + // following happens: + // * read() or recv() fails with EAGAIN or EWOULDBLOCK. (You MUST have non-blocking mode + // enabled on the fd!) + // * The file descriptor is a regular byte-oriented object (like a socket or pipe), + // read() or recv() returns fewer than the number of bytes requested, and `atEndHint()` + // returns false. This can only happen if the buffer is empty but EOF is not reached. (Note, + // though, that for record-oriented file descriptors like Linux's inotify interface, this + // rule does not hold, because it could simply be that the next record did not fit into the + // space available.) + // + // It is an error to call `whenBecomesReadable()` again when the promise returned previously + // has not yet resolved. If you do this, the previous promise may throw an exception. + + inline Maybe<bool> atEndHint() { return atEnd; } + // Returns true if the event system has indicated that EOF has been received. There may still + // be data in the read buffer, but once that is gone, there's nothing left. + // + // Returns false if the event system has indicated that EOF had NOT been received as of the + // last turn of the event loop. + // + // Returns nullptr if the event system does not know whether EOF has been reached. In this + // case, the only way to know for sure is to call read() or recv() and check if it returns + // zero. + // + // This hint may be useful as an optimization to avoid an unnecessary system call. + + Promise<void> whenBecomesWritable(); + // Resolves the next time the file descriptor transitions from having no space available in the + // write buffer to having some space available. + // + // KJ uses "edge-triggered" event notification whenever possible. As a result, it is an error + // to call this method when there is already space in the write buffer which has been there + // since prior to the last turn of the event loop or prior to creation FdWatcher. In this case, + // it is unspecified whether the promise will ever resolve -- it depends on the underlying + // event mechanism being used. + // + // In order to avoid this problem, make sure that you only call `whenBecomesWritable()` + // only at times when you know the buffer is full. You know this for sure when one of the + // following happens: + // * write() or send() fails with EAGAIN or EWOULDBLOCK. (You MUST have non-blocking mode + // enabled on the fd!) + // * write() or send() succeeds but accepts fewer than the number of bytes provided. This can + // only happen if the buffer is full. + // + // It is an error to call `whenBecomesWritable()` again when the promise returned previously + // has not yet resolved. If you do this, the previous promise may throw an exception. + + Promise<void> whenUrgentDataAvailable(); + // Resolves the next time the file descriptor's read buffer contains "urgent" data. + // + // The conditions for availability of urgent data are specific to the file descriptor's + // underlying implementation. + // + // It is an error to call `whenUrgentDataAvailable()` again when the promise returned previously + // has not yet resolved. If you do this, the previous promise may throw an exception. + // + // WARNING: This has some known weird behavior on macOS. See + // https://github.com/sandstorm-io/capnproto/issues/374. + +private: + UnixEventPort& eventPort; + int fd; + uint flags; + + kj::Maybe<Own<PromiseFulfiller<void>>> readFulfiller; + kj::Maybe<Own<PromiseFulfiller<void>>> writeFulfiller; + kj::Maybe<Own<PromiseFulfiller<void>>> urgentFulfiller; + // Replaced each time `whenBecomesReadable()` or `whenBecomesWritable()` is called. Reverted to + // null every time an event is fired. + + Maybe<bool> atEnd; + + void fire(short events); + +#if !KJ_USE_EPOLL + FdObserver* next; + FdObserver** prev; + // Linked list of observers which currently have a non-null readFulfiller or writeFulfiller. + // If `prev` is null then the observer is not currently in the list. + + short getEventMask(); +#endif + + friend class UnixEventPort; +}; + +} // namespace kj + +#endif // KJ_ASYNC_UNIX_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/async.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,682 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef KJ_ASYNC_H_ +#define KJ_ASYNC_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "async-prelude.h" +#include "exception.h" +#include "refcount.h" + +namespace kj { + +class EventLoop; +class WaitScope; + +template <typename T> +class Promise; +template <typename T> +class ForkedPromise; +template <typename T> +class PromiseFulfiller; +template <typename T> +struct PromiseFulfillerPair; + +template <typename Func, typename T> +using PromiseForResult = Promise<_::JoinPromises<_::ReturnType<Func, T>>>; +// Evaluates to the type of Promise for the result of calling functor type Func with parameter type +// T. If T is void, then the promise is for the result of calling Func with no arguments. If +// Func itself returns a promise, the promises are joined, so you never get Promise<Promise<T>>. + +// ======================================================================================= +// Promises + +template <typename T> +class Promise: protected _::PromiseBase { + // The basic primitive of asynchronous computation in KJ. Similar to "futures", but designed + // specifically for event loop concurrency. Similar to E promises and JavaScript Promises/A. + // + // A Promise represents a promise to produce a value of type T some time in the future. Once + // that value has been produced, the promise is "fulfilled". Alternatively, a promise can be + // "broken", with an Exception describing what went wrong. You may implicitly convert a value of + // type T to an already-fulfilled Promise<T>. You may implicitly convert the constant + // `kj::READY_NOW` to an already-fulfilled Promise<void>. You may also implicitly convert a + // `kj::Exception` to an already-broken promise of any type. + // + // Promises are linear types -- they are moveable but not copyable. If a Promise is destroyed + // or goes out of scope (without being moved elsewhere), any ongoing asynchronous operations + // meant to fulfill the promise will be canceled if possible. All methods of `Promise` (unless + // otherwise noted) actually consume the promise in the sense of move semantics. (Arguably they + // should be rvalue-qualified, but at the time this interface was created compilers didn't widely + // support that yet and anyway it would be pretty ugly typing kj::mv(promise).whatever().) If + // you want to use one Promise in two different places, you must fork it with `fork()`. + // + // To use the result of a Promise, you must call `then()` and supply a callback function to + // call with the result. `then()` returns another promise, for the result of the callback. + // Any time that this would result in Promise<Promise<T>>, the promises are collapsed into a + // simple Promise<T> that first waits for the outer promise, then the inner. Example: + // + // // Open a remote file, read the content, and then count the + // // number of lines of text. + // // Note that none of the calls here block. `file`, `content` + // // and `lineCount` are all initialized immediately before any + // // asynchronous operations occur. The lambda callbacks are + // // called later. + // Promise<Own<File>> file = openFtp("ftp://host/foo/bar"); + // Promise<String> content = file.then( + // [](Own<File> file) -> Promise<String> { + // return file.readAll(); + // }); + // Promise<int> lineCount = content.then( + // [](String text) -> int { + // uint count = 0; + // for (char c: text) count += (c == '\n'); + // return count; + // }); + // + // For `then()` to work, the current thread must have an active `EventLoop`. Each callback + // is scheduled to execute in that loop. Since `then()` schedules callbacks only on the current + // thread's event loop, you do not need to worry about two callbacks running at the same time. + // You will need to set up at least one `EventLoop` at the top level of your program before you + // can use promises. + // + // To adapt a non-Promise-based asynchronous API to promises, use `newAdaptedPromise()`. + // + // Systems using promises should consider supporting the concept of "pipelining". Pipelining + // means allowing a caller to start issuing method calls against a promised object before the + // promise has actually been fulfilled. This is particularly useful if the promise is for a + // remote object living across a network, as this can avoid round trips when chaining a series + // of calls. It is suggested that any class T which supports pipelining implement a subclass of + // Promise<T> which adds "eventual send" methods -- methods which, when called, say "please + // invoke the corresponding method on the promised value once it is available". These methods + // should in turn return promises for the eventual results of said invocations. Cap'n Proto, + // for example, implements the type `RemotePromise` which supports pipelining RPC requests -- see + // `capnp/capability.h`. + // + // KJ Promises are based on E promises: + // http://wiki.erights.org/wiki/Walnut/Distributed_Computing#Promises + // + // KJ Promises are also inspired in part by the evolving standards for JavaScript/ECMAScript + // promises, which are themselves influenced by E promises: + // http://promisesaplus.com/ + // https://github.com/domenic/promises-unwrapping + +public: + Promise(_::FixVoid<T> value); + // Construct an already-fulfilled Promise from a value of type T. For non-void promises, the + // parameter type is simply T. So, e.g., in a function that returns `Promise<int>`, you can + // say `return 123;` to return a promise that is already fulfilled to 123. + // + // For void promises, use `kj::READY_NOW` as the value, e.g. `return kj::READY_NOW`. + + Promise(kj::Exception&& e); + // Construct an already-broken Promise. + + inline Promise(decltype(nullptr)) {} + + template <typename Func, typename ErrorFunc = _::PropagateException> + PromiseForResult<Func, T> then(Func&& func, ErrorFunc&& errorHandler = _::PropagateException()) + KJ_WARN_UNUSED_RESULT; + // Register a continuation function to be executed when the promise completes. The continuation + // (`func`) takes the promised value (an rvalue of type `T`) as its parameter. The continuation + // may return a new value; `then()` itself returns a promise for the continuation's eventual + // result. If the continuation itself returns a `Promise<U>`, then `then()` shall also return + // a `Promise<U>` which first waits for the original promise, then executes the continuation, + // then waits for the inner promise (i.e. it automatically "unwraps" the promise). + // + // In all cases, `then()` returns immediately. The continuation is executed later. The + // continuation is always executed on the same EventLoop (and, therefore, the same thread) which + // called `then()`, therefore no synchronization is necessary on state shared by the continuation + // and the surrounding scope. If no EventLoop is running on the current thread, `then()` throws + // an exception. + // + // You may also specify an error handler continuation as the second parameter. `errorHandler` + // must be a functor taking a parameter of type `kj::Exception&&`. It must return the same + // type as `func` returns (except when `func` returns `Promise<U>`, in which case `errorHandler` + // may return either `Promise<U>` or just `U`). The default error handler simply propagates the + // exception to the returned promise. + // + // Either `func` or `errorHandler` may, of course, throw an exception, in which case the promise + // is broken. When compiled with -fno-exceptions, the framework will still detect when a + // recoverable exception was thrown inside of a continuation and will consider the promise + // broken even though a (presumably garbage) result was returned. + // + // If the returned promise is destroyed before the callback runs, the callback will be canceled + // (it will never run). + // + // Note that `then()` -- like all other Promise methods -- consumes the promise on which it is + // called, in the sense of move semantics. After returning, the original promise is no longer + // valid, but `then()` returns a new promise. + // + // *Advanced implementation tips:* Most users will never need to worry about the below, but + // it is good to be aware of. + // + // As an optimization, if the callback function `func` does _not_ return another promise, then + // execution of `func` itself may be delayed until its result is known to be needed. The + // expectation here is that `func` is just doing some transformation on the results, not + // scheduling any other actions, therefore the system doesn't need to be proactive about + // evaluating it. This way, a chain of trivial then() transformations can be executed all at + // once without repeatedly re-scheduling through the event loop. Use the `eagerlyEvaluate()` + // method to suppress this behavior. + // + // On the other hand, if `func` _does_ return another promise, then the system evaluates `func` + // as soon as possible, because the promise it returns might be for a newly-scheduled + // long-running asynchronous task. + // + // As another optimization, when a callback function registered with `then()` is actually + // scheduled, it is scheduled to occur immediately, preempting other work in the event queue. + // This allows a long chain of `then`s to execute all at once, improving cache locality by + // clustering operations on the same data. However, this implies that starvation can occur + // if a chain of `then()`s takes a very long time to execute without ever stopping to wait for + // actual I/O. To solve this, use `kj::evalLater()` to yield control; this way, all other events + // in the queue will get a chance to run before your callback is executed. + + Promise<void> ignoreResult() KJ_WARN_UNUSED_RESULT { return then([](T&&) {}); } + // Convenience method to convert the promise to a void promise by ignoring the return value. + // + // You must still wait on the returned promise if you want the task to execute. + + template <typename ErrorFunc> + Promise<T> catch_(ErrorFunc&& errorHandler) KJ_WARN_UNUSED_RESULT; + // Equivalent to `.then(identityFunc, errorHandler)`, where `identifyFunc` is a function that + // just returns its input. + + T wait(WaitScope& waitScope); + // Run the event loop until the promise is fulfilled, then return its result. If the promise + // is rejected, throw an exception. + // + // wait() is primarily useful at the top level of a program -- typically, within the function + // that allocated the EventLoop. For example, a program that performs one or two RPCs and then + // exits would likely use wait() in its main() function to wait on each RPC. On the other hand, + // server-side code generally cannot use wait(), because it has to be able to accept multiple + // requests at once. + // + // If the promise is rejected, `wait()` throws an exception. If the program was compiled without + // exceptions (-fno-exceptions), this will usually abort. In this case you really should first + // use `then()` to set an appropriate handler for the exception case, so that the promise you + // actually wait on never throws. + // + // `waitScope` is an object proving that the caller is in a scope where wait() is allowed. By + // convention, any function which might call wait(), or which might call another function which + // might call wait(), must take `WaitScope&` as one of its parameters. This is needed for two + // reasons: + // * `wait()` is not allowed during an event callback, because event callbacks are themselves + // called during some other `wait()`, and such recursive `wait()`s would only be able to + // complete in LIFO order, which might mean that the outer `wait()` ends up waiting longer + // than it is supposed to. To prevent this, a `WaitScope` cannot be constructed or used during + // an event callback. + // * Since `wait()` runs the event loop, unrelated event callbacks may execute before `wait()` + // returns. This means that anyone calling `wait()` must be reentrant -- state may change + // around them in arbitrary ways. Therefore, callers really need to know if a function they + // are calling might wait(), and the `WaitScope&` parameter makes this clear. + // + // TODO(someday): Implement fibers, and let them call wait() even when they are handling an + // event. + + ForkedPromise<T> fork() KJ_WARN_UNUSED_RESULT; + // Forks the promise, so that multiple different clients can independently wait on the result. + // `T` must be copy-constructable for this to work. Or, in the special case where `T` is + // `Own<U>`, `U` must have a method `Own<U> addRef()` which returns a new reference to the same + // (or an equivalent) object (probably implemented via reference counting). + + _::SplitTuplePromise<T> split(); + // Split a promise for a tuple into a tuple of promises. + // + // E.g. if you have `Promise<kj::Tuple<T, U>>`, `split()` returns + // `kj::Tuple<Promise<T>, Promise<U>>`. + + Promise<T> exclusiveJoin(Promise<T>&& other) KJ_WARN_UNUSED_RESULT; + // Return a new promise that resolves when either the original promise resolves or `other` + // resolves (whichever comes first). The promise that didn't resolve first is canceled. + + // TODO(someday): inclusiveJoin(), or perhaps just join(), which waits for both completions + // and produces a tuple? + + template <typename... Attachments> + Promise<T> attach(Attachments&&... attachments) KJ_WARN_UNUSED_RESULT; + // "Attaches" one or more movable objects (often, Own<T>s) to the promise, such that they will + // be destroyed when the promise resolves. This is useful when a promise's callback contains + // pointers into some object and you want to make sure the object still exists when the callback + // runs -- after calling then(), use attach() to add necessary objects to the result. + + template <typename ErrorFunc> + Promise<T> eagerlyEvaluate(ErrorFunc&& errorHandler) KJ_WARN_UNUSED_RESULT; + Promise<T> eagerlyEvaluate(decltype(nullptr)) KJ_WARN_UNUSED_RESULT; + // Force eager evaluation of this promise. Use this if you are going to hold on to the promise + // for awhile without consuming the result, but you want to make sure that the system actually + // processes it. + // + // `errorHandler` is a function that takes `kj::Exception&&`, like the second parameter to + // `then()`, except that it must return void. We make you specify this because otherwise it's + // easy to forget to handle errors in a promise that you never use. You may specify nullptr for + // the error handler if you are sure that ignoring errors is fine, or if you know that you'll + // eventually wait on the promise somewhere. + + template <typename ErrorFunc> + void detach(ErrorFunc&& errorHandler); + // Allows the promise to continue running in the background until it completes or the + // `EventLoop` is destroyed. Be careful when using this: since you can no longer cancel this + // promise, you need to make sure that the promise owns all the objects it touches or make sure + // those objects outlive the EventLoop. + // + // `errorHandler` is a function that takes `kj::Exception&&`, like the second parameter to + // `then()`, except that it must return void. + // + // This function exists mainly to implement the Cap'n Proto requirement that RPC calls cannot be + // canceled unless the callee explicitly permits it. + + kj::String trace(); + // Returns a dump of debug info about this promise. Not for production use. Requires RTTI. + // This method does NOT consume the promise as other methods do. + +private: + Promise(bool, Own<_::PromiseNode>&& node): PromiseBase(kj::mv(node)) {} + // Second parameter prevent ambiguity with immediate-value constructor. + + template <typename> + friend class Promise; + friend class EventLoop; + template <typename U, typename Adapter, typename... Params> + friend Promise<U> newAdaptedPromise(Params&&... adapterConstructorParams); + template <typename U> + friend PromiseFulfillerPair<U> newPromiseAndFulfiller(); + template <typename> + friend class _::ForkHub; + friend class _::TaskSetImpl; + friend Promise<void> _::yield(); + friend class _::NeverDone; + template <typename U> + friend Promise<Array<U>> joinPromises(Array<Promise<U>>&& promises); + friend Promise<void> joinPromises(Array<Promise<void>>&& promises); +}; + +template <typename T> +class ForkedPromise { + // The result of `Promise::fork()` and `EventLoop::fork()`. Allows branches to be created. + // Like `Promise<T>`, this is a pass-by-move type. + +public: + inline ForkedPromise(decltype(nullptr)) {} + + Promise<T> addBranch(); + // Add a new branch to the fork. The branch is equivalent to the original promise. + +private: + Own<_::ForkHub<_::FixVoid<T>>> hub; + + inline ForkedPromise(bool, Own<_::ForkHub<_::FixVoid<T>>>&& hub): hub(kj::mv(hub)) {} + + friend class Promise<T>; + friend class EventLoop; +}; + +constexpr _::Void READY_NOW = _::Void(); +// Use this when you need a Promise<void> that is already fulfilled -- this value can be implicitly +// cast to `Promise<void>`. + +constexpr _::NeverDone NEVER_DONE = _::NeverDone(); +// The opposite of `READY_NOW`, return this when the promise should never resolve. This can be +// implicitly converted to any promise type. You may also call `NEVER_DONE.wait()` to wait +// forever (useful for servers). + +template <typename Func> +PromiseForResult<Func, void> evalLater(Func&& func) KJ_WARN_UNUSED_RESULT; +// Schedule for the given zero-parameter function to be executed in the event loop at some +// point in the near future. Returns a Promise for its result -- or, if `func()` itself returns +// a promise, `evalLater()` returns a Promise for the result of resolving that promise. +// +// Example usage: +// Promise<int> x = evalLater([]() { return 123; }); +// +// The above is exactly equivalent to: +// Promise<int> x = Promise<void>(READY_NOW).then([]() { return 123; }); +// +// If the returned promise is destroyed before the callback runs, the callback will be canceled +// (never called). +// +// If you schedule several evaluations with `evalLater` during the same callback, they are +// guaranteed to be executed in order. + +template <typename Func> +PromiseForResult<Func, void> evalNow(Func&& func) KJ_WARN_UNUSED_RESULT; +// Run `func()` and return a promise for its result. `func()` executes before `evalNow()` returns. +// If `func()` throws an exception, the exception is caught and wrapped in a promise -- this is the +// main reason why `evalNow()` is useful. + +template <typename T> +Promise<Array<T>> joinPromises(Array<Promise<T>>&& promises); +// Join an array of promises into a promise for an array. + +// ======================================================================================= +// Hack for creating a lambda that holds an owned pointer. + +template <typename Func, typename MovedParam> +class CaptureByMove { +public: + inline CaptureByMove(Func&& func, MovedParam&& param) + : func(kj::mv(func)), param(kj::mv(param)) {} + + template <typename... Params> + inline auto operator()(Params&&... params) + -> decltype(kj::instance<Func>()(kj::instance<MovedParam&&>(), kj::fwd<Params>(params)...)) { + return func(kj::mv(param), kj::fwd<Params>(params)...); + } + +private: + Func func; + MovedParam param; +}; + +template <typename Func, typename MovedParam> +inline CaptureByMove<Func, Decay<MovedParam>> mvCapture(MovedParam&& param, Func&& func) { + // Hack to create a "lambda" which captures a variable by moving it rather than copying or + // referencing. C++14 generalized captures should make this obsolete, but for now in C++11 this + // is commonly needed for Promise continuations that own their state. Example usage: + // + // Own<Foo> ptr = makeFoo(); + // Promise<int> promise = callRpc(); + // promise.then(mvCapture(ptr, [](Own<Foo>&& ptr, int result) { + // return ptr->finish(result); + // })); + + return CaptureByMove<Func, Decay<MovedParam>>(kj::fwd<Func>(func), kj::mv(param)); +} + +// ======================================================================================= +// Advanced promise construction + +template <typename T> +class PromiseFulfiller { + // A callback which can be used to fulfill a promise. Only the first call to fulfill() or + // reject() matters; subsequent calls are ignored. + +public: + virtual void fulfill(T&& value) = 0; + // Fulfill the promise with the given value. + + virtual void reject(Exception&& exception) = 0; + // Reject the promise with an error. + + virtual bool isWaiting() = 0; + // Returns true if the promise is still unfulfilled and someone is potentially waiting for it. + // Returns false if fulfill()/reject() has already been called *or* if the promise to be + // fulfilled has been discarded and therefore the result will never be used anyway. + + template <typename Func> + bool rejectIfThrows(Func&& func); + // Call the function (with no arguments) and return true. If an exception is thrown, call + // `fulfiller.reject()` and then return false. When compiled with exceptions disabled, + // non-fatal exceptions are still detected and handled correctly. +}; + +template <> +class PromiseFulfiller<void> { + // Specialization of PromiseFulfiller for void promises. See PromiseFulfiller<T>. + +public: + virtual void fulfill(_::Void&& value = _::Void()) = 0; + // Call with zero parameters. The parameter is a dummy that only exists so that subclasses don't + // have to specialize for <void>. + + virtual void reject(Exception&& exception) = 0; + virtual bool isWaiting() = 0; + + template <typename Func> + bool rejectIfThrows(Func&& func); +}; + +template <typename T, typename Adapter, typename... Params> +Promise<T> newAdaptedPromise(Params&&... adapterConstructorParams); +// Creates a new promise which owns an instance of `Adapter` which encapsulates the operation +// that will eventually fulfill the promise. This is primarily useful for adapting non-KJ +// asynchronous APIs to use promises. +// +// An instance of `Adapter` will be allocated and owned by the returned `Promise`. A +// `PromiseFulfiller<T>&` will be passed as the first parameter to the adapter's constructor, +// and `adapterConstructorParams` will be forwarded as the subsequent parameters. The adapter +// is expected to perform some asynchronous operation and call the `PromiseFulfiller<T>` once +// it is finished. +// +// The adapter is destroyed when its owning Promise is destroyed. This may occur before the +// Promise has been fulfilled. In this case, the adapter's destructor should cancel the +// asynchronous operation. Once the adapter is destroyed, the fulfillment callback cannot be +// called. +// +// An adapter implementation should be carefully written to ensure that it cannot accidentally +// be left unfulfilled permanently because of an exception. Consider making liberal use of +// `PromiseFulfiller<T>::rejectIfThrows()`. + +template <typename T> +struct PromiseFulfillerPair { + Promise<_::JoinPromises<T>> promise; + Own<PromiseFulfiller<T>> fulfiller; +}; + +template <typename T> +PromiseFulfillerPair<T> newPromiseAndFulfiller(); +// Construct a Promise and a separate PromiseFulfiller which can be used to fulfill the promise. +// If the PromiseFulfiller is destroyed before either of its methods are called, the Promise is +// implicitly rejected. +// +// Although this function is easier to use than `newAdaptedPromise()`, it has the serious drawback +// that there is no way to handle cancellation (i.e. detect when the Promise is discarded). +// +// You can arrange to fulfill a promise with another promise by using a promise type for T. E.g. +// `newPromiseAndFulfiller<Promise<U>>()` will produce a promise of type `Promise<U>` but the +// fulfiller will be of type `PromiseFulfiller<Promise<U>>`. Thus you pass a `Promise<U>` to the +// `fulfill()` callback, and the promises are chained. + +// ======================================================================================= +// TaskSet + +class TaskSet { + // Holds a collection of Promise<void>s and ensures that each executes to completion. Memory + // associated with each promise is automatically freed when the promise completes. Destroying + // the TaskSet itself automatically cancels all unfinished promises. + // + // This is useful for "daemon" objects that perform background tasks which aren't intended to + // fulfill any particular external promise, but which may need to be canceled (and thus can't + // use `Promise::detach()`). The daemon object holds a TaskSet to collect these tasks it is + // working on. This way, if the daemon itself is destroyed, the TaskSet is detroyed as well, + // and everything the daemon is doing is canceled. + +public: + class ErrorHandler { + public: + virtual void taskFailed(kj::Exception&& exception) = 0; + }; + + TaskSet(ErrorHandler& errorHandler); + // `loop` will be used to wait on promises. `errorHandler` will be executed any time a task + // throws an exception, and will execute within the given EventLoop. + + ~TaskSet() noexcept(false); + + void add(Promise<void>&& promise); + + kj::String trace(); + // Return debug info about all promises currently in the TaskSet. + +private: + Own<_::TaskSetImpl> impl; +}; + +// ======================================================================================= +// The EventLoop class + +class EventPort { + // Interfaces between an `EventLoop` and events originating from outside of the loop's thread. + // All such events come in through the `EventPort` implementation. + // + // An `EventPort` implementation may interface with low-level operating system APIs and/or other + // threads. You can also write an `EventPort` which wraps some other (non-KJ) event loop + // framework, allowing the two to coexist in a single thread. + +public: + virtual bool wait() = 0; + // Wait for an external event to arrive, sleeping if necessary. Once at least one event has + // arrived, queue it to the event loop (e.g. by fulfilling a promise) and return. + // + // This is called during `Promise::wait()` whenever the event queue becomes empty, in order to + // wait for new events to populate the queue. + // + // It is safe to return even if nothing has actually been queued, so long as calling `wait()` in + // a loop will eventually sleep. (That is to say, false positives are fine.) + // + // Returns true if wake() has been called from another thread. (Precisely, returns true if + // no previous call to wait `wait()` nor `poll()` has returned true since `wake()` was last + // called.) + + virtual bool poll() = 0; + // Check if any external events have arrived, but do not sleep. If any events have arrived, + // add them to the event queue (e.g. by fulfilling promises) before returning. + // + // This may be called during `Promise::wait()` when the EventLoop has been executing for a while + // without a break but is still non-empty. + // + // Returns true if wake() has been called from another thread. (Precisely, returns true if + // no previous call to wait `wait()` nor `poll()` has returned true since `wake()` was last + // called.) + + virtual void setRunnable(bool runnable); + // Called to notify the `EventPort` when the `EventLoop` has work to do; specifically when it + // transitions from empty -> runnable or runnable -> empty. This is typically useful when + // integrating with an external event loop; if the loop is currently runnable then you should + // arrange to call run() on it soon. The default implementation does nothing. + + virtual void wake() const; + // Wake up the EventPort's thread from another thread. + // + // Unlike all other methods on this interface, `wake()` may be called from another thread, hence + // it is `const`. + // + // Technically speaking, `wake()` causes the target thread to cease sleeping and not to sleep + // again until `wait()` or `poll()` has returned true at least once. + // + // The default implementation throws an UNIMPLEMENTED exception. +}; + +class EventLoop { + // Represents a queue of events being executed in a loop. Most code won't interact with + // EventLoop directly, but instead use `Promise`s to interact with it indirectly. See the + // documentation for `Promise`. + // + // Each thread can have at most one current EventLoop. To make an `EventLoop` current for + // the thread, create a `WaitScope`. Async APIs require that the thread has a current EventLoop, + // or they will throw exceptions. APIs that use `Promise::wait()` additionally must explicitly + // be passed a reference to the `WaitScope` to make the caller aware that they might block. + // + // Generally, you will want to construct an `EventLoop` at the top level of your program, e.g. + // in the main() function, or in the start function of a thread. You can then use it to + // construct some promises and wait on the result. Example: + // + // int main() { + // // `loop` becomes the official EventLoop for the thread. + // MyEventPort eventPort; + // EventLoop loop(eventPort); + // + // // Now we can call an async function. + // Promise<String> textPromise = getHttp("http://example.com"); + // + // // And we can wait for the promise to complete. Note that you can only use `wait()` + // // from the top level, not from inside a promise callback. + // String text = textPromise.wait(); + // print(text); + // return 0; + // } + // + // Most applications that do I/O will prefer to use `setupAsyncIo()` from `async-io.h` rather + // than allocate an `EventLoop` directly. + +public: + EventLoop(); + // Construct an `EventLoop` which does not receive external events at all. + + explicit EventLoop(EventPort& port); + // Construct an `EventLoop` which receives external events through the given `EventPort`. + + ~EventLoop() noexcept(false); + + void run(uint maxTurnCount = maxValue); + // Run the event loop for `maxTurnCount` turns or until there is nothing left to be done, + // whichever comes first. This never calls the `EventPort`'s `sleep()` or `poll()`. It will + // call the `EventPort`'s `setRunnable(false)` if the queue becomes empty. + + bool isRunnable(); + // Returns true if run() would currently do anything, or false if the queue is empty. + +private: + EventPort& port; + + bool running = false; + // True while looping -- wait() is then not allowed. + + bool lastRunnableState = false; + // What did we last pass to port.setRunnable()? + + _::Event* head = nullptr; + _::Event** tail = &head; + _::Event** depthFirstInsertPoint = &head; + + Own<_::TaskSetImpl> daemons; + + bool turn(); + void setRunnable(bool runnable); + void enterScope(); + void leaveScope(); + + friend void _::detach(kj::Promise<void>&& promise); + friend void _::waitImpl(Own<_::PromiseNode>&& node, _::ExceptionOrValue& result, + WaitScope& waitScope); + friend class _::Event; + friend class WaitScope; +}; + +class WaitScope { + // Represents a scope in which asynchronous programming can occur. A `WaitScope` should usually + // be allocated on the stack and serves two purposes: + // * While the `WaitScope` exists, its `EventLoop` is registered as the current loop for the + // thread. Most operations dealing with `Promise` (including all of its methods) do not work + // unless the thread has a current `EventLoop`. + // * `WaitScope` may be passed to `Promise::wait()` to synchronously wait for a particular + // promise to complete. See `Promise::wait()` for an extended discussion. + +public: + inline explicit WaitScope(EventLoop& loop): loop(loop) { loop.enterScope(); } + inline ~WaitScope() { loop.leaveScope(); } + KJ_DISALLOW_COPY(WaitScope); + +private: + EventLoop& loop; + friend class EventLoop; + friend void _::waitImpl(Own<_::PromiseNode>&& node, _::ExceptionOrValue& result, + WaitScope& waitScope); +}; + +} // namespace kj + +#include "async-inl.h" + +#endif // KJ_ASYNC_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/common.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,1342 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// Header that should be #included by everyone. +// +// This defines very simple utilities that are widely applicable. + +#ifndef KJ_COMMON_H_ +#define KJ_COMMON_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#ifndef KJ_NO_COMPILER_CHECK +#if __cplusplus < 201103L && !__CDT_PARSER__ && !_MSC_VER + #error "This code requires C++11. Either your compiler does not support it or it is not enabled." + #ifdef __GNUC__ + // Compiler claims compatibility with GCC, so presumably supports -std. + #error "Pass -std=c++11 on the compiler command line to enable C++11." + #endif +#endif + +#ifdef __GNUC__ + #if __clang__ + #if __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2) + #warning "This library requires at least Clang 3.2." + #elif defined(__apple_build_version__) && __apple_build_version__ <= 4250028 + #warning "This library requires at least Clang 3.2. XCode 4.6's Clang, which claims to be "\ + "version 4.2 (wat?), is actually built from some random SVN revision between 3.1 "\ + "and 3.2. Unfortunately, it is insufficient for compiling this library. You can "\ + "download the real Clang 3.2 (or newer) from the Clang web site. Step-by-step "\ + "instructions can be found in Cap'n Proto's documentation: "\ + "http://kentonv.github.io/capnproto/install.html#clang_32_on_mac_osx" + #elif __cplusplus >= 201103L && !__has_include(<initializer_list>) + #warning "Your compiler supports C++11 but your C++ standard library does not. If your "\ + "system has libc++ installed (as should be the case on e.g. Mac OSX), try adding "\ + "-stdlib=libc++ to your CXXFLAGS." + #endif + #else + #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7) + #warning "This library requires at least GCC 4.7." + #endif + #endif +#elif defined(_MSC_VER) + #if _MSC_VER < 1900 + #error "You need Visual Studio 2015 or better to compile this code." + #elif !CAPNP_LITE + // TODO(cleanup): This is KJ, but we're talking about Cap'n Proto. + #error "As of this writing, Cap'n Proto only supports Visual C++ in 'lite mode'; please #define CAPNP_LITE" + #endif +#else + #warning "I don't recognize your compiler. As of this writing, Clang and GCC are the only "\ + "known compilers with enough C++11 support for this library. "\ + "#define KJ_NO_COMPILER_CHECK to make this warning go away." +#endif +#endif + +#include <stddef.h> +#include <initializer_list> + +#if __linux__ && __cplusplus > 201200L +// Hack around stdlib bug with C++14 that exists on some Linux systems. +// Apparently in this mode the C library decides not to define gets() but the C++ library still +// tries to import it into the std namespace. This bug has been fixed at the source but is still +// widely present in the wild e.g. on Ubuntu 14.04. +#undef _GLIBCXX_HAVE_GETS +#endif + +#if defined(_MSC_VER) +#include <intrin.h> // __popcnt +#endif + +// ======================================================================================= + +namespace kj { + +typedef unsigned int uint; +typedef unsigned char byte; + +// ======================================================================================= +// Common macros, especially for common yet compiler-specific features. + +// Detect whether RTTI and exceptions are enabled, assuming they are unless we have specific +// evidence to the contrary. Clients can always define KJ_NO_RTTI or KJ_NO_EXCEPTIONS explicitly +// to override these checks. +#ifdef __GNUC__ + #if !defined(KJ_NO_RTTI) && !__GXX_RTTI + #define KJ_NO_RTTI 1 + #endif + #if !defined(KJ_NO_EXCEPTIONS) && !__EXCEPTIONS + #define KJ_NO_EXCEPTIONS 1 + #endif +#elif defined(_MSC_VER) + #if !defined(KJ_NO_RTTI) && !defined(_CPPRTTI) + #define KJ_NO_RTTI 1 + #endif + #if !defined(KJ_NO_EXCEPTIONS) && !defined(_CPPUNWIND) + #define KJ_NO_EXCEPTIONS 1 + #endif +#endif + +#if !defined(KJ_DEBUG) && !defined(KJ_NDEBUG) +// Heuristically decide whether to enable debug mode. If DEBUG or NDEBUG is defined, use that. +// Otherwise, fall back to checking whether optimization is enabled. +#if defined(DEBUG) || defined(_DEBUG) +#define KJ_DEBUG +#elif defined(NDEBUG) +#define KJ_NDEBUG +#elif __OPTIMIZE__ +#define KJ_NDEBUG +#else +#define KJ_DEBUG +#endif +#endif + +#define KJ_DISALLOW_COPY(classname) \ + classname(const classname&) = delete; \ + classname& operator=(const classname&) = delete +// Deletes the implicit copy constructor and assignment operator. + +#ifdef __GNUC__ +#define KJ_LIKELY(condition) __builtin_expect(condition, true) +#define KJ_UNLIKELY(condition) __builtin_expect(condition, false) +// Branch prediction macros. Evaluates to the condition given, but also tells the compiler that we +// expect the condition to be true/false enough of the time that it's worth hard-coding branch +// prediction. +#else +#define KJ_LIKELY(condition) (condition) +#define KJ_UNLIKELY(condition) (condition) +#endif + +#if defined(KJ_DEBUG) || __NO_INLINE__ +#define KJ_ALWAYS_INLINE(prototype) inline prototype +// Don't force inline in debug mode. +#else +#if defined(_MSC_VER) +#define KJ_ALWAYS_INLINE(prototype) __forceinline prototype +#else +#define KJ_ALWAYS_INLINE(prototype) inline prototype __attribute__((always_inline)) +#endif +// Force a function to always be inlined. Apply only to the prototype, not to the definition. +#endif + +#if defined(_MSC_VER) +#define KJ_NOINLINE __declspec(noinline) +#else +#define KJ_NOINLINE __attribute__((noinline)) +#endif + +#if defined(_MSC_VER) +#define KJ_NORETURN(prototype) __declspec(noreturn) prototype +#define KJ_UNUSED +#define KJ_WARN_UNUSED_RESULT +// TODO(msvc): KJ_WARN_UNUSED_RESULT can use _Check_return_ on MSVC, but it's a prefix, so +// wrapping the whole prototype is needed. http://msdn.microsoft.com/en-us/library/jj159529.aspx +// Similarly, KJ_UNUSED could use __pragma(warning(suppress:...)), but again that's a prefix. +#else +#define KJ_NORETURN(prototype) prototype __attribute__((noreturn)) +#define KJ_UNUSED __attribute__((unused)) +#define KJ_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +#endif + +#if __clang__ +#define KJ_UNUSED_MEMBER __attribute__((unused)) +// Inhibits "unused" warning for member variables. Only Clang produces such a warning, while GCC +// complains if the attribute is set on members. +#else +#define KJ_UNUSED_MEMBER +#endif + +#if __clang__ +#define KJ_DEPRECATED(reason) \ + __attribute__((deprecated(reason))) +#define KJ_UNAVAILABLE(reason) \ + __attribute__((unavailable(reason))) +#elif __GNUC__ +#define KJ_DEPRECATED(reason) \ + __attribute__((deprecated)) +#define KJ_UNAVAILABLE(reason) +#else +#define KJ_DEPRECATED(reason) +#define KJ_UNAVAILABLE(reason) +// TODO(msvc): Again, here, MSVC prefers a prefix, __declspec(deprecated). +#endif + +namespace _ { // private + +KJ_NORETURN(void inlineRequireFailure( + const char* file, int line, const char* expectation, const char* macroArgs, + const char* message = nullptr)); + +KJ_NORETURN(void unreachable()); + +} // namespace _ (private) + +#ifdef KJ_DEBUG +#if _MSC_VER +#define KJ_IREQUIRE(condition, ...) \ + if (KJ_LIKELY(condition)); else ::kj::_::inlineRequireFailure( \ + __FILE__, __LINE__, #condition, "" #__VA_ARGS__, __VA_ARGS__) +// Version of KJ_DREQUIRE() which is safe to use in headers that are #included by users. Used to +// check preconditions inside inline methods. KJ_IREQUIRE is particularly useful in that +// it will be enabled depending on whether the application is compiled in debug mode rather than +// whether libkj is. +#else +#define KJ_IREQUIRE(condition, ...) \ + if (KJ_LIKELY(condition)); else ::kj::_::inlineRequireFailure( \ + __FILE__, __LINE__, #condition, #__VA_ARGS__, ##__VA_ARGS__) +// Version of KJ_DREQUIRE() which is safe to use in headers that are #included by users. Used to +// check preconditions inside inline methods. KJ_IREQUIRE is particularly useful in that +// it will be enabled depending on whether the application is compiled in debug mode rather than +// whether libkj is. +#endif +#else +#define KJ_IREQUIRE(condition, ...) +#endif + +#define KJ_IASSERT KJ_IREQUIRE + +#define KJ_UNREACHABLE ::kj::_::unreachable(); +// Put this on code paths that cannot be reached to suppress compiler warnings about missing +// returns. + +#if __clang__ +#define KJ_CLANG_KNOWS_THIS_IS_UNREACHABLE_BUT_GCC_DOESNT +#else +#define KJ_CLANG_KNOWS_THIS_IS_UNREACHABLE_BUT_GCC_DOESNT KJ_UNREACHABLE +#endif + +// #define KJ_STACK_ARRAY(type, name, size, minStack, maxStack) +// +// Allocate an array, preferably on the stack, unless it is too big. On GCC this will use +// variable-sized arrays. For other compilers we could just use a fixed-size array. `minStack` +// is the stack array size to use if variable-width arrays are not supported. `maxStack` is the +// maximum stack array size if variable-width arrays *are* supported. +#if __GNUC__ && !__clang__ +#define KJ_STACK_ARRAY(type, name, size, minStack, maxStack) \ + size_t name##_size = (size); \ + bool name##_isOnStack = name##_size <= (maxStack); \ + type name##_stack[name##_isOnStack ? size : 0]; \ + ::kj::Array<type> name##_heap = name##_isOnStack ? \ + nullptr : kj::heapArray<type>(name##_size); \ + ::kj::ArrayPtr<type> name = name##_isOnStack ? \ + kj::arrayPtr(name##_stack, name##_size) : name##_heap +#else +#define KJ_STACK_ARRAY(type, name, size, minStack, maxStack) \ + size_t name##_size = (size); \ + bool name##_isOnStack = name##_size <= (minStack); \ + type name##_stack[minStack]; \ + ::kj::Array<type> name##_heap = name##_isOnStack ? \ + nullptr : kj::heapArray<type>(name##_size); \ + ::kj::ArrayPtr<type> name = name##_isOnStack ? \ + kj::arrayPtr(name##_stack, name##_size) : name##_heap +#endif + +#define KJ_CONCAT_(x, y) x##y +#define KJ_CONCAT(x, y) KJ_CONCAT_(x, y) +#define KJ_UNIQUE_NAME(prefix) KJ_CONCAT(prefix, __LINE__) +// Create a unique identifier name. We use concatenate __LINE__ rather than __COUNTER__ so that +// the name can be used multiple times in the same macro. + +#if _MSC_VER + +#define KJ_CONSTEXPR(...) __VA_ARGS__ +// Use in cases where MSVC barfs on constexpr. A replacement keyword (e.g. "const") can be +// provided, or just leave blank to remove the keyword entirely. +// +// TODO(msvc): Remove this hack once MSVC fully supports constexpr. + +#ifndef __restrict__ +#define __restrict__ __restrict +// TODO(msvc): Would it be better to define a KJ_RESTRICT macro? +#endif + +#pragma warning(disable: 4521 4522) +// This warning complains when there are two copy constructors, one for a const reference and +// one for a non-const reference. It is often quite necessary to do this in wrapper templates, +// therefore this warning is dumb and we disable it. + +#pragma warning(disable: 4458) +// Warns when a parameter name shadows a class member. Unfortunately my code does this a lot, +// since I don't use a special name format for members. + +#else // _MSC_VER +#define KJ_CONSTEXPR(...) constexpr +#endif + +// ======================================================================================= +// Template metaprogramming helpers. + +template <typename T> struct NoInfer_ { typedef T Type; }; +template <typename T> using NoInfer = typename NoInfer_<T>::Type; +// Use NoInfer<T>::Type in place of T for a template function parameter to prevent inference of +// the type based on the parameter value. + +template <typename T> struct RemoveConst_ { typedef T Type; }; +template <typename T> struct RemoveConst_<const T> { typedef T Type; }; +template <typename T> using RemoveConst = typename RemoveConst_<T>::Type; + +template <typename> struct IsLvalueReference_ { static constexpr bool value = false; }; +template <typename T> struct IsLvalueReference_<T&> { static constexpr bool value = true; }; +template <typename T> +inline constexpr bool isLvalueReference() { return IsLvalueReference_<T>::value; } + +template <typename T> struct Decay_ { typedef T Type; }; +template <typename T> struct Decay_<T&> { typedef typename Decay_<T>::Type Type; }; +template <typename T> struct Decay_<T&&> { typedef typename Decay_<T>::Type Type; }; +template <typename T> struct Decay_<T[]> { typedef typename Decay_<T*>::Type Type; }; +template <typename T> struct Decay_<const T[]> { typedef typename Decay_<const T*>::Type Type; }; +template <typename T, size_t s> struct Decay_<T[s]> { typedef typename Decay_<T*>::Type Type; }; +template <typename T, size_t s> struct Decay_<const T[s]> { typedef typename Decay_<const T*>::Type Type; }; +template <typename T> struct Decay_<const T> { typedef typename Decay_<T>::Type Type; }; +template <typename T> struct Decay_<volatile T> { typedef typename Decay_<T>::Type Type; }; +template <typename T> using Decay = typename Decay_<T>::Type; + +template <bool b> struct EnableIf_; +template <> struct EnableIf_<true> { typedef void Type; }; +template <bool b> using EnableIf = typename EnableIf_<b>::Type; +// Use like: +// +// template <typename T, typename = EnableIf<isValid<T>()> +// void func(T&& t); + +template <typename...> struct VoidSfinae_ { using Type = void; }; +template <typename... Ts> using VoidSfinae = typename VoidSfinae_<Ts...>::Type; +// Note: VoidSfinae is std::void_t from C++17. + +template <typename T> +T instance() noexcept; +// Like std::declval, but doesn't transform T into an rvalue reference. If you want that, specify +// instance<T&&>(). + +struct DisallowConstCopy { + // Inherit from this, or declare a member variable of this type, to prevent the class from being + // copyable from a const reference -- instead, it will only be copyable from non-const references. + // This is useful for enforcing transitive constness of contained pointers. + // + // For example, say you have a type T which contains a pointer. T has non-const methods which + // modify the value at that pointer, but T's const methods are designed to allow reading only. + // Unfortunately, if T has a regular copy constructor, someone can simply make a copy of T and + // then use it to modify the pointed-to value. However, if T inherits DisallowConstCopy, then + // callers will only be able to copy non-const instances of T. Ideally, there is some + // parallel type ImmutableT which is like a version of T that only has const methods, and can + // be copied from a const T. + // + // Note that due to C++ rules about implicit copy constructors and assignment operators, any + // type that contains or inherits from a type that disallows const copies will also automatically + // disallow const copies. Hey, cool, that's exactly what we want. + + DisallowConstCopy() = default; + DisallowConstCopy(DisallowConstCopy&) = default; + DisallowConstCopy(DisallowConstCopy&&) = default; + DisallowConstCopy& operator=(DisallowConstCopy&) = default; + DisallowConstCopy& operator=(DisallowConstCopy&&) = default; +}; + +template <typename T> +struct DisallowConstCopyIfNotConst: public DisallowConstCopy { + // Inherit from this when implementing a template that contains a pointer to T and which should + // enforce transitive constness. If T is a const type, this has no effect. Otherwise, it is + // an alias for DisallowConstCopy. +}; + +template <typename T> +struct DisallowConstCopyIfNotConst<const T> {}; + +template <typename T> struct IsConst_ { static constexpr bool value = false; }; +template <typename T> struct IsConst_<const T> { static constexpr bool value = true; }; +template <typename T> constexpr bool isConst() { return IsConst_<T>::value; } + +template <typename T> struct EnableIfNotConst_ { typedef T Type; }; +template <typename T> struct EnableIfNotConst_<const T>; +template <typename T> using EnableIfNotConst = typename EnableIfNotConst_<T>::Type; + +template <typename T> struct EnableIfConst_; +template <typename T> struct EnableIfConst_<const T> { typedef T Type; }; +template <typename T> using EnableIfConst = typename EnableIfConst_<T>::Type; + +template <typename T> struct RemoveConstOrDisable_ { struct Type; }; +template <typename T> struct RemoveConstOrDisable_<const T> { typedef T Type; }; +template <typename T> using RemoveConstOrDisable = typename RemoveConstOrDisable_<T>::Type; + +template <typename T> struct IsReference_ { static constexpr bool value = false; }; +template <typename T> struct IsReference_<T&> { static constexpr bool value = true; }; +template <typename T> constexpr bool isReference() { return IsReference_<T>::value; } + +template <typename From, typename To> +struct PropagateConst_ { typedef To Type; }; +template <typename From, typename To> +struct PropagateConst_<const From, To> { typedef const To Type; }; +template <typename From, typename To> +using PropagateConst = typename PropagateConst_<From, To>::Type; + +namespace _ { // private + +template <typename T> +T refIfLvalue(T&&); + +} // namespace _ (private) + +#define KJ_DECLTYPE_REF(exp) decltype(::kj::_::refIfLvalue(exp)) +// Like decltype(exp), but if exp is an lvalue, produces a reference type. +// +// int i; +// decltype(i) i1(i); // i1 has type int. +// KJ_DECLTYPE_REF(i + 1) i2(i + 1); // i2 has type int. +// KJ_DECLTYPE_REF(i) i3(i); // i3 has type int&. +// KJ_DECLTYPE_REF(kj::mv(i)) i4(kj::mv(i)); // i4 has type int. + +template <typename T> +struct CanConvert_ { + static int sfinae(T); + static bool sfinae(...); +}; + +template <typename T, typename U> +constexpr bool canConvert() { + return sizeof(CanConvert_<U>::sfinae(instance<T>())) == sizeof(int); +} + +#if __clang__ +template <typename T> +constexpr bool canMemcpy() { + // Returns true if T can be copied using memcpy instead of using the copy constructor or + // assignment operator. + + // Clang unhelpfully defines __has_trivial_{copy,assign}(T) to be true if the copy constructor / + // assign operator are deleted, on the basis that a strict reading of the definition of "trivial" + // according to the standard says that deleted functions are in fact trivial. Meanwhile Clang + // provides these admittedly-better intrinsics, but GCC does not. + return __is_trivially_constructible(T, const T&) && __is_trivially_assignable(T, const T&); +} +#else +template <typename T> +constexpr bool canMemcpy() { + // Returns true if T can be copied using memcpy instead of using the copy constructor or + // assignment operator. + + // GCC defines these to mean what we want them to mean. + return __has_trivial_copy(T) && __has_trivial_assign(T); +} +#endif + +// ======================================================================================= +// Equivalents to std::move() and std::forward(), since these are very commonly needed and the +// std header <utility> pulls in lots of other stuff. +// +// We use abbreviated names mv and fwd because these helpers (especially mv) are so commonly used +// that the cost of typing more letters outweighs the cost of being slightly harder to understand +// when first encountered. + +template<typename T> constexpr T&& mv(T& t) noexcept { return static_cast<T&&>(t); } +template<typename T> constexpr T&& fwd(NoInfer<T>& t) noexcept { return static_cast<T&&>(t); } + +template<typename T> constexpr T cp(T& t) noexcept { return t; } +template<typename T> constexpr T cp(const T& t) noexcept { return t; } +// Useful to force a copy, particularly to pass into a function that expects T&&. + +template <typename T, typename U, bool takeT> struct MinType_; +template <typename T, typename U> struct MinType_<T, U, true> { typedef T Type; }; +template <typename T, typename U> struct MinType_<T, U, false> { typedef U Type; }; + +template <typename T, typename U> +using MinType = typename MinType_<T, U, sizeof(T) <= sizeof(U)>::Type; +// Resolves to the smaller of the two input types. + +template <typename T, typename U> +inline constexpr auto min(T&& a, U&& b) -> MinType<Decay<T>, Decay<U>> { + return a < b ? MinType<Decay<T>, Decay<U>>(a) : MinType<Decay<T>, Decay<U>>(b); +} + +template <typename T, typename U, bool takeT> struct MaxType_; +template <typename T, typename U> struct MaxType_<T, U, true> { typedef T Type; }; +template <typename T, typename U> struct MaxType_<T, U, false> { typedef U Type; }; + +template <typename T, typename U> +using MaxType = typename MaxType_<T, U, sizeof(T) >= sizeof(U)>::Type; +// Resolves to the larger of the two input types. + +template <typename T, typename U> +inline constexpr auto max(T&& a, U&& b) -> MaxType<Decay<T>, Decay<U>> { + return a > b ? MaxType<Decay<T>, Decay<U>>(a) : MaxType<Decay<T>, Decay<U>>(b); +} + +template <typename T, size_t s> +inline constexpr size_t size(T (&arr)[s]) { return s; } +template <typename T> +inline constexpr size_t size(T&& arr) { return arr.size(); } +// Returns the size of the parameter, whether the parameter is a regular C array or a container +// with a `.size()` method. + +class MaxValue_ { +private: + template <typename T> + inline constexpr T maxSigned() const { + return (1ull << (sizeof(T) * 8 - 1)) - 1; + } + template <typename T> + inline constexpr T maxUnsigned() const { + return ~static_cast<T>(0u); + } + +public: +#define _kJ_HANDLE_TYPE(T) \ + inline constexpr operator signed T() const { return MaxValue_::maxSigned < signed T>(); } \ + inline constexpr operator unsigned T() const { return MaxValue_::maxUnsigned<unsigned T>(); } + _kJ_HANDLE_TYPE(char) + _kJ_HANDLE_TYPE(short) + _kJ_HANDLE_TYPE(int) + _kJ_HANDLE_TYPE(long) + _kJ_HANDLE_TYPE(long long) +#undef _kJ_HANDLE_TYPE + + inline constexpr operator char() const { + // `char` is different from both `signed char` and `unsigned char`, and may be signed or + // unsigned on different platforms. Ugh. + return char(-1) < 0 ? MaxValue_::maxSigned<char>() + : MaxValue_::maxUnsigned<char>(); + } +}; + +class MinValue_ { +private: + template <typename T> + inline constexpr T minSigned() const { + return 1ull << (sizeof(T) * 8 - 1); + } + template <typename T> + inline constexpr T minUnsigned() const { + return 0u; + } + +public: +#define _kJ_HANDLE_TYPE(T) \ + inline constexpr operator signed T() const { return MinValue_::minSigned < signed T>(); } \ + inline constexpr operator unsigned T() const { return MinValue_::minUnsigned<unsigned T>(); } + _kJ_HANDLE_TYPE(char) + _kJ_HANDLE_TYPE(short) + _kJ_HANDLE_TYPE(int) + _kJ_HANDLE_TYPE(long) + _kJ_HANDLE_TYPE(long long) +#undef _kJ_HANDLE_TYPE + + inline constexpr operator char() const { + // `char` is different from both `signed char` and `unsigned char`, and may be signed or + // unsigned on different platforms. Ugh. + return char(-1) < 0 ? MinValue_::minSigned<char>() + : MinValue_::minUnsigned<char>(); + } +}; + +static KJ_CONSTEXPR(const) MaxValue_ maxValue = MaxValue_(); +// A special constant which, when cast to an integer type, takes on the maximum possible value of +// that type. This is useful to use as e.g. a parameter to a function because it will be robust +// in the face of changes to the parameter's type. +// +// `char` is not supported, but `signed char` and `unsigned char` are. + +static KJ_CONSTEXPR(const) MinValue_ minValue = MinValue_(); +// A special constant which, when cast to an integer type, takes on the minimum possible value +// of that type. This is useful to use as e.g. a parameter to a function because it will be robust +// in the face of changes to the parameter's type. +// +// `char` is not supported, but `signed char` and `unsigned char` are. + +#if __GNUC__ +inline constexpr float inf() { return __builtin_huge_valf(); } +inline constexpr float nan() { return __builtin_nanf(""); } + +#elif _MSC_VER + +// Do what MSVC math.h does +#pragma warning(push) +#pragma warning(disable: 4756) // "overflow in constant arithmetic" +inline constexpr float inf() { return (float)(1e300 * 1e300); } +#pragma warning(pop) + +float nan(); +// Unfortunatley, inf() * 0.0f produces a NaN with the sign bit set, whereas our preferred +// canonical NaN should not have the sign bit set. std::numeric_limits<float>::quiet_NaN() +// returns the correct NaN, but we don't want to #include that here. So, we give up and make +// this out-of-line on MSVC. +// +// TODO(msvc): Can we do better? + +#else +#error "Not sure how to support your compiler." +#endif + +inline constexpr bool isNaN(float f) { return f != f; } +inline constexpr bool isNaN(double f) { return f != f; } + +inline int popCount(unsigned int x) { +#if defined(_MSC_VER) + return __popcnt(x); + // Note: __popcnt returns unsigned int, but the value is clearly guaranteed to fit into an int +#else + return __builtin_popcount(x); +#endif +} + +// ======================================================================================= +// Useful fake containers + +template <typename T> +class Range { +public: + inline constexpr Range(const T& begin, const T& end): begin_(begin), end_(end) {} + + class Iterator { + public: + Iterator() = default; + inline Iterator(const T& value): value(value) {} + + inline const T& operator* () const { return value; } + inline const T& operator[](size_t index) const { return value + index; } + inline Iterator& operator++() { ++value; return *this; } + inline Iterator operator++(int) { return Iterator(value++); } + inline Iterator& operator--() { --value; return *this; } + inline Iterator operator--(int) { return Iterator(value--); } + inline Iterator& operator+=(ptrdiff_t amount) { value += amount; return *this; } + inline Iterator& operator-=(ptrdiff_t amount) { value -= amount; return *this; } + inline Iterator operator+ (ptrdiff_t amount) const { return Iterator(value + amount); } + inline Iterator operator- (ptrdiff_t amount) const { return Iterator(value - amount); } + inline ptrdiff_t operator- (const Iterator& other) const { return value - other.value; } + + inline bool operator==(const Iterator& other) const { return value == other.value; } + inline bool operator!=(const Iterator& other) const { return value != other.value; } + inline bool operator<=(const Iterator& other) const { return value <= other.value; } + inline bool operator>=(const Iterator& other) const { return value >= other.value; } + inline bool operator< (const Iterator& other) const { return value < other.value; } + inline bool operator> (const Iterator& other) const { return value > other.value; } + + private: + T value; + }; + + inline Iterator begin() const { return Iterator(begin_); } + inline Iterator end() const { return Iterator(end_); } + + inline auto size() const -> decltype(instance<T>() - instance<T>()) { return end_ - begin_; } + +private: + T begin_; + T end_; +}; + +template <typename T> +inline constexpr Range<Decay<T>> range(T begin, T end) { return Range<Decay<T>>(begin, end); } +// Returns a fake iterable container containing all values of T from `begin` (inclusive) to `end` +// (exclusive). Example: +// +// // Prints 1, 2, 3, 4, 5, 6, 7, 8, 9. +// for (int i: kj::range(1, 10)) { print(i); } + +template <typename T> +inline constexpr Range<size_t> indices(T&& container) { + // Shortcut for iterating over the indices of a container: + // + // for (size_t i: kj::indices(myArray)) { handle(myArray[i]); } + + return range<size_t>(0, kj::size(container)); +} + +template <typename T> +class Repeat { +public: + inline constexpr Repeat(const T& value, size_t count): value(value), count(count) {} + + class Iterator { + public: + Iterator() = default; + inline Iterator(const T& value, size_t index): value(value), index(index) {} + + inline const T& operator* () const { return value; } + inline const T& operator[](ptrdiff_t index) const { return value; } + inline Iterator& operator++() { ++index; return *this; } + inline Iterator operator++(int) { return Iterator(value, index++); } + inline Iterator& operator--() { --index; return *this; } + inline Iterator operator--(int) { return Iterator(value, index--); } + inline Iterator& operator+=(ptrdiff_t amount) { index += amount; return *this; } + inline Iterator& operator-=(ptrdiff_t amount) { index -= amount; return *this; } + inline Iterator operator+ (ptrdiff_t amount) const { return Iterator(value, index + amount); } + inline Iterator operator- (ptrdiff_t amount) const { return Iterator(value, index - amount); } + inline ptrdiff_t operator- (const Iterator& other) const { return index - other.index; } + + inline bool operator==(const Iterator& other) const { return index == other.index; } + inline bool operator!=(const Iterator& other) const { return index != other.index; } + inline bool operator<=(const Iterator& other) const { return index <= other.index; } + inline bool operator>=(const Iterator& other) const { return index >= other.index; } + inline bool operator< (const Iterator& other) const { return index < other.index; } + inline bool operator> (const Iterator& other) const { return index > other.index; } + + private: + T value; + size_t index; + }; + + inline Iterator begin() const { return Iterator(value, 0); } + inline Iterator end() const { return Iterator(value, count); } + + inline size_t size() const { return count; } + +private: + T value; + size_t count; +}; + +template <typename T> +inline constexpr Repeat<Decay<T>> repeat(T&& value, size_t count) { + // Returns a fake iterable which contains `count` repeats of `value`. Useful for e.g. creating + // a bunch of spaces: `kj::repeat(' ', indent * 2)` + + return Repeat<Decay<T>>(value, count); +} + +// ======================================================================================= +// Manually invoking constructors and destructors +// +// ctor(x, ...) and dtor(x) invoke x's constructor or destructor, respectively. + +// We want placement new, but we don't want to #include <new>. operator new cannot be defined in +// a namespace, and defining it globally conflicts with the definition in <new>. So we have to +// define a dummy type and an operator new that uses it. + +namespace _ { // private +struct PlacementNew {}; +} // namespace _ (private) +} // namespace kj + +inline void* operator new(size_t, kj::_::PlacementNew, void* __p) noexcept { + return __p; +} + +inline void operator delete(void*, kj::_::PlacementNew, void* __p) noexcept {} + +namespace kj { + +template <typename T, typename... Params> +inline void ctor(T& location, Params&&... params) { + new (_::PlacementNew(), &location) T(kj::fwd<Params>(params)...); +} + +template <typename T> +inline void dtor(T& location) { + location.~T(); +} + +// ======================================================================================= +// Maybe +// +// Use in cases where you want to indicate that a value may be null. Using Maybe<T&> instead of T* +// forces the caller to handle the null case in order to satisfy the compiler, thus reliably +// preventing null pointer dereferences at runtime. +// +// Maybe<T> can be implicitly constructed from T and from nullptr. Additionally, it can be +// implicitly constructed from T*, in which case the pointer is checked for nullness at runtime. +// To read the value of a Maybe<T>, do: +// +// KJ_IF_MAYBE(value, someFuncReturningMaybe()) { +// doSomething(*value); +// } else { +// maybeWasNull(); +// } +// +// KJ_IF_MAYBE's first parameter is a variable name which will be defined within the following +// block. The variable will behave like a (guaranteed non-null) pointer to the Maybe's value, +// though it may or may not actually be a pointer. +// +// Note that Maybe<T&> actually just wraps a pointer, whereas Maybe<T> wraps a T and a boolean +// indicating nullness. + +template <typename T> +class Maybe; + +namespace _ { // private + +#if _MSC_VER + // TODO(msvc): MSVC barfs on noexcept(instance<T&>().~T()) where T = kj::Exception and + // kj::_::Void. It and every other factorization I've tried produces: + // error C2325: 'kj::Blah' unexpected type to the right of '.~': expected 'void' +#define MSVC_NOEXCEPT_DTOR_WORKAROUND(T) __is_nothrow_destructible(T) +#else +#define MSVC_NOEXCEPT_DTOR_WORKAROUND(T) noexcept(instance<T&>().~T()) +#endif + +template <typename T> +class NullableValue { + // Class whose interface behaves much like T*, but actually contains an instance of T and a + // boolean flag indicating nullness. + +public: + inline NullableValue(NullableValue&& other) noexcept(noexcept(T(instance<T&&>()))) + : isSet(other.isSet) { + if (isSet) { + ctor(value, kj::mv(other.value)); + } + } + inline NullableValue(const NullableValue& other) + : isSet(other.isSet) { + if (isSet) { + ctor(value, other.value); + } + } + inline NullableValue(NullableValue& other) + : isSet(other.isSet) { + if (isSet) { + ctor(value, other.value); + } + } + inline ~NullableValue() noexcept(MSVC_NOEXCEPT_DTOR_WORKAROUND(T)) { + if (isSet) { + dtor(value); + } + } + + inline T& operator*() & { return value; } + inline const T& operator*() const & { return value; } + inline T&& operator*() && { return kj::mv(value); } + inline const T&& operator*() const && { return kj::mv(value); } + inline T* operator->() { return &value; } + inline const T* operator->() const { return &value; } + inline operator T*() { return isSet ? &value : nullptr; } + inline operator const T*() const { return isSet ? &value : nullptr; } + + template <typename... Params> + inline T& emplace(Params&&... params) { + if (isSet) { + isSet = false; + dtor(value); + } + ctor(value, kj::fwd<Params>(params)...); + isSet = true; + return value; + } + +private: // internal interface used by friends only + inline NullableValue() noexcept: isSet(false) {} + inline NullableValue(T&& t) noexcept(noexcept(T(instance<T&&>()))) + : isSet(true) { + ctor(value, kj::mv(t)); + } + inline NullableValue(T& t) + : isSet(true) { + ctor(value, t); + } + inline NullableValue(const T& t) + : isSet(true) { + ctor(value, t); + } + inline NullableValue(const T* t) + : isSet(t != nullptr) { + if (isSet) ctor(value, *t); + } + template <typename U> + inline NullableValue(NullableValue<U>&& other) noexcept(noexcept(T(instance<U&&>()))) + : isSet(other.isSet) { + if (isSet) { + ctor(value, kj::mv(other.value)); + } + } + template <typename U> + inline NullableValue(const NullableValue<U>& other) + : isSet(other.isSet) { + if (isSet) { + ctor(value, other.value); + } + } + template <typename U> + inline NullableValue(const NullableValue<U&>& other) + : isSet(other.isSet) { + if (isSet) { + ctor(value, *other.ptr); + } + } + inline NullableValue(decltype(nullptr)): isSet(false) {} + + inline NullableValue& operator=(NullableValue&& other) { + if (&other != this) { + // Careful about throwing destructors/constructors here. + if (isSet) { + isSet = false; + dtor(value); + } + if (other.isSet) { + ctor(value, kj::mv(other.value)); + isSet = true; + } + } + return *this; + } + + inline NullableValue& operator=(NullableValue& other) { + if (&other != this) { + // Careful about throwing destructors/constructors here. + if (isSet) { + isSet = false; + dtor(value); + } + if (other.isSet) { + ctor(value, other.value); + isSet = true; + } + } + return *this; + } + + inline NullableValue& operator=(const NullableValue& other) { + if (&other != this) { + // Careful about throwing destructors/constructors here. + if (isSet) { + isSet = false; + dtor(value); + } + if (other.isSet) { + ctor(value, other.value); + isSet = true; + } + } + return *this; + } + + inline bool operator==(decltype(nullptr)) const { return !isSet; } + inline bool operator!=(decltype(nullptr)) const { return isSet; } + +private: + bool isSet; + +#if _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4624) +// Warns that the anonymous union has a deleted destructor when T is non-trivial. This warning +// seems broken. +#endif + + union { + T value; + }; + +#if _MSC_VER +#pragma warning(pop) +#endif + + friend class kj::Maybe<T>; + template <typename U> + friend NullableValue<U>&& readMaybe(Maybe<U>&& maybe); +}; + +template <typename T> +inline NullableValue<T>&& readMaybe(Maybe<T>&& maybe) { return kj::mv(maybe.ptr); } +template <typename T> +inline T* readMaybe(Maybe<T>& maybe) { return maybe.ptr; } +template <typename T> +inline const T* readMaybe(const Maybe<T>& maybe) { return maybe.ptr; } +template <typename T> +inline T* readMaybe(Maybe<T&>&& maybe) { return maybe.ptr; } +template <typename T> +inline T* readMaybe(const Maybe<T&>& maybe) { return maybe.ptr; } + +template <typename T> +inline T* readMaybe(T* ptr) { return ptr; } +// Allow KJ_IF_MAYBE to work on regular pointers. + +} // namespace _ (private) + +#define KJ_IF_MAYBE(name, exp) if (auto name = ::kj::_::readMaybe(exp)) + +template <typename T> +class Maybe { + // A T, or nullptr. + + // IF YOU CHANGE THIS CLASS: Note that there is a specialization of it in memory.h. + +public: + Maybe(): ptr(nullptr) {} + Maybe(T&& t) noexcept(noexcept(T(instance<T&&>()))): ptr(kj::mv(t)) {} + Maybe(T& t): ptr(t) {} + Maybe(const T& t): ptr(t) {} + Maybe(const T* t) noexcept: ptr(t) {} + Maybe(Maybe&& other) noexcept(noexcept(T(instance<T&&>()))): ptr(kj::mv(other.ptr)) {} + Maybe(const Maybe& other): ptr(other.ptr) {} + Maybe(Maybe& other): ptr(other.ptr) {} + + template <typename U> + Maybe(Maybe<U>&& other) noexcept(noexcept(T(instance<U&&>()))) { + KJ_IF_MAYBE(val, kj::mv(other)) { + ptr = *val; + } + } + template <typename U> + Maybe(const Maybe<U>& other) { + KJ_IF_MAYBE(val, other) { + ptr = *val; + } + } + + Maybe(decltype(nullptr)) noexcept: ptr(nullptr) {} + + template <typename... Params> + inline T& emplace(Params&&... params) { + // Replace this Maybe's content with a new value constructed by passing the given parametrs to + // T's constructor. This can be used to initialize a Maybe without copying or even moving a T. + // Returns a reference to the newly-constructed value. + + return ptr.emplace(kj::fwd<Params>(params)...); + } + + inline Maybe& operator=(Maybe&& other) { ptr = kj::mv(other.ptr); return *this; } + inline Maybe& operator=(Maybe& other) { ptr = other.ptr; return *this; } + inline Maybe& operator=(const Maybe& other) { ptr = other.ptr; return *this; } + + inline bool operator==(decltype(nullptr)) const { return ptr == nullptr; } + inline bool operator!=(decltype(nullptr)) const { return ptr != nullptr; } + + T& orDefault(T& defaultValue) { + if (ptr == nullptr) { + return defaultValue; + } else { + return *ptr; + } + } + const T& orDefault(const T& defaultValue) const { + if (ptr == nullptr) { + return defaultValue; + } else { + return *ptr; + } + } + + template <typename Func> + auto map(Func&& f) & -> Maybe<decltype(f(instance<T&>()))> { + if (ptr == nullptr) { + return nullptr; + } else { + return f(*ptr); + } + } + + template <typename Func> + auto map(Func&& f) const & -> Maybe<decltype(f(instance<const T&>()))> { + if (ptr == nullptr) { + return nullptr; + } else { + return f(*ptr); + } + } + + template <typename Func> + auto map(Func&& f) && -> Maybe<decltype(f(instance<T&&>()))> { + if (ptr == nullptr) { + return nullptr; + } else { + return f(kj::mv(*ptr)); + } + } + + template <typename Func> + auto map(Func&& f) const && -> Maybe<decltype(f(instance<const T&&>()))> { + if (ptr == nullptr) { + return nullptr; + } else { + return f(kj::mv(*ptr)); + } + } + +private: + _::NullableValue<T> ptr; + + template <typename U> + friend class Maybe; + template <typename U> + friend _::NullableValue<U>&& _::readMaybe(Maybe<U>&& maybe); + template <typename U> + friend U* _::readMaybe(Maybe<U>& maybe); + template <typename U> + friend const U* _::readMaybe(const Maybe<U>& maybe); +}; + +template <typename T> +class Maybe<T&>: public DisallowConstCopyIfNotConst<T> { +public: + Maybe() noexcept: ptr(nullptr) {} + Maybe(T& t) noexcept: ptr(&t) {} + Maybe(T* t) noexcept: ptr(t) {} + + template <typename U> + inline Maybe(Maybe<U&>& other) noexcept: ptr(other.ptr) {} + template <typename U> + inline Maybe(const Maybe<const U&>& other) noexcept: ptr(other.ptr) {} + inline Maybe(decltype(nullptr)) noexcept: ptr(nullptr) {} + + inline Maybe& operator=(T& other) noexcept { ptr = &other; return *this; } + inline Maybe& operator=(T* other) noexcept { ptr = other; return *this; } + template <typename U> + inline Maybe& operator=(Maybe<U&>& other) noexcept { ptr = other.ptr; return *this; } + template <typename U> + inline Maybe& operator=(const Maybe<const U&>& other) noexcept { ptr = other.ptr; return *this; } + + inline bool operator==(decltype(nullptr)) const { return ptr == nullptr; } + inline bool operator!=(decltype(nullptr)) const { return ptr != nullptr; } + + T& orDefault(T& defaultValue) { + if (ptr == nullptr) { + return defaultValue; + } else { + return *ptr; + } + } + const T& orDefault(const T& defaultValue) const { + if (ptr == nullptr) { + return defaultValue; + } else { + return *ptr; + } + } + + template <typename Func> + auto map(Func&& f) -> Maybe<decltype(f(instance<T&>()))> { + if (ptr == nullptr) { + return nullptr; + } else { + return f(*ptr); + } + } + +private: + T* ptr; + + template <typename U> + friend class Maybe; + template <typename U> + friend U* _::readMaybe(Maybe<U&>&& maybe); + template <typename U> + friend U* _::readMaybe(const Maybe<U&>& maybe); +}; + +// ======================================================================================= +// ArrayPtr +// +// So common that we put it in common.h rather than array.h. + +template <typename T> +class ArrayPtr: public DisallowConstCopyIfNotConst<T> { + // A pointer to an array. Includes a size. Like any pointer, it doesn't own the target data, + // and passing by value only copies the pointer, not the target. + +public: + inline constexpr ArrayPtr(): ptr(nullptr), size_(0) {} + inline constexpr ArrayPtr(decltype(nullptr)): ptr(nullptr), size_(0) {} + inline constexpr ArrayPtr(T* ptr, size_t size): ptr(ptr), size_(size) {} + inline constexpr ArrayPtr(T* begin, T* end): ptr(begin), size_(end - begin) {} + inline KJ_CONSTEXPR() ArrayPtr(::std::initializer_list<RemoveConstOrDisable<T>> init) + : ptr(init.begin()), size_(init.size()) {} + + template <size_t size> + inline constexpr ArrayPtr(T (&native)[size]): ptr(native), size_(size) {} + // Construct an ArrayPtr from a native C-style array. + + inline operator ArrayPtr<const T>() const { + return ArrayPtr<const T>(ptr, size_); + } + inline ArrayPtr<const T> asConst() const { + return ArrayPtr<const T>(ptr, size_); + } + + inline size_t size() const { return size_; } + inline const T& operator[](size_t index) const { + KJ_IREQUIRE(index < size_, "Out-of-bounds ArrayPtr access."); + return ptr[index]; + } + inline T& operator[](size_t index) { + KJ_IREQUIRE(index < size_, "Out-of-bounds ArrayPtr access."); + return ptr[index]; + } + + inline T* begin() { return ptr; } + inline T* end() { return ptr + size_; } + inline T& front() { return *ptr; } + inline T& back() { return *(ptr + size_ - 1); } + inline const T* begin() const { return ptr; } + inline const T* end() const { return ptr + size_; } + inline const T& front() const { return *ptr; } + inline const T& back() const { return *(ptr + size_ - 1); } + + inline ArrayPtr<const T> slice(size_t start, size_t end) const { + KJ_IREQUIRE(start <= end && end <= size_, "Out-of-bounds ArrayPtr::slice()."); + return ArrayPtr<const T>(ptr + start, end - start); + } + inline ArrayPtr slice(size_t start, size_t end) { + KJ_IREQUIRE(start <= end && end <= size_, "Out-of-bounds ArrayPtr::slice()."); + return ArrayPtr(ptr + start, end - start); + } + + inline ArrayPtr<PropagateConst<T, byte>> asBytes() const { + // Reinterpret the array as a byte array. This is explicitly legal under C++ aliasing + // rules. + return { reinterpret_cast<PropagateConst<T, byte>*>(ptr), size_ * sizeof(T) }; + } + inline ArrayPtr<PropagateConst<T, char>> asChars() const { + // Reinterpret the array as a char array. This is explicitly legal under C++ aliasing + // rules. + return { reinterpret_cast<PropagateConst<T, char>*>(ptr), size_ * sizeof(T) }; + } + + inline bool operator==(decltype(nullptr)) const { return size_ == 0; } + inline bool operator!=(decltype(nullptr)) const { return size_ != 0; } + + inline bool operator==(const ArrayPtr& other) const { + if (size_ != other.size_) return false; + for (size_t i = 0; i < size_; i++) { + if (ptr[i] != other[i]) return false; + } + return true; + } + inline bool operator!=(const ArrayPtr& other) const { return !(*this == other); } + +private: + T* ptr; + size_t size_; +}; + +template <typename T> +inline constexpr ArrayPtr<T> arrayPtr(T* ptr, size_t size) { + // Use this function to construct ArrayPtrs without writing out the type name. + return ArrayPtr<T>(ptr, size); +} + +template <typename T> +inline constexpr ArrayPtr<T> arrayPtr(T* begin, T* end) { + // Use this function to construct ArrayPtrs without writing out the type name. + return ArrayPtr<T>(begin, end); +} + +// ======================================================================================= +// Casts + +template <typename To, typename From> +To implicitCast(From&& from) { + // `implicitCast<T>(value)` casts `value` to type `T` only if the conversion is implicit. Useful + // for e.g. resolving ambiguous overloads without sacrificing type-safety. + return kj::fwd<From>(from); +} + +template <typename To, typename From> +Maybe<To&> dynamicDowncastIfAvailable(From& from) { + // If RTTI is disabled, always returns nullptr. Otherwise, works like dynamic_cast. Useful + // in situations where dynamic_cast could allow an optimization, but isn't strictly necessary + // for correctness. It is highly recommended that you try to arrange all your dynamic_casts + // this way, as a dynamic_cast that is necessary for correctness implies a flaw in the interface + // design. + + // Force a compile error if To is not a subtype of From. Cross-casting is rare; if it is needed + // we should have a separate cast function like dynamicCrosscastIfAvailable(). + if (false) { + kj::implicitCast<From*>(kj::implicitCast<To*>(nullptr)); + } + +#if KJ_NO_RTTI + return nullptr; +#else + return dynamic_cast<To*>(&from); +#endif +} + +template <typename To, typename From> +To& downcast(From& from) { + // Down-cast a value to a sub-type, asserting that the cast is valid. In opt mode this is a + // static_cast, but in debug mode (when RTTI is enabled) a dynamic_cast will be used to verify + // that the value really has the requested type. + + // Force a compile error if To is not a subtype of From. + if (false) { + kj::implicitCast<From*>(kj::implicitCast<To*>(nullptr)); + } + +#if !KJ_NO_RTTI + KJ_IREQUIRE(dynamic_cast<To*>(&from) != nullptr, "Value cannot be downcast() to requested type."); +#endif + + return static_cast<To&>(from); +} + +// ======================================================================================= +// Defer + +namespace _ { // private + +template <typename Func> +class Deferred { +public: + inline Deferred(Func&& func): func(kj::fwd<Func>(func)), canceled(false) {} + inline ~Deferred() noexcept(false) { if (!canceled) func(); } + KJ_DISALLOW_COPY(Deferred); + + // This move constructor is usually optimized away by the compiler. + inline Deferred(Deferred&& other): func(kj::mv(other.func)), canceled(false) { + other.canceled = true; + } +private: + Func func; + bool canceled; +}; + +} // namespace _ (private) + +template <typename Func> +_::Deferred<Func> defer(Func&& func) { + // Returns an object which will invoke the given functor in its destructor. The object is not + // copyable but is movable with the semantics you'd expect. Since the return type is private, + // you need to assign to an `auto` variable. + // + // The KJ_DEFER macro provides slightly more convenient syntax for the common case where you + // want some code to run at current scope exit. + + return _::Deferred<Func>(kj::fwd<Func>(func)); +} + +#define KJ_DEFER(code) auto KJ_UNIQUE_NAME(_kjDefer) = ::kj::defer([&](){code;}) +// Run the given code when the function exits, whether by return or exception. + +} // namespace kj + +#endif // KJ_COMMON_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/debug.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,455 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// This file declares convenient macros for debug logging and error handling. The macros make +// it excessively easy to extract useful context information from code. Example: +// +// KJ_ASSERT(a == b, a, b, "a and b must be the same."); +// +// On failure, this will throw an exception whose description looks like: +// +// myfile.c++:43: bug in code: expected a == b; a = 14; b = 72; a and b must be the same. +// +// As you can see, all arguments after the first provide additional context. +// +// The macros available are: +// +// * `KJ_LOG(severity, ...)`: Just writes a log message, to stderr by default (but you can +// intercept messages by implementing an ExceptionCallback). `severity` is `INFO`, `WARNING`, +// `ERROR`, or `FATAL`. By default, `INFO` logs are not written, but for command-line apps the +// user should be able to pass a flag like `--verbose` to enable them. Other log levels are +// enabled by default. Log messages -- like exceptions -- can be intercepted by registering an +// ExceptionCallback. +// +// * `KJ_DBG(...)`: Like `KJ_LOG`, but intended specifically for temporary log lines added while +// debugging a particular problem. Calls to `KJ_DBG` should always be deleted before committing +// code. It is suggested that you set up a pre-commit hook that checks for this. +// +// * `KJ_ASSERT(condition, ...)`: Throws an exception if `condition` is false, or aborts if +// exceptions are disabled. This macro should be used to check for bugs in the surrounding code +// and its dependencies, but NOT to check for invalid input. The macro may be followed by a +// brace-delimited code block; if so, the block will be executed in the case where the assertion +// fails, before throwing the exception. If control jumps out of the block (e.g. with "break", +// "return", or "goto"), then the error is considered "recoverable" -- in this case, if +// exceptions are disabled, execution will continue normally rather than aborting (but if +// exceptions are enabled, an exception will still be thrown on exiting the block). A "break" +// statement in particular will jump to the code immediately after the block (it does not break +// any surrounding loop or switch). Example: +// +// KJ_ASSERT(value >= 0, "Value cannot be negative.", value) { +// // Assertion failed. Set value to zero to "recover". +// value = 0; +// // Don't abort if exceptions are disabled. Continue normally. +// // (Still throw an exception if they are enabled, though.) +// break; +// } +// // When exceptions are disabled, we'll get here even if the assertion fails. +// // Otherwise, we get here only if the assertion passes. +// +// * `KJ_REQUIRE(condition, ...)`: Like `KJ_ASSERT` but used to check preconditions -- e.g. to +// validate parameters passed from a caller. A failure indicates that the caller is buggy. +// +// * `KJ_SYSCALL(code, ...)`: Executes `code` assuming it makes a system call. A negative result +// is considered an error, with error code reported via `errno`. EINTR is handled by retrying. +// Other errors are handled by throwing an exception. If you need to examine the return code, +// assign it to a variable like so: +// +// int fd; +// KJ_SYSCALL(fd = open(filename, O_RDONLY), filename); +// +// `KJ_SYSCALL` can be followed by a recovery block, just like `KJ_ASSERT`. +// +// * `KJ_NONBLOCKING_SYSCALL(code, ...)`: Like KJ_SYSCALL, but will not throw an exception on +// EAGAIN/EWOULDBLOCK. The calling code should check the syscall's return value to see if it +// indicates an error; in this case, it can assume the error was EAGAIN because any other error +// would have caused an exception to be thrown. +// +// * `KJ_CONTEXT(...)`: Notes additional contextual information relevant to any exceptions thrown +// from within the current scope. That is, until control exits the block in which KJ_CONTEXT() +// is used, if any exception is generated, it will contain the given information in its context +// chain. This is helpful because it can otherwise be very difficult to come up with error +// messages that make sense within low-level helper code. Note that the parameters to +// KJ_CONTEXT() are only evaluated if an exception is thrown. This implies that any variables +// used must remain valid until the end of the scope. +// +// Notes: +// * Do not write expressions with side-effects in the message content part of the macro, as the +// message will not necessarily be evaluated. +// * For every macro `FOO` above except `LOG`, there is also a `FAIL_FOO` macro used to report +// failures that already happened. For the macros that check a boolean condition, `FAIL_FOO` +// omits the first parameter and behaves like it was `false`. `FAIL_SYSCALL` and +// `FAIL_RECOVERABLE_SYSCALL` take a string and an OS error number as the first two parameters. +// The string should be the name of the failed system call. +// * For every macro `FOO` above, there is a `DFOO` version (or `RECOVERABLE_DFOO`) which is only +// executed in debug mode, i.e. when KJ_DEBUG is defined. KJ_DEBUG is defined automatically +// by common.h when compiling without optimization (unless NDEBUG is defined), but you can also +// define it explicitly (e.g. -DKJ_DEBUG). Generally, production builds should NOT use KJ_DEBUG +// as it may enable expensive checks that are unlikely to fail. + +#ifndef KJ_DEBUG_H_ +#define KJ_DEBUG_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "string.h" +#include "exception.h" + +#ifdef ERROR +// This is problematic because windows.h #defines ERROR, which we use in an enum here. +#error "Make sure to to undefine ERROR (or just #include <kj/windows-sanity.h>) before this file" +#endif + +namespace kj { + +#if _MSC_VER +// MSVC does __VA_ARGS__ differently from GCC: +// - A trailing comma before an empty __VA_ARGS__ is removed automatically, whereas GCC wants +// you to request this behavior with "##__VA_ARGS__". +// - If __VA_ARGS__ is passed directly as an argument to another macro, it will be treated as a +// *single* argument rather than an argument list. This can be worked around by wrapping the +// outer macro call in KJ_EXPAND(), which appraently forces __VA_ARGS__ to be expanded before +// the macro is evaluated. I don't understand the C preprocessor. +// - Using "#__VA_ARGS__" to stringify __VA_ARGS__ expands to zero tokens when __VA_ARGS__ is +// empty, rather than expanding to an empty string literal. We can work around by concatenating +// with an empty string literal. + +#define KJ_EXPAND(X) X + +#define KJ_LOG(severity, ...) \ + if (!::kj::_::Debug::shouldLog(::kj::LogSeverity::severity)) {} else \ + ::kj::_::Debug::log(__FILE__, __LINE__, ::kj::LogSeverity::severity, \ + "" #__VA_ARGS__, __VA_ARGS__) + +#define KJ_DBG(...) KJ_EXPAND(KJ_LOG(DBG, __VA_ARGS__)) + +#define KJ_REQUIRE(cond, ...) \ + if (KJ_LIKELY(cond)) {} else \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ + #cond, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) + +#define KJ_FAIL_REQUIRE(...) \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ + nullptr, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) + +#define KJ_SYSCALL(call, ...) \ + if (auto _kjSyscallResult = ::kj::_::Debug::syscall([&](){return (call);}, false)) {} else \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + _kjSyscallResult.getErrorNumber(), #call, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) + +#define KJ_NONBLOCKING_SYSCALL(call, ...) \ + if (auto _kjSyscallResult = ::kj::_::Debug::syscall([&](){return (call);}, true)) {} else \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + _kjSyscallResult.getErrorNumber(), #call, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) + +#define KJ_FAIL_SYSCALL(code, errorNumber, ...) \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + errorNumber, code, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) + +#define KJ_UNIMPLEMENTED(...) \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::UNIMPLEMENTED, \ + nullptr, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) + +#define KJ_CONTEXT(...) \ + auto KJ_UNIQUE_NAME(_kjContextFunc) = [&]() -> ::kj::_::Debug::Context::Value { \ + return ::kj::_::Debug::Context::Value(__FILE__, __LINE__, \ + ::kj::_::Debug::makeDescription("" #__VA_ARGS__, __VA_ARGS__)); \ + }; \ + ::kj::_::Debug::ContextImpl<decltype(KJ_UNIQUE_NAME(_kjContextFunc))> \ + KJ_UNIQUE_NAME(_kjContext)(KJ_UNIQUE_NAME(_kjContextFunc)) + +#define KJ_REQUIRE_NONNULL(value, ...) \ + (*[&] { \ + auto _kj_result = ::kj::_::readMaybe(value); \ + if (KJ_UNLIKELY(!_kj_result)) { \ + ::kj::_::Debug::Fault(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ + #value " != nullptr", "" #__VA_ARGS__, __VA_ARGS__).fatal(); \ + } \ + return _kj_result; \ + }()) + +#define KJ_EXCEPTION(type, ...) \ + ::kj::Exception(::kj::Exception::Type::type, __FILE__, __LINE__, \ + ::kj::_::Debug::makeDescription("" #__VA_ARGS__, __VA_ARGS__)) + +#else + +#define KJ_LOG(severity, ...) \ + if (!::kj::_::Debug::shouldLog(::kj::LogSeverity::severity)) {} else \ + ::kj::_::Debug::log(__FILE__, __LINE__, ::kj::LogSeverity::severity, \ + #__VA_ARGS__, ##__VA_ARGS__) + +#define KJ_DBG(...) KJ_LOG(DBG, ##__VA_ARGS__) + +#define KJ_REQUIRE(cond, ...) \ + if (KJ_LIKELY(cond)) {} else \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ + #cond, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) + +#define KJ_FAIL_REQUIRE(...) \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ + nullptr, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) + +#define KJ_SYSCALL(call, ...) \ + if (auto _kjSyscallResult = ::kj::_::Debug::syscall([&](){return (call);}, false)) {} else \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + _kjSyscallResult.getErrorNumber(), #call, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) + +#define KJ_NONBLOCKING_SYSCALL(call, ...) \ + if (auto _kjSyscallResult = ::kj::_::Debug::syscall([&](){return (call);}, true)) {} else \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + _kjSyscallResult.getErrorNumber(), #call, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) + +#define KJ_FAIL_SYSCALL(code, errorNumber, ...) \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + errorNumber, code, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) + +#define KJ_UNIMPLEMENTED(...) \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::UNIMPLEMENTED, \ + nullptr, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) + +#define KJ_CONTEXT(...) \ + auto KJ_UNIQUE_NAME(_kjContextFunc) = [&]() -> ::kj::_::Debug::Context::Value { \ + return ::kj::_::Debug::Context::Value(__FILE__, __LINE__, \ + ::kj::_::Debug::makeDescription(#__VA_ARGS__, ##__VA_ARGS__)); \ + }; \ + ::kj::_::Debug::ContextImpl<decltype(KJ_UNIQUE_NAME(_kjContextFunc))> \ + KJ_UNIQUE_NAME(_kjContext)(KJ_UNIQUE_NAME(_kjContextFunc)) + +#define KJ_REQUIRE_NONNULL(value, ...) \ + (*({ \ + auto _kj_result = ::kj::_::readMaybe(value); \ + if (KJ_UNLIKELY(!_kj_result)) { \ + ::kj::_::Debug::Fault(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ + #value " != nullptr", #__VA_ARGS__, ##__VA_ARGS__).fatal(); \ + } \ + kj::mv(_kj_result); \ + })) + +#define KJ_EXCEPTION(type, ...) \ + ::kj::Exception(::kj::Exception::Type::type, __FILE__, __LINE__, \ + ::kj::_::Debug::makeDescription(#__VA_ARGS__, ##__VA_ARGS__)) + +#endif + +#define KJ_ASSERT KJ_REQUIRE +#define KJ_FAIL_ASSERT KJ_FAIL_REQUIRE +#define KJ_ASSERT_NONNULL KJ_REQUIRE_NONNULL +// Use "ASSERT" in place of "REQUIRE" when the problem is local to the immediate surrounding code. +// That is, if the assert ever fails, it indicates that the immediate surrounding code is broken. + +#ifdef KJ_DEBUG +#define KJ_DLOG KJ_LOG +#define KJ_DASSERT KJ_ASSERT +#define KJ_DREQUIRE KJ_REQUIRE +#else +#define KJ_DLOG(...) do {} while (false) +#define KJ_DASSERT(...) do {} while (false) +#define KJ_DREQUIRE(...) do {} while (false) +#endif + +namespace _ { // private + +class Debug { +public: + Debug() = delete; + + typedef LogSeverity Severity; // backwards-compatibility + + static inline bool shouldLog(LogSeverity severity) { return severity >= minSeverity; } + // Returns whether messages of the given severity should be logged. + + static inline void setLogLevel(LogSeverity severity) { minSeverity = severity; } + // Set the minimum message severity which will be logged. + // + // TODO(someday): Expose publicly. + + template <typename... Params> + static void log(const char* file, int line, LogSeverity severity, const char* macroArgs, + Params&&... params); + + class Fault { + public: + template <typename... Params> + Fault(const char* file, int line, Exception::Type type, + const char* condition, const char* macroArgs, Params&&... params); + template <typename... Params> + Fault(const char* file, int line, int osErrorNumber, + const char* condition, const char* macroArgs, Params&&... params); + Fault(const char* file, int line, Exception::Type type, + const char* condition, const char* macroArgs); + Fault(const char* file, int line, int osErrorNumber, + const char* condition, const char* macroArgs); + ~Fault() noexcept(false); + + KJ_NOINLINE KJ_NORETURN(void fatal()); + // Throw the exception. + + private: + void init(const char* file, int line, Exception::Type type, + const char* condition, const char* macroArgs, ArrayPtr<String> argValues); + void init(const char* file, int line, int osErrorNumber, + const char* condition, const char* macroArgs, ArrayPtr<String> argValues); + + Exception* exception; + }; + + class SyscallResult { + public: + inline SyscallResult(int errorNumber): errorNumber(errorNumber) {} + inline operator void*() { return errorNumber == 0 ? this : nullptr; } + inline int getErrorNumber() { return errorNumber; } + + private: + int errorNumber; + }; + + template <typename Call> + static SyscallResult syscall(Call&& call, bool nonblocking); + + class Context: public ExceptionCallback { + public: + Context(); + KJ_DISALLOW_COPY(Context); + virtual ~Context() noexcept(false); + + struct Value { + const char* file; + int line; + String description; + + inline Value(const char* file, int line, String&& description) + : file(file), line(line), description(mv(description)) {} + }; + + virtual Value evaluate() = 0; + + virtual void onRecoverableException(Exception&& exception) override; + virtual void onFatalException(Exception&& exception) override; + virtual void logMessage(LogSeverity severity, const char* file, int line, int contextDepth, + String&& text) override; + + private: + bool logged; + Maybe<Value> value; + + Value ensureInitialized(); + }; + + template <typename Func> + class ContextImpl: public Context { + public: + inline ContextImpl(Func& func): func(func) {} + KJ_DISALLOW_COPY(ContextImpl); + + Value evaluate() override { + return func(); + } + private: + Func& func; + }; + + template <typename... Params> + static String makeDescription(const char* macroArgs, Params&&... params); + +private: + static LogSeverity minSeverity; + + static void logInternal(const char* file, int line, LogSeverity severity, const char* macroArgs, + ArrayPtr<String> argValues); + static String makeDescriptionInternal(const char* macroArgs, ArrayPtr<String> argValues); + + static int getOsErrorNumber(bool nonblocking); + // Get the error code of the last error (e.g. from errno). Returns -1 on EINTR. +}; + +template <typename... Params> +void Debug::log(const char* file, int line, LogSeverity severity, const char* macroArgs, + Params&&... params) { + String argValues[sizeof...(Params)] = {str(params)...}; + logInternal(file, line, severity, macroArgs, arrayPtr(argValues, sizeof...(Params))); +} + +template <> +inline void Debug::log<>(const char* file, int line, LogSeverity severity, const char* macroArgs) { + logInternal(file, line, severity, macroArgs, nullptr); +} + +template <typename... Params> +Debug::Fault::Fault(const char* file, int line, Exception::Type type, + const char* condition, const char* macroArgs, Params&&... params) + : exception(nullptr) { + String argValues[sizeof...(Params)] = {str(params)...}; + init(file, line, type, condition, macroArgs, + arrayPtr(argValues, sizeof...(Params))); +} + +template <typename... Params> +Debug::Fault::Fault(const char* file, int line, int osErrorNumber, + const char* condition, const char* macroArgs, Params&&... params) + : exception(nullptr) { + String argValues[sizeof...(Params)] = {str(params)...}; + init(file, line, osErrorNumber, condition, macroArgs, + arrayPtr(argValues, sizeof...(Params))); +} + +inline Debug::Fault::Fault(const char* file, int line, int osErrorNumber, + const char* condition, const char* macroArgs) + : exception(nullptr) { + init(file, line, osErrorNumber, condition, macroArgs, nullptr); +} + +inline Debug::Fault::Fault(const char* file, int line, kj::Exception::Type type, + const char* condition, const char* macroArgs) + : exception(nullptr) { + init(file, line, type, condition, macroArgs, nullptr); +} + +template <typename Call> +Debug::SyscallResult Debug::syscall(Call&& call, bool nonblocking) { + while (call() < 0) { + int errorNum = getOsErrorNumber(nonblocking); + // getOsErrorNumber() returns -1 to indicate EINTR. + // Also, if nonblocking is true, then it returns 0 on EAGAIN, which will then be treated as a + // non-error. + if (errorNum != -1) { + return SyscallResult(errorNum); + } + } + return SyscallResult(0); +} + +template <typename... Params> +String Debug::makeDescription(const char* macroArgs, Params&&... params) { + String argValues[sizeof...(Params)] = {str(params)...}; + return makeDescriptionInternal(macroArgs, arrayPtr(argValues, sizeof...(Params))); +} + +template <> +inline String Debug::makeDescription<>(const char* macroArgs) { + return makeDescriptionInternal(macroArgs, nullptr); +} + +} // namespace _ (private) +} // namespace kj + +#endif // KJ_DEBUG_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/exception.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,337 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef KJ_EXCEPTION_H_ +#define KJ_EXCEPTION_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "memory.h" +#include "array.h" +#include "string.h" + +namespace kj { + +class ExceptionImpl; + +class Exception { + // Exception thrown in case of fatal errors. + // + // Actually, a subclass of this which also implements std::exception will be thrown, but we hide + // that fact from the interface to avoid #including <exception>. + +public: + enum class Type { + // What kind of failure? + + FAILED = 0, + // Something went wrong. This is the usual error type. KJ_ASSERT and KJ_REQUIRE throw this + // error type. + + OVERLOADED = 1, + // The call failed because of a temporary lack of resources. This could be space resources + // (out of memory, out of disk space) or time resources (request queue overflow, operation + // timed out). + // + // The operation might work if tried again, but it should NOT be repeated immediately as this + // may simply exacerbate the problem. + + DISCONNECTED = 2, + // The call required communication over a connection that has been lost. The callee will need + // to re-establish connections and try again. + + UNIMPLEMENTED = 3 + // The requested method is not implemented. The caller may wish to revert to a fallback + // approach based on other methods. + + // IF YOU ADD A NEW VALUE: + // - Update the stringifier. + // - Update Cap'n Proto's RPC protocol's Exception.Type enum. + }; + + Exception(Type type, const char* file, int line, String description = nullptr) noexcept; + Exception(Type type, String file, int line, String description = nullptr) noexcept; + Exception(const Exception& other) noexcept; + Exception(Exception&& other) = default; + ~Exception() noexcept; + + const char* getFile() const { return file; } + int getLine() const { return line; } + Type getType() const { return type; } + StringPtr getDescription() const { return description; } + ArrayPtr<void* const> getStackTrace() const { return arrayPtr(trace, traceCount); } + + struct Context { + // Describes a bit about what was going on when the exception was thrown. + + const char* file; + int line; + String description; + Maybe<Own<Context>> next; + + Context(const char* file, int line, String&& description, Maybe<Own<Context>>&& next) + : file(file), line(line), description(mv(description)), next(mv(next)) {} + Context(const Context& other) noexcept; + }; + + inline Maybe<const Context&> getContext() const { + KJ_IF_MAYBE(c, context) { + return **c; + } else { + return nullptr; + } + } + + void wrapContext(const char* file, int line, String&& description); + // Wraps the context in a new node. This becomes the head node returned by getContext() -- it + // is expected that contexts will be added in reverse order as the exception passes up the + // callback stack. + + KJ_NOINLINE void extendTrace(uint ignoreCount); + // Append the current stack trace to the exception's trace, ignoring the first `ignoreCount` + // frames (see `getStackTrace()` for discussion of `ignoreCount`). + + KJ_NOINLINE void truncateCommonTrace(); + // Remove the part of the stack trace which the exception shares with the caller of this method. + // This is used by the async library to remove the async infrastructure from the stack trace + // before replacing it with the async trace. + + void addTrace(void* ptr); + // Append the given pointer to the backtrace, if it is not already full. This is used by the + // async library to trace through the promise chain that led to the exception. + +private: + String ownFile; + const char* file; + int line; + Type type; + String description; + Maybe<Own<Context>> context; + void* trace[32]; + uint traceCount; + + friend class ExceptionImpl; +}; + +StringPtr KJ_STRINGIFY(Exception::Type type); +String KJ_STRINGIFY(const Exception& e); + +// ======================================================================================= + +enum class LogSeverity { + INFO, // Information describing what the code is up to, which users may request to see + // with a flag like `--verbose`. Does not indicate a problem. Not printed by + // default; you must call setLogLevel(INFO) to enable. + WARNING, // A problem was detected but execution can continue with correct output. + ERROR, // Something is wrong, but execution can continue with garbage output. + FATAL, // Something went wrong, and execution cannot continue. + DBG // Temporary debug logging. See KJ_DBG. + + // Make sure to update the stringifier if you add a new severity level. +}; + +StringPtr KJ_STRINGIFY(LogSeverity severity); + +class ExceptionCallback { + // If you don't like C++ exceptions, you may implement and register an ExceptionCallback in order + // to perform your own exception handling. For example, a reasonable thing to do is to have + // onRecoverableException() set a flag indicating that an error occurred, and then check for that + // flag just before writing to storage and/or returning results to the user. If the flag is set, + // discard whatever you have and return an error instead. + // + // ExceptionCallbacks must always be allocated on the stack. When an exception is thrown, the + // newest ExceptionCallback on the calling thread's stack is called. The default implementation + // of each method calls the next-oldest ExceptionCallback for that thread. Thus the callbacks + // behave a lot like try/catch blocks, except that they are called before any stack unwinding + // occurs. + +public: + ExceptionCallback(); + KJ_DISALLOW_COPY(ExceptionCallback); + virtual ~ExceptionCallback() noexcept(false); + + virtual void onRecoverableException(Exception&& exception); + // Called when an exception has been raised, but the calling code has the ability to continue by + // producing garbage output. This method _should_ throw the exception, but is allowed to simply + // return if garbage output is acceptable. + // + // The global default implementation throws an exception unless the library was compiled with + // -fno-exceptions, in which case it logs an error and returns. + + virtual void onFatalException(Exception&& exception); + // Called when an exception has been raised and the calling code cannot continue. If this method + // returns normally, abort() will be called. The method must throw the exception to avoid + // aborting. + // + // The global default implementation throws an exception unless the library was compiled with + // -fno-exceptions, in which case it logs an error and returns. + + virtual void logMessage(LogSeverity severity, const char* file, int line, int contextDepth, + String&& text); + // Called when something wants to log some debug text. `contextDepth` indicates how many levels + // of context the message passed through; it may make sense to indent the message accordingly. + // + // The global default implementation writes the text to stderr. + +protected: + ExceptionCallback& next; + +private: + ExceptionCallback(ExceptionCallback& next); + + class RootExceptionCallback; + friend ExceptionCallback& getExceptionCallback(); +}; + +ExceptionCallback& getExceptionCallback(); +// Returns the current exception callback. + +KJ_NOINLINE KJ_NORETURN(void throwFatalException(kj::Exception&& exception, uint ignoreCount = 0)); +// Invoke the exception callback to throw the given fatal exception. If the exception callback +// returns, abort. + +KJ_NOINLINE void throwRecoverableException(kj::Exception&& exception, uint ignoreCount = 0); +// Invoke the exception callback to throw the given recoverable exception. If the exception +// callback returns, return normally. + +// ======================================================================================= + +namespace _ { class Runnable; } + +template <typename Func> +Maybe<Exception> runCatchingExceptions(Func&& func) noexcept; +// Executes the given function (usually, a lambda returning nothing) catching any exceptions that +// are thrown. Returns the Exception if there was one, or null if the operation completed normally. +// Non-KJ exceptions will be wrapped. +// +// If exception are disabled (e.g. with -fno-exceptions), this will still detect whether any +// recoverable exceptions occurred while running the function and will return those. + +class UnwindDetector { + // Utility for detecting when a destructor is called due to unwind. Useful for: + // - Avoiding throwing exceptions in this case, which would terminate the program. + // - Detecting whether to commit or roll back a transaction. + // + // To use this class, either inherit privately from it or declare it as a member. The detector + // works by comparing the exception state against that when the constructor was called, so for + // an object that was actually constructed during exception unwind, it will behave as if no + // unwind is taking place. This is usually the desired behavior. + +public: + UnwindDetector(); + + bool isUnwinding() const; + // Returns true if the current thread is in a stack unwind that it wasn't in at the time the + // object was constructed. + + template <typename Func> + void catchExceptionsIfUnwinding(Func&& func) const; + // Runs the given function (e.g., a lambda). If isUnwinding() is true, any exceptions are + // caught and treated as secondary faults, meaning they are considered to be side-effects of the + // exception that is unwinding the stack. Otherwise, exceptions are passed through normally. + +private: + uint uncaughtCount; + + void catchExceptionsAsSecondaryFaults(_::Runnable& runnable) const; +}; + +namespace _ { // private + +class Runnable { +public: + virtual void run() = 0; +}; + +template <typename Func> +class RunnableImpl: public Runnable { +public: + RunnableImpl(Func&& func): func(kj::mv(func)) {} + void run() override { + func(); + } +private: + Func func; +}; + +Maybe<Exception> runCatchingExceptions(Runnable& runnable) noexcept; + +} // namespace _ (private) + +template <typename Func> +Maybe<Exception> runCatchingExceptions(Func&& func) noexcept { + _::RunnableImpl<Decay<Func>> runnable(kj::fwd<Func>(func)); + return _::runCatchingExceptions(runnable); +} + +template <typename Func> +void UnwindDetector::catchExceptionsIfUnwinding(Func&& func) const { + if (isUnwinding()) { + _::RunnableImpl<Decay<Func>> runnable(kj::fwd<Func>(func)); + catchExceptionsAsSecondaryFaults(runnable); + } else { + func(); + } +} + +#define KJ_ON_SCOPE_SUCCESS(code) \ + ::kj::UnwindDetector KJ_UNIQUE_NAME(_kjUnwindDetector); \ + KJ_DEFER(if (!KJ_UNIQUE_NAME(_kjUnwindDetector).isUnwinding()) { code; }) +// Runs `code` if the current scope is exited normally (not due to an exception). + +#define KJ_ON_SCOPE_FAILURE(code) \ + ::kj::UnwindDetector KJ_UNIQUE_NAME(_kjUnwindDetector); \ + KJ_DEFER(if (KJ_UNIQUE_NAME(_kjUnwindDetector).isUnwinding()) { code; }) +// Runs `code` if the current scope is exited due to an exception. + +// ======================================================================================= + +KJ_NOINLINE ArrayPtr<void* const> getStackTrace(ArrayPtr<void*> space, uint ignoreCount); +// Attempt to get the current stack trace, returning a list of pointers to instructions. The +// returned array is a slice of `space`. Provide a larger `space` to get a deeper stack trace. +// If the platform doesn't support stack traces, returns an empty array. +// +// `ignoreCount` items will be truncated from the front of the trace. This is useful for chopping +// off a prefix of the trace that is uninteresting to the developer because it's just locations +// inside the debug infrastructure that is requesting the trace. Be careful to mark functions as +// KJ_NOINLINE if you intend to count them in `ignoreCount`. Note that, unfortunately, the +// ignored entries will still waste space in the `space` array (and the returned array's `begin()` +// is never exactly equal to `space.begin()` due to this effect, even if `ignoreCount` is zero +// since `getStackTrace()` needs to ignore its own internal frames). + +String stringifyStackTrace(ArrayPtr<void* const>); +// Convert the stack trace to a string with file names and line numbers. This may involve executing +// suprocesses. + +void printStackTraceOnCrash(); +// Registers signal handlers on common "crash" signals like SIGSEGV that will (attempt to) print +// a stack trace. You should call this as early as possible on program startup. Programs using +// KJ_MAIN get this automatically. + +kj::StringPtr trimSourceFilename(kj::StringPtr filename); +// Given a source code file name, trim off noisy prefixes like "src/" or +// "/ekam-provider/canonical/". + +} // namespace kj + +#endif // KJ_EXCEPTION_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/function.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,277 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef KJ_FUNCTION_H_ +#define KJ_FUNCTION_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "memory.h" + +namespace kj { + +template <typename Signature> +class Function; +// Function wrapper using virtual-based polymorphism. Use this when template polymorphism is +// not possible. You can, for example, accept a Function as a parameter: +// +// void setFilter(Function<bool(const Widget&)> filter); +// +// The caller of `setFilter()` may then pass any callable object as the parameter. The callable +// object does not have to have the exact signature specified, just one that is "compatible" -- +// i.e. the return type is covariant and the parameters are contravariant. +// +// Unlike `std::function`, `kj::Function`s are movable but not copyable, just like `kj::Own`. This +// is to avoid unexpected heap allocation or slow atomic reference counting. +// +// When a `Function` is constructed from an lvalue, it captures only a reference to the value. +// When constructed from an rvalue, it invokes the value's move constructor. So, for example: +// +// struct AddN { +// int n; +// int operator(int i) { return i + n; } +// } +// +// Function<int(int, int)> f1 = AddN{2}; +// // f1 owns an instance of AddN. It may safely be moved out +// // of the local scope. +// +// AddN adder(2); +// Function<int(int, int)> f2 = adder; +// // f2 contains a reference to `adder`. Thus, it becomes invalid +// // when `adder` goes out-of-scope. +// +// AddN adder2(2); +// Function<int(int, int)> f3 = kj::mv(adder2); +// // f3 owns an insatnce of AddN moved from `adder2`. f3 may safely +// // be moved out of the local scope. +// +// Additionally, a Function may be bound to a class method using KJ_BIND_METHOD(object, methodName). +// For example: +// +// class Printer { +// public: +// void print(int i); +// void print(kj::StringPtr s); +// }; +// +// Printer p; +// +// Function<void(uint)> intPrinter = KJ_BIND_METHOD(p, print); +// // Will call Printer::print(int). +// +// Function<void(const char*)> strPrinter = KJ_BIND_METHOD(p, print); +// // Will call Printer::print(kj::StringPtr). +// +// Notice how KJ_BIND_METHOD is able to figure out which overload to use depending on the kind of +// Function it is binding to. + +template <typename Signature> +class ConstFunction; +// Like Function, but wraps a "const" (i.e. thread-safe) call. + +template <typename Return, typename... Params> +class Function<Return(Params...)> { +public: + template <typename F> + inline Function(F&& f): impl(heap<Impl<F>>(kj::fwd<F>(f))) {} + Function() = default; + + // Make sure people don't accidentally end up wrapping a reference when they meant to return + // a function. + KJ_DISALLOW_COPY(Function); + Function(Function&) = delete; + Function& operator=(Function&) = delete; + template <typename T> Function(const Function<T>&) = delete; + template <typename T> Function& operator=(const Function<T>&) = delete; + template <typename T> Function(const ConstFunction<T>&) = delete; + template <typename T> Function& operator=(const ConstFunction<T>&) = delete; + Function(Function&&) = default; + Function& operator=(Function&&) = default; + + inline Return operator()(Params... params) { + return (*impl)(kj::fwd<Params>(params)...); + } + + Function reference() { + // Forms a new Function of the same type that delegates to this Function by reference. + // Therefore, this Function must outlive the returned Function, but otherwise they behave + // exactly the same. + + return *impl; + } + +private: + class Iface { + public: + virtual Return operator()(Params... params) = 0; + }; + + template <typename F> + class Impl final: public Iface { + public: + explicit Impl(F&& f): f(kj::fwd<F>(f)) {} + + Return operator()(Params... params) override { + return f(kj::fwd<Params>(params)...); + } + + private: + F f; + }; + + Own<Iface> impl; +}; + +template <typename Return, typename... Params> +class ConstFunction<Return(Params...)> { +public: + template <typename F> + inline ConstFunction(F&& f): impl(heap<Impl<F>>(kj::fwd<F>(f))) {} + ConstFunction() = default; + + // Make sure people don't accidentally end up wrapping a reference when they meant to return + // a function. + KJ_DISALLOW_COPY(ConstFunction); + ConstFunction(ConstFunction&) = delete; + ConstFunction& operator=(ConstFunction&) = delete; + template <typename T> ConstFunction(const ConstFunction<T>&) = delete; + template <typename T> ConstFunction& operator=(const ConstFunction<T>&) = delete; + template <typename T> ConstFunction(const Function<T>&) = delete; + template <typename T> ConstFunction& operator=(const Function<T>&) = delete; + ConstFunction(ConstFunction&&) = default; + ConstFunction& operator=(ConstFunction&&) = default; + + inline Return operator()(Params... params) const { + return (*impl)(kj::fwd<Params>(params)...); + } + + ConstFunction reference() const { + // Forms a new ConstFunction of the same type that delegates to this ConstFunction by reference. + // Therefore, this ConstFunction must outlive the returned ConstFunction, but otherwise they + // behave exactly the same. + + return *impl; + } + +private: + class Iface { + public: + virtual Return operator()(Params... params) const = 0; + }; + + template <typename F> + class Impl final: public Iface { + public: + explicit Impl(F&& f): f(kj::fwd<F>(f)) {} + + Return operator()(Params... params) const override { + return f(kj::fwd<Params>(params)...); + } + + private: + F f; + }; + + Own<Iface> impl; +}; + +#if 1 + +namespace _ { // private + +template <typename T, typename Signature, Signature method> +class BoundMethod; + +template <typename T, typename Return, typename... Params, Return (Decay<T>::*method)(Params...)> +class BoundMethod<T, Return (Decay<T>::*)(Params...), method> { +public: + BoundMethod(T&& t): t(kj::fwd<T>(t)) {} + + Return operator()(Params&&... params) { + return (t.*method)(kj::fwd<Params>(params)...); + } + +private: + T t; +}; + +template <typename T, typename Return, typename... Params, + Return (Decay<T>::*method)(Params...) const> +class BoundMethod<T, Return (Decay<T>::*)(Params...) const, method> { +public: + BoundMethod(T&& t): t(kj::fwd<T>(t)) {} + + Return operator()(Params&&... params) const { + return (t.*method)(kj::fwd<Params>(params)...); + } + +private: + T t; +}; + +} // namespace _ (private) + +#define KJ_BIND_METHOD(obj, method) \ + ::kj::_::BoundMethod<KJ_DECLTYPE_REF(obj), \ + decltype(&::kj::Decay<decltype(obj)>::method), \ + &::kj::Decay<decltype(obj)>::method>(obj) +// Macro that produces a functor object which forwards to the method `obj.name`. If `obj` is an +// lvalue, the functor will hold a reference to it. If `obj` is an rvalue, the functor will +// contain a copy (by move) of it. +// +// The current implementation requires that the method is not overloaded. +// +// TODO(someday): C++14's generic lambdas may be able to simplify this code considerably, and +// probably make it work with overloaded methods. + +#else +// Here's a better implementation of the above that doesn't work with GCC (but does with Clang) +// because it uses a local class with a template method. Sigh. This implementation supports +// overloaded methods. + +#define KJ_BIND_METHOD(obj, method) \ + ({ \ + typedef KJ_DECLTYPE_REF(obj) T; \ + class F { \ + public: \ + inline F(T&& t): t(::kj::fwd<T>(t)) {} \ + template <typename... Params> \ + auto operator()(Params&&... params) \ + -> decltype(::kj::instance<T>().method(::kj::fwd<Params>(params)...)) { \ + return t.method(::kj::fwd<Params>(params)...); \ + } \ + private: \ + T t; \ + }; \ + (F(obj)); \ + }) +// Macro that produces a functor object which forwards to the method `obj.name`. If `obj` is an +// lvalue, the functor will hold a reference to it. If `obj` is an rvalue, the functor will +// contain a copy (by move) of it. + +#endif + +} // namespace kj + +#endif // KJ_FUNCTION_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/io.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,331 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef KJ_IO_H_ +#define KJ_IO_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include <stddef.h> +#include "common.h" +#include "array.h" +#include "exception.h" + +namespace kj { + +// ======================================================================================= +// Abstract interfaces + +class InputStream { +public: + virtual ~InputStream() noexcept(false); + + size_t read(void* buffer, size_t minBytes, size_t maxBytes); + // Reads at least minBytes and at most maxBytes, copying them into the given buffer. Returns + // the size read. Throws an exception on errors. Implemented in terms of tryRead(). + // + // maxBytes is the number of bytes the caller really wants, but minBytes is the minimum amount + // needed by the caller before it can start doing useful processing. If the stream returns less + // than maxBytes, the caller will usually call read() again later to get the rest. Returning + // less than maxBytes is useful when it makes sense for the caller to parallelize processing + // with I/O. + // + // Never blocks if minBytes is zero. If minBytes is zero and maxBytes is non-zero, this may + // attempt a non-blocking read or may just return zero. To force a read, use a non-zero minBytes. + // To detect EOF without throwing an exception, use tryRead(). + // + // If the InputStream can't produce minBytes, it MUST throw an exception, as the caller is not + // expected to understand how to deal with partial reads. + + virtual size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) = 0; + // Like read(), but may return fewer than minBytes on EOF. + + inline void read(void* buffer, size_t bytes) { read(buffer, bytes, bytes); } + // Convenience method for reading an exact number of bytes. + + virtual void skip(size_t bytes); + // Skips past the given number of bytes, discarding them. The default implementation read()s + // into a scratch buffer. +}; + +class OutputStream { +public: + virtual ~OutputStream() noexcept(false); + + virtual void write(const void* buffer, size_t size) = 0; + // Always writes the full size. Throws exception on error. + + virtual void write(ArrayPtr<const ArrayPtr<const byte>> pieces); + // Equivalent to write()ing each byte array in sequence, which is what the default implementation + // does. Override if you can do something better, e.g. use writev() to do the write in a single + // syscall. +}; + +class BufferedInputStream: public InputStream { + // An input stream which buffers some bytes in memory to reduce system call overhead. + // - OR - + // An input stream that actually reads from some in-memory data structure and wants to give its + // caller a direct pointer to that memory to potentially avoid a copy. + +public: + virtual ~BufferedInputStream() noexcept(false); + + ArrayPtr<const byte> getReadBuffer(); + // Get a direct pointer into the read buffer, which contains the next bytes in the input. If the + // caller consumes any bytes, it should then call skip() to indicate this. This always returns a + // non-empty buffer or throws an exception. Implemented in terms of tryGetReadBuffer(). + + virtual ArrayPtr<const byte> tryGetReadBuffer() = 0; + // Like getReadBuffer() but may return an empty buffer on EOF. +}; + +class BufferedOutputStream: public OutputStream { + // An output stream which buffers some bytes in memory to reduce system call overhead. + // - OR - + // An output stream that actually writes into some in-memory data structure and wants to give its + // caller a direct pointer to that memory to potentially avoid a copy. + +public: + virtual ~BufferedOutputStream() noexcept(false); + + virtual ArrayPtr<byte> getWriteBuffer() = 0; + // Get a direct pointer into the write buffer. The caller may choose to fill in some prefix of + // this buffer and then pass it to write(), in which case write() may avoid a copy. It is + // incorrect to pass to write any slice of this buffer which is not a prefix. +}; + +// ======================================================================================= +// Buffered streams implemented as wrappers around regular streams + +class BufferedInputStreamWrapper: public BufferedInputStream { + // Implements BufferedInputStream in terms of an InputStream. + // + // Note that the underlying stream's position is unpredictable once the wrapper is destroyed, + // unless the entire stream was consumed. To read a predictable number of bytes in a buffered + // way without going over, you'd need this wrapper to wrap some other wrapper which itself + // implements an artificial EOF at the desired point. Such a stream should be trivial to write + // but is not provided by the library at this time. + +public: + explicit BufferedInputStreamWrapper(InputStream& inner, ArrayPtr<byte> buffer = nullptr); + // Creates a buffered stream wrapping the given non-buffered stream. No guarantee is made about + // the position of the inner stream after a buffered wrapper has been created unless the entire + // input is read. + // + // If the second parameter is non-null, the stream uses the given buffer instead of allocating + // its own. This may improve performance if the buffer can be reused. + + KJ_DISALLOW_COPY(BufferedInputStreamWrapper); + ~BufferedInputStreamWrapper() noexcept(false); + + // implements BufferedInputStream ---------------------------------- + ArrayPtr<const byte> tryGetReadBuffer() override; + size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; + void skip(size_t bytes) override; + +private: + InputStream& inner; + Array<byte> ownedBuffer; + ArrayPtr<byte> buffer; + ArrayPtr<byte> bufferAvailable; +}; + +class BufferedOutputStreamWrapper: public BufferedOutputStream { + // Implements BufferedOutputStream in terms of an OutputStream. Note that writes to the + // underlying stream may be delayed until flush() is called or the wrapper is destroyed. + +public: + explicit BufferedOutputStreamWrapper(OutputStream& inner, ArrayPtr<byte> buffer = nullptr); + // Creates a buffered stream wrapping the given non-buffered stream. + // + // If the second parameter is non-null, the stream uses the given buffer instead of allocating + // its own. This may improve performance if the buffer can be reused. + + KJ_DISALLOW_COPY(BufferedOutputStreamWrapper); + ~BufferedOutputStreamWrapper() noexcept(false); + + void flush(); + // Force the wrapper to write any remaining bytes in its buffer to the inner stream. Note that + // this only flushes this object's buffer; this object has no idea how to flush any other buffers + // that may be present in the underlying stream. + + // implements BufferedOutputStream --------------------------------- + ArrayPtr<byte> getWriteBuffer() override; + void write(const void* buffer, size_t size) override; + +private: + OutputStream& inner; + Array<byte> ownedBuffer; + ArrayPtr<byte> buffer; + byte* bufferPos; + UnwindDetector unwindDetector; +}; + +// ======================================================================================= +// Array I/O + +class ArrayInputStream: public BufferedInputStream { +public: + explicit ArrayInputStream(ArrayPtr<const byte> array); + KJ_DISALLOW_COPY(ArrayInputStream); + ~ArrayInputStream() noexcept(false); + + // implements BufferedInputStream ---------------------------------- + ArrayPtr<const byte> tryGetReadBuffer() override; + size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; + void skip(size_t bytes) override; + +private: + ArrayPtr<const byte> array; +}; + +class ArrayOutputStream: public BufferedOutputStream { +public: + explicit ArrayOutputStream(ArrayPtr<byte> array); + KJ_DISALLOW_COPY(ArrayOutputStream); + ~ArrayOutputStream() noexcept(false); + + ArrayPtr<byte> getArray() { + // Get the portion of the array which has been filled in. + return arrayPtr(array.begin(), fillPos); + } + + // implements BufferedInputStream ---------------------------------- + ArrayPtr<byte> getWriteBuffer() override; + void write(const void* buffer, size_t size) override; + +private: + ArrayPtr<byte> array; + byte* fillPos; +}; + +class VectorOutputStream: public BufferedOutputStream { +public: + explicit VectorOutputStream(size_t initialCapacity = 4096); + KJ_DISALLOW_COPY(VectorOutputStream); + ~VectorOutputStream() noexcept(false); + + ArrayPtr<byte> getArray() { + // Get the portion of the array which has been filled in. + return arrayPtr(vector.begin(), fillPos); + } + + // implements BufferedInputStream ---------------------------------- + ArrayPtr<byte> getWriteBuffer() override; + void write(const void* buffer, size_t size) override; + +private: + Array<byte> vector; + byte* fillPos; + + void grow(size_t minSize); +}; + +// ======================================================================================= +// File descriptor I/O + +class AutoCloseFd { + // A wrapper around a file descriptor which automatically closes the descriptor when destroyed. + // The wrapper supports move construction for transferring ownership of the descriptor. If + // close() returns an error, the destructor throws an exception, UNLESS the destructor is being + // called during unwind from another exception, in which case the close error is ignored. + // + // If your code is not exception-safe, you should not use AutoCloseFd. In this case you will + // have to call close() yourself and handle errors appropriately. + +public: + inline AutoCloseFd(): fd(-1) {} + inline AutoCloseFd(decltype(nullptr)): fd(-1) {} + inline explicit AutoCloseFd(int fd): fd(fd) {} + inline AutoCloseFd(AutoCloseFd&& other) noexcept: fd(other.fd) { other.fd = -1; } + KJ_DISALLOW_COPY(AutoCloseFd); + ~AutoCloseFd() noexcept(false); + + inline AutoCloseFd& operator=(AutoCloseFd&& other) { + AutoCloseFd old(kj::mv(*this)); + fd = other.fd; + other.fd = -1; + return *this; + } + + inline AutoCloseFd& operator=(decltype(nullptr)) { + AutoCloseFd old(kj::mv(*this)); + return *this; + } + + inline operator int() const { return fd; } + inline int get() const { return fd; } + + operator bool() const = delete; + // Deleting this operator prevents accidental use in boolean contexts, which + // the int conversion operator above would otherwise allow. + + inline bool operator==(decltype(nullptr)) { return fd < 0; } + inline bool operator!=(decltype(nullptr)) { return fd >= 0; } + +private: + int fd; + UnwindDetector unwindDetector; +}; + +inline auto KJ_STRINGIFY(const AutoCloseFd& fd) + -> decltype(kj::toCharSequence(implicitCast<int>(fd))) { + return kj::toCharSequence(implicitCast<int>(fd)); +} + +class FdInputStream: public InputStream { + // An InputStream wrapping a file descriptor. + +public: + explicit FdInputStream(int fd): fd(fd) {} + explicit FdInputStream(AutoCloseFd fd): fd(fd), autoclose(mv(fd)) {} + KJ_DISALLOW_COPY(FdInputStream); + ~FdInputStream() noexcept(false); + + size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; + +private: + int fd; + AutoCloseFd autoclose; +}; + +class FdOutputStream: public OutputStream { + // An OutputStream wrapping a file descriptor. + +public: + explicit FdOutputStream(int fd): fd(fd) {} + explicit FdOutputStream(AutoCloseFd fd): fd(fd), autoclose(mv(fd)) {} + KJ_DISALLOW_COPY(FdOutputStream); + ~FdOutputStream() noexcept(false); + + void write(const void* buffer, size_t size) override; + void write(ArrayPtr<const ArrayPtr<const byte>> pieces) override; + +private: + int fd; + AutoCloseFd autoclose; +}; + +} // namespace kj + +#endif // KJ_IO_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/main.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,407 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef KJ_MAIN_H_ +#define KJ_MAIN_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "array.h" +#include "string.h" +#include "vector.h" +#include "function.h" + +namespace kj { + +class ProcessContext { + // Context for command-line programs. + +public: + virtual StringPtr getProgramName() = 0; + // Get argv[0] as passed to main(). + + KJ_NORETURN(virtual void exit()) = 0; + // Indicates program completion. The program is considered successful unless `error()` was + // called. Typically this exits with _Exit(), meaning that the stack is not unwound, buffers + // are not flushed, etc. -- it is the responsibility of the caller to flush any buffers that + // matter. However, an alternate context implementation e.g. for unit testing purposes could + // choose to throw an exception instead. + // + // At first this approach may sound crazy. Isn't it much better to shut down cleanly? What if + // you lose data? However, it turns out that if you look at each common class of program, _Exit() + // is almost always preferable. Let's break it down: + // + // * Commands: A typical program you might run from the command line is single-threaded and + // exits quickly and deterministically. Commands often use buffered I/O and need to flush + // those buffers before exit. However, most of the work performed by destructors is not + // flushing buffers, but rather freeing up memory, placing objects into freelists, and closing + // file descriptors. All of this is irrelevant if the process is about to exit anyway, and + // for a command that runs quickly, time wasted freeing heap space may make a real difference + // in the overall runtime of a script. Meanwhile, it is usually easy to determine exactly what + // resources need to be flushed before exit, and easy to tell if they are not being flushed + // (because the command fails to produce the expected output). Therefore, it is reasonably + // easy for commands to explicitly ensure all output is flushed before exiting, and it is + // probably a good idea for them to do so anyway, because write failures should be detected + // and handled. For commands, a good strategy is to allocate any objects that require clean + // destruction on the stack, and allow them to go out of scope before the command exits. + // Meanwhile, any resources which do not need to be cleaned up should be allocated as members + // of the command's main class, whose destructor normally will not be called. + // + // * Interactive apps: Programs that interact with the user (whether they be graphical apps + // with windows or console-based apps like emacs) generally exit only when the user asks them + // to. Such applications may store large data structures in memory which need to be synced + // to disk, such as documents or user preferences. However, relying on stack unwind or global + // destructors as the mechanism for ensuring such syncing occurs is probably wrong. First of + // all, it's 2013, and applications ought to be actively syncing changes to non-volatile + // storage the moment those changes are made. Applications can crash at any time and a crash + // should never lose data that is more than half a second old. Meanwhile, if a user actually + // does try to close an application while unsaved changes exist, the application UI should + // prompt the user to decide what to do. Such a UI mechanism is obviously too high level to + // be implemented via destructors, so KJ's use of _Exit() shouldn't make a difference here. + // + // * Servers: A good server is fault-tolerant, prepared for the possibility that at any time + // it could crash, the OS could decide to kill it off, or the machine it is running on could + // just die. So, using _Exit() should be no problem. In fact, servers generally never even + // call exit anyway; they are killed externally. + // + // * Batch jobs: A long-running batch job is something between a command and a server. It + // probably knows exactly what needs to be flushed before exiting, and it probably should be + // fault-tolerant. + // + // Meanwhile, regardless of program type, if you are adhering to KJ style, then the use of + // _Exit() shouldn't be a problem anyway: + // + // * KJ style forbids global mutable state (singletons) in general and global constructors and + // destructors in particular. Therefore, everything that could possibly need cleanup either + // lives on the stack or is transitively owned by something living on the stack. + // + // * Calling exit() simply means "Don't clean up anything older than this stack frame.". If you + // have resources that require cleanup before exit, make sure they are owned by stack frames + // beyond the one that eventually calls exit(). To be as safe as possible, don't place any + // state in your program's main class, and don't call exit() yourself. Then, runMainAndExit() + // will do it, and the only thing on the stack at that time will be your main class, which + // has no state anyway. + // + // TODO(someday): Perhaps we should use the new std::quick_exit(), so that at_quick_exit() is + // available for those who really think they need it. Unfortunately, it is not yet available + // on many platforms. + + virtual void warning(StringPtr message) = 0; + // Print the given message to standard error. A newline is printed after the message if it + // doesn't already have one. + + virtual void error(StringPtr message) = 0; + // Like `warning()`, but also sets a flag indicating that the process has failed, and that when + // it eventually exits it should indicate an error status. + + KJ_NORETURN(virtual void exitError(StringPtr message)) = 0; + // Equivalent to `error(message)` followed by `exit()`. + + KJ_NORETURN(virtual void exitInfo(StringPtr message)) = 0; + // Displays the given non-error message to the user and then calls `exit()`. This is used to + // implement things like --help. + + virtual void increaseLoggingVerbosity() = 0; + // Increase the level of detail produced by the debug logging system. `MainBuilder` invokes + // this if the caller uses the -v flag. + + // TODO(someday): Add interfaces representing standard OS resources like the filesystem, so that + // these things can be mocked out. +}; + +class TopLevelProcessContext final: public ProcessContext { + // A ProcessContext implementation appropriate for use at the actual entry point of a process + // (as opposed to when you are trying to call a program's main function from within some other + // program). This implementation writes errors to stderr, and its `exit()` method actually + // calls the C `quick_exit()` function. + +public: + explicit TopLevelProcessContext(StringPtr programName); + + struct CleanShutdownException { int exitCode; }; + // If the environment variable KJ_CLEAN_SHUTDOWN is set, then exit() will actually throw this + // exception rather than exiting. `kj::runMain()` catches this exception and returns normally. + // This is useful primarily for testing purposes, to assist tools like memory leak checkers that + // are easily confused by quick_exit(). + + StringPtr getProgramName() override; + KJ_NORETURN(void exit() override); + void warning(StringPtr message) override; + void error(StringPtr message) override; + KJ_NORETURN(void exitError(StringPtr message) override); + KJ_NORETURN(void exitInfo(StringPtr message) override); + void increaseLoggingVerbosity() override; + +private: + StringPtr programName; + bool cleanShutdown; + bool hadErrors = false; +}; + +typedef Function<void(StringPtr programName, ArrayPtr<const StringPtr> params)> MainFunc; + +int runMainAndExit(ProcessContext& context, MainFunc&& func, int argc, char* argv[]); +// Runs the given main function and then exits using the given context. If an exception is thrown, +// this will catch it, report it via the context and exit with an error code. +// +// Normally this function does not return, because returning would probably lead to wasting time +// on cleanup when the process is just going to exit anyway. However, to facilitate memory leak +// checkers and other tools that require a clean shutdown to do their job, if the environment +// variable KJ_CLEAN_SHUTDOWN is set, the function will in fact return an exit code, which should +// then be returned from main(). +// +// Most users will use the KJ_MAIN() macro rather than call this function directly. + +#define KJ_MAIN(MainClass) \ + int main(int argc, char* argv[]) { \ + ::kj::TopLevelProcessContext context(argv[0]); \ + MainClass mainObject(context); \ + return ::kj::runMainAndExit(context, mainObject.getMain(), argc, argv); \ + } +// Convenience macro for declaring a main function based on the given class. The class must have +// a constructor that accepts a ProcessContext& and a method getMain() which returns +// kj::MainFunc (probably building it using a MainBuilder). + +class MainBuilder { + // Builds a main() function with nice argument parsing. As options and arguments are parsed, + // corresponding callbacks are called, so that you never have to write a massive switch() + // statement to interpret arguments. Additionally, this approach encourages you to write + // main classes that have a reasonable API that can be used as an alternative to their + // command-line interface. + // + // All StringPtrs passed to MainBuilder must remain valid until option parsing completes. The + // assumption is that these strings will all be literals, making this an easy requirement. If + // not, consider allocating them in an Arena. + // + // Some flags are automatically recognized by the main functions built by this class: + // --help: Prints help text and exits. The help text is constructed based on the + // information you provide to the builder as you define each flag. + // --verbose: Increase logging verbosity. + // --version: Print version information and exit. + // + // Example usage: + // + // class FooMain { + // public: + // FooMain(kj::ProcessContext& context): context(context) {} + // + // bool setAll() { all = true; return true; } + // // Enable the --all flag. + // + // kj::MainBuilder::Validity setOutput(kj::StringPtr name) { + // // Set the output file. + // + // if (name.endsWith(".foo")) { + // outputFile = name; + // return true; + // } else { + // return "Output file must have extension .foo."; + // } + // } + // + // kj::MainBuilder::Validity processInput(kj::StringPtr name) { + // // Process an input file. + // + // if (!exists(name)) { + // return kj::str(name, ": file not found"); + // } + // // ... process the input file ... + // return true; + // } + // + // kj::MainFunc getMain() { + // return MainBuilder(context, "Foo Builder v1.5", "Reads <source>s and builds a Foo.") + // .addOption({'a', "all"}, KJ_BIND_METHOD(*this, setAll), + // "Frob all the widgets. Otherwise, only some widgets are frobbed.") + // .addOptionWithArg({'o', "output"}, KJ_BIND_METHOD(*this, setOutput), + // "<filename>", "Output to <filename>. Must be a .foo file.") + // .expectOneOrMoreArgs("<source>", KJ_BIND_METHOD(*this, processInput)) + // .build(); + // } + // + // private: + // bool all = false; + // kj::StringPtr outputFile; + // kj::ProcessContext& context; + // }; + +public: + MainBuilder(ProcessContext& context, StringPtr version, + StringPtr briefDescription, StringPtr extendedDescription = nullptr); + ~MainBuilder() noexcept(false); + + class OptionName { + public: + OptionName() = default; + inline OptionName(char shortName): isLong(false), shortName(shortName) {} + inline OptionName(const char* longName): isLong(true), longName(longName) {} + + private: + bool isLong; + union { + char shortName; + const char* longName; + }; + friend class MainBuilder; + }; + + class Validity { + public: + inline Validity(bool valid) { + if (!valid) errorMessage = heapString("invalid argument"); + } + inline Validity(const char* errorMessage) + : errorMessage(heapString(errorMessage)) {} + inline Validity(String&& errorMessage) + : errorMessage(kj::mv(errorMessage)) {} + + inline const Maybe<String>& getError() const { return errorMessage; } + inline Maybe<String> releaseError() { return kj::mv(errorMessage); } + + private: + Maybe<String> errorMessage; + friend class MainBuilder; + }; + + MainBuilder& addOption(std::initializer_list<OptionName> names, Function<Validity()> callback, + StringPtr helpText); + // Defines a new option (flag). `names` is a list of characters and strings that can be used to + // specify the option on the command line. Single-character names are used with "-" while string + // names are used with "--". `helpText` is a natural-language description of the flag. + // + // `callback` is called when the option is seen. Its return value indicates whether the option + // was accepted. If not, further option processing stops, and error is written, and the process + // exits. + // + // Example: + // + // builder.addOption({'a', "all"}, KJ_BIND_METHOD(*this, showAll), "Show all files."); + // + // This option could be specified in the following ways: + // + // -a + // --all + // + // Note that single-character option names can be combined into a single argument. For example, + // `-abcd` is equivalent to `-a -b -c -d`. + // + // The help text for this option would look like: + // + // -a, --all + // Show all files. + // + // Note that help text is automatically word-wrapped. + + MainBuilder& addOptionWithArg(std::initializer_list<OptionName> names, + Function<Validity(StringPtr)> callback, + StringPtr argumentTitle, StringPtr helpText); + // Like `addOption()`, but adds an option which accepts an argument. `argumentTitle` is used in + // the help text. The argument text is passed to the callback. + // + // Example: + // + // builder.addOptionWithArg({'o', "output"}, KJ_BIND_METHOD(*this, setOutput), + // "<filename>", "Output to <filename>."); + // + // This option could be specified with an argument of "foo" in the following ways: + // + // -ofoo + // -o foo + // --output=foo + // --output foo + // + // Note that single-character option names can be combined, but only the last option can have an + // argument, since the characters after the option letter are interpreted as the argument. E.g. + // `-abofoo` would be equivalent to `-a -b -o foo`. + // + // The help text for this option would look like: + // + // -o FILENAME, --output=FILENAME + // Output to FILENAME. + + MainBuilder& addSubCommand(StringPtr name, Function<MainFunc()> getSubParser, + StringPtr briefHelpText); + // If exactly the given name is seen as an argument, invoke getSubParser() and then pass all + // remaining arguments to the parser it returns. This is useful for implementing commands which + // have lots of sub-commands, like "git" (which has sub-commands "checkout", "branch", "pull", + // etc.). + // + // `getSubParser` is only called if the command is seen. This avoids building main functions + // for commands that aren't used. + // + // `briefHelpText` should be brief enough to show immediately after the command name on a single + // line. It will not be wrapped. Users can use the built-in "help" command to get extended + // help on a particular command. + + MainBuilder& expectArg(StringPtr title, Function<Validity(StringPtr)> callback); + MainBuilder& expectOptionalArg(StringPtr title, Function<Validity(StringPtr)> callback); + MainBuilder& expectZeroOrMoreArgs(StringPtr title, Function<Validity(StringPtr)> callback); + MainBuilder& expectOneOrMoreArgs(StringPtr title, Function<Validity(StringPtr)> callback); + // Set callbacks to handle arguments. `expectArg()` and `expectOptionalArg()` specify positional + // arguments with special handling, while `expect{Zero,One}OrMoreArgs()` specifies a handler for + // an argument list (the handler is called once for each argument in the list). `title` + // specifies how the argument should be represented in the usage text. + // + // All options callbacks are called before argument callbacks, regardless of their ordering on + // the command line. This matches GNU getopt's behavior of permuting non-flag arguments to the + // end of the argument list. Also matching getopt, the special option "--" indicates that the + // rest of the command line is all arguments, not options, even if they start with '-'. + // + // The interpretation of positional arguments is fairly flexible. The non-optional arguments can + // be expected at the beginning, end, or in the middle. If more arguments are specified than + // the number of non-optional args, they are assigned to the optional argument handlers in the + // order of registration. + // + // For example, say you called: + // builder.expectArg("<foo>", ...); + // builder.expectOptionalArg("<bar>", ...); + // builder.expectArg("<baz>", ...); + // builder.expectZeroOrMoreArgs("<qux>", ...); + // builder.expectArg("<corge>", ...); + // + // This command requires at least three arguments: foo, baz, and corge. If four arguments are + // given, the second is assigned to bar. If five or more arguments are specified, then the + // arguments between the third and last are assigned to qux. Note that it never makes sense + // to call `expect*OrMoreArgs()` more than once since only the first call would ever be used. + // + // In practice, you probably shouldn't create such complicated commands as in the above example. + // But, this flexibility seems necessary to support commands where the first argument is special + // as well as commands (like `cp`) where the last argument is special. + + MainBuilder& callAfterParsing(Function<Validity()> callback); + // Call the given function after all arguments have been parsed. + + MainFunc build(); + // Build the "main" function, which simply parses the arguments. Once this returns, the + // `MainBuilder` is no longer valid. + +private: + struct Impl; + Own<Impl> impl; + + class MainImpl; +}; + +} // namespace kj + +#endif // KJ_MAIN_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/memory.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,404 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef KJ_MEMORY_H_ +#define KJ_MEMORY_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "common.h" + +namespace kj { + +// ======================================================================================= +// Disposer -- Implementation details. + +class Disposer { + // Abstract interface for a thing that "disposes" of objects, where "disposing" usually means + // calling the destructor followed by freeing the underlying memory. `Own<T>` encapsulates an + // object pointer with corresponding Disposer. + // + // Few developers will ever touch this interface. It is primarily useful for those implementing + // custom memory allocators. + +protected: + // Do not declare a destructor, as doing so will force a global initializer for each HeapDisposer + // instance. Eww! + + virtual void disposeImpl(void* pointer) const = 0; + // Disposes of the object, given a pointer to the beginning of the object. If the object is + // polymorphic, this pointer is determined by dynamic_cast<void*>(). For non-polymorphic types, + // Own<T> does not allow any casting, so the pointer exactly matches the original one given to + // Own<T>. + +public: + + template <typename T> + void dispose(T* object) const; + // Helper wrapper around disposeImpl(). + // + // If T is polymorphic, calls `disposeImpl(dynamic_cast<void*>(object))`, otherwise calls + // `disposeImpl(implicitCast<void*>(object))`. + // + // Callers must not call dispose() on the same pointer twice, even if the first call throws + // an exception. + +private: + template <typename T, bool polymorphic = __is_polymorphic(T)> + struct Dispose_; +}; + +template <typename T> +class DestructorOnlyDisposer: public Disposer { + // A disposer that merely calls the type's destructor and nothing else. + +public: + static const DestructorOnlyDisposer instance; + + void disposeImpl(void* pointer) const override { + reinterpret_cast<T*>(pointer)->~T(); + } +}; + +template <typename T> +const DestructorOnlyDisposer<T> DestructorOnlyDisposer<T>::instance = DestructorOnlyDisposer<T>(); + +class NullDisposer: public Disposer { + // A disposer that does nothing. + +public: + static const NullDisposer instance; + + void disposeImpl(void* pointer) const override {} +}; + +// ======================================================================================= +// Own<T> -- An owned pointer. + +template <typename T> +class Own { + // A transferrable title to a T. When an Own<T> goes out of scope, the object's Disposer is + // called to dispose of it. An Own<T> can be efficiently passed by move, without relocating the + // underlying object; this transfers ownership. + // + // This is much like std::unique_ptr, except: + // - You cannot release(). An owned object is not necessarily allocated with new (see next + // point), so it would be hard to use release() correctly. + // - The deleter is made polymorphic by virtual call rather than by template. This is much + // more powerful -- it allows the use of custom allocators, freelists, etc. This could + // _almost_ be accomplished with unique_ptr by forcing everyone to use something like + // std::unique_ptr<T, kj::Deleter>, except that things get hairy in the presence of multiple + // inheritance and upcasting, and anyway if you force everyone to use a custom deleter + // then you've lost any benefit to interoperating with the "standard" unique_ptr. + +public: + KJ_DISALLOW_COPY(Own); + inline Own(): disposer(nullptr), ptr(nullptr) {} + inline Own(Own&& other) noexcept + : disposer(other.disposer), ptr(other.ptr) { other.ptr = nullptr; } + inline Own(Own<RemoveConstOrDisable<T>>&& other) noexcept + : disposer(other.disposer), ptr(other.ptr) { other.ptr = nullptr; } + template <typename U, typename = EnableIf<canConvert<U*, T*>()>> + inline Own(Own<U>&& other) noexcept + : disposer(other.disposer), ptr(other.ptr) { + static_assert(__is_polymorphic(T), + "Casting owned pointers requires that the target type is polymorphic."); + other.ptr = nullptr; + } + inline Own(T* ptr, const Disposer& disposer) noexcept: disposer(&disposer), ptr(ptr) {} + + ~Own() noexcept(false) { dispose(); } + + inline Own& operator=(Own&& other) { + // Move-assingnment operator. + + // Careful, this might own `other`. Therefore we have to transfer the pointers first, then + // dispose. + const Disposer* disposerCopy = disposer; + T* ptrCopy = ptr; + disposer = other.disposer; + ptr = other.ptr; + other.ptr = nullptr; + if (ptrCopy != nullptr) { + disposerCopy->dispose(const_cast<RemoveConst<T>*>(ptrCopy)); + } + return *this; + } + + inline Own& operator=(decltype(nullptr)) { + dispose(); + return *this; + } + + template <typename U> + Own<U> downcast() { + // Downcast the pointer to Own<U>, destroying the original pointer. If this pointer does not + // actually point at an instance of U, the results are undefined (throws an exception in debug + // mode if RTTI is enabled, otherwise you're on your own). + + Own<U> result; + if (ptr != nullptr) { + result.ptr = &kj::downcast<U>(*ptr); + result.disposer = disposer; + ptr = nullptr; + } + return result; + } + +#define NULLCHECK KJ_IREQUIRE(ptr != nullptr, "null Own<> dereference") + inline T* operator->() { NULLCHECK; return ptr; } + inline const T* operator->() const { NULLCHECK; return ptr; } + inline T& operator*() { NULLCHECK; return *ptr; } + inline const T& operator*() const { NULLCHECK; return *ptr; } +#undef NULLCHECK + inline T* get() { return ptr; } + inline const T* get() const { return ptr; } + inline operator T*() { return ptr; } + inline operator const T*() const { return ptr; } + +private: + const Disposer* disposer; // Only valid if ptr != nullptr. + T* ptr; + + inline explicit Own(decltype(nullptr)): disposer(nullptr), ptr(nullptr) {} + + inline bool operator==(decltype(nullptr)) { return ptr == nullptr; } + inline bool operator!=(decltype(nullptr)) { return ptr != nullptr; } + // Only called by Maybe<Own<T>>. + + inline void dispose() { + // Make sure that if an exception is thrown, we are left with a null ptr, so we won't possibly + // dispose again. + T* ptrCopy = ptr; + if (ptrCopy != nullptr) { + ptr = nullptr; + disposer->dispose(const_cast<RemoveConst<T>*>(ptrCopy)); + } + } + + template <typename U> + friend class Own; + friend class Maybe<Own<T>>; +}; + +namespace _ { // private + +template <typename T> +class OwnOwn { +public: + inline OwnOwn(Own<T>&& value) noexcept: value(kj::mv(value)) {} + + inline Own<T>& operator*() & { return value; } + inline const Own<T>& operator*() const & { return value; } + inline Own<T>&& operator*() && { return kj::mv(value); } + inline const Own<T>&& operator*() const && { return kj::mv(value); } + inline Own<T>* operator->() { return &value; } + inline const Own<T>* operator->() const { return &value; } + inline operator Own<T>*() { return value ? &value : nullptr; } + inline operator const Own<T>*() const { return value ? &value : nullptr; } + +private: + Own<T> value; +}; + +template <typename T> +OwnOwn<T> readMaybe(Maybe<Own<T>>&& maybe) { return OwnOwn<T>(kj::mv(maybe.ptr)); } +template <typename T> +Own<T>* readMaybe(Maybe<Own<T>>& maybe) { return maybe.ptr ? &maybe.ptr : nullptr; } +template <typename T> +const Own<T>* readMaybe(const Maybe<Own<T>>& maybe) { return maybe.ptr ? &maybe.ptr : nullptr; } + +} // namespace _ (private) + +template <typename T> +class Maybe<Own<T>> { +public: + inline Maybe(): ptr(nullptr) {} + inline Maybe(Own<T>&& t) noexcept: ptr(kj::mv(t)) {} + inline Maybe(Maybe&& other) noexcept: ptr(kj::mv(other.ptr)) {} + + template <typename U> + inline Maybe(Maybe<Own<U>>&& other): ptr(mv(other.ptr)) {} + + inline Maybe(decltype(nullptr)) noexcept: ptr(nullptr) {} + + inline operator Maybe<T&>() { return ptr.get(); } + inline operator Maybe<const T&>() const { return ptr.get(); } + + inline Maybe& operator=(Maybe&& other) { ptr = kj::mv(other.ptr); return *this; } + + inline bool operator==(decltype(nullptr)) const { return ptr == nullptr; } + inline bool operator!=(decltype(nullptr)) const { return ptr != nullptr; } + + Own<T>& orDefault(Own<T>& defaultValue) { + if (ptr == nullptr) { + return defaultValue; + } else { + return ptr; + } + } + const Own<T>& orDefault(const Own<T>& defaultValue) const { + if (ptr == nullptr) { + return defaultValue; + } else { + return ptr; + } + } + + template <typename Func> + auto map(Func&& f) & -> Maybe<decltype(f(instance<Own<T>&>()))> { + if (ptr == nullptr) { + return nullptr; + } else { + return f(ptr); + } + } + + template <typename Func> + auto map(Func&& f) const & -> Maybe<decltype(f(instance<const Own<T>&>()))> { + if (ptr == nullptr) { + return nullptr; + } else { + return f(ptr); + } + } + + template <typename Func> + auto map(Func&& f) && -> Maybe<decltype(f(instance<Own<T>&&>()))> { + if (ptr == nullptr) { + return nullptr; + } else { + return f(kj::mv(ptr)); + } + } + + template <typename Func> + auto map(Func&& f) const && -> Maybe<decltype(f(instance<const Own<T>&&>()))> { + if (ptr == nullptr) { + return nullptr; + } else { + return f(kj::mv(ptr)); + } + } + +private: + Own<T> ptr; + + template <typename U> + friend class Maybe; + template <typename U> + friend _::OwnOwn<U> _::readMaybe(Maybe<Own<U>>&& maybe); + template <typename U> + friend Own<U>* _::readMaybe(Maybe<Own<U>>& maybe); + template <typename U> + friend const Own<U>* _::readMaybe(const Maybe<Own<U>>& maybe); +}; + +namespace _ { // private + +template <typename T> +class HeapDisposer final: public Disposer { +public: + virtual void disposeImpl(void* pointer) const override { delete reinterpret_cast<T*>(pointer); } + + static const HeapDisposer instance; +}; + +template <typename T> +const HeapDisposer<T> HeapDisposer<T>::instance = HeapDisposer<T>(); + +} // namespace _ (private) + +template <typename T, typename... Params> +Own<T> heap(Params&&... params) { + // heap<T>(...) allocates a T on the heap, forwarding the parameters to its constructor. The + // exact heap implementation is unspecified -- for now it is operator new, but you should not + // assume this. (Since we know the object size at delete time, we could actually implement an + // allocator that is more efficient than operator new.) + + return Own<T>(new T(kj::fwd<Params>(params)...), _::HeapDisposer<T>::instance); +} + +template <typename T> +Own<Decay<T>> heap(T&& orig) { + // Allocate a copy (or move) of the argument on the heap. + // + // The purpose of this overload is to allow you to omit the template parameter as there is only + // one argument and the purpose is to copy it. + + typedef Decay<T> T2; + return Own<T2>(new T2(kj::fwd<T>(orig)), _::HeapDisposer<T2>::instance); +} + +// ======================================================================================= +// SpaceFor<T> -- assists in manual allocation + +template <typename T> +class SpaceFor { + // A class which has the same size and alignment as T but does not call its constructor or + // destructor automatically. Instead, call construct() to construct a T in the space, which + // returns an Own<T> which will take care of calling T's destructor later. + +public: + inline SpaceFor() {} + inline ~SpaceFor() {} + + template <typename... Params> + Own<T> construct(Params&&... params) { + ctor(value, kj::fwd<Params>(params)...); + return Own<T>(&value, DestructorOnlyDisposer<T>::instance); + } + +private: + union { + T value; + }; +}; + +// ======================================================================================= +// Inline implementation details + +template <typename T> +struct Disposer::Dispose_<T, true> { + static void dispose(T* object, const Disposer& disposer) { + // Note that dynamic_cast<void*> does not require RTTI to be enabled, because the offset to + // the top of the object is in the vtable -- as it obviously needs to be to correctly implement + // operator delete. + disposer.disposeImpl(dynamic_cast<void*>(object)); + } +}; +template <typename T> +struct Disposer::Dispose_<T, false> { + static void dispose(T* object, const Disposer& disposer) { + disposer.disposeImpl(static_cast<void*>(object)); + } +}; + +template <typename T> +void Disposer::dispose(T* object) const { + Dispose_<T>::dispose(object, *this); +} + +} // namespace kj + +#endif // KJ_MEMORY_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/miniposix.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,152 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef KJ_MINIPOSIX_H_ +#define KJ_MINIPOSIX_H_ + +// This header provides a small subset of the POSIX API which also happens to be available on +// Windows under slightly-different names. + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#if _WIN32 +#include <io.h> +#include <direct.h> +#include <fcntl.h> // _O_BINARY +#else +#include <limits.h> +#include <errno.h> +#endif + +#if !_WIN32 || __MINGW32__ +#include <unistd.h> +#include <sys/stat.h> +#include <sys/types.h> +#endif + +#if !_WIN32 +#include <sys/uio.h> +#endif + +namespace kj { +namespace miniposix { + +#if _WIN32 && !__MINGW32__ +// We're on Windows and not MinGW. So, we need to define wrappers for the POSIX API. + +typedef int ssize_t; + +inline ssize_t read(int fd, void* buffer, size_t size) { + return ::_read(fd, buffer, size); +} +inline ssize_t write(int fd, const void* buffer, size_t size) { + return ::_write(fd, buffer, size); +} +inline int close(int fd) { + return ::_close(fd); +} + +#ifndef F_OK +#define F_OK 0 // access() existence test +#endif + +#ifndef S_ISREG +#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) // stat() regular file test +#endif +#ifndef S_ISDIR +#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) // stat() directory test +#endif + +#ifndef STDIN_FILENO +#define STDIN_FILENO 0 +#endif +#ifndef STDOUT_FILENO +#define STDOUT_FILENO 1 +#endif +#ifndef STDERR_FILENO +#define STDERR_FILENO 2 +#endif + +#else +// We're on a POSIX system or MinGW which already defines the wrappers for us. + +using ::ssize_t; +using ::read; +using ::write; +using ::close; + +#endif + +#if _WIN32 +// We're on Windows, including MinGW. pipe() and mkdir() are non-standard even on MinGW. + +inline int pipe(int fds[2]) { + return ::_pipe(fds, 8192, _O_BINARY); +} +inline int mkdir(const char* path, int mode) { + return ::_mkdir(path); +} + +#else +// We're on real POSIX. + +using ::pipe; +using ::mkdir; + +inline size_t iovMax(size_t count) { + // Apparently, there is a maximum number of iovecs allowed per call. I don't understand why. + // Most platforms define IOV_MAX but Linux defines only UIO_MAXIOV and others, like Hurd, + // define neither. + // + // On platforms where both IOV_MAX and UIO_MAXIOV are undefined, we poke sysconf(_SC_IOV_MAX), + // then try to fall back to the POSIX-mandated minimum of _XOPEN_IOV_MAX if that fails. + // + // http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html#tag_13_23_03_01 + +#if defined(IOV_MAX) + // Solaris (and others?) + return IOV_MAX; +#elif defined(UIO_MAXIOV) + // Linux + return UIO_MAXIOV; +#else + // POSIX mystery meat + + long iovmax; + + errno = 0; + if ((iovmax = sysconf(_SC_IOV_MAX)) == -1) { + // assume iovmax == -1 && errno == 0 means "unbounded" + return errno ? _XOPEN_IOV_MAX : count; + } else { + return (size_t) iovmax; + } +#endif +} + +#endif + +} // namespace miniposix +} // namespace kj + +#endif // KJ_MINIPOSIX_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/mutex.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,369 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef KJ_MUTEX_H_ +#define KJ_MUTEX_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "memory.h" +#include <inttypes.h> + +#if __linux__ && !defined(KJ_USE_FUTEX) +#define KJ_USE_FUTEX 1 +#endif + +#if !KJ_USE_FUTEX && !_WIN32 +// On Linux we use futex. On other platforms we wrap pthreads. +// TODO(someday): Write efficient low-level locking primitives for other platforms. +#include <pthread.h> +#endif + +namespace kj { + +// ======================================================================================= +// Private details -- public interfaces follow below. + +namespace _ { // private + +class Mutex { + // Internal implementation details. See `MutexGuarded<T>`. + +public: + Mutex(); + ~Mutex(); + KJ_DISALLOW_COPY(Mutex); + + enum Exclusivity { + EXCLUSIVE, + SHARED + }; + + void lock(Exclusivity exclusivity); + void unlock(Exclusivity exclusivity); + + void assertLockedByCaller(Exclusivity exclusivity); + // In debug mode, assert that the mutex is locked by the calling thread, or if that is + // non-trivial, assert that the mutex is locked (which should be good enough to catch problems + // in unit tests). In non-debug builds, do nothing. + +private: +#if KJ_USE_FUTEX + uint futex; + // bit 31 (msb) = set if exclusive lock held + // bit 30 (msb) = set if threads are waiting for exclusive lock + // bits 0-29 = count of readers; If an exclusive lock is held, this is the count of threads + // waiting for a read lock, otherwise it is the count of threads that currently hold a read + // lock. + + static constexpr uint EXCLUSIVE_HELD = 1u << 31; + static constexpr uint EXCLUSIVE_REQUESTED = 1u << 30; + static constexpr uint SHARED_COUNT_MASK = EXCLUSIVE_REQUESTED - 1; + +#elif _WIN32 + uintptr_t srwLock; // Actually an SRWLOCK, but don't want to #include <windows.h> in header. + +#else + mutable pthread_rwlock_t mutex; +#endif +}; + +class Once { + // Internal implementation details. See `Lazy<T>`. + +public: +#if KJ_USE_FUTEX + inline Once(bool startInitialized = false) + : futex(startInitialized ? INITIALIZED : UNINITIALIZED) {} +#else + Once(bool startInitialized = false); + ~Once(); +#endif + KJ_DISALLOW_COPY(Once); + + class Initializer { + public: + virtual void run() = 0; + }; + + void runOnce(Initializer& init); + +#if _WIN32 // TODO(perf): Can we make this inline on win32 somehow? + bool isInitialized() noexcept; + +#else + inline bool isInitialized() noexcept { + // Fast path check to see if runOnce() would simply return immediately. +#if KJ_USE_FUTEX + return __atomic_load_n(&futex, __ATOMIC_ACQUIRE) == INITIALIZED; +#else + return __atomic_load_n(&state, __ATOMIC_ACQUIRE) == INITIALIZED; +#endif + } +#endif + + void reset(); + // Returns the state from initialized to uninitialized. It is an error to call this when + // not already initialized, or when runOnce() or isInitialized() might be called concurrently in + // another thread. + +private: +#if KJ_USE_FUTEX + uint futex; + + enum State { + UNINITIALIZED, + INITIALIZING, + INITIALIZING_WITH_WAITERS, + INITIALIZED + }; + +#elif _WIN32 + uintptr_t initOnce; // Actually an INIT_ONCE, but don't want to #include <windows.h> in header. + +#else + enum State { + UNINITIALIZED, + INITIALIZED + }; + State state; + pthread_mutex_t mutex; +#endif +}; + +} // namespace _ (private) + +// ======================================================================================= +// Public interface + +template <typename T> +class Locked { + // Return type for `MutexGuarded<T>::lock()`. `Locked<T>` provides access to the guarded object + // and unlocks the mutex when it goes out of scope. + +public: + KJ_DISALLOW_COPY(Locked); + inline Locked(): mutex(nullptr), ptr(nullptr) {} + inline Locked(Locked&& other): mutex(other.mutex), ptr(other.ptr) { + other.mutex = nullptr; + other.ptr = nullptr; + } + inline ~Locked() { + if (mutex != nullptr) mutex->unlock(isConst<T>() ? _::Mutex::SHARED : _::Mutex::EXCLUSIVE); + } + + inline Locked& operator=(Locked&& other) { + if (mutex != nullptr) mutex->unlock(isConst<T>() ? _::Mutex::SHARED : _::Mutex::EXCLUSIVE); + mutex = other.mutex; + ptr = other.ptr; + other.mutex = nullptr; + other.ptr = nullptr; + return *this; + } + + inline void release() { + if (mutex != nullptr) mutex->unlock(isConst<T>() ? _::Mutex::SHARED : _::Mutex::EXCLUSIVE); + mutex = nullptr; + ptr = nullptr; + } + + inline T* operator->() { return ptr; } + inline const T* operator->() const { return ptr; } + inline T& operator*() { return *ptr; } + inline const T& operator*() const { return *ptr; } + inline T* get() { return ptr; } + inline const T* get() const { return ptr; } + inline operator T*() { return ptr; } + inline operator const T*() const { return ptr; } + +private: + _::Mutex* mutex; + T* ptr; + + inline Locked(_::Mutex& mutex, T& value): mutex(&mutex), ptr(&value) {} + + template <typename U> + friend class MutexGuarded; +}; + +template <typename T> +class MutexGuarded { + // An object of type T, guarded by a mutex. In order to access the object, you must lock it. + // + // Write locks are not "recursive" -- trying to lock again in a thread that already holds a lock + // will deadlock. Recursive write locks are usually a sign of bad design. + // + // Unfortunately, **READ LOCKS ARE NOT RECURSIVE** either. Common sense says they should be. + // But on many operating systems (BSD, OSX), recursively read-locking a pthread_rwlock is + // actually unsafe. The problem is that writers are "prioritized" over readers, so a read lock + // request will block if any write lock requests are outstanding. So, if thread A takes a read + // lock, thread B requests a write lock (and starts waiting), and then thread A tries to take + // another read lock recursively, the result is deadlock. + +public: + template <typename... Params> + explicit MutexGuarded(Params&&... params); + // Initialize the mutex-guarded object by passing the given parameters to its constructor. + + Locked<T> lockExclusive() const; + // Exclusively locks the object and returns it. The returned `Locked<T>` can be passed by + // move, similar to `Own<T>`. + // + // This method is declared `const` in accordance with KJ style rules which say that constness + // should be used to indicate thread-safety. It is safe to share a const pointer between threads, + // but it is not safe to share a mutable pointer. Since the whole point of MutexGuarded is to + // be shared between threads, its methods should be const, even though locking it produces a + // non-const pointer to the contained object. + + Locked<const T> lockShared() const; + // Lock the value for shared access. Multiple shared locks can be taken concurrently, but cannot + // be held at the same time as a non-shared lock. + + inline const T& getWithoutLock() const { return value; } + inline T& getWithoutLock() { return value; } + // Escape hatch for cases where some external factor guarantees that it's safe to get the + // value. You should treat these like const_cast -- be highly suspicious of any use. + + inline const T& getAlreadyLockedShared() const; + inline T& getAlreadyLockedShared(); + inline T& getAlreadyLockedExclusive() const; + // Like `getWithoutLock()`, but asserts that the lock is already held by the calling thread. + +private: + mutable _::Mutex mutex; + mutable T value; +}; + +template <typename T> +class MutexGuarded<const T> { + // MutexGuarded cannot guard a const type. This would be pointless anyway, and would complicate + // the implementation of Locked<T>, which uses constness to decide what kind of lock it holds. + static_assert(sizeof(T) < 0, "MutexGuarded's type cannot be const."); +}; + +template <typename T> +class Lazy { + // A lazily-initialized value. + +public: + template <typename Func> + T& get(Func&& init); + template <typename Func> + const T& get(Func&& init) const; + // The first thread to call get() will invoke the given init function to construct the value. + // Other threads will block until construction completes, then return the same value. + // + // `init` is a functor(typically a lambda) which takes `SpaceFor<T>&` as its parameter and returns + // `Own<T>`. If `init` throws an exception, the exception is propagated out of that thread's + // call to `get()`, and subsequent calls behave as if `get()` hadn't been called at all yet -- + // in other words, subsequent calls retry initialization until it succeeds. + +private: + mutable _::Once once; + mutable SpaceFor<T> space; + mutable Own<T> value; + + template <typename Func> + class InitImpl; +}; + +// ======================================================================================= +// Inline implementation details + +template <typename T> +template <typename... Params> +inline MutexGuarded<T>::MutexGuarded(Params&&... params) + : value(kj::fwd<Params>(params)...) {} + +template <typename T> +inline Locked<T> MutexGuarded<T>::lockExclusive() const { + mutex.lock(_::Mutex::EXCLUSIVE); + return Locked<T>(mutex, value); +} + +template <typename T> +inline Locked<const T> MutexGuarded<T>::lockShared() const { + mutex.lock(_::Mutex::SHARED); + return Locked<const T>(mutex, value); +} + +template <typename T> +inline const T& MutexGuarded<T>::getAlreadyLockedShared() const { +#ifdef KJ_DEBUG + mutex.assertLockedByCaller(_::Mutex::SHARED); +#endif + return value; +} +template <typename T> +inline T& MutexGuarded<T>::getAlreadyLockedShared() { +#ifdef KJ_DEBUG + mutex.assertLockedByCaller(_::Mutex::SHARED); +#endif + return value; +} +template <typename T> +inline T& MutexGuarded<T>::getAlreadyLockedExclusive() const { +#ifdef KJ_DEBUG + mutex.assertLockedByCaller(_::Mutex::EXCLUSIVE); +#endif + return const_cast<T&>(value); +} + +template <typename T> +template <typename Func> +class Lazy<T>::InitImpl: public _::Once::Initializer { +public: + inline InitImpl(const Lazy<T>& lazy, Func&& func): lazy(lazy), func(kj::fwd<Func>(func)) {} + + void run() override { + lazy.value = func(lazy.space); + } + +private: + const Lazy<T>& lazy; + Func func; +}; + +template <typename T> +template <typename Func> +inline T& Lazy<T>::get(Func&& init) { + if (!once.isInitialized()) { + InitImpl<Func> initImpl(*this, kj::fwd<Func>(init)); + once.runOnce(initImpl); + } + return *value; +} + +template <typename T> +template <typename Func> +inline const T& Lazy<T>::get(Func&& init) const { + if (!once.isInitialized()) { + InitImpl<Func> initImpl(*this, kj::fwd<Func>(init)); + once.runOnce(initImpl); + } + return *value; +} + +} // namespace kj + +#endif // KJ_MUTEX_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/one-of.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,150 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef KJ_ONE_OF_H_ +#define KJ_ONE_OF_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "common.h" + +namespace kj { + +namespace _ { // private + +template <uint i, typename Key, typename First, typename... Rest> +struct TypeIndex_ { static constexpr uint value = TypeIndex_<i + 1, Key, Rest...>::value; }; +template <uint i, typename Key, typename... Rest> +struct TypeIndex_<i, Key, Key, Rest...> { static constexpr uint value = i; }; + +} // namespace _ (private) + +template <typename... Variants> +class OneOf { + template <typename Key> + static inline constexpr uint typeIndex() { return _::TypeIndex_<1, Key, Variants...>::value; } + // Get the 1-based index of Key within the type list Types. + +public: + inline OneOf(): tag(0) {} + OneOf(const OneOf& other) { copyFrom(other); } + OneOf(OneOf&& other) { moveFrom(other); } + ~OneOf() { destroy(); } + + OneOf& operator=(const OneOf& other) { if (tag != 0) destroy(); copyFrom(other); return *this; } + OneOf& operator=(OneOf&& other) { if (tag != 0) destroy(); moveFrom(other); return *this; } + + inline bool operator==(decltype(nullptr)) const { return tag == 0; } + inline bool operator!=(decltype(nullptr)) const { return tag != 0; } + + template <typename T> + bool is() const { + return tag == typeIndex<T>(); + } + + template <typename T> + T& get() { + KJ_IREQUIRE(is<T>(), "Must check OneOf::is<T>() before calling get<T>()."); + return *reinterpret_cast<T*>(space); + } + template <typename T> + const T& get() const { + KJ_IREQUIRE(is<T>(), "Must check OneOf::is<T>() before calling get<T>()."); + return *reinterpret_cast<const T*>(space); + } + + template <typename T, typename... Params> + void init(Params&&... params) { + if (tag != 0) destroy(); + ctor(*reinterpret_cast<T*>(space), kj::fwd<Params>(params)...); + tag = typeIndex<T>(); + } + +private: + uint tag; + + static inline constexpr size_t maxSize(size_t a) { + return a; + } + template <typename... Rest> + static inline constexpr size_t maxSize(size_t a, size_t b, Rest... rest) { + return maxSize(kj::max(a, b), rest...); + } + // Returns the maximum of all the parameters. + // TODO(someday): Generalize the above template and make it common. I tried, but C++ decided to + // be difficult so I cut my losses. + + union { + byte space[maxSize(sizeof(Variants)...)]; + + void* forceAligned; + // TODO(someday): Use C++11 alignas() once we require GCC 4.8 / Clang 3.3. + }; + + template <typename... T> + inline void doAll(T... t) {} + + template <typename T> + inline bool destroyVariant() { + if (tag == typeIndex<T>()) { + tag = 0; + dtor(*reinterpret_cast<T*>(space)); + } + return false; + } + void destroy() { + doAll(destroyVariant<Variants>()...); + } + + template <typename T> + inline bool copyVariantFrom(const OneOf& other) { + if (other.is<T>()) { + ctor(*reinterpret_cast<T*>(space), other.get<T>()); + } + return false; + } + void copyFrom(const OneOf& other) { + // Initialize as a copy of `other`. Expects that `this` starts out uninitialized, so the tag + // is invalid. + tag = other.tag; + doAll(copyVariantFrom<Variants>(other)...); + } + + template <typename T> + inline bool moveVariantFrom(OneOf& other) { + if (other.is<T>()) { + ctor(*reinterpret_cast<T*>(space), kj::mv(other.get<T>())); + } + return false; + } + void moveFrom(OneOf& other) { + // Initialize as a copy of `other`. Expects that `this` starts out uninitialized, so the tag + // is invalid. + tag = other.tag; + doAll(moveVariantFrom<Variants>(other)...); + } +}; + +} // namespace kj + +#endif // KJ_ONE_OF_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/refcount.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,107 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include "memory.h" + +#ifndef KJ_REFCOUNT_H_ +#define KJ_REFCOUNT_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +namespace kj { + +class Refcounted: private Disposer { + // Subclass this to create a class that contains a reference count. Then, use + // `kj::refcounted<T>()` to allocate a new refcounted pointer. + // + // Do NOT use this lightly. Refcounting is a crutch. Good designs should strive to make object + // ownership clear, so that refcounting is not necessary. All that said, reference counting can + // sometimes simplify code that would otherwise become convoluted with explicit ownership, even + // when ownership relationships are clear at an abstract level. + // + // NOT THREADSAFE: This refcounting implementation assumes that an object's references are + // manipulated only in one thread, because atomic (thread-safe) refcounting is surprisingly slow. + // + // In general, abstract classes should _not_ subclass this. The concrete class at the bottom + // of the hierarchy should be the one to decide how it implements refcounting. Interfaces should + // expose only an `addRef()` method that returns `Own<InterfaceType>`. There are two reasons for + // this rule: + // 1. Interfaces would need to virtually inherit Refcounted, otherwise two refcounted interfaces + // could not be inherited by the same subclass. Virtual inheritance is awkward and + // inefficient. + // 2. An implementation may decide that it would rather return a copy than a refcount, or use + // some other strategy. + // + // TODO(cleanup): Rethink above. Virtual inheritance is not necessarily that bad. OTOH, a + // virtual function call for every refcount is sad in its own way. A Ref<T> type to replace + // Own<T> could also be nice. + +public: + virtual ~Refcounted() noexcept(false); + + inline bool isShared() const { return refcount > 1; } + // Check if there are multiple references to this object. This is sometimes useful for deciding + // whether it's safe to modify the object vs. make a copy. + +private: + mutable uint refcount = 0; + // "mutable" because disposeImpl() is const. Bleh. + + void disposeImpl(void* pointer) const override; + template <typename T> + static Own<T> addRefInternal(T* object); + + template <typename T> + friend Own<T> addRef(T& object); + template <typename T, typename... Params> + friend Own<T> refcounted(Params&&... params); +}; + +template <typename T, typename... Params> +inline Own<T> refcounted(Params&&... params) { + // Allocate a new refcounted instance of T, passing `params` to its constructor. Returns an + // initial reference to the object. More references can be created with `kj::addRef()`. + + return Refcounted::addRefInternal(new T(kj::fwd<Params>(params)...)); +} + +template <typename T> +Own<T> addRef(T& object) { + // Return a new reference to `object`, which must subclass Refcounted and have been allocated + // using `kj::refcounted<>()`. It is suggested that subclasses implement a non-static addRef() + // method which wraps this and returns the appropriate type. + + KJ_IREQUIRE(object.Refcounted::refcount > 0, "Object not allocated with kj::refcounted()."); + return Refcounted::addRefInternal(&object); +} + +template <typename T> +Own<T> Refcounted::addRefInternal(T* object) { + Refcounted* refcounted = object; + ++refcounted->refcount; + return Own<T>(object, *refcounted); +} + +} // namespace kj + +#endif // KJ_REFCOUNT_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/string-tree.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,212 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef KJ_STRING_TREE_H_ +#define KJ_STRING_TREE_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "string.h" + +namespace kj { + +class StringTree { + // A long string, represented internally as a tree of strings. This data structure is like a + // String, but optimized for concatenation and iteration at the expense of seek time. The + // structure is intended to be used for building large text blobs from many small pieces, where + // repeatedly concatenating smaller strings into larger ones would waste copies. This structure + // is NOT intended for use cases requiring random access or computing substrings. For those, + // you should use a Rope, which is a much more complicated data structure. + // + // The proper way to construct a StringTree is via kj::strTree(...), which works just like + // kj::str(...) but returns a StringTree rather than a String. + // + // KJ_STRINGIFY() functions that construct large strings from many smaller strings are encouraged + // to return StringTree rather than a flat char container. + +public: + inline StringTree(): size_(0) {} + inline StringTree(String&& text): size_(text.size()), text(kj::mv(text)) {} + + StringTree(Array<StringTree>&& pieces, StringPtr delim); + // Build a StringTree by concatenating the given pieces, delimited by the given delimiter + // (e.g. ", "). + + inline size_t size() const { return size_; } + + template <typename Func> + void visit(Func&& func) const; + + String flatten() const; + // Return the contents as a string. + + // TODO(someday): flatten() when *this is an rvalue and when branches.size() == 0 could simply + // return `kj::mv(text)`. Requires reference qualifiers (Clang 3.3 / GCC 4.8). + + void flattenTo(char* __restrict__ target) const; + // Copy the contents to the given character array. Does not add a NUL terminator. + +private: + size_t size_; + String text; + + struct Branch; + Array<Branch> branches; // In order. + + inline void fill(char* pos, size_t branchIndex); + template <typename First, typename... Rest> + void fill(char* pos, size_t branchIndex, First&& first, Rest&&... rest); + template <typename... Rest> + void fill(char* pos, size_t branchIndex, StringTree&& first, Rest&&... rest); + template <typename... Rest> + void fill(char* pos, size_t branchIndex, Array<char>&& first, Rest&&... rest); + template <typename... Rest> + void fill(char* pos, size_t branchIndex, String&& first, Rest&&... rest); + + template <typename... Params> + static StringTree concat(Params&&... params); + static StringTree&& concat(StringTree&& param) { return kj::mv(param); } + + template <typename T> + static inline size_t flatSize(const T& t) { return t.size(); } + static inline size_t flatSize(String&& s) { return 0; } + static inline size_t flatSize(StringTree&& s) { return 0; } + + template <typename T> + static inline size_t branchCount(const T& t) { return 0; } + static inline size_t branchCount(String&& s) { return 1; } + static inline size_t branchCount(StringTree&& s) { return 1; } + + template <typename... Params> + friend StringTree strTree(Params&&... params); +}; + +inline StringTree&& KJ_STRINGIFY(StringTree&& tree) { return kj::mv(tree); } +inline const StringTree& KJ_STRINGIFY(const StringTree& tree) { return tree; } + +inline StringTree KJ_STRINGIFY(Array<StringTree>&& trees) { return StringTree(kj::mv(trees), ""); } + +template <typename... Params> +StringTree strTree(Params&&... params); +// Build a StringTree by stringifying the given parameters and concatenating the results. +// If any of the parameters stringify to StringTree rvalues, they will be incorporated as +// branches to avoid a copy. + +// ======================================================================================= +// Inline implementation details + +namespace _ { // private + +template <typename... Rest> +char* fill(char* __restrict__ target, const StringTree& first, Rest&&... rest) { + // Make str() work with stringifiers that return StringTree by patching fill(). + + first.flattenTo(target); + return fill(target + first.size(), kj::fwd<Rest>(rest)...); +} + +template <typename T> constexpr bool isStringTree() { return false; } +template <> constexpr bool isStringTree<StringTree>() { return true; } + +inline StringTree&& toStringTreeOrCharSequence(StringTree&& tree) { return kj::mv(tree); } +inline StringTree toStringTreeOrCharSequence(String&& str) { return StringTree(kj::mv(str)); } + +template <typename T> +inline auto toStringTreeOrCharSequence(T&& value) + -> decltype(toCharSequence(kj::fwd<T>(value))) { + static_assert(!isStringTree<Decay<T>>(), + "When passing a StringTree into kj::strTree(), either pass it by rvalue " + "(use kj::mv(value)) or explicitly call value.flatten() to make a copy."); + + return toCharSequence(kj::fwd<T>(value)); +} + +} // namespace _ (private) + +struct StringTree::Branch { + size_t index; + // Index in `text` where this branch should be inserted. + + StringTree content; +}; + +template <typename Func> +void StringTree::visit(Func&& func) const { + size_t pos = 0; + for (auto& branch: branches) { + if (branch.index > pos) { + func(text.slice(pos, branch.index)); + pos = branch.index; + } + branch.content.visit(func); + } + if (text.size() > pos) { + func(text.slice(pos, text.size())); + } +} + +inline void StringTree::fill(char* pos, size_t branchIndex) { + KJ_IREQUIRE(pos == text.end() && branchIndex == branches.size(), + kj::str(text.end() - pos, ' ', branches.size() - branchIndex).cStr()); +} + +template <typename First, typename... Rest> +void StringTree::fill(char* pos, size_t branchIndex, First&& first, Rest&&... rest) { + pos = _::fill(pos, kj::fwd<First>(first)); + fill(pos, branchIndex, kj::fwd<Rest>(rest)...); +} + +template <typename... Rest> +void StringTree::fill(char* pos, size_t branchIndex, StringTree&& first, Rest&&... rest) { + branches[branchIndex].index = pos - text.begin(); + branches[branchIndex].content = kj::mv(first); + fill(pos, branchIndex + 1, kj::fwd<Rest>(rest)...); +} + +template <typename... Rest> +void StringTree::fill(char* pos, size_t branchIndex, String&& first, Rest&&... rest) { + branches[branchIndex].index = pos - text.begin(); + branches[branchIndex].content = StringTree(kj::mv(first)); + fill(pos, branchIndex + 1, kj::fwd<Rest>(rest)...); +} + +template <typename... Params> +StringTree StringTree::concat(Params&&... params) { + StringTree result; + result.size_ = _::sum({params.size()...}); + result.text = heapString( + _::sum({StringTree::flatSize(kj::fwd<Params>(params))...})); + result.branches = heapArray<StringTree::Branch>( + _::sum({StringTree::branchCount(kj::fwd<Params>(params))...})); + result.fill(result.text.begin(), 0, kj::fwd<Params>(params)...); + return result; +} + +template <typename... Params> +StringTree strTree(Params&&... params) { + return StringTree::concat(_::toStringTreeOrCharSequence(kj::fwd<Params>(params))...); +} + +} // namespace kj + +#endif // KJ_STRING_TREE_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/string.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,530 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef KJ_STRING_H_ +#define KJ_STRING_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include <initializer_list> +#include "array.h" +#include <string.h> + +namespace kj { + +class StringPtr; +class String; + +class StringTree; // string-tree.h + +// Our STL string SFINAE trick does not work with GCC 4.7, but it works with Clang and GCC 4.8, so +// we'll just preprocess it out if not supported. +#if __clang__ || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || _MSC_VER +#define KJ_COMPILER_SUPPORTS_STL_STRING_INTEROP 1 +#endif + +// ======================================================================================= +// StringPtr -- A NUL-terminated ArrayPtr<const char> containing UTF-8 text. +// +// NUL bytes are allowed to appear before the end of the string. The only requirement is that +// a NUL byte appear immediately after the last byte of the content. This terminator byte is not +// counted in the string's size. + +class StringPtr { +public: + inline StringPtr(): content("", 1) {} + inline StringPtr(decltype(nullptr)): content("", 1) {} + inline StringPtr(const char* value): content(value, strlen(value) + 1) {} + inline StringPtr(const char* value, size_t size): content(value, size + 1) { + KJ_IREQUIRE(value[size] == '\0', "StringPtr must be NUL-terminated."); + } + inline StringPtr(const char* begin, const char* end): StringPtr(begin, end - begin) {} + inline StringPtr(const String& value); + +#if KJ_COMPILER_SUPPORTS_STL_STRING_INTEROP + template <typename T, typename = decltype(instance<T>().c_str())> + inline StringPtr(const T& t): StringPtr(t.c_str()) {} + // Allow implicit conversion from any class that has a c_str() method (namely, std::string). + // We use a template trick to detect std::string in order to avoid including the header for + // those who don't want it. + + template <typename T, typename = decltype(instance<T>().c_str())> + inline operator T() const { return cStr(); } + // Allow implicit conversion to any class that has a c_str() method (namely, std::string). + // We use a template trick to detect std::string in order to avoid including the header for + // those who don't want it. +#endif + + inline operator ArrayPtr<const char>() const; + inline ArrayPtr<const char> asArray() const; + inline ArrayPtr<const byte> asBytes() const { return asArray().asBytes(); } + // Result does not include NUL terminator. + + inline const char* cStr() const { return content.begin(); } + // Returns NUL-terminated string. + + inline size_t size() const { return content.size() - 1; } + // Result does not include NUL terminator. + + inline char operator[](size_t index) const { return content[index]; } + + inline const char* begin() const { return content.begin(); } + inline const char* end() const { return content.end() - 1; } + + inline bool operator==(decltype(nullptr)) const { return content.size() <= 1; } + inline bool operator!=(decltype(nullptr)) const { return content.size() > 1; } + + inline bool operator==(const StringPtr& other) const; + inline bool operator!=(const StringPtr& other) const { return !(*this == other); } + inline bool operator< (const StringPtr& other) const; + inline bool operator> (const StringPtr& other) const { return other < *this; } + inline bool operator<=(const StringPtr& other) const { return !(other < *this); } + inline bool operator>=(const StringPtr& other) const { return !(*this < other); } + + inline StringPtr slice(size_t start) const; + inline ArrayPtr<const char> slice(size_t start, size_t end) const; + // A string slice is only NUL-terminated if it is a suffix, so slice() has a one-parameter + // version that assumes end = size(). + + inline bool startsWith(const StringPtr& other) const; + inline bool endsWith(const StringPtr& other) const; + + inline Maybe<size_t> findFirst(char c) const; + inline Maybe<size_t> findLast(char c) const; + + template <typename T> + T parseAs() const; + // Parse string as template number type. + // Integer numbers prefixed by "0x" and "0X" are parsed in base 16 (like strtoi with base 0). + // Integer numbers prefixed by "0" are parsed in base 10 (unlike strtoi with base 0). + // Overflowed integer numbers throw exception. + // Overflowed floating numbers return inf. + +private: + inline StringPtr(ArrayPtr<const char> content): content(content) {} + + ArrayPtr<const char> content; +}; + +inline bool operator==(const char* a, const StringPtr& b) { return b == a; } +inline bool operator!=(const char* a, const StringPtr& b) { return b != a; } + +template <> char StringPtr::parseAs<char>() const; +template <> signed char StringPtr::parseAs<signed char>() const; +template <> unsigned char StringPtr::parseAs<unsigned char>() const; +template <> short StringPtr::parseAs<short>() const; +template <> unsigned short StringPtr::parseAs<unsigned short>() const; +template <> int StringPtr::parseAs<int>() const; +template <> unsigned StringPtr::parseAs<unsigned>() const; +template <> long StringPtr::parseAs<long>() const; +template <> unsigned long StringPtr::parseAs<unsigned long>() const; +template <> long long StringPtr::parseAs<long long>() const; +template <> unsigned long long StringPtr::parseAs<unsigned long long>() const; +template <> float StringPtr::parseAs<float>() const; +template <> double StringPtr::parseAs<double>() const; + +// ======================================================================================= +// String -- A NUL-terminated Array<char> containing UTF-8 text. +// +// NUL bytes are allowed to appear before the end of the string. The only requirement is that +// a NUL byte appear immediately after the last byte of the content. This terminator byte is not +// counted in the string's size. +// +// To allocate a String, you must call kj::heapString(). We do not implement implicit copying to +// the heap because this hides potential inefficiency from the developer. + +class String { +public: + String() = default; + inline String(decltype(nullptr)): content(nullptr) {} + inline String(char* value, size_t size, const ArrayDisposer& disposer); + // Does not copy. `size` does not include NUL terminator, but `value` must be NUL-terminated. + inline explicit String(Array<char> buffer); + // Does not copy. Requires `buffer` ends with `\0`. + + inline operator ArrayPtr<char>(); + inline operator ArrayPtr<const char>() const; + inline ArrayPtr<char> asArray(); + inline ArrayPtr<const char> asArray() const; + inline ArrayPtr<byte> asBytes() { return asArray().asBytes(); } + inline ArrayPtr<const byte> asBytes() const { return asArray().asBytes(); } + // Result does not include NUL terminator. + + inline const char* cStr() const; + + inline size_t size() const; + // Result does not include NUL terminator. + + inline char operator[](size_t index) const; + inline char& operator[](size_t index); + + inline char* begin(); + inline char* end(); + inline const char* begin() const; + inline const char* end() const; + + inline bool operator==(decltype(nullptr)) const { return content.size() <= 1; } + inline bool operator!=(decltype(nullptr)) const { return content.size() > 1; } + + inline bool operator==(const StringPtr& other) const { return StringPtr(*this) == other; } + inline bool operator!=(const StringPtr& other) const { return StringPtr(*this) != other; } + inline bool operator< (const StringPtr& other) const { return StringPtr(*this) < other; } + inline bool operator> (const StringPtr& other) const { return StringPtr(*this) > other; } + inline bool operator<=(const StringPtr& other) const { return StringPtr(*this) <= other; } + inline bool operator>=(const StringPtr& other) const { return StringPtr(*this) >= other; } + + inline bool startsWith(const StringPtr& other) const { return StringPtr(*this).startsWith(other);} + inline bool endsWith(const StringPtr& other) const { return StringPtr(*this).endsWith(other); } + + inline StringPtr slice(size_t start) const { return StringPtr(*this).slice(start); } + inline ArrayPtr<const char> slice(size_t start, size_t end) const { + return StringPtr(*this).slice(start, end); + } + + inline Maybe<size_t> findFirst(char c) const { return StringPtr(*this).findFirst(c); } + inline Maybe<size_t> findLast(char c) const { return StringPtr(*this).findLast(c); } + + template <typename T> + T parseAs() const { return StringPtr(*this).parseAs<T>(); } + // Parse as number + +private: + Array<char> content; +}; + +inline bool operator==(const char* a, const String& b) { return b == a; } +inline bool operator!=(const char* a, const String& b) { return b != a; } + +String heapString(size_t size); +// Allocate a String of the given size on the heap, not including NUL terminator. The NUL +// terminator will be initialized automatically but the rest of the content is not initialized. + +String heapString(const char* value); +String heapString(const char* value, size_t size); +String heapString(StringPtr value); +String heapString(const String& value); +String heapString(ArrayPtr<const char> value); +// Allocates a copy of the given value on the heap. + +// ======================================================================================= +// Magic str() function which transforms parameters to text and concatenates them into one big +// String. + +namespace _ { // private + +inline size_t sum(std::initializer_list<size_t> nums) { + size_t result = 0; + for (auto num: nums) { + result += num; + } + return result; +} + +inline char* fill(char* ptr) { return ptr; } + +template <typename... Rest> +char* fill(char* __restrict__ target, const StringTree& first, Rest&&... rest); +// Make str() work with stringifiers that return StringTree by patching fill(). +// +// Defined in string-tree.h. + +template <typename First, typename... Rest> +char* fill(char* __restrict__ target, const First& first, Rest&&... rest) { + auto i = first.begin(); + auto end = first.end(); + while (i != end) { + *target++ = *i++; + } + return fill(target, kj::fwd<Rest>(rest)...); +} + +template <typename... Params> +String concat(Params&&... params) { + // Concatenate a bunch of containers into a single Array. The containers can be anything that + // is iterable and whose elements can be converted to `char`. + + String result = heapString(sum({params.size()...})); + fill(result.begin(), kj::fwd<Params>(params)...); + return result; +} + +inline String concat(String&& arr) { + return kj::mv(arr); +} + +struct Stringifier { + // This is a dummy type with only one instance: STR (below). To make an arbitrary type + // stringifiable, define `operator*(Stringifier, T)` to return an iterable container of `char`. + // The container type must have a `size()` method. Be sure to declare the operator in the same + // namespace as `T` **or** in the global scope. + // + // A more usual way to accomplish what we're doing here would be to require that you define + // a function like `toString(T)` and then rely on argument-dependent lookup. However, this has + // the problem that it pollutes other people's namespaces and even the global namespace. For + // example, some other project may already have functions called `toString` which do something + // different. Declaring `operator*` with `Stringifier` as the left operand cannot conflict with + // anything. + + inline ArrayPtr<const char> operator*(ArrayPtr<const char> s) const { return s; } + inline ArrayPtr<const char> operator*(ArrayPtr<char> s) const { return s; } + inline ArrayPtr<const char> operator*(const Array<const char>& s) const { return s; } + inline ArrayPtr<const char> operator*(const Array<char>& s) const { return s; } + template<size_t n> + inline ArrayPtr<const char> operator*(const CappedArray<char, n>& s) const { return s; } + template<size_t n> + inline ArrayPtr<const char> operator*(const FixedArray<char, n>& s) const { return s; } + inline ArrayPtr<const char> operator*(const char* s) const { return arrayPtr(s, strlen(s)); } + inline ArrayPtr<const char> operator*(const String& s) const { return s.asArray(); } + inline ArrayPtr<const char> operator*(const StringPtr& s) const { return s.asArray(); } + + inline Range<char> operator*(const Range<char>& r) const { return r; } + inline Repeat<char> operator*(const Repeat<char>& r) const { return r; } + + inline FixedArray<char, 1> operator*(char c) const { + FixedArray<char, 1> result; + result[0] = c; + return result; + } + + StringPtr operator*(decltype(nullptr)) const; + StringPtr operator*(bool b) const; + + CappedArray<char, 5> operator*(signed char i) const; + CappedArray<char, 5> operator*(unsigned char i) const; + CappedArray<char, sizeof(short) * 3 + 2> operator*(short i) const; + CappedArray<char, sizeof(unsigned short) * 3 + 2> operator*(unsigned short i) const; + CappedArray<char, sizeof(int) * 3 + 2> operator*(int i) const; + CappedArray<char, sizeof(unsigned int) * 3 + 2> operator*(unsigned int i) const; + CappedArray<char, sizeof(long) * 3 + 2> operator*(long i) const; + CappedArray<char, sizeof(unsigned long) * 3 + 2> operator*(unsigned long i) const; + CappedArray<char, sizeof(long long) * 3 + 2> operator*(long long i) const; + CappedArray<char, sizeof(unsigned long long) * 3 + 2> operator*(unsigned long long i) const; + CappedArray<char, 24> operator*(float f) const; + CappedArray<char, 32> operator*(double f) const; + CappedArray<char, sizeof(const void*) * 3 + 2> operator*(const void* s) const; + + template <typename T> + String operator*(ArrayPtr<T> arr) const; + template <typename T> + String operator*(const Array<T>& arr) const; + +#if KJ_COMPILER_SUPPORTS_STL_STRING_INTEROP // supports expression SFINAE? + template <typename T, typename Result = decltype(instance<T>().toString())> + inline Result operator*(T&& value) const { return kj::fwd<T>(value).toString(); } +#endif +}; +static KJ_CONSTEXPR(const) Stringifier STR = Stringifier(); + +} // namespace _ (private) + +template <typename T> +auto toCharSequence(T&& value) -> decltype(_::STR * kj::fwd<T>(value)) { + // Returns an iterable of chars that represent a textual representation of the value, suitable + // for debugging. + // + // Most users should use str() instead, but toCharSequence() may occasionally be useful to avoid + // heap allocation overhead that str() implies. + // + // To specialize this function for your type, see KJ_STRINGIFY. + + return _::STR * kj::fwd<T>(value); +} + +CappedArray<char, sizeof(unsigned char) * 2 + 1> hex(unsigned char i); +CappedArray<char, sizeof(unsigned short) * 2 + 1> hex(unsigned short i); +CappedArray<char, sizeof(unsigned int) * 2 + 1> hex(unsigned int i); +CappedArray<char, sizeof(unsigned long) * 2 + 1> hex(unsigned long i); +CappedArray<char, sizeof(unsigned long long) * 2 + 1> hex(unsigned long long i); + +template <typename... Params> +String str(Params&&... params) { + // Magic function which builds a string from a bunch of arbitrary values. Example: + // str(1, " / ", 2, " = ", 0.5) + // returns: + // "1 / 2 = 0.5" + // To teach `str` how to stringify a type, see `Stringifier`. + + return _::concat(toCharSequence(kj::fwd<Params>(params))...); +} + +inline String str(String&& s) { return mv(s); } +// Overload to prevent redundant allocation. + +template <typename T> +String strArray(T&& arr, const char* delim) { + size_t delimLen = strlen(delim); + KJ_STACK_ARRAY(decltype(_::STR * arr[0]), pieces, kj::size(arr), 8, 32); + size_t size = 0; + for (size_t i = 0; i < kj::size(arr); i++) { + if (i > 0) size += delimLen; + pieces[i] = _::STR * arr[i]; + size += pieces[i].size(); + } + + String result = heapString(size); + char* pos = result.begin(); + for (size_t i = 0; i < kj::size(arr); i++) { + if (i > 0) { + memcpy(pos, delim, delimLen); + pos += delimLen; + } + pos = _::fill(pos, pieces[i]); + } + return result; +} + +namespace _ { // private + +template <typename T> +inline String Stringifier::operator*(ArrayPtr<T> arr) const { + return strArray(arr, ", "); +} + +template <typename T> +inline String Stringifier::operator*(const Array<T>& arr) const { + return strArray(arr, ", "); +} + +} // namespace _ (private) + +#define KJ_STRINGIFY(...) operator*(::kj::_::Stringifier, __VA_ARGS__) +// Defines a stringifier for a custom type. Example: +// +// class Foo {...}; +// inline StringPtr KJ_STRINGIFY(const Foo& foo) { return foo.name(); } +// +// This allows Foo to be passed to str(). +// +// The function should be declared either in the same namespace as the target type or in the global +// namespace. It can return any type which is an iterable container of chars. + +// ======================================================================================= +// Inline implementation details. + +inline StringPtr::StringPtr(const String& value): content(value.begin(), value.size() + 1) {} + +inline StringPtr::operator ArrayPtr<const char>() const { + return content.slice(0, content.size() - 1); +} + +inline ArrayPtr<const char> StringPtr::asArray() const { + return content.slice(0, content.size() - 1); +} + +inline bool StringPtr::operator==(const StringPtr& other) const { + return content.size() == other.content.size() && + memcmp(content.begin(), other.content.begin(), content.size() - 1) == 0; +} + +inline bool StringPtr::operator<(const StringPtr& other) const { + bool shorter = content.size() < other.content.size(); + int cmp = memcmp(content.begin(), other.content.begin(), + shorter ? content.size() : other.content.size()); + return cmp < 0 || (cmp == 0 && shorter); +} + +inline StringPtr StringPtr::slice(size_t start) const { + return StringPtr(content.slice(start, content.size())); +} +inline ArrayPtr<const char> StringPtr::slice(size_t start, size_t end) const { + return content.slice(start, end); +} + +inline bool StringPtr::startsWith(const StringPtr& other) const { + return other.content.size() <= content.size() && + memcmp(content.begin(), other.content.begin(), other.size()) == 0; +} +inline bool StringPtr::endsWith(const StringPtr& other) const { + return other.content.size() <= content.size() && + memcmp(end() - other.size(), other.content.begin(), other.size()) == 0; +} + +inline Maybe<size_t> StringPtr::findFirst(char c) const { + const char* pos = reinterpret_cast<const char*>(memchr(content.begin(), c, size())); + if (pos == nullptr) { + return nullptr; + } else { + return pos - content.begin(); + } +} + +inline Maybe<size_t> StringPtr::findLast(char c) const { + for (size_t i = size(); i > 0; --i) { + if (content[i-1] == c) { + return i-1; + } + } + return nullptr; +} + +inline String::operator ArrayPtr<char>() { + return content == nullptr ? ArrayPtr<char>(nullptr) : content.slice(0, content.size() - 1); +} +inline String::operator ArrayPtr<const char>() const { + return content == nullptr ? ArrayPtr<const char>(nullptr) : content.slice(0, content.size() - 1); +} + +inline ArrayPtr<char> String::asArray() { + return content == nullptr ? ArrayPtr<char>(nullptr) : content.slice(0, content.size() - 1); +} +inline ArrayPtr<const char> String::asArray() const { + return content == nullptr ? ArrayPtr<const char>(nullptr) : content.slice(0, content.size() - 1); +} + +inline const char* String::cStr() const { return content == nullptr ? "" : content.begin(); } + +inline size_t String::size() const { return content == nullptr ? 0 : content.size() - 1; } + +inline char String::operator[](size_t index) const { return content[index]; } +inline char& String::operator[](size_t index) { return content[index]; } + +inline char* String::begin() { return content == nullptr ? nullptr : content.begin(); } +inline char* String::end() { return content == nullptr ? nullptr : content.end() - 1; } +inline const char* String::begin() const { return content == nullptr ? nullptr : content.begin(); } +inline const char* String::end() const { return content == nullptr ? nullptr : content.end() - 1; } + +inline String::String(char* value, size_t size, const ArrayDisposer& disposer) + : content(value, size + 1, disposer) { + KJ_IREQUIRE(value[size] == '\0', "String must be NUL-terminated."); +} + +inline String::String(Array<char> buffer): content(kj::mv(buffer)) { + KJ_IREQUIRE(content.size() > 0 && content.back() == '\0', "String must be NUL-terminated."); +} + +inline String heapString(const char* value) { + return heapString(value, strlen(value)); +} +inline String heapString(StringPtr value) { + return heapString(value.begin(), value.size()); +} +inline String heapString(const String& value) { + return heapString(value.begin(), value.size()); +} +inline String heapString(ArrayPtr<const char> value) { + return heapString(value.begin(), value.size()); +} + +} // namespace kj + +#endif // KJ_STRING_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/test.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,144 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef KJ_TEST_H_ +#define KJ_TEST_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "debug.h" +#include "vector.h" + +namespace kj { + +class TestRunner; + +class TestCase { +public: + TestCase(const char* file, uint line, const char* description); + ~TestCase(); + + virtual void run() = 0; + +private: + const char* file; + uint line; + const char* description; + TestCase* next; + TestCase** prev; + bool matchedFilter; + + friend class TestRunner; +}; + +#define KJ_TEST(description) \ + /* Make sure the linker fails if tests are not in anonymous namespaces. */ \ + extern int KJ_CONCAT(YouMustWrapTestsInAnonymousNamespace, __COUNTER__) KJ_UNUSED; \ + class KJ_UNIQUE_NAME(TestCase): public ::kj::TestCase { \ + public: \ + KJ_UNIQUE_NAME(TestCase)(): ::kj::TestCase(__FILE__, __LINE__, description) {} \ + void run() override; \ + } KJ_UNIQUE_NAME(testCase); \ + void KJ_UNIQUE_NAME(TestCase)::run() + +#if _MSC_VER +#define KJ_INDIRECT_EXPAND(m, vargs) m vargs +#define KJ_FAIL_EXPECT(...) \ + KJ_INDIRECT_EXPAND(KJ_LOG, (ERROR , __VA_ARGS__)); +#define KJ_EXPECT(cond, ...) \ + if (cond); else KJ_INDIRECT_EXPAND(KJ_FAIL_EXPECT, ("failed: expected " #cond , __VA_ARGS__)) +#else +#define KJ_FAIL_EXPECT(...) \ + KJ_LOG(ERROR, ##__VA_ARGS__); +#define KJ_EXPECT(cond, ...) \ + if (cond); else KJ_FAIL_EXPECT("failed: expected " #cond, ##__VA_ARGS__) +#endif + +#define KJ_EXPECT_THROW(type, code) \ + do { \ + KJ_IF_MAYBE(e, ::kj::runCatchingExceptions([&]() { code; })) { \ + KJ_EXPECT(e->getType() == ::kj::Exception::Type::type, \ + "code threw wrong exception type: " #code, e->getType()); \ + } else { \ + KJ_FAIL_EXPECT("code did not throw: " #code); \ + } \ + } while (false) + +#define KJ_EXPECT_THROW_MESSAGE(message, code) \ + do { \ + KJ_IF_MAYBE(e, ::kj::runCatchingExceptions([&]() { code; })) { \ + KJ_EXPECT(::kj::_::hasSubstring(e->getDescription(), message), \ + "exception description didn't contain expected substring", e->getDescription()); \ + } else { \ + KJ_FAIL_EXPECT("code did not throw: " #code); \ + } \ + } while (false) + +#define KJ_EXPECT_LOG(level, substring) \ + ::kj::_::LogExpectation KJ_UNIQUE_NAME(_kjLogExpectation)(::kj::LogSeverity::level, substring) +// Expects that a log message with the given level and substring text will be printed within +// the current scope. This message will not cause the test to fail, even if it is an error. + +// ======================================================================================= + +namespace _ { // private + +bool hasSubstring(kj::StringPtr haystack, kj::StringPtr needle); + +class LogExpectation: public ExceptionCallback { +public: + LogExpectation(LogSeverity severity, StringPtr substring); + ~LogExpectation(); + + void logMessage(LogSeverity severity, const char* file, int line, int contextDepth, + String&& text) override; + +private: + LogSeverity severity; + StringPtr substring; + bool seen; + UnwindDetector unwindDetector; +}; + +class GlobFilter { + // Implements glob filters for the --filter flag. + // + // Exposed in header only for testing. + +public: + explicit GlobFilter(const char* pattern); + explicit GlobFilter(ArrayPtr<const char> pattern); + + bool matches(StringPtr name); + +private: + String pattern; + Vector<uint> states; + + void applyState(char c, int state); +}; + +} // namespace _ (private) +} // namespace kj + +#endif // KJ_TEST_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/thread.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,85 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef KJ_THREAD_H_ +#define KJ_THREAD_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "common.h" +#include "function.h" +#include "exception.h" + +namespace kj { + +class Thread { + // A thread! Pass a lambda to the constructor, and it runs in the thread. The destructor joins + // the thread. If the function throws an exception, it is rethrown from the thread's destructor + // (if not unwinding from another exception). + +public: + explicit Thread(Function<void()> func); + KJ_DISALLOW_COPY(Thread); + + ~Thread() noexcept(false); + +#if !_WIN32 + void sendSignal(int signo); + // Send a Unix signal to the given thread, using pthread_kill or an equivalent. +#endif + + void detach(); + // Don't join the thread in ~Thread(). + // + // TODO(soon): Currently broken: the thread uses the Thread objects during its execution; instead + // the Thread object and the thread itself will need to share a refcounted object. + +private: + struct ThreadState { + Function<void()> func; + kj::Maybe<kj::Exception> exception; + + unsigned int refcount; + // Owned by the parent thread and the child thread. + + void unref(); + }; + ThreadState* state; + +#if _WIN32 + void* threadHandle; +#else + unsigned long long threadId; // actually pthread_t +#endif + bool detached = false; + +#if _WIN32 + static unsigned long __stdcall runThread(void* ptr); +#else + static void* runThread(void* ptr); +#endif +}; + +} // namespace kj + +#endif // KJ_THREAD_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/threadlocal.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,136 @@ +// Copyright (c) 2014, Jason Choy <jjwchoy@gmail.com> +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef KJ_THREADLOCAL_H_ +#define KJ_THREADLOCAL_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif +// This file declares a macro `KJ_THREADLOCAL_PTR` for declaring thread-local pointer-typed +// variables. Use like: +// KJ_THREADLOCAL_PTR(MyType) foo = nullptr; +// This is equivalent to: +// thread_local MyType* foo = nullptr; +// This can only be used at the global scope. +// +// AVOID USING THIS. Use of thread-locals is discouraged because they often have many of the same +// properties as singletons: http://www.object-oriented-security.org/lets-argue/singletons +// +// Also, thread-locals tend to be hostile to event-driven code, which can be particularly +// surprising when using fibers (all fibers in the same thread will share the same threadlocals, +// even though they do not share a stack). +// +// That said, thread-locals are sometimes needed for runtime logistics in the KJ framework. For +// example, the current exception callback and current EventLoop are stored as thread-local +// pointers. Since KJ only ever needs to store pointers, not values, we avoid the question of +// whether these values' destructors need to be run, and we avoid the need for heap allocation. + +#include "common.h" + +#if !defined(KJ_USE_PTHREAD_THREADLOCAL) && defined(__APPLE__) +#include "TargetConditionals.h" +#if TARGET_OS_IPHONE +// iOS apparently does not support __thread (nor C++11 thread_local). +#define KJ_USE_PTHREAD_TLS 1 +#endif +#endif + +#if KJ_USE_PTHREAD_TLS +#include <pthread.h> +#endif + +namespace kj { + +#if KJ_USE_PTHREAD_TLS +// If __thread is unavailable, we'll fall back to pthreads. + +#define KJ_THREADLOCAL_PTR(type) \ + namespace { struct KJ_UNIQUE_NAME(_kj_TlpTag); } \ + static ::kj::_::ThreadLocalPtr< type, KJ_UNIQUE_NAME(_kj_TlpTag)> +// Hack: In order to ensure each thread-local results in a unique template instance, we declare +// a one-off dummy type to use as the second type parameter. + +namespace _ { // private + +template <typename T, typename> +class ThreadLocalPtr { + // Hacky type to emulate __thread T*. We need a separate instance of the ThreadLocalPtr template + // for every thread-local variable, because we don't want to require a global constructor, and in + // order to initialize the TLS on first use we need to use a local static variable (in getKey()). + // Each template instance will get a separate such local static variable, fulfilling our need. + +public: + ThreadLocalPtr() = default; + constexpr ThreadLocalPtr(decltype(nullptr)) {} + // Allow initialization to nullptr without a global constructor. + + inline ThreadLocalPtr& operator=(T* val) { + pthread_setspecific(getKey(), val); + return *this; + } + + inline operator T*() const { + return get(); + } + + inline T& operator*() const { + return *get(); + } + + inline T* operator->() const { + return get(); + } + +private: + inline T* get() const { + return reinterpret_cast<T*>(pthread_getspecific(getKey())); + } + + inline static pthread_key_t getKey() { + static pthread_key_t key = createKey(); + return key; + } + + static pthread_key_t createKey() { + pthread_key_t key; + pthread_key_create(&key, 0); + return key; + } +}; + +} // namespace _ (private) + +#elif __GNUC__ + +#define KJ_THREADLOCAL_PTR(type) static __thread type* +// GCC's __thread is lighter-weight than thread_local and is good enough for our purposes. + +#else + +#define KJ_THREADLOCAL_PTR(type) static thread_local type* + +#endif // KJ_USE_PTHREAD_TLS + +} // namespace kj + +#endif // KJ_THREADLOCAL_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/time.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,119 @@ +// Copyright (c) 2014 Google Inc. (contributed by Remy Blank <rblank@google.com>) +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef KJ_TIME_H_ +#define KJ_TIME_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "async.h" +#include "units.h" +#include <inttypes.h> + +namespace kj { +namespace _ { // private + +class NanosecondLabel; +class TimeLabel; +class DateLabel; + +} // namespace _ (private) + +using Duration = Quantity<int64_t, _::NanosecondLabel>; +// A time value, in microseconds. + +constexpr Duration NANOSECONDS = unit<Duration>(); +constexpr Duration MICROSECONDS = 1000 * NANOSECONDS; +constexpr Duration MILLISECONDS = 1000 * MICROSECONDS; +constexpr Duration SECONDS = 1000 * MILLISECONDS; +constexpr Duration MINUTES = 60 * SECONDS; +constexpr Duration HOURS = 60 * MINUTES; +constexpr Duration DAYS = 24 * HOURS; + +using TimePoint = Absolute<Duration, _::TimeLabel>; +// An absolute time measured by some particular instance of `Timer`. `Time`s from two different +// `Timer`s may be measured from different origins and so are not necessarily compatible. + +using Date = Absolute<Duration, _::DateLabel>; +// A point in real-world time, measured relative to the Unix epoch (Jan 1, 1970 00:00:00 UTC). + +constexpr Date UNIX_EPOCH = origin<Date>(); +// The `Date` representing Jan 1, 1970 00:00:00 UTC. + +class Timer { + // Interface to time and timer functionality. + // + // Each `Timer` may have a different origin, and some `Timer`s may in fact tick at a different + // rate than real time (e.g. a `Timer` could represent CPU time consumed by a thread). However, + // all `Timer`s are monotonic: time will never appear to move backwards, even if the calendar + // date as tracked by the system is manually modified. + +public: + virtual TimePoint now() = 0; + // Returns the current value of a clock that moves steadily forward, independent of any + // changes in the wall clock. The value is updated every time the event loop waits, + // and is constant in-between waits. + + virtual Promise<void> atTime(TimePoint time) = 0; + // Returns a promise that returns as soon as now() >= time. + + virtual Promise<void> afterDelay(Duration delay) = 0; + // Equivalent to atTime(now() + delay). + + template <typename T> + Promise<T> timeoutAt(TimePoint time, Promise<T>&& promise) KJ_WARN_UNUSED_RESULT; + // Return a promise equivalent to `promise` but which throws an exception (and cancels the + // original promise) if it hasn't completed by `time`. The thrown exception is of type + // "OVERLOADED". + + template <typename T> + Promise<T> timeoutAfter(Duration delay, Promise<T>&& promise) KJ_WARN_UNUSED_RESULT; + // Return a promise equivalent to `promise` but which throws an exception (and cancels the + // original promise) if it hasn't completed after `delay` from now. The thrown exception is of + // type "OVERLOADED". + +private: + static kj::Exception makeTimeoutException(); +}; + +// ======================================================================================= +// inline implementation details + +template <typename T> +Promise<T> Timer::timeoutAt(TimePoint time, Promise<T>&& promise) { + return promise.exclusiveJoin(atTime(time).then([]() -> kj::Promise<T> { + return makeTimeoutException(); + })); +} + +template <typename T> +Promise<T> Timer::timeoutAfter(Duration delay, Promise<T>&& promise) { + return promise.exclusiveJoin(afterDelay(delay).then([]() -> kj::Promise<T> { + return makeTimeoutException(); + })); +} + +} // namespace kj + +#endif // KJ_TIME_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/tuple.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,364 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// This file defines a notion of tuples that is simpler that `std::tuple`. It works as follows: +// - `kj::Tuple<A, B, C> is the type of a tuple of an A, a B, and a C. +// - `kj::tuple(a, b, c)` returns a tuple containing a, b, and c. If any of these are themselves +// tuples, they are flattened, so `tuple(a, tuple(b, c), d)` is equivalent to `tuple(a, b, c, d)`. +// - `kj::get<n>(myTuple)` returns the element of `myTuple` at index n. +// - `kj::apply(func, ...)` calls func on the following arguments after first expanding any tuples +// in the argument list. So `kj::apply(foo, a, tuple(b, c), d)` would call `foo(a, b, c, d)`. +// +// Note that: +// - The type `Tuple<T>` is a synonym for T. This is why `get` and `apply` are not members of the +// type. +// - It is illegal for an element of `Tuple` to itself be a tuple, as tuples are meant to be +// flattened. +// - It is illegal for an element of `Tuple` to be a reference, due to problems this would cause +// with type inference and `tuple()`. + +#ifndef KJ_TUPLE_H_ +#define KJ_TUPLE_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "common.h" + +namespace kj { +namespace _ { // private + +template <size_t index, typename... T> +struct TypeByIndex_; +template <typename First, typename... Rest> +struct TypeByIndex_<0, First, Rest...> { + typedef First Type; +}; +template <size_t index, typename First, typename... Rest> +struct TypeByIndex_<index, First, Rest...> + : public TypeByIndex_<index - 1, Rest...> {}; +template <size_t index> +struct TypeByIndex_<index> { + static_assert(index != index, "Index out-of-range."); +}; +template <size_t index, typename... T> +using TypeByIndex = typename TypeByIndex_<index, T...>::Type; +// Chose a particular type out of a list of types, by index. + +template <size_t... s> +struct Indexes {}; +// Dummy helper type that just encapsulates a sequential list of indexes, so that we can match +// templates against them and unpack them with '...'. + +template <size_t end, size_t... prefix> +struct MakeIndexes_: public MakeIndexes_<end - 1, end - 1, prefix...> {}; +template <size_t... prefix> +struct MakeIndexes_<0, prefix...> { + typedef Indexes<prefix...> Type; +}; +template <size_t end> +using MakeIndexes = typename MakeIndexes_<end>::Type; +// Equivalent to Indexes<0, 1, 2, ..., end>. + +template <typename... T> +class Tuple; +template <size_t index, typename... U> +inline TypeByIndex<index, U...>& getImpl(Tuple<U...>& tuple); +template <size_t index, typename... U> +inline TypeByIndex<index, U...>&& getImpl(Tuple<U...>&& tuple); +template <size_t index, typename... U> +inline const TypeByIndex<index, U...>& getImpl(const Tuple<U...>& tuple); + +template <uint index, typename T> +struct TupleElement { + // Encapsulates one element of a tuple. The actual tuple implementation multiply-inherits + // from a TupleElement for each element, which is more efficient than a recursive definition. + + T value; + TupleElement() = default; + constexpr inline TupleElement(const T& value): value(value) {} + constexpr inline TupleElement(T&& value): value(kj::mv(value)) {} +}; + +template <uint index, typename T> +struct TupleElement<index, T&> { + // If tuples contained references, one of the following would have to be true: + // - `auto x = tuple(y, z)` would cause x to be a tuple of references to y and z, which is + // probably not what you expected. + // - `Tuple<Foo&, Bar&> x = tuple(a, b)` would not work, because `tuple()` returned + // Tuple<Foo, Bar>. + static_assert(sizeof(T*) == 0, "Sorry, tuples cannot contain references."); +}; + +template <uint index, typename... T> +struct TupleElement<index, Tuple<T...>> { + static_assert(sizeof(Tuple<T...>*) == 0, + "Tuples cannot contain other tuples -- they should be flattened."); +}; + +template <typename Indexes, typename... Types> +struct TupleImpl; + +template <size_t... indexes, typename... Types> +struct TupleImpl<Indexes<indexes...>, Types...> + : public TupleElement<indexes, Types>... { + // Implementation of Tuple. The only reason we need this rather than rolling this into class + // Tuple (below) is so that we can get "indexes" as an unpackable list. + + static_assert(sizeof...(indexes) == sizeof...(Types), "Incorrect use of TupleImpl."); + + template <typename... Params> + inline TupleImpl(Params&&... params) + : TupleElement<indexes, Types>(kj::fwd<Params>(params))... { + // Work around Clang 3.2 bug 16303 where this is not detected. (Unfortunately, Clang sometimes + // segfaults instead.) + static_assert(sizeof...(params) == sizeof...(indexes), + "Wrong number of parameters to Tuple constructor."); + } + + template <typename... U> + constexpr inline TupleImpl(Tuple<U...>&& other) + : TupleElement<indexes, Types>(kj::mv(getImpl<indexes>(other)))... {} + template <typename... U> + constexpr inline TupleImpl(Tuple<U...>& other) + : TupleElement<indexes, Types>(getImpl<indexes>(other))... {} + template <typename... U> + constexpr inline TupleImpl(const Tuple<U...>& other) + : TupleElement<indexes, Types>(getImpl<indexes>(other))... {} +}; + +struct MakeTupleFunc; + +template <typename... T> +class Tuple { + // The actual Tuple class (used for tuples of size other than 1). + +public: + template <typename... U> + constexpr inline Tuple(Tuple<U...>&& other): impl(kj::mv(other)) {} + template <typename... U> + constexpr inline Tuple(Tuple<U...>& other): impl(other) {} + template <typename... U> + constexpr inline Tuple(const Tuple<U...>& other): impl(other) {} + +private: + template <typename... Params> + constexpr Tuple(Params&&... params): impl(kj::fwd<Params>(params)...) {} + + TupleImpl<MakeIndexes<sizeof...(T)>, T...> impl; + + template <size_t index, typename... U> + friend inline TypeByIndex<index, U...>& getImpl(Tuple<U...>& tuple); + template <size_t index, typename... U> + friend inline TypeByIndex<index, U...>&& getImpl(Tuple<U...>&& tuple); + template <size_t index, typename... U> + friend inline const TypeByIndex<index, U...>& getImpl(const Tuple<U...>& tuple); + friend struct MakeTupleFunc; +}; + +template <> +class Tuple<> { + // Simplified zero-member version of Tuple. In particular this is important to make sure that + // Tuple<>() is constexpr. +}; + +template <typename T> +class Tuple<T>; +// Single-element tuple should never be used. The public API should ensure this. + +template <size_t index, typename... T> +inline TypeByIndex<index, T...>& getImpl(Tuple<T...>& tuple) { + // Get member of a Tuple by index, e.g. `get<2>(myTuple)`. + static_assert(index < sizeof...(T), "Tuple element index out-of-bounds."); + return implicitCast<TupleElement<index, TypeByIndex<index, T...>>&>(tuple.impl).value; +} +template <size_t index, typename... T> +inline TypeByIndex<index, T...>&& getImpl(Tuple<T...>&& tuple) { + // Get member of a Tuple by index, e.g. `get<2>(myTuple)`. + static_assert(index < sizeof...(T), "Tuple element index out-of-bounds."); + return kj::mv(implicitCast<TupleElement<index, TypeByIndex<index, T...>>&>(tuple.impl).value); +} +template <size_t index, typename... T> +inline const TypeByIndex<index, T...>& getImpl(const Tuple<T...>& tuple) { + // Get member of a Tuple by index, e.g. `get<2>(myTuple)`. + static_assert(index < sizeof...(T), "Tuple element index out-of-bounds."); + return implicitCast<const TupleElement<index, TypeByIndex<index, T...>>&>(tuple.impl).value; +} +template <size_t index, typename T> +inline T&& getImpl(T&& value) { + // Get member of a Tuple by index, e.g. `getImpl<2>(myTuple)`. + + // Non-tuples are equivalent to one-element tuples. + static_assert(index == 0, "Tuple element index out-of-bounds."); + return kj::fwd<T>(value); +} + + +template <typename Func, typename SoFar, typename... T> +struct ExpandAndApplyResult_; +// Template which computes the return type of applying Func to T... after flattening tuples. +// SoFar starts as Tuple<> and accumulates the flattened parameter types -- so after this template +// is recursively expanded, T... is empty and SoFar is a Tuple containing all the parameters. + +template <typename Func, typename First, typename... Rest, typename... T> +struct ExpandAndApplyResult_<Func, Tuple<T...>, First, Rest...> + : public ExpandAndApplyResult_<Func, Tuple<T..., First>, Rest...> {}; +template <typename Func, typename... FirstTypes, typename... Rest, typename... T> +struct ExpandAndApplyResult_<Func, Tuple<T...>, Tuple<FirstTypes...>, Rest...> + : public ExpandAndApplyResult_<Func, Tuple<T...>, FirstTypes&&..., Rest...> {}; +template <typename Func, typename... FirstTypes, typename... Rest, typename... T> +struct ExpandAndApplyResult_<Func, Tuple<T...>, Tuple<FirstTypes...>&, Rest...> + : public ExpandAndApplyResult_<Func, Tuple<T...>, FirstTypes&..., Rest...> {}; +template <typename Func, typename... FirstTypes, typename... Rest, typename... T> +struct ExpandAndApplyResult_<Func, Tuple<T...>, const Tuple<FirstTypes...>&, Rest...> + : public ExpandAndApplyResult_<Func, Tuple<T...>, const FirstTypes&..., Rest...> {}; +template <typename Func, typename... T> +struct ExpandAndApplyResult_<Func, Tuple<T...>> { + typedef decltype(instance<Func>()(instance<T&&>()...)) Type; +}; +template <typename Func, typename... T> +using ExpandAndApplyResult = typename ExpandAndApplyResult_<Func, Tuple<>, T...>::Type; +// Computes the expected return type of `expandAndApply()`. + +template <typename Func> +inline auto expandAndApply(Func&& func) -> ExpandAndApplyResult<Func> { + return func(); +} + +template <typename Func, typename First, typename... Rest> +struct ExpandAndApplyFunc { + Func&& func; + First&& first; + ExpandAndApplyFunc(Func&& func, First&& first) + : func(kj::fwd<Func>(func)), first(kj::fwd<First>(first)) {} + template <typename... T> + auto operator()(T&&... params) + -> decltype(this->func(kj::fwd<First>(first), kj::fwd<T>(params)...)) { + return this->func(kj::fwd<First>(first), kj::fwd<T>(params)...); + } +}; + +template <typename Func, typename First, typename... Rest> +inline auto expandAndApply(Func&& func, First&& first, Rest&&... rest) + -> ExpandAndApplyResult<Func, First, Rest...> { + + return expandAndApply( + ExpandAndApplyFunc<Func, First, Rest...>(kj::fwd<Func>(func), kj::fwd<First>(first)), + kj::fwd<Rest>(rest)...); +} + +template <typename Func, typename... FirstTypes, typename... Rest> +inline auto expandAndApply(Func&& func, Tuple<FirstTypes...>&& first, Rest&&... rest) + -> ExpandAndApplyResult<Func, FirstTypes&&..., Rest...> { + return expandAndApplyWithIndexes(MakeIndexes<sizeof...(FirstTypes)>(), + kj::fwd<Func>(func), kj::mv(first), kj::fwd<Rest>(rest)...); +} + +template <typename Func, typename... FirstTypes, typename... Rest> +inline auto expandAndApply(Func&& func, Tuple<FirstTypes...>& first, Rest&&... rest) + -> ExpandAndApplyResult<Func, FirstTypes..., Rest...> { + return expandAndApplyWithIndexes(MakeIndexes<sizeof...(FirstTypes)>(), + kj::fwd<Func>(func), first, kj::fwd<Rest>(rest)...); +} + +template <typename Func, typename... FirstTypes, typename... Rest> +inline auto expandAndApply(Func&& func, const Tuple<FirstTypes...>& first, Rest&&... rest) + -> ExpandAndApplyResult<Func, FirstTypes..., Rest...> { + return expandAndApplyWithIndexes(MakeIndexes<sizeof...(FirstTypes)>(), + kj::fwd<Func>(func), first, kj::fwd<Rest>(rest)...); +} + +template <typename Func, typename... FirstTypes, typename... Rest, size_t... indexes> +inline auto expandAndApplyWithIndexes( + Indexes<indexes...>, Func&& func, Tuple<FirstTypes...>&& first, Rest&&... rest) + -> ExpandAndApplyResult<Func, FirstTypes&&..., Rest...> { + return expandAndApply(kj::fwd<Func>(func), kj::mv(getImpl<indexes>(first))..., + kj::fwd<Rest>(rest)...); +} + +template <typename Func, typename... FirstTypes, typename... Rest, size_t... indexes> +inline auto expandAndApplyWithIndexes( + Indexes<indexes...>, Func&& func, const Tuple<FirstTypes...>& first, Rest&&... rest) + -> ExpandAndApplyResult<Func, FirstTypes..., Rest...> { + return expandAndApply(kj::fwd<Func>(func), getImpl<indexes>(first)..., + kj::fwd<Rest>(rest)...); +} + +struct MakeTupleFunc { + template <typename... Params> + Tuple<Decay<Params>...> operator()(Params&&... params) { + return Tuple<Decay<Params>...>(kj::fwd<Params>(params)...); + } + template <typename Param> + Decay<Param> operator()(Param&& param) { + return kj::fwd<Param>(param); + } +}; + +} // namespace _ (private) + +template <typename... T> struct Tuple_ { typedef _::Tuple<T...> Type; }; +template <typename T> struct Tuple_<T> { typedef T Type; }; + +template <typename... T> using Tuple = typename Tuple_<T...>::Type; +// Tuple type. `Tuple<T>` (i.e. a single-element tuple) is a synonym for `T`. Tuples of size +// other than 1 expand to an internal type. Either way, you can construct a Tuple using +// `kj::tuple(...)`, get an element by index `i` using `kj::get<i>(myTuple)`, and expand the tuple +// as arguments to a function using `kj::apply(func, myTuple)`. +// +// Tuples are always flat -- that is, no element of a Tuple is ever itself a Tuple. If you +// construct a tuple from other tuples, the elements are flattened and concatenated. + +template <typename... Params> +inline auto tuple(Params&&... params) + -> decltype(_::expandAndApply(_::MakeTupleFunc(), kj::fwd<Params>(params)...)) { + // Construct a new tuple from the given values. Any tuples in the argument list will be + // flattened into the result. + return _::expandAndApply(_::MakeTupleFunc(), kj::fwd<Params>(params)...); +} + +template <size_t index, typename Tuple> +inline auto get(Tuple&& tuple) -> decltype(_::getImpl<index>(kj::fwd<Tuple>(tuple))) { + // Unpack and return the tuple element at the given index. The index is specified as a template + // parameter, e.g. `kj::get<3>(myTuple)`. + return _::getImpl<index>(kj::fwd<Tuple>(tuple)); +} + +template <typename Func, typename... Params> +inline auto apply(Func&& func, Params&&... params) + -> decltype(_::expandAndApply(kj::fwd<Func>(func), kj::fwd<Params>(params)...)) { + // Apply a function to some arguments, expanding tuples into separate arguments. + return _::expandAndApply(kj::fwd<Func>(func), kj::fwd<Params>(params)...); +} + +template <typename T> struct TupleSize_ { static constexpr size_t size = 1; }; +template <typename... T> struct TupleSize_<_::Tuple<T...>> { + static constexpr size_t size = sizeof...(T); +}; + +template <typename T> +constexpr size_t tupleSize() { return TupleSize_<T>::size; } +// Returns size of the tuple T. + +} // namespace kj + +#endif // KJ_TUPLE_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/units.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,433 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// This file contains types which are intended to help detect incorrect usage at compile +// time, but should then be optimized down to basic primitives (usually, integers) by the +// compiler. + +#ifndef KJ_UNITS_H_ +#define KJ_UNITS_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "common.h" + +namespace kj { + +// ======================================================================================= +// IDs + +template <typename UnderlyingType, typename Label> +struct Id { + // A type-safe numeric ID. `UnderlyingType` is the underlying integer representation. `Label` + // distinguishes this Id from other Id types. Sample usage: + // + // class Foo; + // typedef Id<uint, Foo> FooId; + // + // class Bar; + // typedef Id<uint, Bar> BarId; + // + // You can now use the FooId and BarId types without any possibility of accidentally using a + // FooId when you really wanted a BarId or vice-versa. + + UnderlyingType value; + + inline constexpr Id(): value(0) {} + inline constexpr explicit Id(int value): value(value) {} + + inline constexpr bool operator==(const Id& other) const { return value == other.value; } + inline constexpr bool operator!=(const Id& other) const { return value != other.value; } + inline constexpr bool operator<=(const Id& other) const { return value <= other.value; } + inline constexpr bool operator>=(const Id& other) const { return value >= other.value; } + inline constexpr bool operator< (const Id& other) const { return value < other.value; } + inline constexpr bool operator> (const Id& other) const { return value > other.value; } +}; + +// ======================================================================================= +// Quantity and UnitRatio -- implement unit analysis via the type system + +template <typename T> constexpr bool isIntegral() { return false; } +template <> constexpr bool isIntegral<char>() { return true; } +template <> constexpr bool isIntegral<signed char>() { return true; } +template <> constexpr bool isIntegral<short>() { return true; } +template <> constexpr bool isIntegral<int>() { return true; } +template <> constexpr bool isIntegral<long>() { return true; } +template <> constexpr bool isIntegral<long long>() { return true; } +template <> constexpr bool isIntegral<unsigned char>() { return true; } +template <> constexpr bool isIntegral<unsigned short>() { return true; } +template <> constexpr bool isIntegral<unsigned int>() { return true; } +template <> constexpr bool isIntegral<unsigned long>() { return true; } +template <> constexpr bool isIntegral<unsigned long long>() { return true; } + +template <typename Number, typename Unit1, typename Unit2> +class UnitRatio { + // A multiplier used to convert Quantities of one unit to Quantities of another unit. See + // Quantity, below. + // + // Construct this type by dividing one Quantity by another of a different unit. Use this type + // by multiplying it by a Quantity, or dividing a Quantity by it. + + static_assert(isIntegral<Number>(), "Underlying type for UnitRatio must be integer."); + +public: + inline UnitRatio() {} + + constexpr explicit UnitRatio(Number unit1PerUnit2): unit1PerUnit2(unit1PerUnit2) {} + // This constructor was intended to be private, but GCC complains about it being private in a + // bunch of places that don't appear to even call it, so I made it public. Oh well. + + template <typename OtherNumber> + inline constexpr UnitRatio(const UnitRatio<OtherNumber, Unit1, Unit2>& other) + : unit1PerUnit2(other.unit1PerUnit2) {} + + template <typename OtherNumber> + inline constexpr UnitRatio<decltype(Number(1)+OtherNumber(1)), Unit1, Unit2> + operator+(UnitRatio<OtherNumber, Unit1, Unit2> other) const { + return UnitRatio<decltype(Number(1)+OtherNumber(1)), Unit1, Unit2>( + unit1PerUnit2 + other.unit1PerUnit2); + } + template <typename OtherNumber> + inline constexpr UnitRatio<decltype(Number(1)-OtherNumber(1)), Unit1, Unit2> + operator-(UnitRatio<OtherNumber, Unit1, Unit2> other) const { + return UnitRatio<decltype(Number(1)-OtherNumber(1)), Unit1, Unit2>( + unit1PerUnit2 - other.unit1PerUnit2); + } + + template <typename OtherNumber, typename Unit3> + inline constexpr UnitRatio<decltype(Number(1)*OtherNumber(1)), Unit3, Unit2> + operator*(UnitRatio<OtherNumber, Unit3, Unit1> other) const { + // U1 / U2 * U3 / U1 = U3 / U2 + return UnitRatio<decltype(Number(1)*OtherNumber(1)), Unit3, Unit2>( + unit1PerUnit2 * other.unit1PerUnit2); + } + template <typename OtherNumber, typename Unit3> + inline constexpr UnitRatio<decltype(Number(1)*OtherNumber(1)), Unit1, Unit3> + operator*(UnitRatio<OtherNumber, Unit2, Unit3> other) const { + // U1 / U2 * U2 / U3 = U1 / U3 + return UnitRatio<decltype(Number(1)*OtherNumber(1)), Unit1, Unit3>( + unit1PerUnit2 * other.unit1PerUnit2); + } + + template <typename OtherNumber, typename Unit3> + inline constexpr UnitRatio<decltype(Number(1)*OtherNumber(1)), Unit3, Unit2> + operator/(UnitRatio<OtherNumber, Unit1, Unit3> other) const { + // (U1 / U2) / (U1 / U3) = U3 / U2 + return UnitRatio<decltype(Number(1)*OtherNumber(1)), Unit3, Unit2>( + unit1PerUnit2 / other.unit1PerUnit2); + } + template <typename OtherNumber, typename Unit3> + inline constexpr UnitRatio<decltype(Number(1)*OtherNumber(1)), Unit1, Unit3> + operator/(UnitRatio<OtherNumber, Unit3, Unit2> other) const { + // (U1 / U2) / (U3 / U2) = U1 / U3 + return UnitRatio<decltype(Number(1)*OtherNumber(1)), Unit1, Unit3>( + unit1PerUnit2 / other.unit1PerUnit2); + } + + template <typename OtherNumber> + inline decltype(Number(1) / OtherNumber(1)) + operator/(UnitRatio<OtherNumber, Unit1, Unit2> other) const { + return unit1PerUnit2 / other.unit1PerUnit2; + } + + inline bool operator==(UnitRatio other) const { return unit1PerUnit2 == other.unit1PerUnit2; } + inline bool operator!=(UnitRatio other) const { return unit1PerUnit2 != other.unit1PerUnit2; } + +private: + Number unit1PerUnit2; + + template <typename OtherNumber, typename OtherUnit> + friend class Quantity; + template <typename OtherNumber, typename OtherUnit1, typename OtherUnit2> + friend class UnitRatio; + + template <typename N1, typename N2, typename U1, typename U2> + friend inline constexpr UnitRatio<decltype(N1(1) * N2(1)), U1, U2> + operator*(N1, UnitRatio<N2, U1, U2>); +}; + +template <typename N1, typename N2, typename U1, typename U2> +inline constexpr UnitRatio<decltype(N1(1) * N2(1)), U1, U2> + operator*(N1 n, UnitRatio<N2, U1, U2> r) { + return UnitRatio<decltype(N1(1) * N2(1)), U1, U2>(n * r.unit1PerUnit2); +} + +template <typename Number, typename Unit> +class Quantity { + // A type-safe numeric quantity, specified in terms of some unit. Two Quantities cannot be used + // in arithmetic unless they use the same unit. The `Unit` type parameter is only used to prevent + // accidental mixing of units; this type is never instantiated and can very well be incomplete. + // `Number` is the underlying primitive numeric type. + // + // Quantities support most basic arithmetic operators, intelligently handling units, and + // automatically casting the underlying type in the same way that the compiler would. + // + // To convert a primitive number to a Quantity, multiply it by unit<Quantity<N, U>>(). + // To convert a Quantity to a primitive number, divide it by unit<Quantity<N, U>>(). + // To convert a Quantity of one unit to another unit, multiply or divide by a UnitRatio. + // + // The Quantity class is not well-suited to hardcore physics as it does not allow multiplying + // one quantity by another. For example, multiplying meters by meters won't get you square + // meters; it will get you a compiler error. It would be interesting to see if template + // metaprogramming could properly deal with such things but this isn't needed for the present + // use case. + // + // Sample usage: + // + // class SecondsLabel; + // typedef Quantity<double, SecondsLabel> Seconds; + // constexpr Seconds SECONDS = unit<Seconds>(); + // + // class MinutesLabel; + // typedef Quantity<double, MinutesLabel> Minutes; + // constexpr Minutes MINUTES = unit<Minutes>(); + // + // constexpr UnitRatio<double, SecondsLabel, MinutesLabel> SECONDS_PER_MINUTE = + // 60 * SECONDS / MINUTES; + // + // void waitFor(Seconds seconds) { + // sleep(seconds / SECONDS); + // } + // void waitFor(Minutes minutes) { + // waitFor(minutes * SECONDS_PER_MINUTE); + // } + // + // void waitThreeMinutes() { + // waitFor(3 * MINUTES); + // } + + static_assert(isIntegral<Number>(), "Underlying type for Quantity must be integer."); + +public: + inline constexpr Quantity() {} + + inline constexpr Quantity(MaxValue_): value(maxValue) {} + inline constexpr Quantity(MinValue_): value(minValue) {} + // Allow initialization from maxValue and minValue. + // TODO(msvc): decltype(maxValue) and decltype(minValue) deduce unknown-type for these function + // parameters, causing the compiler to complain of a duplicate constructor definition, so we + // specify MaxValue_ and MinValue_ types explicitly. + + inline explicit constexpr Quantity(Number value): value(value) {} + // This constructor was intended to be private, but GCC complains about it being private in a + // bunch of places that don't appear to even call it, so I made it public. Oh well. + + template <typename OtherNumber> + inline constexpr Quantity(const Quantity<OtherNumber, Unit>& other) + : value(other.value) {} + + template <typename OtherNumber> + inline constexpr Quantity<decltype(Number(1) + OtherNumber(1)), Unit> + operator+(const Quantity<OtherNumber, Unit>& other) const { + return Quantity<decltype(Number(1) + OtherNumber(1)), Unit>(value + other.value); + } + template <typename OtherNumber> + inline constexpr Quantity<decltype(Number(1) - OtherNumber(1)), Unit> + operator-(const Quantity<OtherNumber, Unit>& other) const { + return Quantity<decltype(Number(1) - OtherNumber(1)), Unit>(value - other.value); + } + template <typename OtherNumber> + inline constexpr Quantity<decltype(Number(1) * OtherNumber(1)), Unit> + operator*(OtherNumber other) const { + static_assert(isIntegral<OtherNumber>(), "Multiplied Quantity by non-integer."); + return Quantity<decltype(Number(1) * other), Unit>(value * other); + } + template <typename OtherNumber> + inline constexpr Quantity<decltype(Number(1) / OtherNumber(1)), Unit> + operator/(OtherNumber other) const { + static_assert(isIntegral<OtherNumber>(), "Divided Quantity by non-integer."); + return Quantity<decltype(Number(1) / other), Unit>(value / other); + } + template <typename OtherNumber> + inline constexpr decltype(Number(1) / OtherNumber(1)) + operator/(const Quantity<OtherNumber, Unit>& other) const { + return value / other.value; + } + template <typename OtherNumber> + inline constexpr decltype(Number(1) % OtherNumber(1)) + operator%(const Quantity<OtherNumber, Unit>& other) const { + return value % other.value; + } + + template <typename OtherNumber, typename OtherUnit> + inline constexpr Quantity<decltype(Number(1) * OtherNumber(1)), OtherUnit> + operator*(const UnitRatio<OtherNumber, OtherUnit, Unit>& ratio) const { + return Quantity<decltype(Number(1) * OtherNumber(1)), OtherUnit>( + value * ratio.unit1PerUnit2); + } + template <typename OtherNumber, typename OtherUnit> + inline constexpr Quantity<decltype(Number(1) / OtherNumber(1)), OtherUnit> + operator/(const UnitRatio<OtherNumber, Unit, OtherUnit>& ratio) const { + return Quantity<decltype(Number(1) / OtherNumber(1)), OtherUnit>( + value / ratio.unit1PerUnit2); + } + template <typename OtherNumber, typename OtherUnit> + inline constexpr Quantity<decltype(Number(1) % OtherNumber(1)), Unit> + operator%(const UnitRatio<OtherNumber, Unit, OtherUnit>& ratio) const { + return Quantity<decltype(Number(1) % OtherNumber(1)), Unit>( + value % ratio.unit1PerUnit2); + } + template <typename OtherNumber, typename OtherUnit> + inline constexpr UnitRatio<decltype(Number(1) / OtherNumber(1)), Unit, OtherUnit> + operator/(const Quantity<OtherNumber, OtherUnit>& other) const { + return UnitRatio<decltype(Number(1) / OtherNumber(1)), Unit, OtherUnit>(value / other.value); + } + + template <typename OtherNumber> + inline constexpr bool operator==(const Quantity<OtherNumber, Unit>& other) const { + return value == other.value; + } + template <typename OtherNumber> + inline constexpr bool operator!=(const Quantity<OtherNumber, Unit>& other) const { + return value != other.value; + } + template <typename OtherNumber> + inline constexpr bool operator<=(const Quantity<OtherNumber, Unit>& other) const { + return value <= other.value; + } + template <typename OtherNumber> + inline constexpr bool operator>=(const Quantity<OtherNumber, Unit>& other) const { + return value >= other.value; + } + template <typename OtherNumber> + inline constexpr bool operator<(const Quantity<OtherNumber, Unit>& other) const { + return value < other.value; + } + template <typename OtherNumber> + inline constexpr bool operator>(const Quantity<OtherNumber, Unit>& other) const { + return value > other.value; + } + + template <typename OtherNumber> + inline Quantity& operator+=(const Quantity<OtherNumber, Unit>& other) { + value += other.value; + return *this; + } + template <typename OtherNumber> + inline Quantity& operator-=(const Quantity<OtherNumber, Unit>& other) { + value -= other.value; + return *this; + } + template <typename OtherNumber> + inline Quantity& operator*=(OtherNumber other) { + value *= other; + return *this; + } + template <typename OtherNumber> + inline Quantity& operator/=(OtherNumber other) { + value /= other.value; + return *this; + } + +private: + Number value; + + template <typename OtherNumber, typename OtherUnit> + friend class Quantity; + + template <typename Number1, typename Number2, typename Unit2> + friend inline constexpr auto operator*(Number1 a, Quantity<Number2, Unit2> b) + -> Quantity<decltype(Number1(1) * Number2(1)), Unit2>; + + template <typename T> + friend inline constexpr T unit(); +}; + +template <typename T> +inline constexpr T unit() { return T(1); } +// unit<Quantity<T, U>>() returns a Quantity of value 1. It also, intentionally, works on basic +// numeric types. + +template <typename Number1, typename Number2, typename Unit> +inline constexpr auto operator*(Number1 a, Quantity<Number2, Unit> b) + -> Quantity<decltype(Number1(1) * Number2(1)), Unit> { + return Quantity<decltype(Number1(1) * Number2(1)), Unit>(a * b.value); +} + +template <typename Number1, typename Number2, typename Unit, typename Unit2> +inline constexpr auto operator*(UnitRatio<Number1, Unit2, Unit> ratio, + Quantity<Number2, Unit> measure) + -> decltype(measure * ratio) { + return measure * ratio; +} + +// ======================================================================================= +// Absolute measures + +template <typename T, typename Label> +class Absolute { + // Wraps some other value -- typically a Quantity -- but represents a value measured based on + // some absolute origin. For example, if `Duration` is a type representing a time duration, + // Absolute<Duration, UnixEpoch> might be a calendar date. + // + // Since Absolute represents measurements relative to some arbitrary origin, the only sensible + // arithmetic to perform on them is addition and subtraction. + + // TODO(someday): Do the same automatic expansion of integer width that Quantity does? Doesn't + // matter for our time use case, where we always use 64-bit anyway. Note that fixing this + // would implicitly allow things like multiplying an Absolute by a UnitRatio to change its + // units, which is actually totally logical and kind of neat. + +public: + inline constexpr Absolute operator+(const T& other) const { return Absolute(value + other); } + inline constexpr Absolute operator-(const T& other) const { return Absolute(value - other); } + inline constexpr T operator-(const Absolute& other) const { return value - other.value; } + + inline Absolute& operator+=(const T& other) { value += other; return *this; } + inline Absolute& operator-=(const T& other) { value -= other; return *this; } + + inline constexpr bool operator==(const Absolute& other) const { return value == other.value; } + inline constexpr bool operator!=(const Absolute& other) const { return value != other.value; } + inline constexpr bool operator<=(const Absolute& other) const { return value <= other.value; } + inline constexpr bool operator>=(const Absolute& other) const { return value >= other.value; } + inline constexpr bool operator< (const Absolute& other) const { return value < other.value; } + inline constexpr bool operator> (const Absolute& other) const { return value > other.value; } + +private: + T value; + + explicit constexpr Absolute(T value): value(value) {} + + template <typename U> + friend inline constexpr U origin(); +}; + +template <typename T, typename Label> +inline constexpr Absolute<T, Label> operator+(const T& a, const Absolute<T, Label>& b) { + return b + a; +} + +template <typename T> struct UnitOf_ { typedef T Type; }; +template <typename T, typename Label> struct UnitOf_<Absolute<T, Label>> { typedef T Type; }; +template <typename T> +using UnitOf = typename UnitOf_<T>::Type; +// UnitOf<Absolute<T, U>> is T. UnitOf<AnythingElse> is AnythingElse. + +template <typename T> +inline constexpr T origin() { return T(0 * unit<UnitOf<T>>()); } +// origin<Absolute<T, U>>() returns an Absolute of value 0. It also, intentionally, works on basic +// numeric types. + +} // namespace kj + +#endif // KJ_UNITS_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/vector.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,145 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef KJ_VECTOR_H_ +#define KJ_VECTOR_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#include "array.h" + +namespace kj { + +template <typename T> +class Vector { + // Similar to std::vector, but based on KJ framework. + // + // This implementation always uses move constructors when growing the backing array. If the + // move constructor throws, the Vector is left in an inconsistent state. This is acceptable + // under KJ exception theory which assumes that exceptions leave things in inconsistent states. + + // TODO(someday): Allow specifying a custom allocator. + +public: + inline Vector() = default; + inline explicit Vector(size_t capacity): builder(heapArrayBuilder<T>(capacity)) {} + + inline operator ArrayPtr<T>() { return builder; } + inline operator ArrayPtr<const T>() const { return builder; } + inline ArrayPtr<T> asPtr() { return builder.asPtr(); } + inline ArrayPtr<const T> asPtr() const { return builder.asPtr(); } + + inline size_t size() const { return builder.size(); } + inline bool empty() const { return size() == 0; } + inline size_t capacity() const { return builder.capacity(); } + inline T& operator[](size_t index) const { return builder[index]; } + + inline const T* begin() const { return builder.begin(); } + inline const T* end() const { return builder.end(); } + inline const T& front() const { return builder.front(); } + inline const T& back() const { return builder.back(); } + inline T* begin() { return builder.begin(); } + inline T* end() { return builder.end(); } + inline T& front() { return builder.front(); } + inline T& back() { return builder.back(); } + + inline Array<T> releaseAsArray() { + // TODO(perf): Avoid a copy/move by allowing Array<T> to point to incomplete space? + if (!builder.isFull()) { + setCapacity(size()); + } + return builder.finish(); + } + + template <typename... Params> + inline T& add(Params&&... params) { + if (builder.isFull()) grow(); + return builder.add(kj::fwd<Params>(params)...); + } + + template <typename Iterator> + inline void addAll(Iterator begin, Iterator end) { + size_t needed = builder.size() + (end - begin); + if (needed > builder.capacity()) grow(needed); + builder.addAll(begin, end); + } + + template <typename Container> + inline void addAll(Container&& container) { + addAll(container.begin(), container.end()); + } + + inline void removeLast() { + builder.removeLast(); + } + + inline void resize(size_t size) { + if (size > builder.capacity()) grow(size); + while (builder.size() < size) { + builder.add(T()); + } + while (builder.size() > size) { + builder.removeLast(); + } + } + + inline void operator=(decltype(nullptr)) { + builder = nullptr; + } + + inline void clear() { + while (builder.size() > 0) { + builder.removeLast(); + } + } + + inline void truncate(size_t size) { + while (builder.size() > size) { + builder.removeLast(); + } + } + +private: + ArrayBuilder<T> builder; + + void grow(size_t minCapacity = 0) { + setCapacity(kj::max(minCapacity, capacity() == 0 ? 4 : capacity() * 2)); + } + void setCapacity(size_t newSize) { + ArrayBuilder<T> newBuilder = heapArrayBuilder<T>(newSize); + size_t moveCount = kj::min(newSize, builder.size()); + for (size_t i = 0; i < moveCount; i++) { + newBuilder.add(kj::mv(builder[i])); + } + builder = kj::mv(newBuilder); + } +}; + +template <typename T> +inline auto KJ_STRINGIFY(const Vector<T>& v) -> decltype(toCharSequence(v.asPtr())) { + return toCharSequence(v.asPtr()); +} + +} // namespace kj + +#endif // KJ_VECTOR_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/kj/windows-sanity.h Wed Oct 26 13:18:45 2016 +0100 @@ -0,0 +1,41 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef KJ_WINDOWS_SANITY_H_ +#define KJ_WINDOWS_SANITY_H_ + +#if defined(__GNUC__) && !KJ_HEADER_WARNINGS +#pragma GCC system_header +#endif + +#ifndef _INC_WINDOWS +#error "windows.h needs to be included before kj/windows-sanity.h (or perhaps you don't need either?)" +#endif + +namespace win32 { + const auto ERROR_ = ERROR; +#undef ERROR + const auto ERROR = ERROR_; +} + +using win32::ERROR; + +#endif // KJ_WINDOWS_SANITY_H_