Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

taeber/java-multiline

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

7 Commits

Repository files navigation

Java Multiline Strings

An experiment using a custom Annotation to repurpose Javadocs as a multiline String.

Copyright © 2023 Taeber Rapczak <taeber@rapczak.com>. License: MIT .

Quickstart

make

Protobuf Message Templates

Building protobuf messages in Java is a bit tedious, especially when the message is complex and the values you're setting are few.

If I was given this template and asked to implement it:

subject: {
 id: ${agentId}
}
predicate: KNOWS
object: {
 name: ${fullname}
}

I'd probably write something like:

Expression expr =
 Expression.newBuilder()
 .setSubject(Thing.newBuilder().setId(agentId))
 .setPredicate(Predicate.KNOWS)
 .setObject(Thing.newBuilder().setName(fullname))
 .build();

Honestly, not bad once you get used to it and if you have an ML-assisted editor, you probably wouldn't think twice.

I've dealt with much more complex messages and wished that I could just use String.format with the template I was given, but alas there was no multiline string literal support in Java before Java 13 (JEP-355), so it becomes:

String msg = String.format(
 "subject: { " +
 " id: %d " +
 "} " +
 "predicate: KNOWS" +
 "object: { " +
 " name: %s " +
 "} ",
 006, "James Bond");

With the Annotation ProtobufTemplate and a custom Processor, you could instead write:

/**
 subject: {
 id: ${agentId}
 }
 predicate: KNOWS
 object: {
 name: "${fullname}"
 }
 */
@ProtobufTemplate("AgentKnowsAgentTemplate")
private static Expression buildAgentKnowsAgent(long agentId, String fullname) {
 return AgentKnowsAgentTemplate.format(agentId, fullname);
}

I originally had thought to generate the Builder code, but so far I'm still using com.google.protobuf.TextFormat.

Here's some sample generated output:

// THIS FILE WAS GENERATED by ProtobufTemplateProcessor.
package com.rapczak.taeber.protobuf;
import com.google.protobuf.TextFormat;
final class AgentKnowsAgentTemplate {
 private static String msg = "subject: {\n id: ${agentId}\n }\n predicate: KNOWS\n object: {\n name: \"${fullname}\"\n }";
 public static com.rapczak.taeber.protobuf.Expression format(long agentId,java.lang.String fullname) {
 var builder = com.rapczak.taeber.protobuf.Expression.newBuilder();
 String[] placeholders = {"agentId","fullname"};
 String[] replacements = {String.valueOf(agentId),fullname.toString()};
 var txt = msg;
 for (var i = 0; i < placeholders.length; i++) {
 txt = txt.replace("${" + placeholders[i] + "}", replacements[i]);
 }
 try {TextFormat.getParser().merge(txt, builder);}
 catch (Exception e) {throw new RuntimeException(e);}
 return builder.build();
 }
 private AgentKnowsAgentTemplate() {}
}

About

An experiment using a custom Annotation to repurpose Javadocs as a multiline String.

Topics

Resources

License

Stars

Watchers

Forks

AltStyle によって変換されたページ (->オリジナル) /