summaryrefslogtreecommitdiff
path: root/tools/InterfaceGenerator/Generator.py
blob: 905b0754b33875f44f63fb2153a1663b27b9a1c5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
"""
Generator application that generates c++ interfaces code from xml description

usage: Generator.py [-h] --parser-type {sdlrpcv2}
                    source-xml namespace output-dir

SmartSchema interface generator

positional arguments:
  source-xml
  namespace
  output-dir

optional arguments:
  -h, --help            show this help message and exit
  --parser-type {sdlrpcv2}
"""

import os.path
import argparse
import errno
import sys

import generator.parsers.SDLRPCV1
import generator.parsers.SDLRPCV2
import generator.parsers.JSONRPC
import generator.generators.SmartFactorySDLRPC
import generator.generators.SmartFactoryJSONRPC
import generator.generators.PolicyTypes
import MsgVersionGenerate

from generator.parsers.RPCBase import ParseError
from generator.generators.SmartFactoryBase import GenerateError

SUPPORTED_FORMATS = {
    "sdlrpcv1": (generator.parsers.SDLRPCV1.Parser,
                 generator.generators.SmartFactorySDLRPC.CodeGenerator),
    "sdlrpcv2": (generator.parsers.SDLRPCV2.Parser,
                 generator.generators.SmartFactorySDLRPC.CodeGenerator),
    "jsonrpc": (generator.parsers.JSONRPC.Parser,
                generator.generators.SmartFactoryJSONRPC.CodeGenerator),
    "mobile-policy-types": (generator.parsers.SDLRPCV2.Parser,
                generator.generators.PolicyTypes.CodeGenerator),
    "hmi-policy-types": (generator.parsers.JSONRPC.Parser,
                generator.generators.PolicyTypes.CodeGenerator)
}


def _create_parser():
    """Create parser for parsing command-line arguments.

    Returns an instance of argparse.ArgumentParser

    """

    parser = argparse.ArgumentParser(
        description="SmartSchema interface generator"
    )
    parser.add_argument("source-xml")
    parser.add_argument("namespace")
    parser.add_argument("output-dir")
    parser.add_argument("--parser-type",
                        choices=SUPPORTED_FORMATS.keys(),
                        required=True)
    return parser


def _handle_fatal_error(error):
    """Handle fatal error during parsing or code generation.

    Keyword arguments:
    error -- base exception to handle.

    """

    print(error.message)
    print
    sys.exit(errno.EINVAL)

def main():
    """Main function of the generator that does actual work."""

    args = vars(_create_parser().parse_args())

    src_xml = args["source-xml"]
    src_xml_name = os.path.splitext(os.path.basename(src_xml))[0]
    namespace = args["namespace"]
    output_dir = args["output-dir"]
    parser_type = args["parser_type"]

    print("""
Generating interface source code with following parameters:
    Source xml      : {0}
    Namespace       : {1}
    Output directory: {2}
    Parser type     : {3}
""".format(src_xml, namespace, output_dir, parser_type))

    # Select required parser and code generator
    parser = SUPPORTED_FORMATS[parser_type][0]()
    code_generator = SUPPORTED_FORMATS[parser_type][1]()

    # Convert incoming xml to internal model
    try:
        interface = parser.parse(args["source-xml"])
    except ParseError as error:
        _handle_fatal_error(error)

    # Parse sdl version from MOBILE_API.xml and create source file with this version
    if src_xml_name == "MOBILE_API":
        try:
            MsgVersionGenerate.generate_msg_version(src_xml, output_dir)
        except ParseError as error:
            _handle_fatal_error(error)

    # Generate SmartFactory source code from internal model
    try:
        code_generator.generate(interface,
                                src_xml_name,
                                namespace,
                                output_dir)
    except GenerateError as error:
        _handle_fatal_error(error)

    print("Done.")

if __name__ == '__main__':
    main()