Mangle extension, enum and top-level names so they don't collide with dart keywords (#289)
diff --git a/protoc_plugin/CHANGELOG.md b/protoc_plugin/CHANGELOG.md
index 2b48b7b..a2d59e6 100644
--- a/protoc_plugin/CHANGELOG.md
+++ b/protoc_plugin/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 18.0.2
+
+* Fix mangling of extension names, message type names, and enum names that are Dart keywords.
+
+ Now you can have an extension called `is` and an enum called `class`.
+
## 18.0.1
* Add a `bin/protoc-gen-dart.bat` script making it easier to compile on windows using a local
diff --git a/protoc_plugin/Makefile b/protoc_plugin/Makefile
index 797cbfa..6d6fd08 100644
--- a/protoc_plugin/Makefile
+++ b/protoc_plugin/Makefile
@@ -43,6 +43,8 @@
non_nested_extension \
oneof \
reserved_names \
+ reserved_names_extension \
+ reserved_names_message \
duplicate_names_import \
package1 \
package2 \
diff --git a/protoc_plugin/lib/enum_generator.dart b/protoc_plugin/lib/enum_generator.dart
index c51ea77..f3c1a9f 100644
--- a/protoc_plugin/lib/enum_generator.dart
+++ b/protoc_plugin/lib/enum_generator.dart
@@ -41,7 +41,7 @@
? descriptor.name
: '${parent.fullName}.${descriptor.name}',
_descriptor = descriptor {
- final usedNames = reservedEnumNames;
+ final usedNames = Set<String>()..addAll(reservedEnumNames);
for (var i = 0; i < descriptor.value.length; i++) {
EnumValueDescriptorProto value = descriptor.value[i];
EnumValueDescriptorProto canonicalValue =
diff --git a/protoc_plugin/lib/file_generator.dart b/protoc_plugin/lib/file_generator.dart
index d120d57..91c357c 100644
--- a/protoc_plugin/lib/file_generator.dart
+++ b/protoc_plugin/lib/file_generator.dart
@@ -117,12 +117,12 @@
/// Used to avoid collisions after names have been mangled to match the Dart
/// style.
final Set<String> usedTopLevelNames = Set<String>()
- ..addAll(toplevelReservedCapitalizedNames);
+ ..addAll(forbiddenTopLevelNames);
/// Used to avoid collisions in the service file after names have been mangled
/// to match the dart style.
final Set<String> usedTopLevelServiceNames = Set<String>()
- ..addAll(toplevelReservedCapitalizedNames);
+ ..addAll(forbiddenTopLevelNames);
final Set<String> usedExtensionNames = Set<String>()
..addAll(forbiddenExtensionNames);
@@ -158,7 +158,7 @@
}
for (var i = 0; i < descriptor.extension.length; i++) {
extensionGenerators.add(ExtensionGenerator.topLevel(
- descriptor.extension[i], this, usedTopLevelNames, i));
+ descriptor.extension[i], this, usedExtensionNames, i));
}
for (ServiceDescriptorProto service in descriptor.service) {
if (options.useGrpc) {
diff --git a/protoc_plugin/lib/names.dart b/protoc_plugin/lib/names.dart
index d85d757..0373187 100644
--- a/protoc_plugin/lib/names.dart
+++ b/protoc_plugin/lib/names.dart
@@ -199,6 +199,7 @@
/// generated subclasses.
Set<String> get reservedEnumNames => Set<String>()
..addAll(ProtobufEnum_reservedNames)
+ ..addAll(_dartReservedWords)
..addAll(_protobufEnumNames);
Iterable<String> enumSuffixes() sync* {
@@ -446,13 +447,12 @@
final _dartFieldNameExpr = RegExp(r'^[a-z]\w+$');
-/// Names that would collide with capitalized core Dart names as top-level
-/// identifiers.
-final List<String> toplevelReservedCapitalizedNames = const <String>[
+/// Names that would collide as top-level identifiers.
+final List<String> forbiddenTopLevelNames = <String>[
'List',
'Function',
'Map',
-];
+]..addAll(_dartReservedWords);
final List<String> reservedMemberNames = <String>[]
..addAll(_dartReservedWords)
diff --git a/protoc_plugin/pubspec.yaml b/protoc_plugin/pubspec.yaml
index 2eaa85e..1138584 100644
--- a/protoc_plugin/pubspec.yaml
+++ b/protoc_plugin/pubspec.yaml
@@ -1,5 +1,5 @@
name: protoc_plugin
-version: 18.0.1
+version: 18.0.2
author: Dart Team <misc@dartlang.org>
description: Protoc compiler plugin to generate Dart code
homepage: https://github.com/dart-lang/protobuf
diff --git a/protoc_plugin/test/generated_message_test.dart b/protoc_plugin/test/generated_message_test.dart
index c008f2d..c0db210 100755
--- a/protoc_plugin/test/generated_message_test.dart
+++ b/protoc_plugin/test/generated_message_test.dart
@@ -13,6 +13,8 @@
import '../out/protos/google/protobuf/unittest_optimize_for.pb.dart';
import '../out/protos/multiple_files_test.pb.dart';
import '../out/protos/reserved_names.pb.dart';
+import '../out/protos/reserved_names_extension.pb.dart';
+import '../out/protos/reserved_names_message.pb.dart';
import '../out/protos/duplicate_names_import.pb.dart';
import '../out/protos/package1.pb.dart' as p1;
import '../out/protos/package2.pb.dart' as p2;
@@ -694,6 +696,116 @@
message.with_33 = 1;
});
+ test('testReservedWordsRequired', () {
+ MessageWithReservedEnum message = MessageWithReservedEnum();
+ message.enum_1 = ReservedEnum.assert_;
+ message.enum_1 = ReservedEnum.break_;
+ message.enum_1 = ReservedEnum.case_;
+ message.enum_1 = ReservedEnum.catch_;
+ message.enum_1 = ReservedEnum.class_;
+ message.enum_1 = ReservedEnum.const_;
+ message.enum_1 = ReservedEnum.continue_;
+ message.enum_1 = ReservedEnum.default_;
+ message.enum_1 = ReservedEnum.do_;
+ message.enum_1 = ReservedEnum.else_;
+ message.enum_1 = ReservedEnum.enum_;
+ message.enum_1 = ReservedEnum.extends_;
+ message.enum_1 = ReservedEnum.false_;
+ message.enum_1 = ReservedEnum.final_;
+ message.enum_1 = ReservedEnum.finally_;
+ message.enum_1 = ReservedEnum.for_;
+ message.enum_1 = ReservedEnum.if_;
+ message.enum_1 = ReservedEnum.in_;
+ message.enum_1 = ReservedEnum.is_;
+ message.enum_1 = ReservedEnum.new_;
+ message.enum_1 = ReservedEnum.null_;
+ message.enum_1 = ReservedEnum.rethrow_;
+ message.enum_1 = ReservedEnum.return_;
+ message.enum_1 = ReservedEnum.super_;
+ message.enum_1 = ReservedEnum.switch_;
+ message.enum_1 = ReservedEnum.this_;
+ message.enum_1 = ReservedEnum.throw_;
+ message.enum_1 = ReservedEnum.true_;
+ message.enum_1 = ReservedEnum.try_;
+ message.enum_1 = ReservedEnum.var_;
+ message.enum_1 = ReservedEnum.void_;
+ message.enum_1 = ReservedEnum.while_;
+ message.enum_1 = ReservedEnum.with_;
+ });
+
+ test('testReservedWordsExtension', () {
+ ExtendMe message = ExtendMe();
+ message.setExtension(Reserved_names_extension.assert_1001, 1);
+ message.setExtension(Reserved_names_extension.break_1002, 1);
+ message.setExtension(Reserved_names_extension.case_1003, 1);
+ message.setExtension(Reserved_names_extension.catch_1004, 1);
+ message.setExtension(Reserved_names_extension.class_1005, 1);
+ message.setExtension(Reserved_names_extension.const_1006, 1);
+ message.setExtension(Reserved_names_extension.continue_1007, 1);
+ message.setExtension(Reserved_names_extension.default_1008, 1);
+ message.setExtension(Reserved_names_extension.do_1009, 1);
+ message.setExtension(Reserved_names_extension.else_1010, 1);
+ message.setExtension(Reserved_names_extension.enum_1011, 1);
+ message.setExtension(Reserved_names_extension.extends_1012, 1);
+ message.setExtension(Reserved_names_extension.false_1013, 1);
+ message.setExtension(Reserved_names_extension.final_1014, 1);
+ message.setExtension(Reserved_names_extension.finally_1015, 1);
+ message.setExtension(Reserved_names_extension.for_1016, 1);
+ message.setExtension(Reserved_names_extension.if_1017, 1);
+ message.setExtension(Reserved_names_extension.in_1018, 1);
+ message.setExtension(Reserved_names_extension.is_1019, 1);
+ message.setExtension(Reserved_names_extension.new_1020, 1);
+ message.setExtension(Reserved_names_extension.null_1021, 1);
+ message.setExtension(Reserved_names_extension.rethrow_1022, 1);
+ message.setExtension(Reserved_names_extension.return_1023, 1);
+ message.setExtension(Reserved_names_extension.super_1024, 1);
+ message.setExtension(Reserved_names_extension.switch_1025, 1);
+ message.setExtension(Reserved_names_extension.this_1026, 1);
+ message.setExtension(Reserved_names_extension.throw_1027, 1);
+ message.setExtension(Reserved_names_extension.true_1028, 1);
+ message.setExtension(Reserved_names_extension.try_1029, 1);
+ message.setExtension(Reserved_names_extension.var_1030, 1);
+ message.setExtension(Reserved_names_extension.void_1031, 1);
+ message.setExtension(Reserved_names_extension.while_1032, 1);
+ message.setExtension(Reserved_names_extension.with_1033, 1);
+ });
+
+ test('testReservedWordsMessage', () {
+ assert_();
+ break_();
+ case_();
+ catch_();
+ class_();
+ const_();
+ continue_();
+ default_();
+ do_();
+ else_();
+ enum_();
+ extends_();
+ false_();
+ final_();
+ finally_();
+ for_();
+ if_();
+ in_();
+ is_();
+ new_();
+ null_();
+ rethrow_();
+ return_();
+ super_();
+ switch_();
+ this_();
+ throw_();
+ true_();
+ try_();
+ var_();
+ void_();
+ while_();
+ with_();
+ });
+
test('testImportDuplicatenames', () {
M message = M();
message.m1 = p1.M();
diff --git a/protoc_plugin/test/protos/reserved_names.proto b/protoc_plugin/test/protos/reserved_names.proto
index fcee7c5..dff00aa 100644
--- a/protoc_plugin/test/protos/reserved_names.proto
+++ b/protoc_plugin/test/protos/reserved_names.proto
@@ -251,3 +251,43 @@
required int32 while = 32;
required int32 with = 33;
}
+
+message MessageWithReservedEnum {
+ optional ReservedEnum enum = 1;
+}
+
+enum ReservedEnum {
+ assert = 0;
+ break = 1;
+ case = 2;
+ catch = 3;
+ class = 4;
+ const = 5;
+ continue = 6;
+ default = 7;
+ do = 8;
+ else = 9;
+ enum = 10;
+ extends = 11;
+ false = 12;
+ final = 13;
+ finally = 14;
+ for = 15;
+ if = 16;
+ in = 17;
+ is = 18;
+ new = 19;
+ null = 20;
+ rethrow = 21;
+ return = 22;
+ super = 23;
+ switch = 24;
+ this = 25;
+ throw = 26;
+ true = 27;
+ try = 28;
+ var = 29;
+ void = 30;
+ while = 31;
+ with = 32;
+}
diff --git a/protoc_plugin/test/protos/reserved_names_extension.proto b/protoc_plugin/test/protos/reserved_names_extension.proto
new file mode 100644
index 0000000..bf43916
--- /dev/null
+++ b/protoc_plugin/test/protos/reserved_names_extension.proto
@@ -0,0 +1,47 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+syntax = "proto2";
+
+package reserved_names_extension;
+
+message ExtendMe {
+ extensions 1000 to max;
+}
+
+extend ExtendMe {
+ optional int32 assert = 1001;
+ optional int32 break = 1002;
+ optional int32 case = 1003;
+ optional int32 catch = 1004;
+ optional int32 class = 1005;
+ optional int32 const = 1006;
+ optional int32 continue = 1007;
+ optional int32 default = 1008;
+ optional int32 do = 1009;
+ optional int32 else = 1010;
+ optional int32 enum = 1011;
+ optional int32 extends = 1012;
+ optional int32 false = 1013;
+ optional int32 final = 1014;
+ optional int32 finally = 1015;
+ optional int32 for = 1016;
+ optional int32 if = 1017;
+ optional int32 in = 1018;
+ optional int32 is = 1019;
+ optional int32 new = 1020;
+ optional int32 null = 1021;
+ optional int32 rethrow = 1022;
+ optional int32 return = 1023;
+ optional int32 super = 1024;
+ optional int32 switch = 1025;
+ optional int32 this = 1026;
+ optional int32 throw = 1027;
+ optional int32 true = 1028;
+ optional int32 try = 1029;
+ optional int32 var = 1030;
+ optional int32 void = 1031;
+ optional int32 while = 1032;
+ optional int32 with = 1033;
+}
\ No newline at end of file
diff --git a/protoc_plugin/test/protos/reserved_names_message.proto b/protoc_plugin/test/protos/reserved_names_message.proto
new file mode 100644
index 0000000..aa072f5
--- /dev/null
+++ b/protoc_plugin/test/protos/reserved_names_message.proto
@@ -0,0 +1,74 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+syntax = "proto2";
+
+package reserved_names_messages;
+
+message assert {
+}
+message break {
+}
+message case {
+}
+message catch {
+}
+message class {
+}
+message const {
+}
+message continue {
+}
+message default {
+}
+message do {
+}
+message else {
+}
+message enum {
+}
+message extends {
+}
+message false {
+}
+message final {
+}
+message finally {
+}
+message for {
+}
+message if {
+}
+message in {
+}
+message is {
+}
+message new {
+}
+message null {
+}
+message rethrow {
+}
+message return {
+}
+message super {
+}
+message switch {
+}
+message this {
+}
+message throw {
+}
+message true {
+}
+message try {
+}
+message var {
+}
+message void {
+}
+message while {
+}
+message with {
+}
\ No newline at end of file