summaryrefslogtreecommitdiff
path: root/qface/idl/listener.py
diff options
context:
space:
mode:
Diffstat (limited to 'qface/idl/listener.py')
-rw-r--r--qface/idl/listener.py197
1 files changed, 197 insertions, 0 deletions
diff --git a/qface/idl/listener.py b/qface/idl/listener.py
new file mode 100644
index 0000000..b257005
--- /dev/null
+++ b/qface/idl/listener.py
@@ -0,0 +1,197 @@
+# Copyright (c) Pelagicore AB 2016
+import logging
+from _operator import concat
+
+from .parser.TListener import TListener
+from .parser.TParser import TParser
+from .domain import *
+from antlr4 import ParserRuleContext
+
+
+log = logging.getLogger(__name__)
+
+# associates parser context to domain objects
+contextMap = {}
+
+class DomainListener(TListener):
+ """The domain listener is called by the parser to fill the
+ domain data struture. As a result a system is passed
+ back"""
+ def __init__(self, system):
+ super(DomainListener, self).__init__()
+ contextMap.clear()
+ self.system = system or System() # type:System
+ self.module = None # type:Module
+ self.interface = None # type:Interface
+ self.struct = None # type:Struct
+ self.enum = None # type:Enum
+ self.enumCounter = 0 # int
+ self.operation = None # type:Operation
+ self.parameter = None # type:Parameter
+ self.property = None # type:Property
+ self.field = None # type:Field
+
+ def parse_type(self, ctx: ParserRuleContext, type: TypeSymbol):
+ if not ctx.typeSymbol():
+ # import pdb; pdb.set_trace()
+ type.is_void = True
+ type.name = 'void'
+ else:
+ if ctx.typeSymbol().primitiveTypeSymbol():
+ ctxSymbol = ctx.typeSymbol().primitiveTypeSymbol() # type:TParser.PrimitiveTypeSymbolContext
+ type.is_primitive = True
+ type.name = ctxSymbol.name.text
+ elif ctx.typeSymbol().complexTypeSymbol():
+ ctxSymbol = ctx.typeSymbol().complexTypeSymbol() # type:TParser.ComplexTypeSymbolContext
+ type.is_complex = True
+ type.name = ctxSymbol.name.text
+ elif ctx.typeSymbol().listTypeSymbol():
+ ctxSymbol = ctx.typeSymbol().listTypeSymbol() # type:TParser.ListTypeSymbolContext
+ type.is_list = True
+ type.name = 'list'
+ type.nested = TypeSymbol("", type)
+ self.parse_type(ctxSymbol, type.nested)
+ elif ctx.typeSymbol().modelTypeSymbol():
+ ctxSymbol = ctx.typeSymbol().modelTypeSymbol() # type:TParser.ModelTypeSymbolContext
+ type.is_model = True
+ type.name = 'model'
+ type.nested = TypeSymbol("", type)
+ self.parse_type(ctxSymbol, type.nested)
+ if not type.module.checkType(type):
+ log.warn('Unknown type: {0}. Missing import?'.format(type.name))
+
+ def parse_comment(self, ctx, symbol):
+ if ctx.comment:
+ comment = ctx.comment.text
+ symbol.comment = comment
+
+ def enterEveryRule(self, ctx):
+ log.debug('enter ' + ctx.__class__.__name__)
+
+ def exitEveryRule(self, ctx):
+ log.debug('exit ' + ctx.__class__.__name__)
+
+ def enterModuleSymbol(self, ctx: TParser.ModuleSymbolContext):
+ assert self.system
+ name = ctx.name.text
+ version = ctx.version.text
+ self.module = Module(name, self.system)
+ self.module.version = version
+ contextMap[ctx] = self.module
+
+ def exitModuleSymbol(self, ctx: TParser.ModuleSymbolContext):
+ pass
+
+ def enterInterfaceSymbol(self, ctx: TParser.InterfaceSymbolContext):
+ assert self.module
+ name = ctx.name.text
+ self.interface = Interface(name, self.module)
+ self.parse_comment(ctx, self.interface)
+ contextMap[ctx] = self.interface
+
+ def exitInterfaceSymbol(self, ctx: TParser.InterfaceSymbolContext):
+ self.interface = None
+
+ def enterStructSymbol(self, ctx: TParser.StructSymbolContext):
+ assert self.module
+ name = ctx.name.text
+ self.struct = Struct(name, self.module)
+ self.parse_comment(ctx, self.struct)
+ contextMap[ctx] = self.struct
+
+ def exitStructSymbol(self, ctx: TParser.StructSymbolContext):
+ self.struct = None
+
+ def enterEnumSymbol(self, ctx: TParser.EnumSymbolContext):
+ assert self.module
+ name = ctx.name.text
+ # import ipdb; ipdb.set_trace()
+ self.enum = Enum(name, self.module)
+ self.parse_comment(ctx, self.enum)
+ contextMap[ctx] = self.enum
+
+ def exitEnumSymbol(self, ctx: TParser.EnumSymbolContext):
+ self.enum = None
+ self.enumCounter = 0
+
+ def enterEnumTypeSymbol(self, ctx: TParser.EnumTypeSymbolContext):
+ assert self.enum
+ self.enumCounter = 0
+ if ctx.isFlag:
+ self.enum.is_enum = False
+ self.enum.is_flag = True
+ self.enumCounter = 1
+
+ def exitEnumTypeSymbol(self, ctx: TParser.EnumTypeSymbolContext):
+ pass
+
+ def enterOperationSymbol(self, ctx: TParser.OperationSymbolContext):
+ assert self.interface
+ name = ctx.name.text
+ is_event = bool(ctx.isEvent)
+ self.operation = Operation(name, self.interface, is_event)
+ self.parse_comment(ctx, self.operation)
+ self.parse_type(ctx, self.operation.type)
+ contextMap[ctx] = self.operation
+
+ def exitOperationSymbol(self, ctx: TParser.OperationSymbolContext):
+ self.operation = None
+
+ def enterOperationParameterSymbol(self, ctx: TParser.OperationParameterSymbolContext):
+ name = ctx.name.text
+ self.parameter = Parameter(name, self.operation)
+ contextMap[ctx] = self.parameter
+
+ def exitOperationParameterSymbol(self, ctx: TParser.OperationParameterSymbolContext):
+ self.parse_type(ctx, self.parameter.type)
+
+ def enterPropertySymbol(self, ctx: TParser.PropertySymbolContext):
+ assert self.interface
+ name = ctx.name.text
+ self.property = Property(name, self.interface)
+ self.property.is_readonly = bool(ctx.isReadOnly)
+ self.parse_comment(ctx, self.property)
+ self.parse_type(ctx, self.property.type)
+ contextMap[ctx] = self.property
+
+ def exitPropertySymbol(self, ctx: TParser.PropertySymbolContext):
+ self.property = None
+
+ def enterStructFieldSymbol(self, ctx: TParser.StructFieldSymbolContext):
+ assert self.struct
+ name = ctx.name.text
+ self.field = Field(name, self.struct)
+ contextMap[ctx] = self.field
+
+ def exitStructFieldSymbol(self, ctx: TParser.StructFieldSymbolContext):
+ self.parse_type(ctx, self.field.type)
+ self.field = None
+
+ def enterEnumMemberSymbol(self, ctx: TParser.EnumMemberSymbolContext):
+ assert self.enum
+ name = ctx.name.text
+ self.field = EnumMember(name, self.enum)
+ value = self.enumCounter
+ if ctx.intSymbol():
+ value = int(ctx.intSymbol().value.text, 0)
+ self.field.value = value
+ contextMap[ctx] = self.field
+ # import ipdb; ipdb.set_trace()
+ if self.enum.is_flag:
+ self.enumCounter <<= 1
+ else:
+ self.enumCounter += 1
+
+ def exitEnumMemberSymbol(self, ctx: TParser.EnumMemberSymbolContext):
+ self.field = None
+
+ def enterImportSymbol(self, ctx: TParser.ImportSymbolContext):
+ assert self.module
+ name = ctx.name.text
+ version = ctx.version.text
+ # import ipdb; ipdb.set_trace()
+ self.module._importMap[name] = '{0} {1}'.format(name, version)
+
+ def exitImportSymbol(self, ctx: TParser.ImportSymbolContext):
+ pass
+