<?xml version='1.0'?>
<!DOCTYPE rfc SYSTEM 'rfc2629.dtd'>
<rfc ipr="trust200902" docName="draft-hallambaker-protogen-01">
<front>
<title abbrev="Protocol Specification Tool">Protocol Specification Tool</title>
<author fullname="Phillip Hallam-Baker" initials="P. M." surname="Hallam-Baker">
<organization>Comodo Group Inc.</organization>
<address>
<email>philliph@comodo.com</email>
</address>
</author>
<date day="6" month="July" year="2015"/>
<area>General</area>
<workgroup/>
<keyword>JSON</keyword>
<abstract>
<t>The syntax for the PROTOGEN protocol specification tool is described and the use of the tool to generate protocol specifications, prototype and production implementations. While the primary focus of PROTOGEN is to develop protocols using JSON message syntax, the PROTOGEN framework has been successfully applied to generate prototypes using ASN.1, TLS, XML and RFC822 style syntax. </t>
</abstract>
</front>
<middle>
<section title="Introduction" anchor="Section_1">
<t>The use of schemas to describe communication protocols is well established and plays a central role in the development of ASN.1 and XML based protocols. No such tools are currently widely used for writing JSON based protocols. </t>
<t>It is the view of the author that the first, last and only purpose of a protocol schema language is to enable the use of tools to support the development effort. A schema language that delays rather than advances the development of correct code and consistent documentation has become a liabilty, not an enabler. </t>
<section title="Previous work" anchor="Section_1_1">
<t>One of the main reasons for the lack of such a tool has been the widespread concern as to the complexity of traditional schema tools and in particular the tendency of such tools to impose a complex data model on simple problems.</t>
<t>One major difference in the design of the Protogen schema language to its predecessors is that it does not attempt to support every feature of the JSON data model. Protogen is designed to allow programmers to design and implement network service protocols quickly using widely used programming languages such as C, C# and Java. JSON features that do not map conveniently to the majority of widely used languages are best ignored. </t>
<t>The XML Schema language is particularly obtuse presenting a two level type system in which element definitions provide typing for data and element types provide a type system for elements. At least three different inheritance mechanisms are supported. </t>
<t>The ASN.1 schema language introduces a distinction between lists and sets that is entirely frivolous in a serialization format and gratuitous distinctions between implicit and explict tagging.</t>
<t>The lesson to be drawn from these abominations is clear: The primary purpose of a schema language should be to allow the programmer to forget and ignore the wireline representation of protocol messages. Features that allow fine tuning of the wireline representation should be avoided.</t>
<t>While the notion of validating input data against a schema prior to passing data to an application is superficially attractive, schema constraints are rarely sufficient for this purpose. Thus applied to protocol design, schema validation rarely provides a meaningful benefit over checking that an encoding is well formed. </t>
</section>
<section title="Schema driven documentation" anchor="Section_1_2">
</section>
<section title="Schema driven code generation" anchor="Section_1_3">
</section>
<section title="Application Examples" anchor="Section_1_4">
<t>The following is based on an example from [RFC4627]. </t>
<figure>
<artwork>
<![CDATA[[
       {
          "precision": "zip",
          "Latitude":  37.7668,
          "Longitude": -122.3959,
          "Address":   "",
          "City":      "SAN FRANCISCO",
          "State":     "CA",
          "Zip":       "94107",
          "Country":   "US"
       },
       {
          "precision": "zip",
          "Latitude":  37.371991,
          "Longitude": -122.026020,
          "Address":   "",
          "City":      "SUNNYVALE",
          "State":     "CA",
          "Zip":       "94085",
          "Country":   "US"
       }
   ]]]></artwork>
</figure>
<t>The corresponding Protogen schema is: </t>
<figure>
<artwork>
<![CDATA[    	Structure SiteList
		Description
			|A list of sites
		Struct Site Sites
			Multiple

	Structure Site
		Description
			|A site location
		String		Country
			Description
				|ISO ALPHA-2 Country Code.
		String		precision
		Decimal		Latitude
		Decimal		Longitude
		String		Address
		String		City
		String		State
		String		Zip]]></artwork>
</figure>
<t>For the sake of example, the description of the site structure entries is elided. While Protogen does not require description elements to be provided to produce code, descriptions are of course essential if useful documentation is to be generated.</t>
<t>Protogen is built using the Goedel code metasynthesizer which attempts to eliminate all unnecessary clutter from the code specification to minimize error. By default, indentation and the off-side rule are used to denote block structure following the approach used in occam and Python. Punctuation characters are only used to delimit strings ("), text blocks (|) and comments (!). </t>
<t>Note that the Latitude and Longitude are specified using the type Decimal rather than Float. This allows an implementation to avoid the loss of precision that inevitably occurs converting between a binary floating point representation such as IEEE 754 binary 64 and the decimal encoding used in JSON.</t>
<t>The example fragment is sufficient to describe a data structure and generate methods for JSON serialization and deserializtion. It is not however sufficient to generate a useful implementation of a Web service or client access library. to do this we must define a protocol with services, transactions and messages defined as follows:</t>
<t><list style="hanging">
<t hangText="Protocol">A collection of related services.</t>
<t hangText="Service">A set of transactions with a distinct DNS SRV prefix and HTTP well known service label.</t>
<t hangText="Transaction">A defined sequence of protocol messages supported by a service. Currently only request-response design pattern is supported.</t>
<t hangText="Message">A JSON document that corresponds to a request or response.</t>
</list></t>
<t>To build a service using the Site structure, we prepend add following declaration: </t>
<figure>
<artwork>
<![CDATA[Protocol Sitefinder STFND

	Service Finder "_siteFinder._wks" "SiteFinder" Request Response
		Description
			|Find sites for new donut stores.

	Message Request
		Struct Site WhereIAm
	Message Response
		Struct Site WhereAreDonuts
			Multiple]]></artwork>
</figure>
<t>We can now run Protogen to generate any of the following:</t>
<t><list style="symbols">
<t>Documentation in HTML</t>
<t>Documentation in RFC2XML schema</t>
<t>A C# client access library.</t>
<t>A C# stub service library.</t>
<t>A C header file describing corresponding C structures and data tables to enable serialization/deserialization.</t>
</list></t>
<t>Support for partial classes makes C# a particularly attractive target language for code generation as it allows classes produced by generated code to be conveniently extended. Support for other modern languages aligned with the Java/.NET data model requires only straightforward modification of the code generator.</t>
<t>While the C# generator is optimized for development of protocols and production code, the generator for C is intended for developing production code after the protocol architecture is largely static. The generator is intentionally biased towards flexibility rather than functionality since a modern programer using C is most likely to be doing so to build on a legacy code base. The ability to easily adapt the output of the generator to the existing coding style(s) is likely to be more highly valued than minimizing implementation effort.</t>
</section>
</section>
<section title="Protocol Specification" anchor="Section_2">
<section title="Protocol" anchor="Section_2_1">
<t>Top level specification of a protocol. The Protocol element contains two attributes and a list of entries as follows:</t>
<t><list style="hanging">
<t hangText="Namespace">Namespace identifier for use in .NET and Java style programming environments</t>
<t hangText="Prefix">Prefix for use in C style programming environments.</t>
<t hangText="Entries">A list of [Service Transaction Message Structure Description Using] elements</t>
</list></t>
</section>
<section title="Description" anchor="Section_2_2">
<t>Describes the parent element. Multiple description elements may be specified in which case the first SHOULD be a standalone short description. The description element has one attribute:</t>
<t><list style="hanging">
<t hangText="Text">Text field data identified by use of the | prefix.</t>
</list></t>
</section>
<section title="Service" anchor="Section_2_3">
<t>A service is a named set of transactions within a protocol namespace. </t>
<t>At present, due to an implementation limitation, all request and response messages used in a service MUST inherit from a single message type. This is bogus and should be fixed.</t>
<t>The service element has the following attributes:</t>
<t><list style="hanging">
<t hangText="ID">The code identifier of the service</t>
<t hangText="Discovery">The DNS service prefix of the service for use in SRV, NAPTR style discovery</t>
<t hangText="WellKnown">The HTTP well known service prefix.</t>
<t hangText="Request">The parent class for all request messages supported by the service.</t>
<t hangText="Response">The parent class for all response messages supported by the service.</t>
<t hangText="Entries">A list of [Description Status] entries</t>
</list></t>
</section>
<section title="Transaction" anchor="Section_2_4">
<t>Specifies a Request-Response transaction supported by a specified service.</t>
<t>At present transactions are specific to a service which is kind of bogus if multiple services were defined.</t>
<t>The Transaction element has the following attributes:</t>
<t><list style="hanging">
<t hangText="Service">The identifier of the service</t>
<t hangText="ID">The identifier of the transaction</t>
<t hangText="Request">The request message which must not be an abstract type.</t>
<t hangText="Response">The response message returned for normal completion. An abstract type may be specified.</t>
<t hangText="Entries">A list of [Description Status] entries</t>
</list></t>
</section>
<section title="Message" anchor="Section_2_5">
<t>Specifies a protocol message. This is almost the same as a structure except that the name of a request message is a command to a server and the name of a response message identifies a response.</t>
<t><list style="hanging">
<t hangText="Id">The message identifier</t>
<t hangText="Entries">A list of [Description Abstract Inherits Boolean Integer Binary Float Label Name String URI DateTime Struct Enum Status Authentication Format Decimal] entries</t>
</list></t>
</section>
<section title="Structure" anchor="Section_2_6">
</section>
<section title="Status" anchor="Section_2_7">
<t>This feature is not yet implemented, the idea being that status codes should be represented at both the HTTP layer and JSON layer so that appropriate handling can be specified at either.</t>
</section>
<section title="Using" anchor="Section_2_8">
<t>Specifies a message or structure defined in another schema.</t>
</section>
</section>
<section title="Data Types" anchor="Section_3">
<t>Protogen recognizes ten intrinsic data types. While this is considerably larger than the three intrinsic types supported in JSON, the additional expressive power allows the tools to do more work for the programmer. For example, distinguishing strings that represent date-time values from other strings allows the tool to perform the work of encoding/decoding these values. </t>
<t>The following table sumarizes the Protogen schema types and their (default) corresponding C#/C equivalents.</t>
<texttable >
<ttcol>Schema</ttcol>
<ttcol>JSON</ttcol>
<ttcol>C#</ttcol>
<ttcol>C</ttcol>
<c>Boolean</c>
<c>true | false</c>
<c>bool</c>
<c>bool</c>
<c>Float</c>
<c>number</c>
<c>double</c>
<c>double</c>
<c>Decimal</c>
<c>number</c>
<c>Int64</c>
<c>long long</c>
<c>Integer</c>
<c>number</c>
<c>Int64</c>
<c>int</c>
<c>Binary</c>
<c>string (base64 encoded)</c>
<c>byte[] Data</c>
<c>BinaryType</c>
<c>Label</c>
<c>string</c>
<c>string</c>
<c>StringType</c>
<c>Name</c>
<c>string</c>
<c>string</c>
<c>StringType</c>
<c>String</c>
<c>string</c>
<c>string</c>
<c>StringType</c>
<c>URI</c>
<c>string</c>
<c>string</c>
<c>StringType</c>
<c>DateTime</c>
<c>string</c>
<c>DateTime</c>
<c>struct tm</c>
</texttable >
<t> Every data type supports the following options:</t>
<t><list style="hanging">
<t hangText="Required">The minimum number of occurrences is 1.</t>
<t hangText="Multiple">Multiple values may be specified.</t>
<t hangText="Description">Description of the element for use in code generation.</t>
<t hangText="Deaful">Default value for the element if unspecified.</t>
</list></t>
<t>While the Protogen schema definition does include additional options for some data types (e.g. LengthBits, LengthFixed) these are only used in the TLS encoding generator and are ignored when JSON encoding is being used.</t>
<section title="Abstract" anchor="Section_3_1">
<t>Messages and structures may be marked Abstract which means that they may be used as base classes for inheritance from other messages or structures but cannot appear on the wire.</t>
</section>
<section title="Inherits" anchor="Section_3_2">
<t>Specifies that a message or structure inherits from another message or structure.</t>
<t>Note that inheritance relationships are represented in the generated code for languages that support inheritance (e.g. C#) and flattened out in languages that do not (e.g. C). </t>
</section>
<section title="Null Values" anchor="Section_3_3">
<t>No distinction is made between a value that is not present and a value that is present with the value null. Thus the following JSON documents are considered to specify the same object.</t>
<figure>
<artwork>
<![CDATA[{ "Value": 1 }]]></artwork>
</figure>
<figure>
<artwork>
<![CDATA[{ "Value": 1,
  "Optional": null }]]></artwork>
</figure>
<t>An entry that has the 'Required' option set MUST always be specified even if the value is null. </t>
</section>
<section title="Lists" anchor="Section_3_4">
<t>No distinction is made between a list that is not present, a list with the null value and an empty list. Thus the following encodings desribe the same object:</t>
<figure>
<artwork>
<![CDATA[{ "Value": 1 }]]></artwork>
</figure>
<figure>
<artwork>
<![CDATA[{ "Value": 1,
  "List": null }]]></artwork>
</figure>
<figure>
<artwork>
<![CDATA[{ "Value": 1,
  "List": [] }]]></artwork>
</figure>
<t>To simplify scripting language implementation an entry that has the 'Multiple' option MUST be encoded as a list. </t>
</section>
<section title="Decimal" anchor="Section_3_5">
<t>The decimal encoding provides an alternative to use of floating point to represent decimal fractions.</t>
<t>Since 10 is not a power of 2, conversion between decimal and binary fractions is inexact and using Real32 or Real64 values for this purpose introduces an unnecessary loss of precision. </t>
<t>Since modern programming languages lack support for a Decimal intrinsic type, this is implemented by mapping the datum to a 64 bit integer with an offset of 1,000,000,000. This approach allows for numbers up to 9,223,372 to be represented with nine digit precision.</t>
</section>
<section title="DateTime" anchor="Section_3_6">
<t>Date Time Values are encoded as strings in IETF format.</t>
</section>
<section title="Binary" anchor="Section_3_7">
<t>Binary values are encoded using BASE64URL encoding.</t>
</section>
</section>
<section title="Further Work" anchor="Section_4">
</section>
<section title="Acnowledgements" anchor="Section_5">
</section>
</middle>
<back>
<references title="Normative References">
<reference anchor="RFC4627">
<front>
<title>The application/json Media Type for JavaScript Object Notation (JSON)</title>
<author fullname="D. Crockford" initials="D." surname="Crockford">
<organization/>
<address>
</address>
</author>
<date month="July" year="2006"/>
</front>
<seriesInfo name="RFC" value="4627"/>
<format type="TXT" target="http://www.rfc-editor.org/rfc/rfc4627.txt" octets="16319"/>
</reference>
</references>
</back>
</rfc>
