.. _conventions: ==================== Coding Conventions ==================== This page summarizes the coding conventions used for |project|. Generally, :term:`data types ` are described using the `Google Protocol Buffers`_ IDL syntax and hence the proposed conventions for this language apply. They can be found in the `Google Protocol Buffers Style Guide `_. Apart from the general conventions we apply the following ones: .. note:: The source code is continuously checked against these conventions using the CI server. Results of the checks can be found at: https://ci.cor-lab.org/view/rst/job/rst-trunk-static-analysis/ Naming ====== * Do not include a description of a particular communication pattern in the name of a :term:`data type`. For example, if you currently send events containing images, your :term:`data type` must not be called ``ImageEvent``, but ``Image``, as the name ``Image`` would also be suitable for other patterns like RPC communication. * The `Google Protocol Buffers`_ option ``java_outer_class_name`` has to specified and its value has to be of the form :samp:`{TYPE-NAME}Type`. For example, the correct value for ``Image`` is ``ImageType``. Directory and File Layout ========================= * The directory (relative to the ``proto/{stable,sandbox}`` directory in the project root) in which the proto-file resides must match the package name with all "."s replaced with "/"s. * The filename must match the name of the "primary" message definition (with ".proto" appended). * There should only be one "primary" message definition in each proto-file. * Groups of related messages should reside in individual files and refer to each other using the ``import`` directive. * Directory names are all lowercase and without word separations, e.g. ``imageprocessing``. * ``import``\ s are always performed using absolute paths starting from the ``rst`` package, e.g. ``import "rst/vision/Image.proto";``. Rationale --------- * Facilitate easy documentation and reuse via ``import``. * :term:`Data type` definitions can be treated as resources with unique URLs in e.g. a repository browser. Example ------- In case you define a :term:`data type` named ``MyData`` which logically belongs to the ``foo`` package, the containing file has to contain the package declaration ``package rst.foo;`` in the first line and must reside in the directory ``proto/{stable,sandbox}/rst/foo`` with the name :file:`MyData.proto`. File Content Structure ====================== Each file is constructed as follows: #. ``package`` declaration on first line #. ``import`` statement(s) #. ``option`` statement(s) #. Message definition(s) .. _conventions-documentation-strings: Documentation Strings ===================== All :term:`data types ` should be documented according to the convention described in the following paragraphs to ensure understandability and reusability. This issue is particularly important for data type definitions due to the fact that even small details regarding the interpretation of the respective definitions can break compatibility between programs using the data types. Furthermore, these conventions in combination with a specific markup syntax enable the automated extraction and processing of the documentation strings and thus the generation of the :ref:`data-types` section of this manual. Each of the following elements of message :term:`data type` definitions should have a documentation string: * The top-level ``message`` * Nested ``messages``\ s and ``enum``\ s * Message fields and enum values Documentation String Syntax --------------------------- Documentation strings use the "Javadoc comment style" (i.e. ``/**`` at the beginning of the first line, ``*`` for following lines and ``*/`` for the final line). The first sentence should give a short summary of the message or field. Detailed explanations should follow in further sentences or paragraphs (after a blank line). Documentation comments can contain certain markup elements of the form: .. parsed-literal:: @\ :samp:`{NAME}` :samp:`{ARGUMENT 1}` :samp:`{ARGUMENT 2}` … for example .. code-block:: protobuf /** * @author Joe User */ The number and interpretation of arguments depend on :samp:`{NAME}`\ . The following markup elements are currently supported: * :samp:`@author {FIRSTNAME} [{LASTNAME} [<{EMAIL}>]]` Indicate the author of the current message definition. * :samp:`@ref {NAME}` Insert a link to the to the message or field named :samp:`{NAME}` which can be a dotted name. * :samp:`@see {NAME} [{TITLE} [{SUBTITLE}]]` Insert a "see also" link to the documentation item named :samp:`{NAME}`. The optional :samp:`{TITLE}` and :samp:`{SUBTITLE}` parameters control the title and subtitle of the link respectively. * :samp:`@todo "{TEXT}"` Insert a "TODO" indicator containing :samp:`{TEXT}`. Example .. code-block:: protobuf /** * An uncompressed image with a certain pixel format, color and depth. * * The binary intensity data is contained in the @ref .data field. * * Suggested interpretation of RSB timestamps: * * create * * Image grab time * * @todo "to be more precisely defined. e.g. what does this mean * for rolling shutter cameras?" * * @author Johannes Wienke */ message Image { // … } Best Practices for Documentation Strings ---------------------------------------- Ensure that the following questions are answered: * ``repeated`` fields * Is an empty collection allowed? * Is the order of elements significant? If so, what is the meaning of a particular order? * Are there any special values? For example, if the value -1 of an integer field has a special meaning, please describe this fact. * Similarly, do certain combinations of values have special interpretations? * Does the type in question involve coordinate systems or other kinds of context? Unit and Constraint Annotations =============================== In addition to :ref:`documentation strings `, message and field definitions can be annotated with certain kinds of machine-readable meta-data, currently constraints and units. The general syntax for such annotations is: .. parsed-literal:: /** \* :samp:`{DOCUMENTATION}` \*/ // @\ :samp:`{ANNOTATION_1}`\ (:samp:`{PARAMETERS_1}`) // @\ :samp:`{ANNOTATION_2}`\ (:samp:`{PARAMETERS_2}`) ⋮ message … That is, annotations also use comment syntax, but are separate from the documentation comments. Constraint Annotations ---------------------- .. parsed-literal:: // @constraint(:samp:`{EXPRESSION}`) Applicable to message and field definitions. :samp:`{EXPRESSION}` describes the constraint by referring to the ``value`` variable and potentially to other fields of the same messages. Existing type definitions contain examples of constraint annotations. Unit Annotations ---------------- .. parsed-literal:: // @unit(:samp:`{UNIT-NAME}`) Applicable to field definitions. Indicates that the value of the field is a quantity with unit :samp:`{UNIT-NAME}`. Existing type definitions contain examples of unit annotations. Indentation and White Spaces ============================ * Indentation is performed exclusively using spaces (not tabs). * Indentations are always multiples of 4 spaces. * There must be no have trailing spaces. * Each file ends with a newline. * File-wide declarations like ``package``, ``import`` or ``option`` statements must not be indented. * All text inside ``message`` and ``enum`` definitions are indented by 4 spaces. * Curly braces are placed on the same lines as the corresponding ``message`` or ``enum`` keywords. The closing curly brace is on a separate line. * All elements are at a maximum separated by one empty line.