diff --git a/src/Reflection/Reflector.php b/src/Reflection/Reflector.php index 5bef5fb..1571ea1 100644 --- a/src/Reflection/Reflector.php +++ b/src/Reflection/Reflector.php @@ -188,7 +188,7 @@ private function doGetMessage(object $message, ?\Closure $presence = null): Mess if ($property->attributes->has(Field::class)) { $field = $property->attributes->get(Field::class); - if ($presence($field, $value)) { + if (($property->default !== null && $property->default->value === null) || $presence($field, $value)) { $descriptors[] = Protobuf\fieldOf( $field->num, $field->type->accept($this->valueVisitor)($value), diff --git a/tests/Encoder/Internal/ReflectionEncoderTest.php b/tests/Encoder/Internal/ReflectionEncoderTest.php index 65156e3..5098598 100644 --- a/tests/Encoder/Internal/ReflectionEncoderTest.php +++ b/tests/Encoder/Internal/ReflectionEncoderTest.php @@ -21,6 +21,16 @@ public function testEncode(): void self::assertSame('0a084a6f686e20446f651032', bin2hex($encoder->encode(new Request('John Doe', 50)))); } + + public function testEncodeOptionalScalarZeroValues(): void + { + $encoder = Builder::buildDefault(); + + self::assertSame( + '080012001800', + bin2hex($encoder->encode(new OptionalScalarRequest(0, '', false))), + ); + } } final readonly class Request @@ -32,3 +42,15 @@ public function __construct( public int $id, ) {} } + +final readonly class OptionalScalarRequest +{ + public function __construct( + #[Reflection\Field(1, Reflection\Int32T::T)] + public ?int $oneofIndex = null, + #[Reflection\Field(2, Reflection\StringT::T)] + public ?string $label = null, + #[Reflection\Field(3, Reflection\BoolT::T)] + public ?bool $enabled = null, + ) {} +}