Fixup documentation
This commit is contained in:
parent
e87599708e
commit
bc458299dc
1 changed files with 50 additions and 35 deletions
85
README.md
85
README.md
|
@ -37,10 +37,10 @@ Endgen currently contains two separate parsers:
|
|||
* endpoint - A DSL for expressing HTTP endpoints.
|
||||
* state - A DSL for expressing state and transitions.
|
||||
|
||||
Which parser that is used to read the input file is determined by the file name ending
|
||||
'.endpoints' or '.states' or by a command line argument.
|
||||
Only one parser will be sued when reading a file. Determined by the file name ending;
|
||||
'.endpoints', or '.states', or by a command line argument.
|
||||
|
||||
The endpoint DSL and the state DSL share the grammar for expressing configuration and data types
|
||||
The endpoint-DSL and the state-DSL share the grammar for expressing configuration and data types
|
||||
,see below for details.
|
||||
|
||||
## How to Run
|
||||
|
@ -89,15 +89,20 @@ a very limited DSL, you can for example not express what type of HTTP Verb to us
|
|||
no plans to extend the DSL to do that either.
|
||||
|
||||
## DSL
|
||||
This is the ANTLR grammar for the root of the DSL
|
||||
This is the ANTLR grammar for the root of the Endpoint-DSL
|
||||
|
||||
```antlrv4
|
||||
document : generatorconfig? (namedTypeDeclaration|endpoint)* ;
|
||||
```
|
||||
|
||||
the corresponding grammar for the root of the State-DSL
|
||||
|
||||
```antlrv4
|
||||
document : generatorconfig? transition (',' transition)* ;
|
||||
```
|
||||
|
||||
### Configuration block
|
||||
Meaning that the DSL file has an optional `generatorconfig` block at the top. Then you can write either; a type
|
||||
definition, or an endpoint declaration, as many times as you like.
|
||||
Both types of DSL files has an optional `generatorconfig` block at the top.
|
||||
|
||||
Here is an example:
|
||||
```
|
||||
|
@ -105,25 +110,32 @@ Here is an example:
|
|||
package: se.rutdev.senash,
|
||||
mykey: myvalue
|
||||
}
|
||||
```
|
||||
|
||||
This consists of a config block with 2 items, the 'package' and the 'mykey' definition. These are available to be used
|
||||
in the freemarker template as a Map of String-keys to String-values.
|
||||
|
||||
### Endpoint DSL
|
||||
After the optional configuration block you can write either; a type definition, or an endpoint declaration, and repeat
|
||||
as many times as you like.
|
||||
|
||||
Here is an example:
|
||||
```
|
||||
/some/endpoint <- SomeType(foo:String)
|
||||
|
||||
Embedded(foo:Bar)
|
||||
/some/other/endpoint <- (bar:Seq[Embedded])
|
||||
```
|
||||
|
||||
This consists of a config block with 2 items, the 'package' and the 'mykey' definition. These are available to be used
|
||||
in the freemarker template as a Map of String-keys to String-values.
|
||||
|
||||
### Endpoint definition
|
||||
|
||||
`/some/endpoint <- SomeType(foo:String)` is an endpoint definition. It declares one endpoint that have a request body
|
||||
data type called `SomeType` that has a field called `foo` of the type `String`.
|
||||
|
||||
### Data types
|
||||
The DSL uses Scala convention of writing data types after the field name separated by a colon. Of course the DSL parser
|
||||
does not know anything about java or scala types, as far as it is concerned these are 2 strings and the first one is
|
||||
just named field-name and the other string is named field-type.
|
||||
Both DSL-grammars use the Scala convention of writing data types after the field name separated by a colon. Of course
|
||||
the parsers do not know anything about java or scala types, as far as the parser is concerned these are 2 strings and
|
||||
the first one is just named: field-name and the other string is named: field-type.
|
||||
|
||||
`Embedded(foo:Bar)` is a `namedTypeDeclaration` which is parsed the same way as the request type above. But isn't tied
|
||||
to a specific endpoint.
|
||||
|
@ -148,45 +160,44 @@ It is possible to have an optional response data type declared like so:
|
|||
The right pointing arrow `->` denotes a response type, it can be an anonymous data type in which case the parser till
|
||||
name it from the last path segment and add 'Response' to the end of the data type name.
|
||||
|
||||
### State grammar
|
||||
|
||||
### State DSL
|
||||
This is an example of a state file:
|
||||
```
|
||||
start -> middle: message,
|
||||
middle -> middle: selfmessage,
|
||||
middle -> end: endmessage
|
||||
start -> middle: message,
|
||||
middle -> middle: selfmessage,
|
||||
middle -> end: endmessage
|
||||
```
|
||||
The file declares 3 transitions. The first line states: Transition from the 'start' state to the 'middle' state with
|
||||
the message 'message'.
|
||||
|
||||
It contains 3 state definitions `start`, `middle` and `end`. A state definition will be parsed as a data type with
|
||||
the name of the state as the type name.
|
||||
|
||||
It also contains 3 message definitions `message`, `selfmessage` and `endmessage`. Message definitions will also be
|
||||
parsed as data types.
|
||||
From this we can see that the file contains 3 state definitions `start`, `middle` and `end`.
|
||||
A state definition will be parsed as a data type with the name of the state as the type name. It also contains 3
|
||||
message definitions `message`, `selfmessage` and `endmessage`. Message definitions will also be parsed as data types.
|
||||
|
||||
Since the parser will extract datatypes it is possible to define the fields of the data types. This is a slightly more
|
||||
complicated example:
|
||||
|
||||
```
|
||||
start(foo:Foo) -> middle: message(a: String),
|
||||
middle(bar:Bar) -> middle: selfmessage,
|
||||
middle -> end: endmessage
|
||||
start -> middle: message(a: String),
|
||||
middle(bar:Bar) -> middle: selfmessage,
|
||||
middle -> end: endmessage
|
||||
```
|
||||
Where for example the data type for `middle` will have the field declaration with the name `bar` and the type `Bar`.
|
||||
The data type for `middle` will have a field declaration with the name `bar` and the type `Bar`.
|
||||
|
||||
Fields for the same state data type, or message data type, will be merged. Here is a complex example:
|
||||
|
||||
```
|
||||
start(s:S) -> middle(foo:foo): message(foo:foo),
|
||||
middle -> middle(bar:bar): selfmessage(bar:bar),
|
||||
middle -> end: message(bar:baz)
|
||||
start(s:S) -> middle(foo:foo): message(foo:foo),
|
||||
middle -> middle(bar:bar): selfmessage(bar:bar),
|
||||
middle -> end: message(bar:baz)
|
||||
```
|
||||
|
||||
Not that we can declare fields on both the `from` and `to` state declarations. The `middle` datat type will have field
|
||||
Note that we can declare fields on both the `from` and `to` state declarations. The `middle` datat type will have field
|
||||
definitons for `foo` and `bar`.
|
||||
|
||||
The data type for `message` will have fields for `foo` and `bar`.
|
||||
|
||||
One restriction is that states and messages may not have the same name, i.e. be parsed as the same data type.
|
||||
One restriction is that a state and a messages may share have the same name, i.e. be parsed as the same data type.
|
||||
|
||||
## Generating
|
||||
If the parser is successful it will hold the following data in the AST
|
||||
|
@ -221,8 +232,8 @@ that writes the value for a config key called 'package'.
|
|||
`package ${config.package}`
|
||||
|
||||
### Data types
|
||||
These are all the data types the parser have collected, either from explicit declarations, request payloads and response
|
||||
bodies.
|
||||
These are all the data types the parser have collected, either from explicit declarations, request payloads, response
|
||||
bodies, states or messages.
|
||||
|
||||
```java
|
||||
public record TypeNode(String name, List<FieldNode> fields) { }
|
||||
|
@ -281,11 +292,15 @@ The set of states will hold items of this shape:
|
|||
public record StateNode(String name, String data, Set<TransitionNode> transitions) {
|
||||
}
|
||||
```
|
||||
* `name` is the name of the state.
|
||||
* `data` is the name of the data type for the state.
|
||||
* `transistions` are the outgoing arrows from the named state.
|
||||
|
||||
and the transitions has this structure:
|
||||
Transitions have this structure:
|
||||
|
||||
```injectedfreemarker
|
||||
public record TransitionNode(String message, String toState) {
|
||||
}
|
||||
```
|
||||
|
||||
* `name` is the message name.
|
||||
* `toState` is the name of the target state.
|
||||
|
|
Loading…
Add table
Reference in a new issue