diff options
author | 2024-04-17 07:55:05 +0000 | |
---|---|---|
committer | 2024-04-18 10:54:26 +0000 | |
commit | 804f0134e8f5e47c59a07a98cf938c84fc85a006 (patch) | |
tree | 19583e1538dbb8cd79bdd00e5156f8783c5a1d58 | |
parent | 2163c8ae365c6cab3988af86d73c28825183dd22 (diff) |
Avoid outer/inner class name clashes
In some cases, protoc-gen-javastream could emit outer classes
and inner classes with the same name, which is invalid java.
This commit extends protoc-gen-javastream to append an "OuterClass"
suffix, if the outer class name clashes with any message.
This behavior is consistent with the standard protoc.
Bug: 276433199
Test: presubmit
Change-Id: I4e92d70c10c4d92d103b00f15b159acc08dffff2
-rw-r--r-- | tools/streaming_proto/java/java_proto_stream_code_generator.cpp | 47 |
1 files changed, 34 insertions, 13 deletions
diff --git a/tools/streaming_proto/java/java_proto_stream_code_generator.cpp b/tools/streaming_proto/java/java_proto_stream_code_generator.cpp index 0e5d35bada47..be5c197b7c5b 100644 --- a/tools/streaming_proto/java/java_proto_stream_code_generator.cpp +++ b/tools/streaming_proto/java/java_proto_stream_code_generator.cpp @@ -18,6 +18,7 @@ #include <stdio.h> +#include <algorithm> #include <iomanip> #include <iostream> #include <map> @@ -31,21 +32,39 @@ using namespace android::stream_proto; using namespace google::protobuf::io; using namespace std; +static bool outer_class_name_clashes_with_any_message(const string& outer_class_name, + const vector<DescriptorProto>& messages) { + return any_of(messages.cbegin(), messages.cend(), [&](const DescriptorProto& message) { + return message.name() == outer_class_name; + }); +} + /** * If the descriptor gives us a class name, use that. Otherwise make one up from * the filename of the .proto file. */ -static string make_outer_class_name(const FileDescriptorProto& file_descriptor) { +static string make_outer_class_name(const FileDescriptorProto& file_descriptor, + const vector<DescriptorProto>& messages) { string name = file_descriptor.options().java_outer_classname(); - if (name.size() == 0) { - name = to_camel_case(file_base_name(file_descriptor.name())); - if (name.size() == 0) { - ERRORS.Add(UNKNOWN_FILE, UNKNOWN_LINE, - "Unable to make an outer class name for file: %s", - file_descriptor.name().c_str()); - name = "Unknown"; - } + if (!name.empty()) { + return name; + } + + // Outer class and messages with the same name would result in invalid java (outer class and + // inner class cannot have same names). + // If the outer class name clashes with any message, let's append an "OuterClass" suffix. + // This behavior is consistent with the standard protoc. + name = to_camel_case(file_base_name(file_descriptor.name())); + while (outer_class_name_clashes_with_any_message(name, messages)) { + name += "OuterClass"; + } + + if (name.empty()) { + ERRORS.Add(UNKNOWN_FILE, UNKNOWN_LINE, "Unable to make an outer class name for file: %s", + file_descriptor.name().c_str()); + name = "Unknown"; } + return name; } @@ -172,7 +191,7 @@ static void write_file(CodeGeneratorResponse* response, const FileDescriptorProt stringstream text; string const package_name = make_java_package(file_descriptor); - string const outer_class_name = make_outer_class_name(file_descriptor); + string const outer_class_name = make_outer_class_name(file_descriptor, messages); text << "// Generated by protoc-gen-javastream. DO NOT MODIFY." << endl; text << "// source: " << file_descriptor.name() << endl << endl; @@ -239,7 +258,8 @@ static void write_multiple_files(CodeGeneratorResponse* response, if (messages_allowlist.empty() || !enums.empty()) { write_file(response, file_descriptor, - make_file_name(file_descriptor, make_outer_class_name(file_descriptor)), + make_file_name(file_descriptor, + make_outer_class_name(file_descriptor, messages)), true, enums, messages); } } @@ -297,8 +317,9 @@ static void write_single_file(CodeGeneratorResponse* response, if (messages_allowlist.empty() || !enums.empty() || !messages.empty()) { write_file(response, file_descriptor, - make_file_name(file_descriptor, make_outer_class_name(file_descriptor)), true, - enums, messages); + make_file_name(file_descriptor, + make_outer_class_name(file_descriptor, messages)), + true, enums, messages); } } |