Skip to content

Commit

Permalink
feat(codegen): added wildcard support for type switch
Browse files Browse the repository at this point in the history
  • Loading branch information
sruehl committed Jan 17, 2022
1 parent bddf87d commit 30817ad
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import net.objecthunter.exp4j.Expression;
import net.objecthunter.exp4j.ExpressionBuilder;
import org.apache.plc4x.plugins.codegenerator.language.mspec.model.definitions.DefaultDataIoTypeDefinition;
import org.apache.plc4x.plugins.codegenerator.language.mspec.model.terms.WildcardTerm;
import org.apache.plc4x.plugins.codegenerator.types.definitions.*;
import org.apache.plc4x.plugins.codegenerator.types.enums.EnumValue;
import org.apache.plc4x.plugins.codegenerator.types.fields.*;
Expand Down Expand Up @@ -1136,6 +1137,10 @@ protected ImplicitField getReferencedImplicitField(VariableLiteral vl, TypeDefin
return null;
}

public boolean isWildcard(Term term) {
return term instanceof WildcardTerm;
}

/**
* can be used to throw a exception from the template
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ type I${type.name} interface {
func (m *${type.name}) ${discriminatorName?cap_first}() <#if typeRef.isComplexTypeReference() && !helper.isEnumTypeReference(typeRef)>I</#if>${helper.getLanguageTypeNameForTypeReference(typeRef)} {
<@compress single_line=true>
return
<#if discriminatorTerm??>
<#if discriminatorTerm?? && !helper.isWildcard(discriminatorTerm)>
<#if helper.isComplexTypeReference(typeRef)>
<#if helper.isEnumTypeReference(typeRef)>
<#assign enumType=helper.getLanguageTypeNameForTypeReference(typeRef)>
Expand Down Expand Up @@ -1149,30 +1149,34 @@ func ${type.name}Parse(readBuffer utils.ReadBuffer<#if hasParserArguments>, ${pa
<#if case.discriminatorValueTerms?has_content>
case
<#list case.discriminatorValueTerms as discriminatorValueTerm>
<#assign discriminatorExpression=switchField.discriminatorExpressions[discriminatorValueTerm?index]>
<#assign parsedDiscriminatorExpression=helper.toParseExpression(null, null, discriminatorExpression, parserArguments)>
<#-- We remove debug informations as we need them for lookup-->
<#assign parsedDiscriminatorExpression=tracer.removeTraces(parsedDiscriminatorExpression)>
<#if helper.getDiscriminatorTypes()[parsedDiscriminatorExpression]??><#assign discriminatorType=helper.getDiscriminatorTypes()[parsedDiscriminatorExpression]></#if>
<#if helper.isComplexTypeReference(discriminatorType)>
<#--TODO: What is meant to be here????-->
</#if>
${helper.toParseExpression(null, null, discriminatorExpression, parserArguments)} ==
<#if helper.discriminatorValueNeedsStringEqualityCheck(discriminatorExpression)>"${helper.toParseExpression(null, discriminatorType,discriminatorValueTerm, parserArguments)}"
<#elseif helper.isComplexTypeReference(discriminatorType)>
<#if helper.isEnumTypeReference(discriminatorType)>
<#assign enumType=helper.getLanguageTypeNameForTypeReference(discriminatorType)>
<#assign enumTypeWithoutTraces=tracer.removeTraces(enumType)>
<#assign enumTypeTraces=tracer.extractTraces(enumType)>
<#assign enumValue=helper.toParseExpression(null, discriminatorType,discriminatorValueTerm, parserArguments)>
<#assign enumValueWithoutTraces=tracer.removeTraces(enumValue)>
<#assign enumValueTraces=tracer.extractTraces(enumValue)>
${enumTypeTraces}${enumValueTraces}${enumTypeWithoutTraces}_${enumValueWithoutTraces}
<#if helper.isWildcard(discriminatorValueTerm)>
true
<#else>
<#assign discriminatorExpression=switchField.discriminatorExpressions[discriminatorValueTerm?index]>
<#assign parsedDiscriminatorExpression=helper.toParseExpression(null, null, discriminatorExpression, parserArguments)>
<#-- We remove debug informations as we need them for lookup-->
<#assign parsedDiscriminatorExpression=tracer.removeTraces(parsedDiscriminatorExpression)>
<#if helper.getDiscriminatorTypes()[parsedDiscriminatorExpression]??><#assign discriminatorType=helper.getDiscriminatorTypes()[parsedDiscriminatorExpression]></#if>
<#if helper.isComplexTypeReference(discriminatorType)>
<#--TODO: What is meant to be here????-->
</#if>
${helper.toParseExpression(null, null, discriminatorExpression, parserArguments)} ==
<#if helper.discriminatorValueNeedsStringEqualityCheck(discriminatorExpression)>"${helper.toParseExpression(null, discriminatorType,discriminatorValueTerm, parserArguments)}"
<#elseif helper.isComplexTypeReference(discriminatorType)>
<#if helper.isEnumTypeReference(discriminatorType)>
<#assign enumType=helper.getLanguageTypeNameForTypeReference(discriminatorType)>
<#assign enumTypeWithoutTraces=tracer.removeTraces(enumType)>
<#assign enumTypeTraces=tracer.extractTraces(enumType)>
<#assign enumValue=helper.toParseExpression(null, discriminatorType,discriminatorValueTerm, parserArguments)>
<#assign enumValueWithoutTraces=tracer.removeTraces(enumValue)>
<#assign enumValueTraces=tracer.extractTraces(enumValue)>
${enumTypeTraces}${enumValueTraces}${enumTypeWithoutTraces}_${enumValueWithoutTraces}
<#else>
${helper.toParseExpression(null, discriminatorType,discriminatorValueTerm, parserArguments)}
</#if>
<#else>
${helper.toParseExpression(null, discriminatorType,discriminatorValueTerm, parserArguments)}
</#if>
<#else>
${helper.toParseExpression(null, discriminatorType,discriminatorValueTerm, parserArguments)}
</#if>
<#sep> && </#sep>
</#list>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,18 +243,22 @@ public class ${type.name}IO implements MessageInput<${type.name}> {
<#if case.discriminatorValueTerms?has_content>
if(
<#list case.discriminatorValueTerms as discriminatorValueTerm>
<#assign discriminatorExpression=switchField.discriminatorExpressions[discriminatorValueTerm?index].asLiteral().orElseThrow().asVariableLiteral().orElseThrow()>
<#assign discriminatorType=helper.getDiscriminatorTypes()[discriminatorExpression.discriminatorName]>
EvaluationHelper.equals(
${helper.toParseExpression(switchField, discriminatorType, discriminatorExpression, parserArguments)},
<#if helper.isEnumTypeReference(discriminatorType)>
${helper.getLanguageTypeNameForTypeReference(discriminatorType)}.${helper.toParseExpression(switchField, discriminatorType, discriminatorValueTerm, parserArguments)}
<#if helper.isWildcard(discriminatorValueTerm)>
true
<#else>
${helper.toParseExpression(switchField, discriminatorType, discriminatorValueTerm, parserArguments)}
<#assign discriminatorExpression=switchField.discriminatorExpressions[discriminatorValueTerm?index].asLiteral().orElseThrow().asVariableLiteral().orElseThrow()>
<#assign discriminatorType=helper.getDiscriminatorTypes()[discriminatorExpression.discriminatorName]>
EvaluationHelper.equals(
${helper.toParseExpression(switchField, discriminatorType, discriminatorExpression, parserArguments)},
<#if helper.isEnumTypeReference(discriminatorType)>
${helper.getLanguageTypeNameForTypeReference(discriminatorType)}.${helper.toParseExpression(switchField, discriminatorType, discriminatorValueTerm, parserArguments)}
<#else>
${helper.toParseExpression(switchField, discriminatorType, discriminatorValueTerm, parserArguments)}
</#if>
)
</#if>
)
<#sep> && </#sep>
</#list>
</#list>
)
</#if>{
</@compress>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public<#if type.isDiscriminatedParentTypeDefinition()> abstract</#if> class ${ty
<#if !discriminatedChildType.isNonDiscriminatorField(discriminatorName)><#--&& !discriminatedChildType.isParserArgument(discriminatorName)-->
<#assign discriminatorType = helper.getDiscriminatorTypes()[discriminatorName]>
public ${helper.getLanguageTypeNameForTypeReference(discriminatorType)} get${discriminatorName?cap_first}() {
<#if discriminatorValue??>
<#if discriminatorValue?? && !helper.isWildcard(discriminatorValue)>
<#if helper.isEnumTypeReference(discriminatorType)>
return ${helper.getLanguageTypeNameForTypeReference(discriminatorType)}.${helper.toParseExpression(null, discriminatorType, discriminatorValue, parserArguments)};
<#else>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ argumentList

expression
: TICK expr=innerExpression TICK
// TODO: check if this is really universal or should be specific to case statement
| ASTERISK
;

multipleExpressions
Expand All @@ -212,7 +214,7 @@ innerExpression
| IDENTIFIER_LITERAL ('(' (innerExpression (',' innerExpression)* )? ')')? ('[' innerExpression ']')?
| innerExpression '.' innerExpression // Field Reference or method call
| innerExpression '[' + INTEGER_LITERAL + ']' // Array index
| innerExpression BinaryOperator innerExpression // Addition
| innerExpression binaryOperator innerExpression // Addition
| innerExpression '?' innerExpression ':' innerExpression
| '(' innerExpression ')'
| '"' innerExpression '"'
Expand All @@ -233,19 +235,11 @@ idExpression
| id=ARRAY_LOOP_TYPE
;

TICK : '\'';
LBRACKET : '[';
RBRACKET : ']';
LRBRACKET : '(';
RRBRACKET : ')';
LCBRACKET : '{';
RCBRACKET : '}';

BinaryOperator
binaryOperator
: '+'
| '-'
| '/'
| '*'
| ASTERISK
| '^'
| '=='
| '!='
Expand All @@ -262,6 +256,16 @@ BinaryOperator
| '%'
;

TICK : '\'';
LBRACKET : '[';
RBRACKET : ']';
LRBRACKET : '(';
RRBRACKET : ')';
LCBRACKET : '{';
RCBRACKET : '}';

ASTERISK : '*';

ARRAY_LOOP_TYPE
: 'count'
| 'length'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.plc4x.plugins.codegenerator.language.mspec.model.terms;

import org.apache.plc4x.plugins.codegenerator.types.terms.Term;

public class WildcardTerm implements Term {

public static final WildcardTerm INSTANCE = new WildcardTerm();

@Override
public boolean contains(String s) {
throw new IllegalStateException("Should never be called");
}

@Override
public String stringRepresentation() {
throw new IllegalStateException("Should never be called");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.apache.plc4x.plugins.codegenerator.language.mspec.expression.ExpressionStringParser;
import org.apache.plc4x.plugins.codegenerator.language.mspec.model.definitions.*;
import org.apache.plc4x.plugins.codegenerator.language.mspec.model.fields.*;
import org.apache.plc4x.plugins.codegenerator.language.mspec.model.terms.WildcardTerm;
import org.apache.plc4x.plugins.codegenerator.types.definitions.Argument;
import org.apache.plc4x.plugins.codegenerator.types.definitions.DefaultArgument;
import org.apache.plc4x.plugins.codegenerator.types.definitions.DiscriminatedComplexTypeDefinition;
Expand Down Expand Up @@ -485,7 +486,11 @@ public void enterEnumValueDefinition(MSpecParser.EnumValueDefinitionContext ctx)
}

private Term getExpressionTerm(MSpecParser.ExpressionContext expressionContext) {
if (expressionContext.ASTERISK() != null) {
return WildcardTerm.INSTANCE;
}
String expressionString = getExprString(expressionContext);
Objects.requireNonNull(expressionString, "Expression string should not be null");
InputStream inputStream = IOUtils.toInputStream(expressionString, Charset.defaultCharset());
ExpressionStringParser parser = new ExpressionStringParser();
try {
Expand Down

0 comments on commit 30817ad

Please sign in to comment.