blob: d8ec47b3adccaf9834fd69b6a20c9881ed9f0167 [file]
// Copyright (c) 2013, Kenton Varda <[email protected]>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This file is included form all generated headers.
#ifndef CAPNPROTO_GENERATED_HEADER_SUPPORT_H_
#define CAPNPROTO_GENERATED_HEADER_SUPPORT_H_
#include "layout.h"
#include "list.h"
namespace capnproto {
class MessageBuilder; // So that it can be declared a friend.
template <typename T, Kind k = 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 internal {
template <typename T>
struct PointerHelpers<T, Kind::STRUCT> {
static inline typename T::Reader get(StructReader reader, WirePointerCount index,
const word* defaultValue = nullptr) {
return typename T::Reader(reader.getStructField(index, defaultValue));
}
static inline typename T::Builder get(StructBuilder builder, WirePointerCount index,
const word* defaultValue = nullptr) {
return typename T::Builder(builder.getStructField(index, structSize<T>(), defaultValue));
}
static inline void set(StructBuilder builder, WirePointerCount index,
typename T::Reader value) {
builder.setStructField(index, value._reader);
}
static inline typename T::Builder init(StructBuilder builder, WirePointerCount index) {
return typename T::Builder(builder.initStructField(index, structSize<T>()));
}
};
template <typename T>
struct PointerHelpers<List<T>, Kind::LIST> {
static inline typename List<T>::Reader get(StructReader reader, WirePointerCount index,
const word* defaultValue = nullptr) {
return typename List<T>::Reader(List<T>::getAsFieldOf(reader, index, defaultValue));
}
static inline typename List<T>::Builder get(StructBuilder builder, WirePointerCount index,
const word* defaultValue = nullptr) {
return typename List<T>::Builder(List<T>::getAsFieldOf(builder, index, defaultValue));
}
static inline void set(StructBuilder builder, WirePointerCount index,
typename List<T>::Reader value) {
builder.setListField(index, value.reader);
}
template <typename U>
static void set(StructBuilder builder, WirePointerCount index, std::initializer_list<U> value) {
auto l = init(builder, index, value.size());
uint i = 0;
for (auto& element: value) {
l.set(i++, element);
}
}
static inline typename List<T>::Builder init(
StructBuilder builder, WirePointerCount index, uint size) {
return typename List<T>::Builder(List<T>::initAsFieldOf(builder, index, size));
}
};
template <typename T>
struct PointerHelpers<T, Kind::BLOB> {
static inline typename T::Reader get(StructReader reader, WirePointerCount index,
const void* defaultValue = nullptr,
uint defaultBytes = 0) {
return reader.getBlobField<T>(index, defaultValue, defaultBytes * BYTES);
}
static inline typename T::Builder get(StructBuilder builder, WirePointerCount index,
const void* defaultValue = nullptr,
uint defaultBytes = 0) {
return builder.getBlobField<T>(index, defaultValue, defaultBytes * BYTES);
}
static inline void set(StructBuilder builder, WirePointerCount index, typename T::Reader value) {
builder.setBlobField<T>(index, value);
}
static inline typename T::Builder init(StructBuilder builder, WirePointerCount index, uint size) {
return builder.initBlobField<T>(index, size * BYTES);
}
};
#if defined(CAPNPROTO_PRIVATE) || defined(__CDT_PARSER__)
struct UncheckedMessage {
typedef const word* Reader;
};
template <>
struct PointerHelpers<UncheckedMessage> {
// Reads an Object 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(StructReader reader, WirePointerCount index) {
return reader.getUncheckedPointer(index);
}
};
#endif
struct RawSchema {
// The generated code defines a constant RawSchema for every compiled declaration.
//
// This is an internal structure which could change in the future.
const word* encodedNode;
// Encoded SchemaNode, readable via readMessageUnchecked<schema::Node>(encodedNode).
const RawSchema* const* dependencies;
// Pointers to other types on which this one depends, sorted by ID.
// TODO(someday): Make this a hashtable.
struct MemberInfo {
uint16_t unionIndex; // 0 = not in a union, >0 = parent union's index + 1
uint16_t index; // index of the member
MemberInfo() = default;
inline MemberInfo(uint16_t unionIndex, uint16_t index): unionIndex(unionIndex), index(index) {}
};
const MemberInfo* 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 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.
};
template <typename T>
struct RawSchemaFor;
template <typename T>
inline const RawSchema& rawSchema() {
return RawSchemaFor<T>::getSchema();
}
template <typename T>
struct TypeIdFor;
kj::String debugString(StructReader reader, const RawSchema& schema);
// Declared here so that we can declare inline debugString() 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::String debugString(StructReader reader) {
return debugString(reader, rawSchema<T>());
}
} // namespace internal
template <typename T>
inline constexpr uint64_t typeId() { return internal::TypeIdFor<T>::typeId; }
// typeId<MyType>() returns the type ID as defined in the schema. Works with structs, enums, and
// interfaces.
} // namespace capnproto
#define CAPNPROTO_DECLARE_ENUM(type, id) \
template <> struct KindOf<type> { static constexpr Kind kind = Kind::ENUM; }; \
template <> struct TypeIdFor<type> { static constexpr uint64_t typeId = 0x##id; }; \
template <> struct RawSchemaFor<type> { \
static inline const RawSchema& getSchema() { return schemas::s_##id; } \
}
#define CAPNPROTO_DEFINE_ENUM(type) \
constexpr Kind KindOf<type>::kind; \
constexpr uint64_t TypeIdFor<type>::typeId;
#define CAPNPROTO_DECLARE_STRUCT(type, id, dataWordSize, pointerCount, preferredElementEncoding) \
template <> struct KindOf<type> { static constexpr Kind kind = Kind::STRUCT; }; \
template <> struct StructSizeFor<type> { \
static constexpr StructSize value = StructSize( \
dataWordSize * WORDS, pointerCount * POINTERS, FieldSize::preferredElementEncoding); \
}; \
template <> struct TypeIdFor<type> { static constexpr uint64_t typeId = 0x##id; }; \
template <> struct RawSchemaFor<type> { \
static inline const RawSchema& getSchema() { return schemas::s_##id; } \
}
#define CAPNPROTO_DEFINE_STRUCT(type) \
constexpr Kind KindOf<type>::kind; \
constexpr StructSize StructSizeFor<type>::value; \
constexpr uint64_t TypeIdFor<type>::typeId;
#define CAPNPROTO_DECLARE_INTERFACE(type, id) \
template <> struct KindOf<type> { static constexpr Kind kind = Kind::INTERFACE; }; \
template <> struct TypeIdFor<type> { static constexpr uint64_t typeId = 0x##id; }; \
template <> struct RawSchemaFor<type> { \
static inline const RawSchema& getSchema() { return schemas::s_##id; } \
}
#define CAPNPROTO_DEFINE_INTERFACE(type) \
constexpr Kind KindOf<type>::kind; \
constexpr uint64_t TypeIdFor<type>::typeId;
#endif // CAPNPROTO_GENERATED_HEADER_SUPPORT_H_