src/Parser/Doctrine/DoctrineParser.php
final private function validateFieldPrefixesToClasses(array $fieldPrefixesToClasses)
    {
        // validate fieldPrefixesToClasses
        foreach ($fieldPrefixesToClasses as $fieldPrefix => $associationClass) {
            $suffixPattern = '/\.((?!\.).)+$/';
            $suffixMatches = [];
            $doesFieldPrefixHaveSuffix = preg_match($suffixPattern, $fieldPrefix, $suffixMatches);
            if ($doesFieldPrefixHaveSuffix) { // $fieldPrefix is for an Association in an Association
                $fieldPrefixPrefix = preg_replace($suffixPattern, '', $fieldPrefix);
                $fieldSuffix = str_replace('.', '', $suffixMatches[0]); // remove preceding dot
                if (!array_key_exists($fieldPrefixPrefix, $fieldPrefixesToClasses)) {
                    throw new MissingAssociationClassException(sprintf(
                        'Missing association class for queryBuilderFieldPrefix %s, at class %s, for parser %s',
                        $fieldPrefixPrefix,
                        $this->className,
                        static::class
                    ));
                }
                $classForThisPrefix = $fieldPrefixesToClasses[$fieldPrefixPrefix];
                $this->validateClassHasProperty($classForThisPrefix, $fieldSuffix);
            } else { // $fieldPrefix an association for $this->className
                $this->validateClassHasProperty($this->className, $fieldPrefix);
            }
        }
    }
final private function validateFieldPrefixesToClasses(array $fieldPrefixesToClasses)
    {
        // validate fieldPrefixesToClasses
        foreach ($fieldPrefixesToClasses as $fieldPrefix => $associationClass) {
            $suffixPattern = '/\.((?!\.).)+$/';
            $suffixMatches = [];
            $doesFieldPrefixHaveSuffix = preg_match($suffixPattern, $fieldPrefix, $suffixMatches);
            if ($doesFieldPrefixHaveSuffix) { // $fieldPrefix is for an Association in an Association
                $fieldPrefixPrefix = preg_replace($suffixPattern, '', $fieldPrefix);
                $fieldSuffix = str_replace('.', '', $suffixMatches[0]); // remove preceding dot
                if (!array_key_exists($fieldPrefixPrefix, $fieldPrefixesToClasses)) {
                    throw new MissingAssociationClassException(sprintf(
                        'Missing association class for queryBuilderFieldPrefix %s, at class %s, for parser %s',
                        $fieldPrefixPrefix,
                        $this->className,
                        static::class
                    ));
                }
                $classForThisPrefix = $fieldPrefixesToClasses[$fieldPrefixPrefix];
                $this->validateClassHasProperty($classForThisPrefix, $fieldSuffix);
            } else { // $fieldPrefix an association for $this->className
                $this->validateClassHasProperty($this->className, $fieldPrefix);
            }
        }
    }
@param array $fieldPrefixesToClasses

@throws InvalidClassNameException|FieldMappingException|MissingAssociationClassException