annotate Resources/CodeGeneration/stonegentool.py @ 474:38997ceb9bc6 bgo-commands-codegen

Ongoing work on message code generation
author bgo-osimis
date Wed, 13 Feb 2019 20:42:26 +0100
parents 628941d63b8c
children f58fe38c8c04
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
1 import json
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
2 import re
473
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
3 import sys
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
4 from typing import Dict, List, Set
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
5
469
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
6
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
7 """
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
8 1 2 3 4 5 6 7
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
9 12345678901234567890123456789012345678901234567890123456789012345678901234567890
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
10 """
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
11
473
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
12 import json
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
13 import re
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
14
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
15 """A set of utilities to perform JSON operation"""
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
16
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
17 class JsonHelpers:
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
18 @staticmethod
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
19 def removeCommentsFromJsonContent(string):
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
20 """
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
21 remove comments from a JSON file
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
22
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
23 Comments are not allowed in JSON but, i.e., Orthanc configuration files contains C++ like comments that we need to remove before python can parse the file
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
24 """
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
25 string = re.sub(re.compile("/\*.*?\*/", re.DOTALL), "",
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
26 string) # remove all occurance streamed comments (/*COMMENT */) from string
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
27 string = re.sub(re.compile("//.*?\n"), "",
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
28 string) # remove all occurance singleline comments (//COMMENT\n ) from string
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
29 return string
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
30
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
31 @staticmethod
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
32 def loadJsonWithComments(path):
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
33 """
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
34 reads a JSON file that may contain C++ like comments
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
35 """
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
36 with open(path, 'r') as fp:
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
37 fileContent = fp.read()
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
38 fileContent = JsonHelpers.removeCommentsFromJsonContent(fileContent)
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
39 return json.loads(fileContent)
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
40
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
41
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
42 def LoadSchema(filePath : str):
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
43 return JsonHelpers.loadJsonWithComments(filePath)
469
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
44
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
45 # class Type:
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
46 # def __init__(self, canonicalTypeName:str, kind:str):
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
47 # allowedTypeKinds = ["primitive","enum","struct","collection"]
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
48 # """dependent type is the list of canonical types this type depends on.
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
49 # For instance, vector<map<string,int32>> depends on map<string,int32>
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
50 # that, in turn, depends on string and int32 that, in turn, depend on
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
51 # nothing"""
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
52 # self.canonicalTypeName = canonicalTypeName
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
53 # assert(kind in allowedTypeKinds)
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
54
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
55 # def setDependentTypes(self, dependentTypes:List[Type]) -> None:
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
56 # self.dependentTypes = dependentTypes
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
57
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
58 # def getDependentTypes(self) -> List[Type]:
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
59 # return self.dependentTypes
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
60
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
61 def GetCppTypeNameFromCanonical(canonicalTypeName : str) -> str:
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
62 # C++: prefix map vector and string with std::map, std::vector and
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
63 # std::string
469
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
64 # replace int32 by int32_t
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
65 # replace float32 by float
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
66 # replace float64 by double
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
67 retVal : str = canonicalTypeName.replace("map","std::map")
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
68 retVal : str = canonicalTypeName.replace("vector","std::vector")
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
69 retVal : str = canonicalTypeName.replace("int32","int32_t")
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
70 retVal : str = canonicalTypeName.replace("float32","float")
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
71 retVal : str = canonicalTypeName.replace("float64","double")
469
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
72 return retVal
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
73
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
74 def GetTypeScriptTypeNameFromCanonical(canonicalTypeName : str) -> str:
469
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
75 # TS: replace vector with Array and map with Map
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
76 # string remains string
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
77 # replace int32 by number
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
78 # replace float32 by number
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
79 # replace float64 by number
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
80 retVal : str = canonicalTypeName.replace("map","Map")
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
81 retVal : str = canonicalTypeName.replace("vector","Array")
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
82 retVal : str = canonicalTypeName.replace("int32","number")
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
83 retVal : str = canonicalTypeName.replace("float32","number")
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
84 retVal : str = canonicalTypeName.replace("float64","number")
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
85 retVal : str = canonicalTypeName.replace("bool","boolean")
469
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
86 return retVal
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
87
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
88 # class Schema:
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
89 # def __init__(self, root_prefix : str, defined_types : List[Type]):
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
90 # self.rootName : str = root_prefix
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
91 # self.definedTypes : str = defined_types
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
92
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
93 def CheckTypeSchema(definedType : Dict) -> None:
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
94 allowedDefinedTypeKinds = ["enum","struct"]
473
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
95 if not 'name' in definedType:
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
96 raise Exception("type lacks the 'name' key")
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
97 name = definedType['name']
473
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
98 if not 'kind' in definedType:
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
99 raise Exception(f"type {name} lacks the 'kind' key")
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
100 kind = definedType['kind']
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
101 if not (kind in allowedDefinedTypeKinds):
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
102 raise Exception(f"type {name} : kind {kind} is not allowed. " +
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
103 f"It must be one of {allowedDefinedTypeKinds}")
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
104
473
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
105 if not 'fields' in definedType:
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
106 raise Exception("type {name} lacks the 'fields' key")
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
107
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
108 # generic check on all kinds of types
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
109 fields = definedType['fields']
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
110 for field in fields:
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
111 fieldName = field['name']
473
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
112 if not 'name' in field:
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
113 raise Exception("field in type {name} lacks the 'name' key")
469
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
114
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
115 # fields in struct must have types
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
116 if kind == 'struct':
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
117 for field in fields:
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
118 fieldName = field['name']
473
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
119 if not 'type' in field:
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
120 raise Exception(f"field {fieldName} in type {name} "
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
121 + "lacks the 'type' key")
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
122
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
123 def CheckSchemaSchema(schema : Dict) -> None:
473
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
124 if not 'root_name' in schema:
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
125 raise Exception("schema lacks the 'root_name' key")
473
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
126 if not 'types' in schema:
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
127 raise Exception("schema lacks the 'types' key")
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
128 for definedType in schema['types']:
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
129 CheckTypeSchema(definedType)
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
130
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
131 # def CreateAndCacheTypeObject(allTypes : Dict[str,Type], typeDict : Dict) -> None:
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
132 # """This does not set the dependentTypes field"""
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
133 # typeName : str = typeDict['name']
473
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
134 # if typeName in allTypes:
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
135 # raise Exception(f'Type {typeName} is defined more than once!')
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
136 # else:
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
137 # typeObject = Type(typeName, typeDict['kind'])
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
138 # allTypes[typeName] = typeObject
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
139
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
140 def EatToken(sentence : str) -> (str,str):
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
141 """splits "A,B,C" into "A" and "B,C" where A, B and C are type names
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
142 (including templates) like "int32", "TotoTutu", or
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
143 "map<map<int32,vector<string>>,map<string,int32>>" """
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
144
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
145 if sentence.count('<') != sentence.count('>'):
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
146 raise Exception(f"Error in the partial template type list {sentence}."
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
147 + " The number of < and > do not match!")
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
148
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
149 # the template level we're currently in
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
150 templateLevel = 0
473
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
151 for i in range(len(sentence)):
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
152 if (sentence[i] == ",") and (templateLevel == 0):
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
153 return (sentence[0:i],sentence[i+1:])
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
154 elif (sentence[i] == "<"):
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
155 templateLevel += 1
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
156 elif (sentence[i] == ">"):
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
157 templateLevel -= 1
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
158 return (sentence,"")
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
159
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
160 def SplitListOfTypes(typeName : str) -> List[str]:
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
161 """Splits something like
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
162 vector<string>,int32,map<string,map<string,int32>>
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
163 in:
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
164 - vector<string>
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
165 - int32
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
166 map<string,map<string,int32>>
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
167
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
168 This is not possible with a regex so
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
169 """
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
170 stillStuffToEat : bool = True
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
171 tokenList = []
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
172 restOfString = typeName
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
173 while stillStuffToEat:
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
174 firstToken,restOfString = EatToken(restOfString)
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
175 tokenList.append(firstToken)
473
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
176 if restOfString == "":
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
177 stillStuffToEat = False
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
178 return tokenList
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
179
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
180 templateRegex = \
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
181 re.compile(r"([a-zA-Z0-9_]*[a-zA-Z0-9_]*)<([a-zA-Z0-9_,:<>]+)>")
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
182
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
183 def ParseTemplateType(typeName) -> (bool,str,List[str]):
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
184 """ If the type is a template like "SOMETHING<SOME<THING,EL<SE>>>", then
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
185 it returns (true,"SOMETHING","SOME<THING,EL<SE>>")
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
186 otherwise it returns (false,"","")"""
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
187
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
188 # let's remove all whitespace from the type
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
189 # split without argument uses any whitespace string as separator
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
190 # (space, tab, newline, return or formfeed)
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
191 typeName = "".join(typeName.split())
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
192 matches = templateRegex.match(typeName)
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
193 if matches == None:
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
194 return (False,"","")
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
195 else:
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
196 # we need to split with the commas that are outside of the defined types
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
197 # simply splitting at commas won't work
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
198 listOfDependentTypes = SplitListOfTypes(matches.group(2))
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
199 return (True,matches.group(1),listOfDependentTypes)
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
200
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
201 # def GetPrimitiveType(typeName : str) -> Type:
473
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
202 # if typeName in allTypes:
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
203 # return allTypes[typeName]
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
204 # else:
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
205 # primitiveTypes = ['int32', 'float32', 'float64', 'string']
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
206 # if not (typeName in primitiveTypes):
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
207 # raise Exception(f"Type {typeName} is unknown.")
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
208 # typeObject = Type(typeName,'primitive')
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
209 # # there are no dependent types in a primitive type --> Type object
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
210 # # constrution is finished at this point
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
211 # allTypes[typeName] = typeObject
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
212 # return typeObject
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
213
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
214 def ProcessTypeTree(
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
215 ancestors : List[str]
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
216 , genOrderQueue : List[str]
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
217 , structTypes : Dict[str,Dict], typeName : str) -> None:
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
218 if typeName in ancestors:
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
219 raise Exception(f"Cyclic dependency chain found: the last of {ancestors} "
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
220 + f"depends on {typeName} that is already in the list.")
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
221
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
222 if not (typeName in genOrderQueue):
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
223 # if we reach this point, it means the type is NOT a struct or an enum.
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
224 # it is another (non directly user-defined) type that we must parse and
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
225 # create. Let's do it!
474
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
226 (isTemplate,_,dependentTypeNames) = ParseTemplateType(typeName)
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
227 if isTemplate:
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
228 for dependentTypeName in dependentTypeNames:
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
229 # childAncestors = ancestors.copy() NO TEMPLATE ANCESTOR!!!
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
230 # childAncestors.append(typeName)
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
231 ProcessTypeTree(ancestors, genOrderQueue,
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
232 structTypes, dependentTypeName)
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
233 else:
473
628941d63b8c Ongoing work. Parsing tests work
bgo-osimis
parents: 472
diff changeset
234 if typeName in structTypes:
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
235 ProcessStructType_DepthFirstRecursive(genOrderQueue, structTypes,
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
236 structTypes[typeName])
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
237
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
238 def ProcessStructType_DepthFirstRecursive(
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
239 genOrderQueue : List[str], structTypes : Dict[str,Dict]
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
240 , typeDict : Dict) -> None:
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
241 # let's generate the code according to the
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
242 typeName : str = typeDict['name']
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
243 if typeDict['kind'] != 'struct':
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
244 raise Exception(f"Unexpected kind '{typeDict['kind']}' for " +
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
245 "type '{typeName}'")
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
246 typeFields : List[Dict] = typeDict['fields']
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
247 for typeField in typeFields:
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
248 ancestors = [typeName]
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
249 ProcessTypeTree(ancestors, genOrderQueue
474
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
250 , structTypes, typeField['type'])
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
251 # now we're pretty sure our dependencies have been processed,
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
252 # we can start marking our code for generation
474
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
253 genOrderQueue.add(typeName)
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
254
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
255 def ProcessEnumerationType(definedType) -> (str,str):
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
256 print(f"About to process enumeration: {definedType['name']}")
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
257 tsText : str = """import blah
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
258
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
259 enum PROUT
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
260 {
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
261 value1
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
262 value2
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
263 }"""
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
264
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
265 cppText : str = """import blah
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
266
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
267 enum PROUT
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
268 {
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
269 value1
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
270 value2
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
271 }"""
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
272
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
273 return (tsText,cppText)
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
274
474
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
275 def ProcessStructType(typeDict) -> (str,str):
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
276 print(f"About to process enumeration: {definedType['name']}")
474
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
277 tsText : str = """import blah
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
278
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
279 class PROUT
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
280 {
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
281 public value1 : Type1
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
282 public value2 : Type2
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
283 }"""
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
284
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
285 cppText : str = """import blah
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
286
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
287 class PROUT
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
288 {
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
289 public:
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
290 Type1: value1
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
291 Type2: value2
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
292 }"""
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
293
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
294 return (tsText,cppText)
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
295
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
296
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
297
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
298 def ProcessSchema(schema : dict) -> None:
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
299 CheckSchemaSchema(schema)
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
300 rootName : str = schema['root_name']
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
301 definedTypes : list = schema['types']
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
302
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
303 print(f"Processing schema. rootName = f{rootName}")
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
304 # this will be filled with the generation queue. That is, the type
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
305 # names in the order where they must be defined.
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
306 genOrderQueue : Set = set()
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
307
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
308 # the struct names are mapped to their JSON dictionary
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
309 structTypes : Dict[str,Dict] = {}
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
310
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
311 # the order here is the generation order
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
312 for definedType in definedTypes:
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
313 if definedType['kind'] == 'enum':
474
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
314 ProcessEnumerationType(definedType)
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
315
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
316 for definedType in definedTypes:
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
317 if definedType['kind'] == 'struct':
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
318 structTypes[definedType['name']] = definedType
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
319
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
320 # the order here is NOT the generation order: the types
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
321 # will be processed according to their dependency graph
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
322 for definedType in definedTypes:
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
323 if definedType['kind'] == 'struct':
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
324 ProcessStructType_DepthFirstRecursive(genOrderQueue,structTypes,
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
325 definedType)
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
326
474
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
327 for i in range(len(genOrderQueue))
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
328 typeName = genOrderQueue[i]
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
329 typeDict = structTypes[typeName]
38997ceb9bc6 Ongoing work on message code generation
bgo-osimis
parents: 473
diff changeset
330 ProcessStructType(typeDict)
468
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
331
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
332 if __name__ == '__main__':
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
333 import argparse
472
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
334 parser = argparse.ArgumentParser(
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
335 usage = """stonegentool.py [-h] [-o OUT_DIR] [-v] input_schemas
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
336 EXAMPLE: python command_gen.py -o "generated_files/" """
3db3289e1c25 Ongoing codegen work
bgo-osimis
parents: 471
diff changeset
337 + """ "mainSchema.json,App Specific Commands.json" """)
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
338 parser.add_argument("input_schema", type=str,
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
339 help = "path to the schema file")
468
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
340 parser.add_argument("-o", "--out_dir", type=str, default=".",
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
341 help = """path of the directory where the files
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
342 will be generated. Default is current
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
343 working folder""")
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
344 parser.add_argument("-v", "--verbosity", action="count", default=0,
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
345 help = """increase output verbosity (0 == errors
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
346 only, 1 == some verbosity, 2 == nerd
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
347 mode""")
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
348
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
349 args = parser.parse_args()
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
350 inputSchemaFilename = args.input_schema
469
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
351 outDir = args.out_dir
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
352
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
353 print("input schema = " + str(inputSchemaFilename))
469
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
354 print("out dir = " + str(outDir))
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
355
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
356 ProcessSchema(LoadSchema(inputSchemaFilename))
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
357
468
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
358
469
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
359 ###################
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
360 ## ATTIC ##
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
361 ###################
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
362
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
363 # this works
468
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
364
469
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
365 if False:
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
366 obj = json.loads("""{
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
367 "firstName": "Alice",
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
368 "lastName": "Hall",
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
369 "age": 35
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
370 }""")
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
371 print(obj)