Skip to content

Commit c513c31

Browse files
authored
Merge pull request #155 from salesforce/feature/proto3-optional
Implement proto3 optional support
2 parents 9abb217 + 0aa0985 commit c513c31

File tree

10 files changed

+79
-68
lines changed

10 files changed

+79
-68
lines changed

jprotoc/jprotoc-test/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@
4545
<artifactId>grpc-stub</artifactId>
4646
<scope>test</scope>
4747
</dependency>
48+
<dependency>
49+
<groupId>io.grpc</groupId>
50+
<artifactId>grpc-api</artifactId>
51+
<scope>test</scope>
52+
</dependency>
4853
<dependency>
4954
<groupId>io.grpc</groupId>
5055
<artifactId>grpc-protobuf</artifactId>

jprotoc/jprotoc-test/src/test/java/com/salesforce/jprotoc/CompletableFutureEndToEndTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public void serverRunsAndRespondsCorrectly() throws ExecutionException,
4242
server.start();
4343

4444
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", server.getPort())
45-
.usePlaintext(true)
45+
.usePlaintext()
4646
.build();
4747

4848
GreeterGrpc8.GreeterCompletableFutureStub stub = GreeterGrpc8.newCompletableFutureStub(channel);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
syntax = "proto3";
2+
3+
package my.optional;
4+
5+
message SomeParameter {
6+
optional string id = 1;
7+
}

jprotoc/jprotoc/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ public class MyGenerator extends Generator {
3535
}
3636
}
3737

38+
@Override
39+
protected List<PluginProtos.CodeGeneratorResponse.Feature> supportedFeatures() {
40+
return Collections.singletonList(PluginProtos.CodeGeneratorResponse.Feature.FEATURE_PROTO3_OPTIONAL);
41+
}
42+
3843
@Override
3944
public Stream<PluginProtos.CodeGeneratorResponse.File> generate(PluginProtos.CodeGeneratorRequest request)
4045
throws GeneratorException {

jprotoc/jprotoc/pom.xml

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,6 @@
1919
<artifactId>jprotoc</artifactId>
2020

2121
<dependencies>
22-
<dependency>
23-
<groupId>io.grpc</groupId>
24-
<artifactId>grpc-protobuf</artifactId>
25-
</dependency>
2622
<dependency>
2723
<groupId>com.github.spullara.mustache.java</groupId>
2824
<artifactId>compiler</artifactId>
@@ -36,46 +32,10 @@
3632
<artifactId>protobuf-java-util</artifactId>
3733
<version>${protoc.version}</version>
3834
</dependency>
39-
40-
<!-- Test dependencies -->
41-
<dependency>
42-
<groupId>junit</groupId>
43-
<artifactId>junit</artifactId>
44-
<scope>test</scope>
45-
</dependency>
46-
<dependency>
47-
<groupId>org.assertj</groupId>
48-
<artifactId>assertj-core</artifactId>
49-
<scope>test</scope>
50-
</dependency>
51-
<dependency>
52-
<groupId>commons-lang</groupId>
53-
<artifactId>commons-lang</artifactId>
54-
<scope>test</scope>
55-
</dependency>
5635
</dependencies>
5736

5837
<build>
5938
<plugins>
60-
<!-- <plugin>-->
61-
<!-- <groupId>org.springframework.boot</groupId>-->
62-
<!-- <artifactId>spring-boot-maven-plugin</artifactId>-->
63-
<!-- <version>1.5.8.RELEASE</version>-->
64-
<!-- <executions>-->
65-
<!-- <execution>-->
66-
<!-- <goals>-->
67-
<!-- <goal>repackage</goal>-->
68-
<!-- </goals>-->
69-
<!-- </execution>-->
70-
<!-- </executions>-->
71-
<!-- <configuration>-->
72-
<!-- <mainClass>com.salesforce.jprotoc.dump.DumpGenerator</mainClass>-->
73-
<!-- <layout>JAR</layout>-->
74-
<!-- <classifier>jdk8</classifier>-->
75-
<!-- <executable>true</executable>-->
76-
<!-- </configuration>-->
77-
<!-- </plugin>-->
78-
7939
<plugin>
8040
<groupId>org.apache.maven.plugins</groupId>
8141
<artifactId>maven-shade-plugin</artifactId>

jprotoc/jprotoc/src/main/java/com/salesforce/jprotoc/Generator.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
* Generator is the base class for all protoc generators managed by {@link ProtocPlugin}.
2828
*/
2929
public abstract class Generator {
30-
private static MustacheFactory mustacheFactory = new DefaultMustacheFactory();
30+
private static final MustacheFactory MUSTACHE_FACTORY = new DefaultMustacheFactory();
3131

3232
/**
3333
* Processes a generator request into a set of files to output.
@@ -51,6 +51,16 @@ public List<PluginProtos.CodeGeneratorResponse.File> generateFiles(PluginProtos.
5151
return Collections.emptyList();
5252
}
5353

54+
/**
55+
* Signals to protoc which additional generator features this Generator supports. By default, this method returns
56+
* FEATURE_NONE. You must override this method and supply a value, like FEATURE_PROTO3_OPTIONAL.
57+
*
58+
* @return A list of enumerated features.
59+
*/
60+
protected List<PluginProtos.CodeGeneratorResponse.Feature> supportedFeatures() {
61+
return Collections.singletonList(PluginProtos.CodeGeneratorResponse.Feature.FEATURE_NONE);
62+
}
63+
5464
/**
5565
* Executes a mustache template against a generatorContext object to generate an output string.
5666
* @param resourcePath Embedded resource template to use.
@@ -67,7 +77,7 @@ protected String applyTemplate(@Nonnull String resourcePath, @Nonnull Object gen
6777
}
6878

6979
InputStreamReader resourceReader = new InputStreamReader(resource, Charsets.UTF_8);
70-
Mustache template = mustacheFactory.compile(resourceReader, resourcePath);
80+
Mustache template = MUSTACHE_FACTORY.compile(resourceReader, resourcePath);
7181
return template.execute(new StringWriter(), generatorContext).toString();
7282
}
7383

jprotoc/jprotoc/src/main/java/com/salesforce/jprotoc/ProtocPlugin.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,10 +190,22 @@ private static PluginProtos.CodeGeneratorResponse generate(
190190
.stream()
191191
.flatMap(gen -> gen.generateFiles(request).stream());
192192

193+
int featureMask = generators
194+
.stream()
195+
.map(gen -> gen.supportedFeatures().stream())
196+
// OR each generator's feature set together into a mask
197+
.map(featureStream -> featureStream.map(PluginProtos.CodeGeneratorResponse.Feature::getNumber)
198+
.reduce((l, r) -> l | r)
199+
.orElse(PluginProtos.CodeGeneratorResponse.Feature.FEATURE_NONE_VALUE))
200+
// AND together all the masks
201+
.reduce((l, r) -> l & r)
202+
.orElse(PluginProtos.CodeGeneratorResponse.Feature.FEATURE_NONE_VALUE);
203+
193204
// Send the files back to protoc
194205
return PluginProtos.CodeGeneratorResponse
195206
.newBuilder()
196207
.addAllFile(Stream.concat(oldWay, newWay).collect(Collectors.toList()))
208+
.setSupportedFeatures(featureMask)
197209
.build();
198210
}
199211

jprotoc/jprotoc/src/main/java/com/salesforce/jprotoc/dump/DumpGenerator.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import com.salesforce.jprotoc.ProtocPlugin;
1616

1717
import java.util.Arrays;
18+
import java.util.Collections;
1819
import java.util.List;
1920

2021
/**
@@ -25,6 +26,11 @@ public static void main(String[] args) {
2526
ProtocPlugin.generate(new DumpGenerator());
2627
}
2728

29+
@Override
30+
protected List<PluginProtos.CodeGeneratorResponse.Feature> supportedFeatures() {
31+
return Collections.singletonList(PluginProtos.CodeGeneratorResponse.Feature.FEATURE_PROTO3_OPTIONAL);
32+
}
33+
2834
@Override
2935
public List<PluginProtos.CodeGeneratorResponse.File> generateFiles(PluginProtos.CodeGeneratorRequest request) throws GeneratorException {
3036
try {

jprotoc/jprotoc/src/main/java/com/salesforce/jprotoc/jdk8/Jdk8Generator.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.util.ArrayList;
2020
import java.util.Arrays;
21+
import java.util.Collections;
2122
import java.util.List;
2223

2324
/**
@@ -37,6 +38,11 @@ public static void main(String[] args) {
3738
private static final String SERVICE_JAVADOC_PREFIX = " ";
3839
private static final String METHOD_JAVADOC_PREFIX = " ";
3940

41+
@Override
42+
protected List<PluginProtos.CodeGeneratorResponse.Feature> supportedFeatures() {
43+
return Collections.singletonList(PluginProtos.CodeGeneratorResponse.Feature.FEATURE_PROTO3_OPTIONAL);
44+
}
45+
4046
@Override
4147
public List<PluginProtos.CodeGeneratorResponse.File> generateFiles(PluginProtos.CodeGeneratorRequest request) throws GeneratorException {
4248
final ProtoTypeMap protoTypeMap = ProtoTypeMap.of(request.getProtoFileList());

jprotoc/pom.xml

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,13 @@
5858
<mavenBaseUrl>https://oss.sonatype.org/content/repositories</mavenBaseUrl>
5959

6060
<!-- Dependency Versions -->
61-
<contrib.version>0.8.2-SNAPSHOT</contrib.version>
62-
63-
<grpc.version>1.24.0</grpc.version>
64-
<protoc.version>3.9.1</protoc.version> <!-- Same version as grpc-proto -->
65-
<slf4j.version>1.7.21</slf4j.version>
66-
<gson.version>2.7</gson.version> <!-- Same version as grpc-proto -->
61+
<protoc.version>3.15.8</protoc.version>
62+
<gson.version>2.7</gson.version>
6763
<mustache-java.version>0.9.4</mustache-java.version>
68-
<spring.version>4.2.0.RELEASE</spring.version>
6964

7065
<!-- Test Dependency Versions -->
66+
<contrib.version>0.8.1</contrib.version>
67+
<grpc.version>1.37.0</grpc.version>
7168
<junit.version>4.13.1</junit.version>
7269
<assertj.version>3.6.2</assertj.version>
7370
<commons-lang.version>2.6</commons-lang.version>
@@ -102,11 +99,27 @@
10299
~ Protobuf would require keeping them manually aligned with gRPC. Instead, Guava and Protobuf are
103100
~ referenced transitively via gRPC itself.
104101
-->
105-
102+
<dependency>
103+
<groupId>com.github.spullara.mustache.java</groupId>
104+
<artifactId>compiler</artifactId>
105+
<version>${mustache-java.version}</version>
106+
</dependency>
107+
<dependency>
108+
<groupId>com.google.code.gson</groupId>
109+
<artifactId>gson</artifactId>
110+
<version>${gson.version}</version>
111+
</dependency>
112+
<!-- Test dependencies -->
106113
<dependency>
107114
<groupId>com.salesforce.servicelibs</groupId>
108115
<artifactId>grpc-contrib</artifactId>
109116
<version>${contrib.version}</version>
117+
<exclusions>
118+
<exclusion>
119+
<groupId>io.grpc</groupId>
120+
<artifactId>*</artifactId>
121+
</exclusion>
122+
</exclusions>
110123
</dependency>
111124
<dependency>
112125
<groupId>com.salesforce.servicelibs</groupId>
@@ -130,27 +143,14 @@
130143
</dependency>
131144
<dependency>
132145
<groupId>io.grpc</groupId>
133-
<artifactId>grpc-stub</artifactId>
146+
<artifactId>grpc-api</artifactId>
134147
<version>${grpc.version}</version>
135148
</dependency>
136149
<dependency>
137-
<groupId>com.github.spullara.mustache.java</groupId>
138-
<artifactId>compiler</artifactId>
139-
<version>${mustache-java.version}</version>
140-
</dependency>
141-
<dependency>
142-
<groupId>com.google.code.gson</groupId>
143-
<artifactId>gson</artifactId>
144-
<version>${gson.version}</version>
145-
</dependency>
146-
<!-- Provided dependencies -->
147-
<dependency>
148-
<groupId>org.slf4j</groupId>
149-
<artifactId>slf4j-api</artifactId>
150-
<version>${slf4j.version}</version>
151-
<scope>provided</scope>
150+
<groupId>io.grpc</groupId>
151+
<artifactId>grpc-stub</artifactId>
152+
<version>${grpc.version}</version>
152153
</dependency>
153-
<!-- Test dependencies -->
154154
<dependency>
155155
<groupId>junit</groupId>
156156
<artifactId>junit</artifactId>

0 commit comments

Comments
 (0)