Skip to content

Commit d00f905

Browse files
authored
Fix slow handling of protobuf comments (#955)
This syncs cl/613879585 and cl/614589429. Closes #935.
1 parent 12f0f4a commit d00f905

File tree

2 files changed

+33
-10
lines changed

2 files changed

+33
-10
lines changed

protoc_plugin/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
and values are now handled to generate Dart `@deprecated` annotations.
1414
([#900], [#908])
1515
* `protoc_plugin` and generated files now require Dart 3.3.0. (#953)
16+
* Fix performance issues when handling documentation comments in protobufs.
17+
([#935], [#955])
1618

1719
[#738]: https://github.com/google/protobuf.dart/issues/738
1820
[#903]: https://github.com/google/protobuf.dart/pull/903
@@ -22,6 +24,8 @@
2224
[#909]: https://github.com/google/protobuf.dart/pull/909
2325
[#908]: https://github.com/google/protobuf.dart/pull/908
2426
[#953]: https://github.com/google/protobuf.dart/pull/953
27+
[#935]: https://github.com/google/protobuf.dart/pull/935
28+
[#955]: https://github.com/google/protobuf.dart/pull/955
2529

2630
## 21.1.2
2731

protoc_plugin/lib/src/shared.dart

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'dart:convert';
66
import 'dart:io';
77

88
import '../protoc.dart';
9+
import '../src/generated/descriptor.pb.dart';
910

1011
const protobufImportPrefix = r'$pb';
1112
const asyncImportPrefix = r'$async';
@@ -14,6 +15,20 @@ const grpcImportPrefix = r'$grpc';
1415
const mixinImportPrefix = r'$mixin';
1516

1617
extension FileDescriptorProtoExt on FileGenerator {
18+
bool _listEquals(List<int> a, List<int> b) {
19+
if (a.length != b.length) {
20+
return false;
21+
}
22+
// Note: paths are much likely to share common prefixes than to share common
23+
// suffixes, so it's probably faster to run this loop backwards ;)
24+
for (var i = a.length - 1; i >= 0; i--) {
25+
if (a[i] != b[i]) {
26+
return false;
27+
}
28+
}
29+
return true;
30+
}
31+
1732
/// Convert leading comments of a definition at [path] to Dart doc comment
1833
/// syntax.
1934
///
@@ -23,18 +38,22 @@ extension FileDescriptorProtoExt on FileGenerator {
2338
/// The output can contain multiple lines. None of the lines will have
2439
/// trailing whitespace.
2540
String? commentBlock(List<int> path) {
26-
final bits = descriptor.sourceCodeInfo.location
27-
.where((element) => element.path.toString() == path.toString())
28-
.toList();
29-
30-
if (bits.length == 1) {
31-
final match = bits.single;
32-
return toDartComment(match.leadingComments);
41+
SourceCodeInfo_Location? singleMatch;
42+
for (final location in descriptor.sourceCodeInfo.location) {
43+
if (_listEquals(location.path, path)) {
44+
if (singleMatch == null) {
45+
singleMatch = location;
46+
} else {
47+
// TODO: evaluate if we should just concatenate all of the matching
48+
// entries.
49+
stderr.writeln('Too many source code locations. Skipping.');
50+
return null;
51+
}
52+
}
3353
}
3454

35-
if (bits.length > 1) {
36-
// TODO: evaluate if we should just concatenate all of the entries.
37-
stderr.writeln('Too many source code locations. Skipping.');
55+
if (singleMatch != null) {
56+
return toDartComment(singleMatch.leadingComments);
3857
}
3958

4059
return null;

0 commit comments

Comments
 (0)