From 25036744225189bd45f7784c7488d242e3362da2 Mon Sep 17 00:00:00 2001 From: kafkiansky Date: Fri, 30 Aug 2024 15:19:56 +0300 Subject: [PATCH] Implement defaults --- Internal/Label/LabelDefault.php | 51 ------------------- Internal/Label/Labels.php | 1 - .../Reflection/ArrayPropertyMarshaller.php | 1 - .../ArrayShapePropertyMarshaller.php | 1 - .../ConstantEnumPropertyMarshaller.php | 1 - .../Reflection/EnumPropertyMarshaller.php | 2 - .../HashTablePropertyMarshaller.php | 1 - .../PropertyDeserializeDescriptor.php | 17 ++----- Internal/Reflection/ProtobufReflector.php | 16 +++++- .../Reflection/StructPropertyMarshaller.php | 1 - Internal/Type/BoolType.php | 1 - Internal/Type/DoubleType.php | 1 - Internal/Type/DurationType.php | 4 +- Internal/Type/Fixed32Type.php | 1 - Internal/Type/Fixed64Type.php | 1 - Internal/Type/FloatType.php | 1 - Internal/Type/SFixed32Type.php | 1 - Internal/Type/SFixed64Type.php | 1 - Internal/Type/SInt32Type.php | 1 - Internal/Type/SInt64Type.php | 1 - Internal/Type/StringType.php | 1 - Internal/Type/TimestampType.php | 4 +- Internal/Type/ValueType.php | 4 +- Internal/Type/VarintType.php | 1 - Internal/Wire/ProtobufMarshaller.php | 2 +- 25 files changed, 24 insertions(+), 93 deletions(-) delete mode 100644 Internal/Label/LabelDefault.php diff --git a/Internal/Label/LabelDefault.php b/Internal/Label/LabelDefault.php deleted file mode 100644 index abe7043..0000000 --- a/Internal/Label/LabelDefault.php +++ /dev/null @@ -1,51 +0,0 @@ - - */ -enum LabelDefault implements OptionalKey -{ - case key; - - /** - * {@inheritdoc} - */ - public function default(TypedMap $map): mixed - { - return null; // @phpstan-ignore-line - } -} diff --git a/Internal/Label/Labels.php b/Internal/Label/Labels.php index 6569017..2dd98ab 100644 --- a/Internal/Label/Labels.php +++ b/Internal/Label/Labels.php @@ -36,7 +36,6 @@ */ enum Labels { - public const default = LabelDefault::key; public const wireType = LabelWireType::key; public const schemaType = LabelSchemaType::key; public const packed = LabelPacked::key; diff --git a/Internal/Reflection/ArrayPropertyMarshaller.php b/Internal/Reflection/ArrayPropertyMarshaller.php index 6c99dc8..9d62913 100644 --- a/Internal/Reflection/ArrayPropertyMarshaller.php +++ b/Internal/Reflection/ArrayPropertyMarshaller.php @@ -118,7 +118,6 @@ public function labels(): TypedMap } return $labels - ->with(Labels::default, []) ->with(Labels::isEmpty, static fn (array $values): bool => [] === $values) ->with(Labels::serializeTag, false) ; diff --git a/Internal/Reflection/ArrayShapePropertyMarshaller.php b/Internal/Reflection/ArrayShapePropertyMarshaller.php index 17e547a..ac37cc9 100644 --- a/Internal/Reflection/ArrayShapePropertyMarshaller.php +++ b/Internal/Reflection/ArrayShapePropertyMarshaller.php @@ -118,7 +118,6 @@ public function matchValue(mixed $value): bool public function labels(): TypedMap { return Labels::new(Wire\Type::BYTES) - ->with(Labels::default, []) ->with(Labels::isEmpty, static fn (array $values): bool => [] === $values) ->with(Labels::serializeTag, false) ; diff --git a/Internal/Reflection/ConstantEnumPropertyMarshaller.php b/Internal/Reflection/ConstantEnumPropertyMarshaller.php index 1e7ef59..ea9bcae 100644 --- a/Internal/Reflection/ConstantEnumPropertyMarshaller.php +++ b/Internal/Reflection/ConstantEnumPropertyMarshaller.php @@ -101,7 +101,6 @@ public function matchValue(mixed $value): bool public function labels(): TypedMap { return $this->type->labels() - ->with(Labels::default, 0) ->with(Labels::isEmpty, static fn (int $variant): bool => 0 === $variant) ; } diff --git a/Internal/Reflection/EnumPropertyMarshaller.php b/Internal/Reflection/EnumPropertyMarshaller.php index 0bb3007..b993320 100644 --- a/Internal/Reflection/EnumPropertyMarshaller.php +++ b/Internal/Reflection/EnumPropertyMarshaller.php @@ -29,7 +29,6 @@ use Prototype\Byte; use Prototype\Serializer\Exception\EnumDoesNotContainVariant; -use Prototype\Serializer\Exception\EnumDoesNotContainZeroVariant; use Prototype\Serializer\Internal\Label\Labels; use Prototype\Serializer\Internal\Type\TypeSerializer; use Prototype\Serializer\Internal\Type\VarintType; @@ -89,7 +88,6 @@ public function matchValue(mixed $value): bool public function labels(): TypedMap { return $this->type->labels() - ->with(Labels::default, $this->enumName::tryFrom(0) ?: throw new EnumDoesNotContainZeroVariant($this->enumName)) ->with(Labels::isEmpty, static fn (\BackedEnum $enum): bool => 0 === $enum->value) ; } diff --git a/Internal/Reflection/HashTablePropertyMarshaller.php b/Internal/Reflection/HashTablePropertyMarshaller.php index cec6a49..613fbc8 100644 --- a/Internal/Reflection/HashTablePropertyMarshaller.php +++ b/Internal/Reflection/HashTablePropertyMarshaller.php @@ -125,7 +125,6 @@ public function matchValue(mixed $value): bool public function labels(): TypedMap { return Labels::new(Wire\Type::BYTES) - ->with(Labels::default, []) ->with(Labels::isEmpty, static fn (array $values): bool => [] === $values) ->with(Labels::serializeTag, false) ; diff --git a/Internal/Reflection/PropertyDeserializeDescriptor.php b/Internal/Reflection/PropertyDeserializeDescriptor.php index 516d569..55d9659 100644 --- a/Internal/Reflection/PropertyDeserializeDescriptor.php +++ b/Internal/Reflection/PropertyDeserializeDescriptor.php @@ -28,7 +28,6 @@ namespace Prototype\Serializer\Internal\Reflection; use Prototype\Byte; -use Prototype\Serializer\Internal\Label\Labels; use Prototype\Serializer\Internal\Wire\Tag; use Prototype\Serializer\PrototypeException; @@ -41,22 +40,14 @@ final class PropertyDeserializeDescriptor { /** * @param PropertyMarshaller $marshaller + * @param T $default */ public function __construct( private readonly \ReflectionProperty $property, private readonly PropertyMarshaller $marshaller, + private readonly mixed $default = null, ) {} - /** - * @return T - * @throws PrototypeException - */ - public function default(): mixed - { - /** @var T */ - return $this->marshaller->labels()[Labels::default]; - } - /** * @return T * @throws \ReflectionException @@ -80,9 +71,9 @@ public function setValue(object $object, mixed $value): void * @template TClass of object * @param TClass $object */ - public function setDefault(object $object, mixed $value): void + public function setDefault(object $object): void { - $this->setValue($object, $this->property->getType()?->allowsNull() ? null : $value); + $this->setValue($object, $this->property->getType()?->allowsNull() && null === $this->default ? null : $this->default); } /** diff --git a/Internal/Reflection/ProtobufReflector.php b/Internal/Reflection/ProtobufReflector.php index 5ea174b..d0457cd 100644 --- a/Internal/Reflection/ProtobufReflector.php +++ b/Internal/Reflection/ProtobufReflector.php @@ -35,6 +35,7 @@ use Typhoon\DeclarationId\NamedClassId; use Typhoon\Reflection\AttributeReflection; use Typhoon\Reflection\ClassReflection; +use Typhoon\Reflection\MethodReflection; use Typhoon\Reflection\PropertyReflection; use Typhoon\Reflection\TyphoonReflector; @@ -66,9 +67,10 @@ public function propertySerializers(ClassReflection $class, TyphoonReflector $re */ public function propertyDeserializers(ClassReflection $class, TyphoonReflector $reflector): array { - return self::properties($class, $reflector, static fn (\ReflectionProperty $property, PropertyMarshaller $marshaller): PropertyDeserializeDescriptor => new PropertyDeserializeDescriptor( + return self::properties($class, $reflector, static fn (\ReflectionProperty $property, PropertyMarshaller $marshaller, mixed $default = null): PropertyDeserializeDescriptor => new PropertyDeserializeDescriptor( $property, $marshaller, + $default, )); } @@ -76,7 +78,7 @@ public function propertyDeserializers(ClassReflection $class, TyphoonReflector $ * @template T of object * @template E * @param ClassReflection>|AnonymousClassId>> $class - * @param callable(\ReflectionProperty, PropertyMarshaller): E $toPropertyDescriptor + * @param callable(\ReflectionProperty, PropertyMarshaller, mixed=): E $toPropertyDescriptor * @psalm-return array * @throws PrototypeException */ @@ -89,6 +91,15 @@ private static function properties(ClassReflection $class, TyphoonReflector $ref ->filter(static fn (PropertyReflection $property): bool => $property->isPublic() && !$property->isStatic()) ; + $constructorProperties = $class + ->methods() + ->filter(static fn (MethodReflection $reflection): bool => $reflection->id->name === '__construct') + ->first() + ?->parameters() + ->toArray() ?? [] + ; + + /** @var PropertyReflection $property */ foreach ($classProperties as $property) { /** @var ?Field $field */ $field = $property @@ -138,6 +149,7 @@ private static function properties(ClassReflection $class, TyphoonReflector $ref $properties[$n] = $toPropertyDescriptor( $property->toNativeReflection(), $propertyMarshaller, + ($constructorProperties[$property->id->name] ?? null)?->defaultValue() ?? null, ); } } diff --git a/Internal/Reflection/StructPropertyMarshaller.php b/Internal/Reflection/StructPropertyMarshaller.php index f27da3e..d2feb41 100644 --- a/Internal/Reflection/StructPropertyMarshaller.php +++ b/Internal/Reflection/StructPropertyMarshaller.php @@ -85,7 +85,6 @@ public function matchValue(mixed $value): bool public function labels(): TypedMap { return Labels::new(Wire\Type::BYTES) - ->with(Labels::default, []) ->with(Labels::isEmpty, static fn (array $values): bool => [] === $values) ->with(Labels::serializeTag, false) ; diff --git a/Internal/Type/BoolType.php b/Internal/Type/BoolType.php index ee40592..1b68b55 100644 --- a/Internal/Type/BoolType.php +++ b/Internal/Type/BoolType.php @@ -59,7 +59,6 @@ public function writeTo(Byte\Writer $writer, mixed $value): void public function labels(): TypedMap { return Labels::new(Wire\Type::VARINT) - ->with(Labels::default, false) ->with(Labels::packed, true) ->with(Labels::schemaType, ProtobufType::bool) ; diff --git a/Internal/Type/DoubleType.php b/Internal/Type/DoubleType.php index 478d760..6531a53 100644 --- a/Internal/Type/DoubleType.php +++ b/Internal/Type/DoubleType.php @@ -59,7 +59,6 @@ public function readFrom(Byte\Reader $reader): float public function labels(): TypedMap { return Labels::new(Wire\Type::FIXED64) - ->with(Labels::default, 0.0) ->with(Labels::packed, true) ->with(Labels::schemaType, ProtobufType::double) ; diff --git a/Internal/Type/DurationType.php b/Internal/Type/DurationType.php index 57554bd..406a9c0 100644 --- a/Internal/Type/DurationType.php +++ b/Internal/Type/DurationType.php @@ -38,8 +38,8 @@ final class DurationType * @param int32 $nanos */ private function __construct( - public readonly int $seconds, - public readonly int $nanos, + public readonly int $seconds = 0, + public readonly int $nanos = 0, ) {} public static function fromDateInterval(\DateInterval $interval): self diff --git a/Internal/Type/Fixed32Type.php b/Internal/Type/Fixed32Type.php index d477d48..f213456 100644 --- a/Internal/Type/Fixed32Type.php +++ b/Internal/Type/Fixed32Type.php @@ -59,7 +59,6 @@ public function readFrom(Byte\Reader $reader): int public function labels(): TypedMap { return Labels::new(Wire\Type::FIXED32) - ->with(Labels::default, 0) ->with(Labels::packed, true) ->with(Labels::schemaType, ProtobufType::fixed32) ; diff --git a/Internal/Type/Fixed64Type.php b/Internal/Type/Fixed64Type.php index 8800a7c..7bfe5c0 100644 --- a/Internal/Type/Fixed64Type.php +++ b/Internal/Type/Fixed64Type.php @@ -59,7 +59,6 @@ public function readFrom(Byte\Reader $reader): int public function labels(): TypedMap { return Labels::new(Wire\Type::FIXED64) - ->with(Labels::default, 0) ->with(Labels::packed, true) ->with(Labels::schemaType, ProtobufType::fixed64) ; diff --git a/Internal/Type/FloatType.php b/Internal/Type/FloatType.php index 2aef4b0..3d2d317 100644 --- a/Internal/Type/FloatType.php +++ b/Internal/Type/FloatType.php @@ -59,7 +59,6 @@ public function readFrom(Byte\Reader $reader): float public function labels(): TypedMap { return Labels::new(Wire\Type::FIXED32) - ->with(Labels::default, 0.0) ->with(Labels::packed, true) ->with(Labels::schemaType, ProtobufType::float) ; diff --git a/Internal/Type/SFixed32Type.php b/Internal/Type/SFixed32Type.php index 26cf58c..0275bde 100644 --- a/Internal/Type/SFixed32Type.php +++ b/Internal/Type/SFixed32Type.php @@ -59,7 +59,6 @@ public function readFrom(Byte\Reader $reader): int public function labels(): TypedMap { return Labels::new(Wire\Type::FIXED32) - ->with(Labels::default, 0) ->with(Labels::packed, true) ->with(Labels::schemaType, ProtobufType::sfixed32) ; diff --git a/Internal/Type/SFixed64Type.php b/Internal/Type/SFixed64Type.php index a199a9e..7111f73 100644 --- a/Internal/Type/SFixed64Type.php +++ b/Internal/Type/SFixed64Type.php @@ -59,7 +59,6 @@ public function readFrom(Byte\Reader $reader): int public function labels(): TypedMap { return Labels::new(Wire\Type::FIXED64) - ->with(Labels::default, 0) ->with(Labels::packed, true) ->with(Labels::schemaType, ProtobufType::sfixed64) ; diff --git a/Internal/Type/SInt32Type.php b/Internal/Type/SInt32Type.php index a98914e..b47d2e7 100644 --- a/Internal/Type/SInt32Type.php +++ b/Internal/Type/SInt32Type.php @@ -59,7 +59,6 @@ public function readFrom(Byte\Reader $reader): int public function labels(): TypedMap { return Labels::new(Wire\Type::VARINT) - ->with(Labels::default, 0) ->with(Labels::packed, true) ->with(Labels::schemaType, ProtobufType::sint32) ; diff --git a/Internal/Type/SInt64Type.php b/Internal/Type/SInt64Type.php index b0d654d..77c96e8 100644 --- a/Internal/Type/SInt64Type.php +++ b/Internal/Type/SInt64Type.php @@ -59,7 +59,6 @@ public function readFrom(Byte\Reader $reader): int public function labels(): TypedMap { return Labels::new(Wire\Type::VARINT) - ->with(Labels::default, 0) ->with(Labels::packed, true) ->with(Labels::schemaType, ProtobufType::sint64) ; diff --git a/Internal/Type/StringType.php b/Internal/Type/StringType.php index 3e5941d..3705970 100644 --- a/Internal/Type/StringType.php +++ b/Internal/Type/StringType.php @@ -59,7 +59,6 @@ public function readFrom(Byte\Reader $reader): string public function labels(): TypedMap { return Labels::new(Wire\Type::BYTES) - ->with(Labels::default, '') ->with(Labels::schemaType, ProtobufType::string) ; } diff --git a/Internal/Type/TimestampType.php b/Internal/Type/TimestampType.php index 42470b5..b03f66b 100644 --- a/Internal/Type/TimestampType.php +++ b/Internal/Type/TimestampType.php @@ -40,8 +40,8 @@ final class TimestampType * @param int32 $nanos */ private function __construct( - public readonly int $seconds, - public readonly int $nanos, + public readonly int $seconds = 0, + public readonly int $nanos = 0, ) {} public static function fromDateTime(\DateTimeInterface $dateTime): self diff --git a/Internal/Type/ValueType.php b/Internal/Type/ValueType.php index 6702b2a..d3aef1e 100644 --- a/Internal/Type/ValueType.php +++ b/Internal/Type/ValueType.php @@ -161,9 +161,7 @@ public function writeTo(Byte\Writer $writer, mixed $value): void public function labels(): TypedMap { - return Labels::new(Type::BYTES) - ->with(Labels::default, []) - ; + return Labels::new(Type::BYTES); } /** diff --git a/Internal/Type/VarintType.php b/Internal/Type/VarintType.php index d847bd6..d4ec1a4 100644 --- a/Internal/Type/VarintType.php +++ b/Internal/Type/VarintType.php @@ -59,7 +59,6 @@ public function writeTo(Byte\Writer $writer, mixed $value): void public function labels(): TypedMap { return Labels::new(Wire\Type::VARINT) - ->with(Labels::default, 0) ->with(Labels::packed, true) ->with(Labels::schemaType, ProtobufType::int64) ; diff --git a/Internal/Wire/ProtobufMarshaller.php b/Internal/Wire/ProtobufMarshaller.php index 5417be2..275690a 100644 --- a/Internal/Wire/ProtobufMarshaller.php +++ b/Internal/Wire/ProtobufMarshaller.php @@ -139,7 +139,7 @@ public function deserialize(string $messageType, Byte\Reader $reader): object // so that we can distinguish between a real value and no value. foreach ($properties as $propertyDeserializer) { if (!$propertyDeserializer->isInitialized($object)) { - $propertyDeserializer->setDefault($object, $propertyDeserializer->default()); + $propertyDeserializer->setDefault($object); } }