[record_use] Generate syntax
diff --git a/pkgs/json_syntax_generator/lib/src/generator/property_generator.dart b/pkgs/json_syntax_generator/lib/src/generator/property_generator.dart
index b5094fc..c3fc90e 100644
--- a/pkgs/json_syntax_generator/lib/src/generator/property_generator.dart
+++ b/pkgs/json_syntax_generator/lib/src/generator/property_generator.dart
@@ -381,7 +381,8 @@
 List<String> $validateName() => _reader.$jsonValidate('$jsonKey');
 ''');
       default:
-        throw UnimplementedError(itemType.toString());
+      // TODO(dcharkes): Implement this.
+      // throw UnimplementedError(itemType.toString());
     }
   }
 
diff --git a/pkgs/json_syntax_generator/lib/src/parser/schema_analyzer.dart b/pkgs/json_syntax_generator/lib/src/parser/schema_analyzer.dart
index 54e11e3..b034131 100644
--- a/pkgs/json_syntax_generator/lib/src/parser/schema_analyzer.dart
+++ b/pkgs/json_syntax_generator/lib/src/parser/schema_analyzer.dart
@@ -372,13 +372,28 @@
               );
             }
           case SchemaType.object:
-            final typeName = items.className!;
-            _analyzeClass(items);
-            final classInfo = _classes[typeName]!;
-            dartType = ListDartType(
-              itemType: ClassDartType(classInfo: classInfo, isNullable: false),
-              isNullable: !required,
-            );
+            final typeName = items.className;
+            if (typeName != null) {
+              _analyzeClass(items);
+              final classInfo = _classes[typeName]!;
+              dartType = ListDartType(
+                itemType: ClassDartType(
+                  classInfo: classInfo,
+                  isNullable: false,
+                ),
+                isNullable: !required,
+              );
+            } else if (items.generateMapOf) {
+              dartType = const ListDartType(
+                itemType: MapDartType(
+                  valueType: ObjectDartType(isNullable: true),
+                  isNullable: true,
+                ),
+                isNullable: true,
+              );
+            } else {
+              throw UnimplementedError(itemType.toString());
+            }
           default:
             throw UnimplementedError(itemType.toString());
         }
diff --git a/pkgs/record_use/doc/schema/record_use.schema.json b/pkgs/record_use/doc/schema/record_use.schema.json
new file mode 100644
index 0000000..27ea9cc
--- /dev/null
+++ b/pkgs/record_use/doc/schema/record_use.schema.json
@@ -0,0 +1,220 @@
+{
+    "$schema": "http://json-schema.org/draft-07/schema#",
+    "$ref": "#/definitions/RecordedUses",
+    "definitions": {
+        "RecordedUses": {
+            "type": "object",
+            "properties": {
+                "metadata": {
+                    "type": "object",
+                    "properties": {
+                        "version": {
+                            "type": "string"
+                        },
+                        "comment": {
+                            "type": "string"
+                        }
+                    },
+                    "required": [
+                        "version",
+                        "comment"
+                    ]
+                },
+                "ids": {
+                    "type": "array",
+                    "items": {
+                        "$ref": "#/definitions/Identifier"
+                    }
+                },
+                "constants": {
+                    "type": "array",
+                    "items": {
+                        "$ref": "#/definitions/Constant"
+                    }
+                },
+                "usages": {
+                    "type": "array",
+                    "items": {
+                        "$ref": "#/definitions/Usage"
+                    }
+                }
+            },
+            "required": [
+                "metadata"
+            ]
+        },
+        "Identifier": {
+            "type": "object",
+            "properties": {
+                "uri": {
+                    "type": "string"
+                },
+                "name": {
+                    "type": "string"
+                },
+                "parent": {
+                    "type": "string"
+                }
+            },
+            "required": [
+                "uri",
+                "name"
+            ]
+        },
+        "Constant": {
+            "type": "object",
+            "properties": {
+                "type": {
+                    "type": "string",
+                    "enum": [
+                        "String",
+                        "bool",
+                        "int",
+                        "list",
+                        "map",
+                        "Null",
+                        "Instance"
+                    ]
+                },
+                "value": {
+                    "type": [
+                        "string",
+                        "boolean",
+                        "integer",
+                        "array",
+                        "object",
+                        "null"
+                    ]
+                }
+            },
+            "required": [
+                "type"
+            ]
+        },
+        "Instance": {
+            "type": "object",
+            "properties": {
+                "instanceConstant": {
+                    "type": "integer"
+                },
+                "loadingUnit": {
+                    "type": "string"
+                }
+            },
+            "required": [
+                "instanceConstant",
+                "loadingUnit"
+            ]
+        },
+        "Arguments": {
+            "type": "object",
+            "properties": {
+                "constant": {
+                    "type": "object",
+                    "properties": {
+                        "positional": {
+                            "type": "object",
+                            "additionalProperties": true
+                        },
+                        "named": {
+                            "type": "object",
+                            "additionalProperties": true
+                        }
+                    }
+                },
+                "nonConstant": {
+                    "type": "object",
+                    "properties": {
+                        "positional": {
+                            "type": "array",
+                            "items": {
+                                "type": "object",
+                                "additionalProperties": true
+                            }
+                        },
+                        "named": {
+                            "type": "array",
+                            "items": {
+                                "type": "object",
+                                "additionalProperties": true
+                            }
+                        }
+                    }
+                }
+            }
+        },
+        "Reference": {
+            "type": "object",
+            "properties": {
+                "arguments": {
+                    "$ref": "#/definitions/Arguments"
+                },
+                "loadingUnit": {
+                    "type": "string"
+                }
+            },
+            "required": [
+                "arguments",
+                "loadingUnit"
+            ]
+        },
+        "Usage": {
+            "type": "object",
+            "properties": {
+                "identifier": {
+                    "type": "integer"
+                },
+                "instances": {
+                    "type": "array",
+                    "items": {
+                        "$ref": "#/definitions/Instance"
+                    }
+                },
+                "calls": {
+                    "type": "array",
+                    "items": {
+                        "$ref": "#/definitions/Call"
+                    }
+                },
+                "loadingUnit": {
+                    "type": "string"
+                }
+            },
+            "required": [
+                "identifier"
+            ]
+        },
+        "Call": {
+            "type": "object",
+            "properties": {
+                "arguments": {
+                    "$ref": "#/definitions/Arguments"
+                },
+                "loadingUnit": {
+                    "type": "string"
+                },
+                "definition": {
+                    "type": "object",
+                    "properties": {
+                        "id": {
+                            "type": "integer"
+                        },
+                        "loadingUnit": {
+                            "type": "string"
+                        }
+                    },
+                    "required": [
+                        "id",
+                        "loadingUnit"
+                    ]
+                },
+                "references": {
+                    "type": "array",
+                    "items": {
+                        "$ref": "#/definitions/Reference"
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/pkgs/record_use/lib/src/syntax.g.dart b/pkgs/record_use/lib/src/syntax.g.dart
new file mode 100644
index 0000000..7ebc52f
--- /dev/null
+++ b/pkgs/record_use/lib/src/syntax.g.dart
@@ -0,0 +1,991 @@
+// Copyright (c) 2025, 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.
+
+// This file is generated, do not edit.
+// File generated by pkg/record_use/tool/generate_syntax.dart.
+
+// ignore_for_file: unused_element
+
+import 'dart:io';
+
+class Arguments {
+  final Map<String, Object?> json;
+
+  final List<Object> path;
+
+  JsonReader get _reader => JsonReader(json, path);
+
+  Arguments.fromJson(this.json, {this.path = const []});
+
+  Arguments({required Constant? constant, required NonConstant? nonConstant})
+    : json = {},
+      path = const [] {
+    _constant = constant;
+    _nonConstant = nonConstant;
+    json.sortOnKey();
+  }
+
+  Constant? get constant {
+    final jsonValue = _reader.optionalMap('constant');
+    if (jsonValue == null) return null;
+    return Constant.fromJson(jsonValue, path: [...path, 'constant']);
+  }
+
+  set _constant(Constant? value) {
+    json.setOrRemove('constant', value?.json);
+  }
+
+  List<String> _validateConstant() {
+    final mapErrors = _reader.validate<Map<String, Object?>?>('constant');
+    if (mapErrors.isNotEmpty) {
+      return mapErrors;
+    }
+    return constant?.validate() ?? [];
+  }
+
+  NonConstant? get nonConstant {
+    final jsonValue = _reader.optionalMap('nonConstant');
+    if (jsonValue == null) return null;
+    return NonConstant.fromJson(jsonValue, path: [...path, 'nonConstant']);
+  }
+
+  set _nonConstant(NonConstant? value) {
+    json.setOrRemove('nonConstant', value?.json);
+  }
+
+  List<String> _validateNonConstant() {
+    final mapErrors = _reader.validate<Map<String, Object?>?>('nonConstant');
+    if (mapErrors.isNotEmpty) {
+      return mapErrors;
+    }
+    return nonConstant?.validate() ?? [];
+  }
+
+  List<String> validate() => [
+    ..._validateConstant(),
+    ..._validateNonConstant(),
+  ];
+
+  @override
+  String toString() => 'Arguments($json)';
+}
+
+class Call {
+  final Map<String, Object?> json;
+
+  final List<Object> path;
+
+  JsonReader get _reader => JsonReader(json, path);
+
+  Call.fromJson(this.json, {this.path = const []});
+
+  Call({
+    required Arguments? arguments,
+    required Definition? definition,
+    required String? loadingUnit,
+    required List<Reference>? references,
+  }) : json = {},
+       path = const [] {
+    _arguments = arguments;
+    _definition = definition;
+    _loadingUnit = loadingUnit;
+    _references = references;
+    json.sortOnKey();
+  }
+
+  Arguments? get arguments {
+    final jsonValue = _reader.optionalMap('arguments');
+    if (jsonValue == null) return null;
+    return Arguments.fromJson(jsonValue, path: [...path, 'arguments']);
+  }
+
+  set _arguments(Arguments? value) {
+    json.setOrRemove('arguments', value?.json);
+  }
+
+  List<String> _validateArguments() {
+    final mapErrors = _reader.validate<Map<String, Object?>?>('arguments');
+    if (mapErrors.isNotEmpty) {
+      return mapErrors;
+    }
+    return arguments?.validate() ?? [];
+  }
+
+  Definition? get definition {
+    final jsonValue = _reader.optionalMap('definition');
+    if (jsonValue == null) return null;
+    return Definition.fromJson(jsonValue, path: [...path, 'definition']);
+  }
+
+  set _definition(Definition? value) {
+    json.setOrRemove('definition', value?.json);
+  }
+
+  List<String> _validateDefinition() {
+    final mapErrors = _reader.validate<Map<String, Object?>?>('definition');
+    if (mapErrors.isNotEmpty) {
+      return mapErrors;
+    }
+    return definition?.validate() ?? [];
+  }
+
+  String? get loadingUnit => _reader.get<String?>('loadingUnit');
+
+  set _loadingUnit(String? value) {
+    json.setOrRemove('loadingUnit', value);
+  }
+
+  List<String> _validateLoadingUnit() =>
+      _reader.validate<String?>('loadingUnit');
+
+  List<Reference>? get references {
+    final jsonValue = _reader.optionalList('references');
+    if (jsonValue == null) return null;
+    return [
+      for (final (index, element) in jsonValue.indexed)
+        Reference.fromJson(
+          element as Map<String, Object?>,
+          path: [...path, 'references', index],
+        ),
+    ];
+  }
+
+  set _references(List<Reference>? value) {
+    if (value == null) {
+      json.remove('references');
+    } else {
+      json['references'] = [for (final item in value) item.json];
+    }
+  }
+
+  List<String> _validateReferences() {
+    final listErrors = _reader.validateOptionalList<Map<String, Object?>>(
+      'references',
+    );
+    if (listErrors.isNotEmpty) {
+      return listErrors;
+    }
+    final elements = references;
+    if (elements == null) {
+      return [];
+    }
+    return [for (final element in elements) ...element.validate()];
+  }
+
+  List<String> validate() => [
+    ..._validateArguments(),
+    ..._validateDefinition(),
+    ..._validateLoadingUnit(),
+    ..._validateReferences(),
+  ];
+
+  @override
+  String toString() => 'Call($json)';
+}
+
+class Constant {
+  final Map<String, Object?> json;
+
+  final List<Object> path;
+
+  JsonReader get _reader => JsonReader(json, path);
+
+  Constant.fromJson(this.json, {this.path = const []});
+
+  Constant({
+    required Map<String, Object?>? named,
+    required Map<String, Object?>? positional,
+  }) : json = {},
+       path = const [] {
+    _named = named;
+    _positional = positional;
+    json.sortOnKey();
+  }
+
+  Map<String, Object?>? get named => _reader.optionalMap('named');
+
+  set _named(Map<String, Object?>? value) {
+    json.setOrRemove('named', value);
+  }
+
+  List<String> _validateNamed() => _reader.validateOptionalMap('named');
+
+  Map<String, Object?>? get positional => _reader.optionalMap('positional');
+
+  set _positional(Map<String, Object?>? value) {
+    json.setOrRemove('positional', value);
+  }
+
+  List<String> _validatePositional() =>
+      _reader.validateOptionalMap('positional');
+
+  List<String> validate() => [..._validateNamed(), ..._validatePositional()];
+
+  @override
+  String toString() => 'Constant($json)';
+}
+
+class Definition {
+  final Map<String, Object?> json;
+
+  final List<Object> path;
+
+  JsonReader get _reader => JsonReader(json, path);
+
+  Definition.fromJson(this.json, {this.path = const []});
+
+  Definition({required int id, required String loadingUnit})
+    : json = {},
+      path = const [] {
+    _id = id;
+    _loadingUnit = loadingUnit;
+    json.sortOnKey();
+  }
+
+  int get id => _reader.get<int>('id');
+
+  set _id(int value) {
+    json.setOrRemove('id', value);
+  }
+
+  List<String> _validateId() => _reader.validate<int>('id');
+
+  String get loadingUnit => _reader.get<String>('loadingUnit');
+
+  set _loadingUnit(String value) {
+    json.setOrRemove('loadingUnit', value);
+  }
+
+  List<String> _validateLoadingUnit() =>
+      _reader.validate<String>('loadingUnit');
+
+  List<String> validate() => [..._validateId(), ..._validateLoadingUnit()];
+
+  @override
+  String toString() => 'Definition($json)';
+}
+
+class Identifier {
+  final Map<String, Object?> json;
+
+  final List<Object> path;
+
+  JsonReader get _reader => JsonReader(json, path);
+
+  Identifier.fromJson(this.json, {this.path = const []});
+
+  Identifier({
+    required String name,
+    required String? parent,
+    required String uri,
+  }) : json = {},
+       path = const [] {
+    _name = name;
+    _parent = parent;
+    _uri = uri;
+    json.sortOnKey();
+  }
+
+  String get name => _reader.get<String>('name');
+
+  set _name(String value) {
+    json.setOrRemove('name', value);
+  }
+
+  List<String> _validateName() => _reader.validate<String>('name');
+
+  String? get parent => _reader.get<String?>('parent');
+
+  set _parent(String? value) {
+    json.setOrRemove('parent', value);
+  }
+
+  List<String> _validateParent() => _reader.validate<String?>('parent');
+
+  String get uri => _reader.get<String>('uri');
+
+  set _uri(String value) {
+    json.setOrRemove('uri', value);
+  }
+
+  List<String> _validateUri() => _reader.validate<String>('uri');
+
+  List<String> validate() => [
+    ..._validateName(),
+    ..._validateParent(),
+    ..._validateUri(),
+  ];
+
+  @override
+  String toString() => 'Identifier($json)';
+}
+
+class Instance {
+  final Map<String, Object?> json;
+
+  final List<Object> path;
+
+  JsonReader get _reader => JsonReader(json, path);
+
+  Instance.fromJson(this.json, {this.path = const []});
+
+  Instance({required int instanceConstant, required String loadingUnit})
+    : json = {},
+      path = const [] {
+    _instanceConstant = instanceConstant;
+    _loadingUnit = loadingUnit;
+    json.sortOnKey();
+  }
+
+  int get instanceConstant => _reader.get<int>('instanceConstant');
+
+  set _instanceConstant(int value) {
+    json.setOrRemove('instanceConstant', value);
+  }
+
+  List<String> _validateInstanceConstant() =>
+      _reader.validate<int>('instanceConstant');
+
+  String get loadingUnit => _reader.get<String>('loadingUnit');
+
+  set _loadingUnit(String value) {
+    json.setOrRemove('loadingUnit', value);
+  }
+
+  List<String> _validateLoadingUnit() =>
+      _reader.validate<String>('loadingUnit');
+
+  List<String> validate() => [
+    ..._validateInstanceConstant(),
+    ..._validateLoadingUnit(),
+  ];
+
+  @override
+  String toString() => 'Instance($json)';
+}
+
+class Metadata {
+  final Map<String, Object?> json;
+
+  final List<Object> path;
+
+  JsonReader get _reader => JsonReader(json, path);
+
+  Metadata.fromJson(this.json, {this.path = const []});
+
+  Metadata({required String comment, required String version})
+    : json = {},
+      path = const [] {
+    _comment = comment;
+    _version = version;
+    json.sortOnKey();
+  }
+
+  String get comment => _reader.get<String>('comment');
+
+  set _comment(String value) {
+    json.setOrRemove('comment', value);
+  }
+
+  List<String> _validateComment() => _reader.validate<String>('comment');
+
+  String get version => _reader.get<String>('version');
+
+  set _version(String value) {
+    json.setOrRemove('version', value);
+  }
+
+  List<String> _validateVersion() => _reader.validate<String>('version');
+
+  List<String> validate() => [..._validateComment(), ..._validateVersion()];
+
+  @override
+  String toString() => 'Metadata($json)';
+}
+
+class NonConstant {
+  final Map<String, Object?> json;
+
+  final List<Object> path;
+
+  JsonReader get _reader => JsonReader(json, path);
+
+  NonConstant.fromJson(this.json, {this.path = const []});
+
+  NonConstant({
+    required List<Map<String, Object?>?>? named,
+    required List<Map<String, Object?>?>? positional,
+  }) : json = {},
+       path = const [] {
+    _named = named;
+    _positional = positional;
+    json.sortOnKey();
+  }
+
+  List<String> validate() => [..._validateNamed(), ..._validatePositional()];
+
+  @override
+  String toString() => 'NonConstant($json)';
+}
+
+class RecordedUses {
+  final Map<String, Object?> json;
+
+  final List<Object> path;
+
+  JsonReader get _reader => JsonReader(json, path);
+
+  RecordedUses.fromJson(this.json, {this.path = const []});
+
+  RecordedUses({
+    required List<Constant>? constants,
+    required List<Identifier>? ids,
+    required Metadata metadata,
+    required List<Usage>? usages,
+  }) : json = {},
+       path = const [] {
+    _constants = constants;
+    _ids = ids;
+    _metadata = metadata;
+    _usages = usages;
+    json.sortOnKey();
+  }
+
+  List<Constant>? get constants {
+    final jsonValue = _reader.optionalList('constants');
+    if (jsonValue == null) return null;
+    return [
+      for (final (index, element) in jsonValue.indexed)
+        Constant.fromJson(
+          element as Map<String, Object?>,
+          path: [...path, 'constants', index],
+        ),
+    ];
+  }
+
+  set _constants(List<Constant>? value) {
+    if (value == null) {
+      json.remove('constants');
+    } else {
+      json['constants'] = [for (final item in value) item.json];
+    }
+  }
+
+  List<String> _validateConstants() {
+    final listErrors = _reader.validateOptionalList<Map<String, Object?>>(
+      'constants',
+    );
+    if (listErrors.isNotEmpty) {
+      return listErrors;
+    }
+    final elements = constants;
+    if (elements == null) {
+      return [];
+    }
+    return [for (final element in elements) ...element.validate()];
+  }
+
+  List<Identifier>? get ids {
+    final jsonValue = _reader.optionalList('ids');
+    if (jsonValue == null) return null;
+    return [
+      for (final (index, element) in jsonValue.indexed)
+        Identifier.fromJson(
+          element as Map<String, Object?>,
+          path: [...path, 'ids', index],
+        ),
+    ];
+  }
+
+  set _ids(List<Identifier>? value) {
+    if (value == null) {
+      json.remove('ids');
+    } else {
+      json['ids'] = [for (final item in value) item.json];
+    }
+  }
+
+  List<String> _validateIds() {
+    final listErrors = _reader.validateOptionalList<Map<String, Object?>>(
+      'ids',
+    );
+    if (listErrors.isNotEmpty) {
+      return listErrors;
+    }
+    final elements = ids;
+    if (elements == null) {
+      return [];
+    }
+    return [for (final element in elements) ...element.validate()];
+  }
+
+  Metadata get metadata {
+    final jsonValue = _reader.map$('metadata');
+    return Metadata.fromJson(jsonValue, path: [...path, 'metadata']);
+  }
+
+  set _metadata(Metadata value) {
+    json['metadata'] = value.json;
+  }
+
+  List<String> _validateMetadata() {
+    final mapErrors = _reader.validate<Map<String, Object?>>('metadata');
+    if (mapErrors.isNotEmpty) {
+      return mapErrors;
+    }
+    return metadata.validate();
+  }
+
+  List<Usage>? get usages {
+    final jsonValue = _reader.optionalList('usages');
+    if (jsonValue == null) return null;
+    return [
+      for (final (index, element) in jsonValue.indexed)
+        Usage.fromJson(
+          element as Map<String, Object?>,
+          path: [...path, 'usages', index],
+        ),
+    ];
+  }
+
+  set _usages(List<Usage>? value) {
+    if (value == null) {
+      json.remove('usages');
+    } else {
+      json['usages'] = [for (final item in value) item.json];
+    }
+  }
+
+  List<String> _validateUsages() {
+    final listErrors = _reader.validateOptionalList<Map<String, Object?>>(
+      'usages',
+    );
+    if (listErrors.isNotEmpty) {
+      return listErrors;
+    }
+    final elements = usages;
+    if (elements == null) {
+      return [];
+    }
+    return [for (final element in elements) ...element.validate()];
+  }
+
+  List<String> validate() => [
+    ..._validateConstants(),
+    ..._validateIds(),
+    ..._validateMetadata(),
+    ..._validateUsages(),
+  ];
+
+  @override
+  String toString() => 'RecordedUses($json)';
+}
+
+class Reference {
+  final Map<String, Object?> json;
+
+  final List<Object> path;
+
+  JsonReader get _reader => JsonReader(json, path);
+
+  Reference.fromJson(this.json, {this.path = const []});
+
+  Reference({required Arguments arguments, required String loadingUnit})
+    : json = {},
+      path = const [] {
+    _arguments = arguments;
+    _loadingUnit = loadingUnit;
+    json.sortOnKey();
+  }
+
+  Arguments get arguments {
+    final jsonValue = _reader.map$('arguments');
+    return Arguments.fromJson(jsonValue, path: [...path, 'arguments']);
+  }
+
+  set _arguments(Arguments value) {
+    json['arguments'] = value.json;
+  }
+
+  List<String> _validateArguments() {
+    final mapErrors = _reader.validate<Map<String, Object?>>('arguments');
+    if (mapErrors.isNotEmpty) {
+      return mapErrors;
+    }
+    return arguments.validate();
+  }
+
+  String get loadingUnit => _reader.get<String>('loadingUnit');
+
+  set _loadingUnit(String value) {
+    json.setOrRemove('loadingUnit', value);
+  }
+
+  List<String> _validateLoadingUnit() =>
+      _reader.validate<String>('loadingUnit');
+
+  List<String> validate() => [
+    ..._validateArguments(),
+    ..._validateLoadingUnit(),
+  ];
+
+  @override
+  String toString() => 'Reference($json)';
+}
+
+class Usage {
+  final Map<String, Object?> json;
+
+  final List<Object> path;
+
+  JsonReader get _reader => JsonReader(json, path);
+
+  Usage.fromJson(this.json, {this.path = const []});
+
+  Usage({
+    required List<Call>? calls,
+    required int identifier,
+    required List<Instance>? instances,
+    required String? loadingUnit,
+  }) : json = {},
+       path = const [] {
+    _calls = calls;
+    _identifier = identifier;
+    _instances = instances;
+    _loadingUnit = loadingUnit;
+    json.sortOnKey();
+  }
+
+  List<Call>? get calls {
+    final jsonValue = _reader.optionalList('calls');
+    if (jsonValue == null) return null;
+    return [
+      for (final (index, element) in jsonValue.indexed)
+        Call.fromJson(
+          element as Map<String, Object?>,
+          path: [...path, 'calls', index],
+        ),
+    ];
+  }
+
+  set _calls(List<Call>? value) {
+    if (value == null) {
+      json.remove('calls');
+    } else {
+      json['calls'] = [for (final item in value) item.json];
+    }
+  }
+
+  List<String> _validateCalls() {
+    final listErrors = _reader.validateOptionalList<Map<String, Object?>>(
+      'calls',
+    );
+    if (listErrors.isNotEmpty) {
+      return listErrors;
+    }
+    final elements = calls;
+    if (elements == null) {
+      return [];
+    }
+    return [for (final element in elements) ...element.validate()];
+  }
+
+  int get identifier => _reader.get<int>('identifier');
+
+  set _identifier(int value) {
+    json.setOrRemove('identifier', value);
+  }
+
+  List<String> _validateIdentifier() => _reader.validate<int>('identifier');
+
+  List<Instance>? get instances {
+    final jsonValue = _reader.optionalList('instances');
+    if (jsonValue == null) return null;
+    return [
+      for (final (index, element) in jsonValue.indexed)
+        Instance.fromJson(
+          element as Map<String, Object?>,
+          path: [...path, 'instances', index],
+        ),
+    ];
+  }
+
+  set _instances(List<Instance>? value) {
+    if (value == null) {
+      json.remove('instances');
+    } else {
+      json['instances'] = [for (final item in value) item.json];
+    }
+  }
+
+  List<String> _validateInstances() {
+    final listErrors = _reader.validateOptionalList<Map<String, Object?>>(
+      'instances',
+    );
+    if (listErrors.isNotEmpty) {
+      return listErrors;
+    }
+    final elements = instances;
+    if (elements == null) {
+      return [];
+    }
+    return [for (final element in elements) ...element.validate()];
+  }
+
+  String? get loadingUnit => _reader.get<String?>('loadingUnit');
+
+  set _loadingUnit(String? value) {
+    json.setOrRemove('loadingUnit', value);
+  }
+
+  List<String> _validateLoadingUnit() =>
+      _reader.validate<String?>('loadingUnit');
+
+  List<String> validate() => [
+    ..._validateCalls(),
+    ..._validateIdentifier(),
+    ..._validateInstances(),
+    ..._validateLoadingUnit(),
+  ];
+
+  @override
+  String toString() => 'Usage($json)';
+}
+
+class JsonReader {
+  /// The JSON Object this reader is reading.
+  final Map<String, Object?> json;
+
+  /// The path traversed by readers of the surrounding JSON.
+  ///
+  /// Contains [String] property keys and [int] indices.
+  ///
+  /// This is used to give more precise error messages.
+  final List<Object> path;
+
+  JsonReader(this.json, this.path);
+
+  T get<T extends Object?>(String key) {
+    final value = json[key];
+    if (value is T) return value;
+    throwFormatException(value, T, [key]);
+  }
+
+  List<String> validate<T extends Object?>(String key) {
+    final value = json[key];
+    if (value is T) return [];
+    return [
+      errorString(value, T, [key]),
+    ];
+  }
+
+  List<T> list<T extends Object?>(String key) =>
+      _castList<T>(get<List<Object?>>(key), key);
+
+  List<String> validateList<T extends Object?>(String key) {
+    final listErrors = validate<List<Object?>>(key);
+    if (listErrors.isNotEmpty) {
+      return listErrors;
+    }
+    return _validateListElements(get<List<Object?>>(key), key);
+  }
+
+  List<T>? optionalList<T extends Object?>(String key) =>
+      switch (get<List<Object?>?>(key)?.cast<T>()) {
+        null => null,
+        final l => _castList<T>(l, key),
+      };
+
+  List<String> validateOptionalList<T extends Object?>(String key) {
+    final listErrors = validate<List<Object?>?>(key);
+    if (listErrors.isNotEmpty) {
+      return listErrors;
+    }
+    final list = get<List<Object?>?>(key);
+    if (list == null) {
+      return [];
+    }
+    return _validateListElements(list, key);
+  }
+
+  /// [List.cast] but with [FormatException]s.
+  List<T> _castList<T extends Object?>(List<Object?> list, String key) {
+    for (final (index, value) in list.indexed) {
+      if (value is! T) {
+        throwFormatException(value, T, [key, index]);
+      }
+    }
+    return list.cast();
+  }
+
+  List<String> _validateListElements<T extends Object?>(
+    List<Object?> list,
+    String key,
+  ) {
+    final result = <String>[];
+    for (final (index, value) in list.indexed) {
+      if (value is! T) {
+        result.add(errorString(value, T, [key, index]));
+      }
+    }
+    return result;
+  }
+
+  Map<String, T> map$<T extends Object?>(String key) =>
+      _castMap<T>(get<Map<String, Object?>>(key), key);
+
+  List<String> validateMap<T extends Object?>(String key) {
+    final mapErrors = validate<Map<String, Object?>>(key);
+    if (mapErrors.isNotEmpty) {
+      return mapErrors;
+    }
+    return _validateMapElements<T>(get<Map<String, Object?>>(key), key);
+  }
+
+  Map<String, T>? optionalMap<T extends Object?>(String key) =>
+      switch (get<Map<String, Object?>?>(key)) {
+        null => null,
+        final m => _castMap<T>(m, key),
+      };
+
+  List<String> validateOptionalMap<T extends Object?>(String key) {
+    final mapErrors = validate<Map<String, Object?>?>(key);
+    if (mapErrors.isNotEmpty) {
+      return mapErrors;
+    }
+    final map = get<Map<String, Object?>?>(key);
+    if (map == null) {
+      return [];
+    }
+    return _validateMapElements<T>(map, key);
+  }
+
+  /// [Map.cast] but with [FormatException]s.
+  Map<String, T> _castMap<T extends Object?>(
+    Map<String, Object?> map_,
+    String parentKey,
+  ) {
+    for (final MapEntry(:key, :value) in map_.entries) {
+      if (value is! T) {
+        throwFormatException(value, T, [parentKey, key]);
+      }
+    }
+    return map_.cast();
+  }
+
+  List<String> _validateMapElements<T extends Object?>(
+    Map<String, Object?> map_,
+    String parentKey,
+  ) {
+    final result = <String>[];
+    for (final MapEntry(:key, :value) in map_.entries) {
+      if (value is! T) {
+        result.add(errorString(value, T, [parentKey, key]));
+      }
+    }
+    return result;
+  }
+
+  List<String>? optionalStringList(String key) => optionalList<String>(key);
+
+  List<String> validateOptionalStringList(String key) =>
+      validateOptionalList<String>(key);
+
+  List<String> stringList(String key) => list<String>(key);
+
+  List<String> validateStringList(String key) => validateList<String>(key);
+
+  Uri path$(String key) => _fileSystemPathToUri(get<String>(key));
+
+  List<String> validatePath(String key) => validate<String>(key);
+
+  Uri? optionalPath(String key) {
+    final value = get<String?>(key);
+    if (value == null) return null;
+    return _fileSystemPathToUri(value);
+  }
+
+  List<String> validateOptionalPath(String key) => validate<String?>(key);
+
+  List<Uri>? optionalPathList(String key) {
+    final strings = optionalStringList(key);
+    if (strings == null) {
+      return null;
+    }
+    return [for (final string in strings) _fileSystemPathToUri(string)];
+  }
+
+  List<String> validateOptionalPathList(String key) =>
+      validateOptionalStringList(key);
+
+  static Uri _fileSystemPathToUri(String path) {
+    if (path.endsWith(Platform.pathSeparator)) {
+      return Uri.directory(path);
+    }
+    return Uri.file(path);
+  }
+
+  String _jsonPathToString(List<Object> pathEnding) =>
+      [...path, ...pathEnding].join('.');
+
+  Never throwFormatException(
+    Object? value,
+    Type expectedType,
+    List<Object> pathExtension,
+  ) {
+    throw FormatException(errorString(value, expectedType, pathExtension));
+  }
+
+  String errorString(
+    Object? value,
+    Type expectedType,
+    List<Object> pathExtension,
+  ) {
+    final pathString = _jsonPathToString(pathExtension);
+    if (value == null) {
+      return "No value was provided for '$pathString'."
+          ' Expected a $expectedType.';
+    }
+    return "Unexpected value '$value' (${value.runtimeType}) for '$pathString'."
+        ' Expected a $expectedType.';
+  }
+
+  /// Traverses a JSON path, returns `null` if the path cannot be traversed.
+  Object? tryTraverse(List<String> path) {
+    Object? json = this.json;
+    for (final key in path) {
+      if (json is! Map<String, Object?>) {
+        return null;
+      }
+      json = json[key];
+    }
+    return json;
+  }
+}
+
+extension on Map<String, Object?> {
+  void setOrRemove(String key, Object? value) {
+    if (value == null) {
+      remove(key);
+    } else {
+      this[key] = value;
+    }
+  }
+}
+
+extension on List<Uri> {
+  List<String> toJson() => [for (final uri in this) uri.toFilePath()];
+}
+
+extension<K extends Comparable<K>, V extends Object?> on Map<K, V> {
+  void sortOnKey() {
+    final result = <K, V>{};
+    final keysSorted = keys.toList()..sort();
+    for (final key in keysSorted) {
+      result[key] = this[key] as V;
+    }
+    clear();
+    addAll(result);
+  }
+}
diff --git a/pkgs/record_use/lib/src/syntax.g.txt b/pkgs/record_use/lib/src/syntax.g.txt
new file mode 100644
index 0000000..f43a89c
--- /dev/null
+++ b/pkgs/record_use/lib/src/syntax.g.txt
@@ -0,0 +1,339 @@
+SchemaInfo(
+  classes: [
+    NormalClassInfo(
+      name: Arguments,
+      superclassName: null,
+      subclassNames: [  ],
+      properties: [
+        PropertyInfo(
+          name: constant,
+          jsonKey: constant,
+          type: Constant?,
+          isOverride: false,
+          setterPrivate: true,
+        ),
+        PropertyInfo(
+          name: nonConstant,
+          jsonKey: nonConstant,
+          type: NonConstant?,
+          isOverride: false,
+          setterPrivate: true,
+        )
+      ],
+      taggedUnionProperty: null,
+      taggedUnionValue: null,
+      extraValidation: [
+    
+      ],
+    ),
+    NormalClassInfo(
+      name: Call,
+      superclassName: null,
+      subclassNames: [  ],
+      properties: [
+        PropertyInfo(
+          name: arguments,
+          jsonKey: arguments,
+          type: Arguments?,
+          isOverride: false,
+          setterPrivate: true,
+        ),
+        PropertyInfo(
+          name: definition,
+          jsonKey: definition,
+          type: Definition?,
+          isOverride: false,
+          setterPrivate: true,
+        ),
+        PropertyInfo(
+          name: loadingUnit,
+          jsonKey: loadingUnit,
+          type: String?,
+          isOverride: false,
+          setterPrivate: true,
+        ),
+        PropertyInfo(
+          name: references,
+          jsonKey: references,
+          type: List<Reference>?,
+          isOverride: false,
+          setterPrivate: true,
+        )
+      ],
+      taggedUnionProperty: null,
+      taggedUnionValue: null,
+      extraValidation: [
+    
+      ],
+    ),
+    NormalClassInfo(
+      name: Constant,
+      superclassName: null,
+      subclassNames: [  ],
+      properties: [
+        PropertyInfo(
+          name: named,
+          jsonKey: named,
+          type: Map<String, Object?>?,
+          isOverride: false,
+          setterPrivate: true,
+        ),
+        PropertyInfo(
+          name: positional,
+          jsonKey: positional,
+          type: Map<String, Object?>?,
+          isOverride: false,
+          setterPrivate: true,
+        )
+      ],
+      taggedUnionProperty: null,
+      taggedUnionValue: null,
+      extraValidation: [
+    
+      ],
+    ),
+    NormalClassInfo(
+      name: Definition,
+      superclassName: null,
+      subclassNames: [  ],
+      properties: [
+        PropertyInfo(
+          name: id,
+          jsonKey: id,
+          type: int,
+          isOverride: false,
+          setterPrivate: true,
+        ),
+        PropertyInfo(
+          name: loadingUnit,
+          jsonKey: loadingUnit,
+          type: String,
+          isOverride: false,
+          setterPrivate: true,
+        )
+      ],
+      taggedUnionProperty: null,
+      taggedUnionValue: null,
+      extraValidation: [
+    
+      ],
+    ),
+    NormalClassInfo(
+      name: Identifier,
+      superclassName: null,
+      subclassNames: [  ],
+      properties: [
+        PropertyInfo(
+          name: name,
+          jsonKey: name,
+          type: String,
+          isOverride: false,
+          setterPrivate: true,
+        ),
+        PropertyInfo(
+          name: parent,
+          jsonKey: parent,
+          type: String?,
+          isOverride: false,
+          setterPrivate: true,
+        ),
+        PropertyInfo(
+          name: uri,
+          jsonKey: uri,
+          type: String,
+          isOverride: false,
+          setterPrivate: true,
+        )
+      ],
+      taggedUnionProperty: null,
+      taggedUnionValue: null,
+      extraValidation: [
+    
+      ],
+    ),
+    NormalClassInfo(
+      name: Instance,
+      superclassName: null,
+      subclassNames: [  ],
+      properties: [
+        PropertyInfo(
+          name: instanceConstant,
+          jsonKey: instanceConstant,
+          type: int,
+          isOverride: false,
+          setterPrivate: true,
+        ),
+        PropertyInfo(
+          name: loadingUnit,
+          jsonKey: loadingUnit,
+          type: String,
+          isOverride: false,
+          setterPrivate: true,
+        )
+      ],
+      taggedUnionProperty: null,
+      taggedUnionValue: null,
+      extraValidation: [
+    
+      ],
+    ),
+    NormalClassInfo(
+      name: Metadata,
+      superclassName: null,
+      subclassNames: [  ],
+      properties: [
+        PropertyInfo(
+          name: comment,
+          jsonKey: comment,
+          type: String,
+          isOverride: false,
+          setterPrivate: true,
+        ),
+        PropertyInfo(
+          name: version,
+          jsonKey: version,
+          type: String,
+          isOverride: false,
+          setterPrivate: true,
+        )
+      ],
+      taggedUnionProperty: null,
+      taggedUnionValue: null,
+      extraValidation: [
+    
+      ],
+    ),
+    NormalClassInfo(
+      name: NonConstant,
+      superclassName: null,
+      subclassNames: [  ],
+      properties: [
+        PropertyInfo(
+          name: named,
+          jsonKey: named,
+          type: List<Map<String, Object?>?>?,
+          isOverride: false,
+          setterPrivate: true,
+        ),
+        PropertyInfo(
+          name: positional,
+          jsonKey: positional,
+          type: List<Map<String, Object?>?>?,
+          isOverride: false,
+          setterPrivate: true,
+        )
+      ],
+      taggedUnionProperty: null,
+      taggedUnionValue: null,
+      extraValidation: [
+    
+      ],
+    ),
+    NormalClassInfo(
+      name: RecordedUses,
+      superclassName: null,
+      subclassNames: [  ],
+      properties: [
+        PropertyInfo(
+          name: constants,
+          jsonKey: constants,
+          type: List<Constant>?,
+          isOverride: false,
+          setterPrivate: true,
+        ),
+        PropertyInfo(
+          name: ids,
+          jsonKey: ids,
+          type: List<Identifier>?,
+          isOverride: false,
+          setterPrivate: true,
+        ),
+        PropertyInfo(
+          name: metadata,
+          jsonKey: metadata,
+          type: Metadata,
+          isOverride: false,
+          setterPrivate: true,
+        ),
+        PropertyInfo(
+          name: usages,
+          jsonKey: usages,
+          type: List<Usage>?,
+          isOverride: false,
+          setterPrivate: true,
+        )
+      ],
+      taggedUnionProperty: null,
+      taggedUnionValue: null,
+      extraValidation: [
+    
+      ],
+    ),
+    NormalClassInfo(
+      name: Reference,
+      superclassName: null,
+      subclassNames: [  ],
+      properties: [
+        PropertyInfo(
+          name: arguments,
+          jsonKey: arguments,
+          type: Arguments,
+          isOverride: false,
+          setterPrivate: true,
+        ),
+        PropertyInfo(
+          name: loadingUnit,
+          jsonKey: loadingUnit,
+          type: String,
+          isOverride: false,
+          setterPrivate: true,
+        )
+      ],
+      taggedUnionProperty: null,
+      taggedUnionValue: null,
+      extraValidation: [
+    
+      ],
+    ),
+    NormalClassInfo(
+      name: Usage,
+      superclassName: null,
+      subclassNames: [  ],
+      properties: [
+        PropertyInfo(
+          name: calls,
+          jsonKey: calls,
+          type: List<Call>?,
+          isOverride: false,
+          setterPrivate: true,
+        ),
+        PropertyInfo(
+          name: identifier,
+          jsonKey: identifier,
+          type: int,
+          isOverride: false,
+          setterPrivate: true,
+        ),
+        PropertyInfo(
+          name: instances,
+          jsonKey: instances,
+          type: List<Instance>?,
+          isOverride: false,
+          setterPrivate: true,
+        ),
+        PropertyInfo(
+          name: loadingUnit,
+          jsonKey: loadingUnit,
+          type: String?,
+          isOverride: false,
+          setterPrivate: true,
+        )
+      ],
+      taggedUnionProperty: null,
+      taggedUnionValue: null,
+      extraValidation: [
+    
+      ],
+    )
+  ]
+)
\ No newline at end of file
diff --git a/pkgs/record_use/pubspec.yaml b/pkgs/record_use/pubspec.yaml
new file mode 100644
index 0000000..97ec2f2
--- /dev/null
+++ b/pkgs/record_use/pubspec.yaml
@@ -0,0 +1,20 @@
+name: record_use
+description: >
+  The serialization logic and API for the usage recording SDK feature.
+version: 0.4.0
+repository: https://github.com/dart-lang/sdk/tree/main/pkg/record_use
+
+environment:
+  sdk: ^3.7.0
+
+dependencies:
+  collection: ^1.18.0
+  pub_semver: ^2.1.4
+
+dev_dependencies:
+  dart_flutter_team_lints: any
+  json_schema: any
+  json_syntax_generator:
+    path: ../json_syntax_generator
+  lints: any
+  test: any
diff --git a/pkgs/record_use/test_data/json/recorded_uses.json b/pkgs/record_use/test_data/json/recorded_uses.json
new file mode 100644
index 0000000..e732030
--- /dev/null
+++ b/pkgs/record_use/test_data/json/recorded_uses.json
@@ -0,0 +1,153 @@
+{
+    "$schema": "../../doc/schema/record_use.schema.json",
+    "metadata": {
+        "version": "1.6.2-wip+5.-.2.z",
+        "comment": "Recorded references at compile time and their argument values, as far as known, to definitions annotated with @RecordUse"
+    },
+    "ids": [
+        {
+            "uri": "file://lib/_internal/js_runtime/lib/js_helper.dart",
+            "name": "MyAnnotation"
+        },
+        {
+            "uri": "file://lib/_internal/js_runtime/lib/js_helper.dart",
+            "parent": "MyClass",
+            "name": "get:loadDeferredLibrary"
+        }
+    ],
+    "constants": [
+        {
+            "type": "String",
+            "value": "jenkins"
+        },
+        {
+            "type": "String",
+            "value": "mercury"
+        },
+        {
+            "type": "String",
+            "value": "lib_SHA1"
+        },
+        {
+            "type": "bool",
+            "value": false
+        },
+        {
+            "type": "int",
+            "value": 1
+        },
+        {
+            "type": "String",
+            "value": "camus"
+        },
+        {
+            "type": "String",
+            "value": "einstein"
+        },
+        {
+            "type": "String",
+            "value": "insert"
+        },
+        {
+            "type": "list",
+            "value": [
+                6,
+                7,
+                3
+            ]
+        },
+        {
+            "type": "list",
+            "value": [
+                5,
+                8,
+                6
+            ]
+        },
+        {
+            "type": "int",
+            "value": 0
+        },
+        {
+            "type": "int",
+            "value": 99
+        },
+        {
+            "type": "map",
+            "value": {
+                "key": 11
+            }
+        },
+        {
+            "type": "int",
+            "value": 42
+        },
+        {
+            "type": "Null"
+        },
+        {
+            "type": "Instance",
+            "value": {
+                "a": 13,
+                "b": 14
+            }
+        }
+    ],
+    "usages": [
+        {
+            "identifier": 0,
+            "instances": [
+                {
+                    "instanceConstant": 15,
+                    "loadingUnit": "3"
+                }
+            ]
+        },
+        {
+            "identifier": 1,
+            "calls": [
+                {
+                    "arguments": {
+                        "constant": {
+                            "positional": {
+                                "0": 2,
+                                "1": 3,
+                                "2": 4
+                            },
+                            "named": {
+                                "leroy": 0,
+                                "freddy": 1
+                            }
+                        }
+                    },
+                    "loadingUnit": "o.js"
+                },
+                {
+                    "arguments": {
+                        "constant": {
+                            "positional": {
+                                "0": 2,
+                                "2": 10,
+                                "4": 12
+                            },
+                            "named": {
+                                "leroy": 0,
+                                "albert": 9
+                            }
+                        },
+                        "nonConstant": {
+                            "positional": [
+                                1
+                            ],
+                            "named": [
+                                "freddy"
+                            ]
+                        }
+                    },
+                    "loadingUnit": "o.js"
+                }
+            ],
+            "loadingUnit": "part_15.js"
+        }
+    ]
+}
diff --git a/pkgs/record_use/test_data/json/recorded_uses_2.json b/pkgs/record_use/test_data/json/recorded_uses_2.json
new file mode 100644
index 0000000..f110080
--- /dev/null
+++ b/pkgs/record_use/test_data/json/recorded_uses_2.json
@@ -0,0 +1,44 @@
+{
+    "$schema": "../../doc/schema/record_use.schema.json",
+    "metadata": {
+        "comment": "Recorded usages of objects tagged with a `RecordUse` annotation",
+        "version": "0.1.0"
+    },
+    "ids": [
+        {
+            "uri": "package:drop_dylib_recording/src/drop_dylib_recording.dart",
+            "name": "getMathMethod"
+        }
+    ],
+    "constants": [
+        {
+            "type": "String",
+            "value": "add"
+        }
+    ],
+    "usages": [
+        {
+            "identifier": 0,
+            "calls": [
+                {
+                    "definition": {
+                        "id": 0,
+                        "loadingUnit": "1"
+                    },
+                    "references": [
+                        {
+                            "arguments": {
+                                "constant": {
+                                    "positional": {
+                                        "0": 0
+                                    }
+                                }
+                            },
+                            "loadingUnit": "1"
+                        }
+                    ]
+                }
+            ]
+        }
+    ]
+}
diff --git a/pkgs/record_use/tool/generate_syntax.dart b/pkgs/record_use/tool/generate_syntax.dart
new file mode 100644
index 0000000..47a6833
--- /dev/null
+++ b/pkgs/record_use/tool/generate_syntax.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2025, 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:convert';
+import 'dart:io';
+
+import 'package:json_schema/json_schema.dart';
+import 'package:json_syntax_generator/json_syntax_generator.dart';
+
+void main(List<String> args) {
+  final schemaFile = File.fromUri(
+    Platform.script.resolve('../doc/schema/record_use.schema.json'),
+  );
+  final schemaJson = jsonDecode(schemaFile.readAsStringSync()) as Map;
+  final schema = JsonSchema.create(schemaJson);
+
+  final analyzedSchema = SchemaAnalyzer(schema).analyze();
+  final textDumpFile = File.fromUri(
+    Platform.script.resolve('../lib/src/syntax.g.txt'),
+  );
+  textDumpFile.parent.createSync(recursive: true);
+  if (args.contains('-d')) {
+    textDumpFile.writeAsStringSync(analyzedSchema.toString());
+  } else if (textDumpFile.existsSync()) {
+    textDumpFile.deleteSync();
+  }
+  final output =
+      SyntaxGenerator(
+        analyzedSchema,
+        header: '''
+// This file is generated, do not edit.
+// File generated by pkg/record_use/tool/generate_syntax.dart.
+''',
+      ).generate();
+  final outputUri = Platform.script.resolve('../lib/src/syntax.g.dart');
+  File.fromUri(outputUri).writeAsStringSync(output);
+  Process.runSync(Platform.executable, ['format', outputUri.toFilePath()]);
+  print('Generated $outputUri');
+}