/** * @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()); }
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; }
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); }