diff --git a/code-generator/src/main/java/io/streamnative/lightproto/generator/LightProto.java b/code-generator/src/main/java/io/streamnative/lightproto/generator/LightProto.java index ddf74c6..ef0e110 100644 --- a/code-generator/src/main/java/io/streamnative/lightproto/generator/LightProto.java +++ b/code-generator/src/main/java/io/streamnative/lightproto/generator/LightProto.java @@ -40,12 +40,19 @@ public class LightProto { public LightProto(ProtoFileDescriptor proto, String protoFileName, String outerClassName, boolean useOuterClass) { - this(proto, protoFileName, outerClassName, useOuterClass, false); + this(proto, protoFileName, outerClassName, useOuterClass, false, false); } public LightProto(ProtoFileDescriptor proto, String protoFileName, String outerClassName, boolean useOuterClass, boolean generateTextFormat) { + this(proto, protoFileName, outerClassName, useOuterClass, generateTextFormat, false); + } + + public LightProto(ProtoFileDescriptor proto, String protoFileName, + String outerClassName, boolean useOuterClass, + boolean generateTextFormat, + boolean generateJson) { this.proto = proto; this.protoFileName = protoFileName; this.outerClassName = outerClassName; @@ -59,7 +66,7 @@ public LightProto(ProtoFileDescriptor proto, String protoFileName, " */%n", LightProtoGenerator.getVersion(), protoFileName); this.enums = proto.getEnumGroups().stream().map(LightProtoEnum::new).collect(Collectors.toList()); - this.messages = proto.getMessages().stream().map(m -> new LightProtoMessage(m, useOuterClass, generateTextFormat)).collect(Collectors.toList()); + this.messages = proto.getMessages().stream().map(m -> new LightProtoMessage(m, useOuterClass, generateTextFormat, generateJson)).collect(Collectors.toList()); this.services = proto.getServices().stream().map(LightProtoService::new).collect(Collectors.toList()); } diff --git a/code-generator/src/main/java/io/streamnative/lightproto/generator/LightProtoGenerator.java b/code-generator/src/main/java/io/streamnative/lightproto/generator/LightProtoGenerator.java index 6e62947..5689d1b 100644 --- a/code-generator/src/main/java/io/streamnative/lightproto/generator/LightProtoGenerator.java +++ b/code-generator/src/main/java/io/streamnative/lightproto/generator/LightProtoGenerator.java @@ -51,13 +51,21 @@ static String getVersion() { public static List generate(List descriptors, File outputDirectory, String classPrefix, boolean useOuterClass, List fileNames) throws Exception { - return generate(descriptors, outputDirectory, classPrefix, useOuterClass, fileNames, false); + return generate(descriptors, outputDirectory, classPrefix, useOuterClass, fileNames, false, false); } public static List generate(List descriptors, File outputDirectory, String classPrefix, boolean useOuterClass, List fileNames, boolean generateTextFormat) throws Exception { + return generate(descriptors, outputDirectory, classPrefix, useOuterClass, fileNames, generateTextFormat, false); + } + + public static List generate(List descriptors, File outputDirectory, + String classPrefix, boolean useOuterClass, + List fileNames, + boolean generateTextFormat, + boolean generateJson) throws Exception { List generatedFiles = new ArrayList<>(); Set javaPackages = new HashSet<>(); @@ -74,7 +82,7 @@ public static List generate(List descriptors, File ou String javaDir = Joiner.on('/').join(javaPackageName.split("\\.")); Path targetDir = Paths.get(String.format("%s/%s", outputDirectory, javaDir)); - LightProto lightProto = new LightProto(proto, fileName, outerClassName, useOuterClass, generateTextFormat); + LightProto lightProto = new LightProto(proto, fileName, outerClassName, useOuterClass, generateTextFormat, generateJson); generatedFiles.addAll(lightProto.generate(targetDir.toFile())); javaPackages.add(javaPackageName); diff --git a/code-generator/src/main/java/io/streamnative/lightproto/generator/LightProtoMessage.java b/code-generator/src/main/java/io/streamnative/lightproto/generator/LightProtoMessage.java index c201fbd..83356c4 100644 --- a/code-generator/src/main/java/io/streamnative/lightproto/generator/LightProtoMessage.java +++ b/code-generator/src/main/java/io/streamnative/lightproto/generator/LightProtoMessage.java @@ -27,6 +27,7 @@ public class LightProtoMessage { private final ProtoMessageDescriptor message; private final boolean isNested; private final boolean generateTextFormat; + private final boolean generateJson; private final List enums; private final List fields; private final List nestedMessages; @@ -34,15 +35,21 @@ public class LightProtoMessage { private final Map> oneofFields; public LightProtoMessage(ProtoMessageDescriptor message, boolean isNested) { - this(message, isNested, false); + this(message, isNested, false, false); } public LightProtoMessage(ProtoMessageDescriptor message, boolean isNested, boolean generateTextFormat) { + this(message, isNested, generateTextFormat, false); + } + + public LightProtoMessage(ProtoMessageDescriptor message, boolean isNested, + boolean generateTextFormat, boolean generateJson) { this.message = message; this.isNested = isNested; this.generateTextFormat = generateTextFormat; + this.generateJson = generateJson; this.enums = message.getNestedEnumGroups().stream().map(LightProtoEnum::new).collect(Collectors.toList()); - this.nestedMessages = message.getNestedMessages().stream().map(m -> new LightProtoMessage(m, true, generateTextFormat)).collect(Collectors.toList()); + this.nestedMessages = message.getNestedMessages().stream().map(m -> new LightProtoMessage(m, true, generateTextFormat, generateJson)).collect(Collectors.toList()); this.oneofs = message.getOneofs(); this.fields = new ArrayList<>(); @@ -83,13 +90,17 @@ public void generate(PrintWriter w) { generateOneofFields(w); generateSerialize(w); generateGetSerializedSize(w); - generateWriteJsonTo(w); + if (generateJson) { + generateWriteJsonTo(w); + } generateParseFrom(w); generateCheckRequiredFields(w); generateClear(w); generateCopyFrom(w); - generateParseFromJson(w); + if (generateJson) { + generateParseFromJson(w); + } if (generateTextFormat) { generateWriteTextFormatTo(w); generateParseFromTextFormat(w); @@ -281,7 +292,7 @@ private void generateWriteJsonTo(PrintWriter w) { w.println(" * the protobuf JSON encoding (lowerCamelCase field names)."); w.println(" * @return the number of bytes written"); w.println(" */"); - w.format(" @Override public int writeJsonTo(io.netty.buffer.ByteBuf _b) {\n"); + w.format(" public int writeJsonTo(io.netty.buffer.ByteBuf _b) {\n"); w.format(" int _wIdx = _b.writerIndex();\n"); w.format(" _b.writeByte('{');\n"); w.format(" boolean _first = true;\n"); @@ -317,20 +328,26 @@ private void generateWriteJsonTo(PrintWriter w) { // Convenience method: toJson() w.println(" /** Serialize this message to a JSON string. */"); w.println(" public String toJson() {"); - w.println(" return LightProtoCodec.toJson(this);"); + w.println(" io.netty.buffer.ByteBuf _b = io.netty.buffer.Unpooled.buffer(256);"); + w.println(" try {"); + w.println(" writeJsonTo(_b);"); + w.println(" return _b.toString(java.nio.charset.StandardCharsets.UTF_8);"); + w.println(" } finally {"); + w.println(" _b.release();"); + w.println(" }"); w.println(" }"); } private void generateParseFromJson(PrintWriter w) { // Public API: parseFromJson(byte[]) w.println(" /** Deserialize this message from a JSON byte array. */"); - w.println(" @Override public void parseFromJson(byte[] _a) {"); + w.println(" public void parseFromJson(byte[] _a) {"); w.println(" parseFromJson(io.netty.buffer.Unpooled.wrappedBuffer(_a));"); w.println(" }"); // Public API: parseFromJson(ByteBuf) w.println(" /** Deserialize this message from a JSON-encoded ByteBuf. */"); - w.println(" @Override public void parseFromJson(io.netty.buffer.ByteBuf _b) {"); + w.println(" public void parseFromJson(io.netty.buffer.ByteBuf _b) {"); w.println(" clear();"); w.println(" _parseJsonObject(new LightProtoCodec.JsonReader(_b));"); w.println(" }"); diff --git a/code-generator/src/main/resources/io/streamnative/lightproto/generator/LightProtoCodec.java b/code-generator/src/main/resources/io/streamnative/lightproto/generator/LightProtoCodec.java index c068755..12bcdbd 100644 --- a/code-generator/src/main/resources/io/streamnative/lightproto/generator/LightProtoCodec.java +++ b/code-generator/src/main/resources/io/streamnative/lightproto/generator/LightProtoCodec.java @@ -576,28 +576,11 @@ static void skipUnknownField(int tag, ByteBuf buffer) { interface LightProtoMessage { int getSerializedSize(); int writeTo(ByteBuf b); - int writeJsonTo(ByteBuf b); void parseFrom(ByteBuf buffer, int size); void parseFrom(byte[] a); - void parseFromJson(byte[] a); - void parseFromJson(ByteBuf b); void materialize(); } - static void parseFromJson(LightProtoMessage msg, String json) { - msg.parseFromJson(json.getBytes(java.nio.charset.StandardCharsets.UTF_8)); - } - - static String toJson(LightProtoMessage msg) { - ByteBuf buf = io.netty.buffer.Unpooled.buffer(256); - try { - msg.writeJsonTo(buf); - return buf.toString(java.nio.charset.StandardCharsets.UTF_8); - } finally { - buf.release(); - } - } - static final class StringHolder { String s; int idx; diff --git a/gradle-plugin/src/main/java/io/streamnative/lightproto/gradle/GenerateLightProtoTask.java b/gradle-plugin/src/main/java/io/streamnative/lightproto/gradle/GenerateLightProtoTask.java index cc51894..a69abe7 100644 --- a/gradle-plugin/src/main/java/io/streamnative/lightproto/gradle/GenerateLightProtoTask.java +++ b/gradle-plugin/src/main/java/io/streamnative/lightproto/gradle/GenerateLightProtoTask.java @@ -49,6 +49,9 @@ public abstract class GenerateLightProtoTask extends DefaultTask { @Input public abstract Property getGenerateTextFormat(); + @Input + public abstract Property getGenerateJson(); + @Input public abstract Property getProtocVersion(); @@ -147,7 +150,8 @@ public void generate() { } LightProtoGenerator.generate(descriptors, outputDir, getClassPrefix().get(), - getSingleOuterClass().get(), fileNames, getGenerateTextFormat().get()); + getSingleOuterClass().get(), fileNames, getGenerateTextFormat().get(), + getGenerateJson().get()); } catch (GradleException e) { throw e; } catch (Exception e) { diff --git a/gradle-plugin/src/main/java/io/streamnative/lightproto/gradle/LightProtoExtension.java b/gradle-plugin/src/main/java/io/streamnative/lightproto/gradle/LightProtoExtension.java index 39ee205..a0440f1 100644 --- a/gradle-plugin/src/main/java/io/streamnative/lightproto/gradle/LightProtoExtension.java +++ b/gradle-plugin/src/main/java/io/streamnative/lightproto/gradle/LightProtoExtension.java @@ -27,6 +27,8 @@ public abstract class LightProtoExtension { public abstract Property getGenerateTextFormat(); + public abstract Property getGenerateJson(); + public abstract Property getProtocVersion(); public abstract Property getProtocPath(); diff --git a/gradle-plugin/src/main/java/io/streamnative/lightproto/gradle/LightProtoPlugin.java b/gradle-plugin/src/main/java/io/streamnative/lightproto/gradle/LightProtoPlugin.java index 8f065ec..05e970b 100644 --- a/gradle-plugin/src/main/java/io/streamnative/lightproto/gradle/LightProtoPlugin.java +++ b/gradle-plugin/src/main/java/io/streamnative/lightproto/gradle/LightProtoPlugin.java @@ -35,6 +35,7 @@ public void apply(Project project) { extension.getClassPrefix().convention(""); extension.getSingleOuterClass().convention(false); extension.getGenerateTextFormat().convention(false); + extension.getGenerateJson().convention(false); extension.getProtocVersion().convention("4.34.0"); registerTaskForSourceSet(project, extension, "main"); @@ -53,6 +54,7 @@ private void registerTaskForSourceSet(Project project, LightProtoExtension exten task.getClassPrefix().set(extension.getClassPrefix()); task.getSingleOuterClass().set(extension.getSingleOuterClass()); task.getGenerateTextFormat().set(extension.getGenerateTextFormat()); + task.getGenerateJson().set(extension.getGenerateJson()); task.getProtocVersion().set(extension.getProtocVersion()); task.getProtocPath().set(extension.getProtocPath()); task.getExtraProtoPaths().from(extension.getExtraProtoPaths()); diff --git a/maven-plugin/src/main/java/io/streamnative/lightproto/maven/plugin/LightProtoMojo.java b/maven-plugin/src/main/java/io/streamnative/lightproto/maven/plugin/LightProtoMojo.java index 6177c53..6a82f60 100644 --- a/maven-plugin/src/main/java/io/streamnative/lightproto/maven/plugin/LightProtoMojo.java +++ b/maven-plugin/src/main/java/io/streamnative/lightproto/maven/plugin/LightProtoMojo.java @@ -58,6 +58,9 @@ public class LightProtoMojo extends AbstractMojo { @Parameter(property = "generateTextFormat", defaultValue = "false", required = false) private boolean generateTextFormat; + @Parameter(property = "generateJson", defaultValue = "false", required = false) + private boolean generateJson; + @Parameter(property = "sources", required = false) private List sources; @@ -162,7 +165,7 @@ private void generate(File protoDir, List protoFiles, File outputDirectory } } - LightProtoGenerator.generate(descriptors, outputDirectory, classPrefix, singleOuterClass, fileNames, generateTextFormat); + LightProtoGenerator.generate(descriptors, outputDirectory, classPrefix, singleOuterClass, fileNames, generateTextFormat, generateJson); } catch (MojoExecutionException e) { throw e; } catch (Exception e) { diff --git a/tests/pom.xml b/tests/pom.xml index 3bf5a7e..1f9262f 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -101,6 +101,7 @@ ${project.version} true + true