Skip to content

Commit cd88380

Browse files
authored
Fix package name support for embedded composites (#915)
* enhanced test case. * Bugfix: embedded composites were missing import for required types. * polish * use Collections.emptySet() * chain append statements * renamed method argument additionalPackages -> importedTypesPackages
1 parent ff5158e commit cd88380

File tree

2 files changed

+92
-23
lines changed

2 files changed

+92
-23
lines changed

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

Lines changed: 74 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.io.IOException;
3030
import java.io.Writer;
3131
import java.util.ArrayList;
32+
import java.util.Collections;
3233
import java.util.Formatter;
3334
import java.util.HashSet;
3435
import java.util.List;
@@ -60,6 +61,7 @@ enum CodecType
6061
private static final String PACKAGE_INFO = "package-info";
6162
private static final String BASE_INDENT = "";
6263
private static final String INDENT = " ";
64+
private static final Set<String> NO_PACKAGES = Collections.emptySet();
6365

6466
private final Ir ir;
6567
private final DynamicPackageOutputManager outputManager;
@@ -184,11 +186,15 @@ public void generateTypeStubs() throws IOException
184186
*/
185187
private String registerTypesPackageName(final Token token, final Ir ir)
186188
{
187-
if (shouldSupportTypesPackageNames && token.packageName() != null)
189+
190+
if (!shouldSupportTypesPackageNames)
191+
{
192+
return ir.applicableNamespace();
193+
}
194+
if (token.packageName() != null)
188195
{
189196
packageNameByTypes.add(token.packageName());
190197
outputManager.setPackageName(token.packageName());
191-
192198
return token.packageName();
193199
}
194200
return ir.applicableNamespace();
@@ -1243,7 +1249,8 @@ private void generateBitSet(final List<Token> tokens) throws IOException
12431249
try (Writer out = outputManager.createOutput(decoderName))
12441250
{
12451251
final Encoding encoding = token.encoding();
1246-
generateFixedFlyweightHeader(out, token, decoderName, implementsString, readOnlyBuffer, fqReadOnlyBuffer);
1252+
generateFixedFlyweightHeader(out, token, decoderName, implementsString, readOnlyBuffer, fqReadOnlyBuffer,
1253+
NO_PACKAGES);
12471254
out.append(generateChoiceIsEmpty(encoding.primitiveType()));
12481255

12491256
new Formatter(out).format(
@@ -1263,7 +1270,8 @@ private void generateBitSet(final List<Token> tokens) throws IOException
12631270
registerTypesPackageName(token, ir);
12641271
try (Writer out = outputManager.createOutput(encoderName))
12651272
{
1266-
generateFixedFlyweightHeader(out, token, encoderName, implementsString, mutableBuffer, fqMutableBuffer);
1273+
generateFixedFlyweightHeader(out, token, encoderName, implementsString, mutableBuffer, fqMutableBuffer,
1274+
NO_PACKAGES);
12671275
generateChoiceClear(out, encoderName, token);
12681276
generateChoiceEncoders(out, encoderName, choiceList);
12691277
out.append("}\n");
@@ -1276,10 +1284,11 @@ private void generateFixedFlyweightHeader(
12761284
final String typeName,
12771285
final String implementsString,
12781286
final String buffer,
1279-
final String fqBuffer) throws IOException
1287+
final String fqBuffer,
1288+
final Set<String> importedTypesPackages) throws IOException
12801289
{
12811290
final String packageName = registerTypesPackageName(token, ir);
1282-
out.append(generateFileHeader(packageName, fqBuffer));
1291+
out.append(generateFileHeader(packageName, importedTypesPackages, fqBuffer));
12831292
out.append(generateDeclaration(typeName, implementsString, token));
12841293
out.append(generateFixedFlyweightCode(typeName, token.encodedLength(), buffer));
12851294
}
@@ -1290,10 +1299,11 @@ private void generateCompositeFlyweightHeader(
12901299
final Writer out,
12911300
final String buffer,
12921301
final String fqBuffer,
1293-
final String implementsString) throws IOException
1302+
final String implementsString,
1303+
final Set<String> importedTypesPackages) throws IOException
12941304
{
12951305
final String packageName = registerTypesPackageName(token, ir);
1296-
out.append(generateFileHeader(packageName, fqBuffer));
1306+
out.append(generateFileHeader(packageName, importedTypesPackages, fqBuffer));
12971307
out.append(generateDeclaration(typeName, implementsString, token));
12981308
out.append(generateFixedFlyweightCode(typeName, token.encodedLength(), buffer));
12991309
}
@@ -1329,11 +1339,12 @@ private void generateComposite(final List<Token> tokens) throws IOException
13291339
final String encoderName = encoderName(compositeName);
13301340

13311341
registerTypesPackageName(token, ir);
1342+
final Set<String> importedTypesPackages = scanPackagesToImport(tokens);
13321343
try (Writer out = outputManager.createOutput(decoderName))
13331344
{
13341345
final String implementsString = implementsInterface(CompositeDecoderFlyweight.class.getSimpleName());
13351346
generateCompositeFlyweightHeader(
1336-
token, decoderName, out, readOnlyBuffer, fqReadOnlyBuffer, implementsString);
1347+
token, decoderName, out, readOnlyBuffer, fqReadOnlyBuffer, implementsString, importedTypesPackages);
13371348

13381349
for (int i = 1, end = tokens.size() - 1; i < end;)
13391350
{
@@ -1381,7 +1392,8 @@ private void generateComposite(final List<Token> tokens) throws IOException
13811392
try (Writer out = outputManager.createOutput(encoderName))
13821393
{
13831394
final String implementsString = implementsInterface(CompositeEncoderFlyweight.class.getSimpleName());
1384-
generateCompositeFlyweightHeader(token, encoderName, out, mutableBuffer, fqMutableBuffer, implementsString);
1395+
generateCompositeFlyweightHeader(token, encoderName, out, mutableBuffer, fqMutableBuffer, implementsString,
1396+
importedTypesPackages);
13851397

13861398
for (int i = 1, end = tokens.size() - 1; i < end;)
13871399
{
@@ -1423,6 +1435,30 @@ private void generateComposite(final List<Token> tokens) throws IOException
14231435
}
14241436
}
14251437

1438+
private Set<String> scanPackagesToImport(final List<Token> tokens)
1439+
{
1440+
if (!shouldSupportTypesPackageNames)
1441+
{
1442+
return NO_PACKAGES;
1443+
}
1444+
1445+
final Set<String> packagesToImport = new HashSet<>();
1446+
for (int i = 1; i < tokens.size() - 1; i++)
1447+
{
1448+
final Token typeToken = tokens.get(i);
1449+
if (typeToken.signal() == Signal.BEGIN_ENUM ||
1450+
typeToken.signal() == Signal.BEGIN_SET ||
1451+
typeToken.signal() == Signal.BEGIN_COMPOSITE)
1452+
{
1453+
if (typeToken.packageName() != null)
1454+
{
1455+
packagesToImport.add(typeToken.packageName());
1456+
}
1457+
}
1458+
}
1459+
return packagesToImport;
1460+
}
1461+
14261462
private void generateChoiceClear(final Appendable out, final String bitSetClassName, final Token token)
14271463
throws IOException
14281464
{
@@ -1608,6 +1644,23 @@ private CharSequence generateEnumLookupMethod(final List<Token> tokens, final St
16081644
return sb;
16091645
}
16101646

1647+
private StringBuilder generateImportStatements(final Set<String> packages, final String currentPackage)
1648+
{
1649+
final StringBuilder importsStatements = new StringBuilder();
1650+
for (final String candidatePackage : packages)
1651+
{
1652+
if (!candidatePackage.equalsIgnoreCase(currentPackage))
1653+
{
1654+
importsStatements.append("import ").append(candidatePackage).append(".*;\n");
1655+
}
1656+
}
1657+
if (importsStatements.length() > 0)
1658+
{
1659+
importsStatements.append("\n\n");
1660+
}
1661+
return importsStatements;
1662+
}
1663+
16111664
private String interfaceImportLine()
16121665
{
16131666
if (!shouldGenerateInterfaces)
@@ -1618,25 +1671,23 @@ private String interfaceImportLine()
16181671
return "import " + JAVA_INTERFACE_PACKAGE + ".*;\n\n";
16191672
}
16201673

1621-
private CharSequence generateFileHeader(final String packageName, final String fqBuffer)
1674+
1675+
private CharSequence generateFileHeader(final String packageName, final Set<String> importedTypesPackages,
1676+
final String fqBuffer)
16221677
{
1623-
return
1624-
"/* Generated SBE (Simple Binary Encoding) message codec. */\n" +
1678+
final StringBuilder importStatements = generateImportStatements(importedTypesPackages, packageName);
1679+
1680+
return "/* Generated SBE (Simple Binary Encoding) message codec. */\n" +
16251681
"package " + packageName + ";\n\n" +
16261682
"import " + fqBuffer + ";\n" +
1627-
interfaceImportLine();
1683+
interfaceImportLine() +
1684+
importStatements;
16281685
}
16291686

16301687
private CharSequence generateMainHeader(
16311688
final String packageName, final CodecType codecType, final boolean hasVarData)
16321689
{
1633-
final StringBuilder packageImports = new StringBuilder();
1634-
for (final String typePackage : packageNameByTypes)
1635-
{
1636-
packageImports.append("import ");
1637-
packageImports.append(typePackage);
1638-
packageImports.append(".*;\n");
1639-
}
1690+
final StringBuilder importStatements = generateImportStatements(packageNameByTypes, packageName);
16401691

16411692
if (fqMutableBuffer.equals(fqReadOnlyBuffer))
16421693
{
@@ -1645,7 +1696,7 @@ private CharSequence generateMainHeader(
16451696
"package " + packageName + ";\n\n" +
16461697
"import " + fqMutableBuffer + ";\n" +
16471698
interfaceImportLine() +
1648-
packageImports;
1699+
importStatements;
16491700
}
16501701
else
16511702
{
@@ -1658,7 +1709,7 @@ private CharSequence generateMainHeader(
16581709
(hasMutableBuffer ? "import " + fqMutableBuffer + ";\n" : "") +
16591710
(hasReadOnlyBuffer ? "import " + fqReadOnlyBuffer + ";\n" : "") +
16601711
interfaceImportLine() +
1661-
packageImports;
1712+
importStatements;
16621713
}
16631714
}
16641715

sbe-tool/src/test/resources/explicit-package-test-schema.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,24 @@
1818
<composite name="Car" description="Message identifiers and length of message root">
1919
<type name="make" primitiveType="uint16"/>
2020
<type name="model" primitiveType="uint16"/>
21+
<ref name="vintage" type="BooleanType"/>
22+
<composite name="Engine">
23+
<type name="power" primitiveType="int32"/>
24+
<type name="torque" primitiveType="int32"/>
25+
<ref name="ice" type="BooleanType"/>
26+
<ref name="fuel" type="FuelSpec"/>
27+
</composite>
2128
</composite>
2229
</types>
2330
<types package="outside.schema">
2431
<enum name="BooleanType" encodingType="int8">
2532
<validValue name="FALSE">0</validValue>
2633
<validValue name="TRUE">1</validValue>
2734
</enum>
35+
<composite name="FuelSpec">
36+
<type name="limit" primitiveType="int32"/>
37+
<ref name="fuel" type="FuelType"/>
38+
</composite>
2839
<set name="Days" encodingType="uint8">
2940
<choice name="Monday">0</choice>
3041
<choice name="Tuesday">1</choice>
@@ -34,6 +45,13 @@
3445
<choice name="Saturday">5</choice>
3546
<choice name="Sunday">6</choice>
3647
</set>
48+
<set name="FuelType" encodingType="uint8">
49+
<choice name="Petrol">1</choice>
50+
<choice name="Diesel">2</choice>
51+
<choice name="LPG">3</choice>
52+
<choice name="Electric">4</choice>
53+
<choice name="Hybrid">5</choice>
54+
</set>
3755
</types>
3856

3957
<sbe:message name="TestMessage" id="1">

0 commit comments

Comments
 (0)