forked from COVESA/vss-tools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
vspec2protobuf.py
executable file
·90 lines (73 loc) · 2.48 KB
/
vspec2protobuf.py
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
#!/usr/bin/env python3
# Copyright (c) 2021 Motius GmbH
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
#
# Convert vspec file to proto
#
import sys
import os
#Add path to main py vspec parser
myDir= os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(myDir, ".."))
import vspec
import getopt
from anytree import RenderTree, PreOrderIter
from vspec.model.vsstree import VSSNode
mapped = {
"uint16": "uint32",
"uint8": "uint32",
"int8": "int32",
"int16": "int32",
"boolean": "bool",
}
def traverse_tree(tree, proto_file):
tree_node: VSSNode
for tree_node in filter(lambda n: n.is_branch(), PreOrderIter(tree)):
proto_file.write(f"message {tree_node.qualified_name('')} {{" + "\n")
print_message_body(tree_node.children, proto_file)
proto_file.write("}\n\n")
def print_message_body(nodes, proto_file):
for i, node in enumerate(nodes, 1):
data_type = node.qualified_name("")
if not node.is_branch():
dt_val = node.datatype.value
data_type = mapped.get(dt_val.strip("[]"), dt_val.strip("[]"))
data_type = ("repeated " if dt_val.endswith("[]") else "") + data_type
proto_file.write(f" {data_type} {node.name} = {i};" + "\n")
def usage():
print(
"""Usage: vspec2protobuf.py [-I include_dir] ... vspec_file output_file
-I include_dir Add include directory to search for included vspec
files. Can be used multiple times.
vspec_file The vehicle specification file to parse.
proto_file The file to output the proto file to.)
"""
)
sys.exit(255)
if __name__ == "__main__":
#
# Check that we have the correct arguments
#
opts, args = getopt.getopt(sys.argv[1:], "I:")
# Always search current directory for include_file
include_dirs = ["."]
for o, a in opts:
if o == "-I":
include_dirs.append(a)
else:
usage()
if len(args) != 2:
usage()
proto_file = open(args[1], "w")
proto_file.write('syntax = "proto3";\n\n')
proto_file.write("package vehicle;\n\n")
try:
tree = vspec.load_tree(args[0], include_dirs)
traverse_tree(tree, proto_file)
except vspec.VSpecError as e:
print("Error: {}".format(e))
exit(255)
proto_file.close()