Update Kotlin compiler to escape package names (#13310)

The current Kotlin code generator creates code which fails to compile with imports like:

```
syntax = "proto3";
package net.example.v1;
message Sample {
  string net = 1;
}
```

This results in a condition where 'net' is ambiguous in some cases (could refer to the field or the package). To avoid these issues, the code generator should enclose package paths in backticks:

```
net.example.v1.SampleKt => `net.example.v1`.SampleKt
```

Fixes #13182.

Closes #13310

COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/13310 from pkwarren:pkw/issue-13182 3f72b2f1e1
PiperOrigin-RevId: 564481691
pull/14039/head
Philip K. Warren 2 years ago committed by Copybara-Service
parent dfc8445c72
commit 437ec356fb
  1. 3
      src/google/protobuf/compiler/java/message.cc
  2. 6
      src/google/protobuf/compiler/java/message_lite.cc
  3. 15
      src/google/protobuf/compiler/java/name_resolver.cc
  4. 1
      src/google/protobuf/compiler/java/name_resolver.h

@ -1316,8 +1316,7 @@ void ImmutableMessageGenerator::GenerateTopLevelKotlinMembers(
"message",
EscapeKotlinKeywords(name_resolver_->GetClassName(descriptor_, true)),
"message_kt",
EscapeKotlinKeywords(
name_resolver_->GetKotlinExtensionsClassName(descriptor_)));
name_resolver_->GetKotlinExtensionsClassNameEscaped(descriptor_));
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
if (IsMapEntry(descriptor_->nested_type(i))) continue;

@ -841,8 +841,7 @@ void ImmutableMessageLiteGenerator::GenerateTopLevelKotlinMembers(
"message",
EscapeKotlinKeywords(name_resolver_->GetClassName(descriptor_, true)),
"message_kt",
EscapeKotlinKeywords(
name_resolver_->GetKotlinExtensionsClassName(descriptor_)));
name_resolver_->GetKotlinExtensionsClassNameEscaped(descriptor_));
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
if (IsMapEntry(descriptor_->nested_type(i))) continue;
@ -853,7 +852,8 @@ void ImmutableMessageLiteGenerator::GenerateTopLevelKotlinMembers(
GenerateKotlinOrNull(printer);
}
void ImmutableMessageLiteGenerator::GenerateKotlinOrNull(io::Printer* printer) const {
void ImmutableMessageLiteGenerator::GenerateKotlinOrNull(
io::Printer* printer) const {
// Generate getFieldOrNull getters for all optional message fields.
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = descriptor_->field(i);

@ -342,6 +342,21 @@ std::string ClassNameResolver::GetKotlinExtensionsClassName(
descriptor->file(), true, true, true);
}
std::string ClassNameResolver::GetKotlinExtensionsClassNameEscaped(
const Descriptor* descriptor) {
std::string name_without_package = ClassNameWithoutPackageKotlin(descriptor);
std::string full_name = GetClassFullName(
name_without_package, descriptor->file(), true, true, true);
std::string name_without_package_suffix =
absl::StrCat(".", name_without_package, "Kt");
size_t package_end = full_name.rfind(name_without_package_suffix);
if (package_end != std::string::npos) {
return absl::StrCat("`", full_name.substr(0, package_end), "`",
name_without_package_suffix);
}
return full_name;
}
std::string ClassNameResolver::GetJavaMutableClassName(
const Descriptor* descriptor) {
return GetJavaClassFullName(ClassNameWithoutPackage(descriptor, false),

@ -102,6 +102,7 @@ class ClassNameResolver {
std::string GetJavaImmutableClassName(const ServiceDescriptor* descriptor);
std::string GetKotlinFactoryName(const Descriptor* descriptor);
std::string GetKotlinExtensionsClassName(const Descriptor* descriptor);
std::string GetKotlinExtensionsClassNameEscaped(const Descriptor* descriptor);
std::string GetJavaMutableClassName(const Descriptor* descriptor);
std::string GetJavaMutableClassName(const EnumDescriptor* descriptor);
std::string GetJavaMutableClassName(const ServiceDescriptor* descriptor);

Loading…
Cancel
Save