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