diff --git a/docs/modules/ROOT/pages/language-bindings.adoc b/docs/modules/ROOT/pages/language-bindings.adoc index fab388fe..6c401d82 100644 --- a/docs/modules/ROOT/pages/language-bindings.adoc +++ b/docs/modules/ROOT/pages/language-bindings.adoc @@ -4,3 +4,6 @@ * xref:kotlin-binding:index.adoc[Kotlin] * xref:swift:ROOT:index.adoc[Swift] * xref:go:ROOT:index.adoc[Go] +* xref:bindings-specification:index.adoc[Specification] +** xref:bindings-specification:message-passing-api.adoc[Message Passing API] +** xref:bindings-specification:binary-encoding.adoc[Pkl Binary Encoding] diff --git a/docs/modules/ROOT/partials/component-attributes.adoc b/docs/modules/ROOT/partials/component-attributes.adoc index b23b5070..a30a4ba0 100644 --- a/docs/modules/ROOT/partials/component-attributes.adoc +++ b/docs/modules/ROOT/partials/component-attributes.adoc @@ -66,3 +66,76 @@ endif::[] :uri-config-java-example: {uri-pkl-examples-tree}/config-java :uri-config-kotlin-example: {uri-pkl-examples-tree}/config-kotlin :uri-pkldoc-example: {uri-pkl-examples-tree}/pkldoc + +:uri-stdlib-baseModule: {uri-pkl-stdlib-docs}/base +:uri-stdlib-jsonnetModule: {uri-pkl-stdlib-docs}/jsonnet +:uri-stdlib-reflectModule: {uri-pkl-stdlib-docs}/reflect +:uri-stdlib-xmlModule: {uri-pkl-stdlib-docs}/xml +:uri-stdlib-protobufModule: {uri-pkl-stdlib-docs}/protobuf +:uri-stdlib-Boolean: {uri-stdlib-baseModule}/Boolean +:uri-stdlib-xor: {uri-stdlib-baseModule}/Boolean#xor() +:uri-stdlib-implies: {uri-stdlib-baseModule}/Boolean#implies() +:uri-stdlib-Any: {uri-stdlib-baseModule}/Any +:uri-stdlib-String: {uri-stdlib-baseModule}/String +:uri-stdlib-Int: {uri-stdlib-baseModule}/Int +:uri-stdlib-Float: {uri-stdlib-baseModule}/Float +:uri-stdlib-Number: {uri-stdlib-baseModule}/Number +:uri-stdlib-NaN: {uri-stdlib-baseModule}/#NaN +:uri-stdlib-Infinity: {uri-stdlib-baseModule}/#Infinity +:uri-stdlib-isBetween: {uri-stdlib-baseModule}/Number#isBetween +:uri-stdlib-isFinite: {uri-stdlib-baseModule}/Number#isFinite +:uri-stdlib-Int8: {uri-stdlib-baseModule}/#Int8 +:uri-stdlib-Int16: {uri-stdlib-baseModule}/#Int16 +:uri-stdlib-Int32: {uri-stdlib-baseModule}/#Int32 +:uri-stdlib-UInt8: {uri-stdlib-baseModule}/#UInt8 +:uri-stdlib-UInt16: {uri-stdlib-baseModule}/#UInt16 +:uri-stdlib-UInt32: {uri-stdlib-baseModule}/#UInt32 +:uri-stdlib-UInt: {uri-stdlib-baseModule}/#UInt +:uri-stdlib-Uri: {uri-stdlib-baseModule}/#Uri +:uri-stdlib-matches: {uri-stdlib-baseModule}/String#matches() +:uri-stdlib-Null: {uri-stdlib-baseModule}/Null +:uri-stdlib-ifNonNull: {uri-stdlib-baseModule}/Null#ifNonNull() +:uri-stdlib-List: {uri-stdlib-baseModule}/List +:uri-stdlib-Set: {uri-stdlib-baseModule}/Set +:uri-stdlib-Map: {uri-stdlib-baseModule}/Map +:uri-stdlib-Listing: {uri-stdlib-baseModule}/Listing +:uri-stdlib-Listing-default: {uri-stdlib-baseModule}/Listing#default +:uri-stdlib-Listing-isDistinct: {uri-stdlib-baseModule}/Listing#isDistinct +:uri-stdlib-Listing-isDistinctBy: {uri-stdlib-baseModule}/Listing#isDistinctBy() +:uri-stdlib-Mapping: {uri-stdlib-baseModule}/Mapping +:uri-stdlib-Mapping-default: {uri-stdlib-baseModule}/Mapping#default +:uri-stdlib-Duration: {uri-stdlib-baseModule}/Duration +:uri-stdlib-Duration-value: {uri-stdlib-baseModule}/Duration#value +:uri-stdlib-Duration-unit: {uri-stdlib-baseModule}/Duration#unit +:uri-stdlib-DurationUnit: {uri-stdlib-baseModule}/#DurationUnit +:uri-stdlib-DataSize: {uri-stdlib-baseModule}/DataSize +:uri-stdlib-DataSize-value: {uri-stdlib-baseModule}/DataSize#value +:uri-stdlib-DataSize-unit: {uri-stdlib-baseModule}/DataSize#unit +:uri-stdlib-DataSizeUnit: {uri-stdlib-baseModule}/#DataSizeUnit +:uri-stdlib-Dynamic: {uri-stdlib-baseModule}/Dynamic +:uri-stdlib-Dynamic-toTyped: {uri-stdlib-baseModule}/Dynamic#toTyped() +:uri-stdlib-Typed: {uri-stdlib-baseModule}/Typed +:uri-stdlib-Regex: {uri-stdlib-baseModule}/Regex +:uri-stdlib-Regex-method: {uri-stdlib-baseModule}/#Regex() +:uri-stdlib-Regex-match: {uri-stdlib-baseModule}/Regex#match +:uri-stdlib-RegexMatch: {uri-stdlib-baseModule}/RegexMatch +:uri-stdlib-Pair: {uri-stdlib-baseModule}/Pair +:uri-stdlib-IntSeq: {uri-stdlib-baseModule}/IntSeq +:uri-stdlib-Class: {uri-stdlib-baseModule}/Class +:uri-stdlib-TypeAlias: {uri-stdlib-baseModule}/TypeAlias +:uri-stdlib-Deprecated: {uri-stdlib-baseModule}/Deprecated +:uri-stdlib-ValueRenderer: {uri-stdlib-baseModule}/ValueRenderer +:uri-stdlib-PcfRenderer-converters: {uri-stdlib-baseModule}/PcfRenderer#converters +:uri-stdlib-Function: {uri-stdlib-baseModule}/Function +:uri-stdlib-Function0: {uri-stdlib-baseModule}/Function0 +:uri-stdlib-Function1: {uri-stdlib-baseModule}/Function1 +:uri-stdlib-Function1-apply: {uri-stdlib-baseModule}/Function1#apply() +:uri-stdlib-Function2: {uri-stdlib-baseModule}/Function2 +:uri-stdlib-Function3: {uri-stdlib-baseModule}/Function3 +:uri-stdlib-Function4: {uri-stdlib-baseModule}/Function4 +:uri-stdlib-Function5: {uri-stdlib-baseModule}/Function5 +:uri-stdlib-Resource: {uri-stdlib-baseModule}/Resource +:uri-stdlib-outputFiles: {uri-stdlib-baseModule}/ModuleOutput#files + +:uri-messagepack: https://msgpack.org/index.html +:uri-messagepack-spec: https://github.com/msgpack/msgpack/blob/master/spec.md diff --git a/docs/modules/bindings-specification/pages/binary-encoding.adoc b/docs/modules/bindings-specification/pages/binary-encoding.adoc new file mode 100644 index 00000000..3bde4139 --- /dev/null +++ b/docs/modules/bindings-specification/pages/binary-encoding.adoc @@ -0,0 +1,197 @@ += Pkl Binary Encoding +include::ROOT:partial$component-attributes.adoc[] +include::partial$component-attributes.adoc[] + +Pkl values can be encoded into a binary format. +This format is used for Pkl's non-JVM language bindings, for example, for its Go and Swift bindings. + +The binary format is uses link:{uri-messagepack}[MessagePack] encoding. + +== Primitives + +All Pkl primitives turn into their respective MessagePack primitive. + +|=== +|Pkl Type|MessagePack format + +|link:{uri-stdlib-Int}[Int] +|link:{uri-messagepack-int}[int] + +|link:{uri-stdlib-Float}[Float] +|link:{uri-messagepack-float}[float] + +|link:{uri-stdlib-String}[String] +|link:{uri-messagepack-str}[string] + +|link:{uri-stdlib-Boolean}[Boolean] +|link:{uri-messagepack-bool}[bool] + +|link:{uri-stdlib-Null}[Null] +|link:{uri-messagepack-nil}[nil] +|=== + +NOTE: Pkl integers are encoded into the smallest int type that the number will fit into. +For example, value `8` gets encoded as MessagePack `int8` format. + +== Non-primitives + +All non-primitive values are encoded as MessagePack arrays. +The first slot of the array designates the value's type. The remaining slots have fixed meanings depending on the type. + +The array's length is the number of slots that are filled. For example, xref:{uri-stdlib-List}[List] is encoded as an MessagePack array with two elements. + +|=== +|Pkl type |Slot 1 2+|Slot 2 2+|Slot 3 2+|Slot 4 + +||code |type |description |type |description |type |description + +|link:{uri-stdlib-Typed}[Typed], link:{uri-stdlib-Dynamic}[Dynamic] +|`0x1` +|link:{uri-messagepack-str}[str] +|Fully qualified class name +|link:{uri-messagepack-str}[str] +|Enclosing module URI +|link:{uri-messagepack-array}[array] +|Array of <> + +|link:{uri-stdlib-Map}[Map] +|`0x2` +|link:{uri-messagepack-map}[map] +|Map of `` to `` +| +| +| +| + +|link:{uri-stdlib-Mapping}[Mapping] +|`0x3` +|link:{uri-messagepack-map}[map] +|Map of `` to `` +| +| +| +| + +|link:{uri-stdlib-List}[List] +|`0x4` +|link:{uri-messagepack-array}[array] +|Array of `` +| +| +| +| + +|link:{uri-stdlib-Listing}[Listing] +|`0x5` +|link:{uri-messagepack-array}[array] +|Array of `` +| +| +| +| + +|link:{uri-stdlib-Set}[Set] +|`0x6` +|link:{uri-messagepack-array}[array] +|Array of `` +| +| +| +| + +|link:{uri-stdlib-Duration}[Duration] +|`0x7` +|{uri-messagepack-float}[float64] +|Duration value +|link:{uri-messagepack-str}[str] +|link:{uri-stdlib-DurationUnit}[Duration unit] (`"ns"`, `"ms"`, etc.) +| +| + +|link:{uri-stdlib-DataSize}[DataSize] +|`0x8` +|link:{uri-messagepack-float}[float64] +|Value (float64) +|link:{uri-messagepack-str}[str] +|link:{uri-stdlib-DataSizeUnit}[DataSize unit] (`"b"`, `"kb"`, etc.) +| +| + +|link:{uri-stdlib-Pair}[Pair] +|`0x9` +|`` +|First value +|`` +|Second value +| +| + +|link:{uri-stdlib-IntSeq}[IntSeq] +|`0xA` +|link:{uri-messagepack-int}[int] +|Start +|link:{uri-messagepack-int}[int] +|End +|link:{uri-messagepack-int}[int] +|Step + +|link:{uri-stdlib-Regex}[Regex] +|`0xB` +|link:{uri-messagepack-str}[str] +|Regex string representation +| +| +| +| + +|link:{uri-stdlib-Class}[Class] +|`0xC` +| +| +| +| +| +| + +|link:{uri-stdlib-TypeAlias}[TypeAlias] +|`0xD` +| +| +| +| +| +| +|=== + +[[object-members]] +== Object Members + +Like non-primitive values, object members are encoded as MessagePack arrays, where the first slot designates the value's type. + +|=== +|Member type |Slot 1 2+|Slot 2 2+|Slot 3 + +| |code |type |description |type |description + +|Property +|`0x10` +|link:{uri-messagepack-str}[str] +|key +|`` +|property value + +|Entry +|`0x11` +|`` +|entry key +|`` +|entry value + +|Element +|`0x12` +|link:{uri-messagepack-int}[int] +|index +|`` +|element value +|=== + diff --git a/docs/modules/bindings-specification/pages/index.adoc b/docs/modules/bindings-specification/pages/index.adoc new file mode 100644 index 00000000..7aebdf67 --- /dev/null +++ b/docs/modules/bindings-specification/pages/index.adoc @@ -0,0 +1,173 @@ += Language Binding Specification + +:uri-pkl-go-github: https://github.com/apple/pkl-go +:uri-pkl-swift-github: https://github.com/apple/pkl-swift + +Pkl can be embedded within any host application. +The host application has access to low level controls. +It is able to manage the lifecycle of evaluators, as well as provide custom modules and resources to Pkl. + +Currently, Pkl must be embedded as a child process, by shelling out to the CLI using the xref:pkl-cli:index.adoc#command-server[`pkl server`] command. In the future, a C library will also be provided. + +When embedded, communication between a host application and Pkl happens via message passing. +The message passing specification can be found in xref:message-passing-api.adoc[]. + +For examples of language bindings in practice, review the xref:{uri-pkl-go-github}[pkl-go], or the xref:{uri-pkl-swift-github}[pkl-swift] codebases. + +NOTE: Pkl's Java and Kotlin libraries binds to Pkl directly, and do not use message passing. + +== Features of a language binding + +A language binding for Pkl should generally have the following components: + +. A client that spawns `pkl server`, and talks to it using message passing. +. A deserializer that turns xref:binary-encoding.adoc[pkl binary encoding] into a structure in the host language. +. A code generator that transforms Pkl schemas into schemas written in the host language. + The code generator is mostly written in Pkl, with a lightweight executable that acts as the glue layer. + For examples of code generators, consult link:{uri-pkl-go-github}/tree/main/codegen[pkl-go] and link:{uri-pkl-swift-github}/tree/main/codegen[pkl-swift]. + +== Sample flow + +Here is a sample flow for evaluating a module with the following contents: + +.\file:///path/to/myModule.pkl +[source,{pkl}] +---- +module MyModule + +theModules = import*("customfs:/*.pkl") +---- + +. Client sends xref:message-passing-api.adoc#create-evaluator-request[Create Evaluator Request], including `customfs` as a custom module reader. ++ +[source,json] +---- +[ + 0x20, + { + "requestId": 135, + "allowedModules": ["pkl:", "repl:", "file:", "customfs:"], + "clientModuleReaders": [ + { + "scheme": "customfs", + "hasHierarchicalUris": true, + "isGlobbable": true, + "isLocal": true + } + ] + } +] +---- +. Server sends xref:message-passing-api.adoc#create-evaluator-response[Create Evaluator Response], with an evaluator id. ++ +[source,json] +---- +[ + 0x21, + { + "requestId": 135, + "evaluatorId": -135901 + } +] +---- +. Client sends xref:message-passing-api.adoc#evaluate-request[Evaluate Request], providing the module's URI. ++ +[source,json] +---- +[ + 0x23, + { + "requestId": 9805131, + "evaluatorId": -13901, + "moduleUri": "file:///path/to/myModule.pkl" + } +] +---- +. During evaluation, server evaluates `import*("customfs:/*.pkl")`, and sends xref:message-passing-api.adoc#list-modules-request[List Modules Request]. ++ +[source,json] +---- +[ + 0x2c, + { + "requestId": -6478924, + "evaluatorId": -13901, + "uri": "customfs:/" + } +] +---- +. Client responds with xref:message-passing-api.adoc#list-modules-response[List Modules Response]. +In our pretend scenario, there is only one file; `foo.pkl`. ++ +[source,json] +---- +[ + 0x2d, + { + "requestId": -6478924, + "evaluatorId": -13901, + "pathElements": [ + { + "name": "foo.pkl", + "isDirectory": false + } + ] + } +] +---- +. Server sends xref:message-passing-api.adoc#read-module-request[Read Module Request] to read `foo.pkl`. ++ +[source,json] +---- +[ + 0x28, + { + "requestId": 36408291, + "evaluatorId": -13901, + "uri": "customfs:/foo.pkl" + } +] +---- +. Client responds with the module's contents ++ +[source,json] +---- +[ + 0x29, + { + "requestId": 36408291, + "evaluatorId": -13901, + "contents": "foo = 1" + } +] +---- +. Server finishes evaluation, and responds with the xref:message-passing-api.adoc#evaluate-response[Evaluate Response]. ++ +[source,json] +---- +[ + 0x24, + { + "requestId": 9805131, + "evaluatorId": -13901, + "result": + } +] +---- +. Client sends xref:message-passing-api.adoc#close-evaluator[Close Evaluator]. ++ +[source,json] +---- +[ + 0x22, + { + "evaluatorId": -13901 + } +] +---- + +== Debug logs + +Set the env var `PKL_DEBUG=1` to enable more verbose logging from Pkl. +It is recommended that clients also use this environment variable to enable debug logs of their own. + diff --git a/docs/modules/bindings-specification/pages/message-passing-api.adoc b/docs/modules/bindings-specification/pages/message-passing-api.adoc new file mode 100644 index 00000000..c53cb614 --- /dev/null +++ b/docs/modules/bindings-specification/pages/message-passing-api.adoc @@ -0,0 +1,531 @@ += Message Passing API + +include::ROOT:partial$component-attributes.adoc[] +include::partial$component-attributes.adoc[] + +All messages are encoded in link:{uri-messagepack}[MessagePack], as an array with two elements. + +The first element of the array is a code that designates the message's type, encoded as an int. +The second element of the array is the message body, encoded as a map. + +Messages are passed between the _client_ and the _server_. +The _client_ is the host language (for example, the Swift application when using pkl-swift). +The _server_ is the entity that provides controls for interacting with Pkl. + +For example, in JSON representation: + +[source,json] +---- +[ + 1, // <1> + { "someKey": "someValue" } // <2> +] +---- +<1> Code indicating message type +<2> Message body + +== Message types + +[[client-message]] +=== Client Message +A message passed from the client to the server. + +[[server-message]] +=== Server Message +A message passed from the server to the client. + +[[request-message]] +=== Request Message +A message sent with a `requestId` value. +The `requestId` should be a unique number at the time of message send. +The other side is expected to respond with a <> with the same `requestId`. + +[[response-message]] +=== Response Message +A message that is the response to a <>. +It contains the same `requestId` of the request message. + +[[one-way-message]] +=== One Way Message + +A fire-and-forget message where no response is expected. + +== Messages + +All messages have their schema described in Pkl. +A nullable type means that the property should be omitted (as opposed to the property's value being `nil`). + +[[create-evaluator-request]] +=== Create Evaluator Request + +Code: `0x20` + +Type: <> <> + +Create an evaluator with the provided evaluator settings. +Upon creating the evaluator, the server sends back a <> message. + +Schema: +[source,pkl] +---- +/// A number identifying this request +requestId: Int + +/// Regex patterns to determine which modules are allowed for import. +/// +/// API version of the CLI's `--allowed-modules` flag +allowedModules: Listing? + +/// Regex patterns to dettermine which resources are allowed to be read. +/// +/// API version of the CLI's `--allowed-resources` flag +allowedResources: Listing? + +/// Register client-side module readers. +clientModuleReaders: Listing? + +/// Register client-side resource readers. +clientResourceReaders: Listing? + +/// Directories, ZIP archives, or JAR archives +/// to search when resolving `modulepath:` URIs. +/// +/// API version of the CLI's `--module-path` flag. +modulePaths: Listing? + +/// Environment variable to set. +/// +/// API version of the CLI's `--env-var` flag. +env: Mapping? + +/// External properties to set. +/// +/// API version of the CLI's `--properties` flag. +properties: Mapping? + +/// Duration, in seconds, after which evaluation of a source module will be timed out. +/// +/// API version of the CLI's `--timeout` flag. +timeoutSeconds: Int? + +/// Restricts access to file-based modules and resources to those located under the root directory. +rootDir: String? + +/// The cache directory for storing packages. +cacheDir: String? + +/// The format to generate. +/// +/// This sets the `pkl.outputFormat` external property. +outputFormat: String? + +/// The project dependency settings. +project: Project? + +class ClientResourceReader { + /// The URI scheme this reader is responsible for reading. + scheme: String + + /// Tells whether the path part of ths URI has a + /// [hier-part](https://datatracker.ietf.org/doc/html/rfc3986#section-3). + /// + /// An example of a hierarchical URI is `file:///path/to/my/file`, where + /// `/path/to/my/file` designates a nested path through the `/` character. + /// + /// An example of a non-hierarchical URI is `pkl.base`, where the `base` does not denote + /// any form of hierarchy. + hasHierarchicalUris: Boolean + + /// Tells whether this reader supports globbing. + isGlobbable: Boolean +} + +class ClientModuleReader { + /// The URI scheme this reader is responsible for reading. + scheme: String + + /// Tells whether the path part of ths URI has a + /// [hier-part](https://datatracker.ietf.org/doc/html/rfc3986#section-3). + /// + /// An example of a hierarchical URI is `file:///path/to/my/file`, where + /// `/path/to/my/file` designates a nested path through the `/` character. + /// + /// An example of a non-hierarchical URI is `pkl.base`, where the `base` does not denote + /// any form of hierarchy. + hasHierarchicalUris: Boolean + + /// Tells whether this reader supports globbing. + isGlobbable: Boolean + + /// Tells whether the module is local to the system. + /// + /// A local resource that [hasHierarchicalUris] supports triple-dot imports. + isLocal: Boolean +} + +class Project { + type: "local" + + /// The canonical URI of this project's package + packageUri: String? + + /// The URI pointing to the location of the project file. + projectFileUri: String + + /// The dependencies of this project. + dependencies: Mapping +} + +class RemoteDependency { + type: "remote" + + /// The canonical URI of this dependency + packageUri: String? + + /// The checksums of this remote dependency + checksums: Checksums? +} + +class Checksums { + /// The sha-256 checksum of this dependency's metadata. + sha256: String +} +---- + +Example: +[source,json5] +---- +[ + 0x20, + { + "requestId": 193501, + "allowedModules": ["pkl:", "repl:"], + "allowedResources": ["file:", "package:", "projectpackage:"] + } +] +---- + +[[create-evaluator-response]] +=== Create Evaluator Response + +Code: `0x21` + +Type: <> <> + +The response for a <>. +If the evaluator was created successfully, `evaluatorId` is set. Otherwise, `error` is set to the resulting error. + +[source,pkl] +---- +/// A number identifying this request +requestId: Int + +/// A number identifying the created evaluator. +evaluatorId: Int? + +/// A message detailing why the evaluator was not created. +error: String? +---- + +[[close-evaluator]] +=== Close Evaluator + +Code: `0x22` + +Type: <> <> + +Tells the Pkl server to close an evaluator, releasing any resources it may be holding. + +[source,pkl] +---- +/// A number identifying this evaluator. +evaluatorId: Int +---- + +[[evaluate-request]] +=== Evaluate Request + +Code: `0x23` + +Type: <> <> + +Evaluate a module. + +[source,pkl] +---- +/// A number identifying this request +requestId: Int + +/// A number identifying this evaluator. +evaluatorId: Int + +/// The absolute URI of the module to be evaluated. +moduleUri: String + +/// The module's contents. +/// +/// If [null], Pkl will load the module at runtime. +moduleText: String? + +/// The Pkl expression to be evaluated within the module. +/// +/// If [null], evaluates the whole module. +expr: String? +---- + +[[evaluate-response]] +=== Evaluate Response + +Code: `0x24` + +Type: <> <> + +The server's response to <>. +If the evaluation is successful, the response is the Pkl value encoded in xref:binary-encoding.adoc[binary encoding]. + +[source,pkl] +---- +/// The requestId of the Evaluate request +requestId: Int + +/// A number identifying this evaluator. +evaluatorId: Int + +/// The evaluation contents, if successful. +result: Binary? // <1> + +/// A message detailing why evaluation failed. +error: String? + +typealias Binary = Any // <1> +---- +<1> xref:binary-encoding.adoc[Pkl Binary Encoding] in link:{uri-messagepack-bin}[bin format] (not expressable in Pkl) + +[[log]] +=== Log + +Code: `0x25` + +Type: <> <> + +Tells the client to emit a log message, during the execution of a Pkl program. +A log can occur through a xref:language-reference:index.adoc#debugging[trace()] expression, or through a warning (for example, when encountering a link:{uri-stdlib-Deprecated}[Deprecated] value.) + +[source,pkl] +---- +/// A number identifying this evaluator. +evaluatorId: Int + +/// A number identifying the log level. +/// +/// - 0: trace +/// - 1: warn +level: Int(this == 0 || this == 1) + +/// The message to be logged +message: String + +/// A string representing the source location within Pkl code producing this log output. +frameUri: String +---- + +[[read-resource-request]] +=== Read Resource Request + +Code: `0x26` + +Type: <> <> + +Read a resource at the given URI. +This message occurs when a read expression (`read`/`read?`/`read*`) is encountered within a program, and its scheme matches a client resource reader. + +[source,pkl] +---- +/// A number identifying this request. +requestId: Int + +/// A number identifying this evaluator. +evaluatorId: Int + +/// The URI of the resource. +uri: String +---- + +[[read-resource-response]] +=== Read Resource Response + +Code: `0x27` + +Type: <> <> + +The response to <>. +If successful, `contents` is set. +Otherwise, `error` is set. + +[source,pkl] +---- +/// A number identifying this request. +requestId: Int + +/// A number identifying this evaluator. +evaluatorId: Int + +/// The contents of the resource. +contents: Binary? // <1> + +/// The description of the error that occured when reading this resource. +error: String? + +typealias Binary = Any // <1> +---- +<1> MessagePack's link:https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family[bin format family] (not expressable in Pkl) + +[[read-module-request]] +=== Read Module Request + +Code: `0x28` + +Type: <> <> + +Read a module at the given URI. +This message occurs during the evaluation of an import statement or expression (`import`/`import*`), when a scheme matches a client module reader. + +[source,pkl] +---- +/// A number identifying this request. +requestId: Int + +/// A number identifying this evaluator. +evaluatorId: Int + +/// The URI of the module. +uri: String +---- + +[[read-module-response]] +=== Read Module Response + +Code: `0x29` + +Type: <> <> + +The response to <>. +If successful, `contents` is set. +Otherwise, `error` is set. + +[source,pkl] +---- +/// A number identifying this request. +requestId: Int + +/// A number identifying this evaluator. +evaluatorId: Int + +/// The string contents of the module. +contents: String? + +/// The description of the error that occured when reading this resource. +error: String? +---- + +[[list-resources-request]] +=== List Resources Request + +Code: `0x2a` + +Type: <> <> + +List resources at the specified base path. +This message occurs during the evaluation of a xref:language-reference:index.adoc#globbed-reads[globbed read], when a scheme matches a client resource reader's scheme. + +If the resource reader does not have hierarchical URIs, `dummy` is used as the path, and the response is expected to contain all resource elements for that scheme. + +[source,pkl] +---- +/// A number identifying this request. +requestId: Int + +/// A number identifying this evaluator. +evaluatorId: Int + +/// The base URI to list resources. +uri: String +---- + +[[list-resources-response]] +=== List Resources Response + +Code: `0x2b` + +Type: <> <> + +The response to <>. +If successful, `pathElements` is set. +Otherwise, `error` is set. + +[source,pkl] +---- +/// A number identifying this request. +requestId: Int + +/// A number identifying this evaluator. +evaluatorId: Int + +/// The elements at the provided base path. +pathElements: Listing? + +/// The description of the error that occured when listing elements. +error: String? + +class PathElement { + /// The name of the element at this path + name: String + + /// Tells whether the element is a directory. + isDirectory: Boolean +} +---- + +[[list-modules-request]] +=== List Modules Request + +Code: `0x2c` + +Type: <> <> + +List modules at the specified base path. +This message occurs during the evaluation of a xref:language-reference:index.adoc#globbed-imports[globbed import], when a scheme matches a client resource reader's scheme. + +If the module reader does not have hierarchical URIs, `dummy` is used as the path, and the response is expected to contain all module elements for that scheme. + +[source,pkl] +---- +/// A number identifying this request. +requestId: Int + +/// A number identifying this evaluator. +evaluatorId: Int + +/// The base URI to list modules. +uri: String +---- + +[[list-modules-response]] +=== List Modules Response + +Code: `0x2d` + +Type: <> <> + +The response to <>. +If successful, `pathElements` is set. +Otherwise, `error` is set. + +[source,pkl] +---- +/// A number identifying this request. +requestId: Int + +/// A number identifying this evaluator. +evaluatorId: Int + +/// The elements at the provided base path. +pathElements: Listing? + +/// The description of the error that occured when listing elements. +error: String? + +class PathElement { + /// The name of the element at this path + name: String + + /// Tells whether the element is a directory. + isDirectory: Boolean +} +---- diff --git a/docs/modules/bindings-specification/partials/component-attributes.adoc b/docs/modules/bindings-specification/partials/component-attributes.adoc new file mode 100644 index 00000000..41891600 --- /dev/null +++ b/docs/modules/bindings-specification/partials/component-attributes.adoc @@ -0,0 +1,9 @@ +:uri-github-binary-encoding-snippet-tests: {uri-github-tree}/pkl-server/src/test/files/SnippetTests +:uri-messagepack-bool: {uri-messagepack-spec}#bool-format-family +:uri-messagepack-int: {uri-messagepack-spec}#int-format-family +:uri-messagepack-float: {uri-messagepack-spec}#float-format-family +:uri-messagepack-str: {uri-messagepack-spec}#str-format-family +:uri-messagepack-bin: {uri-messagepack-spec}#bin-format-family +:uri-messagepack-array: {uri-messagepack-spec}#array-format-family +:uri-messagepack-map: {uri-messagepack-spec}#map-format-family +:uri-messagepack-nil: {uri-messagepack-spec}#nil-format diff --git a/docs/modules/language-reference/pages/index.adoc b/docs/modules/language-reference/pages/index.adoc index 1a2160fe..60f4c747 100644 --- a/docs/modules/language-reference/pages/index.adoc +++ b/docs/modules/language-reference/pages/index.adoc @@ -9,70 +9,6 @@ include::ROOT:partial$component-attributes.adoc[] :uri-javadoc-Pattern: https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html :uri-github-PklLexer: {uri-github-tree}/pkl-core/src/main/antlr/PklLexer.g4 :uri-github-PklParser: {uri-github-tree}/pkl-core/src/main/antlr/PklParser.g4 -:uri-stdlib-baseModule: {uri-pkl-stdlib-docs}/base -:uri-stdlib-jsonnetModule: {uri-pkl-stdlib-docs}/jsonnet -:uri-stdlib-reflectModule: {uri-pkl-stdlib-docs}/reflect -:uri-stdlib-xmlModule: {uri-pkl-stdlib-docs}/xml -:uri-stdlib-protobufModule: {uri-pkl-stdlib-docs}/protobuf -:uri-stdlib-Boolean: {uri-stdlib-baseModule}/Boolean -:uri-stdlib-xor: {uri-stdlib-baseModule}/Boolean#xor() -:uri-stdlib-implies: {uri-stdlib-baseModule}/Boolean#implies() -:uri-stdlib-Any: {uri-stdlib-baseModule}/Any -:uri-stdlib-String: {uri-stdlib-baseModule}/String -:uri-stdlib-Int: {uri-stdlib-baseModule}/Int -:uri-stdlib-Float: {uri-stdlib-baseModule}/Float -:uri-stdlib-Number: {uri-stdlib-baseModule}/Number -:uri-stdlib-NaN: {uri-stdlib-baseModule}/#NaN -:uri-stdlib-Infinity: {uri-stdlib-baseModule}/#Infinity -:uri-stdlib-isBetween: {uri-stdlib-baseModule}/Number#isBetween -:uri-stdlib-isFinite: {uri-stdlib-baseModule}/Number#isFinite -:uri-stdlib-Int8: {uri-stdlib-baseModule}/#Int8 -:uri-stdlib-Int16: {uri-stdlib-baseModule}/#Int16 -:uri-stdlib-Int32: {uri-stdlib-baseModule}/#Int32 -:uri-stdlib-UInt8: {uri-stdlib-baseModule}/#UInt8 -:uri-stdlib-UInt16: {uri-stdlib-baseModule}/#UInt16 -:uri-stdlib-UInt32: {uri-stdlib-baseModule}/#UInt32 -:uri-stdlib-UInt: {uri-stdlib-baseModule}/#UInt -:uri-stdlib-Uri: {uri-stdlib-baseModule}/#Uri -:uri-stdlib-matches: {uri-stdlib-baseModule}/String#matches() -:uri-stdlib-Null: {uri-stdlib-baseModule}/Null -:uri-stdlib-ifNonNull: {uri-stdlib-baseModule}/Null#ifNonNull() -:uri-stdlib-List: {uri-stdlib-baseModule}/List -:uri-stdlib-Set: {uri-stdlib-baseModule}/Set -:uri-stdlib-Map: {uri-stdlib-baseModule}/Map -:uri-stdlib-Listing: {uri-stdlib-baseModule}/Listing -:uri-stdlib-Listing-default: {uri-stdlib-baseModule}/Listing#default -:uri-stdlib-Listing-isDistinct: {uri-stdlib-baseModule}/Listing#isDistinct -:uri-stdlib-Listing-isDistinctBy: {uri-stdlib-baseModule}/Listing#isDistinctBy() -:uri-stdlib-Mapping: {uri-stdlib-baseModule}/Mapping -:uri-stdlib-Mapping-default: {uri-stdlib-baseModule}/Mapping#default -:uri-stdlib-Duration: {uri-stdlib-baseModule}/Duration -:uri-stdlib-Duration-value: {uri-stdlib-baseModule}/Duration#value -:uri-stdlib-Duration-unit: {uri-stdlib-baseModule}/Duration#unit -:uri-stdlib-DurationUnit: {uri-stdlib-baseModule}/#DurationUnit -:uri-stdlib-DataSize: {uri-stdlib-baseModule}/DataSize -:uri-stdlib-DataSize-value: {uri-stdlib-baseModule}/DataSize#value -:uri-stdlib-DataSize-unit: {uri-stdlib-baseModule}/DataSize#unit -:uri-stdlib-DataSizeUnit: {uri-stdlib-baseModule}/#DataSizeUnit -:uri-stdlib-Dynamic: {uri-stdlib-baseModule}/Dynamic -:uri-stdlib-Dynamic-toTyped: {uri-stdlib-baseModule}/Dynamic#toTyped() -:uri-stdlib-Typed: {uri-stdlib-baseModule}/Typed -:uri-stdlib-Regex: {uri-stdlib-baseModule}/Regex -:uri-stdlib-Regex-method: {uri-stdlib-baseModule}/#Regex() -:uri-stdlib-Regex-match: {uri-stdlib-baseModule}/Regex#match -:uri-stdlib-RegexMatch: {uri-stdlib-baseModule}/RegexMatch -:uri-stdlib-ValueRenderer: {uri-stdlib-baseModule}/ValueRenderer -:uri-stdlib-PcfRenderer-converters: {uri-stdlib-baseModule}/PcfRenderer#converters -:uri-stdlib-Function: {uri-stdlib-baseModule}/Function -:uri-stdlib-Function0: {uri-stdlib-baseModule}/Function0 -:uri-stdlib-Function1: {uri-stdlib-baseModule}/Function1 -:uri-stdlib-Function1-apply: {uri-stdlib-baseModule}/Function1#apply() -:uri-stdlib-Function2: {uri-stdlib-baseModule}/Function2 -:uri-stdlib-Function3: {uri-stdlib-baseModule}/Function3 -:uri-stdlib-Function4: {uri-stdlib-baseModule}/Function4 -:uri-stdlib-Function5: {uri-stdlib-baseModule}/Function5 -:uri-stdlib-Resource: {uri-stdlib-baseModule}/Resource -:uri-stdlib-outputFiles: {uri-stdlib-baseModule}/ModuleOutput#files :uri-pkl-core-ModuleSchema: {uri-pkl-core-main-sources}/ModuleSchema.java :uri-pkl-core-SecurityManager: {uri-pkl-core-main-sources}/SecurityManager.java :uri-pkl-core-ResourceReader: {uri-pkl-core-main-sources}/resource/ResourceReader.java diff --git a/docs/nav.adoc b/docs/nav.adoc index d3fe0bfe..dbfa1cd7 100644 --- a/docs/nav.adoc +++ b/docs/nav.adoc @@ -23,6 +23,9 @@ **** xref:kotlin-binding:pkl-config-kotlin.adoc[pkl-config-kotlin Library] *** xref:swift:ROOT:index.adoc[Swift] *** xref:go:ROOT:index.adoc[Go] +*** xref:bindings-specification:index.adoc[Specification] +**** xref:bindings-specification:message-passing-api.adoc[Message Passing API] +**** xref:bindings-specification:binary-encoding.adoc[Pkl Binary Encoding] * xref:ROOT:tools.adoc[Tools] ** xref:pkl-cli:index.adoc[CLI] @@ -38,3 +41,4 @@ * xref:release-notes:index.adoc[Release Notes] ** xref:release-notes:0.25.adoc[0.25 Release Notes] ** xref:release-notes:changelog.adoc[Changelog] +