Add specification for language binding API (#257)

This adds documentation for how the language bindings works, for those that wish to create their own bindings.
This commit is contained in:
Daniel Chao
2024-02-28 08:10:16 -08:00
committed by Dan Chao
parent a210bfd6a3
commit d9f8b8efa9
8 changed files with 990 additions and 64 deletions

View File

@@ -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]

View File

@@ -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

View File

@@ -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 <<object-members,object members>>
|link:{uri-stdlib-Map}[Map]
|`0x2`
|link:{uri-messagepack-map}[map]
|Map of `<value>` to `<value>`
|
|
|
|
|link:{uri-stdlib-Mapping}[Mapping]
|`0x3`
|link:{uri-messagepack-map}[map]
|Map of `<value>` to `<value>`
|
|
|
|
|link:{uri-stdlib-List}[List]
|`0x4`
|link:{uri-messagepack-array}[array]
|Array of `<value>`
|
|
|
|
|link:{uri-stdlib-Listing}[Listing]
|`0x5`
|link:{uri-messagepack-array}[array]
|Array of `<value>`
|
|
|
|
|link:{uri-stdlib-Set}[Set]
|`0x6`
|link:{uri-messagepack-array}[array]
|Array of `<value>`
|
|
|
|
|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`
|`<value>`
|First value
|`<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
|`<value>`
|property value
|Entry
|`0x11`
|`<value>`
|entry key
|`<value>`
|entry value
|Element
|`0x12`
|link:{uri-messagepack-int}[int]
|index
|`<value>`
|element value
|===

View File

@@ -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": <pkl binary value>
}
]
----
. 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.

View File

@@ -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 <<response-message>> with the same `requestId`.
[[response-message]]
=== Response Message
A message that is the response to a <<request-message>>.
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: <<client-message,Client>> <<request-message,Request>>
Create an evaluator with the provided evaluator settings.
Upon creating the evaluator, the server sends back a <<create-evaluator-response>> 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<String>?
/// Regex patterns to dettermine which resources are allowed to be read.
///
/// API version of the CLI's `--allowed-resources` flag
allowedResources: Listing<String>?
/// Register client-side module readers.
clientModuleReaders: Listing<ClientModuleReader>?
/// Register client-side resource readers.
clientResourceReaders: Listing<ClientResourceReader>?
/// Directories, ZIP archives, or JAR archives
/// to search when resolving `modulepath:` URIs.
///
/// API version of the CLI's `--module-path` flag.
modulePaths: Listing<String>?
/// Environment variable to set.
///
/// API version of the CLI's `--env-var` flag.
env: Mapping<String, String>?
/// External properties to set.
///
/// API version of the CLI's `--properties` flag.
properties: Mapping<String, String>?
/// 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<String, Project|RemoteDependency>
}
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: <<server-message,Server>> <<response-message,Response>>
The response for a <<create-evaluator-request>>.
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: <<client-message,Client>> <<one-way-message,One Way>>
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: <<client-message,Client>> <<request-message,Request>>
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: <<server-message,Server>> <<response-message,Response>>
The server's response to <<evaluate-request>>.
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: <<server-message,Server>> <<one-way-message,One Way>>
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: <<server-message,Server>> <<request-message,Request>>
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: <<client-message,Client>> <<response-message,Response>>
The response to <<read-resource-request>>.
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: <<server-message,Server>> <<request-message,Request>>
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: <<client-message,Client>> <<response-message,Response>>
The response to <<read-module-request>>.
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: <<server-message,Server>> <<request-message,Request>>
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: <<client-message,Client>> <<response-message,Response>>
The response to <<list-resources-request>>.
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<PathElement>?
/// 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: <<server-message,Server>> <<request-message,Request>>
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: <<client-message,Client>> <<response-message,Response>>
The response to <<list-modules-request>>.
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<PathElement>?
/// 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
}
----

View File

@@ -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

View File

@@ -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

View File

@@ -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]