#
# Autogenerated by Thrift Compiler (0.18.1)
#
# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
#
#  options string: py
#

from thrift.Thrift import TType, TMessageType, TFrozenDict, TException, TApplicationException
from thrift.protocol.TProtocol import TProtocolException
from thrift.TRecursive import fix_spec

import sys
import airavata.model.commons.ttypes
import airavata.model.appcatalog.parallelism.ttypes

from thrift.transport import TTransport
all_structs = []


class SetEnvPaths(object):
    """
    Key Value pairs to be used to set environments

    name:
      Name of the environment variable such as PATH, LD_LIBRARY_PATH, NETCDF_HOME.

    value:
      Value of the environment variable to set

    envPathOrder:
      The order of the setting of the env variables when there are multiple env variables

    Attributes:
     - name
     - value
     - envPathOrder

    """


    def __init__(self, name=None, value=None, envPathOrder=None,):
        self.name = name
        self.value = value
        self.envPathOrder = envPathOrder

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRING:
                    self.name = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRING:
                    self.value = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.I32:
                    self.envPathOrder = iprot.readI32()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('SetEnvPaths')
        if self.name is not None:
            oprot.writeFieldBegin('name', TType.STRING, 1)
            oprot.writeString(self.name.encode('utf-8') if sys.version_info[0] == 2 else self.name)
            oprot.writeFieldEnd()
        if self.value is not None:
            oprot.writeFieldBegin('value', TType.STRING, 2)
            oprot.writeString(self.value.encode('utf-8') if sys.version_info[0] == 2 else self.value)
            oprot.writeFieldEnd()
        if self.envPathOrder is not None:
            oprot.writeFieldBegin('envPathOrder', TType.I32, 3)
            oprot.writeI32(self.envPathOrder)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.name is None:
            raise TProtocolException(message='Required field name is unset!')
        if self.value is None:
            raise TProtocolException(message='Required field value is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class CommandObject(object):
    """
    Job commands to be used in Pre Job, Post Job and Module Load Commands

    command:
      The actual command in string format

    commandOrder:
      Order of the command in the multiple command situation

    Attributes:
     - command
     - commandOrder

    """


    def __init__(self, command=None, commandOrder=None,):
        self.command = command
        self.commandOrder = commandOrder

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRING:
                    self.command = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.I32:
                    self.commandOrder = iprot.readI32()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('CommandObject')
        if self.command is not None:
            oprot.writeFieldBegin('command', TType.STRING, 1)
            oprot.writeString(self.command.encode('utf-8') if sys.version_info[0] == 2 else self.command)
            oprot.writeFieldEnd()
        if self.commandOrder is not None:
            oprot.writeFieldBegin('commandOrder', TType.I32, 2)
            oprot.writeI32(self.commandOrder)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.command is None:
            raise TProtocolException(message='Required field command is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class ApplicationModule(object):
    """
    Application Module Information. A module has to be registered before registering a deployment.

    appModuleId: Airavata Internal Unique Job ID. This is set by the registry.

    appModuleName:
      Name of the application module.

    appModuleVersion:
      Version of the application.

    appModuleDescription:
       Descriprion of the Module


    Attributes:
     - appModuleId
     - appModuleName
     - appModuleVersion
     - appModuleDescription

    """


    def __init__(self, appModuleId="DO_NOT_SET_AT_CLIENTS", appModuleName=None, appModuleVersion=None, appModuleDescription=None,):
        self.appModuleId = appModuleId
        self.appModuleName = appModuleName
        self.appModuleVersion = appModuleVersion
        self.appModuleDescription = appModuleDescription

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRING:
                    self.appModuleId = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRING:
                    self.appModuleName = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRING:
                    self.appModuleVersion = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 4:
                if ftype == TType.STRING:
                    self.appModuleDescription = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('ApplicationModule')
        if self.appModuleId is not None:
            oprot.writeFieldBegin('appModuleId', TType.STRING, 1)
            oprot.writeString(self.appModuleId.encode('utf-8') if sys.version_info[0] == 2 else self.appModuleId)
            oprot.writeFieldEnd()
        if self.appModuleName is not None:
            oprot.writeFieldBegin('appModuleName', TType.STRING, 2)
            oprot.writeString(self.appModuleName.encode('utf-8') if sys.version_info[0] == 2 else self.appModuleName)
            oprot.writeFieldEnd()
        if self.appModuleVersion is not None:
            oprot.writeFieldBegin('appModuleVersion', TType.STRING, 3)
            oprot.writeString(self.appModuleVersion.encode('utf-8') if sys.version_info[0] == 2 else self.appModuleVersion)
            oprot.writeFieldEnd()
        if self.appModuleDescription is not None:
            oprot.writeFieldBegin('appModuleDescription', TType.STRING, 4)
            oprot.writeString(self.appModuleDescription.encode('utf-8') if sys.version_info[0] == 2 else self.appModuleDescription)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.appModuleId is None:
            raise TProtocolException(message='Required field appModuleId is unset!')
        if self.appModuleName is None:
            raise TProtocolException(message='Required field appModuleName is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)


class ApplicationDeploymentDescription(object):
    """
    Application Deployment Description

    appDeploymentId: Airavata Internal Unique Job ID. This is set by the registry.

    appModuleName:
      Application Module Name. This has to be precise describing the binary.

    computeHostId:
      This ID maps application deployment to a particular resource previously described within Airavata.
      Example: Stampede is first registered and refered when registering WRF.

    moduleLoadCmd:
     Command string to load modules. This will be placed in the job submisison
     Ex: module load amber

    libPrependPaths:
     prepend to a path variable the value

    libAppendPaths:
     append to a path variable the value

    setEnvironment:
     assigns to the environment variable "NAME" the value


    Attributes:
     - appDeploymentId
     - appModuleId
     - computeHostId
     - executablePath
     - parallelism
     - appDeploymentDescription
     - moduleLoadCmds
     - libPrependPaths
     - libAppendPaths
     - setEnvironment
     - preJobCommands
     - postJobCommands
     - defaultQueueName
     - defaultNodeCount
     - defaultCPUCount
     - defaultWalltime
     - editableByUser

    """


    def __init__(self, appDeploymentId="DO_NOT_SET_AT_CLIENTS", appModuleId=None, computeHostId=None, executablePath=None, parallelism=    0, appDeploymentDescription=None, moduleLoadCmds=None, libPrependPaths=None, libAppendPaths=None, setEnvironment=None, preJobCommands=None, postJobCommands=None, defaultQueueName=None, defaultNodeCount=None, defaultCPUCount=None, defaultWalltime=None, editableByUser=None,):
        self.appDeploymentId = appDeploymentId
        self.appModuleId = appModuleId
        self.computeHostId = computeHostId
        self.executablePath = executablePath
        self.parallelism = parallelism
        self.appDeploymentDescription = appDeploymentDescription
        self.moduleLoadCmds = moduleLoadCmds
        self.libPrependPaths = libPrependPaths
        self.libAppendPaths = libAppendPaths
        self.setEnvironment = setEnvironment
        self.preJobCommands = preJobCommands
        self.postJobCommands = postJobCommands
        self.defaultQueueName = defaultQueueName
        self.defaultNodeCount = defaultNodeCount
        self.defaultCPUCount = defaultCPUCount
        self.defaultWalltime = defaultWalltime
        self.editableByUser = editableByUser

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRING:
                    self.appDeploymentId = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRING:
                    self.appModuleId = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRING:
                    self.computeHostId = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 4:
                if ftype == TType.STRING:
                    self.executablePath = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 5:
                if ftype == TType.I32:
                    self.parallelism = iprot.readI32()
                else:
                    iprot.skip(ftype)
            elif fid == 6:
                if ftype == TType.STRING:
                    self.appDeploymentDescription = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 7:
                if ftype == TType.LIST:
                    self.moduleLoadCmds = []
                    (_etype3, _size0) = iprot.readListBegin()
                    for _i4 in range(_size0):
                        _elem5 = CommandObject()
                        _elem5.read(iprot)
                        self.moduleLoadCmds.append(_elem5)
                    iprot.readListEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 8:
                if ftype == TType.LIST:
                    self.libPrependPaths = []
                    (_etype9, _size6) = iprot.readListBegin()
                    for _i10 in range(_size6):
                        _elem11 = SetEnvPaths()
                        _elem11.read(iprot)
                        self.libPrependPaths.append(_elem11)
                    iprot.readListEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 9:
                if ftype == TType.LIST:
                    self.libAppendPaths = []
                    (_etype15, _size12) = iprot.readListBegin()
                    for _i16 in range(_size12):
                        _elem17 = SetEnvPaths()
                        _elem17.read(iprot)
                        self.libAppendPaths.append(_elem17)
                    iprot.readListEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 10:
                if ftype == TType.LIST:
                    self.setEnvironment = []
                    (_etype21, _size18) = iprot.readListBegin()
                    for _i22 in range(_size18):
                        _elem23 = SetEnvPaths()
                        _elem23.read(iprot)
                        self.setEnvironment.append(_elem23)
                    iprot.readListEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 11:
                if ftype == TType.LIST:
                    self.preJobCommands = []
                    (_etype27, _size24) = iprot.readListBegin()
                    for _i28 in range(_size24):
                        _elem29 = CommandObject()
                        _elem29.read(iprot)
                        self.preJobCommands.append(_elem29)
                    iprot.readListEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 12:
                if ftype == TType.LIST:
                    self.postJobCommands = []
                    (_etype33, _size30) = iprot.readListBegin()
                    for _i34 in range(_size30):
                        _elem35 = CommandObject()
                        _elem35.read(iprot)
                        self.postJobCommands.append(_elem35)
                    iprot.readListEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 13:
                if ftype == TType.STRING:
                    self.defaultQueueName = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 14:
                if ftype == TType.I32:
                    self.defaultNodeCount = iprot.readI32()
                else:
                    iprot.skip(ftype)
            elif fid == 15:
                if ftype == TType.I32:
                    self.defaultCPUCount = iprot.readI32()
                else:
                    iprot.skip(ftype)
            elif fid == 16:
                if ftype == TType.I32:
                    self.defaultWalltime = iprot.readI32()
                else:
                    iprot.skip(ftype)
            elif fid == 17:
                if ftype == TType.BOOL:
                    self.editableByUser = iprot.readBool()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('ApplicationDeploymentDescription')
        if self.appDeploymentId is not None:
            oprot.writeFieldBegin('appDeploymentId', TType.STRING, 1)
            oprot.writeString(self.appDeploymentId.encode('utf-8') if sys.version_info[0] == 2 else self.appDeploymentId)
            oprot.writeFieldEnd()
        if self.appModuleId is not None:
            oprot.writeFieldBegin('appModuleId', TType.STRING, 2)
            oprot.writeString(self.appModuleId.encode('utf-8') if sys.version_info[0] == 2 else self.appModuleId)
            oprot.writeFieldEnd()
        if self.computeHostId is not None:
            oprot.writeFieldBegin('computeHostId', TType.STRING, 3)
            oprot.writeString(self.computeHostId.encode('utf-8') if sys.version_info[0] == 2 else self.computeHostId)
            oprot.writeFieldEnd()
        if self.executablePath is not None:
            oprot.writeFieldBegin('executablePath', TType.STRING, 4)
            oprot.writeString(self.executablePath.encode('utf-8') if sys.version_info[0] == 2 else self.executablePath)
            oprot.writeFieldEnd()
        if self.parallelism is not None:
            oprot.writeFieldBegin('parallelism', TType.I32, 5)
            oprot.writeI32(self.parallelism)
            oprot.writeFieldEnd()
        if self.appDeploymentDescription is not None:
            oprot.writeFieldBegin('appDeploymentDescription', TType.STRING, 6)
            oprot.writeString(self.appDeploymentDescription.encode('utf-8') if sys.version_info[0] == 2 else self.appDeploymentDescription)
            oprot.writeFieldEnd()
        if self.moduleLoadCmds is not None:
            oprot.writeFieldBegin('moduleLoadCmds', TType.LIST, 7)
            oprot.writeListBegin(TType.STRUCT, len(self.moduleLoadCmds))
            for iter36 in self.moduleLoadCmds:
                iter36.write(oprot)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        if self.libPrependPaths is not None:
            oprot.writeFieldBegin('libPrependPaths', TType.LIST, 8)
            oprot.writeListBegin(TType.STRUCT, len(self.libPrependPaths))
            for iter37 in self.libPrependPaths:
                iter37.write(oprot)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        if self.libAppendPaths is not None:
            oprot.writeFieldBegin('libAppendPaths', TType.LIST, 9)
            oprot.writeListBegin(TType.STRUCT, len(self.libAppendPaths))
            for iter38 in self.libAppendPaths:
                iter38.write(oprot)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        if self.setEnvironment is not None:
            oprot.writeFieldBegin('setEnvironment', TType.LIST, 10)
            oprot.writeListBegin(TType.STRUCT, len(self.setEnvironment))
            for iter39 in self.setEnvironment:
                iter39.write(oprot)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        if self.preJobCommands is not None:
            oprot.writeFieldBegin('preJobCommands', TType.LIST, 11)
            oprot.writeListBegin(TType.STRUCT, len(self.preJobCommands))
            for iter40 in self.preJobCommands:
                iter40.write(oprot)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        if self.postJobCommands is not None:
            oprot.writeFieldBegin('postJobCommands', TType.LIST, 12)
            oprot.writeListBegin(TType.STRUCT, len(self.postJobCommands))
            for iter41 in self.postJobCommands:
                iter41.write(oprot)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        if self.defaultQueueName is not None:
            oprot.writeFieldBegin('defaultQueueName', TType.STRING, 13)
            oprot.writeString(self.defaultQueueName.encode('utf-8') if sys.version_info[0] == 2 else self.defaultQueueName)
            oprot.writeFieldEnd()
        if self.defaultNodeCount is not None:
            oprot.writeFieldBegin('defaultNodeCount', TType.I32, 14)
            oprot.writeI32(self.defaultNodeCount)
            oprot.writeFieldEnd()
        if self.defaultCPUCount is not None:
            oprot.writeFieldBegin('defaultCPUCount', TType.I32, 15)
            oprot.writeI32(self.defaultCPUCount)
            oprot.writeFieldEnd()
        if self.defaultWalltime is not None:
            oprot.writeFieldBegin('defaultWalltime', TType.I32, 16)
            oprot.writeI32(self.defaultWalltime)
            oprot.writeFieldEnd()
        if self.editableByUser is not None:
            oprot.writeFieldBegin('editableByUser', TType.BOOL, 17)
            oprot.writeBool(self.editableByUser)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.appDeploymentId is None:
            raise TProtocolException(message='Required field appDeploymentId is unset!')
        if self.appModuleId is None:
            raise TProtocolException(message='Required field appModuleId is unset!')
        if self.computeHostId is None:
            raise TProtocolException(message='Required field computeHostId is unset!')
        if self.executablePath is None:
            raise TProtocolException(message='Required field executablePath is unset!')
        if self.parallelism is None:
            raise TProtocolException(message='Required field parallelism is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(SetEnvPaths)
SetEnvPaths.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'name', 'UTF8', None, ),  # 1
    (2, TType.STRING, 'value', 'UTF8', None, ),  # 2
    (3, TType.I32, 'envPathOrder', None, None, ),  # 3
)
all_structs.append(CommandObject)
CommandObject.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'command', 'UTF8', None, ),  # 1
    (2, TType.I32, 'commandOrder', None, None, ),  # 2
)
all_structs.append(ApplicationModule)
ApplicationModule.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'appModuleId', 'UTF8', "DO_NOT_SET_AT_CLIENTS", ),  # 1
    (2, TType.STRING, 'appModuleName', 'UTF8', None, ),  # 2
    (3, TType.STRING, 'appModuleVersion', 'UTF8', None, ),  # 3
    (4, TType.STRING, 'appModuleDescription', 'UTF8', None, ),  # 4
)
all_structs.append(ApplicationDeploymentDescription)
ApplicationDeploymentDescription.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'appDeploymentId', 'UTF8', "DO_NOT_SET_AT_CLIENTS", ),  # 1
    (2, TType.STRING, 'appModuleId', 'UTF8', None, ),  # 2
    (3, TType.STRING, 'computeHostId', 'UTF8', None, ),  # 3
    (4, TType.STRING, 'executablePath', 'UTF8', None, ),  # 4
    (5, TType.I32, 'parallelism', None,     0, ),  # 5
    (6, TType.STRING, 'appDeploymentDescription', 'UTF8', None, ),  # 6
    (7, TType.LIST, 'moduleLoadCmds', (TType.STRUCT, [CommandObject, None], False), None, ),  # 7
    (8, TType.LIST, 'libPrependPaths', (TType.STRUCT, [SetEnvPaths, None], False), None, ),  # 8
    (9, TType.LIST, 'libAppendPaths', (TType.STRUCT, [SetEnvPaths, None], False), None, ),  # 9
    (10, TType.LIST, 'setEnvironment', (TType.STRUCT, [SetEnvPaths, None], False), None, ),  # 10
    (11, TType.LIST, 'preJobCommands', (TType.STRUCT, [CommandObject, None], False), None, ),  # 11
    (12, TType.LIST, 'postJobCommands', (TType.STRUCT, [CommandObject, None], False), None, ),  # 12
    (13, TType.STRING, 'defaultQueueName', 'UTF8', None, ),  # 13
    (14, TType.I32, 'defaultNodeCount', None, None, ),  # 14
    (15, TType.I32, 'defaultCPUCount', None, None, ),  # 15
    (16, TType.I32, 'defaultWalltime', None, None, ),  # 16
    (17, TType.BOOL, 'editableByUser', None, None, ),  # 17
)
fix_spec(all_structs)
del all_structs
