/** * @param \Protobuf\Stream $stream * * @return \Protobuf\Stream */ public function compile(Stream $stream) { // Parse the request $request = CodeGeneratorRequest::fromStream($stream, $this->config); $response = new CodeGeneratorResponse(); $context = $this->createContext($request); $entities = $context->getEntities(); $options = $context->getOptions(); $generator = new Generator($context); // whether or not it will renegerate classes with new extensions $regenerate = false; $hasExtension = $context->hasProtobufExtension(); // Run each entity foreach ($entities as $key => $entity) { $generateImported = $options->getGenerateImported(); $isFileToGenerate = $entity->isFileToGenerate(); // Only compile those given to generate, not the imported ones if (!$generateImported && !$isFileToGenerate) { $this->logger->debug(sprintf('Skipping generation of imported class "%s"', $entity->getClass())); continue; } $this->logger->info(sprintf('Generating class "%s"', $entity->getClass())); $generator->visit($entity); $file = new File(); $path = $entity->getPath(); $content = $entity->getContent(); $file->setName($path); $file->setContent($content); $response->addFile($file); if ($hasExtension && $this->loadEntityClass($entity)) { $regenerate = true; } } if ($regenerate) { $this->logger->info('Regenerating classes with new extensions'); $stream->seek(0); // Renegerate classes with new extensions return $this->compile($stream); } $this->logger->info('Generation completed.'); // Finally serialize the response object return $response->toStream($this->config); }
public function testGenerateSimpleMessage() { $binaryRequest = $this->getFixtureFileContent('compiler/generator-request-simple.bin'); $expectedContent = $this->getFixtureFileContent('Simple.tpl'); $compiler = new Compiler($this->logger); $binaryResponse = $compiler->compile(Stream::wrap($binaryRequest)); $response = CodeGeneratorResponse::fromStream($binaryResponse); $this->assertInstanceOf('google\\protobuf\\compiler\\CodeGeneratorResponse', $response); $this->assertInstanceOf('Protobuf\\Collection', $response->getFileList()); $this->assertCount(1, $response->getFileList()); $file = $response->getFileList()[0]; $this->assertInstanceOf('google\\protobuf\\compiler\\CodeGeneratorResponse\\File', $file); $this->assertEquals('ProtobufCompilerTest/Protos/Simple.php', $file->getName()); $this->assertEquals($expectedContent, $file->getContent()); }
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; }