diff --git a/src/Generator/Message/ReadFieldStatementGenerator.php b/src/Generator/Message/ReadFieldStatementGenerator.php index 3dfc151..108274c 100644 --- a/src/Generator/Message/ReadFieldStatementGenerator.php +++ b/src/Generator/Message/ReadFieldStatementGenerator.php @@ -64,7 +64,7 @@ public function generateFieldReadStatement(Entity $entity, FieldDescriptorProto $rule = $field->getLabel(); $tag = $field->getNumber(); $options = $field->getOptions(); - $isPack = $options ? $options->getPacked() : false; + $isPack = $options ? $options->getPacked() : $this->isDefaultPacked($rule, $type); $variable = $this->targetVar ?: '$this->' . $name; $breakSttm = $this->getBreakStatement($variable); @@ -208,6 +208,31 @@ protected function generateReadScalarStatement($type) throw new InvalidArgumentException('Unknown field type : ' . $type); } + /** + * check if field is packed by default + * + * @param Label $label + * @param Type $type + * + * @return bool + */ + protected function isDefaultPacked(Label $label, Type $type) + { + return $label === Label::LABEL_REPEATED() && in_array($type, [ + Type::TYPE_FIXED32(), + Type::TYPE_FIXED64(), + Type::TYPE_INT32(), + Type::TYPE_INT64(), + Type::TYPE_SFIXED32(), + Type::TYPE_SFIXED64(), + Type::TYPE_UINT32(), + Type::TYPE_UINT64(), + Type::TYPE_FLOAT(), + Type::TYPE_DOUBLE(), + Type::TYPE_ENUM(), + ]); + } + /** * @param string $variable * diff --git a/tests/Generator/Message/ReadFieldStatementGeneratorTest.php b/tests/Generator/Message/ReadFieldStatementGeneratorTest.php index 35cbf26..305a14f 100644 --- a/tests/Generator/Message/ReadFieldStatementGeneratorTest.php +++ b/tests/Generator/Message/ReadFieldStatementGeneratorTest.php @@ -138,13 +138,16 @@ public function testGenerateReadEnumRepeatedStatement() $actual = $this->invokeMethod($generator, 'generateFieldReadStatement', [$entity, $field]); $expected = <<<'CODE' -\Protobuf\WireFormat::assertWireType($wire, 14); +$innerSize = $reader->readVarint($stream); +$innerLimit = $stream->tell() + $innerSize; if ($this->status === null) { $this->status = new \Protobuf\EnumCollection(); } -$this->status->add(\ProtobufCompilerTest\Protos\Type::valueOf($reader->readVarint($stream))); +while ($stream->tell() < $innerLimit) { + $this->status->add(\ProtobufCompilerTest\Protos\Type::valueOf($reader->readVarint($stream))); +} continue; CODE; @@ -372,4 +375,35 @@ public function testGenerateReadScalarStatementException() $this->invokeMethod($generator, 'generateReadScalarStatement', [-123]); } + + public function testIsDefaultPacked() + { + $context = $this->createMessagesContext([]); + $generator = new ReadFieldStatementGenerator($context); + + $this->assertTrue( + $this->invokeMethod($generator, 'isDefaultPacked', + [ + FieldDescriptorProto\Label::LABEL_REPEATED(), + FieldDescriptorProto\Type::TYPE_UINT32() + ] + ) + ); + $this->assertFalse( + $this->invokeMethod($generator, 'isDefaultPacked', + [ + FieldDescriptorProto\Label::LABEL_OPTIONAL(), + FieldDescriptorProto\Type::TYPE_STRING() + ] + ) + ); + $this->assertFalse( + $this->invokeMethod($generator, 'isDefaultPacked', + [ + FieldDescriptorProto\Label::LABEL_REPEATED(), + FieldDescriptorProto\Type::TYPE_STRING() + ] + ) + ); + } } diff --git a/tests/Generator/Message/ReadFromGeneratorTest.php b/tests/Generator/Message/ReadFromGeneratorTest.php index 3c15a61..af0c36f 100644 --- a/tests/Generator/Message/ReadFromGeneratorTest.php +++ b/tests/Generator/Message/ReadFromGeneratorTest.php @@ -60,13 +60,16 @@ public function testGenerateBody() } if ($tag === 1) { - \Protobuf\WireFormat::assertWireType($wire, 5); + $innerSize = $reader->readVarint($stream); + $innerLimit = $stream->tell() + $innerSize; if ($this->lines === null) { $this->lines = new \Protobuf\ScalarCollection(); } - $this->lines->add($reader->readVarint($stream)); + while ($stream->tell() < $innerLimit) { + $this->lines->add($reader->readVarint($stream)); + } continue; }