blob: ce2d410ac2204796eac63992976b9dee092018d8 [file] [log] [blame]
// Copyright (c) 2026, 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 library defines the context objects used to manage reference pools
/// during serialization and deserialization of normalized JSON.
///
/// A **pool** is a deduplicated collection of semantic objects (such as
/// [Constant]s) that are represented as a list at the top level of the JSON.
/// Other objects reference these by their integer index into the pool.
///
/// ### Layer Responsibilities
///
/// The **Syntax Layer** ([ConstantSyntax], [RecordedUsesSyntax], etc.) is
/// designed to be context-free, acting as a thin wrapper around JSON data. This
/// aligns with the capabilities of standard JSON Schema. The syntax defines how
/// pools are physically encoded in JSON as flat, top-level arrays (e.g.,
/// [RecordedUsesSyntax.constants]). It uses integer indices to represent
/// relationships, keeping the JSON structure normalized and deduplicated.
///
/// The **Semantic Layer** ([Constant]s, [Recordings], etc.) translates these
/// flat indices into rich, interconnected semantic objects. It uses
/// [DeserializationContext] and [SerializationContext] to map between the
/// integer indices in the JSON and deduplicated [Constant] objects, ensuring
/// identity is preserved across the system.
///
/// ### (De)serialization Order
///
/// The order of operations ensures that all dependencies are available at each
/// step:
///
/// 1. **Loading Units**: Loading unit identifiers are deserialized from or
/// serialized to the [RecordedUsesSyntax.loadingUnits] pool first.
/// 2. **Definitions**: [Definition] objects are deserialized from or
/// serialized to the [RecordedUsesSyntax.definitions] pool second.
/// 3. **Constants**: [Constant] objects are deserialized from or serialized
/// to the [RecordedUsesSyntax.constants] pool third. They may contain
/// references to the definitions pool (e.g. for [InstanceConstant]) and the
/// constants pool (for recursive collections).
/// 4. **Recordings**: Recordings are (de)serialized last from or to
/// [RecordedUsesSyntax.uses] as they depend on loading units,
/// [Constant]s, and [Definition]s.
library;
import 'package:meta/meta.dart';
import 'constant.dart';
import 'definition.dart';
import 'loading_unit.dart';
import 'recordings.dart';
import 'syntax.g.dart';
/// Context providing access to the loading unit pool during deserialization.
@immutable
base class LoadingUnitDeserializationContext {
final List<LoadingUnit> loadingUnits;
const LoadingUnitDeserializationContext(this.loadingUnits);
}
/// Context providing access to the [Definition] pool during deserialization.
@immutable
base class DefinitionDeserializationContext
extends LoadingUnitDeserializationContext {
final List<Definition> definitions;
DefinitionDeserializationContext.fromPrevious(
LoadingUnitDeserializationContext previous,
this.definitions,
) : super(previous.loadingUnits);
}
/// The final deserialization state where all pools are resolved.
@immutable
final class DeserializationContext extends DefinitionDeserializationContext {
/// The mapping from the unique integer index in
/// [RecordedUsesSyntax.constants] to the semantic [MaybeConstant]s.
final List<MaybeConstant> constants;
DeserializationContext.fromPrevious(
DefinitionDeserializationContext previous,
this.constants,
) : super.fromPrevious(previous, previous.definitions);
}
/// The serialization state containing indices for all pools.
///
/// Canonicalization is responsible for collecting all reachable objects across
/// the recording and providing the basis for these index maps.
@immutable
final class SerializationContext {
/// The mapping from semantic [LoadingUnit] objects to their unique integer
/// index within the loading unit pool ([RecordedUsesSyntax.loadingUnits]).
final Map<LoadingUnit, int> loadingUnits;
/// The mapping from semantic [Definition] objects to their unique integer
/// index within the definitions pool ([RecordedUsesSyntax.definitions]).
final Map<Definition, int> definitions;
/// The mapping from semantic [MaybeConstant] objects to their unique integer
/// index within the constants pool ([RecordedUsesSyntax.constants]).
final Map<MaybeConstant, int> constants;
const SerializationContext({
required this.loadingUnits,
required this.definitions,
required this.constants,
});
}