/**
  * @return array
  */
 protected function getFileToGenerateMap()
 {
     $map = [];
     $list = $this->request->getFileToGenerateList();
     if ($list === null) {
         return $map;
     }
     foreach ($list as $fileName) {
         $map[$fileName] = $fileName;
     }
     return $map;
 }
 public function testBuildEntities()
 {
     $descriptor1 = $this->createFileDescriptorProto('simple.proto', 'Protos', ['messages' => [['name' => 'Simple', 'fields' => []]]]);
     $descriptor2 = $this->createFileDescriptorProto('include.proto', 'Protos', ['messages' => [['name' => 'Include', 'fields' => []]]]);
     $request = new CodeGeneratorRequest();
     $request->addProtoFile($descriptor1);
     $request->addProtoFile($descriptor2);
     $request->addFileToGenerate($descriptor1->getName());
     $builder = new EntityBuilder($request);
     $entities = $builder->buildEntities();
     $this->assertCount(2, $entities);
     $this->assertArrayhasKey('Protos.Simple', $entities);
     $this->assertArrayhasKey('Protos.Include', $entities);
     $this->assertInstanceOf(Entity::CLASS, $entities['Protos.Simple']);
     $this->assertInstanceOf(Entity::CLASS, $entities['Protos.Include']);
     $this->assertEquals('Protos.Simple', $entities['Protos.Simple']->getClass());
     $this->assertEquals('Protos.Include', $entities['Protos.Include']->getClass());
     $this->assertEquals(Entity::TYPE_MESSAGE, $entities['Protos.Simple']->getType());
     $this->assertEquals(Entity::TYPE_MESSAGE, $entities['Protos.Include']->getType());
     $this->assertTrue($entities['Protos.Simple']->isFileToGenerate());
     $this->assertFalse($entities['Protos.Include']->isFileToGenerate());
 }
Beispiel #3
0
 public function handle(CodeGeneratorRequest $request)
 {
     $files = array();
     foreach ((array) $request->getProtoFile() as $file) {
         /** @var FileDescriptorProto $file */
         $this->collectFile($file, array());
         $specClassName = "Skrz\\Meta\\MetaSpec";
         $customSpecClassName = false;
         foreach ($file->getSourceCodeInfo()->getLocation() as $location) {
             if ($location->getPath() === array(FileDescriptorProtoMeta::PACKAGE_PROTOBUF_FIELD) && $location->getLeadingComments() && preg_match("/@spec\\s+([a-zA-Z0-9_\\\\]+)/", $location->getLeadingComments(), $m)) {
                 $specClassName = $m[1];
                 $customSpecClassName = true;
             }
         }
         uksort($this->messages, function ($a, $b) {
             if (strlen($a) === strlen($b)) {
                 return strcmp($b, $a);
             }
             return strlen($b) - strlen($a);
         });
         $tmpFiles = array();
         foreach ($this->messages as $className => $message) {
             // compile message file
             $codeFile = new CodeGeneratorResponse\File();
             $codeFile->setName(str_replace("\\", "/", $className) . ".php");
             $result = $this->generateMessage($className, $message);
             $codeFile->setContent((string) $result->getFile());
             $files[$className] = $codeFile;
             // compile meta file
             if (!class_exists($className)) {
                 $tmpFiles[] = $tmpFile = tempnam(sys_get_temp_dir(), "protoc-gen-php");
                 file_put_contents($tmpFile, (string) $result->getFile());
                 require_once $tmpFile;
             }
             /** @var AbstractMetaSpec $spec */
             $spec = new $specClassName();
             if (!$customSpecClassName) {
                 $spec->match($className)->addModule(new ProtobufModule());
             }
             $metaResult = $spec->compile($type = Type::fromString($className));
             if ($metaResult !== null) {
                 $metaFile = new CodeGeneratorResponse\File();
                 $metaFile->setName(str_replace("\\", "/", $spec->createMetaClassName($type)) . ".php");
                 $metaFile->setContent((string) $metaResult->getFile());
                 $files[$metaResult->getClass()->getName()] = $metaFile;
             }
         }
         foreach ($tmpFiles as $tmpFile) {
             unlink($tmpFile);
         }
         foreach ($this->enums as $className => $enum) {
             $enumFile = new CodeGeneratorResponse\File();
             $enumFile->setName(str_replace("\\", "/", $className) . ".php");
             $result = $this->generateEnum($className, $enum);
             $enumFile->setContent((string) $result->getFile());
             $files[$className] = $enumFile;
         }
     }
     $response = new CodeGeneratorResponse();
     $response->setFile($files);
     return $response;
 }
 /**
  * @param \google\protobuf\compiler\CodeGeneratorRequest $request
  *
  * @return \Protobuf\Compiler\Options
  */
 protected function createOptions(CodeGeneratorRequest $request)
 {
     $parameter = $request->getParameter();
     $options = [];
     parse_str($parameter, $options);
     return Options::fromArray($options);
 }
 /**
  * @param array         $descriptors
  * @param array         $options
  * @param Configuration $Configuration
  *
  * @return \Protobuf\Compiler\Context
  */
 protected function createContext(array $descriptors, array $options = [], Configuration $config = null)
 {
     $cfg = $config ?: $this->config;
     $opts = Options::fromArray($options);
     $request = new CodeGeneratorRequest();
     foreach ($descriptors as $item) {
         if (is_array($item)) {
             $name = $item['name'];
             $values = $item['values'];
             $package = $item['package'];
             $item = $this->createFileDescriptorProto($name, $package, $values);
         }
         $request->addProtoFile($item);
         $request->addFileToGenerate($item->getName());
     }
     $builder = new EntityBuilder($request);
     $entities = $builder->buildEntities();
     $context = new Context($entities, $opts, $cfg);
     return $context;
 }
Beispiel #6
0
 public function setupDictionary(CodeGeneratorRequest $req)
 {
     /* rough parsing, but works fine */
     $result = array();
     foreach ($req->getProtoFile() as $file) {
         /* @var $file FileDescriptorProto */
         $path = $file->getName();
         $lines = preg_split("/\r?\n/", file_get_contents($path));
         $info = $file->getSourceCodeInfo();
         $result[$file->getName()] = array();
         $tmp_location = null;
         $is_nested = true;
         $type = 0;
         $stack = array();
         $tmp = array();
         $prior = 0;
         $llvel = 0;
         $prior = array(0, 0, 0);
         foreach ($info->getLocation() as $location) {
             /* @var $location \google\protobuf\SourceCodeInfo\Location */
             $path = $location->getPath();
             $span = $location->getSpan();
             if (empty($path)) {
                 // whole entry
                 continue;
             }
             $level = count($path);
             if (count($path) % 2 == 0 && $path[0] == 4) {
                 if ($prior[0] >= $level) {
                     array_pop($stack);
                     $prior[0] = $level - 1;
                 }
                 // whole
                 $name = substr($lines[$span[0]], $span[1], $span[2] - $span[1]);
                 if (preg_match("/^message/i", $name)) {
                     $stack[] = array("name" => $name, "info" => $location);
                     $prior[0] = $level;
                 } else {
                     if (preg_match("/^enum/i", $name)) {
                         $stack[] = array("name" => $name, "info" => $location);
                         $prior[0] = $level;
                     } else {
                         $tmp[] = $location;
                     }
                 }
             }
             if (count($path) % 2 == 1 && $path[0] == 4 && $path[count($path) - 1] == 1) {
                 // name
                 $name = substr($lines[$span[0]], $span[1], $span[2] - $span[1]);
                 // TODO(chobie): fix warnings
                 @(list($dummy, $n, $dummy) = explode(" ", $stack[count($stack) - 1]['name']));
                 if ($name == $n) {
                     // message or enum
                     $result[$file->getName()][$n]["message"] = $stack[count($stack) - 1]['info'];
                 } else {
                     $result[$file->getName()][$n][$name] = @$tmp[count($tmp) - 1];
                     array_pop($tmp);
                 }
             }
         }
         // remove source code info
         $file->clearSourceCodeInfo();
     }
     SourceInfoDictionary::register($result);
 }