77use Nette \PhpGenerator \ClassType ;
88use Nette \PhpGenerator \Constant ;
99use Nette \PhpGenerator \Literal ;
10+ use Nette \PhpGenerator \Method ;
1011use Nette \PhpGenerator \Parameter ;
1112use Nette \PhpGenerator \PhpNamespace ;
1213use Thesis \Protoc \Plugin \NameIndex ;
@@ -20,8 +21,13 @@ public function __construct(
2021 private PhpNamespacer $ namespacer ,
2122 ) {}
2223
24+ /**
25+ * @param list<string> $dependencies
26+ */
2327 public function generate (
2428 NameIndex $ index ,
29+ string $ filename ,
30+ array $ dependencies ,
2531 string $ className ,
2632 string $ buffer ,
2733 ): PhpNamespace {
@@ -44,39 +50,84 @@ public function generate(
4450 $ namespace ->add ($ classType );
4551
4652 $ namespace ->addUse ('Thesis\Protobuf\Pool ' );
53+ $ namespace ->addUse ('Thesis\Protobuf\Pool\File ' );
4754 $ namespace ->addUse (\Override::class);
4855
49- $ classType
56+ $ method = $ classType
5057 ->addMethod ('register ' )
5158 ->setPublic ()
5259 ->setParameters ([
5360 new Parameter ('pool ' )->setType ('Pool\Registry ' ),
5461 ])
5562 ->setReturnType ('void ' )
56- ->addAttribute (\Override::class)
57- ->setBody (
58- \sprintf (
63+ ->addAttribute (\Override::class);
64+
65+ $ method ->addBody ('$pool->add(Pool\Descriptor::base64(self::DESCRIPTOR_BUFFER), new File( ' );
66+ $ method ->addBody (' name: ?, ' , [$ filename ]);
67+
68+ self ::pushParameter ($ method , 'dependencies ' , $ dependencies );
69+ self ::pushParameter (
70+ $ method ,
71+ 'messages ' ,
72+ $ index ->messageTypes ,
73+ static fn (string $ type , string $ fqcn ) => new Literal (
74+ \sprintf ("new File \\MessageDescriptor('%s', \\%s::class) " , $ type , $ fqcn ),
75+ ),
76+ );
77+ self ::pushParameter ($ method , 'enums ' , $ index ->enumTypes , static fn (string $ type , string $ fqcn ) => new Literal (
78+ \sprintf ("new File \\EnumDescriptor('%s', \\%s::class) " , $ type , $ fqcn ),
79+ ));
80+ self ::pushParameter (
81+ $ method ,
82+ 'services ' ,
83+ $ index ->grpc ,
84+ static fn (string $ type , object $ service ) => new Literal (
85+ vsprintf (
5986 <<<'PHP'
60- $pool->add(Pool\Descriptor::base64(self::DESCRIPTOR_BUFFER), [
61- %s,
62- ]);
87+ new File\ServiceDescriptor(
88+ name: '%s',
89+ clientFqcn: %s,
90+ serverFqcn: %s,
91+ )
6392PHP,
64- implode (", \n\t" , array_fill (0 , \count ($ index ), '? ' )),
65- ),
66- array_merge (
67- array_map (
68- static fn (string $ type , string $ fqcn ) => new Literal (\sprintf ("'%s' => new Pool \\MessageMetadata( \\%s::class) " , $ type , $ fqcn )),
69- array_keys ($ index ->messageTypes ),
70- array_values ($ index ->messageTypes ),
71- ),
72- array_map (
73- static fn (string $ type , string $ fqcn ) => new Literal (\sprintf ("'%s' => new Pool \\EnumMetadata( \\%s::class) " , $ type , $ fqcn )),
74- array_keys ($ index ->enumTypes ),
75- array_values ($ index ->enumTypes ),
76- ),
93+ [
94+ $ type ,
95+ isset ($ service ->client ) ? "\\{$ service ->client }::class " : 'null ' ,
96+ isset ($ service ->server ) ? "\\{$ service ->server }::class " : 'null ' ,
97+ ],
7798 ),
78- );
99+ ),
100+ );
101+
102+ $ method ->addBody (')); ' );
79103
80104 return $ namespace ;
81105 }
106+
107+ /**
108+ * @template K of array-key
109+ * @template V
110+ * @template R
111+ * @param non-empty-string $name
112+ * @param array<K, V> $items
113+ * @param ?\Closure(K, V): R $format
114+ */
115+ private static function pushParameter (
116+ Method $ method ,
117+ string $ name ,
118+ array $ items ,
119+ ?\Closure $ format = null ,
120+ ): void {
121+ $ format ??= static fn (mixed $ key , mixed $ value ) => $ value ;
122+
123+ if ($ items !== []) {
124+ $ method ->addBody (" {$ name }: [ " );
125+
126+ foreach ($ items as $ key => $ value ) {
127+ $ method ->addBody (' ?, ' , [$ format ($ key , $ value )]);
128+ }
129+
130+ $ method ->addBody (' ], ' );
131+ }
132+ }
82133}
0 commit comments