unset($GLOBALS['argv'][$key + 1]); } } } if ($optionError || count($argv) != 2) { printf('USAGE: %s [OPTIONS] PROTO_FILE' . PHP_EOL, $argv[0]); printf(' -n, --use-namespaces Use native PHP namespaces' . PHP_EOL); printf(' -p, --filename-prefix [PREFIX] Specify a prefix for generated file names' . PHP_EOL); printf(' --psr Output class files in a psr-4 directory structure' . PHP_EOL); exit(1); } // Reindex argv $GLOBALS['argv'] = array_values($GLOBALS['argv']); $parser = new ProtobufParser($useNamespaces); if ($filenamePrefix !== false) { $parser->setFilenamePrefix($filenamePrefix); } if ($outputPsr !== false) { $parser->setSavePsrOutput(true); } $file = $argv[1]; if (!file_exists($file)) { printf($file . ' does not exist' . PHP_EOL); exit(1); } if (!is_file($file)) { printf($file . ' is not a file' . PHP_EOL); exit(1); } try { $parser->parse($file);
/** * Parses protobuf file and returns MessageDescriptor * * @param FileDescriptor $file File descriptors * @param string $messageContent Protobuf message content * @param MessageDescriptor $parent Parent message (if nested) * * @return MessageDescriptor * * @throws Exception */ private function _parseMessageType(FileDescriptor $file, $messageContent, MessageDescriptor $parent = null) { if ($messageContent == '') { return; } while (strlen($messageContent) > 0) { $next = $this->_next($messageContent); if (strtolower($next) == 'message') { $messageContent = trim(substr($messageContent, strlen($next))); $name = $this->_next($messageContent); $offset = $this->_getBeginEnd($messageContent, '{', '}'); // now extract the content and call parse_message again $content = trim(substr($messageContent, $offset['begin'] + 1, $offset['end'] - $offset['begin'] - 2)); $childMessage = new MessageDescriptor($name, $file, $parent); $this->_parseMessageType($file, $content, $childMessage); $messageContent = '' . trim(substr($messageContent, $offset['end'])); } else { if (strtolower($next) == 'enum') { $messageContent = trim(substr($messageContent, strlen($next))); $name = $this->_next($messageContent); $offset = $this->_getBeginEnd($messageContent, '{', '}'); // now extract the content and call parse_message again $content = trim(substr($messageContent, $offset['begin'] + 1, $offset['end'] - $offset['begin'] - 2)); $enum = new EnumDescriptor($name, $file, $parent); $this->_parseEnum($enum, $content); // ignore ";" at the end of the enum definition if (strlen($messageContent) > $offset['end'] && $messageContent[$offset['end']] === ';') { $offset['end']++; } // removing it from string $messageContent = '' . trim(substr($messageContent, $offset['end'])); } else { if (strtolower($next) == 'import') { $name = $this->_next($messageContent); $match = preg_match('/"([^"]+)";*\\s?/', $messageContent, $matches, PREG_OFFSET_CAPTURE); if (!$match) { throw new Exception('Malformed include / look at your import statement: ' . $messageContent); } $includedFilename = $matches[1][0]; if (!file_exists($includedFilename)) { foreach ($this->_includes as &$dir) { $fn = $dir . "/" . $includedFilename; if (file_exists($fn)) { $includedFilename = $fn; break; } } } if (!file_exists($includedFilename)) { throw new Exception('Included file ' . $includedFilename . ' does not exist'); } $messageContent = trim(substr($messageContent, $matches[0][1] + strlen($matches[0][0]))); $parserKey = realpath($includedFilename); if (!isset(self::$_parsers[$parserKey])) { $pbp = new ProtobufParser($this->_useNativeNamespaces, $this->_includes); $pbp->setFilenamePrefix($this->_filenamePrefix); self::$_parsers[$parserKey] = $pbp; } else { $pbp = self::$_parsers[$parserKey]; } $file->addDependency($pbp->parse($includedFilename)); } else { if (strtolower($next) == 'option') { // We don't support option parameters just yet, skip for now. $messageContent = preg_replace('/^.+\\n/', '', $messageContent); } else { if (strtolower($next) == 'extensions') { // We don't support extension parameters just yet, skip for now. $messageContent = trim(preg_replace('/^.+;/', '', $messageContent)); } else { if (strtolower($next) == 'package') { $match = preg_match('/package[\\s]+([^;]+);?/', $messageContent, $matches, PREG_OFFSET_CAPTURE); if (!$match) { throw new Exception('Malformed package'); } $file->setPackage($matches[1][0]); $messageContent = trim(substr($messageContent, $matches[0][1] + strlen($matches[0][0]))); } else { // now a normal field $match = preg_match('/(.*);/', $messageContent, $matches, PREG_OFFSET_CAPTURE); if (!$match || !$parent) { throw new Exception('Proto file missformed'); } $parent->addField($this->_parseField($matches[0][0])); $messageContent = trim(substr($messageContent, $matches[0][1] + strlen($matches[0][0]))); } } } } } } } }