ttcn3mapping.etl 46.3 KB
Newer Older
	                    var ci = mr.collectionIndex.dataInstance.equivalent();
	                    if (ci.isKindOf(TTCN!TemplateDef)) {
	                        efr.array.ref.head.target = ci.base;
	                    } else if (ci.isKindOf(TTCN!ConstDef)) {
	                        efr.array.ref.head.target = ci.defs.list.get(0);             
	                    } else {
	                        //what else can it be?
	                    }

	                    body.simple.expr.ref.fields.add(efr);
	                }
                }            
            } else {
                var t = body.simple.expr.ref.head;
                for (mr in mad.reduction) {
                    if (mr.member.isDefined()) {
                        t.tail = new TTCN!RefValueTail();
                        t.tail.value = mr.member.equivalent();
                        
                    }
                    t = t.tail;
                }
            }
            
        } else {
            //nested anonymous definitions
            //or overriding
            body.field = mad.transformWildcardMemberAssignment();
        }
    } else {
        body.simple = new TTCN!SimpleSpec();
        body.simple.spec = new TTCN!SimpleTemplateSpec();
        body.simple.spec.expr = new TTCN!SingleTemplateExpression();
        body.simple.spec.expr.symbol = new TTCN!MatchingSymbol();
        if (mad.isUndefined() 
          and self.unassignedMember.isDefined() 
          and self.unassignedMember.name = "AnyValueOrOmit") {
            if (m.isOptional) {
                body.simple.spec.expr.symbol.anyornone = "*";
            } else {
                body.simple.spec.expr.symbol.any = "?";
            }
        } else if (mad.isUndefined() 
          and self.unassignedMember.isDefined() 
          and self.unassignedMember.name = "AnyValue") {
            body.simple.spec.expr.symbol.any = "?";
        } else if (mad.isDefined() 
          and mad.isKindOf(TDL!AnyValue)) {
            body.simple.spec.expr.symbol.any = "?";
        } else if (mad.isDefined() 
          and mad.isKindOf(TDL!AnyValueOrOmit)) {
            body.simple.spec.expr.symbol.anyornone = "*";
        } else if (mad.isDefined()) {
            ("TODO: Implement?").log(1);
        } 
    }
    return body;
}

operation TDL!StaticDataUse transformWildcardMemberAssignment() : TTCN!FieldSpecList {
    //dataInstance? or inferred type
    //unassignedMember?
    //argument -> ParameterBinding (parameter:Member, dataUse:DataUse)
    //reduction? -> MemberReference
    var field = new TTCN!FieldSpecList();
    var t;
    if (self.dataInstance.isDefined()) {
        t = self.dataInstance.dataType;
        ("DI:"+self.dataInstance.name).log(1);
    } else {
        if (self.eContainer.isKindOf(TDL!ParameterBinding)) {
            t = self.eContainer.parameter.dataType;
        } else if (self.eContainer.isKindOf(TDL!MemberAssignment)) {
            t = self.eContainer.member.dataType;
        } else {
            ("TODO: Context Not Implemented Yet").log(1);
        }
    }
    for (m in t.member) {
        var fs = new TTCN!FieldSpec(); 
        fs.ref = m.equivalent();
        
        var mad;
        var ma = self.argument.selectOne(a|a.parameter = m);
        //default: no wildcard, defined
        //in case not defined, check for inherited
        if (ma.isDefined()) {
            mad = ma.dataUse;
        } else if (ma.isUndefined() 
          and self.isKindOf(TDL!DataInstanceUse) 
          and self.dataInstance.isDefined()) {
            var mai = self.dataInstance.memberAssignment.selectOne(a|a.member = m);
            if (mai.isDefined()) {
	            mad = mai.memberSpec;
            } 
        } else {
            
        }  

        fs.body = self.transformSingleMemberAssignment(m, mad);
        field.spec.add(fs);
    }
    return field;

}

operation TDL!StructuredDataInstance transformWildcardMemberAssignment() : TTCN!FieldSpecList {
    var field = new TTCN!FieldSpecList();
    for (m in self.dataType.member) {
        var fs = new TTCN!FieldSpec(); 
        fs.ref = m.equivalent();
        
        var ma = self.memberAssignment.selectOne(ma|ma.member = m);
        var mad;
        if (ma.isDefined()) {
            mad = ma.memberSpec;
        } 

        fs.body = new TTCN!TemplateBody();
        fs.body = self.transformSingleMemberAssignment(m, mad);
        field.spec.add(fs);
    }
    return field;
}

//TODO: deprecated?
operation TDL!StructuredDataInstance transformMemberAssignment() : TTCN!CompoundExpression {
    var expr;
    if (not self.memberAssignment.isEmpty()) {
        expr = new TTCN!FieldExpressionList();
        for (ma in self.memberAssignment) {
            var fes = new TTCN!FieldExpressionSpec(); 
            fes.fieldRef = ma.member.equivalent();
            
            //ma.memberSpec
            fes.expr = new TTCN!Value();
            if (ma.memberSpec.isKindOf(TDL!DataInstanceUse) 
              and ma.memberSpec.dataInstance.isDefined()) {
                fes.expr.ref = new TTCN!ReferencedValue();
                fes.expr.ref.head = new TTCN!Head();
                
                //Template ->target = BaseTemplate reference
                //Constant ->target = SingleConstDef reference
                var e = ma.memberSpec.dataInstance.equivalent();
                if (e.isKindOf(TTCN!TemplateDef)) {
                    fes.expr.ref.head.target = e.base;
                } else if (e.isKindOf(TTCN!ConstDef)) {
                    fes.expr.ref.head.target = e.defs.list.get(0);             
                } else {
                    //what else can it be?
                }
                //TODO: handle overriding parameters?
            } else {
                fes.expr.predef = new TTCN!PredefinedValue();
                fes.expr.predef.charString = "\"TODO: Not Implemented Yet\"";
            }
        
            expr.specs.add(fes);
        }
        //TODO: handle unassigned members? -> add guards to corresponding rule
        //TODO: handle special characters
        var assigned = self.memberAssignment.collect(ma|ma.member);
        for (m in self.dataType.member.excludingAll(assigned)) {
            (self.name + ": Skipping unassigned member "+m.name).log(1);
        }
        
    } else {
        expr = new TTCN!ArrayExpression();
    }
    return expr;

}

operation TDL!DataType getTTCNType() : TTCN!Type {
    var type = new TTCN!Type();
    if (resolvePredefined and self.name == "String") {
        //TODO: add support for universal
	    type.`pre` = "charstring";
    } else if (resolvePredefined and self.name == "Integer") {
        type.`pre` = "integer";
    } else if (resolvePredefined and self.name == "Boolean") {
        type.`pre` = "boolean";
    } else if (resolvePredefined and self.name == "Verdict") {
        type.`pre` = "verdicttype";
    } else {
        //TODO: use data mapping to overide predefined?
        if (useDataMapping) {
            //TODO: handle predefined types?
            //t.`pre` = "TODO_"+dt.name;
            //use mappings, simple approach
            var mapping = TDL!DataElementMapping.allInstances().select(m|m.mappableDataElement = self).first();
            if (mapping.isDefined()) {
                //t.ref = new TTCN!TypeReference();
                //TODO: check if defined
                //t.ref.head = mapping.elementURI;
                type.`pre` = mapping.elementURI.replaceAll("\"","");
            } else {
                type.`pre` = "MAP_"+self.TTCNname();
            }
        } else {
            type.ref = new TTCN!TypeReference();
            //TODO: check if defined
            type.ref.head = self.equivalent();
        }
    }
    
    return type;
} 

@cached
operation TTCN!TTCN3Module getSDT() : TTCN!SubTypeDefNamed {
    if (self.~sdt.isUndefined()) {
        var sdt = new TTCN!SubTypeDefNamed();
        sdt.name = "SimpleDataType";
        sdt.type = new TTCN!Type();
        //TODO: make configurable? 
        sdt.type.`pre` = "charstring";
        var body = self.createTypeDefBody();
        body.sub = sdt;
        self.~sdt = sdt;
    } 
    return self.~sdt;
}

@cached
operation String getComponent() : TTCN!ComponentDef {
	return TTCN!ComponentDef.allInstances().select(c|c.name = self).first();
} 

@cached
operation String getFunction() : TTCN!FunctionDef {
	return TTCN!FunctionDef.allInstances().select(c|c.name = self).first();
} 

operation TDL!GateReference checkGateReference() : Boolean {
    var accepted = false;
    if (self.component.role.name = "Tester") {
        accepted = true;
    }
    if (self.component.role.name = "SUT") {
        if (self.eContainer.isKindOf(TDL!Connection)) {
            var opposite = self.eContainer.endPoint.select(e|e <> self).first();
            if (opposite.component.role.name = "Tester") {
		        accepted = true;
            }
        }
    }
    return accepted;
}

operation TDL!GateReference mergeIntoSUT(sut : TTCN!TypeDefBody) {
    var pe = new TTCN!PortElement();

    pe.name = self.component.TTCNname()+"_"+self.gate.TTCNname();

    var d = new TTCN!ComponentDefList();
    sut.structured.component.defs.add(d);

    d.sc = ";";
    d.element = new TTCN!ComponentElementDef();
    d.element.port = new TTCN!PortInstance();

    d.element.port.ref = self.gate.type.equivalent();
    d.element.port.instances.add(pe);
    
    self.equivalent().port = pe;
}

operation TDL!DataInstanceUse getTemplateBody() : TTCN!TemplateBody {
	var tb = new TTCN!TemplateBody();
	tb.simple = new TTCN!SimpleSpec();
	tb.simple.expr = new TTCN!Value();
	if (useDataMapping) {
		var mapping = TDL!DataElementMapping.allInstances().select(m|m.mappableDataElement = self.dataInstance).first();
		tb.simple.expr.predef = new TTCN!PredefinedValue();
		if (mapping.isDefined()) {
		    //t.ref = new TTCN!TypeReference();
		    //TODO: check if defined
		    //t.ref.head = mapping.elementURI;
			tb.simple.expr.predef.charString = mapping.elementURI.replaceAll("\"","");
	    } else {
			tb.simple.expr.predef.charString = "MAP_"+self.dataInstance.name;
	    }
	} else {
		tb.simple.expr.ref = new TTCN!ReferencedValue();
		tb.simple.expr.ref.head = new TTCN!Head();
		tb.simple.expr.ref.head.target = self.dataInstance.equivalent().base;
	}
	return tb;
}

operation Any getTestDescription() : Any {
	if (self.eContainer.isDefined()) {
		if (not self.eContainer.isKindOf(TestDescription)) {
			return self.eContainer.getTestDescription();
		} else {
			return self.eContainer;
		}
	} 
}


operation TDL!Interaction executeSource() : TTCN!FunctionStatementList {
	var ssl = new TTCN!FunctionStatementList();
	
	var sfs = new TTCN!FunctionStatement();
	sfs.communication = new TTCN!CommunicationStatements();
	sfs.communication.send = new TTCN!SendStatement();
	sfs.communication.send.port = self.sourceGate.gate.equivalent();
	sfs.communication.send.send = new TTCN!PortSendOp();
	sfs.communication.send.send.template = new TTCN!InLineTemplate();
	sfs.communication.send.send.template.template = self.argument.getTemplateBody();
	
	ssl.statements.add(sfs);
	ssl.sc.add(";");
	return ssl;
}

operation TDL!Interaction executeTarget(t : TDL!Target) : TTCN!FunctionStatementList {
	var tsl = new TTCN!FunctionStatementList();
	
	var tfs = new TTCN!FunctionStatement();
	tfs.communication = new TTCN!CommunicationStatements();
	tfs.communication.receive = new TTCN!ReceiveStatement();
	tfs.communication.receive.any = new TTCN!PortOrAny();
	tfs.communication.receive.any.ref = t.targetGate.gate.equivalent();
	tfs.communication.receive.receive = new TTCN!PortReceiveOp();
	tfs.communication.receive.receive.template = new TTCN!InLineTemplate();
	tfs.communication.receive.receive.template.template = self.argument.getTemplateBody();
	
	tsl.statements.add(tfs);
	tsl.sc.add(";");
	return tsl;
}

operation TDL!Interaction execute() {
	//TODO: needs adapting to context
	//      add a statement block stack for each component during transformation?
	var td = self.getTestDescription();
	
	//var sfd = (td.name+"_"+self.sourceGate.component.name+"_main").getFunction();
	//var sb = sfd.statement;
	var sc = self.getMainContext(self.sourceGate.component);
	var sb = stack.get(sc).last();

	//var tfd = (td.name+"_"+self.target.first().targetGate.component.name+"_main").getFunction();
	//var tb = tfd.statement;
	var tc = self.getMainContext(self.target.first().targetGate.component);
	var tb = stack.get(tc).last();

	self.execute(sb, tb);
}

operation TDL!Interaction execute(sourceContext : TTCN!StatementBlock, targetContext : TTCN!StatementBlock) {
	//source behaviour
	var ssl = self.executeSource();
	sourceContext.stat.add(ssl);
	//TODO: handle multicast?
	//target behaviour
	var t = self.target.first();
	var tsl = self.executeTarget(t);
	targetContext.stat.add(tsl);

}

operation TDL!Behaviour getMainContext(component : TDL!ComponentInstance) : String {
	return self.getTestDescription().name+"_"+component.name+"_main";
}

operation TDL!AlternativeBehaviour execute() {
	if (not transformAlt) return;
	var td = self.getTestDescription();
	//TODO: naive simplified assumption
	var fb = self.block.first().behaviour.first();
	if (fb.isKindOf(TDL!Interaction)) {
		var sc = self.getMainContext(fb.sourceGate.component);
		var sb = stack.get(sc).last();
		self.executeSource(sb);

		var tc = self.getMainContext(fb.target.first().targetGate.component);
		var tb = stack.get(tc).last();
		self.executeTarget(tb);
	}
	
}

operation TDL!AlternativeBehaviour executeTarget(targetContext : TTCN!StatementBlock) {
	var tsl = self.executeTarget();
	targetContext.stat.add(tsl);
}

operation TDL!AlternativeBehaviour executeSource(sourceContext : TTCN!StatementBlock) {
	//TODO: simple assumption - trigger first
	//TODO: needs to follow path, right now triggers first interactions in other branches as well
	var fb = self.block.first().behaviour.first();
	if (fb.isKindOf(TDL!Interaction)) {
		var ssl = fb.executeSource();
		sourceContext.stat.add(ssl);
	}
}

operation TDL!AlternativeBehaviour checkPath() : Boolean {
	var first = true;
	if (self.eContainer.isDefined()) {
		if (self.eContainer.isKindOf(TDL!Block)) {
			if (self.eContainer.eContainer.isKindOf(TDL!AlternativeBehaviour)) {
				if (self.eContainer.eContainer.block.indexOf(self.eContainer) <> 0) {
					first = false;
				} else {
					first = self.eContainer.eContainer.checkPath();
				}
			}
		}
	} 
	
	return first;
}


operation TDL!AlternativeBehaviour executeTarget() : TTCN!FunctionStatementList {
	if (not transformAlt) return;
	//TODO
	
	//target only so far..
	//where should this be placed? in the receiving side?
	//how about source
	//TODO: add explicit scoping
	
	var tsl = new TTCN!FunctionStatementList();
	
	var fs = new TTCN!FunctionStatement();
	fs.behavior = new TTCN!BehaviourStatements();
	fs.behavior.alt = new TTCN!AltConstruct();
	fs.behavior.alt.agList = new TTCN!AltGuardList();
	
	for (block in self.block) {
		var gs = block.executeAltBlock();
		fs.behavior.alt.agList.guardList.add(gs);
	}
	
	tsl.statements.add(fs);
	//tsl.sc.add(";");
	return tsl;
}


operation TDL!Block executeAltBlock() : TTCN!GuardStatement {
	var gs = new TTCN!GuardStatement();
	gs.`guard` = new TTCN!AltGuardChar();
	//TODO: expression

	gs.block = new TTCN!StatementBlock();
	
	//naive assumption
	var cf = self.behaviour.first().getMainContext(self.behaviour.first().target.first().targetGate.component);
	stack.get(cf).add(gs.block);
	
	var i = 0;
	for (b in self.behaviour) {
		if (i==0) {
			if (b.isKindOf(TDL!Interaction)) {
				gs.op = b.getGuardOp();
			} else {
				//TODO: handle other behaviours?	
			}
		} else {
			b.execute();
		}
		i = i+1;
	}

	stack.get(cf).remove(gs.block);
	//TODO: statement block
	return gs;
}

operation TDL!Interaction getGuardOp() : TTCN!GuardOp {
	var op = new TTCN!GuardOp();
	op.receive = new TTCN!ReceiveStatement();
	op.receive.any = new TTCN!PortOrAny();
	//TODO: handle broadcast?
	op.receive.any.ref = self.target.first().targetGate.gate.equivalent();
	op.receive.receive = new TTCN!PortReceiveOp();
	op.receive.receive.template = new TTCN!InLineTemplate();
	op.receive.receive.template.template = self.argument.getTemplateBody();
	return op;
}

operation TDL!BoundedLoopBehaviour execute() {
	//TODO
	for (b in self.block.behaviour) {
		b.execute();
	}
}

operation TDL!UnboundedLoopBehaviour execute() {
	//TODO
	for (b in self.block.behaviour) {
		b.execute();
	}
}

operation TDL!ActionReference execute() {
	//TODO
}

operation TDL!VerdictAssignment execute() {
	//TODO
}

operation TDL!CompoundBehaviour execute() {
	//TODO
	for (b in self.block.behaviour) {
		b.execute();
	}
}


operation TDL!Behaviour execute() {
	("  Skipping " +self.type.name+" (not yet supported)").println();
	if (self.type.name = "ParallelBehaviour" and false) {
		(indent+"group Parallel").printlno();
		var i = 0;
		for (block in self.block) {
			for (b in block.behaviour) {
				b.execute(indent+"  ");
			}
			if (i <= block.size()) {
				(indent+"else").printlno();
			}
			i = i+1;
		}
		(indent+"end").printlno();
	}
}