<?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"
  >
  
  
  
  
  
  <define name="attributeDeclBody"
    cc:params="Locator locator, boolean isLocal,String defaultValue,String fixedValue"
    cc:return-type="AttributeDeclImpl" cc:return-value="makeResult()">
    
    <cc:java-body>
      private boolean form;
      private boolean formSpecified = false;
      
      private AttributeDeclImpl makeResult() {
        
        if(type==null)
          // type defaults to anySimpleType
          type = $runtime.parser.schemaSet.anySimpleType;
        
        if(!formSpecified) form = $runtime.attributeFormDefault;
          // global attributes are always qualified
          if(!isLocal)       form = true;
        
        String tns;
        if(form==true)  tns = $runtime.currentSchema.getTargetNamespace();
        else            tns = "";
        
        // proper handling of anonymous types
        return new AttributeDeclImpl( $runtime.document, tns, name,
          annotation, locator, fa, isLocal,
          $runtime.createXmlString(defaultValue),
          $runtime.createXmlString(fixedValue),
          type );
      }
      private Ref.SimpleType type;
    </cc:java-body>
    
    <optional>
      <attribute name="form">
        <ref name="qualification" cc:alias="form" />
        formSpecified = true;
      </attribute>
    </optional>
    <!--optional>
      <attribute name="id">
        <data type="ID"/>
      </attribute>
    </optional-->
    <attribute name="name">
      <data type="NCName" cc:alias="name"/>
    </attribute>
    fa = <ref name="foreignAttributes"/>(fa);
    <optional>
      <ref name="annotation" cc:alias="annotation"/>(null,AnnotationContext.ATTRIBUTE_DECL);
    </optional>
    <choice>
      <empty/> <!-- default to anySimpleType -->
      <attribute name="type">
        <ref name="qname" cc:alias="typeName"/>
        <cc:java>
          type = new DelayedRef.SimpleType(
            $runtime, locator, $runtime.currentSchema, typeName );
        </cc:java>
      </attribute>
      <ref name="simpleType" cc:alias="type"/>
    </choice>
  </define>
  
  
  
  
  <define name="attributeGroupDecl"
    cc:return-type="AttGroupDeclImpl" cc:return-value="result">
    
    <cc:java-body>
      private AttGroupDeclImpl result;
      private Locator locator;
    </cc:java-body>
    <element name="attributeGroup">
      <cc:java>locator=$runtime.copyLocator();</cc:java>
      <attribute name="name">
        <data type="NCName" cc:alias="name"/>
      </attribute>
      <optional>
        <attribute name="id">
          <data type="ID"/>
        </attribute>
      </optional>
      fa = <ref name="foreignAttributes"/>(fa);
      <optional>
        <ref name="annotation" cc:alias="annotation"/>(null,AnnotationContext.ATTRIBUTE_GROUP);
      </optional>
      <cc:java>
        result = new AttGroupDeclImpl(
          $runtime.document, annotation, locator, fa, name );
      </cc:java>
      <ref name="attributeUses" cc:with-params="result"/>
    </element>
  </define>
  
  
  
  <define name="attributeUses" cc:params="AttributesHolder owner">
    <cc:java-body>
      private Ref.Attribute decl;
      private Locator wloc; // locator for wildcards
      private Locator locator;
    </cc:java-body>
    
    <zeroOrMore>
      <choice>
        <!-- attribute use -->
        <element name="attribute">
          <cc:java>
            locator=$runtime.copyLocator();
            use=null;
            defaultValue=null;
            fixedValue=null;
            decl=null;
            annotation=null;
          </cc:java>
          <optional>
            <attribute name="use">
              <text cc:alias="use" />
              <!--choice>
                <value>optional</value>
                <value>prohibited</value>
                <value>required</value>
              </choice-->
            </attribute>
          </optional>
          <optional>
            <attribute name="default" cc:alias="defaultValue"/>
          </optional>
          <optional>
            <attribute name="fixed" cc:alias="fixedValue"/>
          </optional>
          <choice>
            <group>
              <ref name="attributeDeclBody" cc:alias="anonymousDecl"
              	cc:with-params="locator,true,defaultValue,fixedValue"/><!-- anonymous attribute decl -->
              <cc:java>
                decl = anonymousDecl;
                attDeclName = new UName(
                  anonymousDecl.getTargetNamespace(),
                  anonymousDecl.getName());
                defaultValue = null;
                fixedValue = null;
              </cc:java>
            </group>
            <group>
              <attribute name="ref" cc:workaround-significant="yes">
                <!-- @workaround-significant avoids a bug in RelaxNGCC
                     see https://sourceforge.net/tracker/index.php?func=detail&aid=579864&group_id=53706&atid=471312
                -->
                <ref name="qname" cc:alias="attDeclName"/>
                <cc:java>
                  decl = new DelayedRef.Attribute(
                    $runtime, locator, $runtime.currentSchema, attDeclName );
                </cc:java>
              </attribute>
              <optional>
                <ref name="annotation" cc:alias="annotation"/>(null,AnnotationContext.ATTRIBUTE_USE);
              </optional>
              fa = <ref name="foreignAttributes" />(null);
            </group>
          </choice>
          <cc:java>
            if("prohibited".equals(use))
              owner.addProhibitedAttribute(attDeclName);
            else
              owner.addAttributeUse(attDeclName,
                new AttributeUseImpl( $runtime.document, annotation,locator,fa,decl,
                  $runtime.createXmlString(defaultValue),
                  $runtime.createXmlString(fixedValue),
                  "required".equals(use)));
          </cc:java>
        </element>
        <!-- attribute group reference -->
        <element name="attributeGroup">
          <cc:java>locator=$runtime.copyLocator();</cc:java>
          <attribute name="ref">
            <ref name="qname" cc:alias="groupName"/>
          </attribute>
          <optional>
            <ref name="annotation" />(null,AnnotationContext.ATTRIBUTE_USE);
          </optional>
          <cc:java>
            owner.addAttGroup(new DelayedRef.AttGroup(
              $runtime, locator, $runtime.currentSchema, groupName ));
          </cc:java>
        </element>
      </choice>
    </zeroOrMore>
    <optional>
      <element name="anyAttribute">
        <cc:java>wloc = $runtime.copyLocator();</cc:java>
        <ref name="wildcardBody" cc:alias="wildcard" cc:with-params="wloc" />
        <cc:java>
          owner.setWildcard(wildcard);
        </cc:java>
      </element>
    </optional>
  </define>


</grammar>
