Commit c772a700 authored by Kenton Varda's avatar Kenton Varda

Implement "lite mode", where reflection is disabled.

To use, pass --disable-reflection to the configure script.

This produces a smaller runtime library. However, using it for this purpose is not recommended. The main purpose of lite mode is to define a subset of Cap'n Proto which might plausibly compile under MSVC. MSVC still lacks full support for constexpr and expression SFINAE; luckily, most of our use of these things relates to reflection, and not all users need reflection.

Cap'n Proto lite mode inherits its name from Protocol Buffers' lite mode. However, there are some key differences:

- Protobuf generated code included global constructors related to registering descriptors and extensions. For many people, this was the main reason to use lite mode: to get rid of these global constructors and achieve faster startup times. Cap'n Proto, on the other hand, never had global constructors in the first place.

- Schemas are actually still available in lite mode, though only in their raw (Cap'n Proto structure) form. Only the schema API (which wraps the raw schemas in a more convenient interface) and reflection API (which offers a convenient way to use the schemas) are unavailable.

- Lite mode is enabled in an application by defining CAPNP_LITE rather than by specifying an annotation in the schema file. This better-reflects real-world usage patterns, where you typically want to enable lite mode application-wide anyway.

- We do not build the lite mode library by default. You must request it by passing --disable-reflection to the configure script. Before you can do that, you must have a prebuilt Cap'n Proto compiler binary available, since the compiler can't be built without reflection.

- Relatedly, the lite mode library is built with the same name as the full library. This library is not intended to be installed. If anything it should be statically linked. But, mostly the option only exists on non-MSVC platform to give us a way to test that we haven't broken lite mode.
parent f8b7a398
......@@ -163,6 +163,7 @@ includecapnp_HEADERS = \
src/capnp/message.h \
src/capnp/capability.h \
src/capnp/schema.capnp.h \
src/capnp/schema-lite.h \
src/capnp/schema.h \
src/capnp/schema-loader.h \
src/capnp/schema-parser.h \
......@@ -180,7 +181,11 @@ includecapnp_HEADERS = \
src/capnp/rpc-twoparty.capnp.h \
src/capnp/ez-rpc.h
if LITE_MODE
lib_LTLIBRARIES = libkj.la libcapnp.la
else
lib_LTLIBRARIES = libkj.la libkj-async.la libcapnp.la libcapnp-rpc.la libcapnpc.la
endif
# -lpthread is here to work around https://bugzilla.redhat.com/show_bug.cgi?id=661333
libkj_la_LIBADD = $(PTHREAD_LIBS) -lpthread
......@@ -202,6 +207,7 @@ libkj_la_SOURCES= \
src/kj/main.c++ \
src/kj/parse/char.c++
if !LITE_MODE
# -lpthread is here to work around https://bugzilla.redhat.com/show_bug.cgi?id=661333
libkj_async_la_LIBADD = libkj.la $(PTHREAD_LIBS) -lpthread
libkj_async_la_LDFLAGS = -release $(VERSION) -no-undefined
......@@ -209,6 +215,15 @@ libkj_async_la_SOURCES= \
src/kj/async.c++ \
src/kj/async-unix.c++ \
src/kj/async-io.c++
endif !LITE_MODE
if !LITE_MODE
heavy_sources = \
src/capnp/schema.c++ \
src/capnp/schema-loader.c++ \
src/capnp/dynamic.c++ \
src/capnp/stringify.c++
endif !LITE_MODE
# -lpthread is here to work around https://bugzilla.redhat.com/show_bug.cgi?id=661333
libcapnp_la_LIBADD = libkj.la $(PTHREAD_LIBS) -lpthread
......@@ -223,12 +238,11 @@ libcapnp_la_SOURCES= \
src/capnp/any.c++ \
src/capnp/message.c++ \
src/capnp/schema.capnp.c++ \
src/capnp/schema.c++ \
src/capnp/schema-loader.c++ \
src/capnp/dynamic.c++ \
src/capnp/stringify.c++ \
src/capnp/serialize.c++ \
src/capnp/serialize-packed.c++
src/capnp/serialize-packed.c++ \
$(heavy_sources)
if !LITE_MODE
# -lpthread is here to work around https://bugzilla.redhat.com/show_bug.cgi?id=661333
libcapnp_rpc_la_LIBADD = libcapnp.la libkj-async.la libkj.la $(PTHREAD_LIBS) -lpthread
......@@ -279,6 +293,8 @@ capnpc_capnp_SOURCES = src/capnp/compiler/capnpc-capnp.c++
capnpc_c___LDADD = libcapnp.la libkj.la $(PTHREAD_LIBS)
capnpc_c___SOURCES = src/capnp/compiler/capnpc-c++.c++
endif !LITE_MODE
# Symlink capnpc -> capnp. The capnp binary will behave like the old capnpc
# binary (i.e. like "capnp compile") when invoked via this symlink.
#
......@@ -330,9 +346,38 @@ $(test_capnpc_outputs): test_capnpc_middleman
BUILT_SOURCES = $(test_capnpc_outputs)
if LITE_MODE
check_PROGRAMS = capnp-test
compiler_tests =
capnp_test_LDADD = gtest/lib/libgtest.la gtest/lib/libgtest_main.la \
libcapnp.la libkj.la
else !LITE_MODE
check_PROGRAMS = capnp-test capnp-evolution-test
heavy_tests = \
src/kj/async-test.c++ \
src/kj/async-unix-test.c++ \
src/kj/async-io-test.c++ \
src/kj/parse/common-test.c++ \
src/kj/parse/char-test.c++ \
src/capnp/capability-test.c++ \
src/capnp/schema-test.c++ \
src/capnp/schema-loader-test.c++ \
src/capnp/dynamic-test.c++ \
src/capnp/stringify-test.c++ \
src/capnp/serialize-async-test.c++ \
src/capnp/rpc-test.c++ \
src/capnp/rpc-twoparty-test.c++ \
src/capnp/ez-rpc-test.c++ \
src/capnp/compiler/lexer-test.c++ \
src/capnp/compiler/md5-test.c++
capnp_test_LDADD = gtest/lib/libgtest.la gtest/lib/libgtest_main.la \
libcapnpc.la libcapnp-rpc.la libcapnp.la libkj-async.la libkj.la
endif !LITE_MODE
capnp_test_CPPFLAGS = -Wno-deprecated-declarations -Igtest/include -I$(srcdir)/gtest/include
capnp_test_SOURCES = \
src/kj/common-test.c++ \
......@@ -352,11 +397,6 @@ capnp_test_SOURCES = \
src/kj/mutex-test.c++ \
src/kj/threadlocal-test.c++ \
src/kj/threadlocal-pthread-test.c++ \
src/kj/async-test.c++ \
src/kj/async-unix-test.c++ \
src/kj/async-io-test.c++ \
src/kj/parse/common-test.c++ \
src/kj/parse/char-test.c++ \
src/capnp/common-test.c++ \
src/capnp/blob-test.c++ \
src/capnp/endian-test.c++ \
......@@ -365,26 +405,22 @@ capnp_test_SOURCES = \
src/capnp/layout-test.c++ \
src/capnp/any-test.c++ \
src/capnp/message-test.c++ \
src/capnp/capability-test.c++ \
src/capnp/schema-test.c++ \
src/capnp/schema-loader-test.c++ \
src/capnp/dynamic-test.c++ \
src/capnp/stringify-test.c++ \
src/capnp/encoding-test.c++ \
src/capnp/orphan-test.c++ \
src/capnp/serialize-test.c++ \
src/capnp/serialize-async-test.c++ \
src/capnp/serialize-packed-test.c++ \
src/capnp/rpc-test.c++ \
src/capnp/rpc-twoparty-test.c++ \
src/capnp/ez-rpc-test.c++ \
src/capnp/test-util.c++ \
src/capnp/test-util.h \
src/capnp/compiler/lexer-test.c++ \
src/capnp/compiler/md5-test.c++
$(heavy_tests)
nodist_capnp_test_SOURCES = $(test_capnpc_outputs)
if !LITE_MODE
capnp_evolution_test_LDADD = libcapnpc.la libcapnp.la libkj.la
capnp_evolution_test_SOURCES = src/capnp/compiler/evolution-test.c++
endif !LITE_MODE
if LITE_MODE
TESTS = capnp-test
else !LITE_MODE
TESTS = capnp-test capnp-evolution-test src/capnp/compiler/capnp-test.sh
endif !LITE_MODE
......@@ -8,4 +8,4 @@ Description: Insanely fast serialization system
Version: @VERSION@
Libs: -L${libdir} -lcapnp -lkj @PTHREAD_CFLAGS@ @PTHREAD_LIBS@ @STDLIB_FLAG@
Libs.private: @LIBS@
Cflags: -I${includedir} @PTHREAD_CFLAGS@ @STDLIB_FLAG@
Cflags: -I${includedir} @PTHREAD_CFLAGS@ @STDLIB_FLAG@ @CAPNP_LITE_FLAG@
......@@ -22,6 +22,30 @@ AC_ARG_WITH([external-capnp],
one (useful for cross-compiling)])],
[external_capnp=yes],[external_capnp=no])
AC_ARG_ENABLE([reflection], [
AS_HELP_STRING([--disable-reflection], [
compile Cap'n Proto in "lite mode", in which all reflection APIs (schema.h, dynamic.h, etc.)
are not included. Produces a smaller library at the cost of features. All programs built
against the library MUST be compiled with -DCAPNP_LITE=1. Note that because the compiler
itself uses reflection in its implementation, you must also use --with-external-capnp when
using this option.])
], [
case "${enableval}" in
yes)
lite_mode=no
;;
no)
lite_mode=yes
AS_IF([test "$external_capnp" != "yes"], [
AC_MSG_ERROR([you must specify --with-external-capnp when using --disable-reflection])
])
;;
*)
AC_MSG_ERROR([bad value ${enableval} for --enable-reflection])
;;
esac
], [lite_mode=no])
# Checks for programs.
AC_PROG_CC
AC_PROG_CXX
......@@ -48,6 +72,14 @@ AS_IF([test "$external_capnp" != "no"], [
])
AM_CONDITIONAL([USE_EXTERNAL_CAPNP], [test "$external_capnp" != "no"])
AM_CONDITIONAL([LITE_MODE], [test "$lite_mode" = "yes"])
AS_IF([test "$lite_mode" = "yes"], [
CXXFLAGS="-DCAPNP_LITE $CXXFLAGS"
CAPNP_LITE_FLAG=-DCAPNP_LITE
])
AC_SUBST([CAPNP_LITE_FLAG])
AC_SEARCH_LIBS(sched_yield, rt)
# Users will need to use the same -stdlib as us so we'd better let pkg-config know about it.
......
......@@ -95,6 +95,7 @@ set(capnp_headers
capnp/message.h
capnp/capability.h
capnp/schema.capnp.h
capnp/schema-lite.h
capnp/schema.h
capnp/schema-loader.h
capnp/schema-parser.h
......
......@@ -20,10 +20,15 @@
// THE SOFTWARE.
#include "any.h"
#if !CAPNP_LITE
#include "capability.h"
#endif // !CAPNP_LITE
namespace capnp {
#if !CAPNP_LITE
kj::Own<ClientHook> PipelineHook::getPipelinedCap(kj::Array<PipelineOp>&& ops) {
return getPipelinedCap(ops.asPtr());
}
......@@ -70,4 +75,6 @@ kj::Own<ClientHook> AnyPointer::Pipeline::asCap() {
return hook->getPipelinedCap(ops);
}
#endif // !CAPNP_LITE
} // namespace capnp
......@@ -71,9 +71,11 @@ struct AnyPointer {
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;
......@@ -181,6 +183,7 @@ struct AnyPointer {
friend class CapBuilderContext;
};
#if !CAPNP_LITE
class Pipeline {
public:
inline Pipeline(decltype(nullptr)) {}
......@@ -212,6 +215,7 @@ struct AnyPointer {
friend class LocalClient;
friend class PipelineHook;
};
#endif // !CAPNP_LITE
};
template <>
......@@ -284,6 +288,8 @@ private:
// 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.
......@@ -320,6 +326,8 @@ public:
}
};
#endif // !CAPNP_LITE
// =======================================================================================
// Inline implementation details
......
......@@ -22,13 +22,16 @@
#define CAPNP_PRIVATE
#include "arena.h"
#include "message.h"
#include "capability.h"
#include <kj/debug.h>
#include <kj/refcount.h>
#include <vector>
#include <string.h>
#include <stdio.h>
#if !CAPNP_LITE
#include "capability.h"
#endif // !CAPNP_LITE
namespace capnp {
namespace _ { // private
......@@ -105,6 +108,7 @@ void ReaderArena::reportReadLimitReached() {
}
}
#if !CAPNP_LITE
kj::Maybe<kj::Own<ClientHook>> ReaderArena::extractCap(uint index) {
if (index < capTable.size()) {
return capTable[index].map([](kj::Own<ClientHook>& cap) { return cap->addRef(); });
......@@ -112,6 +116,7 @@ kj::Maybe<kj::Own<ClientHook>> ReaderArena::extractCap(uint index) {
return nullptr;
}
}
#endif // !CAPNP_LITE
// =======================================================================================
......@@ -261,6 +266,7 @@ void BuilderArena::reportReadLimitReached() {
}
}
#if !CAPNP_LITE
kj::Maybe<kj::Own<ClientHook>> BuilderArena::extractCap(uint index) {
if (index < capTable.size()) {
return capTable[index].map([](kj::Own<ClientHook>& cap) { return cap->addRef(); });
......@@ -283,6 +289,7 @@ void BuilderArena::dropCap(uint index) {
}
capTable[index] = nullptr;
}
#endif // !CAPNP_LITE
} // namespace _ (private)
} // namespace capnp
......@@ -34,11 +34,16 @@
#include "common.h"
#include "message.h"
#include "layout.h"
#if !CAPNP_LITE
#include "capability.h"
#endif // !CAPNP_LITE
namespace capnp {
#if !CAPNP_LITE
class ClientHook;
#endif // !CAPNP_LITE
namespace _ { // private
......@@ -91,6 +96,7 @@ private:
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.
......@@ -98,6 +104,7 @@ class BrokenCapFactory {
public:
virtual kj::Own<ClientHook> newBrokenCap(kj::StringPtr description) = 0;
};
#endif // !CAPNP_LITE
class SegmentReader {
public:
......@@ -183,8 +190,10 @@ public:
// the VALIDATE_INPUT() macro which may throw an exception; if it returns normally, the caller
// will need to continue with default values.
#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 ReaderArena final: public Arena {
......@@ -193,22 +202,28 @@ public:
~ReaderArena() noexcept(false);
KJ_DISALLOW_COPY(ReaderArena);
#if !CAPNP_LITE
inline void initCapTable(kj::Array<kj::Maybe<kj::Own<ClientHook>>> capTable) {
// Imbues the arena with a capability table. This is not passed to the constructor because the
// table itself may be built based on some other part of the message (as is the case with the
// RPC protocol).
this->capTable = kj::mv(capTable);
}
#endif // !CAPNP_LITE
// implements Arena ------------------------------------------------
SegmentReader* tryGetSegment(SegmentId id) override;
void reportReadLimitReached() override;
#if !CAPNP_LITE
kj::Maybe<kj::Own<ClientHook>> extractCap(uint index);
#endif // !CAPNP_LITE
private:
MessageReader* message;
ReadLimiter readLimiter;
#if !CAPNP_LITE
kj::Array<kj::Maybe<kj::Own<ClientHook>>> capTable;
#endif // !CAPNP_LITE
// Optimize for single-segment messages so that small messages are handled quickly.
SegmentReader segment0;
......@@ -239,8 +254,10 @@ public:
// portion of each segment, whereas tryGetSegment() returns something that includes
// not-yet-allocated space.
#if !CAPNP_LITE
inline kj::ArrayPtr<kj::Maybe<kj::Own<ClientHook>>> getCapTable() { return capTable; }
// Return the capability table.
#endif // !CAPNP_LITE
SegmentBuilder* getSegment(SegmentId id);
// Get the segment with the given id. Crashes or throws an exception if no such segment exists.
......@@ -267,10 +284,12 @@ public:
// from disk (until the message itself is written out). `Orphanage` provides the public API for
// this feature.
#if !CAPNP_LITE
uint injectCap(kj::Own<ClientHook>&& cap);
// 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.
#endif // !CAPNP_LITE
void dropCap(uint index);
// Remove a capability injected earlier. Called when the pointer is overwritten or zero'd out.
......@@ -278,12 +297,16 @@ public:
// implements Arena ------------------------------------------------
SegmentReader* tryGetSegment(SegmentId id) override;
void reportReadLimitReached() override;
#if !CAPNP_LITE
kj::Maybe<kj::Own<ClientHook>> extractCap(uint index);
#endif // !CAPNP_LITE
private:
MessageBuilder* message;
ReadLimiter dummyLimiter;
#if !CAPNP_LITE
kj::Vector<kj::Maybe<kj::Own<ClientHook>>> capTable;
#endif // !CAPNP_LITE
SegmentBuilder segment0;
kj::ArrayPtr<const word> segment0ForOutput;
......
......@@ -28,12 +28,15 @@ static const ::capnp::_::AlignedData<21> b_b9c6f99ebf805f2c = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, }
};
::capnp::word const* const bp_b9c6f99ebf805f2c = b_b9c6f99ebf805f2c.words;
#if !CAPNP_LITE
const ::capnp::_::RawBrandedSchema::Dependency bd_b9c6f99ebf805f2c[] = {
};
const ::capnp::_::RawSchema s_b9c6f99ebf805f2c = {
0xb9c6f99ebf805f2c, b_b9c6f99ebf805f2c.words, 21, nullptr, nullptr,
0, 0, nullptr, nullptr, nullptr, { &s_b9c6f99ebf805f2c, nullptr, bd_b9c6f99ebf805f2c, 0, sizeof(bd_b9c6f99ebf805f2c) / sizeof(bd_b9c6f99ebf805f2c[0]), nullptr }
};
#endif // !CAPNP_LITE
static const ::capnp::_::AlignedData<20> b_f264a779fef191ce = {
{ 0, 0, 0, 0, 5, 0, 6, 0,
206, 145, 241, 254, 121, 167, 100, 242,
......@@ -56,11 +59,14 @@ static const ::capnp::_::AlignedData<20> b_f264a779fef191ce = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, }
};
::capnp::word const* const bp_f264a779fef191ce = b_f264a779fef191ce.words;
#if !CAPNP_LITE
const ::capnp::_::RawBrandedSchema::Dependency bd_f264a779fef191ce[] = {
};
const ::capnp::_::RawSchema s_f264a779fef191ce = {
0xf264a779fef191ce, b_f264a779fef191ce.words, 20, nullptr, nullptr,
0, 0, nullptr, nullptr, nullptr, { &s_f264a779fef191ce, nullptr, bd_f264a779fef191ce, 0, sizeof(bd_f264a779fef191ce) / sizeof(bd_f264a779fef191ce[0]), nullptr }
};
#endif // !CAPNP_LITE
} // namespace schemas
} // namespace capnp
......@@ -14,8 +14,8 @@
namespace capnp {
namespace schemas {
extern const ::capnp::_::RawSchema s_b9c6f99ebf805f2c;
extern const ::capnp::_::RawSchema s_f264a779fef191ce;
CAPNP_DECLARE_SCHEMA(b9c6f99ebf805f2c);
CAPNP_DECLARE_SCHEMA(f264a779fef191ce);
} // namespace schemas
} // namespace capnp
......
......@@ -22,6 +22,10 @@
#ifndef CAPNP_CAPABILITY_H_
#define CAPNP_CAPABILITY_H_
#if CAPNP_LITE
#error "RPC APIs, including this header, are not available in lite mode."
#endif
#include <kj/async.h>
#include "any.h"
#include "pointer-helpers.h"
......@@ -67,6 +71,7 @@ struct Capability {
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;
......
......@@ -45,5 +45,19 @@ TEST(Common, Version) {
#endif
}
struct ExampleStruct {
struct _capnpPrivate {
struct IsStruct;
};
};
struct ExampleInterface {
struct _capnpPrivate {
struct IsInterface;
};
};
static_assert(_::Kind_<ExampleStruct>::kind == Kind::STRUCT, "Kind SFINAE failed.");
static_assert(_::Kind_<ExampleInterface>::kind == Kind::INTERFACE, "Kind SFINAE failed.");
} // namespace
} // namespace capnp
......@@ -38,6 +38,11 @@ namespace capnp {
#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
typedef unsigned int uint;
struct Void {
......@@ -80,7 +85,12 @@ struct EnumInfo;
namespace _ { // private
template <typename T> struct Kind_;
template <typename T, typename = typename T::_capnpPrivate::IsStruct> uint8_t kindSfinae(int);
template <typename T, typename = typename T::_capnpPrivate::IsInterface> uint16_t kindSfinae(int);
template <typename T, typename = typename schemas::EnumInfo<T>::IsEnum> uint32_t kindSfinae(int);
template <typename T> uint64_t kindSfinae(...);
template <typename T, size_t s = sizeof(kindSfinae<T>(0))> struct Kind_;
template <> struct Kind_<Void> { static constexpr Kind kind = Kind::PRIMITIVE; };
template <> struct Kind_<bool> { static constexpr Kind kind = Kind::PRIMITIVE; };
......@@ -97,8 +107,19 @@ 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, sizeof(uint8_t)> { static constexpr Kind kind = Kind::STRUCT; };
template <typename T> struct Kind_<T, sizeof(uint16_t)> { static constexpr Kind kind = Kind::INTERFACE; };
template <typename T> struct Kind_<T, sizeof(uint32_t)> { static constexpr Kind kind = Kind::ENUM; };
} // namespace _ (private)
#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
template <typename T, Kind k = _::Kind_<T>::kind>
inline constexpr Kind kind() {
// This overload of kind() matches types which have a Kind_ specialization.
......@@ -106,22 +127,12 @@ inline constexpr Kind kind() {
return k;
}
template <typename T, typename CapnpPrivate = typename T::_capnpPrivate, bool = false>
inline constexpr Kind kind() {
// This overload of kind() matches types which have a _capnpPrivate member. This is how
// generated-code types identify themselves. This is necessary because in the presence of
// generics, a generated type may be an inner type of a template, in which case it is impossible
// to specialize _::Kind_<T> over it.
return CapnpPrivate::kind;
}
#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, uint64_t id = schemas::EnumInfo<T>::typeId>
inline constexpr Kind kind() {
return Kind::ENUM;
}
#endif // CAPNP_LITE, else
template <typename T, Kind k = kind<T>()>
template <typename T, Kind k = CAPNP_KIND(T)>
struct List;
template <typename T> struct ListElementType_;
......@@ -129,28 +140,30 @@ 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; };
template <typename T, Kind k> struct Kind_<List<T, k>, sizeof(uint64_t)> {
static constexpr Kind kind = Kind::LIST;
};
} // namespace _ (private)
template <typename T, Kind k = kind<T>()> struct ReaderFor_ { typedef typename T::Reader Type; };
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 = kind<T>()> struct BuilderFor_ { typedef typename T::Builder Type; };
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 = kind<T>()> struct PipelineFor_ { typedef typename T::Pipeline Type;};
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 = kind<T>()> struct TypeIfEnum_;
template <typename T, Kind k = CAPNP_KIND(T)> struct TypeIfEnum_;
template <typename T> struct TypeIfEnum_<T, Kind::ENUM> { typedef T Type; };
template <typename T>
......@@ -173,7 +186,7 @@ using FromServer = typename kj::Decay<T>::Serves;
// FromBuilder<MyType::Server> = MyType (for any Cap'n Proto interface type).
namespace _ { // private
template <typename T, Kind k = kind<T>()>
template <typename T, Kind k = CAPNP_KIND(T)>
struct PointerHelpers;
} // namespace _ (private)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -202,6 +202,8 @@ static const ::capnp::_::AlignedData<195> b_91cc55cd57de5419 = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, }
};
::capnp::word const* const bp_91cc55cd57de5419 = b_91cc55cd57de5419.words;
#if !CAPNP_LITE
static const ::capnp::_::RawSchema* const d_91cc55cd57de5419[] = {
&s_91cc55cd57de5419,
};
......@@ -213,6 +215,7 @@ const ::capnp::_::RawSchema s_91cc55cd57de5419 = {
0x91cc55cd57de5419, b_91cc55cd57de5419.words, 195, d_91cc55cd57de5419, m_91cc55cd57de5419,
1, 10, i_91cc55cd57de5419, nullptr, nullptr, { &s_91cc55cd57de5419, nullptr, bd_91cc55cd57de5419, 0, sizeof(bd_91cc55cd57de5419) / sizeof(bd_91cc55cd57de5419[0]), nullptr }
};
#endif // !CAPNP_LITE
static const ::capnp::_::AlignedData<119> b_c6725e678d60fa37 = {
{ 0, 0, 0, 0, 5, 0, 6, 0,
55, 250, 96, 141, 103, 94, 114, 198,
......@@ -334,6 +337,8 @@ static const ::capnp::_::AlignedData<119> b_c6725e678d60fa37 = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, }
};
::capnp::word const* const bp_c6725e678d60fa37 = b_c6725e678d60fa37.words;
#if !CAPNP_LITE
static const ::capnp::_::RawSchema* const d_c6725e678d60fa37[] = {
&s_91cc55cd57de5419,
&s_c6725e678d60fa37,
......@@ -346,6 +351,7 @@ const ::capnp::_::RawSchema s_c6725e678d60fa37 = {
0xc6725e678d60fa37, b_c6725e678d60fa37.words, 119, d_c6725e678d60fa37, m_c6725e678d60fa37,
2, 6, i_c6725e678d60fa37, nullptr, nullptr, { &s_c6725e678d60fa37, nullptr, bd_c6725e678d60fa37, 0, sizeof(bd_c6725e678d60fa37) / sizeof(bd_c6725e678d60fa37[0]), nullptr }
};
#endif // !CAPNP_LITE
static const ::capnp::_::AlignedData<38> b_9e69a92512b19d18 = {
{ 0, 0, 0, 0, 5, 0, 6, 0,
24, 157, 177, 18, 37, 169, 105, 158,
......@@ -386,6 +392,8 @@ static const ::capnp::_::AlignedData<38> b_9e69a92512b19d18 = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, }
};
::capnp::word const* const bp_9e69a92512b19d18 = b_9e69a92512b19d18.words;
#if !CAPNP_LITE
static const ::capnp::_::RawSchema* const d_9e69a92512b19d18[] = {
&s_91cc55cd57de5419,
};
......@@ -397,6 +405,7 @@ const ::capnp::_::RawSchema s_9e69a92512b19d18 = {
0x9e69a92512b19d18, b_9e69a92512b19d18.words, 38, d_9e69a92512b19d18, m_9e69a92512b19d18,
1, 1, i_9e69a92512b19d18, nullptr, nullptr, { &s_9e69a92512b19d18, nullptr, bd_9e69a92512b19d18, 0, sizeof(bd_9e69a92512b19d18) / sizeof(bd_9e69a92512b19d18[0]), nullptr }
};
#endif // !CAPNP_LITE
static const ::capnp::_::AlignedData<40> b_a11f97b9d6c73dd4 = {
{ 0, 0, 0, 0, 5, 0, 6, 0,
212, 61, 199, 214, 185, 151, 31, 161,
......@@ -439,6 +448,8 @@ static const ::capnp::_::AlignedData<40> b_a11f97b9d6c73dd4 = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, }
};
::capnp::word const* const bp_a11f97b9d6c73dd4 = b_a11f97b9d6c73dd4.words;
#if !CAPNP_LITE
static const ::capnp::_::RawSchema* const d_a11f97b9d6c73dd4[] = {
&s_c6725e678d60fa37,
};
......@@ -450,6 +461,7 @@ const ::capnp::_::RawSchema s_a11f97b9d6c73dd4 = {
0xa11f97b9d6c73dd4, b_a11f97b9d6c73dd4.words, 40, d_a11f97b9d6c73dd4, m_a11f97b9d6c73dd4,
1, 1, i_a11f97b9d6c73dd4, nullptr, nullptr, { &s_a11f97b9d6c73dd4, nullptr, bd_a11f97b9d6c73dd4, 0, sizeof(bd_a11f97b9d6c73dd4) / sizeof(bd_a11f97b9d6c73dd4[0]), nullptr }
};
#endif // !CAPNP_LITE
} // namespace schemas
} // namespace capnp
......@@ -458,10 +470,10 @@ const ::capnp::_::RawSchema s_a11f97b9d6c73dd4 = {
namespace capnp {
namespace compiler {
CAPNP_DEFINE_STRUCT(Token, );
CAPNP_DEFINE_STRUCT(Statement, );
CAPNP_DEFINE_STRUCT(LexedTokens, );
CAPNP_DEFINE_STRUCT(LexedStatements, );
CAPNP_DEFINE_STRUCT(Token, , 91cc55cd57de5419);
CAPNP_DEFINE_STRUCT(Statement, , c6725e678d60fa37);
CAPNP_DEFINE_STRUCT(LexedTokens, , 9e69a92512b19d18);
CAPNP_DEFINE_STRUCT(LexedStatements, , a11f97b9d6c73dd4);
} // namespace
} // namespace
......
......@@ -14,10 +14,10 @@
namespace capnp {
namespace schemas {
extern const ::capnp::_::RawSchema s_91cc55cd57de5419;
extern const ::capnp::_::RawSchema s_c6725e678d60fa37;
extern const ::capnp::_::RawSchema s_9e69a92512b19d18;
extern const ::capnp::_::RawSchema s_a11f97b9d6c73dd4;
CAPNP_DECLARE_SCHEMA(91cc55cd57de5419);
CAPNP_DECLARE_SCHEMA(c6725e678d60fa37);
CAPNP_DECLARE_SCHEMA(9e69a92512b19d18);
CAPNP_DECLARE_SCHEMA(a11f97b9d6c73dd4);
} // namespace schemas
} // namespace capnp
......@@ -92,9 +92,11 @@ public:
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 isIdentifier() const;
......@@ -155,7 +157,9 @@ public:
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 isIdentifier();
......@@ -229,6 +233,7 @@ private:
friend class ::capnp::Orphanage;
};
#if !CAPNP_LITE
class Token::Pipeline {
public:
typedef Token Pipelines;
......@@ -242,6 +247,7 @@ private:
template <typename, ::capnp::Kind>
friend struct ::capnp::ToDynamic_;
};
#endif // !CAPNP_LITE
class Statement::Reader {
public:
......@@ -254,9 +260,11 @@ public:
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 hasTokens() const;
......@@ -300,7 +308,9 @@ public:
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 hasTokens();
......@@ -342,6 +352,7 @@ private:
friend class ::capnp::Orphanage;
};
#if !CAPNP_LITE
class Statement::Pipeline {
public:
typedef Statement Pipelines;
......@@ -355,6 +366,7 @@ private:
template <typename, ::capnp::Kind>
friend struct ::capnp::ToDynamic_;
};
#endif // !CAPNP_LITE
class LexedTokens::Reader {
public:
......@@ -367,9 +379,11 @@ public:
return _reader.totalSize().asPublic();
}
#if !CAPNP_LITE
inline ::kj::StringTree toString() const {
return ::capnp::_::structString(_reader, *_capnpPrivate::brand);
}
#endif // !CAPNP_LITE
inline bool hasTokens() const;
inline ::capnp::List< ::capnp::compiler::Token>::Reader getTokens() const;
......@@ -398,7 +412,9 @@ public:
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 hasTokens();
inline ::capnp::List< ::capnp::compiler::Token>::Builder getTokens();
......@@ -414,6 +430,7 @@ private:
friend class ::capnp::Orphanage;
};
#if !CAPNP_LITE
class LexedTokens::Pipeline {
public:
typedef LexedTokens Pipelines;
......@@ -427,6 +444,7 @@ private:
template <typename, ::capnp::Kind>
friend struct ::capnp::ToDynamic_;
};
#endif // !CAPNP_LITE
class LexedStatements::Reader {
public:
......@@ -439,9 +457,11 @@ public:
return _reader.totalSize().asPublic();
}
#if !CAPNP_LITE
inline ::kj::StringTree toString() const {
return ::capnp::_::structString(_reader, *_capnpPrivate::brand);
}
#endif // !CAPNP_LITE
inline bool hasStatements() const;
inline ::capnp::List< ::capnp::compiler::Statement>::Reader getStatements() const;
......@@ -470,7 +490,9 @@ public:
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 hasStatements();
inline ::capnp::List< ::capnp::compiler::Statement>::Builder getStatements();
......@@ -486,6 +508,7 @@ private:
friend class ::capnp::Orphanage;
};
#if !CAPNP_LITE
class LexedStatements::Pipeline {
public:
typedef LexedStatements Pipelines;
......@@ -499,6 +522,7 @@ private:
template <typename, ::capnp::Kind>
friend struct ::capnp::ToDynamic_;
};
#endif // !CAPNP_LITE
// =======================================================================================
......
......@@ -25,6 +25,7 @@
#include <kj/debug.h>
#include <gtest/gtest.h>
#include "test-util.h"
#include "schema-lite.h"
namespace capnp {
namespace _ { // private
......@@ -297,12 +298,14 @@ TEST(Encoding, UnnamedUnion) {
EXPECT_DEBUG_ANY_THROW(root.getBar());
EXPECT_DEBUG_ANY_THROW(root.asReader().getBar());
#if !CAPNP_LITE
StructSchema schema = Schema::from<test::TestUnnamedUnion>();
// The discriminant is allocated just before allocating "bar".
EXPECT_EQ(2u, schema.getProto().getStruct().getDiscriminantOffset());
EXPECT_EQ(0u, schema.getFieldByName("foo").getProto().getSlot().getOffset());
EXPECT_EQ(2u, schema.getFieldByName("bar").getProto().getSlot().getOffset());
#endif // !CAPNP_LITE
}
TEST(Encoding, Groups) {
......@@ -1333,7 +1336,7 @@ TEST(Encoding, Imports) {
TestImport2::Builder root = builder.getRoot<TestImport2>();
initTestMessage(root.initFoo());
checkTestMessage(root.asReader().getFoo());
root.setBar(Schema::from<TestAllTypes>().getProto());
root.setBar(schemaProto<TestAllTypes>());
initTestMessage(root.initBaz().initField());
checkTestMessage(root.asReader().getBaz().getField());
}
......
......@@ -36,13 +36,15 @@ namespace capnp {
class MessageBuilder; // So that it can be declared a friend.
template <typename T, Kind k = kind<T>()>
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.
namespace _ { // private
#if !CAPNP_LITE
struct RawSchema;
struct RawBrandedSchema {
......@@ -353,6 +355,8 @@ inline kj::StringTree structString(StructReader reader) {
return structString(reader, rawBrandedSchema<T>());
}
#endif // !CAPNP_LITE
// TODO(cleanup): Unify ConstStruct and ConstList.
template <typename T>
class ConstStruct {
......@@ -434,7 +438,7 @@ 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, bool = false>
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.
......@@ -455,22 +459,76 @@ inline constexpr uint sizeInWords() {
// all commas must be replaced with CAPNP_COMMA otherwise they will be interpreted as macro
// parameter separators! Ugh.
#if CAPNP_LITE
#define CAPNP_DECLARE_SCHEMA(id) \
extern ::capnp::word const* const bp_##id
#define CAPNP_DECLARE_ENUM(type, id) \
template <> struct EnumInfo<type##_##id> { \
struct IsEnum; \
static constexpr uint64_t typeId = 0x##id; \
static inline ::capnp::word const* const encodedSchema() { return bp_##id; } \
}
#define CAPNP_DEFINE_ENUM(type, id) \
constexpr uint64_t EnumInfo<type>::typeId
#define CAPNP_DECLARE_STRUCT_HEADER(id, dataWordSize, pointerCount, preferredElementEncoding) \
struct _capnpPrivate { \
struct IsStruct; \
static constexpr uint64_t typeId = 0x##id; \
static constexpr ::capnp::_::StructSize structSize = ::capnp::_::StructSize( \
dataWordSize * ::capnp::WORDS, pointerCount * ::capnp::POINTERS, \
::capnp::_::FieldSize::preferredElementEncoding); \
static inline ::capnp::word const* const encodedSchema() { return ::capnp::schemas::bp_##id; }
#define CAPNP_DECLARE_STRUCT(id, dataWordSize, pointerCount, preferredElementEncoding) \
CAPNP_DECLARE_STRUCT_HEADER(id, dataWordSize, pointerCount, preferredElementEncoding) \
}
#define CAPNP_DECLARE_TEMPLATE_STRUCT(id, dataWordSize, pointerCount, preferredElementEncoding, \
...) \
CAPNP_DECLARE_STRUCT_HEADER(id, dataWordSize, pointerCount, preferredElementEncoding) \
}
#define CAPNP_DEFINE_STRUCT(type, templates, id) \
templates constexpr uint64_t type::_capnpPrivate::typeId; \
templates constexpr ::capnp::_::StructSize type::_capnpPrivate::structSize
#define CAPNP_DEFINE_TEMPLATE_STRUCT(type, templates, id, brandScopesInitializer, \
brandBindingsInitializer, brandDependenciesInitializer) \
templates constexpr uint64_t type::_capnpPrivate::typeId; \
templates constexpr ::capnp::_::StructSize type::_capnpPrivate::structSize
#define CAPNP_DECLARE_INTERFACE(id) static_assert(true, "")
#define CAPNP_DECLARE_TEMPLATE_INTERFACE(id, ...) static_assert(true, "")
#define CAPNP_DEFINE_INTERFACE(type, templates, id) static_assert(true, "")
#define CAPNP_DEFINE_TEMPLATE_INTERFACE(type, templates, id, brandScopesInitializer, \
brandBindingsInitializer, brandDependenciesInitializer) \
static_assert(true, "")
#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) \
template <> struct EnumInfo<type##_##id> { \
struct IsEnum; \
static constexpr uint64_t typeId = 0x##id; \
static inline ::capnp::word const* const encodedSchema() { return bp_##id; } \
static constexpr ::capnp::_::RawSchema const* schema = &s_##id; \
}
#define CAPNP_DEFINE_ENUM(type) \
#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, preferredElementEncoding) \
struct _capnpPrivate { \
struct IsStruct; \
static constexpr uint64_t typeId = 0x##id; \
static constexpr ::capnp::Kind kind = ::capnp::Kind::STRUCT; \
static constexpr ::capnp::_::StructSize structSize = ::capnp::_::StructSize( \
dataWordSize * ::capnp::WORDS, pointerCount * ::capnp::POINTERS, \
::capnp::_::FieldSize::preferredElementEncoding); \
static inline ::capnp::word const* const encodedSchema() { return ::capnp::schemas::bp_##id; } \
static constexpr ::capnp::_::RawSchema const* schema = &::capnp::schemas::s_##id;
#define CAPNP_DECLARE_STRUCT(id, dataWordSize, pointerCount, preferredElementEncoding) \
CAPNP_DECLARE_STRUCT_HEADER(id, dataWordSize, pointerCount, preferredElementEncoding) \
......@@ -486,7 +544,7 @@ inline constexpr uint sizeInWords() {
static constexpr ::capnp::_::RawBrandedSchema const* brand = \
::capnp::_::ChooseBrand<_capnpPrivate, __VA_ARGS__>::brand; \
}
#define CAPNP_DEFINE_STRUCT(type, templates) \
#define CAPNP_DEFINE_STRUCT(type, templates, id) \
templates constexpr uint64_t type::_capnpPrivate::typeId; \
templates constexpr ::capnp::Kind type::_capnpPrivate::kind; \
templates constexpr ::capnp::_::StructSize type::_capnpPrivate::structSize; \
......@@ -514,8 +572,10 @@ inline constexpr uint sizeInWords() {
#define CAPNP_DECLARE_INTERFACE_HEADER(id) \
struct _capnpPrivate { \
struct IsInterface; \
static constexpr uint64_t typeId = 0x##id; \
static constexpr ::capnp::Kind kind = ::capnp::Kind::INTERFACE; \
static inline ::capnp::word const* const encodedSchema() { return ::capnp::schemas::bp_##id; } \
static constexpr ::capnp::_::RawSchema const* schema = &::capnp::schemas::s_##id;
#define CAPNP_DECLARE_INTERFACE(id) \
CAPNP_DECLARE_INTERFACE_HEADER(id) \
......@@ -530,7 +590,7 @@ inline constexpr uint sizeInWords() {
static constexpr ::capnp::_::RawBrandedSchema const* brand = \
::capnp::_::ChooseBrand<_capnpPrivate, __VA_ARGS__>::brand; \
}
#define CAPNP_DEFINE_INTERFACE(type, templates) \
#define CAPNP_DEFINE_INTERFACE(type, templates, id) \
templates constexpr uint64_t type::_capnpPrivate::typeId; \
templates constexpr ::capnp::Kind type::_capnpPrivate::kind; \
templates constexpr ::capnp::_::RawSchema const* type::_capnpPrivate::schema; \
......@@ -554,4 +614,6 @@ inline constexpr uint sizeInWords() {
nullptr \
}
#endif // CAPNP_LITE, else
#endif // CAPNP_GENERATED_HEADER_SUPPORT_H_
......@@ -23,13 +23,17 @@
#include "layout.h"
#include <kj/debug.h>
#include "arena.h"
#include "capability.h"
#include <string.h>
#include <stdlib.h>
#if !CAPNP_LITE
#include "capability.h"
#endif // !CAPNP_LITE
namespace capnp {
namespace _ { // private
#if !CAPNP_LITE
static BrokenCapFactory* brokenCapFactory = nullptr;
// Horrible hack: We need to be able to construct broken caps without any capability context,
// but we can't have a link-time dependency on libcapnp-rpc.
......@@ -39,6 +43,7 @@ void setGlobalBrokenCapFactoryForLayoutCpp(BrokenCapFactory& factory) {
// is ready for it. May be called multiple times but always with the same value.
__atomic_store_n(&brokenCapFactory, &factory, __ATOMIC_RELAXED);
}
#endif // !CAPNP_LITE
// =======================================================================================
......@@ -490,7 +495,11 @@ struct WireHelpers {
}
case WirePointer::OTHER:
if (ref->isCapability()) {
#if CAPNP_LITE
KJ_FAIL_ASSERT("Capability encountered in builder in lite mode?") { break; }
#else // CAPNP_LINE
segment->getArena()->dropCap(ref->capRef.index.get());
#endif // CAPNP_LITE, else
} else {
KJ_FAIL_REQUIRE("Unknown pointer type.") { break; }
}
......@@ -1547,6 +1556,7 @@ struct WireHelpers {
return { segment, ptr };
}
#if !CAPNP_LITE
static void setCapabilityPointer(
SegmentBuilder* segment, WirePointer* ref, kj::Own<ClientHook>&& cap,
BuilderArena* orphanArena = nullptr) {
......@@ -1556,6 +1566,7 @@ struct WireHelpers {
ref->setCap(orphanArena->injectCap(kj::mv(cap)));
}
}
#endif // !CAPNP_LITE
static SegmentAnd<word*> setListPointer(
SegmentBuilder* segment, WirePointer* ref, ListReader value,
......@@ -1737,14 +1748,18 @@ struct WireHelpers {
goto useDefault;
}
#if !CAPNP_LITE
KJ_IF_MAYBE(cap, srcSegment->getArena()->extractCap(src->capRef.index.get())) {
setCapabilityPointer(dstSegment, dst, kj::mv(*cap), orphanArena);
return { dstSegment, nullptr };
} else {
#endif // !CAPNP_LITE
KJ_FAIL_REQUIRE("Message contained invalid capability pointer.") {
goto useDefault;
}
#if !CAPNP_LITE
}
#endif // !CAPNP_LITE
}
}
......@@ -1851,6 +1866,7 @@ struct WireHelpers {
0 * BITS, nestingLimit - 1);
}
#if !CAPNP_LITE
static KJ_ALWAYS_INLINE(kj::Own<ClientHook> readCapabilityPointer(
SegmentReader* segment, const WirePointer* ref, int nestingLimit)) {
kj::Maybe<kj::Own<ClientHook>> maybeCap;
......@@ -1878,6 +1894,7 @@ struct WireHelpers {
return brokenCapFactory->newBrokenCap("Calling invalid capability pointer.");
}
}
#endif // !CAPNP_LITE
static KJ_ALWAYS_INLINE(ListReader readListPointer(
SegmentReader* segment, const WirePointer* ref, const word* defaultValue,
......@@ -2182,6 +2199,7 @@ void PointerBuilder::setList(const ListReader& value) {
WireHelpers::setListPointer(segment, pointer, value);
}
#if !CAPNP_LITE
kj::Own<ClientHook> PointerBuilder::getCapability() {
return WireHelpers::readCapabilityPointer(
segment, pointer, kj::maxValue);
......@@ -2190,6 +2208,7 @@ kj::Own<ClientHook> PointerBuilder::getCapability() {
void PointerBuilder::setCapability(kj::Own<ClientHook>&& cap) {
WireHelpers::setCapabilityPointer(segment, pointer, kj::mv(cap));
}
#endif // !CAPNP_LITE
void PointerBuilder::adopt(OrphanBuilder&& value) {
WireHelpers::adopt(segment, pointer, kj::mv(value));
......@@ -2260,10 +2279,12 @@ Data::Reader PointerReader::getBlob<Data>(const void* defaultValue, ByteCount de
return WireHelpers::readDataPointer(segment, ref, defaultValue, defaultSize);
}
#if !CAPNP_LITE
kj::Own<ClientHook> PointerReader::getCapability() const {
const WirePointer* ref = pointer == nullptr ? &zero.pointer : pointer;
return WireHelpers::readCapabilityPointer(segment, ref, nestingLimit);
}
#endif // !CAPNP_LITE
const word* PointerReader::getUnchecked() const {
KJ_REQUIRE(segment == nullptr, "getUncheckedPointer() only allowed on unchecked messages.");
......@@ -2600,6 +2621,7 @@ OrphanBuilder OrphanBuilder::copy(BuilderArena* arena, Data::Reader copyFrom) {
return result;
}
#if !CAPNP_LITE
OrphanBuilder OrphanBuilder::copy(BuilderArena* arena, kj::Own<ClientHook> copyFrom) {
OrphanBuilder result;
WireHelpers::setCapabilityPointer(nullptr, result.tagAsPtr(), kj::mv(copyFrom), arena);
......@@ -2607,6 +2629,7 @@ OrphanBuilder OrphanBuilder::copy(BuilderArena* arena, kj::Own<ClientHook> copyF
result.location = &result.tag; // dummy to make location non-null
return result;
}
#endif // !CAPNP_LITE
OrphanBuilder OrphanBuilder::referenceExternalData(BuilderArena* arena, Data::Reader data) {
KJ_REQUIRE(reinterpret_cast<uintptr_t>(data.begin()) % sizeof(void*) == 0,
......@@ -2691,9 +2714,11 @@ ListReader OrphanBuilder::asListReader(FieldSize elementSize) const {
segment, tagAsPtr(), location, nullptr, elementSize, kj::maxValue);
}
#if !CAPNP_LITE
kj::Own<ClientHook> OrphanBuilder::asCapability() const {
return WireHelpers::readCapabilityPointer(segment, tagAsPtr(), kj::maxValue);
}
#endif // !CAPNP_LITE
Text::Reader OrphanBuilder::asTextReader() const {
KJ_DASSERT(tagAsPtr()->isNull() == (location == nullptr));
......
......@@ -56,7 +56,9 @@
namespace capnp {
#if !CAPNP_LITE
class ClientHook;
#endif // !CAPNP_LITE
namespace _ { // private
......@@ -153,9 +155,9 @@ template <> struct ElementSizeForByteSize<8> { static constexpr FieldSize value
template <typename T> struct ElementSizeForType {
static constexpr FieldSize value =
// Primitive types that aren't special-cased below can be determined from sizeof().
kind<T>() == Kind::PRIMITIVE ? ElementSizeForByteSize<sizeof(T)>::value :
kind<T>() == Kind::ENUM ? FieldSize::TWO_BYTES :
kind<T>() == Kind::STRUCT ? FieldSize::INLINE_COMPOSITE :
CAPNP_KIND(T) == Kind::PRIMITIVE ? ElementSizeForByteSize<sizeof(T)>::value :
CAPNP_KIND(T) == Kind::ENUM ? FieldSize::TWO_BYTES :
CAPNP_KIND(T) == Kind::STRUCT ? FieldSize::INLINE_COMPOSITE :
// Everything else is a pointer.
FieldSize::POINTER;
......@@ -239,7 +241,7 @@ inline constexpr StructSize structSize() {
// -------------------------------------------------------------------
// Masking of default values
template <typename T, Kind kind = kind<T>()> struct Mask_;
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; };
......@@ -333,7 +335,9 @@ public:
ListBuilder getList(FieldSize elementSize, const word* defaultValue);
ListBuilder getStructList(StructSize elementSize, 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.
......@@ -348,7 +352,9 @@ public:
void setStruct(const StructReader& value);
void setList(const ListReader& value);
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.
......@@ -407,7 +413,9 @@ public:
ListReader getList(FieldSize expectedElementSize, 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.
......@@ -750,7 +758,9 @@ public:
static OrphanBuilder copy(BuilderArena* arena, PointerReader copyFrom);
static OrphanBuilder copy(BuilderArena* arena, Text::Reader copyFrom);
static OrphanBuilder copy(BuilderArena* arena, Data::Reader copyFrom);
#if !CAPNP_LITE
static OrphanBuilder copy(BuilderArena* arena, kj::Own<ClientHook> copyFrom);
#endif // !CAPNP_LITE
static OrphanBuilder referenceExternalData(BuilderArena* arena, Data::Reader data);
......@@ -776,7 +786,9 @@ public:
StructReader asStructReader(StructSize size) const;
ListReader asListReader(FieldSize elementSize) const;
#if !CAPNP_LITE
kj::Own<ClientHook> asCapability() const;
#endif // !CAPNP_LITE
Text::Reader asTextReader() const;
Data::Reader asDataReader() const;
......
......@@ -102,6 +102,7 @@ kj::ArrayPtr<const kj::ArrayPtr<const word>> MessageBuilder::getSegmentsForOutpu
}
}
#if !CAPNP_LITE
kj::ArrayPtr<kj::Maybe<kj::Own<ClientHook>>> MessageBuilder::getCapTable() {
if (allocatedArena) {
return arena()->getCapTable();
......@@ -109,6 +110,7 @@ kj::ArrayPtr<kj::Maybe<kj::Own<ClientHook>>> MessageBuilder::getCapTable() {
return nullptr;
}
}
#endif // !CAPNP_LITE
Orphanage MessageBuilder::getOrphanage() {
// We must ensure that the arena and root pointer have been allocated before the Orphanage
......
......@@ -116,6 +116,7 @@ public:
// RootType in this case must be DynamicStruct, and you must #include <capnp/dynamic.h> to
// use this.
#if !CAPNP_LITE
void initCapTable(kj::Array<kj::Maybe<kj::Own<ClientHook>>> capTable);
// Sets the table of capabilities embedded in this message. Capability pointers found in the
// message content contain indexes into this table. You must call this before attempting to
......@@ -125,6 +126,7 @@ public:
//
// You must link against libcapnp-rpc to call this method (the rest of MessageBuilder is in
// regular libcapnp).
#endif // !CAPNP_LITE
private:
ReaderOptions options;
......@@ -197,11 +199,13 @@ public:
kj::ArrayPtr<const kj::ArrayPtr<const word>> getSegmentsForOutput();
// Get the raw data that makes up the message.
#if !CAPNP_LITE
kj::ArrayPtr<kj::Maybe<kj::Own<ClientHook>>> getCapTable();
// Get the table of capabilities (interface pointers) that have been added to this message.
// When you later parse this message, you must call `initCapTable()` on the `MessageReader` and
// give it an equivalent set of capabilities, otherwise cap pointers in the message will be
// unusable.
#endif // !CAPNP_LITE
Orphanage getOrphanage();
......
......@@ -303,6 +303,7 @@ TEST(Orphans, ListAnyPointer) {
checkList(root.asReader().getAnyPointerField().getAs<List<uint32_t>>(), {12u, 34u, 56u});
}
#if !CAPNP_LITE
TEST(Orphans, DynamicStruct) {
MallocMessageBuilder builder;
auto root = builder.initRoot<test::TestAnyPointer>();
......@@ -588,6 +589,7 @@ TEST(Orphans, DynamicDisownGroup) {
EXPECT_EQ("foo", newBar.getGrault());
EXPECT_EQ(9876543210987ll, newBar.getGarply());
}
#endif // !CAPNP_LITE
TEST(Orphans, OrphanageFromBuilder) {
MallocMessageBuilder builder;
......@@ -609,6 +611,7 @@ TEST(Orphans, OrphanageFromBuilder) {
checkTestMessage(root.asReader().getStructField());
}
#if !CAPNP_LITE
{
Orphanage orphanage = Orphanage::getForMessageContaining(toDynamic(root));
Orphan<TestAllTypes> orphan = orphanage.newOrphan<TestAllTypes>();
......@@ -624,6 +627,7 @@ TEST(Orphans, OrphanageFromBuilder) {
root.adoptStructField(kj::mv(orphan));
checkTestMessage(root.asReader().getStructField());
}
#endif // !CAPNP_LITE
}
static bool allZero(const word* begin, const word* end) {
......
......@@ -155,9 +155,9 @@ private:
inline explicit Orphanage(_::BuilderArena* arena): arena(arena) {}
template <typename T, Kind = kind<T>()>
template <typename T, Kind = CAPNP_KIND(T)>
struct GetInnerBuilder;
template <typename T, Kind = kind<T>()>
template <typename T, Kind = CAPNP_KIND(T)>
struct GetInnerReader;
template <typename T>
struct NewOrphanListImpl;
......@@ -170,7 +170,7 @@ private:
namespace _ { // private
template <typename T, Kind = kind<T>()>
template <typename T, Kind = CAPNP_KIND(T)>
struct OrphanGetImpl;
template <typename T>
......@@ -183,6 +183,7 @@ struct OrphanGetImpl<T, Kind::STRUCT> {
}
};
#if !CAPNP_LITE
template <typename T>
struct OrphanGetImpl<T, Kind::INTERFACE> {
static inline typename T::Client apply(_::OrphanBuilder& builder) {
......@@ -192,6 +193,7 @@ struct OrphanGetImpl<T, Kind::INTERFACE> {
return typename T::Client(builder.asCapability());
}
};
#endif // !CAPNP_LITE
template <typename T, Kind k>
struct OrphanGetImpl<List<T, k>, Kind::LIST> {
......
......@@ -33,6 +33,8 @@ static const ::capnp::_::AlignedData<26> b_9fd69ebc87b9719c = {
115, 101, 114, 118, 101, 114, 0, 0,
99, 108, 105, 101, 110, 116, 0, 0, }
};
::capnp::word const* const bp_9fd69ebc87b9719c = b_9fd69ebc87b9719c.words;
#if !CAPNP_LITE
static const uint16_t m_9fd69ebc87b9719c[] = {1, 0};
const ::capnp::_::RawBrandedSchema::Dependency bd_9fd69ebc87b9719c[] = {
};
......@@ -40,7 +42,8 @@ const ::capnp::_::RawSchema s_9fd69ebc87b9719c = {
0x9fd69ebc87b9719c, b_9fd69ebc87b9719c.words, 26, nullptr, m_9fd69ebc87b9719c,
0, 2, nullptr, nullptr, nullptr, { &s_9fd69ebc87b9719c, nullptr, bd_9fd69ebc87b9719c, 0, sizeof(bd_9fd69ebc87b9719c) / sizeof(bd_9fd69ebc87b9719c[0]), nullptr }
};
CAPNP_DEFINE_ENUM(Side_9fd69ebc87b9719c);
#endif // !CAPNP_LITE
CAPNP_DEFINE_ENUM(Side_9fd69ebc87b9719c, 9fd69ebc87b9719c);
static const ::capnp::_::AlignedData<35> b_e615e371b1036508 = {
{ 0, 0, 0, 0, 5, 0, 6, 0,
8, 101, 3, 177, 113, 227, 21, 230,
......@@ -78,6 +81,8 @@ static const ::capnp::_::AlignedData<35> b_e615e371b1036508 = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, }
};
::capnp::word const* const bp_e615e371b1036508 = b_e615e371b1036508.words;
#if !CAPNP_LITE
static const ::capnp::_::RawSchema* const d_e615e371b1036508[] = {
&s_9fd69ebc87b9719c,
};
......@@ -89,6 +94,7 @@ const ::capnp::_::RawSchema s_e615e371b1036508 = {
0xe615e371b1036508, b_e615e371b1036508.words, 35, d_e615e371b1036508, m_e615e371b1036508,
1, 1, i_e615e371b1036508, nullptr, nullptr, { &s_e615e371b1036508, nullptr, bd_e615e371b1036508, 0, sizeof(bd_e615e371b1036508) / sizeof(bd_e615e371b1036508[0]), nullptr }
};
#endif // !CAPNP_LITE
static const ::capnp::_::AlignedData<34> b_b88d09a9c5f39817 = {
{ 0, 0, 0, 0, 5, 0, 6, 0,
23, 152, 243, 197, 169, 9, 141, 184,
......@@ -125,6 +131,8 @@ static const ::capnp::_::AlignedData<34> b_b88d09a9c5f39817 = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, }
};
::capnp::word const* const bp_b88d09a9c5f39817 = b_b88d09a9c5f39817.words;
#if !CAPNP_LITE
static const uint16_t m_b88d09a9c5f39817[] = {0};
static const uint16_t i_b88d09a9c5f39817[] = {0};
const ::capnp::_::RawBrandedSchema::Dependency bd_b88d09a9c5f39817[] = {
......@@ -133,6 +141,7 @@ const ::capnp::_::RawSchema s_b88d09a9c5f39817 = {
0xb88d09a9c5f39817, b_b88d09a9c5f39817.words, 34, nullptr, m_b88d09a9c5f39817,
0, 1, i_b88d09a9c5f39817, nullptr, nullptr, { &s_b88d09a9c5f39817, nullptr, bd_b88d09a9c5f39817, 0, sizeof(bd_b88d09a9c5f39817) / sizeof(bd_b88d09a9c5f39817[0]), nullptr }
};
#endif // !CAPNP_LITE
static const ::capnp::_::AlignedData<18> b_89f389b6fd4082c1 = {
{ 0, 0, 0, 0, 5, 0, 6, 0,
193, 130, 64, 253, 182, 137, 243, 137,
......@@ -153,12 +162,15 @@ static const ::capnp::_::AlignedData<18> b_89f389b6fd4082c1 = {
110, 116, 73, 100, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 1, 0, }
};
::capnp::word const* const bp_89f389b6fd4082c1 = b_89f389b6fd4082c1.words;
#if !CAPNP_LITE
const ::capnp::_::RawBrandedSchema::Dependency bd_89f389b6fd4082c1[] = {
};
const ::capnp::_::RawSchema s_89f389b6fd4082c1 = {
0x89f389b6fd4082c1, b_89f389b6fd4082c1.words, 18, nullptr, nullptr,
0, 0, nullptr, nullptr, nullptr, { &s_89f389b6fd4082c1, nullptr, bd_89f389b6fd4082c1, 0, sizeof(bd_89f389b6fd4082c1) / sizeof(bd_89f389b6fd4082c1[0]), nullptr }
};
#endif // !CAPNP_LITE
static const ::capnp::_::AlignedData<19> b_b47f4979672cb59d = {
{ 0, 0, 0, 0, 5, 0, 6, 0,
157, 181, 44, 103, 121, 73, 127, 180,
......@@ -180,12 +192,15 @@ static const ::capnp::_::AlignedData<19> b_b47f4979672cb59d = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 1, 0, }
};
::capnp::word const* const bp_b47f4979672cb59d = b_b47f4979672cb59d.words;
#if !CAPNP_LITE
const ::capnp::_::RawBrandedSchema::Dependency bd_b47f4979672cb59d[] = {
};
const ::capnp::_::RawSchema s_b47f4979672cb59d = {
0xb47f4979672cb59d, b_b47f4979672cb59d.words, 19, nullptr, nullptr,
0, 0, nullptr, nullptr, nullptr, { &s_b47f4979672cb59d, nullptr, bd_b47f4979672cb59d, 0, sizeof(bd_b47f4979672cb59d) / sizeof(bd_b47f4979672cb59d[0]), nullptr }
};
#endif // !CAPNP_LITE
static const ::capnp::_::AlignedData<65> b_95b29059097fca83 = {
{ 0, 0, 0, 0, 5, 0, 6, 0,
131, 202, 127, 9, 89, 144, 178, 149,
......@@ -253,6 +268,8 @@ static const ::capnp::_::AlignedData<65> b_95b29059097fca83 = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, }
};
::capnp::word const* const bp_95b29059097fca83 = b_95b29059097fca83.words;
#if !CAPNP_LITE
static const uint16_t m_95b29059097fca83[] = {0, 1, 2};
static const uint16_t i_95b29059097fca83[] = {0, 1, 2};
const ::capnp::_::RawBrandedSchema::Dependency bd_95b29059097fca83[] = {
......@@ -261,6 +278,7 @@ const ::capnp::_::RawSchema s_95b29059097fca83 = {
0x95b29059097fca83, b_95b29059097fca83.words, 65, nullptr, m_95b29059097fca83,
0, 3, i_95b29059097fca83, nullptr, nullptr, { &s_95b29059097fca83, nullptr, bd_95b29059097fca83, 0, sizeof(bd_95b29059097fca83) / sizeof(bd_95b29059097fca83[0]), nullptr }
};
#endif // !CAPNP_LITE
static const ::capnp::_::AlignedData<65> b_9d263a3630b7ebee = {
{ 0, 0, 0, 0, 5, 0, 6, 0,
238, 235, 183, 48, 54, 58, 38, 157,
......@@ -328,6 +346,8 @@ static const ::capnp::_::AlignedData<65> b_9d263a3630b7ebee = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, }
};
::capnp::word const* const bp_9d263a3630b7ebee = b_9d263a3630b7ebee.words;
#if !CAPNP_LITE
static const uint16_t m_9d263a3630b7ebee[] = {2, 0, 1};
static const uint16_t i_9d263a3630b7ebee[] = {0, 1, 2};
const ::capnp::_::RawBrandedSchema::Dependency bd_9d263a3630b7ebee[] = {
......@@ -336,6 +356,7 @@ const ::capnp::_::RawSchema s_9d263a3630b7ebee = {
0x9d263a3630b7ebee, b_9d263a3630b7ebee.words, 65, nullptr, m_9d263a3630b7ebee,
0, 3, i_9d263a3630b7ebee, nullptr, nullptr, { &s_9d263a3630b7ebee, nullptr, bd_9d263a3630b7ebee, 0, sizeof(bd_9d263a3630b7ebee) / sizeof(bd_9d263a3630b7ebee[0]), nullptr }
};
#endif // !CAPNP_LITE
} // namespace schemas
} // namespace capnp
......@@ -345,12 +366,12 @@ namespace capnp {
namespace rpc {
namespace twoparty {
CAPNP_DEFINE_STRUCT(SturdyRefHostId, );
CAPNP_DEFINE_STRUCT(ProvisionId, );
CAPNP_DEFINE_STRUCT(RecipientId, );
CAPNP_DEFINE_STRUCT(ThirdPartyCapId, );
CAPNP_DEFINE_STRUCT(JoinKeyPart, );
CAPNP_DEFINE_STRUCT(JoinResult, );
CAPNP_DEFINE_STRUCT(SturdyRefHostId, , e615e371b1036508);
CAPNP_DEFINE_STRUCT(ProvisionId, , b88d09a9c5f39817);
CAPNP_DEFINE_STRUCT(RecipientId, , 89f389b6fd4082c1);
CAPNP_DEFINE_STRUCT(ThirdPartyCapId, , b47f4979672cb59d);
CAPNP_DEFINE_STRUCT(JoinKeyPart, , 95b29059097fca83);
CAPNP_DEFINE_STRUCT(JoinResult, , 9d263a3630b7ebee);
} // namespace
} // namespace
......
......@@ -14,18 +14,18 @@
namespace capnp {
namespace schemas {
extern const ::capnp::_::RawSchema s_9fd69ebc87b9719c;
CAPNP_DECLARE_SCHEMA(9fd69ebc87b9719c);
enum class Side_9fd69ebc87b9719c: uint16_t {
SERVER,
CLIENT,
};
CAPNP_DECLARE_ENUM(Side, 9fd69ebc87b9719c);
extern const ::capnp::_::RawSchema s_e615e371b1036508;
extern const ::capnp::_::RawSchema s_b88d09a9c5f39817;
extern const ::capnp::_::RawSchema s_89f389b6fd4082c1;
extern const ::capnp::_::RawSchema s_b47f4979672cb59d;
extern const ::capnp::_::RawSchema s_95b29059097fca83;
extern const ::capnp::_::RawSchema s_9d263a3630b7ebee;
CAPNP_DECLARE_SCHEMA(e615e371b1036508);
CAPNP_DECLARE_SCHEMA(b88d09a9c5f39817);
CAPNP_DECLARE_SCHEMA(89f389b6fd4082c1);
CAPNP_DECLARE_SCHEMA(b47f4979672cb59d);
CAPNP_DECLARE_SCHEMA(95b29059097fca83);
CAPNP_DECLARE_SCHEMA(9d263a3630b7ebee);
} // namespace schemas
} // namespace capnp
......@@ -109,9 +109,11 @@ public:
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;
......@@ -139,7 +141,9 @@ public:
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);
......@@ -151,6 +155,7 @@ private:
friend class ::capnp::Orphanage;
};
#if !CAPNP_LITE
class SturdyRefHostId::Pipeline {
public:
typedef SturdyRefHostId Pipelines;
......@@ -164,6 +169,7 @@ private:
template <typename, ::capnp::Kind>
friend struct ::capnp::ToDynamic_;
};
#endif // !CAPNP_LITE
class ProvisionId::Reader {
public:
......@@ -176,9 +182,11 @@ public:
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;
......@@ -206,7 +214,9 @@ public:
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);
......@@ -218,6 +228,7 @@ private:
friend class ::capnp::Orphanage;
};
#if !CAPNP_LITE
class ProvisionId::Pipeline {
public:
typedef ProvisionId Pipelines;
......@@ -231,6 +242,7 @@ private:
template <typename, ::capnp::Kind>
friend struct ::capnp::ToDynamic_;
};
#endif // !CAPNP_LITE
class RecipientId::Reader {
public:
......@@ -243,9 +255,11 @@ public:
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;
......@@ -271,7 +285,9 @@ public:
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;
......@@ -280,6 +296,7 @@ private:
friend class ::capnp::Orphanage;
};
#if !CAPNP_LITE
class RecipientId::Pipeline {
public:
typedef RecipientId Pipelines;
......@@ -293,6 +310,7 @@ private:
template <typename, ::capnp::Kind>
friend struct ::capnp::ToDynamic_;
};
#endif // !CAPNP_LITE
class ThirdPartyCapId::Reader {
public:
......@@ -305,9 +323,11 @@ public:
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;
......@@ -333,7 +353,9 @@ public:
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;
......@@ -342,6 +364,7 @@ private:
friend class ::capnp::Orphanage;
};
#if !CAPNP_LITE
class ThirdPartyCapId::Pipeline {
public:
typedef ThirdPartyCapId Pipelines;
......@@ -355,6 +378,7 @@ private:
template <typename, ::capnp::Kind>
friend struct ::capnp::ToDynamic_;
};
#endif // !CAPNP_LITE
class JoinKeyPart::Reader {
public:
......@@ -367,9 +391,11 @@ public:
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;
......@@ -401,7 +427,9 @@ public:
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);
......@@ -419,6 +447,7 @@ private:
friend class ::capnp::Orphanage;
};
#if !CAPNP_LITE
class JoinKeyPart::Pipeline {
public:
typedef JoinKeyPart Pipelines;
......@@ -432,6 +461,7 @@ private:
template <typename, ::capnp::Kind>
friend struct ::capnp::ToDynamic_;
};
#endif // !CAPNP_LITE
class JoinResult::Reader {
public:
......@@ -444,9 +474,11 @@ public:
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;
......@@ -479,7 +511,9 @@ public:
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);
......@@ -498,6 +532,7 @@ private:
friend class ::capnp::Orphanage;
};
#if !CAPNP_LITE
class JoinResult::Pipeline {
public:
typedef JoinResult Pipelines;
......@@ -511,6 +546,7 @@ private:
template <typename, ::capnp::Kind>
friend struct ::capnp::ToDynamic_;
};
#endif // !CAPNP_LITE
// =======================================================================================
......
This diff is collapsed.
This diff is collapsed.
// 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_
#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_
This diff is collapsed.
This diff is collapsed.
......@@ -22,6 +22,10 @@
#ifndef CAPNP_SCHEMA_H_
#define CAPNP_SCHEMA_H_
#if CAPNP_LITE
#error "Reflection APIs, including this header, are not available in lite mode."
#endif
#include <capnp/schema.capnp.h>
namespace capnp {
......
This diff is collapsed.
......@@ -25,9 +25,12 @@
#include <capnp/test.capnp.h>
#include <iostream>
#include "blob.h"
#include "dynamic.h"
#include <gtest/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, ".")
......@@ -94,6 +97,7 @@ 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);
......@@ -102,6 +106,7 @@ 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, typename U>
void checkList(T reader, std::initializer_list<U> expected) {
......@@ -136,6 +141,7 @@ 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>();
......@@ -150,12 +156,15 @@ void checkList(T reader, std::initializer_list<ReaderFor<Element>> expected) {
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);
......@@ -271,6 +280,8 @@ private:
TestInterfaceImpl impl;
};
#endif // !CAPNP_LITE
} // namespace _ (private)
} // namespace capnp
......
......@@ -294,6 +294,15 @@ doit make distclean
doit ./configure --prefix="$STAGING" --disable-shared \
--with-external-capnp CAPNP=$STAGING/bin/capnp
doit make -j6 check
echo "========================================================================="
echo "Testing --disable-reflection"
echo "========================================================================="
doit make distclean
doit ./configure --prefix="$STAGING" --disable-shared --disable-reflection \
--with-external-capnp CAPNP=$STAGING/bin/capnp
doit make -j6 check
doit make distclean
# Test 32-bit build now while we have $STAGING available for cross-compiling.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment