UNPKG

@thi.ng/wasm-api-bindgen

Version:

Polyglot bindings code generators (TS/JS, Zig, C11) for hybrid WebAssembly projects

313 lines (312 loc) 9.55 kB
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://schema.thi.ng/wasm-api/20221111.json", "title": "WASM API code generator type specs", "description": "Polyglot type definition for hybrid WASM/TypeScript applications", "type": "array", "items": { "type": "object", "oneOf": [ { "$ref": "#/$defs/enum" }, { "$ref": "#/$defs/ext" }, { "$ref": "#/$defs/funcptr" }, { "$ref": "#/$defs/struct" }, { "$ref": "#/$defs/union" } ] }, "$defs": { "enum": { "type": "object", "properties": { "body": { "$ref": "#/$defs/body" }, "doc": { "$ref": "#/$defs/doc" }, "name": { "$ref": "#/$defs/name" }, "skip": { "$ref": "#/$defs/skip" }, "type": { "const": "enum", "description": "This spec describes an `enum`-style type." }, "tag": { "$ref": "#/$defs/int", "description": "Optional integer type to use. Defaults to `i32` Note: If C ABI compatibility is required, then `i32` MUST be used." }, "values": { "type": "array", "items": { "oneOf": [ { "type": "string" }, { "type": "object", "properties": { "name": { "type": "string" }, "value": { "type": "integer", "description": "Integer value associated with this name" }, "doc": { "$ref": "#/$defs/doc" } }, "required": ["name"] } ], "description": "Names should be given in lowercase. Some code generators can be configured to auto-capitalize these names." }, "title": "Possible enum names", "description": "Nonconsecutive or specific values are described via objects of `name`/`value` pairs." } }, "required": ["name", "type", "values"] }, "ext": { "type": "object", "properties": { "doc": { "$ref": "#/$defs/doc" }, "name": { "$ref": "#/$defs/name" }, "type": { "const": "ext", "description": "This spec describes an external type." }, "align": { "type": "integer", "description": "Type alignment (in bytes)" }, "size": { "type": "integer", "description": "Type size (in bytes)" } }, "required": ["name", "type", "align", "size"] }, "funcptr": { "type": "object", "properties": { "body": { "$ref": "#/$defs/body" }, "doc": { "$ref": "#/$defs/doc" }, "name": { "$ref": "#/$defs/name" }, "skip": { "$ref": "#/$defs/skip" }, "type": { "const": "funcptr", "description": "This spec describes a function pointer type." }, "rtype": { "anyOf": [ { "const": "void" }, { "$ref": "#/$defs/prim" }, { "type": "string" } ], "title": "Function return type", "$ref": "#/$defs/docArgs" }, "args": { "type": "array", "items": { "$ref": "#/$defs/field" }, "title": "Function arguments", "$ref": "#/$defs/docArgs" } }, "required": ["name", "type", "rtype", "args"] }, "struct": { "type": "object", "properties": { "body": { "$ref": "#/$defs/body" }, "doc": { "$ref": "#/$defs/doc" }, "fields": { "$ref": "#/$defs/fields" }, "name": { "$ref": "#/$defs/name" }, "skip": { "$ref": "#/$defs/skip" }, "type": { "const": "struct", "description": "This spec describes a struct-style type." } } }, "union": { "type": "object", "properties": { "body": { "$ref": "#/$defs/body" }, "doc": { "$ref": "#/$defs/doc" }, "fields": { "$ref": "#/$defs/fields" }, "name": { "$ref": "#/$defs/name" }, "skip": { "$ref": "#/$defs/skip" }, "type": { "const": "union", "description": "This spec describes a union type." } } }, "int": { "enum": [ "i8", "u8", "i16", "u16", "i32", "u32", "i64", "u64", "isize", "usize" ] }, "prim": { "oneOf": [ { "$ref": "#/$defs/int" }, { "enum": ["f32", "f64"] } ] }, "stringOrArray": { "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" } } ], "description": "Each line will be automatically word-wrapped and prefixed with the appropriate comment syntax of the target language." }, "name": { "type": "string", "title": "Type or field name", "description": "This name will be used as-is by all code generators and therefore should ensure to not violate naming rules of any of the intended target languages." }, "doc": { "$ref": "#/$defs/stringOrArray", "title": "Docstring for this type or field." }, "docArgs": { "description": "With a few exceptions & language specific limitations, the range of possibilities is similar to field types." }, "field": { "type": "object", "description": "Type spec for a single field within a struct or union. If `pad` is given, all other keys are ignored and the field is only considered for padding/alignment/sizing purposes. Names for padding fields will be autogenerated.", "properties": { "name": { "$ref": "#/$defs/name" }, "doc": { "$ref": "#/$defs/doc" }, "type": { "$ref": "#/$defs/fieldType" }, "tag": { "$ref": "#/$defs/fieldTag" }, "const": { "type": "boolean", "description": "Marks type as constant / readonly data. Note: For pointers this refers to the target data, not to the pointer itself." }, "optional": { "type": "boolean", "description": "Marks type as optional. Language specific and currently only supported for pointer types." }, "sentinel": { "type": "integer", "description": "Optional value for sentinel-terminated arrays/pointers" }, "pad": { "type": "integer", "minimum": 1, "description": "Number of padding bytes. If given, all other keys are ignored." }, "default": { "description": "Optional default value (or verbatim source code). If given as object, language specific defaults can be provided.", "oneOf": [ { "type": "number" }, { "type": "string" }, { "type": "object", "additionalProperties": { "oneOf": [ { "type": "number" }, { "type": "string" } ] } } ] }, "skip": { "type": "boolean", "default": false, "description": "If true, code generation of this field will be skipped for WASM host environment languages (e.g. TypeScript)" }, "getter": { "type": "boolean", "default": true, "description": "If false, omits getter for languages which would usually define one (e.g. TypeScript)" }, "setter": { "type": "boolean", "default": true, "description": "If false, omits setter for languages which would usually define one (e.g. TypeScript)" } }, "required": ["name", "type"], "if": { "properties": { "tag": { "oneOf": [{ "const": "array" }, { "const": "vec" }] } }, "required": ["tag"] }, "then": { "properties": { "len": { "type": "integer", "minimum": 1, "default": 1, "description": "Array or vector length" } }, "required": ["len"] } }, "fieldType": { "anyOf": [ { "$ref": "#/$defs/prim" }, { "enum": ["opaque", "string"] }, { "type": "string" } ], "title": "Field type", "description": "Either a WASM primitive type, a preset name (i.e. `opaque` or `string`) or the name of another type in this document.\n\n- `isize` / `usize` types will be sized depending on chosen WASM target (wasm32/wasm64).\n- `opaque` types are always considered pointers only.\n- `string` types are language specific and the result type can be configured via codegen options (i.e. slice vs. raw pointer)." }, "fieldTag": { "enum": ["array", "ptr", "single", "slice", "vec"], "default": "single", "title": "Optional array type modifier", "description": "If `array` or `vec` is selected, the `len` MUST be given too. Note: Not all tags are natively supported by all languages and might result in generation of \"polyfills\". E.g. vectors are similar to arrays, but have stricter alignment & potentially different codegeneration (language specific)." }, "fields": { "type": "array", "items": { "$ref": "#/$defs/field" }, "description": "Array of fields specs for a struct or union type" }, "body": { "type": "object", "title": "Optional custom per-language user code injections", "description": "Keys of this object are target language IDs and values are source code (will be automatically indented). Use object values (with `decl` and `impl` keys) for languages requiring multiple injection points for declaration vs. implementation (e.g. TypeScript).", "additionalProperties": { "oneOf": [ { "$ref": "#/$defs/stringOrArray" }, { "type": "object", "properties": { "decl": { "$ref": "#/$defs/stringOrArray", "title": "User code for additional declarations" }, "impl": { "$ref": "#/$defs/stringOrArray", "title": "User code for additional implementations" } }, "description": "The `decl` and `impl` keys can be used for languages requiring multiple injection points for declarations (e.g. interface additions) vs. implementation methods (e.g. within a struct)" } ] } }, "skip": { "type": "array", "items": { "type": "string" }, "description": "List of language IDs for which code generation of this type should be skipped." } } }