<?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"
	>

	
	
  <!-- ################################################################## -->
  <!--                                                                    -->
  <!-- particles and model groups                                         -->
  <!--                                                                    -->
  <!-- ################################################################## -->
  
  <!--define name="modelGroup"
  	cc:return-type="XSModelGroup" cc:return-value="modelGroup">
  	
  	<cc:java-body>
  		String name;
  	</cc:java-body>
  	
    <cc:java>name=$localName;</cc:java> <!- compositor name ->
    <element>
      <choice>
        <name>all</name>
        <name>choice</name>
        <name>sequence</name>
      </choice>
      <ref name="modelGroupBody" cc:alias="modelGroup" />
    </element>
  </define-->
  
  
  <define name="modelGroupBody"
  	cc:params="Locator locator, String compositorName"
  	cc:return-type="ModelGroupImpl" cc:return-value="result">
  	
  	<cc:java-import>
  		import java.util.Vector;
  	</cc:java-import>
  	<cc:java-body>
  		private ModelGroupImpl result;
  		
  		private final List particles = new ArrayList();
  	</cc:java-body>
    <!--optional>
      <attribute name="ID">
        <data type="ID"/>
      </attribute>
    </optional-->
    fa = <ref name="foreignAttributes"/>(null);
    <optional>
      <ref name="annotation" cc:alias="annotation"/>(null,AnnotationContext.MODELGROUP);
    </optional>
    
    <!-- children of the particle -->
    <zeroOrMore>
      <ref name="particle" cc:alias="childParticle"/>
      <cc:java>
        particles.add(childParticle);
      </cc:java>
    </zeroOrMore>
    <!-- TODO: make sure the position of this code -->
    <cc:java>
      XSModelGroup.Compositor compositor = null;
      if(compositorName.equals("all"))      compositor = XSModelGroup.ALL;
      if(compositorName.equals("sequence")) compositor = XSModelGroup.SEQUENCE;
      if(compositorName.equals("choice"))   compositor = XSModelGroup.CHOICE;
      if(compositor==null)
        throw new InternalError("unable to process "+compositorName);
      
      result = new ModelGroupImpl( $runtime.document, annotation, locator, fa, compositor,
            (ParticleImpl[])particles.toArray(new ParticleImpl[0]));
    </cc:java>
  </define>
  
  
  <define name="particle"
    cc:return-type="ParticleImpl" cc:return-value="result">
    
    <cc:java-body>
    	private Locator wloc;
    	private Locator loc;
      private ParticleImpl result;
      private String compositorName;
    </cc:java-body>
    <choice>
      <group>
        <cc:java>
          compositorName = $localName;
          loc = $runtime.copyLocator();
        </cc:java>
        <element>
          <choice>
            <name>all</name>
            <name>choice</name>
            <name>sequence</name>
          </choice>
          <ref name="occurs" cc:alias="occurs" />
          <ref name="modelGroupBody" cc:alias="term"
            cc:with-params="loc,compositorName"/>
          <cc:java>
            result = new ParticleImpl( $runtime.document, null, term, loc, occurs.max, occurs.min );
          </cc:java>
        </element>
      </group>
      <element name="group">
        <cc:java>loc = $runtime.copyLocator();</cc:java>
        <ref name="occurs" cc:alias="occurs"/>
        <attribute name="ref">
          <ref name="qname" cc:alias="groupName" />
        </attribute>
        <optional>
          <ref name="annotation" cc:alias="annotation" />(null,AnnotationContext.PARTICLE);
        </optional>
        <cc:java>
          result = new ParticleImpl( $runtime.document, annotation, new DelayedRef.ModelGroup(
              $runtime, loc, $runtime.currentSchema, groupName ),
            loc, occurs.max, occurs.min );
        </cc:java>
      </element>
      <element name="element">
        <cc:java>loc = $runtime.copyLocator();</cc:java>
        <ref name="occurs" cc:alias="occurs"/>
        <choice>
          <group>
            <attribute name="ref" cc:workaround-significant="true">
              <ref name="qname" cc:alias="elementTypeName"/>
            </attribute>
            <optional>
              <ref name="annotation" cc:alias="annotation" />(null,AnnotationContext.PARTICLE);
            </optional>
            <cc:java>
              result = new ParticleImpl( $runtime.document, annotation, new DelayedRef.Element(
                  $runtime, loc, $runtime.currentSchema, elementTypeName ),
                  loc, occurs.max, occurs.min );
            </cc:java>
          </group>
          <group>
            <ref name="elementDeclBody"
              cc:alias="anonymousElementDecl" cc:with-params="loc,false" />
            <cc:java>
              result = new ParticleImpl( $runtime.document, null,
                anonymousElementDecl,
                loc, occurs.max, occurs.min );
            </cc:java>
          </group>
        </choice>
      </element>
      <element name="any">
      	<cc:java>wloc = $runtime.copyLocator();</cc:java>
        <!--optional>
          <attribute name="ID">
            <data type="ID"/>
          </attribute>
        </optional-->
        <ref name="occurs" cc:alias="occurs"/>
        <ref name="wildcardBody" cc:with-params="wloc" cc:alias="wcBody"/>
        <cc:java>
          result = new ParticleImpl( $runtime.document, null, wcBody, wloc, occurs.max, occurs.min );
        </cc:java>
      </element>
    </choice>
  </define>
  
  
  
  
  
  <define name="group"
  	cc:return-type="ModelGroupDeclImpl" cc:return-value="result">
  	
  	<cc:java-body>
  		private ModelGroupDeclImpl result;
  		private Locator loc,mloc;
  		private String compositorName;
  	</cc:java-body>
    <element name="group">
      <cc:java>loc = $runtime.copyLocator();</cc:java>
      <optional>
        <attribute name="ID">
          <data type="ID"/>
        </attribute>
      </optional>
      <attribute name="name">
        <data type="NCName" cc:alias="name"/>
      </attribute>
      <optional>
        <ref name="annotation" cc:alias="annotation" />(null,AnnotationContext.MODELGROUP_DECL);
      </optional>
      fa = <ref name="foreignAttributes"/>(null);
      <cc:java>
        mloc = $runtime.copyLocator();
        compositorName = $localName;
      </cc:java>
      <element>
        <choice>
          <name>all</name>
          <name>choice</name>
          <name>sequence</name>
        </choice>
        <ref name="modelGroupBody" cc:alias="term"
          cc:with-params="mloc,compositorName" />
      </element>
    </element>
    <cc:java>
    	result = new ModelGroupDeclImpl( $runtime.document,
    		annotation, loc, fa,
    		$runtime.currentSchema.getTargetNamespace(),
				name,
				term
			);
    </cc:java>
  </define>
	
	

</grammar>
