<?xml version="1.0" encoding="UTF-8"?>
<!--

    Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved.

    This program and the accompanying materials are made available under the
    terms of the Eclipse Distribution License v. 1.0, which is available at
    http://www.eclipse.org/org/documents/edl-v10.php.

    SPDX-License-Identifier: BSD-3-Clause

-->

<grammar
	ns="http://www.w3.org/2001/XMLSchema"
	xmlns:cc="http://www.xml.gr.jp/xmlns/relaxngcc"
	xmlns="http://relaxng.org/ns/structure/1.0"
	datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
	>
	
	
	
  <!-- ################################################################## -->
  <!--                                                                    -->
  <!-- simpleType                                                         -->
  <!--                                                                    -->
  <!-- ################################################################## -->
  <define name="simpleType"
  	cc:return-type="SimpleTypeImpl"
  	cc:return-value="result">
  	<cc:java-body>
  		/** computed simple type object */
  		private SimpleTypeImpl result;
  		
  		private Locator locator;

      private Set finalSet;

      private Set makeFinalSet(String finalValue) {
        if(finalValue==null)
          return Collections.EMPTY_SET;

        Set s = new HashSet();
        StringTokenizer tokens = new StringTokenizer(finalValue);
        while(tokens.hasMoreTokens()) {
          String token = tokens.nextToken();
          if(token.equals("#all")) {
            s.add(XSVariety.ATOMIC);
            s.add(XSVariety.UNION);
            s.add(XSVariety.LIST);
          }
          if(token.equals("list")) {
            s.add(XSVariety.LIST);
          }
          if(token.equals("union")) {
            s.add(XSVariety.UNION);
          }
          if(token.equals("restriction")) {
            s.add(XSVariety.ATOMIC);
          }
        }
        return s;
      }
    </cc:java-body>
    <element name="simpleType">
    	<cc:java>locator=$runtime.copyLocator();</cc:java>
      <optional>
        <attribute name="final">
          finalValue = <text />
          <!--
          <choice>
            <value>#all</value>
            <list>
              <zeroOrMore>
                <choice>
                  <value>list</value>
                  <value>union</value>
                  <value>restriction</value>
                </choice>
              </zeroOrMore>
            </list>
          </choice>
          -->
        </attribute>
      </optional>
      <!--optional>
        <attribute name="ID">
          <data type="ID"/>
        </attribute>
      </optional-->
      <optional>
        <attribute name="name">
          <data type="NCName" cc:alias="name" />
        </attribute>
      </optional>
      fa = <ref name="foreignAttributes"/>(fa);
      
      <optional>
        annotation = <ref name="annotation"/>(null,AnnotationContext.SIMPLETYPE_DECL);
      </optional>

      finalSet = makeFinalSet(finalValue);

      <choice>
      	<ref name="simpleType.restriction"
      		cc:alias="result" cc:with-params="annotation,locator,fa,name,finalSet" />
      	<ref name="simpleType.list"
      		cc:alias="result" cc:with-params="annotation,locator,fa,name,finalSet" />
      	<ref name="simpleType.union"
      		cc:alias="result" cc:with-params="annotation,locator,fa,name,finalSet" />
      </choice>
    </element>
  </define>
  
  
  <define name="simpleType.restriction" cc:class="SimpleType_Restriction"
  		cc:params="AnnotationImpl annotation,Locator locator,ForeignAttributesImpl fa,String name,Set finalSet"
  		cc:return-type="RestrictionSimpleTypeImpl"
  		cc:return-value="result">
  	
  	<cc:java-body>
  		/** computed simple type object */
  		private RestrictionSimpleTypeImpl result;
  		
  		// reference to the base type
  		private Ref.SimpleType baseType;
  		
  		// location of restriction
  		private Locator rloc;
  	</cc:java-body>
    <element name="restriction">
    	<cc:java>rloc=$runtime.copyLocator();</cc:java>
      <!--optional>
        <attribute name="ID">
          <data type="ID"/>
        </attribute>
      </optional-->
      fa = <ref name="foreignAttributes"/>(fa);
      <optional>
        <ref name="annotation" cc:alias="annotation" cc:with-params="annotation,AnnotationContext.SIMPLETYPE_DECL"/>
      </optional>
      <!-- base type reference or nested anonymous simple type -->
      <choice>
        <attribute name="base">
          <ref name="qname" cc:alias="baseTypeName" />
          <cc:java>
            baseType = new DelayedRef.SimpleType(
              $runtime, rloc, $runtime.currentSchema, baseTypeName );
           </cc:java>
        </attribute>
        <ref name="simpleType" cc:alias="baseType"/>
      </choice>
      <!-- create the result object -->
      <cc:java>
      	result = new RestrictionSimpleTypeImpl(
					$runtime.document, annotation, locator, fa, name, name==null, finalSet, baseType );
      </cc:java>
      <zeroOrMore>
        <ref name="facet" cc:alias="facet"/>
        <cc:java>
        	result.addFacet(facet);
        </cc:java>
      </zeroOrMore>
    </element>
  </define>
  
  
  
  <define name="facet" cc:return-type="XSFacet" cc:return-value="result">
  	<cc:java-body>
  		private FacetImpl result;
  		private Locator locator;
  	</cc:java-body>
    <element>
      <choice>
        <name>minExclusive</name>
        <name>maxExclusive</name>
        <name>minInclusive</name>
        <name>maxInclusive</name>
        <name>totalDigits</name>
        <name>fractionDigits</name>
        <name>length</name>
        <name>maxLength</name>
        <name>minLength</name>
        <name>enumeration</name>
        <name>whiteSpace</name>
        <name>pattern</name>
      </choice>
      <cc:java>locator=$runtime.copyLocator();</cc:java>
      <!-- 	attribute ID	{xsd:ID}?, -->
      <attribute name="value">
      	<text cc:alias="value" />
      </attribute>
      <optional>
      	<attribute name="fixed">
      		<data type="boolean" cc:alias="fixed"/>
      	</attribute>
      </optional>
      fa = <ref name="foreignAttributes"/>(fa);
      <optional>
        <ref name="annotation" cc:alias="annotation" cc:with-params="null,AnnotationContext.SIMPLETYPE_DECL"/>
      </optional>
    </element>
    <cc:java>
    	result = new FacetImpl( $runtime.document,
    		annotation, locator, fa, $localName/*name of the facet*/,
    		$runtime.createXmlString(value), $runtime.parseBoolean(fixed) );
    </cc:java>
  </define>
  
  
  <define name="simpleType.list" cc:class="SimpleType_List"
  		cc:params="AnnotationImpl annotation,Locator locator,ForeignAttributesImpl fa,String name,Set finalSet"
  		cc:return-type="ListSimpleTypeImpl"
  		cc:return-value="result">
  	
  	<cc:java-body>
  		/** computed simple type object */
  		private ListSimpleTypeImpl result;
  		
  		// reference to the base type
  		private Ref.SimpleType itemType;
  		
  		// locator of &lt;list>
  		private Locator lloc;
  	</cc:java-body>
    <element name="list">
    	<cc:java>lloc=$runtime.copyLocator();</cc:java>
      <!--optional>
        <attribute name="ID">
          <data type="ID"/>
        </attribute>
      </optional-->
      fa = <ref name="foreignAttributes"/>(fa);
      <optional>
        <ref name="annotation" cc:alias="annotation" cc:with-params="annotation,AnnotationContext.SIMPLETYPE_DECL"/>
      </optional>
      <!-- item type reference or nested anonymous simple type -->
      <choice>
        <attribute name="itemType">
          <ref name="qname" cc:alias="itemTypeName"/>
          <cc:java>
          	itemType = new DelayedRef.SimpleType(
          		$runtime, lloc, $runtime.currentSchema, itemTypeName);
          </cc:java>
        </attribute>
        <ref name="simpleType" cc:alias="itemType" />
      </choice>
    </element>
    <cc:java>
    	result = new ListSimpleTypeImpl(
    		$runtime.document, annotation, locator, fa,
    		name, name==null, finalSet, itemType );
    </cc:java>
  </define>
  
  
  <define name="simpleType.union" cc:class="SimpleType_Union"
  		cc:params="AnnotationImpl annotation,Locator locator,ForeignAttributesImpl fa,String name,Set finalSet"
  		cc:return-type="UnionSimpleTypeImpl"
  		cc:return-value="result">
  	
  	<cc:java-import>
  		import java.util.Vector;
  	</cc:java-import>
  	<cc:java-body>
  		/** computed simple type object */
  		private UnionSimpleTypeImpl result;
  		
  		// Vector of Ref.SimpleType
  		private final Vector members = new Vector();
  		
  		// locator of &lt;union>
  		private Locator uloc;
  	</cc:java-body>
  	
    <element name="union">
    	<cc:java>uloc=$runtime.copyLocator();</cc:java>
      <!--optional>
        <attribute name="ID">
          <data type="ID"/>
        </attribute>
      </optional-->
      <optional>
        <attribute name="memberTypes">
          <list>
            <oneOrMore>
              <ref name="qname" cc:alias="memberTypeName"/>
              <cc:java>
              	members.add( new DelayedRef.SimpleType(
	            		$runtime, uloc, $runtime.currentSchema, memberTypeName));
              </cc:java>
            </oneOrMore>
          </list>
        </attribute>
      </optional>
      fa = <ref name="foreignAttributes"/>(fa);
      <optional>
        <ref name="annotation" cc:alias="annotation" cc:with-params="annotation,AnnotationContext.SIMPLETYPE_DECL"/>
      </optional>
      <zeroOrMore>
        <ref name="simpleType" cc:alias="anonymousMemberType" />
        <cc:java>
          members.add(anonymousMemberType);
        </cc:java>
      </zeroOrMore>
    </element>
    <cc:java>
			result = new UnionSimpleTypeImpl(
				$runtime.document, annotation, locator, fa, name, name==null, finalSet,
				(Ref.SimpleType[])members.toArray(new Ref.SimpleType[members.size()]) );
    </cc:java>
  </define>


</grammar>
