由 Mongodb Document 属性 property 设置成对应的 Entity 字段 Field 属性
@param AbstractField $annotation
@param $propertyValue
@return array|bool|\DateTime|float|int|mixed|ObjectId|string
764009
private function propertyToField($propertyValue, AbstractField $annotation)
    {
        $fieldType = $annotation->type;
        switch ($fieldType) {
            case 'string':
                $fieldValue = strval($propertyValue);
                break;
            case 'bool':
                $fieldValue = boolval($propertyValue);
                break;
            case 'int':
                $fieldValue = intval($propertyValue);
                break;
            case 'float':
                $fieldValue = floatval($propertyValue);
                break;
            case 'array':
                $fieldValue = is_array($propertyValue) ? $propertyValue : (array)($propertyValue);
                break;
            case 'date':
                /** @var UTCDateTime $propertyValue */
                $fieldValue = ($propertyValue instanceof UTCDateTime) ? $propertyValue->toDateTime()->setTimezone(new \DateTimeZone(date_default_timezone_get())) : $propertyValue;
                break;
            case 'id':
                /** @var ObjectId $propertyValue */
                $fieldValue = $propertyValue;
                break;
            case 'embedOne':
                $fieldValue = $this->propertyToEmbedOne($propertyValue, $annotation);
                break;
            case 'embedMany':
                $fieldValue = $this->propertyToEmbedMany((array)$propertyValue, $annotation);
                break;
            case 'raw':
                $fieldValue = $propertyValue;
                break;
            default:
                $fieldValue = $propertyValue;
                break;
        }
        return $fieldValue;
    }
930885
public static function parseSimpleAnnotationValue($annotation, $docComment)
    {
        $matches = [];
        preg_match("#@$annotation\\s+([^\\s]+)#", $docComment, $matches);
        return !empty($matches) ? $matches[1] : null;
    }
857694
public function parser(
        string $className,
        $objectAnnotation = null,
        string $propertyName = "",
        string $methodName = "",
        $propertyValue = null
    ) {

        PoolCollector::collect($className, $objectAnnotation, $propertyName, $methodName, $propertyValue);
        return [$className, Scope::SINGLETON, ""];
    }
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);
            }
        }
    }
16116
public static function initByPolymorphicOneToOne($model, $propertyName, $annotation)
    {
        $className = BeanFactory::getObjectClass($model);

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

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

        if(null === $model->$leftField)
        {
            $rightModel = $modelClass::newInstance();
        }
        else
        {
            $rightModel = $modelClass::query()->where($annotation->type, '=', $annotation->typeValue)->where($rightField, '=', $model->$leftField)->select()->get();
            if(null === $rightModel)
            {
                $rightModel = $modelClass::newInstance();
            }
        }

        $model->$propertyName = $rightModel;
    }
671424
protected function getValueByAnnotatedType(ReflectionProperty $property, $value)
    {
        $comment = $property->getDocComment();
        if (preg_match('/@var (.+?)(\|null)? /', $comment, $matches)) {
            switch ($matches[1]) {
                case 'integer':
                case 'int':
                    $value = (int) $value;
                    break;
                case 'float':
                    $value = (float) $value;
                    break;
            }
        }

        return $value;
    }
226214
public static function collect(string $className, $objectAnnotation = null, string $propertyName = "", string $methodName = "", $propertyValue = null)
    {
        if ($objectAnnotation instanceof Breaker) {
            $breakerName = $objectAnnotation->getName();
            $breakerName = empty($breakerName) ? $className : $breakerName;

            self::$breakers[$breakerName] = $className;
        }
    }
1216465
public static function parseByPolymorphicManyToMany($model, $propertyName, $annotation)
    {
        $className = BeanFactory::getObjectClass($model);

        $struct = new PolymorphicManyToMany($className, $propertyName, $annotation);
        $middleModel = $struct->getMiddleModel();
        $middleLeftField = $struct->getMiddleLeftField();
        $leftField = $struct->getLeftField();

        foreach($model->$propertyName as $index => $row)
        {
            if(!$row instanceof $middleModel)
            {
                $row = $middleModel::newInstance($row);
                $model->$propertyName[$index] = $row;
            }
            $row[$middleLeftField] = $model->$leftField;
            $row[$annotation->type] = $annotation->typeValue;
            $row->insert();
        }
    }
536769
public static function collect(
        string $className,
        $objectAnnotation = null,
        string $propertyName = '',
        string $methodName = '',
        $propertyValue = null
    ) {
        if ($objectAnnotation instanceof Command) {
            self::collectCommand($className, $objectAnnotation);
        } elseif ($objectAnnotation instanceof Mapping) {
            self::collectMapping($className, $objectAnnotation, $methodName);
        } elseif ($objectAnnotation === null && isset(self::$commandMapping[$className])) {
            self::collectWithoutAnnotation($className, $methodName);
        }
    }
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;
    }
854947
private function embedManyToProperty(array $embeds, AbstractField $annotation)
    {
        $documents = [];
        foreach ($embeds as $embed) {
            $documents[] = $this->embedOneToProperty($embed, $annotation);
        }
        return $documents;
    }
51440
private function embedOneToProperty($embed, AbstractField $annotation)
    {
        $className = $annotation->target;

        try {
            $reflectClass = new \ReflectionClass($className);
        } catch (\Exception $exception) {
            return $embed;
        }

        $property = new \stdClass();

        foreach ($reflectClass->getProperties() as $field) {
            if ($field->isStatic()) {
                continue;
            }

            $annotation = $this->annotationParser->getPropertyAnnotation($field);

            $propertyName = $annotation->name ?? $field->getName();

            try {
                $reflectProperty = new \ReflectionProperty($embed, $propertyName);

                $reflectProperty->setAccessible(true);
                $fieldValue = $reflectProperty->getValue($embed);

                $propertyValue = $this->fieldToProperty($fieldValue, $annotation);


            } catch (\Exception $exception) {
                $propertyValue = null;
            }

            $property->{$propertyName} = $propertyValue;
        }

        return $property;
    }
422129
final protected function nonNullIfHasDefault(AbstractAnnotation $annotation): void
    {
        $type = $annotation->getTypeInstance();
        if ($type instanceof NonNull && $annotation->hasDefaultValue()) {
            $annotation->setTypeInstance($type->getWrappedType());
        }
    }
987217
private function getMetaFieldAnnotationData($property, $directory)
    {
        /** @var MetaField $annotation */
        $annotation = $this->reader->getPropertyAnnotation($property, self::ID_ANNOTATION);
        $annotation = $annotation ?: $this->reader->getPropertyAnnotation($property, self::PARENT_ANNOTATION);
        $annotation = $annotation ?: $this->reader->getPropertyAnnotation($property, self::ROUTING_ANNOTATION);
        $annotation = $annotation ?: $this->reader->getPropertyAnnotation($property, self::VERSION_ANNOTATION);

        if ($annotation === null) {
            return null;
        }

        $data = [
            'name' => $annotation->getName(),
            'settings' => $annotation->getSettings(),
        ];

        if ($annotation instanceof ParentDocument) {
            $data['settings']['type'] = $this->getDocumentType($annotation->class, $directory);
        }

        return $data;
    }
827418
@Override
    public AbstractDate with(TemporalField field, long newValue) {
        if (field instanceof ChronoField) {
            ChronoField f = (ChronoField) field;
            getChronology().range(f).checkValidValue(newValue, f);
            int nvalue = (int) newValue;
            switch (f) {
                case DAY_OF_WEEK:
                    return plusDays(newValue - getDayOfWeek());
                case ALIGNED_DAY_OF_WEEK_IN_MONTH:
                    return plusDays(newValue - getLong(ALIGNED_DAY_OF_WEEK_IN_MONTH));
                case ALIGNED_DAY_OF_WEEK_IN_YEAR:
                    return plusDays(newValue - getLong(ALIGNED_DAY_OF_WEEK_IN_YEAR));
                case DAY_OF_MONTH:
                    return resolvePrevious(getProlepticYear(), getMonth(), nvalue);
                case DAY_OF_YEAR:
                    return withDayOfYear(nvalue);
                case EPOCH_DAY:
                    return resolveEpochDay(newValue);
                case ALIGNED_WEEK_OF_MONTH:
                    return plusDays((newValue - getLong(ALIGNED_WEEK_OF_MONTH)) * lengthOfWeek());
                case ALIGNED_WEEK_OF_YEAR:
                    return plusDays((newValue - getLong(ALIGNED_WEEK_OF_YEAR)) * lengthOfWeek());
                case MONTH_OF_YEAR:
                    return resolvePrevious(getProlepticYear(), nvalue, getDayOfMonth());
                case PROLEPTIC_MONTH:
                    return plusMonths(newValue - getProlepticMonth());
                case YEAR_OF_ERA:
                    return resolvePrevious(getProlepticYear() >= 1 ? nvalue : 1 - nvalue, getMonth(), getDayOfMonth());
                case YEAR:
                    return resolvePrevious(nvalue, getMonth(), getDayOfMonth());
                case ERA:
                    return newValue == getLong(ERA) ? this : resolvePrevious(1 - getProlepticYear(), getMonth(), getDayOfMonth());
                default:
                    break;
            }
            throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
        }
        return field.adjustInto(this, newValue);
    }
963001
public static function initByOneToOne($model, $propertyName, $annotation)
    {
        $className = BeanFactory::getObjectClass($model);

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

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

        if(null === $model->$leftField)
        {
            $rightModel = $modelClass::newInstance();
        }
        else
        {
            $rightModel = $modelClass::query()->where($rightField, '=', $model->$leftField)->select()->get();
            if(null === $rightModel)
            {
                $rightModel = $modelClass::newInstance();
            }
        }

        $model->$propertyName = $rightModel;
    }
620982
public function matches(AbstractAnnotation $annotation) {
		if (!$annotation instanceof self) {
			return false;
		}
		if ($annotation->getType() !== $this->type) {
			return false;
		}

		return true;
	}