Skip to content

Commit cce1047

Browse files
authored
Merge pull request #1008 from nbradac/enum-keyword-check
[Java] add keyword suffix check for java enums
2 parents 4c8f35b + 156b528 commit cce1047

File tree

4 files changed

+145
-7
lines changed

4 files changed

+145
-7
lines changed

sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/java/JavaGenerator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2238,7 +2238,7 @@ private CharSequence generateEnumValues(final List<Token> tokens, final String n
22382238
final Encoding encoding = token.encoding();
22392239
final CharSequence constVal = generateLiteral(encoding.primitiveType(), encoding.constValue().toString());
22402240
generateTypeJavadoc(sb, INDENT, token);
2241-
sb.append(INDENT).append(token.name()).append('(').append(constVal).append("),\n\n");
2241+
sb.append(INDENT).append(formatForJavaKeyword(token.name())).append('(').append(constVal).append("),\n\n");
22422242
}
22432243

22442244
if (shouldDecodeUnknownEnumValues)
@@ -2297,7 +2297,7 @@ private CharSequence generateEnumLookupMethod(final List<Token> tokens, final St
22972297
for (final Token token : tokens)
22982298
{
22992299
final String constStr = token.encoding().constValue().toString();
2300-
final String name = token.name();
2300+
final String name = formatForJavaKeyword(token.name());
23012301
sb.append(" case ").append(constStr).append(": return ").append(name).append(";\n");
23022302
}
23032303

sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/java/JavaUtil.java

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -155,22 +155,34 @@ public static String javaTypeName(final PrimitiveType primitiveType)
155155
*/
156156
public static String formatPropertyName(final String value)
157157
{
158-
String formattedValue = Generators.toLowerFirstChar(value);
158+
return formatForJavaKeyword(Generators.toLowerFirstChar(value));
159+
}
159160

160-
if (ValidationUtil.isJavaKeyword(formattedValue))
161+
/**
162+
* Format a name for generated code.
163+
* <p>
164+
* If the formatted name is a keyword then {@link SbeTool#KEYWORD_APPEND_TOKEN} is appended if set.
165+
*
166+
* @param value to be formatted.
167+
* @return the string formatted as a valid name.
168+
* @throws IllegalStateException if a keyword and {@link SbeTool#KEYWORD_APPEND_TOKEN} is not set.
169+
*/
170+
public static String formatForJavaKeyword(final String value)
171+
{
172+
if (ValidationUtil.isJavaKeyword(value))
161173
{
162174
final String keywordAppendToken = System.getProperty(SbeTool.KEYWORD_APPEND_TOKEN);
163175
if (null == keywordAppendToken)
164176
{
165177
throw new IllegalStateException(
166-
"Invalid property name='" + formattedValue +
178+
"Invalid property name='" + value +
167179
"' please correct the schema or consider setting system property: " + SbeTool.KEYWORD_APPEND_TOKEN);
168180
}
169181

170-
formattedValue += keywordAppendToken;
182+
return value + keywordAppendToken;
171183
}
172184

173-
return formattedValue;
185+
return value;
174186
}
175187

176188
/**
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
* Copyright 2013-2024 Real Logic Limited.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package uk.co.real_logic.sbe.generation.java;
17+
18+
import org.agrona.DirectBuffer;
19+
import org.agrona.MutableDirectBuffer;
20+
import org.agrona.generation.StringWriterOutputManager;
21+
import org.junit.jupiter.api.Test;
22+
import uk.co.real_logic.sbe.SbeTool;
23+
import uk.co.real_logic.sbe.Tests;
24+
import uk.co.real_logic.sbe.ir.Ir;
25+
import uk.co.real_logic.sbe.xml.IrGenerator;
26+
import uk.co.real_logic.sbe.xml.MessageSchema;
27+
import uk.co.real_logic.sbe.xml.ParserOptions;
28+
import uk.co.real_logic.sbe.xml.XmlSchemaParser;
29+
30+
import java.io.InputStream;
31+
32+
import static org.hamcrest.MatcherAssert.assertThat;
33+
import static org.hamcrest.core.StringContains.containsString;
34+
import static org.junit.jupiter.api.Assertions.assertEquals;
35+
import static org.junit.jupiter.api.Assertions.fail;
36+
37+
class EnumTest
38+
{
39+
private static final Class<?> BUFFER_CLASS = MutableDirectBuffer.class;
40+
private static final String BUFFER_NAME = BUFFER_CLASS.getName();
41+
private static final Class<DirectBuffer> READ_ONLY_BUFFER_CLASS = DirectBuffer.class;
42+
private static final String READ_ONLY_BUFFER_NAME = READ_ONLY_BUFFER_CLASS.getName();
43+
44+
private StringWriterOutputManager outputManager;
45+
private JavaGenerator generator;
46+
47+
private void setupGenerator(final InputStream in) throws Exception
48+
{
49+
final ParserOptions options = ParserOptions.builder().stopOnError(true).build();
50+
final MessageSchema schema = XmlSchemaParser.parse(in, options);
51+
final IrGenerator irg = new IrGenerator();
52+
final Ir ir = irg.generate(schema);
53+
54+
outputManager = new StringWriterOutputManager();
55+
outputManager.setPackageName(ir.applicableNamespace());
56+
generator = new JavaGenerator(
57+
ir, BUFFER_NAME, READ_ONLY_BUFFER_NAME, false, false, false, outputManager);
58+
}
59+
60+
@SuppressWarnings("checkstyle:LineLength")
61+
@Test
62+
void shouldFailOnKeywordEnumValues() throws Exception
63+
{
64+
try (InputStream in = Tests.getLocalResource("issue1007.xml"))
65+
{
66+
setupGenerator(in);
67+
68+
try
69+
{
70+
generator.generate();
71+
}
72+
catch (final IllegalStateException exception)
73+
{
74+
assertEquals(
75+
"Invalid property name='false' please correct the schema or consider setting system property: sbe.keyword.append.token",
76+
exception.getMessage());
77+
return;
78+
}
79+
80+
fail("expected IllegalStateException");
81+
}
82+
}
83+
84+
@Test
85+
void shouldAddSuffixToEnumValues() throws Exception
86+
{
87+
System.setProperty(SbeTool.KEYWORD_APPEND_TOKEN, "_");
88+
89+
try (InputStream in = Tests.getLocalResource("issue1007.xml"))
90+
{
91+
setupGenerator(in);
92+
93+
generator.generate();
94+
final String sources = outputManager.getSources().toString();
95+
96+
assertThat(sources, containsString("false_("));
97+
assertThat(sources, containsString("true_("));
98+
assertThat(sources, containsString("return false_;"));
99+
assertThat(sources, containsString("return true_;"));
100+
}
101+
}
102+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<sbe:messageSchema xmlns:sbe="http://fixprotocol.io/2016/sbe"
3+
package="issue1007"
4+
id="1007"
5+
version="0"
6+
semanticVersion="1.0"
7+
description="issue 1007 test case"
8+
byteOrder="bigEndian">
9+
<types>
10+
<composite name="messageHeader" description="Message identifiers and length of message root">
11+
<type name="blockLength" primitiveType="uint16"/>
12+
<type name="templateId" primitiveType="uint16"/>
13+
<type name="schemaId" primitiveType="uint16"/>
14+
<type name="version" primitiveType="uint16"/>
15+
</composite>
16+
<enum name="MyEnum" encodingType="uint8">
17+
<validValue name="false">0</validValue>
18+
<validValue name="true">1</validValue>
19+
</enum>
20+
</types>
21+
<sbe:message name="issue1007" id="1" description="issue 1007 test">
22+
<field name="constant" type="MyEnum" id="1"/>
23+
</sbe:message>
24+
</sbe:messageSchema>

0 commit comments

Comments
 (0)