Store unlinked data for AnalysisDriver in a more direct binary format.

Change-Id: Ie1421bdda0c9962a097d1bb77587c2088d805db4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/216264
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 0c1cd75..b0eccb6 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -80,7 +80,7 @@
 /// TODO(scheglov) Clean up the list of implicitly analyzed files.
 class AnalysisDriver implements AnalysisDriverGeneric {
   /// The version of data format, should be incremented on every format change.
-  static const int DATA_VERSION = 184;
+  static const int DATA_VERSION = 185;
 
   /// The number of exception contexts allowed to write. Once this field is
   /// zero, we stop writing any new exception contexts in this process.
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index f0607d2..d44f37d 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -21,6 +21,7 @@
 import 'package:analyzer/src/dart/analysis/performance_logger.dart';
 import 'package:analyzer/src/dart/analysis/referenced_names.dart';
 import 'package:analyzer/src/dart/analysis/unlinked_api_signature.dart';
+import 'package:analyzer/src/dart/analysis/unlinked_data.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/scanner/reader.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart';
@@ -31,8 +32,6 @@
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/source/source_resource.dart';
 import 'package:analyzer/src/summary/api_signature.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
 import 'package:analyzer/src/summary2/informative_data.dart';
 import 'package:analyzer/src/util/either.dart';
@@ -129,7 +128,7 @@
   AnalysisDriverUnlinkedUnit? _driverUnlinkedUnit;
   Uint8List? _apiSignature;
 
-  UnlinkedUnit2? _unlinked2;
+  UnlinkedUnit? _unlinked2;
 
   List<FileState?>? _importedFiles;
   List<FileState?>? _exportedFiles;
@@ -327,8 +326,8 @@
     return librarySignatureBuilder.toHex();
   }
 
-  /// The [UnlinkedUnit2] of the file.
-  UnlinkedUnit2 get unlinked2 => _unlinked2!;
+  /// The [UnlinkedUnit] of the file.
+  UnlinkedUnit get unlinked2 => _unlinked2!;
 
   /// The MD5 signature based on the content, feature sets, language version.
   Uint8List get unlinkedSignature => _unlinkedSignature!;
@@ -409,12 +408,12 @@
     var bytes = _getUnlinkedBytes();
 
     // Read the unlinked bundle.
-    _driverUnlinkedUnit = AnalysisDriverUnlinkedUnit.fromBuffer(bytes);
-    _unlinked2 = _driverUnlinkedUnit!.unit2;
+    _driverUnlinkedUnit = AnalysisDriverUnlinkedUnit.fromBytes(bytes);
+    _unlinked2 = _driverUnlinkedUnit!.unit;
     _lineInfo = LineInfo(_unlinked2!.lineStarts);
 
     // Prepare API signature.
-    var newApiSignature = Uint8List.fromList(_unlinked2!.apiSignature);
+    var newApiSignature = _unlinked2!.apiSignature;
     bool apiSignatureChanged = _apiSignature != null &&
         !_equalByteLists(_apiSignature, newApiSignature);
     _apiSignature = newApiSignature;
@@ -495,25 +494,25 @@
   }
 
   /// Return the bytes of the unlinked summary - existing or new.
-  List<int> _getUnlinkedBytes() {
+  Uint8List _getUnlinkedBytes() {
     var bytes = _fsState._byteStore.get(_unlinkedKey!);
     if (bytes != null && bytes.isNotEmpty) {
-      return bytes;
+      return bytes as Uint8List;
     }
 
     var unit = parse();
     return _fsState._logger.run('Create unlinked for $path', () {
       var unlinkedUnit = serializeAstUnlinked2(unit);
       var definedNames = computeDefinedNames(unit);
-      var referencedNames = computeReferencedNames(unit).toList();
-      var subtypedNames = computeSubtypedNames(unit).toList();
-      var bytes = AnalysisDriverUnlinkedUnitBuilder(
-        unit2: unlinkedUnit,
-        definedTopLevelNames: definedNames.topLevelNames.toList(),
-        definedClassMemberNames: definedNames.classMemberNames.toList(),
+      var referencedNames = computeReferencedNames(unit);
+      var subtypedNames = computeSubtypedNames(unit);
+      var bytes = AnalysisDriverUnlinkedUnit(
+        definedTopLevelNames: definedNames.topLevelNames,
+        definedClassMemberNames: definedNames.classMemberNames,
         referencedNames: referencedNames,
         subtypedNames: subtypedNames,
-      ).toBuffer();
+        unit: unlinkedUnit,
+      ).toBytes();
       _fsState._byteStore.put(_unlinkedKey!, bytes);
       counterUnlinkedBytes += bytes.length;
       counterUnlinkedLinkedBytes += bytes.length;
@@ -584,9 +583,9 @@
     return directive.uri;
   }
 
-  static UnlinkedUnit2Builder serializeAstUnlinked2(CompilationUnit unit) {
-    var exports = <UnlinkedNamespaceDirectiveBuilder>[];
-    var imports = <UnlinkedNamespaceDirectiveBuilder>[];
+  static UnlinkedUnit serializeAstUnlinked2(CompilationUnit unit) {
+    var exports = <UnlinkedNamespaceDirective>[];
+    var imports = <UnlinkedNamespaceDirective>[];
     var parts = <String>[];
     var hasDartCoreImport = false;
     var hasLibraryDirective = false;
@@ -612,19 +611,22 @@
     }
     if (!hasDartCoreImport) {
       imports.add(
-        UnlinkedNamespaceDirectiveBuilder(
+        UnlinkedNamespaceDirective(
+          configurations: [],
           uri: 'dart:core',
         ),
       );
     }
-    return UnlinkedUnit2Builder(
-      apiSignature: computeUnlinkedApiSignature(unit),
+    return UnlinkedUnit(
+      apiSignature: Uint8List.fromList(computeUnlinkedApiSignature(unit)),
       exports: exports,
-      imports: imports,
-      parts: parts,
       hasLibraryDirective: hasLibraryDirective,
       hasPartOfDirective: hasPartOfDirective,
-      lineStarts: unit.lineInfo!.lineStarts,
+      imports: imports,
+      lineStarts: Uint32List.fromList(unit.lineInfo!.lineStarts),
+      partOfName: null,
+      partOfUri: null,
+      parts: parts,
     );
   }
 
@@ -646,13 +648,13 @@
     return true;
   }
 
-  static UnlinkedNamespaceDirectiveBuilder _serializeNamespaceDirective(
+  static UnlinkedNamespaceDirective _serializeNamespaceDirective(
       NamespaceDirective directive) {
-    return UnlinkedNamespaceDirectiveBuilder(
+    return UnlinkedNamespaceDirective(
       configurations: directive.configurations.map((configuration) {
         var name = configuration.name.components.join('.');
         var value = configuration.value?.stringValue ?? '';
-        return UnlinkedNamespaceDirectiveConfigurationBuilder(
+        return UnlinkedNamespaceDirectiveConfiguration(
           name: name,
           value: value,
           uri: configuration.uri.stringValue ?? '',
diff --git a/pkg/analyzer/lib/src/dart/analysis/unlinked_data.dart b/pkg/analyzer/lib/src/dart/analysis/unlinked_data.dart
new file mode 100644
index 0000000..2c7b78b
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/analysis/unlinked_data.dart
@@ -0,0 +1,213 @@
+// Copyright (c) 2021, 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.
+
+import 'dart:typed_data';
+
+import 'package:analyzer/src/summary2/data_reader.dart';
+import 'package:analyzer/src/summary2/data_writer.dart';
+
+/// Unlinked information about a compilation unit.
+class AnalysisDriverUnlinkedUnit {
+  /// Set of class member names defined by the unit.
+  final Set<String> definedClassMemberNames;
+
+  /// Set of top-level names defined by the unit.
+  final Set<String> definedTopLevelNames;
+
+  /// Set of external names referenced by the unit.
+  final Set<String> referencedNames;
+
+  /// Set of names which are used in `extends`, `with` or `implements` clauses
+  /// in the file. Import prefixes and type arguments are not included.
+  final Set<String> subtypedNames;
+
+  /// Unlinked information for the unit.
+  final UnlinkedUnit unit;
+
+  AnalysisDriverUnlinkedUnit({
+    required this.definedClassMemberNames,
+    required this.definedTopLevelNames,
+    required this.referencedNames,
+    required this.subtypedNames,
+    required this.unit,
+  });
+
+  factory AnalysisDriverUnlinkedUnit.fromBytes(Uint8List bytes) {
+    return AnalysisDriverUnlinkedUnit.read(
+      SummaryDataReader(bytes),
+    );
+  }
+
+  factory AnalysisDriverUnlinkedUnit.read(SummaryDataReader reader) {
+    return AnalysisDriverUnlinkedUnit(
+      definedClassMemberNames: reader.readStringUtf8Set(),
+      definedTopLevelNames: reader.readStringUtf8Set(),
+      referencedNames: reader.readStringUtf8Set(),
+      subtypedNames: reader.readStringUtf8Set(),
+      unit: UnlinkedUnit.read(reader),
+    );
+  }
+
+  Uint8List toBytes() {
+    var byteSink = ByteSink();
+    var sink = BufferedSink(byteSink);
+    write(sink);
+    return sink.flushAndTake();
+  }
+
+  void write(BufferedSink sink) {
+    sink.writeStringUtf8Iterable(definedClassMemberNames);
+    sink.writeStringUtf8Iterable(definedTopLevelNames);
+    sink.writeStringUtf8Iterable(referencedNames);
+    sink.writeStringUtf8Iterable(subtypedNames);
+    unit.write(sink);
+  }
+}
+
+/// Unlinked information about a namespace directive.
+class UnlinkedNamespaceDirective {
+  /// The configurations that control which library will actually be used.
+  final List<UnlinkedNamespaceDirectiveConfiguration> configurations;
+
+  /// The URI referenced by this directive, nad used by default when none
+  /// of the [configurations] matches.
+  final String uri;
+
+  UnlinkedNamespaceDirective({
+    required this.configurations,
+    required this.uri,
+  });
+
+  factory UnlinkedNamespaceDirective.read(SummaryDataReader reader) {
+    return UnlinkedNamespaceDirective(
+      configurations: reader.readTypedList(
+        () => UnlinkedNamespaceDirectiveConfiguration.read(reader),
+      ),
+      uri: reader.readStringUtf8(),
+    );
+  }
+
+  void write(BufferedSink sink) {
+    sink.writeList<UnlinkedNamespaceDirectiveConfiguration>(
+      configurations,
+      (x) {
+        x.write(sink);
+      },
+    );
+    sink.writeStringUtf8(uri);
+  }
+}
+
+/// Unlinked information about a namespace directive configuration.
+class UnlinkedNamespaceDirectiveConfiguration {
+  /// The name of the declared variable used in the condition.
+  final String name;
+
+  /// The URI to be used if the condition is true.
+  final String uri;
+
+  /// The value to which the value of the declared variable will be compared,
+  /// or the empty string if the condition does not include an equality test.
+  final String value;
+
+  UnlinkedNamespaceDirectiveConfiguration({
+    required this.name,
+    required this.uri,
+    required this.value,
+  });
+
+  factory UnlinkedNamespaceDirectiveConfiguration.read(
+    SummaryDataReader reader,
+  ) {
+    return UnlinkedNamespaceDirectiveConfiguration(
+      name: reader.readStringUtf8(),
+      uri: reader.readStringUtf8(),
+      value: reader.readStringUtf8(),
+    );
+  }
+
+  void write(BufferedSink sink) {
+    sink.writeStringUtf8(name);
+    sink.writeStringUtf8(uri);
+    sink.writeStringUtf8(value);
+  }
+}
+
+/// Unlinked information about a compilation unit.
+class UnlinkedUnit {
+  /// The MD5 hash signature of the API portion of this unit. It depends on all
+  /// tokens that might affect APIs of declarations in the unit.
+  /// TODO(scheglov) Do we need it?
+  final Uint8List apiSignature;
+
+  /// URIs of `export` directives.
+  final List<UnlinkedNamespaceDirective> exports;
+
+  /// Is `true` if the unit contains a `library` directive.
+  final bool hasLibraryDirective;
+
+  /// Is `true` if the unit contains a `part of` directive.
+  final bool hasPartOfDirective;
+
+  /// URIs of `import` directives.
+  final List<UnlinkedNamespaceDirective> imports;
+
+  /// Offsets of the first character of each line in the source code.
+  final Uint32List lineStarts;
+
+  /// The library name of the `part of my.name;` directive.
+  final String? partOfName;
+
+  /// URI of the `part of 'uri';` directive.
+  final String? partOfUri;
+
+  /// URIs of `part` directives.
+  final List<String> parts;
+
+  UnlinkedUnit({
+    required this.apiSignature,
+    required this.exports,
+    required this.hasLibraryDirective,
+    required this.hasPartOfDirective,
+    required this.imports,
+    required this.lineStarts,
+    required this.partOfName,
+    required this.partOfUri,
+    required this.parts,
+  });
+
+  factory UnlinkedUnit.read(SummaryDataReader reader) {
+    return UnlinkedUnit(
+      apiSignature: reader.readUint8List(),
+      exports: reader.readTypedList(
+        () => UnlinkedNamespaceDirective.read(reader),
+      ),
+      hasLibraryDirective: reader.readBool(),
+      hasPartOfDirective: reader.readBool(),
+      imports: reader.readTypedList(
+        () => UnlinkedNamespaceDirective.read(reader),
+      ),
+      lineStarts: reader.readUInt30List(),
+      partOfName: reader.readOptionalStringUtf8(),
+      partOfUri: reader.readOptionalStringUtf8(),
+      parts: reader.readStringUtf8List(),
+    );
+  }
+
+  void write(BufferedSink sink) {
+    sink.writeUint8List(apiSignature);
+    sink.writeList<UnlinkedNamespaceDirective>(exports, (x) {
+      x.write(sink);
+    });
+    sink.writeBool(hasLibraryDirective);
+    sink.writeBool(hasPartOfDirective);
+    sink.writeList<UnlinkedNamespaceDirective>(imports, (x) {
+      x.write(sink);
+    });
+    sink.writeUint30List(lineStarts);
+    sink.writeOptionalStringUtf8(partOfName);
+    sink.writeOptionalStringUtf8(partOfUri);
+    sink.writeStringUtf8Iterable(parts);
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index e59c7f2..42602414 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -1830,277 +1830,6 @@
   String toString() => convert.json.encode(toJson());
 }
 
-class AnalysisDriverUnlinkedUnitBuilder extends Object
-    with _AnalysisDriverUnlinkedUnitMixin
-    implements idl.AnalysisDriverUnlinkedUnit {
-  List<String>? _definedClassMemberNames;
-  List<String>? _definedTopLevelNames;
-  List<String>? _referencedNames;
-  List<String>? _subtypedNames;
-  UnlinkedUnit2Builder? _unit2;
-
-  @override
-  List<String> get definedClassMemberNames =>
-      _definedClassMemberNames ??= <String>[];
-
-  /// List of class member names defined by the unit.
-  set definedClassMemberNames(List<String> value) {
-    this._definedClassMemberNames = value;
-  }
-
-  @override
-  List<String> get definedTopLevelNames => _definedTopLevelNames ??= <String>[];
-
-  /// List of top-level names defined by the unit.
-  set definedTopLevelNames(List<String> value) {
-    this._definedTopLevelNames = value;
-  }
-
-  @override
-  List<String> get referencedNames => _referencedNames ??= <String>[];
-
-  /// List of external names referenced by the unit.
-  set referencedNames(List<String> value) {
-    this._referencedNames = value;
-  }
-
-  @override
-  List<String> get subtypedNames => _subtypedNames ??= <String>[];
-
-  /// List of names which are used in `extends`, `with` or `implements` clauses
-  /// in the file. Import prefixes and type arguments are not included.
-  set subtypedNames(List<String> value) {
-    this._subtypedNames = value;
-  }
-
-  @override
-  UnlinkedUnit2Builder? get unit2 => _unit2;
-
-  /// Unlinked information for the unit.
-  set unit2(UnlinkedUnit2Builder? value) {
-    this._unit2 = value;
-  }
-
-  AnalysisDriverUnlinkedUnitBuilder(
-      {List<String>? definedClassMemberNames,
-      List<String>? definedTopLevelNames,
-      List<String>? referencedNames,
-      List<String>? subtypedNames,
-      UnlinkedUnit2Builder? unit2})
-      : _definedClassMemberNames = definedClassMemberNames,
-        _definedTopLevelNames = definedTopLevelNames,
-        _referencedNames = referencedNames,
-        _subtypedNames = subtypedNames,
-        _unit2 = unit2;
-
-  /// Flush [informative] data recursively.
-  void flushInformative() {
-    _unit2?.flushInformative();
-  }
-
-  /// Accumulate non-[informative] data into [signature].
-  void collectApiSignature(api_sig.ApiSignature signatureSink) {
-    var referencedNames = this._referencedNames;
-    if (referencedNames == null) {
-      signatureSink.addInt(0);
-    } else {
-      signatureSink.addInt(referencedNames.length);
-      for (var x in referencedNames) {
-        signatureSink.addString(x);
-      }
-    }
-    var definedTopLevelNames = this._definedTopLevelNames;
-    if (definedTopLevelNames == null) {
-      signatureSink.addInt(0);
-    } else {
-      signatureSink.addInt(definedTopLevelNames.length);
-      for (var x in definedTopLevelNames) {
-        signatureSink.addString(x);
-      }
-    }
-    var definedClassMemberNames = this._definedClassMemberNames;
-    if (definedClassMemberNames == null) {
-      signatureSink.addInt(0);
-    } else {
-      signatureSink.addInt(definedClassMemberNames.length);
-      for (var x in definedClassMemberNames) {
-        signatureSink.addString(x);
-      }
-    }
-    var subtypedNames = this._subtypedNames;
-    if (subtypedNames == null) {
-      signatureSink.addInt(0);
-    } else {
-      signatureSink.addInt(subtypedNames.length);
-      for (var x in subtypedNames) {
-        signatureSink.addString(x);
-      }
-    }
-    signatureSink.addBool(this._unit2 != null);
-    this._unit2?.collectApiSignature(signatureSink);
-  }
-
-  List<int> toBuffer() {
-    fb.Builder fbBuilder = fb.Builder();
-    return fbBuilder.finish(finish(fbBuilder), "ADUU");
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset? offset_definedClassMemberNames;
-    fb.Offset? offset_definedTopLevelNames;
-    fb.Offset? offset_referencedNames;
-    fb.Offset? offset_subtypedNames;
-    fb.Offset? offset_unit2;
-    var definedClassMemberNames = _definedClassMemberNames;
-    if (!(definedClassMemberNames == null || definedClassMemberNames.isEmpty)) {
-      offset_definedClassMemberNames = fbBuilder.writeList(
-          definedClassMemberNames
-              .map((b) => fbBuilder.writeString(b))
-              .toList());
-    }
-    var definedTopLevelNames = _definedTopLevelNames;
-    if (!(definedTopLevelNames == null || definedTopLevelNames.isEmpty)) {
-      offset_definedTopLevelNames = fbBuilder.writeList(
-          definedTopLevelNames.map((b) => fbBuilder.writeString(b)).toList());
-    }
-    var referencedNames = _referencedNames;
-    if (!(referencedNames == null || referencedNames.isEmpty)) {
-      offset_referencedNames = fbBuilder.writeList(
-          referencedNames.map((b) => fbBuilder.writeString(b)).toList());
-    }
-    var subtypedNames = _subtypedNames;
-    if (!(subtypedNames == null || subtypedNames.isEmpty)) {
-      offset_subtypedNames = fbBuilder.writeList(
-          subtypedNames.map((b) => fbBuilder.writeString(b)).toList());
-    }
-    var unit2 = _unit2;
-    if (unit2 != null) {
-      offset_unit2 = unit2.finish(fbBuilder);
-    }
-    fbBuilder.startTable();
-    if (offset_definedClassMemberNames != null) {
-      fbBuilder.addOffset(2, offset_definedClassMemberNames);
-    }
-    if (offset_definedTopLevelNames != null) {
-      fbBuilder.addOffset(1, offset_definedTopLevelNames);
-    }
-    if (offset_referencedNames != null) {
-      fbBuilder.addOffset(0, offset_referencedNames);
-    }
-    if (offset_subtypedNames != null) {
-      fbBuilder.addOffset(3, offset_subtypedNames);
-    }
-    if (offset_unit2 != null) {
-      fbBuilder.addOffset(4, offset_unit2);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-idl.AnalysisDriverUnlinkedUnit readAnalysisDriverUnlinkedUnit(
-    List<int> buffer) {
-  fb.BufferContext rootRef = fb.BufferContext.fromBytes(buffer);
-  return const _AnalysisDriverUnlinkedUnitReader().read(rootRef, 0);
-}
-
-class _AnalysisDriverUnlinkedUnitReader
-    extends fb.TableReader<_AnalysisDriverUnlinkedUnitImpl> {
-  const _AnalysisDriverUnlinkedUnitReader();
-
-  @override
-  _AnalysisDriverUnlinkedUnitImpl createObject(
-          fb.BufferContext bc, int offset) =>
-      _AnalysisDriverUnlinkedUnitImpl(bc, offset);
-}
-
-class _AnalysisDriverUnlinkedUnitImpl extends Object
-    with _AnalysisDriverUnlinkedUnitMixin
-    implements idl.AnalysisDriverUnlinkedUnit {
-  final fb.BufferContext _bc;
-  final int _bcOffset;
-
-  _AnalysisDriverUnlinkedUnitImpl(this._bc, this._bcOffset);
-
-  List<String>? _definedClassMemberNames;
-  List<String>? _definedTopLevelNames;
-  List<String>? _referencedNames;
-  List<String>? _subtypedNames;
-  idl.UnlinkedUnit2? _unit2;
-
-  @override
-  List<String> get definedClassMemberNames {
-    return _definedClassMemberNames ??=
-        const fb.ListReader<String>(fb.StringReader())
-            .vTableGet(_bc, _bcOffset, 2, const <String>[]);
-  }
-
-  @override
-  List<String> get definedTopLevelNames {
-    return _definedTopLevelNames ??=
-        const fb.ListReader<String>(fb.StringReader())
-            .vTableGet(_bc, _bcOffset, 1, const <String>[]);
-  }
-
-  @override
-  List<String> get referencedNames {
-    return _referencedNames ??= const fb.ListReader<String>(fb.StringReader())
-        .vTableGet(_bc, _bcOffset, 0, const <String>[]);
-  }
-
-  @override
-  List<String> get subtypedNames {
-    return _subtypedNames ??= const fb.ListReader<String>(fb.StringReader())
-        .vTableGet(_bc, _bcOffset, 3, const <String>[]);
-  }
-
-  @override
-  idl.UnlinkedUnit2? get unit2 {
-    return _unit2 ??=
-        const _UnlinkedUnit2Reader().vTableGetOrNull(_bc, _bcOffset, 4);
-  }
-}
-
-abstract class _AnalysisDriverUnlinkedUnitMixin
-    implements idl.AnalysisDriverUnlinkedUnit {
-  @override
-  Map<String, Object> toJson() {
-    Map<String, Object> _result = <String, Object>{};
-    var local_definedClassMemberNames = definedClassMemberNames;
-    if (local_definedClassMemberNames.isNotEmpty) {
-      _result["definedClassMemberNames"] = local_definedClassMemberNames;
-    }
-    var local_definedTopLevelNames = definedTopLevelNames;
-    if (local_definedTopLevelNames.isNotEmpty) {
-      _result["definedTopLevelNames"] = local_definedTopLevelNames;
-    }
-    var local_referencedNames = referencedNames;
-    if (local_referencedNames.isNotEmpty) {
-      _result["referencedNames"] = local_referencedNames;
-    }
-    var local_subtypedNames = subtypedNames;
-    if (local_subtypedNames.isNotEmpty) {
-      _result["subtypedNames"] = local_subtypedNames;
-    }
-    var local_unit2 = unit2;
-    if (local_unit2 != null) {
-      _result["unit2"] = local_unit2.toJson();
-    }
-    return _result;
-  }
-
-  @override
-  Map<String, Object?> toMap() => {
-        "definedClassMemberNames": definedClassMemberNames,
-        "definedTopLevelNames": definedTopLevelNames,
-        "referencedNames": referencedNames,
-        "subtypedNames": subtypedNames,
-        "unit2": unit2,
-      };
-
-  @override
-  String toString() => convert.json.encode(toJson());
-}
-
 class AvailableDeclarationBuilder extends Object
     with _AvailableDeclarationMixin
     implements idl.AvailableDeclaration {
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index 18b2f2a..67ee567 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -293,25 +293,6 @@
   usedNames:[uint] (id: 14);
 }
 
-/// Information about an unlinked unit.
-table AnalysisDriverUnlinkedUnit {
-  /// List of class member names defined by the unit.
-  definedClassMemberNames:[string] (id: 2);
-
-  /// List of top-level names defined by the unit.
-  definedTopLevelNames:[string] (id: 1);
-
-  /// List of external names referenced by the unit.
-  referencedNames:[string] (id: 0);
-
-  /// List of names which are used in `extends`, `with` or `implements` clauses
-  /// in the file. Import prefixes and type arguments are not included.
-  subtypedNames:[string] (id: 3);
-
-  /// Unlinked information for the unit.
-  unit2:UnlinkedUnit2 (id: 4);
-}
-
 /// Information about a single declaration.
 table AvailableDeclaration {
   children:[AvailableDeclaration] (id: 0);
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index d715b69..cb5eb79 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -259,34 +259,6 @@
   List<int> get usedNames;
 }
 
-/// Information about an unlinked unit.
-@TopLevel('ADUU')
-abstract class AnalysisDriverUnlinkedUnit extends base.SummaryClass {
-  factory AnalysisDriverUnlinkedUnit.fromBuffer(List<int> buffer) =>
-      generated.readAnalysisDriverUnlinkedUnit(buffer);
-
-  /// List of class member names defined by the unit.
-  @Id(2)
-  List<String> get definedClassMemberNames;
-
-  /// List of top-level names defined by the unit.
-  @Id(1)
-  List<String> get definedTopLevelNames;
-
-  /// List of external names referenced by the unit.
-  @Id(0)
-  List<String> get referencedNames;
-
-  /// List of names which are used in `extends`, `with` or `implements` clauses
-  /// in the file. Import prefixes and type arguments are not included.
-  @Id(3)
-  List<String> get subtypedNames;
-
-  /// Unlinked information for the unit.
-  @Id(4)
-  UnlinkedUnit2? get unit2;
-}
-
 /// Information about a single declaration.
 abstract class AvailableDeclaration extends base.SummaryClass {
   @Id(0)
diff --git a/pkg/analyzer/lib/src/summary2/data_reader.dart b/pkg/analyzer/lib/src/summary2/data_reader.dart
index a961d0d..f9986ed 100644
--- a/pkg/analyzer/lib/src/summary2/data_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/data_reader.dart
@@ -85,6 +85,20 @@
     return utf8.decode(bytes);
   }
 
+  List<String> readStringUtf8List() {
+    return readTypedList(readStringUtf8);
+  }
+
+  Set<String> readStringUtf8Set() {
+    var length = readUInt30();
+    var result = <String>{};
+    for (var i = 0; i < length; i++) {
+      var item = readStringUtf8();
+      result.add(item);
+    }
+    return result;
+  }
+
   List<T> readTypedList<T>(T Function() read) {
     var length = readUInt30();
     return List<T>.generate(length, (_) {
diff --git a/pkg/analyzer/lib/src/summary2/data_writer.dart b/pkg/analyzer/lib/src/summary2/data_writer.dart
index d7aedcd..3f560a8 100644
--- a/pkg/analyzer/lib/src/summary2/data_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/data_writer.dart
@@ -161,6 +161,13 @@
     writeUint8List(bytes as Uint8List);
   }
 
+  void writeStringUtf8Iterable(Iterable<String> items) {
+    writeUInt30(items.length);
+    for (var item in items) {
+      writeStringUtf8(item);
+    }
+  }
+
   @pragma("vm:prefer-inline")
   void writeUInt30(int value) {
     assert(value >= 0 && value >> 30 == 0);