schema.capnp 12.7 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
  nestedNodes @4 :List(NestedNode);
51 52 53 54 55 56 57 58 59 60 61 62 63
  # List of nodes nested within this node, along with the names under which they were declared.

  struct NestedNode {
    name @0 :Text;
    # Unqualified symbol name.  Unlike Node.name, this *can* be used programmatically.
    #
    # (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
64
  annotations @5 :List(Annotation);
65 66
  # Annotations applied to this node.

Kenton Varda's avatar
Kenton Varda committed
67
  union {
68 69
    # Info specific to each kind of node.

Kenton Varda's avatar
Kenton Varda committed
70 71 72
    file @6 :Void;

    struct :group {
73 74 75 76 77
      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
78 79 80 81 82 83 84 85 86 87 88

      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.
      #
89
      # All group nodes share the same dataWordCount and pointerCount as the top-level
Kenton Varda's avatar
Kenton Varda committed
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
      # 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.
    }
123

124 125 126 127
    enum :group {
      enumerants@14 :List(Enumerant);
      # Enumerants ordered by numeric value (ordinal).
    }
128

129 130 131
    interface :group {
      methods @15 :List(Method);
      # Methods ordered by ordinal.
132 133 134

      extends @31 :List(Id);
      # Superclasses of this interface.
135
    }
136

Kenton Varda's avatar
Kenton Varda committed
137 138 139 140
    const :group {
      type @16 :Type;
      value @17 :Value;
    }
141

Kenton Varda's avatar
Kenton Varda committed
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
    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;
    }
158 159 160
  }
}

Kenton Varda's avatar
Kenton Varda committed
161 162
struct Field {
  # Schema for a field of a struct.
163

Kenton Varda's avatar
Kenton Varda committed
164
  name @0 :Text;
165

Kenton Varda's avatar
Kenton Varda committed
166 167 168 169 170 171 172
  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).
173

Kenton Varda's avatar
Kenton Varda committed
174
  annotations @2 :List(Annotation);
175

176 177 178
  const noDiscriminant :UInt16 = 0xffff;

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

Kenton Varda's avatar
Kenton Varda committed
182
  union {
183 184
    slot :group {
      # A regular, non-group, non-fixed-list field.
185

Kenton Varda's avatar
Kenton Varda committed
186 187 188 189
      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.
190

Kenton Varda's avatar
Kenton Varda committed
191 192
      type @5 :Type;
      defaultValue @6 :Value;
193 194 195 196 197 198

      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
199
    }
200

201 202 203 204 205 206
    group :group {
      # A group.

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

Kenton Varda's avatar
Kenton Varda committed
209 210 211 212 213 214 215 216 217
  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.
  }
}
218

Kenton Varda's avatar
Kenton Varda committed
219 220
struct Enumerant {
  # Schema for member of an enum.
221

Kenton Varda's avatar
Kenton Varda committed
222
  name @0 :Text;
223

Kenton Varda's avatar
Kenton Varda committed
224 225 226
  codeOrder @1 :UInt16;
  # Specifies order in which the enumerants were declared in the code.
  # Like Struct.Field.codeOrder.
227

Kenton Varda's avatar
Kenton Varda committed
228 229
  annotations @2 :List(Annotation);
}
230

Kenton Varda's avatar
Kenton Varda committed
231 232
struct Method {
  # Schema for method of an interface.
233

Kenton Varda's avatar
Kenton Varda committed
234
  name @0 :Text;
235

Kenton Varda's avatar
Kenton Varda committed
236 237 238
  codeOrder @1 :UInt16;
  # Specifies order in which the methods were declared in the code.
  # Like Struct.Field.codeOrder.
239

240 241 242 243 244
  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.
245

246 247
  resultStructType @3 :Id;
  # ID of the return struct type; similar to `paramStructType`.
248

249
  annotations @4 :List(Annotation);
250 251
}

Kenton Varda's avatar
Kenton Varda committed
252 253
struct Type {
  # Represents a type expression.
254

Kenton Varda's avatar
Kenton Varda committed
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
  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;

273 274 275
    list :group {
      elementType @14 :Type;
    }
Kenton Varda's avatar
Kenton Varda committed
276

277 278 279 280 281 282 283 284 285
    enum :group {
      typeId @15 :Id;
    }
    struct :group {
      typeId @16 :Id;
    }
    interface :group {
      typeId @17 :Id;
    }
Kenton Varda's avatar
Kenton Varda committed
286

287
    anyPointer @18 :Void;
288 289 290
  }
}

Kenton Varda's avatar
Kenton Varda committed
291 292
struct Value {
  # Represents a value, e.g. a field default value, constant value, or annotation value.
293

Kenton Varda's avatar
Kenton Varda committed
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
  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;

312
    list @14 :AnyPointer;
Kenton Varda's avatar
Kenton Varda committed
313 314

    enum @15 :UInt16;
315
    struct @16 :AnyPointer;
Kenton Varda's avatar
Kenton Varda committed
316 317 318 319

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

321
    anyPointer @18 :AnyPointer;
322 323 324
  }
}

Kenton Varda's avatar
Kenton Varda committed
325 326 327 328 329 330 331
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.

332 333 334
  value @1 :Value;
}

Kenton Varda's avatar
Kenton Varda committed
335 336 337 338 339 340 341 342 343 344 345 346
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;
347 348 349 350 351 352 353
}

struct CodeGeneratorRequest {
  nodes @0 :List(Node);
  # All nodes parsed by the compiler, including for the files on the command line and their
  # imports.

Kenton Varda's avatar
Kenton Varda committed
354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380
  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.)
    }
  }
381
}