<?xml version="1.0"?>
<!--
 * Copyright (c)2010 Elsevier, Inc.

 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * The use of the Apache License does not indicate that this project is
 * affiliated with the Apache Software Foundation.
 -->
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://www.xqdoc.org/1.0"
            xmlns="http://www.xqdoc.org/1.0"
            elementFormDefault="qualified"
            attributeFormDefault="unqualified">

  <!-- Simple type for defining the uris associated
       with things such as library modules associated
       with functions, variables, imports, etc. -->
  <xsd:simpleType name="uri">
    <xsd:restriction base="xsd:string"/>
  </xsd:simpleType>

  <!-- Simple type for defining the type associated
     with things such as global variables, function
     parameters, and function return types etc. -->
  <xsd:complexType name="type">
    <xsd:simpleContent>
      <xsd:extension base="xsd:string">
        <xsd:attribute name="occurrence" type="occurrence" use="optional"/>
      </xsd:extension>
    </xsd:simpleContent>
  </xsd:complexType>

  <!-- Complex type for function parameters -->
  <xsd:complexType name="parameters">
    <xsd:sequence>
      <xsd:element name="parameter" type="parameter" maxOccurs="unbounded"/>
    </xsd:sequence>
  </xsd:complexType>

  <!-- Complex type for an individual function parameter -->
  <xsd:complexType name="parameter">
    <xsd:sequence>
      <xsd:element name="name" type="name" minOccurs="0"/>
      <xsd:element name="type" type="type" minOccurs="0"/>
    </xsd:sequence>
  </xsd:complexType>

  <!-- Complex type for the return value from a function -->
  <xsd:complexType name="return">
    <xsd:sequence>
      <xsd:element name="type" type="type" minOccurs="0"/>
    </xsd:sequence>
  </xsd:complexType>

  <!-- Simple type used for definging the number of occurrences for a global variable, function parameter
    or function return type -->
  <xsd:simpleType name="occurrence">
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="?"/>
      <xsd:enumeration value="*"/>
      <xsd:enumeration value="+"/>
    </xsd:restriction>
  </xsd:simpleType>

  <!-- Simple type for defining the names associated
       with things such as functions, paramters, module name, etc. -->
  <xsd:simpleType name="name">
    <xsd:restriction base="xsd:string"/>
  </xsd:simpleType>

  <!-- Complex type used for defining the functions
       invoked from within a particular function.  -->
  <xsd:complexType name="invoked">
    <xsd:sequence>
      <xsd:element name="uri" type="uri"/>
      <xsd:element name="name" type="name"/>
    </xsd:sequence>
    <xsd:attribute name="arity" type="xsd:integer" use="optional"/>
  </xsd:complexType>

  <!-- Complex type used for defining a custom comment type.
     The tag attribute allows the differentiation of the custom
     comment types. If the custom comment is @example, then the
       value in the 'tag' attribute would be 'example'. -->
  <xsd:complexType name="custom">
    <xsd:complexContent>
      <xsd:extension base="mixed-text">
        <xsd:attribute name="tag" type="xsd:string" use="required"/>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>


  <!-- Complex type used for defining the comments associated
       with a library module, imports, variables, or functions.
       The follow xqdoc 'directives' map to the equivalent
       elements defined below ... with the exception of description
       where there is no directive.

       @author ...... author
       @version ..... version
       @param ....... param
       @return ...... return
       @error ....... error
       @deprecated .. deprecated
       @see ......... see
       @since ....... since
       @custom....... custom -->
  <xsd:complexType name="comment">
    <xsd:sequence>
      <xsd:element name="description" type="mixed-text" minOccurs="0"/>
      <xsd:element name="author" type="mixed-text" minOccurs="0" maxOccurs="unbounded"/>
      <xsd:element name="version" type="mixed-text" minOccurs="0"/>
      <xsd:element name="param" type="mixed-text" minOccurs="0" maxOccurs="unbounded"/>
      <xsd:element name="return" type="mixed-text" minOccurs="0"/>
      <xsd:element name="error" type="mixed-text" minOccurs="0" maxOccurs="unbounded"/>
      <xsd:element name="deprecated" type="mixed-text" minOccurs="0"/>
      <xsd:element name="see" type="mixed-text" minOccurs="0" maxOccurs="unbounded"/>
      <xsd:element name="since" type="mixed-text" minOccurs="0" maxOccurs="unbounded"/>
      <xsd:element name="custom" type="custom" minOccurs="0" maxOccurs="unbounded"/>      
    </xsd:sequence>
  </xsd:complexType>

  <!-- Complex type used for comment text to allow the inclusion
       of embedded HTML markup within comments. -->
  <xsd:complexType name="mixed-text"  mixed="true">
    <xsd:sequence>
      <xsd:any minOccurs="0" maxOccurs="unbounded" processContents="skip"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="annotation">
     <xsd:attribute name="prefix" type="xsd:string" use="optional"/>
     <xsd:attribute name="namespace" type="xsd:string" use="optional"/>
     <xsd:attribute name="localname" type="xsd:string" use="optional"/>
     <xsd:attribute name="value" type="xsd:string" use="optional"/>
  </xsd:complexType>

  <xsd:complexType name="annotations">
    <xsd:sequence>
      <xsd:element name="annotation" type="annotation" minOccurs="1" maxOccurs="unbounded"/>      
    </xsd:sequence>
  </xsd:complexType>

  <!-- Complex type used for defining information about the package
      version (and date) used to generate the internal xqdoc XML.
     Date should be the date when the XML xqdoc file is genearted.
     Version should either be the version of the XQDoc conversion package
     used to generate the XML or 'n/a' if the XML is generated from
     some other mechanism (i.e. scripts from XHTML for MarkLogic). -->
  <xsd:complexType name="control">
    <xsd:sequence>
      <xsd:element name="date" type="xsd:string"/>
      <xsd:element name="version">
        <xsd:simpleType>
          <xsd:restriction base="xsd:string">
            <xsd:enumeration value="1.0"/>
            <xsd:enumeration value="N/A"/>
          </xsd:restriction>
        </xsd:simpleType>
      </xsd:element>
    </xsd:sequence>
  </xsd:complexType>

  <!-- Complex type used for defining the module URI and any
     high-level comments associated with the module. -->
  <xsd:complexType name="module">
    <xsd:sequence>
      <xsd:element name="uri" type="uri"/>
      <xsd:element name="name" type="name" minOccurs="0"/>
      <xsd:element name="comment" type="comment" minOccurs="0"/>
      <xsd:element name="body" type="xsd:string" minOccurs="0"/>
      <xsd:element name="custom" type="custom" minOccurs="0" />
    </xsd:sequence>
    <xsd:attribute name="type" use="required">
      <xsd:simpleType>
            <xsd:restriction base="xsd:string">
                <xsd:enumeration value="main"/>
                <xsd:enumeration value="library"/>
              </xsd:restriction>
        </xsd:simpleType>
    </xsd:attribute>
  </xsd:complexType>

  <!-- Complex type used for defining the variable names defined within
     the library module and any comments associated with the variables. -->
  <xsd:complexType name="variables">
    <xsd:sequence>
      <xsd:element name="variable" minOccurs="0" maxOccurs="unbounded">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="uri" type="uri"/>
            <xsd:element name="type" type="type" minOccurs="0"/>
            <xsd:element name="comment" type="comment" minOccurs="0"/>
            <xsd:choice minOccurs="0" maxOccurs="unbounded">
              <xsd:element name="invoked" type="invoked" minOccurs="0" maxOccurs="unbounded"/>
              <xsd:element name="ref-variable" type="invoked" minOccurs="0" maxOccurs="unbounded"/>
            </xsd:choice>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
    </xsd:sequence>
  </xsd:complexType>

  <!-- Complex type used for defining the collection names defined within
     the library module and any comments associated with the collections. -->
  <xsd:complexType name="collections">
    <xsd:sequence>
      <xsd:element name="collection" minOccurs="0" maxOccurs="unbounded">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="name" type="name"/>
            <xsd:element name="type" type="type" minOccurs="0"/>
            <xsd:element name="comment" type="comment" minOccurs="0"/>
            <xsd:element name="annotations" type="annotations" minOccurs="0" maxOccurs="1"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
    </xsd:sequence>
  </xsd:complexType>

  <!-- Complex type used for defining the index names defined within
     the library module and any comments associated with the indexes. -->
  <xsd:complexType name="indexes">
    <xsd:sequence>
      <xsd:element name="index" minOccurs="0" maxOccurs="unbounded">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="name" type="name"/>
            <xsd:element name="source" minOccurs="0" maxOccurs="unbounded">
              <xsd:complexType>
                <xsd:sequence>
                  <xsd:element name="uri" type="uri"/>
                  <xsd:element name="name" type="name"/>
                </xsd:sequence>
              </xsd:complexType>
            </xsd:element>
            <xsd:element name="comment" type="comment" minOccurs="0"/>
            <xsd:element name="annotations" type="annotations" minOccurs="0" maxOccurs="1"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
    </xsd:sequence>
  </xsd:complexType>

  <!-- Complex type used for defining the imported modules within the
     the library module and any comments associated with the imports. -->
  <xsd:complexType name="imports">
    <xsd:sequence>
      <xsd:element name="import" minOccurs="0" maxOccurs="unbounded">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="uri" type="uri"/>
            <xsd:element name="comment" type="comment" minOccurs="0"/>
          </xsd:sequence>
          <xsd:attribute name="type" use="optional">
            <xsd:simpleType>
              <xsd:restriction base="xsd:string">
                <xsd:enumeration value="library"/>
                <xsd:enumeration value="schema"/>
              </xsd:restriction>
            </xsd:simpleType>
          </xsd:attribute>
        </xsd:complexType>
      </xsd:element>
    </xsd:sequence>
  </xsd:complexType>

  <!-- Complex type used for defining the functions contained within the
     the library module and any comments associated with the functions.
     Any 'invoked' functions associated with this function should also
     be defined.  -->
  <xsd:complexType name="functions">
    <xsd:sequence>
      <xsd:element name="function" minOccurs="0" maxOccurs="unbounded">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="comment" type="comment" minOccurs="0"/>
            <xsd:element name="name" type="name"/>
            <xsd:element name="annotations" type="annotations" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="signature" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
            <xsd:element name="parameters" type="parameters" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="return" type="parameter" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="custom" type="custom" minOccurs="0" maxOccurs="unbounded"/>
            <xsd:choice minOccurs="0" maxOccurs="unbounded">
              <xsd:element name="invoked" type="invoked" minOccurs="0" maxOccurs="unbounded"/>
              <xsd:element name="ref-variable" type="invoked" minOccurs="0" maxOccurs="unbounded"/>
            </xsd:choice>
            <xsd:element name="body" type="xsd:string" minOccurs="0"/>
          </xsd:sequence>
          <xsd:attribute name="arity" type="xsd:integer" use="optional"/>
        </xsd:complexType>
      </xsd:element>
    </xsd:sequence>
  </xsd:complexType>

  <!-- Complex type used for defining the global root element of xqdoc.
       There should be '1' xqdoc xml file for each library module. -->
  <xsd:element name="xqdoc">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="control" type="control"/>
        <xsd:element name="module" type="module"/>
        <xsd:element name="imports" type="imports" minOccurs="0"/>
        <xsd:element name="variables" type="variables" minOccurs="0"/>
        <xsd:element name="collections" type="collections" minOccurs="0"/>
        <xsd:element name="indexes" type="indexes" minOccurs="0"/>
        <xsd:element name="functions" type="functions" minOccurs="0"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>
