<?xml version="1.0" encoding="UTF-8"?>
<!--
     Open Document Format for Office Applications (OpenDocument) Version 1.4
     OASIS Standard
     11 March 2024
     Copyright (c) OASIS Open 2024. All Rights Reserved.
     Source: https://docs.oasis-open.org/office/OpenDocument/v1.4/csd01/schemas/
     Latest stage of specification: https://docs.oasis-open.org/office/OpenDocument/v1.4/OpenDocument-v1.4-part1-introduction.html
     TC IPR Statement: https://www.oasis-open.org/committees/office/ipr.php

        Open Document Format for Office Applications (OpenDocument) Version 1.4
        Manifest Relax-NG Schema
        OpenDocument-v1.4-manifest-schema.rng
-->
<!-- https://issues.oasis-open.org/browse/OFFICE-2153 -->

<rng:grammar xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0"
xmlns:rng="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
  <rng:start>
    <rng:choice>
      <rng:ref name="manifest"/>
    </rng:choice>
  </rng:start>
  <rng:define name="algorithm">
    <rng:element name="manifest:algorithm">
      <rng:ref name="algorithm-attlist"/>
      <rng:ref name="anyElements"/>
    </rng:element>
  </rng:define>
  <rng:define name="algorithm-attlist">
    <rng:interleave>
      <rng:attribute name="manifest:algorithm-name">
        <rng:choice>
          <rng:value>Blowfish CFB</rng:value>
          <rng:ref name="anyURI"/>
        </rng:choice>
      </rng:attribute>
      <rng:attribute name="manifest:initialisation-vector">
        <rng:ref name="base64Binary"/>
      </rng:attribute>
    </rng:interleave>
  </rng:define>
  <rng:define name="anyAttListOrElements">
    <rng:zeroOrMore>
      <rng:attribute>
        <rng:anyName/>
        <rng:text/>
      </rng:attribute>
    </rng:zeroOrMore>
    <rng:ref name="anyElements"/>
  </rng:define>
  <rng:define name="anyElements">
    <rng:zeroOrMore>
      <rng:element>
        <rng:anyName/>
        <rng:mixed>
          <rng:ref name="anyAttListOrElements"/>
        </rng:mixed>
      </rng:element>
    </rng:zeroOrMore>
  </rng:define>
  <rng:define name="anyURI">
    <rng:data type="anyURI"/>
  </rng:define>
  <rng:define name="base64Binary">
    <rng:data type="base64Binary"/>
  </rng:define>
  <rng:define name="encrypted-key">
    <rng:element name="manifest:encrypted-key">
      <rng:optional>
        <rng:element name="manifest:encryption-method">
          <rng:attribute name="manifest:PGPAlgorithm">
            <rng:ref name="anyURI"/>
          </rng:attribute>
        </rng:element>
      </rng:optional>
      <rng:element name="manifest:keyinfo">
        <rng:element name="manifest:PGPData">
          <rng:element name="manifest:PGPKeyID">
            <rng:ref name="base64Binary"/>
          </rng:element>
          <rng:optional>
            <rng:element name="manifest:PGPKeyPacket">
              <rng:ref name="base64Binary"/>
            </rng:element>
          </rng:optional>
        </rng:element>
      </rng:element>
      <rng:element name="manifest:CipherData">
        <rng:element name="manifest:CipherValue">
          <rng:ref name="base64Binary"/>
        </rng:element>
      </rng:element>
    </rng:element>
  </rng:define>
  <rng:define name="encryption-data">
    <rng:element name="manifest:encryption-data">
      <rng:ref name="encryption-data-attlist"/>
      <rng:ref name="algorithm"/>
      <rng:optional>
        <rng:ref name="start-key-generation"/>
      </rng:optional>
      <rng:ref name="key-derivation"/>
    </rng:element>
  </rng:define>
  <rng:define name="encryption-data-attlist">
    <rng:optional>
      <rng:interleave>
        <rng:attribute name="manifest:checksum-type">
          <rng:choice>
            <rng:value>SHA1/1K</rng:value>
            <rng:ref name="anyURI"/>
         </rng:choice>
        </rng:attribute>
        <rng:attribute name="manifest:checksum">
          <rng:ref name="base64Binary"/>
        </rng:attribute>
      </rng:interleave>
    </rng:optional>
  </rng:define>
  <rng:define name="file-entry">
    <rng:element name="manifest:file-entry">
      <rng:ref name="file-entry-attlist"/>
      <rng:optional>
        <rng:ref name="encryption-data"/>
      </rng:optional>
    </rng:element>
  </rng:define>
  <rng:define name="file-entry-attlist">
    <rng:interleave>
      <rng:attribute name="manifest:full-path">
        <rng:ref name="string"/>
      </rng:attribute>
      <rng:optional>
        <rng:attribute name="manifest:size">
          <rng:ref name="nonNegativeInteger"/>
        </rng:attribute>
      </rng:optional>
      <rng:attribute name="manifest:media-type">
        <rng:ref name="string"/>
      </rng:attribute>
      <rng:optional>
        <rng:attribute name="manifest:preferred-view-mode">
          <rng:choice>
            <rng:value>edit</rng:value>
            <rng:value>presentation-slide-show</rng:value>
            <rng:value>read-only</rng:value>
            <rng:ref name="namespacedToken"/>
          </rng:choice>
        </rng:attribute>
      </rng:optional>
      <rng:optional>
        <rng:attribute name="manifest:version">
          <rng:ref name="string"/>
        </rng:attribute>
      </rng:optional>
    </rng:interleave>
  </rng:define>
  <rng:define name="key-derivation">
    <rng:element name="manifest:key-derivation">
      <rng:ref name="key-derivation-attlist"/>
      <rng:empty/>
    </rng:element>
  </rng:define>
  <rng:define name="key-derivation-attlist">
    <rng:choice>
      <rng:attribute name="manifest:key-derivation-name">
        <rng:value>PGP</rng:value>
      </rng:attribute>
      <rng:interleave>
        <rng:choice>
          <rng:interleave>
            <rng:attribute name="manifest:key-derivation-name">
              <rng:choice>
                <rng:value>PBKDF2</rng:value>
                <rng:ref name="anyURI"/>
              </rng:choice>
            </rng:attribute>
            <rng:attribute name="manifest:iteration-count">
              <rng:ref name="nonNegativeInteger"/>
            </rng:attribute>
          </rng:interleave>
          <rng:interleave>
            <rng:attribute name="manifest:key-derivation-name">
            <!--
              <rng:value>urn:oasis:names:tc:opendocument:xmlns:manifest:1.5#argon2id</rng:value>
              -->
              <rng:value>urn:org:documentfoundation:names:experimental:office:manifest:argon2id</rng:value>
            </rng:attribute>
            <rng:attribute name="loext:argon2-iterations">
              <rng:ref name="positiveInteger"/>
            </rng:attribute>
            <rng:attribute name="loext:argon2-memory">
              <rng:ref name="positiveInteger"/>
            </rng:attribute>
            <rng:attribute name="loext:argon2-lanes">
              <rng:ref name="positiveInteger"/>
            </rng:attribute>
          </rng:interleave>
        </rng:choice>
        <rng:attribute name="manifest:salt">
          <rng:ref name="base64Binary"/>
        </rng:attribute>
        <rng:optional>
          <rng:attribute name="manifest:key-size">
            <rng:ref name="nonNegativeInteger"/>
          </rng:attribute>
        </rng:optional>
      </rng:interleave>
    </rng:choice>
  </rng:define>
  <rng:define name="manifest">
    <rng:element name="manifest:manifest">
      <rng:ref name="manifest-attlist"/>
      <rng:zeroOrMore>
        <rng:ref name="encrypted-key"/>
      </rng:zeroOrMore>
      <!-- https://issues.oasis-open.org/browse/OFFICE-3940 -->
      <rng:oneOrMore>
        <rng:ref name="file-entry"/>
      </rng:oneOrMore>
    </rng:element>
  </rng:define>
  <rng:define name="manifest-attlist">
    <rng:attribute name="manifest:version">
      <!-- FIXME remove this hack once tests can pick different schemas to validate -->
      <rng:choice>
      <rng:value>1.2</rng:value>
      <rng:value>1.3</rng:value>
      <rng:value>1.4</rng:value>
      </rng:choice>
    </rng:attribute>
  </rng:define>
  <rng:define name="namespacedToken">
    <rng:data type="QName">
      <rng:param name="pattern">[^:]+:[^:]+</rng:param>
    </rng:data>
  </rng:define>
  <rng:define name="nonNegativeInteger">
    <rng:data type="nonNegativeInteger"/>
  </rng:define>
  <rng:define name="positiveInteger">
    <rng:data type="positiveInteger"/>
  </rng:define>
  <rng:define name="start-key-generation">
    <rng:element name="manifest:start-key-generation">
      <rng:ref name="start-key-generation-attlist"/>
      <rng:empty/>
    </rng:element>
  </rng:define>
  <rng:define name="start-key-generation-attlist">
    <rng:interleave>
      <rng:attribute name="manifest:start-key-generation-name">
        <rng:choice>
          <rng:value>SHA1</rng:value>
          <rng:ref name="anyURI"/>
        </rng:choice>
      </rng:attribute>
      <rng:optional>
        <rng:attribute name="manifest:key-size">
          <rng:ref name="nonNegativeInteger"/>
        </rng:attribute>
      </rng:optional>
    </rng:interleave>
  </rng:define>
  <rng:define name="string">
    <rng:data type="string"/>
  </rng:define>
</rng:grammar>
