io7m | single-page | multi-page | epub | Cedarbridge User Manual 2.0.0

Cedarbridge User Manual 2.0.0

DATE 2022-09-16T19:14:04+00:00
DESCRIPTION User manual for the Cedarbridge language tools.
IDENTIFIER 312d8e8b-a104-4ac2-88a7-7667b16fe1ee
LANGUAGE en
SOURCE https://www.io7m.com/software/cedarbridge/
TITLE Cedarbridge User Manual 2.0.0
The cedarbridge language is a language designed for specifying message protocols with a focus on minimalism and a clean mathematical foundation. The language has the following notable features:

1.2. Features

  • A carefully written language specification.
  • A minimal data definition language based on algebraic sum and product types.
  • Strong versioning as a core aspect of the language.
  • A small, easily auditable codebase with a heavy use of modularity for correctness.
  • An extensive automated test suite with high coverage.
  • A small footprint; the generated Java code consists of trivial record definitions and incredibly simple and straightforward code to serialize and deserialize values.
  • Platform independence. No platform-dependent code is included in any form.
  • OSGi-ready
  • JPMS-ready
  • ISC license
The cedarbridge package is available from the following sources:
Regardless of the distribution method, the cedarbridge package will contain a command named cedarbridge that acts as the main entrypoint to all the package's functionality. The cedarbridge command expects an environment variable named CEDARBRIDGE_HOME to be defined that points to the installation directory. See the documentation for the installation methods below for details.
A distribution package can be found at Maven Central.
The cedarbridge command requires that a Java 17+ compatible JVM be accessible via /usr/bin/env java.
Verify the integrity of the distribution zip file:

2.2.4. Verify

$ gpg --verify com.io7m.cedarbridge.cmdline-2.0.0-distribution.zip.asc
gpg: assuming signed data in 'com.io7m.cedarbridge.cmdline-2.0.0-distribution.zip.asc'
gpg: Signature made Tue 28 Jun 2022 15:01:56 GMT
gpg:                using RSA key 3CCE59428B30462D10459909C5607DA146E128B8
gpg:                issuer "contact@io7m.com"
gpg: using pgp trust model
gpg: Good signature from "io7m.com (2022 maven-rsa-key) <contact@io7m.com>" [unknown]
Unzip the zip file, and set CEDARBRIDGE_HOME appropriately:

2.2.6. Extract

$ unzip com.io7m.cedarbridge.cmdline-2.0.0-distribution.zip
$ export CEDARBRIDGE_HOME=$(realpath cedarbridge)
$ ./cedarbridge/bin/cedarbridge
info: Usage: cedarbridge [options] [command] [command options]
...
This section of the manual attempts to provide a basic introduction to the cedarbridge language.
The syntax of the cedarbridge language is based on S-expressions, with each cedarbridge source file consisting of a series of statements structured as S-expressions.
A cedarbridge file should start with a language statement indicating which version of the cedarbridge language the file is targeting. Should any backwards-incompatible changes be made to the language in the future, any files that explicitly declared which version of the language they are targeting would continue to be compiled correctly without errors. A file that does not contain a language statement will be compiled using whatever is the latest version of the language the compiler supports. The following example specifies that the file is intended for cedarbridge major version 1, minor version 0:

3.2.3. Language Statement

(language cedarbridge 1 0)
The language allows for using parentheses or square brackets to enclose expressions as long as the use is balanced. For example, all of these expressions are valid:

3.2.5. Valid Parentheses/Brackets

(language cedarbridge 1 0)
[language cedarbridge 1 0]
However, these expressions are not valid and will cause a parse error:

3.2.7. Invalid Parentheses/Brackets

(language cedarbridge 1 0]
[language cedarbridge 1 0)
The cedarbridge language contains a basic package system. All declared message types and protocols must be declared inside packages. A package has a unique name conventionally in lowercase reverse domain notation. A package statement begins the definition of a package, and the definition continues to the next package statement or end-of-file, whichever occurs first. The following statement begins defining a package com.example:

3.3.2. com.example Package

(package com.example)
Packages may import other packages using import statements:

3.3.4. Imports

(import x.y.z z)
(import a.b.c d)
An import statement (import x z) exposes all of the types present in package x via the short name z. For example, if a type T is declared in x, the type can be referred to using the qualified name z:T:

3.3.6. Qualified Names

(import x.y.z z)

(record Q
  [field something z:T])
The cedarbridge language allows for defining message types based on algebraic sums and products. Product types are referred to as record types (similar to structs in the C language), and sum types are referred to as variant types (similar to algebraic data types in Haskell or the ML family of languages). Types may be parameterized by other types (referred to as generics or parametric polymorphism in other languages). A record type consists of a series of uniquely-named fields, and the order of fields is significant. The following statement declares a simple Color record type consisting of red, green, and blue fields:

3.4.2. Example Record

(record Color
  [field red   Float64]
  [field green Float64]
  [field blue  Float64])
The cedarbridge language supports conventional variant types. The classic example for a variant type is the option type where values of type option may either be None or Some s for some value s. The following statement declares the classic parameterized Option type, with the None case having zero fields, and the Some case having exactly one field which is given the name value:

3.4.4. Example Option

(variant Option
  [parameter A]
  [case None]
  [case Some [field value A]])
In the cedarbridge language, there are no backwards-compatible changes possible for types: Adding, removing, or reordering record fields is a backwards-incompatible change. Reordering the cases of a variant type, or changing the fields of cases are backwards-incompatible changes. Rather than resort to the horrendously fragile and excessively permissive model used by other message protocol languages such as protobuf, the cedarbridge language exposes a strict and principled versioning mechanism that allows for unambiguous reasoning about any given version of a protocol; if you know the version of the protocol you are speaking, you know the exact shape of any and all messages that appear in that protocol without the possibility of any extra or missing fields.
A protocol declares a set of versions, with each version declaring the set of types present in each version of the protocol. The following example defines a simple protocol Foo with three versions:

3.5.3. Example Protocol

[import com.io7m.cedarbridge cb]

[record Command0
  [field name cb:String]
  [field ex   cb:IntegerUnsigned16]]

[record Command1
  [field name cb:String]
  [field ex   cb:IntegerUnsigned32]]

[record Command2
  [field name cb:String]
  [field ex   cb:IntegerUnsigned64]]

[record Response
  [field text cb:String]]

[protocol Foo
  [version 1
    [types-added Command0 Command1 Response]
  ]
  [version 2
    [types-added Command2]
  ]
  [version 3
    [types-removed Command0]
  ]
Note that Command0 and Command1 appear in the first two versions of the protocol, but version 3 of the protocol drops support for Command0. The Response type appears in all versions of the protocol. This allows for a disciplined approach to versioning; if a newer version of a protocol requires "changing" a message, the approach taken is to simply declare a new protocol version that contains a new message type (and, almost certainly, removes the old message type).
The cedarbridge package provides a command-line interface for performing tasks such as type-checking definitions, generating code, generating documentation, etc. The base cedarbridge command is broken into a number of subcommands which are documented over the following sections.

4.1.2. Command-Line Overview

Usage: cedarbridge [options] [command] [command options]

  Options:
    --verbose
      Set the minimum logging verbosity level.
      Default: info
      Possible Values: [trace, debug, info, warn, error]

  Use the "help" command to examine specific commands:

    $ cedarbridge help help.

  Command-line arguments can be placed one per line into a file, and the file
  can be referenced using the @ symbol:

    $ echo help > file.txt
    $ echo help >> file.txt
    $ cedarbridge @file.txt

  Commands:
    check                             Type-check a schema file.
    compile                           Compile a schema file and generate code.
    document                          Compile a schema file and generate documentation.
    help                              Show detailed help messages for commands.
    list-code-generators              List available code generators
    list-documentation-generators     List available documentation generators
    version                           Show the application version.

  Documentation:
    https://www.io7m.com/software/cedarbridge/documentation/
All subcommands accept a --verbose parameter that may be set to one of trace, debug, info, warn, or error. This parameter sets the lower bound for the severity of messages that will be logged. For example, at debug verbosity, only messages of severity debug and above will be logged. Setting the verbosity to trace level effectively causes everything to be logged, and will produce large volumes of debugging output.
The cedarbridge command-line tool uses jcommander to parse command-line arguments, and therefore supports placing command-line arguments into a file, one argument per line, and then referencing that file with @. For example:

4.1.5. @ Syntax

$ cedarbridge check --file example.cbs

$ (cat <<EOF
check
--file
example.cbs
EOF
) > args.txt

$ cedarbridge @args.txt
All subcommands, unless otherwise specified, yield an exit code of 0 on success, and a non-zero exit code on failure.
check - Check the validity of cedarbridge definitions
The check command checks the validity of cedarbridge definitions.

4.2.2.2. Parameters

Parameter Type Required Description
--verbose CLPLogLevel false Set the minimum logging verbosity level.
--file List false The file(s) to type-check
--include List false The directories containing source files
--no-core boolean false Disable registration of the core com.io7m.cedarbridge package

4.2.3.1. Example

$ cedarbridge check --file invalid.cbs
ERROR: invalid.cbs:3:1: Name "T" has already been defined.
  Specification: https://www.io7m.com/software/cedarbridge/specification/index.xhtml#id_1cf38aec-7544-4b5e-a5ac-bb01567ffe77
(record T))
^
  See invalid.cbs:2:1:
(record T))
^

$ cedarbridge check --file valid.cbs
compile - Compile cedarbridge sources
The compile command compiles cedarbridge sources.

4.3.2.2. Parameters

Parameter Type Required Description
--verbose CLPLogLevel false Set the minimum logging verbosity level.
--file List false The file(s) to type-check
--include List false The directories containing source files
--output-directory Path true The output directory containing generated files
--no-core boolean false Disable registration of the core com.io7m.cedarbridge package
--language String true The language name used to select a code generator

4.3.3.1. Example

$ cedarbridge compile --file invalid.cbs --language 'Java 17+'
ERROR: invalid.cbs:3:1: Name "T" has already been defined.
  Specification: https://www.io7m.com/software/cedarbridge/specification/index.xhtml#id_1cf38aec-7544-4b5e-a5ac-bb01567ffe77
(record T))
^
  See invalid.cbs:2:1:
(record T))
^

$ cedarbridge compile --file valid.cbs --language 'Java 17+'
document - Generate documentation for cedarbridge sources
The document command generates documentation for cedarbridge sources.

4.4.2.2. Parameters

Parameter Type Required Description
--verbose CLPLogLevel false Set the minimum logging verbosity level.
--file List false The file(s) to type-check
--include List false The directories containing source files
--output-directory Path true The output directory containing generated files
--no-core boolean false Disable registration of the core com.io7m.cedarbridge package
--language String true The language name used to select a documentation generator

4.4.3.1. Example

$ cedarbridge document --file invalid.cbs --language 'xhtml'
ERROR: invalid.cbs:3:1: Name "T" has already been defined.
  Specification: https://www.io7m.com/software/cedarbridge/specification/index.xhtml#id_1cf38aec-7544-4b5e-a5ac-bb01567ffe77
(record T))
^
  See invalid.cbs:2:1:
(record T))
^

$ cedarbridge document --file valid.cbs --language 'xhtml'
list-code-generators - List the available code generators
The list-code-generators command lists the available code generators.

4.5.2.2. Parameters

Parameter Type Required Description
--verbose CLPLogLevel false Set the minimum logging verbosity level.

4.5.3.1. Example

$ cedarbridge list-code-generators
list-documentation-generators - List the available documentation generators
The list-documentation-generators command lists the available documentation generators.

4.6.2.2. Parameters

Parameter Type Required Description
--verbose CLPLogLevel false Set the minimum logging verbosity level.

4.6.3.1. Example

$ cedarbridge list-documentation-generators
version - Display the cedarbridge version
The version command displays the current version of the command-line tool.

4.7.2.2. Parameters

Parameter Type Required Description
--verbose CLPLogLevel false Set the minimum logging verbosity level.

4.7.3.1. Example

$ cedarbridge version
1.0.0
Documentation for the compiler's API is provided in the included JavaDoc.
io7m | single-page | multi-page | epub | Cedarbridge User Manual 2.0.0