Skip to content

Commit 1949748

Browse files
committed
Add @external-id
1 parent 2576e5a commit 1949748

3 files changed

Lines changed: 81 additions & 22 deletions

File tree

design/mvp/Binary.md

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -391,14 +391,15 @@ in the explainer.)
391391
```ebnf
392392
import ::= in:<importname'> ed:<externdesc> => (import in ed)
393393
export ::= en:<exportname'> si:<sortidx> ed?:<externdesc>? => (export en si ed?)
394-
importname' ::= 0x00 len:<u32> in:<importname> => in (if len = |in|)
395-
| 0x01 len:<u32> in:<importname> => in (if len = |in|)
396-
| 0x02 len:<u32> in:<importname> opts:vec(<nameopt>) => in opts (if len = |in|) 🏷️/🔗
397-
exportname' ::= 0x00 len:<u32> in:<exportname> => in (if len = |in|)
398-
| 0x01 len:<u32> in:<exportname> => in (if len = |in|)
399-
| 0x02 len:<u32> in:<importname> opts:vec(<nameopt>) => in opts (if len = |in|) 🏷️/🔗
400-
nameopt ::= 0x00 len:<u32> n:<interfacename> => (implements i) 🏷️
401-
| 0x01 len:<u32> vs:<semversuffix> => (versionsuffix vs) 🔗
394+
importname' ::= 0x00 len:<u32> in:<importname> => in (if len = |in|)
395+
| 0x01 len:<u32> in:<importname> => in (if len = |in|)
396+
| 0x02 len:<u32> in:<importname> at*:vec(<attribute>) => in at* (if len = |in|) 🏷️/🔗
397+
exportname' ::= 0x00 len:<u32> en:<exportname> => en (if len = |en|)
398+
| 0x01 len:<u32> en:<exportname> => en (if len = |en|)
399+
| 0x02 len:<u32> en:<importname> at*:vec(<attribute>) => en at* (if len = |en|) 🏷️/🔗
400+
attribute ::= 0x00 len:<u32> in:<interfacename> => (implements in) (if len = |in|) 🏷️
401+
| 0x01 len:<u32> vs:<semversuffix> => (versionsuffix vs) (if len = |vs|) 🔗
402+
| 0x02 n:<name> => (externalid n) 🏷️
402403
```
403404

404405
Notes:
@@ -422,9 +423,12 @@ Notes:
422423
preceding `resource` import or export, respectively, in the same scope
423424
(component, component type or instance type).
424425
* 🏷️ Validation requires that `implements`-annotated imports or exports are
425-
`instance`-typed.
426-
* 🏷️ Validation requires that `implements`-annotated imports or exports have a
427-
`<plainname>` name.
426+
`instance`-typed and have a `<plainname>` name.
427+
* 🏷️/🔗 Validation requires that a `vec(<attribute>)` contains each kind of
428+
`attribute` at most once.
429+
* 🏷️/🔗 Even though `componenttype` and `instancetype` structurally contain a
430+
`vec(<attribute>)`, this list is entirely ignored when validating the types
431+
of components and instances.
428432
* Validation of `[constructor]` names requires a `func` type whose result type
429433
is either `(own $R)` or `(result (own $R) E?)` where `$R` is a resource type
430434
labeled `r`.

design/mvp/Explainer.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2549,11 +2549,14 @@ exported (e.g., `(export $x "x" (func $f))` binds a new identifier `$x`).
25492549

25502550
Given this, the syntax of imports and exports are defined as follows:
25512551
```ebnf
2552-
import ::= (import "<importname>" bind-id(<externdesc>))
2553-
| (import "<importname>" <versionsuffix> bind-id(<externdesc>)) 🔗
2554-
export ::= (export <id>? "<exportname>" <sortidx> <externdesc>?)
2555-
| (export <id>? "<exportname>" <versionsuffix> <sortidx> <externdesc>?) 🔗
2552+
import ::= (import "<importname>" <attribute>* bind-id(<externdesc>))
2553+
export ::= (export <id>? "<exportname>" <attribute>* <sortidx> <externdesc>?)
2554+
attribute ::= <versionsuffix> 🔗
2555+
| <implements> 🏷️
2556+
| <externalid> 🏷️
25562557
versionsuffix ::= (versionsuffix "<semversuffix>") 🔗
2558+
implements ::= (implements "<interfacename>") 🏷️
2559+
externalid ::= (external-id <name>) 🏷️
25572560
```
25582561

25592562
All import names must be [strongly-unique]. Separately, all export

design/mvp/WIT.md

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,7 @@ token ::= whitespace
10111011
| keyword
10121012
| integer
10131013
| identifier
1014+
| string
10141015
```
10151016

10161017
Whitespace and comments are ignored when parsing structures defined elsewhere
@@ -1107,6 +1108,14 @@ sequence of digits:
11071108
integer ::= [0-9]+
11081109
```
11091110

1111+
### Strings
1112+
1113+
WIT string literals use the same text format as the Core WebAssembly text
1114+
format's [`string`] literal, which is a quoted sequence of Unicode Scalar Values
1115+
like `"a"`, `"☃︎"`, `"\7f"` and `"\u{7fff}"`.
1116+
1117+
[`string`]: https://webassembly.github.io/spec/core/text/values.html#text-string
1118+
11101119
## Top-level items
11111120

11121121
A `wit` document is a sequence of items specified at the top level. These items
@@ -1422,22 +1431,36 @@ world-item ::= gate 'world' id '{' world-items* '}'
14221431
14231432
world-items ::= gate world-definition
14241433
1425-
world-definition ::= export-item
1426-
| import-item
1434+
world-definition ::= external-id? export-item
1435+
| external-id? import-item
14271436
| use-item
14281437
| typedef-item
14291438
| include-item
14301439
1431-
export-item ::= 'export' id ':' extern-type
1440+
export-item ::= external-id? 'export' id ':' extern-type
14321441
| 'export' use-path ';'
1433-
import-item ::= 'import' id ':' extern-type
1442+
import-item ::= external-id? 'import' id ':' extern-type
14341443
| 'import' use-path ';'
14351444
1445+
external-id ::= '@external-id' '(' string ')' 🏷️
1446+
14361447
extern-type ::= func-type ';'
14371448
| 'interface' '{' interface-items* '}'
14381449
| use-path ';' 🏷️
14391450
```
14401451

1452+
🏷️ The optional `external-id` attribute allows ... For example:
1453+
1454+
```wit
1455+
world my-world {
1456+
@external-id("foo/0")
1457+
import foo: func() -> string;
1458+
1459+
@external-id("HOME_DIRECTORY")
1460+
import bar: func() -> string;
1461+
}
1462+
```
1463+
14411464
🏷️ The third case of `extern-type` allows a named interface to be imported or
14421465
exported with a custom [plain name]. For example:
14431466

@@ -1449,6 +1472,18 @@ world my-world {
14491472
}
14501473
```
14511474

1475+
When using both together ... For example:
1476+
1477+
```wit
1478+
world my-world {
1479+
@external-id("asdf")
1480+
import primary: wasi:keyvalue/store;
1481+
1482+
@external-id("asdf")
1483+
import secondary: wasi:keyvalue/store;
1484+
}
1485+
```
1486+
14521487
Here, `primary` and `secondary` are two distinct imports that both have the
14531488
instance type of the `wasi:keyvalue/store` interface. The plain name of the
14541489
import is the `id` before the colon (e.g., `primary`), not the interface name.
@@ -1510,9 +1545,9 @@ interface-item ::= gate 'interface' id '{' interface-items* '}'
15101545
15111546
interface-items ::= gate interface-definition
15121547
1513-
interface-definition ::= typedef-item
1514-
| use-item
1515-
| func-item
1548+
interface-definition ::= use-item
1549+
| external-id? typedef-item
1550+
| external-id? func-item
15161551
15171552
typedef-item ::= resource-item
15181553
| variant-items
@@ -1536,6 +1571,22 @@ named-type-list ::= ϵ
15361571
named-type ::= id ':' ty
15371572
```
15381573

1574+
🏷️ The optional `external-id` attribute allows ... For example:
1575+
1576+
```wit
1577+
interface my-interface {
1578+
@external-id("foo/0")
1579+
foo: func() -> string;
1580+
1581+
@external-id("GlobalScope.Bar")
1582+
resource bar {
1583+
@external-id("Bar.Baz/1")
1584+
baz: func() -> string;
1585+
}
1586+
}
1587+
```
1588+
1589+
15391590
The optional `async` prefix in a WIT function type indicates that the callee
15401591
may block and thus the caller should use the async ABI and asynchronous
15411592
source-language bindings (e.g., `async` functions in JS, Python, C# or Rust) if
@@ -2164,6 +2215,7 @@ annotation defined in [Explainer.md](Explainer.md#import-and-export-definitions)
21642215
interface the instance implements. Note though that each copy implements a
21652216
unique version of the interface in question. For example, the following WIT:
21662217

2218+
TODO: extend
21672219
```wit
21682220
package local:demo;
21692221

0 commit comments

Comments
 (0)