diff --git a/java/core/src/main/java/com/google/protobuf/GeneratorNames.java b/java/core/src/main/java/com/google/protobuf/GeneratorNames.java index 39ab8780dfa09..c188ee01a2258 100644 --- a/java/core/src/main/java/com/google/protobuf/GeneratorNames.java +++ b/java/core/src/main/java/com/google/protobuf/GeneratorNames.java @@ -139,7 +139,8 @@ static String getDefaultFileClassName( FileDescriptorProtoOrBuilder file, boolean useOldOuterClassnameDefault) { // Replicates the logic of ClassNameResolver::GetFileDefaultImmutableClassName. String name = file.getName(); - name = name.substring(name.lastIndexOf('/')); + // The `+ 1` includes the case where no '/' is present. + name = name.substring(name.lastIndexOf('/') + 1); name = underscoresToCamelCase(stripProto(name)); return useOldOuterClassnameDefault ? name : name + "Proto"; } diff --git a/java/core/src/test/java/com/google/protobuf/GeneratorNamesTest.java b/java/core/src/test/java/com/google/protobuf/GeneratorNamesTest.java index 369fcfc52ae5d..2c18cfd6d3552 100644 --- a/java/core/src/test/java/com/google/protobuf/GeneratorNamesTest.java +++ b/java/core/src/test/java/com/google/protobuf/GeneratorNamesTest.java @@ -234,6 +234,15 @@ public void getFileClassName_weirdExtension() { .isEqualTo("BarNotproto"); } + @Test + public void getFileClassName_noDirectory() { + // This isn't exercisable in blazel because all our tests are in a directory. + assertThat( + GeneratorNames.getFileClassName( + FileDescriptorProto.newBuilder().setName("bar.proto").build())) + .isEqualTo("Bar"); + } + @Test public void getFileClassName_conflictingName2024() { // This isn't exercisable in blazel because conflicts trigger a protoc error in edition 2024.