\chapter{Schema Language (Orderly)}
\label{orderly}

We wish to thank Lloyd Hilaiel for his work in defining the Orderly language, and express our gratitude for allowing the use of Orderly in this specification. 

The following is a description of the Orderly Language. In this description, we have liberally copied sections from the original Orderly definition from \url{http://Orderly-json.org/}. In some cases, there may be differences between the description here and the description from \url{http://Orderly-json.org/}. In any case, the description of Orderly in this specification SHALL be used to describe the JSON elements of this specification. 



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Overview
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Overview}

Orderly is an ergonomic micro-language that can represent a subset of JSONSchema. Orderly is designed to feel familiar to the average programmer and to be extremely easy to learn and remember. This document provides a conversational overview of Orderly as well as a normative grammar.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% A subset of JSONSchema
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{A subset of JSONSchema}

JSONSchema attempts to provide a representation for three distinct types of information about JSON structures:
\begin{itemize*}
	\item Data structure (for documentation and validation purposes)
	\item Storage attributes (information pertinent to tools that wish to persist JSON data)
	\item Interaction Control (providing hints on how to render a UI where data can be manipulated).
\end{itemize*}

Orderly purposefuly ignores all features of JSONSchema which aren't useful for validation, including the following attributes:
\begin{itemize*}
	\item options (label/value)
	\item title
	\item description
	\item transient
	\item hidden
	\item disallow
	\item extends
	\item identity
\end{itemize*}

An exhaustive list of the differences between Orderly and JSONSchema is below.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% A Non-Normative Tutorial
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newpage
\section{A Non-Normative Tutorial}

A collection of Non-normative examples of Orderly:


\subsection{Comments and Whitespace}

Orderly supports comments, comments are initiated with either '\#' or '//' and continue to the first encountered newline ('\textbackslash{}n').

Orderly doesn't rely overmuch on whitespace, leaving the decision of how to format your schema up to you.


\subsection{Property Names}

Property names may be anything that is allowed inside JSON strings. Unlike JSON itself, however, Orderly provides a shorthand that allows a subset of strings to be represented without quotes. 

For instance these are all valid Orderly:

\begin{lstlisting}[language=Orderly]
string foo;
string "foo";
string "this is a property name with spaces";
\end{lstlisting}


\subsection{Common Properties}

From the JSONSchema specification, four options exist which apply to all data types:

The optional property indicates a value which is not required in a conformant JSON instance. Optional values are represented in Orderly with a trailing question mark:

\begin{lstlisting}[language=Orderly]
string name?;
string "name"?;
\end{lstlisting}

The requires property says that if a value is present in the instance JSON, another named value MUST also be present. In Orderly a requirement on another type is expressed by placing the property name (optionally quoted) enclosed in angle brackets at the end of a type definition:

\begin{lstlisting}[language=Orderly]
string town <state>;
\end{lstlisting}

Multiple properties MAY be required, and SHOULD be separated with commas:

\begin{lstlisting}[language=Orderly]
string town <state,zip>;
\end{lstlisting}

The enum property specifies a set of allowable values for a key in the JSON document.

\begin{lstlisting}[language=Orderly]
string mood [ "happy", "sad", "meh" ];
integer secretOfLife [ 7, 42 ];
\end{lstlisting}

In a JSONSchema document the default property specifies a default value for a property. One could imagine that as an input object passes validation it will be automatically augmented with default values for required properties missing in the instance object. The specification of default values in Orderly looks something like assignment in most programming languages:

\begin{lstlisting}[language=Orderly]
string mood [ "happy", "sad", "meh" ] = "happy"; # optimistically default to "happy"
\end{lstlisting}


\subsection{String Types}

Strings are specified in Orderly using the string type specifier. Strings in JSONSchema support "minLength" and "maxLength" properties, which are represented in Orderly using curly braces immediately after the type:

\begin{lstlisting}[language=Orderly]
string{4,12} login;
\end{lstlisting}

Omission of a specification of either minimum or maximum is allowed:

\begin{lstlisting}[language=Orderly]
string{4,} login; # login requires at least 4 chars
string{,32} name; # name may not be longer than 32 chars
\end{lstlisting}

Regular expressions are supported in JSONSchema for string values. In Orderly you may directly provide a regular expression using '/' syntax to denote the beginning and end of the regular expression:

\begin{lstlisting}[language=Orderly]
string mood /^((happy)|(sad)|(meh))$/;
\end{lstlisting}


\subsection{Number and Integer types}

Numbers are specified in Orderly using the number type specifier. In JSONSchema numbers and integers support ranges, in Orderly these ranges for numbers are specified in the same way we specify ranges for strings:

\begin{lstlisting}[language=Orderly]
number{0.02, 0.98} numNum;
integer{0,10} rating
\end{lstlisting}

Syntactically, numbers in Orderly follow the same rules as numbers in JSON.


\subsection{Boolean Types}

Boolean types are represented in Orderly using the boolean type specifier:

\begin{lstlisting}[language=Orderly]
boolean iShouldStay; 
\end{lstlisting}


\subsection{Object Types}

Objects are represented in Orderly using the object type specifier:

\begin{lstlisting}[language=Orderly]
object {
    string foo;
    integer bar;
    number baz;
};
\end{lstlisting}


Object definitions may be "closed", meaning that properties that are not explicitly mentioned are not allowed, or "open". A trailing star (*) indicates an "open" object defintion:

\begin{lstlisting}[language=Orderly]
object {
    string foo;
    # whatever other properties you want, thanks to that star
}*;
\end{lstlisting}


\subsection{Array Types}

Arrays are specified using the array type specifier.  Schemas for arrays elements may be specified in one of two ways.  First,  we can specify a single schema that governs all array members, with the schema enclosed by square brackets:

\begin{lstlisting}[language=Orderly]
array [
    numbers{0.00, 1.00};
] weights; # an array of floating point weights between 0 and 1.
\end{lstlisting}

Alternately, "tuple typing" may be used to specify the allowable values for an array, in this case a list of schemas that apply to each member of the array in sequence:

\begin{lstlisting}[language=Orderly]
array {
    integer;
    string;
    number;
} artificial;
\end{lstlisting}

When tuple typing is used, the * operator may be used to allow additional elements at the end of an array. For instance, to specify an array where the first element is an integer and the remaining are of arbitrary number and type, one might use the following schema:

\begin{lstlisting}[language=Orderly]
array { integer; }* intFollowedByWhatever;
\end{lstlisting}

Finally, array types also support range semantics, for min/max number of elements:

\begin{lstlisting}[language=Orderly]
array { integer; } {0,10} myArrayOfSmallInts;
\end{lstlisting}


\subsection{Additional properties in arrays and objects}

JSONSchema provides the additionalProperties attribute, which allows a schema author to either:

\begin{itemize}
	\item specify that a valid instance object/array may not have any properties not in the schema
	\item specify an additional schema that applies to any additional properties in the instance object or array that are not explicitly mentioned in the schema
\end{itemize}

Orderly allows you to specify if additional properties SHOULD be allowed, but does not allow you to specify a schema which governs these additional properties.   A trailing * in Orderly indicates additional properties are allowed, and occurs immediately after the definition of nested schemas (the closing curly brace) for both objects:

\begin{lstlisting}[language=Orderly]
object {
    string name;
    string title;
}* employee;
\end{lstlisting}

And for arrays:

\begin{lstlisting}[language=Orderly]
array { integer; string; }* myOpenTupleTypedArray
\end{lstlisting}


\subsection{Null Types}

The null type in JSONSchema specifies a value that MUST be null. The null type specifier is Orderly's equivalent:

\begin{lstlisting}[language=Orderly]
null likeAir;
\end{lstlisting}

As explained in the JSONSchema proposal, null is useful "mainly for purpose of being able use union types to define nullability". For example:

\begin{lstlisting}[language=Orderly]
union {
    string [ "Sr.", "Jr.", "III" ];
    null; 
} suffix;
\end{lstlisting}


\subsection{Any types}

"Any types" are represented in Orderly using the any type specifier:

\begin{lstlisting}[language=Orderly]
any notes;
\end{lstlisting}


\subsection{Unions}

It is possible in JSONSchema to specify a property that may be of one of many different types. In Orderly this functionality is represented using the union type specifier:

\begin{lstlisting}[language=Orderly]
union {
    string;
    number;
} myUnion;
\end{lstlisting}

A key syntactic feature to note is the supported (required?) omission of property names where they would be meaningless.


\subsection{Maps}

Associative arrays are neither defined in Orderly nor in JSONSchema. The CMIS Browser Binding introduces associative arrays (“maps”) to describe a collection of unique keys and a collection of values. 

Maps describe JSON objects without fixing the property names and the number of properties. 
The keys become JSON object property names and have to be non-null strings. Keys can be restricted, for example, by defining a min and max length, regular expressions, an enum, etc.
The values data type can be defined by any unnamed entry including null. 

Maps are specified using the map type specifier. Key and value types are defined within curly braces. The key type first, followed by “=>”, followed by the value type:

For example:

\begin{lstlisting}[language=Orderly]
map { string => boolean } isAllowed;
map { string{2,10} => union { string; integer; null; } } things;
map { string [ "happy", "sad", "meh" ] => integer } intMapping; 
\end{lstlisting}


\subsection{Extensions or Extra Properties}

Orderly is capable of concisely representing a subset of JSONSchema, however at times it might be desirable to be able to represent properties in JSONSchema that are not supported natively in Orderly. For this reason the backtick operators will allow you to encode a JSON object as part of an Orderly schema.  

For example to attach a description to a schema entry one might generate something like:

\begin{lstlisting}[language=Orderly]
string `{"description": "The name of the service"}`;
\end{lstlisting}

The author has full control over formatting, as whitespace is ignored:

\begin{lstlisting}[language=Orderly]
string `{
  "title": "Service Name",
  "description": "The name of the service",
  "ui_hints": "Use the blink tag"
}`;
\end{lstlisting}


\subsection{ID's}
\label{orderly:ids}

Schema elements can have an id, specified using the property “id”.   

For example:

\begin{lstlisting}[language=Orderly]
object {
    id "http://docs.oasis-open.org/ns/cmis/browser/201103/ACLcapabilities";
    string supportedPermissions [ "basic", "repository", "both" ];
    string propagation [ "repositorydetermined", "objectonly", "propagate" ];
    array { ref "http://docs.oasis-open.org/ns/cmis/browser/201103/permissionDefinition" } permissions;
    ref "http://docs.oasis-open.org/ns/cmis/browser/201103/permissionMapping" mapping?;
 }*;
\end{lstlisting}


\subsection{References}

The reference type specifier “ref” is used to refer to another Orderly schema element using the “id” described in section \ref{orderly:ids}.  For example:

\begin{lstlisting}[language=Orderly]
object {
    string name;
    string title;
    ref "http://json-schema.org/card" secretary;
    array {
        ref "http://json-schema.org/card";
    } reports;
} employee;
\end{lstlisting}


\subsection{Bases}

The specifier "base" is used to define the base schema element of the element. All properties are inherited from the base element. For example:

\begin{lstlisting}[language=Orderly]
object {
    id "http://example.com/person";
    string firstname;
    string lastname;
} person;

object {
    id "http://example.com/employee";
    base "http://example.com/person";
    integer employee_number;
} employee;

// The schema element "http://example.com/employee" consists of 
// the properties "firstname", "lastname" and "employee_number".
\end{lstlisting}

\newpage
\subsection{More Complex Examples}

A number with a range, enumerated possible values, and a default value:

\begin{lstlisting}[language=Orderly]
integer{0,256} powerOfTwo[1,2,4,8,16,32,64,128,256] = 1;
\end{lstlisting}

An object with enumerated possible values and a default.

\begin{lstlisting}[language=Orderly]
object {
  string beast;
  number normalTemperature;
} temps [ { "beast": "canine", "normalTemperature": 101.2 },
    { "beast": "human", "normalTemperature": 98.6 } ]
  = { "beast": "canine", "normalTemperature": 101.2 };
\end{lstlisting}


\subsection{Cautions}

When you stare hard enough at the grammar of a non-trivial language you usually learn quite a deal. Sometimes what you learn can be surprising or downright confusing. Here's a tour of the darker parts alleys of Orderly:

Brackets and braces -- visually a tad confusing:

\begin{lstlisting}[language=Orderly]
integer{7,42} secretOfLife[7,42];
\end{lstlisting}

And a little bit more confusing:

\begin{lstlisting}[language=Orderly]
array { integer{7,42}[7,42]; } secretOfLife;
\end{lstlisting}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The Normative Grammar
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newpage
\section{The Normative Grammar}

\begin{lstlisting}[language=OrderlyGrammer]
Orderly_schema
    unnamed_entry ';'
    unnamed_entry

named_entries
    named_entry ';' named_entries
    named_entry 
    # nothing

unnamed_entries
    unnamed_entry ';' unnamed_entries
    unnamed_entry 
    # nothing

named_entry
    definition_prefix property_name definition_suffix
    string_prefix property_name string_suffix

unnamed_entry
    definition_prefix definition_suffix
    string_prefix string_suffix

definition_prefix
    'id' 
    'integer' optional_range
    'number' optional_range
    'boolean'
    'null'
    'any'
    # a tuple-typed array 
    'array'  '{' unnamed_entries '}' optional_additional_marker optional_range 
    # a simple-typed array (notice the '*' marker is disallowed)
    'array'  '[' unnamed_entry ']' optional_range   
    'object' '{' named_entries '}' optional_additional_marker   
    'union'  '{' unnamed_entries '}'
    'map' '{' map_key '=>' unnamed_entries '}' optional_optional_marker
    'ref' ref_string
    'base' ref_string

string_prefix
    'string' optional_range

string_suffix
    optional_perl_regex definition_suffix

definition_suffix
    optional_enum_values optional_default_value optional_requires \
        optional_optional_marker optional_extra_properties
    # nothing

map_key
     string_prefix string_suffix

ref_string
     '"' json_string '"'

csv_property_names
    property_name "," csv_property_names
    property_name

optional_extra_properties
    '`' json_object '`'
    # nothing

optional_requires
    '<' csv_property_names '>'
    # nothing

optional_optional_marker
    '?'
    # nothing  

optional_additional_marker
    '*'
    # nothing  

optional_enum_values
    json_array
    # nothing  

optional_default_value
    '=' json_value
    # nothing  

optional_range
    '{' json_number ',' json_number '}'
    '{' json_number ',' '}'
    '{' ',' json_number '}'
    '{' ',' '}'                          # meaningless, yes.
    # nothing

property_name
    json_string
    [A-Za-z_\-]+                         # (alpha & underbar & dash)

optional_perl_regex # perl compatible regular expressions are supported
    '/' ([^/]|\/) '/' # a Perl 5 compatible regular expression
    #nothing

----------------------------------------
---------- [The JSON Grammar] ----------
----------------------------------------

json_object
    {}
    { members } 
members
    pair
    pair , members
pair
    json_string : json_value
json_array
    []
    [ elements ]
elements
    json_value
    json_value , elements
json_value
    json_string
    json_number
    json_object
    json_array
    'true'
    'false'
    'null'

----------------------------------------

json_string
    ""
    " chars "
chars
    char
    char chars
char
    any-Unicode-character-
        except-quote-or-backslash-or-
        control-character
    \" #double quote (")
    \\
    \/
    \b
    \f
    \n
    \r
    \t
    \u four-hex-digits 
json_number
    int
    int frac
    int exp
    int frac exp 
int
    digit
    digit1-9 digits
    - digit
    - digit1-9 digits 
frac
    . digits
exp
    e digits
digits
    digit
    digit digits
e
    e
    e+
    e-
    E
    E+
    E-
\end{lstlisting}
