<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd">

    <parameters>
        <parameter key="serializer.mapping.cache.file">%kernel.cache_dir%/serialization.php</parameter>
    </parameters>

    <services>
        <defaults public="false" />

        <service id="serializer" class="Symfony\Component\Serializer\Serializer" public="true">
            <argument type="collection" />
            <argument type="collection" />
        </service>
        <service id="Symfony\Component\Serializer\SerializerInterface" alias="serializer" />
        <service id="Symfony\Component\Serializer\Normalizer\NormalizerInterface" alias="serializer" />
        <service id="Symfony\Component\Serializer\Normalizer\DenormalizerInterface" alias="serializer" />
        <service id="Symfony\Component\Serializer\Encoder\EncoderInterface" alias="serializer" />
        <service id="Symfony\Component\Serializer\Encoder\DecoderInterface" alias="serializer" />

        <service id="serializer.property_accessor" alias="property_accessor" />

        <!-- Discriminator Map -->
        <service id="serializer.mapping.class_discriminator_resolver" class="Symfony\Component\Serializer\Mapping\ClassDiscriminatorFromClassMetadata">
            <argument type="service" id="serializer.mapping.class_metadata_factory" />
        </service>
        <service id="Symfony\Component\Serializer\Mapping\ClassDiscriminatorResolverInterface" alias="serializer.mapping.class_discriminator_resolver" />

        <!-- Normalizer -->
        <service id="serializer.normalizer.constraint_violation_list" class="Symfony\Component\Serializer\Normalizer\ConstraintViolationListNormalizer">
            <argument type="collection" />
            <argument type="service" id="serializer.name_converter.metadata_aware" />
            <!-- Run before serializer.normalizer.object -->
            <tag name="serializer.normalizer" priority="-915" />
        </service>

        <service id="serializer.normalizer.datetimezone" class="Symfony\Component\Serializer\Normalizer\DateTimeZoneNormalizer">
            <!-- Run before serializer.normalizer.object -->
            <tag name="serializer.normalizer" priority="-915" />
        </service>

        <service id="serializer.normalizer.dateinterval" class="Symfony\Component\Serializer\Normalizer\DateIntervalNormalizer">
            <!-- Run before serializer.normalizer.object -->
            <tag name="serializer.normalizer" priority="-915" />
        </service>

        <service id="serializer.normalizer.data_uri" class="Symfony\Component\Serializer\Normalizer\DataUriNormalizer">
            <argument type="service" id="mime_types" on-invalid="null" />
            <!-- Run before serializer.normalizer.object -->
            <tag name="serializer.normalizer" priority="-920" />
        </service>

        <service id="serializer.normalizer.datetime" class="Symfony\Component\Serializer\Normalizer\DateTimeNormalizer">
            <!-- Run before serializer.normalizer.object -->
            <tag name="serializer.normalizer" priority="-910" />
        </service>

        <service id="serializer.normalizer.json_serializable" class="Symfony\Component\Serializer\Normalizer\JsonSerializableNormalizer">
            <!-- Run before serializer.normalizer.object -->
            <tag name="serializer.normalizer" priority="-950" />
        </service>

        <service id="serializer.normalizer.problem" class="Symfony\Component\Serializer\Normalizer\ProblemNormalizer">
            <argument>%kernel.debug%</argument>
            <!-- Run before serializer.normalizer.object -->
            <tag name="serializer.normalizer" priority="-890" />
        </service>

        <service id="serializer.normalizer.object" class="Symfony\Component\Serializer\Normalizer\ObjectNormalizer">
            <argument type="service" id="serializer.mapping.class_metadata_factory" />
            <argument type="service" id="serializer.name_converter.metadata_aware" />
            <argument type="service" id="serializer.property_accessor" />
            <argument type="service" id="property_info" on-invalid="ignore" />
            <argument type="service" id="serializer.mapping.class_discriminator_resolver" on-invalid="ignore" />
            <argument>null</argument>
            <argument type="collection" />

            <!-- Run after all custom normalizers -->
            <tag name="serializer.normalizer" priority="-1000" />
        </service>
        <service id="Symfony\Component\Serializer\Normalizer\ObjectNormalizer" alias="serializer.normalizer.object" />

        <service id="serializer.denormalizer.array" class="Symfony\Component\Serializer\Normalizer\ArrayDenormalizer">
            <!-- Run before the object normalizer -->
            <tag name="serializer.normalizer" priority="-990" />
        </service>

        <!-- Loader -->
        <service id="serializer.mapping.chain_loader" class="Symfony\Component\Serializer\Mapping\Loader\LoaderChain">
            <argument type="collection" />
        </service>

        <!-- Class Metadata Factory -->
        <service id="serializer.mapping.class_metadata_factory" class="Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory">
            <argument type="service" id="serializer.mapping.chain_loader" />
        </service>

        <service id="Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface" alias="serializer.mapping.class_metadata_factory" />

        <!-- Cache -->
        <service id="serializer.mapping.cache_warmer" class="Symfony\Bundle\FrameworkBundle\CacheWarmer\SerializerCacheWarmer">
            <argument type="collection" /><!-- Loaders injected by the extension -->
            <argument>%serializer.mapping.cache.file%</argument>
            <tag name="kernel.cache_warmer" />
        </service>

        <service id="serializer.mapping.cache.symfony" class="Psr\Cache\CacheItemPoolInterface">
            <factory class="Symfony\Component\Cache\Adapter\PhpArrayAdapter" method="create" />
            <argument>%serializer.mapping.cache.file%</argument>
            <argument type="service" id="cache.serializer" />
        </service>

        <service id="serializer.mapping.cache_class_metadata_factory" decorates="serializer.mapping.class_metadata_factory" class="Symfony\Component\Serializer\Mapping\Factory\CacheClassMetadataFactory">
            <argument type="service" id="serializer.mapping.cache_class_metadata_factory.inner" />
            <argument type="service" id="serializer.mapping.cache.symfony" />
        </service>

        <!-- Encoders -->
        <service id="serializer.encoder.xml" class="Symfony\Component\Serializer\Encoder\XmlEncoder">
            <tag name="serializer.encoder" />
        </service>

        <service id="serializer.encoder.json" class="Symfony\Component\Serializer\Encoder\JsonEncoder">
            <tag name="serializer.encoder" />
        </service>

        <service id="serializer.encoder.yaml" class="Symfony\Component\Serializer\Encoder\YamlEncoder">
            <tag name="serializer.encoder" />
        </service>

        <service id="serializer.encoder.csv" class="Symfony\Component\Serializer\Encoder\CsvEncoder">
            <tag name="serializer.encoder" />
        </service>

        <!-- Name converter -->
        <service id="serializer.name_converter.camel_case_to_snake_case" class="Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter" />

        <service id="serializer.name_converter.metadata_aware" class="Symfony\Component\Serializer\NameConverter\MetadataAwareNameConverter" >
            <argument type="service" id="serializer.mapping.class_metadata_factory"/>
        </service>

        <!-- PropertyInfo extractor -->
        <service id="property_info.serializer_extractor" class="Symfony\Component\PropertyInfo\Extractor\SerializerExtractor">
            <argument type="service" id="serializer.mapping.class_metadata_factory" />

            <tag name="property_info.list_extractor" priority="-999" />
        </service>

        <!-- ErrorRenderer integration -->
        <service id="error_renderer" alias="error_renderer.serializer" />
        <service id="error_renderer.serializer" alias="error_handler.error_renderer.serializer" />
        <service id="error_handler.error_renderer.serializer" class="Symfony\Component\ErrorHandler\ErrorRenderer\SerializerErrorRenderer">
            <argument type="service" id="serializer" />
            <argument type="service">
                <service>
                    <factory class="Symfony\Component\ErrorHandler\ErrorRenderer\SerializerErrorRenderer" method="getPreferredFormat" />
                    <argument type="service" id="request_stack" />
                </service>
            </argument>
            <argument type="service" id="error_renderer.html" />
            <argument type="service">
                <service>
                    <factory class="Symfony\Component\ErrorHandler\ErrorRenderer\HtmlErrorRenderer" method="isDebug" />
                    <argument type="service" id="request_stack" />
                    <argument>%kernel.debug%</argument>
                </service>
            </argument>
        </service>
    </services>
</container>
