|
| 1 | +#!/usr/bin/env php |
| 2 | +<?php |
| 3 | + |
| 4 | +declare(strict_types=1); |
| 5 | + |
| 6 | +const PHP_PACKAGE_NAMESPACE = 'GamingPlatform\\Api'; |
| 7 | +const PHP_PACKAGE_PATH = '/project/php/GamingPlatform/Api'; |
| 8 | +const GO_PACKAGE_PATH = '/project/go'; |
| 9 | + |
| 10 | +function loadFiles($directory): void |
| 11 | +{ |
| 12 | + $entries = array_diff(scandir($directory), ['.', '..']); |
| 13 | + foreach ($entries as $entry) { |
| 14 | + $path = $directory . '/' . $entry; |
| 15 | + is_dir($path) ? loadFiles($path) : require_once $path; |
| 16 | + } |
| 17 | +} |
| 18 | + |
| 19 | +function findMessagesClasses(): array |
| 20 | +{ |
| 21 | + $definedMessages = array_filter( |
| 22 | + get_declared_classes(), |
| 23 | + static fn(string $class) => str_starts_with($class, PHP_PACKAGE_NAMESPACE) |
| 24 | + && in_array(\Google\Protobuf\Internal\Message::class, class_parents($class)) |
| 25 | + ); |
| 26 | + $domains = []; |
| 27 | + |
| 28 | + foreach ($definedMessages as $message) { |
| 29 | + preg_match( |
| 30 | + '/(?<domain>.*)\\\\(?<version>V\d+)\\\\(?<message>.*)/', |
| 31 | + substr($message, strlen(PHP_PACKAGE_NAMESPACE) + 1), |
| 32 | + $matches |
| 33 | + ); |
| 34 | + |
| 35 | + $domainKey = $matches['domain'] . $matches['version']; |
| 36 | + $domains[$domainKey] ??= ['name' => $matches['domain'], 'version' => $matches['version'], 'messages' => []]; |
| 37 | + $domains[$domainKey]['messages'][] = [ |
| 38 | + 'name' => $matches['message'], |
| 39 | + 'snakeName' => str_replace('\\', '_', $matches['message']), |
| 40 | + 'wireType' => !str_contains($matches['message'], '\\') |
| 41 | + ? $matches['domain'] . '.' . $matches['message'] . '.' . strtolower($matches['version']) |
| 42 | + : null |
| 43 | + ]; |
| 44 | + } |
| 45 | + |
| 46 | + return $domains; |
| 47 | +} |
| 48 | + |
| 49 | +function writePhpFiles(array $domains): void |
| 50 | +{ |
| 51 | + foreach ($domains as $domain) { |
| 52 | + $path = PHP_PACKAGE_PATH . '/' . $domain['name'] . '/' . $domain['version'] . '/' . $domain['name'] . $domain['version'] . '.php'; |
| 53 | + $namespace = PHP_PACKAGE_NAMESPACE . '\\' . $domain['name'] . '\\' . $domain['version']; |
| 54 | + |
| 55 | + $content = '<?php' . PHP_EOL . PHP_EOL; |
| 56 | + $content .= 'declare(strict_types=1);' . PHP_EOL . PHP_EOL; |
| 57 | + $content .= 'namespace ' . $namespace . ';' . PHP_EOL . PHP_EOL; |
| 58 | + $content .= '// This file is auto-generated. Do not edit!' . PHP_EOL . PHP_EOL; |
| 59 | + $content .= 'final class ' . $domain['name'] . $domain['version'] . PHP_EOL; |
| 60 | + $content .= '{' . PHP_EOL; |
| 61 | + foreach ($domain['messages'] as $message) { |
| 62 | + if ($message['wireType']) { |
| 63 | + $content .= ' public const string ' . $message['name'] . 'Type = \'' . $message['wireType'] . '\';' . PHP_EOL; |
| 64 | + } |
| 65 | + $content .= ' public static function create' . $message['snakeName'] . '(' . PHP_EOL; |
| 66 | + $content .= ' ?string $data = null' . PHP_EOL; |
| 67 | + $content .= ' ): ' . $message['name'] . ' {' . PHP_EOL; |
| 68 | + $content .= ' static $template;' . PHP_EOL; |
| 69 | + $content .= ' $template ??= new ' . $message['name'] . '();' . PHP_EOL; |
| 70 | + $content .= ' $message = clone $template;' . PHP_EOL; |
| 71 | + $content .= ' if ($data !== null) $message->mergeFromString($data);' . PHP_EOL; |
| 72 | + $content .= ' return $message;' . PHP_EOL; |
| 73 | + $content .= ' }' . PHP_EOL; |
| 74 | + } |
| 75 | + $content .= '}' . PHP_EOL; |
| 76 | + |
| 77 | + echo 'Write ' . $path . PHP_EOL; |
| 78 | + file_put_contents($path, $content); |
| 79 | + } |
| 80 | +} |
| 81 | + |
| 82 | +function writeGoFiles(array $domains): void |
| 83 | +{ |
| 84 | + foreach ($domains as $domain) { |
| 85 | + $path = GO_PACKAGE_PATH . '/' . strtolower($domain['name'] . '/' . $domain['version']) . '/gamingplatform.go'; |
| 86 | + |
| 87 | + $content = 'package ' . strtolower($domain['name'] . $domain['version']) . PHP_EOL . PHP_EOL; |
| 88 | + $content .= '// This file is auto-generated. Do not edit!' . PHP_EOL . PHP_EOL; |
| 89 | + foreach ($domain['messages'] as $message) { |
| 90 | + if ($message['wireType']) { |
| 91 | + $content .= 'const ' . $message['name'] . 'Type = "' . $message['wireType'] . '"' . PHP_EOL; |
| 92 | + } |
| 93 | + } |
| 94 | + |
| 95 | + echo 'Write ' . $path . PHP_EOL; |
| 96 | + file_put_contents($path, $content); |
| 97 | + } |
| 98 | +} |
| 99 | + |
| 100 | +loadFiles(PHP_PACKAGE_PATH); |
| 101 | + |
| 102 | +$messageClasses = findMessagesClasses(); |
| 103 | +writePhpFiles($messageClasses); |
| 104 | +writeGoFiles($messageClasses); |
0 commit comments