Skip to content

Commit

Permalink
Add gates to 'interface' and 'world' definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
lukewagner committed Apr 19, 2024
1 parent 8c066b4 commit 8d34a70
Showing 1 changed file with 57 additions and 48 deletions.
105 changes: 57 additions & 48 deletions design/mvp/WIT.md
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,61 @@ Concretely, the structure of a `wit` file is:
wit-file ::= package-decl? (toplevel-use-item | interface-item | world-item)*
```

### Feature Gates

Various WIT items can be "gated", to reflect the fact that the item is part of
an unstable feature or that the item was added as part of a minor version
update and shouldn't be used when targeting an earlier minor version.

For example, the following interface has 4 items, 3 of which are gated:
```wit
interface foo {
a: func();
@since(version = "0.2.1")
b: func();
@since(version = "0.2.2", feature = "fancy-foo")
c: func();
@unstable(feature = "fancier-foo")
d: func();
}
```
The `@since` gate indicates that `b` and `c` were added as part of the `0.2.1`
and `0.2.2` releases, resp. Thus, when building a component targeting, e.g.,
`0.2.1`, `b` can be used, but `c` cannot. An important expectation set by the
`@since` gate is that, once applied to an item, the item is not modified
incompatibly going forward (according to general semantic versioning rules).

In contrast, the `@unstable` gate on `d` indicates that `d` is part of the
`fancier-foo` feature that is still under active development and thus `d` may
change type or be removed at any time. An important expectation set by the
`@unstable` gate is that toolchains will not expose `@unstable` features by
default unless explicitly opted-into by the developer.

Together, these gates support a development flow in which new features start
with an `@unstable` gate while the details are still being hashed out. Then,
once the feature is stable (and, in a WASI context, voted upon), the
`@unstable` gate is switched to a `@since` gate. To enable a smooth transition
(during which producer toolchains are targeting a version earlier than the
`@since`-specified `version`), the `@since` gate contains an optional `feature`
field that, when present, says to enable the feature when *either* the target
version is greator-or-equal *or* the feature name is explicitly enabled by the
developer. Thus, `c` is enabled if the version is `0.2.2` or newer or the
`fancy-foo` feature is explicitly enabled by the developer. The `feature` field
can be removed once producer toolchains have updated their default version to
enable the feature by default.

Specifically, the syntax for feature gates is:
```wit
gate ::= unstable-gate
| since-gate
unstable-gate ::= '@unstable' '(' feature-field ')'
feature-field ::= 'feature' '=' '"' id '"'
since-gate ::= '@since' '(' 'version' '=' '"' <valid semver> '"' ( ',' feature-field )? ')'
```

## Package declaration

WIT files optionally start with a package declaration which defines the ID of
Expand Down Expand Up @@ -895,7 +950,7 @@ Worlds define a [componenttype](https://github.com/WebAssembly/component-model/b
Concretely, the structure of a world is:

```ebnf
world-item ::= 'world' id '{' world-items* '}'
world-item ::= gate 'world' id '{' world-items* '}'
world-items ::= export-item | import-item | use-item | typedef-item | include-item
Expand Down Expand Up @@ -937,61 +992,15 @@ Interfaces can be defined in a `wit` file. Interfaces have a name and a
sequence of items and functions, all of which can be gated on an `id` or a
semantic version.

For example, the following interface has 4 items, 3 of which are gated:
```wit
interface foo {
a: func();
@since(version = "0.2.1")
b: func();
@since(version = "0.2.2", feature = "fancy-foo")
c: func();
@unstable(feature = "fancier-foo")
d: func();
}
```
The `@since` gate indicates that `b` and `c` were added as part of the `0.2.1`
and `0.2.2` releases, resp. Thus, when building a component targeting, e.g.,
`0.2.1`, `b` can be used, but `c` cannot. An important expectation set by the
`@since` gate is that, once applied to an item, the item is not modified
incompatibly going forward (according to general semantic versioning rules).

In contrast, the `@unstable` gate on `d` indicates that `d` is part of the
`fancier-foo` feature that is still under active development and thus `d` may
change type or be removed at any time. An important expectation set by the
`@unstable` gate is that toolchains will not expose `@unstable` features by
default unless explicitly opted-into by the developer.

Together, these gates support a development flow in which new features start
with an `@unstable` gate while the details are still being hashed out. Then,
once the feature is stable (and, in a WASI context, voted upon), the
`@unstable` gate is switched to a `@since` gate. To enable a smooth transition
(during which producer toolchains are targeting a version earlier than the
`@since`-specified `version`), the `@since` gate contains an optional `feature`
field that, when present, says to enable the feature when *either* the target
version is greator-or-equal *or* the feature name is explicitly enabled by the
developer. Thus, `c` is enabled if the version is `0.2.2` or newer or the
`fancy-foo` feature is explicitly enabled by the developer. The `feature` field
can be removed once producer toolchains have updated their default version to
enable the feature by default.

Specifically interfaces have the structure:

> **Note**: The symbol `ε`, also known as Epsilon, denotes an empty string.
```ebnf
interface-item ::= 'interface' id '{' interface-items* '}'
interface-item ::= gate 'interface' id '{' interface-items* '}'
interface-items ::= gate interface-definition
gate ::= unstable-gate
| since-gate
unstable-gate ::= '@unstable' '(' feature-field ')'
feature-field ::= 'feature' '=' '"' id '"'
since-gate ::= '@since' '(' 'version' '=' '"' <valid semver> '"' ( ',' feature-field )? ')'
interface-definition ::= typedef-item
| use-item
| func-item
Expand Down

0 comments on commit 8d34a70

Please sign in to comment.