/**
  * @param Entity $entity
  */
 public function visit(Entity $entity)
 {
     $type = $entity->getType();
     $class = $entity->getNamespacedName();
     $path = $this->getPsr4ClassPath($class);
     $entity->setPath($path);
     if (!isset($this->generators[$type])) {
         return;
     }
     $this->generators[$type]->visit($entity);
 }
 /**
  * @param \Protobuf\Compiler\Entity $entity
  *
  * @return string[]
  */
 public function generateBody(Entity $entity)
 {
     $lines = [];
     $descriptor = $entity->getDescriptor();
     $class = $entity->getNamespacedName();
     $fields = $descriptor->getFieldList() ?: [];
     $message = var_export("Argument 1 passed to %s must be a %s, %s given", true);
     $exception = 'sprintf(' . $message . ', __METHOD__, __CLASS__, get_class($message))';
     $lines[] = 'if ( ! $message instanceof ' . $class . ') {';
     $lines[] = '    throw new \\InvalidArgumentException(' . $exception . ');';
     $lines[] = '}';
     $lines[] = null;
     foreach ($fields as $field) {
         $item = $this->generateFieldMerge($entity, $field);
         $lines = array_merge($lines, $item);
     }
     return $lines;
 }
 /**
  * @param \Protobuf\Compiler\Entity             $entity
  * @param \google\protobuf\FieldDescriptorProto $field
  *
  * @return string[]
  */
 protected function generateRequiredFieldException(Entity $entity, FieldDescriptorProto $field)
 {
     $name = $field->getName();
     $label = $field->getLabel();
     $tag = $field->getNumber();
     $isRequired = $label === Label::LABEL_REQUIRED();
     if (!$isRequired) {
         return [];
     }
     $class = $entity->getNamespacedName();
     $format = 'Field "%s#%s" (tag %s) is required but has no value.';
     $message = var_export(sprintf($format, $class, $name, $tag), true);
     $body[] = 'if ($this->' . $name . ' === null) {';
     $body[] = '    throw new \\UnexpectedValueException(' . $message . ');';
     $body[] = '}';
     $body[] = null;
     return $body;
 }
 /**
  * @param \Protobuf\Compiler\Entity             $entity
  * @param \google\protobuf\FieldDescriptorProto $field
  *
  * @return string[]
  */
 protected function generateRequiredFieldException(Entity $entity, FieldDescriptorProto $field)
 {
     $name = $field->getName();
     $tag = $field->getNumber();
     $class = $entity->getNamespacedName();
     $format = 'Field "%s" (tag %s) is required but has no value.';
     $message = var_export(sprintf($format, $name, $tag), true);
     $body[] = 'if ( ! isset($values[\'' . $name . '\'])) {';
     $body[] = '    throw new \\InvalidArgumentException(' . $message . ');';
     $body[] = '}';
     return $body;
 }
 /**
  * @param \Protobuf\Compiler\Entity $entity
  *
  * @return bool
  */
 protected function loadEntityClass(Entity $entity)
 {
     $type = $entity->getType();
     $content = $entity->getContent();
     $class = $entity->getNamespacedName();
     if (class_exists($class) || interface_exists($class)) {
         return false;
     }
     $this->logger->info(sprintf('Loading class "%s"', $class));
     $tempname = tempnam(sys_get_temp_dir(), 'proto') . '.php';
     file_put_contents($tempname, $content);
     include $tempname;
     @unlink($tempname);
     if ($type === Entity::TYPE_EXTENSION) {
         $this->logger->info(sprintf('Registering extension "%s"', $class));
         $config = $this->config;
         $registry = $config->getExtensionRegistry();
         $class::registerAllExtensions($registry);
         return true;
     }
     return false;
 }
 /**
  * @param \Protobuf\Compiler\Entity $entity
  *
  * @return string
  */
 public function generateValueOfMethod(Entity $entity)
 {
     $body = [];
     $descriptor = $entity->getDescriptor();
     $class = $entity->getNamespacedName();
     $values = $descriptor->getValueList() ?: [];
     $body[] = 'switch ($value) {';
     foreach ($values as $value) {
         $name = $value->getName();
         $number = $value->getNumber();
         $body[] = '    case ' . $number . ': return self::' . $name . '();';
     }
     $body[] = '    default: return null;';
     $body[] = '}';
     $method = MethodGenerator::fromArray(['static' => true, 'name' => 'valueOf', 'body' => implode(PHP_EOL, $body), 'parameters' => [['name' => 'value', 'type' => 'int']], 'docblock' => ['tags' => [['name' => 'param', 'description' => 'int $value'], ['name' => 'return', 'description' => $class]]]]);
     $method->getDocblock()->setWordWrap(false);
     return $method;
 }
 public function testGetNamespacedName()
 {
     $name = 'SimpleMessage';
     $type = Entity::TYPE_MESSAGE;
     $descriptor = new DescriptorProto();
     $fileDescriptor1 = new FileDescriptorProto();
     $fileDescriptor2 = new FileDescriptorProto();
     $fileDescriptor3 = new FileDescriptorProto();
     $fileDescriptor2->setPackage('package');
     $fileDescriptor3->setPackage('package');
     $entity1 = new Entity($type, $name, $descriptor, $fileDescriptor1);
     $entity2 = new Entity($type, $name, $descriptor, $fileDescriptor2);
     $entity3 = new Entity($type, $name, $descriptor, $fileDescriptor3, 'Parent');
     $this->assertEquals('\\SimpleMessage', $entity1->getNamespacedName());
     $this->assertEquals('\\package\\SimpleMessage', $entity2->getNamespacedName());
     $this->assertEquals('\\package\\Parent\\SimpleMessage', $entity3->getNamespacedName());
 }