/** * Serialized \Google\Protobuf\FileDescriptorSet to Protocol Buffers message. * * @param FileDescriptorSet $object * @param array $filter * * @throws \Exception * * @return string */ public static function toProtobuf($object, $filter = NULL) { $output = ''; if (isset($object->file) && ($filter === null || isset($filter['file']))) { foreach ($object->file instanceof \Traversable ? $object->file : (array) $object->file as $k => $v) { $output .= "\n"; $buffer = FileDescriptorProtoMeta::toProtobuf($v, $filter === null ? null : $filter['file']); $output .= Binary::encodeVarint(strlen($buffer)); $output .= $buffer; } } return $output; }
/** * Serialized \Google\Protobuf\DescriptorProto\ReservedRange to Protocol Buffers message. * * @param ReservedRange $object * @param array $filter * * @throws \Exception * * @return string */ public static function toProtobuf($object, $filter = NULL) { $output = ''; if (isset($object->start) && ($filter === null || isset($filter['start']))) { $output .= ""; $output .= Binary::encodeVarint($object->start); } if (isset($object->end) && ($filter === null || isset($filter['end']))) { $output .= ""; $output .= Binary::encodeVarint($object->end); } return $output; }
/** * Serialized \Google\Protobuf\UninterpretedOption\NamePart to Protocol Buffers message. * * @param NamePart $object * @param array $filter * * @throws \Exception * * @return string */ public static function toProtobuf($object, $filter = NULL) { $output = ''; if (isset($object->namePart) && ($filter === null || isset($filter['namePart']))) { $output .= "\n"; $output .= Binary::encodeVarint(strlen($object->namePart)); $output .= $object->namePart; } if (isset($object->isExtension) && ($filter === null || isset($filter['isExtension']))) { $output .= ""; $output .= Binary::encodeVarint((int) $object->isExtension); } return $output; }
/** * Serialized \Google\Protobuf\EnumDescriptorProto to Protocol Buffers message. * * @param EnumDescriptorProto $object * @param array $filter * * @throws \Exception * * @return string */ public static function toProtobuf($object, $filter = NULL) { $output = ''; if (isset($object->name) && ($filter === null || isset($filter['name']))) { $output .= "\n"; $output .= Binary::encodeVarint(strlen($object->name)); $output .= $object->name; } if (isset($object->value) && ($filter === null || isset($filter['value']))) { foreach ($object->value instanceof \Traversable ? $object->value : (array) $object->value as $k => $v) { $output .= ""; $buffer = EnumValueDescriptorProtoMeta::toProtobuf($v, $filter === null ? null : $filter['value']); $output .= Binary::encodeVarint(strlen($buffer)); $output .= $buffer; } } if (isset($object->options) && ($filter === null || isset($filter['options']))) { $output .= ""; $buffer = EnumOptionsMeta::toProtobuf($object->options, $filter === null ? null : $filter['options']); $output .= Binary::encodeVarint(strlen($buffer)); $output .= $buffer; } return $output; }
/** * Serialized \Google\Protobuf\OneofDescriptorProto to Protocol Buffers message. * * @param OneofDescriptorProto $object * @param array $filter * * @throws \Exception * * @return string */ public static function toProtobuf($object, $filter = NULL) { $output = ''; if (isset($object->name) && ($filter === null || isset($filter['name']))) { $output .= "\n"; $output .= Binary::encodeVarint(strlen($object->name)); $output .= $object->name; } return $output; }
/** * Serialized \Skrz\Bundle\BunnyBundle\Tests\Fixtures\Message to Protocol Buffers message. * * @param Message $object * @param array $filter * * @throws \Exception * * @return string */ public static function toProtobuf($object, $filter = NULL) { $output = ''; if (isset($object->intValue) && ($filter === null || isset($filter['intValue']))) { $output .= ""; $output .= Binary::encodeVarint($object->intValue); } if (isset($object->floatValue) && ($filter === null || isset($filter['floatValue']))) { $output .= ""; $output .= Binary::encodeDouble($object->floatValue); } if (isset($object->stringValue) && ($filter === null || isset($filter['stringValue']))) { $output .= ""; $output .= Binary::encodeVarint(strlen($object->stringValue)); $output .= $object->stringValue; } return $output; }
/** * Serialized \Google\Protobuf\FileDescriptorProto to Protocol Buffers message. * * @param FileDescriptorProto $object * @param array $filter * * @throws \Exception * * @return string */ public static function toProtobuf($object, $filter = NULL) { $output = ''; if (isset($object->name) && ($filter === null || isset($filter['name']))) { $output .= "\n"; $output .= Binary::encodeVarint(strlen($object->name)); $output .= $object->name; } if (isset($object->package) && ($filter === null || isset($filter['package']))) { $output .= ""; $output .= Binary::encodeVarint(strlen($object->package)); $output .= $object->package; } if (isset($object->dependency) && ($filter === null || isset($filter['dependency']))) { foreach ($object->dependency instanceof \Traversable ? $object->dependency : (array) $object->dependency as $k => $v) { $output .= ""; $output .= Binary::encodeVarint(strlen($v)); $output .= $v; } } if (isset($object->publicDependency) && ($filter === null || isset($filter['publicDependency']))) { foreach ($object->publicDependency instanceof \Traversable ? $object->publicDependency : (array) $object->publicDependency as $k => $v) { $output .= "P"; $output .= Binary::encodeVarint($v); } } if (isset($object->weakDependency) && ($filter === null || isset($filter['weakDependency']))) { foreach ($object->weakDependency instanceof \Traversable ? $object->weakDependency : (array) $object->weakDependency as $k => $v) { $output .= "X"; $output .= Binary::encodeVarint($v); } } if (isset($object->messageType) && ($filter === null || isset($filter['messageType']))) { foreach ($object->messageType instanceof \Traversable ? $object->messageType : (array) $object->messageType as $k => $v) { $output .= "\""; $buffer = DescriptorProtoMeta::toProtobuf($v, $filter === null ? null : $filter['messageType']); $output .= Binary::encodeVarint(strlen($buffer)); $output .= $buffer; } } if (isset($object->enumType) && ($filter === null || isset($filter['enumType']))) { foreach ($object->enumType instanceof \Traversable ? $object->enumType : (array) $object->enumType as $k => $v) { $output .= "*"; $buffer = EnumDescriptorProtoMeta::toProtobuf($v, $filter === null ? null : $filter['enumType']); $output .= Binary::encodeVarint(strlen($buffer)); $output .= $buffer; } } if (isset($object->service) && ($filter === null || isset($filter['service']))) { foreach ($object->service instanceof \Traversable ? $object->service : (array) $object->service as $k => $v) { $output .= "2"; $buffer = ServiceDescriptorProtoMeta::toProtobuf($v, $filter === null ? null : $filter['service']); $output .= Binary::encodeVarint(strlen($buffer)); $output .= $buffer; } } if (isset($object->extension) && ($filter === null || isset($filter['extension']))) { foreach ($object->extension instanceof \Traversable ? $object->extension : (array) $object->extension as $k => $v) { $output .= ":"; $buffer = FieldDescriptorProtoMeta::toProtobuf($v, $filter === null ? null : $filter['extension']); $output .= Binary::encodeVarint(strlen($buffer)); $output .= $buffer; } } if (isset($object->options) && ($filter === null || isset($filter['options']))) { $output .= "B"; $buffer = FileOptionsMeta::toProtobuf($object->options, $filter === null ? null : $filter['options']); $output .= Binary::encodeVarint(strlen($buffer)); $output .= $buffer; } if (isset($object->sourceCodeInfo) && ($filter === null || isset($filter['sourceCodeInfo']))) { $output .= "J"; $buffer = SourceCodeInfoMeta::toProtobuf($object->sourceCodeInfo, $filter === null ? null : $filter['sourceCodeInfo']); $output .= Binary::encodeVarint(strlen($buffer)); $output .= $buffer; } if (isset($object->syntax) && ($filter === null || isset($filter['syntax']))) { $output .= "b"; $output .= Binary::encodeVarint(strlen($object->syntax)); $output .= $object->syntax; } return $output; }
/** * Serialized \Google\Protobuf\EnumValueDescriptorProto to Protocol Buffers message. * * @param EnumValueDescriptorProto $object * @param array $filter * * @throws \Exception * * @return string */ public static function toProtobuf($object, $filter = NULL) { $output = ''; if (isset($object->name) && ($filter === null || isset($filter['name']))) { $output .= "\n"; $output .= Binary::encodeVarint(strlen($object->name)); $output .= $object->name; } if (isset($object->number) && ($filter === null || isset($filter['number']))) { $output .= ""; $output .= Binary::encodeVarint($object->number); } if (isset($object->options) && ($filter === null || isset($filter['options']))) { $output .= ""; $buffer = EnumValueOptionsMeta::toProtobuf($object->options, $filter === null ? null : $filter['options']); $output .= Binary::encodeVarint(strlen($buffer)); $output .= $buffer; } return $output; }
/** * Serialized \Google\Protobuf\FieldDescriptorProto to Protocol Buffers message. * * @param FieldDescriptorProto $object * @param array $filter * * @throws \Exception * * @return string */ public static function toProtobuf($object, $filter = NULL) { $output = ''; if (isset($object->name) && ($filter === null || isset($filter['name']))) { $output .= "\n"; $output .= Binary::encodeVarint(strlen($object->name)); $output .= $object->name; } if (isset($object->number) && ($filter === null || isset($filter['number']))) { $output .= ""; $output .= Binary::encodeVarint($object->number); } if (isset($object->label) && ($filter === null || isset($filter['label']))) { $output .= " "; $output .= Binary::encodeVarint($object->label); } if (isset($object->type) && ($filter === null || isset($filter['type']))) { $output .= "("; $output .= Binary::encodeVarint($object->type); } if (isset($object->typeName) && ($filter === null || isset($filter['typeName']))) { $output .= "2"; $output .= Binary::encodeVarint(strlen($object->typeName)); $output .= $object->typeName; } if (isset($object->extendee) && ($filter === null || isset($filter['extendee']))) { $output .= ""; $output .= Binary::encodeVarint(strlen($object->extendee)); $output .= $object->extendee; } if (isset($object->defaultValue) && ($filter === null || isset($filter['defaultValue']))) { $output .= ":"; $output .= Binary::encodeVarint(strlen($object->defaultValue)); $output .= $object->defaultValue; } if (isset($object->oneofIndex) && ($filter === null || isset($filter['oneofIndex']))) { $output .= "H"; $output .= Binary::encodeVarint($object->oneofIndex); } if (isset($object->jsonName) && ($filter === null || isset($filter['jsonName']))) { $output .= "R"; $output .= Binary::encodeVarint(strlen($object->jsonName)); $output .= $object->jsonName; } if (isset($object->options) && ($filter === null || isset($filter['options']))) { $output .= "B"; $buffer = FieldOptionsMeta::toProtobuf($object->options, $filter === null ? null : $filter['options']); $output .= Binary::encodeVarint(strlen($buffer)); $output .= $buffer; } return $output; }
/** * Serialized \Skrz\Meta\Fixtures\Protobuf\ClassWithEmbeddedMessageProperty to Protocol Buffers message. * * @param ClassWithEmbeddedMessageProperty $object * @param array $filter * * @throws \Exception * * @return string */ public static function toProtobuf($object, $filter = NULL) { $output = ''; if (isset($object->x) && ($filter === null || isset($filter['x']))) { $output .= "\n"; $buffer = EmbeddedMeta::toProtobuf($object->x, $filter === null ? null : $filter['x']); $output .= Binary::encodeVarint(strlen($buffer)); $output .= $buffer; } return $output; }
/** * Serialized \Google\Protobuf\UninterpretedOption to Protocol Buffers message. * * @param UninterpretedOption $object * @param array $filter * * @throws \Exception * * @return string */ public static function toProtobuf($object, $filter = NULL) { $output = ''; if (isset($object->name) && ($filter === null || isset($filter['name']))) { foreach ($object->name instanceof \Traversable ? $object->name : (array) $object->name as $k => $v) { $output .= ""; $buffer = NamePartMeta::toProtobuf($v, $filter === null ? null : $filter['name']); $output .= Binary::encodeVarint(strlen($buffer)); $output .= $buffer; } } if (isset($object->identifierValue) && ($filter === null || isset($filter['identifierValue']))) { $output .= ""; $output .= Binary::encodeVarint(strlen($object->identifierValue)); $output .= $object->identifierValue; } if (isset($object->positiveIntValue) && ($filter === null || isset($filter['positiveIntValue']))) { $output .= " "; $output .= Binary::encodeVarint($object->positiveIntValue); } if (isset($object->negativeIntValue) && ($filter === null || isset($filter['negativeIntValue']))) { $output .= "("; $output .= Binary::encodeVarint($object->negativeIntValue); } if (isset($object->doubleValue) && ($filter === null || isset($filter['doubleValue']))) { $output .= "1"; $output .= Binary::encodeDouble($object->doubleValue); } if (isset($object->stringValue) && ($filter === null || isset($filter['stringValue']))) { $output .= ":"; $output .= Binary::encodeVarint(strlen($object->stringValue)); $output .= $object->stringValue; } if (isset($object->aggregateValue) && ($filter === null || isset($filter['aggregateValue']))) { $output .= "B"; $output .= Binary::encodeVarint(strlen($object->aggregateValue)); $output .= $object->aggregateValue; } return $output; }
/** * Serialized \Google\Protobuf\DescriptorProto to Protocol Buffers message. * * @param DescriptorProto $object * @param array $filter * * @throws \Exception * * @return string */ public static function toProtobuf($object, $filter = NULL) { $output = ''; if (isset($object->name) && ($filter === null || isset($filter['name']))) { $output .= "\n"; $output .= Binary::encodeVarint(strlen($object->name)); $output .= $object->name; } if (isset($object->field) && ($filter === null || isset($filter['field']))) { foreach ($object->field instanceof \Traversable ? $object->field : (array) $object->field as $k => $v) { $output .= ""; $buffer = FieldDescriptorProtoMeta::toProtobuf($v, $filter === null ? null : $filter['field']); $output .= Binary::encodeVarint(strlen($buffer)); $output .= $buffer; } } if (isset($object->extension) && ($filter === null || isset($filter['extension']))) { foreach ($object->extension instanceof \Traversable ? $object->extension : (array) $object->extension as $k => $v) { $output .= "2"; $buffer = FieldDescriptorProtoMeta::toProtobuf($v, $filter === null ? null : $filter['extension']); $output .= Binary::encodeVarint(strlen($buffer)); $output .= $buffer; } } if (isset($object->nestedType) && ($filter === null || isset($filter['nestedType']))) { foreach ($object->nestedType instanceof \Traversable ? $object->nestedType : (array) $object->nestedType as $k => $v) { $output .= ""; $buffer = DescriptorProtoMeta::toProtobuf($v, $filter === null ? null : $filter['nestedType']); $output .= Binary::encodeVarint(strlen($buffer)); $output .= $buffer; } } if (isset($object->enumType) && ($filter === null || isset($filter['enumType']))) { foreach ($object->enumType instanceof \Traversable ? $object->enumType : (array) $object->enumType as $k => $v) { $output .= "\""; $buffer = EnumDescriptorProtoMeta::toProtobuf($v, $filter === null ? null : $filter['enumType']); $output .= Binary::encodeVarint(strlen($buffer)); $output .= $buffer; } } if (isset($object->extensionRange) && ($filter === null || isset($filter['extensionRange']))) { foreach ($object->extensionRange instanceof \Traversable ? $object->extensionRange : (array) $object->extensionRange as $k => $v) { $output .= "*"; $buffer = ExtensionRangeMeta::toProtobuf($v, $filter === null ? null : $filter['extensionRange']); $output .= Binary::encodeVarint(strlen($buffer)); $output .= $buffer; } } if (isset($object->oneofDecl) && ($filter === null || isset($filter['oneofDecl']))) { foreach ($object->oneofDecl instanceof \Traversable ? $object->oneofDecl : (array) $object->oneofDecl as $k => $v) { $output .= "B"; $buffer = OneofDescriptorProtoMeta::toProtobuf($v, $filter === null ? null : $filter['oneofDecl']); $output .= Binary::encodeVarint(strlen($buffer)); $output .= $buffer; } } if (isset($object->options) && ($filter === null || isset($filter['options']))) { $output .= ":"; $buffer = MessageOptionsMeta::toProtobuf($object->options, $filter === null ? null : $filter['options']); $output .= Binary::encodeVarint(strlen($buffer)); $output .= $buffer; } if (isset($object->reservedRange) && ($filter === null || isset($filter['reservedRange']))) { foreach ($object->reservedRange instanceof \Traversable ? $object->reservedRange : (array) $object->reservedRange as $k => $v) { $output .= "J"; $buffer = ReservedRangeMeta::toProtobuf($v, $filter === null ? null : $filter['reservedRange']); $output .= Binary::encodeVarint(strlen($buffer)); $output .= $buffer; } } if (isset($object->reservedName) && ($filter === null || isset($filter['reservedName']))) { foreach ($object->reservedName instanceof \Traversable ? $object->reservedName : (array) $object->reservedName as $k => $v) { $output .= "R"; $output .= Binary::encodeVarint(strlen($v)); $output .= $v; } } return $output; }
public function onGenerate(AbstractMetaSpec $spec, MetaSpecMatcher $matcher, Type $type, ClassType $class) { $ns = $class->getNamespace(); $ns->addUse("Skrz\\Meta\\Protobuf\\ProtobufMetaInterface"); $ns->addUse($type->getName(), null, $typeAlias); $ns->addUse("Skrz\\Meta\\Protobuf\\Binary", null, $binary); $ns->addUse("Skrz\\Meta\\Protobuf\\ProtobufException", null, $protobufExceptionAlias); $class->addImplement("Skrz\\Meta\\Protobuf\\ProtobufMetaInterface"); foreach ($type->getProperties() as $property) { if ($property->hasAnnotation("Skrz\\Meta\\Transient")) { continue; } /** @var ProtobufField $field */ $field = $property->getAnnotation("Skrz\\Meta\\Protobuf\\ProtobufField"); $class->addConst(strtoupper(trim(preg_replace("/([A-Z])/", "_\$1", $property->getName() . "ProtobufField"), "_")), $field->number); } $fromProtobuf = $class->addMethod("fromProtobuf"); $fromProtobuf->setStatic(true); $fromProtobuf->addParameter("input"); $fromProtobuf->addParameter("object", null)->setOptional(true); $fromProtobuf->addParameter("start", 0)->setReference(true)->setOptional(true); $fromProtobuf->addParameter("end", null)->setOptional(true); $fromProtobuf->addComment("Creates \\{$type->getName()} object from serialized Protocol Buffers message.")->addComment("")->addComment("@param string \$input")->addComment("@param {$typeAlias} \$object")->addComment("@param int \$start")->addComment("@param int \$end")->addComment("")->addComment("@throws \\Exception")->addComment("")->addComment("@return {$typeAlias}"); $fromProtobuf->addBody("if (\$object === null) {")->addBody("\t\$object = new {$typeAlias}();")->addBody("}")->addBody("")->addBody("if (\$end === null) {")->addBody("\t\$end = strlen(\$input);")->addBody("}")->addBody(""); $fromProtobuf->addBody("while (\$start < \$end) {"); $fromProtobuf->addBody("\t\$tag = {$binary}::decodeVarint(\$input, \$start);"); $fromProtobuf->addBody("\t\$wireType = \$tag & 0x7;"); $fromProtobuf->addBody("\t\$number = \$tag >> 3;"); $fromProtobuf->addBody("\tswitch (\$number) {"); foreach ($type->getProperties() as $property) { if ($property->hasAnnotation("Skrz\\Meta\\Transient")) { continue; } $propertyType = $property->getType(); $baseType = $propertyType; if ($baseType instanceof ArrayType) { $baseType = $baseType->getBaseType(); } /** @var ProtobufField $field */ $field = $property->getAnnotation("Skrz\\Meta\\Protobuf\\ProtobufField"); $fromProtobuf->addBody("\t\tcase {$field->number}:"); if ($field->packed) { $binaryWireType = WireTypeEnum::toBinaryWireType(WireTypeEnum::STRING); } else { $binaryWireType = WireTypeEnum::toBinaryWireType($field->wireType); } $fromProtobuf->addBody("\t\t\tif (\$wireType !== {$binaryWireType}) {"); $fromProtobuf->addBody("\t\t\t\tthrow new {$protobufExceptionAlias}('Unexpected wire type ' . \$wireType . ', expected {$binaryWireType}.', \$number);"); $fromProtobuf->addBody("\t\t\t}"); $propertyLhs = "\$object->{$property->getName()}"; if ($propertyType->isArray()) { $fromProtobuf->addBody("\t\t\tif (!(isset({$propertyLhs}) && is_array({$propertyLhs}))) {"); $fromProtobuf->addBody("\t\t\t\t{$propertyLhs} = array();"); $fromProtobuf->addBody("\t\t\t}"); $propertyLhs .= "[]"; } if ($field->packed) { $fromProtobuf->addBody("\t\t\t\$packedLength = {$binary}::decodeVarint(\$input, \$start);")->addBody("\t\t\t\$expectedPacked = \$start + \$packedLength;")->addBody("\t\t\tif (\$expectedPacked > \$end) {")->addBody("\t\t\t\tthrow new {$protobufExceptionAlias}('Not enough data.');")->addBody("\t\t\t}")->addBody("\t\t\twhile (\$start < \$expectedPacked) {"); $indent = "\t\t\t\t"; } else { $indent = "\t\t\t"; } switch ($field->wireType) { case WireTypeEnum::VARINT: $fromProtobuf->addBody("{$indent}{$propertyLhs} = " . ($baseType instanceof BoolType ? "(bool)" : "") . "{$binary}::decodeVarint(\$input, \$start);"); break; case WireTypeEnum::ZIGZAG: $fromProtobuf->addBody("{$indent}{$propertyLhs} = {$binary}::decodeZigzag(\$input, \$start);"); break; case WireTypeEnum::FIXED64: $fromProtobuf->addBody("{$indent}\$expectedStart = \$start + 8;")->addBody("{$indent}if (\$expectedStart > \$end) {")->addBody("{$indent}\tthrow new {$protobufExceptionAlias}('Not enough data.');")->addBody("{$indent}}"); if ($baseType instanceof FloatType) { $fromProtobuf->addBody("{$indent}{$propertyLhs} = {$binary}::decodeDouble(\$input, \$start);"); } elseif ($baseType instanceof IntType && $field->unsigned) { $fromProtobuf->addBody("{$indent}{$propertyLhs} = {$binary}::decodeUint64(\$input, \$start);"); } elseif ($baseType instanceof IntType && !$field->unsigned) { $fromProtobuf->addBody("{$indent}{$propertyLhs} = {$binary}::decodeInt64(\$input, \$start);"); } else { throw new MetaException("Property {$type->getName()}::\${$property->getName()} has wire type '{$field->wireType}' and base type {$baseType}. " . "'{$field->wireType}' supports only float or int base types."); } $fromProtobuf->addBody("{$indent}if (\$start !== \$expectedStart) {")->addBody("{$indent}\tthrow new {$protobufExceptionAlias}('Unexpected start. Expected ' . \$expectedStart . ', got ' . \$start . '.', \$number);")->addBody("{$indent}}"); break; case WireTypeEnum::FIXED32: $fromProtobuf->addBody("{$indent}\$expectedStart = \$start + 4;")->addBody("{$indent}if (\$expectedStart > \$end) {")->addBody("{$indent}\tthrow new {$protobufExceptionAlias}('Not enough data.');")->addBody("{$indent}}"); if ($baseType instanceof FloatType) { $fromProtobuf->addBody("{$indent}{$propertyLhs} = {$binary}::decodeFloat(\$input, \$start);"); } elseif ($baseType instanceof IntType && $field->unsigned) { $fromProtobuf->addBody("{$indent}{$propertyLhs} = {$binary}::decodeUint32(\$input, \$start);"); } elseif ($baseType instanceof IntType && !$field->unsigned) { $fromProtobuf->addBody("{$indent}{$propertyLhs} = {$binary}::decodeInt32(\$input, \$start);"); } else { throw new MetaException("Property {$type->getName()}::\${$property->getName()} has wire type '{$field->wireType}' and base type {$baseType}. " . "'{$field->wireType}' supports only float or int base types."); } $fromProtobuf->addBody("{$indent}if (\$start !== \$expectedStart) {")->addBody("{$indent}\tthrow new {$protobufExceptionAlias}('Unexpected start. Expected ' . \$expectedStart . ', got ' . \$start . '.', \$number);")->addBody("{$indent}}"); break; case WireTypeEnum::STRING: $fromProtobuf->addBody("{$indent}\$length = {$binary}::decodeVarint(\$input, \$start);")->addBody("{$indent}\$expectedStart = \$start + \$length;")->addBody("{$indent}if (\$expectedStart > \$end) {")->addBody("{$indent}\tthrow new {$protobufExceptionAlias}('Not enough data.');")->addBody("{$indent}}"); if ($baseType instanceof StringType) { $fromProtobuf->addBody("{$indent}{$propertyLhs} = substr(\$input, \$start, \$length);"); $fromProtobuf->addBody("{$indent}\$start += \$length;"); } elseif ($baseType instanceof Type) { $propertyTypeMetaClassName = $spec->createMetaClassName($baseType); $ns->addUse($propertyTypeMetaClassName, null, $propertyTypeMetaClassNameAlias); $fromProtobuf->addBody("{$indent}{$propertyLhs} = {$propertyTypeMetaClassNameAlias}::fromProtobuf(\$input, null, \$start, \$start + \$length);"); } else { throw new MetaException("Property {$type->getName()}::\${$property->getName()} has wire type '{$field->wireType}' and base type {$baseType}. " . "'{$field->wireType}' supports only string or object types."); } $fromProtobuf->addBody("{$indent}if (\$start !== \$expectedStart) {")->addBody("{$indent}\tthrow new {$protobufExceptionAlias}('Unexpected start. Expected ' . \$expectedStart . ', got ' . \$start . '.', \$number);")->addBody("{$indent}}"); break; default: throw new \InvalidArgumentException("Unhandled field wire type '{$field->wireType}'."); } if ($field->packed) { $fromProtobuf->addBody("\t\t\t}")->addBody("\t\t\tif (\$start !== \$expectedPacked) {")->addBody("\t\t\t\tthrow new {$protobufExceptionAlias}('Unexpected start. Expected ' . \$expectedPacked . ', got ' . \$start . '.', \$number);")->addBody("\t\t\t}"); } $fromProtobuf->addBody("\t\t\tbreak;"); } $fromProtobuf->addBody("\t\tdefault:")->addBody("\t\t\tswitch (\$wireType) {")->addBody("\t\t\t\tcase " . WireTypeEnum::toBinaryWireType(WireTypeEnum::VARINT) . ":")->addBody("\t\t\t\t\t{$binary}::decodeVarint(\$input, \$start);")->addBody("\t\t\t\t\tbreak;")->addBody("\t\t\t\tcase " . WireTypeEnum::toBinaryWireType(WireTypeEnum::FIXED64) . ":")->addBody("\t\t\t\t\t\$start += 8;")->addBody("\t\t\t\t\tbreak;")->addBody("\t\t\t\tcase " . WireTypeEnum::toBinaryWireType(WireTypeEnum::STRING) . ":")->addBody("\t\t\t\t\t\$start += {$binary}::decodeVarint(\$input, \$start);")->addBody("\t\t\t\t\tbreak;")->addBody("\t\t\t\tcase " . WireTypeEnum::toBinaryWireType(WireTypeEnum::FIXED32) . ":")->addBody("\t\t\t\t\t\$start += 4;")->addBody("\t\t\t\t\tbreak;")->addBody("\t\t\t\tdefault:")->addBody("\t\t\t\t\tthrow new {$protobufExceptionAlias}('Unexpected wire type ' . \$wireType . '.', \$number);")->addBody("\t\t\t}"); $fromProtobuf->addBody("\t}"); $fromProtobuf->addBody("}"); $fromProtobuf->addBody("")->addBody("return \$object;"); $toProtobuf = $class->addMethod("toProtobuf"); $toProtobuf->setStatic(true); $toProtobuf->addParameter("object"); $toProtobuf->addParameter("filter", null); $toProtobuf->addComment("Serialized \\{$type->getName()} to Protocol Buffers message.")->addComment("")->addComment("@param {$typeAlias} \$object")->addComment("@param array \$filter")->addComment("")->addComment("@throws \\Exception")->addComment("")->addComment("@return string"); $toProtobuf->addBody("\$output = '';")->addBody(""); foreach ($type->getProperties() as $property) { if ($property->hasAnnotation("Skrz\\Meta\\Transient")) { continue; } $propertyType = $property->getType(); $baseType = $propertyType; if ($baseType instanceof ArrayType) { $baseType = $baseType->getBaseType(); } /** @var ProtobufField $field */ $field = $property->getAnnotation("Skrz\\Meta\\Protobuf\\ProtobufField"); $toProtobuf->addBody("if (isset(\$object->{$property->getName()}) && (\$filter === null || isset(\$filter[" . var_export($property->getName(), true) . "]))) {"); $var = "\$object->{$property->getName()}"; $output = "\$output"; $indent = "\t"; if ($field->packed) { $toProtobuf->addBody("\t\$packedBuffer = '';")->addBody("\t\$output .= \"" . implode("", array_map(function ($s) { return "\\x" . $s; }, str_split(bin2hex(Binary::encodeVarint($field->number << 3 | WireTypeEnum::toBinaryWireType(WireTypeEnum::STRING))), 2))) . "\";"); $output = "\$packedBuffer"; } if ($propertyType->isArray()) { $toProtobuf->addBody("\tforeach ({$var} instanceof \\Traversable ? {$var} : (array){$var} as \$k => \$v) {"); $var = "\$v"; $indent .= "\t"; } if (!$field->packed) { $toProtobuf->addBody("{$indent}{$output} .= \"" . implode("", array_map(function ($s) { return "\\x" . $s; }, str_split(bin2hex(Binary::encodeVarint($field->number << 3 | WireTypeEnum::toBinaryWireType($field->wireType))), 2))) . "\";"); } switch ($field->wireType) { case WireTypeEnum::VARINT: $toProtobuf->addBody("{$indent}{$output} .= {$binary}::encodeVarint(" . ($baseType instanceof BoolType ? "(int)" : "") . "{$var});"); break; case WireTypeEnum::ZIGZAG: $toProtobuf->addBody("{$indent}{$output} .= {$binary}::encodeZigzag({$var});"); break; case WireTypeEnum::FIXED64: if ($baseType instanceof FloatType) { $toProtobuf->addBody("{$indent}{$output} .= {$binary}::encodeDouble({$var});"); } elseif ($baseType instanceof IntType && $field->unsigned) { $toProtobuf->addBody("{$indent}{$output} .= {$binary}::encodeUint64({$var});"); } elseif ($baseType instanceof IntType && !$field->unsigned) { $toProtobuf->addBody("{$indent}{$output} .= {$binary}::encodeInt64({$var});"); } else { throw new MetaException("Property {$type->getName()}::\${$property->getName()} has wire type '{$field->wireType}' and base type {$baseType}. " . "'{$field->wireType}' supports only float or int base types."); } break; case WireTypeEnum::STRING: if ($baseType instanceof StringType) { $toProtobuf->addBody("{$indent}{$output} .= {$binary}::encodeVarint(strlen({$var}));"); $toProtobuf->addBody("{$indent}{$output} .= {$var};"); } elseif ($baseType instanceof Type) { $propertyTypeMetaClassName = $spec->createMetaClassName($baseType); $ns->addUse($propertyTypeMetaClassName, null, $propertyTypeMetaClassNameAlias); $toProtobuf->addBody("{$indent}\$buffer = {$propertyTypeMetaClassNameAlias}::toProtobuf({$var}, \$filter === null ? null : \$filter[" . var_export($property->getName(), true) . "]);"); $toProtobuf->addBody("{$indent}{$output} .= {$binary}::encodeVarint(strlen(\$buffer));"); $toProtobuf->addBody("{$indent}{$output} .= \$buffer;"); } else { throw new MetaException("Property {$type->getName()}::\${$property->getName()} has wire type '{$field->wireType}' and base type {$baseType}. " . "'{$field->wireType}' supports only string or object types."); } break; case WireTypeEnum::FIXED32: if ($baseType instanceof FloatType) { $toProtobuf->addBody("{$indent}{$output} .= {$binary}::encodeFloat({$var});"); } elseif ($baseType instanceof IntType && $field->unsigned) { $toProtobuf->addBody("{$indent}{$output} .= {$binary}::encodeUint32({$var});"); } elseif ($baseType instanceof IntType && !$field->unsigned) { $toProtobuf->addBody("{$indent}{$output} .= {$binary}::encodeInt32({$var});"); } else { throw new MetaException("Property {$type->getName()}::\${$property->getName()} has wire type '{$field->wireType}' and base type {$baseType}. " . "'{$field->wireType}' supports only float or int base types."); } break; } if ($propertyType->isArray()) { $toProtobuf->addBody("\t}"); } if ($field->packed) { $toProtobuf->addBody("\t\$output .= {$binary}::encodeVarint(strlen(\$packedBuffer));"); $toProtobuf->addBody("\t\$output .= \$packedBuffer;"); } $toProtobuf->addBody("}")->addBody(""); } $toProtobuf->addBody("return \$output;"); }
/** * Serialized \Google\Protobuf\MethodDescriptorProto to Protocol Buffers message. * * @param MethodDescriptorProto $object * @param array $filter * * @throws \Exception * * @return string */ public static function toProtobuf($object, $filter = NULL) { $output = ''; if (isset($object->name) && ($filter === null || isset($filter['name']))) { $output .= "\n"; $output .= Binary::encodeVarint(strlen($object->name)); $output .= $object->name; } if (isset($object->inputType) && ($filter === null || isset($filter['inputType']))) { $output .= ""; $output .= Binary::encodeVarint(strlen($object->inputType)); $output .= $object->inputType; } if (isset($object->outputType) && ($filter === null || isset($filter['outputType']))) { $output .= ""; $output .= Binary::encodeVarint(strlen($object->outputType)); $output .= $object->outputType; } if (isset($object->options) && ($filter === null || isset($filter['options']))) { $output .= "\""; $buffer = MethodOptionsMeta::toProtobuf($object->options, $filter === null ? null : $filter['options']); $output .= Binary::encodeVarint(strlen($buffer)); $output .= $buffer; } if (isset($object->clientStreaming) && ($filter === null || isset($filter['clientStreaming']))) { $output .= "("; $output .= Binary::encodeVarint((int) $object->clientStreaming); } if (isset($object->serverStreaming) && ($filter === null || isset($filter['serverStreaming']))) { $output .= "0"; $output .= Binary::encodeVarint((int) $object->serverStreaming); } return $output; }
/** * Serialized \Google\Protobuf\SourceCodeInfo\Location to Protocol Buffers message. * * @param Location $object * @param array $filter * * @throws \Exception * * @return string */ public static function toProtobuf($object, $filter = NULL) { $output = ''; if (isset($object->path) && ($filter === null || isset($filter['path']))) { $packedBuffer = ''; $output .= "\n"; foreach ($object->path instanceof \Traversable ? $object->path : (array) $object->path as $k => $v) { $packedBuffer .= Binary::encodeVarint($v); } $output .= Binary::encodeVarint(strlen($packedBuffer)); $output .= $packedBuffer; } if (isset($object->span) && ($filter === null || isset($filter['span']))) { $packedBuffer = ''; $output .= ""; foreach ($object->span instanceof \Traversable ? $object->span : (array) $object->span as $k => $v) { $packedBuffer .= Binary::encodeVarint($v); } $output .= Binary::encodeVarint(strlen($packedBuffer)); $output .= $packedBuffer; } if (isset($object->leadingComments) && ($filter === null || isset($filter['leadingComments']))) { $output .= ""; $output .= Binary::encodeVarint(strlen($object->leadingComments)); $output .= $object->leadingComments; } if (isset($object->trailingComments) && ($filter === null || isset($filter['trailingComments']))) { $output .= "\""; $output .= Binary::encodeVarint(strlen($object->trailingComments)); $output .= $object->trailingComments; } if (isset($object->leadingDetachedComments) && ($filter === null || isset($filter['leadingDetachedComments']))) { foreach ($object->leadingDetachedComments instanceof \Traversable ? $object->leadingDetachedComments : (array) $object->leadingDetachedComments as $k => $v) { $output .= "2"; $output .= Binary::encodeVarint(strlen($v)); $output .= $v; } } return $output; }