schema.capnp 17.8 KB
Newer Older
Kenton Varda's avatar
Kenton Varda committed
1 2
# Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
# Licensed under the MIT License:
3
#
Kenton Varda's avatar
Kenton Varda committed
4 5 6 7 8 9
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
10
#
Kenton Varda's avatar
Kenton Varda committed
11 12
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
13
#
Kenton Varda's avatar
Kenton Varda committed
14 15 16 17 18 19 20
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
21

22
using Cxx = import "/capnp/c++.capnp";
23

Kenton Varda's avatar
Kenton Varda committed
24
@0xa93fc509624c72d9;
25
$Cxx.namespace("capnp::schema");
26 27 28 29 30 31 32 33 34 35 36 37 38

using Id = UInt64;
# The globally-unique ID of a file, type, or annotation.

struct Node {
  id @0 :Id;

  displayName @1 :Text;
  # Name to present to humans to identify this Node.  You should not attempt to parse this.  Its
  # format could change.  It is not guaranteed to be unique.
  #
  # (On Zooko's triangle, this is the node's nickname.)

Kenton Varda's avatar
Kenton Varda committed
39
  displayNamePrefixLength @2 :UInt32;
Kenton Varda's avatar
Kenton Varda committed
40 41 42
  # If you want a shorter version of `displayName` (just naming this node, without its surrounding
  # scope), chop off this many characters from the beginning of `displayName`.

Kenton Varda's avatar
Kenton Varda committed
43
  scopeId @3 :Id;
44
  # ID of the lexical parent node.  Typically, the scope node will have a NestedNode pointing back
Kenton Varda's avatar
Kenton Varda committed
45 46 47 48
  # at this node, but robust code should avoid relying on this (and, in fact, group nodes are not
  # listed in the outer struct's nestedNodes, since they are listed in the fields).  `scopeId` is
  # zero if the node has no parent, which is normally only the case with files, but should be
  # allowed for any kind of node (in order to make runtime type generation easier).
49

Kenton Varda's avatar
Kenton Varda committed
50 51 52
  parameters @32 :List(Parameter);
  # If this node is parameterized (generic), the list of parameters. Empty for non-generic types.

53 54 55 56
  isGeneric @33 :Bool;
  # True if this node is generic, meaning that it or one of its parent scopes has a non-empty
  # `parameters`.

Kenton Varda's avatar
Kenton Varda committed
57 58 59 60 61 62
  struct Parameter {
    # Information about one of the node's parameters.

    name @0 :Text;
  }

Kenton Varda's avatar
Kenton Varda committed
63
  nestedNodes @4 :List(NestedNode);
64 65 66 67
  # List of nodes nested within this node, along with the names under which they were declared.

  struct NestedNode {
    name @0 :Text;
David Renshaw's avatar
David Renshaw committed
68
    # Unqualified symbol name.  Unlike Node.displayName, this *can* be used programmatically.
69 70 71 72 73 74 75 76
    #
    # (On Zooko's triangle, this is the node's petname according to its parent scope.)

    id @1 :Id;
    # ID of the nested node.  Typically, the target node's scopeId points back to this node, but
    # robust code should avoid relying on this.
  }

Kenton Varda's avatar
Kenton Varda committed
77
  annotations @5 :List(Annotation);
78 79
  # Annotations applied to this node.

Kenton Varda's avatar
Kenton Varda committed
80
  union {
81 82
    # Info specific to each kind of node.

Kenton Varda's avatar
Kenton Varda committed
83 84 85
    file @6 :Void;

    struct :group {
86 87 88 89 90
      dataWordCount @7 :UInt16;
      # Size of the data section, in words.

      pointerCount @8 :UInt16;
      # Size of the pointer section, in pointers (which are one word each).
Kenton Varda's avatar
Kenton Varda committed
91 92 93 94 95 96 97 98 99 100 101

      preferredListEncoding @9 :ElementSize;
      # The preferred element size to use when encoding a list of this struct.  If this is anything
      # other than `inlineComposite` then the struct is one word or less in size and is a candidate
      # for list packing optimization.

      isGroup @10 :Bool;
      # If true, then this "struct" node is actually not an independent node, but merely represents
      # some named union or group within a particular parent struct.  This node's scopeId refers
      # to the parent struct, which may itself be a union/group in yet another struct.
      #
102
      # All group nodes share the same dataWordCount and pointerCount as the top-level
Kenton Varda's avatar
Kenton Varda committed
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
      # struct, and their fields live in the same ordinal and offset spaces as all other fields in
      # the struct.
      #
      # Note that a named union is considered a special kind of group -- in fact, a named union
      # is exactly equivalent to a group that contains nothing but an unnamed union.

      discriminantCount @11 :UInt16;
      # Number of fields in this struct which are members of an anonymous union, and thus may
      # overlap.  If this is non-zero, then a 16-bit discriminant is present indicating which
      # of the overlapping fields is active.  This can never be 1 -- if it is non-zero, it must be
      # two or more.
      #
      # Note that the fields of an unnamed union are considered fields of the scope containing the
      # union -- an unnamed union is not its own group.  So, a top-level struct may contain a
      # non-zero discriminant count.  Named unions, on the other hand, are equivalent to groups
      # containing unnamed unions.  So, a named union has its own independent schema node, with
      # `isGroup` = true.

      discriminantOffset @12 :UInt32;
      # If `discriminantCount` is non-zero, this is the offset of the union discriminant, in
      # multiples of 16 bits.

      fields @13 :List(Field);
      # Fields defined within this scope (either the struct's top-level fields, or the fields of
      # a particular group; see `isGroup`).
      #
      # The fields are sorted by ordinal number, but note that because groups share the same
      # ordinal space, the field's index in this list is not necessarily exactly its ordinal.
      # On the other hand, the field's position in this list does remain the same even as the
      # protocol evolves, since it is not possible to insert or remove an earlier ordinal.
      # Therefore, for most use cases, if you want to identify a field by number, it may make the
      # most sense to use the field's index in this list rather than its ordinal.
    }
136

137 138 139 140
    enum :group {
      enumerants@14 :List(Enumerant);
      # Enumerants ordered by numeric value (ordinal).
    }
141

142 143 144
    interface :group {
      methods @15 :List(Method);
      # Methods ordered by ordinal.
145

146
      superclasses @31 :List(Superclass);
147
      # Superclasses of this interface.
148
    }
149

Kenton Varda's avatar
Kenton Varda committed
150 151 152 153
    const :group {
      type @16 :Type;
      value @17 :Value;
    }
154

Kenton Varda's avatar
Kenton Varda committed
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
    annotation :group {
      type @18 :Type;

      targetsFile @19 :Bool;
      targetsConst @20 :Bool;
      targetsEnum @21 :Bool;
      targetsEnumerant @22 :Bool;
      targetsStruct @23 :Bool;
      targetsField @24 :Bool;
      targetsUnion @25 :Bool;
      targetsGroup @26 :Bool;
      targetsInterface @27 :Bool;
      targetsMethod @28 :Bool;
      targetsParam @29 :Bool;
      targetsAnnotation @30 :Bool;
    }
171 172
  }

173 174 175 176 177
  struct SourceInfo {
    # Additional information about a node which is not needed at runtime, but may be useful for
    # documentation or debugging purposes. This is kept in a separate struct to make sure it
    # doesn't accidentally get included in contexts where it is not needed. The
    # `CodeGeneratorRequest` includes this information in a separate array.
178

179 180
    id @0 :Id;
    # ID of the Node which this info describes.
181

182 183
    docComment @1 :Text;
    # The top-level doc comment for the Node.
184

185 186 187 188 189 190 191 192 193 194 195 196 197 198
    members @2 :List(Member);
    # Information about each member -- i.e. fields (for structs), enumerants (for enums), or
    # methods (for interfaces).
    #
    # This list is the same length and order as the corresponding list in the Node, i.e.
    # Node.struct.fields, Node.enum.enumerants, or Node.interface.methods.

    struct Member {
      docComment @0 :Text;
      # Doc comment on the member.
    }

    # TODO(someday): Record location of the declaration in the original source code.
  }
199 200
}

Kenton Varda's avatar
Kenton Varda committed
201 202
struct Field {
  # Schema for a field of a struct.
203

Kenton Varda's avatar
Kenton Varda committed
204
  name @0 :Text;
205

Kenton Varda's avatar
Kenton Varda committed
206 207 208 209 210 211 212
  codeOrder @1 :UInt16;
  # Indicates where this member appeared in the code, relative to other members.
  # Code ordering may have semantic relevance -- programmers tend to place related fields
  # together.  So, using code ordering makes sense in human-readable formats where ordering is
  # otherwise irrelevant, like JSON.  The values of codeOrder are tightly-packed, so the maximum
  # value is count(members) - 1.  Fields that are members of a union are only ordered relative to
  # the other members of that union, so the maximum value there is count(union.members).
213

Kenton Varda's avatar
Kenton Varda committed
214
  annotations @2 :List(Annotation);
215

216 217 218
  const noDiscriminant :UInt16 = 0xffff;

  discriminantValue @3 :UInt16 = Field.noDiscriminant;
Kenton Varda's avatar
Kenton Varda committed
219
  # If the field is in a union, this is the value which the union's discriminant should take when
220
  # the field is active.  If the field is not in a union, this is 0xffff.
221

Kenton Varda's avatar
Kenton Varda committed
222
  union {
223 224
    slot :group {
      # A regular, non-group, non-fixed-list field.
225

Kenton Varda's avatar
Kenton Varda committed
226 227 228 229
      offset @4 :UInt32;
      # Offset, in units of the field's size, from the beginning of the section in which the field
      # resides.  E.g. for a UInt32 field, multiply this by 4 to get the byte offset from the
      # beginning of the data section.
230

Kenton Varda's avatar
Kenton Varda committed
231 232
      type @5 :Type;
      defaultValue @6 :Value;
233 234 235 236 237 238

      hadExplicitDefault @10 :Bool;
      # Whether the default value was specified explicitly.  Non-explicit default values are always
      # zero or empty values.  Usually, whether the default value was explicit shouldn't matter.
      # The main use case for this flag is for structs representing method parameters:
      # explicitly-defaulted parameters may be allowed to be omitted when calling the method.
Kenton Varda's avatar
Kenton Varda committed
239
    }
240

241 242 243 244 245 246
    group :group {
      # A group.

      typeId @7 :Id;
      # The ID of the group's node.
    }
Kenton Varda's avatar
Kenton Varda committed
247
  }
248

Kenton Varda's avatar
Kenton Varda committed
249 250 251 252 253 254 255 256 257
  ordinal :union {
    implicit @8 :Void;
    explicit @9 :UInt16;
    # The original ordinal number given to the field.  You probably should NOT use this; if you need
    # a numeric identifier for a field, use its position within the field array for its scope.
    # The ordinal is given here mainly just so that the original schema text can be reproduced given
    # the compiled version -- i.e. so that `capnp compile -ocapnp` can do its job.
  }
}
258

Kenton Varda's avatar
Kenton Varda committed
259 260
struct Enumerant {
  # Schema for member of an enum.
261

Kenton Varda's avatar
Kenton Varda committed
262
  name @0 :Text;
263

Kenton Varda's avatar
Kenton Varda committed
264 265 266
  codeOrder @1 :UInt16;
  # Specifies order in which the enumerants were declared in the code.
  # Like Struct.Field.codeOrder.
267

Kenton Varda's avatar
Kenton Varda committed
268 269
  annotations @2 :List(Annotation);
}
270

271 272 273 274 275
struct Superclass {
  id @0 :Id;
  brand @1 :Brand;
}

Kenton Varda's avatar
Kenton Varda committed
276 277
struct Method {
  # Schema for method of an interface.
278

Kenton Varda's avatar
Kenton Varda committed
279
  name @0 :Text;
280

Kenton Varda's avatar
Kenton Varda committed
281 282 283
  codeOrder @1 :UInt16;
  # Specifies order in which the methods were declared in the code.
  # Like Struct.Field.codeOrder.
284

285 286 287 288
  implicitParameters @7 :List(Node.Parameter);
  # The parameters listed in [] (typically, type / generic parameters), whose bindings are intended
  # to be inferred rather than specified explicitly, although not all languages support this.

289 290 291 292 293
  paramStructType @2 :Id;
  # ID of the parameter struct type.  If a named parameter list was specified in the method
  # declaration (rather than a single struct parameter type) then a corresponding struct type is
  # auto-generated.  Such an auto-generated type will not be listed in the interface's
  # `nestedNodes` and its `scopeId` will be zero -- it is completely detached from the namespace.
Kenton Varda's avatar
Kenton Varda committed
294 295 296 297
  # (Awkwardly, it does of course inherit generic parameters from the method's scope, which makes
  # this a situation where you can't just climb the scope chain to find where a particular
  # generic parameter was introduced. Making the `scopeId` zero was a mistake.)

298 299
  paramBrand @5 :Brand;
  # Brand of param struct type.
300

301 302
  resultStructType @3 :Id;
  # ID of the return struct type; similar to `paramStructType`.
303

304 305
  resultBrand @6 :Brand;
  # Brand of result struct type.
Kenton Varda's avatar
Kenton Varda committed
306

307
  annotations @4 :List(Annotation);
308 309
}

Kenton Varda's avatar
Kenton Varda committed
310 311
struct Type {
  # Represents a type expression.
312

Kenton Varda's avatar
Kenton Varda committed
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
  union {
    # The ordinals intentionally match those of Value.

    void @0 :Void;
    bool @1 :Void;
    int8 @2 :Void;
    int16 @3 :Void;
    int32 @4 :Void;
    int64 @5 :Void;
    uint8 @6 :Void;
    uint16 @7 :Void;
    uint32 @8 :Void;
    uint64 @9 :Void;
    float32 @10 :Void;
    float64 @11 :Void;
    text @12 :Void;
    data @13 :Void;

331 332 333
    list :group {
      elementType @14 :Type;
    }
Kenton Varda's avatar
Kenton Varda committed
334

335 336
    enum :group {
      typeId @15 :Id;
337
      brand @21 :Brand;
338 339 340
    }
    struct :group {
      typeId @16 :Id;
341
      brand @22 :Brand;
342 343 344
    }
    interface :group {
      typeId @17 :Id;
345
      brand @23 :Brand;
Kenton Varda's avatar
Kenton Varda committed
346 347 348
    }

    anyPointer :union {
349 350 351
      unconstrained :union {
        # A regular AnyPointer.
        #
352
        # The name "unconstrained" means as opposed to constraining it to match a type parameter.
353 354 355 356 357 358 359 360
        # In retrospect this name is probably a poor choice given that it may still be constrained
        # to be a struct, list, or capability.

        anyKind @18 :Void;       # truly AnyPointer
        struct @25 :Void;        # AnyStruct
        list @26 :Void;          # AnyList
        capability @27 :Void;    # Capability
      }
Kenton Varda's avatar
Kenton Varda committed
361 362 363 364

      parameter :group {
        # This is actually a reference to a type parameter defined within this scope.

365 366 367
        scopeId @19 :Id;
        # ID of the generic type whose parameter we're referencing. This should be a parent of the
        # current scope.
Kenton Varda's avatar
Kenton Varda committed
368 369 370 371

        parameterIndex @20 :UInt16;
        # Index of the parameter within the generic type's parameter list.
      }
372 373 374 375 376 377 378

      implicitMethodParameter :group {
        # This is actually a reference to an implicit (generic) parameter of a method. The only
        # legal context for this type to appear is inside Method.paramBrand or Method.resultBrand.

        parameterIndex @24 :UInt16;
      }
379
    }
Kenton Varda's avatar
Kenton Varda committed
380 381 382
  }
}

383 384 385
struct Brand {
  # Specifies bindings for parameters of generics. Since these bindings turn a generic into a
  # non-generic, we call it the "brand".
Kenton Varda's avatar
Kenton Varda committed
386 387 388 389 390 391 392 393 394

  scopes @0 :List(Scope);
  # For each of the target type and each of its parent scopes, a parameterization may be included
  # in this list. If no parameterization is included for a particular relevant scope, then either
  # that scope has no parameters or all parameters should be considered to be `AnyPointer`.

  struct Scope {
    scopeId @0 :Id;
    # ID of the scope to which these params apply.
Kenton Varda's avatar
Kenton Varda committed
395

396 397 398 399 400
    union {
      bind @1 :List(Binding);
      # List of parameter bindings.

      inherit @2 :Void;
David Renshaw's avatar
David Renshaw committed
401
      # The place where this Brand appears is actually within this scope or a sub-scope,
402 403
      # and the bindings for this scope should be inherited from the reference point.
    }
Kenton Varda's avatar
Kenton Varda committed
404 405 406 407 408 409 410 411 412
  }

  struct Binding {
    union {
      unbound @0 :Void;
      type @1 :Type;

      # TODO(someday): Allow non-type parameters? Unsure if useful.
    }
413 414 415
  }
}

Kenton Varda's avatar
Kenton Varda committed
416 417
struct Value {
  # Represents a value, e.g. a field default value, constant value, or annotation value.
418

Kenton Varda's avatar
Kenton Varda committed
419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436
  union {
    # The ordinals intentionally match those of Type.

    void @0 :Void;
    bool @1 :Bool;
    int8 @2 :Int8;
    int16 @3 :Int16;
    int32 @4 :Int32;
    int64 @5 :Int64;
    uint8 @6 :UInt8;
    uint16 @7 :UInt16;
    uint32 @8 :UInt32;
    uint64 @9 :UInt64;
    float32 @10 :Float32;
    float64 @11 :Float64;
    text @12 :Text;
    data @13 :Data;

437
    list @14 :AnyPointer;
Kenton Varda's avatar
Kenton Varda committed
438 439

    enum @15 :UInt16;
440
    struct @16 :AnyPointer;
Kenton Varda's avatar
Kenton Varda committed
441 442 443 444

    interface @17 :Void;
    # The only interface value that can be represented statically is "null", whose methods always
    # throw exceptions.
445

446
    anyPointer @18 :AnyPointer;
447 448 449
  }
}

Kenton Varda's avatar
Kenton Varda committed
450 451 452 453 454 455 456
struct Annotation {
  # Describes an annotation applied to a declaration.  Note AnnotationNode describes the
  # annotation's declaration, while this describes a use of the annotation.

  id @0 :Id;
  # ID of the annotation node.

457 458
  brand @2 :Brand;
  # Brand of the annotation.
Kenton Varda's avatar
Kenton Varda committed
459 460 461
  #
  # Note that the annotation itself is not allowed to be parameterized, but its scope might be.

462 463 464
  value @1 :Value;
}

Kenton Varda's avatar
Kenton Varda committed
465 466 467 468 469 470 471 472 473 474 475 476
enum ElementSize {
  # Possible element sizes for encoded lists.  These correspond exactly to the possible values of
  # the 3-bit element size component of a list pointer.

  empty @0;    # aka "void", but that's a keyword.
  bit @1;
  byte @2;
  twoBytes @3;
  fourBytes @4;
  eightBytes @5;
  pointer @6;
  inlineComposite @7;
477 478
}

479 480 481 482 483 484
struct CapnpVersion {
  major @0 :UInt16;
  minor @1 :UInt8;
  micro @2 :UInt8;
}

485
struct CodeGeneratorRequest {
486 487 488 489 490 491 492 493
  capnpVersion @2 :CapnpVersion;
  # Version of the `capnp` executable. Generally, code generators should ignore this, but the code
  # generators that ship with `capnp` itself will print a warning if this mismatches since that
  # probably indicates something is misconfigured.
  #
  # The first version of 'capnp' to set this was 0.6.0. So, if it's missing, the compiler version
  # is older than that.

494 495 496 497
  nodes @0 :List(Node);
  # All nodes parsed by the compiler, including for the files on the command line and their
  # imports.

498 499 500
  sourceInfo @3 :List(Node.SourceInfo);
  # Information about the original source code for each node, where available. This array may be
  # omitted or may be missing some nodes if no info is available for them.
501

Kenton Varda's avatar
Kenton Varda committed
502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528
  requestedFiles @1 :List(RequestedFile);
  # Files which were listed on the command line.

  struct RequestedFile {
    id @0 :Id;
    # ID of the file.

    filename @1 :Text;
    # Name of the file as it appeared on the command-line (minus the src-prefix).  You may use
    # this to decide where to write the output.

    imports @2 :List(Import);
    # List of all imported paths seen in this file.

    struct Import {
      id @0 :Id;
      # ID of the imported file.

      name @1 :Text;
      # Name which *this* file used to refer to the foreign file.  This may be a relative name.
      # This information is provided because it might be useful for code generation, e.g. to
      # generate #include directives in C++.  We don't put this in Node.file because this
      # information is only meaningful at compile time anyway.
      #
      # (On Zooko's triangle, this is the import's petname according to the importing file.)
    }
  }
529
}