Permalink
Switch branches/tags
Nothing to show
Find file Copy path
1406 lines (1021 sloc) 37.6 KB

MSON Specification

Markdown Syntax for Object Notation (MSON) is a plain-text syntax for the description and validation of data structures.

Quick Links

1 How to Read the Grammar

  • An arrow (→) mark grammar productions that can be read as "is defined by|is defined by a(n)"
  • A double arrow (⇒) marks grammar productions that can be read as "contains|contains a(n)"
  • Italic text indicates syntactic categories
  • A code span indicates literal characters, words and punctuations
  • A pipe character (|) separates alternative grammar productions
  • A following [opt] indicates optional syntactic categories and literals

1.1 Markdown Syntax

Note this reference is using ATX-style headers (#) and hyphen-style lists (-) exclusively. However you MAY use Setext-style headers and/or asterisk (*) or plus (+) style lists if you prefer.

1.2 Notational Conventions

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC2119.

1.3 Promises

By default, MSON explicitly defines data structures and the meaning of their members without making any assertion to the exclusivity of structures or their members. Further, no assertion is made concerning the presence of defined structures or members. Rather, MSON describes structures that MAY be observed versus what MUST be observed.

However, much like JSON Schema being able to restrict "additionalProperties", MSON allows annotating structures to indicate when they are strictly defined to preclude other structures and members and when they have strict ordering.

2 Types

In MSON, data structures are described by header-defined and/or list-defined Types and/or combinations thereof built from a limited set of Base Types. A particular Type is defined by its Type Declaration and combination of optional Type Sections.

TypeType Declaration

TypeType Sections [opt]

More specifically:

TypeType Declaration

TypeBlock Description [opt]

TypeMember Type Group [opt] | Nested Member Types [opt]

TypeSample [opt]

TypeValidations [opt]

  • Header-defined Named Type

    # Person (object)
    A person.
    
    ## Properties
    - `first_name`
    - `last_name`
    - address
        - city
        - street
    
  • List-defined Member Type

    - person (object) - A person
        - `first_name`
        - `last_name`
        - address
            - city
            - street
    

    or, equivalently:

    - person (Person) - A person
    

2.1 Base Types

MSON defines a number of distinct base, case-insensitive Primitive and Structure Types from which all data structures are built (sub-typed).

2.1.1 Primitive Types

Applies to basic data structure and type definitions. Types that are sub-typed from Primitive Types MUST NOT contain a Member Type Group or Nested Member Types.

  • boolean

    Specifies a type with allowed values of true or false.

  • string

    Specifies any string.

  • number

    Specifies any number.

2.1.2 Structure Types

Applies to recursive, composite data structure and type definitions. Types that are sub-typed from Structure Types MAY contain a Member Type Group or Nested Member Types.

Structure Types may directly or indirectly contain recursive references to themselves.

  • array

    Specifies a list of items for values.

  • enum

    Specifies an exclusive list of possible Values or Types for values.

  • object

    Specifies a structure that contains properties as members.

2.2 Named Types

Users may extend Base Types to define new header-defined Named Types that MAY be referenced to build other Types.

Named TypeNamed Declaration | Generic Named Declaration

Named TypeType Sections [opt]

# Person (object)
- first_name
- last_name

2.3 Member Types

Markdown lists specify MSON Member Types, which define the structure and types of individual members of Types built from Structure Types. A Member Type that contains Nested Member Types defines an inner, anonymous type that specifies the structure of values of that particular member.

2.3.1 Property Member Types

Define individual members of object type structures.

Property Member TypeProperty Member Declaration

Property Member TypeType Sections [opt]

Any list of Property Member Types collectively MAY define an implied parent object type structure.

- person (object) - A person
    - `first_name`
    - `last_name`
    - address
- company (string)

Defines a person Property Member Type with a value that is an explicit object type structure with members first_name, last_name, and address and, at the same time, is a member together with company of another implied object structure.

2.3.2 Value Member Types

Define individual members of array or enum type structures.

Value Member TypeValue Member Declaration

Value Member TypeType Sections [opt]

- (array)
    - red (string) - A sample value
    - green (string)

3 Type Declaration

Defines a particular MSON Type.

Type DeclarationNamed Declaration | Generic Named Declaration | Property Member Declaration | Value Member Declaration

3.1 Named Declaration

Defines a Named Type.

Named Declaration# Type NameType Definition [opt]

# Person (object)

3.1.1 Generic Named Declaration

Defines a Named Type that allows an italicized Variable Type Name to represent a Type Name at any location in the Type Specification of a Variable Type Specification.

Generic Named Declaration# Type NameVariable Type Specification

# One or Many (enum[*T*])

3.2 Property Member Declaration

Defines a Property Member Type.

Property Member Declaration- Property Name : [opt] Value Definition [opt] - [opt] Description [opt]

- person (object) - A person

The optional : is only applicable in the case where a Value Definition is present and includes a Value.

- company: Apiary (string)

3.2.1 Property Name

Defines the name of a property in an object type structure.

Property NameLiteral Value | Variable Property Name

- customer (object)

Defines a Property Member Declaration with a Property Name "customer".

3.2.2 Variable Property Name

Defines a Property Name that is associated with a specific Value Definition in an object type structure that MAY be any arbitrary name in an actual implementation. The Value of the Variable Property Name serves as a sample.

Variable Property Name*Value Definition*

In the case of specifying a Variable Property Name, the Value Definition MAY reference a Named Type that MUST be sub-typed from a string Primitive Type.

*rel (Custom String)* (object)

Where rel is a sample value for the arbitrary Property Name of a Property Member Declaration.

3.3 Value Member Declaration

Defines a Value Member Type. A Value Member Declaration MUST only be used to define structures of array or enum Member Types.

Value Member Declaration- Value Definition - [opt] Description [opt]

The optional - is only applicable in the case where a Description is provided.

- (array)

3.4 Value Definition

Every Member Type MAY specify type information associated with values in a structure or member in a structure. This includes a Value Definition that may include literal or sample Values and a Type Definition, including a Type Specification and/or Type Attributes, of associated types.

Value DefinitionValue [opt] Type Definition [opt]

A Value Definition MUST include at least a Value or a Type Definition. A Value Definition of an object Member Type MUST NOT specify a Value.

5, 6 (array)

Defines a Value Definition for an array type structure with sample values "5" and "6".

3.4.1 Value

Defines either sample or actual value(s) in Member Types based on the associated Type Definition in a Value Definition.

ValueLiteral Value | Variable Value | Values List

Values ListValue | Value, Values List

A Values List MUST only be used with array or enum Structure Types or Named Types derived from them.

By default:

  • A Value Definition that incorporates a Values List but has no Type Definition implies an array type structure.
- list: 1, 2, 3

is equivalent to:

- list: 1, 2, 3 (array)

Where "1", "2", and "3" are sample values of the array structure.

  • A Value Definition that incorporates a Values List defines fully-qualified values of an enum type structure.
- colors: red, green (enum)

Where "red" and "green" are fully-qualified values of the colors enumeration.

3.4.2 Literal Value

Literal value of a type instance. Some limitations apply (see Reserved Characters & Keywords).

5

3.4.3 Variable Value

Defines a Value that is not concrete using Markdown italics.

Variable Value*Literal Value*

A Variable Value MAY be used to indicate a Variable Property Name in a Property Member Declaration or more generally, a sample value in a Value Definition.

*rel*

3.5 Type Definition

Explicitly specifies the type of a value in an MSON instance.

Type Definition(Type Specification [opt] , [opt] Type Attributes List [opt])

Type Attributes ListType Attribute | Type Attribute, Type Attributes List

A Type Definition MUST separate multiple items with commas and is order-independent.

(enum, optional)

3.5.1 Type Specification

Defines sub-typed Base Types or Types for a particular Type.

Type SpecificationType Name | Type Name[Nested Type Name List]

Nested Type Name ListType Name | Type Name, Nested Type Name List

An array or enum Value Definition MAY specify the Type Specifications of implied Nested Member Types members in-line using [] as a Nested Type Name List.

array[number, string]

Indicates a array type structure MAY include distinct numbers or strings as values.

3.5.1.1 Variable Type Specification

Defines a variable Type Specification to indicate generic Named Types.

Variable Type SpecificationType Specification

A Variable Type Specification MUST include at least one Variable Type Name.

# One or Many (enum[*T*])

3.5.2 Type Name

References the name of a type in Base Types or Named Types. Some limitations apply (see Reserved Characters & Keywords).

Type NameLiteral Value | Variable Type Name | Wildcard Type Name | Referenced Type Name

Referenced Type NameA valid Markdown-style link, where the link name MUST be a Literal Value

A Variable Type Name MUST only be used in two situations:

A Referenced Type Name MAY be used to link to a Type Name defined in another location in an MSON document solely as a navigation convenience.

3.5.2.1 Variable Type Name

An italicized variable that MAY be used in place of a Type Name for a Type Definition in a Generic Named Declaration.

Variable Type Name*Literal Value*

3.5.2.2 Wildcard Type Name

Indicates any type MAY be possible.

Wildcard Type Name*

A Wildcard Type Name MAY only be used in a Type Specification for Member Types.

3.5.3 Type Attribute

Defines extra attributes associated with the implementation of a type.

  • required - instance of this type is required
  • optional - instance of this type is optional (default)
  • fixed - instance of this type structure and values are fixed. This attribute propagates to Nested Member Types.
  • fixed-type - instance of this type structure is fixed, value is not. This attribute does not propagate to Nested Member Types.
  • nullable - instance of this type Value MAY be unset (e.g. null or nil). nullable may only be used within properties of objects.
  • sample - Alternate way to indicate a Value is a sample. See Sample.
  • default - Alternate way to indicate a Value is a default. See Default.

A sample Type Attribute is mutually exclusive with default.

3.6 Description

Describes a Member Type in-line.

Description- Markdown-formatted text

- name: Andrew (string) - A Description

4 Type Sections

Types MAY contain any Block Description, Member Type Group, Nested Member Types, Sample, Default and/or Validations Type Sections. Apart from a Block Description, multiple Type Sections MAY be specified and MAY have any order.

# Person (object)
An additional
multi-line description

- here
- there

## Sample
...

## Properties
- `first_name`
- `last_name`

## Validations
...

## Sample
Another ...

In general, Type Sections nested under:

4.1 Block Description

Describes a Type using a nested (multi-line) Markdown text block.

Block DescriptionMarkdown-formatted text

A Block Description MUST be located directly under a Type Declaration and MUST start with text. Markdown lists MAY be included in a Block Description after initial text content and are considered part of the block text.

- name: Andrew (string) - A Description

    An additional
    multi-line description.

    - here
    - there

    More text.

Note that here and there are NOT Nested Member Types but rather are part of a Markdown list in the Block Description.

A Member Types Block Description MUST escape Member Type Separator Keywords as a code span when used in a Markdown list.

- person (object)
    This person does not have:

    - `Properties`
        - first_name
        - last_name

    - Properties
        - `given_name`
        - surname

4.2 Member Type Group

A Member Type Group delineates Nested Member Types and MUST be used when other Type Sections are present.

Member Type Group- Member Type Separator | ## Member Type Separator

Member Type GroupNested Member Types

In order to specify Nested Member Types after a Block Description, Types MUST use an appropriate Member Type Group to indicate the end of the Block Description and the beginning of a Nested Member Types list.

  • Named Type

    A header-defined (##) Member Type Group SHOULD be nested one additional header level under the associated Named Type, when required.

    # Person (object)
    An additional
    multi-line description
    
    - here
    - there
    
    ## Properties
    - `first_name`
    - `last_name`
    
  • Member Type

    A list-defined (-) Member Type Group SHOULD be nested one indentation level under the associated Member Type.

    - person (object)
    
        An additional
        multi-line description
    
        - here
        - there
    
        - Properties
            - `first_name`
            - `last_name`
    

A Member Type Group of an appropriate type MUST be used to define Nested Member Types whenever any other Type Section is specified at the same level.

4.2.1 Member Type Separator

Defines the names of separators to indicate the beginning of a section of Nested Member Types.

Member Type SeparatorItems | Members | Properties

  • Array Structures - MUST use Items for a Member Type Separator

  • Enum Structures - MUST use Members for a Member Type Separator

  • Object Structures - MUST use Properties for a Member Type Separator

4.3 Nested Member Types

Types built from Structure Types MAY contain Nested Member Types, which are defined using nested Markdown lists of allowed Member Types.

A Member Type that contains Nested Member Types defines an inner, anonymous type that specifies the structure of values of that particular member.

Nested Member TypesMember Types

By Default:

With a fixed Type Attribute:

  • If a Named Type or Member Type annotates its type as fixed, all Nested Member Types inherit the fixed attribute as well.

    - person (object, fixed)
        - name
    

    Implies:

    - person (object, fixed)
        - name (fixed)
    
  • An array based Named Type or Member Type MAY specify fixed to indicate the structure is a "fixed ordered list" of only the specified values and/or types, if any, of its Nested Member Types.

    - colors (array, fixed)
        - red
        - green
    

    Implies a fixed-list array structure that MUST only contain the two items "red" and "green" in that order.

    - components (array, fixed)
        - (object)
        - (string)
    

    Implies a fixed-list array structure that MUST only contain the two items of an arbitrary object and string in that order.

  • An object based Named Type or Member Type MAY specify fixed to indicate a "value object" where all the properties MUST be present and the values of the properties MUST be the values specified, if any, in its Nested Member Types. Further, such an object type structure MUST NOT contain any other properties.

    - person (object, fixed)
        - `first_name`: Andrew
        - `last_name`: Smith
    

    Implies a "value object" that MUST contain only the properties "first_name" and "last_name" with the values "Andrew" and "Smith", respectively.

    - person (object, fixed)
        - `first_name`
        - `last_name`
    

    Implies an object that MUST contain only the properties "first_name" and "last_name", respectively.

  • Individual Nested Member Types MAY override inherited behavior from a fixed inherited type by using an optional attribute and/or MAY indicate values are samples using a Variable Value.

    - person (object, fixed)
        - `first_name`
        - `last_name` (optional)
    

    Implies a "value object" that MUST contain the property "first_name" and MAY contain the property "last_name".

    - colors (array, fixed)
        - red
        - *green*
    

    Implies an array type structure that MUST contain "red" as an item and MAY contain any other strings, where "green" is a sample value.

With a fixed-type Type Attribute:

  • If a Named Type or Member Type annotates its type as fixed-type, Nested Member Types do not inherit the fixed-type attribute.

  • An array based Named Type or Member Type MAY specify fixed-type to indicate the structure MUST contain items of the specified types only.

    - colors (array, fixed-type)
        - red (string)
    

    Implies a fixed-list array structure that MUST only contain any string items; red is an example value.

  • An object based Named Type or Member Type MAY specify fixed-type to indicate an object where all the properties MUST be present. Further, such an object type structure MUST NOT contain any other properties.

    - person (object, fixed-type)
        - first_name: John
        - last_name: Smith
    

    Implies an object that MUST contain only the properties "first_name" and "last_name", respectively; John and Smith are example values.

4.4 Sample

Defines alternate sample Values for Member Types as a nested Markdown list with (multi-line) text.

Sample- Sample | - Sample : Value | ## Sample

SampleMarkdown-formatted text | Value Member Types

A Type MAY have multiple Sample lists.

  • Named Types

    A header-defined (##) Sample MUST be nested one additional header level under the associated Named Type if a Block Description is used.

    # Colors (array)
    A list of colors
    
    ## Sample
    - red
    
    ## Items
    - (string)
    
    ## Sample
    - blue
    - green
    

    A sample Type Attribute MUST NOT be used in the Type Definition of a Named Declaration.

  • Member Types

    A list-defined (-) Sample SHOULD be nested one indentation level under the associated Member Type.

    - colors (array)
      - Sample: red
      - Sample
          - blue
          - green
    

    A sample Type Attribute MAY be used to indicate a Value in a Value Member Type is a sample value.

    - list: 3, 4 (enum, sample)
    

    Is equivalent to:

    - list: *3, 4* (enum)
    

    Which, is equivalent to:

    - list (enum)
        - Sample
            - 3
            - 4
    

4.5 Default

Indicates Values for Member Types as a nested Markdown list with (multi-line) text are defaults.

Default- Default | - Default : Value | ## Default

DefaultMarkdown-formatted text | Value Member Types

A Type MAY have one Default Type Section. A Default for a Member Type MAY also indicate a Sample.

4.6 Validations

Reserved for future use.

5 Type Inheritance

A Member Type or Named Type that inherits from another Named Type also inherits any Nested Member Types in the same order they are defined in the inherited Named Type and in order based on the placement of the Mixin Type.

# Person (object)
- `first_name`
- `last_name`

And:

- person (Person)
    - address

Implies the same structure as:

- person (object)
    - `first_name`
    - `last_name`
    - address

Where the inherited Member Types from Person Named Type are listed first.

An object may not inherit from itself, either directly or indirectly.

5.1 Mixin Type

MSON defines a Mixin Type that supports multiple inheritance from another Named Type. The Named Type being inherited MUST be a Structure Type or its sub-type.

Nested Member Types defined in and inherited from the mixed-in Named Type are added at the same indentation level of the Mixin Type.

Mixin Type- Include Type Name | - Include Type Definition

Example 1

# Person (object)
- `first_name`
- `last_name`

And:

- `formal_person` (object)
    - prefix: Mr
    - Include Person

Implies the same structure as:

- `formal_person` (object)
    - prefix: Mr
    - `first_name`
    - `last_name`

Example 2

Alternately:

- `formal_person` (object)
    - Include Person
    - prefix: Mr.

Implies the same structure as:

- `formal_person` (object)
    - `first_name`
    - `last_name`
    - prefix: Mr.

A Mixin Type MUST use an appropriate Member Type Separator in a Member Type Group in order to specify Nested Member Types after a Block Description.

- address (object)
    An address

    - Properties
        - Include Address

5.2 One Of Type

MSON defines a One Of Type that can be used to describe mutually exclusive sets of Nested Member Types. A One of Type MUST only be used to define Property Member Types for a object type structure.

One of Type- One Of

One of TypeMember Type Group

One of TypeNested Member Types

One of TypeMixin Type

One of TypeOne of Type

- `first_name`
- One Of
    - `last_name`
    - One Of
        - `given_name`: Smith
        - `suffixed_name`: Smith, Sr.

Implies values with a structure of:

- `first_name`
- `last_name`

Or:

- `first_name`
- `given_name`: Smith

Or:

- `first_name`
- `suffixed_name`: Smith, Sr.

A One Of Type MUST use a Properties Member Type Separator in a Member Type Group:

5.3 Generic Named Type

Defines a Named Type that allows an italicized Variable Type Name to represent a Type Name at any location in a Type Specification.

Generic Named TypeNamed Type

By default:

  • A Named Type that contains at least one Variable Type Name is a Generic Named Type.

  • A Variable Type Name in a Type Specification MAY only be used in the Type Definition of explicitly defined Nested Member Types in the Generic Named Type and MUST NOT define any implied Nested Member Types.

  • Inherited type as a variable

    # Address Decorator (*T*)
        - address
    
    # Person (object)
        - `first_name`
        - `last_name`
    

    And:

    - `decorated_person` (Address Decorator(Person))
    

    Implies the same structure as:

    - decorated_person (object)
        - `first_name`
        - `last_name`
        - address
    
  • Type passed into explicitly defined Member Types

    # One or Many (*S*[*T*, string])
    - (*T*)
    - (array[*T*])
    

    And:

    - rel (One or Many(enum, object))
    

    Implies the same structure as:

    - rel (enum)
        - (string)
        - (object)
        - array[object]
    

5.4 Member Type Precedence

Implementers of tooling for MSON structures SHOULD use an inheritance precedence such that the last redundant Member Type specified in a list at the same indentation level appends or overrides a previously defined Member Type.

# Person (object, fixed)
- `first_name`
- `last_name`
- address (object)
  • Add/Override Attributes

    Example 1

    - person (Person)
        - `last_name` (optional)
    

    Is literally the same as:

    - person (object)
        - `first_name` (fixed)
        - `last_name` (fixed)
        - address (object, fixed)
        - `last_name` (optional)
    

    Which implies a structure the same as:

    - person (object)
        - `first_name` (fixed)
        - `last_name` (optional)
        - address (object, fixed)
    

    Example 2

    - person (object)
        - `first_name` (optional)
        - Include Person
    

    Is literally the same as:

    - person (object)
        - `first_name` (optional)
        - `first_name` (fixed)
        - `last_name` (fixed)
        - address (object, fixed)
    

    Which implies a structure the same as:

    - person (object)
        - `first_name` (fixed)
        - `last_name` (fixed)
        - address (object, fixed)
    

    Example 3

    - person (object)
        - Include Person
        - `first_name` (optional)
    
    

    Is literally the same as:

    - person (object)
        - `first_name` (fixed)
        - `last_name` (fixed)
        - address (object, fixed)
        - `first_name` (optional)
    

    Implies a structure the same as:

    - person (object)
        - `first_name` (optional)
        - `last_name` (fixed)
        - address (object, fixed)
    
  • Add New Member Types

    - person (Person)
        - citizenship
    

    Implies a structure the same as:

    - person (object, fixed)
        - `first_name`
        - `last_name`
        - address (object)
        - citizenship
    
  • Override Member Types

    - person (object)
        - Include Person
        - address (string)
    

    Is literally the same as:

    - person (object)
        - `first_name` (fixed)
        - `last_name` (fixed)
        - address (object, fixed)
        - address (string)
    

    Implies a structure the same as:

    - person (object)
        - `first_name` (fixed)
        - `last_name` (fixed)
        - address (string)
    

6 Reserved Characters & Keywords

When using following characters or keywords in a Property Name, Literal Value or Type Name the name or literal MUST be escaped in backticks `. Otherwise, a code span MAY be used for any arbitrary formatting and has no specific meaning in an MSON document.

6.1 Characters

:, (,), <, >, {, }, [, ], _, *, -, +, `

6.2 Keywords

Property, Properties, Item, Items, Member, Members, Include, One of, Sample

Note keywords are case-insensitive.

6.3 Additional Keywords

Following keywords are reserved for future use:

Trait, Traits, Parameter, Parameters, Attribute, Attributes, Filter, Validation, Choice, Choices, Enumeration, Enum, Object, Array, Element, Elements, Description