From 3fbadf1f122ee4eea38e37c08ec2b996824dffe0 Mon Sep 17 00:00:00 2001 From: ayush00git Date: Fri, 13 Feb 2026 20:12:59 +0530 Subject: [PATCH 01/15] updated float16 wrapper logic --- .../fory/lib/src/datatype/float16.dart | 412 +++++++++++++----- 1 file changed, 294 insertions(+), 118 deletions(-) diff --git a/dart/packages/fory/lib/src/datatype/float16.dart b/dart/packages/fory/lib/src/datatype/float16.dart index 501e04aea0..2e33bbe93b 100644 --- a/dart/packages/fory/lib/src/datatype/float16.dart +++ b/dart/packages/fory/lib/src/datatype/float16.dart @@ -17,159 +17,335 @@ * under the License. */ -import 'dart:math' as math show pow, log, ln2; +import 'dart:math' as math; +import 'dart:typed_data'; // For ByteData import 'float32.dart' show Float32; import 'fory_fixed_num.dart'; import 'int16.dart' show Int16; import 'int32.dart' show Int32; +// ignore: unused_import import 'int8.dart' show Int8; +// ignore: unused_import +import 'uint8.dart' show UInt8; +// ignore: unused_import +import 'uint16.dart' show UInt16; +// ignore: unused_import +import 'uint32.dart' show UInt32; /// Float16: 16-bit floating point (IEEE 754 half precision) +/// Wraps a 16-bit integer representing the IEEE 754 binary16 format. final class Float16 extends FixedNum { - static const double MIN_VALUE = -65504; - static const double MAX_VALUE = 65504; - static const double EPSILON = 0.0009765625; // 2^-10 - - static Float16 get maxValue => Float16(MAX_VALUE); - - static Float16 get minValue => Float16(MIN_VALUE); - - final double _value; - - Float16(num input) : _value = _convert(input); - - static double _convert(num value) { - // This is a proper IEEE 754 half-precision implementation - double val = value.toDouble(); - if (val.isNaN) return double.nan; - if (val.isInfinite) return val; - - // Handle zeros - if (val == 0.0) return val.sign < 0 ? -0.0 : 0.0; - - // Clamp to float16 range - val = val.clamp(-MAX_VALUE, MAX_VALUE).toDouble(); - - // Implementing IEEE 754 half-precision conversion - int bits; - if (val.abs() < EPSILON) { - // Handle subnormal numbers - bits = - ((val < 0 ? 1 : 0) << 15) | ((val.abs() / EPSILON).round() & 0x3FF); - } else { - // Extract components from double - int sign = val < 0 ? 1 : 0; - double absVal = val.abs(); - int exp = (math.log(absVal) / math.ln2).floor(); - double frac = absVal / math.pow(2, exp) - 1.0; - - // Adjust for 5-bit exponent - exp += 15; // Bias - exp = exp.clamp(0, 31); - - // Convert to 10-bit fraction - int fracBits = (frac * 1024).round() & 0x3FF; - - // Combine into 16 bits - bits = (sign << 15) | (exp << 10) | fracBits; - } - - // Convert back to double (simulates float16 storage and retrieval) - // In a real-world implementation, you would use binary data directly - int sign = (bits >> 15) & 0x1; - int exp = (bits >> 10) & 0x1F; - int frac = bits & 0x3FF; - - if (exp == 0) { - // Subnormal numbers - return (sign == 0 ? 1.0 : -1.0) * frac * EPSILON; - } else if (exp == 31) { - // Infinity or NaN - return frac == 0 - ? (sign == 0 ? double.infinity : double.negativeInfinity) - : double.nan; - } - - // Normal numbers - double result = (sign == 0 ? 1.0 : -1.0) * - math.pow(2, exp - 15) * - (1.0 + frac / 1024.0); - return result; + /// The raw 16-bit integer storage. + final int _bits; + + /// Masks the bits to ensure 16-bit range. + static const int _mask = 0xFFFF; + + // --- Constants --- + static const int _exponentBias = 15; + static const int _maxExponent = 31; // 2^5 - 1 + // ignore: unused_field + static const int _mantissaBits = 10; + + // Bit placeholders + static const int _signMask = 0x8000; + static const int _exponentMask = 0x7C00; + static const int _mantissaMask = 0x03FF; + + // --- Public Constants --- + static const Float16 positiveZero = Float16.fromBits(0x0000); + static const Float16 negativeZero = Float16.fromBits(0x8000); + static const Float16 positiveInfinity = Float16.fromBits(0x7C00); + static const Float16 negativeInfinity = Float16.fromBits(0xFC00); + static const Float16 nan = Float16.fromBits(0x7E00); // Canonical NaN + + static const double minValue = 6.103515625e-05; // 2^-14 (Normal) + static const double minSubnormal = 5.960464477539063e-08; // 2^-24 + static const double maxValue = 65504.0; + static const double epsilon = 0.0009765625; // 2^-10 + + /// Constructs a [Float16] from a number. + /// Delegates to [Float16.fromDouble]. + factory Float16(num value) => Float16.fromDouble(value.toDouble()); + + /// Constructs a [Float16] directly from raw bits. + const Float16.fromBits(int bits) : _bits = bits & _mask; + + /// Converts a [double] to [Float16] using IEEE 754 half-precision rules (round-to-nearest-even). + factory Float16.fromDouble(double value) { + if (value.isNaN) { + return Float16.nan; + } + + final int doubleBits = _doubleToBits(value); + final int sign = (doubleBits >> 63) & 0x1; + final int rawExp = (doubleBits >> 52) & 0x7FF; + final int rawMantissa = doubleBits & 0xFFFFFFFFFFFFF; + + // 1. Convert double exp to float16 exp + // Double bias: 1023, Float16 bias: 15. + // Shift: 1023 - 15 = 1008. + int exp = rawExp - 1023 + _exponentBias; + + if (exp >= _maxExponent) { + // Overflow or Infinity + return rawExp == 2047 && rawMantissa != 0 + ? Float16.nan // Should have been caught by value.isNaN check above usually + : (sign == 0 ? Float16.positiveInfinity : Float16.negativeInfinity); + } else if (exp <= 0) { + // Subnormal or Zero + if (exp < -10) { + // Too small for subnormal -> signed zero + return sign == 0 ? Float16.positiveZero : Float16.negativeZero; + } + + // Convert to subnormal + return Float16.fromBits(_doubleToFloat16Bits(value)); + } else { + // Normalized + return Float16.fromBits(_doubleToFloat16Bits(value)); + } } + static int _doubleToBits(double value) { + var bdata = ByteData(8); + bdata.setFloat64(0, value, Endian.little); + return bdata.getUint64(0, Endian.little); + } + + static double _bitsToDouble(int bits) { + // Logic for converting float16 bits to double + int s = (bits >> 15) & 0x0001; + int e = (bits >> 10) & 0x001f; + int m = bits & 0x03ff; + + if (e == 0) { + if (m == 0) { + // signed zero + return s == 1 ? -0.0 : 0.0; + } else { + // subnormal + return (s == 1 ? -1 : 1) * math.pow(2, -14) * (m / 1024.0); + } + } else if (e == 31) { + if (m == 0) { + return s == 1 ? double.negativeInfinity : double.infinity; + } else { + return double.nan; + } + } else { + // normalized + return (s == 1 ? -1 : 1) * math.pow(2, e - 15) * (1 + m / 1024.0); + } + } + + /// Helper to convert double to float16 bits with proper rounding + static int _doubleToFloat16Bits(double val) { + if (val.isNaN) return 0x7E00; // Canonical NaN + + // Check for zero + if (val == 0.0) { + return (1 / val) == double.negativeInfinity ? 0x8000 : 0x0000; + } + + int fbits = _doubleToBits(val); + int sign = (fbits >> 63) & 1; + int exp = (fbits >> 52) & 0x7FF; // 11 bits + + // Bias adjustment + int newExp = exp - 1023 + 15; + + // Inf / NaN handled? + if (exp == 2047) { + // Infinity only (NaN handled at start) + return (sign << 15) | 0x7C00; + } + + if (newExp >= 31) { + // Overflow to Infinity + return (sign << 15) | 0x7C00; + } + + if (newExp <= 0) { + // Possible subnormal or zero + if (newExp < -10) { + // Underflow to zero + return sign << 15; + } + + double absVal = val.abs(); + if (absVal < minValue) { + // It is subnormal + // val = 0.m * 2^-14 + // m = val / 2^-14 + double m = absVal / math.pow(2, -14); + // m is now in [0, 1). + // We want 10 bits of it. + // bits = round(m * 1024) + int mBits = (m * 1024).round(); + return (sign << 15) | mBits; + } + } + + // Normalized + // We need to round the mantissa. + + int fullMantissa = (fbits & 0xFFFFFFFFFFFFF); + // We want to reduce 52 bits to 10 bits. + // So we shift right by 42. + // The bits we shift out are the last 42 bits. + // The 42nd bit (from right, 0-indexed) is the round bit. + // The bits 0-41 are safety/sticky bits. + + int m10 = fullMantissa >> 42; + int guard = (fullMantissa >> 41) & 1; + int sticky = (fullMantissa & 0x1FFFFFFFFFF) != 0 ? 1 : 0; + + if (guard == 1) { + if (sticky == 1 || (m10 & 1) == 1) { + m10++; + } + } + + if (m10 >= 1024) { + // Mantissa overflowed, increment exponent + m10 = 0; + newExp++; + if (newExp >= 31) { + return (sign << 15) | 0x7C00; // Inf + } + } + + return (sign << 15) | (newExp << 10) | m10; + } + + /// Returns the raw 16-bit integer. + int toBits() => _bits; + + /// Returns the value as a [double]. @override - double get value => _value; + double toDouble() => _bitsToDouble(_bits); - // Operators + /// Returns the underlying values as a [double]. + @override + double get value => toDouble(); + + // --- Classification --- + bool get isNaN => (_bits & _exponentMask) == _exponentMask && (_bits & _mantissaMask) != 0; + + bool get isInfinite => (_bits & _exponentMask) == _exponentMask && (_bits & _mantissaMask) == 0; + + bool get isFinite => (_bits & _exponentMask) != _exponentMask; + + bool get isNormal => + (_bits & _exponentMask) != 0 && (_bits & _exponentMask) != _exponentMask; + + bool get isSubnormal => + (_bits & _exponentMask) == 0 && (_bits & _mantissaMask) != 0; + + bool get isZero => (_bits & 0x7FFF) == 0; + + bool get isNegative => (_bits & _signMask) != 0; + + int get sign => isNaN ? 0 : (isNegative ? -1 : 1); + + // --- Arithmetic (Explicit) --- + + Float16 add(Float16 other) => Float16.fromDouble(toDouble() + other.toDouble()); + Float16 sub(Float16 other) => Float16.fromDouble(toDouble() - other.toDouble()); + Float16 mul(Float16 other) => Float16.fromDouble(toDouble() * other.toDouble()); + Float16 div(Float16 other) => Float16.fromDouble(toDouble() / other.toDouble()); + + Float16 neg() => Float16.fromBits(_bits ^ _signMask); + + Float16 abs() => Float16.fromBits(_bits & 0x7FFF); + + // --- Comparisons --- + + /// Bitwise equality. +0 != -0, NaN == NaN (if payload matches). + /// This is effectively `_bits == other._bits`. + bool equalsValue(Float16 other) => _bits == other._bits; + + /// IEEE comparison. + /// NaN != NaN. +0 == -0. + bool ieeeEquals(Float16 other) => toDouble() == other.toDouble(); + + bool lessThan(Float16 other) => toDouble() < other.toDouble(); + bool lessThanOrEqual(Float16 other) => toDouble() <= other.toDouble(); + bool greaterThan(Float16 other) => toDouble() > other.toDouble(); + bool greaterThanOrEqual(Float16 other) => toDouble() >= other.toDouble(); + + static int compare(Float16 a, Float16 b) => a.toDouble().compareTo(b.toDouble()); + + // --- Operators (Delegation) --- + + @override Float16 operator +(dynamic other) => - Float16(_value + (other is FixedNum ? other.value : other)); + add(other is Float16 ? other : Float16(other)); + @override Float16 operator -(dynamic other) => - Float16(_value - (other is FixedNum ? other.value : other)); + sub(other is Float16 ? other : Float16(other)); + @override Float16 operator *(dynamic other) => - Float16(_value * (other is FixedNum ? other.value : other)); + mul(other is Float16 ? other : Float16(other)); + @override double operator /(dynamic other) => - _value / (other is FixedNum ? other.value : other); - + toDouble() / (other is Float16 ? other.toDouble() : other); + + @override Float16 operator ~/(dynamic other) => - Float16(_value ~/ (other is FixedNum ? other.value : other)); + Float16((toDouble() ~/ (other is Float16 ? other.toDouble() : other))); + @override Float16 operator %(dynamic other) => - Float16(_value % (other is FixedNum ? other.value : other)); + Float16(toDouble() % (other is Float16 ? other.toDouble() : other)); - Float16 operator -() => Float16(-_value); + @override + Float16 operator -() => neg(); - // Comparison - bool operator <(dynamic other) => - _value < (other is FixedNum ? other.value : other); + // Comparison Operators + @override + bool operator <(dynamic other) => toDouble() < (other is Float16 ? other.toDouble() : other); - bool operator <=(dynamic other) => - _value <= (other is FixedNum ? other.value : other); + @override + bool operator <=(dynamic other) => toDouble() <= (other is Float16 ? other.toDouble() : other); - bool operator >(dynamic other) => - _value > (other is FixedNum ? other.value : other); + @override + bool operator >(dynamic other) => toDouble() > (other is Float16 ? other.toDouble() : other); - bool operator >=(dynamic other) => - _value >= (other is FixedNum ? other.value : other); + @override + bool operator >=(dynamic other) => toDouble() >= (other is Float16 ? other.toDouble() : other); - // Equality @override bool operator ==(Object other) { - if (other is FixedNum) return _value == other.value; - if (other is num) return _value == other; + if (other is Float16) return _bits == other._bits; // Policy A: Bitwise equality return false; } @override - int get hashCode => _value.hashCode; - - // Common num methods - double abs() => _value.abs(); - double get sign => _value.sign; - bool get isNegative => _value < 0; - bool get isNaN => _value.isNaN; - bool get isInfinite => _value.isInfinite; - bool get isFinite => _value.isFinite; - - // Type conversions - int toInt() => _value.toInt(); - double toDouble() => _value; - Int8 toInt8() => Int8(_value); - Int16 toInt16() => Int16(_value); - Int32 toInt32() => Int32(_value); - Float32 toFloat32() => Float32(_value); - - // String formatting - String toStringAsFixed(int fractionDigits) => - _value.toStringAsFixed(fractionDigits); - String toStringAsExponential([int? fractionDigits]) => - _value.toStringAsExponential(fractionDigits); - String toStringAsPrecision(int precision) => - _value.toStringAsPrecision(precision); + int get hashCode => _bits.hashCode; + // --- Type Conversions --- + + @override + int toInt() => toDouble().toInt(); + + Int8 toInt8() => Int8(toInt()); + Int16 toInt16() => Int16(toInt()); + Int32 toInt32() => Int32(toInt()); + + Float32 toFloat32() => Float32(toDouble()); + + // --- String Formatting --- + + String toStringAsFixed(int fractionDigits) => toDouble().toStringAsFixed(fractionDigits); + String toStringAsExponential([int? fractionDigits]) => toDouble().toStringAsExponential(fractionDigits); + String toStringAsPrecision(int precision) => toDouble().toStringAsPrecision(precision); + @override - String toString() => _value.toString(); + String toString() => toDouble().toString(); } From 5f792ee7c61a1abdcf64b480045b1e868c273c43 Mon Sep 17 00:00:00 2001 From: ayush00git Date: Fri, 13 Feb 2026 20:24:06 +0530 Subject: [PATCH 02/15] updated float16 --- dart/packages/fory/lib/src/datatype/float16.dart | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/dart/packages/fory/lib/src/datatype/float16.dart b/dart/packages/fory/lib/src/datatype/float16.dart index 2e33bbe93b..f6f0099ad3 100644 --- a/dart/packages/fory/lib/src/datatype/float16.dart +++ b/dart/packages/fory/lib/src/datatype/float16.dart @@ -18,19 +18,15 @@ */ import 'dart:math' as math; -import 'dart:typed_data'; // For ByteData +import 'dart:typed_data'; import 'float32.dart' show Float32; import 'fory_fixed_num.dart'; import 'int16.dart' show Int16; import 'int32.dart' show Int32; -// ignore: unused_import import 'int8.dart' show Int8; -// ignore: unused_import import 'uint8.dart' show UInt8; -// ignore: unused_import import 'uint16.dart' show UInt16; -// ignore: unused_import import 'uint32.dart' show UInt32; /// Float16: 16-bit floating point (IEEE 754 half precision) @@ -45,7 +41,6 @@ final class Float16 extends FixedNum { // --- Constants --- static const int _exponentBias = 15; static const int _maxExponent = 31; // 2^5 - 1 - // ignore: unused_field static const int _mantissaBits = 10; // Bit placeholders @@ -58,12 +53,12 @@ final class Float16 extends FixedNum { static const Float16 negativeZero = Float16.fromBits(0x8000); static const Float16 positiveInfinity = Float16.fromBits(0x7C00); static const Float16 negativeInfinity = Float16.fromBits(0xFC00); - static const Float16 nan = Float16.fromBits(0x7E00); // Canonical NaN + static const Float16 nan = Float16.fromBits(0x7E00); - static const double minValue = 6.103515625e-05; // 2^-14 (Normal) - static const double minSubnormal = 5.960464477539063e-08; // 2^-24 + static const double minValue = 6.103515625e-05; + static const double minSubnormal = 5.960464477539063e-08; static const double maxValue = 65504.0; - static const double epsilon = 0.0009765625; // 2^-10 + static const double epsilon = 0.0009765625; /// Constructs a [Float16] from a number. /// Delegates to [Float16.fromDouble]. From 012114834bf75b6eb4e064aad4d8f036c0bd1e42 Mon Sep 17 00:00:00 2001 From: ayush00git Date: Fri, 13 Feb 2026 20:26:38 +0530 Subject: [PATCH 03/15] added float16 to writer and reader --- dart/packages/fory/lib/src/memory/byte_reader.dart | 4 ++++ dart/packages/fory/lib/src/memory/byte_reader_impl.dart | 8 ++++++++ dart/packages/fory/lib/src/memory/byte_writer.dart | 2 ++ dart/packages/fory/lib/src/memory/byte_writer_impl.dart | 8 ++++++++ 4 files changed, 22 insertions(+) diff --git a/dart/packages/fory/lib/src/memory/byte_reader.dart b/dart/packages/fory/lib/src/memory/byte_reader.dart index e10f7214e9..b8531d7826 100644 --- a/dart/packages/fory/lib/src/memory/byte_reader.dart +++ b/dart/packages/fory/lib/src/memory/byte_reader.dart @@ -19,6 +19,7 @@ import 'dart:typed_data'; import 'package:meta/meta.dart'; +import 'package:fory/src/datatype/float16.dart'; import 'package:fory/src/memory/byte_reader_impl.dart'; abstract base class ByteReader { @@ -66,6 +67,9 @@ abstract base class ByteReader { /// Reads a 64-bit floating point number from the stream. double readFloat64(); + /// Reads a 16-bit floating point number from the stream. + Float16 readFloat16(); + int readVarUint36Small(); int readVarInt32(); diff --git a/dart/packages/fory/lib/src/memory/byte_reader_impl.dart b/dart/packages/fory/lib/src/memory/byte_reader_impl.dart index 7a8f341609..571a9d2e3f 100644 --- a/dart/packages/fory/lib/src/memory/byte_reader_impl.dart +++ b/dart/packages/fory/lib/src/memory/byte_reader_impl.dart @@ -19,6 +19,7 @@ import 'dart:typed_data'; import 'package:fory/src/dev_annotation/optimize.dart'; +import 'package:fory/src/datatype/float16.dart'; import 'package:fory/src/memory/byte_reader.dart'; final class ByteReaderImpl extends ByteReader { @@ -118,6 +119,13 @@ final class ByteReaderImpl extends ByteReader { return value; } + @override + Float16 readFloat16() { + int value = _bd.getUint16(_offset, endian); + _offset += 2; + return Float16.fromBits(value); + } + @override Uint8List readBytesView(int length) { // create a view of the original list diff --git a/dart/packages/fory/lib/src/memory/byte_writer.dart b/dart/packages/fory/lib/src/memory/byte_writer.dart index 78f76bfa3b..fb556afd02 100644 --- a/dart/packages/fory/lib/src/memory/byte_writer.dart +++ b/dart/packages/fory/lib/src/memory/byte_writer.dart @@ -20,6 +20,7 @@ import 'dart:typed_data'; import 'package:meta/meta.dart'; import 'package:fory/src/memory/byte_writer_impl.dart'; +import 'package:fory/src/datatype/float16.dart'; abstract base class ByteWriter { @protected @@ -45,6 +46,7 @@ abstract base class ByteWriter { void writeFloat32(double value); void writeFloat64(double value); + void writeFloat16(Float16 value); void writeBytes(List bytes); diff --git a/dart/packages/fory/lib/src/memory/byte_writer_impl.dart b/dart/packages/fory/lib/src/memory/byte_writer_impl.dart index 110ae286c7..56d7ecbfd0 100644 --- a/dart/packages/fory/lib/src/memory/byte_writer_impl.dart +++ b/dart/packages/fory/lib/src/memory/byte_writer_impl.dart @@ -19,6 +19,7 @@ import 'dart:typed_data'; import 'package:fory/src/dev_annotation/optimize.dart'; +import 'package:fory/src/datatype/float16.dart'; import 'package:fory/src/memory/byte_writer.dart'; final class ByteWriterImpl extends ByteWriter { @@ -134,6 +135,13 @@ final class ByteWriterImpl extends ByteWriter { _buffer.add(_tempByteData.buffer.asUint8List(0, 8)); } + /// Append a `Float16` (2 bytes, Little Endian) to the buffer + @inline + @override + void writeFloat16(Float16 value) { + writeUint16(value.toBits()); + } + /// Append a list of bytes to the buffer @override @inline From ab05c761568d1848e57a09b3f3e47c7801cac9b0 Mon Sep 17 00:00:00 2001 From: ayush00git Date: Fri, 13 Feb 2026 22:35:18 +0530 Subject: [PATCH 04/15] registered float16 to dart types --- dart/packages/fory/lib/src/const/dart_type.dart | 3 +++ dart/packages/fory/lib/src/datatype/float16.dart | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/dart/packages/fory/lib/src/const/dart_type.dart b/dart/packages/fory/lib/src/const/dart_type.dart index c7fafd36b8..85c37fcf11 100644 --- a/dart/packages/fory/lib/src/const/dart_type.dart +++ b/dart/packages/fory/lib/src/const/dart_type.dart @@ -21,6 +21,7 @@ import 'dart:collection'; import 'dart:typed_data'; import 'package:collection/collection.dart' show BoolList; import 'package:decimal/decimal.dart'; +import 'package:fory/src/datatype/float16.dart'; import 'package:fory/src/datatype/float32.dart'; import 'package:fory/src/datatype/int16.dart'; import 'package:fory/src/datatype/int32.dart'; @@ -57,6 +58,8 @@ enum DartTypeEnum { INT(int, true, 'int', 'dart', 'core', ObjType.INT64, true, 'dart:core@int'), FLOAT32(Float32, true, 'Float32', 'package', 'fory/src/datatype/float32.dart', ObjType.FLOAT32, true, 'dart:core@Float32'), + FLOAT16(Float16, true, 'Float16', 'package', 'fory/src/datatype/float16.dart', + ObjType.FLOAT16, true, 'dart:core@Float16'), DOUBLE(double, true, 'double', 'dart', 'core', ObjType.FLOAT64, true, 'dart:core@double'), STRING(String, true, 'String', 'dart', 'core', ObjType.STRING, true, diff --git a/dart/packages/fory/lib/src/datatype/float16.dart b/dart/packages/fory/lib/src/datatype/float16.dart index f6f0099ad3..fa1faffc6c 100644 --- a/dart/packages/fory/lib/src/datatype/float16.dart +++ b/dart/packages/fory/lib/src/datatype/float16.dart @@ -65,7 +65,7 @@ final class Float16 extends FixedNum { factory Float16(num value) => Float16.fromDouble(value.toDouble()); /// Constructs a [Float16] directly from raw bits. - const Float16.fromBits(int bits) : _bits = bits & _mask; + const Float16.fromBits(int bits) : _bits = bits & _mask, super(); /// Converts a [double] to [Float16] using IEEE 754 half-precision rules (round-to-nearest-even). factory Float16.fromDouble(double value) { From 5a6bfa641a0dc7226ee2ee26f605ca9204f74fa5 Mon Sep 17 00:00:00 2001 From: ayush00git Date: Fri, 13 Feb 2026 22:36:15 +0530 Subject: [PATCH 05/15] added float16 to the primitive types --- .../serializer/primitive_type_serializer.dart | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/dart/packages/fory/lib/src/serializer/primitive_type_serializer.dart b/dart/packages/fory/lib/src/serializer/primitive_type_serializer.dart index dd145df227..fdbc5ea94f 100644 --- a/dart/packages/fory/lib/src/serializer/primitive_type_serializer.dart +++ b/dart/packages/fory/lib/src/serializer/primitive_type_serializer.dart @@ -19,6 +19,7 @@ import 'package:fory/src/config/fory_config.dart'; import 'package:fory/src/const/types.dart'; +import 'package:fory/src/datatype/float16.dart'; import 'package:fory/src/datatype/float32.dart'; import 'package:fory/src/datatype/fory_fixed_num.dart'; import 'package:fory/src/datatype/int16.dart'; @@ -271,6 +272,42 @@ final class Float32Serializer extends Serializer { } } +final class _Float16SerializerCache extends PrimitiveSerializerCache { + static Float16Serializer? serializerWithRef; + static Float16Serializer? serializerWithoutRef; + + const _Float16SerializerCache(); + + @override + Serializer getSerializerWithRef(bool writeRef) { + if (writeRef) { + serializerWithRef ??= Float16Serializer._(true); + return serializerWithRef!; + } else { + serializerWithoutRef ??= Float16Serializer._(false); + return serializerWithoutRef!; + } + } +} + +// Dart does not have float16; the user can specify converting Dart double to float16 through annotation, so precision errors may occur +final class Float16Serializer extends Serializer { + static const SerializerCache cache = _Float16SerializerCache(); + + Float16Serializer._(bool writeRef) : super(ObjType.FLOAT16, writeRef); + + @override + Float16 read(ByteReader br, int refId, DeserializationContext pack) { + return br.readFloat16(); + } + + @override + void write(ByteWriter bw, covariant Float16 v, SerializationContext pack) { + // No checks are performed here + bw.writeFloat16(v); + } +} + final class _Float64SerializerCache extends PrimitiveSerializerCache { static Float64Serializer? serializerWithRef; static Float64Serializer? serializerWithoutRef; From 80cf5d006e62670a4b6e12bdf3e74190ce26e24e Mon Sep 17 00:00:00 2001 From: ayush00git Date: Fri, 13 Feb 2026 22:37:12 +0530 Subject: [PATCH 06/15] added float16 type to the serializer pool --- dart/packages/fory/lib/src/serializer/serializer_pool.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dart/packages/fory/lib/src/serializer/serializer_pool.dart b/dart/packages/fory/lib/src/serializer/serializer_pool.dart index ad1a84a6a6..6bf2cee007 100644 --- a/dart/packages/fory/lib/src/serializer/serializer_pool.dart +++ b/dart/packages/fory/lib/src/serializer/serializer_pool.dart @@ -23,6 +23,7 @@ import 'package:collection/collection.dart'; import 'package:fory/src/config/fory_config.dart'; import 'package:fory/src/const/dart_type.dart'; import 'package:fory/src/const/types.dart'; +import 'package:fory/src/datatype/float16.dart'; import 'package:fory/src/datatype/float32.dart'; import 'package:fory/src/datatype/int16.dart'; import 'package:fory/src/datatype/int32.dart'; @@ -79,6 +80,8 @@ class SerializerPool { UInt32Serializer.cache.getSerializer(conf); typeToTypeInfo[Float32]!.serializer = Float32Serializer.cache.getSerializer(conf); + typeToTypeInfo[Float16]!.serializer = + Float16Serializer.cache.getSerializer(conf); typeToTypeInfo[String]!.serializer = StringSerializer.cache.getSerializer(conf); From 3d7b3ae72b21b444d6cf4c613d5e58b4dc1988b9 Mon Sep 17 00:00:00 2001 From: ayush00git Date: Fri, 13 Feb 2026 22:37:28 +0530 Subject: [PATCH 07/15] added test suites --- .../test/datatype_test/float16_test.dart | 158 ++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 dart/packages/fory-test/test/datatype_test/float16_test.dart diff --git a/dart/packages/fory-test/test/datatype_test/float16_test.dart b/dart/packages/fory-test/test/datatype_test/float16_test.dart new file mode 100644 index 0000000000..54cd8773af --- /dev/null +++ b/dart/packages/fory-test/test/datatype_test/float16_test.dart @@ -0,0 +1,158 @@ +import 'dart:math' as math; +import 'dart:typed_data'; +import 'package:test/test.dart'; +import 'package:fory/src/datatype/float16.dart'; +import 'package:fory/src/datatype/float32.dart'; +import 'package:fory/src/memory/byte_writer.dart'; +import 'package:fory/src/memory/byte_reader.dart'; + +void main() { + group('Float16 Conversion', () { + test('Zero', () { + expect(Float16.positiveZero.toDouble(), 0.0); + expect(Float16.negativeZero.toDouble(), -0.0); + expect(Float16.fromDouble(0.0).toBits(), 0x0000); + expect(Float16.fromDouble(-0.0).toBits(), 0x8000); + + // Verify -0.0 vs 0.0 distinction + expect(Float16.fromDouble(-0.0).isNegative, true); + expect(Float16.fromDouble(0.0).isNegative, false); + }); + + test('Infinity', () { + expect(Float16.positiveInfinity.toDouble(), double.infinity); + expect(Float16.negativeInfinity.toDouble(), double.negativeInfinity); + expect(Float16.fromDouble(double.infinity).toBits(), 0x7C00); + expect(Float16.fromDouble(double.negativeInfinity).toBits(), 0xFC00); + }); + + test('NaN', () { + expect(Float16.nan.toDouble().isNaN, true); + expect(Float16.fromDouble(double.nan).isNaN, true); + // Canonical NaN + expect(Float16.fromDouble(double.nan).toBits(), 0x7E00); + }); + + test('Exact values', () { + expect(Float16(1.0).toDouble(), 1.0); + expect(Float16(-1.0).toDouble(), -1.0); + expect(Float16(1.5).toDouble(), 1.5); + expect(Float16(0.5).toDouble(), 0.5); + expect(Float16(65504.0).toDouble(), 65504.0); // Max Value + }); + + test('Rounding', () { + // 1.0 is 0x3C00. Next is 1 + 2^-10 = 1.0009765625 (0x3C01) + // Halfway is 1.00048828125 + + // Round down + expect(Float16.fromDouble(1.0004).toDouble(), 1.0); + + // Round up + expect(Float16.fromDouble(1.0006).toDouble(), 1.0009765625); + + // Tie to even (1.0 is even (last bit 0)) + // 1.0 + half_epsilon = 1.00048828125 + // 3C00 is even. 3C01 is odd. + // If result is exactly halfway, pick even. + // 1.0 corresponds to stored bits ...00 + + double one = 1.0; + double next = 1.0009765625; + double mid = (one + next) / 2; + + // 1.0 (0x3C00) is even. + expect(Float16.fromDouble(mid).toBits(), 0x3C00); // 1.0 + + // 1.0009765625 (0x3C01) is odd. + // Next is 1.001953125 (0x3C02) - even. + // Mid between 3C01 and 3C02 + double val1 = 1.0009765625; + double val2 = 1.001953125; + double mid2 = (val1 + val2) / 2; + expect(Float16.fromDouble(mid2).toBits(), 0x3C02); // Round to even (up) + }); + + test('Subnormal', () { + // Min subnormal: 2^-24 approx 5.96e-8 + double minSub = math.pow(2, -24).toDouble(); + expect(Float16.fromDouble(minSub).toDouble(), minSub); + expect(Float16.fromDouble(minSub).toBits(), 0x0001); + + // Below min subnormal -> 0 + expect(Float16.fromDouble(minSub / 2.1).toBits(), 0x0000); + // Round up to min subnormal + expect(Float16.fromDouble(minSub * 0.6).toBits(), 0x0001); + + // Max subnormal: 0x03FF = (1 - 2^-10) * 2^-14 + int maxSubBits = 0x03FF; + Float16 maxSub = Float16.fromBits(maxSubBits); + expect(maxSub.isSubnormal, true); + expect(Float16.fromDouble(maxSub.toDouble()).toBits(), maxSubBits); + }); + }); + + group('Float16 Arithmetic', () { + test('Add', () { + expect((Float16(1.0) + Float16(2.0)).toDouble(), 3.0); + expect((Float16(1.0) + 2.0).toDouble(), 3.0); + }); + test('Sub', () { + expect((Float16(3.0) - Float16(1.0)).toDouble(), 2.0); + }); + test('Mul', () { + expect((Float16(2.0) * Float16(3.0)).toDouble(), 6.0); + }); + test('Div', () { + expect((Float16(1.0) / Float16(2.0)), 0.5); + }); + test('Neg', () { + expect((-Float16(1.0)).toDouble(), -1.0); + }); + test('Abs', () { + expect(Float16(-1.0).abs().toDouble(), 1.0); + }); + }); + + group('Float16 Comparision', () { + test('Equality', () { + expect(Float16(1.0) == Float16(1.0), true); + expect(Float16(1.0) == Float16(2.0), false); + expect(Float16.nan == Float16.nan, true); // Bitwise equality + }); + + test('Less/Greater', () { + expect(Float16(1.0) < Float16(2.0), true); + expect(Float16(2.0) > Float16(1.0), true); + }); + }); + + group('Serialization', () { + test('RoundTrip', () { + var bw = ByteWriter(); + var f1 = Float16(1.234375); // 0x3D3C approx + var f2 = Float16(-100.0); + var f3 = Float16.nan; + var f4 = Float16.positiveInfinity; + + bw.writeFloat16(f1); + bw.writeFloat16(f2); + bw.writeFloat16(f3); + bw.writeFloat16(f4); + + var bytes = bw.toBytes(); + var br = ByteReader.forBytes(bytes); + + var r1 = br.readFloat16(); + var r2 = br.readFloat16(); + var r3 = br.readFloat16(); + var r4 = br.readFloat16(); + + expect(r1.toDouble(), f1.toDouble()); + expect(r2.toDouble(), f2.toDouble()); + expect(r3.isNaN, true); + expect(r4.isInfinite, true); + expect(r4.sign, 1); + }); + }); +} From b125a60623d8e1abab2dcaf367efaccf19e5ceba Mon Sep 17 00:00:00 2001 From: ayush00git Date: Fri, 13 Feb 2026 22:38:09 +0530 Subject: [PATCH 08/15] added FixedNum() method --- dart/packages/fory/lib/src/datatype/fory_fixed_num.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dart/packages/fory/lib/src/datatype/fory_fixed_num.dart b/dart/packages/fory/lib/src/datatype/fory_fixed_num.dart index d3f2ece2bc..2e1fead364 100644 --- a/dart/packages/fory/lib/src/datatype/fory_fixed_num.dart +++ b/dart/packages/fory/lib/src/datatype/fory_fixed_num.dart @@ -27,6 +27,8 @@ enum NumType { int8, int16, int32, float16, float32 } /// Base abstract class for fixed-size numeric types abstract base class FixedNum implements Comparable { + const FixedNum(); + num get value; // Factory constructor to create the appropriate type From 73dd9895d73257accd49e881165ee2236c4b4724 Mon Sep 17 00:00:00 2001 From: ayush00git Date: Fri, 13 Feb 2026 22:53:59 +0530 Subject: [PATCH 09/15] ci checks and xlang_tests updated --- .../test/cross_lang_test/xlang_test_defs.dart | 26 +++++++++---------- .../test/datatype_test/float16_test.dart | 22 ++++++++++++++-- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/dart/packages/fory-test/test/cross_lang_test/xlang_test_defs.dart b/dart/packages/fory-test/test/cross_lang_test/xlang_test_defs.dart index 51bfcf9b82..35804b0188 100644 --- a/dart/packages/fory-test/test/cross_lang_test/xlang_test_defs.dart +++ b/dart/packages/fory-test/test/cross_lang_test/xlang_test_defs.dart @@ -20,9 +20,9 @@ part of 'xlang_test_main.dart'; enum TestEnum { - VALUE_A, - VALUE_B, - VALUE_C, + valueA, + valueB, + valueC, } const EnumSpec _testEnumSpec = EnumSpec( @@ -31,8 +31,8 @@ const EnumSpec _testEnumSpec = EnumSpec( ); class TwoEnumFieldStructEvolution { - TestEnum f1 = TestEnum.VALUE_A; - TestEnum f2 = TestEnum.VALUE_A; + TestEnum f1 = TestEnum.valueA; + TestEnum f2 = TestEnum.valueA; } final TypeSpec _twoEnumFieldStructEvolutionSpec = TypeSpec( @@ -723,10 +723,10 @@ final TypeSpec _nullableComprehensiveCompatibleSpec = TypeSpec( ); enum Color { - Green, - Red, - Blue, - White, + green, + red, + blue, + white, } const EnumSpec _colorSpec = EnumSpec( @@ -761,7 +761,7 @@ class SimpleStruct { Int32 f2 = Int32(0); Item f3 = Item(); String f4 = ''; - Color f5 = Color.Green; + Color f5 = Color.green; List f6 = []; Int32 f7 = Int32(0); Int32 f8 = Int32(0); @@ -1117,7 +1117,7 @@ final TypeSpec _twoStringFieldStructSpec = TypeSpec( ); class OneEnumFieldStruct { - TestEnum f1 = TestEnum.VALUE_A; + TestEnum f1 = TestEnum.valueA; } final TypeSpec _oneEnumFieldStructSpec = TypeSpec( @@ -1141,8 +1141,8 @@ final TypeSpec _oneEnumFieldStructSpec = TypeSpec( ); class TwoEnumFieldStruct { - TestEnum f1 = TestEnum.VALUE_A; - TestEnum f2 = TestEnum.VALUE_A; + TestEnum f1 = TestEnum.valueA; + TestEnum f2 = TestEnum.valueA; } final TypeSpec _twoEnumFieldStructSpec = TypeSpec( diff --git a/dart/packages/fory-test/test/datatype_test/float16_test.dart b/dart/packages/fory-test/test/datatype_test/float16_test.dart index 54cd8773af..b96cffffe2 100644 --- a/dart/packages/fory-test/test/datatype_test/float16_test.dart +++ b/dart/packages/fory-test/test/datatype_test/float16_test.dart @@ -1,8 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// @Skip() import 'dart:math' as math; -import 'dart:typed_data'; import 'package:test/test.dart'; import 'package:fory/src/datatype/float16.dart'; -import 'package:fory/src/datatype/float32.dart'; import 'package:fory/src/memory/byte_writer.dart'; import 'package:fory/src/memory/byte_reader.dart'; From b91b2e4136e9e8d28867b5474a19ae3a708ea3d7 Mon Sep 17 00:00:00 2001 From: ayush00git Date: Fri, 13 Feb 2026 23:00:33 +0530 Subject: [PATCH 10/15] corrected char casing --- .../fory-test/test/cross_lang_test/xlang_test_main.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dart/packages/fory-test/test/cross_lang_test/xlang_test_main.dart b/dart/packages/fory-test/test/cross_lang_test/xlang_test_main.dart index 7d59be0c3f..64675dce39 100644 --- a/dart/packages/fory-test/test/cross_lang_test/xlang_test_main.dart +++ b/dart/packages/fory-test/test/cross_lang_test/xlang_test_main.dart @@ -65,8 +65,8 @@ void _runEnumSchemaEvolutionCompatibleReverse() { _registerStructType(fory, TwoEnumFieldStructEvolution, typeId: 211); final TwoEnumFieldStructEvolution obj = fory.deserialize(data) as TwoEnumFieldStructEvolution; - if (obj.f1 != TestEnum.VALUE_C) { - throw StateError('Expected f1=VALUE_C, got ${obj.f1}'); + if (obj.f1 != TestEnum.valueC) { + throw StateError('Expected f1=valueC, got ${obj.f1}'); } _writeFile(dataFile, fory.serialize(obj)); } From 5dc7a85799676aa583dacc0bc6114c69685b5f7b Mon Sep 17 00:00:00 2001 From: ayush00git Date: Fri, 13 Feb 2026 23:08:38 +0530 Subject: [PATCH 11/15] removed unused imports and override const --- .../packages/fory/lib/src/datatype/float16.dart | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/dart/packages/fory/lib/src/datatype/float16.dart b/dart/packages/fory/lib/src/datatype/float16.dart index fa1faffc6c..7fbf4145ef 100644 --- a/dart/packages/fory/lib/src/datatype/float16.dart +++ b/dart/packages/fory/lib/src/datatype/float16.dart @@ -25,9 +25,6 @@ import 'fory_fixed_num.dart'; import 'int16.dart' show Int16; import 'int32.dart' show Int32; import 'int8.dart' show Int8; -import 'uint8.dart' show UInt8; -import 'uint16.dart' show UInt16; -import 'uint32.dart' show UInt32; /// Float16: 16-bit floating point (IEEE 754 half precision) /// Wraps a 16-bit integer representing the IEEE 754 binary16 format. @@ -41,7 +38,6 @@ final class Float16 extends FixedNum { // --- Constants --- static const int _exponentBias = 15; static const int _maxExponent = 31; // 2^5 - 1 - static const int _mantissaBits = 10; // Bit placeholders static const int _signMask = 0x8000; @@ -219,7 +215,6 @@ final class Float16 extends FixedNum { int toBits() => _bits; /// Returns the value as a [double]. - @override double toDouble() => _bitsToDouble(_bits); /// Returns the underlying values as a [double]. @@ -275,44 +270,33 @@ final class Float16 extends FixedNum { // --- Operators (Delegation) --- - @override Float16 operator +(dynamic other) => add(other is Float16 ? other : Float16(other)); - @override Float16 operator -(dynamic other) => sub(other is Float16 ? other : Float16(other)); - @override Float16 operator *(dynamic other) => mul(other is Float16 ? other : Float16(other)); - @override double operator /(dynamic other) => toDouble() / (other is Float16 ? other.toDouble() : other); - @override Float16 operator ~/(dynamic other) => Float16((toDouble() ~/ (other is Float16 ? other.toDouble() : other))); - @override Float16 operator %(dynamic other) => Float16(toDouble() % (other is Float16 ? other.toDouble() : other)); - @override Float16 operator -() => neg(); // Comparison Operators - @override bool operator <(dynamic other) => toDouble() < (other is Float16 ? other.toDouble() : other); - @override bool operator <=(dynamic other) => toDouble() <= (other is Float16 ? other.toDouble() : other); - @override bool operator >(dynamic other) => toDouble() > (other is Float16 ? other.toDouble() : other); - @override bool operator >=(dynamic other) => toDouble() >= (other is Float16 ? other.toDouble() : other); @override @@ -326,7 +310,6 @@ final class Float16 extends FixedNum { // --- Type Conversions --- - @override int toInt() => toDouble().toInt(); Int8 toInt8() => Int8(toInt()); From 47a55d2043dd6a69ad27cf4aa999b828e5a542ff Mon Sep 17 00:00:00 2001 From: ayush00git Date: Sat, 14 Feb 2026 22:25:07 +0530 Subject: [PATCH 12/15] trigger ci checks From cb706d48f47099dfe289154c5b747bdbf69c623a Mon Sep 17 00:00:00 2001 From: ayush00git Date: Sun, 15 Feb 2026 12:02:43 +0530 Subject: [PATCH 13/15] trigger ci From 0eb61233fd52e5c75f537c0ca21d0e8bb48eae9b Mon Sep 17 00:00:00 2001 From: ayush00git Date: Tue, 17 Feb 2026 20:05:29 +0530 Subject: [PATCH 14/15] deleted xlang_test_defs.dart --- .../test/cross_lang_test/xlang_test_defs.dart | 1723 ----------------- 1 file changed, 1723 deletions(-) delete mode 100644 dart/packages/fory-test/test/cross_lang_test/xlang_test_defs.dart diff --git a/dart/packages/fory-test/test/cross_lang_test/xlang_test_defs.dart b/dart/packages/fory-test/test/cross_lang_test/xlang_test_defs.dart deleted file mode 100644 index 35804b0188..0000000000 --- a/dart/packages/fory-test/test/cross_lang_test/xlang_test_defs.dart +++ /dev/null @@ -1,1723 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -part of 'xlang_test_main.dart'; - -enum TestEnum { - valueA, - valueB, - valueC, -} - -const EnumSpec _testEnumSpec = EnumSpec( - TestEnum, - TestEnum.values, -); - -class TwoEnumFieldStructEvolution { - TestEnum f1 = TestEnum.valueA; - TestEnum f2 = TestEnum.valueA; -} - -final TypeSpec _twoEnumFieldStructEvolutionSpec = TypeSpec( - TwoEnumFieldStructEvolution, - false, - true, - [ - FieldSpec( - 'f1', - const FieldTypeSpec( - TestEnum, - ObjType.ENUM, - false, - true, - _testEnumSpec, - [], - ), - true, - true, - (Object inst) => (inst as TwoEnumFieldStructEvolution).f1, - (Object inst, dynamic v) => - (inst as TwoEnumFieldStructEvolution).f1 = v as TestEnum, - ), - FieldSpec( - 'f2', - const FieldTypeSpec( - TestEnum, - ObjType.ENUM, - false, - true, - _testEnumSpec, - [], - ), - false, - true, - (Object inst) => (inst as TwoEnumFieldStructEvolution).f2, - (Object inst, dynamic v) => - (inst as TwoEnumFieldStructEvolution).f2 = v as TestEnum, - ), - ], - null, - () => TwoEnumFieldStructEvolution(), -); - -class RefOverrideElement { - Int32 id = Int32(0); - String name = ''; -} - -class RefOverrideContainer { - List listField = []; - Map mapField = {}; -} - -final TypeSpec _refOverrideElementSpec = TypeSpec( - RefOverrideElement, - false, - true, - [ - FieldSpec( - 'id', - const FieldTypeSpec( - Int32, - ObjType.VAR_INT32, - false, - true, - null, - [], - ), - true, - true, - (Object inst) => (inst as RefOverrideElement).id, - (Object inst, dynamic v) => (inst as RefOverrideElement).id = v as Int32, - ), - FieldSpec( - 'name', - const FieldTypeSpec( - String, - ObjType.STRING, - false, - true, - null, - [], - ), - true, - true, - (Object inst) => (inst as RefOverrideElement).name, - (Object inst, dynamic v) => - (inst as RefOverrideElement).name = v as String, - ), - ], - null, - () => RefOverrideElement(), -); - -final TypeSpec _refOverrideContainerSpec = TypeSpec( - RefOverrideContainer, - false, - true, - [ - FieldSpec( - 'list_field', - const FieldTypeSpec( - List, - ObjType.LIST, - false, - false, - null, - [ - FieldTypeSpec( - RefOverrideElement, - ObjType.STRUCT, - false, - true, - null, - [], - ), - ], - ), - true, - true, - (Object inst) => (inst as RefOverrideContainer).listField, - (Object inst, dynamic v) => (inst as RefOverrideContainer).listField = - (v as List).cast(), - ), - FieldSpec( - 'map_field', - const FieldTypeSpec( - Map, - ObjType.MAP, - false, - false, - null, - [ - FieldTypeSpec( - String, - ObjType.STRING, - true, - true, - null, - [], - ), - FieldTypeSpec( - RefOverrideElement, - ObjType.STRUCT, - false, - true, - null, - [], - ), - ], - ), - true, - true, - (Object inst) => (inst as RefOverrideContainer).mapField, - (Object inst, dynamic v) => - (inst as RefOverrideContainer).mapField = (v as Map).map( - (Object? k, Object? value) => MapEntry( - k as String, - value as RefOverrideElement, - ), - ), - ), - ], - null, - () => RefOverrideContainer(), -); - -class NullableComprehensiveCompatible { - double boxedDouble = 0.0; - double doubleField = 0.0; - Float32 boxedFloat = Float32(0); - Float32 floatField = Float32(0); - Int16 shortField = Int16(0); - Int8 byteField = Int8(0); - bool boolField = false; - bool boxedBool = false; - int boxedLong = 0; - int longField = 0; - Int32 boxedInt = Int32(0); - Int32 intField = Int32(0); - - double nullableDouble1 = 0.0; - Float32 nullableFloat1 = Float32(0); - bool nullableBool1 = false; - int nullableLong1 = 0; - Int32 nullableInt1 = Int32(0); - - String nullableString2 = ''; - String stringField = ''; - List listField = []; - List nullableList2 = []; - Set nullableSet2 = {}; - Set setField = {}; - Map mapField = {}; - Map nullableMap2 = {}; -} - -Map _asStringMap(Object? value) { - if (value == null) { - return {}; - } - return (value as Map).map( - (Object? k, Object? v) => MapEntry(k as String, v as String), - ); -} - -final TypeSpec _nullableComprehensiveCompatibleSpec = TypeSpec( - NullableComprehensiveCompatible, - false, - true, - [ - FieldSpec( - 'boxed_double', - const FieldTypeSpec( - double, - ObjType.FLOAT64, - false, - true, - null, - [], - ), - true, - true, - (Object inst) => (inst as NullableComprehensiveCompatible).boxedDouble, - (Object inst, dynamic v) => - (inst as NullableComprehensiveCompatible).boxedDouble = v as double, - ), - FieldSpec( - 'double_field', - const FieldTypeSpec( - double, - ObjType.FLOAT64, - false, - true, - null, - [], - ), - true, - true, - (Object inst) => (inst as NullableComprehensiveCompatible).doubleField, - (Object inst, dynamic v) => - (inst as NullableComprehensiveCompatible).doubleField = v as double, - ), - FieldSpec( - 'boxed_float', - const FieldTypeSpec( - Float32, - ObjType.FLOAT32, - false, - true, - null, - [], - ), - true, - true, - (Object inst) => (inst as NullableComprehensiveCompatible).boxedFloat, - (Object inst, dynamic v) => - (inst as NullableComprehensiveCompatible).boxedFloat = v as Float32, - ), - FieldSpec( - 'float_field', - const FieldTypeSpec( - Float32, - ObjType.FLOAT32, - false, - true, - null, - [], - ), - true, - true, - (Object inst) => (inst as NullableComprehensiveCompatible).floatField, - (Object inst, dynamic v) => - (inst as NullableComprehensiveCompatible).floatField = v as Float32, - ), - FieldSpec( - 'short_field', - const FieldTypeSpec( - Int16, - ObjType.INT16, - false, - true, - null, - [], - ), - true, - true, - (Object inst) => (inst as NullableComprehensiveCompatible).shortField, - (Object inst, dynamic v) => - (inst as NullableComprehensiveCompatible).shortField = v as Int16, - ), - FieldSpec( - 'byte_field', - const FieldTypeSpec( - Int8, - ObjType.INT8, - false, - true, - null, - [], - ), - true, - true, - (Object inst) => (inst as NullableComprehensiveCompatible).byteField, - (Object inst, dynamic v) => - (inst as NullableComprehensiveCompatible).byteField = v as Int8, - ), - FieldSpec( - 'bool_field', - const FieldTypeSpec( - bool, - ObjType.BOOL, - false, - true, - null, - [], - ), - true, - true, - (Object inst) => (inst as NullableComprehensiveCompatible).boolField, - (Object inst, dynamic v) => - (inst as NullableComprehensiveCompatible).boolField = v as bool, - ), - FieldSpec( - 'boxed_bool', - const FieldTypeSpec( - bool, - ObjType.BOOL, - false, - true, - null, - [], - ), - true, - true, - (Object inst) => (inst as NullableComprehensiveCompatible).boxedBool, - (Object inst, dynamic v) => - (inst as NullableComprehensiveCompatible).boxedBool = v as bool, - ), - FieldSpec( - 'boxed_long', - const FieldTypeSpec( - int, - ObjType.VAR_INT64, - false, - true, - null, - [], - ), - true, - true, - (Object inst) => (inst as NullableComprehensiveCompatible).boxedLong, - (Object inst, dynamic v) => - (inst as NullableComprehensiveCompatible).boxedLong = v as int, - ), - FieldSpec( - 'long_field', - const FieldTypeSpec( - int, - ObjType.VAR_INT64, - false, - true, - null, - [], - ), - true, - true, - (Object inst) => (inst as NullableComprehensiveCompatible).longField, - (Object inst, dynamic v) => - (inst as NullableComprehensiveCompatible).longField = v as int, - ), - FieldSpec( - 'boxed_int', - const FieldTypeSpec( - Int32, - ObjType.VAR_INT32, - false, - true, - null, - [], - ), - true, - true, - (Object inst) => (inst as NullableComprehensiveCompatible).boxedInt, - (Object inst, dynamic v) => - (inst as NullableComprehensiveCompatible).boxedInt = v as Int32, - ), - FieldSpec( - 'int_field', - const FieldTypeSpec( - Int32, - ObjType.VAR_INT32, - false, - true, - null, - [], - ), - true, - true, - (Object inst) => (inst as NullableComprehensiveCompatible).intField, - (Object inst, dynamic v) => - (inst as NullableComprehensiveCompatible).intField = v as Int32, - ), - FieldSpec( - 'nullable_double1', - const FieldTypeSpec( - double, - ObjType.FLOAT64, - true, - true, - null, - [], - ), - true, - true, - (Object inst) => - (inst as NullableComprehensiveCompatible).nullableDouble1, - (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible) - .nullableDouble1 = (v as double?) ?? 0.0, - ), - FieldSpec( - 'nullable_float1', - const FieldTypeSpec( - Float32, - ObjType.FLOAT32, - true, - true, - null, - [], - ), - true, - true, - (Object inst) => (inst as NullableComprehensiveCompatible).nullableFloat1, - (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible) - .nullableFloat1 = (v as Float32?) ?? Float32(0), - ), - FieldSpec( - 'nullable_bool1', - const FieldTypeSpec( - bool, - ObjType.BOOL, - true, - true, - null, - [], - ), - true, - true, - (Object inst) => (inst as NullableComprehensiveCompatible).nullableBool1, - (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible) - .nullableBool1 = (v as bool?) ?? false, - ), - FieldSpec( - 'nullable_long1', - const FieldTypeSpec( - int, - ObjType.VAR_INT64, - true, - true, - null, - [], - ), - true, - true, - (Object inst) => (inst as NullableComprehensiveCompatible).nullableLong1, - (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible) - .nullableLong1 = (v as int?) ?? 0, - ), - FieldSpec( - 'nullable_int1', - const FieldTypeSpec( - Int32, - ObjType.VAR_INT32, - true, - true, - null, - [], - ), - true, - true, - (Object inst) => (inst as NullableComprehensiveCompatible).nullableInt1, - (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible) - .nullableInt1 = (v as Int32?) ?? Int32(0), - ), - FieldSpec( - 'nullable_string2', - const FieldTypeSpec( - String, - ObjType.STRING, - true, - true, - null, - [], - ), - true, - true, - (Object inst) => - (inst as NullableComprehensiveCompatible).nullableString2, - (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible) - .nullableString2 = (v as String?) ?? '', - ), - FieldSpec( - 'string_field', - const FieldTypeSpec( - String, - ObjType.STRING, - false, - true, - null, - [], - ), - true, - true, - (Object inst) => (inst as NullableComprehensiveCompatible).stringField, - (Object inst, dynamic v) => - (inst as NullableComprehensiveCompatible).stringField = v as String, - ), - FieldSpec( - 'list_field', - const FieldTypeSpec( - List, - ObjType.LIST, - false, - false, - null, - [ - FieldTypeSpec( - String, - ObjType.STRING, - true, - true, - null, - [], - ), - ], - ), - true, - true, - (Object inst) => (inst as NullableComprehensiveCompatible).listField, - (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible) - .listField = (v as List).cast(), - ), - FieldSpec( - 'nullable_list2', - const FieldTypeSpec( - List, - ObjType.LIST, - true, - false, - null, - [ - FieldTypeSpec( - String, - ObjType.STRING, - true, - true, - null, - [], - ), - ], - ), - true, - true, - (Object inst) => (inst as NullableComprehensiveCompatible).nullableList2, - (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible) - .nullableList2 = v == null ? [] : (v as List).cast(), - ), - FieldSpec( - 'nullable_set2', - const FieldTypeSpec( - Set, - ObjType.SET, - true, - false, - null, - [ - FieldTypeSpec( - String, - ObjType.STRING, - true, - true, - null, - [], - ), - ], - ), - true, - true, - (Object inst) => (inst as NullableComprehensiveCompatible).nullableSet2, - (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible) - .nullableSet2 = v == null ? {} : (v as Set).cast(), - ), - FieldSpec( - 'set_field', - const FieldTypeSpec( - Set, - ObjType.SET, - false, - false, - null, - [ - FieldTypeSpec( - String, - ObjType.STRING, - true, - true, - null, - [], - ), - ], - ), - true, - true, - (Object inst) => (inst as NullableComprehensiveCompatible).setField, - (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible) - .setField = (v as Set).cast(), - ), - FieldSpec( - 'map_field', - const FieldTypeSpec( - Map, - ObjType.MAP, - false, - false, - null, - [ - FieldTypeSpec( - String, - ObjType.STRING, - true, - true, - null, - [], - ), - FieldTypeSpec( - String, - ObjType.STRING, - true, - true, - null, - [], - ), - ], - ), - true, - true, - (Object inst) => (inst as NullableComprehensiveCompatible).mapField, - (Object inst, dynamic v) => - (inst as NullableComprehensiveCompatible).mapField = _asStringMap(v), - ), - FieldSpec( - 'nullable_map2', - const FieldTypeSpec( - Map, - ObjType.MAP, - true, - false, - null, - [ - FieldTypeSpec( - String, - ObjType.STRING, - true, - true, - null, - [], - ), - FieldTypeSpec( - String, - ObjType.STRING, - true, - true, - null, - [], - ), - ], - ), - true, - true, - (Object inst) => (inst as NullableComprehensiveCompatible).nullableMap2, - (Object inst, dynamic v) => (inst as NullableComprehensiveCompatible) - .nullableMap2 = _asStringMap(v), - ), - ], - null, - () => NullableComprehensiveCompatible(), -); - -enum Color { - green, - red, - blue, - white, -} - -const EnumSpec _colorSpec = EnumSpec( - Color, - Color.values, -); - -class Item { - String name = ''; -} - -final TypeSpec _itemSpec = TypeSpec( - Item, - false, - true, - [ - FieldSpec( - 'name', - const FieldTypeSpec(String, ObjType.STRING, false, true, null, []), - true, - true, - (Object inst) => (inst as Item).name, - (Object inst, dynamic v) => (inst as Item).name = v as String, - ), - ], - null, - () => Item(), -); - -class SimpleStruct { - Map f1 = {}; - Int32 f2 = Int32(0); - Item f3 = Item(); - String f4 = ''; - Color f5 = Color.green; - List f6 = []; - Int32 f7 = Int32(0); - Int32 f8 = Int32(0); - Int32 last = Int32(0); -} - -Map _asInt32DoubleMap(Object? value) { - if (value == null) { - return {}; - } - return (value as Map).map( - (Object? k, Object? v) => MapEntry(k as Int32, v as double), - ); -} - -final TypeSpec _simpleStructSpec = TypeSpec( - SimpleStruct, - false, - true, - [ - FieldSpec( - 'f1', - const FieldTypeSpec( - Map, - ObjType.MAP, - false, - false, - null, - [ - FieldTypeSpec(Int32, ObjType.VAR_INT32, true, true, null, []), - FieldTypeSpec(double, ObjType.FLOAT64, true, true, null, []), - ], - ), - true, - true, - (Object inst) => (inst as SimpleStruct).f1, - (Object inst, dynamic v) => - (inst as SimpleStruct).f1 = _asInt32DoubleMap(v), - ), - FieldSpec( - 'f2', - const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []), - true, - true, - (Object inst) => (inst as SimpleStruct).f2, - (Object inst, dynamic v) => (inst as SimpleStruct).f2 = v as Int32, - ), - FieldSpec( - 'f3', - const FieldTypeSpec(Item, ObjType.STRUCT, false, false, null, []), - true, - true, - (Object inst) => (inst as SimpleStruct).f3, - (Object inst, dynamic v) => (inst as SimpleStruct).f3 = v as Item, - ), - FieldSpec( - 'f4', - const FieldTypeSpec(String, ObjType.STRING, false, true, null, []), - true, - true, - (Object inst) => (inst as SimpleStruct).f4, - (Object inst, dynamic v) => (inst as SimpleStruct).f4 = v as String, - ), - FieldSpec( - 'f5', - const FieldTypeSpec(Color, ObjType.ENUM, false, true, _colorSpec, []), - true, - true, - (Object inst) => (inst as SimpleStruct).f5, - (Object inst, dynamic v) => (inst as SimpleStruct).f5 = v as Color, - ), - FieldSpec( - 'f6', - const FieldTypeSpec( - List, - ObjType.LIST, - false, - false, - null, - [ - FieldTypeSpec(String, ObjType.STRING, true, true, null, []), - ], - ), - true, - true, - (Object inst) => (inst as SimpleStruct).f6, - (Object inst, dynamic v) => - (inst as SimpleStruct).f6 = (v as List).cast(), - ), - FieldSpec( - 'f7', - const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []), - true, - true, - (Object inst) => (inst as SimpleStruct).f7, - (Object inst, dynamic v) => (inst as SimpleStruct).f7 = v as Int32, - ), - FieldSpec( - 'f8', - const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []), - true, - true, - (Object inst) => (inst as SimpleStruct).f8, - (Object inst, dynamic v) => (inst as SimpleStruct).f8 = v as Int32, - ), - FieldSpec( - 'last', - const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []), - true, - true, - (Object inst) => (inst as SimpleStruct).last, - (Object inst, dynamic v) => (inst as SimpleStruct).last = v as Int32, - ), - ], - null, - () => SimpleStruct(), -); - -class Item1 { - Int32 f1 = Int32(0); - Int32 f2 = Int32(0); - Int32 f3 = Int32(0); - Int32 f4 = Int32(0); - Int32 f5 = Int32(0); - Int32 f6 = Int32(0); -} - -final TypeSpec _item1Spec = TypeSpec( - Item1, - false, - true, - [ - FieldSpec( - 'f1', - const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []), - true, - true, - (Object inst) => (inst as Item1).f1, - (Object inst, dynamic v) => (inst as Item1).f1 = v as Int32, - ), - FieldSpec( - 'f2', - const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []), - true, - true, - (Object inst) => (inst as Item1).f2, - (Object inst, dynamic v) => (inst as Item1).f2 = v as Int32, - ), - FieldSpec( - 'f3', - const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []), - true, - true, - (Object inst) => (inst as Item1).f3, - (Object inst, dynamic v) => (inst as Item1).f3 = v as Int32, - ), - FieldSpec( - 'f4', - const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []), - true, - true, - (Object inst) => (inst as Item1).f4, - (Object inst, dynamic v) => (inst as Item1).f4 = v as Int32, - ), - FieldSpec( - 'f5', - const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []), - true, - true, - (Object inst) => (inst as Item1).f5, - (Object inst, dynamic v) => (inst as Item1).f5 = v as Int32, - ), - FieldSpec( - 'f6', - const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []), - true, - true, - (Object inst) => (inst as Item1).f6, - (Object inst, dynamic v) => (inst as Item1).f6 = v as Int32, - ), - ], - null, - () => Item1(), -); - -class StructWithList { - List items = []; -} - -final TypeSpec _structWithListSpec = TypeSpec( - StructWithList, - false, - true, - [ - FieldSpec( - 'items', - const FieldTypeSpec( - List, - ObjType.LIST, - false, - false, - null, - [FieldTypeSpec(String, ObjType.STRING, true, true, null, [])], - ), - true, - true, - (Object inst) => (inst as StructWithList).items, - (Object inst, dynamic v) => - (inst as StructWithList).items = (v as List).cast(), - ), - ], - null, - () => StructWithList(), -); - -class StructWithMap { - Map data = {}; -} - -Map _asNullableStringMap(Object? value) { - if (value == null) { - return {}; - } - return (value as Map).map( - (Object? k, Object? v) => MapEntry(k as String?, v as String?), - ); -} - -final TypeSpec _structWithMapSpec = TypeSpec( - StructWithMap, - false, - true, - [ - FieldSpec( - 'data', - const FieldTypeSpec( - Map, - ObjType.MAP, - false, - false, - null, - [ - FieldTypeSpec(String, ObjType.STRING, true, true, null, []), - FieldTypeSpec(String, ObjType.STRING, true, true, null, []), - ], - ), - true, - true, - (Object inst) => (inst as StructWithMap).data, - (Object inst, dynamic v) => - (inst as StructWithMap).data = _asNullableStringMap(v), - ), - ], - null, - () => StructWithMap(), -); - -class VersionCheckStruct { - Int32 f1 = Int32(0); - String f2 = ''; - double f3 = 0.0; -} - -final TypeSpec _versionCheckStructSpec = TypeSpec( - VersionCheckStruct, - false, - true, - [ - FieldSpec( - 'f1', - const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []), - true, - true, - (Object inst) => (inst as VersionCheckStruct).f1, - (Object inst, dynamic v) => (inst as VersionCheckStruct).f1 = v as Int32, - ), - FieldSpec( - 'f2', - const FieldTypeSpec(String, ObjType.STRING, true, true, null, []), - true, - true, - (Object inst) => (inst as VersionCheckStruct).f2, - (Object inst, dynamic v) => - (inst as VersionCheckStruct).f2 = (v as String?) ?? '', - ), - FieldSpec( - 'f3', - const FieldTypeSpec(double, ObjType.FLOAT64, false, true, null, []), - true, - true, - (Object inst) => (inst as VersionCheckStruct).f3, - (Object inst, dynamic v) => (inst as VersionCheckStruct).f3 = v as double, - ), - ], - null, - () => VersionCheckStruct(), -); - -class OneStringFieldStruct { - String f1 = ''; -} - -final TypeSpec _oneStringFieldStructSpec = TypeSpec( - OneStringFieldStruct, - false, - true, - [ - FieldSpec( - 'f1', - const FieldTypeSpec(String, ObjType.STRING, true, true, null, []), - true, - true, - (Object inst) => (inst as OneStringFieldStruct).f1, - (Object inst, dynamic v) => - (inst as OneStringFieldStruct).f1 = (v as String?) ?? '', - ), - ], - null, - () => OneStringFieldStruct(), -); - -class TwoStringFieldStruct { - String f1 = ''; - String f2 = ''; -} - -final TypeSpec _twoStringFieldStructSpec = TypeSpec( - TwoStringFieldStruct, - false, - true, - [ - FieldSpec( - 'f1', - const FieldTypeSpec(String, ObjType.STRING, false, true, null, []), - true, - true, - (Object inst) => (inst as TwoStringFieldStruct).f1, - (Object inst, dynamic v) => - (inst as TwoStringFieldStruct).f1 = v as String, - ), - FieldSpec( - 'f2', - const FieldTypeSpec(String, ObjType.STRING, false, true, null, []), - true, - true, - (Object inst) => (inst as TwoStringFieldStruct).f2, - (Object inst, dynamic v) => - (inst as TwoStringFieldStruct).f2 = v as String, - ), - ], - null, - () => TwoStringFieldStruct(), -); - -class OneEnumFieldStruct { - TestEnum f1 = TestEnum.valueA; -} - -final TypeSpec _oneEnumFieldStructSpec = TypeSpec( - OneEnumFieldStruct, - false, - true, - [ - FieldSpec( - 'f1', - const FieldTypeSpec( - TestEnum, ObjType.ENUM, false, true, _testEnumSpec, []), - true, - true, - (Object inst) => (inst as OneEnumFieldStruct).f1, - (Object inst, dynamic v) => - (inst as OneEnumFieldStruct).f1 = v as TestEnum, - ), - ], - null, - () => OneEnumFieldStruct(), -); - -class TwoEnumFieldStruct { - TestEnum f1 = TestEnum.valueA; - TestEnum f2 = TestEnum.valueA; -} - -final TypeSpec _twoEnumFieldStructSpec = TypeSpec( - TwoEnumFieldStruct, - false, - true, - [ - FieldSpec( - 'f1', - const FieldTypeSpec( - TestEnum, ObjType.ENUM, false, true, _testEnumSpec, []), - true, - true, - (Object inst) => (inst as TwoEnumFieldStruct).f1, - (Object inst, dynamic v) => - (inst as TwoEnumFieldStruct).f1 = v as TestEnum, - ), - FieldSpec( - 'f2', - const FieldTypeSpec( - TestEnum, ObjType.ENUM, false, true, _testEnumSpec, []), - true, - true, - (Object inst) => (inst as TwoEnumFieldStruct).f2, - (Object inst, dynamic v) => - (inst as TwoEnumFieldStruct).f2 = v as TestEnum, - ), - ], - null, - () => TwoEnumFieldStruct(), -); - -class NullableComprehensiveSchemaConsistent { - Int8 byteField = Int8(0); - Int16 shortField = Int16(0); - Int32 intField = Int32(0); - int longField = 0; - Float32 floatField = Float32(0); - double doubleField = 0.0; - bool boolField = false; - String stringField = ''; - List listField = []; - Set setField = {}; - Map mapField = {}; - Int32? nullableInt; - int? nullableLong; - Float32? nullableFloat; - double? nullableDouble; - bool? nullableBool; - String? nullableString; - List? nullableList; - Set? nullableSet; - Map? nullableMap; -} - -final TypeSpec _nullableComprehensiveSchemaConsistentSpec = TypeSpec( - NullableComprehensiveSchemaConsistent, - false, - true, - [ - FieldSpec( - 'byte_field', - const FieldTypeSpec(Int8, ObjType.INT8, false, true, null, []), - true, - true, - (Object inst) => - (inst as NullableComprehensiveSchemaConsistent).byteField, - (Object inst, dynamic v) => - (inst as NullableComprehensiveSchemaConsistent).byteField = v as Int8, - ), - FieldSpec( - 'short_field', - const FieldTypeSpec(Int16, ObjType.INT16, false, true, null, []), - true, - true, - (Object inst) => - (inst as NullableComprehensiveSchemaConsistent).shortField, - (Object inst, dynamic v) => - (inst as NullableComprehensiveSchemaConsistent).shortField = - v as Int16, - ), - FieldSpec( - 'int_field', - const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []), - true, - true, - (Object inst) => (inst as NullableComprehensiveSchemaConsistent).intField, - (Object inst, dynamic v) => - (inst as NullableComprehensiveSchemaConsistent).intField = v as Int32, - ), - FieldSpec( - 'long_field', - const FieldTypeSpec(int, ObjType.VAR_INT64, false, true, null, []), - true, - true, - (Object inst) => - (inst as NullableComprehensiveSchemaConsistent).longField, - (Object inst, dynamic v) => - (inst as NullableComprehensiveSchemaConsistent).longField = v as int, - ), - FieldSpec( - 'float_field', - const FieldTypeSpec(Float32, ObjType.FLOAT32, false, true, null, []), - true, - true, - (Object inst) => - (inst as NullableComprehensiveSchemaConsistent).floatField, - (Object inst, dynamic v) => - (inst as NullableComprehensiveSchemaConsistent).floatField = - v as Float32, - ), - FieldSpec( - 'double_field', - const FieldTypeSpec(double, ObjType.FLOAT64, false, true, null, []), - true, - true, - (Object inst) => - (inst as NullableComprehensiveSchemaConsistent).doubleField, - (Object inst, dynamic v) => - (inst as NullableComprehensiveSchemaConsistent).doubleField = - v as double, - ), - FieldSpec( - 'bool_field', - const FieldTypeSpec(bool, ObjType.BOOL, false, true, null, []), - true, - true, - (Object inst) => - (inst as NullableComprehensiveSchemaConsistent).boolField, - (Object inst, dynamic v) => - (inst as NullableComprehensiveSchemaConsistent).boolField = v as bool, - ), - FieldSpec( - 'string_field', - const FieldTypeSpec(String, ObjType.STRING, false, true, null, []), - true, - true, - (Object inst) => - (inst as NullableComprehensiveSchemaConsistent).stringField, - (Object inst, dynamic v) => - (inst as NullableComprehensiveSchemaConsistent).stringField = - v as String, - ), - FieldSpec( - 'list_field', - const FieldTypeSpec( - List, - ObjType.LIST, - false, - false, - null, - [FieldTypeSpec(String, ObjType.STRING, true, true, null, [])], - ), - true, - true, - (Object inst) => - (inst as NullableComprehensiveSchemaConsistent).listField, - (Object inst, dynamic v) => - (inst as NullableComprehensiveSchemaConsistent).listField = - (v as List).cast(), - ), - FieldSpec( - 'set_field', - const FieldTypeSpec( - Set, - ObjType.SET, - false, - false, - null, - [FieldTypeSpec(String, ObjType.STRING, true, true, null, [])], - ), - true, - true, - (Object inst) => (inst as NullableComprehensiveSchemaConsistent).setField, - (Object inst, dynamic v) => - (inst as NullableComprehensiveSchemaConsistent).setField = - (v as Set).cast(), - ), - FieldSpec( - 'map_field', - const FieldTypeSpec( - Map, - ObjType.MAP, - false, - false, - null, - [ - FieldTypeSpec(String, ObjType.STRING, true, true, null, []), - FieldTypeSpec(String, ObjType.STRING, true, true, null, []), - ], - ), - true, - true, - (Object inst) => (inst as NullableComprehensiveSchemaConsistent).mapField, - (Object inst, dynamic v) => - (inst as NullableComprehensiveSchemaConsistent).mapField = - _asStringMap(v), - ), - FieldSpec( - 'nullable_int', - const FieldTypeSpec(Int32, ObjType.VAR_INT32, true, true, null, []), - true, - true, - (Object inst) => - (inst as NullableComprehensiveSchemaConsistent).nullableInt, - (Object inst, dynamic v) => - (inst as NullableComprehensiveSchemaConsistent).nullableInt = - v as Int32?, - ), - FieldSpec( - 'nullable_long', - const FieldTypeSpec(int, ObjType.VAR_INT64, true, true, null, []), - true, - true, - (Object inst) => - (inst as NullableComprehensiveSchemaConsistent).nullableLong, - (Object inst, dynamic v) => - (inst as NullableComprehensiveSchemaConsistent).nullableLong = - v as int?, - ), - FieldSpec( - 'nullable_float', - const FieldTypeSpec(Float32, ObjType.FLOAT32, true, true, null, []), - true, - true, - (Object inst) => - (inst as NullableComprehensiveSchemaConsistent).nullableFloat, - (Object inst, dynamic v) => - (inst as NullableComprehensiveSchemaConsistent).nullableFloat = - v as Float32?, - ), - FieldSpec( - 'nullable_double', - const FieldTypeSpec(double, ObjType.FLOAT64, true, true, null, []), - true, - true, - (Object inst) => - (inst as NullableComprehensiveSchemaConsistent).nullableDouble, - (Object inst, dynamic v) => - (inst as NullableComprehensiveSchemaConsistent).nullableDouble = - v as double?, - ), - FieldSpec( - 'nullable_bool', - const FieldTypeSpec(bool, ObjType.BOOL, true, true, null, []), - true, - true, - (Object inst) => - (inst as NullableComprehensiveSchemaConsistent).nullableBool, - (Object inst, dynamic v) => - (inst as NullableComprehensiveSchemaConsistent).nullableBool = - v as bool?, - ), - FieldSpec( - 'nullable_string', - const FieldTypeSpec(String, ObjType.STRING, true, true, null, []), - true, - true, - (Object inst) => - (inst as NullableComprehensiveSchemaConsistent).nullableString, - (Object inst, dynamic v) => - (inst as NullableComprehensiveSchemaConsistent).nullableString = - v as String?, - ), - FieldSpec( - 'nullable_list', - const FieldTypeSpec( - List, - ObjType.LIST, - true, - false, - null, - [FieldTypeSpec(String, ObjType.STRING, true, true, null, [])], - ), - true, - true, - (Object inst) => - (inst as NullableComprehensiveSchemaConsistent).nullableList, - (Object inst, dynamic v) => - (inst as NullableComprehensiveSchemaConsistent).nullableList = - v == null ? null : (v as List).cast(), - ), - FieldSpec( - 'nullable_set', - const FieldTypeSpec( - Set, - ObjType.SET, - true, - false, - null, - [FieldTypeSpec(String, ObjType.STRING, true, true, null, [])], - ), - true, - true, - (Object inst) => - (inst as NullableComprehensiveSchemaConsistent).nullableSet, - (Object inst, dynamic v) => - (inst as NullableComprehensiveSchemaConsistent).nullableSet = - v == null ? null : (v as Set).cast(), - ), - FieldSpec( - 'nullable_map', - const FieldTypeSpec( - Map, - ObjType.MAP, - true, - false, - null, - [ - FieldTypeSpec(String, ObjType.STRING, true, true, null, []), - FieldTypeSpec(String, ObjType.STRING, true, true, null, []), - ], - ), - true, - true, - (Object inst) => - (inst as NullableComprehensiveSchemaConsistent).nullableMap, - (Object inst, dynamic v) => - (inst as NullableComprehensiveSchemaConsistent).nullableMap = - v == null ? null : _asStringMap(v), - ), - ], - null, - () => NullableComprehensiveSchemaConsistent(), -); - -class RefInnerSchemaConsistent { - Int32 id = Int32(0); - String name = ''; -} - -class RefOuterSchemaConsistent { - RefInnerSchemaConsistent? inner1; - RefInnerSchemaConsistent? inner2; -} - -final TypeSpec _refInnerSchemaConsistentSpec = TypeSpec( - RefInnerSchemaConsistent, - false, - true, - [ - FieldSpec( - 'id', - const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []), - true, - true, - (Object inst) => (inst as RefInnerSchemaConsistent).id, - (Object inst, dynamic v) => - (inst as RefInnerSchemaConsistent).id = v as Int32, - ), - FieldSpec( - 'name', - const FieldTypeSpec(String, ObjType.STRING, false, true, null, []), - true, - true, - (Object inst) => (inst as RefInnerSchemaConsistent).name, - (Object inst, dynamic v) => - (inst as RefInnerSchemaConsistent).name = v as String, - ), - ], - null, - () => RefInnerSchemaConsistent(), -); - -final TypeSpec _refOuterSchemaConsistentSpec = TypeSpec( - RefOuterSchemaConsistent, - false, - true, - [ - FieldSpec( - 'inner1', - const FieldTypeSpec( - RefInnerSchemaConsistent, - ObjType.STRUCT, - true, - true, - null, - [], - ), - true, - true, - (Object inst) => (inst as RefOuterSchemaConsistent).inner1, - (Object inst, dynamic v) => (inst as RefOuterSchemaConsistent).inner1 = - v as RefInnerSchemaConsistent?, - trackingRef: true, - ), - FieldSpec( - 'inner2', - const FieldTypeSpec( - RefInnerSchemaConsistent, - ObjType.STRUCT, - true, - true, - null, - [], - ), - true, - true, - (Object inst) => (inst as RefOuterSchemaConsistent).inner2, - (Object inst, dynamic v) => (inst as RefOuterSchemaConsistent).inner2 = - v as RefInnerSchemaConsistent?, - trackingRef: true, - ), - ], - null, - () => RefOuterSchemaConsistent(), -); - -class RefInnerCompatible { - Int32 id = Int32(0); - String name = ''; -} - -class RefOuterCompatible { - RefInnerCompatible? inner1; - RefInnerCompatible? inner2; -} - -final TypeSpec _refInnerCompatibleSpec = TypeSpec( - RefInnerCompatible, - false, - true, - [ - FieldSpec( - 'id', - const FieldTypeSpec(Int32, ObjType.VAR_INT32, false, true, null, []), - true, - true, - (Object inst) => (inst as RefInnerCompatible).id, - (Object inst, dynamic v) => (inst as RefInnerCompatible).id = v as Int32, - ), - FieldSpec( - 'name', - const FieldTypeSpec(String, ObjType.STRING, false, true, null, []), - true, - true, - (Object inst) => (inst as RefInnerCompatible).name, - (Object inst, dynamic v) => - (inst as RefInnerCompatible).name = v as String, - ), - ], - null, - () => RefInnerCompatible(), -); - -final TypeSpec _refOuterCompatibleSpec = TypeSpec( - RefOuterCompatible, - false, - true, - [ - FieldSpec( - 'inner1', - const FieldTypeSpec( - RefInnerCompatible, ObjType.STRUCT, true, false, null, []), - true, - true, - (Object inst) => (inst as RefOuterCompatible).inner1, - (Object inst, dynamic v) => - (inst as RefOuterCompatible).inner1 = v as RefInnerCompatible?, - trackingRef: true, - ), - FieldSpec( - 'inner2', - const FieldTypeSpec( - RefInnerCompatible, ObjType.STRUCT, true, false, null, []), - true, - true, - (Object inst) => (inst as RefOuterCompatible).inner2, - (Object inst, dynamic v) => - (inst as RefOuterCompatible).inner2 = v as RefInnerCompatible?, - trackingRef: true, - ), - ], - null, - () => RefOuterCompatible(), -); - -class CircularRefStruct { - String name = ''; - CircularRefStruct? selfRef; -} - -final TypeSpec _circularRefStructSpec = TypeSpec( - CircularRefStruct, - false, - false, - [ - FieldSpec( - 'name', - const FieldTypeSpec(String, ObjType.STRING, false, true, null, []), - true, - true, - (Object inst) => (inst as CircularRefStruct).name, - (Object inst, dynamic v) => - (inst as CircularRefStruct).name = v as String, - ), - FieldSpec( - 'self_ref', - const FieldTypeSpec( - CircularRefStruct, ObjType.STRUCT, true, true, null, []), - true, - true, - (Object inst) => (inst as CircularRefStruct).selfRef, - (Object inst, dynamic v) => - (inst as CircularRefStruct).selfRef = v as CircularRefStruct?, - trackingRef: true, - ), - ], - null, - () => CircularRefStruct(), -); - -final Map _structSpecByType = { - TwoEnumFieldStructEvolution: _twoEnumFieldStructEvolutionSpec, - RefOverrideElement: _refOverrideElementSpec, - RefOverrideContainer: _refOverrideContainerSpec, - NullableComprehensiveCompatible: _nullableComprehensiveCompatibleSpec, - Item: _itemSpec, - SimpleStruct: _simpleStructSpec, - Item1: _item1Spec, - StructWithList: _structWithListSpec, - StructWithMap: _structWithMapSpec, - VersionCheckStruct: _versionCheckStructSpec, - OneStringFieldStruct: _oneStringFieldStructSpec, - TwoStringFieldStruct: _twoStringFieldStructSpec, - OneEnumFieldStruct: _oneEnumFieldStructSpec, - TwoEnumFieldStruct: _twoEnumFieldStructSpec, - NullableComprehensiveSchemaConsistent: - _nullableComprehensiveSchemaConsistentSpec, - RefInnerSchemaConsistent: _refInnerSchemaConsistentSpec, - RefOuterSchemaConsistent: _refOuterSchemaConsistentSpec, - RefInnerCompatible: _refInnerCompatibleSpec, - RefOuterCompatible: _refOuterCompatibleSpec, - CircularRefStruct: _circularRefStructSpec, -}; - -final Map _enumSpecByType = { - TestEnum: _testEnumSpec, - Color: _colorSpec, -}; - -void _registerStructType( - Fory fory, - Type type, { - int? typeId, - String? namespace, - String? typename, -}) { - final TypeSpec? spec = _structSpecByType[type]; - if (spec == null) { - throw StateError('No struct spec registered for $type'); - } - fory.registerStruct( - spec, - typeId: typeId, - namespace: namespace, - typename: typename, - ); -} - -void _registerEnumType( - Fory fory, - Type type, { - int? typeId, - String? namespace, - String? typename, -}) { - final EnumSpec? spec = _enumSpecByType[type]; - if (spec == null) { - throw StateError('No enum spec registered for $type'); - } - fory.registerEnum( - spec, - typeId: typeId, - namespace: namespace, - typename: typename, - ); -} From 67c8eb34038f16a2c13bd2ca191264a58b9c1b8b Mon Sep 17 00:00:00 2001 From: ayush00git Date: Tue, 17 Feb 2026 22:06:25 +0530 Subject: [PATCH 15/15] added SpecLook in packages to avoid src/ --- .../lib/entity/xlang_test_models.dart | 27 +++++++++---------- dart/packages/fory/lib/fory.dart | 1 + 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/dart/packages/fory-test/lib/entity/xlang_test_models.dart b/dart/packages/fory-test/lib/entity/xlang_test_models.dart index 6f9aef9b96..41f67225d5 100644 --- a/dart/packages/fory-test/lib/entity/xlang_test_models.dart +++ b/dart/packages/fory-test/lib/entity/xlang_test_models.dart @@ -18,7 +18,6 @@ */ import 'package:fory/fory.dart'; -import 'package:fory/src/resolver/spec_lookup.dart'; part '../generated/xlang_test_models.g.dart'; @@ -87,17 +86,17 @@ void registerXlangEnum( @foryEnum enum TestEnum { - VALUE_A, - VALUE_B, - VALUE_C, + valueA, + valueB, + valueC, } @foryClass class TwoEnumFieldStructEvolution { - TestEnum f1 = TestEnum.VALUE_A; + TestEnum f1 = TestEnum.valueA; @ForyKey(includeFromFory: false) - TestEnum f2 = TestEnum.VALUE_A; + TestEnum f2 = TestEnum.valueA; } @foryClass @@ -157,10 +156,10 @@ class NullableComprehensiveCompatible { @foryEnum enum Color { - Green, - Red, - Blue, - White, + green, + red, + blue, + white, } @foryClass @@ -174,7 +173,7 @@ class SimpleStruct { Int32 f2 = Int32(0); Item f3 = Item(); String f4 = ''; - Color f5 = Color.Green; + Color f5 = Color.green; List f6 = []; Int32 f7 = Int32(0); Int32 f8 = Int32(0); @@ -221,13 +220,13 @@ class TwoStringFieldStruct { @foryClass class OneEnumFieldStruct { - TestEnum f1 = TestEnum.VALUE_A; + TestEnum f1 = TestEnum.valueA; } @foryClass class TwoEnumFieldStruct { - TestEnum f1 = TestEnum.VALUE_A; - TestEnum f2 = TestEnum.VALUE_A; + TestEnum f1 = TestEnum.valueA; + TestEnum f2 = TestEnum.valueA; } @foryClass diff --git a/dart/packages/fory/lib/fory.dart b/dart/packages/fory/lib/fory.dart index 9f795ad15d..ba5526ca23 100644 --- a/dart/packages/fory/lib/fory.dart +++ b/dart/packages/fory/lib/fory.dart @@ -40,6 +40,7 @@ export 'src/config/fory_config.dart'; // Constants export 'src/const/types.dart'; +export 'src/resolver/spec_lookup.dart'; // User-related export 'src/fory_type_provider.dart';