Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Reverse engineer XSD from MOBILE_API.xml * Add v6.0.0 compatible attributes into XSD * #203 SDL-0234 Proxy Library RPC Generation * Added reverse-engineered [MOBILE_API.xsd](MOBILE_API.xsd) * Moved XML Parser named [InterfaceParser](InterfaceParser) from [InterfaceGenerator of smartdevicelink/sdl_core](smartdevicelink/sdl_core/tools/InterfaceGenerator) * Refactored [InterfaceParser](InterfaceParser) to be more readable by splitting classes into separate files * Refactored [InterfaceParser](InterfaceParser) to be compatible with Python 3.5 * Added README.md with the base XML structure description into [InterfaceParser](InterfaceParser) * Refactored Markdown Generator to use [InterfaceParser](InterfaceParser) and be compatible with Python 3.5 * Update InterfaceParser/README.md * Parser types section added * Table markdown correction * refactoring according to comments in pull/202 * updating markdown_generator to support command line arguments * adding skip/overwrite feature to markdown * delete SDLRPCV1 and JSONRPC parsers * delete SDLRPCV1 and JSONRPC parsers * adding xsd validating * small refactoring as requested in code review * small refactoring as requested in code review * refactoring rpc_base, split it into some helper functions with descriptive method * Update README.md Added Requirements section * added Double string to extracting type * adding args.source_xsd into parse * adding args.source_xsd into parse * rename ArgumentParser description * adding manual handling * minor fixes in markdown_generator * minor fixes in markdown_generator * fix issue with hexvalue renaming * wrap xml.etree.ElementTree.ParseError into parsers.parse_error.ParseError for SDLRPCV2 * wrap XMLSchema exeption * Add until param for enum elements in the MOBILE_API XML schema definintion file * Address review comments * Add reserved keywords * Apply suggestions from code review Co-Authored-By: Joel Fischer <joeljfischer@gmail.com> * Add setFunctionID to reserved keywords * Remove response params from reserved keywords * Add keywords without get/set prefixes Co-authored-by: Vladyslav Mustafin <vmustafin@luxoft.com> Co-authored-by: Kostiantyn Sologubov <ksologubov@luxoft.com> Co-authored-by: Aleksandr Mishchenko <AMishchenko@luxoft.com> Co-authored-by: ShobhitAd <adlakhashobhit@gmail.com> Co-authored-by: Shobhit Adlakha <ShobhitAd@users.noreply.github.com> Co-authored-by: Bilal Alsharifi <bilal.alsharifi@gmail.com> Co-authored-by: Bilal Alsharifi <599206+bilal-alsharifi@users.noreply.github.com> Co-authored-by: Joel Fischer <joeljfischer@gmail.com> Co-authored-by: theresalech <theresa@livio.io> Co-authored-by: Joey Grover <joeygrover@gmail.com>
- Loading branch information
1 parent
c87eb00
commit 53e3dfb
Showing
43 changed files
with
3,039 additions
and
606 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
.idea | ||
*.iml | ||
*venv* | ||
*.pyc | ||
*out | ||
.DS_Store | ||
*htmlcov | ||
*.coverage | ||
*__pycache__ | ||
*.pytest_cache |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
# Requirements | ||
|
||
The parser requires Python 3.5 pre-installed in the system. This is the minimal Python 3 version that has not reached the end-of-life (https://devguide.python.org/devcycle/#end-of-life-branches). | ||
|
||
The parser requires `xmlschema` library in order to provide the required schema validation. Additionally `pylint` and `coverage` libraries are required for unit tests. | ||
|
||
Those libraries are described in `requirements.txt` and should be pre-installed by the command: | ||
```shell script | ||
pip install -r requirements.txt | ||
``` | ||
|
||
# Parser types | ||
Different parser types implemented in Interface Parser for parsing different types of source XML and generating the code in SDL_core project. | ||
|
||
Parser | Source file | ||
------ | ------ | ||
sdlrpcv1 | sdl_core/src/components/interfaces/v4_protocol_v1_2_no_extra.xml | ||
sdlrpcv2 | sdl_core/src/components/interfaces/MOBILE_API.xml | ||
jsonrpc | sdl_core/src/components/interfaces/HMI_API.xml | ||
mobile-policy-types | sdl_core/src/components/interfaces/MOBILE_API.xml | ||
hmi-policy-types | sdl_core/src/components/interfaces/HMI_API.xml | ||
|
||
# `MOBILE_RPC.xml` structure | ||
|
||
## Overview | ||
This document contains the description of the `MOBILE_API.xml` structure in order of preparation specification and transformation rules for Proxy Library RPC Generation. This is not a full XML specification and only elements and attributes required for the code generation are described here. For the full specification see MOBILE_API.xsd. | ||
|
||
## `<interface>` | ||
The root element is the `<interface>`. The `<interface>` contains any number of `<enum>`, `<struct>` and `<function>`. | ||
|
||
Example: | ||
```xml | ||
<interface name="string" version="string" minVersion="string" date="string"> | ||
<!--Zero or more repetitions:--> | ||
<enum/> | ||
<!--Zero or more repetitions:--> | ||
<struct/> | ||
<!--Zero or more repetitions:--> | ||
<function/> | ||
</interface> | ||
``` | ||
|
||
## `<enum>` | ||
The `<enum>` element contains any number of `<element>` that represents a set of possible values. The `<enum>` has a required `"name"` attribute. | ||
|
||
Example: | ||
```xml | ||
<enum deprecated="boolean" internal_scope="string" name="string" platform="string" since="string" until="string"> | ||
<!--Zero or more repetitions:--> | ||
<description>string</description> | ||
<!--Zero or more repetitions:--> | ||
<element hexvalue="string" internal_name="string" name="string" rootscreen="boolean" since="string" value="integer"> | ||
<!--Zero or more repetitions:--> | ||
<description>string</description> | ||
<!--Zero or more repetitions:--> | ||
<warning>string</warning> | ||
</element> | ||
<!--Optional:--> | ||
<history> | ||
<enum/> | ||
</history> | ||
</enum> | ||
``` | ||
SDL has two different enum types: `string` and `integer`. If `"hexvalue"` or `"value"` attribute exists, the enum type is `integer`, otherwise the enum type is `string`. | ||
|
||
The `<element>` has a required `"name"` attribute. For `string` enums, the value of `"name"` attribute will be one of the possible values of the particular `<enum>`. For `integer` enums, the value of `"value"` attribute will be one of the possible values, the `"hexvalue"` is just a hexadecimal representation of the `"value"` attribute, any of them could be used but `"hexvalue"` is preferred if exist. | ||
|
||
Additionally, `<element>` could have an `"internal_name"` attribute. This helper attribute is not used in communication with SDL Core and describes the `<element>` name for SDL libraries. The actual naming of `<element>` in libraries is per the following rationale: If the `<element>` has an `"internal_name"` attribute, all libraries should name the `<element>` based on this attribute. If `"internal_name"` is not specified, the libraries should name the `<element>` based on the `"name"` attribute. There are possible additional rules, e.g., for `internal_name="SamplingRate_8KHZ"` to cut the leading `<enum>` name, but those rules must be individually specified per each library. | ||
|
||
## `<struct>` | ||
The `<struct>` is a complex data type. The `<struct>` contains any number of `<param>`. The `<struct>` has a required `"name"` attribute. | ||
|
||
Example: | ||
```xml | ||
<struct deprecated="boolean" name="string" since="string" until="string"> | ||
<!--Optional:--> | ||
<history> | ||
<struct/> | ||
</history> | ||
<!--Zero or more repetitions:--> | ||
<description>string</description> | ||
<!--Zero or more repetitions:--> | ||
<param array="boolean" defvalue="integer|decimal|boolean|string" deprecated="boolean" mandatory="boolean" maxlength="integer" maxsize="integer" maxvalue="decimal" minlength="integer" minsize="integer" minvalue="decimal" name="string" since="string" type="string" until="string"> | ||
<!--Zero or more repetitions:--> | ||
<description>string</description> | ||
<!--Optional:--> | ||
<history> | ||
<param/> | ||
</history> | ||
</param> | ||
</struct> | ||
``` | ||
Each `<param>` requires `"name"`, `"type"` and `"mandatory"` attributes. The `"type"` attribute value should be one of `"Boolean"`, `"Float"`, `"Integer"`, `"String"` or the one of `<enum>`, `<struct>` name specified in the Mobile API. | ||
|
||
Additionally, `<param>` could have `"array"` attribute to represent an array of values or objects of the described type. Attributes `"maxsize"` and `"minsize"` provide additional restrictions to an array. | ||
|
||
Numeric types can be restricted using `"minvalue"` and `"maxvalue"`. The `"defvalue"` attribute contains default value with different type, depends on `<param>` type, note: this attribute is not allowed for `<struct>` type. | ||
|
||
## `<function>` | ||
The `<function>` element represents a specific RPC and message type of the Mobile API. It contains any number of `<param>`. The `<function>` has a required `"name"`, `"messagetype"`, `"functionID"` attributes. | ||
|
||
Example: | ||
```xml | ||
|
||
<function deprecated="boolean" functionID="string" messagetype="string" name="string" since="string" until="string"> | ||
<!--Optional:--> | ||
<history> | ||
<function/> | ||
</history> | ||
<!--Zero or more repetitions:--> | ||
<description>string</description> | ||
<!--Zero or more repetitions:--> | ||
<param array="boolean" defvalue="integer|decimal|boolean|string" deprecated="boolean" mandatory="boolean" maxlength="integer" maxsize="integer" maxvalue="decimal" minlength="integer" minsize="integer" minvalue="decimal" name="string" platform="string" since="string" type="string" until="string"> | ||
<!--Zero or more repetitions:--> | ||
<description>string</description> | ||
<!--Optional:--> | ||
<history> | ||
<param/> | ||
</history> | ||
<!--Zero or more repetitions:--> | ||
<todo>string</todo> | ||
<!--Zero or more repetitions:--> | ||
<element name="string"> | ||
<!--Optional:--> | ||
<description>string</description> | ||
</element> | ||
</param> | ||
</function> | ||
``` | ||
The `"messagetype"` attribute value should be one of `"request"`, `"response"`, or `"notification"`. The `"functionID"` attribute value should match the `"name`" attribute of one `<element>` of the `<enum>` named `"FunctionID"`. | ||
|
||
Just like `<param>` elements in `<struct>`, each `<param>` has required `"name"`, `"type"`, and `"mandatory"` attributes. The `"type"` attribute value should be one of `"Boolean"`, `"Float"`, `"Integer"`, `"String"` or the one of `<enum>`, `<struct>` name exists in XML. | ||
|
||
Additionally, `<param>` could have `"array"` attribute which means the param represents array of described types. Attributes `"max*"` and `"min*"` provide additional restrictions. The `"defvalue"` attribute contains default value with different type, depends on `<param>` type, note: this attribute is not allowed for `<struct>` type. | ||
|
||
The `<param>` with `<enum>` type could additionally contain any number of `<element>` (but not more than the number of `<element>` in the related `<enum>`). The `<element>` has required `"name"` attribute and this should match the one of `<element>`'s `"name"` or `"internal_name"` attribute in the related `<enum>`. This restricts the represented value by the defined list of `<element>` instead of the full list of `<element>` in the related `<enum>`. |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
"""Array type. | ||
""" | ||
|
||
|
||
class Array: | ||
"""Array type. | ||
:param min_size: minimum array size | ||
:param max_size: maximum array size | ||
:param element_type: type of array element | ||
""" | ||
|
||
def __init__(self, min_size=None, max_size=None, element_type=None): | ||
self.min_size = min_size | ||
self.max_size = max_size | ||
self.element_type = element_type |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
"""Boolean type. | ||
""" | ||
|
||
|
||
class Boolean: | ||
"""Boolean type. | ||
:param default_value: default value | ||
""" | ||
|
||
def __init__(self, default_value=None): | ||
self.default_value = default_value |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
"""Enumeration. | ||
""" | ||
from collections import OrderedDict | ||
|
||
from model.interface_item_base import InterfaceItemBase | ||
|
||
|
||
class Enum(InterfaceItemBase): | ||
"""Enumeration. | ||
:param name: item name | ||
:param description: list of string description elements | ||
:param design_description: list of string design description elements | ||
:param issues: list of issues | ||
:param todos: list of string todo elements | ||
:param platform: optional platform (string or None) | ||
:param scope: optional scope: internal, partner or none (none by default, means public) | ||
:param since: string that defines the rpc spec version an element was introduced | ||
:param until: string that defines the rpc spec version an element was removed, deprecated, or changed | ||
:param deprecated: boolean that defines if an element is planned to be removed in a future release | ||
:param removed: boolean that defines if an element was removed from the api | ||
:param history: array of api element signature changes | ||
:param internal_scope: optional internal scope | ||
:param elements: dictionary of enumeration elements (instances of EnumElement class) | ||
""" | ||
|
||
def __init__(self, name, description=None, design_description=None, | ||
issues=None, todos=None, platform=None, internal_scope=None, | ||
elements=None, scope=None, since=None, until=None, | ||
deprecated=None, removed=None, history=None): | ||
super(Enum, self).__init__( | ||
name, description=description, design_description=design_description, | ||
issues=issues, todos=todos, platform=platform, scope=scope, | ||
since=since, until=until, deprecated=deprecated, removed=removed, history=history) | ||
|
||
self.internal_scope = internal_scope | ||
self.elements = elements if elements is not None else OrderedDict() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
"""Element of enumeration. | ||
""" | ||
|
||
from model.interface_item_base import InterfaceItemBase | ||
|
||
|
||
class EnumElement(InterfaceItemBase): | ||
"""Element of enumeration. | ||
:param name: item name | ||
:param description: list of string description elements | ||
:param design_description: list of string design description elements | ||
:param issues: list of issues | ||
:param todos: list of string todo elements | ||
:param platform: optional platform (string or None) | ||
:param since: string that defines the rpc spec version an element was introduced | ||
:param until: string that defines the rpc spec version an element was removed, deprecated, or changed | ||
:param deprecated: boolean that defines if an element is planned to be removed in a future release | ||
:param removed: boolean that defines if an element was removed from the api | ||
:param history: array of api element signature changes | ||
:param internal_name: internal name of an element must be used by a | ||
generator if it is provided (not None) | ||
:param value: optional element value | ||
:param hex_value: optional element hex value | ||
""" | ||
|
||
def __init__(self, name, description=None, design_description=None, | ||
issues=None, todos=None, platform=None, internal_name=None, | ||
value=None, hex_value=None, since=None, until=None, | ||
deprecated=None, removed=None, history=None): | ||
super(EnumElement, self).__init__( | ||
name, description=description, design_description=design_description, | ||
issues=issues, todos=todos, platform=platform, since=since, | ||
until=until, deprecated=deprecated, removed=removed, history=history) | ||
|
||
self.internal_name = internal_name | ||
self.value = value | ||
self.hex_value = hex_value | ||
|
||
@property | ||
def primary_name(self): | ||
"""Primary name of the EnumElement. | ||
Return the 'internal_name' property if presented or 'name' property | ||
otherwise. | ||
""" | ||
return self.name if self.internal_name is None else self.internal_name |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
"""Enumeration subset. | ||
""" | ||
|
||
from model.interface_item_base import InterfaceItemBase | ||
|
||
|
||
class EnumSubset(InterfaceItemBase): | ||
"""Enumeration subset. | ||
:param name: item name | ||
:param description: list of string description elements | ||
:param design_description: list of string design description elements | ||
:param issues: list of issues | ||
:param todos: list of string todo elements | ||
:param platform: optional platform (string or None) | ||
:param since: string that defines the rpc spec version an element was introduced | ||
:param until: string that defines the rpc spec version an element was removed, deprecated, or changed | ||
:param deprecated: boolean that defines if an element is planned to be removed in a future release | ||
:param removed: boolean that defines if an element was removed from the api | ||
:param history: array of api element signature changes | ||
:param enum: enumeration | ||
:param allowed_elements: dictionary of elements of enumeration | ||
which are allowed in this subset | ||
""" | ||
|
||
def __init__(self, name, enum, description=None, design_description=None, | ||
issues=None, todos=None, platform=None, allowed_elements=None, | ||
since=None, until=None, deprecated=None, removed=None, history=None): | ||
super(EnumSubset, self).__init__( | ||
name, description=description, design_description=design_description, | ||
issues=issues, todos=todos, platform=platform, | ||
since=since, until=until, deprecated=deprecated, removed=removed, history=history) | ||
|
||
self.enum = enum | ||
self.allowed_elements = allowed_elements if allowed_elements is not None else {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
"""Floating-point type. | ||
""" | ||
|
||
|
||
class Float: | ||
"""Floating-point type. | ||
:param min_value: minimum allowed value | ||
:param max_value: maximum allowed value | ||
:param default_value: default value | ||
""" | ||
|
||
def __init__(self, min_value=None, max_value=None, default_value=None): | ||
self.min_value = min_value | ||
self.max_value = max_value | ||
self.default_value = default_value |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
"""Function. | ||
""" | ||
|
||
from collections import OrderedDict | ||
|
||
from model.interface_item_base import InterfaceItemBase | ||
|
||
|
||
class Function(InterfaceItemBase): | ||
"""Function. | ||
:param name: item name | ||
:param description: list of string description elements | ||
:param design_description: list of string design description elements | ||
:param issues: list of issues | ||
:param todos: list of string todo elements | ||
:param platform: optional platform (string or None) | ||
:param scope: optional scope: internal, partner or none (none by default, means public). | ||
Note exists only in the hmi_api.xml | ||
:param since: string that defines the rpc spec version an element was introduced | ||
:param until: string that defines the rpc spec version an element was removed, deprecated, or changed | ||
:param deprecated: boolean that defines if an element is planned to be removed in a future release | ||
:param removed: boolean that defines if an element was removed from the api | ||
:param history: array of api element signature changes | ||
:param function_id: function identifier (EnumElement from Enum "FunctionID") | ||
:param message_type: message type (EnumElement from Enum "messageType") | ||
:param params: dictionary of function parameters (instances of FunctionParam class) | ||
""" | ||
|
||
def __init__(self, name, function_id, message_type, description=None, | ||
design_description=None, issues=None, todos=None, | ||
platform=None, params=None, scope=None, since=None, until=None, deprecated=None, removed=None, | ||
history=None): | ||
super(Function, self).__init__( | ||
name, description=description, design_description=design_description, | ||
issues=issues, todos=todos, platform=platform, scope=scope, | ||
since=since, until=until, deprecated=deprecated, removed=removed, history=history) | ||
|
||
self.function_id = function_id | ||
self.message_type = message_type | ||
self.params = params if params is not None else OrderedDict() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
"""Integer type. | ||
""" | ||
|
||
|
||
class Integer: | ||
"""Integer type. | ||
:param min_value: minimum allowed value | ||
:param max_value: maximum allowed value | ||
:param default_value: default value | ||
""" | ||
|
||
def __init__(self, min_value=None, max_value=None, default_value=None): | ||
self.min_value = min_value | ||
self.max_value = max_value | ||
self.default_value = default_value |
Oops, something went wrong.