Skip to content

Commit a293fb9

Browse files
authored
Handle deprecated options in grpc services and methods, enum types and values, messages (#908)
Similar to #909, a new kind of golden test is added here where the test input is not a hand-crafted message descriptor but an actual .proto file.
1 parent 9a408a7 commit a293fb9

File tree

12 files changed

+278
-5
lines changed

12 files changed

+278
-5
lines changed

protoc_plugin/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,17 @@
99
protobuf library. ([#503], [#907])
1010
* Generate doc comments for enum types and values, rpc services and methods.
1111
([#900], [#909])
12+
* `deprecated` options in messages, grpc services and methods, and enum types
13+
and values are now handled to generate Dart `@deprecated` annotations.
14+
([#900], [#908])
1215

1316
[#738]: https://github.com/google/protobuf.dart/issues/738
1417
[#903]: https://github.com/google/protobuf.dart/pull/903
1518
[#503]: https://github.com/google/protobuf.dart/issues/503
1619
[#907]: https://github.com/google/protobuf.dart/pull/907
1720
[#900]: https://github.com/google/protobuf.dart/issues/900
1821
[#909]: https://github.com/google/protobuf.dart/pull/909
22+
[#908]: https://github.com/google/protobuf.dart/pull/908
1923

2024
## 21.1.2
2125

protoc_plugin/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ TEST_PROTO_LIST = \
2424
google/protobuf/wrappers \
2525
custom_option \
2626
dart_name \
27+
deprecations \
2728
doc_comments \
2829
default_value_escape \
2930
entity \

protoc_plugin/lib/src/client_generator.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ class ClientApiGenerator {
4646
if (commentBlock != null) {
4747
out.println(commentBlock);
4848
}
49+
if (service._descriptor.options.deprecated) {
50+
out.println(
51+
'@$coreImportPrefix.Deprecated(\'This service is deprecated\')');
52+
}
4953
out.addBlock('class ${className}Api {', '}', () {
5054
out.println('$_clientType _client;');
5155
out.println('${className}Api(this._client);');
@@ -73,6 +77,10 @@ class ClientApiGenerator {
7377
if (commentBlock != null) {
7478
out.println(commentBlock);
7579
}
80+
if (m.options.deprecated) {
81+
out.println(
82+
'@$coreImportPrefix.Deprecated(\'This method is deprecated\')');
83+
}
7684
out.addBlock(
7785
'$asyncImportPrefix.Future<$outputType> $methodName('
7886
'$protobufImportPrefix.ClientContext? ctx, $inputType request) =>',

protoc_plugin/lib/src/enum_generator.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,9 @@ class EnumGenerator extends ProtobufContainer {
106106
if (commentBlock != null) {
107107
out.println(commentBlock);
108108
}
109+
if (_descriptor.options.deprecated) {
110+
out.println('@$coreImportPrefix.Deprecated(\'This enum is deprecated\')');
111+
}
109112
out.addAnnotatedBlock(
110113
'class $classname extends $protobufImportPrefix.ProtobufEnum {',
111114
'}\n', [
@@ -129,6 +132,11 @@ class EnumGenerator extends ProtobufContainer {
129132
out.println(commentBlock);
130133
}
131134

135+
if (val.options.deprecated) {
136+
out.println(
137+
'@$coreImportPrefix.Deprecated(\'This enum value is deprecated\')');
138+
}
139+
132140
out.printlnAnnotated(
133141
'static const $classname $name = '
134142
'$classname._(${val.number}, $conditionalValName);',

protoc_plugin/lib/src/grpc_generator.dart

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ class GrpcServiceGenerator {
106106
}
107107

108108
void _generateClient(IndentingWriter out) {
109+
if (_descriptor.options.deprecated) {
110+
out.println(
111+
'@$coreImportPrefix.Deprecated(\'This service is deprecated\')');
112+
}
109113
out.println(
110114
'@$protobufImportPrefix.GrpcServiceName(\'$_fullServiceName\')');
111115
out.addBlock('class $_clientClassname extends $_client {', '}', () {
@@ -170,6 +174,8 @@ class _GrpcMethod {
170174
final String _clientReturnType;
171175
final String _serverReturnType;
172176

177+
final bool _deprecated;
178+
173179
_GrpcMethod._(
174180
this._grpcName,
175181
this._dartName,
@@ -180,7 +186,8 @@ class _GrpcMethod {
180186
this._responseType,
181187
this._argumentType,
182188
this._clientReturnType,
183-
this._serverReturnType);
189+
this._serverReturnType,
190+
this._deprecated);
184191

185192
factory _GrpcMethod(GrpcServiceGenerator service, GenerationContext ctx,
186193
MethodDescriptorProto method) {
@@ -204,6 +211,8 @@ class _GrpcMethod {
204211
final serverReturnType =
205212
serverStreaming ? '$_stream<$responseType>' : '$_future<$responseType>';
206213

214+
final deprecated = method.options.deprecated;
215+
207216
return _GrpcMethod._(
208217
grpcName,
209218
dartName,
@@ -214,7 +223,8 @@ class _GrpcMethod {
214223
responseType,
215224
argumentType,
216225
clientReturnType,
217-
serverReturnType);
226+
serverReturnType,
227+
deprecated);
218228
}
219229

220230
void generateClientMethodDescriptor(IndentingWriter out) {
@@ -228,6 +238,10 @@ class _GrpcMethod {
228238

229239
void generateClientStub(IndentingWriter out) {
230240
out.println();
241+
if (_deprecated) {
242+
out.println(
243+
'@$coreImportPrefix.Deprecated(\'This method is deprecated\')');
244+
}
231245
out.addBlock(
232246
'$_clientReturnType $_dartName($_argumentType request, {${GrpcServiceGenerator._callOptions}? options}) {',
233247
'}', () {

protoc_plugin/lib/src/message_generator.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,10 @@ class MessageGenerator extends ProtobufContainer {
327327
if (commentBlock != null) {
328328
out.println(commentBlock);
329329
}
330+
if (_descriptor.options.deprecated) {
331+
out.println(
332+
'@$coreImportPrefix.Deprecated(\'This message is deprecated\')');
333+
}
330334
out.addAnnotatedBlock(
331335
'class $classname extends $protobufImportPrefix.$extendedClass$mixinClause {',
332336
'}', [
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'dart:io';
6+
7+
import 'package:test/test.dart';
8+
9+
import 'golden_file.dart';
10+
11+
void main() {
12+
test('Deprecated annotation generation for messages', () {
13+
final actual = File('out/protos/deprecations.pb.dart').readAsStringSync();
14+
expectMatchesGoldenFile(actual, 'test/goldens/deprecations');
15+
});
16+
17+
test('Deprecated annotation generation for enums', () {
18+
final actual = File('out/protos/constructor_args/deprecations.pbenum.dart')
19+
.readAsStringSync();
20+
expectMatchesGoldenFile(actual, 'test/goldens/deprecations.pbenum');
21+
});
22+
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
//
2+
// Generated code. Do not modify.
3+
// source: deprecations.proto
4+
//
5+
// @dart = 2.12
6+
7+
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
8+
// ignore_for_file: constant_identifier_names, library_prefixes
9+
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
10+
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
11+
12+
import 'dart:async' as $async;
13+
import 'dart:core' as $core;
14+
15+
import 'package:protobuf/protobuf.dart' as $pb;
16+
17+
export 'package:protobuf/protobuf.dart' show GeneratedMessageGenericExtensions;
18+
19+
export 'deprecations.pbenum.dart';
20+
21+
@$core.Deprecated('This message is deprecated')
22+
class HelloRequest extends $pb.GeneratedMessage {
23+
factory HelloRequest() => create();
24+
HelloRequest._() : super();
25+
factory HelloRequest.fromBuffer($core.List<$core.int> i,
26+
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
27+
create()..mergeFromBuffer(i, r);
28+
factory HelloRequest.fromJson($core.String i,
29+
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
30+
create()..mergeFromJson(i, r);
31+
32+
static final $pb.BuilderInfo _i = $pb.BuilderInfo(
33+
_omitMessageNames ? '' : 'HelloRequest',
34+
package: const $pb.PackageName(_omitMessageNames ? '' : 'service2'),
35+
createEmptyInstance: create)
36+
..aOS(1, _omitFieldNames ? '' : 'name')
37+
..hasRequiredFields = false;
38+
39+
@$core.Deprecated('Using this can add significant overhead to your binary. '
40+
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
41+
'Will be removed in next major version')
42+
HelloRequest clone() => HelloRequest()..mergeFromMessage(this);
43+
@$core.Deprecated('Using this can add significant overhead to your binary. '
44+
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
45+
'Will be removed in next major version')
46+
HelloRequest copyWith(void Function(HelloRequest) updates) =>
47+
super.copyWith((message) => updates(message as HelloRequest))
48+
as HelloRequest;
49+
50+
$pb.BuilderInfo get info_ => _i;
51+
52+
@$core.pragma('dart2js:noInline')
53+
static HelloRequest create() => HelloRequest._();
54+
HelloRequest createEmptyInstance() => create();
55+
static $pb.PbList<HelloRequest> createRepeated() =>
56+
$pb.PbList<HelloRequest>();
57+
@$core.pragma('dart2js:noInline')
58+
static HelloRequest getDefault() => _defaultInstance ??=
59+
$pb.GeneratedMessage.$_defaultFor<HelloRequest>(create);
60+
static HelloRequest? _defaultInstance;
61+
62+
@$core.Deprecated('This field is deprecated.')
63+
@$pb.TagNumber(1)
64+
$core.String get name => $_getSZ(0);
65+
@$core.Deprecated('This field is deprecated.')
66+
@$pb.TagNumber(1)
67+
set name($core.String v) {
68+
$_setString(0, v);
69+
}
70+
71+
@$core.Deprecated('This field is deprecated.')
72+
@$pb.TagNumber(1)
73+
$core.bool hasName() => $_has(0);
74+
@$core.Deprecated('This field is deprecated.')
75+
@$pb.TagNumber(1)
76+
void clearName() => clearField(1);
77+
}
78+
79+
class HelloReply extends $pb.GeneratedMessage {
80+
factory HelloReply() => create();
81+
HelloReply._() : super();
82+
factory HelloReply.fromBuffer($core.List<$core.int> i,
83+
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
84+
create()..mergeFromBuffer(i, r);
85+
factory HelloReply.fromJson($core.String i,
86+
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
87+
create()..mergeFromJson(i, r);
88+
89+
static final $pb.BuilderInfo _i = $pb.BuilderInfo(
90+
_omitMessageNames ? '' : 'HelloReply',
91+
package: const $pb.PackageName(_omitMessageNames ? '' : 'service2'),
92+
createEmptyInstance: create)
93+
..aOS(1, _omitFieldNames ? '' : 'message')
94+
..hasRequiredFields = false;
95+
96+
@$core.Deprecated('Using this can add significant overhead to your binary. '
97+
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
98+
'Will be removed in next major version')
99+
HelloReply clone() => HelloReply()..mergeFromMessage(this);
100+
@$core.Deprecated('Using this can add significant overhead to your binary. '
101+
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
102+
'Will be removed in next major version')
103+
HelloReply copyWith(void Function(HelloReply) updates) =>
104+
super.copyWith((message) => updates(message as HelloReply)) as HelloReply;
105+
106+
$pb.BuilderInfo get info_ => _i;
107+
108+
@$core.pragma('dart2js:noInline')
109+
static HelloReply create() => HelloReply._();
110+
HelloReply createEmptyInstance() => create();
111+
static $pb.PbList<HelloReply> createRepeated() => $pb.PbList<HelloReply>();
112+
@$core.pragma('dart2js:noInline')
113+
static HelloReply getDefault() => _defaultInstance ??=
114+
$pb.GeneratedMessage.$_defaultFor<HelloReply>(create);
115+
static HelloReply? _defaultInstance;
116+
117+
@$pb.TagNumber(1)
118+
$core.String get message => $_getSZ(0);
119+
@$pb.TagNumber(1)
120+
set message($core.String v) {
121+
$_setString(0, v);
122+
}
123+
124+
@$pb.TagNumber(1)
125+
$core.bool hasMessage() => $_has(0);
126+
@$pb.TagNumber(1)
127+
void clearMessage() => clearField(1);
128+
}
129+
130+
@$core.Deprecated('This service is deprecated')
131+
class GreeterApi {
132+
$pb.RpcClient _client;
133+
GreeterApi(this._client);
134+
135+
@$core.Deprecated('This method is deprecated')
136+
$async.Future<HelloReply> sayHello(
137+
$pb.ClientContext? ctx, HelloRequest request) =>
138+
_client.invoke<HelloReply>(
139+
ctx, 'Greeter', 'SayHello', request, HelloReply());
140+
}
141+
142+
const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names');
143+
const _omitMessageNames =
144+
$core.bool.fromEnvironment('protobuf.omit_message_names');
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//
2+
// Generated code. Do not modify.
3+
// source: deprecations.proto
4+
//
5+
// @dart = 2.12
6+
7+
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
8+
// ignore_for_file: constant_identifier_names, library_prefixes
9+
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
10+
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
11+
12+
import 'dart:core' as $core;
13+
14+
import 'package:protobuf/protobuf.dart' as $pb;
15+
16+
@$core.Deprecated('This enum is deprecated')
17+
class A extends $pb.ProtobufEnum {
18+
@$core.Deprecated('This enum value is deprecated')
19+
static const A A1 = A._(0, _omitEnumNames ? '' : 'A1');
20+
static const A A2 = A._(1, _omitEnumNames ? '' : 'A2');
21+
22+
static const $core.List<A> values = <A>[
23+
A1,
24+
A2,
25+
];
26+
27+
static final $core.Map<$core.int, A> _byValue =
28+
$pb.ProtobufEnum.initByValue(values);
29+
static A? valueOf($core.int value) => _byValue[value];
30+
31+
const A._($core.int v, $core.String n) : super(v, n);
32+
}
33+
34+
const _omitEnumNames = $core.bool.fromEnvironment('protobuf.omit_enum_names');

protoc_plugin/test/goldens/doc_comments

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import 'dart:core' as $core;
1414

1515
import 'package:protobuf/protobuf.dart' as $pb;
1616

17+
export 'package:protobuf/protobuf.dart' show GeneratedMessageGenericExtensions;
18+
1719
export 'doc_comments.pbenum.dart';
1820

1921
/// This is a message.
@@ -29,7 +31,7 @@ class HelloRequest extends $pb.GeneratedMessage {
2931

3032
static final $pb.BuilderInfo _i = $pb.BuilderInfo(
3133
_omitMessageNames ? '' : 'HelloRequest',
32-
package: const $pb.PackageName(_omitMessageNames ? '' : 'service'),
34+
package: const $pb.PackageName(_omitMessageNames ? '' : 'service1'),
3335
createEmptyInstance: create)
3436
..aOS(1, _omitFieldNames ? '' : 'name')
3537
..hasRequiredFields = false;
@@ -83,7 +85,7 @@ class HelloReply extends $pb.GeneratedMessage {
8385

8486
static final $pb.BuilderInfo _i = $pb.BuilderInfo(
8587
_omitMessageNames ? '' : 'HelloReply',
86-
package: const $pb.PackageName(_omitMessageNames ? '' : 'service'),
88+
package: const $pb.PackageName(_omitMessageNames ? '' : 'service1'),
8789
createEmptyInstance: create)
8890
..aOS(1, _omitFieldNames ? '' : 'message')
8991
..hasRequiredFields = false;

0 commit comments

Comments
 (0)