Skip to content

Commit bb0130e

Browse files
authored
Merge pull request #1009 from nbradac/cpp-csharp-enum-keyword-check
[Java] add enum keyword check to C++ and C#
2 parents 7d3da8a + 5e0dcfb commit bb0130e

File tree

7 files changed

+253
-9
lines changed

7 files changed

+253
-9
lines changed

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

+11-3
Original file line numberDiff line numberDiff line change
@@ -1471,7 +1471,11 @@ private CharSequence generateEnumValues(final List<Token> tokens, final Token en
14711471
{
14721472
final CharSequence constVal = generateLiteral(
14731473
token.encoding().primitiveType(), token.encoding().constValue().toString());
1474-
sb.append(" ").append(token.name()).append(" = ").append(constVal).append(",\n");
1474+
sb.append(" ")
1475+
.append(formatForCppKeyword(token.name()))
1476+
.append(" = ")
1477+
.append(constVal)
1478+
.append(",\n");
14751479
}
14761480

14771481
final CharSequence nullLiteral = generateLiteral(
@@ -1505,7 +1509,11 @@ private CharSequence generateEnumLookupMethod(final List<Token> tokens, final To
15051509
final CharSequence constVal = generateLiteral(
15061510
token.encoding().primitiveType(), token.encoding().constValue().toString());
15071511

1508-
sb.append(" case ").append(constVal).append(": return ").append(token.name()).append(";\n");
1512+
sb.append(" case ")
1513+
.append(constVal)
1514+
.append(": return ")
1515+
.append(formatForCppKeyword(token.name()))
1516+
.append(";\n");
15091517
}
15101518

15111519
final CharSequence nullVal = generateLiteral(
@@ -3839,7 +3847,7 @@ private CharSequence generateEnumDisplay(final List<Token> tokens, final Token e
38393847
{
38403848
new Formatter(sb).format(
38413849
" case %1$s: return \"%1$s\";\n",
3842-
token.name());
3850+
formatForCppKeyword(token.name()));
38433851
}
38443852

38453853
sb.append(" case NULL_VALUE: return \"NULL_VALUE\";\n").append(" }\n\n");

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

+14-5
Original file line numberDiff line numberDiff line change
@@ -67,22 +67,31 @@ public static String cppTypeName(final PrimitiveType primitiveType)
6767
*/
6868
public static String formatPropertyName(final String value)
6969
{
70-
String formattedValue = toLowerFirstChar(value);
70+
return formatForCppKeyword(toLowerFirstChar(value));
71+
}
7172

72-
if (ValidationUtil.isCppKeyword(formattedValue))
73+
/**
74+
* Format a String with a suffix in case it's a keyword.
75+
*
76+
* @param value to be formatted.
77+
* @return the formatted string.
78+
*/
79+
public static String formatForCppKeyword(final String value)
80+
{
81+
if (ValidationUtil.isCppKeyword(value))
7382
{
7483
final String keywordAppendToken = System.getProperty(SbeTool.KEYWORD_APPEND_TOKEN);
7584
if (null == keywordAppendToken)
7685
{
7786
throw new IllegalStateException(
78-
"Invalid property name='" + formattedValue +
87+
"Invalid property name='" + value +
7988
"' please correct the schema or consider setting system property: " + SbeTool.KEYWORD_APPEND_TOKEN);
8089
}
8190

82-
formattedValue += keywordAppendToken;
91+
return value + keywordAppendToken;
8392
}
8493

85-
return formattedValue;
94+
return value;
8695
}
8796

8897
/**

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -775,7 +775,7 @@ private CharSequence generateEnumValues(final List<Token> tokens, final Token en
775775
for (final Token token : tokens)
776776
{
777777
sb.append(generateDocumentation(INDENT + INDENT, token))
778-
.append(INDENT).append(INDENT).append(token.name()).append(" = ")
778+
.append(INDENT).append(INDENT).append(formatForCSharpKeyword(token.name())).append(" = ")
779779
.append(token.encoding().constValue()).append(",\n");
780780
}
781781

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

+26
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
package uk.co.real_logic.sbe.generation.csharp;
1818

1919
import uk.co.real_logic.sbe.PrimitiveType;
20+
import uk.co.real_logic.sbe.SbeTool;
21+
import uk.co.real_logic.sbe.ValidationUtil;
2022
import uk.co.real_logic.sbe.generation.Generators;
2123
import uk.co.real_logic.sbe.ir.Token;
2224

@@ -241,6 +243,30 @@ public static String formatPropertyName(final String str)
241243
return toUpperFirstChar(str);
242244
}
243245

246+
/**
247+
* Format a String with a suffix in case it's a keyword.
248+
*
249+
* @param value to be formatted.
250+
* @return the formatted string.
251+
*/
252+
public static String formatForCSharpKeyword(final String value)
253+
{
254+
if (ValidationUtil.isCSharpKeyword(value))
255+
{
256+
final String keywordAppendToken = System.getProperty(SbeTool.KEYWORD_APPEND_TOKEN);
257+
if (null == keywordAppendToken)
258+
{
259+
throw new IllegalStateException(
260+
"Invalid property name='" + value +
261+
"' please correct the schema or consider setting system property: " + SbeTool.KEYWORD_APPEND_TOKEN);
262+
}
263+
264+
return value + keywordAppendToken;
265+
}
266+
267+
return value;
268+
}
269+
244270
/**
245271
* Format a String as a variable name.
246272
*
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.cpp;
17+
18+
import org.agrona.generation.StringWriterOutputManager;
19+
import org.junit.jupiter.api.Test;
20+
import uk.co.real_logic.sbe.SbeTool;
21+
import uk.co.real_logic.sbe.Tests;
22+
import uk.co.real_logic.sbe.ir.Ir;
23+
import uk.co.real_logic.sbe.xml.IrGenerator;
24+
import uk.co.real_logic.sbe.xml.MessageSchema;
25+
import uk.co.real_logic.sbe.xml.ParserOptions;
26+
27+
import java.io.InputStream;
28+
29+
import static org.hamcrest.MatcherAssert.assertThat;
30+
import static org.hamcrest.Matchers.containsString;
31+
import static org.junit.jupiter.api.Assertions.assertEquals;
32+
import static uk.co.real_logic.sbe.xml.XmlSchemaParser.parse;
33+
34+
import static org.junit.jupiter.api.Assertions.fail;
35+
36+
class CppEnumTest
37+
{
38+
private StringWriterOutputManager outputManager;
39+
private CppGenerator generator;
40+
41+
private void setupGenerator(final InputStream in) throws Exception
42+
{
43+
final ParserOptions options = ParserOptions.builder().stopOnError(true).build();
44+
final MessageSchema schema = parse(in, options);
45+
final IrGenerator irg = new IrGenerator();
46+
final Ir ir = irg.generate(schema);
47+
48+
outputManager = new StringWriterOutputManager();
49+
outputManager.setPackageName(ir.applicableNamespace());
50+
generator = new CppGenerator(ir, false, outputManager);
51+
}
52+
53+
@SuppressWarnings("checkstyle:LineLength")
54+
@Test
55+
void shouldFailOnKeywordEnumValues() throws Exception
56+
{
57+
System.clearProperty(SbeTool.KEYWORD_APPEND_TOKEN);
58+
59+
try (InputStream in = Tests.getLocalResource("issue1007.xml"))
60+
{
61+
setupGenerator(in);
62+
63+
try
64+
{
65+
generator.generate();
66+
}
67+
catch (final IllegalStateException exception)
68+
{
69+
assertEquals(
70+
"Invalid property name='false' please correct the schema or consider setting system property: sbe.keyword.append.token",
71+
exception.getMessage());
72+
return;
73+
}
74+
75+
fail("expected IllegalStateException");
76+
final String source = outputManager.getSources().toString();
77+
78+
System.err.println(source);
79+
}
80+
}
81+
82+
@Test
83+
void shouldAddSuffixToEnumValues() throws Exception
84+
{
85+
System.setProperty(SbeTool.KEYWORD_APPEND_TOKEN, "_");
86+
87+
try (InputStream in = Tests.getLocalResource("issue1007.xml"))
88+
{
89+
setupGenerator(in);
90+
91+
generator.generate();
92+
final String sources = outputManager.getSources().toString();
93+
94+
assertThat(sources, containsString("false_ = static"));
95+
assertThat(sources, containsString("true_ = static"));
96+
assertThat(sources, containsString("return false_;"));
97+
assertThat(sources, containsString("return true_;"));
98+
assertThat(sources, containsString("case false_:"));
99+
assertThat(sources, containsString("case true_:"));
100+
}
101+
}
102+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
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.csharp;
17+
18+
import org.agrona.generation.StringWriterOutputManager;
19+
import org.junit.jupiter.api.Test;
20+
import uk.co.real_logic.sbe.SbeTool;
21+
import uk.co.real_logic.sbe.Tests;
22+
import uk.co.real_logic.sbe.ir.Ir;
23+
import uk.co.real_logic.sbe.xml.IrGenerator;
24+
import uk.co.real_logic.sbe.xml.MessageSchema;
25+
import uk.co.real_logic.sbe.xml.ParserOptions;
26+
27+
import java.io.InputStream;
28+
29+
import static org.hamcrest.MatcherAssert.assertThat;
30+
import static org.hamcrest.Matchers.containsString;
31+
import static org.junit.jupiter.api.Assertions.assertEquals;
32+
import static org.junit.jupiter.api.Assertions.fail;
33+
import static uk.co.real_logic.sbe.xml.XmlSchemaParser.parse;
34+
35+
class CSharpEnumTest
36+
{
37+
private StringWriterOutputManager outputManager;
38+
private CSharpGenerator generator;
39+
40+
private void setupGenerator(final InputStream in) throws Exception
41+
{
42+
final ParserOptions options = ParserOptions.builder().stopOnError(true).build();
43+
final MessageSchema schema = parse(in, options);
44+
final IrGenerator irg = new IrGenerator();
45+
final Ir ir = irg.generate(schema);
46+
47+
outputManager = new StringWriterOutputManager();
48+
outputManager.setPackageName(ir.applicableNamespace());
49+
generator = new CSharpGenerator(ir, outputManager);
50+
}
51+
52+
@SuppressWarnings("checkstyle:LineLength")
53+
@Test
54+
void shouldFailOnKeywordEnumValues() throws Exception
55+
{
56+
System.clearProperty(SbeTool.KEYWORD_APPEND_TOKEN);
57+
58+
try (InputStream in = Tests.getLocalResource("issue1007.xml"))
59+
{
60+
setupGenerator(in);
61+
62+
try
63+
{
64+
generator.generate();
65+
}
66+
catch (final IllegalStateException exception)
67+
{
68+
assertEquals(
69+
"Invalid property name='false' please correct the schema or consider setting system property: sbe.keyword.append.token",
70+
exception.getMessage());
71+
return;
72+
}
73+
74+
fail("expected IllegalStateException");
75+
final String source = outputManager.getSources().toString();
76+
77+
System.err.println(source);
78+
}
79+
}
80+
81+
@Test
82+
void shouldAddSuffixToEnumValues() throws Exception
83+
{
84+
System.setProperty(SbeTool.KEYWORD_APPEND_TOKEN, "_");
85+
86+
try (InputStream in = Tests.getLocalResource("issue1007.xml"))
87+
{
88+
setupGenerator(in);
89+
90+
generator.generate();
91+
final String sources = outputManager.getSources().toString();
92+
93+
assertThat(sources, containsString("false_ = "));
94+
assertThat(sources, containsString("true_ = "));
95+
}
96+
}
97+
}

sbe-tool/src/test/java/uk/co/real_logic/sbe/generation/java/EnumTest.java

+2
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ private void setupGenerator(final InputStream in) throws Exception
6161
@Test
6262
void shouldFailOnKeywordEnumValues() throws Exception
6363
{
64+
System.clearProperty(SbeTool.KEYWORD_APPEND_TOKEN);
65+
6466
try (InputStream in = Tests.getLocalResource("issue1007.xml"))
6567
{
6668
setupGenerator(in);

0 commit comments

Comments
 (0)