Fix comment references
diff --git a/analysis_options.yaml b/analysis_options.yaml
index 6e1ff09..91f5433 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -16,6 +16,7 @@
   - await_only_futures
   - camel_case_extensions
   - camel_case_types
+  - comment_references
   - constant_identifier_names
   - control_flow_in_finally
   - curly_braces_in_flow_control_structures
diff --git a/protobuf/analysis_options.yaml b/protobuf/analysis_options.yaml
index 56e6618..b5891f0 100644
--- a/protobuf/analysis_options.yaml
+++ b/protobuf/analysis_options.yaml
@@ -2,6 +2,7 @@
 
 linter:
   rules:
+    comment_references: true
     directives_ordering: true
     prefer_relative_imports: true
     prefer_single_quotes: true
diff --git a/protobuf/benchmarks/common.dart b/protobuf/benchmarks/common.dart
index dbdfe1e..a7f7c0b 100644
--- a/protobuf/benchmarks/common.dart
+++ b/protobuf/benchmarks/common.dart
@@ -73,7 +73,7 @@
   static Factories forMessage(String name) =>
       _factories[name] ?? (throw 'Unsupported message: $name');
 
-  /// Mapping between [BenchmarkProto.messageName] and corresponding
+  /// Mapping between [BenchmarkDataset.messageName] and corresponding
   /// deserialization factories.
   static final _factories = {
     'benchmarks.proto2.GoogleMessage1': Factories._(
diff --git a/protobuf/benchmarks/d8.dart b/protobuf/benchmarks/d8.dart
index d709383..f55ef70 100644
--- a/protobuf/benchmarks/d8.dart
+++ b/protobuf/benchmarks/d8.dart
@@ -11,11 +11,11 @@
 import 'package:js/js.dart';
 
 /// Read the file at the given [path] and return its contents in
-/// an [ArrayBuffer].
+/// an [ByteBuffer].
 @JS()
 external ByteBuffer readbuffer(String path);
 
-/// Read the file at the given [path] and return its contents in
+/// Read the [file] and return its contents in
 /// a Uint8List.
 Uint8List readAsBytesSync(String file) {
   return Uint8List.view(readbuffer(file));
diff --git a/protobuf/lib/src/protobuf/coded_buffer_writer.dart b/protobuf/lib/src/protobuf/coded_buffer_writer.dart
index a39c620..b1821d8 100644
--- a/protobuf/lib/src/protobuf/coded_buffer_writer.dart
+++ b/protobuf/lib/src/protobuf/coded_buffer_writer.dart
@@ -14,7 +14,7 @@
 /// length-delimited representation, which means that they are represented as
 /// a varint encoded length followed by specified number of bytes of data.
 ///
-/// Due to this [CodedBufferWritter] maintains two output buffers:
+/// Due to this [CodedBufferWriter] maintains two output buffers:
 /// [_outputChunks] which contains all continuously written bytes and
 /// [_splices] which describes additional bytes to splice in-between
 /// [_outputChunks] bytes.
@@ -176,8 +176,8 @@
 
   /// Move the current [_outputChunk] into [_outputChunks].
   ///
-  /// If [allocateNew] is [true] then allocate a new chunk, otherwise
-  /// set [_outputChunk] to null.
+  /// If [allocateNew] is `true` then allocate a new chunk, otherwise
+  /// set [_outputChunk] to `null`.
   void _commitChunk(bool allocateNew) {
     if (_bytesInChunk != 0) {
       _outputChunks.add(_outputChunk);
diff --git a/protobuf/lib/src/protobuf/extension_registry.dart b/protobuf/lib/src/protobuf/extension_registry.dart
index 93aa9fc..be1f3d1 100644
--- a/protobuf/lib/src/protobuf/extension_registry.dart
+++ b/protobuf/lib/src/protobuf/extension_registry.dart
@@ -35,7 +35,7 @@
     return null;
   }
 
-  /// Returns a shallow copy of [message], with all extensions in [this] parsed
+  /// Returns a shallow copy of [message], with all extensions in `this` parsed
   /// from the unknown fields of [message] and of every nested submessage.
   ///
   /// Extensions already present in [message] will be preserved.
diff --git a/protobuf/lib/src/protobuf/field_set.dart b/protobuf/lib/src/protobuf/field_set.dart
index f2e6faa..f137aad 100644
--- a/protobuf/lib/src/protobuf/field_set.dart
+++ b/protobuf/lib/src/protobuf/field_set.dart
@@ -765,7 +765,7 @@
   /// recursively merged.
   void _mergeFromMessage(_FieldSet other) {
     // TODO(https://github.com/google/protobuf.dart/issues/60): Recognize
-    // when [this] and [other] are the same protobuf (e.g. from cloning). In
+    // when `this` and [other] are the same protobuf (e.g. from cloning). In
     // this case, we can merge the non-extension fields without field lookups or
     // validation checks.
 
diff --git a/protobuf/lib/src/protobuf/generated_message.dart b/protobuf/lib/src/protobuf/generated_message.dart
index 64d1395..60d40d1 100644
--- a/protobuf/lib/src/protobuf/generated_message.dart
+++ b/protobuf/lib/src/protobuf/generated_message.dart
@@ -78,11 +78,11 @@
 
   /// Returns a writable, shallow copy of this message.
   ///
-  /// Sub messages will be shared with [this] and will still be frozen if [this]
+  /// Sub messages will be shared with `this` and will still be frozen if `this`
   /// is frozen.
   ///
   /// The lists representing repeated fields are copied. But their elements will
-  /// be shared with the corresponding list in [this].
+  /// be shared with the corresponding list in `this`.
   ///
   /// Similarly for map fields, the maps will be copied, but share the elements.
   // TODO(nichite, sigurdm): Consider returning an actual builder object that
@@ -216,10 +216,10 @@
   /// actual runtime value) are represented as strings. Enumerated values are
   /// represented as their integer value.
   ///
-  /// For the proto3 JSON format use: [toProto3JSON].
+  /// For the proto3 JSON format use: [toProto3Json].
   String writeToJson() => jsonEncode(writeToJsonMap());
 
-  /// Returns an Object representing Proto3 JSON serialization of [this].
+  /// Returns an Object representing Proto3 JSON serialization of `this`.
   ///
   /// The key for each field is be the camel-cased name of the field.
   ///
@@ -273,7 +273,7 @@
   /// Merges field values from [data], a JSON object, encoded as described by
   /// [GeneratedMessage.writeToJson].
   ///
-  /// For the proto3 JSON format use: [mergeFromProto3JSON].
+  /// For the proto3 JSON format use: [mergeFromProto3Json].
   void mergeFromJson(String data,
       [ExtensionRegistry extensionRegistry = ExtensionRegistry.EMPTY]) {
     /// Disable lazy creation of Dart objects for a dart2js speedup.
diff --git a/protobuf/lib/src/protobuf/json.dart b/protobuf/lib/src/protobuf/json.dart
index 0a5c827..c2c7368 100644
--- a/protobuf/lib/src/protobuf/json.dart
+++ b/protobuf/lib/src/protobuf/json.dart
@@ -166,7 +166,7 @@
 /// Converts [value] from the Json format to the Dart data type
 /// suitable for inserting into the corresponding [GeneratedMessage] field.
 ///
-/// Returns the converted value.  This function returns [null] if it is an
+/// Returns the converted value.  This function returns `null` if it is an
 /// unknown enum value, in which case the caller should figure out the default
 /// enum value to return instead.
 /// This function throws [ArgumentError] if it cannot convert the value.
diff --git a/protobuf/lib/src/protobuf/json_parsing_context.dart b/protobuf/lib/src/protobuf/json_parsing_context.dart
index 7d74fbf..5d11ced 100644
--- a/protobuf/lib/src/protobuf/json_parsing_context.dart
+++ b/protobuf/lib/src/protobuf/json_parsing_context.dart
@@ -24,7 +24,7 @@
     _path.removeLast();
   }
 
-  /// Returns a FormatException indicating the indices to the current [path].
+  /// Returns a FormatException indicating the indices to the current path.
   Exception parseException(String message, Object? source) {
     var formattedPath = _path.map((s) => '["$s"]').join();
     return FormatException(
diff --git a/protobuf/lib/src/protobuf/mixins/well_known.dart b/protobuf/lib/src/protobuf/mixins/well_known.dart
index 308832b..5d7ca0a 100644
--- a/protobuf/lib/src/protobuf/mixins/well_known.dart
+++ b/protobuf/lib/src/protobuf/mixins/well_known.dart
@@ -156,7 +156,7 @@
       seconds.toInt() * Duration.microsecondsPerSecond + nanos ~/ 1000,
       isUtc: true);
 
-  /// Updates [target] to be the time at [datetime].
+  /// Updates [target] to be the time at [dateTime].
   ///
   /// Time zone information will not be preserved.
   static void setFromDateTime(TimestampMixin target, DateTime dateTime) {
diff --git a/protobuf/lib/src/protobuf/pb_list.dart b/protobuf/lib/src/protobuf/pb_list.dart
index fac87cd..6b53d1f 100644
--- a/protobuf/lib/src/protobuf/pb_list.dart
+++ b/protobuf/lib/src/protobuf/pb_list.dart
@@ -75,118 +75,86 @@
   /// Freezes the list by converting to [FrozenPbList].
   FrozenPbList<E> toFrozenPbList() => FrozenPbList<E>.from(this);
 
-  /// Adds [value] at the end of the list, extending the length by one.
-  /// Throws an [UnsupportedError] if the list is not extendable.
   @override
-  void add(E value) {
-    check(value);
-    _wrappedList.add(value);
+  void add(E element) {
+    check(element);
+    _wrappedList.add(element);
   }
 
-  /// Appends all elements of the [collection] to the end of list.
-  /// Extends the length of the list by the length of [collection].
-  /// Throws an [UnsupportedError] if the list is not extendable.
   @override
-  void addAll(Iterable<E> collection) {
-    collection.forEach(check);
-    _wrappedList.addAll(collection);
+  void addAll(Iterable<E> iterable) {
+    iterable.forEach(check);
+    _wrappedList.addAll(iterable);
   }
 
-  /// Returns an [Iterable] of the objects in this list in reverse order.
   @override
   Iterable<E> get reversed => _wrappedList.reversed;
 
-  /// Sorts this list according to the order specified by the [compare]
-  /// function.
   @override
   void sort([int Function(E a, E b)? compare]) => _wrappedList.sort(compare);
 
-  /// Shuffles the elements of this list randomly.
   @override
   void shuffle([math.Random? random]) => _wrappedList.shuffle(random);
 
-  /// Removes all objects from this list; the length of the list becomes zero.
   @override
   void clear() => _wrappedList.clear();
 
-  /// Inserts a new element in the list.
-  /// The element must be valid (and not nullable) for the PbList type.
   @override
   void insert(int index, E element) {
     check(element);
     _wrappedList.insert(index, element);
   }
 
-  /// Inserts all elements of [iterable] at position [index] in the list.
-  ///
-  /// Elements in [iterable] must be valid and not nullable for the PbList type.
   @override
   void insertAll(int index, Iterable<E> iterable) {
     iterable.forEach(check);
     _wrappedList.insertAll(index, iterable);
   }
 
-  /// Overwrites elements of `this` with elements of [iterable] starting at
-  /// position [index] in the list.
-  ///
-  /// Elements in [iterable] must be valid and not nullable for the PbList type.
   @override
   void setAll(int index, Iterable<E> iterable) {
     iterable.forEach(check);
     _wrappedList.setAll(index, iterable);
   }
 
-  /// Removes the first occurrence of [value] from this list.
   @override
-  bool remove(Object? value) => _wrappedList.remove(value);
+  bool remove(Object? element) => _wrappedList.remove(element);
 
-  /// Removes the object at position [index] from this list.
   @override
   E removeAt(int index) => _wrappedList.removeAt(index);
 
-  /// Pops and returns the last object in this list.
   @override
   E removeLast() => _wrappedList.removeLast();
 
-  /// Removes all objects from this list that satisfy [test].
   @override
   void removeWhere(bool Function(E element) test) =>
       _wrappedList.removeWhere(test);
 
-  /// Removes all objects from this list that fail to satisfy [test].
   @override
   void retainWhere(bool Function(E element) test) =>
       _wrappedList.retainWhere(test);
 
-  /// Copies [:end - start:] elements of the [from] array, starting from
-  /// [skipCount], into [:this:], starting at [start].
-  /// Throws an [UnsupportedError] if the list is not extendable.
   @override
-  void setRange(int start, int end, Iterable<E> from, [int skipCount = 0]) {
+  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
     // NOTE: In case `take()` returns less than `end - start` elements, the
     // _wrappedList will fail with a `StateError`.
-    from.skip(skipCount).take(end - start).forEach(check);
-    _wrappedList.setRange(start, end, from, skipCount);
+    iterable.skip(skipCount).take(end - start).forEach(check);
+    _wrappedList.setRange(start, end, iterable, skipCount);
   }
 
-  /// Removes the objects in the range [start] inclusive to [end] exclusive.
   @override
   void removeRange(int start, int end) => _wrappedList.removeRange(start, end);
 
-  /// Sets the objects in the range [start] inclusive to [end] exclusive to the
-  /// given [fillValue].
   @override
-  void fillRange(int start, int end, [E? fillValue]) {
-    check(fillValue);
-    _wrappedList.fillRange(start, end, fillValue);
+  void fillRange(int start, int end, [E? fill]) {
+    check(fill);
+    _wrappedList.fillRange(start, end, fill);
   }
 
-  /// Removes the objects in the range [start] inclusive to [end] exclusive and
-  /// inserts the contents of [replacement] in its place.
   @override
-  void replaceRange(int start, int end, Iterable<E> replacement) {
-    final values = replacement.toList();
-    replacement.forEach(check);
+  void replaceRange(int start, int end, Iterable<E> newContents) {
+    final values = newContents.toList();
+    newContents.forEach(check);
     _wrappedList.replaceRange(start, end, values);
   }
 }
@@ -213,167 +181,119 @@
   @override
   int get hashCode => _HashUtils._hashObjects(_wrappedList);
 
-  /// Returns an [Iterator] for the list.
   @override
   Iterator<E> get iterator => _wrappedList.iterator;
 
-  /// Returns a new lazy [Iterable] with elements that are created by calling
-  /// `f` on each element of this `PbListBase` in iteration order.
   @override
   Iterable<T> map<T>(T Function(E e) f) => _wrappedList.map<T>(f);
 
-  /// Returns a new lazy [Iterable] with all elements that satisfy the predicate
-  /// [test].
   @override
   Iterable<E> where(bool Function(E element) test) => _wrappedList.where(test);
 
-  /// Expands each element of this [Iterable] into zero or more elements.
   @override
   Iterable<T> expand<T>(Iterable<T> Function(E element) f) =>
       _wrappedList.expand(f);
 
-  /// Returns true if the collection contains an element equal to [element].
   @override
   bool contains(Object? element) => _wrappedList.contains(element);
 
-  /// Applies the function [f] to each element of this list in iteration order.
   @override
-  void forEach(void Function(E element) f) {
-    _wrappedList.forEach(f);
+  void forEach(void Function(E element) action) {
+    _wrappedList.forEach(action);
   }
 
-  /// Reduces a collection to a single value by iteratively combining elements
-  /// of the collection using the provided function.
   @override
   E reduce(E Function(E value, E element) combine) =>
       _wrappedList.reduce(combine);
 
-  /// Reduces a collection to a single value by iteratively combining each
-  /// element of the collection with an existing value.
   @override
   T fold<T>(T initialValue, T Function(T previousValue, E element) combine) =>
       _wrappedList.fold(initialValue, combine);
 
-  /// Checks whether every element of this iterable satisfies [test].
   @override
   bool every(bool Function(E element) test) => _wrappedList.every(test);
 
-  /// Converts each element to a [String] and concatenates the strings.
   @override
   String join([String separator = '']) => _wrappedList.join(separator);
 
-  /// Checks whether any element of this iterable satisfies [test].
   @override
   bool any(bool Function(E element) test) => _wrappedList.any(test);
 
-  /// Creates a [List] containing the elements of this [Iterable].
   @override
   List<E> toList({bool growable = true}) =>
       _wrappedList.toList(growable: growable);
 
-  /// Creates a [Set] containing the same elements as this iterable.
   @override
   Set<E> toSet() => _wrappedList.toSet();
 
-  /// Returns `true` if there are no elements in this collection.
   @override
   bool get isEmpty => _wrappedList.isEmpty;
 
-  /// Returns `true` if there is at least one element in this collection.
   @override
   bool get isNotEmpty => _wrappedList.isNotEmpty;
 
-  /// Returns a lazy iterable of the [count] first elements of this iterable.
   @override
   Iterable<E> take(int count) => _wrappedList.take(count);
 
-  /// Returns a lazy iterable of the leading elements satisfying [test].
   @override
   Iterable<E> takeWhile(bool Function(E value) test) =>
       _wrappedList.takeWhile(test);
 
-  /// Returns an [Iterable] that provides all but the first [count] elements.
   @override
   Iterable<E> skip(int count) => _wrappedList.skip(count);
 
-  /// Returns an `Iterable` that skips leading elements while [test] is
-  /// satisfied.
   @override
   Iterable<E> skipWhile(bool Function(E value) test) =>
       _wrappedList.skipWhile(test);
 
-  /// Returns the first element.
   @override
   E get first => _wrappedList.first;
 
-  /// Returns the last element.
   @override
   E get last => _wrappedList.last;
 
-  /// Checks that this iterable has only one element, and returns that element.
   @override
   E get single => _wrappedList.single;
 
-  /// Returns the first element that satisfies the given predicate [test].
   @override
   E firstWhere(bool Function(E element) test, {E Function()? orElse}) =>
       _wrappedList.firstWhere(test, orElse: orElse);
 
-  /// Returns the last element that satisfies the given predicate [test].
   @override
   E lastWhere(bool Function(E element) test, {E Function()? orElse}) =>
       _wrappedList.lastWhere(test, orElse: orElse);
 
-  /// Returns the single element that satisfies [test].
-  // TODO(jakobr): Implement once Dart 2 corelib changes have landed.
-  //E singleWhere(bool test(E element), {E orElse()}) =>
-  //    _wrappedList.singleWhere(test, orElse: orElse);
-
-  /// Returns the [index]th element.
   @override
   E elementAt(int index) => _wrappedList.elementAt(index);
 
-  /// Returns a string representation of (some of) the elements of `this`.
   @override
   String toString() => _wrappedList.toString();
 
-  /// Returns the element at the given [index] in the list or throws an
-  /// [IndexOutOfRangeException] if [index] is out of bounds.
   @override
   E operator [](int index) => _wrappedList[index];
 
-  /// Returns the number of elements in this collection.
   @override
   int get length => _wrappedList.length;
 
   // TODO(jakobr): E instead of Object once dart-lang/sdk#31311 is fixed.
-  /// Returns the first index of [element] in this list.
   @override
   int indexOf(Object? element, [int start = 0]) =>
       _wrappedList.indexOf(element as E, start);
 
   // TODO(jakobr): E instead of Object once dart-lang/sdk#31311 is fixed.
-  /// Returns the last index of [element] in this list.
   @override
   int lastIndexOf(Object? element, [int? start]) =>
       _wrappedList.lastIndexOf(element as E, start);
 
-  /// Returns a new list containing the objects from [start] inclusive to [end]
-  /// exclusive.
   @override
   List<E> sublist(int start, [int? end]) => _wrappedList.sublist(start, end);
 
-  /// Returns an [Iterable] that iterates over the objects in the range [start]
-  /// inclusive to [end] exclusive.
   @override
   Iterable<E> getRange(int start, int end) => _wrappedList.getRange(start, end);
 
-  /// Returns an unmodifiable [Map] view of `this`.
   @override
   Map<int, E> asMap() => _wrappedList.asMap();
 
-  /// Sets the entry at the given [index] in the list to [value].
-  /// Throws an [IndexOutOfRangeException] if [index] is out of bounds.
   @override
   void operator []=(int index, E value) {
     check(value);
diff --git a/protoc_plugin/analysis_options.yaml b/protoc_plugin/analysis_options.yaml
index dc7ec89..4c7bd51 100644
--- a/protoc_plugin/analysis_options.yaml
+++ b/protoc_plugin/analysis_options.yaml
@@ -7,6 +7,7 @@
 linter:
   rules:
     camel_case_types: true
+    comment_references: true
     control_flow_in_finally: true
     directives_ordering: true
     prefer_relative_imports: true
diff --git a/protoc_plugin/lib/names.dart b/protoc_plugin/lib/names.dart
index 1694f0b..a209443 100644
--- a/protoc_plugin/lib/names.dart
+++ b/protoc_plugin/lib/names.dart
@@ -152,8 +152,8 @@
 ///
 /// The chosen name is added to [usedNames].
 ///
-/// If [variants] is given, all the variants of a name must be available before
-/// that name is chosen, and all the chosen variants will be added to
+/// If [generateVariants] is given, all the variants of a name must be available
+/// before that name is chosen, and all the chosen variants will be added to
 /// [usedNames].
 /// The returned name is that, which will generate the accepted variants.
 String disambiguateName(
diff --git a/protoc_plugin/lib/src/base_type.dart b/protoc_plugin/lib/src/base_type.dart
index 0003f1b..f9326da 100644
--- a/protoc_plugin/lib/src/base_type.dart
+++ b/protoc_plugin/lib/src/base_type.dart
@@ -47,8 +47,9 @@
   /// Returns the name to use in generated code for this Dart type.
   ///
   /// Doesn't include the List type for repeated fields.
-  /// [protoFileUri] represents the current proto file where we are generating
-  /// code. The Dart class might be imported from a different proto file.
+  /// [FileGenerator.protoFileUri] represents the current proto file where we
+  /// are generating code.
+  /// The Dart class might be imported from a different proto file.
   String getDartType(FileGenerator fileGen) =>
       (fileGen.protoFileUri == generator?.fileGen?.protoFileUri)
           ? unprefixed
diff --git a/protoc_plugin/lib/src/code_generator.dart b/protoc_plugin/lib/src/code_generator.dart
index 38e7596..2f47a89 100644
--- a/protoc_plugin/lib/src/code_generator.dart
+++ b/protoc_plugin/lib/src/code_generator.dart
@@ -85,7 +85,7 @@
 
   /// Runs the code generator. The optional [optionParsers] can be used to
   /// change how command line options are parsed (see [parseGenerationOptions]
-  /// for details), and [outputConfiguration] can be used to override where
+  /// for details), and [config] can be used to override where
   /// generated files are created and how imports between generated files are
   /// constructed (see [OutputConfiguration] for details).
   void generate(
diff --git a/protoc_plugin/lib/src/extension_generator.dart b/protoc_plugin/lib/src/extension_generator.dart
index 9e8f088..05e9455 100644
--- a/protoc_plugin/lib/src/extension_generator.dart
+++ b/protoc_plugin/lib/src/extension_generator.dart
@@ -84,8 +84,6 @@
     }
   }
 
-  /// Adds dependencies of [generateConstants] to [imports].
-  ///
   /// For each .pb.dart file that the generated code needs to import,
   /// add its generator.
   void addConstantImportsTo(Set<FileGenerator> imports) {
diff --git a/protoc_plugin/lib/src/message_generator.dart b/protoc_plugin/lib/src/message_generator.dart
index acf3bfa..92c3beb 100644
--- a/protoc_plugin/lib/src/message_generator.dart
+++ b/protoc_plugin/lib/src/message_generator.dart
@@ -718,7 +718,7 @@
 
   /// Returns the mixin for this message, or null if none.
   ///
-  /// First searches [wellKnownMixins], then [declaredMixins],
+  /// First searches [_wellKnownMixins], then [declaredMixins],
   /// then internal mixins declared by [findMixin].
   PbMixin _getMixin(Map<String, PbMixin> declaredMixins, PbMixin defaultMixin) {
     var wellKnownMixin = wellKnownMixinForFullName(fullName);
diff --git a/protoc_plugin/lib/src/options.dart b/protoc_plugin/lib/src/options.dart
index 55323ba..aa7b463 100644
--- a/protoc_plugin/lib/src/options.dart
+++ b/protoc_plugin/lib/src/options.dart
@@ -92,7 +92,7 @@
 }
 
 /// Parser used by the compiler, which supports the `rpc` option (see
-/// [RpcOptionParser]) and any additional option added in [parsers]. If
+/// [GrpcOptionParser]) and any additional option added in [parsers]. If
 /// [parsers] has a key for `rpc`, it will be ignored.
 GenerationOptions? parseGenerationOptions(
     CodeGeneratorRequest request, CodeGeneratorResponse response,