operties
 */
return static function (string|\Stringable $string, \Psr\Container\ContainerInterface $transformers, \Symfony\Component\JsonStreamer\Read\Instantiator $instantiator, array $options): mixed {
    $providers['Symfony\\Component\\JsonStreamer\\Tests\\Fixtures\\Model\\DummyWithSyntheticProperties'] = static function ($data) use ($options, $transformers, $instantiator, &$providers) {
        return $instantiator->instantiate(\Symfony\Component\JsonStreamer\Tests\Fixtures\Model\DummyWithSyntheticProp

) {
            return '_symfony_missing_value' !== $v;
        }));
    };
    return $providers['Symfony\\Component\\JsonStreamer\\Tests\\Fixtures\\Model\\DummyWithSyntheticProperties'](\Symfony\Component\JsonStreamer\Read\Decoder::decodeString((string)

erties::class, \array_filter([], static function ($v


r\Tests\Fixtures\Model\DummyWithUnionProperties
 */
return static function (string|\Stringable $string, \Psr\Container\ContainerInterface $transformers, \Symfony\Component\JsonStreamer\Read\Instantiator $instantiator, array $options): mixed {
    $providers['Symfony\\Component\\JsonStreamer\\Tests\\Fixtures\\Model\\DummyWithUnionProperties'] = static function ($data) use ($options, $transformers, $instantiator, &$providers) {
        return $instantiator->instantiate(\Symfony\Component\JsonStreamer\Tests\Fi

mfony_missing_value'], static function ($v) {
            return '_symfony_missing_value' !== $v;
        }));
    };
    $providers['Symfony\\Component\\JsonStreamer\\Tests\\Fixtures\\Enum\\DummyBackedEnum'] = static function ($data) {
        return \Sym

xtures\Model\DummyWithUnionProperties::class, \array_filter(['value' => \array_key_exists('value', $data) ? $providers['Symfony\\Component\\JsonStreamer\\Tests\\Fixtures\\Enum\\DummyBackedEnum|null|string']($data['value']) : '_sy


fony\Component\JsonStreamer\Tests\Fixtures\Model\DummyWithValueTransformerAttributes
 */
return static function (string|\Stringable $string, \Psr\Container\ContainerInterface $transformers, \Symfony\Component\JsonStreamer\Read\Instantiator $instantiator, array $options): mixed {
    $providers['Symfony\\Component\\JsonStreamer\\Tests\\Fixtures\\Model\\DummyWithValueTransformerAttributes'] = static function ($data) use ($options, $transformers, $instantiator, &$providers) {
        return $instantiator->inst

stToIntValueTransformer')->transform($data['id'] ?? '_symfony_missing_value', $options), 'active' => $transformers->get('Symfony\\Component\\JsonStreamer\\Tests\\Fixtures\\Transformer\\StringToBooleanValueTransformer')->transform($data['active'] ?? '_symfo


eamer\Tests\Fixtures\Model\DummyWithNestedArray> $data
 */
return static function (mixed $data, \Psr\Container\ContainerInterface $transformers, array $options): \Traversable {
    try {
        yield "[";
        $prefix1 = '';
        foreach ($data as $value1) {
            $prefix2 = '';
            yield "{$prefix1}{{$prefix2}\"dummies\":";
            yield "{";
            $prefix3 = '';
            foreach ($value1->dummies as $key2 => $value2) {
                $key2 = is_int($key2) ? $key2 : \subs

mies as $key3 => $value3) {
                    $key3 = is_int($key3) ? $key3 : \substr(\json_encode($key3), 1, -1);
                    $prefix6 = '';
                    yield "{$prefix5}\"{$key3}\":{{$prefix6}\"id\":";
                    yield \json_en

tr(\json_encode($key2), 1, -1);
                $prefix4 = '';
                yield "{$prefix3}\"{$key2}\":{{$prefix4}\"dummies\":";
                yield "{";
                $prefix5 = '';
                foreach ($value2->dum


* @param list<Symfony\Component\JsonStreamer\Tests\Fixtures\Model\DummyWithList> $data
 */
return static function (mixed $data, \Psr\Container\ContainerInterface $transformers, array $options): \Traversable {
    try {
        yield "[";
        $prefix1 = '';
        foreach ($data as $value1) {
            $prefix2 = '';
            yield "{$prefix1}{{$prefix2}\"dummies\":";
            yield "[";
            $prefix3 = '';
            foreach ($value1->dummies as $value2) {
                $prefix4 = '';

 \json_encode($value2->name, \JSON_THROW_ON_ERROR, 508);
                yield "}";
                $prefix3 = ',';
            }
            $prefix2 = ',';
            yield "]{$prefix2}\"customProperty\":";
            yield \json_encode($value1->custom

                yield "{$prefix3}{{$prefix4}\"id\":";
                yield \json_encode($value2->id, \JSON_THROW_ON_ERROR, 508);
                $prefix4 = ',';
                yield "{$prefix4}\"name\":";
                yield


* @return Symfony\Component\JsonStreamer\Tests\Fixtures\Model\ClassicDummy
 */
return static function (mixed $stream, \Psr\Container\ContainerInterface $transformers, \Symfony\Component\JsonStreamer\Read\LazyInstantiator $instantiator, array $options): mixed {
    $providers['Symfony\\Component\\JsonStreamer\\Tests\\Fixtures\\Model\\ClassicDummy'] = static function ($stream, $offset, $length) use ($options, $transformers, $instantiator, &$providers) {
        $data = \Symfony\Component\JsonStreamer\Read\Spl

rs, $instantiator, &$providers) {
            foreach ($data as $k => $v) {
                match ($k) {
                    'id' => $object->id = \Symfony\Component\JsonStreamer\Read\Decoder::decodeStream($stream, $v[0], $v[1]),
                    'name'

itter::splitDict($stream, $offset, $length);
        return $instantiator->instantiate(\Symfony\Component\JsonStreamer\Tests\Fixtures\Model\ClassicDummy::class, static function ($object) use ($stream, $data, $options, $transforme


Component\JsonStreamer\Tests\Fixtures\Model\ClassicDummy>
 */
return static function (mixed $stream, \Psr\Container\ContainerInterface $transformers, \Symfony\Component\JsonStreamer\Read\LazyInstantiator $instantiator, array $options): mixed {
    $providers['iterable<int|string, Symfony\\Component\\JsonStreamer\\Tests\\Fixtures\\Model\\ClassicDummy>'] = static function ($stream, $offset, $length) use ($options, $transformers, $instantiator, &$providers) {
        $data = \Symfony\Component\JsonStreamer\Rea

 => $providers['Symfony\\Component\\JsonStreamer\\Tests\\Fixtures\\Model\\ClassicDummy']($stream, $v[0], $v[1]);
            }
        };
        return $iterable($stream, $data);
    };
    $providers['Symfony\\Component\\JsonStreamer\\Tests\\Fixtures\\Mo

d\Splitter::splitDict($stream, $offset, $length);
        $iterable = static function ($stream, $data) use ($options, $transformers, $instantiator, &$providers) {
            foreach ($data as $k => $v) {
                yield $k


r\Tests\Fixtures\Model\DummyWithDateTimes
 */
return static function (mixed $stream, \Psr\Container\ContainerInterface $transformers, \Symfony\Component\JsonStreamer\Read\LazyInstantiator $instantiator, array $options): mixed {
    $providers['Symfony\\Component\\JsonStreamer\\Tests\\Fixtures\\Model\\DummyWithDateTimes'] = static function ($stream, $offset, $length) use ($options, $transformers, $instantiator, &$providers) {
        $data = \Symfony\Component\JsonStreamer\Read\Splitter::splitDict($stream, $

providers) {
            foreach ($data as $k => $v) {
                match ($k) {
                    'interface' => $object->interface = $providers['DateTimeInterface']($stream, $v[0], $v[1]),
                    'immutable' => $object->immutable = $pro

offset, $length);
        return $instantiator->instantiate(\Symfony\Component\JsonStreamer\Tests\Fixtures\Model\DummyWithDateTimes::class, static function ($object) use ($stream, $data, $options, $transformers, $instantiator, &$


* @param list<Symfony\Component\JsonStreamer\Tests\Fixtures\Model\DummyWithArray> $data
 */
return static function (mixed $data, \Psr\Container\ContainerInterface $transformers, array $options): \Traversable {
    try {
        yield "[";
        $prefix1 = '';
        foreach ($data as $value1) {
            $prefix2 = '';
            yield "{$prefix1}{{$prefix2}\"dummies\":";
            yield "{";
            $prefix3 = '';
            foreach ($value1->dummies as $key2 => $value2) {
                $key

R, 508);
                $prefix4 = ',';
                yield "{$prefix4}\"name\":";
                yield \json_encode($value2->name, \JSON_THROW_ON_ERROR, 508);
                yield "}";
                $prefix3 = ',';
            }
            $prefix

2 = is_int($key2) ? $key2 : \substr(\json_encode($key2), 1, -1);
                $prefix4 = '';
                yield "{$prefix3}\"{$key2}\":{{$prefix4}\"id\":";
                yield \json_encode($value2->id, \JSON_THROW_ON_ERRO


r\Tests\Fixtures\Model\DummyWithOtherDummies
 */
return static function (string|\Stringable $string, \Psr\Container\ContainerInterface $transformers, \Symfony\Component\JsonStreamer\Read\Instantiator $instantiator, array $options): mixed {
    $providers['Symfony\\Component\\JsonStreamer\\Tests\\Fixtures\\Model\\DummyWithOtherDummies'] = static function ($data) use ($options, $transformers, $instantiator, &$providers) {
        return $instantiator->instantiate(\Symfony\Component\JsonStreamer\Tests\Fixtures

\\Model\\DummyWithNameAttributes']($data['otherDummyOne']) : '_symfony_missing_value', 'otherDummyTwo' => \array_key_exists('otherDummyTwo', $data) ? $providers['Symfony\\Component\\JsonStreamer\\Tests\\Fixtures\\Model\\ClassicDummy']($data['otherDummyTwo'

\Model\DummyWithOtherDummies::class, \array_filter(['name' => $data['name'] ?? '_symfony_missing_value', 'otherDummyOne' => \array_key_exists('otherDummyOne', $data) ? $providers['Symfony\\Component\\JsonStreamer\\Tests\\Fixtures


/**
 * @param Symfony\Component\JsonStreamer\Tests\Fixtures\Model\DummyWithNameAttributes|null $data
 */
return static function (mixed $data, \Psr\Container\ContainerInterface $transformers, array $options): \Traversable {
    try {
        if ($data instanceof \Symfony\Component\JsonStreamer\Tests\Fixtures\Model\DummyWithNameAttributes) {
            $prefix1 = '';
            yield "{{$prefix1}\"@id\":";
            yield \json_encode($data->id, \JSON_THROW_ON_ERROR, 511);
            $prefix1 = ',';

 new \Symfony\Component\JsonStreamer\Exception\UnexpectedValueException(\sprintf('Unexpected "%s" value.', \get_debug_type($data)));
        }
    } catch (\JsonException $e) {
        throw new \Symfony\Component\JsonStreamer\Exception\NotEncodableValueEx

         yield "{$prefix1}\"name\":";
            yield \json_encode($data->name, \JSON_THROW_ON_ERROR, 511);
            yield "}";
        } elseif (null === $data) {
            yield "null";
        } else {
            throw


list<Symfony\Component\JsonStreamer\Tests\Fixtures\Enum\DummyBackedEnum>
 */
return static function (mixed $stream, \Psr\Container\ContainerInterface $transformers, \Symfony\Component\JsonStreamer\Read\LazyInstantiator $instantiator, array $options): mixed {
    $providers['list<Symfony\\Component\\JsonStreamer\\Tests\\Fixtures\\Enum\\DummyBackedEnum>'] = static function ($stream, $offset, $length) use ($options, $transformers, $instantiator, &$providers) {
        $data = \Symfony\Component\JsonStreamer\Re

k => $providers['Symfony\\Component\\JsonStreamer\\Tests\\Fixtures\\Enum\\DummyBackedEnum']($stream, $v[0], $v[1]);
            }
        };
        return \iterator_to_array($iterable($stream, $data));
    };
    $providers['Symfony\\Component\\JsonStream

ad\Splitter::splitList($stream, $offset, $length);
        $iterable = static function ($stream, $data) use ($options, $transformers, $instantiator, &$providers) {
            foreach ($data as $k => $v) {
                yield $


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\JsonStreamer\Tests\Mapping\Read;

use PHPUnit\Framework\TestCase;
use Symfony\Component\JsonStreamer\Exception\InvalidArgumentException;
use Symfony\Component\JsonStreamer\Mapping\PropertyMetadata;
use Symfony\Component\JsonStreamer\Mapping\PropertyMetadataLoader;
use Symfony\Component\JsonStreamer\Mapping\Read\AttributePropertyMetadataLoader;
us


ception\RuntimeException;
use Symfony\Component\JsonStreamer\Exception\UnsupportedException;
use Symfony\Component\JsonStreamer\Mapping\GenericTypePropertyMetadataLoader;
use Symfony\Component\JsonStreamer\Mapping\PropertyMetadata;
use Symfony\Component\JsonStreamer\Mapping\PropertyMetadataLoader;
use Symfony\Component\JsonStreamer\Mapping\PropertyMetadataLoaderInterface;
use Symfony\Component\JsonStreamer\Mapping\Write\AttributePropertyMetadataLoader;
use Symfony\Component\JsonStreamer\Tests\Fixtures\Enum\

\ClassicDummy;
use Symfony\Component\JsonStreamer\Tests\Fixtures\Model\DummyWithArray;
use Symfony\Component\JsonStreamer\Tests\Fixtures\Model\DummyWithDateTimes;
use Symfony\Component\JsonStreamer\Tests\Fixtures\Model\DummyWithDollarNamedProperties;
use S

DummyBackedEnum;
use Symfony\Component\JsonStreamer\Tests\Fixtures\Enum\DummyEnum;
use Symfony\Component\JsonStreamer\Tests\Fixtures\Mapping\SyntheticPropertyMetadataLoader;
use Symfony\Component\JsonStreamer\Tests\Fixtures\Model


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\JsonStreamer\Tests\ValueTransformer;

use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\IgnoreDeprecations;
use PHPUnit\Framework\TestCase;
use Symfony\Component\JsonStreamer\Exception\InvalidArgumentException;
use Symfony\Component\JsonStreamer\ValueTransformer\StringToDat

rmer();

        $this->assertEquals(
            new \DateTimeImmutable('2023-07-26'),
            $valueTransformer->transform('2023-07-26', []),
        );

        $this->assertEquals(
            (new \DateTimeImmutable('2023-07-26'))->setTime(0, 0),

eTimeValueTransformer;

#[Group('legacy')]
#[IgnoreDeprecations]
class StringToDateTimeValueTransformerTest extends TestCase
{
    public function testTransform()
    {
        $valueTransformer = new StringToDateTimeValueTransfo


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\JsonStreamer\Tests\DependencyInjection;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\JsonStreamer\DependencyInjection\Strea

register('.json_streamer.cache_warmer.streamer')->setArguments([null]);

        $container->register('streamable')->setClass('Foo')->addResourceTag('json_streamer.streamable', ['object' => true, 'list' => true]);
        $container->register('notStreamabl

mablePass;

class StreamablePassTest extends TestCase
{
    public function testSetStreamable()
    {
        $container = new ContainerBuilder();

        $container->register('json_streamer.stream_writer');
        $container->


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\JsonStreamer\Tests\DataModel\Write;

use PHPUnit\Framework\TestCase;
use Symfony\Component\JsonStreamer\DataModel\Write\CollectionNode;
use Symfony\Component\JsonStreamer\DataModel\Write\CompositeNode;
use Symfony\Component\JsonStreamer\DataModel\Write\ObjectNode;
use Symfony\Component\JsonStream

eType()
    {
        $this->expectException(InvalidArgumentException::class);
        $this->expectExceptionMessage(\sprintf('"%s" expects at least 2 nodes.', CompositeNode::class));

        new CompositeNode('$data', [new ScalarNode('$data', Type::int()

er\DataModel\Write\ScalarNode;
use Symfony\Component\JsonStreamer\Exception\InvalidArgumentException;
use Symfony\Component\TypeInfo\Type;

class CompositeNodeTest extends TestCase
{
    public function testCannotCreateWithOnlyOn


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\JsonStreamer\Tests\DataModel\Write;

use PHPUnit\Framework\TestCase;
use Symfony\Component\JsonStreamer\DataModel\Write\ObjectNode;
use Symfony\Component\JsonStreamer\DataModel\Write\ScalarNode;
use Symfony\Component\TypeInfo\Type;

class ObjectNodeTest exte

()', Type::int()),
            new ScalarNode('function()', Type::int()),
            new ScalarNode('$bar', Type::int()),
        ]);
        $object = $object->withAccessor('$baz');

        $this->assertSame('$baz', $object->getAccessor());
        $thi

nds TestCase
{
    public function testWithAccessor()
    {
        $object = new ObjectNode('$foo', Type::object(self::class), [
            new ScalarNode('$foo->property', Type::int()),
            new ScalarNode('$foo->method


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\JsonStreamer\Tests\Mapping\Write;

use PHPUnit\Framework\TestCase;
use Symfony\Component\JsonStreamer\Exception\InvalidArgumentException;
use Symfony\Component\JsonStreamer\Mapping\PropertyMetadata;
use Symfony\Component\JsonStreamer\Mapping\PropertyMetadataLoader;
use Symfony\Component\JsonStreamer\Mapping\Write\AttributePropertyMetadataLoader;


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\JsonStreamer\Tests\CacheWarmer;

use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
use Symfony\Component\JsonStreamer\CacheWarmer\StreamerCacheWarmer;
use Symfony\Component\JsonStreamer\Mapping\PropertyMetadataLoader;
use Symfony\Component\JsonStreamer\Tests\Fixtures\Model\ClassicDummy;
use Symfony\Component\JsonStreamer\Tests\Fixtures\Mode

r;
    private string $streamReadersDir;

    protected function setUp(): void
    {
        parent::setUp();

        $this->streamWritersDir = \sprintf('%s/symfony_json_streamer_test/stream_writer', sys_get_temp_dir());
        $this->streamReadersDir =

l\DummyWithNameAttributes;
use Symfony\Component\JsonStreamer\Tests\ServiceContainer;
use Symfony\Component\TypeInfo\TypeResolver\TypeResolver;

class StreamerCacheWarmerTest extends TestCase
{
    private string $streamWritersDi


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\JsonStreamer\Tests\DataModel\Read;

use PHPUnit\Framework\TestCase;
use Symfony\Component\JsonStreamer\DataModel\Read\CollectionNode;
use Symfony\Component\JsonStreamer\DataModel\Read\CompositeNode;
use Symfony\Component\JsonStreamer\DataModel\Read\ObjectNode;
use Symfon

annotCreateWithOnlyOneType()
    {
        $this->expectException(InvalidArgumentException::class);
        $this->expectExceptionMessage(\sprintf('"%s" expects at least 2 nodes.', CompositeNode::class));

        new CompositeNode([new ScalarNode(Type::in

y\Component\JsonStreamer\DataModel\Read\ScalarNode;
use Symfony\Component\JsonStreamer\Exception\InvalidArgumentException;
use Symfony\Component\TypeInfo\Type;

class CompositeNodeTest extends TestCase
{
    public function testC


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\JsonStreamer\Tests\ValueTransformer;

use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\IgnoreDeprecations;
use PHPUnit\Framework\TestCase;
use Symfony\Component\JsonStreamer\Exception\InvalidArgumentException;
use Symfony\Component\JsonStreamer\Va

teTimeToStringValueTransformer();

        $this->assertSame(
            '2023-07-26T00:00:00+00:00',
            $valueTransformer->transform(new \DateTimeImmutable('2023-07-26', new \DateTimeZone('UTC')), []),
        );

        $this->assertSame(

lueTransformer\DateTimeToStringValueTransformer;

#[Group('legacy')]
#[IgnoreDeprecations]
class DateTimeToStringValueTransformerTest extends TestCase
{
    public function testTransform()
    {
        $valueTransformer = new Da


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\JsonStreamer\DependencyInjection;

use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\I

Interface;

/**
 * Collects and merges services tagged with "json_streamer.property_value_transformer"
 * or "json_streamer.value_object_transformer" and sets them as arguments for the
 * services that need transformers.
 *
 * @author Mathias Arlaud <mathi

nvalidArgumentException;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\JsonStreamer\Transformer\PropertyValueTransformerInterface;
use Symfony\Component\JsonStreamer\Transformer\ValueObjectTransformer


buted with this source code.
 */

namespace Symfony\Component\JsonStreamer\Tests\DependencyInjection;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\JsonStreamer\DependencyInjection\TransformerPass;
use Symfony\Component\JsonStreamer\Test

Component\JsonStreamer\Transformer\ValueObjectTransformerInterface;

class TransformerPassTest extends TestCase
{
    public function testDoNothingIfStreamWriterNotDefined()
    {
        $container = new ContainerBuilder();
        $container->register('j

s\Fixtures\Transformer\BooleanToStringValueTransformer;
use Symfony\Component\JsonStreamer\Transformer\DateTimeValueObjectTransformer;
use Symfony\Component\JsonStreamer\Transformer\PropertyValueTransformerInterface;
use Symfony\


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\JsonStreamer\DataModel\Read;

use Symfony\Component\TypeInfo\Type\ObjectType;
use Symfony\Component\TypeInfo\Type\UnionType;

/**
 * Represents an object in the data model graph representation.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 *
 * @i

ction __construct(
        private ObjectType $type,
        private array $properties,
        private bool $mock = false,
    ) {
    }

    public static function createMock(ObjectType|UnionType $type): self
    {
        return new self($type, [], true

nternal
 */
final class ObjectNode implements DataModelNodeInterface
{
    /**
     * @param array<string, array{name: string, value: DataModelNodeInterface, accessor: callable(string): string}> $properties
     */
    public fun


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ObjectMapper\Metadata;

use Symfony\Component\ObjectMapper\Attribute\Map;
use Symfony\Component\ObjectMapper\Exception\MappingException;

/**
 * @internal
 *
 * @author Antoine Bluchet <soyuka@gmail.com>
 */
final class ReflectionObjectMapperMetadataFactory implements Ob

       try {
            $key = $object::class.($property ?? '');

            if (isset($this->attributesCache[$key])) {
                return $this->attributesCache[$key];
            }

            $refl = $this->reflectionClassCache[$object::class] ??

jectMapperMetadataFactoryInterface
{
    private array $reflectionClassCache = [];
    private array $attributesCache = [];

    public function create(object $object, ?string $property = null, array $context = []): array
    {


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ObjectMapper\Metadata;

use Symfony\Component\ObjectMapper\Attribute\Map;

/**
 * Maps classes based on attributes found on the target's properties.
 *
 * @author Florent Blaison <florent.blaison@gmail.com>
 */
final class ReverseClassObjectMapperMetadataFactory implements ObjectMapperMetadataFac

 private readonly ObjectMapperMetadataFactoryInterface $objectMapperMetadataFactory,
        private readonly array $classMap,
    ) {
    }

    public function create(object $object, ?string $property = null, array $context = []): array
    {
        $cl

toryInterface
{
    /**
     * @var array<string, list<Mapping>>
     */
    private array $attributesCache = [];

    /**
     * @param array<class-string, class-string> $classMap
     */
    public function __construct(


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ObjectMapper\DependencyInjection;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

/**
 * @author Florent Blaison <florent.blaison@gmail.com>
 */
final class ReverseMappin

        $reverseClassObjectMapperMetadataFactory = $container->getDefinition('object_mapper.metadata_factory.reverse_class');

        $classes = [];
        foreach ($container->findTaggedResourceIds('object_mapper.map') as $tags) {
            foreach

gPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container): void
    {
        if (!$container->hasDefinition('object_mapper.metadata_factory.reverse_class')) {
            return;
        }


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form;

use Symfony\Component\Form\Exception\InvalidArgumentException;
use Symfony\Component\Form\Exception\UnexpectedTypeException;

/**
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
abstract class AbstractExtension implements FormExtensionInterface
{
    /**
     * The types provided by this extension.
     *
     * @var FormTypeInterfa

provided by this extension.
     */
    private ?FormTypeGuesserInterface $typeGuesser = null;

    /**
     * Whether the type guesser has been loaded.
     */
    private bool $typeGuesserLoaded = false;

    public function getType(string $name): FormTy

ce[]
     */
    private array $types;

    /**
     * The type extensions provided by this extension.
     *
     * @var FormTypeExtensionInterface[][]
     */
    private array $typeExtensions;

    /**
     * The type guesser


buted with this source code.
 */

namespace Symfony\Component\Form;

use Symfony\Contracts\Service\ResetInterface;

/**
 * Default implementation of {@link FormRendererEngineInterface}.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
abstract class AbstractRendererEngine implements FormRendererEngineInterface, ResetInterface
{
    /**
     * The variable in {@link FormView} used as cache key.
     */
    public const CACHE_KEY_VAR = 'cache_key';

    /**
     * @var array[]
     */
    protected a

 private array $resourceHierarchyLevels = [];

    /**
     * @var array<string, array<string, bool>>
     */
    private array $resourceInheritability = [];

    /**
     * Creates a new renderer engine.
     *
     * @param array $defaultThemes The defau

rray $themes = [];

    /**
     * @var bool[]
     */
    protected array $useDefaultThemes = [];

    /**
     * @var array[]
     */
    protected array $resources = [];

    /**
     * @var array<array<int|false>>
     */


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form;

use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\Util\StringUtil;
use Symfony\Component\OptionsResolver\OptionsResolver;

/**
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
abstract class AbstractType i

FormBuilderInterface $builder, array $options): void
    {
    }

    public function buildView(FormView $view, FormInterface $form, array $options): void
    {
    }

    public function finishView(FormView $view, FormInterface $form, array $options): voi

mplements FormTypeInterface
{
    public function getParent(): ?string
    {
        return FormType::class;
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
    }

    public function buildForm(


is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form;

use Symfony\Component\OptionsResolver\OptionsResolver;

/**
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
abstract class AbstractTypeExtension implements FormTypeExtensionInterface
{
    public function configureOptions(OptionsResolver $resolver): void

erInterface $builder, array $options): void
    {
    }

    public function buildView(FormView $view, FormInterface $form, array $options): void
    {
    }

    public function finishView(FormView $view, FormInterface $form, array $options): void
    {

    {
    }

    public function buildForm(FormBuild


buted with this source code.
 */

namespace Symfony\Component\Form;

use Symfony\Component\Form\Exception\AlreadySubmittedException;
use Symfony\Component\Form\Exception\BadMethodCallException;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Symfony\Component\PropertyAccess\PropertyPathInterface;

/**
 * A form button.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 *
 * @implements \IteratorAggregate<string, FormInterface>
 */
class Button implements \IteratorAggregate, FormI

ce $config,
    ) {
    }

    /**
     * Unsupported method.
     */
    public function offsetExists(mixed $offset): bool
    {
        return false;
    }

    /**
     * Unsupported method.
     *
     * This method should not be invoked.
     *
     *

nterface
{
    private ?FormInterface $parent = null;
    private bool $submitted = false;

    /**
     * Creates a new button from a form configuration.
     */
    public function __construct(
        private FormConfigInterfa


\Component\Form\Exception\InvalidArgumentException;
use Symfony\Component\PropertyAccess\PropertyPathInterface;

/**
 * A builder for {@link Button} instances.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 *
 * @implements \IteratorAggregate<string, FormBuilderInterface>
 */
class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface
{
    protected bool $locked = false;

    private bool $disabled = false;
    private ResolvedFormTypeInterface $type;
    private string $name;
    priva

e || null === $name) {
            throw new InvalidArgumentException('Buttons cannot have empty names.');
        }

        $this->name = $name;

        FormConfigBuilder::validateName($name);
    }

    /**
     * Unsupported method.
     *
     * @thr

te array $attributes = [];

    /**
     * @throws InvalidArgumentException if the name is empty
     */
    public function __construct(
        ?string $name,
        private array $options = [],
    ) {
        if ('' === $nam


* This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form;

class CallbackTransformer implements DataTransformerInterface
{
    private \Closure $transform;
    private \Closure $reverseTransform;

    public function __construct(callable $transform, callable $reverseTransform)
    {
        $this->transform

 $reverseTransform(...);
    }

    public function transform(mixed $data): mixed
    {
        return ($this->transform)($data);
    }

    public function reverseTransform(mixed $data): mixed
    {
        return ($this->reverseTransform)($data);
    }
}

= $transform(...);
        $this->reverseTransform =


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form;

/**
 * Writes and reads values to/from an object or array bound to a form.
 *
 * @author Yonel Ceruto <yonelceruto@gmail.com>
 */
interface DataAccessorInterface
{
    /**
     * Returns the value at the end of the property of the object graph.
     *
     * @thro

ject graph.
     *
     * @throws Exception\AccessException If unable to write the given value
     */
    public function setValue(object|array &$viewData, mixed $value, FormInterface $form): void;

    /**
     * Returns whether a value can be read from

ws Exception\AccessException If unable to read from the given form data
     */
    public function getValue(object|array $viewData, FormInterface $form): mixed;

    /**
     * Sets the value at the end of the property of the ob


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form;

/**
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
interface DataMapperInterface
{
    /**
     * Maps the view data of a compound form to its children.
     *
     * The method is responsible for calling {@link FormInterface::setData()}
     * on the children of compound forms, de

rmInterface} instances
     *
     * @throws Exception\UnexpectedTypeException if the type of the data parameter is not supported
     */
    public function mapDataToForms(mixed $viewData, \Traversable $forms): void;

    /**
     * Maps the model data of

fining their underlying model data.
     *
     * @param mixed                              $viewData View data of the compound form being initialized
     * @param \Traversable<mixed, FormInterface> $forms    A list of {@link Fo


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form;

use Symfony\Component\Form\Exception\TransformationFailedException;

/**
 * Transforms a value between different representations.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 *
 * @template TValue
 * @template TTransformedValue
 */
interface DataTransformerInterface
{
    /**
     * Transforms a value from the original representa

normalize the model data.
     *    This is mainly useful when the same form type (the same configuration)
     *    has to handle different kind of underlying data, e.g The DateType can
     *    deal with strings or \DateTime objects as input.
     *

tion to a transformed representation.
     *
     * This method is called when the form field is initialized with its default data, on
     * two occasions for two types of transformers:
     *
     * 1. Model transformers which


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form;

use Symfony\Component\Form\Extension\Core\Type\EnumType;
use Symfony\Component\Form\Guess\Guess;
use Symfony\Component\Form\Guess\TypeGuess;
use Symfony\Component\Form\Guess\ValueGuess;

final class EnumFormTypeGuesser implements FormTypeGuesserInterface
{
    /**
     * @var array<string,

  return null;
        }

        return new TypeGuess(EnumType::class, ['class' => ltrim($enum, '?')], Guess::HIGH_CONFIDENCE);
    }

    public function guessRequired(string $class, string $property): ?ValueGuess
    {
        if (!($enum = $this->getPr

 array<string, string|false>>
     */
    private array $cache = [];

    public function guessType(string $class, string $property): ?TypeGuess
    {
        if (!($enum = $this->getPropertyType($class, $property))) {


y simple fields
 *       or map children model data for compound fields
 *
 * A date field, for example, may store a date as "Y-m-d" string (1) in the
 * object. To facilitate processing in the field, this value is normalized
 * to a DateTime object (2). In the HTML representation of your form, a
 * localized string (3) may be presented to and modified by the user, or it could be an array of values
 * to be mapped to choices fields.
 *
 * In most cases, format (1) and format (2) will be the same. For exampl

ViewTransformer().
 *
 * In some cases though it makes sense to make format (1) configurable. To
 * demonstrate this, let's extend our above date field to store the value
 * either as "Y-m-d" string or as timestamp. Internally we still want to
 * use a Dat

e,
 * a checkbox field uses a Boolean value for both internal processing and
 * storage in the object. In these cases you need to set a view transformer
 * to convert between formats (2) and (3). You can do this by calling
 * add


buted with this source code.
 */

namespace Symfony\Component\Form;

use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Form\Exception\BadMethodCallException;
use Symfony\Component\Form\Exception\InvalidArgumentException;
use Symfony\Component\Form\Extension\Core\Type\TextType;

/**
 * A builder for creating {@link Form} instances.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 *
 * @implements \IteratorAggregate<string, FormBuilderInterface>
 */
class FormBuilder

The data of children who haven't been converted to form builders yet.
     */
    private array $unresolvedChildren = [];

    public function __construct(?string $name, ?string $dataClass, EventDispatcherInterface $dispatcher, FormFactoryInterface $factor

extends FormConfigBuilder implements \IteratorAggregate, FormBuilderInterface
{
    /**
     * The children of the form builder.
     *
     * @var FormBuilderInterface[]
     */
    private array $children = [];

    /**
     *


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form;

/**
 * @author Bernhard Schussek <bschussek@gmail.com>
 *
 * @extends \Traversable<string, FormBuilderInterface>
 */
interface FormBuilderInterface extends \Traversable, \Countable, FormConfigBuilderInterface
{
    /**
     * Adds a new field to this group. A field must have a unique name

ace>|null $type
     * @param array<string, mixed>                 $options
     */
    public function add(string|self $child, ?string $type = null, array $options = []): static;

    /**
     * Creates a form builder.
     *
     * @param string

within
     * the group. Otherwise the existing field is overwritten.
     *
     * If you add a nested group, this group should also be represented in the
     * object hierarchy.
     *
     * @param class-string<FormTypeInterf


mplements FormConfigBuilderInterface
{
    protected bool $locked = false;

    /**
     * Caches a globally unique {@link NativeRequestHandler} instance.
     */
    private static NativeRequestHandler $nativeRequestHandler;

    private string $name;
    private ?PropertyPathInterface $propertyPath = null;
    private bool $mapped = true;
    private bool $byReference = true;
    private bool $inheritData = false;
    private bool $compound = false;
    private ResolvedFormTypeInterface $type;
    private

 = false;
    private mixed $emptyData = null;
    private array $attributes = [];
    private mixed $data = null;
    private ?string $dataClass;
    private bool $dataLocked = false;
    private FormFactoryInterface $formFactory;
    private string $acti

 array $viewTransformers = [];
    private array $modelTransformers = [];
    private ?DataMapperInterface $dataMapper = null;
    private bool $required = true;
    private bool $disabled = false;
    private bool $errorBubbling


buted with this source code.
 */

namespace Symfony\Component\Form;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\PropertyAccess\PropertyPathInterface;

/**
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
interface FormConfigBuilderInterface extends FormConfigInterface
{
    /**
     * Adds an event listener to an event on this form.
     *
     * @param int $priority The priority of the listener. Listeners
     *                      with a higher priority ar

  * Adds an event subscriber for events on this form.
     *
     * @return $this
     */
    public function addEventSubscriber(EventSubscriberInterface $subscriber): static;

    /**
     * Appends / prepends a transformer to the view transformer chain.

e called before
     *                      listeners with a lower priority.
     *
     * @return $this
     */
    public function addEventListener(string $eventName, callable $listener, int $priority = 0): static;

    /**


buted with this source code.
 */

namespace Symfony\Component\Form;

use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\PropertyAccess\PropertyPathInterface;

/**
 * The configuration of a {@link Form} object.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
interface FormConfigInterface
{
    /**
     * Returns the event dispatcher used to dispatch form events.
     */
    public function getEventDispatcher(): EventDispatcherInterface;

    /**
     * Returns the

erface;

    /**
     * Returns whether the form should be mapped to an element of its
     * parent's data.
     */
    public function getMapped(): bool;

    /**
     * Returns whether the form's data should be modified by reference.
     */
    public

 name of the form used as HTTP parameter.
     */
    public function getName(): string;

    /**
     * Returns the property path that the form should be mapped to.
     */
    public function getPropertyPath(): ?PropertyPathInt


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form;

use Symfony\Component\Form\Exception\BadMethodCallException;
use Symfony\Component\Translation\Translator;

/**
 * Wraps errors in forms.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
class FormError
{
    protected string $messageTemplate;

    /**
     * The form that spawned

The translated error message
     * @param string|null $messageTemplate      The template for the error message
     * @param array       $messageParameters    The parameters that should be
     *                                          substituted in the

 this error.
     */
    private ?FormInterface $origin = null;

    /**
     * Any array key in $messageParameters will be used as a placeholder in
     * $messageTemplate.
     *
     * @param string      $message


buted with this source code.
 */

namespace Symfony\Component\Form;

use Symfony\Component\Form\Exception\BadMethodCallException;
use Symfony\Component\Form\Exception\InvalidArgumentException;
use Symfony\Component\Form\Exception\LogicException;
use Symfony\Component\Form\Exception\OutOfBoundsException;
use Symfony\Component\Validator\ConstraintViolation;

/**
 * Iterates over the errors of a form.
 *
 * This class supports recursive iteration. In order to iterate recursively,
 * pass a structure of {@link

ors.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 *
 * @template T of FormError|FormErrorIterator
 *
 * @implements \ArrayAccess<int, T>
 * @implements \RecursiveIterator<int, T>
 * @implements \SeekableIterator<int, T>
 */
class FormErrorIterato

FormError} and {@link FormErrorIterator} objects
 * to the $errors constructor argument.
 *
 * You can also wrap the iterator into a {@link \RecursiveIteratorIterator} to
 * flatten the recursive structure into a flat list of err


n Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form;

use Symfony\Contracts\EventDispatcher\Event;

/**
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
class FormEvent extends Event
{
    public function __construct(
        private FormInterface $form,
        protected mixed $data,
    ) {
    }

    /**
     * Returns the form at the source of the eve

face
    {
        return $this->form;
    }

    /**
     * Returns the data associated with this event.
     */
    public function getData(): mixed
    {
        return $this->data;
    }

    /**
     * Allows updating with some filtered data.
     */

nt.
     */
    public function getForm(): FormInter


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form;

use Symfony\Component\Form\Event\PostSetDataEvent;
use Symfony\Component\Form\Event\PostSubmitEvent;
use Symfony\Component\Form\Event\PreSetDataEvent;
use Symfony\Component\Form\Event\PreSubmitEvent;
use Symfony\Component\Form\Event\SubmitEvent;

/**
 * To learn more about how form events work check the documentation
 * entry at {@link htt

l}.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
final class FormEvents
{
    /**
     * The PRE_SUBMIT event is dispatched at the beginning of the Form::submit() method.
     *
     * It can be used to:
     *  - Change data from the request,

ps://symfony.com/doc/any/components/form/form_events.html}.
 *
 * To learn how to dynamically modify forms using events check the cookbook
 * entry at {@link https://symfony.com/doc/any/cookbook/form/dynamic_form_modification.htm


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form;

/**
 * Interface for extensions which provide types, type extensions and a guesser.
 */
interface FormExtensionInterface
{
    /**
     * Returns a type by name.
     *
     * @param string $name The name of the type
     *
     * @throws Exception\In

tring $name The name of the type
     */
    public function hasType(string $name): bool;

    /**
     * Returns the extensions for the given type.
     *
     * @param string $name The name of the type
     *
     * @return FormTypeExtensionInterface[]

validArgumentException if the given type is not supported by this extension
     */
    public function getType(string $name): FormTypeInterface;

    /**
     * Returns whether the given type is supported.
     *
     * @param s


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form;

use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Flow\FormFlowBuilderInterface;
use Symfony\Component\Form\Flow\FormFlowInterface;
use Symfony\Component\Form\Flow\FormFlowTypeInterface;

class FormFactory implements FormFactoryInterface
{
    public

tring $type = FormType::class, mixed $data = null, array $options = []): FormInterface
    {
        return $this->createBuilder($type, $data, $options)->getForm();
    }

    /**
     * @return ($type is class-string<FormFlowTypeInterface> ? FormFlowInter

 function __construct(
        private FormRegistryInterface $registry,
    ) {
    }

    /**
     * @return ($type is class-string<FormFlowTypeInterface> ? FormFlowInterface : FormInterface)
     */
    public function create(s


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form;

use Symfony\Component\Form\Extension\Core\CoreExtension;

/**
 * The default implementation of FormFactoryBuilderInterface.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
class FormFactoryBuilder implements FormFactoryBuilderInterface
{
    private ResolvedFormTypeFactoryInterface $resolvedTypeFactory;

    /**
     * @var FormE

tensions = [];

    /**
     * @var FormTypeGuesserInterface[]
     */
    private array $typeGuessers = [];

    public function __construct(
        private bool $forceCoreExtension = false,
    ) {
    }

    public function setResolvedTypeFactory(Resol

xtensionInterface[]
     */
    private array $extensions = [];

    /**
     * @var FormTypeInterface[]
     */
    private array $types = [];

    /**
     * @var FormTypeExtensionInterface[][]
     */
    private array $typeEx


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form;

/**
 * A builder for FormFactoryInterface objects.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
interface FormFactoryBuilderInterface
{
    /**
     * Sets the factory for creating ResolvedFormTypeInterface instances.
     *
     * @return $this
     */
    public function set

Interface $extension): static;

    /**
     * Adds a list of extensions to be loaded by the factory.
     *
     * @param FormExtensionInterface[] $extensions The extensions
     *
     * @return $this
     */
    public function addExtensions(array $exte

ResolvedTypeFactory(ResolvedFormTypeFactoryInterface $resolvedTypeFactory): static;

    /**
     * Adds an extension to be loaded by the factory.
     *
     * @return $this
     */
    public function addExtension(FormExtension


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form;

use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\Flow\FormFlowBuilderInterface;
use Symfony\Component\Form\Flow\FormFlowInterface;
use Symfony\Component\Form\Flow\FormFlowTypeInterface;
use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException;

/**
 * Allows creating a form based on a name,

a
     *
     * @return ($type is class-string<FormFlowTypeInterface> ? FormFlowInterface : FormInterface)
     *
     * @throws InvalidOptionsException if any given option is not applicable to the given type
     */
    public function create(string $type

 a class or a property.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
interface FormFactoryInterface
{
    /**
     * Returns a form.
     *
     * @see createBuilder()
     *
     * @param mixed $data The initial dat


 * @author Bernhard Schussek <bschussek@gmail.com>
 *
 * @extends \ArrayAccess<string, FormInterface>
 * @extends \Traversable<string, FormInterface>
 */
interface FormInterface extends \ArrayAccess, \Traversable, \Countable
{
    /**
     * Sets the parent form.
     *
     * @param FormInterface|null $parent The parent form or null if it's the root
     *
     * @return $this
     *
     * @throws Exception\AlreadySubmittedException if the form has already been submitted
     * @throws Exception\LogicExc

     */
    public function getParent(): ?self;

    /**
     * Adds or replaces a child to the form.
     *
     * @param FormInterface|string $child   The FormInterface instance or the name of the child
     * @param string|null          $type    The ch

eption            when trying to set a parent for a form with
     *                                             an empty name
     */
    public function setParent(?self $parent): static;

    /**
     * Returns the parent form.


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form;

use Symfony\Component\Form\Exception\ExceptionInterface;
use Symfony\Component\Form\Exception\InvalidArgumentException;
use Symfony\Component\Form\Exception\LogicException;
use Symfony\Component\Form\Exception\UnexpectedTypeException;

/**
 * The central registry of the Form component.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>

= [];

    private FormTypeGuesserInterface|false|null $guesser = false;
    private array $checkedTypes = [];

    /**
     * @param FormExtensionInterface[] $extensions
     *
     * @throws UnexpectedTypeException if any extension does not implement For

 */
class FormRegistry implements FormRegistryInterface
{
    /**
     * @var FormExtensionInterface[]
     */
    private array $extensions = [];

    /**
     * @var ResolvedFormTypeInterface[]
     */
    private array $types


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form;

/**
 * The central registry of the Form component.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
interface FormRegistryInterface
{
    /**
     * Returns a form type by name.
     *
     * This method registers the type extensions fr

urns whether the given form type is supported.
     */
    public function hasType(string $name): bool;

    /**
     * Returns the guesser responsible for guessing types.
     */
    public function getTypeGuesser(): ?FormTypeGuesserInterface;

    /**

om the form extensions.
     *
     * @throws Exception\InvalidArgumentException if the type cannot be retrieved from any extension
     */
    public function getType(string $name): ResolvedFormTypeInterface;

    /**
     * Ret


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\JsonStreamer\DataModel\Write;

use Symfony\Component\TypeInfo\Type\BackedEnumType;

/**
 * Represents a backed enum in the data model graph representation.
 *
 * Backed enums are leaves in the data model tree.
 *
 * @author Mathias Arlaud <mathias.arla

unction withAccessor(string $accessor): self
    {
        return new self($accessor, $this->type);
    }

    public function getIdentifier(): string
    {
        return (string) $this->getType();
    }

    public function getAccessor(): string
    {

ud@gmail.com>
 *
 * @internal
 */
final class BackedEnumNode implements DataModelNodeInterface
{
    public function __construct(
        private string $accessor,
        private BackedEnumType $type,
    ) {
    }

    public f


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\JsonStreamer\DataModel\Write;

use Symfony\Component\JsonStreamer\Exception\InvalidArgumentException;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\Type\UnionType;

/**
 * Represents a "OR" node composition in the data model graph representation.
 *
 * Composing nodes are so

onNode::class => 3,
        ObjectNode::class => 2,
        BackedEnumNode::class => 1,
        ScalarNode::class => 0,
    ];

    /**
     * @var list<DataModelNodeInterface>
     */
    private array $nodes;

    /**
     * @param list<DataModelNodeInte

rted by their precision (descending).
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 *
 * @internal
 */
final class CompositeNode implements DataModelNodeInterface
{
    private const NODE_PRECISION = [
        Collecti


hp

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\JsonStreamer\DataModel\Write;

use Symfony\Component\TypeInfo\Type\BuiltinType;

/**
 * Represents a scalar in the data model graph representation.
 *
 * Scalars are leaves in the data model tree.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.c

sor(string $accessor): self
    {
        return new self($accessor, $this->type);
    }

    public function getIdentifier(): string
    {
        return (string) $this->getType();
    }

    public function getAccessor(): string
    {
        return $thi

om>
 *
 * @internal
 */
final class ScalarNode implements DataModelNodeInterface
{
    public function __construct(
        private string $accessor,
        private BuiltinType $type,
    ) {
    }

    public function withAcces


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ObjectMapper;

use Symfony\Component\ObjectMapper\Exception\MappingException;
use Symfony\Component\ObjectMapper\Exception\MappingTransformException;
use Symfony\Component\ObjectMapper\Exception\NoSuchPropertyException;

/**
 * Object to object mapper.

T>|null $target The object or class to map to
     *
     * @return T
     *
     * @throws MappingException          When the mapping configuration is wrong
     * @throws MappingTransformException When a transformation on an object does not return an obj

 *
 * @author Antoine Bluchet <soyuka@gmail.com>
 */
interface ObjectMapperInterface
{
    /**
     * @template T of object
     *
     * @param object                 $source The object to map from
     * @param T|class-string<


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ObjectMapper\Transform;

use Symfony\Component\ObjectMapper\Exception\MappingException;
use Symfony\Component\ObjectMapper\ObjectMapper;
use Symfony\Component\ObjectMapper\ObjectMapperAwareInterface;
use Symfony\Component\ObjectMapper\ObjectMapperInterface;
use Symfony\C

   public function __construct(
        private ?ObjectMapperInterface $objectMapper = null,
        public readonly ?string $targetClass = null,
    ) {
    }

    public function withObjectMapper(ObjectMapperInterface $objectMapper): static
    {

omponent\ObjectMapper\TransformCallableInterface;

/**
 * @template T of object
 *
 * @implements TransformCallableInterface<object, T>
 */
class MapCollection implements TransformCallableInterface, ObjectMapperAwareInterface
{


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ObjectMapper\Condition;

use Symfony\Component\ObjectMapper\ConditionCallableInterface;

/**
 * Marker interface for condition callables that validate class rules.
 *
 * Conditions implementing this interface are evaluated before fetching
 * the prope

owing early skip of mapping rules based on
 * source/target class checks.
 *
 * @template T of object
 * @template T2 of object
 *
 * @extends ConditionCallableInterface<T, T2>
 */
interface ClassRuleConditionCallableInterface extends ConditionCallableInte


?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ObjectMapper\Condition;

/**
 * @template T of object
 *
 * @implements ClassRuleConditionCallableInterface<T, object>
 */
final class SourceClass implements ClassRuleConditionCallableInterface
{
    /**
     * @var non-empty-array<class-string>

Name) ? $className : [$className];
    }

    public function __invoke(mixed $value, object $source, ?object $target): bool
    {
        foreach ($this->sources as $validSource) {
            if ($source instanceof $validSource) {
                return t

    */
    private readonly array $sources;

    /**
     * @param class-string<T>|array<class-string<T>> $className
     */
    public function __construct(string|array $className)
    {
        $this->sources = \is_array($class


RequestWithSourceAndAutoMappedView;
use Symfony\Component\ObjectMapper\Tests\Fixtures\ClassMap\CostRequestWithSourceView;
use Symfony\Component\ObjectMapper\Tests\Fixtures\ClassMap\Quote;
use Symfony\Component\ObjectMapper\Tests\Fixtures\ClassMap\QuoteRequestView;
use Symfony\Component\ObjectMapper\Tests\Fixtures\ClassRule\A as ClassRuleA;
use Symfony\Component\ObjectMapper\Tests\Fixtures\ClassRule\B as ClassRuleB;
use Symfony\Component\ObjectMapper\Tests\Fixtures\ClassRule\C as ClassRuleC;
use Symfony\Comp

 ConditionalSourceMapAddress;
use Symfony\Component\ObjectMapper\Tests\Fixtures\ConditionalSourceMap\User as ConditionalSourceMapUser;
use Symfony\Component\ObjectMapper\Tests\Fixtures\ConditionalSourceMap\UserDto as ConditionalSourceMapUserDto;
use Symfon


 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ObjectMapper\Tests\Fixtures;

use Symfony\Component\VarExporter\LazyObjectInterface;

class LazyFoo extends \stdClass implements LazyObjectInterface
{
    private bool $initialized = false;

    public function isLazyObjectInitialized(bool $partial = false

        return $this->initialized;
    }

    public function initializeLazyObject(): object
    {
        $this->initialized = true;

        return $this;
    }

    public function resetLazyObject(): bool
    {
        $this->initialized = false;


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ObjectMapper\Tests\Fixtures\ClassRule;

use Symfony\Component\ObjectMapper\Attribute\Map;
use Symfony\Component\ObjectMapper\Condition\ClassRule;
use Symfony\Component\ObjectMapper\Condition\ClassRuleList;
use Symfony\Component\ObjectMapper\Condition\SourceC

strtolower',
        if: new ClassRuleList([
            new SourceClass(B::class),
        ]),
    )]
    #[Map(
        source: 'bar',
        if: new ClassRuleList([
            new ClassRule(sources: [C::class]),
        ]),
    )]
    public string $s

lass;
use Symfony\Component\ObjectMapper\Condition\TargetClass;

#[Map(source: B::class)]
#[Map(source: C::class)]
#[Map(target: B::class)]
#[Map(target: C::class)]
class A
{
    #[Map(
        source: 'foo',
        transform: '


php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ObjectMapper\Tests\Fixtures\MultipleTargets;

use Symfony\Component\ObjectMapper\Attribute\Map;

#[Map(target: B::class, if: [A::class, 'shouldMapToB'])]
#[Map(target: C::class, if: [A::class, 'shouldMapToC'])]
class A
{
    public function __const

adonly string $foo = 'bar')
    {
    }

    public static function shouldMapToB(mixed $value, object $object): bool
    {
        return false;
    }

    public static function shouldMapToC(mixed $value, object $object): bool
    {
        return true;


hp

namespace Symfony\Component\ObjectMapper\Tests\Fixtures\NestedMappingWithClassTransformer;

class ParentTarget
{
    public string $name;
    public ChildWithClassTransformTarget $childWithClassTransformer;
    public ChildWithoutClassTransformerTarget $childWithoutClassTransformer;
    public ChildWithClassTransformTarget $childWithBothTransformers;
    public bool $transformed = false;

    public static function createFromSource(self $value, ParentSource $source): self
    {
        $value->transform

ithoutClassTransformerTarget();

        $target->name = 'child';
        $target->propertyTransformed = true;

        return $target;
    }

    public static function childBothTransformer(ChildWithClassTransformSource $value, ParentSource $source): Chil

ed = true;

        return $value;
    }

    public static function childPropertyTransformer(ChildWithoutClassTransformerSource $value, ParentSource $source): ChildWithoutClassTransformerTarget
    {
        $target = new ChildW


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ObjectMapper\Tests\Fixtures\MapStruct;

use Symfony\Component\ObjectMapper\Metadata\Mapping;
use Symfony\Component\ObjectMapper\Metadata\ObjectMapperMetadataFactoryInterface;
use Symfony\Component\ObjectMapper\ObjectMapperInterface;

/**
 * A Metadata factory that implem

ate readonly string $mapper)
    {
        if (!is_a($mapper, ObjectMapperInterface::class, true)) {
            throw new \RuntimeException(\sprintf('Mapper should implement "%s".', ObjectMapperInterface::class));
        }
    }

    public function crea

ents the basics behind https://mapstruct.org/.
 *
 * @author Antoine Bluchet <soyuka@gmail.com>
 */
final class MapStructMapperMetadataFactory implements ObjectMapperMetadataFactoryInterface
{
    public function __construct(priv


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\JsonStreamer\DependencyInjection;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

/**
 * Sets the streamable metadata to the services that need them.
 *
 * @author Mathia

ter')) {
            return;
        }

        $streamable = [];

        foreach ($container->findTaggedResourceIds('json_streamer.streamable') as $id => $tag) {
            $class = $container->getDefinition($id)->getClass();
            $streamable[$cl

s Arlaud <mathias.arlaud@gmail.com>
 */
class StreamablePass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container): void
    {
        if (!$container->hasDefinition('json_streamer.stream_wri


ackage.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\JsonStreamer\DataModel\Read;

use Symfony\Component\TypeInfo\Type\BackedEnumType;

/**
 * Represents a backed enum in the data model graph representation.
 *
 * Backed enums are leaves in the data model tree.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 *
 * @internal
 */
final cl

{
    public function __construct(
        public BackedEnumType $type,
    ) {
    }

    public function getIdentifier(): string
    {
        return (string) $this->type;
    }

    public function getType(): BackedEnumType
    {
        return $this->

ass BackedEnumNode implements DataModelNodeInterface


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\JsonStreamer\DataModel\Read;

use Symfony\Component\JsonStreamer\Exception\InvalidArgumentException;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\Type\UnionType;

/**
 * Represents a "OR" node composition in the data model graph representation.
 *
 * Composing nodes are sor

nNode::class => 3,
        ObjectNode::class => 2,
        BackedEnumNode::class => 1,
        ScalarNode::class => 0,
    ];

    /**
     * @var list<DataModelNodeInterface>
     */
    private array $nodes;

    /**
     * @param list<DataModelNodeInter

ted by their precision (descending).
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 *
 * @internal
 */
final class CompositeNode implements DataModelNodeInterface
{
    private const NODE_PRECISION = [
        Collectio


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\JsonStreamer\DataModel\Write;

use Symfony\Component\TypeInfo\Type\CollectionType;

/**
 * Represents a collection in the data model graph representation.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 *
 * @internal
 */
final class CollectionNode

y,
    ) {
    }

    public function withAccessor(string $accessor): self
    {
        return new self($accessor, $this->type, $this->item, $this->key);
    }

    public function getIdentifier(): string
    {
        return (string) $this->getType();

implements DataModelNodeInterface
{
    public function __construct(
        private string $accessor,
        private CollectionType $type,
        private DataModelNodeInterface $item,
        private DataModelNodeInterface $ke


ony\Component\ObjectMapper\Metadata\ReflectionObjectMapperMetadataFactory;
use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException as PropertyAccessorNoSuchPropertyException;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
use Symfony\Component\VarExporter\LazyObjectInterface;

/**
 * Object to object mapper.
 *
 * @author Antoine Bluchet <soyuka@gmail.com>
 */
final class ObjectMapper implements ObjectMapperInterface, ObjectMapperAwareInterface
{
    /**
     * Tracks recursi

   private readonly ?PropertyAccessorInterface $propertyAccessor = null,
        private readonly ?ContainerInterface $transformCallableLocator = null,
        private readonly ?ContainerInterface $conditionCallableLocator = null,
        private ?ObjectMa

ve references.
     */
    private ?\WeakMap $objectMap = null;

    public function __construct(
        private readonly ObjectMapperMetadataFactoryInterface $metadataFactory = new ReflectionObjectMapperMetadataFactory(),


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ObjectMapper\Condition;

use Symfony\Component\ObjectMapper\Exception\InvalidArgumentException;

/**
 * @template T1 of object
 * @template T2 of object
 *
 * @implements ClassRuleConditionCallableInterface<T1, T2>
 */
final class ClassRule implements ClassRuleConditionC

ts = [],
    ) {
        if (!$this->sources && !$this->targets) {
            throw new InvalidArgumentException('A ClassRule needs a sources list and/or a targets list.');
        }
    }

    public function __invoke(mixed $value, object $source, ?objec

allableInterface
{
    /**
     * @param array<class-string>|null $sources
     * @param array<class-string>|null $targets
     */
    public function __construct(
        private array $sources = [],
        private array $targe


n Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ObjectMapper\Condition;

use Symfony\Component\ObjectMapper\Exception\InvalidArgumentException;

/**
 * @implements ClassRuleConditionCallableInterface<object, object>
 */
final class ClassRuleList implements ClassRuleConditionCallableInterface
{
    /**
     * @param non-empty-array<ClassRule|SourceClass|TargetCla

rivate array $rules)
    {
        if (!$this->rules) {
            throw new InvalidArgumentException('A ClassRuleList needs at least one rule.');
        }
    }

    public function __invoke(mixed $value, object $source, ?object $target): bool
    {

ss> $rules
     */
    public function __construct(p


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ObjectMapper\Tests\Fixtures\ServiceLoadedValue;

use Symfony\Component\ObjectMapper\Metadata\ObjectMapperMetadataFactoryInterface;
use Symfony\Component\ObjectMapper\TransformCallableInterface;

/**
 * @implements TransformCallableInterface<object,object>
 *

a)
    {
    }

    public function __invoke(mixed $value, object $source, ?object $target): mixed
    {
        $metadata = $this->metadata->create($value);

        if (1 !== \count($metadata)) {
            throw new \LogicException('Exactly one metadat

/
class ServiceLoadedValueTransformer implements TransformCallableInterface
{
    public function __construct(private readonly LoadedValueService $serviceLoadedValue, private readonly ObjectMapperMetadataFactoryInterface $metadat


*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ObjectMapper\Tests\Fixtures\MultipleTargetProperty;

use Symfony\Component\ObjectMapper\Attribute\Map;
use Symfony\Component\ObjectMapper\Condition\TargetClass;

#[Map(target: B::class)]
#[Map(target: C::class)]
class A
{
    #[Map(target: 'foo', transfo

  #[Map(target: 'bar')]
    public string $something = 'test';

    #[Map(target: 'otherFoo', transform: 'strtolower', if: new TargetClass([B::class, C::class]))]
    public string $somethingOther = 'TESTOTHER';

    public string $doesNotExistInTargetB =

rm: 'strtoupper', if: new TargetClass(B::class))]


 file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ObjectMapper\Tests\Fixtures\MapStruct;

use Symfony\Component\ObjectMapper\ObjectMapper;
use Symfony\Component\ObjectMapper\ObjectMapperInterface;

#[Map(source: Source::class, target: Target::class)]
class AToBMapper implements ObjectMapperInterface
{
    public

$objectMapper)
    {
    }

    #[Map(source: 'propertyA', target: 'propertyD')]
    #[Map(source: 'propertyB', if: false)]
    public function map(object $source, object|string|null $target = null): object
    {
        return $this->objectMapper->map($so

function __construct(private readonly ObjectMapper


 file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\JsonStreamer\DataModel\Read;

use Symfony\Component\TypeInfo\Type\BuiltinType;

/**
 * Represents a scalar in the data model graph representation.
 *
 * Scalars are leaves in the data model tree.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 *
 * @inte

NodeInterface
{
    public function __construct(
        public BuiltinType $type,
    ) {
    }

    public function getIdentifier(): string
    {
        return (string) $this->type;
    }

    public function getType(): BuiltinType
    {
        return

rnal
 */
final class ScalarNode implements DataModel


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\JsonStreamer\DataModel\Write;

use Symfony\Component\TypeInfo\Type\ObjectType;

/**
 * Represents an object in the data model graph representation.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 *
 * @internal
 */
final class ObjectNode implements DataModelNode

       private bool $mock = false,
    ) {
    }

    public static function createMock(string $accessor, ObjectType $type): self
    {
        return new self($accessor, $type, [], true);
    }

    public function withAccessor(string $accessor): self

Interface
{
    /**
     * @param array<string, DataModelNodeInterface> $properties
     */
    public function __construct(
        private string $accessor,
        private ObjectType $type,
        private array $properties,


hp

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ObjectMapper\Condition;

/**
 * @template T of object
 *
 * @implements ClassRuleConditionCallableInterface<object, object>
 */
final class TargetClass implements ClassRuleConditionCallableInterface
{
    /**
     * @var non-empty-array<class-string

assName) ? $className : [$className];
    }

    public function __invoke(mixed $value, object $source, ?object $target): bool
    {
        foreach ($this->targets as $validTarget) {
            if ($target instanceof $validTarget) {
                retur

>
     */
    private readonly array $targets;

    /**
     * @param class-string<T>|array<class-string<T>> $className
     */
    public function __construct(string|array $className)
    {
        $this->targets = \is_array($cl


appingWithClassTransformer;

use Symfony\Component\ObjectMapper\Attribute\Map;

#[Map(target: ParentTarget::class, transform: [ParentTarget::class, 'createFromSource'])]
class ParentSource
{
    public string $name = 'parent';

    public ChildWithClassTransformSource $childWithClassTransformer;

    #[Map(transform: [ParentTarget::class, 'childPropertyTransformer'])]
    public ChildWithoutClassTransformerSource $childWithoutClassTransformer;

    #[Map(transform: [ParentTarget::class, 'childBothTransforme

dWithBothTransformers;

    public function __construct()
    {
        $this->childWithClassTransformer = new ChildWithClassTransformSource();
        $this->childWithoutClassTransformer = new ChildWithoutClassTransformerSource();
        $this->childWith

r'])]
    public ChildWithClassTransformSource $chil


* This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ObjectMapper\Tests\Fixtures\MultipleSourceProperty;

use Symfony\Component\ObjectMapper\Attribute\Map;
use Symfony\Component\ObjectMapper\Condition\SourceClass;

#[Map(source: B::class)]
#[Map(source: C::class)]
class A
{
    #[Map(source: 'foo', transform:

[Map(source: 'bar', if: new SourceClass(C::class))]
    public string $something;

    #[Map(source: 'foo', transform: 'strtoupper', if: new SourceClass([B::class, C::class]))]
    public string $somethingOther;

    public string $doesNotExistInSourceB;
}

 'strtolower', if: new SourceClass(B::class))]
    #


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ObjectMapper\Attribute;

/**
 * Configures a class or a property to map to.
 *
 * @author Antoine Bluchet <soyuka@gmail.com>
 */
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_PROPERTY | \Attribute::IS_REPEATABLE)]
class Map
{
    /**
     * @par

                                               $target    The property or the class to map to
     * @param string|bool|callable(mixed, object, ?object): bool|null                                                  $if        A boolean, a service id or a cal

am string|class-string|null                                                                                $source    The property or the class to map from
     * @param string|class-string|null


n Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\JsonStreamer\DataModel\Read;

use Symfony\Component\TypeInfo\Type\CollectionType;

/**
 * Represents a collection in the data model graph representation.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 *
 * @internal
 */
final class CollectionNode implements DataModelNodeInterface
{
    public function __c

    private DataModelNodeInterface $item,
    ) {
    }

    public function getIdentifier(): string
    {
        return (string) $this->type;
    }

    public function getType(): CollectionType
    {
        return $this->type;
    }

    public functio

onstruct(
        private CollectionType $type,


ony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ObjectMapper\Tests\Fixtures;

use Symfony\Component\ObjectMapper\Attribute\Map;

#[Map(B::class)]
class A
{
    #[Map('bar')]
    public string $foo;

    public string $baz;

    public string $notinb;

    #[Map(transform: 'strtoupper')]
    public string $transform;

    #[Map(transform: [self::class, 'concatFn'])]
    public ?string $

 bool $nomap = false;

    public C $relation;

    public D $relationNotMapped;

    public function getConcat()
    {
        return 'should';
    }

    public static function concatFn($v, $object): string
    {
        return $v.$object->foo.$object->b

concat = null;

    #[Map(if: 'boolval')]
    public


Security\Csrf\CsrfTokenManagerInterface;
use Twig\Environment;

/**
 * Renders a form into HTML using a rendering engine.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
class FormRenderer implements FormRendererInterface
{
    public const CACHE_KEY_VAR = 'unique_block_prefix';

    private array $blockNameHierarchyMap = [];
    private array $hierarchyLevelMap = [];
    private array $variableStack = [];

    public function __construct(
        private FormRendererEngineInterface $engine,

ixed $themes, bool $useDefaultThemes = true): void
    {
        $this->engine->setTheme($view, $themes, $useDefaultThemes);
    }

    public function renderCsrfToken(string $tokenId): string
    {
        if (null === $this->csrfTokenManager) {

   private ?CsrfTokenManagerInterface $csrfTokenManager = null,
    ) {
    }

    public function getEngine(): FormRendererEngineInterface
    {
        return $this->engine;
    }

    public function setTheme(FormView $view, m


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form\Flow\Type;

use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\Flow\AbstractFlowType;
use Symfony\Component\Form\Flow\ButtonFlowInterface;
use Symfony\Component\Form\Flow\DataStorage\DataStorageInterface;
use Symfony\Component\Form\Flow\DataStorage\NullDataStorage;
use Symfony\Component\Form\Flow\FormFlowBuil

m\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\Exception\MissingOptionsException;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsRe

derInterface;
use Symfony\Component\Form\Flow\FormFlowInterface;
use Symfony\Component\Form\Flow\StepAccessor\PropertyPathStepAccessor;
use Symfony\Component\Form\Flow\StepAccessor\StepAccessorInterface;
use Symfony\Component\For


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form\Flow\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

/**
 * A navigator type that defines default buttons to interact with a form flow.
 *
 * @autho

ss);
        $builder->add('next', NextFlowType::class);
        $builder->add('finish', FinishFlowType::class);

        if ($options['with_reset']) {
            $builder->add('reset', ResetFlowType::class);
        }
    }

    public function configure

r Yonel Ceruto <open@yceruto.dev>
 */
class NavigatorFlowType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder->add('previous', PreviousFlowType::cla


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form\Flow\Type;

use Symfony\Component\Form\Flow\AbstractButtonFlowType;
use Symfony\Component\Form\Flow\ButtonFlowInterface;
use Symfony\Component\Form\Flow\FormFlowCursor;
use Symfony\Component\Form\Flow\FormFlowInterface;
use Symfony\Component\Form\

uilder->setAttribute('action', 'next');
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'handler' => static fn (mixed $data, ButtonFlowInterface $button, FormFlowInterface $flo

FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class NextFlowType extends AbstractButtonFlowType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $b


  $builder->setAttribute('action', 'previous');
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'handler' => static fn (mixed $data, ButtonFlowInterface $button, FormFlowInterf

FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class PreviousFlowType extends AbstractButtonFlowType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {


?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form\Flow\Type;

use Symfony\Component\Form\Flow\AbstractButtonFlowType;
use Symfony\Component\Form\Flow\ButtonFlowInterface;
use Symfony\Component\Form\Flow\FormFlowInterface;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component

   }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'handler' => static fn (mixed $data, ButtonFlowInterface $button, FormFlowInterface $flow) => $flow->reset(),
            'clear_

\OptionsResolver\OptionsResolver;

class ResetFlowType extends AbstractButtonFlowType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder->setAttribute('action', 'reset');


 file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form\Flow\DataStorage;

/**
 * @author Yonel Ceruto <open@yceruto.dev>
 */
class InMemoryDataStorage implements DataStorageInterface
{
    private array $memory = [];

    public function __construct(
        private readonly string $key,
    ) {
    }

    publi

    $this->memory[$this->key] = $data;
    }

    public function load(object|array|null $default = null): object|array|null
    {
        return $this->memory[$this->key] ?? $default;
    }

    public function clear(): void
    {
        unset($this->mem

c function save(object|array $data): void
    {


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form\Flow\DataStorage;

use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\VarExporter\DeepCloner;

/**
 * @author Yonel Ceruto <open@yceruto.dev>
 */
class SessionDataStorage implements DataStorageInterface
{
    public function

>requestStack->getSession()->set($this->key, $data->isStaticValue() ? $data->clone() : $data);
    }

    public function load(object|array|null $default = null): object|array|null
    {
        if (null === $data = $this->requestStack->getSession()->get($

__construct(
        private readonly string $key,
        private readonly RequestStack $requestStack,
    ) {
    }

    public function save(object|array $data): void
    {
        $data = new DeepCloner($data);
        $this-


is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form\Extension\DataCollector;

use Symfony\Component\Form\AbstractExtension;

/**
 * Extension for collecting data of the forms on a page.
 *
 * @author Robert Schönthal <robert.schoenthal@gmail.com>
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
class DataColl

c function __construct(
        private FormDataCollectorInterface $dataCollector,
    ) {
    }

    protected function loadTypeExtensions(): array
    {
        return [
            new Type\DataCollectorTypeExtension($this->dataCollector),
        ];

ectorExtension extends AbstractExtension
{
    publi


ion\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
use Symfony\Component\Validator\ConstraintViolationInterface;
use Symfony\Component\VarDumper\Caster\Caster;
use Symfony\Component\VarDumper\Caster\ClassStub;
use Symfony\Component\VarDumper\Caster\StubCaster;
use Symfony\Component\VarDumper\Cloner\Data;
use Symfony\Component\VarDumper\Cloner\Stub;

/**
 * Data collector for {@link FormInterface} instances.
 *
 * @author Robert Schönthal

 {@link FormInterface} instance.
     *
     * Uses the hashes of the forms as keys. This is preferable over using
     * {@link \SplObjectStorage}, because in this way no references are kept
     * to the {@link FormInterface} instances.
     */
    priva

 <robert.schoenthal@gmail.com>
 * @author Bernhard Schussek <bschussek@gmail.com>
 *
 * @final
 */
class FormDataCollector extends DataCollector implements FormDataCollectorInterface
{
    /**
     * Stores the collected data per


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form\Extension\DataCollector;

use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface;
use Symfony\Component\VarDumper\Cloner\Data;

/**
 * Collects and structures information about forms.
 *
 * @author

figuration(FormInterface $form): void;

    /**
     * Stores the default data of the given form and its children.
     */
    public function collectDefaultData(FormInterface $form): void;

    /**
     * Stores the submitted data of the given form and it

Bernhard Schussek <bschussek@gmail.com>
 */
interface FormDataCollectorInterface extends DataCollectorInterface
{
    /**
     * Stores configuration data of the given form and its children.
     */
    public function collectCon


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form\Extension\DataCollector;

use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\Validator\ConstraintViolationInterface;

/**
 * Default implementation of {@link FormDataExtractorInterface}.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
class FormDataExtractor implements FormDataExtra

tConfig()->getType()->getInnerType()::class,
            'synchronized' => $form->isSynchronized(),
            'passed_options' => [],
            'resolved_options' => [],
        ];

        foreach ($form->getConfig()->getAttribute('data_collector/pass

ctorInterface
{
    public function extractConfiguration(FormInterface $form): array
    {
        $data = [
            'id' => $this->buildId($form),
            'name' => $form->getName(),
            'type_class' => $form->ge


?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form\Extension\DataCollector;

use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;

/**
 * Extracts arrays of information out of forms.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
interface FormDataExtracto

 extractDefaultData(FormInterface $form): array;

    /**
     * Extracts the submitted data of a form.
     */
    public function extractSubmittedData(FormInterface $form): array;

    /**
     * Extracts the view variables of a form.
     */
    public

rInterface
{
    /**
     * Extracts the configuration data of a form.
     */
    public function extractConfiguration(FormInterface $form): array;

    /**
     * Extracts the default data of a form.
     */
    public function


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form\Extension\DataCollector\Proxy;

use Symfony\Component\Form\Extension\DataCollector\FormDataCollectorInterface;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormTypeInterface;
use Symfony\Component\Form\FormView;
use Symfo

om>
 */
class ResolvedTypeDataCollectorProxy implements ResolvedFormTypeInterface
{
    public function __construct(
        private ResolvedFormTypeInterface $proxiedType,
        private FormDataCollectorInterface $dataCollector,
    ) {
    }

    publi

ny\Component\Form\ResolvedFormTypeInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

/**
 * Proxy that invokes a data collector when creating a form and its view.
 *
 * @author Bernhard Schussek <bschussek@gmail.c


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form\Extension\DataCollector\Proxy;

use Symfony\Component\Form\Extension\DataCollector\FormDataCollectorInterface;
use Symfony\Component\Form\FormTypeInterface;
use Symfony\Component\Form\ResolvedFormTypeFactoryInterface;
use Symfony\Component\Form\Resolved

 ResolvedFormTypeFactoryInterface
{
    public function __construct(
        private ResolvedFormTypeFactoryInterface $proxiedFactory,
        private FormDataCollectorInterface $dataCollector,
    ) {
    }

    public function createResolvedType(FormType

FormTypeInterface;

/**
 * Proxy that wraps resolved types into {@link ResolvedTypeDataCollectorProxy}
 * instances.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
class ResolvedTypeFactoryDataCollectorProxy implements


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form\Extension\DataCollector\Type;

use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\Extension\DataCollector\EventListener\DataCollectorListener;
use Symfony\Component\Form\

>
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
class DataCollectorTypeExtension extends AbstractTypeExtension
{
    private DataCollectorListener $listener;

    public function __construct(FormDataCollectorInterface $dataCollector)
    {

Extension\DataCollector\FormDataCollectorInterface;
use Symfony\Component\Form\FormBuilderInterface;

/**
 * Type extension for collecting data of a form with this type.
 *
 * @author Robert Schönthal <robert.schoenthal@gmail.com


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form\Extension\DataCollector\EventListener;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\Extension\DataCollector\FormDataCollectorInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;

/**
 * Listener that invokes a

   public function __construct(
        private FormDataCollectorInterface $dataCollector,
    ) {
    }

    public static function getSubscribedEvents(): array
    {
        return [
            // Low priority in order to be called as late as possible

data collector for the {@link FormEvents::POST_SET_DATA}
 * and {@link FormEvents::POST_SUBMIT} events.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
class DataCollectorListener implements EventSubscriberInterface
{