final class GenerationPlan<TRequiresNonEmpty of bool>
Public API: explicitly declared with @visibility public.

An immutable plan selecting the start rule, productions, lexemes and expansion limits. Plans can be reused without carrying mutable choice cursors between generations.

Keep a generation plan immutable and independent of earlier callsdoctest
$plan = \SqlFaker\Generation\Plan\GenerationPlan::all()->withExpansionBudget(100);
    $plan->expansionBudget() // => 100

Methods§

public function __construct(
    private non-empty-string|null $startRule,
    private array<string, non-empty-list<ProductionPattern>> $patterns,
    private array<string, ProductionPattern> $patternsForEveryOccurrence,
    private array<string, array<int, string>> $lexemes,
    private non-empty-string|null $lexicalTarget,
    private array<string, int> $parameters,
    private TRequiresNonEmpty $requiresNonEmpty,
    private int $maxDepth,
    private bool $reserveSteps = false,
    private ?int $expansionBudget = null,
    private array<string, non-empty-list<string>> $candidateKeys = [],
    private array<string, RulePlan> $rules = [],
)
Restricted visibility: declared "@visibility SqlFaker\Generation\Choice". Code outside that scope must not name this declaration.

Binds every choice a generation is directed by.

Parameters

$startRulenon-empty-string|nullRule the walk begins at, or null for the grammar entry point
$patternsarray<string, non-empty-list<ProductionPattern>>Patterns directing each occurrence of a rule
$patternsForEveryOccurrencearray<string, ProductionPattern>Pattern directing every further occurrence of a rule
$lexemesarray<string, array<int, string>>Lexemes directing each occurrence of a terminal
$lexicalTargetnon-empty-string|nullLexical rule to realize instead of walking the grammar
$parametersarray<string, int>Parameters the lexical target is realized with
$requiresNonEmptyTRequiresNonEmptyWhether the walk must produce at least one symbol
$maxDepthint
$reserveStepsboolWhether to budget the remaining form and prefer fewer rule expansions
$expansionBudget?int
$candidateKeysarray<string, non-empty-list<string>>Exact candidate semantics by terminal occurrence
$rulesarray<string, RulePlan>Scoped production, list and lexical conditions
public static function all(): self<false>

Directs a walk over the whole grammar from its own entry point.

Returns

self<false> Plan that constrains nothing
Test cases 83
Called from 4
Calls 1
public static function fromRule(string $startRule): self<false>

Directs a walk that begins at one rule instead of the grammar entry point.

Parameters

$startRulestringRule the walk begins at

Returns

self<false> Plan restricted to that rule

Throws

InvalidArgumentException When a required generation constraint is empty
Test cases 34
Called from 31
Calls 2
public static function constrained(
    string $startRule,
    array<string, non-empty-list<ProductionPattern>> $patterns,
): self<false>

Directs a walk that begins at one rule and takes the productions the caller named.

Parameters

$startRulestringRule the walk begins at
$patternsarray<string, non-empty-list<ProductionPattern>>Patterns directing each occurrence of a rule

Returns

self<false> Plan restricted to those productions

Throws

InvalidArgumentException When a required generation constraint is empty
Test cases 29
Called from 33
Calls 2
public static function lexical(string $target, array<string, int> $parameters): self<true>

Directs the realization of one lexical rule instead of a walk over the grammar.

Parameters

$targetstringLexical rule to realize
$parametersarray<string, int>Parameters the target is realized with

Returns

self<true> Plan that realizes that target

Throws

InvalidArgumentException When a required generation constraint is empty
Test cases 10
Called from 26
Calls 2
public function requiringNonEmpty(): self<true>

Answers a plan whose walk must produce at least one symbol.

Returns

self<true> Plan that refuses an empty result
Calls 1
public function withLexemes(array<string, array<int, string>> $lexemes): self<TRequiresNonEmpty>

Answers a plan that spells each occurrence of a terminal the way the caller asked.

Parameters

$lexemesarray<string, array<int, string>>Lexemes directing each occurrence of a terminal

Returns

self<TRequiresNonEmpty> Plan carrying those lexemes

Throws

InvalidArgumentException When a required generation constraint is empty
Called from 1
Calls 2
public function withMaxDepth(int $maxDepth): self<TRequiresNonEmpty>

Answers a plan whose walk recurses no deeper than the caller allows.

Parameters

$maxDepthint

Returns

self<TRequiresNonEmpty> Plan bounded to that depth
Calls 2
public function withRule(string $rule, RulePlan $plan): self<TRequiresNonEmpty>

Adds subtree conditions without choosing unrelated grammar alternatives.

Parameters

$rulestring
$planRulePlan

Returns

self<TRequiresNonEmpty>

Throws

InvalidArgumentException When the rule or combined conditions are invalid
Calls 3
public function refine(
    array<string, ProductionPattern>|null $patternsForEveryOccurrence = null,
    array<string, array<int, string>>|null $lexemes = null,
    array<string, non-empty-list<string>>|null $candidateKeys = null,
    array<string, RulePlan>|null $rules = null,
    positive-int|null $maxDepth = null,
    positive-int|null $expansionBudget = null,
    ?bool $reserveSteps = null,
): self<TRequiresNonEmpty>
Restricted visibility: declared "@visibility namespace". Code outside that scope must not name this declaration.

Copies independent settings while preserving the start rule and output guarantee.

Parameters

$patternsForEveryOccurrencearray<string, ProductionPattern>|null
$lexemesarray<string, array<int, string>>|null
$candidateKeysarray<string, non-empty-list<string>>|null
$rulesarray<string, RulePlan>|null
$maxDepthpositive-int|null
$expansionBudgetpositive-int|null
$reserveSteps?bool

Returns

self<TRequiresNonEmpty>
Called from 7
Calls 1
public function hasRemainingPatterns(array<string, int> $occurrences): bool
public function withPatternForEveryOccurrence(
    string $rule,
    ProductionPattern $pattern,
): self<TRequiresNonEmpty>

Answers a plan that directs every further occurrence of one rule the same way.

Parameters

$rulestringRule to direct
$patternProductionPatternPattern every occurrence not named directly takes

Returns

self<TRequiresNonEmpty> Plan carrying that fallback

Throws

InvalidArgumentException When a required generation constraint is empty
Calls 2
public function lexemeAt(string $terminal, int $occurrence): string|null

Answers the lexeme one occurrence of a terminal is spelled with.

Parameters

$terminalstringTerminal the walk has reached
$occurrenceintHow many times the walk has reached it before

Returns

string|null Lexeme to write, or null when the walk may choose freely
Test cases 1
Called from 2
public function withStepBudget(): self<TRequiresNonEmpty>

Reserves enough derivation steps to finish the entire remaining form.

Returns

self<TRequiresNonEmpty> Plan with a bounded completion policy
Calls 1
public function usesStepBudget(): bool

Reports whether production choice reserves steps for the remaining form.

Returns

bool
Called from 1
public function withExpansionBudget(int $budget): self<TRequiresNonEmpty>

Bounds total expansions independently of the legacy depth policy.

Parameters

$budgetint

Returns

self<TRequiresNonEmpty>

Throws

InvalidArgumentException When no expansion is permitted
Called from 1
Calls 2
public function withCandidateKeys(array<string, non-empty-list<string>> $keys): self<TRequiresNonEmpty>

Pins candidate semantics as well as spelling, including empty marker candidates.

Parameters

$keysarray<string, non-empty-list<string>>

Returns

self<TRequiresNonEmpty>
Calls 1
public function candidateKeyAt(string $terminal, int $occurrence): ?string

Returns the exact candidate semantics requested for one terminal occurrence.

Parameters

$terminalstring
$occurrenceint

Returns

?string
Test cases 1
public static function statement(non-empty-string|null $startRule, int $maxDepth): self<true>

Directs a bounded walk that must produce a statement.

Parameters

$startRulenon-empty-string|nullRule the statement is grown from, or null for the grammar entry point
$maxDepthint

Returns

self<true> Plan for one bounded, non-empty statement
Test cases 3
Called from 30
Calls 2

Private surface 12§

Implementation details, listed for orientation only.

private non-empty-string|null $startRule
private array<string, non-empty-list<ProductionPattern>> $patterns
private array<string, ProductionPattern> $patternsForEveryOccurrence
private array<string, array<int, string>> $lexemes
private non-empty-string|null $lexicalTarget
private array<string, int> $parameters
private TRequiresNonEmpty $requiresNonEmpty
private int $maxDepth
private bool $reserveSteps = false
private ?int $expansionBudget = null
private array<string, non-empty-list<string>> $candidateKeys = []
private array<string, RulePlan> $rules = []

Test cases 153§

Test cases that cover or call this symbol, from the coverage report and from the analyzed test sources.

Dedicated tests 31
Other tests reaching this symbol 122

Relations§

Instantiated in 1
Static calls 122
Method calls 46
Type declarations 115