Skip to content

Commit 49d7a42

Browse files
committed
[Java] toString generation for debugging purpose
Change-Id: I3b45eb18c24ddbc3d6b4c278b38e677d4f6245ed
1 parent 554eea9 commit 49d7a42

File tree

3 files changed

+299
-0
lines changed

3 files changed

+299
-0
lines changed

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

Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,9 @@ private void generateEncoder(
213213
out.append(sb);
214214

215215
out.append(generateEncoderVarData(className, varData, indent));
216+
217+
out.append(generateEncoderDisplay(formatClassName(decoderName(msgToken.name())), indent));
218+
216219
out.append("}\n");
217220
}
218221
}
@@ -242,6 +245,8 @@ private void generateDecoder(
242245

243246
out.append(generateDecoderVarData(varData, BASE_INDENT));
244247

248+
out.append(generateDecoderDisplay(msgToken.name(), fields, groups, varData, BASE_INDENT));
249+
245250
out.append("}\n");
246251
}
247252
}
@@ -282,6 +287,8 @@ private void generateDecoderGroups(
282287
i = collectVarData(tokens, i, varData);
283288
sb.append(generateDecoderVarData(varData, indent + INDENT));
284289

290+
appendGroupInstanceDecoderDisplay(sb, fields, groups, varData, indent + INDENT);
291+
285292
sb.append(indent).append(" }\n");
286293
}
287294
}
@@ -940,6 +947,7 @@ private void generateBitSet(final List<Token> tokens) throws IOException
940947
{
941948
generateFixedFlyweightHeader(token, decoderName, out, readOnlyBuffer, fqReadOnlyBuffer, "");
942949
out.append(generateChoiceDecoders(messageBody));
950+
out.append(generateChoiceDisplay(messageBody));
943951
out.append("}\n");
944952
}
945953

@@ -1022,6 +1030,8 @@ private void generateComposite(final List<Token> tokens) throws IOException
10221030
}
10231031
}
10241032

1033+
out.append(generateCompositeDecoderDisplay(tokens, BASE_INDENT));
1034+
10251035
out.append("}\n");
10261036
}
10271037

@@ -1057,6 +1067,8 @@ private void generateComposite(final List<Token> tokens) throws IOException
10571067
}
10581068
}
10591069

1070+
out.append(generateCompositeEncoderDisplay(decoderName, BASE_INDENT));
1071+
10601072
out.append("}\n");
10611073
}
10621074
}
@@ -2367,4 +2379,275 @@ private String generateChoicePut(
23672379

23682380
throw new IllegalArgumentException("primitive type not supported: " + type);
23692381
}
2382+
2383+
private CharSequence generateEncoderDisplay(String decoderName, String baseIndent)
2384+
{
2385+
final String indent = baseIndent + " ";
2386+
final StringBuilder sb = new StringBuilder();
2387+
appendToString(sb, indent);
2388+
sb.append("\n");
2389+
addLine(sb, indent, "public StringBuilder appendTo(StringBuilder builder)");
2390+
addLine(sb, indent, "{");
2391+
addLine(sb, indent, " " + decoderName + " writer = new " + decoderName + "();");
2392+
addLine(sb, indent, " writer.wrap(buffer, offset, BLOCK_LENGTH, SCHEMA_VERSION);");
2393+
addLine(sb, indent, " return writer.appendTo(builder);");
2394+
addLine(sb, indent, "}");
2395+
return sb.toString();
2396+
}
2397+
2398+
private CharSequence generateCompositeEncoderDisplay(String decoderName, String baseIndent)
2399+
{
2400+
final String indent = baseIndent + " ";
2401+
final StringBuilder sb = new StringBuilder();
2402+
appendToString(sb, indent);
2403+
sb.append("\n");
2404+
addLine(sb, indent, "public StringBuilder appendTo(StringBuilder builder)");
2405+
addLine(sb, indent, "{");
2406+
addLine(sb, indent, " " + decoderName + " writer = new " + decoderName + "();");
2407+
addLine(sb, indent, " writer.wrap(buffer, offset);");
2408+
addLine(sb, indent, " return writer.appendTo(builder);");
2409+
addLine(sb, indent, "}");
2410+
return sb.toString();
2411+
}
2412+
2413+
private CharSequence generateCompositeDecoderDisplay(List<Token> tokens, String baseIndent)
2414+
{
2415+
final String indent = baseIndent + " ";
2416+
final StringBuilder sb = new StringBuilder();
2417+
appendToString(sb, indent);
2418+
sb.append("\n");
2419+
addLine(sb, indent, "public StringBuilder appendTo(StringBuilder builder)");
2420+
addLine(sb, indent, "{");
2421+
addLine(sb, indent, " builder.append(\"[\");");
2422+
for (int i = 1, end = tokens.size() - 1; i < end; i++)
2423+
{
2424+
final Token encodingToken = tokens.get(i);
2425+
final String propertyName = formatPropertyName(encodingToken.name());
2426+
writeTokenDisplay(propertyName, encodingToken, sb, indent + " ");
2427+
if (encodingToken.signal() == Signal.BEGIN_COMPOSITE)
2428+
{
2429+
i = findEndSignal(tokens, i, Signal.END_COMPOSITE, encodingToken.name());
2430+
}
2431+
}
2432+
addLine(sb, indent, " builder.setLength(builder.length()-1);");
2433+
addLine(sb, indent, " builder.append(\"]\");");
2434+
addLine(sb, indent, " return builder;");
2435+
addLine(sb, indent, "}");
2436+
return sb.toString();
2437+
}
2438+
2439+
private CharSequence generateChoiceDisplay(List<Token> tokens)
2440+
{
2441+
final String indent = " ";
2442+
final StringBuilder sb = new StringBuilder();
2443+
appendToString(sb, indent);
2444+
sb.append("\n");
2445+
addLine(sb, indent, "public StringBuilder appendTo(StringBuilder builder)");
2446+
addLine(sb, indent, "{");
2447+
addLine(sb, indent, " builder.append('{');");
2448+
addLine(sb, indent, " boolean atLeastOne = false;");
2449+
tokens
2450+
.stream()
2451+
.filter((token) -> token.signal() == Signal.CHOICE)
2452+
.forEach(
2453+
(token) ->
2454+
{
2455+
final String choiceName = formatPropertyName(token.name());
2456+
addLine(sb, indent, " if(" + choiceName + "())");
2457+
addLine(sb, indent, " {");
2458+
addLine(sb, indent, " if(atLeastOne)");
2459+
addLine(sb, indent, " {");
2460+
addLine(sb, indent, " builder.append(',');");
2461+
addLine(sb, indent, " }");
2462+
addLine(sb, indent, " builder.append(\"" + choiceName + "\");");
2463+
addLine(sb, indent, " atLeastOne = true;");
2464+
addLine(sb, indent, " }");
2465+
}
2466+
);
2467+
addLine(sb, indent, " builder.append('}');");
2468+
addLine(sb, indent, " return builder;");
2469+
addLine(sb, indent, "}");
2470+
return sb.toString();
2471+
}
2472+
2473+
private CharSequence generateDecoderDisplay(
2474+
final String name,
2475+
final List<Token> tokens,
2476+
final List<Token> groups,
2477+
final List<Token> varLens,
2478+
final String indent) throws IOException
2479+
{
2480+
final StringBuilder sb = new StringBuilder();
2481+
sb.append("\n");
2482+
appendToString(sb, indent);
2483+
sb.append("\n");
2484+
addLine(sb, indent, "public StringBuilder appendTo(StringBuilder builder)");
2485+
addLine(sb, indent, "{");
2486+
addLine(sb, indent, " int realLimit = limit();");
2487+
addLine(sb, indent, " limit(offset + actingBlockLength);");
2488+
addLine(sb, indent, " builder.append(\"[" + name + "](sbeTemplateId=\");");
2489+
addLine(sb, indent, " builder.append(TEMPLATE_ID);");
2490+
addLine(sb, indent, " builder.append(\"|sbeSchemaId=\");");
2491+
addLine(sb, indent, " builder.append(SCHEMA_ID);");
2492+
addLine(sb, indent, " builder.append(\"|sbeSchemaVersion=\");");
2493+
addLine(sb, indent, " if (actingVersion != SCHEMA_VERSION)");
2494+
addLine(sb, indent, " {");
2495+
addLine(sb, indent, " builder.append(actingVersion);");
2496+
addLine(sb, indent, " builder.append('/');");
2497+
addLine(sb, indent, " }");
2498+
addLine(sb, indent, " builder.append(SCHEMA_VERSION);");
2499+
addLine(sb, indent, " builder.append(\"|sbeBlockLength=\");");
2500+
addLine(sb, indent, " if (actingBlockLength != BLOCK_LENGTH)");
2501+
addLine(sb, indent, " {");
2502+
addLine(sb, indent, " builder.append(actingBlockLength);");
2503+
addLine(sb, indent, " builder.append('/');");
2504+
addLine(sb, indent, " }");
2505+
addLine(sb, indent, " builder.append(BLOCK_LENGTH);");
2506+
addLine(sb, indent, " builder.append(\"):\");");
2507+
appendDecoderDisplay(sb, tokens, groups, varLens, indent + " ");
2508+
addLine(sb, indent, " limit(realLimit);");
2509+
addLine(sb, indent, " return builder;");
2510+
addLine(sb, indent, "}");
2511+
return sb.toString();
2512+
}
2513+
2514+
private StringBuilder appendGroupInstanceDecoderDisplay(
2515+
final StringBuilder sb,
2516+
final List<Token> tokens,
2517+
final List<Token> groups,
2518+
final List<Token> varLens,
2519+
final String indent)
2520+
{
2521+
sb.append("\n");
2522+
appendToString(sb, indent);
2523+
sb.append("\n");
2524+
addLine(sb, indent, "public StringBuilder appendTo(StringBuilder builder)");
2525+
addLine(sb, indent, "{");
2526+
appendDecoderDisplay(sb, tokens, groups, varLens, indent + " ");
2527+
addLine(sb, indent, " return builder;");
2528+
addLine(sb, indent, "}");
2529+
return sb;
2530+
}
2531+
2532+
private StringBuilder appendDecoderDisplay(
2533+
final StringBuilder sb,
2534+
final List<Token> tokens,
2535+
final List<Token> groups,
2536+
final List<Token> varLens,
2537+
final String indent)
2538+
{
2539+
eachField(
2540+
tokens,
2541+
(fieldToken, typeToken) ->
2542+
{
2543+
final String fieldName = formatPropertyName(fieldToken.name());
2544+
addLine(sb, indent, "//" + fieldToken);
2545+
writeTokenDisplay(fieldName, typeToken, sb, indent);
2546+
}
2547+
);
2548+
//groups
2549+
for (int i = 0, size = groups.size(); i < size; i++)
2550+
{
2551+
final Token groupToken = groups.get(i);
2552+
if (groupToken.signal() != Signal.BEGIN_GROUP)
2553+
{
2554+
throw new IllegalStateException("tokens must begin with BEGIN_GROUP: token=" + groupToken);
2555+
}
2556+
addLine(sb, indent, "//" + groupToken);
2557+
final String groupName = formatPropertyName(groupToken.name());
2558+
final String groupDecoderName = decoderName(formatClassName(groupToken.name()));
2559+
addLine(sb, indent, "builder.append(\"" + groupName + "={\");");
2560+
addLine(sb, indent, groupDecoderName + " " + groupName + " = " + groupName + "();");
2561+
addLine(sb, indent, "while (" + groupName + ".hasNext())");
2562+
addLine(sb, indent, "{");
2563+
addLine(sb, indent, " builder.append('[');");
2564+
addLine(sb, indent, " " + groupName + ".next().appendTo(builder);");
2565+
addLine(sb, indent, " builder.setLength(builder.length()-1);");
2566+
addLine(sb, indent, " builder.append(']');");
2567+
addLine(sb, indent, "}");
2568+
addLine(sb, indent, "builder.append(\"}|\");");
2569+
i = findEndSignal(groups, i, Signal.END_GROUP, groupToken.name());
2570+
}
2571+
//varLength
2572+
for (int i = 0, size = varLens.size(); i < size;)
2573+
{
2574+
final Token varLenToken = varLens.get(i);
2575+
if (varLenToken.signal() != Signal.BEGIN_VAR_DATA)
2576+
{
2577+
throw new IllegalStateException("tokens must begin with BEGIN_VAR_DATA: token=" + varLenToken);
2578+
}
2579+
addLine(sb, indent, "//" + varLenToken);
2580+
final String varLenName = formatPropertyName(varLenToken.name());
2581+
addLine(sb, indent, "builder.append(\"" + varLenName + "=\");");
2582+
addLine(sb, indent, "builder.append(" + varLenName + "());");
2583+
addLine(sb, indent, "builder.append('|');");
2584+
i += varLenToken.componentTokenCount();
2585+
}
2586+
return sb;
2587+
}
2588+
2589+
private void writeTokenDisplay(final String fieldName,
2590+
final Token typeToken,
2591+
final StringBuilder sb,
2592+
final String indent)
2593+
{
2594+
addLine(sb, indent, "//" + typeToken);
2595+
// not interested in anything not "binarily" present
2596+
if (typeToken.encodedLength() <= 0 || typeToken.isConstantEncoding())
2597+
{
2598+
return;
2599+
}
2600+
addLine(sb, indent, "builder.append(\"" + fieldName + "=\");");
2601+
switch (typeToken.signal())
2602+
{
2603+
case ENCODING:
2604+
if (typeToken.arrayLength() > 1)
2605+
{
2606+
if (typeToken.encoding().primitiveType() == PrimitiveType.CHAR)
2607+
{
2608+
addLine(sb, indent, "for(int i = 0; i < " + fieldName + "Length() && " +
2609+
fieldName + "(i)>0; i++)");
2610+
addLine(sb, indent, "{");
2611+
addLine(sb, indent, " builder.append((char)" + fieldName + "(i));");
2612+
addLine(sb, indent, "}");
2613+
}
2614+
else
2615+
{
2616+
addLine(sb, indent, "builder.append('[');");
2617+
addLine(sb, indent, "if (" + fieldName + "Length() > 0)");
2618+
addLine(sb, indent, "{");
2619+
addLine(sb, indent, " for(int i = 0; i < " + fieldName + "Length(); i++)");
2620+
addLine(sb, indent, " {");
2621+
addLine(sb, indent, " builder.append(" + fieldName + "(i)).append(',');");
2622+
addLine(sb, indent, " }");
2623+
addLine(sb, indent, " builder.setLength(builder.length()-1);");
2624+
addLine(sb, indent, "}");
2625+
addLine(sb, indent, "builder.append(']');");
2626+
}
2627+
}
2628+
else
2629+
{
2630+
// have to duplicate because of checkstyle :/
2631+
addLine(sb, indent, "builder.append(" + fieldName + "());");
2632+
}
2633+
break;
2634+
case BEGIN_ENUM:
2635+
case BEGIN_SET:
2636+
addLine(sb, indent, "builder.append(" + fieldName + "());");
2637+
break;
2638+
case BEGIN_COMPOSITE:
2639+
addLine(sb, indent, fieldName + "().appendTo(builder);");
2640+
break;
2641+
}
2642+
addLine(sb, indent, "builder.append('|');");
2643+
}
2644+
2645+
private void appendToString(final StringBuilder sb, final String indent)
2646+
{
2647+
sb.append("\n");
2648+
addLine(sb, indent, "public String toString()");
2649+
addLine(sb, indent, "{");
2650+
addLine(sb, indent, " return appendTo(new StringBuilder(100)).toString();");
2651+
addLine(sb, indent, "}");
2652+
}
23702653
}

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,17 @@ public static String formatClassName(final String value)
116116
{
117117
return toUpperFirstChar(value);
118118
}
119+
120+
121+
/**
122+
* Shortcut to add a line of generated code
123+
*
124+
* @param builder string builder to which to add the line
125+
* @param indent current text indentation
126+
* @param line line to be added
127+
*/
128+
public static void addLine(StringBuilder builder, String indent, String line)
129+
{
130+
builder.append(indent + line + "\n");
131+
}
119132
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import static org.hamcrest.CoreMatchers.is;
3737
import static org.hamcrest.Matchers.greaterThan;
3838
import static org.hamcrest.Matchers.hasToString;
39+
import static org.hamcrest.Matchers.startsWith;
3940
import static org.junit.Assert.*;
4041
import static org.mockito.Mockito.*;
4142
import static uk.co.real_logic.sbe.generation.CodeGenerator.MESSAGE_HEADER_DECODER_TYPE;
@@ -242,6 +243,8 @@ public void shouldGenerateBasicMessage() throws Exception
242243
final Object groupFlyweight = fuelFiguresCount(msgFlyweight, 0);
243244

244245
assertNotNull(groupFlyweight);
246+
247+
assertThat(msgFlyweight.toString(), startsWith("[Car]"));
245248
}
246249

247250
@Test

0 commit comments

Comments
 (0)