From 46242ce8f845cf2ed46013468c1cff020b0e40ff Mon Sep 17 00:00:00 2001 From: Noel Yap Date: Tue, 5 Sep 2017 13:01:00 -0700 Subject: [PATCH 1/3] protoc extensions supported. --- .../com/salesforce/jprotoc/ProtocPlugin.java | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/jprotoc/src/main/java/com/salesforce/jprotoc/ProtocPlugin.java b/jprotoc/src/main/java/com/salesforce/jprotoc/ProtocPlugin.java index 00aefc4f..21c3ee5c 100644 --- a/jprotoc/src/main/java/com/salesforce/jprotoc/ProtocPlugin.java +++ b/jprotoc/src/main/java/com/salesforce/jprotoc/ProtocPlugin.java @@ -9,13 +9,14 @@ import com.google.common.base.Preconditions; import com.google.common.io.ByteStreams; +import com.google.protobuf.ExtensionRegistry; +import com.google.protobuf.GeneratedMessage.GeneratedExtension; import com.google.protobuf.compiler.PluginProtos; - -import javax.annotation.Nonnull; import java.io.IOException; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; +import javax.annotation.Nonnull; /** * ProtocPlugin is the main entry point for running one or more java-base protoc plugins. This class handles @@ -40,13 +41,25 @@ public static void generate(@Nonnull Generator generator) { * @param generators The list of generators to run. */ public static void generate(@Nonnull List generators) { + generate(generators, Collections.emptyList()); + } + + public static void generate( + @Nonnull List generators, List extensions) { Preconditions.checkNotNull(generators, "generators"); Preconditions.checkArgument(!generators.isEmpty(), "generators.isEmpty()"); + Preconditions.checkNotNull(extensions, "extensions"); + + ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance(); + for (GeneratedExtension extension : extensions) { + extensionRegistry.add(extension); + } try { // Parse the input stream to extract the generator request byte[] generatorRequestBytes = ByteStreams.toByteArray(System.in); - PluginProtos.CodeGeneratorRequest request = PluginProtos.CodeGeneratorRequest.parseFrom(generatorRequestBytes); + PluginProtos.CodeGeneratorRequest request = PluginProtos.CodeGeneratorRequest.parseFrom( + generatorRequestBytes, extensionRegistry); // Run each file generator, collecting the output List outputFiles = generators From 37c203f5209f9760fcefef104d6a51636ad21664 Mon Sep 17 00:00:00 2001 From: Noel Yap Date: Wed, 6 Sep 2017 10:45:26 -0700 Subject: [PATCH 2/3] Documentation added. --- jprotoc/README.md | 41 ++++++++++++++++++- .../com/salesforce/jprotoc/ProtocPlugin.java | 9 ++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/jprotoc/README.md b/jprotoc/README.md index 878c9735..12dc0708 100644 --- a/jprotoc/README.md +++ b/jprotoc/README.md @@ -130,4 +130,43 @@ Using the Jdk8 Protoc generator 3. Reference the java 8 client stubs like this: ```java MyServiceGrpc8.GreeterCompletableFutureStub stub = MyServiceGrpc8.newCompletableFutureStub(channel); - ``` \ No newline at end of file + ``` + +Implementing Custom Protoc Options +================================== +1. Create a custom option as per https://developers.google.com/protocol-buffers/docs/reference/java-generated#extension. +For example: + + ``` + syntax = "proto3"; + + package com.example.proto.options; + + import "google/protobuf/descriptor.proto"; + + option java_multiple_files = true; + option java_outer_classname = "ServerOptionsProto"; + option java_package = "com.example.proto.options"; + + extend google.protobuf.FileOptions { + ServerOptions server = 50621; + } + + message ServerOptions { + // Java classname + string name = 1; + } + ``` + +2. Use `ProtocPlugin.generate(List generators, List extensions)` so +that the option gets registered: + + ``` + class Generator extends com.salesforce.jprotoc.Generator { + public static void main(String[] args) { + ProtocPlugin.generate([new Generator()], [com.example.proto.options.ServerOptionsProto.server]); + } + + // ? + } + ``` diff --git a/jprotoc/src/main/java/com/salesforce/jprotoc/ProtocPlugin.java b/jprotoc/src/main/java/com/salesforce/jprotoc/ProtocPlugin.java index 21c3ee5c..8d825711 100644 --- a/jprotoc/src/main/java/com/salesforce/jprotoc/ProtocPlugin.java +++ b/jprotoc/src/main/java/com/salesforce/jprotoc/ProtocPlugin.java @@ -44,12 +44,21 @@ public static void generate(@Nonnull List generators) { generate(generators, Collections.emptyList()); } + /** + * Apply multiple generators to the parsed proto descriptor, aggregating their results. + * Also register the given extensions so they may be processed by the generator. + * + * @param generators The list of generators to run. + * @param extensions The list of extensions to register. + */ public static void generate( @Nonnull List generators, List extensions) { Preconditions.checkNotNull(generators, "generators"); Preconditions.checkArgument(!generators.isEmpty(), "generators.isEmpty()"); Preconditions.checkNotNull(extensions, "extensions"); + // As per https://developers.google.com/protocol-buffers/docs/reference/java-generated#extension, + // extensions must be registered in order to be processed. ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance(); for (GeneratedExtension extension : extensions) { extensionRegistry.add(extension); From 5da2d2e45f96691c3ce0e18fc76e78f9d662cd36 Mon Sep 17 00:00:00 2001 From: Noel Yap Date: Wed, 6 Sep 2017 12:58:16 -0700 Subject: [PATCH 3/3] Step added to document generating code from an extension proto. --- jprotoc/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jprotoc/README.md b/jprotoc/README.md index 12dc0708..15307056 100644 --- a/jprotoc/README.md +++ b/jprotoc/README.md @@ -158,7 +158,9 @@ For example: } ``` -2. Use `ProtocPlugin.generate(List generators, List extensions)` so +2. Run the Protoc generator on the Extension proto. + +3. Use `ProtocPlugin.generate(List generators, List extensions)` so that the option gets registered: ```