Allow Java reserved keywords to be used in extensions (#5709)
* add check for reserved keywords in extensions * add all reserved keywords * use string without std:: * add test and update name in lite version * test updates
This commit is contained in:
parent
ec3d94819d
commit
5e0812d4b1
@ -30,6 +30,8 @@
|
||||
|
||||
package com.google.protobuf;
|
||||
|
||||
import protobuf_unittest.NestedExtension;
|
||||
import protobuf_unittest.NestedExtensionLite;
|
||||
import protobuf_unittest.NonNestedExtension;
|
||||
import protobuf_unittest.NonNestedExtensionLite;
|
||||
import java.lang.reflect.Method;
|
||||
@ -69,6 +71,8 @@ public class ExtensionRegistryFactoryTest extends TestCase {
|
||||
void testAdd();
|
||||
|
||||
void testAdd_immutable();
|
||||
|
||||
void testExtensionRenamesKeywords();
|
||||
}
|
||||
|
||||
/** Test implementations for the non-Lite usage of ExtensionRegistryFactory. */
|
||||
@ -156,6 +160,23 @@ public class ExtensionRegistryFactoryTest extends TestCase {
|
||||
} catch (IllegalArgumentException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testExtensionRenamesKeywords() {
|
||||
assertTrue(NonNestedExtension.if_ instanceof GeneratedMessage.GeneratedExtension);
|
||||
assertTrue(NestedExtension.MyNestedExtension.default_ instanceof GeneratedMessage.GeneratedExtension);
|
||||
|
||||
NonNestedExtension.MessageToBeExtended msg =
|
||||
NonNestedExtension.MessageToBeExtended.newBuilder()
|
||||
.setExtension(NonNestedExtension.if_, "!fi")
|
||||
.build();
|
||||
assertEquals("!fi", msg.getExtension(NonNestedExtension.if_));
|
||||
|
||||
msg = NonNestedExtension.MessageToBeExtended.newBuilder()
|
||||
.setExtension(NestedExtension.MyNestedExtension.default_, 8)
|
||||
.build();
|
||||
assertEquals(8, msg.getExtension(NestedExtension.MyNestedExtension.default_).intValue());
|
||||
}
|
||||
}
|
||||
|
||||
/** Test implementations for the Lite usage of ExtensionRegistryFactory. */
|
||||
@ -202,6 +223,23 @@ public class ExtensionRegistryFactoryTest extends TestCase {
|
||||
} catch (UnsupportedOperationException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testExtensionRenamesKeywords() {
|
||||
assertTrue(NonNestedExtensionLite.package_ instanceof GeneratedMessageLite.GeneratedExtension);
|
||||
assertTrue(NestedExtensionLite.MyNestedExtensionLite.private_ instanceof GeneratedMessageLite.GeneratedExtension);
|
||||
|
||||
NonNestedExtensionLite.MessageLiteToBeExtended msg =
|
||||
NonNestedExtensionLite.MessageLiteToBeExtended.newBuilder()
|
||||
.setExtension(NonNestedExtensionLite.package_, true)
|
||||
.build();
|
||||
assertTrue(msg.getExtension(NonNestedExtensionLite.package_));
|
||||
|
||||
msg = NonNestedExtensionLite.MessageLiteToBeExtended.newBuilder()
|
||||
.setExtension(NestedExtensionLite.MyNestedExtensionLite.private_, 2.4)
|
||||
.build();
|
||||
assertEquals(2.4, msg.getExtension(NestedExtensionLite.MyNestedExtensionLite.private_), 0.001);
|
||||
}
|
||||
}
|
||||
|
||||
/** Defines a suite of tests which the JUnit3 runner retrieves by reflection. */
|
||||
|
@ -43,5 +43,6 @@ package protobuf_unittest;
|
||||
message MyNestedExtension {
|
||||
extend MessageToBeExtended {
|
||||
optional MessageToBeExtended recursiveExtension = 2;
|
||||
optional int32 default = 2002;
|
||||
}
|
||||
}
|
||||
|
@ -45,5 +45,6 @@ import "com/google/protobuf/non_nested_extension_lite.proto";
|
||||
message MyNestedExtensionLite {
|
||||
extend MessageLiteToBeExtended {
|
||||
optional MessageLiteToBeExtended recursiveExtensionLite = 3;
|
||||
optional double private = 2004;
|
||||
}
|
||||
}
|
||||
|
@ -45,4 +45,5 @@ message MyNonNestedExtension {}
|
||||
|
||||
extend MessageToBeExtended {
|
||||
optional MyNonNestedExtension nonNestedExtension = 1;
|
||||
optional string if = 2000;
|
||||
}
|
||||
|
@ -46,4 +46,5 @@ message MyNonNestedExtensionLite {}
|
||||
|
||||
extend MessageLiteToBeExtended {
|
||||
optional MyNonNestedExtensionLite nonNestedExtensionLite = 1;
|
||||
optional bool package = 2006;
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ void ExtensionGenerator::InitTemplateVars(
|
||||
std::map<std::string, std::string>* vars_pointer) {
|
||||
std::map<std::string, std::string>& vars = *vars_pointer;
|
||||
vars["scope"] = scope;
|
||||
vars["name"] = UnderscoresToCamelCase(descriptor);
|
||||
vars["name"] = UnderscoresToCamelCaseCheckReserved(descriptor);
|
||||
vars["containing_type"] =
|
||||
name_resolver->GetClassName(descriptor->containing_type(), immutable);
|
||||
vars["number"] = StrCat(descriptor->number());
|
||||
@ -153,7 +153,7 @@ int ImmutableExtensionGenerator::GenerateNonNestedInitializationCode(
|
||||
// Only applies to non-nested extensions.
|
||||
printer->Print(
|
||||
"$name$.internalInit(descriptor.getExtensions().get($index$));\n",
|
||||
"name", UnderscoresToCamelCase(descriptor_), "index",
|
||||
"name", UnderscoresToCamelCaseCheckReserved(descriptor_), "index",
|
||||
StrCat(descriptor_->index()));
|
||||
bytecode_estimate += 21;
|
||||
}
|
||||
@ -165,7 +165,7 @@ int ImmutableExtensionGenerator::GenerateRegistrationCode(
|
||||
printer->Print(
|
||||
"registry.add($scope$.$name$);\n",
|
||||
"scope", scope_,
|
||||
"name", UnderscoresToCamelCase(descriptor_));
|
||||
"name", UnderscoresToCamelCaseCheckReserved(descriptor_));
|
||||
return 7;
|
||||
}
|
||||
|
||||
|
@ -109,7 +109,7 @@ int ImmutableExtensionLiteGenerator::GenerateRegistrationCode(
|
||||
printer->Print(
|
||||
"registry.add($scope$.$name$);\n",
|
||||
"scope", scope_,
|
||||
"name", UnderscoresToCamelCase(descriptor_));
|
||||
"name", UnderscoresToCamelCaseCheckReserved(descriptor_));
|
||||
return 7;
|
||||
}
|
||||
|
||||
|
@ -76,6 +76,16 @@ const char* kForbiddenWordList[] = {
|
||||
"class",
|
||||
};
|
||||
|
||||
const std::unordered_set<string> kReservedNames = {
|
||||
"abstract", "assert", "boolean", "break", "byte", "case", "catch", "char",
|
||||
"class", "const", "continue", "default", "do", "double", "else", "enum",
|
||||
"extends", "final", "finally", "float", "for", "goto", "if", "implements",
|
||||
"import", "instanceof", "int", "interface", "long", "native", "new", "package",
|
||||
"private", "protected", "public", "return", "short", "static", "strictfp", "super",
|
||||
"switch", "synchronized", "this", "throw", "throws", "transient", "try", "void",
|
||||
"volatile", "while",
|
||||
};
|
||||
|
||||
const int kDefaultLookUpStartFieldNumber = 40;
|
||||
|
||||
bool IsForbidden(const std::string& field_name) {
|
||||
@ -195,6 +205,14 @@ std::string UnderscoresToCamelCase(const MethodDescriptor* method) {
|
||||
return UnderscoresToCamelCase(method->name(), false);
|
||||
}
|
||||
|
||||
std::string UnderscoresToCamelCaseCheckReserved(const FieldDescriptor* field) {
|
||||
std::string name = UnderscoresToCamelCase(field);
|
||||
if (kReservedNames.find(name) != kReservedNames.end()) {
|
||||
return name + "_";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
std::string UniqueFileScopeIdentifier(const Descriptor* descriptor) {
|
||||
return "static_" + StringReplace(descriptor->full_name(), ".", "_", true);
|
||||
}
|
||||
|
@ -83,6 +83,9 @@ std::string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field);
|
||||
// of lower-casing the first letter of the name.)
|
||||
std::string UnderscoresToCamelCase(const MethodDescriptor* method);
|
||||
|
||||
// Same as UnderscoresToCamelCase, but checks for reserved keywords
|
||||
std::string UnderscoresToCamelCaseCheckReserved(const FieldDescriptor* field);
|
||||
|
||||
// Similar to UnderscoresToCamelCase, but guarentees that the result is a
|
||||
// complete Java identifier by adding a _ if needed.
|
||||
std::string CamelCaseFieldName(const FieldDescriptor* field);
|
||||
|
Loading…
Reference in New Issue
Block a user