annotate Resources/CodeGeneration/stonegentool.py @ 471:125c19b294e3 bgo-commands-codegen

Ongoing codegen work
author bgo-osimis
date Wed, 13 Feb 2019 06:24:35 +0100
parents db093eb6b29d
children 3db3289e1c25
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
1 from typing import List,Dict
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
2 import sys
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
3 import json
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
4 import re
469
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
5
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
6 def LoadSchema(file_path : str):
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
7 with open(file_path, 'r') as fp:
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
8 obj = json.load(fp)
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
9 return obj
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
10
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
11 class Type:
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
12 def __init__(self, canonicalTypeName:str, kind:str):
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
13 allowedTypeKinds = ["primitive","enum","struct","collection"]
469
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
14 """dependent type is the list of canonical types this type depends on.
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
15 For instance, vector<map<string,int32>> depends on map<string,int32>
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
16 that, in turn, depends on string and int32 that, in turn, depend on
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
17 nothing"""
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
18 self.canonicalTypeName = canonicalTypeName
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
19 assert(kind in allowedTypeKinds)
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
20
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
21 def setDependentTypes(self, dependentTypes:List[Type]) -> None:
469
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
22 self.dependentTypes = dependentTypes
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
23
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
24 def getDependentTypes(self) -> List[Type]:
469
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
25 return self.dependentTypes
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
26
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
27 def getCppTypeName(self) -> str:
469
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
28 # C++: prefix map vector and string with std::map, std::vector and std::string
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
29 # replace int32 by int32_t
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
30 # replace float32 by float
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
31 # replace float64 by double
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
32 retVal : str = self.canonicalTypeName.replace("map","std::map")
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
33 retVal : str = self.canonicalTypeName.replace("vector","std::vector")
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
34 retVal : str = self.canonicalTypeName.replace("int32","int32_t")
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
35 retVal : str = self.canonicalTypeName.replace("float32","float")
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
36 retVal : str = self.canonicalTypeName.replace("float64","double")
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
37 return retVal
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
38
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
39 def getTypeScriptTypeName(self) -> str:
469
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
40 # TS: replace vector with Array and map with Map
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
41 # string remains string
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
42 # replace int32 by number
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
43 # replace float32 by number
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
44 # replace float64 by number
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
45 retVal : str = self.canonicalTypeName.replace("map","Map")
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
46 retVal : str = self.canonicalTypeName.replace("vector","Array")
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
47 retVal : str = self.canonicalTypeName.replace("int32","number")
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
48 retVal : str = self.canonicalTypeName.replace("float32","number")
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
49 retVal : str = self.canonicalTypeName.replace("float64","number")
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
50 retVal : str = self.canonicalTypeName.replace("bool","boolean")
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
51 return retVal
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
52
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
53 class Schema:
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
54 def __init__(self, root_prefix : str, defined_types : List[Type]):
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
55 self.rootName : str = root_prefix
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
56 self.definedTypes : str = defined_types
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
57
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
58 def CheckTypeSchema(definedType : Dict) -> None:
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
59 allowedDefinedTypeKinds = ["enum","struct"]
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
60 if not definedType.has_key('name'):
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
61 raise Exception("type lacks the 'name' key")
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
62 name = definedType['name']
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
63 if not definedType.has_key('kind'):
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
64 raise Exception(f"type {name} lacks the 'kind' key")
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
65 kind = definedType['kind']
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
66 if not (kind in allowedDefinedTypeKinds):
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
67 raise Exception(f"type {name} : kind {kind} is not allowed. It must be one of {allowedDefinedTypeKinds}")
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
68
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
69 if not definedType.has_key('fields'):
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
70 raise Exception("type {name} lacks the 'fields' key")
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
71
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
72 # generic check on all kinds of types
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
73 fields = definedType['fields']
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
74 for field in fields:
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
75 fieldName = field['name']
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
76 if not field.has_key('name'):
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
77 raise Exception("field in type {name} lacks the 'name' key")
469
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
78
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
79 # fields in struct must have types
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
80 if kind == 'struct':
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
81 for field in fields:
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
82 fieldName = field['name']
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
83 if not field.has_key('type'):
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
84 raise Exception(f"field {fieldName} in type {name} lacks the 'type' key")
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
85
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
86 def CheckSchemaSchema(schema : Dict) -> None:
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
87 if not schema.has_key('root_name'):
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
88 raise Exception("schema lacks the 'root_name' key")
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
89 if not schema.has_key('types'):
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
90 raise Exception("schema lacks the 'types' key")
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
91 for definedType in schema['types']:
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
92 CheckTypeSchema(definedType)
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
93
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
94 def CreateAndCacheTypeObject(allTypes : Dict[str,Type], typeDict : Dict) -> None:
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
95 """This does not set the dependentTypes field"""
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
96 typeName : str = typeDict['name']
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
97 if allTypes.has_key(typeName):
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
98 raise Exception(f'Type {typeName} is defined more than once!')
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
99 else:
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
100 typeObject = Type(typeName, typeDict['kind'])
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
101 allTypes[typeName] = typeObject
468
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
102
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
103
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
104
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
105 def EatToken(sentence : str) -> (str,str):
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
106 """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
107 (including templates) like "int32", "TotoTutu", or
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
108 "map<map<int32,vector<string>>,map<string,int32>>" """
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
109 token = []
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
110 if sentence.count('<') != sentence.count('>'):
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
111 raise Exception(f"Error in the partial template type list {sentence}. The number of < and > do not match!")
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
112
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
113 # the template level we're currently in
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
114 templateLevel = 0
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
115 for i in len(sentence):
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
116 if (sentence[i] == ",") and (templateLevel == 0):
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
117 return (sentence[0:i],sentence[i+1:])
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
118 elif (sentence[i] == "<"):
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
119 templateLevel += 1
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
120 elif (sentence[i] == ">"):
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
121 templateLevel -= 1
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
122 return (sentence,"")
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
123
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
124 def SplitListOfTypes(typeName : str) -> List[str]:
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
125 """Splits something like
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
126 vector<string>,int32,map<string,map<string,int32>>
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
127 in:
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
128 - vector<string>
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
129 - int32
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
130 map<string,map<string,int32>>
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
131
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
132 This is not possible with a regex so
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
133 """
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
134 stillStuffToEat : bool = True
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
135 tokenList = []
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
136 restOfString = typeName
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
137 while stillStuffToEat:
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
138 firstToken,restOfString = EatToken(restOfString)
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
139 tokenList.append(firstToken)
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
140 return tokenList
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
141
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
142 templateRegex = re.compile(r"([a-zA-Z0-9_]*[a-zA-Z0-9_]*)<([a-zA-Z0-9_,:<>]+)>")
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
143 def ParseTemplateType(typeName) -> (bool,str,List[str]):
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
144 """ If the type is a template like "SOMETHING<SOME<THING,EL<SE>>>", then
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
145 it returns (true,"SOMETHING","SOME<THING,EL<SE>>")
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
146 otherwise it returns (false,"","")"""
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
147
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
148 # let's remove all whitespace from the type
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
149 # split without argument uses any whitespace string as separator
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
150 # (space, tab, newline, return or formfeed)
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
151 typeName = "".join(typeName.split())
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
152 matches = templateRegex.match(typeName)
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
153 if matches == None:
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
154 return (False,"","")
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
155 else:
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
156 # we need to split with the commas that are outside of the defined types
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
157 # simply splitting at commas won't work
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
158 listOfDependentTypes = SplitListOfTypes(matches.group(2))
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
159 return (True,matches.group(1),listOfDependentTypes)
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
160
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
161 def GetPrimitiveType(typeName : str) -> Type:
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
162 if allTypes.has_key(typeName):
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
163 return allTypes[typeName]
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
164 else:
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
165 primitiveTypes = ['int32', 'float32', 'float64', 'string']
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
166 if not (typeName in primitiveTypes):
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
167 raise Exception(f"Type {typeName} is unknown.")
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
168 typeObject = Type(typeName,'primitive')
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
169 # there are no dependent types in a primitive type --> Type object
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
170 # constrution is finished at this point
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
171 allTypes[typeName] = typeObject
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
172 return typeObject
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
173
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
174 def ProcessTypeTree(
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
175 ancestors : List[str]
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
176 , generationQueue : List[str]
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
177 , structTypes : Dict[str,Dict], typeName : str) -> None:
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
178 if typeName in ancestors:
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
179 raise Exception(f"Cyclic dependency chain found: the last of {ancestors} depends on {typeName} that is already in the list.")
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
180
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
181 if not (typeName in generationQueue):
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
182 # if we reach this point, it means the type is NOT a struct or an enum.
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
183 # it is another (non directly user-defined) type that we must parse and create
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
184 # let's do it
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
185 dependentTypes = []
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
186 (isTemplate,templateType,parameters) = ParseTemplateType(typeName)
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
187 if isTemplate:
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
188 dependentTypeNames : List[str] = SplitListOfTypes(parameters)
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
189 for dependentTypeName in dependentTypeNames:
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
190 # childAncestors = ancestors.copy() NO TEMPLATE ANCESTOR!!!
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
191 # childAncestors.append(typeName)
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
192 ProcessTypeTree(ancestors, processedTypes, structTypes, dependentTypeName)
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
193 else:
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
194 if structTypes.has_key(typeName):
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
195 ProcesStructType_DepthFirstRecursive(generationQueue, structTypes,
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
196 structTypes[typeName])
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
197
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
198 def ProcesStructType_DepthFirstRecursive(
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
199 generationQueue : List[str], structTypes : Dict[str,Dict]
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
200 , typeDict : Dict) -> None:
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
201 # let's generate the code according to the
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
202 typeName : str = typeDict['name']
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
203 if typeDict['kind'] != 'struct':
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
204 raise Exception(f"Unexpected kind '{typeDict['kind']}' for " +
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
205 "type '{typeName}'")
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
206 typeFields : List[Dict] = typeDict['fields']
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
207 for typeField in typeFields:
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
208 ancestors = [typeName]
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
209 ProcessTypeTree(ancestors, generationQueue
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
210 , structTypes, typeField['name'])
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
211 # now we're pretty sure our dependencies have been processed,
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
212 # we can start marking our code for generation
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
213 generationQueue.append(typeName)
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
214
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
215 def ProcessSchema(schema : dict) -> None:
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
216 CheckSchemaSchema(schema)
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
217 rootName : str = schema['root_name']
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
218 definedTypes : list = schema['types']
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
219
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
220 # mark already processed types
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
221 processedTypes : set[str] = set()
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
222
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
223 # the struct names are mapped to their JSON dictionary
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
224 structTypes : Dict[str,Dict] = {}
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
225
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
226 # the order here is the generation order
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
227 for definedType in definedTypes:
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
228 if definedType['kind'] == 'enum':
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
229 ProcessEnumerationType(processedTypes, definedType);
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
230
471
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
231 # the order here is NOT the generation order: the types
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
232 # will be processed according to their dependency graph
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
233 for definedType in definedTypes:
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
234 if definedType['kind'] == 'struct':
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
235 structTypes[definedType['name']] = definedType
125c19b294e3 Ongoing codegen work
bgo-osimis
parents: 470
diff changeset
236 ProcesStructType_DepthFirstRecursive(processedTypes,structTypes,definedType)
468
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
237
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
238 if __name__ == '__main__':
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
239 import argparse
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
240 parser = argparse.ArgumentParser(usage = """stonegentool.py [-h] [-o OUT_DIR] [-v] input_schemas
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
241 EXAMPLE: python command_gen.py -o "generated_files/" "mainSchema.json,App Specific Commands.json" """)
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
242 parser.add_argument("input_schema", type=str,
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
243 help = "path to the schema file")
468
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
244 parser.add_argument("-o", "--out_dir", type=str, default=".",
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
245 help = """path of the directory where the files
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
246 will be generated. Default is current
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
247 working folder""")
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
248 parser.add_argument("-v", "--verbosity", action="count", default=0,
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
249 help = """increase output verbosity (0 == errors
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
250 only, 1 == some verbosity, 2 == nerd
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
251 mode""")
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
252
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
253 args = parser.parse_args()
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
254 inputSchemaFilename = args.input_schema
469
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
255 outDir = args.out_dir
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
256
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
257 print("input schema = " + str(inputSchemaFilename))
469
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
258 print("out dir = " + str(outDir))
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
259
470
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
260 ProcessSchema(LoadSchema(inputSchemaFilename))
db093eb6b29d Ongoing code generation tool
bgo-osimis
parents: 469
diff changeset
261
468
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
262
469
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
263 ###################
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
264 ## ATTIC ##
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
265 ###################
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
266
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
267 # this works
468
cef55b4e6c21 stonegentool first commit
bgo-osimis
parents:
diff changeset
268
469
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
269 if False:
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
270 obj = json.loads("""{
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
271 "firstName": "Alice",
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
272 "lastName": "Hall",
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
273 "age": 35
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
274 }""")
52549faf47ba Ongoing code generation work
bgo-osimis
parents: 468
diff changeset
275 print(obj)