Skip to content

Commit 0caf77e

Browse files
authored
Merge pull request #1024 from nbradac/cpp-and-csharp-package-overrides
[C++,C#] respect the package override option for codecs and DTOs
2 parents d38b4bf + ea52edd commit 0caf77e

File tree

15 files changed

+484
-65
lines changed

15 files changed

+484
-65
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ csharp/sbe-generated/since-deprecated
9494
csharp/sbe-generated/order_check
9595
csharp/sbe-generated/mktdata/*.cs
9696
csharp/sbe-generated/uk_co_real_logic_sbe_benchmarks_fix
97+
csharp/sbe-generated/test_message_schema
9798
csharp/sbe-tests/*.sbe
9899
csharp/nuget/
99100
csharp/csharp.sln.DotSettings.user

build.gradle

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -894,7 +894,8 @@ tasks.register('generateCSharpTestCodecs', JavaExec) {
894894
'sbe.target.language': 'uk.co.real_logic.sbe.generation.csharp.CSharp',
895895
'sbe.xinclude.aware': 'true',
896896
'sbe.validation.xsd': validationXsdPath,
897-
'sbe.generate.precedence.checks': 'true')
897+
'sbe.generate.precedence.checks': 'true',
898+
'sbe.types.package.override': 'true')
898899
args = ['sbe-tool/src/test/resources/FixBinary.xml',
899900
'sbe-tool/src/test/resources/issue435.xml',
900901
'sbe-tool/src/test/resources/issue483.xml',
@@ -912,15 +913,41 @@ tasks.register('generateCSharpTestDtos', JavaExec) {
912913
'sbe.output.dir': 'csharp/sbe-generated',
913914
'sbe.target.language': 'uk.co.real_logic.sbe.generation.csharp.CSharpDtos',
914915
'sbe.xinclude.aware': 'true',
915-
'sbe.validation.xsd': validationXsdPath)
916+
'sbe.validation.xsd': validationXsdPath,
917+
'sbe.types.package.override': 'true')
916918
args = ['sbe-samples/src/main/resources/example-extension-schema.xml']
917919
}
918920

921+
tasks.register('generateCSharpExplicitPackageOverrideCodecs', JavaExec) {
922+
mainClass.set('uk.co.real_logic.sbe.SbeTool')
923+
classpath = project(':sbe-tool').sourceSets.main.runtimeClasspath
924+
systemProperties(
925+
'sbe.output.dir': 'csharp/sbe-generated',
926+
'sbe.target.language': 'uk.co.real_logic.sbe.generation.csharp.CSharp',
927+
'sbe.xinclude.aware': 'true',
928+
'sbe.generate.precedence.checks': 'true',
929+
'sbe.types.package.override': 'true')
930+
args = ['sbe-tool/src/test/resources/explicit-package-test-schema.xml']
931+
}
932+
933+
tasks.register('generateCSharpExplicitPackageOverrideDtos', JavaExec) {
934+
mainClass.set('uk.co.real_logic.sbe.SbeTool')
935+
classpath = project(':sbe-tool').sourceSets.main.runtimeClasspath
936+
systemProperties(
937+
'sbe.output.dir': 'csharp/sbe-generated',
938+
'sbe.target.language': 'uk.co.real_logic.sbe.generation.csharp.CSharpDtos',
939+
'sbe.xinclude.aware': 'true',
940+
'sbe.types.package.override': 'true')
941+
args = ['sbe-tool/src/test/resources/explicit-package-test-schema.xml']
942+
}
943+
919944
tasks.register('generateCSharpCodecs') {
920945
description = 'Generate csharp codecs'
921946
dependsOn 'generateCSharpTestCodecs',
922947
'generateCSharpTestDtos',
923-
'generateCSharpCodecsWithXIncludes'
948+
'generateCSharpCodecsWithXIncludes',
949+
'generateCSharpExplicitPackageOverrideCodecs',
950+
'generateCSharpExplicitPackageOverrideDtos'
924951
}
925952

926953
tasks.register('generateJavaIrCodecs', JavaExec) {

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,21 @@ public CodeGenerator newInstance(final Ir ir, final String outputDir)
107107
final NamespaceOutputManager outputManager = new NamespaceOutputManager(
108108
outputDir, ir.applicableNamespace());
109109
final boolean decodeUnknownEnumValues = Boolean.getBoolean(DECODE_UNKNOWN_ENUM_VALUES);
110+
final boolean shouldSupportTypesPackageNames = Boolean.getBoolean(TYPES_PACKAGE_OVERRIDE);
110111

111-
final CodeGenerator codecGenerator = new CppGenerator(ir, decodeUnknownEnumValues, precedenceChecks(),
112+
final CodeGenerator codecGenerator = new CppGenerator(
113+
ir,
114+
decodeUnknownEnumValues,
115+
precedenceChecks(),
116+
shouldSupportTypesPackageNames,
112117
outputManager);
113118

114119
if (Boolean.getBoolean(CPP_GENERATE_DTOS))
115120
{
116-
final CodeGenerator dtoGenerator = new CppDtoGenerator(ir, outputManager);
121+
final CodeGenerator dtoGenerator = new CppDtoGenerator(
122+
ir,
123+
shouldSupportTypesPackageNames,
124+
outputManager);
117125
return () ->
118126
{
119127
codecGenerator.generate();

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

Lines changed: 82 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -50,27 +50,65 @@ public class CppDtoGenerator implements CodeGenerator
5050

5151
private final Ir ir;
5252
private final OutputManager outputManager;
53+
private final boolean shouldSupportTypesPackageNames;
54+
private final Map<String, String> namespaceByType = new HashMap<>();
5355

5456
/**
5557
* Create a new C++ DTO {@link CodeGenerator}.
5658
*
57-
* @param ir for the messages and types.
58-
* @param outputManager for generating the DTOs to.
59+
* @param ir for the messages and types.
60+
* @param shouldSupportTypesPackageNames generator support for types in their own package.
61+
* @param outputManager for generating the DTOs to.
5962
*/
60-
public CppDtoGenerator(final Ir ir, final OutputManager outputManager)
63+
public CppDtoGenerator(
64+
final Ir ir,
65+
final boolean shouldSupportTypesPackageNames,
66+
final OutputManager outputManager)
6167
{
6268
Verify.notNull(ir, "ir");
6369
Verify.notNull(outputManager, "outputManager");
6470

6571
this.ir = ir;
72+
this.shouldSupportTypesPackageNames = shouldSupportTypesPackageNames;
6673
this.outputManager = outputManager;
6774
}
6875

76+
private String[] fetchTypesPackageName(final Token token, final Ir ir)
77+
{
78+
if (!shouldSupportTypesPackageNames)
79+
{
80+
return ir.namespaces();
81+
}
82+
83+
if (token.packageName() != null)
84+
{
85+
return Ir.getNamespaces(token.packageName());
86+
}
87+
88+
return ir.namespaces();
89+
}
90+
6991
/**
7092
* {@inheritDoc}
7193
*/
7294
public void generate() throws IOException
7395
{
96+
namespaceByType.clear();
97+
98+
if (shouldSupportTypesPackageNames)
99+
{
100+
for (final List<Token> tokens : ir.types())
101+
{
102+
final Token token = tokens.get(0);
103+
final String packageName = token.packageName();
104+
105+
if (packageName != null)
106+
{
107+
namespaceByType.put(token.applicableTypeName(), packageName);
108+
}
109+
}
110+
}
111+
74112
generateDtosForTypes();
75113

76114
for (final List<Token> tokens : ir.messages())
@@ -116,13 +154,14 @@ public void generate() throws IOException
116154
final Set<String> referencedTypes = generateTypesToIncludes(beginTypeTokensInSchema);
117155
referencedTypes.add(codecClassName);
118156

157+
final String[] namespaces = fetchTypesPackageName(msgToken, ir);
119158
out.append(generateDtoFileHeader(
120-
ir.namespaces(),
159+
namespaces,
121160
className,
122161
referencedTypes));
123162
out.append(generateDocumentation(BASE_INDENT, msgToken));
124163
classBuilder.appendTo(out);
125-
out.append(CppUtil.closingBraces(ir.namespaces().length));
164+
out.append(CppUtil.closingBraces(namespaces.length));
126165
out.append("#endif\n");
127166
}
128167
}
@@ -1732,7 +1771,8 @@ private void generateDtosForTypes() throws IOException
17321771

17331772
private void generateComposite(final List<Token> tokens) throws IOException
17341773
{
1735-
final String name = tokens.get(0).applicableTypeName();
1774+
final Token token = tokens.get(0);
1775+
final String name = token.applicableTypeName();
17361776
final String className = formatDtoClassName(name);
17371777
final String codecClassName = formatClassName(name);
17381778

@@ -1741,8 +1781,9 @@ private void generateComposite(final List<Token> tokens) throws IOException
17411781
final List<Token> compositeTokens = tokens.subList(1, tokens.size() - 1);
17421782
final Set<String> referencedTypes = generateTypesToIncludes(compositeTokens);
17431783
referencedTypes.add(codecClassName);
1744-
out.append(generateDtoFileHeader(ir.namespaces(), className, referencedTypes));
1745-
out.append(generateDocumentation(BASE_INDENT, tokens.get(0)));
1784+
final String[] namespaces = fetchTypesPackageName(token, ir);
1785+
out.append(generateDtoFileHeader(namespaces, className, referencedTypes));
1786+
out.append(generateDocumentation(BASE_INDENT, token));
17461787

17471788
final ClassBuilder classBuilder = new ClassBuilder(className, BASE_INDENT);
17481789

@@ -1754,14 +1795,15 @@ private void generateComposite(final List<Token> tokens) throws IOException
17541795
codecClassName + "::sbeSchemaVersion()", BASE_INDENT + INDENT);
17551796

17561797
classBuilder.appendTo(out);
1757-
out.append(CppUtil.closingBraces(ir.namespaces().length));
1798+
out.append(CppUtil.closingBraces(namespaces.length));
17581799
out.append("#endif\n");
17591800
}
17601801
}
17611802

17621803
private void generateChoiceSet(final List<Token> tokens) throws IOException
17631804
{
1764-
final String name = tokens.get(0).applicableTypeName();
1805+
final Token token = tokens.get(0);
1806+
final String name = token.applicableTypeName();
17651807
final String className = formatDtoClassName(name);
17661808
final String codecClassName = formatClassName(name);
17671809

@@ -1770,7 +1812,8 @@ private void generateChoiceSet(final List<Token> tokens) throws IOException
17701812
final List<Token> setTokens = tokens.subList(1, tokens.size() - 1);
17711813
final Set<String> referencedTypes = generateTypesToIncludes(setTokens);
17721814
referencedTypes.add(codecClassName);
1773-
out.append(generateDtoFileHeader(ir.namespaces(), className, referencedTypes));
1815+
final String[] namespaces = fetchTypesPackageName(token, ir);
1816+
out.append(generateDtoFileHeader(namespaces, className, referencedTypes));
17741817
out.append(generateDocumentation(BASE_INDENT, tokens.get(0)));
17751818

17761819
final ClassBuilder classBuilder = new ClassBuilder(className, BASE_INDENT);
@@ -1780,7 +1823,7 @@ private void generateChoiceSet(final List<Token> tokens) throws IOException
17801823
generateChoiceSetEncodeWith(classBuilder, className, codecClassName, setTokens, BASE_INDENT + INDENT);
17811824

17821825
classBuilder.appendTo(out);
1783-
out.append(CppUtil.closingBraces(ir.namespaces().length));
1826+
out.append(CppUtil.closingBraces(namespaces.length));
17841827
out.append("#endif\n");
17851828
}
17861829
}
@@ -1965,7 +2008,7 @@ private static CharSequence typeWithFieldOptionality(
19652008
}
19662009
}
19672010

1968-
private static CharSequence generateDtoFileHeader(
2011+
private CharSequence generateDtoFileHeader(
19692012
final CharSequence[] namespaces,
19702013
final String className,
19712014
final Collection<String> typesToInclude)
@@ -2010,6 +2053,32 @@ private static CharSequence generateDtoFileHeader(
20102053
sb.append(String.join(" {\nnamespace ", namespaces));
20112054
sb.append(" {\n\n");
20122055

2056+
if (shouldSupportTypesPackageNames && typesToInclude != null && !typesToInclude.isEmpty())
2057+
{
2058+
final Set<String> namespacesToUse = namespaceByType
2059+
.entrySet()
2060+
.stream()
2061+
.filter(e -> typesToInclude.contains(e.getKey()))
2062+
.map(Map.Entry::getValue)
2063+
.collect(Collectors.toSet());
2064+
2065+
// remove the current namespace
2066+
namespacesToUse.remove(String.join(".", namespaces));
2067+
2068+
for (final String namespace : namespacesToUse)
2069+
{
2070+
sb
2071+
.append("using namespace ")
2072+
.append(namespace.replaceAll("\\.", "::"))
2073+
.append(";\n");
2074+
}
2075+
2076+
if (!namespacesToUse.isEmpty())
2077+
{
2078+
sb.append("\n");
2079+
}
2080+
}
2081+
20132082
return sb;
20142083
}
20152084

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,6 @@ public class CppDtos implements TargetCodeGenerator
3131
*/
3232
public CodeGenerator newInstance(final Ir ir, final String outputDir)
3333
{
34-
return new CppDtoGenerator(ir, new NamespaceOutputManager(outputDir, ir.applicableNamespace()));
34+
return new CppDtoGenerator(ir, false, new NamespaceOutputManager(outputDir, ir.applicableNamespace()));
3535
}
3636
}

0 commit comments

Comments
 (0)