@param Annotation\Annotation[] $propertyAnnotations

@return Mapping\ManyToOneAssociationMetadata
179697
private function convertReflectionPropertyToManyToOneAssociationMetadata(
        ReflectionProperty $reflectionProperty,
        array $propertyAnnotations,
        Mapping\ClassMetadata $metadata
    ) {
        $className      = $metadata->getClassName();
        $fieldName      = $reflectionProperty->getName();
        $manyToOneAnnot = $propertyAnnotations[Annotation\ManyToOne::class];
        $assocMetadata  = new Mapping\ManyToOneAssociationMetadata($fieldName);
        $targetEntity   = $manyToOneAnnot->targetEntity;

        $assocMetadata->setTargetEntity($targetEntity);
        $assocMetadata->setCascade($this->getCascade($className, $fieldName, $manyToOneAnnot->cascade));
        $assocMetadata->setFetchMode($this->getFetchMode($className, $manyToOneAnnot->fetch));

        if (! empty($manyToOneAnnot->inversedBy)) {
            $assocMetadata->setInversedBy($manyToOneAnnot->inversedBy);
        }

        // Check for Id
        if (isset($propertyAnnotations[Annotation\Id::class])) {
            $assocMetadata->setPrimaryKey(true);
        }

        $this->attachAssociationPropertyCache($propertyAnnotations, $reflectionProperty, $assocMetadata, $metadata);

        // Check for JoinColumn/JoinColumns annotations
        switch (true) {
            case isset($propertyAnnotations[Annotation\JoinColumn::class]):
                $joinColumnAnnot = $propertyAnnotations[Annotation\JoinColumn::class];

                $assocMetadata->addJoinColumn(
                    $this->convertJoinColumnAnnotationToJoinColumnMetadata($joinColumnAnnot)
                );

                break;

            case isset($propertyAnnotations[Annotation\JoinColumns::class]):
                $joinColumnsAnnot = $propertyAnnotations[Annotation\JoinColumns::class];

                foreach ($joinColumnsAnnot->value as $joinColumnAnnot) {
                    $assocMetadata->addJoinColumn(
                        $this->convertJoinColumnAnnotationToJoinColumnMetadata($joinColumnAnnot)
                    );
                }

                break;
        }

        return $assocMetadata;
    }
1346955
private function convertReflectionPropertyToOneToManyAssociationMetadata(
        ReflectionProperty $reflectionProperty,
        array $propertyAnnotations,
        Mapping\ClassMetadata $classMetadata
    ) {
        $className      = $classMetadata->getClassName();
        $fieldName      = $reflectionProperty->getName();
        $oneToManyAnnot = $propertyAnnotations[Annotation\OneToMany::class];

        if ($oneToManyAnnot->targetEntity === null) {
            throw Mapping\MappingException::missingTargetEntity($fieldName);
        }

        $assocMetadata = new Mapping\OneToManyAssociationMetadata($fieldName);
        $targetEntity  = $oneToManyAnnot->targetEntity;

        $assocMetadata->setSourceEntity($className);
        $assocMetadata->setTargetEntity($targetEntity);
        $assocMetadata->setCascade($this->getCascade($className, $fieldName, $oneToManyAnnot->cascade));
        $assocMetadata->setOrphanRemoval($oneToManyAnnot->orphanRemoval);
        $assocMetadata->setFetchMode($this->getFetchMode($className, $oneToManyAnnot->fetch));

        if (! empty($oneToManyAnnot->mappedBy)) {
            $assocMetadata->setMappedBy($oneToManyAnnot->mappedBy);
        }

        if (! empty($oneToManyAnnot->indexBy)) {
            $assocMetadata->setIndexedBy($oneToManyAnnot->indexBy);
        }

        // Check for OrderBy
        if (isset($propertyAnnotations[Annotation\OrderBy::class])) {
            $orderByAnnot = $propertyAnnotations[Annotation\OrderBy::class];

            $assocMetadata->setOrderBy($orderByAnnot->value);
        }

        // Check for Id
        if (isset($propertyAnnotations[Annotation\Id::class])) {
            $assocMetadata->setPrimaryKey(true);
        }

        // Check for Cache
        if (isset($propertyAnnotations[Annotation\Cache::class])) {
            $cacheAnnot    = $propertyAnnotations[Annotation\Cache::class];
            $cacheMetadata = $this->convertCacheAnnotationToCacheMetadata($cacheAnnot, $classMetadata, $fieldName);

            $assocMetadata->setCache($cacheMetadata);
        }

        return $assocMetadata;
    }
657870
protected function getAnnotation($entity, $property, $annotation) {
        $classRef = new \ReflectionClass($entity);
        $propertyRef = $classRef->getProperty($property);
        if ($propertyRef) return $this->annoReader->getPropertyAnnotation($propertyRef, $annotation);
        else return null;
    }
347343
private function buildToOneAssociationMappings(Mapping\ClassMetadata $metadata)
    {
        $tableName   = $metadata->getTableName();
        $primaryKeys = $this->getTablePrimaryKeys($this->tables[$tableName]);
        $foreignKeys = $this->getTableForeignKeys($this->tables[$tableName]);

        foreach ($foreignKeys as $foreignKey) {
            $foreignTableName   = $foreignKey->getForeignTableName();
            $fkColumns          = $foreignKey->getColumns();
            $fkForeignColumns   = $foreignKey->getForeignColumns();
            $localColumn        = current($fkColumns);
            $associationMapping = [
                'fieldName'    => $this->getFieldNameForColumn($tableName, $localColumn, true),
                'targetEntity' => $this->getClassNameForTable($foreignTableName),
            ];

            if ($metadata->getProperty($associationMapping['fieldName'])) {
                $associationMapping['fieldName'] .= '2'; // "foo" => "foo2"
            }

            if ($primaryKeys && in_array($localColumn, $primaryKeys, true)) {
                $associationMapping['id'] = true;
            }

            for ($i = 0, $l = count($fkColumns); $i < $l; $i++) {
                $joinColumn = new Mapping\JoinColumnMetadata();

                $joinColumn->setColumnName($fkColumns[$i]);
                $joinColumn->setReferencedColumnName($fkForeignColumns[$i]);

                $associationMapping['joinColumns'][] = $joinColumn;
            }

            // Here we need to check if $fkColumns are the same as $primaryKeys
            if (! array_diff($fkColumns, $primaryKeys)) {
                $metadata->addProperty($associationMapping);
            } else {
                $metadata->addProperty($associationMapping);
            }
        }
    }
651827
protected function indexAnnotationsByType(array $annotations)
    {
        $indexed = array();

        // if we are receiving annotations indexed by number, transform it to by class name
        if ($annotations && is_numeric(key($annotations))) {
            foreach ($annotations as $annotation) {
                $annotationType = get_class($annotation);

                if (isset($indexed[$annotationType]) && !is_array($indexed[$annotationType])) {
                    $indexed[$annotationType] = array($indexed[$annotationType], $annotation);
                } elseif (isset($indexed[$annotationType])) {
                    $indexed[$annotationType][] = $annotation;
                } else {
                    $indexed[$annotationType] = $annotation;
                }
            }
        }

        return $indexed;
    }
37824
public static function initByPolymorphicOneToMany($model, $propertyName, $annotation)
    {
        $className = BeanFactory::getObjectClass($model);

        if(class_exists($annotation->model))
        {
            $modelClass = $annotation->model;
        }
        else
        {
            $modelClass = Imi::getClassNamespace($className) . '\\' . $annotation->model;
        }

        $struct = new PolymorphicOneToMany($className, $propertyName, $annotation);
        $leftField = $struct->getLeftField();
        $rightField = $struct->getRightField();

        $model->$propertyName = new ArrayList($modelClass);
        if(null !== $model->$leftField)
        {
            $list = $modelClass::query()->where($annotation->type, '=', $annotation->typeValue)->where($rightField, '=', $model->$leftField)->select()->getArray();
            if(null !== $list)
            {
                $model->$propertyName->append(...$list);
            }
        }
    }
1200199
private function formatPropertyMappings(iterable $propertyMappings)
    {
        $output = [];

        foreach ($propertyMappings as $propertyName => $property) {
            $output[] = $this->formatField(sprintf('  %s', $propertyName), '');

            if ($property instanceof FieldMetadata) {
                $output = array_merge($output, $this->formatColumn($property));
            } elseif ($property instanceof AssociationMetadata) {
                // @todo guilhermeblanco Fix me! We are trying to iterate through an AssociationMetadata instance
                foreach ($property as $field => $value) {
                    $output[] = $this->formatField(sprintf('    %s', $field), $this->formatValue($value));
                }
            }
        }

        return $output;
    }
962435
protected function generateEntityAssociationMappingProperties(ClassMetadataInfo $metadata)
    {
        $lines = array();

        foreach ($metadata->associationMappings as $associationMapping) {
            if ($this->hasProperty($associationMapping['fieldName'], $metadata)) {
                continue;
            }

            $lines[] = $this->generateAssociationMappingPropertyDocBlock($associationMapping, $metadata);
            $lines[] = $this->spaces . $this->fieldVisibility . ' $' . $associationMapping['fieldName']
                     . ($associationMapping['type'] == 'manyToMany' ? ' = array()' : null) . ";\n";
        }

        return implode("\n", $lines);
    }
248231
public static function parseByPolymorphicOneToMany($model, $propertyName, $annotation)
    {
        $className = BeanFactory::getObjectClass($model);

        $struct = new PolymorphicOneToMany($className, $propertyName, $annotation);
        $leftField = $struct->getLeftField();
        $rightField = $struct->getRightField();
        $rightModel = $struct->getRightModel();

        foreach($model->$propertyName as $index => $row)
        {
            if(!$row instanceof $rightModel)
            {
                $row = $rightModel::newInstance($row);
                $model->$propertyName[$index] = $row;
            }
            $row[$rightField] = $model->$leftField;
            $row[$annotation->type] = $annotation->typeValue;
            $row->insert();
        }
    }
639368
public function loadAnnotations($annotations)
    {
        $moreSettings = parse_ini_string($annotations, true) ?: [];

        if (@$guardedFields = $moreSettings['blacklist']) {
            $this->setBlacklist(explode(',', $guardedFields));
        } // if

        if (@$moreSettings['casting'] && is_array($moreSettings['casting'])) {
            $this->setCastedFields($moreSettings['casting']);
        } // if

        if (@$modelName = $moreSettings['model']) {
            $this->setModelName($modelName);
        } // if

        $this->isPivotTable(@ (bool)$moreSettings['isPivot']);
        $this->withoutTimestamps(@ (bool)$moreSettings['withoutTimestamps']);

        return !@$moreSettings['ignore'];
    }
368088
private function convertClassAnnotationsToClassMetadata(
        array $classAnnotations,
        ReflectionClass $reflectionClass,
        Mapping\ClassMetadata $parent
    ) {
        switch (true) {
            case isset($classAnnotations[Annotation\Entity::class]):
                return $this->convertClassAnnotationsToEntityClassMetadata(
                    $classAnnotations,
                    $reflectionClass,
                    $parent
                );

                break;

            case isset($classAnnotations[Annotation\MappedSuperclass::class]):
                return $this->convertClassAnnotationsToMappedSuperClassMetadata(
                    $classAnnotations,
                    $reflectionClass,
                    $parent
                );
            case isset($classAnnotations[Annotation\Embeddable::class]):
                return $this->convertClassAnnotationsToEntityClassMetadata(
                    $classAnnotations,
                    $reflectionClass,
                    $parent
                );
            default:
                throw Mapping\MappingException::classIsNotAValidEntityOrMappedSuperClass($reflectionClass->getName());
        }
    }
1210253
public function getObjectPropertyAnnotations($document)
    {
        $cacheKey = "object_property_annotations_" . get_class($document);
        if (!$this->cache->contains($cacheKey)) {
            $refObject   = new \ReflectionObject($document);
            $annotations = array();
            foreach ($refObject->getProperties() as $property) {
                $annotation = $this->getPropertyAnnotation($property);
                if ($annotation) {
                    $annotations[$property->getName()] = $annotation;
                }
            }
            $this->cache->save($cacheKey, $annotations);
        }
        return $this->cache->fetch($cacheKey);
    }
431228
public static function propertyAnnotations($class, $propertyName)
    {
        $class = is_object($class) ? get_class($class) : $class;
        if (!class_exists('ReflectionProperty')) {
            throw new \RuntimeException("Property type of " . $class . "::{$propertyName} cannot be resolved");
        }

        if ($annotations =& self::$propertiesType[$class][$propertyName]) {
            return $annotations;
        }

        if (!($refl =& self::$propertiesRefl[$class][$propertyName])) {
            $getter = self::getter($class, $propertyName);
            $refl = new \ReflectionMethod($class, $getter);
            self::$propertiesRefl[$class][$propertyName] = $refl;
        }

        // todo: smarter regexp
        if (!preg_match_all(
            '~\@([^\s@\(]+)[\t ]*(?:\(?([^\n@]+)\)?)?~i',
            $refl->getDocComment(),
            $annots,
            PREG_PATTERN_ORDER)
        ) {
            return null;
        }
        foreach ($annots[1] as $i => $annot) {
            $annotations[strtolower($annot)] = empty($annots[2][$i]) ? TRUE : rtrim($annots[2][$i], " \t\n\r)");
        }

        return $annotations;
    }
332783
private function getLabels($annotations)
    {
        $it = $this->getAnnotations()->filter($annotations)
            ->is(Label::class)
            ->onProperties();
        $labels = [];
        foreach ($it as $annotation) {
            $labels[$annotation->getPropertyName()] = $annotation->value;
        }
        return $labels;
    }
994142
public function get($entity, $annotation)
    {
        $properties = $this->getProperties($entity);

        $return = array();
        foreach ($properties as $reflectionProperty) {
            $propertyAnnotation = $this->reader->getPropertyAnnotation($reflectionProperty, $annotation);
            if (!is_null($propertyAnnotation) && get_class($propertyAnnotation) == $annotation) {
                $return[$reflectionProperty->name] = $reflectionProperty;
            }
        }

        return $return;
    }
375867
public static function getPropertiesAnnotations($className, $annotationClassName = null)
    {
        if(null === $annotationClassName)
        {
            return static::$annotations[$className]['Properties'] ?? [];
        }
        $result = [];
        foreach(static::$annotations[$className]['Properties'] ?? [] as $propertyName => $annotations)
        {
            foreach($annotations as $annotation)
            {
                if($annotation instanceof $annotationClassName)
                {
                    $result[$propertyName][] = $annotation;
                }
            }
        }
        return $result;
    }
584677
protected function parseConfig(AnnotationBag $propertyAnnotations) {
		$this->attribute = $propertyAnnotations->has('Attr') ? $propertyAnnotations->get('Attr') : null;
		$this->lazy = $propertyAnnotations->has('Lazy');
		$this->cascade = $propertyAnnotations->has('Cascade');
		$this->join = $propertyAnnotations->has('Join') ? $propertyAnnotations->get('Join') : null;
		
		//parse options
		$this->index = $propertyAnnotations->has('Index') ? $propertyAnnotations->get('Index')->getValue() : null;
		$order = $propertyAnnotations->find('OrderBy', Filter::HAS_ARGUMENT);
		
		if (!empty($order)) {
			$this->order = [];
				
			foreach ($order as $option)
				$this->order[] = $option->getValue();
		}
		
		$this->cache = $propertyAnnotations->has('Cache') ? $propertyAnnotations->get('Cache') : null;
	}