‘brevity is the soul of wit’ –– Polonius in Shakespeare’s Hamlet (blitheringly)
This is a Kotlin implementation of a WIT processor. It compiles WIT specifications into Kotlin interfaces, as well as host and guest bridging code for the Wasm runtime.
See the Explainer, Overview and Spec.
This project contains documentation and specifications copyrighted by the W3C WebAssembly Community Group, licensed under the Apache license.
- brevity: A runtime library for running components in Kotlin. It declares built-in types for
TupleandResulttypes. - brevity-build: Gradle project so we can run Brevity’s Gradle plugin in Brevity’s own build.
- brevity-cli: Command-line executable that compiles
.witinto.kt. - brevity-gradle-plugin: Invokes brevity-cli from Gradle.
- brevity-integration-tests: executes generated API stubs on the Chicory runtime, using both Kotlin and Rust as guest languages.
- brevity-kotlin-generator: uses parsed
.witfiles to generate.ktfiles. - brevity-testing: test facets for our own internal testing.
- brevity-wit: Parses and models
.witfiles. - sample: Sample project to exercise brevity gradle functionality.
- wasi
- brevity-wasi: Our implementations of the WASI APIs.
- brevity-wasi-p1: A hand-authored host binding for WASI Preview 1. We can't use Brevity
to generate this, because WASI Preview 1 cannot be expressed with
.wit. - brevity-wasi-p2: Compiles the WASI 0.2.0 tag (Preview 2) to Kotlin.
- brevity-wasi-p3: Compiles the WASI main branch (Preview 3) to Kotlin.
Brevity generates nice Kotlin APIs from .wit source files. It supports Kotlin as the host
(Kotlin/JVM) and the guest (Kotlin/Wasm).
Brevity generates APIs using okio.ByteString for list<s8> and list<u8> inputs.
Brevity flattens nested types interfaces. This yields simpler generated code, particularly for
WASI which uses types convention extensively.
Brevity can map limited WIT types like WallClock.Datetime to preferred platform types like
kotlin.time.Instant.
Add the Brevity plugin to your build.gradle.kts:
plugins {
id("dev.wasmo.brevity")
}Then add the worlds you want to generate APIs for:
brevity {
worlds.add("wasmo:platform/wasmo")
}WIT source is defined in commonMain/wit in a wkg-friendly structure. wkg is run on commonMain/wit
to fetch dependencies as part of the build process. Refer to wkg documentation for information on how
this may be configured.
Custom type mappings may be declared in your build file, too:
customTypeMappings.put("wasi:clocks/wall-clock.datetime@0.2.0", "kotlin.time.Instant")...and then implemented in Kotlin by providing an implementation of the generated Adapters interface in the same package:
package wit.wasi.clocks.v0_2_0
import dev.wasmo.brevity.WitAdapter
import kotlin.time.Instant
internal object RealAdapters : Adapters {
override val wallClockDatetime = object : WitAdapter<WallClock.Datetime, Instant> {
override fun fromWit(wit: WallClock.Datetime) =
Instant.fromEpochSeconds(wit.seconds.toLong(), wit.nanoseconds.toInt())
override fun toWit(value: Instant) =
WallClock.Datetime(value.epochSeconds.toULong(), value.nanosecondsOfSecond.toUInt())
}
}If you need to generate a Kotlin interface for a world defined in an existing WASM component
(as is done in :wasi:brevity-wasi-p3), manually add the source packages and all their dependencies
to brevity's build source in your gradle file:
brevity {
ociPackages.addAll(
"wasi:cli@0.3.1",
"wasi:clocks@0.3.1",
"wasi:filesystem@0.3.1",
"wasi:http@0.3.1",
"wasi:random@0.3.1",
"wasi:sockets@0.3.1",
)
worlds.add("wasi:http/service@0.3.1")
}Add a publish section to publish wit APIs through gradle:
brevity {
publish {
// Required - true if your wit folder is a single package layout, false if it
// is a whole workspace of packages.
workplace = true
// Optional - override wkg's config.toml file. Any paths defined here are resolved relative
// to the working dir where wkg is invoked, `build/brevity/sourceWit`.
config = "path/to/config/file"
}
}We have several different representations of the .wit code, that fit together in a pipeline.
- io: a direct representation of the
.witsource code. This isn’t linked and so type references are just strings and not resolved. UseIoWitPackageReaderto load this model. - ir: a linked representation of an entire project. Type references are resolved to their
fully-qualified values. Includes are applied, so worlds contain their full transitive
dependencies. This representation doesn’t model syntactic sugar like
UseandInclude. UseIrMapperto transformiointo this model. - api: a user-facing Kotlin API for a project, represented as
KotlinPoetfiles.