From c4fd596252e0467c1ee2a2f1832c561399efd5a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Sat, 6 Jan 2024 09:57:17 +0100 Subject: [PATCH] Export GeneratedMessageGenericExtensions in generated files (#907) Currently when a user calls deprecated methods `clone` or `copyWith`, the deprecation message points to `GeneratedMessageGenericExtensions` `deepCopy` and `rebuild` methods. However we can't just replace `clone` with `deepCopy` as currently the extension is not exported by the generated files. Instead we need to import the library explicitly in the use site. We could mention this in the deprecation message ("Use rebuild from protobuf library instead"), but it's more convenient to just export the extension in the generated message files. Closes #503. --- benchmarks/bin/deep_copy.dart | 1 - protoc_plugin/CHANGELOG.md | 4 ++ protoc_plugin/lib/indenting_writer.dart | 25 +++++++-- protoc_plugin/lib/src/file_generator.dart | 3 + protoc_plugin/test/goldens/grpc_service.pb | 2 + .../test/goldens/header_in_package.pb | 2 + .../test/goldens/header_with_fixnum.pb | 2 + protoc_plugin/test/goldens/imports.pb | 2 + protoc_plugin/test/goldens/int64.pb | 2 + protoc_plugin/test/goldens/oneMessage.pb | 2 + protoc_plugin/test/goldens/oneMessage.pb.meta | 56 +++++++++---------- protoc_plugin/test/goldens/service.pb | 2 + protoc_plugin/test/goldens/topLevelEnum.pb | 2 + protoc_plugin/test/oneof_test.dart | 1 - 14 files changed, 70 insertions(+), 36 deletions(-) diff --git a/benchmarks/bin/deep_copy.dart b/benchmarks/bin/deep_copy.dart index 5cd0fda8..6f37c260 100644 --- a/benchmarks/bin/deep_copy.dart +++ b/benchmarks/bin/deep_copy.dart @@ -2,7 +2,6 @@ // 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. -import 'package:protobuf/protobuf.dart'; import 'package:protobuf_benchmarks/benchmark_base.dart'; import 'package:protobuf_benchmarks/generated/google_message1_proto2.pb.dart' as p2; diff --git a/protoc_plugin/CHANGELOG.md b/protoc_plugin/CHANGELOG.md index 0684291b..239fb377 100644 --- a/protoc_plugin/CHANGELOG.md +++ b/protoc_plugin/CHANGELOG.md @@ -5,9 +5,13 @@ fields is now `PbMap` (instead of `Map`). ([#903]) This change requires protobuf-4.0.0. +* Generated files now export `GeneratedMessageGenericExtensions` from the + protobuf library. ([#503], [#907]) [#738]: https://github.com/google/protobuf.dart/issues/738 [#903]: https://github.com/google/protobuf.dart/pull/903 +[#503]: https://github.com/google/protobuf.dart/issues/503 +[#907]: https://github.com/google/protobuf.dart/pull/907 ## 21.1.2 diff --git a/protoc_plugin/lib/indenting_writer.dart b/protoc_plugin/lib/indenting_writer.dart index 4bdcd32b..f6b8dae4 100644 --- a/protoc_plugin/lib/indenting_writer.dart +++ b/protoc_plugin/lib/indenting_writer.dart @@ -173,14 +173,16 @@ class ImportWriter { final Set _dartImports = SplayTreeSet(); final Set _packageImports = SplayTreeSet(); final Set _fileImports = SplayTreeSet(); - final Set _exports = SplayTreeSet(); + final Set _packageExports = SplayTreeSet(); + final Set _fileExports = SplayTreeSet(); /// Whether any imports were written. bool get hasImports => _dartImports.isNotEmpty || _packageImports.isNotEmpty || _fileImports.isNotEmpty || - _exports.isNotEmpty; + _packageExports.isNotEmpty || + _fileExports.isNotEmpty; /// Add an import with an optional import prefix. void addImport(String url, {String? prefix}) { @@ -196,8 +198,15 @@ class ImportWriter { } /// And an export. - void addExport(String url) { - _exports.add("export '$url';"); + void addExport(String url, {List members = const []}) { + final directive = members.isNotEmpty + ? "export '$url' show ${members.join(', ')};" + : "export '$url';"; + if (url.startsWith('package:')) { + _packageExports.add(directive); + } else { + _fileExports.add(directive); + } } /// Return the generated text for the set of imports. @@ -215,9 +224,13 @@ class ImportWriter { if (buf.isNotEmpty) buf.writeln(); _fileImports.forEach(buf.writeln); } - if (_exports.isNotEmpty) { + if (_packageExports.isNotEmpty) { + if (buf.isNotEmpty) buf.writeln(); + _packageExports.forEach(buf.writeln); + } + if (_fileExports.isNotEmpty) { if (buf.isNotEmpty) buf.writeln(); - _exports.forEach(buf.writeln); + _fileExports.forEach(buf.writeln); } return buf.toString(); diff --git a/protoc_plugin/lib/src/file_generator.dart b/protoc_plugin/lib/src/file_generator.dart index c1be6731..b14684e8 100644 --- a/protoc_plugin/lib/src/file_generator.dart +++ b/protoc_plugin/lib/src/file_generator.dart @@ -341,6 +341,9 @@ class FileGenerator extends ProtobufContainer { _addImport(importWriter, config, target, '.pbenum.dart'); } + importWriter.addExport(_protobufImportUrl, + members: ['GeneratedMessageGenericExtensions']); + for (final publicDependency in descriptor.publicDependency) { _addExport(importWriter, config, Uri.file(descriptor.dependency[publicDependency]), '.pb.dart'); diff --git a/protoc_plugin/test/goldens/grpc_service.pb b/protoc_plugin/test/goldens/grpc_service.pb index 3b4a7a45..b7a21b7c 100644 --- a/protoc_plugin/test/goldens/grpc_service.pb +++ b/protoc_plugin/test/goldens/grpc_service.pb @@ -13,6 +13,8 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; +export 'package:protobuf/protobuf.dart' show GeneratedMessageGenericExtensions; + class Empty extends $pb.GeneratedMessage { factory Empty() => create(); Empty._() : super(); diff --git a/protoc_plugin/test/goldens/header_in_package.pb b/protoc_plugin/test/goldens/header_in_package.pb index 10a0966a..14dcfbd6 100644 --- a/protoc_plugin/test/goldens/header_in_package.pb +++ b/protoc_plugin/test/goldens/header_in_package.pb @@ -13,3 +13,5 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; +export 'package:protobuf/protobuf.dart' show GeneratedMessageGenericExtensions; + diff --git a/protoc_plugin/test/goldens/header_with_fixnum.pb b/protoc_plugin/test/goldens/header_with_fixnum.pb index 04d040a2..d50ef3dc 100644 --- a/protoc_plugin/test/goldens/header_with_fixnum.pb +++ b/protoc_plugin/test/goldens/header_with_fixnum.pb @@ -14,3 +14,5 @@ import 'dart:core' as $core; import 'package:fixnum/fixnum.dart' as $fixnum; import 'package:protobuf/protobuf.dart' as $pb; +export 'package:protobuf/protobuf.dart' show GeneratedMessageGenericExtensions; + diff --git a/protoc_plugin/test/goldens/imports.pb b/protoc_plugin/test/goldens/imports.pb index 5c24303f..0f8f8913 100644 --- a/protoc_plugin/test/goldens/imports.pb +++ b/protoc_plugin/test/goldens/imports.pb @@ -16,6 +16,8 @@ import 'package:protobuf/protobuf.dart' as $pb; import 'package1.pb.dart' as $1; import 'package2.pb.dart' as $2; +export 'package:protobuf/protobuf.dart' show GeneratedMessageGenericExtensions; + class M extends $pb.GeneratedMessage { factory M() => create(); M._() : super(); diff --git a/protoc_plugin/test/goldens/int64.pb b/protoc_plugin/test/goldens/int64.pb index a7f91462..047e0121 100644 --- a/protoc_plugin/test/goldens/int64.pb +++ b/protoc_plugin/test/goldens/int64.pb @@ -14,6 +14,8 @@ import 'dart:core' as $core; import 'package:fixnum/fixnum.dart' as $fixnum; import 'package:protobuf/protobuf.dart' as $pb; +export 'package:protobuf/protobuf.dart' show GeneratedMessageGenericExtensions; + class Int64 extends $pb.GeneratedMessage { factory Int64() => create(); Int64._() : super(); diff --git a/protoc_plugin/test/goldens/oneMessage.pb b/protoc_plugin/test/goldens/oneMessage.pb index 8ba6be3a..984bc61b 100644 --- a/protoc_plugin/test/goldens/oneMessage.pb +++ b/protoc_plugin/test/goldens/oneMessage.pb @@ -13,6 +13,8 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; +export 'package:protobuf/protobuf.dart' show GeneratedMessageGenericExtensions; + class PhoneNumber extends $pb.GeneratedMessage { factory PhoneNumber() => create(); PhoneNumber._() : super(); diff --git a/protoc_plugin/test/goldens/oneMessage.pb.meta b/protoc_plugin/test/goldens/oneMessage.pb.meta index 1b984ea7..9e1a0e93 100644 --- a/protoc_plugin/test/goldens/oneMessage.pb.meta +++ b/protoc_plugin/test/goldens/oneMessage.pb.meta @@ -2,15 +2,15 @@ annotation: { path: 4 path: 0 sourceFile: test - begin: 445 - end: 456 + begin: 526 + end: 537 } annotation: { path: 4 path: 0 sourceFile: test - begin: 527 - end: 538 + begin: 608 + end: 619 } annotation: { path: 4 @@ -18,8 +18,8 @@ annotation: { path: 2 path: 0 sourceFile: test - begin: 2247 - end: 2253 + begin: 2328 + end: 2334 } annotation: { path: 4 @@ -27,8 +27,8 @@ annotation: { path: 2 path: 0 sourceFile: test - begin: 2295 - end: 2301 + begin: 2376 + end: 2382 } annotation: { path: 4 @@ -36,8 +36,8 @@ annotation: { path: 2 path: 0 sourceFile: test - begin: 2374 - end: 2383 + begin: 2455 + end: 2464 } annotation: { path: 4 @@ -45,8 +45,8 @@ annotation: { path: 2 path: 0 sourceFile: test - begin: 2426 - end: 2437 + begin: 2507 + end: 2518 } annotation: { path: 4 @@ -54,8 +54,8 @@ annotation: { path: 2 path: 1 sourceFile: test - begin: 2495 - end: 2499 + begin: 2576 + end: 2580 } annotation: { path: 4 @@ -63,8 +63,8 @@ annotation: { path: 2 path: 1 sourceFile: test - begin: 2541 - end: 2545 + begin: 2622 + end: 2626 } annotation: { path: 4 @@ -72,8 +72,8 @@ annotation: { path: 2 path: 1 sourceFile: test - begin: 2620 - end: 2627 + begin: 2701 + end: 2708 } annotation: { path: 4 @@ -81,8 +81,8 @@ annotation: { path: 2 path: 1 sourceFile: test - begin: 2670 - end: 2679 + begin: 2751 + end: 2760 } annotation: { path: 4 @@ -90,8 +90,8 @@ annotation: { path: 2 path: 2 sourceFile: test - begin: 2740 - end: 2744 + begin: 2821 + end: 2825 } annotation: { path: 4 @@ -99,8 +99,8 @@ annotation: { path: 2 path: 2 sourceFile: test - begin: 2791 - end: 2795 + begin: 2872 + end: 2876 } annotation: { path: 4 @@ -108,8 +108,8 @@ annotation: { path: 2 path: 2 sourceFile: test - begin: 2868 - end: 2875 + begin: 2949 + end: 2956 } annotation: { path: 4 @@ -117,6 +117,6 @@ annotation: { path: 2 path: 2 sourceFile: test - begin: 2918 - end: 2927 + begin: 2999 + end: 3008 } diff --git a/protoc_plugin/test/goldens/service.pb b/protoc_plugin/test/goldens/service.pb index aeeafada..706e352a 100644 --- a/protoc_plugin/test/goldens/service.pb +++ b/protoc_plugin/test/goldens/service.pb @@ -14,6 +14,8 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; +export 'package:protobuf/protobuf.dart' show GeneratedMessageGenericExtensions; + class Empty extends $pb.GeneratedMessage { factory Empty() => create(); Empty._() : super(); diff --git a/protoc_plugin/test/goldens/topLevelEnum.pb b/protoc_plugin/test/goldens/topLevelEnum.pb index 09c5d230..9a8ed601 100644 --- a/protoc_plugin/test/goldens/topLevelEnum.pb +++ b/protoc_plugin/test/goldens/topLevelEnum.pb @@ -11,5 +11,7 @@ import 'dart:core' as $core; +export 'package:protobuf/protobuf.dart' show GeneratedMessageGenericExtensions; + export 'test.pbenum.dart'; diff --git a/protoc_plugin/test/oneof_test.dart b/protoc_plugin/test/oneof_test.dart index 5223c85e..ccbf8a9d 100644 --- a/protoc_plugin/test/oneof_test.dart +++ b/protoc_plugin/test/oneof_test.dart @@ -2,7 +2,6 @@ // 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. -import 'package:protobuf/protobuf.dart'; import 'package:test/test.dart'; import '../out/protos/oneof.pb.dart';