<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
 * Schema for DI configuration
 *
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:redefine schemaLocation="urn:magento:framework:Data/etc/argument/types.xsd">
        <xs:complexType name="string">
            <xs:complexContent>
                <xs:extension base="argumentType">
                    <xs:attribute name="translatable" use="optional" type="xs:boolean" />
                </xs:extension>
            </xs:complexContent>
        </xs:complexType>
        <xs:complexType name="argumentType" abstract="true" mixed="false">
            <xs:complexContent>
                <xs:extension base="argumentType" />
            </xs:complexContent>
        </xs:complexType>

        <xs:complexType name="object">
            <xs:complexContent>
                <xs:extension base="object">
                    <xs:attribute name="shared" use="optional" type="xs:boolean"/>
                    <xs:attribute name="sortOrder" use="optional" type="xs:integer"/>
                </xs:extension>
            </xs:complexContent>
        </xs:complexType>
    </xs:redefine>

    <xs:simpleType name="phpClassName">
        <xs:annotation>
            <xs:documentation>
                A string that matches a Fully Qualified Class Name from PHP, especially not starting
                with a backslash as this is an invalid character to start a class name with but a
                somewhat common mistake so this simple type can be used to validate against it
                already
            </xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:string">
            <xs:pattern value="(\\?[a-zA-Z_&#x7f;-&#xff;][a-zA-Z0-9_&#x7f;-&#xff;]*)(\\[a-zA-Z_&#x7f;-&#xff;][a-zA-Z0-9_&#x7f;-&#xff;]*)*"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:complexType name="init_parameter">
        <xs:complexContent>
            <xs:extension base="argumentType" />
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="const">
        <xs:complexContent>
            <xs:extension base="argumentType" />
        </xs:complexContent>
    </xs:complexType>

    <xs:element name="config">
        <xs:complexType>
            <xs:choice maxOccurs="unbounded">
                <xs:element name="preference" type="preferenceType" minOccurs="0" maxOccurs="unbounded" />
                <xs:element name="type" type="typeType" minOccurs="0" maxOccurs="unbounded">
                    <xs:unique name="uniqueTypeParam">
                        <xs:annotation>
                            <xs:documentation>
                                Param name should be unique in scope of type
                            </xs:documentation>
                        </xs:annotation>
                        <xs:selector xpath="param" />
                        <xs:field xpath="@name" />
                    </xs:unique>
                </xs:element>
                <xs:element name="virtualType" type="virtualTypeType" minOccurs="0" maxOccurs="unbounded">
                    <xs:unique name="uniqueVirtualTypeParam">
                        <xs:annotation>
                            <xs:documentation>
                                Param name should be unique in scope of virtual type
                            </xs:documentation>
                        </xs:annotation>
                        <xs:selector xpath="param" />
                        <xs:field xpath="@name" />
                    </xs:unique>
                </xs:element>
            </xs:choice>
        </xs:complexType>

        <xs:unique name="uniquePreference">
            <xs:annotation>
                <xs:documentation>
                    Preference for each class should be unique in scope of file
                </xs:documentation>
            </xs:annotation>
            <xs:selector xpath="preference" />
            <xs:field xpath="@for" />
        </xs:unique>
        <xs:unique name="uniqueType">
            <xs:annotation>
                <xs:documentation>
                    Type name should be unique in scope of file
                </xs:documentation>
            </xs:annotation>
            <xs:selector xpath="type" />
            <xs:field xpath="@name" />
        </xs:unique>
        <xs:unique name="uniqueVirtualType">
            <xs:annotation>
                <xs:documentation>
                    Virtual type name should be unique in scope of file
                </xs:documentation>
            </xs:annotation>
            <xs:selector xpath="virtualType" />
            <xs:field xpath="@name" />
        </xs:unique>
    </xs:element>

    <xs:complexType name="preferenceType">
        <xs:annotation>
            <xs:documentation>
                Preference help Object Manager to choose class for corresponding interface
            </xs:documentation>
        </xs:annotation>
        <xs:attribute name="for" type="phpClassName" use="required"/>
        <xs:attribute name="type" type="phpClassName" use="required" />
    </xs:complexType>

    <xs:complexType name="typeType">
        <xs:annotation>
            <xs:documentation>
                With 'type' tag you can point parameters and plugins for certain class
            </xs:documentation>
        </xs:annotation>
        <xs:choice maxOccurs="unbounded">
            <xs:element name="arguments" type="argumentsType" minOccurs="0" maxOccurs="1">
                <xs:key name="argumentName">
                    <xs:selector xpath="argument"></xs:selector>
                    <xs:field xpath="@name"></xs:field>
                </xs:key>
            </xs:element>
            <xs:element name="plugin" type="pluginType" minOccurs="0" maxOccurs="unbounded" />
        </xs:choice>
        <xs:attribute name="name" type="phpClassName" use="required" />
        <xs:attribute name="shared" type="xs:boolean" use="optional" />
    </xs:complexType>

    <xs:complexType name="virtualTypeType">
        <xs:complexContent>
            <xs:extension base="typeType">
                <xs:annotation>
                    <xs:documentation>
                        With 'virtualType' tag you can point parameters and plugins for autogenerated class
                    </xs:documentation>
                </xs:annotation>
                <xs:attribute name="type" type="phpClassName" use="optional" />
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="pluginType">
        <xs:attribute name="name" type="xs:string" use="required" />
        <xs:attribute name="type" type="phpClassName" use="optional" />
        <xs:attribute name="disabled" type="xs:boolean" use="optional" />
        <xs:attribute name="sortOrder" type="xs:int" use="optional" />
    </xs:complexType>
</xs:schema>
