text: import sys
  from autosar.parser.parser_base import ElementParser
  import autosar.datatype
  
  class DataTypeParser(ElementParser):
      def __init__(self,version=3.0):
          super().__init__(version)
  
          if self.version >= 3.0 and self.version < 4.0:
              self.switcher = {'ARRAY-TYPE': self.parseArrayType,
                               'BOOLEAN-TYPE': self.parseBooleanType,
                               'INTEGER-TYPE': self.parseIntegerType,
                               'REAL-TYPE': self.parseRealType,
                               'RECORD-TYPE': self.parseRecordType,
                               'STRING-TYPE': self.parseStringType}
          elif self.version >= 4.0:
              self.switcher = {
                 'DATA-CONSTR': self.parseDataConstraint,
                 'IMPLEMENTATION-DATA-TYPE': self.parseImplementationDataType,
                 'SW-BASE-TYPE': self.parseSwBaseType,
                 'DATA-TYPE-MAPPING-SET': self.parseDataTypeMappingSet,
                 'APPLICATION-PRIMITIVE-DATA-TYPE': self.parseApplicationPrimitiveDataType,
                 'APPLICATION-ARRAY-DATA-TYPE' : self.parseApplicationArrayDataType,
                 'APPLICATION-RECORD-DATA-TYPE': self.parseApplicationRecordDataTypeXML,
              }
  
      def getSupportedTags(self):
          return self.switcher.keys()
  
      def parseElement(self, xmlElement, parent = None):
          parseFunc = self.switcher.get(xmlElement.tag)
          if parseFunc is not None:
              return parseFunc(xmlElement,parent)
          else:
              return None
  
  
      def parseIntegerType(self,root,parent=None):
          if self.version>=3.0:
              name=root.find("./SHORT-NAME").text
              minval = int(root.find("./LOWER-LIMIT").text)
              maxval = int(root.find("./UPPER-LIMIT").text)
              dataDefXML = root.find('./SW-DATA-DEF-PROPS')
              dataType = autosar.datatype.IntegerDataType(name,minval,maxval)
              self.parseDesc(root,dataType)
              if dataDefXML is not None:
                  for elem in dataDefXML.findall('./*'):
                      if elem.tag=='COMPU-METHOD-REF':
                          dataType.compuMethodRef=self.parseTextNode(elem)
                      else:
                          raise NotImplementedError(elem.tag)
              return dataType
  
      def parseRecordType(self,root,parent=None):
          if self.version>=3.0:
              elements = []
              name=root.find("./SHORT-NAME").text
              for elem in root.findall('./ELEMENTS/RECORD-ELEMENT'):
                  elemName = self.parseTextNode(elem.find("./SHORT-NAME"))
                  elemTypeRef = self.parseTextNode(elem.find("./TYPE-TREF"))
                  elements.append(autosar.datatype.RecordTypeElement(elemName, elemTypeRef))
              dataType=autosar.datatype.RecordDataType(name,elements);
              self.parseDesc(root,dataType)
              return dataType
  
      def parseArrayType(self,root,parent=None):
          if self.version>=3.0:
              name=root.find("./SHORT-NAME").text
              length=int(root.find('ELEMENT/MAX-NUMBER-OF-ELEMENTS').text)
              typeRef=root.find('ELEMENT/TYPE-TREF').text
              dataType=autosar.datatype.ArrayDataType(name,typeRef,length)
              self.parseDesc(root,dataType)
              return dataType;
  
      def parseBooleanType(self,root,parent=None):
          if self.version>=3:
              name=root.find("./SHORT-NAME").text
              dataType=autosar.datatype.BooleanDataType(name)
              self.parseDesc(root,dataType)
              return dataType
  
      def parseStringType(self,root,parent=None):
          if self.version>=3.0:
              name=root.find("./SHORT-NAME").text
  
              length=int(root.find('MAX-NUMBER-OF-CHARS').text)
              encoding=root.find('ENCODING').text
              dataType=autosar.datatype.StringDataType(name,length,encoding)
              self.parseDesc(root,dataType)
              return dataType
  
      def parseRealType(self,root,parent=None):
          if self.version>=3.0:
              name=root.find("./SHORT-NAME").text
  
              elem = root.find("./LOWER-LIMIT")
              if elem is not None:
                  minval = elem.text
                  minvalType = elem.attrib['INTERVAL-TYPE']
              elem = root.find("./UPPER-LIMIT")
              if elem is not None:
                  maxval = elem.text
                  maxvalType = elem.attrib['INTERVAL-TYPE']
              hasNaNText = self.parseTextNode(root.find("./ALLOW-NAN"))
              hasNaN = True if (hasNaNText is not None and hasNaNText == 'true') else False
              encoding = self.parseTextNode(root.find("./ENCODING"))
              dataType=autosar.datatype.RealDataType(name,minval,maxval,minvalType,maxvalType,hasNaN,encoding)
              self.parseDesc(root,dataType)
              return dataType
  
      def parseDataConstraint(self, xmlRoot, parent=None):
          assert (xmlRoot.tag == 'DATA-CONSTR')
          rules=[]
          constraintLevel = None
          self.push()
          for xmlElem in xmlRoot.findall('./*'):
              if xmlElem.tag == 'DATA-CONSTR-RULES':
                  for xmlChildElem in xmlElem.findall('./DATA-CONSTR-RULE/*'):
                      if xmlChildElem.tag == 'INTERNAL-CONSTRS':
                          rules.append(self._parseDataConstraintRule(xmlChildElem, 'internalConstraint'))
                      elif xmlChildElem.tag == 'PHYS-CONSTRS':
                          rules.append(self._parseDataConstraintRule(xmlChildElem, 'physicalConstraint'))
                      elif xmlChildElem.tag == 'CONSTR-LEVEL':
                          constraintLevel = self.parseIntNode(xmlChildElem)
                      else:
                          raise NotImplementedError(xmlChildElem.tag)
              else:
                  self.defaultHandler(xmlElem)
          elem = autosar.datatype.DataConstraint(self.name, rules, constraintLevel, parent, self.adminData)
          self.pop(elem)
          return elem
  
      def _parseDataConstraintRule(self, xmlElem, constraintType):
          lowerLimitXML = xmlElem.find('./LOWER-LIMIT')
          upperLimitXML = xmlElem.find('./UPPER-LIMIT')
          lowerLimit = None if lowerLimitXML is None else self.parseNumberNode(lowerLimitXML)
          upperLimit = None if upperLimitXML is None else self.parseNumberNode(upperLimitXML)
          lowerLimitType = 'CLOSED'
          upperLimitType = 'CLOSED'
          key = 'INTERVAL-TYPE'
          if lowerLimitXML is not None and key in lowerLimitXML.attrib and lowerLimitXML.attrib[key]=='OPEN':
              lowerLimitType='OPEN'
          if upperLimitXML is not None and key in upperLimitXML.attrib and upperLimitXML.attrib[key]=='OPEN':
              upperLimitType='OPEN'
          return {
              'type': constraintType,
              'lowerLimit': lowerLimit,
              'upperLimit': upperLimit,
              'lowerLimitType': lowerLimitType,
              'upperLimitType': upperLimitType}
  
  
      def parseImplementationDataType(self, xmlRoot, parent=None):
          assert (xmlRoot.tag == 'IMPLEMENTATION-DATA-TYPE')
          variantProps, typeEmitter, parseTextNode, dynamicArraySizeProfile, subElementsXML, symbolProps = None, None, None, None, None, None
          self.push()
          for xmlElem in xmlRoot.findall('./*'):
              if xmlElem.tag == 'SW-DATA-DEF-PROPS':
                  variantProps = self.parseSwDataDefProps(xmlElem)
              elif xmlElem.tag == 'TYPE-EMITTER':
                  typeEmitter = self.parseTextNode(xmlElem)
              elif xmlElem.tag == 'DYNAMIC-ARRAY-SIZE-PROFILE':
                  dynamicArraySizeProfile = self.parseTextNode(xmlElem)
              elif xmlElem.tag == 'SUB-ELEMENTS':
                  subElementsXML = xmlElem
              elif xmlElem.tag == 'SYMBOL-PROPS':
                  symbolProps = self.parseSymbolProps(xmlElem)
              else:
                  self.defaultHandler(xmlElem)
  
          dataType = autosar.datatype.ImplementationDataType(
              self.name,
              variantProps = variantProps,
              dynamicArraySizeProfile = dynamicArraySizeProfile,
              typeEmitter = typeEmitter,
              category = self.category,
              parent = parent,
              adminData = self.adminData
              )
          if subElementsXML is not None:
              dataType.subElements = self.parseImplementationDataTypeSubElements(subElementsXML, dataType)
          if symbolProps is not None:
              dataType.symbolProps = symbolProps
          self.pop(dataType)
          return dataType
  
      def parseImplementationDataTypeSubElements(self, xmlRoot, parent):
          assert (xmlRoot.tag == 'SUB-ELEMENTS')
          elements = []
          for xmlElem in xmlRoot.findall('./*'):
              if xmlElem.tag == 'IMPLEMENTATION-DATA-TYPE-ELEMENT':
                  elements.append(self.parseImplementationDataTypeElement(xmlElem, parent))
              else:
                  raise NotImplementedError(xmlElem.tag)
          return elements
  
      def parseImplementationDataTypeElement(self, xmlRoot, parent):
          assert (xmlRoot.tag == 'IMPLEMENTATION-DATA-TYPE-ELEMENT')
          (arraySize, arraySizeSemantics, variants) = (None, None, None)
          self.push()
          for xmlElem in xmlRoot.findall('./*'):
              if xmlElem.tag == 'SW-DATA-DEF-PROPS':
                  variants = self.parseSwDataDefProps(xmlElem)
              elif xmlElem.tag == 'ARRAY-SIZE':
                  arraySize = self.parseTextNode(xmlElem)
              elif xmlElem.tag == 'ARRAY-SIZE-SEMANTICS':
                  arraySizeSemantics = self.parseTextNode(xmlElem)
              elif xmlElem.tag == 'SUB-ELEMENTS':
                  pass #implement later
              else:
                  self.defaultHandler(xmlElem)
          elem = autosar.datatype.ImplementationDataTypeElement(self.name, self.category, arraySize, arraySizeSemantics, variants, parent, self.adminData)
          self.pop(elem)
          return elem
  
  
      def parseSwBaseType(self, xmlRoot, parent = None):
          assert (xmlRoot.tag == 'SW-BASE-TYPE')
          baseTypeSize, baseTypeEncoding, nativeDeclaration = None, None, None
          self.push()
          for xmlElem in xmlRoot.findall('./*'):
              if xmlElem.tag == 'BASE-TYPE-SIZE':
                  baseTypeSize = self.parseTextNode(xmlElem)
              elif xmlElem.tag == 'BASE-TYPE-ENCODING':
                  baseTypeEncoding = self.parseTextNode(xmlElem)
              elif xmlElem.tag == 'NATIVE-DECLARATION':
                  nativeDeclaration = self.parseTextNode(xmlElem)
              elif xmlElem.tag == 'MEM-ALIGNMENT':
                  pass #implement later
              elif xmlElem.tag == 'BYTE-ORDER':
                  pass #implement later
              else:
                  self.defaultHandler(xmlElem)
          elem = autosar.datatype.SwBaseType(self.name, baseTypeSize, baseTypeEncoding, nativeDeclaration, self.category, parent, self.adminData)
          self.pop(elem)
          return elem
  
      def parseDataTypeMappingSet(self, xmlRoot, parent = None):
          assert (xmlRoot.tag == 'DATA-TYPE-MAPPING-SET')
          (name, dataTypeMaps, adminData) = (None, None, None)
          dataTypeMaps = []
          for xmlElem in xmlRoot.findall('./*'):
              if xmlElem.tag == 'ADMIN-DATA':
                  adminData=self.parseAdminDataNode(xmlElem)
              elif xmlElem.tag == 'SHORT-NAME':
                  name = self.parseTextNode(xmlElem)
              elif xmlElem.tag == 'DATA-TYPE-MAPS':
                  for xmlChild in xmlElem.findall('./*'):
                      if xmlChild.tag == 'DATA-TYPE-MAP':
                          dataTypeMap = self.parseDataTypeMap(xmlChild)
                          assert(dataTypeMap is not None)
                          dataTypeMaps.append(dataTypeMap)
                      else:
                          raise NotImplementedError(xmlElem.tag)
              elif xmlElem.tag == 'MODE-REQUEST-TYPE-MAPS':
                  pass #Implement later
              else:
                  raise NotImplementedError(xmlElem.tag)
          if (name is None):
              raise RuntimeError('SHORT-NAME cannot be None')
          elem = autosar.datatype.DataTypeMappingSet(name, parent, adminData)
          for dataTypeMap in dataTypeMaps:
              elem.add(dataTypeMap)
          return elem
  
      def parseApplicationPrimitiveDataType(self, xmlRoot, parent = None):
          assert (xmlRoot.tag == 'APPLICATION-PRIMITIVE-DATA-TYPE')
          variantProps = None
          self.push()
          for xmlElem in xmlRoot.findall('./*'):
              if xmlElem.tag == 'SW-DATA-DEF-PROPS':
                  variantProps = self.parseSwDataDefProps(xmlElem)
              else:
                  self.defaultHandler(xmlElem)
          if (self.name is None):
              raise RuntimeError('SHORT-NAME cannot be None')
          elem = autosar.datatype.ApplicationPrimitiveDataType(self.name, variantProps, self.category, parent, self.adminData)
          self.pop(elem)
          return elem
  
      def parseApplicationArrayDataType(self, xmlRoot, parent = None):
          assert (xmlRoot.tag == 'APPLICATION-ARRAY-DATA-TYPE')
          element, variantProps = None, None
          self.push()
          for xmlElem in xmlRoot.findall('./*'):
              if xmlElem.tag == 'ELEMENT':
                  element = self.parseApplicationArrayElement(xmlElem)
              elif xmlElem.tag == 'SW-DATA-DEF-PROPS':
                  variantProps = self.parseSwDataDefProps(xmlElem)
              elif xmlElem.tag == 'DYNAMIC-ARRAY-SIZE-PROFILE':
                  pass #implement later
              else:
                  self.defaultHandler(xmlElem)
          if element is None:
              raise RuntimeError('No <ELEMENT> object found')
          elem = autosar.datatype.ApplicationArrayDataType(self.name, element, variantProps, self.category, parent, self.adminData)
          self.pop(elem)
          return elem
  
      def parseApplicationArrayElement(self, xmlRoot):
          assert (xmlRoot.tag == 'ELEMENT')
          (typeRef, arraySize, sizeHandling, sizeSemantics) = (None, None, None, None)
          self.push()
          for xmlElem in xmlRoot.findall('./*'):
              if xmlElem.tag == 'TYPE-TREF':
                  typeRef = self.parseTextNode(xmlElem)
              elif xmlElem.tag == 'ARRAY-SIZE-HANDLING':
                  sizeHandling = self.parseTextNode(xmlElem)
              elif xmlElem.tag == 'ARRAY-SIZE-SEMANTICS':
                  sizeSemantics = self.parseTextNode(xmlElem)
              elif xmlElem.tag == 'MAX-NUMBER-OF-ELEMENTS':
                  arraySize = self.parseTextNode(xmlElem)
              else:
                  self.defaultHandler(xmlElem)
          elem = autosar.datatype.ApplicationArrayElement(self.name, typeRef, arraySize, sizeHandling, sizeSemantics, self.category, adminData = self.adminData)
          self.pop(elem)
          return elem
  
      def parseApplicationRecordDataTypeXML(self, xmlRoot, parent = None):
          assert (xmlRoot.tag == 'APPLICATION-RECORD-DATA-TYPE')
          elementsXML, variantProps = None, None
          self.push()
          for xmlElem in xmlRoot.findall('./*'):
              if xmlElem.tag == 'ELEMENTS':
                  elementsXML = xmlElem
              elif xmlElem.tag == 'SW-DATA-DEF-PROPS':
                  variantProps = self.parseSwDataDefProps(xmlElem)
              else:
                  self.defaultHandler(xmlElem)
          elem = autosar.datatype.ApplicationRecordDataType(self.name, None, variantProps, self.category, parent, self.adminData)
          if elementsXML is not None:
              for xmlChild in elementsXML.findall('./'):
                  if xmlChild.tag == 'APPLICATION-RECORD-ELEMENT':
                      elem.elements.append(self._parseApplicationRecordElementXML(xmlChild, parent = elem))
                  else:
                      raise NotImplementedError(xmlChild.tag)
          self.pop(elem)
          return elem
  
      def _parseApplicationRecordElementXML(self, xmlRoot, parent):
          assert (xmlRoot.tag == 'APPLICATION-RECORD-ELEMENT')
          typeRef, variantProps = None, None
          self.push()
          for xmlElem in xmlRoot.findall('./*'):
              if xmlElem.tag == 'TYPE-TREF':
                  typeRef = self.parseTextNode(xmlElem)
              elif xmlElem.tag == 'SW-DATA-DEF-PROPS':
                  variantProps = self.parseSwDataDefProps(xmlElem)
              else:
                  self.defaultHandler(xmlElem)
          elem = autosar.datatype.ApplicationRecordElement(self.name, typeRef, self.category, parent, self.adminData)
          self.pop(elem)
          return elem
  
  
      def parseDataTypeMap(self, xmlRoot):
          assert (xmlRoot.tag == 'DATA-TYPE-MAP')
          (applicationDataTypeRef, implementationDataTypeRef) = (None, None)
          for xmlElem in xmlRoot.findall('./*'):
              if xmlElem.tag == 'APPLICATION-DATA-TYPE-REF':
                  applicationDataTypeRef = self.parseTextNode(xmlElem)
              elif xmlElem.tag == 'IMPLEMENTATION-DATA-TYPE-REF':
                  implementationDataTypeRef = self.parseTextNode(xmlElem)
              else:
                  raise NotImplementedError(xmlElem.tag)
          return autosar.datatype.DataTypeMap(applicationDataTypeRef, implementationDataTypeRef)
  
  
  
  class DataTypeSemanticsParser(ElementParser):
      def __init__(self,version=3.0):
          super().__init__(version)
  
      def getSupportedTags(self):
          return ['COMPU-METHOD']
  
      def parseElement(self, xmlElement, parent = None):
          if xmlElement.tag == 'COMPU-METHOD':
              return self._parseCompuMethodXML(xmlElement, parent)
          else:
              return None
  
      def _parseCompuMethodXML(self, xmlRoot, parent=None):
          assert (xmlRoot.tag == 'COMPU-METHOD')
          compuInternalToPhys, compuPhysToInternal, unitRef = None, None, None
  
          self.push()
          for xmlElem in xmlRoot.findall('./*'):
              if xmlElem.tag == 'COMPU-INTERNAL-TO-PHYS':
                  compuInternalToPhys = self._parseComputationXML(xmlElem)
                  assert(compuInternalToPhys is not None)
              elif xmlElem.tag == 'COMPU-PHYS-TO-INTERNAL':
                  compuPhysToInternal = self._parseComputationXML(xmlElem)
                  assert(compuPhysToInternal is not None)
              elif xmlElem.tag == 'UNIT-REF':
                  unitRef = self.parseTextNode(xmlElem)
              else:
                  self.defaultHandler(xmlElem)
          compuMethod = autosar.datatype.CompuMethod(self.name, False, False, unitRef, self.category, parent, self.adminData)
          self.pop(compuMethod)
          if compuInternalToPhys is not None:
              compuMethod.intToPhys = compuInternalToPhys
          if compuPhysToInternal is not None:
              compuMethod.physToInt = compuPhysToInternal
          return compuMethod
  
      def _parseComputationXML(self, xmlRoot):
          assert (xmlRoot.tag == 'COMPU-INTERNAL-TO-PHYS') or (xmlRoot.tag == 'COMPU-PHYS-TO-INTERNAL')
          computation = autosar.datatype.Computation()
          for xmlElem in xmlRoot.findall('./*'):
              if xmlElem.tag == 'COMPU-SCALES':
                  for compuScaleXml in xmlElem.findall('COMPU-SCALE'):
                      compuScale = self._parseCompuScaleXML(compuScaleXml)
                      computation.elements.append(compuScale)
              elif xmlElem.tag == 'COMPU-DEFAULT-VALUE':
                  for xmlChild in xmlElem.findall('./*'):
                      if xmlChild.tag == 'V':
                          computation.defaultValue = self.parseNumberNode(xmlChild)
                          break
                      elif xmlChild.tag == 'VT':
                          computation.defaultValue = self.parseTextNode(xmlChild)
                          break
                      elif xmlChild.tag == 'VF':
                          computation.defaultValue = self.parseNumberNode(xmlChild)
                          break
                      else:
                          raise NotImplementedError(xmlChild.tag)
              else:
                  raise NotImplementedError(xmlElem.tag)
          return computation
  
      def _parseCompuScaleXML(self, xmlRoot):
          assert(xmlRoot.tag == 'COMPU-SCALE')
          label, lowerLimit, upperLimit, lowerLimitType, upperLimitType, symbol, adminData = None, None, None, None, None, None, None
          offset, numerator, denominator, textValue, mask = None, None, None, None, None
  
          for xmlElem in xmlRoot.findall('./*'):
              if xmlElem.tag == 'DESC':
                  pass #implement later
              elif xmlElem.tag == 'SHORT-LABEL':
                  label = self.parseTextNode(xmlElem)
              elif xmlElem.tag == 'LOWER-LIMIT':
                  lowerLimit = self.parseNumberNode(xmlElem)
                  if (self.version >= 4.0) and 'INTERVAL-TYPE' in xmlElem.attrib:
                      lowerLimitType = xmlElem.attrib['INTERVAL-TYPE']
              elif xmlElem.tag == 'UPPER-LIMIT':
                  upperLimit = self.parseNumberNode(xmlElem)
                  if (self.version >= 4.0) and 'INTERVAL-TYPE' in xmlElem.attrib:
                      upperLimitType = xmlElem.attrib['INTERVAL-TYPE']
              elif xmlElem.tag == 'COMPU-RATIONAL-COEFFS':
                  offset, numerator, denominator = self._parseCompuRationalXML(xmlElem)
              elif xmlElem.tag == 'SYMBOL':
                  symbol = self.parseTextNode(xmlElem)
              elif xmlElem.tag == 'ADMIN-DATA':
                  adminData = self.parseAdminDataNode(xmlElem)
              elif xmlElem.tag == 'COMPU-CONST':
                  textValue = self.parseTextNode(xmlElem.find('./VT'))
              elif xmlElem.tag == 'MASK':
                  mask = self.parseIntNode(xmlElem)
              else:
                  raise NotImplementedError(xmlElem.tag)
          compuScale = autosar.datatype.CompuScaleElement(lowerLimit, upperLimit, lowerLimitType, upperLimitType, label, symbol, adminData)
          compuScale.offset = offset
          compuScale.numerator = numerator
          compuScale.denominator = denominator
          compuScale.textValue = textValue
          compuScale.mask = mask
          return compuScale
  
      def _parseCompuRationalXML(self, xmlRoot):
          assert(xmlRoot.tag == 'COMPU-RATIONAL-COEFFS')
          numXml = xmlRoot.findall('./COMPU-NUMERATOR/V')
          denXml = xmlRoot.findall('./COMPU-DENOMINATOR/V')
          assert(numXml is not None)
          assert(len(numXml) == 2)
          assert(denXml is not None)
          if self.parseTextNode(numXml[0]):
              offset = self.parseNumberNode(numXml[0])
          else:
              offset = 0
          if self.parseTextNode(numXml[1]):
              numerator = self.parseNumberNode(numXml[1])
          else:
              numerator = 1
          denominator = self.parseNumberNode(denXml[0])
          return offset, numerator, denominator
  
  class DataTypeUnitsParser(ElementParser):
      def __init__(self,version=3.0):
          super().__init__(version)
  
  
      def getSupportedTags(self):
          return ['UNIT']
  
      def parseElement(self, xmlElement, parent = None):
          if xmlElement.tag == 'UNIT':
              return self._parseUnit(xmlElement, parent)
          else:
              return None
  
      def _parseUnit(self, xmlRoot, parent=None):
          assert (xmlRoot.tag == 'UNIT')
          name = self.parseTextNode(xmlRoot.find("./SHORT-NAME"))
          displayName = self.parseTextNode(xmlRoot.find("./DISPLAY-NAME"))
          if self.version>=4.0:
              factor = self.parseTextNode(xmlRoot.find("./FACTOR-SI-TO-UNIT"))
              offset = self.parseTextNode(xmlRoot.find("./OFFSET-SI-TO-UNIT"))
          else:
              (factor,offset) = (None, None)
          return autosar.datatype.Unit(name, displayName, factor, offset, parent)
  