|
| 1 | +# WIT + `world` |
| 2 | + |
| 3 | +As it exists today [WIT](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md) is a format for describing the interface of a singular [instance](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#instance-definitions). Toolchains like [wit-bindgen](https://github.com/bytecodealliance/wit-bindgen) consume `*.wit` files as *imports* or *exports* to generate *guest* or *host* components implying **4** ways to consume an interface: |
| 4 | + |
| 5 | +| {guest,host}⋅{export, import} | export | import | |
| 6 | +| -------- | -------- | -------- | |
| 7 | +| **guest** | _guest export_ | _guest import_ | |
| 8 | +| **host** | _host export_ | _host import_ | |
| 9 | + |
| 10 | +Furthermore, a single component may refer to 0..N interfaces in its imports and exports. |
| 11 | + |
| 12 | +The `world` syntax described below allows collecting *N* _imports_ and *N* _exports_ into a single definition reducing this number of perspectives to **2**: |
| 13 | +1. As a *guest* **targeting** the `world` |
| 14 | + |
| 15 | + From the perspective of a guest the *imports* declared in a `world` describe the **maximum** set of imports that the component may `import`, whereas the *exports* describe the **minimum** set of imports that the component must `export`. |
| 16 | + |
| 17 | +2. A a *host* **implementing** the `world` |
| 18 | + |
| 19 | + From the perspective of a host, the *imports* declared in a `world` describe the **minimum** set of functions that must be implemented by the host and supplied as imports to components running on that host, whereas the exports declared describe the **maximum** set of functions that the host may call in response to host events. |
| 20 | + |
| 21 | +Thus, there are inherently two opposing perspectives on each `world`: the **host** and **guest**. |
| 22 | + |
| 23 | +> NOTE: As a developer, assuming the *guest* or *host* perspective is inherent in whether we are embedding a WASM runtime or compiling to WASM. so a world effectively gives us 1 thing to say, and it implies all the rest, i.e. (imports and exports). |
| 24 | +> |
| 25 | +> Because the [Component Model](https://github.com/WebAssembly/component-model) allows one component to [instantiate]() and link other components, components can technically take either the host or guest perspective for a given `world` (although it will be far more common for components to take the guest perspective). Native host runtimes traditionally only take the host perspective, but in theory a native runtime could implement a component that is imported and instantiated by a wasm component, with the native runtime thereby taking the guest perspective. |
| 26 | +
|
| 27 | +In the examples shown below, because *import* and *export* in the syntax go in the same direction as they are defined in a guest component, we can say that a `world` is **written** from the *guest* perspective. |
| 28 | + |
| 29 | + |
| 30 | +--- |
| 31 | + |
| 32 | +The lexical structure of the following syntax is identical to that of [WIT](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md#lexical-structure) with the following additions: |
| 33 | + |
| 34 | +- keywords ```world import export``` |
| 35 | +- a new token `quoted-string` |
| 36 | + |
| 37 | +## `world` |
| 38 | +A `world` declaration defines a set of imports and exports. From a component-model POV a `world` is syntax for a [componenttype](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#type-definitions), e.g.: |
| 39 | + |
| 40 | +``` |
| 41 | +// wasi:http/proxy |
| 42 | +world proxy { |
| 43 | + import frontend: "wasi:http/handler" |
| 44 | + export backend: "wasi:http/handler" |
| 45 | +} |
| 46 | +``` |
| 47 | + |
| 48 | +By way of metaphor, a `world` is like a function type: |
| 49 | + * `world` imports and exports are like parameters and results |
| 50 | + * `world` hosts are like the callers of a given function type |
| 51 | + * `world` guests are like functions that have a given function type |
| 52 | + * The rules for when a given guest is compatible with a given host are like traditional function subtyping |
| 53 | + |
| 54 | +> Given any component `.wasm`, one should be able to derive a `WIT` file containing a `world` that represents the syntax for that `.wasm`'s component type. |
| 55 | +
|
| 56 | + |
| 57 | +Conceretely, the structure of a `world` declaration is: |
| 58 | + |
| 59 | +``` |
| 60 | +world ::= 'world' id '{' (import | export)* '}' . |
| 61 | +``` |
| 62 | + |
| 63 | +### `import` |
| 64 | + |
| 65 | +An `import` declaration states that a component type depends on an externally provided [function](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md#item-func), [value](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md#types), or instance of an interface type. |
| 66 | + |
| 67 | +For example, consider the following `import` declarations: |
| 68 | + |
| 69 | +``` |
| 70 | +// Import instance of "wasi:filesystem" interface and give it name "fs" |
| 71 | +import fs: "wasi:filesystem" |
| 72 | +
|
| 73 | +// Import function with functype and give it name "some-func" |
| 74 | +import some-func: func(arg: string) -> result<_, _> |
| 75 | +
|
| 76 | +// Import the inlined interface and give it name "foobar" |
| 77 | +import foobar: { |
| 78 | + foo: func() |
| 79 | + bar: func() |
| 80 | +} |
| 81 | +
|
| 82 | +// ... |
| 83 | +``` |
| 84 | + |
| 85 | +Concretely, the structure of an `import` declaration is: |
| 86 | + |
| 87 | +``` |
| 88 | +import-item ::= `import` id `:` import-type . |
| 89 | +import-type ::= id | extern-type . |
| 90 | +extern-type ::= func-type | value-type | instance-type . |
| 91 | +
|
| 92 | +instance-type ::= `{` wit-item* `}` | wit-url. |
| 93 | +``` |
| 94 | + |
| 95 | +> NOTE: `wit-url` is lexically a `quoted-string` describing a [URL](https://url.spec.whatwg.org/) resolving to a `*.wit` document. Additionally `wit-item` refers to the items that can be declared using [WIT](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md#top-level-items) today. |
| 96 | +
|
| 97 | +### `export` |
| 98 | + |
| 99 | +An `export` declaration states that a component type can provide a instance of a [function](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md#item-func), [value](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md#types), or interface type. |
| 100 | + |
| 101 | +For example: |
| 102 | + |
| 103 | +``` |
| 104 | +// Export an instance of the "wasi:http/handler" interface. |
| 105 | +export frontend: "wasi:http/handler" |
| 106 | +
|
| 107 | +// ... |
| 108 | +``` |
| 109 | + |
| 110 | +Concretely, the structure of an `export` statement is: |
| 111 | + |
| 112 | +``` |
| 113 | +export-item ::= `export` id `:` export-type . |
| 114 | +export-type ::= id | extern-type . |
| 115 | +``` |
| 116 | + |
| 117 | +> NOTE: `extern-type` as specified in `import`. |
0 commit comments