annotate osx/include/capnp/schema.h @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents 0994c39f1e94
children
rev   line source
cannam@62 1 // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
cannam@62 2 // Licensed under the MIT License:
cannam@62 3 //
cannam@62 4 // Permission is hereby granted, free of charge, to any person obtaining a copy
cannam@62 5 // of this software and associated documentation files (the "Software"), to deal
cannam@62 6 // in the Software without restriction, including without limitation the rights
cannam@62 7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
cannam@62 8 // copies of the Software, and to permit persons to whom the Software is
cannam@62 9 // furnished to do so, subject to the following conditions:
cannam@62 10 //
cannam@62 11 // The above copyright notice and this permission notice shall be included in
cannam@62 12 // all copies or substantial portions of the Software.
cannam@62 13 //
cannam@62 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
cannam@62 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
cannam@62 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
cannam@62 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
cannam@62 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
cannam@62 19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
cannam@62 20 // THE SOFTWARE.
cannam@62 21
cannam@62 22 #ifndef CAPNP_SCHEMA_H_
cannam@62 23 #define CAPNP_SCHEMA_H_
cannam@62 24
cannam@62 25 #if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS)
cannam@62 26 #pragma GCC system_header
cannam@62 27 #endif
cannam@62 28
cannam@62 29 #if CAPNP_LITE
cannam@62 30 #error "Reflection APIs, including this header, are not available in lite mode."
cannam@62 31 #endif
cannam@62 32
cannam@62 33 #include <capnp/schema.capnp.h>
cannam@62 34
cannam@62 35 namespace capnp {
cannam@62 36
cannam@62 37 class Schema;
cannam@62 38 class StructSchema;
cannam@62 39 class EnumSchema;
cannam@62 40 class InterfaceSchema;
cannam@62 41 class ConstSchema;
cannam@62 42 class ListSchema;
cannam@62 43 class Type;
cannam@62 44
cannam@62 45 template <typename T, Kind k = kind<T>()> struct SchemaType_ { typedef Schema Type; };
cannam@62 46 template <typename T> struct SchemaType_<T, Kind::PRIMITIVE> { typedef schema::Type::Which Type; };
cannam@62 47 template <typename T> struct SchemaType_<T, Kind::BLOB> { typedef schema::Type::Which Type; };
cannam@62 48 template <typename T> struct SchemaType_<T, Kind::ENUM> { typedef EnumSchema Type; };
cannam@62 49 template <typename T> struct SchemaType_<T, Kind::STRUCT> { typedef StructSchema Type; };
cannam@62 50 template <typename T> struct SchemaType_<T, Kind::INTERFACE> { typedef InterfaceSchema Type; };
cannam@62 51 template <typename T> struct SchemaType_<T, Kind::LIST> { typedef ListSchema Type; };
cannam@62 52
cannam@62 53 template <typename T>
cannam@62 54 using SchemaType = typename SchemaType_<T>::Type;
cannam@62 55 // SchemaType<T> is the type of T's schema, e.g. StructSchema if T is a struct.
cannam@62 56
cannam@62 57 namespace _ { // private
cannam@62 58 extern const RawSchema NULL_SCHEMA;
cannam@62 59 extern const RawSchema NULL_STRUCT_SCHEMA;
cannam@62 60 extern const RawSchema NULL_ENUM_SCHEMA;
cannam@62 61 extern const RawSchema NULL_INTERFACE_SCHEMA;
cannam@62 62 extern const RawSchema NULL_CONST_SCHEMA;
cannam@62 63 // The schema types default to these null (empty) schemas in case of error, especially when
cannam@62 64 // exceptions are disabled.
cannam@62 65 } // namespace _ (private)
cannam@62 66
cannam@62 67 class Schema {
cannam@62 68 // Convenience wrapper around capnp::schema::Node.
cannam@62 69
cannam@62 70 public:
cannam@62 71 inline Schema(): raw(&_::NULL_SCHEMA.defaultBrand) {}
cannam@62 72
cannam@62 73 template <typename T>
cannam@62 74 static inline SchemaType<T> from() { return SchemaType<T>::template fromImpl<T>(); }
cannam@62 75 // Get the Schema for a particular compiled-in type.
cannam@62 76
cannam@62 77 schema::Node::Reader getProto() const;
cannam@62 78 // Get the underlying Cap'n Proto representation of the schema node. (Note that this accessor
cannam@62 79 // has performance comparable to accessors of struct-typed fields on Reader classes.)
cannam@62 80
cannam@62 81 kj::ArrayPtr<const word> asUncheckedMessage() const;
cannam@62 82 // Get the encoded schema node content as a single message segment. It is safe to read as an
cannam@62 83 // unchecked message.
cannam@62 84
cannam@62 85 Schema getDependency(uint64_t id) const KJ_DEPRECATED("Does not handle generics correctly.");
cannam@62 86 // DEPRECATED: This method cannot correctly account for generic type parameter bindings that
cannam@62 87 // may apply to the dependency. Instead of using this method, use a method of the Schema API
cannam@62 88 // that corresponds to the exact kind of dependency. For example, to get a field type, use
cannam@62 89 // StructSchema::Field::getType().
cannam@62 90 //
cannam@62 91 // Gets the Schema for one of this Schema's dependencies. For example, if this Schema is for a
cannam@62 92 // struct, you could look up the schema for one of its fields' types. Throws an exception if this
cannam@62 93 // schema doesn't actually depend on the given id.
cannam@62 94 //
cannam@62 95 // Note that not all type IDs found in the schema node are considered "dependencies" -- only the
cannam@62 96 // ones that are needed to implement the dynamic API are. That includes:
cannam@62 97 // - Field types.
cannam@62 98 // - Group types.
cannam@62 99 // - scopeId for group nodes, but NOT otherwise.
cannam@62 100 // - Method parameter and return types.
cannam@62 101 //
cannam@62 102 // The following are NOT considered dependencies:
cannam@62 103 // - Nested nodes.
cannam@62 104 // - scopeId for a non-group node.
cannam@62 105 // - Annotations.
cannam@62 106 //
cannam@62 107 // To obtain schemas for those, you would need a SchemaLoader.
cannam@62 108
cannam@62 109 bool isBranded() const;
cannam@62 110 // Returns true if this schema represents a non-default parameterization of this type.
cannam@62 111
cannam@62 112 Schema getGeneric() const;
cannam@62 113 // Get the version of this schema with any brands removed.
cannam@62 114
cannam@62 115 class BrandArgumentList;
cannam@62 116 BrandArgumentList getBrandArgumentsAtScope(uint64_t scopeId) const;
cannam@62 117 // Gets the values bound to the brand parameters at the given scope.
cannam@62 118
cannam@62 119 StructSchema asStruct() const;
cannam@62 120 EnumSchema asEnum() const;
cannam@62 121 InterfaceSchema asInterface() const;
cannam@62 122 ConstSchema asConst() const;
cannam@62 123 // Cast the Schema to a specific type. Throws an exception if the type doesn't match. Use
cannam@62 124 // getProto() to determine type, e.g. getProto().isStruct().
cannam@62 125
cannam@62 126 inline bool operator==(const Schema& other) const { return raw == other.raw; }
cannam@62 127 inline bool operator!=(const Schema& other) const { return raw != other.raw; }
cannam@62 128 // Determine whether two Schemas are wrapping the exact same underlying data, by identity. If
cannam@62 129 // you want to check if two Schemas represent the same type (but possibly different versions of
cannam@62 130 // it), compare their IDs instead.
cannam@62 131
cannam@62 132 template <typename T>
cannam@62 133 void requireUsableAs() const;
cannam@62 134 // Throws an exception if a value with this Schema cannot safely be cast to a native value of
cannam@62 135 // the given type. This passes if either:
cannam@62 136 // - *this == from<T>()
cannam@62 137 // - This schema was loaded with SchemaLoader, the type ID matches typeId<T>(), and
cannam@62 138 // loadCompiledTypeAndDependencies<T>() was called on the SchemaLoader.
cannam@62 139
cannam@62 140 kj::StringPtr getShortDisplayName() const;
cannam@62 141 // Get the short version of the node's display name.
cannam@62 142
cannam@62 143 private:
cannam@62 144 const _::RawBrandedSchema* raw;
cannam@62 145
cannam@62 146 inline explicit Schema(const _::RawBrandedSchema* raw): raw(raw) {
cannam@62 147 KJ_IREQUIRE(raw->lazyInitializer == nullptr,
cannam@62 148 "Must call ensureInitialized() on RawSchema before constructing Schema.");
cannam@62 149 }
cannam@62 150
cannam@62 151 template <typename T> static inline Schema fromImpl() {
cannam@62 152 return Schema(&_::rawSchema<T>());
cannam@62 153 }
cannam@62 154
cannam@62 155 void requireUsableAs(const _::RawSchema* expected) const;
cannam@62 156
cannam@62 157 uint32_t getSchemaOffset(const schema::Value::Reader& value) const;
cannam@62 158
cannam@62 159 Type getBrandBinding(uint64_t scopeId, uint index) const;
cannam@62 160 // Look up the binding for a brand parameter used by this Schema. Returns `AnyPointer` if the
cannam@62 161 // parameter is not bound.
cannam@62 162 //
cannam@62 163 // TODO(someday): Public interface for iterating over all bindings?
cannam@62 164
cannam@62 165 Schema getDependency(uint64_t id, uint location) const;
cannam@62 166 // Look up schema for a particular dependency of this schema. `location` is the dependency
cannam@62 167 // location number as defined in _::RawBrandedSchema.
cannam@62 168
cannam@62 169 Type interpretType(schema::Type::Reader proto, uint location) const;
cannam@62 170 // Interpret a schema::Type in the given location within the schema, compiling it into a
cannam@62 171 // Type object.
cannam@62 172
cannam@62 173 friend class StructSchema;
cannam@62 174 friend class EnumSchema;
cannam@62 175 friend class InterfaceSchema;
cannam@62 176 friend class ConstSchema;
cannam@62 177 friend class ListSchema;
cannam@62 178 friend class SchemaLoader;
cannam@62 179 friend class Type;
cannam@62 180 friend kj::StringTree _::structString(
cannam@62 181 _::StructReader reader, const _::RawBrandedSchema& schema);
cannam@62 182 friend kj::String _::enumString(uint16_t value, const _::RawBrandedSchema& schema);
cannam@62 183 };
cannam@62 184
cannam@62 185 kj::StringPtr KJ_STRINGIFY(const Schema& schema);
cannam@62 186
cannam@62 187 class Schema::BrandArgumentList {
cannam@62 188 // A list of generic parameter bindings for parameters of some particular type. Note that since
cannam@62 189 // parameters on an outer type apply to all inner types as well, a deeply-nested type can have
cannam@62 190 // multiple BrandArgumentLists that apply to it.
cannam@62 191 //
cannam@62 192 // A BrandArgumentList only represents the arguments that the client of the type specified. Since
cannam@62 193 // new parameters can be added over time, this list may not cover all defined parameters for the
cannam@62 194 // type. Missing parameters should be treated as AnyPointer. This class's implementation of
cannam@62 195 // operator[] already does this for you; out-of-bounds access will safely return AnyPointer.
cannam@62 196
cannam@62 197 public:
cannam@62 198 inline BrandArgumentList(): scopeId(0), size_(0), bindings(nullptr) {}
cannam@62 199
cannam@62 200 inline uint size() const { return size_; }
cannam@62 201 Type operator[](uint index) const;
cannam@62 202
cannam@62 203 typedef _::IndexingIterator<const BrandArgumentList, Type> Iterator;
cannam@62 204 inline Iterator begin() const { return Iterator(this, 0); }
cannam@62 205 inline Iterator end() const { return Iterator(this, size()); }
cannam@62 206
cannam@62 207 private:
cannam@62 208 uint64_t scopeId;
cannam@62 209 uint size_;
cannam@62 210 bool isUnbound;
cannam@62 211 const _::RawBrandedSchema::Binding* bindings;
cannam@62 212
cannam@62 213 inline BrandArgumentList(uint64_t scopeId, bool isUnbound)
cannam@62 214 : scopeId(scopeId), size_(0), isUnbound(isUnbound), bindings(nullptr) {}
cannam@62 215 inline BrandArgumentList(uint64_t scopeId, uint size,
cannam@62 216 const _::RawBrandedSchema::Binding* bindings)
cannam@62 217 : scopeId(scopeId), size_(size), isUnbound(false), bindings(bindings) {}
cannam@62 218
cannam@62 219 friend class Schema;
cannam@62 220 };
cannam@62 221
cannam@62 222 // -------------------------------------------------------------------
cannam@62 223
cannam@62 224 class StructSchema: public Schema {
cannam@62 225 public:
cannam@62 226 inline StructSchema(): Schema(&_::NULL_STRUCT_SCHEMA.defaultBrand) {}
cannam@62 227
cannam@62 228 class Field;
cannam@62 229 class FieldList;
cannam@62 230 class FieldSubset;
cannam@62 231
cannam@62 232 FieldList getFields() const;
cannam@62 233 // List top-level fields of this struct. This list will contain top-level groups (including
cannam@62 234 // named unions) but not the members of those groups. The list does, however, contain the
cannam@62 235 // members of the unnamed union, if there is one.
cannam@62 236
cannam@62 237 FieldSubset getUnionFields() const;
cannam@62 238 // If the field contains an unnamed union, get a list of fields in the union, ordered by
cannam@62 239 // ordinal. Since discriminant values are assigned sequentially by ordinal, you may index this
cannam@62 240 // list by discriminant value.
cannam@62 241
cannam@62 242 FieldSubset getNonUnionFields() const;
cannam@62 243 // Get the fields of this struct which are not in an unnamed union, ordered by ordinal.
cannam@62 244
cannam@62 245 kj::Maybe<Field> findFieldByName(kj::StringPtr name) const;
cannam@62 246 // Find the field with the given name, or return null if there is no such field. If the struct
cannam@62 247 // contains an unnamed union, then this will find fields of that union in addition to fields
cannam@62 248 // of the outer struct, since they exist in the same namespace. It will not, however, find
cannam@62 249 // members of groups (including named unions) -- you must first look up the group itself,
cannam@62 250 // then dig into its type.
cannam@62 251
cannam@62 252 Field getFieldByName(kj::StringPtr name) const;
cannam@62 253 // Like findFieldByName() but throws an exception on failure.
cannam@62 254
cannam@62 255 kj::Maybe<Field> getFieldByDiscriminant(uint16_t discriminant) const;
cannam@62 256 // Finds the field whose `discriminantValue` is equal to the given value, or returns null if
cannam@62 257 // there is no such field. (If the schema does not represent a union or a struct containing
cannam@62 258 // an unnamed union, then this always returns null.)
cannam@62 259
cannam@62 260 private:
cannam@62 261 StructSchema(Schema base): Schema(base) {}
cannam@62 262 template <typename T> static inline StructSchema fromImpl() {
cannam@62 263 return StructSchema(Schema(&_::rawBrandedSchema<T>()));
cannam@62 264 }
cannam@62 265 friend class Schema;
cannam@62 266 friend class Type;
cannam@62 267 };
cannam@62 268
cannam@62 269 class StructSchema::Field {
cannam@62 270 public:
cannam@62 271 Field() = default;
cannam@62 272
cannam@62 273 inline schema::Field::Reader getProto() const { return proto; }
cannam@62 274 inline StructSchema getContainingStruct() const { return parent; }
cannam@62 275
cannam@62 276 inline uint getIndex() const { return index; }
cannam@62 277 // Get the index of this field within the containing struct or union.
cannam@62 278
cannam@62 279 Type getType() const;
cannam@62 280 // Get the type of this field. Note that this is preferred over getProto().getType() as this
cannam@62 281 // method will apply generics.
cannam@62 282
cannam@62 283 uint32_t getDefaultValueSchemaOffset() const;
cannam@62 284 // For struct, list, and object fields, returns the offset, in words, within the first segment of
cannam@62 285 // the struct's schema, where this field's default value pointer is located. The schema is
cannam@62 286 // always stored as a single-segment unchecked message, which in turn means that the default
cannam@62 287 // value pointer itself can be treated as the root of an unchecked message -- if you know where
cannam@62 288 // to find it, which is what this method helps you with.
cannam@62 289 //
cannam@62 290 // For blobs, returns the offset of the beginning of the blob's content within the first segment
cannam@62 291 // of the struct's schema.
cannam@62 292 //
cannam@62 293 // This is primarily useful for code generators. The C++ code generator, for example, embeds
cannam@62 294 // the entire schema as a raw word array within the generated code. Of course, to implement
cannam@62 295 // field accessors, it needs access to those fields' default values. Embedding separate copies
cannam@62 296 // of those default values would be redundant since they are already included in the schema, but
cannam@62 297 // seeking through the schema at runtime to find the default values would be ugly. Instead,
cannam@62 298 // the code generator can use getDefaultValueSchemaOffset() to find the offset of the default
cannam@62 299 // value within the schema, and can simply apply that offset at runtime.
cannam@62 300 //
cannam@62 301 // If the above does not make sense, you probably don't need this method.
cannam@62 302
cannam@62 303 inline bool operator==(const Field& other) const;
cannam@62 304 inline bool operator!=(const Field& other) const { return !(*this == other); }
cannam@62 305
cannam@62 306 private:
cannam@62 307 StructSchema parent;
cannam@62 308 uint index;
cannam@62 309 schema::Field::Reader proto;
cannam@62 310
cannam@62 311 inline Field(StructSchema parent, uint index, schema::Field::Reader proto)
cannam@62 312 : parent(parent), index(index), proto(proto) {}
cannam@62 313
cannam@62 314 friend class StructSchema;
cannam@62 315 };
cannam@62 316
cannam@62 317 kj::StringPtr KJ_STRINGIFY(const StructSchema::Field& field);
cannam@62 318
cannam@62 319 class StructSchema::FieldList {
cannam@62 320 public:
cannam@62 321 FieldList() = default; // empty list
cannam@62 322
cannam@62 323 inline uint size() const { return list.size(); }
cannam@62 324 inline Field operator[](uint index) const { return Field(parent, index, list[index]); }
cannam@62 325
cannam@62 326 typedef _::IndexingIterator<const FieldList, Field> Iterator;
cannam@62 327 inline Iterator begin() const { return Iterator(this, 0); }
cannam@62 328 inline Iterator end() const { return Iterator(this, size()); }
cannam@62 329
cannam@62 330 private:
cannam@62 331 StructSchema parent;
cannam@62 332 List<schema::Field>::Reader list;
cannam@62 333
cannam@62 334 inline FieldList(StructSchema parent, List<schema::Field>::Reader list)
cannam@62 335 : parent(parent), list(list) {}
cannam@62 336
cannam@62 337 friend class StructSchema;
cannam@62 338 };
cannam@62 339
cannam@62 340 class StructSchema::FieldSubset {
cannam@62 341 public:
cannam@62 342 FieldSubset() = default; // empty list
cannam@62 343
cannam@62 344 inline uint size() const { return size_; }
cannam@62 345 inline Field operator[](uint index) const {
cannam@62 346 return Field(parent, indices[index], list[indices[index]]);
cannam@62 347 }
cannam@62 348
cannam@62 349 typedef _::IndexingIterator<const FieldSubset, Field> Iterator;
cannam@62 350 inline Iterator begin() const { return Iterator(this, 0); }
cannam@62 351 inline Iterator end() const { return Iterator(this, size()); }
cannam@62 352
cannam@62 353 private:
cannam@62 354 StructSchema parent;
cannam@62 355 List<schema::Field>::Reader list;
cannam@62 356 const uint16_t* indices;
cannam@62 357 uint size_;
cannam@62 358
cannam@62 359 inline FieldSubset(StructSchema parent, List<schema::Field>::Reader list,
cannam@62 360 const uint16_t* indices, uint size)
cannam@62 361 : parent(parent), list(list), indices(indices), size_(size) {}
cannam@62 362
cannam@62 363 friend class StructSchema;
cannam@62 364 };
cannam@62 365
cannam@62 366 // -------------------------------------------------------------------
cannam@62 367
cannam@62 368 class EnumSchema: public Schema {
cannam@62 369 public:
cannam@62 370 inline EnumSchema(): Schema(&_::NULL_ENUM_SCHEMA.defaultBrand) {}
cannam@62 371
cannam@62 372 class Enumerant;
cannam@62 373 class EnumerantList;
cannam@62 374
cannam@62 375 EnumerantList getEnumerants() const;
cannam@62 376
cannam@62 377 kj::Maybe<Enumerant> findEnumerantByName(kj::StringPtr name) const;
cannam@62 378
cannam@62 379 Enumerant getEnumerantByName(kj::StringPtr name) const;
cannam@62 380 // Like findEnumerantByName() but throws an exception on failure.
cannam@62 381
cannam@62 382 private:
cannam@62 383 EnumSchema(Schema base): Schema(base) {}
cannam@62 384 template <typename T> static inline EnumSchema fromImpl() {
cannam@62 385 return EnumSchema(Schema(&_::rawBrandedSchema<T>()));
cannam@62 386 }
cannam@62 387 friend class Schema;
cannam@62 388 friend class Type;
cannam@62 389 };
cannam@62 390
cannam@62 391 class EnumSchema::Enumerant {
cannam@62 392 public:
cannam@62 393 Enumerant() = default;
cannam@62 394
cannam@62 395 inline schema::Enumerant::Reader getProto() const { return proto; }
cannam@62 396 inline EnumSchema getContainingEnum() const { return parent; }
cannam@62 397
cannam@62 398 inline uint16_t getOrdinal() const { return ordinal; }
cannam@62 399 inline uint getIndex() const { return ordinal; }
cannam@62 400
cannam@62 401 inline bool operator==(const Enumerant& other) const;
cannam@62 402 inline bool operator!=(const Enumerant& other) const { return !(*this == other); }
cannam@62 403
cannam@62 404 private:
cannam@62 405 EnumSchema parent;
cannam@62 406 uint16_t ordinal;
cannam@62 407 schema::Enumerant::Reader proto;
cannam@62 408
cannam@62 409 inline Enumerant(EnumSchema parent, uint16_t ordinal, schema::Enumerant::Reader proto)
cannam@62 410 : parent(parent), ordinal(ordinal), proto(proto) {}
cannam@62 411
cannam@62 412 friend class EnumSchema;
cannam@62 413 };
cannam@62 414
cannam@62 415 class EnumSchema::EnumerantList {
cannam@62 416 public:
cannam@62 417 EnumerantList() = default; // empty list
cannam@62 418
cannam@62 419 inline uint size() const { return list.size(); }
cannam@62 420 inline Enumerant operator[](uint index) const { return Enumerant(parent, index, list[index]); }
cannam@62 421
cannam@62 422 typedef _::IndexingIterator<const EnumerantList, Enumerant> Iterator;
cannam@62 423 inline Iterator begin() const { return Iterator(this, 0); }
cannam@62 424 inline Iterator end() const { return Iterator(this, size()); }
cannam@62 425
cannam@62 426 private:
cannam@62 427 EnumSchema parent;
cannam@62 428 List<schema::Enumerant>::Reader list;
cannam@62 429
cannam@62 430 inline EnumerantList(EnumSchema parent, List<schema::Enumerant>::Reader list)
cannam@62 431 : parent(parent), list(list) {}
cannam@62 432
cannam@62 433 friend class EnumSchema;
cannam@62 434 };
cannam@62 435
cannam@62 436 // -------------------------------------------------------------------
cannam@62 437
cannam@62 438 class InterfaceSchema: public Schema {
cannam@62 439 public:
cannam@62 440 inline InterfaceSchema(): Schema(&_::NULL_INTERFACE_SCHEMA.defaultBrand) {}
cannam@62 441
cannam@62 442 class Method;
cannam@62 443 class MethodList;
cannam@62 444
cannam@62 445 MethodList getMethods() const;
cannam@62 446
cannam@62 447 kj::Maybe<Method> findMethodByName(kj::StringPtr name) const;
cannam@62 448
cannam@62 449 Method getMethodByName(kj::StringPtr name) const;
cannam@62 450 // Like findMethodByName() but throws an exception on failure.
cannam@62 451
cannam@62 452 class SuperclassList;
cannam@62 453
cannam@62 454 SuperclassList getSuperclasses() const;
cannam@62 455 // Get the immediate superclasses of this type, after applying generics.
cannam@62 456
cannam@62 457 bool extends(InterfaceSchema other) const;
cannam@62 458 // Returns true if `other` is a superclass of this interface (including if `other == *this`).
cannam@62 459
cannam@62 460 kj::Maybe<InterfaceSchema> findSuperclass(uint64_t typeId) const;
cannam@62 461 // Find the superclass of this interface with the given type ID. Returns null if the interface
cannam@62 462 // extends no such type.
cannam@62 463
cannam@62 464 private:
cannam@62 465 InterfaceSchema(Schema base): Schema(base) {}
cannam@62 466 template <typename T> static inline InterfaceSchema fromImpl() {
cannam@62 467 return InterfaceSchema(Schema(&_::rawBrandedSchema<T>()));
cannam@62 468 }
cannam@62 469 friend class Schema;
cannam@62 470 friend class Type;
cannam@62 471
cannam@62 472 kj::Maybe<Method> findMethodByName(kj::StringPtr name, uint& counter) const;
cannam@62 473 bool extends(InterfaceSchema other, uint& counter) const;
cannam@62 474 kj::Maybe<InterfaceSchema> findSuperclass(uint64_t typeId, uint& counter) const;
cannam@62 475 // We protect against malicious schemas with large or cyclic hierarchies by cutting off the
cannam@62 476 // search when the counter reaches a threshold.
cannam@62 477 };
cannam@62 478
cannam@62 479 class InterfaceSchema::Method {
cannam@62 480 public:
cannam@62 481 Method() = default;
cannam@62 482
cannam@62 483 inline schema::Method::Reader getProto() const { return proto; }
cannam@62 484 inline InterfaceSchema getContainingInterface() const { return parent; }
cannam@62 485
cannam@62 486 inline uint16_t getOrdinal() const { return ordinal; }
cannam@62 487 inline uint getIndex() const { return ordinal; }
cannam@62 488
cannam@62 489 StructSchema getParamType() const;
cannam@62 490 StructSchema getResultType() const;
cannam@62 491 // Get the parameter and result types, including substituting generic parameters.
cannam@62 492
cannam@62 493 inline bool operator==(const Method& other) const;
cannam@62 494 inline bool operator!=(const Method& other) const { return !(*this == other); }
cannam@62 495
cannam@62 496 private:
cannam@62 497 InterfaceSchema parent;
cannam@62 498 uint16_t ordinal;
cannam@62 499 schema::Method::Reader proto;
cannam@62 500
cannam@62 501 inline Method(InterfaceSchema parent, uint16_t ordinal,
cannam@62 502 schema::Method::Reader proto)
cannam@62 503 : parent(parent), ordinal(ordinal), proto(proto) {}
cannam@62 504
cannam@62 505 friend class InterfaceSchema;
cannam@62 506 };
cannam@62 507
cannam@62 508 class InterfaceSchema::MethodList {
cannam@62 509 public:
cannam@62 510 MethodList() = default; // empty list
cannam@62 511
cannam@62 512 inline uint size() const { return list.size(); }
cannam@62 513 inline Method operator[](uint index) const { return Method(parent, index, list[index]); }
cannam@62 514
cannam@62 515 typedef _::IndexingIterator<const MethodList, Method> Iterator;
cannam@62 516 inline Iterator begin() const { return Iterator(this, 0); }
cannam@62 517 inline Iterator end() const { return Iterator(this, size()); }
cannam@62 518
cannam@62 519 private:
cannam@62 520 InterfaceSchema parent;
cannam@62 521 List<schema::Method>::Reader list;
cannam@62 522
cannam@62 523 inline MethodList(InterfaceSchema parent, List<schema::Method>::Reader list)
cannam@62 524 : parent(parent), list(list) {}
cannam@62 525
cannam@62 526 friend class InterfaceSchema;
cannam@62 527 };
cannam@62 528
cannam@62 529 class InterfaceSchema::SuperclassList {
cannam@62 530 public:
cannam@62 531 SuperclassList() = default; // empty list
cannam@62 532
cannam@62 533 inline uint size() const { return list.size(); }
cannam@62 534 InterfaceSchema operator[](uint index) const;
cannam@62 535
cannam@62 536 typedef _::IndexingIterator<const SuperclassList, InterfaceSchema> Iterator;
cannam@62 537 inline Iterator begin() const { return Iterator(this, 0); }
cannam@62 538 inline Iterator end() const { return Iterator(this, size()); }
cannam@62 539
cannam@62 540 private:
cannam@62 541 InterfaceSchema parent;
cannam@62 542 List<schema::Superclass>::Reader list;
cannam@62 543
cannam@62 544 inline SuperclassList(InterfaceSchema parent, List<schema::Superclass>::Reader list)
cannam@62 545 : parent(parent), list(list) {}
cannam@62 546
cannam@62 547 friend class InterfaceSchema;
cannam@62 548 };
cannam@62 549
cannam@62 550 // -------------------------------------------------------------------
cannam@62 551
cannam@62 552 class ConstSchema: public Schema {
cannam@62 553 // Represents a constant declaration.
cannam@62 554 //
cannam@62 555 // `ConstSchema` can be implicitly cast to DynamicValue to read its value.
cannam@62 556
cannam@62 557 public:
cannam@62 558 inline ConstSchema(): Schema(&_::NULL_CONST_SCHEMA.defaultBrand) {}
cannam@62 559
cannam@62 560 template <typename T>
cannam@62 561 ReaderFor<T> as() const;
cannam@62 562 // Read the constant's value. This is a convenience method equivalent to casting the ConstSchema
cannam@62 563 // to a DynamicValue and then calling its `as<T>()` method. For dependency reasons, this method
cannam@62 564 // is defined in <capnp/dynamic.h>, which you must #include explicitly.
cannam@62 565
cannam@62 566 uint32_t getValueSchemaOffset() const;
cannam@62 567 // Much like StructSchema::Field::getDefaultValueSchemaOffset(), if the constant has pointer
cannam@62 568 // type, this gets the offset from the beginning of the constant's schema node to a pointer
cannam@62 569 // representing the constant value.
cannam@62 570
cannam@62 571 Type getType() const;
cannam@62 572
cannam@62 573 private:
cannam@62 574 ConstSchema(Schema base): Schema(base) {}
cannam@62 575 friend class Schema;
cannam@62 576 };
cannam@62 577
cannam@62 578 // -------------------------------------------------------------------
cannam@62 579
cannam@62 580 class Type {
cannam@62 581 public:
cannam@62 582 struct BrandParameter {
cannam@62 583 uint64_t scopeId;
cannam@62 584 uint index;
cannam@62 585 };
cannam@62 586 struct ImplicitParameter {
cannam@62 587 uint index;
cannam@62 588 };
cannam@62 589
cannam@62 590 inline Type();
cannam@62 591 inline Type(schema::Type::Which primitive);
cannam@62 592 inline Type(StructSchema schema);
cannam@62 593 inline Type(EnumSchema schema);
cannam@62 594 inline Type(InterfaceSchema schema);
cannam@62 595 inline Type(ListSchema schema);
cannam@62 596 inline Type(schema::Type::AnyPointer::Unconstrained::Which anyPointerKind);
cannam@62 597 inline Type(BrandParameter param);
cannam@62 598 inline Type(ImplicitParameter param);
cannam@62 599
cannam@62 600 template <typename T>
cannam@62 601 inline static Type from();
cannam@62 602
cannam@62 603 inline schema::Type::Which which() const;
cannam@62 604
cannam@62 605 StructSchema asStruct() const;
cannam@62 606 EnumSchema asEnum() const;
cannam@62 607 InterfaceSchema asInterface() const;
cannam@62 608 ListSchema asList() const;
cannam@62 609 // Each of these methods may only be called if which() returns the corresponding type.
cannam@62 610
cannam@62 611 kj::Maybe<BrandParameter> getBrandParameter() const;
cannam@62 612 // Only callable if which() returns ANY_POINTER. Returns null if the type is just a regular
cannam@62 613 // AnyPointer and not a parameter.
cannam@62 614
cannam@62 615 kj::Maybe<ImplicitParameter> getImplicitParameter() const;
cannam@62 616 // Only callable if which() returns ANY_POINTER. Returns null if the type is just a regular
cannam@62 617 // AnyPointer and not a parameter. "Implicit parameters" refer to type parameters on methods.
cannam@62 618
cannam@62 619 inline schema::Type::AnyPointer::Unconstrained::Which whichAnyPointerKind() const;
cannam@62 620 // Only callable if which() returns ANY_POINTER.
cannam@62 621
cannam@62 622 inline bool isVoid() const;
cannam@62 623 inline bool isBool() const;
cannam@62 624 inline bool isInt8() const;
cannam@62 625 inline bool isInt16() const;
cannam@62 626 inline bool isInt32() const;
cannam@62 627 inline bool isInt64() const;
cannam@62 628 inline bool isUInt8() const;
cannam@62 629 inline bool isUInt16() const;
cannam@62 630 inline bool isUInt32() const;
cannam@62 631 inline bool isUInt64() const;
cannam@62 632 inline bool isFloat32() const;
cannam@62 633 inline bool isFloat64() const;
cannam@62 634 inline bool isText() const;
cannam@62 635 inline bool isData() const;
cannam@62 636 inline bool isList() const;
cannam@62 637 inline bool isEnum() const;
cannam@62 638 inline bool isStruct() const;
cannam@62 639 inline bool isInterface() const;
cannam@62 640 inline bool isAnyPointer() const;
cannam@62 641
cannam@62 642 bool operator==(const Type& other) const;
cannam@62 643 inline bool operator!=(const Type& other) const { return !(*this == other); }
cannam@62 644
cannam@62 645 size_t hashCode() const;
cannam@62 646
cannam@62 647 inline Type wrapInList(uint depth = 1) const;
cannam@62 648 // Return the Type formed by wrapping this type in List() `depth` times.
cannam@62 649
cannam@62 650 inline Type(schema::Type::Which derived, const _::RawBrandedSchema* schema);
cannam@62 651 // For internal use.
cannam@62 652
cannam@62 653 private:
cannam@62 654 schema::Type::Which baseType; // type not including applications of List()
cannam@62 655 uint8_t listDepth; // 0 for T, 1 for List(T), 2 for List(List(T)), ...
cannam@62 656
cannam@62 657 bool isImplicitParam;
cannam@62 658 // If true, this refers to an implicit method parameter. baseType must be ANY_POINTER, scopeId
cannam@62 659 // must be zero, and paramIndex indicates the parameter index.
cannam@62 660
cannam@62 661 union {
cannam@62 662 uint16_t paramIndex;
cannam@62 663 // If baseType is ANY_POINTER but this Type actually refers to a type parameter, this is the
cannam@62 664 // index of the parameter among the parameters at its scope, and `scopeId` below is the type ID
cannam@62 665 // of the scope where the parameter was defined.
cannam@62 666
cannam@62 667 schema::Type::AnyPointer::Unconstrained::Which anyPointerKind;
cannam@62 668 // If scopeId is zero and isImplicitParam is false.
cannam@62 669 };
cannam@62 670
cannam@62 671 union {
cannam@62 672 const _::RawBrandedSchema* schema; // if type is struct, enum, interface...
cannam@62 673 uint64_t scopeId; // if type is AnyPointer but it's actually a type parameter...
cannam@62 674 };
cannam@62 675
cannam@62 676 Type(schema::Type::Which baseType, uint8_t listDepth, const _::RawBrandedSchema* schema)
cannam@62 677 : baseType(baseType), listDepth(listDepth), schema(schema) {
cannam@62 678 KJ_IREQUIRE(baseType != schema::Type::ANY_POINTER);
cannam@62 679 }
cannam@62 680
cannam@62 681 void requireUsableAs(Type expected) const;
cannam@62 682
cannam@62 683 friend class ListSchema; // only for requireUsableAs()
cannam@62 684 };
cannam@62 685
cannam@62 686 // -------------------------------------------------------------------
cannam@62 687
cannam@62 688 class ListSchema {
cannam@62 689 // ListSchema is a little different because list types are not described by schema nodes. So,
cannam@62 690 // ListSchema doesn't subclass Schema.
cannam@62 691
cannam@62 692 public:
cannam@62 693 ListSchema() = default;
cannam@62 694
cannam@62 695 static ListSchema of(schema::Type::Which primitiveType);
cannam@62 696 static ListSchema of(StructSchema elementType);
cannam@62 697 static ListSchema of(EnumSchema elementType);
cannam@62 698 static ListSchema of(InterfaceSchema elementType);
cannam@62 699 static ListSchema of(ListSchema elementType);
cannam@62 700 static ListSchema of(Type elementType);
cannam@62 701 // Construct the schema for a list of the given type.
cannam@62 702
cannam@62 703 static ListSchema of(schema::Type::Reader elementType, Schema context)
cannam@62 704 KJ_DEPRECATED("Does not handle generics correctly.");
cannam@62 705 // DEPRECATED: This method cannot correctly account for generic type parameter bindings that
cannam@62 706 // may apply to the input type. Instead of using this method, use a method of the Schema API
cannam@62 707 // that corresponds to the exact kind of dependency. For example, to get a field type, use
cannam@62 708 // StructSchema::Field::getType().
cannam@62 709 //
cannam@62 710 // Construct from an element type schema. Requires a context which can handle getDependency()
cannam@62 711 // requests for any type ID found in the schema.
cannam@62 712
cannam@62 713 Type getElementType() const;
cannam@62 714
cannam@62 715 inline schema::Type::Which whichElementType() const;
cannam@62 716 // Get the element type's "which()". ListSchema does not actually store a schema::Type::Reader
cannam@62 717 // describing the element type, but if it did, this would be equivalent to calling
cannam@62 718 // .getBody().which() on that type.
cannam@62 719
cannam@62 720 StructSchema getStructElementType() const;
cannam@62 721 EnumSchema getEnumElementType() const;
cannam@62 722 InterfaceSchema getInterfaceElementType() const;
cannam@62 723 ListSchema getListElementType() const;
cannam@62 724 // Get the schema for complex element types. Each of these throws an exception if the element
cannam@62 725 // type is not of the requested kind.
cannam@62 726
cannam@62 727 inline bool operator==(const ListSchema& other) const { return elementType == other.elementType; }
cannam@62 728 inline bool operator!=(const ListSchema& other) const { return elementType != other.elementType; }
cannam@62 729
cannam@62 730 template <typename T>
cannam@62 731 void requireUsableAs() const;
cannam@62 732
cannam@62 733 private:
cannam@62 734 Type elementType;
cannam@62 735
cannam@62 736 inline explicit ListSchema(Type elementType): elementType(elementType) {}
cannam@62 737
cannam@62 738 template <typename T>
cannam@62 739 struct FromImpl;
cannam@62 740 template <typename T> static inline ListSchema fromImpl() {
cannam@62 741 return FromImpl<T>::get();
cannam@62 742 }
cannam@62 743
cannam@62 744 void requireUsableAs(ListSchema expected) const;
cannam@62 745
cannam@62 746 friend class Schema;
cannam@62 747 };
cannam@62 748
cannam@62 749 // =======================================================================================
cannam@62 750 // inline implementation
cannam@62 751
cannam@62 752 template <> inline schema::Type::Which Schema::from<Void>() { return schema::Type::VOID; }
cannam@62 753 template <> inline schema::Type::Which Schema::from<bool>() { return schema::Type::BOOL; }
cannam@62 754 template <> inline schema::Type::Which Schema::from<int8_t>() { return schema::Type::INT8; }
cannam@62 755 template <> inline schema::Type::Which Schema::from<int16_t>() { return schema::Type::INT16; }
cannam@62 756 template <> inline schema::Type::Which Schema::from<int32_t>() { return schema::Type::INT32; }
cannam@62 757 template <> inline schema::Type::Which Schema::from<int64_t>() { return schema::Type::INT64; }
cannam@62 758 template <> inline schema::Type::Which Schema::from<uint8_t>() { return schema::Type::UINT8; }
cannam@62 759 template <> inline schema::Type::Which Schema::from<uint16_t>() { return schema::Type::UINT16; }
cannam@62 760 template <> inline schema::Type::Which Schema::from<uint32_t>() { return schema::Type::UINT32; }
cannam@62 761 template <> inline schema::Type::Which Schema::from<uint64_t>() { return schema::Type::UINT64; }
cannam@62 762 template <> inline schema::Type::Which Schema::from<float>() { return schema::Type::FLOAT32; }
cannam@62 763 template <> inline schema::Type::Which Schema::from<double>() { return schema::Type::FLOAT64; }
cannam@62 764 template <> inline schema::Type::Which Schema::from<Text>() { return schema::Type::TEXT; }
cannam@62 765 template <> inline schema::Type::Which Schema::from<Data>() { return schema::Type::DATA; }
cannam@62 766
cannam@62 767 inline Schema Schema::getDependency(uint64_t id) const {
cannam@62 768 return getDependency(id, 0);
cannam@62 769 }
cannam@62 770
cannam@62 771 inline bool Schema::isBranded() const {
cannam@62 772 return raw != &raw->generic->defaultBrand;
cannam@62 773 }
cannam@62 774
cannam@62 775 inline Schema Schema::getGeneric() const {
cannam@62 776 return Schema(&raw->generic->defaultBrand);
cannam@62 777 }
cannam@62 778
cannam@62 779 template <typename T>
cannam@62 780 inline void Schema::requireUsableAs() const {
cannam@62 781 requireUsableAs(&_::rawSchema<T>());
cannam@62 782 }
cannam@62 783
cannam@62 784 inline bool StructSchema::Field::operator==(const Field& other) const {
cannam@62 785 return parent == other.parent && index == other.index;
cannam@62 786 }
cannam@62 787 inline bool EnumSchema::Enumerant::operator==(const Enumerant& other) const {
cannam@62 788 return parent == other.parent && ordinal == other.ordinal;
cannam@62 789 }
cannam@62 790 inline bool InterfaceSchema::Method::operator==(const Method& other) const {
cannam@62 791 return parent == other.parent && ordinal == other.ordinal;
cannam@62 792 }
cannam@62 793
cannam@62 794 inline ListSchema ListSchema::of(StructSchema elementType) {
cannam@62 795 return ListSchema(Type(elementType));
cannam@62 796 }
cannam@62 797 inline ListSchema ListSchema::of(EnumSchema elementType) {
cannam@62 798 return ListSchema(Type(elementType));
cannam@62 799 }
cannam@62 800 inline ListSchema ListSchema::of(InterfaceSchema elementType) {
cannam@62 801 return ListSchema(Type(elementType));
cannam@62 802 }
cannam@62 803 inline ListSchema ListSchema::of(ListSchema elementType) {
cannam@62 804 return ListSchema(Type(elementType));
cannam@62 805 }
cannam@62 806 inline ListSchema ListSchema::of(Type elementType) {
cannam@62 807 return ListSchema(elementType);
cannam@62 808 }
cannam@62 809
cannam@62 810 inline Type ListSchema::getElementType() const {
cannam@62 811 return elementType;
cannam@62 812 }
cannam@62 813
cannam@62 814 inline schema::Type::Which ListSchema::whichElementType() const {
cannam@62 815 return elementType.which();
cannam@62 816 }
cannam@62 817
cannam@62 818 inline StructSchema ListSchema::getStructElementType() const {
cannam@62 819 return elementType.asStruct();
cannam@62 820 }
cannam@62 821
cannam@62 822 inline EnumSchema ListSchema::getEnumElementType() const {
cannam@62 823 return elementType.asEnum();
cannam@62 824 }
cannam@62 825
cannam@62 826 inline InterfaceSchema ListSchema::getInterfaceElementType() const {
cannam@62 827 return elementType.asInterface();
cannam@62 828 }
cannam@62 829
cannam@62 830 inline ListSchema ListSchema::getListElementType() const {
cannam@62 831 return elementType.asList();
cannam@62 832 }
cannam@62 833
cannam@62 834 template <typename T>
cannam@62 835 inline void ListSchema::requireUsableAs() const {
cannam@62 836 static_assert(kind<T>() == Kind::LIST,
cannam@62 837 "ListSchema::requireUsableAs<T>() requires T is a list type.");
cannam@62 838 requireUsableAs(Schema::from<T>());
cannam@62 839 }
cannam@62 840
cannam@62 841 inline void ListSchema::requireUsableAs(ListSchema expected) const {
cannam@62 842 elementType.requireUsableAs(expected.elementType);
cannam@62 843 }
cannam@62 844
cannam@62 845 template <typename T>
cannam@62 846 struct ListSchema::FromImpl<List<T>> {
cannam@62 847 static inline ListSchema get() { return of(Schema::from<T>()); }
cannam@62 848 };
cannam@62 849
cannam@62 850 inline Type::Type(): baseType(schema::Type::VOID), listDepth(0), schema(nullptr) {}
cannam@62 851 inline Type::Type(schema::Type::Which primitive)
cannam@62 852 : baseType(primitive), listDepth(0), isImplicitParam(false) {
cannam@62 853 KJ_IREQUIRE(primitive != schema::Type::STRUCT &&
cannam@62 854 primitive != schema::Type::ENUM &&
cannam@62 855 primitive != schema::Type::INTERFACE &&
cannam@62 856 primitive != schema::Type::LIST);
cannam@62 857 if (primitive == schema::Type::ANY_POINTER) {
cannam@62 858 scopeId = 0;
cannam@62 859 anyPointerKind = schema::Type::AnyPointer::Unconstrained::ANY_KIND;
cannam@62 860 } else {
cannam@62 861 schema = nullptr;
cannam@62 862 }
cannam@62 863 }
cannam@62 864 inline Type::Type(schema::Type::Which derived, const _::RawBrandedSchema* schema)
cannam@62 865 : baseType(derived), listDepth(0), isImplicitParam(false), schema(schema) {
cannam@62 866 KJ_IREQUIRE(derived == schema::Type::STRUCT ||
cannam@62 867 derived == schema::Type::ENUM ||
cannam@62 868 derived == schema::Type::INTERFACE);
cannam@62 869 }
cannam@62 870
cannam@62 871 inline Type::Type(StructSchema schema)
cannam@62 872 : baseType(schema::Type::STRUCT), listDepth(0), schema(schema.raw) {}
cannam@62 873 inline Type::Type(EnumSchema schema)
cannam@62 874 : baseType(schema::Type::ENUM), listDepth(0), schema(schema.raw) {}
cannam@62 875 inline Type::Type(InterfaceSchema schema)
cannam@62 876 : baseType(schema::Type::INTERFACE), listDepth(0), schema(schema.raw) {}
cannam@62 877 inline Type::Type(ListSchema schema)
cannam@62 878 : Type(schema.getElementType()) { ++listDepth; }
cannam@62 879 inline Type::Type(schema::Type::AnyPointer::Unconstrained::Which anyPointerKind)
cannam@62 880 : baseType(schema::Type::ANY_POINTER), listDepth(0), isImplicitParam(false),
cannam@62 881 anyPointerKind(anyPointerKind), scopeId(0) {}
cannam@62 882 inline Type::Type(BrandParameter param)
cannam@62 883 : baseType(schema::Type::ANY_POINTER), listDepth(0), isImplicitParam(false),
cannam@62 884 paramIndex(param.index), scopeId(param.scopeId) {}
cannam@62 885 inline Type::Type(ImplicitParameter param)
cannam@62 886 : baseType(schema::Type::ANY_POINTER), listDepth(0), isImplicitParam(true),
cannam@62 887 paramIndex(param.index), scopeId(0) {}
cannam@62 888
cannam@62 889 inline schema::Type::Which Type::which() const {
cannam@62 890 return listDepth > 0 ? schema::Type::LIST : baseType;
cannam@62 891 }
cannam@62 892
cannam@62 893 inline schema::Type::AnyPointer::Unconstrained::Which Type::whichAnyPointerKind() const {
cannam@62 894 KJ_IREQUIRE(baseType == schema::Type::ANY_POINTER);
cannam@62 895 return !isImplicitParam && scopeId == 0 ? anyPointerKind
cannam@62 896 : schema::Type::AnyPointer::Unconstrained::ANY_KIND;
cannam@62 897 }
cannam@62 898
cannam@62 899 template <typename T>
cannam@62 900 inline Type Type::from() { return Type(Schema::from<T>()); }
cannam@62 901
cannam@62 902 inline bool Type::isVoid () const { return baseType == schema::Type::VOID && listDepth == 0; }
cannam@62 903 inline bool Type::isBool () const { return baseType == schema::Type::BOOL && listDepth == 0; }
cannam@62 904 inline bool Type::isInt8 () const { return baseType == schema::Type::INT8 && listDepth == 0; }
cannam@62 905 inline bool Type::isInt16 () const { return baseType == schema::Type::INT16 && listDepth == 0; }
cannam@62 906 inline bool Type::isInt32 () const { return baseType == schema::Type::INT32 && listDepth == 0; }
cannam@62 907 inline bool Type::isInt64 () const { return baseType == schema::Type::INT64 && listDepth == 0; }
cannam@62 908 inline bool Type::isUInt8 () const { return baseType == schema::Type::UINT8 && listDepth == 0; }
cannam@62 909 inline bool Type::isUInt16 () const { return baseType == schema::Type::UINT16 && listDepth == 0; }
cannam@62 910 inline bool Type::isUInt32 () const { return baseType == schema::Type::UINT32 && listDepth == 0; }
cannam@62 911 inline bool Type::isUInt64 () const { return baseType == schema::Type::UINT64 && listDepth == 0; }
cannam@62 912 inline bool Type::isFloat32() const { return baseType == schema::Type::FLOAT32 && listDepth == 0; }
cannam@62 913 inline bool Type::isFloat64() const { return baseType == schema::Type::FLOAT64 && listDepth == 0; }
cannam@62 914 inline bool Type::isText () const { return baseType == schema::Type::TEXT && listDepth == 0; }
cannam@62 915 inline bool Type::isData () const { return baseType == schema::Type::DATA && listDepth == 0; }
cannam@62 916 inline bool Type::isList () const { return listDepth > 0; }
cannam@62 917 inline bool Type::isEnum () const { return baseType == schema::Type::ENUM && listDepth == 0; }
cannam@62 918 inline bool Type::isStruct () const { return baseType == schema::Type::STRUCT && listDepth == 0; }
cannam@62 919 inline bool Type::isInterface() const {
cannam@62 920 return baseType == schema::Type::INTERFACE && listDepth == 0;
cannam@62 921 }
cannam@62 922 inline bool Type::isAnyPointer() const {
cannam@62 923 return baseType == schema::Type::ANY_POINTER && listDepth == 0;
cannam@62 924 }
cannam@62 925
cannam@62 926 inline Type Type::wrapInList(uint depth) const {
cannam@62 927 Type result = *this;
cannam@62 928 result.listDepth += depth;
cannam@62 929 return result;
cannam@62 930 }
cannam@62 931
cannam@62 932 } // namespace capnp
cannam@62 933
cannam@62 934 #endif // CAPNP_SCHEMA_H_