code: public function getExpressionBuilder(ExpressionInterface $expression)
      {
          $className = get_class($expression);
  
          if (!isset($this->expressionBuilders[$className])) {
              foreach (array_reverse($this->expressionBuilders) as $expressionClass => $builderClass) {
                  if (is_subclass_of($expression, $expressionClass)) {
                      $this->expressionBuilders[$className] = $builderClass;
                      break;
                  }
              }
  
              if (!isset($this->expressionBuilders[$className])) {
                  throw new InvalidArgumentException('Expression of class ' . $className . ' can not be built in ' . get_class($this));
              }
          }
  
          if ($this->expressionBuilders[$className] === __CLASS__) {
              return $this;
          }
  
          if (!is_object($this->expressionBuilders[$className])) {
              $this->expressionBuilders[$className] = new $this->expressionBuilders[$className]($this);
          }
  
          return $this->expressionBuilders[$className];
      }
docs: Gets object of [[ExpressionBuilderInterface]] that is suitable for $expression.
  Uses [[expressionBuilders]] array to find a suitable builder class.
  
  @param ExpressionInterface $expression
  @return ExpressionBuilderInterface
  @see expressionBuilders
  @since 2.0.14
  @throws InvalidArgumentException when $expression building is not supported by this QueryBuilder.