diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5103a68..6a98c54 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,7 +32,7 @@ jobs: ./plugin/.spago ./conformance/.spago - - name: Install dependencies + - name: Install Plugin dependencies run: | protoc --version echo -n "node " @@ -42,6 +42,7 @@ jobs: echo -n "spago " spago --version echo "" + cd plugin spago install - name: Build Plugin @@ -52,7 +53,7 @@ jobs: - name: Test Plugin # Need --experimental_allow_proto3_optional until the CI protoc is upgraded run: | - protoc --experimental_allow_proto3_optional --plugin=bin/protoc-gen-purescript --purescript_out=./plugin/test/Test/generated --proto_path ./plugin/test ./plugin/test/*.proto + protoc --experimental_allow_proto3_optional --plugin=bin/protoc-gen-purescript --purescript_out=./plugin/test/Test/generated --proto_path=./plugin/test ./plugin/test/*.proto cd plugin spago test diff --git a/.vscode/settings.json b/.vscode/settings.json index 99f3263..fdd4f1f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,3 @@ { - "purescript.buildCommand": "spago build --json-errors", + "purescript.autoStartPscIde": true } diff --git a/README.md b/README.md deleted file mode 100644 index 1cbfed9..0000000 --- a/README.md +++ /dev/null @@ -1,372 +0,0 @@ -# purescript-protobuf 💝 - -[![Pursuit](http://pursuit.purescript.org/packages/purescript-protobuf/badge)](http://pursuit.purescript.org/packages/purescript-protobuf/) -[![Maintainer: jamesdbrock](https://img.shields.io/badge/maintainer-jamesdbrock-teal.svg)](https://github.com/jamesdbrock) - -PureScript library and code generator for -[Google Protocol Buffers version 3](https://protobuf.dev/programming-guides/proto3/). - -This library operates on -[`ArrayBuffer`](https://pursuit.purescript.org/packages/purescript-arraybuffer-types/docs/Data.ArrayBuffer.Types#t:ArrayBuffer), so it will run both -[in *Node.js*](https://pursuit.purescript.org/packages/purescript-node-buffer/docs/Node.Buffer.Class) -and in browser environments. - -## Features - -We aim to support binary-encoded protobuf for -`syntax = "proto3";` descriptor files. - -Many `syntax = "proto2";` descriptor files will -also work, as long as they don't use `"proto2"` features, especially -[groups](https://protobuf.dev/programming-guides/proto2/#groups), -which we do not support. We also do not support `"proto2"` -[extensions](https://protobuf.dev/programming-guides/proto2/#extensions). - -We do not support -[services](https://protobuf.dev/programming-guides/proto3/#services). - -We do not support -[JSON Mapping](https://protobuf.dev/programming-guides/proto3/#json). - -### Conformance and Testing - -In this version, we pass all 684 of the -[Google conformance tests](https://github.com/protocolbuffers/protobuf/tree/main/conformance) -of binary-wire-format *proto3* for [Protocol Buffers v28.2](https://github.com/protocolbuffers/protobuf/releases/tag/v28.2). -See the `conformance/README.md` in this repository for details. - -We also have our own unit tests, see `test/README.md` in this repository. - -## Code Generation - -The `nix develop` environment provides - -* The PureScript toolchain: `purs`, `spago`, and `node`. -* The [`protoc`](https://protobuf.dev/programming-guides/proto3/#generating) compiler. -* The `protoc-gen-purescript` executable plugin for `protoc` on the `PATH` so that - [`protoc` can find it](https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.plugin/). - -``` -$ nix develop - -PureScript Protobuf development environment -libprotoc 28.2 -node v20.15.1 -purs 0.15.15 -spago 0.93.40 - -To build the protoc compiler plugin, run: - - cd plugin - spago build - -To compile PureScript .purs files from .proto files, run for example: - - protoc --purescript_out=. google/protobuf/timestamp.proto -``` - -We can test out code generation immediately by -generating `.purs` files for any of Google’s built-in “well-known types” in the -[`google.protobuf`](https://protobuf.dev/reference/protobuf/google.protobuf/) package namespace. Try the command -```shell -protoc --purescript_out=. google/protobuf/any.proto -``` -or -```shell -protoc --purescript_out=. google/protobuf/timestamp.proto -``` - -To see -[all of the `.proto` definitions](https://github.com/protocolbuffers/protobuf/tree/main/src/google/protobuf) -included with the Nix PureScript Protobuf installation including -the “well-known types,” -```shell -ls $(nix path-info .#protobuf)/src/google/protobuf/*.proto -``` - -If you don't want to use Nix, -1. install the PureScript toolchain and `protoc`. -2. Build the [PureScript plugin for `protoc`](plugin/). -3. Run `protoc` with the path to the PureScript plugin executable, like for example - ```shell - protoc --plugin=bin/protoc-gen-purescript --purescript_out=. google/protobuf/timestamp.proto - ``` - -## Writing programs with the generated code - -Suppose we have a `Rectangle` message declared in a `shapes.proto` descriptor file: - -``` -syntax = "proto3"; -package interproc; - -message Rectangle { - double width = 1; - double height = 2; -} -``` - -We run - -```shell -protoc --purescript_out=. shapes.proto -``` - -which will generate a file `shapes.Interproc.purs`. - -The code generator will use the `package` import statement in the `.proto` file -and the base `.proto` file name as the PureScript module name for that file. - -The generated `shapes.Interproc.purs` file -will export these four names from module `Interproc.Shapes`. - -1. A message data type. - - ```purescript - newtype Rectangle = Rectangle { width :: Maybe Number, height :: Maybe Number } - ``` - - The message data type will also include an `__unknown_fields` array field for - holding received fields which were not in the descriptor `.proto` file. We can - ignore `__unknown_fields` if we want to. - -2. A message maker which constructs a message from a `Record` - with some message fields. - - ```purescript - mkRectangle :: forall r. Record r -> Rectangle - ``` - - All message fields are optional, and can be omitted when making a message. - There are some extra type constraints, not shown here, which will cause a - compiler error if we try to add a field which is not in the message data type. - - If we want the compiler to check that we’ve explicitly supplied all the fields, - then we can use the ordinary message data type constructor `Rectangle`. - -3. A message serializer which works with - [__arraybuffer-builder__](http://pursuit.purescript.org/packages/purescript-arraybuffer-builder/). - - ```purescript - putRectangle :: forall m. MonadEffect m => Rectangle -> PutM m Unit - ``` - -4. A message deserializer which works with - [__parsing-dataview__](http://pursuit.purescript.org/packages/purescript-parsing-dataview/). - - ```purescript - parseRectangle :: forall m. MonadEffect m => ByteLength -> ParserT DataView m Rectangle - ``` - - The message parser needs an argument which tells it the - length of the message which it’s about to parse, because - [“the Protocol Buffer wire format is not self-delimiting.”](https://protobuf.dev/programming-guides/techniques/#streaming) - -In our program, our imports will look something like this. -The only module from this package which we will import into our program -will be the `Protobuf.Library` module. -We'll import the message modules from the generated `.purs` files. -We'll also import modules for reading and writing `ArrayBuffer`s. - - -```purescript -import Protobuf.Library (Bytes(..)) -import Interproc.Shapes (Rectangle, mkRectangle, putRectangle, parseRectangle) -import Parsing (runParserT, ParseError, liftMaybe) -import Data.ArrayBuffer.Builder (execPutM) -import Data.ArrayBuffer.DataView (whole) -import Data.ArrayBuffer.ArrayBuffer (byteLength) -import Data.Tuple (Tuple) -import Data.Newtype (unwrap) -``` - -This is how we serialize a `Rectangle` to an `ArrayBuffer`. -We must be in a `MonadEffect`. - -```purescript -do - arraybuffer <- execPutM $ putRectangle $ mkRectangle - { width: Just 3.0 - , height: Just 4.0 - } -``` - -Next we’ll deserialize `Rectangle` from the `ArrayBuffer` that we just made. - -```purescript - result :: Either ParseError {width :: Number, height :: Number} - <- runParserT (whole arraybuffer) do - rectangle :: Rectangle <- parseRectangle (byteLength arraybuffer) -``` - -At this point we’ve consumed all of the parser input and constructed our -`Rectangle` message, but we’re not finished parsing. -We want to “validate” the `Rectangle` message to make sure it has all of the -fields that we require, because in -[*proto3*, all fields are optional](https://github.com/protocolbuffers/protobuf/issues/2497). - -Fortunately we are already in the `ParserT` monad, -so we can do better than to “validate”: -[Parse, don't validate](https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/). - -We will construct a record `{width::Number, height::Number}` -with the width and height of the `Rectangle`. If the width or height -are missing from the `Rectangle` message, then we will fail in the `ParserT` -monad. - -For this validation step, -[pattern matching](https://github.com/purescript/documentation/blob/master/language/Pattern-Matching.md) -on the `Rectangle` message type works well, so we could validate this way: - -```purescript - case rectangle of - Rectangle { width: Just width, height: Just height } -> - pure {width, height} - _ -> fail "Missing required width or height" -``` - -Or we might want to use `liftMaybe` for more fine-grained validation: - -```purescript - width <- liftMaybe "Missing required width" (unwrap rectangle).width - height <- liftMaybe "Missing required height" (unwrap rectangle).height - pure {width, height} -``` - -And now the `result` is either a parsing error or a fully validated rectangle. - -### Dependencies - -The generated code modules will import modules from this -package. - -The generated code depends on packages which are all in the -[PureScript Registry](https://github.com/purescript/registry). - -If the runtime environment is *Node.js*, then it must be at least *v11*, -because that is the version in which -[`TextDecoder`](https://nodejs.org/docs/latest-v11.x/api/globals.html#globals_textdecoder) - and -[`TextEncoder`](https://nodejs.org/docs/latest-v11.x/api/globals.html#globals_textencoder) -were added to `Globals`. - - -### Generated message instances - -All of the generated message types have instances of -[`Eq`](https://pursuit.purescript.org/packages/purescript-prelude/docs/Data.Eq#t:Eq), -[`Show`](https://pursuit.purescript.org/packages/purescript-prelude/docs/Data.Show#t:Show), -[`Generic`](https://pursuit.purescript.org/packages/purescript-generics-rep/docs/Data.Generic.Rep#t:Generic), -[`NewType`](https://pursuit.purescript.org/packages/purescript-newtype/docs/Data.Newtype#t:Newtype). - -### Usage Examples - -The __protobuf__ repository contains three executable *Node.js* -programs which use code generated by __protobuf__. Refer to these -for further examples of how to use the generated code. - -1. The `protoc` - [compiler plugin](https://github.com/rowtype-yoga/purescript-protobuf/blob/master/plugin/src/Main.purs). - The code generator imports generated code. This program writes itself. -2. The - [unit test suite](https://github.com/rowtype-yoga/purescript-protobuf/blob/master/plugin/test/Test/Main.purs). -3. The Google - [conformance test program](https://github.com/xc-jp/purescript-protobuf/blob/master/conformance/src/Main.purs). - -The [Protobuf Decoder Explainer](http://jamesdbrock.github.io/protobuf-decoder-explainer/) shows an -example of how to use this library to parse binary Protobuf when we don’t -have access to the `.proto` descriptor schema file and can’t generate -message-reading code. - -### Presence Discipline - -This is how [*field presence*](https://github.com/protocolbuffers/protobuf/blob/main/docs/field_presence.md) works -in our implementation. - -#### When deserializing - -A message field will always be `Just` when the field is present on the wire. - -A message field will always be `Nothing` when the field is not present on the wire, even if -it’s a *no presence* field. -If we want to interpret a missing *no presence* field as a -[default value](https://protobuf.dev/programming-guides/proto3/#default) then -we have the -[`Protobuf.Library.toDefault`](https://pursuit.purescript.org/packages/purescript-protobuf/docs/Protobuf.Library#v:toDefault) - function for that. - -#### When serializing - -A *no presence* field will not be serialized on the wire when it is `Nothing`, or `Just` the -default value. - -An *explicit presence* (`optional`) field will not be serialized on the wire when it is `Nothing`. -It will be serialized when it is `Just` the default value. - -### Interpreting invalid encoding parse failures - -When the parser encounters an invalid encoding in the Protobuf input -stream then it will fail to parse. - -When -[`runParserT`](https://pursuit.purescript.org/packages/purescript-parsing/docs/Parsing#v:runParserT) -fails it will return a `ParseError String (Position {index::Int,line::Int,column::Int})`. - -The byte offset at which the parse failure occurred is given by the -`index`. - -The path to the Protobuf definition which failed to parse will be included -in the `ParseError String` and delimited by `'/'`, something -like `"Message1 / string_field_1 / Invalid UTF8 encoding."`. - -### Protobuf Imports - -The Protobuf -[`import`](https://protobuf.dev/programming-guides/proto3/#importing-definitions) -statement allows Protobuf messages to have fields -consisting of Protobuf messages imported from another file, and qualified -by the package name in that file. In order to generate -the correct PureScript module name qualifier on the types of imported message -fields, the code generator must be able to lookup the package name -statement in the imported file. - -For that reason, we can only use top-level -(not [nested](https://protobuf.dev/programming-guides/proto3/#nested)) -`message` and `enum` types from a Protobuf `import`. - -### PureScript Imports - -The generated PureScript code will usually have module imports which cause -the `purs` compiler to emit `ImplicitQualifiedImport` warnings. Sorry. If this causes -trouble then the imports can be fixed automatically in a precompiling pass -with the command-line tool -[__suggest__](https://github.com/nwolverson/purescript-suggest). -Or you can [censor the warnings](https://discourse.purescript.org/t/suppressing-warnings-in-code/2485). - -## Nix derivation - -The `flake.nix` provides a package `protoc-gen-purescript` so that we -can run the `.proto` → `.purs` generation step as part of a Nix -derivation. Include `protoc-gen-purescript` and `protobuf` as `nativeBuildInputs`. -Then `protoc --purescript_out=path_to_output file.proto` will be runnable -in our derivation phases. - -The `flake.nix` provides the Google Protocol Buffers conformance tests -as an `app`. To run the conformance tests right now -[without installing or cloning](https://determinate.systems/posts/nix-run) -anything, - -```shell -nix run github:xc-jp/purescript-protobuf#conformance -``` - -## Contributing - -Pull requests welcome. - -## Other References - -* [__justifill__](https://pursuit.purescript.org/packages/purescript-justifill) package may be useful for message construction. -* [__morello__](https://pursuit.purescript.org/packages/purescript-morello) package may be useful for message validation. -* [Third-Party Add-ons for Protocol Buffers](https://github.com/protocolbuffers/protobuf/blob/main/docs/third_party.md) Google’s list of Protocol Buffers language implementations. -* [A vision for data interchange in Elm](https://gist.github.com/evancz/1c5f2cf34939336ecb79b97bb89d9da6) Comparison of JSON, ProtoBuf, GraphQL by Evan Czaplicki. diff --git a/README.md b/README.md new file mode 120000 index 0000000..f7df018 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +library/README.md \ No newline at end of file diff --git a/conformance/spago.lock b/conformance/spago.lock index 63ecae9..68078b7 100644 --- a/conformance/spago.lock +++ b/conformance/spago.lock @@ -1,7 +1,7 @@ { "workspace": { "packages": { - "conformance-purescript": { + "conformance": { "path": "./", "core": { "dependencies": [ @@ -1276,6 +1276,7 @@ "control", "effect", "either", + "enums", "exceptions", "float32", "foldable-traversable", diff --git a/conformance/spago.yaml b/conformance/spago.yaml index 4a1f32f..3fe28d7 100644 --- a/conformance/spago.yaml +++ b/conformance/spago.yaml @@ -1,5 +1,5 @@ package: - name: conformance-purescript + name: conformance dependencies: - protobuf - aff @@ -14,4 +14,4 @@ workspace: registry: 60.5.1 extraPackages: protobuf: - path: ../library \ No newline at end of file + path: ../library diff --git a/flake.nix b/flake.nix index 00ffa7a..0a9c2cb 100644 --- a/flake.nix +++ b/flake.nix @@ -114,11 +114,11 @@ protoc-gen-purescript ]; - # spago sources not working, TODO + # spago sources not working for whole project, TODO something like: + # export PURS_IDE_SOURCES=$(cd plugin;spago sources) shellHook = '' source <(spago --bash-completion-script `which spago`) source <(node --completion-bash) - export PURS_IDE_SOURCES=$(spago sources --package protobuf) echo "PureScript Protobuf development environment" protoc --version echo -n "node " diff --git a/library/README.md b/library/README.md new file mode 100644 index 0000000..8ef7537 --- /dev/null +++ b/library/README.md @@ -0,0 +1,383 @@ +# purescript-protobuf + +[![Pursuit](http://pursuit.purescript.org/packages/purescript-protobuf/badge)](http://pursuit.purescript.org/packages/purescript-protobuf/) +[![Maintainer: jamesdbrock](https://img.shields.io/badge/maintainer-jamesdbrock-teal.svg)](https://github.com/jamesdbrock) + +PureScript library and code generator for +[Google Protocol Buffers version 3](https://protobuf.dev/programming-guides/proto3/). + +This library operates on +[`ArrayBuffer`](https://pursuit.purescript.org/packages/purescript-arraybuffer-types/docs/Data.ArrayBuffer.Types#t:ArrayBuffer), so it will run both +[in *Node.js*](https://pursuit.purescript.org/packages/purescript-node-buffer/docs/Node.Buffer.Class) +and in browser environments. + +## Features + +We aim to support binary-encoded protobuf for +`syntax = "proto3";` descriptor files. + +Many `syntax = "proto2";` descriptor files will +also work, as long as they don't use `"proto2"` features, especially +[groups](https://protobuf.dev/programming-guides/proto2/#groups), +which we do not support. We also do not support `"proto2"` +[extensions](https://protobuf.dev/programming-guides/proto2/#extensions). + +We do not support +[services](https://protobuf.dev/programming-guides/proto3/#services). + +We do not support +[JSON Mapping](https://protobuf.dev/programming-guides/proto3/#json). + +### Conformance and Testing + +In this version, we pass all 684 of the +[Google conformance tests](https://github.com/protocolbuffers/protobuf/tree/main/conformance) +of binary-wire-format *proto3* for [Protocol Buffers v28.2](https://github.com/protocolbuffers/protobuf/releases/tag/v28.2). +See the `conformance/README.md` in this repository for details. + +We also have our own unit tests, see `test/README.md` in this repository. + +## Code Generation + +The `nix develop` environment provides + +* The PureScript toolchain: `purs`, `spago`, and `node`. +* The [`protoc`](https://protobuf.dev/programming-guides/proto3/#generating) compiler. +* The `protoc-gen-purescript` executable plugin for `protoc` on the `PATH` so that + [`protoc` can find it](https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.plugin/). + +``` +$ nix develop + +PureScript Protobuf development environment +libprotoc 28.2 +node v20.15.1 +purs 0.15.15 +spago 0.93.40 + +To build the protoc compiler plugin, run: + + cd plugin + spago build + +To compile PureScript .purs files from .proto files, run for example: + + protoc --purescript_out=. google/protobuf/timestamp.proto +``` + +We can test out code generation immediately by +generating `.purs` files for any of Google’s built-in “well-known types” in the +[`google.protobuf`](https://protobuf.dev/reference/protobuf/google.protobuf/) package namespace. Try the command +```shell +protoc --purescript_out=. google/protobuf/any.proto +``` +or +```shell +protoc --purescript_out=. google/protobuf/timestamp.proto +``` + +To see +[all of the `.proto` definitions](https://github.com/protocolbuffers/protobuf/tree/main/src/google/protobuf) +included with the Nix PureScript Protobuf installation including +the “well-known types,” +```shell +ls $(nix path-info .#protobuf)/src/google/protobuf/*.proto +``` + +If you don't want to use Nix, +1. install the PureScript toolchain and `protoc`. +2. Build the [PureScript plugin for `protoc`](plugin/). +3. Run `protoc` with the path to the PureScript plugin executable, like for example + ```shell + protoc --plugin=bin/protoc-gen-purescript --purescript_out=. google/protobuf/timestamp.proto + ``` + +## Writing programs with the generated code + +Suppose we have a `Rectangle` message declared in a `shapes.proto` descriptor file: + +``` +syntax = "proto3"; +package interproc; + +message Rectangle { + double width = 1; + double height = 2; +} +``` + +We run + +```shell +protoc --purescript_out=. shapes.proto +``` + +which will generate a file `shapes.Interproc.purs`. + +The code generator will use the `package` import statement in the `.proto` file +and the base `.proto` file name as the PureScript module name for that file. + +The generated `shapes.Interproc.purs` file +will export these four names from module `Interproc.Shapes`. + +1. A message data type. + + ```purescript + newtype Rectangle = Rectangle { width :: Maybe Number, height :: Maybe Number } + ``` + + The message data type will also include an `__unknown_fields` array field for + holding received fields which were not in the descriptor `.proto` file. We can + ignore `__unknown_fields` if we want to. + +2. A message maker which constructs a message from a `Record` + with some message fields. + + ```purescript + mkRectangle :: forall r. Record r -> Rectangle + ``` + + All message fields are optional, and can be omitted when making a message. + There are some extra type constraints, not shown here, which will cause a + compiler error if we try to add a field which is not in the message data type. + + If we want the compiler to check that we’ve explicitly supplied all the fields, + then we can use the ordinary message data type constructor `Rectangle`. + +3. A message serializer which works with + [__arraybuffer-builder__](http://pursuit.purescript.org/packages/purescript-arraybuffer-builder/). + + ```purescript + putRectangle :: forall m. MonadEffect m => Rectangle -> PutM m Unit + ``` + +4. A message deserializer which works with + [__parsing-dataview__](http://pursuit.purescript.org/packages/purescript-parsing-dataview/). + + ```purescript + parseRectangle :: forall m. MonadEffect m => ByteLength -> ParserT DataView m Rectangle + ``` + + The message parser needs an argument which tells it the + length of the message which it’s about to parse, because + [“the Protocol Buffer wire format is not self-delimiting.”](https://protobuf.dev/programming-guides/techniques/#streaming) + +In our program, our imports will look something like this. +The only module from this package which we will import into our program +will be the `Protobuf.Library` module. +We'll import the message modules from the generated `.purs` files. +We'll also import modules for reading and writing `ArrayBuffer`s. + + +```purescript +import Protobuf.Library (Bytes(..)) +import Interproc.Shapes (Rectangle, mkRectangle, putRectangle, parseRectangle) +import Parsing (runParserT, ParseError, liftMaybe) +import Data.ArrayBuffer.Builder (execPutM) +import Data.ArrayBuffer.DataView (whole) +import Data.ArrayBuffer.ArrayBuffer (byteLength) +import Data.Tuple (Tuple) +import Data.Newtype (unwrap) +``` + +This is how we serialize a `Rectangle` to an `ArrayBuffer`. +We must be in a `MonadEffect`. + +```purescript +do + arraybuffer <- execPutM $ putRectangle $ mkRectangle + { width: Just 3.0 + , height: Just 4.0 + } +``` + +Next we’ll deserialize `Rectangle` from the `ArrayBuffer` that we just made. + +```purescript + result :: Either ParseError {width :: Number, height :: Number} + <- runParserT (whole arraybuffer) do + rectangle :: Rectangle <- parseRectangle (byteLength arraybuffer) +``` + +At this point we’ve consumed all of the parser input and constructed our +`Rectangle` message, but we’re not finished parsing. +We want to “validate” the `Rectangle` message to make sure it has all of the +fields that we require, because in +[*proto3*, all fields are optional](https://github.com/protocolbuffers/protobuf/issues/2497). + +Fortunately we are already in the `ParserT` monad, +so we can do better than to “validate”: +[Parse, don't validate](https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/). + +We will construct a record `{width::Number, height::Number}` +with the width and height of the `Rectangle`. If the width or height +are missing from the `Rectangle` message, then we will fail in the `ParserT` +monad. + +For this validation step, +[pattern matching](https://github.com/purescript/documentation/blob/master/language/Pattern-Matching.md) +on the `Rectangle` message type works well, so we could validate this way: + +```purescript + case rectangle of + Rectangle { width: Just width, height: Just height } -> + pure {width, height} + _ -> fail "Missing required width or height" +``` + +Or we might want to use `liftMaybe` for more fine-grained validation: + +```purescript + width <- liftMaybe "Missing required width" (unwrap rectangle).width + height <- liftMaybe "Missing required height" (unwrap rectangle).height + pure {width, height} +``` + +And now the `result` is either a parsing error or a fully validated rectangle. + +### Dependencies + +The generated code modules will import modules from this +package. + +The generated code depends on packages which are all in the +[PureScript Registry](https://github.com/purescript/registry). + +If the runtime environment is *Node.js*, then it must be at least *v11*, +because that is the version in which +[`TextDecoder`](https://nodejs.org/docs/latest-v11.x/api/globals.html#globals_textdecoder) + and +[`TextEncoder`](https://nodejs.org/docs/latest-v11.x/api/globals.html#globals_textencoder) +were added to `Globals`. + + +### Generated message instances + +All of the generated message types have instances of +[`Eq`](https://pursuit.purescript.org/packages/purescript-prelude/docs/Data.Eq#t:Eq), +[`Show`](https://pursuit.purescript.org/packages/purescript-prelude/docs/Data.Show#t:Show), +[`Generic`](https://pursuit.purescript.org/packages/purescript-generics-rep/docs/Data.Generic.Rep#t:Generic), +[`NewType`](https://pursuit.purescript.org/packages/purescript-newtype/docs/Data.Newtype#t:Newtype). + +### Usage Examples + +The __protobuf__ repository contains three executable *Node.js* +programs which use code generated by __protobuf__. Refer to these +for further examples of how to use the generated code. + +1. The `protoc` + [compiler plugin](https://github.com/rowtype-yoga/purescript-protobuf/blob/master/plugin/src/Main.purs). + The code generator imports generated code. This program writes itself. +2. The + [unit test suite](https://github.com/rowtype-yoga/purescript-protobuf/blob/master/plugin/test/Test/Main.purs). +3. The Google + [conformance test program](https://github.com/xc-jp/purescript-protobuf/blob/master/conformance/src/Main.purs). + +The [Protobuf Decoder Explainer](http://jamesdbrock.github.io/protobuf-decoder-explainer/) shows an +example of how to use this library to parse binary Protobuf when we don’t +have access to the `.proto` descriptor schema file and can’t generate +message-reading code. + +### Presence Discipline + +This is how [*field presence*](https://github.com/protocolbuffers/protobuf/blob/main/docs/field_presence.md) works +in our implementation. + +#### When deserializing + +A message field will always be `Just` when the field is present on the wire. + +A message field will always be `Nothing` when the field is not present on the wire, even if +it’s a *no presence* field. +If we want to interpret a missing *no presence* field as a +[default value](https://protobuf.dev/programming-guides/proto3/#default) then +we have the +[`Protobuf.Library.toDefault`](https://pursuit.purescript.org/packages/purescript-protobuf/docs/Protobuf.Library#v:toDefault) + function for that. + +#### When serializing + +A *no presence* field will not be serialized on the wire when it is `Nothing`, or `Just` the +default value. + +An *explicit presence* (`optional`) field will not be serialized on the wire when it is `Nothing`. +It will be serialized when it is `Just` the default value. + +### Interpreting invalid encoding parse failures + +When the parser encounters an invalid encoding in the Protobuf input +stream then it will fail to parse. + +When +[`runParserT`](https://pursuit.purescript.org/packages/purescript-parsing/docs/Parsing#v:runParserT) +fails it will return a `ParseError String (Position {index::Int,line::Int,column::Int})`. + +The byte offset at which the parse failure occurred is given by the +`index`. + +The path to the Protobuf definition which failed to parse will be included +in the `ParseError String` and delimited by `'/'`, something +like `"Message1 / string_field_1 / Invalid UTF8 encoding."`. + +### Protobuf Imports + +The Protobuf +[`import`](https://protobuf.dev/programming-guides/proto3/#importing-definitions) +statement allows Protobuf messages to have fields +consisting of Protobuf messages imported from another file, and qualified +by the package name in that file. In order to generate +the correct PureScript module name qualifier on the types of imported message +fields, the code generator must be able to lookup the package name +statement in the imported file. + +For that reason, we can only use top-level +(not [nested](https://protobuf.dev/programming-guides/proto3/#nested)) +`message` and `enum` types from a Protobuf `import`. + +### PureScript Imports + +The generated PureScript code will usually have module imports which cause +the `purs` compiler to emit `ImplicitQualifiedImport` warnings. Sorry. If this causes +trouble then the imports can be fixed automatically in a precompiling pass +with the command-line tool +[__suggest__](https://github.com/nwolverson/purescript-suggest). +Or you can [censor the warnings](https://discourse.purescript.org/t/suppressing-warnings-in-code/2485). + +## Nix derivation + +The `flake.nix` provides a package `protoc-gen-purescript` so that we +can run the `.proto` → `.purs` generation step as part of a Nix +derivation. Include `protoc-gen-purescript` and `protobuf` as `nativeBuildInputs`. +Then `protoc --purescript_out=path_to_output file.proto` will be runnable +in our derivation phases. + +The `flake.nix` provides the Google Protocol Buffers conformance tests +as an `app`. To run the conformance tests right now +[without installing or cloning](https://determinate.systems/posts/nix-run) +anything, + +```shell +nix run github:xc-jp/purescript-protobuf#conformance +``` + +## Contributing + +Pull requests welcome. + +This repo is organized as a +[Spago polyrepo](https://github.com/purescript/spago#polyrepo-support). + +- `purescript-protobuf` + - [`library`](library) — `protobuf` package, published to Pursuit + - [`spago.yaml`](library/spago.yaml) + - [`plugin`](plugin) — protoc plugin app for code generation + - [`spago.yaml`](plugin/spago.yaml) + - [`conformance`](conformance) — Google Protobuf Conformance test runner app + - [`spago.yaml`](conformance/spago.yaml) + +## Other References + +* [__justifill__](https://pursuit.purescript.org/packages/purescript-justifill) package may be useful for message construction. +* [__morello__](https://pursuit.purescript.org/packages/purescript-morello) package may be useful for message validation. +* [Third-Party Add-ons for Protocol Buffers](https://github.com/protocolbuffers/protobuf/blob/main/docs/third_party.md) Google’s list of Protocol Buffers language implementations. +* [A vision for data interchange in Elm](https://gist.github.com/evancz/1c5f2cf34939336ecb79b97bb89d9da6) Comparison of JSON, ProtoBuf, GraphQL by Evan Czaplicki. diff --git a/library/spago.lock b/library/spago.lock index 7524ec2..9b875b0 100644 --- a/library/spago.lock +++ b/library/spago.lock @@ -26,6 +26,9 @@ { "either": ">=6.1.0 <7.0.0" }, + { + "enums": ">=6.0.1 <7.0.0" + }, { "exceptions": ">=6.0.0 <7.0.0" }, @@ -141,6 +144,521 @@ } } }, + "package_set": { + "address": { + "registry": "60.5.1" + }, + "compiler": ">=0.15.15 <0.16.0", + "content": { + "abc-parser": "2.0.1", + "ace": "9.1.0", + "address-rfc2821": "0.1.1", + "aff": "8.0.0", + "aff-bus": "6.0.0", + "aff-coroutines": "9.0.0", + "aff-promise": "4.0.0", + "aff-retry": "2.0.0", + "affjax": "13.0.0", + "affjax-node": "1.0.0", + "affjax-web": "1.0.0", + "ansi": "7.0.0", + "apexcharts": "0.5.0", + "applicative-phases": "1.0.0", + "argonaut": "9.0.0", + "argonaut-aeson-generic": "0.4.1", + "argonaut-codecs": "9.1.0", + "argonaut-core": "7.0.0", + "argonaut-generic": "8.0.0", + "argonaut-traversals": "10.0.0", + "argparse-basic": "2.0.0", + "array-builder": "0.1.2", + "array-search": "0.6.0", + "arraybuffer": "13.2.0", + "arraybuffer-builder": "3.1.0", + "arraybuffer-types": "3.0.2", + "arrays": "7.3.0", + "arrays-extra": "0.6.1", + "arrays-zipper": "2.0.1", + "ask": "1.0.0", + "assert": "6.0.0", + "assert-multiple": "0.4.0", + "avar": "5.0.0", + "b64": "0.0.8", + "barbies": "1.0.1", + "barlow-lens": "0.9.0", + "bifunctors": "6.0.0", + "bigints": "7.0.1", + "bolson": "0.3.9", + "bookhound": "0.1.7", + "bower-json": "3.0.0", + "call-by-name": "4.0.1", + "canvas": "6.0.0", + "canvas-action": "9.0.0", + "cartesian": "1.0.6", + "catenable-lists": "7.0.0", + "cbor-stream": "1.3.0", + "chameleon": "1.0.0", + "chameleon-halogen": "1.0.3", + "chameleon-react-basic": "1.1.0", + "chameleon-styled": "2.5.0", + "chameleon-transformers": "1.0.0", + "channel": "1.0.0", + "checked-exceptions": "3.1.1", + "choku": "1.0.1", + "classless": "0.1.1", + "classless-arbitrary": "0.1.1", + "classless-decode-json": "0.1.1", + "classless-encode-json": "0.1.3", + "classnames": "2.0.0", + "codec": "6.1.0", + "codec-argonaut": "10.0.0", + "codec-json": "2.0.0", + "colors": "7.0.1", + "concur-core": "0.5.0", + "concur-react": "0.5.0", + "concurrent-queues": "3.0.0", + "console": "6.1.0", + "const": "6.0.0", + "contravariant": "6.0.0", + "control": "6.0.0", + "convertable-options": "1.0.0", + "coroutines": "7.0.0", + "css": "6.0.0", + "css-frameworks": "1.0.1", + "csv-stream": "2.3.0", + "data-mvc": "0.0.2", + "datetime": "6.1.0", + "datetime-parsing": "0.2.0", + "debounce": "0.1.0", + "debug": "6.0.2", + "decimals": "7.1.0", + "default-values": "1.0.1", + "deku": "0.9.23", + "deno": "0.0.5", + "dissect": "1.0.0", + "distributive": "6.0.0", + "dom-filereader": "7.0.0", + "dom-indexed": "12.0.0", + "dom-simple": "0.4.0", + "dotenv": "4.0.3", + "droplet": "0.6.0", + "dts": "1.0.0", + "dual-numbers": "1.0.3", + "dynamic-buffer": "3.0.1", + "echarts-simple": "0.0.1", + "effect": "4.0.0", + "either": "6.1.0", + "elmish": "0.13.0", + "elmish-enzyme": "0.1.1", + "elmish-hooks": "0.10.3", + "elmish-html": "0.9.0", + "elmish-testing-library": "0.3.2", + "email-validate": "7.0.0", + "encoding": "0.0.9", + "enums": "6.0.1", + "env-names": "0.4.0", + "error": "2.0.0", + "eta-conversion": "0.3.2", + "exceptions": "6.1.0", + "exists": "6.0.0", + "exitcodes": "4.0.0", + "expect-inferred": "3.0.0", + "ezfetch": "1.0.0", + "fahrtwind": "2.0.0", + "fallback": "0.1.0", + "fast-vect": "1.2.0", + "fetch": "4.1.0", + "fetch-argonaut": "1.0.1", + "fetch-core": "5.1.0", + "fetch-yoga-json": "1.1.0", + "ffi-simple": "0.5.1", + "fft-js": "0.1.0", + "filterable": "5.0.0", + "fix-functor": "0.1.0", + "fixed-points": "7.0.0", + "fixed-precision": "5.0.0", + "flame": "1.3.0", + "float32": "2.0.0", + "fmt": "0.2.1", + "foldable-traversable": "6.0.0", + "foldable-traversable-extra": "0.0.6", + "foreign": "7.0.0", + "foreign-object": "4.1.0", + "foreign-readwrite": "3.4.0", + "forgetmenot": "0.1.0", + "fork": "6.0.0", + "form-urlencoded": "7.0.0", + "formatters": "7.0.0", + "framer-motion": "1.0.1", + "free": "7.1.0", + "freeap": "7.0.0", + "freer-free": "0.0.1", + "freet": "7.0.0", + "functions": "6.0.0", + "functor1": "3.0.0", + "functors": "5.0.0", + "fuzzy": "0.4.0", + "gen": "4.0.0", + "generate-values": "1.0.1", + "generic-router": "0.0.1", + "geojson": "0.0.5", + "geometria": "2.2.0", + "gojs": "0.1.1", + "grain": "3.0.0", + "grain-router": "3.0.0", + "grain-virtualized": "3.0.0", + "graphs": "8.1.0", + "group": "4.1.1", + "halogen": "7.0.0", + "halogen-bootstrap5": "5.3.2", + "halogen-canvas": "1.0.0", + "halogen-css": "10.0.0", + "halogen-echarts-simple": "0.0.4", + "halogen-formless": "4.0.3", + "halogen-helix": "1.0.1", + "halogen-hooks": "0.6.3", + "halogen-hooks-extra": "0.9.0", + "halogen-infinite-scroll": "1.1.0", + "halogen-store": "0.5.4", + "halogen-storybook": "2.0.0", + "halogen-subscriptions": "2.0.0", + "halogen-svg-elems": "8.0.0", + "halogen-typewriter": "1.0.4", + "halogen-vdom": "8.0.0", + "halogen-vdom-string-renderer": "0.5.0", + "halogen-xterm": "2.0.0", + "heckin": "2.0.1", + "heterogeneous": "0.6.0", + "homogeneous": "0.4.0", + "http-methods": "6.0.0", + "httpurple": "4.0.0", + "huffman": "0.4.0", + "humdrum": "0.0.1", + "hyrule": "2.3.8", + "identity": "6.0.0", + "identy": "4.0.1", + "indexed-db": "1.0.0", + "indexed-monad": "3.0.0", + "int64": "3.0.0", + "integers": "6.0.0", + "interpolate": "5.0.2", + "intersection-observer": "1.0.1", + "invariant": "6.0.0", + "jarilo": "1.0.1", + "jelly": "0.10.0", + "jelly-router": "0.3.0", + "jelly-signal": "0.4.0", + "jest": "1.0.0", + "js-abort-controller": "1.0.0", + "js-bigints": "2.2.1", + "js-date": "8.0.0", + "js-fetch": "0.2.1", + "js-fileio": "3.0.0", + "js-intl": "1.0.4", + "js-iterators": "0.1.1", + "js-maps": "0.1.2", + "js-promise": "1.0.0", + "js-promise-aff": "1.0.0", + "js-timers": "6.1.0", + "js-uri": "3.1.0", + "jsdom": "1.0.0", + "json": "1.1.0", + "json-codecs": "5.0.0", + "justifill": "0.5.0", + "jwt": "0.0.9", + "labeled-data": "0.2.0", + "language-cst-parser": "0.14.0", + "lazy": "6.0.0", + "lazy-joe": "1.0.0", + "lcg": "4.0.0", + "leibniz": "5.0.0", + "leveldb": "1.0.1", + "liminal": "1.0.1", + "linalg": "6.0.0", + "lists": "7.0.0", + "literals": "1.0.2", + "logging": "3.0.0", + "logging-journald": "0.4.0", + "lumi-components": "18.0.0", + "machines": "7.0.0", + "maps-eager": "0.5.0", + "marionette": "1.0.0", + "marionette-react-basic-hooks": "0.1.1", + "marked": "0.1.0", + "matrices": "5.0.1", + "matryoshka": "1.0.0", + "maybe": "6.0.0", + "media-types": "6.0.0", + "meowclient": "1.0.0", + "midi": "4.0.0", + "milkis": "9.0.0", + "minibench": "4.0.1", + "mmorph": "7.0.0", + "monad-control": "5.0.0", + "monad-logger": "1.3.1", + "monad-loops": "0.5.0", + "monad-unlift": "1.0.1", + "monoid-extras": "0.0.1", + "monoidal": "0.16.0", + "morello": "0.4.0", + "mote": "3.0.0", + "motsunabe": "2.0.0", + "mvc": "0.0.1", + "mysql": "6.0.1", + "n3": "0.1.0", + "nano-id": "1.1.0", + "nanoid": "0.1.0", + "naturals": "3.0.0", + "nested-functor": "0.2.1", + "newtype": "5.0.0", + "nextjs": "0.1.1", + "nextui": "0.2.0", + "node-buffer": "9.0.0", + "node-child-process": "11.1.0", + "node-event-emitter": "3.0.0", + "node-execa": "5.0.0", + "node-fs": "9.2.0", + "node-glob-basic": "1.3.0", + "node-http": "9.1.0", + "node-http2": "1.1.1", + "node-human-signals": "1.0.0", + "node-net": "5.1.0", + "node-os": "5.1.0", + "node-path": "5.0.0", + "node-process": "11.2.0", + "node-readline": "8.1.1", + "node-sqlite3": "8.0.0", + "node-stream-pipes": "2.1.6", + "node-streams": "9.0.0", + "node-tls": "0.3.1", + "node-url": "7.0.1", + "node-zlib": "0.4.0", + "nonempty": "7.0.0", + "now": "6.0.0", + "npm-package-json": "2.0.0", + "nullable": "6.0.0", + "numberfield": "0.2.2", + "numbers": "9.0.1", + "oak": "3.1.1", + "oak-debug": "1.2.2", + "object-maps": "0.3.0", + "ocarina": "1.5.4", + "oooooooooorrrrrrrmm-lib": "0.0.1", + "open-colors-scales-and-schemes": "1.0.0", + "open-folds": "6.4.0", + "open-foreign-generic": "11.0.3", + "open-memoize": "6.2.0", + "open-mkdirp-aff": "1.2.0", + "open-pairing": "6.2.0", + "open-smolder": "12.0.2", + "options": "7.0.0", + "optparse": "5.0.1", + "ordered-collections": "3.2.0", + "ordered-set": "0.4.0", + "orders": "6.0.0", + "owoify": "1.2.0", + "pairs": "9.0.1", + "parallel": "7.0.0", + "parsing": "10.2.0", + "parsing-dataview": "3.2.4", + "partial": "4.0.0", + "pathy": "9.0.0", + "pha": "0.13.0", + "phaser": "0.7.0", + "phylio": "1.1.2", + "pipes": "8.0.0", + "pirates-charm": "0.0.1", + "pmock": "0.9.0", + "point-free": "1.0.0", + "pointed-list": "0.5.1", + "polymorphic-vectors": "4.0.0", + "posix-types": "6.0.0", + "postgresql": "2.0.19", + "precise": "6.0.0", + "precise-datetime": "7.0.0", + "prelude": "6.0.1", + "prettier-printer": "3.0.0", + "priority-queue": "0.1.2", + "profunctor": "6.0.1", + "profunctor-lenses": "8.0.0", + "protobuf": "4.3.0", + "psa-utils": "8.0.0", + "psci-support": "6.0.0", + "punycode": "1.0.0", + "qualified-do": "2.2.0", + "quantities": "12.2.0", + "quickcheck": "8.0.1", + "quickcheck-combinators": "0.1.3", + "quickcheck-laws": "7.0.0", + "quickcheck-utf8": "0.0.0", + "random": "6.0.0", + "rationals": "6.0.0", + "rdf": "0.1.0", + "react": "11.0.0", + "react-aria": "0.2.0", + "react-basic": "17.0.0", + "react-basic-classic": "3.0.0", + "react-basic-dnd": "10.1.0", + "react-basic-dom": "6.1.0", + "react-basic-dom-beta": "0.1.1", + "react-basic-emotion": "7.1.0", + "react-basic-hooks": "8.2.0", + "react-basic-storybook": "2.0.0", + "react-dom": "8.0.0", + "react-halo": "3.0.0", + "react-icons": "1.1.5", + "react-markdown": "0.1.0", + "react-testing-library": "4.0.1", + "react-virtuoso": "1.0.0", + "reactix": "0.6.1", + "read": "1.0.1", + "recharts": "1.1.0", + "record": "4.0.0", + "record-extra": "5.0.1", + "record-ptional-fields": "0.1.2", + "record-studio": "1.0.4", + "refs": "6.0.0", + "remotedata": "5.0.1", + "repr": "0.5.0", + "resize-observer": "1.0.0", + "resource": "2.0.1", + "resourcet": "1.0.0", + "result": "1.0.3", + "return": "0.2.0", + "ring-modules": "5.0.1", + "rito": "0.3.4", + "roman": "0.4.0", + "rough-notation": "1.0.2", + "routing": "11.0.0", + "routing-duplex": "0.7.0", + "run": "5.0.0", + "safe-coerce": "2.0.0", + "safely": "4.0.1", + "school-of-music": "1.3.0", + "selection-foldable": "0.2.0", + "selective-functors": "1.0.1", + "semirings": "7.0.0", + "signal": "13.0.0", + "simple-emitter": "3.0.1", + "simple-i18n": "2.0.1", + "simple-json": "9.0.0", + "simple-json-generics": "0.2.1", + "simple-ulid": "3.0.0", + "sized-matrices": "1.0.0", + "sized-vectors": "5.0.2", + "slug": "3.1.0", + "small-ffi": "4.0.1", + "soundfonts": "4.1.0", + "sparse-matrices": "2.0.1", + "sparse-polynomials": "3.0.1", + "spec": "8.1.0", + "spec-discovery": "8.4.0", + "spec-mocha": "5.1.1", + "spec-node": "0.0.3", + "spec-quickcheck": "5.0.2", + "spec-reporter-xunit": "0.7.1", + "splitmix": "2.1.0", + "ssrs": "1.0.0", + "st": "6.2.0", + "statistics": "0.3.2", + "strictlypositiveint": "1.0.1", + "string-parsers": "8.0.0", + "strings": "6.0.1", + "strings-extra": "4.0.0", + "stringutils": "0.0.12", + "substitute": "0.2.3", + "supply": "0.2.0", + "svg-parser": "3.0.0", + "systemd-journald": "0.3.0", + "tagged": "4.0.2", + "tailrec": "6.1.0", + "tecton": "0.2.1", + "tecton-halogen": "0.2.0", + "test-unit": "17.0.0", + "thermite": "6.3.1", + "thermite-dom": "0.3.1", + "these": "6.0.0", + "threading": "0.0.3", + "tldr": "0.0.0", + "toestand": "0.9.0", + "transformation-matrix": "1.0.1", + "transformers": "6.1.0", + "tree-rose": "4.0.2", + "ts-bridge": "4.0.0", + "tuples": "7.0.0", + "two-or-more": "1.0.0", + "type-equality": "4.0.1", + "typedenv": "2.0.1", + "typelevel": "6.0.0", + "typelevel-lists": "2.1.0", + "typelevel-peano": "1.0.1", + "typelevel-prelude": "7.0.0", + "typelevel-regex": "0.0.3", + "typelevel-rows": "0.1.0", + "typisch": "0.4.0", + "uint": "7.0.0", + "ulid": "3.0.1", + "uncurried-transformers": "1.1.0", + "undefined": "2.0.0", + "undefined-is-not-a-problem": "1.1.0", + "unfoldable": "6.0.0", + "unicode": "6.0.0", + "unique": "0.6.1", + "unlift": "1.0.1", + "unordered-collections": "3.1.0", + "unsafe-coerce": "6.0.0", + "unsafe-reference": "5.0.0", + "untagged-to-tagged": "0.1.4", + "untagged-union": "1.0.0", + "uri": "9.0.0", + "url-immutable": "1.0.0", + "uuid": "9.0.0", + "uuidv4": "1.0.0", + "validation": "6.0.0", + "variant": "8.0.0", + "variant-encodings": "2.0.0", + "vectorfield": "1.0.1", + "vectors": "2.1.0", + "versions": "7.0.0", + "visx": "0.0.2", + "web-clipboard": "6.0.0", + "web-cssom": "2.0.0", + "web-cssom-view": "0.1.0", + "web-dom": "6.0.0", + "web-dom-parser": "8.0.0", + "web-dom-xpath": "3.0.0", + "web-encoding": "3.0.0", + "web-events": "4.0.0", + "web-fetch": "4.0.1", + "web-file": "4.0.0", + "web-geometry": "0.1.0", + "web-html": "4.1.0", + "web-pointerevents": "2.0.0", + "web-proletarian": "1.0.0", + "web-promise": "3.2.0", + "web-resize-observer": "2.1.0", + "web-router": "1.0.0", + "web-socket": "4.0.0", + "web-storage": "5.0.0", + "web-streams": "4.0.0", + "web-touchevents": "4.0.0", + "web-uievents": "5.0.0", + "web-url": "2.0.0", + "web-workers": "1.1.0", + "web-xhr": "5.0.1", + "webextension-polyfill": "0.1.0", + "webgpu": "0.0.1", + "which": "2.0.0", + "xterm": "1.0.0", + "yoga-fetch": "1.0.1", + "yoga-json": "5.1.0", + "yoga-om": "0.1.0", + "yoga-postgres": "6.0.0", + "yoga-tree": "1.0.0", + "z3": "0.0.2", + "zipperarray": "2.0.0" + } + }, "extra_packages": {} }, "packages": { diff --git a/library/spago.yaml b/library/spago.yaml index 02af259..65ffaca 100644 --- a/library/spago.yaml +++ b/library/spago.yaml @@ -36,3 +36,7 @@ package: - tuples: ">=7.0.0 <8.0.0" - uint: ">=7.0.0 <8.0.0" - web-encoding: ">=3.0.0 <4.0.0" + +workspace: + packageSet: + registry: 60.5.1 \ No newline at end of file diff --git a/plugin/spago.lock b/plugin/spago.lock index 14cc5c0..042ab97 100644 --- a/plugin/spago.lock +++ b/plugin/spago.lock @@ -1,7 +1,7 @@ { "workspace": { "packages": { - "protoc-plugin": { + "plugin": { "path": "./", "core": { "dependencies": [ @@ -1348,6 +1348,7 @@ "control", "effect", "either", + "enums", "exceptions", "float32", "foldable-traversable", diff --git a/plugin/spago.yaml b/plugin/spago.yaml index 37b0e56..b1aba3b 100644 --- a/plugin/spago.yaml +++ b/plugin/spago.yaml @@ -1,5 +1,5 @@ package: - name: protoc-plugin + name: plugin dependencies: - protobuf - aff diff --git a/plugin/src/Main.purs b/plugin/src/Main.purs index f5490a5..5f6bac1 100644 --- a/plugin/src/Main.purs +++ b/plugin/src/Main.purs @@ -27,7 +27,7 @@ import Data.UInt64 as UInt64 import Effect (Effect) import Effect.Aff (runAff_, throwError, error) import Effect.Class (liftEffect) -import Effect.Console as Console +import Effect.Class.Console as Console import Google.Protobuf.Compiler.Plugin (CodeGeneratorRequest(..), CodeGeneratorResponse, CodeGeneratorResponse_File(..), mkCodeGeneratorResponse, parseCodeGeneratorRequest, putCodeGeneratorResponse) import Google.Protobuf.Descriptor (DescriptorProto(..), EnumDescriptorProto(..), EnumValueDescriptorProto(..), FieldDescriptorProto(..), FieldDescriptorProto_Label(..), FieldDescriptorProto_Type(..), FieldOptions(..), FileDescriptorProto(..), OneofDescriptorProto(..), SourceCodeInfo(..), SourceCodeInfo_Location(..)) import Node.Buffer (Buffer, toArrayBuffer, fromArrayBuffer) @@ -45,7 +45,7 @@ main = runAff_ (either (unsafeCoerce >>> Console.error) (\_ -> pure unit)) do -- Protoc just assumes that when it writes the request, we get the whole -- request on our read of stdin. Protoc doesn't tell us how to determine -- that we have read the whole request. - -- So we read and parse in a loop until we have enough bytes that the + -- So we read chunks and parse in a loop until we have enough bytes that the -- parse succeeds. flip tailRecM [] \bs -> do {buffers:b,readagain} <- readSome stdin @@ -56,10 +56,17 @@ main = runAff_ (either (unsafeCoerce >>> Console.error) (\_ -> pure unit)) do if not readagain then do void $ throwError $ error "stdin is not readable." pure (Done unit) - else if (Array.length bs') < 20 then do + else if (Array.length bs') < 10000 then do + -- What we want to do here is detect whether this parsing error was + -- because we read to the end of the buffer and need to read more. + -- But we don't have a good way to do that right now, so we assume + -- that we need to read more, unless we have already read 10000 chunks. + -- (Chunk size is usually 65536 bytes.) + -- If the parsing error happened for some other reason then we should + -- error out here. pure (Loop bs') else do - void $ throwError $ error $ unsafeCoerce err + void $ throwError $ error $ show err pure (Done unit) Right request -> do responseBuf <- execPutM $ putCodeGeneratorResponse (generate request) diff --git a/spago.lock b/spago.lock deleted file mode 100644 index 576b92e..0000000 --- a/spago.lock +++ /dev/null @@ -1,1319 +0,0 @@ -{ - "workspace": { - "packages": { - "protobuf": { - "path": "library", - "core": { - "dependencies": [ - { - "arraybuffer": ">=13.1.1 <14.0.0" - }, - { - "arraybuffer-builder": ">=3.1.0 <4.0.0" - }, - { - "arraybuffer-types": ">=3.0.2 <4.0.0" - }, - { - "arrays": ">=7.2.0 <8.0.0" - }, - { - "control": ">=6.0.0 <7.0.0" - }, - { - "effect": ">=4.0.0 <5.0.0" - }, - { - "either": ">=6.1.0 <7.0.0" - }, - { - "enums": ">=6.0.1 <7.0.0" - }, - { - "exceptions": ">=6.0.0 <7.0.0" - }, - { - "float32": ">=2.0.0 <3.0.0" - }, - { - "foldable-traversable": ">=6.0.0 <7.0.0" - }, - { - "functions": ">=6.0.0 <7.0.0" - }, - { - "int64": ">=3.0.0 <4.0.0" - }, - { - "lists": ">=7.0.0 <8.0.0" - }, - { - "maybe": ">=6.0.0 <7.0.0" - }, - { - "newtype": ">=5.0.0 <6.0.0" - }, - { - "parsing": ">=10.2.0 <11.0.0" - }, - { - "parsing-dataview": ">=3.2.4 <4.0.0" - }, - { - "prelude": ">=6.0.1 <7.0.0" - }, - { - "record": ">=4.0.0 <5.0.0" - }, - { - "strings": ">=6.0.1 <7.0.0" - }, - { - "tailrec": ">=6.1.0 <7.0.0" - }, - { - "transformers": ">=6.0.0 <7.0.0" - }, - { - "tuples": ">=7.0.0 <8.0.0" - }, - { - "uint": ">=7.0.0 <8.0.0" - }, - { - "web-encoding": ">=3.0.0 <4.0.0" - } - ], - "build_plan": [ - "arraybuffer", - "arraybuffer-builder", - "arraybuffer-types", - "arrays", - "bifunctors", - "const", - "contravariant", - "control", - "distributive", - "effect", - "either", - "enums", - "exceptions", - "exists", - "float32", - "foldable-traversable", - "foreign", - "functions", - "functors", - "gen", - "identity", - "int64", - "integers", - "invariant", - "lazy", - "lists", - "maybe", - "newtype", - "nonempty", - "nullable", - "numbers", - "orders", - "parsing", - "parsing-dataview", - "partial", - "prelude", - "profunctor", - "record", - "refs", - "safe-coerce", - "st", - "strings", - "tailrec", - "transformers", - "tuples", - "type-equality", - "uint", - "unfoldable", - "unicode", - "unsafe-coerce", - "web-encoding" - ] - }, - "test": { - "dependencies": [], - "build_plan": [] - } - } - }, - "package_set": { - "address": { - "registry": "60.5.1" - }, - "compiler": ">=0.15.15 <0.16.0", - "content": { - "abc-parser": "2.0.1", - "ace": "9.1.0", - "address-rfc2821": "0.1.1", - "aff": "8.0.0", - "aff-bus": "6.0.0", - "aff-coroutines": "9.0.0", - "aff-promise": "4.0.0", - "aff-retry": "2.0.0", - "affjax": "13.0.0", - "affjax-node": "1.0.0", - "affjax-web": "1.0.0", - "ansi": "7.0.0", - "apexcharts": "0.5.0", - "applicative-phases": "1.0.0", - "argonaut": "9.0.0", - "argonaut-aeson-generic": "0.4.1", - "argonaut-codecs": "9.1.0", - "argonaut-core": "7.0.0", - "argonaut-generic": "8.0.0", - "argonaut-traversals": "10.0.0", - "argparse-basic": "2.0.0", - "array-builder": "0.1.2", - "array-search": "0.6.0", - "arraybuffer": "13.2.0", - "arraybuffer-builder": "3.1.0", - "arraybuffer-types": "3.0.2", - "arrays": "7.3.0", - "arrays-extra": "0.6.1", - "arrays-zipper": "2.0.1", - "ask": "1.0.0", - "assert": "6.0.0", - "assert-multiple": "0.4.0", - "avar": "5.0.0", - "b64": "0.0.8", - "barbies": "1.0.1", - "barlow-lens": "0.9.0", - "bifunctors": "6.0.0", - "bigints": "7.0.1", - "bolson": "0.3.9", - "bookhound": "0.1.7", - "bower-json": "3.0.0", - "call-by-name": "4.0.1", - "canvas": "6.0.0", - "canvas-action": "9.0.0", - "cartesian": "1.0.6", - "catenable-lists": "7.0.0", - "cbor-stream": "1.3.0", - "chameleon": "1.0.0", - "chameleon-halogen": "1.0.3", - "chameleon-react-basic": "1.1.0", - "chameleon-styled": "2.5.0", - "chameleon-transformers": "1.0.0", - "channel": "1.0.0", - "checked-exceptions": "3.1.1", - "choku": "1.0.1", - "classless": "0.1.1", - "classless-arbitrary": "0.1.1", - "classless-decode-json": "0.1.1", - "classless-encode-json": "0.1.3", - "classnames": "2.0.0", - "codec": "6.1.0", - "codec-argonaut": "10.0.0", - "codec-json": "2.0.0", - "colors": "7.0.1", - "concur-core": "0.5.0", - "concur-react": "0.5.0", - "concurrent-queues": "3.0.0", - "console": "6.1.0", - "const": "6.0.0", - "contravariant": "6.0.0", - "control": "6.0.0", - "convertable-options": "1.0.0", - "coroutines": "7.0.0", - "css": "6.0.0", - "css-frameworks": "1.0.1", - "csv-stream": "2.3.0", - "data-mvc": "0.0.2", - "datetime": "6.1.0", - "datetime-parsing": "0.2.0", - "debounce": "0.1.0", - "debug": "6.0.2", - "decimals": "7.1.0", - "default-values": "1.0.1", - "deku": "0.9.23", - "deno": "0.0.5", - "dissect": "1.0.0", - "distributive": "6.0.0", - "dom-filereader": "7.0.0", - "dom-indexed": "12.0.0", - "dom-simple": "0.4.0", - "dotenv": "4.0.3", - "droplet": "0.6.0", - "dts": "1.0.0", - "dual-numbers": "1.0.3", - "dynamic-buffer": "3.0.1", - "echarts-simple": "0.0.1", - "effect": "4.0.0", - "either": "6.1.0", - "elmish": "0.13.0", - "elmish-enzyme": "0.1.1", - "elmish-hooks": "0.10.3", - "elmish-html": "0.9.0", - "elmish-testing-library": "0.3.2", - "email-validate": "7.0.0", - "encoding": "0.0.9", - "enums": "6.0.1", - "env-names": "0.4.0", - "error": "2.0.0", - "eta-conversion": "0.3.2", - "exceptions": "6.1.0", - "exists": "6.0.0", - "exitcodes": "4.0.0", - "expect-inferred": "3.0.0", - "ezfetch": "1.0.0", - "fahrtwind": "2.0.0", - "fallback": "0.1.0", - "fast-vect": "1.2.0", - "fetch": "4.1.0", - "fetch-argonaut": "1.0.1", - "fetch-core": "5.1.0", - "fetch-yoga-json": "1.1.0", - "ffi-simple": "0.5.1", - "fft-js": "0.1.0", - "filterable": "5.0.0", - "fix-functor": "0.1.0", - "fixed-points": "7.0.0", - "fixed-precision": "5.0.0", - "flame": "1.3.0", - "float32": "2.0.0", - "fmt": "0.2.1", - "foldable-traversable": "6.0.0", - "foldable-traversable-extra": "0.0.6", - "foreign": "7.0.0", - "foreign-object": "4.1.0", - "foreign-readwrite": "3.4.0", - "forgetmenot": "0.1.0", - "fork": "6.0.0", - "form-urlencoded": "7.0.0", - "formatters": "7.0.0", - "framer-motion": "1.0.1", - "free": "7.1.0", - "freeap": "7.0.0", - "freer-free": "0.0.1", - "freet": "7.0.0", - "functions": "6.0.0", - "functor1": "3.0.0", - "functors": "5.0.0", - "fuzzy": "0.4.0", - "gen": "4.0.0", - "generate-values": "1.0.1", - "generic-router": "0.0.1", - "geojson": "0.0.5", - "geometria": "2.2.0", - "gojs": "0.1.1", - "grain": "3.0.0", - "grain-router": "3.0.0", - "grain-virtualized": "3.0.0", - "graphs": "8.1.0", - "group": "4.1.1", - "halogen": "7.0.0", - "halogen-bootstrap5": "5.3.2", - "halogen-canvas": "1.0.0", - "halogen-css": "10.0.0", - "halogen-echarts-simple": "0.0.4", - "halogen-formless": "4.0.3", - "halogen-helix": "1.0.1", - "halogen-hooks": "0.6.3", - "halogen-hooks-extra": "0.9.0", - "halogen-infinite-scroll": "1.1.0", - "halogen-store": "0.5.4", - "halogen-storybook": "2.0.0", - "halogen-subscriptions": "2.0.0", - "halogen-svg-elems": "8.0.0", - "halogen-typewriter": "1.0.4", - "halogen-vdom": "8.0.0", - "halogen-vdom-string-renderer": "0.5.0", - "halogen-xterm": "2.0.0", - "heckin": "2.0.1", - "heterogeneous": "0.6.0", - "homogeneous": "0.4.0", - "http-methods": "6.0.0", - "httpurple": "4.0.0", - "huffman": "0.4.0", - "humdrum": "0.0.1", - "hyrule": "2.3.8", - "identity": "6.0.0", - "identy": "4.0.1", - "indexed-db": "1.0.0", - "indexed-monad": "3.0.0", - "int64": "3.0.0", - "integers": "6.0.0", - "interpolate": "5.0.2", - "intersection-observer": "1.0.1", - "invariant": "6.0.0", - "jarilo": "1.0.1", - "jelly": "0.10.0", - "jelly-router": "0.3.0", - "jelly-signal": "0.4.0", - "jest": "1.0.0", - "js-abort-controller": "1.0.0", - "js-bigints": "2.2.1", - "js-date": "8.0.0", - "js-fetch": "0.2.1", - "js-fileio": "3.0.0", - "js-intl": "1.0.4", - "js-iterators": "0.1.1", - "js-maps": "0.1.2", - "js-promise": "1.0.0", - "js-promise-aff": "1.0.0", - "js-timers": "6.1.0", - "js-uri": "3.1.0", - "jsdom": "1.0.0", - "json": "1.1.0", - "json-codecs": "5.0.0", - "justifill": "0.5.0", - "jwt": "0.0.9", - "labeled-data": "0.2.0", - "language-cst-parser": "0.14.0", - "lazy": "6.0.0", - "lazy-joe": "1.0.0", - "lcg": "4.0.0", - "leibniz": "5.0.0", - "leveldb": "1.0.1", - "liminal": "1.0.1", - "linalg": "6.0.0", - "lists": "7.0.0", - "literals": "1.0.2", - "logging": "3.0.0", - "logging-journald": "0.4.0", - "lumi-components": "18.0.0", - "machines": "7.0.0", - "maps-eager": "0.5.0", - "marionette": "1.0.0", - "marionette-react-basic-hooks": "0.1.1", - "marked": "0.1.0", - "matrices": "5.0.1", - "matryoshka": "1.0.0", - "maybe": "6.0.0", - "media-types": "6.0.0", - "meowclient": "1.0.0", - "midi": "4.0.0", - "milkis": "9.0.0", - "minibench": "4.0.1", - "mmorph": "7.0.0", - "monad-control": "5.0.0", - "monad-logger": "1.3.1", - "monad-loops": "0.5.0", - "monad-unlift": "1.0.1", - "monoid-extras": "0.0.1", - "monoidal": "0.16.0", - "morello": "0.4.0", - "mote": "3.0.0", - "motsunabe": "2.0.0", - "mvc": "0.0.1", - "mysql": "6.0.1", - "n3": "0.1.0", - "nano-id": "1.1.0", - "nanoid": "0.1.0", - "naturals": "3.0.0", - "nested-functor": "0.2.1", - "newtype": "5.0.0", - "nextjs": "0.1.1", - "nextui": "0.2.0", - "node-buffer": "9.0.0", - "node-child-process": "11.1.0", - "node-event-emitter": "3.0.0", - "node-execa": "5.0.0", - "node-fs": "9.2.0", - "node-glob-basic": "1.3.0", - "node-http": "9.1.0", - "node-http2": "1.1.1", - "node-human-signals": "1.0.0", - "node-net": "5.1.0", - "node-os": "5.1.0", - "node-path": "5.0.0", - "node-process": "11.2.0", - "node-readline": "8.1.1", - "node-sqlite3": "8.0.0", - "node-stream-pipes": "2.1.6", - "node-streams": "9.0.0", - "node-tls": "0.3.1", - "node-url": "7.0.1", - "node-zlib": "0.4.0", - "nonempty": "7.0.0", - "now": "6.0.0", - "npm-package-json": "2.0.0", - "nullable": "6.0.0", - "numberfield": "0.2.2", - "numbers": "9.0.1", - "oak": "3.1.1", - "oak-debug": "1.2.2", - "object-maps": "0.3.0", - "ocarina": "1.5.4", - "oooooooooorrrrrrrmm-lib": "0.0.1", - "open-colors-scales-and-schemes": "1.0.0", - "open-folds": "6.4.0", - "open-foreign-generic": "11.0.3", - "open-memoize": "6.2.0", - "open-mkdirp-aff": "1.2.0", - "open-pairing": "6.2.0", - "open-smolder": "12.0.2", - "options": "7.0.0", - "optparse": "5.0.1", - "ordered-collections": "3.2.0", - "ordered-set": "0.4.0", - "orders": "6.0.0", - "owoify": "1.2.0", - "pairs": "9.0.1", - "parallel": "7.0.0", - "parsing": "10.2.0", - "parsing-dataview": "3.2.4", - "partial": "4.0.0", - "pathy": "9.0.0", - "pha": "0.13.0", - "phaser": "0.7.0", - "phylio": "1.1.2", - "pipes": "8.0.0", - "pirates-charm": "0.0.1", - "pmock": "0.9.0", - "point-free": "1.0.0", - "pointed-list": "0.5.1", - "polymorphic-vectors": "4.0.0", - "posix-types": "6.0.0", - "postgresql": "2.0.19", - "precise": "6.0.0", - "precise-datetime": "7.0.0", - "prelude": "6.0.1", - "prettier-printer": "3.0.0", - "priority-queue": "0.1.2", - "profunctor": "6.0.1", - "profunctor-lenses": "8.0.0", - "protobuf": "4.3.0", - "psa-utils": "8.0.0", - "psci-support": "6.0.0", - "punycode": "1.0.0", - "qualified-do": "2.2.0", - "quantities": "12.2.0", - "quickcheck": "8.0.1", - "quickcheck-combinators": "0.1.3", - "quickcheck-laws": "7.0.0", - "quickcheck-utf8": "0.0.0", - "random": "6.0.0", - "rationals": "6.0.0", - "rdf": "0.1.0", - "react": "11.0.0", - "react-aria": "0.2.0", - "react-basic": "17.0.0", - "react-basic-classic": "3.0.0", - "react-basic-dnd": "10.1.0", - "react-basic-dom": "6.1.0", - "react-basic-dom-beta": "0.1.1", - "react-basic-emotion": "7.1.0", - "react-basic-hooks": "8.2.0", - "react-basic-storybook": "2.0.0", - "react-dom": "8.0.0", - "react-halo": "3.0.0", - "react-icons": "1.1.5", - "react-markdown": "0.1.0", - "react-testing-library": "4.0.1", - "react-virtuoso": "1.0.0", - "reactix": "0.6.1", - "read": "1.0.1", - "recharts": "1.1.0", - "record": "4.0.0", - "record-extra": "5.0.1", - "record-ptional-fields": "0.1.2", - "record-studio": "1.0.4", - "refs": "6.0.0", - "remotedata": "5.0.1", - "repr": "0.5.0", - "resize-observer": "1.0.0", - "resource": "2.0.1", - "resourcet": "1.0.0", - "result": "1.0.3", - "return": "0.2.0", - "ring-modules": "5.0.1", - "rito": "0.3.4", - "roman": "0.4.0", - "rough-notation": "1.0.2", - "routing": "11.0.0", - "routing-duplex": "0.7.0", - "run": "5.0.0", - "safe-coerce": "2.0.0", - "safely": "4.0.1", - "school-of-music": "1.3.0", - "selection-foldable": "0.2.0", - "selective-functors": "1.0.1", - "semirings": "7.0.0", - "signal": "13.0.0", - "simple-emitter": "3.0.1", - "simple-i18n": "2.0.1", - "simple-json": "9.0.0", - "simple-json-generics": "0.2.1", - "simple-ulid": "3.0.0", - "sized-matrices": "1.0.0", - "sized-vectors": "5.0.2", - "slug": "3.1.0", - "small-ffi": "4.0.1", - "soundfonts": "4.1.0", - "sparse-matrices": "2.0.1", - "sparse-polynomials": "3.0.1", - "spec": "8.1.0", - "spec-discovery": "8.4.0", - "spec-mocha": "5.1.1", - "spec-node": "0.0.3", - "spec-quickcheck": "5.0.2", - "spec-reporter-xunit": "0.7.1", - "splitmix": "2.1.0", - "ssrs": "1.0.0", - "st": "6.2.0", - "statistics": "0.3.2", - "strictlypositiveint": "1.0.1", - "string-parsers": "8.0.0", - "strings": "6.0.1", - "strings-extra": "4.0.0", - "stringutils": "0.0.12", - "substitute": "0.2.3", - "supply": "0.2.0", - "svg-parser": "3.0.0", - "systemd-journald": "0.3.0", - "tagged": "4.0.2", - "tailrec": "6.1.0", - "tecton": "0.2.1", - "tecton-halogen": "0.2.0", - "test-unit": "17.0.0", - "thermite": "6.3.1", - "thermite-dom": "0.3.1", - "these": "6.0.0", - "threading": "0.0.3", - "tldr": "0.0.0", - "toestand": "0.9.0", - "transformation-matrix": "1.0.1", - "transformers": "6.1.0", - "tree-rose": "4.0.2", - "ts-bridge": "4.0.0", - "tuples": "7.0.0", - "two-or-more": "1.0.0", - "type-equality": "4.0.1", - "typedenv": "2.0.1", - "typelevel": "6.0.0", - "typelevel-lists": "2.1.0", - "typelevel-peano": "1.0.1", - "typelevel-prelude": "7.0.0", - "typelevel-regex": "0.0.3", - "typelevel-rows": "0.1.0", - "typisch": "0.4.0", - "uint": "7.0.0", - "ulid": "3.0.1", - "uncurried-transformers": "1.1.0", - "undefined": "2.0.0", - "undefined-is-not-a-problem": "1.1.0", - "unfoldable": "6.0.0", - "unicode": "6.0.0", - "unique": "0.6.1", - "unlift": "1.0.1", - "unordered-collections": "3.1.0", - "unsafe-coerce": "6.0.0", - "unsafe-reference": "5.0.0", - "untagged-to-tagged": "0.1.4", - "untagged-union": "1.0.0", - "uri": "9.0.0", - "url-immutable": "1.0.0", - "uuid": "9.0.0", - "uuidv4": "1.0.0", - "validation": "6.0.0", - "variant": "8.0.0", - "variant-encodings": "2.0.0", - "vectorfield": "1.0.1", - "vectors": "2.1.0", - "versions": "7.0.0", - "visx": "0.0.2", - "web-clipboard": "6.0.0", - "web-cssom": "2.0.0", - "web-cssom-view": "0.1.0", - "web-dom": "6.0.0", - "web-dom-parser": "8.0.0", - "web-dom-xpath": "3.0.0", - "web-encoding": "3.0.0", - "web-events": "4.0.0", - "web-fetch": "4.0.1", - "web-file": "4.0.0", - "web-geometry": "0.1.0", - "web-html": "4.1.0", - "web-pointerevents": "2.0.0", - "web-proletarian": "1.0.0", - "web-promise": "3.2.0", - "web-resize-observer": "2.1.0", - "web-router": "1.0.0", - "web-socket": "4.0.0", - "web-storage": "5.0.0", - "web-streams": "4.0.0", - "web-touchevents": "4.0.0", - "web-uievents": "5.0.0", - "web-url": "2.0.0", - "web-workers": "1.1.0", - "web-xhr": "5.0.1", - "webextension-polyfill": "0.1.0", - "webgpu": "0.0.1", - "which": "2.0.0", - "xterm": "1.0.0", - "yoga-fetch": "1.0.1", - "yoga-json": "5.1.0", - "yoga-om": "0.1.0", - "yoga-postgres": "6.0.0", - "yoga-tree": "1.0.0", - "z3": "0.0.2", - "zipperarray": "2.0.0" - } - }, - "extra_packages": { - "conformance": { - "path": "./conformance" - }, - "protoc-plugin": { - "path": "./plugin" - } - } - }, - "packages": { - "arraybuffer": { - "type": "registry", - "version": "13.2.0", - "integrity": "sha256-fNsR19aRqcUis9C28MpyMigIlfX6f6Hq1up4IcTOvDU=", - "dependencies": [ - "arraybuffer-types", - "arrays", - "effect", - "float32", - "functions", - "gen", - "maybe", - "nullable", - "prelude", - "tailrec", - "uint", - "unfoldable" - ] - }, - "arraybuffer-builder": { - "type": "registry", - "version": "3.1.0", - "integrity": "sha256-dsNYehLsY5xzp/h9hgbn4cMhS+2hVuLzHLg//aPPCs4=", - "dependencies": [ - "arraybuffer", - "arraybuffer-types", - "effect", - "float32", - "identity", - "lists", - "maybe", - "newtype", - "prelude", - "tailrec", - "transformers", - "uint" - ] - }, - "arraybuffer-types": { - "type": "registry", - "version": "3.0.2", - "integrity": "sha256-mQKokysYVkooS4uXbO+yovmV/s8b138Ws3zQvOwIHRA=", - "dependencies": [] - }, - "arrays": { - "type": "registry", - "version": "7.3.0", - "integrity": "sha256-tmcklBlc/muUtUfr9RapdCPwnlQeB3aSrC4dK85gQlc=", - "dependencies": [ - "bifunctors", - "control", - "foldable-traversable", - "functions", - "maybe", - "nonempty", - "partial", - "prelude", - "safe-coerce", - "st", - "tailrec", - "tuples", - "unfoldable", - "unsafe-coerce" - ] - }, - "bifunctors": { - "type": "registry", - "version": "6.0.0", - "integrity": "sha256-/gZwC9YhNxZNQpnHa5BIYerCGM2jeX9ukZiEvYxm5Nw=", - "dependencies": [ - "const", - "either", - "newtype", - "prelude", - "tuples" - ] - }, - "const": { - "type": "registry", - "version": "6.0.0", - "integrity": "sha256-tNrxDW8D8H4jdHE2HiPzpLy08zkzJMmGHdRqt5BQuTc=", - "dependencies": [ - "invariant", - "newtype", - "prelude" - ] - }, - "contravariant": { - "type": "registry", - "version": "6.0.0", - "integrity": "sha256-TP+ooAp3vvmdjfQsQJSichF5B4BPDHp3wAJoWchip6c=", - "dependencies": [ - "const", - "either", - "newtype", - "prelude", - "tuples" - ] - }, - "control": { - "type": "registry", - "version": "6.0.0", - "integrity": "sha256-sH7Pg9E96JCPF9PIA6oQ8+BjTyO/BH1ZuE/bOcyj4Jk=", - "dependencies": [ - "newtype", - "prelude" - ] - }, - "distributive": { - "type": "registry", - "version": "6.0.0", - "integrity": "sha256-HTDdmEnzigMl+02SJB88j+gAXDx9VKsbvR4MJGDPbOQ=", - "dependencies": [ - "identity", - "newtype", - "prelude", - "tuples", - "type-equality" - ] - }, - "effect": { - "type": "registry", - "version": "4.0.0", - "integrity": "sha256-eBtZu+HZcMa5HilvI6kaDyVX3ji8p0W9MGKy2K4T6+M=", - "dependencies": [ - "prelude" - ] - }, - "either": { - "type": "registry", - "version": "6.1.0", - "integrity": "sha256-6hgTPisnMWVwQivOu2PKYcH8uqjEOOqDyaDQVUchTpY=", - "dependencies": [ - "control", - "invariant", - "maybe", - "prelude" - ] - }, - "enums": { - "type": "registry", - "version": "6.0.1", - "integrity": "sha256-HWaD73JFLorc4A6trKIRUeDMdzE+GpkJaEOM1nTNkC8=", - "dependencies": [ - "control", - "either", - "gen", - "maybe", - "newtype", - "nonempty", - "partial", - "prelude", - "tuples", - "unfoldable" - ] - }, - "exceptions": { - "type": "registry", - "version": "6.1.0", - "integrity": "sha256-K0T89IHtF3vBY7eSAO7eDOqSb2J9kZGAcDN5+IKsF8E=", - "dependencies": [ - "effect", - "either", - "maybe", - "prelude" - ] - }, - "exists": { - "type": "registry", - "version": "6.0.0", - "integrity": "sha256-A0JQHpTfo1dNOj9U5/Fd3xndlRSE0g2IQWOGor2yXn8=", - "dependencies": [ - "unsafe-coerce" - ] - }, - "float32": { - "type": "registry", - "version": "2.0.0", - "integrity": "sha256-PRRdv0zNZ8JdohWTO3ZSLzt51ymxK4/NHtGTwuMWHtw=", - "dependencies": [ - "gen", - "maybe", - "prelude" - ] - }, - "foldable-traversable": { - "type": "registry", - "version": "6.0.0", - "integrity": "sha256-fLeqRYM4jUrZD5H4WqcwUgzU7XfYkzO4zhgtNc3jcWM=", - "dependencies": [ - "bifunctors", - "const", - "control", - "either", - "functors", - "identity", - "maybe", - "newtype", - "orders", - "prelude", - "tuples" - ] - }, - "foreign": { - "type": "registry", - "version": "7.0.0", - "integrity": "sha256-1ORiqoS3HW+qfwSZAppHPWy4/6AQysxZ2t29jcdUMNA=", - "dependencies": [ - "either", - "functions", - "identity", - "integers", - "lists", - "maybe", - "prelude", - "strings", - "transformers" - ] - }, - "functions": { - "type": "registry", - "version": "6.0.0", - "integrity": "sha256-adMyJNEnhGde2unHHAP79gPtlNjNqzgLB8arEOn9hLI=", - "dependencies": [ - "prelude" - ] - }, - "functors": { - "type": "registry", - "version": "5.0.0", - "integrity": "sha256-zfPWWYisbD84MqwpJSZFlvM6v86McM68ob8p9s27ywU=", - "dependencies": [ - "bifunctors", - "const", - "contravariant", - "control", - "distributive", - "either", - "invariant", - "maybe", - "newtype", - "prelude", - "profunctor", - "tuples", - "unsafe-coerce" - ] - }, - "gen": { - "type": "registry", - "version": "4.0.0", - "integrity": "sha256-f7yzAXWwr+xnaqEOcvyO3ezKdoes8+WXWdXIHDBCAPI=", - "dependencies": [ - "either", - "foldable-traversable", - "identity", - "maybe", - "newtype", - "nonempty", - "prelude", - "tailrec", - "tuples", - "unfoldable" - ] - }, - "identity": { - "type": "registry", - "version": "6.0.0", - "integrity": "sha256-4wY0XZbAksjY6UAg99WkuKyJlQlWAfTi2ssadH0wVMY=", - "dependencies": [ - "control", - "invariant", - "newtype", - "prelude" - ] - }, - "int64": { - "type": "registry", - "version": "3.0.0", - "integrity": "sha256-IK5NkLmqjdyqHo7MC3W2loWnpIzTjjJgSyePGV0Jw+c=", - "dependencies": [ - "effect", - "foreign", - "functions", - "gen", - "integers", - "maybe", - "nullable", - "prelude", - "unsafe-coerce" - ] - }, - "integers": { - "type": "registry", - "version": "6.0.0", - "integrity": "sha256-sf+sK26R1hzwl3NhXR7WAu9zCDjQnfoXwcyGoseX158=", - "dependencies": [ - "maybe", - "numbers", - "prelude" - ] - }, - "invariant": { - "type": "registry", - "version": "6.0.0", - "integrity": "sha256-RGWWyYrz0Hs1KjPDA+87Kia67ZFBhfJ5lMGOMCEFoLo=", - "dependencies": [ - "control", - "prelude" - ] - }, - "lazy": { - "type": "registry", - "version": "6.0.0", - "integrity": "sha256-lMsfFOnlqfe4KzRRiW8ot5ge6HtcU3Eyh2XkXcP5IgU=", - "dependencies": [ - "control", - "foldable-traversable", - "invariant", - "prelude" - ] - }, - "lists": { - "type": "registry", - "version": "7.0.0", - "integrity": "sha256-EKF15qYqucuXP2lT/xPxhqy58f0FFT6KHdIB/yBOayI=", - "dependencies": [ - "bifunctors", - "control", - "foldable-traversable", - "lazy", - "maybe", - "newtype", - "nonempty", - "partial", - "prelude", - "tailrec", - "tuples", - "unfoldable" - ] - }, - "maybe": { - "type": "registry", - "version": "6.0.0", - "integrity": "sha256-5cCIb0wPwbat2PRkQhUeZO0jcAmf8jCt2qE0wbC3v2Q=", - "dependencies": [ - "control", - "invariant", - "newtype", - "prelude" - ] - }, - "newtype": { - "type": "registry", - "version": "5.0.0", - "integrity": "sha256-gdrQu8oGe9eZE6L3wOI8ql/igOg+zEGB5ITh2g+uttw=", - "dependencies": [ - "prelude", - "safe-coerce" - ] - }, - "nonempty": { - "type": "registry", - "version": "7.0.0", - "integrity": "sha256-54ablJZUHGvvlTJzi3oXyPCuvY6zsrWJuH/dMJ/MFLs=", - "dependencies": [ - "control", - "foldable-traversable", - "maybe", - "prelude", - "tuples", - "unfoldable" - ] - }, - "nullable": { - "type": "registry", - "version": "6.0.0", - "integrity": "sha256-yiGBVl3AD+Guy4kNWWeN+zl1gCiJK+oeIFtZtPCw4+o=", - "dependencies": [ - "effect", - "functions", - "maybe" - ] - }, - "numbers": { - "type": "registry", - "version": "9.0.1", - "integrity": "sha256-/9M6aeMDBdB4cwYDeJvLFprAHZ49EbtKQLIJsneXLIk=", - "dependencies": [ - "functions", - "maybe" - ] - }, - "orders": { - "type": "registry", - "version": "6.0.0", - "integrity": "sha256-nBA0g3/ai0euH8q9pSbGqk53W2q6agm/dECZTHcoink=", - "dependencies": [ - "newtype", - "prelude" - ] - }, - "parsing": { - "type": "registry", - "version": "10.2.0", - "integrity": "sha256-ZDIdMFAKkst57x6BVa1aUWJnS8smoZnXsZ339Aq1mPA=", - "dependencies": [ - "arrays", - "control", - "effect", - "either", - "enums", - "foldable-traversable", - "functions", - "identity", - "integers", - "lazy", - "lists", - "maybe", - "newtype", - "nullable", - "numbers", - "partial", - "prelude", - "st", - "strings", - "tailrec", - "transformers", - "tuples", - "unfoldable", - "unicode", - "unsafe-coerce" - ] - }, - "parsing-dataview": { - "type": "registry", - "version": "3.2.4", - "integrity": "sha256-Xi7UEBNDOvLh6KEoLHigXoeTeeINWVtBQzeFpm/9fa4=", - "dependencies": [ - "arraybuffer", - "arraybuffer-types", - "effect", - "enums", - "float32", - "maybe", - "parsing", - "prelude", - "strings", - "tailrec", - "transformers", - "tuples", - "uint" - ] - }, - "partial": { - "type": "registry", - "version": "4.0.0", - "integrity": "sha256-fwXerld6Xw1VkReh8yeQsdtLVrjfGiVuC5bA1Wyo/J4=", - "dependencies": [] - }, - "prelude": { - "type": "registry", - "version": "6.0.1", - "integrity": "sha256-o8p6SLYmVPqzXZhQFd2hGAWEwBoXl1swxLG/scpJ0V0=", - "dependencies": [] - }, - "profunctor": { - "type": "registry", - "version": "6.0.1", - "integrity": "sha256-E58hSYdJvF2Qjf9dnWLPlJKh2Z2fLfFLkQoYi16vsFk=", - "dependencies": [ - "control", - "distributive", - "either", - "exists", - "invariant", - "newtype", - "prelude", - "tuples" - ] - }, - "record": { - "type": "registry", - "version": "4.0.0", - "integrity": "sha256-Za5U85bTRJEfGK5Sk4hM41oXy84YQI0I8TL3WUn1Qzg=", - "dependencies": [ - "functions", - "prelude", - "unsafe-coerce" - ] - }, - "refs": { - "type": "registry", - "version": "6.0.0", - "integrity": "sha256-Vgwne7jIbD3ZMoLNNETLT8Litw6lIYo3MfYNdtYWj9s=", - "dependencies": [ - "effect", - "prelude" - ] - }, - "safe-coerce": { - "type": "registry", - "version": "2.0.0", - "integrity": "sha256-a1ibQkiUcbODbLE/WAq7Ttbbh9ex+x33VCQ7GngKudU=", - "dependencies": [ - "unsafe-coerce" - ] - }, - "st": { - "type": "registry", - "version": "6.2.0", - "integrity": "sha256-z9X0WsOUlPwNx9GlCC+YccCyz8MejC8Wb0C4+9fiBRY=", - "dependencies": [ - "partial", - "prelude", - "tailrec", - "unsafe-coerce" - ] - }, - "strings": { - "type": "registry", - "version": "6.0.1", - "integrity": "sha256-WssD3DbX4OPzxSdjvRMX0yvc9+pS7n5gyPv5I2Trb7k=", - "dependencies": [ - "arrays", - "control", - "either", - "enums", - "foldable-traversable", - "gen", - "integers", - "maybe", - "newtype", - "nonempty", - "partial", - "prelude", - "tailrec", - "tuples", - "unfoldable", - "unsafe-coerce" - ] - }, - "tailrec": { - "type": "registry", - "version": "6.1.0", - "integrity": "sha256-Xx19ECVDRrDWpz9D2GxQHHV89vd61dnXxQm0IcYQHGk=", - "dependencies": [ - "bifunctors", - "effect", - "either", - "identity", - "maybe", - "partial", - "prelude", - "refs" - ] - }, - "transformers": { - "type": "registry", - "version": "6.1.0", - "integrity": "sha256-3Bm+Z6tsC/paG888XkywDngJ2JMos+JfOhRlkVfb7gI=", - "dependencies": [ - "control", - "distributive", - "effect", - "either", - "exceptions", - "foldable-traversable", - "identity", - "lazy", - "maybe", - "newtype", - "prelude", - "st", - "tailrec", - "tuples", - "unfoldable" - ] - }, - "tuples": { - "type": "registry", - "version": "7.0.0", - "integrity": "sha256-1rXgTomes9105BjgXqIw0FL6Fz1lqqUTLWOumhWec1M=", - "dependencies": [ - "control", - "invariant", - "prelude" - ] - }, - "type-equality": { - "type": "registry", - "version": "4.0.1", - "integrity": "sha256-Hs9D6Y71zFi/b+qu5NSbuadUQXe5iv5iWx0226vOHUw=", - "dependencies": [] - }, - "uint": { - "type": "registry", - "version": "7.0.0", - "integrity": "sha256-fQ30YjiKz9DS6yqRdmK+WARVbJhpZDDTRcpFw675b6M=", - "dependencies": [ - "effect", - "enums", - "gen", - "maybe", - "numbers", - "prelude" - ] - }, - "unfoldable": { - "type": "registry", - "version": "6.0.0", - "integrity": "sha256-JtikvJdktRap7vr/K4ITlxUX1QexpnqBq0G/InLr6eg=", - "dependencies": [ - "foldable-traversable", - "maybe", - "partial", - "prelude", - "tuples" - ] - }, - "unicode": { - "type": "registry", - "version": "6.0.0", - "integrity": "sha256-QJnTVZpmihEAUiMeYrfkusVoziJWp2hJsgi9bMQLue8=", - "dependencies": [ - "foldable-traversable", - "maybe", - "strings" - ] - }, - "unsafe-coerce": { - "type": "registry", - "version": "6.0.0", - "integrity": "sha256-IqIYW4Vkevn8sI+6aUwRGvd87tVL36BBeOr0cGAE7t0=", - "dependencies": [] - }, - "web-encoding": { - "type": "registry", - "version": "3.0.0", - "integrity": "sha256-lqvbj4Rw9mqgSnKx5vSdeNz4vTGxuRQI/PdSK9+kmk0=", - "dependencies": [ - "arraybuffer-types", - "effect", - "newtype", - "prelude" - ] - } - } -} diff --git a/spago.yaml b/spago.yaml deleted file mode 100644 index c6faf98..0000000 --- a/spago.yaml +++ /dev/null @@ -1,26 +0,0 @@ - -# https://github.com/purescript/spago#monorepo-support -# -# purescript-protobuf -# ├── spago.yaml -# │ -# ├── library -# │ └── spago.yaml -# │ -# ├── plugin -# │ └── spago.yaml -# │ -# ├── conformance -# │ └── spago.yaml -# - -workspace: - packageSet: - registry: 60.5.1 - extraPackages: - # protobuf: - # path: ./library - protoc-plugin: - path: ./plugin - conformance: - path: ./conformance \ No newline at end of file