Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,10 @@

package dev.cel.common.internal;

import com.google.common.base.CaseFormat;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.io.Files;
import com.google.protobuf.DescriptorProtos.FileOptions;
import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.EnumDescriptor;
import com.google.protobuf.Descriptors.FileDescriptor;
import com.google.protobuf.Descriptors.GenericDescriptor;
import com.google.protobuf.Descriptors.ServiceDescriptor;
import com.google.protobuf.GeneratorNames;
import dev.cel.common.annotations.Internal;
import java.util.ArrayDeque;

/**
* Helper class for constructing a fully qualified Java class name from a protobuf descriptor.
Expand All @@ -34,10 +26,6 @@
*/
@Internal
public final class ProtoJavaQualifiedNames {
// Controls how many times we should recursively inspect a nested message for building fully
// qualified java class name before aborting.
private static final int SAFE_RECURSE_LIMIT = 50;

/**
* Retrieves the full Java class name from the given descriptor
*
Expand All @@ -48,44 +36,7 @@ public final class ProtoJavaQualifiedNames {
* (Nested class with java multiple files disabled)
*/
public static String getFullyQualifiedJavaClassName(Descriptor descriptor) {
return getFullyQualifiedJavaClassNameImpl(descriptor);
}

private static String getFullyQualifiedJavaClassNameImpl(GenericDescriptor descriptor) {
StringBuilder fullClassName = new StringBuilder();

fullClassName.append(getJavaPackageName(descriptor.getFile())).append(".");

String javaOuterClass = getJavaOuterClassName(descriptor.getFile());
if (!Strings.isNullOrEmpty(javaOuterClass)) {
fullClassName.append(javaOuterClass).append("$");
}

// Recursively build the target class name in case if the message is nested.
ArrayDeque<String> classNames = new ArrayDeque<>();
GenericDescriptor d = descriptor;

int recurseCount = 0;
while (d != null) {
classNames.push(d.getName());

if (d instanceof EnumDescriptor) {
d = ((EnumDescriptor) d).getContainingType();
} else {
d = ((Descriptor) d).getContainingType();
}
recurseCount++;
if (recurseCount >= SAFE_RECURSE_LIMIT) {
throw new IllegalStateException(
String.format(
"Recursion limit of %d hit while inspecting descriptor: %s",
SAFE_RECURSE_LIMIT, descriptor.getFullName()));
}
}

Joiner.on("$").appendTo(fullClassName, classNames);

return fullClassName.toString();
return GeneratorNames.getBytecodeClassName(descriptor);
}

/**
Expand All @@ -94,68 +45,7 @@ private static String getFullyQualifiedJavaClassNameImpl(GenericDescriptor descr
* on package name generation
*/
public static String getJavaPackageName(FileDescriptor fileDescriptor) {
FileOptions options = fileDescriptor.getFile().getOptions();
StringBuilder javaPackageName = new StringBuilder();
if (options.hasJavaPackage()) {
javaPackageName.append(options.getJavaPackage());
} else {
javaPackageName
// CEL-Internal-1
.append(fileDescriptor.getPackage());
}

// CEL-Internal-2

return javaPackageName.toString();
}

/**
* Gets a wrapping outer class name from the descriptor. The outer class name differs depending on
* the proto options set. See
* https://developers.google.com/protocol-buffers/docs/reference/java-generated#invocation
*/
private static String getJavaOuterClassName(FileDescriptor descriptor) {
FileOptions options = descriptor.getOptions();

if (options.getJavaMultipleFiles()) {
// If java_multiple_files is enabled, protoc does not generate a wrapper outer class
return "";
}

if (options.hasJavaOuterClassname()) {
return options.getJavaOuterClassname();
} else {
// If an outer class name is not explicitly set, the name is converted into
// Pascal case based on the snake cased file name
// Ex: messages_proto.proto becomes MessagesProto
String protoFileNameWithoutExtension =
Files.getNameWithoutExtension(descriptor.getFile().getFullName());
String outerClassName =
CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, protoFileNameWithoutExtension);
if (hasConflictingClassName(descriptor.getFile(), outerClassName)) {
outerClassName += "OuterClass";
}
return outerClassName;
}
}

private static boolean hasConflictingClassName(FileDescriptor file, String name) {
for (EnumDescriptor enumDesc : file.getEnumTypes()) {
if (name.equals(enumDesc.getName())) {
return true;
}
}
for (ServiceDescriptor serviceDesc : file.getServices()) {
if (name.equals(serviceDesc.getName())) {
return true;
}
}
for (Descriptor messageDesc : file.getMessageTypes()) {
if (name.equals(messageDesc.getName())) {
return true;
}
}
return false;
return GeneratorNames.getFileJavaPackage(fileDescriptor.toProto());
}

private ProtoJavaQualifiedNames() {}
Expand Down