Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions jprotoc-test/src/test/proto/nested.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
syntax = "proto3";

package nested;

message Outer { // Level 0
enum FooEnum {
FOO = 0;
BAR = 1;
CHEESE = 2;
}
message MiddleAA { // Level 1

message Inner { // Level 2
int64 ival = 1;
bool booly = 2;
Outer.FooEnum enum = 3;
}
}
message MiddleBB { // Level 1
message Inner { // Level 2
int32 ival = 1;
bool booly = 2;
Outer.FooEnum enum = 3;
}
}
}

service Nested {
rpc doNested (Outer.MiddleAA.Inner) returns (Outer.MiddleBB.Inner) {}
}
19 changes: 18 additions & 1 deletion jprotoc/src/main/java/com/salesforce/jprotoc/Generator.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;

/**
Expand All @@ -28,10 +30,25 @@ public abstract class Generator {

/**
* Processes a generator request into a set of files to output.
*
* @deprecated use {@link #generateFiles(PluginProtos.CodeGeneratorRequest)} and return a List instead of a Stream.
* @param request The raw generator request from protoc.
* @return The completed files to write out.
*/
public abstract Stream<PluginProtos.CodeGeneratorResponse.File> generate(PluginProtos.CodeGeneratorRequest request) throws GeneratorException;
@Deprecated()
public Stream<PluginProtos.CodeGeneratorResponse.File> generate(PluginProtos.CodeGeneratorRequest request) throws GeneratorException {
return Stream.empty();
}

/**
* Processes a generator request into a set of files to output.
*
* @param request The raw generator request from protoc.
* @return The completed files to write out.
*/
public List<PluginProtos.CodeGeneratorResponse.File> generateFiles(PluginProtos.CodeGeneratorRequest request) throws GeneratorException {
return Collections.emptyList();
}

/**
* Executes a mustache template against a generatorContext object to generate an output string.
Expand Down
32 changes: 28 additions & 4 deletions jprotoc/src/main/java/com/salesforce/jprotoc/ProtoTypeMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,21 +57,45 @@ public static ProtoTypeMap of(@Nonnull Collection<DescriptorProtos.FileDescripto
getJavaOuterClassname(fileDescriptor, fileOptions);



// Identify top-level enums
fileDescriptor.getEnumTypeList().forEach(
e -> types.put(
protoPackage + "." + e.getName(),
toJavaTypeName(e.getName(), enclosingClassName, javaPackage)));

// Identify top-level messages, and nested types
fileDescriptor.getMessageTypeList().forEach(
m -> types.put(
protoPackage + "." + m.getName(),
toJavaTypeName(m.getName(), enclosingClassName, javaPackage)));
m -> recursivelyAddTypes(types, m, protoPackage, enclosingClassName, javaPackage)
);
}

return new ProtoTypeMap(types.build());
}

private static void recursivelyAddTypes(ImmutableMap.Builder<String, String> types, DescriptorProtos.DescriptorProto m, String protoPackage, String enclosingClassName, String javaPackage) {
// Identify current type
types.put(
protoPackage + "." + m.getName(),
toJavaTypeName(m.getName(), enclosingClassName, javaPackage));

// Identify any nested Enums
m.getEnumTypeList().forEach(
e -> types.put(
protoPackage + "." + e.getName(),
toJavaTypeName(e.getName(),
enclosingClassName,
javaPackage)));

// Recursively identify any nested types
m.getNestedTypeList().forEach(
n -> recursivelyAddTypes(
types,
n,
protoPackage + "." + m.getName(),
enclosingClassName + "." + m.getName(),
javaPackage));
}

/**
* Returns the full Java type name for the given proto type.
*
Expand Down
12 changes: 8 additions & 4 deletions jprotoc/src/main/java/com/salesforce/jprotoc/ProtocPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Nonnull;

/**
Expand Down Expand Up @@ -71,15 +72,18 @@ public static void generate(
generatorRequestBytes, extensionRegistry);

// Run each file generator, collecting the output
List<PluginProtos.CodeGeneratorResponse.File> outputFiles = generators
Stream<PluginProtos.CodeGeneratorResponse.File> oldWay = generators
.stream()
.flatMap(gen -> gen.generate(request))
.collect(Collectors.toList());
.flatMap(gen -> gen.generate(request));

Stream<PluginProtos.CodeGeneratorResponse.File> newWay = generators
.stream()
.flatMap(gen -> gen.generateFiles(request).stream());

// Send the files back to protoc
PluginProtos.CodeGeneratorResponse response = PluginProtos.CodeGeneratorResponse
.newBuilder()
.addAllFile(outputFiles)
.addAllFile(Stream.concat(oldWay, newWay).collect(Collectors.toList()))
.build();
response.writeTo(System.out);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

/**
* Generates a set of gRPC stubs that support JDK8 {@link java.util.concurrent.CompletableFuture}.
Expand All @@ -30,24 +29,32 @@ public static void main(String[] args) {
private static final String CLASS_SUFFIX = "Grpc8";

@Override
public Stream<PluginProtos.CodeGeneratorResponse.File> generate(PluginProtos.CodeGeneratorRequest request) throws GeneratorException {
public List<PluginProtos.CodeGeneratorResponse.File> generateFiles(PluginProtos.CodeGeneratorRequest request) throws GeneratorException {
final ProtoTypeMap protoTypeMap = ProtoTypeMap.of(request.getProtoFileList());
List<PluginProtos.CodeGeneratorResponse.File> files = new ArrayList<>();

return request.getProtoFileList().stream()
.filter(protoFile -> request.getFileToGenerateList().contains(protoFile.getName()))
.flatMap(f -> extractContext(protoTypeMap, f))
.map(this::buildFile);
for (DescriptorProtos.FileDescriptorProto protoFile : request.getProtoFileList()) {
if (request.getFileToGenerateList().contains(protoFile.getName())) {
for (Context ctx : extractContext(protoTypeMap, protoFile)) {
files.add(buildFile(ctx));
}
}
}

return files;
}

private Stream<Context> extractContext(ProtoTypeMap protoTypeMap, DescriptorProtos.FileDescriptorProto proto) {
return proto.getServiceList().stream()
.map(s -> extractServiceContext(protoTypeMap, s))
.map(ctx -> {
ctx.packageName = extractPackageName(proto); return ctx;
})
.map(ctx -> {
ctx.protoName = proto.getName(); return ctx;
});
private List<Context> extractContext(ProtoTypeMap protoTypeMap, DescriptorProtos.FileDescriptorProto proto) {
List<Context> contexts = new ArrayList<>();

for (DescriptorProtos.ServiceDescriptorProto service : proto.getServiceList()) {
Context ctx = extractServiceContext(protoTypeMap, service);
ctx.packageName = extractPackageName(proto);
ctx.protoName = proto.getName();
contexts.add(ctx);
}

return contexts;
}

private String extractPackageName(DescriptorProtos.FileDescriptorProto proto) {
Expand Down