Skip to content

Commit e0e2cf9

Browse files
committed
Add @feature and @SInCE gates to WIT
1 parent 4a3cd3b commit e0e2cf9

File tree

1 file changed

+92
-4
lines changed

1 file changed

+92
-4
lines changed

design/mvp/WIT.md

Lines changed: 92 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -934,7 +934,46 @@ include-names-item ::= id 'as' id
934934
## Item: `interface`
935935

936936
Interfaces can be defined in a `wit` file. Interfaces have a name and a
937-
sequence of items and functions.
937+
sequence of items and functions, all of which can be gated on an `id` or a
938+
semantic version.
939+
940+
For example, the following interface has 4 items, 3 of which are gated:
941+
```wit
942+
interface foo {
943+
a: func();
944+
945+
@since(version = "0.2.1")
946+
b: func();
947+
948+
@since(version = "0.2.2")
949+
@feature(name = "fancy-foo")
950+
c: func();
951+
952+
@feature(name = "fancier-foo")
953+
d: func();
954+
}
955+
```
956+
The `@since` gate indicates that `b` and `c` were added as part of the `0.2.1`
957+
and `0.2.2` releases, resp. Thus, when building a component targeting, e.g.,
958+
`0.2.1`, `b` can be used, but `c` cannot. An important expectation set by the
959+
`@since` gate is that, once applied to an item, the item is never modified
960+
incompatibly going forward (according to general semantic versioning rules).
961+
962+
In contrast, the lone `@feature` gate on `d` indicates that `d` is part of the
963+
`fancier-foo` feature that is still under active development and thus `d` may
964+
change type or be removed at any time. An important expectation set by the
965+
`@feature` gate is that toolchains will not expose `@feature`-only-gated items
966+
by default unless explicitly opted-into by the developer.
967+
968+
Together, these gates support a development flow in which new features start
969+
with a `@feature` gate while the details are still being hashed out. Then, once
970+
the feature is stable (and, in a WASI context, voted upon), the `@since` gate
971+
can be added. To enable a smooth transition, both gates can be present at the
972+
same time, exposing the feature by when the target version is greater-or-equal.
973+
After a suitable transition period (during which producer toolchains bump their
974+
default target versions to enable the feature by default), the `@feature` gate
975+
can then be removed. Thus, in the above example, the `fancy-foo` feature gate
976+
could be removed from `c` once `0.2.2` is the default target version.
938977

939978
Specifically interfaces have the structure:
940979

@@ -943,9 +982,15 @@ Specifically interfaces have the structure:
943982
```ebnf
944983
interface-item ::= 'interface' id '{' interface-items* '}'
945984
946-
interface-items ::= typedef-item
947-
| use-item
948-
| func-item
985+
interface-items ::= gate interface-definition
986+
987+
gate ::= since-gate? feature-gate?
988+
since-gate ::= '@since' '(' 'version' '=' '"' <valid semver> '"' ')'
989+
feature-gate ::= '@feature' '(' 'name' '=' '"' id '"' ')'
990+
991+
interface-definition ::= typedef-item
992+
| use-item
993+
| func-item
949994
950995
typedef-item ::= resource-item
951996
| variant-items
@@ -970,6 +1015,7 @@ named-type-list ::= ϵ
9701015
named-type ::= id ':' ty
9711016
```
9721017

1018+
9731019
## Item: `use`
9741020

9751021
A `use` statement enables importing type or resource definitions from other
@@ -1626,3 +1672,45 @@ standalone interface definitions (such `wasi:http/handler`) are no longer in a
16261672
`use`s are replaced by direct aliases to preceding type imports as determined
16271673
by the WIT resolution process.
16281674

1675+
Unlike most other WIT constructs, the `@feature` and `@version` gates are not
1676+
represented in the component binary. Instead, these are considered "macro"
1677+
constructs that take the place of maintaining two copies of a single WIT document.
1678+
In particular, when encoding a collection of WIT documents into a binary, a target
1679+
version and set of feature names is supplied and determines whether individual
1680+
gated items are included or not.
1681+
1682+
For example, the following WIT document:
1683+
```wit
1684+
package ns:[email protected];
1685+
1686+
interface i {
1687+
f: func()
1688+
1689+
@since(version = "1.1.0")
1690+
g: func()
1691+
}
1692+
```
1693+
is encoded as the following component when the target version is `1.0.0`:
1694+
```wat
1695+
(component
1696+
(type (export "i") (component
1697+
(export "ns:p/[email protected]" (instance
1698+
(export "f" (func))
1699+
))
1700+
))
1701+
)
1702+
```
1703+
If the target version was instead `1.1.0`, the same WIT document would be
1704+
encoded as:
1705+
```wat
1706+
(component
1707+
(type (export "i") (component
1708+
(export "ns:p/[email protected]" (instance
1709+
(export "f" (func))
1710+
(export "g" (func))
1711+
))
1712+
))
1713+
)
1714+
```
1715+
Thus, `@since` and `@feature` gates are not part of the runtime semantics of
1716+
components, just part of the source-level tooling for producing components.

0 commit comments

Comments
 (0)