Skip to content

Commit

Permalink
fix: Changed typeSwitch to no longer use expressions as discriminator…
Browse files Browse the repository at this point in the history
…s (Now variableLiterals are required) in const fields now no longer expressions can be used and instead only Literals can be used.
  • Loading branch information
chrisdutz committed Nov 26, 2021
1 parent a888473 commit a89e1bd
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ simpleField
;

typeSwitchField
: 'typeSwitch' discriminators=multipleExpressions caseStatement*
: 'typeSwitch' discriminators=multipleVariableLiterals caseStatement*
;

unknownField
Expand Down Expand Up @@ -184,6 +184,16 @@ multipleExpressions
: expression (',' expression)*
;

multipleVariableLiterals
: variableLiteral (',' variableLiteral)*
;

variableLiteral
: IDENTIFIER_LITERAL
| IDENTIFIER_LITERAL '.' variableLiteral // Field Reference or method call
| variableLiteral '[' + INTEGER_LITERAL + ']' // Array index
;

innerExpression
: valueLiteral
// Explicitly allow the loop type keywords in expressions
Expand All @@ -198,6 +208,14 @@ innerExpression
| '!' innerExpression
;

valueLiteral
: BOOLEAN_LITERAL
| HEX_LITERAL
| INTEGER_LITERAL
| FLOAT_LITERAL
| STRING_LITERAL
;

idExpression
: id=IDENTIFIER_LITERAL
// Explicitly allow the loop type keywords in id-expressions
Expand Down Expand Up @@ -255,6 +273,10 @@ INTEGER_CHARACTER
: [0-9]
;

FLOAT_LITERAL
: INTEGER_LITERAL.INTEGER_LITERAL
;

// Hexadecimal literals

HEX_LITERAL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,22 @@
import org.apache.plc4x.plugins.codegenerator.types.definitions.DiscriminatedComplexTypeDefinition;
import org.apache.plc4x.plugins.codegenerator.types.fields.SwitchField;
import org.apache.plc4x.plugins.codegenerator.types.terms.Term;
import org.apache.plc4x.plugins.codegenerator.types.terms.VariableLiteral;

import java.util.*;

public class DefaultSwitchField implements SwitchField {

private final List<Term> discriminatorExpressions;
private final List<VariableLiteral> variableLiterals;
private final List<DiscriminatedComplexTypeDefinition> cases;

public DefaultSwitchField(List<Term> discriminatorExpressions) {
this.discriminatorExpressions = Objects.requireNonNull(discriminatorExpressions);
public DefaultSwitchField(List<VariableLiteral> variableLiterals) {
this.variableLiterals = Objects.requireNonNull(variableLiterals);
this.cases = new LinkedList<>();
}

public List<Term> getDiscriminatorExpressions() {
return discriminatorExpressions;
public List<VariableLiteral> getDiscriminatorExpressions() {
return variableLiterals;
}

// TODO: replace with immutable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.apache.plc4x.plugins.codegenerator.types.references.*;
import org.apache.plc4x.plugins.codegenerator.types.terms.Literal;
import org.apache.plc4x.plugins.codegenerator.types.terms.Term;
import org.apache.plc4x.plugins.codegenerator.types.terms.VariableLiteral;

import java.io.InputStream;
import java.nio.charset.Charset;
Expand Down Expand Up @@ -209,11 +210,7 @@ public void enterChecksumField(MSpecParser.ChecksumFieldContext ctx) {
public void enterConstField(MSpecParser.ConstFieldContext ctx) {
TypeReference type = ctx.type.dataType() != null ? getSimpleTypeReference(ctx.type.dataType()) : getTypeReference(ctx.type);
String name = getIdString(ctx.name);
Term expected = getExpressionTerm(ctx.expected);
if(!(expected instanceof Literal)) {
throw new RuntimeException("only literals allowed as constant value");
}
Field field = new DefaultConstField(getAttributes(ctx), type, name, (Literal) expected);
Field field = new DefaultConstField(getAttributes(ctx), type, name, getValueLiteral(ctx.expected));
if (parserContexts.peek() != null) {
parserContexts.peek().add(field);
}
Expand Down Expand Up @@ -347,7 +344,7 @@ public void enterTypeSwitchField(MSpecParser.TypeSwitchFieldContext ctx) {
List<VariableLiteral> variableLiterals = ctx.discriminators.variableLiteral().stream()
.map(this::getVariableLiteral)
.collect(Collectors.toList());
DefaultSwitchField field = new DefaultSwitchField(discriminatorExpressions);
DefaultSwitchField field = new DefaultSwitchField(variableLiterals);
if (parserContexts.peek() != null) {
parserContexts.peek().add(field);
}
Expand Down Expand Up @@ -476,6 +473,34 @@ private Term getExpressionTerm(MSpecParser.ExpressionContext expressionContext)
}
}

private VariableLiteral getVariableLiteral(MSpecParser.VariableLiteralContext variableLiteralContext) {
// TODO: make nullsafe
final String variableLiteral = variableLiteralContext.getText();
InputStream inputStream = IOUtils.toInputStream(variableLiteral, Charset.defaultCharset());
ExpressionStringParser parser = new ExpressionStringParser();
try {
// As this come from a VariableLiteralContext we know that it is a VariableLiteral
return (VariableLiteral) parser.parse(inputStream);
} catch (Exception e) {
throw new RuntimeException(String.format("Error parsing variable literal: '%s' at line %d column %d",
variableLiteral, variableLiteralContext.start.getLine(), variableLiteralContext.start.getStartIndex()), e);
}
}

private Literal getValueLiteral(MSpecParser.ValueLiteralContext valueLiteralContext) {
// TODO: make nullsafe
final String valueLiteralContextText = valueLiteralContext.getText();
InputStream inputStream = IOUtils.toInputStream(valueLiteralContextText, Charset.defaultCharset());
ExpressionStringParser parser = new ExpressionStringParser();
try {
// As this come from a ValueLiteralContext we know that it is a Literal
return (Literal) parser.parse(inputStream);
} catch (Exception e) {
throw new RuntimeException(String.format("Error parsing variable literal: '%s' at line %d column %d",
valueLiteralContextText, valueLiteralContext.start.getLine(), valueLiteralContext.start.getStartIndex()), e);
}
}

private TypeReference getTypeReference(MSpecParser.TypeReferenceContext ctx) {
if (ctx.simpleTypeReference != null) {
return getSimpleTypeReference(ctx.simpleTypeReference);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@

[type State
[simple bit broadcast ]
[reserved int 7 '0x0' ]
[reserved int 7 '0x0' ]
[simple bit initCommand ]
[simple bit updCommand ]
[simple bit timestampAdded ]
Expand Down Expand Up @@ -207,7 +207,7 @@
]

[discriminatedType ADSData(CommandId commandId, bit response)
[typeSwitch 'commandId', 'response'
[typeSwitch commandId, response
['INVALID', 'true' AdsInvalidResponse]
['INVALID', 'false' AdsInvalidRequest]
['ADS_READ_DEVICE_INFO', 'true' AdsReadDeviceInfoResponse
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
[abstract float 32 abstractFloatField]
[abstract float 64 abstractDoubleField]
[abstract string 8 abstractStringField encoding='UTF-8']
[typeSwitch 'simpleField'
[typeSwitch simpleField
['0' AbstractedType
[simple bit abstractBitField]
[simple int 8 abstractIntField]
Expand All @@ -127,7 +127,7 @@
[abstract float 32 abstractFloatField]
[abstract float 64 abstractDoubleField]
[abstract string 8 abstractStringField encoding='UTF-8']
[typeSwitch 'simpleField'
[typeSwitch simpleField
['0' AbstractedType
//Abstract fields need to be overriden in child
[simple bit abstractBitField]
Expand Down Expand Up @@ -233,7 +233,7 @@
// [virtual float 32 virtualFloatField 'simpleField']
// [virtual float 64 virtualDoubleField 'simpleField']
// [virtual string 24 virtualStringField 'simpleField' encoding='UTF-8']
// [typeSwitch 'simpleField'
// [typeSwitch simpleField
// ['0' DiscriminatedVirtualType
// [simple int 8 intField]
// ]
Expand Down Expand Up @@ -270,7 +270,7 @@

[discriminatedType EnumDiscriminatedType
[discriminator EnumType discr]
[typeSwitch 'discr'
[typeSwitch discr
['BOOL' EnumDiscriminatedTypeA
[simple uint 8 simpA]
]
Expand All @@ -287,7 +287,7 @@
[discriminatedType EnumDiscriminatedTypeMultiple
[discriminator EnumType discr1]
[discriminator EnumTypeInt discr2]
[typeSwitch 'discr1','discr2'
[typeSwitch discr1,discr2
['BOOL','BOOLINT' EnumDiscriminatedTypeMultipleA
[simple uint 8 simpA]
]
Expand All @@ -302,7 +302,7 @@

// Enumerated Parameter
[discriminatedType EnumDiscriminatedTypeParameter(EnumType discr)
[typeSwitch 'discr'
[typeSwitch discr
['BOOL' EnumDiscriminatedTypeAParameter
[simple uint 8 simpA]
]
Expand All @@ -317,7 +317,7 @@

// Multiple Enumerated Parameters
[discriminatedType EnumDiscriminatedTypeParameterMultiple(EnumType discr1, EnumTypeInt discr2)
[typeSwitch 'discr1','discr2'
[typeSwitch discr1,discr2
['BOOL','BOOLINT' EnumDiscriminatedTypeAParameterMultiple
[simple uint 8 simpA]
]
Expand All @@ -332,7 +332,7 @@

[discriminatedType SimpleDiscriminatedType
[discriminator uint 8 discr]
[typeSwitch 'discr'
[typeSwitch discr
['0x00' SimpleDiscriminatedTypeA
[simple uint 8 simpA]
]
Expand All @@ -349,7 +349,7 @@
//Test to check if we can include concrete types as fields. Doesn't work in any language at the moment.
//[discriminatedType SimpleDiscriminatedType
// [discriminator uint 8 discr]
// [typeSwitch 'discr'
// [typeSwitch discr
// ['0x00' SimpleDiscriminatedTypeA
// [simple AnotherSimpleDiscriminatedTypeA simpA]
// ]
Expand All @@ -358,7 +358,7 @@

//[discriminatedType AnotherSimpleDiscriminatedType
// [discriminator uint 8 discr]
// [typeSwitch 'discr'
// [typeSwitch discr
// ['0x00' AnotherSimpleDiscriminatedTypeA
// [simple uint 8 simpA]
// ]
Expand Down Expand Up @@ -434,8 +434,8 @@
// Data IO Tests
////////////////////////////////////////////////////////////////

[dataIo DataIOType(EnumType 'dataType')
[typeSwitch 'dataType'
[dataIo DataIOType(EnumType dataType)
[typeSwitch dataType
['BOOL' BOOL
[simple bit value]
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@
['0x79','true' SysexCommandReportFirmwareResponse
[simple uint 8 majorVersion]
[simple uint 8 minorVersion]
[manualArray byte 'fileName' terminated 'STATIC_CALL("isSysexEnd", readBuffer)' 'STATIC_CALL("parseSysexString", readBuffer)' 'STATIC_CALL("serializeSysexString", writeBuffer, _value)' 'STATIC_CALL("lengthSysexString", fileName)']
[manualArray byte fileName terminated 'STATIC_CALL("isSysexEnd", readBuffer)' 'STATIC_CALL("parseSysexString", readBuffer)' 'STATIC_CALL("serializeSysexString", writeBuffer, _value)' 'STATIC_CALL("lengthSysexString", fileName)']
]
['0x7A' SysexCommandSamplingInterval
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@
[simple uint 16 responseDelayFactorOrPadding ]
// 4.3.1.3.4 (Page 95)
[implicit uint 16 dcpDataLength 'lengthInBytes - 12']
[typeSwitch 'frameId','serviceId','serviceType.response'
[typeSwitch frameId,serviceId,serviceType.response
////////////////////////////////////////////////////////////////////////////
// Multicast (Well theoretically)
////////////////////////////////////////////////////////////////////////////
Expand Down

0 comments on commit a89e1bd

Please sign in to comment.