/**
  * @param \Protobuf\Compiler\Entity             $entity
  * @param \google\protobuf\FieldDescriptorProto $field
  *
  * @return array
  */
 protected function generateFieldMerge(Entity $entity, FieldDescriptorProto $field)
 {
     $lines = [];
     $fieldName = $field->getName();
     $format = '$this->%s = ($message->%s !== null) ? $message->%s : $this->%s;';
     $lines[] = sprintf($format, $fieldName, $fieldName, $fieldName, $fieldName);
     return $lines;
 }
 /**
  * @param \Protobuf\Compiler\Entity             $entity
  * @param \google\protobuf\FieldDescriptorProto $field
  *
  * @return string[]
  */
 public function generateFieldWriteStatement(Entity $entity, FieldDescriptorProto $field)
 {
     $body = [];
     $name = $field->getName();
     $type = $field->getType();
     $rule = $field->getLabel();
     $tag = $field->getNumber();
     $options = $field->getOptions();
     $variable = $this->targetVar ?: '$this->' . $name;
     $isPack = $options ? $options->getPacked() : false;
     $wire = $isPack ? WireFormat::WIRE_LENGTH : WireFormat::getWireType($type->value(), null);
     $key = WireFormat::getFieldKey($tag, $wire);
     if ($rule === Label::LABEL_REPEATED() && $isPack) {
         $itemValSttm = $type === Type::TYPE_ENUM() ? '$val->value()' : '$val';
         $body[] = '$innerSize   = 0;';
         $body[] = '$calculator  = $sizeContext->getSizeCalculator();';
         $body[] = null;
         $body[] = 'foreach (' . $variable . ' as $val) {';
         $body[] = '    $innerSize += ' . $this->generateValueSizeStatement($type->value(), $itemValSttm) . ';';
         $body[] = '}';
         $body[] = null;
         $body[] = '$writer->writeVarint($stream, ' . $key . ');';
         $body[] = '$writer->writeVarint($stream, $innerSize);';
         $body[] = null;
         $body[] = 'foreach (' . $variable . ' as $val) {';
         $body[] = '    ' . $this->generateWriteScalarStatement($type->value(), $itemValSttm) . ';';
         $body[] = '}';
         return $body;
     }
     if ($type === Type::TYPE_MESSAGE() && $rule === Label::LABEL_REPEATED()) {
         $body[] = 'foreach (' . $variable . ' as $val) {';
         $body[] = '    $writer->writeVarint($stream, ' . $key . ');';
         $body[] = '    $writer->writeVarint($stream, $val->serializedSize($sizeContext));';
         $body[] = '    $val->writeTo($context);';
         $body[] = '}';
         return $body;
     }
     if ($type === Type::TYPE_ENUM() && $rule === LABEL::LABEL_REPEATED()) {
         $body[] = 'foreach (' . $variable . ' as $val) {';
         $body[] = '    $writer->writeVarint($stream, ' . $key . ');';
         $body[] = '    ' . $this->generateWriteScalarStatement($type->value(), '$val->value()') . ';';
         $body[] = '}';
         return $body;
     }
     if ($rule === Label::LABEL_REPEATED()) {
         $body[] = 'foreach (' . $variable . ' as $val) {';
         $body[] = '    $writer->writeVarint($stream, ' . $key . ');';
         $body[] = '    ' . $this->generateWriteScalarStatement($type->value(), '$val') . ';';
         $body[] = '}';
         return $body;
     }
     if ($type === Type::TYPE_ENUM()) {
         $body[] = sprintf('$writer->writeVarint($stream, %s);', $key);
         $body[] = $this->generateWriteScalarStatement($type->value(), $variable . '->value()') . ';';
         return $body;
     }
     if ($type !== Type::TYPE_MESSAGE()) {
         $body[] = sprintf('$writer->writeVarint($stream, %s);', $key);
         $body[] = $this->generateWriteScalarStatement($type->value(), $variable) . ';';
         return $body;
     }
     $body[] = '$writer->writeVarint($stream, ' . $key . ');';
     $body[] = '$writer->writeVarint($stream, ' . $variable . '->serializedSize($sizeContext));';
     $body[] = $variable . '->writeTo($context);';
     return $body;
 }
 /**
  * @param \Protobuf\Compiler\Entity             $entity
  * @param \google\protobuf\FieldDescriptorProto $field
  *
  * @return string[]
  */
 public function generateFieldReadStatement(Entity $entity, FieldDescriptorProto $field)
 {
     $body = [];
     $reference = null;
     $type = $field->getType();
     $name = $field->getName();
     $rule = $field->getLabel();
     $tag = $field->getNumber();
     $options = $field->getOptions();
     $isPack = $options ? $options->getPacked() : false;
     $variable = $this->targetVar ?: '$this->' . $name;
     $breakSttm = $this->getBreakStatement($variable);
     if ($field->hasTypeName()) {
         $typeName = $field->getTypeName();
         $typeEntity = $this->getEntity($typeName);
         $reference = $typeEntity->getNamespacedName();
     }
     if (!$isPack) {
         $body[] = sprintf('\\Protobuf\\WireFormat::assertWireType($wire, %s);', $type->value());
         $body[] = null;
     }
     if ($rule === Label::LABEL_REPEATED() && $isPack) {
         $readSttm = $type === Type::TYPE_ENUM() ? $reference . '::valueOf(' . $this->generateReadScalarStatement($type->value()) . ')' : $this->generateReadScalarStatement($type->value());
         $body[] = '$innerSize  = $reader->readVarint($stream);';
         $body[] = '$innerLimit = $stream->tell() + $innerSize;';
         $body[] = null;
         $body[] = 'if (' . $variable . ' === null) {';
         $body[] = '    ' . $variable . ' = new ' . $this->getCollectionClassName($field) . '();';
         $body[] = '}';
         $body[] = null;
         $body[] = 'while ($stream->tell() < $innerLimit) {';
         $body[] = '    ' . $variable . '->add(' . $readSttm . ');';
         $body[] = '}';
         $body[] = null;
         $body[] = $breakSttm;
         return $body;
     }
     if ($type === Type::TYPE_MESSAGE() && $rule === Label::LABEL_REPEATED()) {
         $body[] = '$innerSize    = $reader->readVarint($stream);';
         $body[] = '$innerMessage = new ' . $reference . '();';
         $body[] = null;
         $body[] = 'if (' . $variable . ' === null) {';
         $body[] = '    ' . $variable . ' = new \\Protobuf\\MessageCollection();';
         $body[] = '}';
         $body[] = null;
         $body[] = $variable . '->add($innerMessage);';
         $body[] = null;
         $body[] = '$context->setLength($innerSize);';
         $body[] = '$innerMessage->readFrom($context);';
         $body[] = '$context->setLength($length);';
         $body[] = null;
         $body[] = $breakSttm;
         return $body;
     }
     if ($type === Type::TYPE_ENUM() && $rule === LABEL::LABEL_REPEATED()) {
         $body[] = 'if (' . $variable . ' === null) {';
         $body[] = '    ' . $variable . ' = new ' . $this->getCollectionClassName($field) . '();';
         $body[] = '}';
         $body[] = null;
         $body[] = $variable . '->add(' . $reference . '::valueOf(' . $this->generateReadScalarStatement($type->value()) . '));';
         $body[] = null;
         $body[] = $breakSttm;
         return $body;
     }
     if ($type === Type::TYPE_MESSAGE()) {
         $body[] = '$innerSize    = $reader->readVarint($stream);';
         $body[] = '$innerMessage = new ' . $reference . '();';
         $body[] = null;
         $body[] = $variable . ' = $innerMessage;';
         $body[] = null;
         $body[] = '$context->setLength($innerSize);';
         $body[] = '$innerMessage->readFrom($context);';
         $body[] = '$context->setLength($length);';
         $body[] = null;
         $body[] = $breakSttm;
         return $body;
     }
     if ($type === Type::TYPE_ENUM()) {
         $body[] = $variable . ' = ' . $reference . '::valueOf(' . $this->generateReadScalarStatement($type->value()) . ');';
         $body[] = null;
         $body[] = $breakSttm;
         return $body;
     }
     if ($rule !== LABEL::LABEL_REPEATED()) {
         $body[] = $variable . ' = ' . $this->generateReadScalarStatement($type->value()) . ';';
         $body[] = null;
         $body[] = $breakSttm;
         return $body;
     }
     $body[] = 'if (' . $variable . ' === null) {';
     $body[] = '    ' . $variable . ' = new ' . $this->getCollectionClassName($field) . '();';
     $body[] = '}';
     $body[] = null;
     $body[] = $variable . '->add(' . $this->generateReadScalarStatement($type->value()) . ');';
     $body[] = null;
     $body[] = $breakSttm;
     return $body;
 }
Пример #4
0
 protected function generateAccessors(proto\FieldDescriptorProto $field, $ns, $indent)
 {
     $tag = $field->getNumber();
     $name = $field->getName();
     $camel = $this->compiler->camelize(ucfirst($name));
     $typehint = '';
     $typedoc = $this->getJavaDocType($field);
     if (0 === strpos($typedoc, '\\')) {
         $typehint = $typedoc;
     }
     // hasXXX
     $s[] = "/**";
     $s[] = " * Check if <{$name}> has a value";
     $s[] = " *";
     $s[] = " * @return boolean";
     $s[] = " */";
     $s[] = "public function has{$camel}(){";
     $s[] = "  return \$this->_has({$tag});";
     $s[] = "}";
     $s[] = "";
     // clearXXX
     $s[] = "/**";
     $s[] = " * Clear <{$name}> value";
     $s[] = " *";
     $s[] = " * @return \\" . $this->normalizeNS($ns);
     $s[] = " */";
     $s[] = "public function clear{$camel}(){";
     $s[] = "  return \$this->_clear({$tag});";
     $s[] = "}";
     $s[] = "";
     if ($field->getLabel() === Protobuf::RULE_REPEATED) {
         // getXXX
         $s[] = "/**";
         $s[] = " * Get <{$name}> value";
         $s[] = " *";
         $s[] = " * @param int \$idx";
         $s[] = " * @return {$typedoc}";
         $s[] = " */";
         $s[] = "public function get{$camel}(\$idx = NULL){";
         $s[] = "  return \$this->_get({$tag}, \$idx);";
         $s[] = "}";
         $s[] = "";
         // setXXX
         $s[] = "/**";
         $s[] = " * Set <{$name}> value";
         $s[] = " *";
         $s[] = " * @param {$typedoc} \$value";
         $s[] = " * @return \\" . $this->normalizeNS($ns);
         $s[] = " */";
         $s[] = "public function set{$camel}({$typehint} \$value, \$idx = NULL){";
         $s[] = "  return \$this->_set({$tag}, \$value, \$idx);";
         $s[] = "}";
         $s[] = "";
         $s[] = "/**";
         $s[] = " * Get all elements of <{$name}>";
         $s[] = " *";
         $s[] = " * @return {$typedoc}[]";
         $s[] = " */";
         $s[] = "public function get{$camel}List(){";
         $s[] = " return \$this->_get({$tag});";
         $s[] = "}";
         $s[] = "";
         $s[] = "/**";
         $s[] = " * Add a new element to <{$name}>";
         $s[] = " *";
         $s[] = " * @param {$typedoc} \$value";
         $s[] = " * @return \\" . $this->normalizeNS($ns);
         $s[] = " */";
         $s[] = "public function add{$camel}({$typehint} \$value){";
         $s[] = " return \$this->_add({$tag}, \$value);";
         $s[] = "}";
         $s[] = "";
     } else {
         // getXXX
         $s[] = "/**";
         $s[] = " * Get <{$name}> value";
         $s[] = " *";
         $s[] = " * @return {$typedoc}";
         $s[] = " */";
         $s[] = "public function get{$camel}(){";
         $s[] = "  return \$this->_get({$tag});";
         $s[] = "}";
         $s[] = "";
         // setXXX
         $s[] = "/**";
         $s[] = " * Set <{$name}> value";
         $s[] = " *";
         $s[] = " * @param {$typedoc} \$value";
         $s[] = " * @return \\" . $this->normalizeNS($ns);
         $s[] = " */";
         $s[] = "public function set{$camel}({$typehint} \$value){";
         $s[] = "  return \$this->_set({$tag}, \$value);";
         $s[] = "}";
         $s[] = "";
     }
     return $indent . implode(PHP_EOL . $indent, $s);
 }
 /**
  * @param \Protobuf\Compiler\Entity             $entity
  * @param \google\protobuf\FieldDescriptorProto $field
  *
  * @return string
  */
 protected function generateExtensionMethod(Entity $entity, FieldDescriptorProto $field)
 {
     $fieldName = $field->getName();
     $descriptor = $entity->getDescriptor();
     $methodName = $this->getCamelizedName($field);
     $bodyGen = new ExtensionsGenerator($this->context);
     $body = implode(PHP_EOL, $bodyGen->generateBody($entity, $field));
     $method = MethodGenerator::fromArray(['static' => true, 'body' => $body, 'name' => $methodName, 'docblock' => ['shortDescription' => "Extension field : {$fieldName}", 'tags' => [['name' => 'return', 'description' => '\\Protobuf\\Extension']]]]);
     $method->getDocblock()->setWordWrap(false);
     return $method;
 }
 /**
  * @param \Protobuf\Compiler\Entity             $entity
  * @param \google\protobuf\FieldDescriptorProto $field
  *
  * @return array
  */
 protected function generateAddValue(Entity $entity, FieldDescriptorProto $field)
 {
     $lines = [];
     $fieldName = $field->getName();
     $methodName = 'add' . $this->getClassifiedName($field);
     $lines[] = 'foreach ($values[\'' . $fieldName . '\'] as $item) {';
     $lines[] = '    $message->' . $methodName . '($item);';
     $lines[] = '}';
     return $lines;
 }
 /**
  * @param \google\protobuf\FieldDescriptorProto $field
  *
  * @return string
  */
 protected function getCamelizedName(FieldDescriptorProto $field)
 {
     $name = $field->getName();
     $value = $this->getCamelizedValue($name);
     return $value;
 }
Пример #8
0
 public function generateField(proto\FieldDescriptorProto $field)
 {
     $reference = 'null';
     if ($field->hasTypeName()) {
         $reference = $field->getTypeName();
         if (substr($reference, 0, 1) !== '.') {
             throw new \RuntimeException('Only fully qualified names are supported: ' . $reference);
         }
         $reference = "'" . $this->normalizeNS($reference) . "'";
     }
     $default = 'null';
     if ($field->hasDefaultValue()) {
         switch ($field->getType()) {
             case Protobuf::TYPE_BOOL:
                 $default = $field->getDefaultValue() ? 'true' : 'false';
                 break;
             case Protobuf::TYPE_STRING:
                 $default = '"' . addcslashes($field->getDefaultValue(), '"\\') . '"';
                 break;
             case Protobuf::TYPE_ENUM:
                 $default = $this->normalizeNS($field->getTypeName()) . '.' . $field->getDefaultValue();
                 break;
             default:
                 // Numbers
                 $default = $field->getDefaultValue();
         }
     }
     $data = array("'" . $field->getName() . "'", $field->getLabel(), $field->getType(), $reference, $default, '{}');
     return '[' . implode(', ', $data) . ']';
 }
 /**
  * @param \google\protobuf\FieldDescriptorProto $field
  *
  * @return string[]
  */
 protected function generateFieldBody(FieldDescriptorProto $field)
 {
     $lines = [];
     $name = $field->getName();
     $number = $field->getNumber();
     $typeName = $field->getTypeName();
     $extendee = $field->getExtendee();
     $type = $field->getType()->name();
     $label = $field->getLabel()->name();
     $default = $this->getDefaultFieldValue($field);
     $values = ['number' => var_export($number, true), 'name' => var_export($name, true), 'type' => '\\google\\protobuf\\FieldDescriptorProto\\Type::' . $type . '()', 'label' => '\\google\\protobuf\\FieldDescriptorProto\\Label::' . $label . '()'];
     if ($extendee) {
         $values['extendee'] = var_export($extendee, true);
     }
     if ($typeName) {
         $values['type_name'] = var_export($typeName, true);
     }
     if ($field->hasDefaultValue()) {
         $values['default_value'] = $default;
     }
     $lines[] = '\\google\\protobuf\\FieldDescriptorProto::fromArray([';
     $lines = array_merge($lines, $this->generateArrayLines($values));
     $lines[] = ']),';
     return $lines;
 }
 /**
  * @param \Protobuf\Compiler\Entity             $entity
  * @param \google\protobuf\FieldDescriptorProto $field
  *
  * @return string
  */
 protected function generateExtensionField(Entity $entity, FieldDescriptorProto $field)
 {
     $name = $field->getName();
     $number = $field->getNumber();
     $docBlock = $this->getDocBlockType($field);
     $type = $this->getFieldTypeName($field);
     $label = $this->getFieldLabelName($field);
     $property = PropertyGenerator::fromArray(['static' => true, 'name' => $name, 'visibility' => PropertyGenerator::VISIBILITY_PROTECTED, 'docblock' => ['shortDescription' => "Extension field : {$name} {$label} {$type} = {$number}", 'tags' => [['name' => 'var', 'description' => '\\Protobuf\\Extension']]]]);
     $property->getDocblock()->setWordWrap(false);
     return $property;
 }
 /**
  * @param \Protobuf\Compiler\Entity             $entity
  * @param \google\protobuf\FieldDescriptorProto $field
  *
  * @return string[]
  */
 protected function generateFieldCondition(Entity $entity, FieldDescriptorProto $field)
 {
     $body = [];
     $fieldName = $field->getName();
     $format = 'if ($this->%s !== null) {';
     $sttm = $this->generateFieldWriteStatement($entity, $field);
     $lines = $this->addIndentation($sttm, 1);
     $body[] = sprintf($format, $fieldName);
     $body = array_merge($body, $lines);
     $body[] = '}';
     return $body;
 }