tools/jsonschematoc11/c11types/c11typestruct.py
from .c11type import C11Type
from .c11typebool import C11TypeBool
from .c11typeinteger import C11TypeInteger
from .c11typenumber import C11TypeNumber
from .c11typestring import C11TypeString
from .c11typearray import C11TypeArray
from .c11variable import C11Variable
class C11TypeStruct(C11Type):
"""struct type."""
def __init__(self):
"""Construct and declare some vars."""
C11Type.__init__(self)
self.parents = dict()
self.variables = dict()
self.c11Type = None
def setSchema(self, schemaName, schemaValue):
C11Type.setSchema(self, schemaName, schemaValue)
if u'type' in schemaValue:
schemaValueType = schemaValue[u'type']
if schemaValueType == u'bool' or schemaValueType == u'boolean':
self.c11Type = C11TypeBool()
elif schemaValueType == u'integer':
self.c11Type = C11TypeInteger()
elif schemaValueType == u'number':
self.c11Type = C11TypeNumber()
elif schemaValueType == u'string':
self.c11Type = C11TypeString()
elif schemaValueType == u'array':
self.c11Type = C11TypeArray()
if self.c11Type is None:
if u'allOf' in schemaValue:
schemaValueAllOf = schemaValue[u'allOf']
for schemaValueAllOfItem in schemaValueAllOf:
if u'$ref' in schemaValueAllOfItem:
self.parents[schemaValueAllOfItem[u'$ref']] = None
if u'properties' in schemaValue:
schemaValueProperties = schemaValue[u'properties']
for key in schemaValueProperties:
#if key == u'spot':
# print(key, schemaValueProperties[key])
self.variables[key] = C11Variable(key, schemaValueProperties[key])
def haveParents(self):
return len(self.parents) > 0
def getParentTypeNames(self, recursion=True, withDeclare=False, asVariable=False, withObject=False):
parentTypeNames = []
for key in self.parents:
parent = self.parents[key]
if recursion:
for parentParentTypeName in parent.getParentTypeNames():
parentTypeNames.append(parentParentTypeName)
parentTypeNames.append(parent.codeTypeName(withDeclare, asVariable))
if withObject and len(parentTypeNames) <= 0:
parentTypeNames.append(u'SObject')
return parentTypeNames
def getVariableKeys(self, includeParent=False):
variableKeys = []
for key in self.variables:
variableKeys.append(key)
for key in self.parents:
parent = self.parents[key]
parentVariableKeys = parent.getVariableKeys(True)
for parentVariableKey in parentVariableKeys:
variableKeys.append(parentVariableKey)
return variableKeys
def getVariables(self, includeParent=False):
variables = self.variables
for parentKey in self.parents:
parent = self.parents[parentKey]
parentVariableKeys = parent.getVariableKeys(True)
if len(parentVariableKeys) > 0:
variables = {key: value for key, value in variables.items() if key not in parentVariableKeys }
parentVariableKeys = None
return variables.values()
def revise(self, c11Types):
for key in self.parents:
if key not in c11Types:
return (1, u'Can\'t find the parent %s in %s' % (key, self.codeTypeName()))
self.parents[key] = c11Types[key]
for key in self.variables:
variable = self.variables[key]
(errorCode, errorMessage) = variable.revise(c11Types)
if errorCode != 0:
return (errorCode, errorMessage)
return (0, u'')
def codeTypeName(self, withDeclare=False, asVariable=False, withDocument=False):
codeLine = self.typeName
if self.typeName is None:
#TODO:
print(u':todo:')
if withDeclare:
if withDocument:
codeLine = u'TDataDoc<%s>' % codeLine
else:
codeLine = u'%s' % codeLine
else:
if withDocument:
codeLine = u'TDataDoc<%s>' % codeLine
if asVariable:
if withDocument:
codeLine = u'TDataDoc<std::shared_ptr<%s>>' % codeLine
else:
codeLine = u'std::shared_ptr<%s>' % codeLine
return codeLine
def codeInheritTypes(self):
if len(self.parents) <= 0:
return u' : SObject'
code = u''
for parent in self.parents:
code = code + u', %s' % self.parents[parent].codeTypeName()
code = u' :' + code[1:]
return code
def codeHeader(self, codeTypeNames):
codeLines = []
if self.codeTypeName() in codeTypeNames:
return codeLines
for key in self.parents:
parent = self.parents[key]
if parent.codeTypeName() in codeTypeNames:
continue
for parentCodeLine in parent.codeHeader(codeTypeNames):
codeLines.append(parentCodeLine)
codeLines.append(u'')
codeLines.append(u'/*!')
codeLines.append(u' * struct: %s' % self.codeTypeName())
if hasattr(self, u'description'):
codeLines.append(u' * ' + self.description)
codeLines.append(u' */')
codeLines.append(u'struct %s%s' % (self.codeTypeName(), self.codeInheritTypes()))
codeLines.append(u'{')
codeLines.append(u' %s();' % self.codeTypeName())
codeLines.append(u'')
codeLines.append(u' // Check valid')
codeLines.append(u' operator bool() const;')
if self.c11Type != None:
codeLines.append(u'')
codeLines.append(u' operator %s() const;' % self.c11Type.codeTypeName())
codeLines.append(u'')
codeLines.append(u' %s %sValue;' % (self.c11Type.codeTypeName(), self.c11Type.codeTypeName()))
variables = self.getVariables()
if variables is not None and len(variables) > 0:
codeLines.append(u'')
for variable in variables:
if variable.hasComment():
codeLines.append(u' // %s' % variable.codeComment())
codeLines.append(u' %s;' % variable.codeDeclare())
if self.manualCodeHeaders is not None and len(self.manualCodeHeaders) > 0:
codeLines.append(u'')
codeLines.append(u' // Manual code lines')
for code_header_line in self.manualCodeHeaders:
codeLines.append(u' %s' % code_header_line.replace(u'\n', u''))
codeLines.append(u'};')
return codeLines
def codeSource(self, codeTypeNames):
codeLines = []
if self.codeTypeName() in codeTypeNames:
return codeLines
for key in self.parents:
parent = self.parents[key]
if parent.codeTypeName() in codeTypeNames:
continue
for parentCodeLine in parent.codeSource(codeTypeNames):
codeLines.append(parentCodeLine)
codeLines.append(u'')
codeLines.append(u'%s::%s()' % (self.codeTypeName(), self.codeTypeName()))
beginConstructorDefault = True
parentTypeNames = self.getParentTypeNames(recursion=False, withObject=True)
for parentTypeName in parentTypeNames:
if beginConstructorDefault:
codeLines.append(u' : %s()' % parentTypeName)
beginConstructorDefault = False
else:
codeLines.append(u' , %s()' % parentTypeName)
if self.c11Type != None:
if beginConstructorDefault:
codeLines.append(u' : %sValue(%s)' % (self.c11Type.codeTypeName(), self.c11Type.codeDefaultValue(None)))
beginConstructorDefault = False
else:
codeLines.append(u' , %sValue(%s)' % (self.c11Type.codeTypeName(), self.c11Type.codeDefaultValue(None)))
variables = self.getVariables()
for variable in variables:
if beginConstructorDefault:
codeLines.append(u' : %s' % variable.codeConstructorDefault())
beginConstructorDefault = False
else:
codeLines.append(u' , %s' % variable.codeConstructorDefault())
if self.manualCodeSourcesVariable is not None and len(self.manualCodeSourcesVariable) > 0:
codeLines.append(u' // Manual code lines')
for variable in self.manualCodeSourcesVariable:
if beginConstructorDefault:
codeLines.append(u' : %s' % variable)
beginConstructorDefault = False
else:
codeLines.append(u' , %s' % variable)
codeLines.append(u'{')
codeLines.append(u' //')
codeLines.append(u'}')
codeLines.append(u'')
codeLines.append(u'%s::operator bool() const' % self.codeTypeName())
codeLines.append(u'{')
codeLines.append(u' //TODO:')
codeLines.append(u' return true;')
codeLines.append(u'}')
if self.c11Type != None:
codeLines.append(u'')
codeLines.append(u'%s::operator %s() const' % (self.codeTypeName(), self.c11Type.codeTypeName()))
codeLines.append(u'{')
codeLines.append(u' return %sValue;' % (self.c11Type.codeTypeName()))
codeLines.append(u'}')
if self.manualCodeSourcesFunction is not None and len(self.manualCodeSourcesFunction) > 0:
codeLines.append(u'')
codeLines.append(u'// Manual code lines')
for code_source_function_line in self.manualCodeSourcesFunction:
codeLines.append(u'%s' % code_source_function_line.replace(u'\n', u''))
return codeLines
def codeParserHeader(self):
codeLines = []
codeLines.append(u'bool operator<<(%s& _rData, const JSONCharValue& _JsonValue);' % (self.codeTypeName(withDeclare=True)))
codeLines.append(u'bool operator>>(const TDataDoc<%s>& _rData, JSONCharValue& _JsonValue);' % (self.codeTypeName(withDeclare=True)))
codeLines.append(u'bool operator<<(%s& _rData, const JSONCharValue& _JsonValue);' % (self.codeTypeName(withDeclare=True, asVariable=True)))
codeLines.append(u'bool operator>>(const TDataDoc<%s>& _rData, JSONCharValue& _JsonValue);' % (self.codeTypeName(withDeclare=True, asVariable=True)))
codeLines.append(u'bool operator<<(std::vector<%s>& _vDatas, const JSONCharValue& _JsonValue);' % (self.codeTypeName(withDeclare=True, asVariable=True)))
codeLines.append(u'bool operator>>(const TDataDoc<std::vector<%s>>& _rData, JSONCharValue& _JsonValue);' % (self.codeTypeName(withDeclare=True, asVariable=True)))
return codeLines
def codeParserSource(self):
codeLines = []
codeLines.append(u'bool operator<<(%s& _rData, const JSONCharValue& _JsonValue)' % (self.codeTypeName()))
codeLines.append(u'{')
if self.manualCodeParsersFrom is not None and len(self.manualCodeParsersFrom) > 0:
codeLines.append(u' // Manual code lines')
for code_parser in self.manualCodeParsersFrom:
codeLines.append(u' %s' % code_parser.replace(u'\n', u''))
else:
parentTypes = self.getParentTypeNames(recursion=False)
for parentType in parentTypes:
codeLines.append(u' {')
codeLines.append(u' %s& super_ptr = _rData;' % parentType)
codeLines.append(u' if (!(super_ptr << _JsonValue)) return false;')
codeLines.append(u' }')
if self.c11Type != None:
codeLines.append(u' if (!(_rData.%sValue << _JsonValue)) return false;' % self.c11Type.codeTypeName())
else:
variables = self.getVariables()
for variable in variables:
codeParserLines = variable.codeParser()
for codeParserLine in codeParserLines:
codeLines.append(u' %s' % codeParserLine)
codeLines.append(u' _rData.schemaType = "%s";' % (self.schemaName))
codeLines.append(u' return true;')
codeLines.append(u'}')
codeLines.append(u'')
codeLines.append(u'bool operator>>(const TDataDoc<%s>& _rData, JSONCharValue& _JsonValue)' % (self.codeTypeName()))
codeLines.append(u'{')
if self.manualCodeParsersTo is not None and len(self.manualCodeParsersTo) > 0:
codeLines.append(u' // Manual code lines')
for code_parser in self.manualCodeParsersTo:
codeLines.append(u' %s' % code_parser.replace(u'\n', u''))
else:
codeLines.append(u' if (!_rData.doc) return false;')
codeLines.append(u' _JsonValue.SetObject();')
parentTypes = self.getParentTypeNames(recursion=False)
for parentType in parentTypes:
codeLines.append(u' {')
codeLines.append(u' const %s& super_ptr = _rData.data;' % parentType)
codeLines.append(u' if (!(TDataDoc<%s>(super_ptr, _rData.doc) >> _JsonValue)) return false;' % parentType)
codeLines.append(u' }')
if self.c11Type != None:
codeLines.append(u' if (!(TDataDoc<%s>(_rData.data.%sValue, _rData.doc) >> _JsonValue)) return false;' % (self.c11Type.codeTypeName(), self.c11Type.codeTypeName()))
else:
variables = self.getVariables()
for variable in variables:
codeParserLines = variable.codeParser(isSet=False)
for codeParserLine in codeParserLines:
codeLines.append(u' %s' % codeParserLine)
codeLines.append(u' return true;')
codeLines.append(u'}')
codeLines.append(u'')
codeLines.append(u'bool operator<<(%s& _pData, const JSONCharValue& _JsonValue)' % (self.codeTypeName(asVariable=True)))
codeLines.append(u'{')
codeLines.append(u' %s data_ptr = !!_pData ? _pData : std::make_shared<%s>();' % (self.codeTypeName(asVariable=True), self.codeTypeName()))
codeLines.append(u' if (!(*data_ptr << _JsonValue)) return false;')
codeLines.append(u' _pData = data_ptr;')
codeLines.append(u' return true;')
codeLines.append(u'}')
codeLines.append(u'')
codeLines.append(u'bool operator>>(const TDataDoc<%s>& _rData, JSONCharValue& _JsonValue)' % (self.codeTypeName(asVariable=True)))
codeLines.append(u'{')
codeLines.append(u' if (!_rData.data) return false;')
codeLines.append(u' return (TDataDoc<%s>(*_rData.data, _rData.doc) >> _JsonValue);' % self.codeTypeName())
codeLines.append(u'}')
codeLines.append(u'')
codeLines.append(u'bool operator<<(std::vector<%s>& _vDatas, const JSONCharValue& _JsonValue)' % (self.codeTypeName(asVariable=True)))
codeLines.append(u'{')
codeLines.append(u' return operator<< <%s>(_vDatas, _JsonValue);' % (self.codeTypeName(asVariable=True)))
codeLines.append(u'}')
codeLines.append(u'')
codeLines.append(u'bool operator>>(const TDataDoc<std::vector<%s>>& _rData, JSONCharValue& _JsonValue)' % (self.codeTypeName(asVariable=True)))
codeLines.append(u'{')
codeLines.append(u' return operator>> <%s>(_rData, _JsonValue);' % (self.codeTypeName(asVariable=True)))
codeLines.append(u'}')
return codeLines
def codeDefaultValue(self, schemaDefaultValue):
return u'nullptr'
def codeJsonCheck(self):
if self.c11Type is None:
return u'IsObject()'
return self.c11Type.codeJsonCheck()
def codeJsonSet(self, dataName, variableName):
return u'if (!(%s.%s << _JsonValue["%s"])) return false;' % (dataName, variableName, variableName)
def codeJsonGet(self, dataName, variableName):
return u'if (!(%s.%s >> _JsonValue["%s"])) return false;' % (dataName, variableName, variableName)