43    private array $enumIndexes = [];
 
   48    private array $enumValueIndexes = [];
 
   53    private array $softEnumIndexes = [];
 
   58    private array $postfixIndexes = [];
 
   63    private array $chainedSubCommandDataIndexes = [];
 
   68    private array $chainedSubCommandValueIndexes = [];
 
   74    private array $enumValues = [];
 
   79    private array $chainedSubCommandValues = [];
 
   84    private array $postfixes = [];
 
   89    private array $enums = [];
 
   94    private array $chainedSubCommandData = [];
 
   99    private array $commandData = [];
 
  104    private array $softEnums = [];
 
  109    private array $enumConstraints = [];
 
  122        array $hardcodedEnums,
 
  123        array $hardcodedSoftEnums
 
  125        $builder = new self();
 
  126        foreach($commandData as $data){
 
  127            $builder->addCommandData($data);
 
  129        foreach($hardcodedEnums as $enum){
 
  130            $builder->addHardEnum($enum);
 
  132        foreach($hardcodedSoftEnums as $enum){
 
  133            $builder->addSoftEnum($enum);
 
  137            enumValues: $builder->enumValues,
 
  138            chainedSubCommandValues: $builder->chainedSubCommandValues,
 
  139            postfixes: $builder->postfixes,
 
  140            enums: $builder->enums,
 
  141            chainedSubCommandData: $builder->chainedSubCommandData,
 
  142            commandData: $builder->commandData,
 
  143            softEnums: $builder->softEnums,
 
  144            enumConstraints: $builder->enumConstraints
 
 
  148    private function addEnumValue(
string $str) : int{
 
  149        if(!isset($this->enumValueIndexes[$str])){
 
  150            $this->enumValueIndexes[$str] = count($this->enumValues);
 
  151            $this->enumValues[] = $str;
 
  153        return $this->enumValueIndexes[$str];
 
  156    private function addHardEnum(CommandHardEnum $enum) : int{
 
  157        $key = spl_object_id($enum);
 
  158        if(!isset($this->enumIndexes[$key])){
 
  161            $enumIndex = $this->enumIndexes[$key] = count($this->enums);
 
  164            foreach($enum->getValues() as $value){
 
  165                if($value instanceof ConstrainedEnumValue){
 
  166                    $valueIndex = $this->addEnumValue($value->getValue());
 
  167                    $constraints[] = 
new CommandEnumConstraintRawData($valueIndex, $enumIndex, $value->getConstraints());
 
  169                    $valueIndex = $this->addEnumValue($value);
 
  171                $valueIndexes[] = $valueIndex;
 
  173            if(count($this->enums) !== $enumIndex){
 
  174                throw new \LogicException(
"Didn't expect enum list to be modified while compiling values");
 
  176            $this->enums[] = 
new CommandEnumRawData($enum->getName(), $valueIndexes);
 
  177            array_push($this->enumConstraints, ...$constraints);
 
  180        return $this->enumIndexes[$key];
 
  183    private function addSoftEnum(CommandSoftEnum $enum) : int{
 
  184        $key = spl_object_id($enum);
 
  186        if(!isset($this->softEnumIndexes[$key])){
 
  187            $this->softEnumIndexes[$key] = count($this->softEnums);
 
  188            $this->softEnums[] = $enum;
 
  191        return $this->softEnumIndexes[$key];
 
  194    private function addPostfix(
string $postfix) : int{
 
  195        if(!isset($this->postfixIndexes[$postfix])){
 
  196            $this->postfixIndexes[$postfix] = count($this->postfixes);
 
  197            $this->postfixes[] = $postfix;
 
  199        return $this->postfixIndexes[$postfix];
 
  202    private function addChainedSubCommandValueName(
string $valueName) : int{
 
  203        if(!isset($this->chainedSubCommandValueIndexes[$valueName])){
 
  204            $this->chainedSubCommandValueIndexes[$valueName] = count($this->chainedSubCommandValues);
 
  205            $this->chainedSubCommandValues[] = $valueName;
 
  207        return $this->chainedSubCommandValueIndexes[$valueName];
 
  210    private function addChainedSubCommandData(ChainedSubCommandData $data) : int{
 
  211        $key = spl_object_id($data);
 
  213        if(!isset($this->chainedSubCommandDataIndexes[$key])){
 
  215            foreach($data->getValues() as $value){
 
  216                $valueNameIndex = $this->addChainedSubCommandValueName($value->getName());
 
  217                $rawValueData[] = 
new ChainedSubCommandValueRawData($valueNameIndex, $value->getType());
 
  220            $this->chainedSubCommandDataIndexes[$key] = count($this->chainedSubCommandData);
 
  221            $this->chainedSubCommandData[] = 
new ChainedSubCommandRawData($data->getName(), $rawValueData);
 
  224        return $this->chainedSubCommandDataIndexes[$key];
 
  227    private function addCommandData(CommandData $commandData) : void{
 
  228        $aliasesIndex = $commandData->aliases !== null ? $this->addHardEnum($commandData->aliases) : -1;
 
  230        $chainedSubCommandDataIndexes = [];
 
  231        foreach($commandData->getChainedSubCommandData() as $chainedSubCommandData){
 
  232            $chainedSubCommandDataIndexes[] = $this->addChainedSubCommandData($chainedSubCommandData);
 
  235        $rawOverloadData = [];
 
  236        foreach($commandData->getOverloads() as $overload){
 
  237            $rawParameterData = [];
 
  239            foreach($overload->getParameters() as $parameter){
 
  240                if($parameter->enum !== null){
 
  241                    if($parameter->enum instanceof CommandSoftEnum){
 
  242                        $enumIndex = $this->addSoftEnum($parameter->enum);
 
  243                        $typeInfo = AvailableCommandsPacket::ARG_FLAG_SOFT_ENUM | AvailableCommandsPacket::ARG_FLAG_VALID | $enumIndex;
 
  245                        $enumIndex = $this->addHardEnum($parameter->enum);
 
  246                        $typeInfo = AvailableCommandsPacket::ARG_FLAG_ENUM | AvailableCommandsPacket::ARG_FLAG_VALID | $enumIndex;
 
  248                }elseif($parameter->postfix !== null){
 
  249                    $postfixIndex = $this->addPostfix($parameter->postfix);
 
  250                    $typeInfo = AvailableCommandsPacket::ARG_FLAG_POSTFIX | $postfixIndex;
 
  253                    $typeInfo = AvailableCommandsPacket::ARG_FLAG_VALID | ($parameter->paramType & AvailableCommandsPacket::ARG_FLAG_VALID - 1);
 
  256                $rawParameterData[] = new CommandParameterRawData($parameter->paramName, $typeInfo, $parameter->isOptional, $parameter->flags);
 
  259            $rawOverloadData[] = 
new CommandOverloadRawData($overload->isChaining(), $rawParameterData);
 
  262        $this->commandData[] = 
new CommandRawData(
 
  263            name: $commandData->getName(),
 
  264            description: $commandData->getDescription(),
 
  265            flags: $commandData->getFlags(),
 
  266            permission: $commandData->getPermission(),
 
  267            aliasEnumIndex: $aliasesIndex,
 
  268            chainedSubCommandDataIndexes: $chainedSubCommandDataIndexes,
 
  269            overloads: $rawOverloadData