Add external-id attribute#672
Conversation
9e2219f to
eeb2ed0
Compare
ricochet
left a comment
There was a problem hiding this comment.
This looks good to me. I'd use it right away.
You may want to update Linking.md as well:
mutually known to later stages in the deployment pipeline (specifically with
the [depname] case ofimportnamein the text and binary format).
To something like:
mutually known to later stages in the deployment pipeline. (How an import
name is resolved to a particular registry artifact is left to the host or
build tooling; the optional [external-id] attribute can carry a
tooling-specific identifier such as a registry path or URL.)
| ### Strings | ||
|
|
||
| WIT string literals are double-quoted and use the same text format as the Core | ||
| WebAssembly text format's [`string`] literal. For example `"a"`, `"☃︎"`, `"\7f"` | ||
| and `"\u{7fff}"` are all `string` literals. | ||
|
|
||
| [`string`]: https://webassembly.github.io/spec/core/text/values.html#text-string |
There was a problem hiding this comment.
Clarification on this: core wasm string literals are for encoding byte arrays (e.g. data segments), so could/should this additionally indicate that a utf-8 check is expected?
There was a problem hiding this comment.
Oops, you're right; I should switch these strings back to name which, as you said, is the utf-8 decoding of string.
|
I've got an initial implementation of this over at bytecodealliance/wasm-tools#2555 if you wouldn't mind skimming over the test I've added |
|
Awesome! Test looks good. |
| * 🏷️ Validation requires that `implements`-annotated imports or exports have a | ||
| `<plainname>` name. | ||
| `instance`-typed and have a `plainname` name. | ||
| * 🏷️/🔗 Validation requires that a `vec(<attribute>)` contains each kind of |
There was a problem hiding this comment.
| * 🏷️/🔗 Validation requires that a `vec(<attribute>)` contains each kind of | |
| * 🏷️ Validation requires that `external-id`-annotated imports or exports are | |
| `instance`-typed. | |
| * 🏷️/🔗 Validation requires that a `vec(<attribute>)` contains each kind of |
There was a problem hiding this comment.
Shouldn't external-id be like implements and be only on instances?
There was a problem hiding this comment.
Great catch; I totally missed this discrepancy between the PR and @alexcrichton's above-linked test case. So while implements is inherently tied to a WIT interface (via interfacename) which is inherently tied to an instance type, external-id has no such tie. I think there are also real examples where you'd naturally want to put @external-id on other types of imports/exports (e.g., nullary functions returning capabilities) and indeed WIT.md already includes some (toy) examples that do this too. So perhaps we could keep the spec as-is and change the above test? WDYT @alexcrichton?
There was a problem hiding this comment.
Seems reasonable to me yeah, and sorry forgot to flag this here as well. This restriction came about when I was working on the WIT side of things and I was wondering where to store external-id in the AST of a WIT package.
Would it be ok to limit this to just functions/interfaces for now? Or should types be included? Or perhaps components/etc as well? Or, I suppose another way to ask, should there be any validation of external_id when it's encountered?
There was a problem hiding this comment.
Since @external-ids are really just about closing the kebab-case-name-expressivity gap, I think the use cases for it on instances and funcs are about as strong as for having it on components, core modules and types. E.g., with ESM-integration, it seems valuable for a component to be able to give a core module- or component-typed import a URL external-id so that these dependencies can be fetched by the ESM machinery without needing an import-map. That leaves type; a concrete use case there might be importing a resource type that corresponds to some arbitrary JS identifier? So my inclination is that there would be no validation criteria concerning the type (only that there is at most one external-id in the attribute list). But let me know if that's too big of a lift for now.
| 🏷️ The `external-id` attribute addresses the naming-expressivity gap left | ||
| between the restricted syntax of `externname` (shown next) and whatever |
There was a problem hiding this comment.
| 🏷️ The `external-id` attribute addresses the naming-expressivity gap left | |
| between the restricted syntax of `externname` (shown next) and whatever | |
| 🏷️ Like `implements`, the `external-id` attribute may only be applied to | |
| `instance`-typed imports and exports. It addresses the naming-expressivity gap | |
| left between the restricted syntax of `externname` (shown next) and whatever |
This PR extends #613, which added an
(implements <interfacename>)attribute to imports and exports, with an(external-id <string>)attribute. Theexternal-idattribute is useful when a component import or export name wants to match some external identifier, but the kebab-case syntax is too restrictive. One example is ESM-integration, where Module Specifiers can (now) be arbitrary Unicode strings (including URLs). Another is when importing stateful stores, e.g.:(as enabled by #613) and the platform-defined identifier of these stores isn't a valid
<plainname>, so you'd either have to add a whole separate name-mapping scheme (e.g. mappingredisandmemcachedto their host IDs) or mangle the host IDs into the<plainname>(say, via URL-encoding; ew). Instead, with this PR, you can use the@external-idattribute in WIT:and the WAT
(external-id <string>)is plumbed into the host, alongside(implements <interfacename>), so that the host can reflect on it and act accordingly.As mentioned above,
@external-idcan subsume the use cases forurl=<...>names for ESM-integration. Moreover, the reasoning in #613 for movingimplementsout of the name and into a separate attribute I think similarly suggests that the<urlname>,<depname>and<hashname>cases of<importname>aren't really the right place to solve their associated use cases. IIUC, these 3 name cases aren't currently being produced since there's no WIT syntax to emit them. Thus, this PR tentatively proposes removing these 3 name cases. The use cases are still important, but I think when we're ready to prioritize adding them to WIT/tooling, we should consider adding them as attributes instead. In the meantime, it lets us mergeimportnameandexportnameintoexternname, which simplifies nicely things.The PR also tidies up some sloppiness in the text-format grammar around string literals (e.g.,
"foo-bar") vs. the contents inside the quotes (e.g.foo-bar), using<Xstr>for the former and<X>for the latter.