Skip to content

Commit 2ba38e8

Browse files
committed
Gather constructors which need recursion
1 parent e74f398 commit 2ba38e8

3 files changed

Lines changed: 98 additions & 25 deletions

File tree

tools/FileRefExtractor/BuildMode/Ast.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,15 @@ public static function crc(string $schema): string
5858
return $id;
5959
}
6060

61-
public function finalize(int $layer, array $outgoingCons, array $incomingCons, string $refMapFile, string $refMapFileJson): void
62-
{
61+
public function finalize(
62+
int $layer,
63+
array $outgoingCons,
64+
array $incomingCons,
65+
array $incomingTraversalPairs,
66+
array $outgoingTraversalPairs,
67+
string $refMapFile,
68+
string $refMapFileJson
69+
): void {
6370
$locations = [];
6471

6572
$fileIdCons = [];

tools/FileRefExtractor/FileRefGenerator.php

Lines changed: 88 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -444,22 +444,30 @@ public static function generate(int $layer, string $inputSchema, string $outputF
444444

445445
$locations['account.uploadTheme'][] = new Noop('A freshly uploaded theme file will obtain a context only once it is created via account.createTheme');
446446

447-
$recurse = static function (Closure $onStackEnd, string $type, array &$stack, array &$stackTypes) use ($TL, &$recurse): void {
448-
if ($type === 'Update' || $type === 'Updates') {
449-
$onStackEnd($stack);
450-
return;
451-
}
452-
if ($type === 'PeerStories') {
453-
$onStackEnd($stack);
447+
$constructorList = $TL->tl->getConstructors()->by_id;
448+
$mergedConstructorMethods = [
449+
...$constructorList,
450+
...$TL->tl->getMethods()->by_id,
451+
];
452+
$recurse = static function (Closure $onStackEnd, string $type, array &$stack, array &$stackTypes, bool $incoming) use ($TL, &$recurse, $mergedConstructorMethods, $constructorList): void {
453+
if ($incoming) {
454+
if ($type === 'Update' || $type === 'Updates') {
455+
$onStackEnd($stack);
456+
return;
457+
}
458+
if ($type === 'PeerStories') {
459+
$onStackEnd($stack);
460+
}
454461
}
455462

456463
$pos = \count($stack);
457-
foreach ([...$TL->tl->getConstructors()->by_id, ...$TL->tl->getMethods()->by_id] as $constructor) {
464+
foreach ($incoming ? $constructorList : $mergedConstructorMethods as $constructor) {
458465
$predicate = $constructor['predicate'] ?? $constructor['method'];
459466
if ($predicate === 'updateShortMessage' || $predicate === 'updateShortChatMessage' || $predicate === 'updateShortSentMessage') {
460467
// Assume these are converted to message constructors by the client.
461468
continue;
462469
}
470+
$isMethod = isset($constructor['method']);
463471
$t = $constructor['type'];
464472
$stackTypes[$t] ??= 0;
465473
if ($stackTypes[$t] > 1) {
@@ -482,20 +490,29 @@ public static function generate(int $layer, string $inputSchema, string $outputF
482490
$oldFlag = $stack[$pos][2] ?? 0;
483491
$stack[$pos][2] = $oldFlag | Path::FLAG_UNPACK_ARRAY;
484492
}
485-
$recurse($onStackEnd, $t, $stack, $stackTypes);
493+
if ($isMethod) {
494+
if (!$incoming) {
495+
$onStackEnd($stack);
496+
}
497+
} else {
498+
$recurse($onStackEnd, $t, $stack, $stackTypes, $incoming);
499+
}
486500
unset($stack[$pos]);
487501

488502
}
489503
}
490504
$stackTypes[$t]--;
491505
}
492-
foreach ($TL->getMethodsOfType($type, true) as $method => $data) {
493-
$stack[$pos] = [$method, ''];
494-
$onStackEnd($stack);
495-
}
496-
foreach ($TL->getMethodsOfType("Vector<$type>", true) as $method => $data) {
497-
$stack[$pos] = [$method, '', Path::FLAG_UNPACK_ARRAY];
498-
$onStackEnd($stack);
506+
507+
if ($incoming) {
508+
foreach ($TL->getMethodsOfType($type, true) as $method => $data) {
509+
$stack[$pos] = [$method, ''];
510+
$onStackEnd($stack);
511+
}
512+
foreach ($TL->getMethodsOfType("Vector<$type>", true) as $method => $data) {
513+
$stack[$pos] = [$method, '', Path::FLAG_UNPACK_ARRAY];
514+
$onStackEnd($stack);
515+
}
499516
}
500517
unset($stack[$pos]);
501518
};
@@ -566,14 +583,46 @@ public static function generate(int $layer, string $inputSchema, string $outputF
566583
}
567584
}
568585

569-
$traversalPairs = [];
586+
$outgoingTraversalPairsByCons = [];
587+
foreach ($outgoingCons as $constructor => $contents) {
588+
if ($contents === false) {
589+
continue;
590+
}
591+
$type = $TL->tl->getConstructors()->findByPredicate($constructor)['type'];
592+
$stack = [[$constructor, 'file_reference']];
593+
$stackTypes = [$type => 1];
594+
595+
$outgoingTraversalPairs = [];
596+
$recurse(
597+
static function (array $stack) use (&$outgoingTraversalPairs): void {
598+
foreach ($stack as $pair) {
599+
$encoded = json_encode($pair);
600+
if (!isset($outgoingTraversalPairs[$encoded])) {
601+
$outgoingTraversalPairs[$encoded] = $pair;
602+
}
603+
}
604+
},
605+
$type,
606+
$stack,
607+
$stackTypes,
608+
false,
609+
);
610+
ksort($outgoingTraversalPairs);
611+
$outgoingTraversalPairs = array_values($outgoingTraversalPairs);
612+
$outgoingTraversalPairsByCons[$constructor] = $outgoingTraversalPairs;
613+
}
614+
unset($outgoingTraversalPairs);
615+
616+
$incomingTraversalPairsByCons = [];
570617
$tmp = new Ast(blacklistedPredicates: $blacklistedPredicates, allowUnpacking: true, outputSchema: $pre);
571618
foreach ($incomingCons as $constructor => $_) {
572619
$type = ucfirst($constructor);
573620
$stack = [[$constructor, 'file_reference']];
574621
$stackTypes = [$type => 1];
622+
623+
$incomingTraversalPairs = [];
575624
$recurse(
576-
static function (array $stack) use ($locations, $TL, $tmp, &$traversalPairs, &$validated, $storyMethods, $starMethods, $stickerMethods): void {
625+
static function (array $stack) use ($locations, $TL, $tmp, &$incomingTraversalPairs, &$validated, $storyMethods, $starMethods, $stickerMethods): void {
577626
$slice = [];
578627
$hadAny = false;
579628
$hadAnyNotNoop = false;
@@ -583,6 +632,11 @@ static function (array $stack) use ($locations, $TL, $tmp, &$traversalPairs, &$v
583632
$top = end($stack)[0];
584633
for ($x = \count($stack)-1; $x >= 0; $x--) {
585634
$pair = $stack[$x];
635+
$encoded = json_encode($pair);
636+
if (!isset($tmpPairs[$encoded])) {
637+
$tmpPairs[$encoded] = $pair;
638+
}
639+
586640
foreach ($locations[$pair[0]] ?? [] as $op) {
587641
$normalized = $op->normalize($slice, $pair[0], false);
588642
if ($normalized === null) {
@@ -591,7 +645,6 @@ static function (array $stack) use ($locations, $TL, $tmp, &$traversalPairs, &$v
591645
if (!$normalized instanceof Noop) {
592646
$hadAnyNotNoop = true;
593647
}
594-
$tmpPairs[json_encode($pair)] = $pair;
595648
$hadAny = true;
596649
$normalized->build(new TLContext($TL, $tmp, $top, $TL->isConstructor($top)));
597650
$validated[$pair[0]][spl_object_id($op)] = $op;
@@ -606,7 +659,7 @@ static function (array $stack) use ($locations, $TL, $tmp, &$traversalPairs, &$v
606659
$slice[] = $pair;
607660
}
608661
if ($hadAnyNotNoop) {
609-
$traversalPairs += $tmpPairs;
662+
$incomingTraversalPairs += $tmpPairs;
610663
}
611664
if (!$hadAny) {
612665
throw new AssertionError("Uncovered path: " . json_encode($stack));
@@ -653,9 +706,14 @@ static function (array $stack) use ($locations, $TL, $tmp, &$traversalPairs, &$v
653706
$type,
654707
$stack,
655708
$stackTypes,
709+
true,
656710
);
711+
712+
ksort($incomingTraversalPairs);
713+
$incomingTraversalPairs = array_values($incomingTraversalPairs);
714+
$incomingTraversalPairsByCons[$constructor] = $incomingTraversalPairs;
657715
}
658-
//var_dump(array_values($traversalPairs));
716+
unset($incomingTraversalPairs);
659717

660718
$diff = [];
661719
foreach ($locations as $constructor => $ops) {
@@ -680,7 +738,15 @@ static function (array $stack) use ($locations, $TL, $tmp, &$traversalPairs, &$v
680738
}
681739
}
682740

683-
$output->finalize($layer, array_filter($outgoingCons), $incomingCons, $outputFile, $outputFileJson);
741+
$output->finalize(
742+
$layer,
743+
array_filter($outgoingCons),
744+
$incomingCons,
745+
$incomingTraversalPairsByCons,
746+
$outgoingTraversalPairsByCons,
747+
$outputFile,
748+
$outputFileJson
749+
);
684750

685751
echo("OK $layer!\n".PHP_EOL);
686752
}

tools/gen_filerefmap.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ function generate(int $layer, string $schema): void
6969
}
7070

7171
FileRefGenerator::generate(
72-
(int)$argv[1],
72+
(int) $argv[1],
7373
$argv[2],
7474
$argv[3],
7575
$argv[4],

0 commit comments

Comments
 (0)