header {
/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you 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. 
 *  
 */
package org.apache.directory.api.ldap.model.schema.syntaxes;

import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.directory.api.ldap.model.schema.parsers.LdapComparatorDescription;
import org.apache.directory.api.ldap.model.schema.DitContentRule;
import org.apache.directory.api.ldap.model.schema.DitStructureRule;
import org.apache.directory.api.ldap.model.schema.LdapSyntax;
import org.apache.directory.api.ldap.model.schema.MatchingRule;
import org.apache.directory.api.ldap.model.schema.MutableMatchingRule;
import org.apache.directory.api.ldap.model.schema.MatchingRuleUse;
import org.apache.directory.api.ldap.model.schema.NameForm;
import org.apache.directory.api.ldap.model.schema.parsers.NormalizerDescription;
import org.apache.directory.api.ldap.model.schema.parsers.ParserMonitor;
import org.apache.directory.api.ldap.model.schema.AttributeType;
import org.apache.directory.api.ldap.model.schema.MutableAttributeType;
import org.apache.directory.api.ldap.model.schema.ObjectClass;
import org.apache.directory.api.ldap.model.schema.MutableObjectClass;
import org.apache.directory.api.ldap.model.schema.parsers.SyntaxCheckerDescription;
import org.apache.directory.api.ldap.model.schema.syntaxCheckers.OpenLdapObjectIdentifierMacro;
import org.apache.directory.api.ldap.model.schema.ObjectClassTypeEnum;
import org.apache.directory.api.ldap.model.schema.UsageEnum;

}

/**
 * An antlr generated schema main lexer.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
class AntlrSchemaLexer extends Lexer;

options    {
    k = 8 ;
    exportVocab=AntlrSchema ;
    charVocabulary = '\u0000'..'\uFFFE';
    caseSensitive = false ;
    defaultErrorHandler = false ;
}

WHSP
    :
    ( options {greedy=true;} :
    ' '
    |
    '\t'
    |
    '\r' (options {greedy=true;} : '\n')? { newline(); } 
    |
    '\n' { newline(); }
    |
    '#' (~'\n')* '\n' { newline(); }
    )+
    {$setType(Token.SKIP);} //ignore this token
    ;

LPAR : '(' ;
RPAR : ')' ;
QUOTE : '\'' ;
DOLLAR : '$' ;
LBRACKET : '{' ;
RBRACKET : '}' ;

LEN : LBRACKET ('0'..'9')+ RBRACKET ;

SINGLE_VALUE : ( "single-value" (WHSP)? ) ;
COLLECTIVE : ( "collective" (WHSP)? ) ;
NO_USER_MODIFICATION : ( "no-user-modification" (WHSP)? ) ;

OBSOLETE : ( "obsolete" (WHSP)? ) ;
ABSTRACT : ( "abstract" (WHSP)? ) ;
STRUCTURAL : ( "structural" (WHSP)? ) ;
protected AUXILIARY : ( "auxiliary" (WHSP)? ) ;

OBJECTIDENTIFIER : 
    ( "objectidentifier" 
      WHSP
      ( oiName:UNQUOTED_STRING ) 
      WHSP
      ( oiValue:UNQUOTED_STRING ) 
    ) 
    { setText( oiName.getText() + " " + oiValue.getText() ); }
    ;

OBJECTCLASS : ( "objectclass" (WHSP)? ) ;
ATTRIBUTETYPE : ( "attributetype" (WHSP)? ) ;

STARTNUMERICOID : ( LPAR (options {greedy=true;} : WHSP)? ( numericoid:VALUES ) ) { setText(numericoid.getText()); } ;
NAME : ( "name" (options {greedy=true;} : WHSP)? qdstrings:VALUES ) { setText(qdstrings.getText().trim()); } ;
DESC : ( "desc" (options {greedy=true;} : WHSP)? qdstring:VALUES ) { setText(qdstring.getText().trim()); } ;
SUP : ( "sup" (options {greedy=true;} : WHSP)? sup:VALUES ) { setText(sup.getText().trim()); } ;
MUST : ( "must" (options {greedy=true;} : WHSP)? must:VALUES ) { setText(must.getText().trim()); } ;
MAY : ( "may" (options {greedy=true;} : WHSP)? may:VALUES ) { setText(may.getText()); } ;
protected AUX : ( "aux" (options {greedy=true;} : WHSP)? aux:VALUES ) { setText(aux.getText()); } ;
NOT : ( "not" (options {greedy=true;} : WHSP)? not:VALUES ) { setText(not.getText()); } ;
FORM : ( "form" (options {greedy=true;} : WHSP)? form:VALUES ) { setText(form.getText()); } ;
OC : ( "oc" (options {greedy=true;} : WHSP)? oc:VALUES ) { setText(oc.getText()); } ;
EQUALITY : ( "equality" (options {greedy=true;} : WHSP)? equality:VALUES ) { setText(equality.getText().trim()); } ;
ORDERING : ( "ordering" (options {greedy=true;} : WHSP)? ordering:VALUES ) { setText(ordering.getText().trim()); } ;
SUBSTR : ( "substr" (options {greedy=true;} : WHSP)? substring:VALUES ) { setText(substring.getText().trim()); } ;
SYNTAX : ( "syntax" (options {greedy=true;} : WHSP)? syntax:VALUES (len:LEN)? ) { setText(syntax.getText().trim() + (len!=null?len.getText().trim():"")); } ;
APPLIES : ( "applies" (options {greedy=true;} : WHSP)? applies:VALUES ) { setText(applies.getText().trim()); } ;
EXTENSION : x:( "x-" ( options {greedy=true;} : 'a'..'z' | '-' | '_' )+ (options {greedy=true;} : WHSP)? VALUES ) ; 
FQCN : ( "fqcn" (options {greedy=true;} : WHSP)? fqcn:FQCN_VALUE ) { setText(fqcn.getText().trim()); } ;
BYTECODE : ( "bytecode" (options {greedy=true;} : WHSP)? bytecode:BYTECODE_VALUE ) { setText(bytecode.getText().trim()); } ;

AUX_OR_AUXILIARY :
    ( AUXILIARY ) => AUXILIARY { $setType( AUXILIARY ); }
    |
    ( AUX ) { $setType( AUX ); }
    ;

protected VALUES : ( VALUE | LPAR  VALUE ( (DOLLAR)? VALUE )* RPAR ) ;
protected VALUE : (WHSP)? ( QUOTED_STRING | UNQUOTED_STRING ) (options {greedy=true;}: WHSP)? ;
protected UNQUOTED_STRING : (options{greedy=true;}: 'a'..'z' | '0'..'9' | '-' | '_' | ';' | '.' | ':' )+ ;
protected QUOTED_STRING : ( QUOTE (~'\'')* QUOTE ) ;
protected FQCN_VALUE : ( FQCN_IDENTIFIER ( '.' FQCN_IDENTIFIER )* ) ;
protected FQCN_IDENTIFIER : ( FQCN_LETTER ( FQCN_LETTERORDIGIT )* ) ;
protected FQCN_LETTER : 
       '\u0024' |
       '\u005f' |
       '\u0061'..'\u007a' |
       '\u00c0'..'\u00d6' |
       '\u00d8'..'\u00f6' |
       '\u00f8'..'\u00ff' |
       '\u0100'..'\u1fff' |
       '\u3040'..'\u318f' |
       '\u3300'..'\u337f' |
       '\u3400'..'\u3d2d' |
       '\u4e00'..'\u9fff' |
       '\uf900'..'\ufaff' ;
protected FQCN_LETTERORDIGIT : 
       '\u0024' |
       '\u005f' |
       '\u0061'..'\u007a' |
       '\u00c0'..'\u00d6' |
       '\u00d8'..'\u00f6' |
       '\u00f8'..'\u00ff' |
       '\u0100'..'\u1fff' |
       '\u3040'..'\u318f' |
       '\u3300'..'\u337f' |
       '\u3400'..'\u3d2d' |
       '\u4e00'..'\u9fff' |
       '\uf900'..'\ufaff' |
       '\u0030'..'\u0039' ;
protected BYTECODE_VALUE : ( 'a'..'z' | '0'..'9' | '+' | '/' | '=' )+ ;


USAGE : ( "usage" (WHSP)? ) ;
USER_APPLICATIONS : ( "userapplications" (WHSP)? ) ;
DIRECTORY_OPERATION : ( "directoryoperation" (WHSP)? ) ;
DISTRIBUTED_OPERATION : ( "distributedoperation" (WHSP)? ) ;
DSA_OPERATION : ( "dsaoperation" (WHSP)? ) ;

/**
 * An antlr generated schema main parser.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
class AntlrSchemaParser extends Parser;
options    {
    k = 3 ;
    defaultErrorHandler = false ;
    //buildAST=true ;
}

{
    private ParserMonitor monitor = null;
    private boolean isQuirksModeEnabled = false;
    public void setParserMonitor( ParserMonitor monitor )
    {
        this.monitor = monitor;
    }
    private void matchedProduction( String msg )
    {
        if ( null != monitor )
        {
            monitor.matchedProduction( msg );
        }
    }
    public void setQuirksMode( boolean enabled )
    {
        this.isQuirksModeEnabled = enabled;
    }
    public boolean isQuirksMode()
    {
        return this.isQuirksModeEnabled;
    }
    static class Extension
    {
        String key = "";
        List<String> values = new ArrayList<String>();
        
        public void addValue( String value )
        {
            this.values.add( value );
        }
    }
    static class NoidLen
    {
        String noid = "";
        long len = 0L;
    }
    static class ElementTracker
    {
        Map<String, Integer> elementMap = new HashMap<String, Integer>();
        void track(String element, Token token) throws SemanticException 
        {
            if(elementMap.containsKey(element))
            {
                throw new SemanticException( element + " appears twice.", token.getFilename(), token.getLine() , token.getColumn() );
            }
            elementMap.put(element, Integer.valueOf(1));
        }
        boolean contains(String element) 
        {
            return elementMap.containsKey(element);
        }
    }

}

openLdapSchema returns [List<Object> list = new ArrayList<Object>()]
    {
        AttributeType attributeType = null;
        ObjectClass objectClass = null;
        OpenLdapObjectIdentifierMacro oloid = null;
    }
    :
    (
        oloid = openLdapObjectIdentifier { list.add( oloid ); }
        |
        attributeType = openLdapAttributeType { list.add( attributeType ); }
        |
        objectClass = openLdapObjectClass { list.add( objectClass ); }
    )*
    ;

openLdapObjectIdentifier returns [OpenLdapObjectIdentifierMacro oloid]
    {
        matchedProduction( "openLdapObjectIdentifier()" );
    }
    :
    (
        oi:OBJECTIDENTIFIER 
        {
            String[] nameAndValue = oi.getText().split( " " );
            oloid = new OpenLdapObjectIdentifierMacro();
            oloid.setName( nameAndValue[0] );
            oloid.setRawOidOrNameSuffix( nameAndValue[1] );
        }
    )
    ;
    

openLdapObjectClass returns [ObjectClass objectClass]
    {
        matchedProduction( "openLdapObjectClass()" );
    }
    :
    (
        OBJECTCLASS
        ( objectClass=objectClassDescription )
    )
    ;
    
    
openLdapAttributeType returns [AttributeType attributeType]
    {
        matchedProduction( "openLdapAttributeType()" );
    }
    :
    (
        ATTRIBUTETYPE
        ( attributeType=attributeTypeDescription )
    )
    ;


    /**
     * Production for matching object class descriptions. It is fault-tolerant
     * against element ordering.
     *
     * <pre>
     * ObjectClassDescription = LPAREN WSP
     *     numericoid                 ; object identifier
     *     [ SP "NAME" SP qdescrs ]   ; short names (descriptors)
     *     [ SP "DESC" SP qdstring ]  ; description
     *     [ SP "OBSOLETE" ]          ; not active
     *     [ SP "SUP" SP oids ]       ; superior object classes
     *     [ SP kind ]                ; kind of class
     *     [ SP "MUST" SP oids ]      ; attribute types
     *     [ SP "MAY" SP oids ]       ; attribute types
     *     extensions WSP RPAREN
     *
     * kind = "ABSTRACT" / "STRUCTURAL" / "AUXILIARY"
     * 
     * extensions = *( SP xstring SP qdstrings )
     * xstring = "X" HYPHEN 1*( ALPHA / HYPHEN / USCORE ) 
     * </pre>
    */
objectClassDescription returns [MutableObjectClass objectClass]
    {
        matchedProduction( "objectClassDescription()" );
        ElementTracker et = new ElementTracker();
    }
    :
    ( oid:STARTNUMERICOID { objectClass = new MutableObjectClass(numericoid(oid.getText())); } )
    (
        ( name:NAME { et.track("NAME", name); objectClass.setNames(qdescrs(name.getText())); } )
        |
        ( desc:DESC { et.track("DESC", desc); objectClass.setDescription(qdstring(desc.getText())); } )
        |
        ( obsolete:OBSOLETE { et.track("OBSOLETE", obsolete); objectClass.setObsolete( true ); } )
        |
        ( sup:SUP { et.track("SUP", sup); objectClass.setSuperiorOids(oids(sup.getText())); } )
        |
        ( kind1:ABSTRACT { et.track("KIND", kind1); objectClass.setType( ObjectClassTypeEnum.ABSTRACT ); }
          |
          kind2:STRUCTURAL { et.track("KIND", kind2); objectClass.setType( ObjectClassTypeEnum.STRUCTURAL ); }
          |
          kind3:AUXILIARY { et.track("KIND", kind3); objectClass.setType( ObjectClassTypeEnum.AUXILIARY ); } 
        )
        |
        ( must:MUST { et.track("MUST", must); objectClass.setMustAttributeTypeOids(oids(must.getText())); } )
        |
        ( may:MAY { et.track("MAY", may); objectClass.setMayAttributeTypeOids(oids(may.getText())); } )
        |
        ( extension:EXTENSION { 
            Extension ex = extension(extension.getText());
            et.track(ex.key, extension); 
            objectClass.addExtension(ex.key, ex.values); 
         } )
    )*    
    RPAR
    ;


    /**
     * Production for matching attribute type descriptions. It is fault-tolerant
     * against element ordering.
     *
     * <pre>
     * AttributeTypeDescription = LPAREN WSP
     *     numericoid                    ; object identifier
     *     [ SP "NAME" SP qdescrs ]      ; short names (descriptors)
     *     [ SP "DESC" SP qdstring ]     ; description
     *     [ SP "OBSOLETE" ]             ; not active
     *     [ SP "SUP" SP oid ]           ; supertype
     *     [ SP "EQUALITY" SP oid ]      ; equality matching rule
     *     [ SP "ORDERING" SP oid ]      ; ordering matching rule
     *     [ SP "SUBSTR" SP oid ]        ; substrings matching rule
     *     [ SP "SYNTAX" SP noidlen ]    ; value syntax
     *     [ SP "SINGLE-VALUE" ]         ; single-value
     *     [ SP "COLLECTIVE" ]           ; collective
     *     [ SP "NO-USER-MODIFICATION" ] ; not user modifiable
     *     [ SP "USAGE" SP usage ]       ; usage
     *     extensions WSP RPAREN         ; extensions
     * 
     * usage = "userApplications"     /  ; user
     *         "directoryOperation"   /  ; directory operational
     *         "distributedOperation" /  ; DSA-shared operational
     *         "dSAOperation"            ; DSA-specific operational     
     * 
     * extensions = *( SP xstring SP qdstrings )
     * xstring = "X" HYPHEN 1*( ALPHA / HYPHEN / USCORE ) 
     * </pre>
    */
attributeTypeDescription returns [MutableAttributeType attributeType]
    {
        matchedProduction( "attributeTypeDescription()" );
        ElementTracker et = new ElementTracker();
    }
    :
    ( oid:STARTNUMERICOID { attributeType = new MutableAttributeType(numericoid(oid.getText())); } )
    (
        ( name:NAME { et.track("NAME", name); attributeType.setNames(qdescrs(name.getText())); } )
        |
        ( desc:DESC { et.track("DESC", desc); attributeType.setDescription(qdstring(desc.getText())); } )
        |
        ( obsolete:OBSOLETE { et.track("OBSOLETE", obsolete); attributeType.setObsolete( true ); } )
        |
        ( superior:SUP { et.track("SUP", superior); attributeType.setSuperiorOid(oid(superior.getText())); } )
        |
        ( equality:EQUALITY { et.track("EQUALITY", equality); attributeType.setEqualityOid(oid(equality.getText())); } )
        |
        ( ordering:ORDERING { et.track("ORDERING", ordering); attributeType.setOrderingOid(oid(ordering.getText())); } )
        |
        ( substring:SUBSTR { et.track("SUBSTR", substring); attributeType.setSubstringOid(oid(substring.getText())); } )
        |
        ( syntax:SYNTAX { 
           et.track("SYNTAX", syntax); 
            NoidLen noidlen = noidlen(syntax.getText());
            attributeType.setSyntaxOid(noidlen.noid); 
            attributeType.setSyntaxLength(noidlen.len);
          } )
        |
        ( singleValued:SINGLE_VALUE { et.track("SINGLE_VALUE", singleValued); attributeType.setSingleValued( true ); } )
        |
        ( collective:COLLECTIVE { et.track("COLLECTIVE", collective); attributeType.setCollective( true ); } )
        |
        ( noUserModification:NO_USER_MODIFICATION { et.track("NO_USER_MODIFICATION", noUserModification); attributeType.setUserModifiable( false ); } )
        |
        ( usage1:USAGE (WHSP)* USER_APPLICATIONS { et.track("USAGE", usage1); attributeType.setUsage( UsageEnum.USER_APPLICATIONS ); }
          |
          usage2:USAGE DIRECTORY_OPERATION { et.track("USAGE", usage2); attributeType.setUsage( UsageEnum.DIRECTORY_OPERATION ); }
          |
          usage3:USAGE DISTRIBUTED_OPERATION { et.track("USAGE", usage3); attributeType.setUsage( UsageEnum.DISTRIBUTED_OPERATION ); } 
          |
          usage4:USAGE DSA_OPERATION { et.track("USAGE", usage4); attributeType.setUsage( UsageEnum.DSA_OPERATION ); } 
        )
        |
        ( extension:EXTENSION { 
            Extension ex = extension(extension.getText());
            et.track(ex.key, extension); 
            attributeType.addExtension(ex.key, ex.values); 
         } )
    )*    
    RPAR
    {
        if( !isQuirksModeEnabled )
        {
            // semantic check: required elements
            if( !et.contains("SYNTAX") && !et.contains("SUP") ) 
            {
                throw new SemanticException( "One of SYNTAX or SUP is required", null, 0, 0 );
            }
        
            // COLLECTIVE requires USAGE userApplications
            if ( attributeType.isCollective() && ( attributeType.getUsage() != UsageEnum.USER_APPLICATIONS ) )
            {
                throw new SemanticException( "COLLECTIVE requires USAGE userApplications", null, 0, 0 );
            }
        
            // NO-USER-MODIFICATION requires an operational USAGE.
            if ( !attributeType.isUserModifiable() && ( attributeType.getUsage() == UsageEnum.USER_APPLICATIONS ) )
            {
                throw new SemanticException( "NO-USER-MODIFICATION requires an operational USAGE", null, 0, 0 );
            }
        }
    }
    ;


    /**
     * Production for matching ldap syntax descriptions. It is fault-tolerant
     * against element ordering.
     *
     * <pre>
     * SyntaxDescription = LPAREN WSP
     *    numericoid                 ; object identifier
     *    [ SP "DESC" SP qdstring ]  ; description
     *    extensions WSP RPAREN      ; extensions
     * </pre>
    */
ldapSyntaxDescription returns [LdapSyntax ldapSyntax]
    {
        matchedProduction( "ldapSyntaxDescription()" );
        ElementTracker et = new ElementTracker();
    }
    :
    ( oid:STARTNUMERICOID { ldapSyntax = new LdapSyntax(numericoid(oid.getText())); } )
    (
        ( name:NAME { et.track("NAME", name); ldapSyntax.setNames(qdescrs(name.getText())); } )
        |
        ( desc:DESC { et.track("DESC", desc); ldapSyntax.setDescription(qdstring(desc.getText())); } )
        |
        ( extension:EXTENSION { 
            Extension ex = extension(extension.getText());
            et.track(ex.key, extension); 
            ldapSyntax.addExtension(ex.key, ex.values); 
         } )
    )*
    RPAR
    ;



    /**
     * Production for matching rule descriptions. It is fault-tolerant
     * against element ordering.
     *
     * <pre>
     * MatchingRuleDescription = LPAREN WSP
     *    numericoid                 ; object identifier
     *    [ SP "NAME" SP qdescrs ]   ; short names (descriptors)
     *    [ SP "DESC" SP qdstring ]  ; description
     *    [ SP "OBSOLETE" ]          ; not active
     *    SP "SYNTAX" SP numericoid  ; assertion syntax
     *    extensions WSP RPAREN      ; extensions
     * </pre>
    */
matchingRuleDescription returns [MutableMatchingRule matchingRule]
    {
        matchedProduction( "matchingRuleDescription()" );
        ElementTracker et = new ElementTracker();
    }
    :
    ( oid:STARTNUMERICOID { matchingRule = new MutableMatchingRule(numericoid(oid.getText())); } )
    (
        ( name:NAME { et.track("NAME", name); matchingRule.setNames(qdescrs(name.getText())); } )
        |
        ( desc:DESC { et.track("DESC", desc); matchingRule.setDescription(qdstring(desc.getText())); } )
        |
        ( obsolete:OBSOLETE { et.track("OBSOLETE", obsolete); matchingRule.setObsolete( true ); } )
        |
        ( syntax:SYNTAX { et.track("SYNTAX", syntax); matchingRule.setSyntaxOid(numericoid(syntax.getText())); } )
        |
        ( extension:EXTENSION { 
            Extension ex = extension(extension.getText());
            et.track(ex.key, extension); 
            matchingRule.addExtension(ex.key, ex.values); 
         } )
    )*
    RPAR
    {
        if( !isQuirksModeEnabled )
        {    
            // semantic check: required elements
            if( !et.contains("SYNTAX") ) {
                throw new SemanticException( "SYNTAX is required", null, 0, 0 );
            }
        }
    }
    ;


    /**
     * Production for matching rule use descriptions. It is fault-tolerant
     * against element ordering.
     *
     * <pre>
     * MatchingRuleUseDescription = LPAREN WSP
     *    numericoid                 ; object identifier
     *    [ SP "NAME" SP qdescrs ]   ; short names (descriptors)
     *    [ SP "DESC" SP qdstring ]  ; description
     *    [ SP "OBSOLETE" ]          ; not active
     *    SP "APPLIES" SP oids       ; attribute types
     *    extensions WSP RPAREN      ; extensions
     * </pre>
    */
matchingRuleUseDescription returns [MatchingRuleUse matchingRuleUse]
    {
        matchedProduction( "matchingRuleUseDescription()" );
        ElementTracker et = new ElementTracker();
    }
    :
    ( oid:STARTNUMERICOID { matchingRuleUse = new MatchingRuleUse(numericoid(oid.getText())); } )
    (
        ( name:NAME { et.track("NAME", name); matchingRuleUse.setNames(qdescrs(name.getText())); } )
        |
        ( desc:DESC { et.track("DESC", desc); matchingRuleUse.setDescription(qdstring(desc.getText())); } )
        |
        ( obsolete:OBSOLETE { et.track("OBSOLETE", obsolete); matchingRuleUse.setObsolete( true ); } )
        |
        ( applies:APPLIES { et.track("APPLIES", applies); matchingRuleUse.setApplicableAttributeOids(oids(applies.getText())); } )
        |
        ( extension:EXTENSION { 
            Extension ex = extension(extension.getText());
            et.track(ex.key, extension); 
            matchingRuleUse.addExtension(ex.key, ex.values); 
         } )
    )*
    RPAR
    {
        if( !isQuirksModeEnabled )
        {
            // semantic check: required elements
            if( !et.contains("APPLIES") ) {
                throw new SemanticException( "APPLIES is required", null, 0, 0 );
            }
        }
    }
    ;


    /**
     * Production for DIT content rule descriptions. It is fault-tolerant
     * against element ordering.
     *
     * <pre>
     * DITContentRuleDescription = LPAREN WSP
     *    numericoid                 ; object identifier
     *    [ SP "NAME" SP qdescrs ]   ; short names (descriptors)
     *    [ SP "DESC" SP qdstring ]  ; description
     *    [ SP "OBSOLETE" ]          ; not active
     *    [ SP "AUX" SP oids ]       ; auxiliary object classes
     *    [ SP "MUST" SP oids ]      ; attribute types
     *    [ SP "MAY" SP oids ]       ; attribute types
     *    [ SP "NOT" SP oids ]       ; attribute types
     *    extensions WSP RPAREN      ; extensions
     * </pre>
    */
ditContentRuleDescription returns [DitContentRule ditContentRule]
    {
        matchedProduction( "ditContentRuleDescription()" );
        ElementTracker et = new ElementTracker();
    }
    :
    ( oid:STARTNUMERICOID { ditContentRule = new DitContentRule(numericoid(oid.getText())); } )
    (
        ( name:NAME { et.track("NAME", name); ditContentRule.setNames(qdescrs(name.getText())); } )
        |
        ( desc:DESC { et.track("DESC", desc); ditContentRule.setDescription(qdstring(desc.getText())); } )
        |
        ( obsolete:OBSOLETE { et.track("OBSOLETE", obsolete); ditContentRule.setObsolete( true ); } )
        |
        ( aux:AUX { et.track("AUX", aux); ditContentRule.setAuxObjectClassOids(oids(aux.getText())); } )
        |
        ( must:MUST { et.track("MUST", must); ditContentRule.setMustAttributeTypeOids(oids(must.getText())); } )
        |
        ( may:MAY { et.track("MAY", may); ditContentRule.setMayAttributeTypeOids(oids(may.getText())); } )
        |
        ( not:NOT { et.track("NOT", not); ditContentRule.setNotAttributeTypeOids(oids(not.getText())); } )
        |
        ( extension:EXTENSION { 
            Extension ex = extension(extension.getText());
            et.track(ex.key, extension); 
            ditContentRule.addExtension(ex.key, ex.values); 
         } )
    )*
    RPAR
    ;


    /**
     * Production for DIT structure rules descriptions. It is fault-tolerant
     * against element ordering.
     *
     * <pre>
     * DITStructureRuleDescription = LPAREN WSP
     *   ruleid                     ; rule identifier
     *   [ SP "NAME" SP qdescrs ]   ; short names (descriptors)
     *   [ SP "DESC" SP qdstring ]  ; description
     *   [ SP "OBSOLETE" ]          ; not active
     *   SP "FORM" SP oid           ; NameForm
     *   [ SP "SUP" ruleids ]       ; superior rules
     *   extensions WSP RPAREN      ; extensions
     *
     * ruleids = ruleid / ( LPAREN WSP ruleidlist WSP RPAREN )
     * ruleidlist = ruleid *( SP ruleid )
     * ruleid = number
     * </pre>
    */
ditStructureRuleDescription returns [DitStructureRule ditStructureRule]
    {
        matchedProduction( "ditStructureRuleDescription()" );
        ElementTracker et = new ElementTracker();
    }
    :
    ( ruleid:STARTNUMERICOID { ditStructureRule = new DitStructureRule(ruleid(ruleid.getText())); } )
    (
        ( name:NAME { et.track("NAME", name); ditStructureRule.setNames(qdescrs(name.getText())); } )
        |
        ( desc:DESC { et.track("DESC", desc); ditStructureRule.setDescription(qdstring(desc.getText())); } )
        |
        ( obsolete:OBSOLETE { et.track("OBSOLETE", obsolete); ditStructureRule.setObsolete( true ); } )
        |
        ( form:FORM { et.track("FORM", form); ditStructureRule.setForm(oid(form.getText())); } )
        |
        ( sup:SUP { et.track("SUP", sup); ditStructureRule.setSuperRules(ruleids(sup.getText())); } )
        |
        ( extension:EXTENSION { 
            Extension ex = extension(extension.getText());
            et.track(ex.key, extension); 
            ditStructureRule.addExtension(ex.key, ex.values); 
         } )
    )*
    RPAR
    {
        if( !isQuirksModeEnabled )
        {
            // semantic check: required elements
            if( !et.contains("FORM") ) {
                throw new SemanticException( "FORM is required", null, 0, 0 );
            }
        }
    }
    ;


    /**
     * Production for name form descriptions. It is fault-tolerant
     * against element ordering.
     *
     * <pre>
     * NameFormDescription = LPAREN WSP
     *    numericoid                 ; object identifier
     *    [ SP "NAME" SP qdescrs ]   ; short names (descriptors)
     *    [ SP "DESC" SP qdstring ]  ; description
     *    [ SP "OBSOLETE" ]          ; not active
     *    SP "OC" SP oid             ; structural object class
     *    SP "MUST" SP oids          ; attribute types
     *    [ SP "MAY" SP oids ]       ; attribute types
     *    extensions WSP RPAREN      ; extensions
     * </pre>
    */
nameFormDescription returns [NameForm nameForm]
    {
        matchedProduction( "nameFormDescription()" );
        ElementTracker et = new ElementTracker();
    }
    :
    ( oid:STARTNUMERICOID { nameForm = new NameForm(numericoid(oid.getText())); } )
    (
        ( name:NAME { et.track("NAME", name); nameForm.setNames(qdescrs(name.getText())); } )
        |
        ( desc:DESC { et.track("DESC", desc); nameForm.setDescription(qdstring(desc.getText())); } )
        |
        ( obsolete:OBSOLETE { et.track("OBSOLETE", obsolete); nameForm.setObsolete( true ); } )
        |
        ( oc:OC { et.track("OC", oc); nameForm.setStructuralObjectClassOid(oid(oc.getText())); } )
        |
        ( must:MUST { et.track("MUST", must); nameForm.setMustAttributeTypeOids(oids(must.getText())); } )
        |
        ( may:MAY { et.track("MAY", may); nameForm.setMayAttributeTypeOids(oids(may.getText())); } )
        |
        ( extension:EXTENSION { 
            Extension ex = extension(extension.getText());
            et.track(ex.key, extension); 
            nameForm.addExtension(ex.key, ex.values); 
         } )
    )*
    RPAR
    {
        if( !isQuirksModeEnabled )
        {
            // semantic check: required elements
            if( !et.contains("MUST") ) {
                throw new SemanticException( "MUST is required", null, 0, 0 );
            }
            if( !et.contains("OC") ) {
                throw new SemanticException( "OC is required", null, 0, 0 );
            }
        
            // semantic check: MUST and MAY must be disjoint
            //List<String> aList = new ArrayList<String>( nfd.getMustAttributeTypes() );
            //aList.retainAll( nfd.getMayAttributeTypes() );
            //if( !aList.isEmpty() ) 
            //{
            //    throw new SemanticException( "MUST and MAY must be disjoint, "+aList.get( 0 )+" appears in both", null, 0, 0 );
            //}
        }
    }
    ;
    

    /**
     * Production for comparator descriptions. It is fault-tolerant
     * against element ordering.
     *
     * <pre>
     * LdapComparator = LPAREN WSP
     *       numericoid                           ; object identifier
     *       [ SP "DESC" SP qdstring ]            ; description
     *       SP "FQCN" SP fqcn                    ; fully qualified class name
     *       [ SP "BYTECODE" SP base64 ]          ; optional base64 encoded bytecode
     *       extensions WSP RPAREN                ; extensions
     * 
     * base64          = *(4base64-char)
     * base64-char     = ALPHA / DIGIT / "+" / "/"
     * fqcn = fqcnComponent 1*( DOT fqcnComponent )
     * fqcnComponent = ???
     * </pre>
    */
ldapComparator returns [LdapComparatorDescription lcd]
    {
        matchedProduction( "ldapComparator()" );
        ElementTracker et = new ElementTracker();
    }
    :
    ( oid:STARTNUMERICOID { lcd = new LdapComparatorDescription(numericoid(oid.getText())); } )
    (
        ( desc:DESC { et.track("DESC", desc); lcd.setDescription(qdstring(desc.getText())); } )
        |
        ( fqcn:FQCN { et.track("FQCN", fqcn); lcd.setFqcn(fqcn.getText()); } )
        |
        ( bytecode:BYTECODE { et.track("BYTECODE", bytecode); lcd.setBytecode(bytecode.getText()); } )
        |
        ( extension:EXTENSION { 
            Extension ex = extension(extension.getText());
            et.track(ex.key, extension); 
            lcd.addExtension(ex.key, ex.values); 
         } )
    )*
    RPAR
    {
        if( !isQuirksModeEnabled )
        {
            // semantic check: required elements
            if( !et.contains("FQCN") ) {
                throw new SemanticException( "FQCN is required", null, 0, 0 );
            }
        
            // semantic check: length should be divisible by 4
            if( ( lcd.getBytecode() != null ) && ( lcd.getBytecode().length() % 4 != 0 ) ) {
                throw new SemanticException( "BYTECODE must be divisible by 4", null, 0, 0 );
            }
        }
    }
    ;
    

    /**
     * Production for normalizer descriptions. It is fault-tolerant
     * against element ordering.
     *
     * <pre>
     * NormalizerDescription = LPAREN WSP
     *       numericoid                           ; object identifier
     *       [ SP "DESC" SP qdstring ]            ; description
     *       SP "FQCN" SP fqcn                    ; fully qualified class name
     *       [ SP "BYTECODE" SP base64 ]          ; optional base64 encoded bytecode
     *       extensions WSP RPAREN                ; extensions
     * 
     * base64          = *(4base64-char)
     * base64-char     = ALPHA / DIGIT / "+" / "/"
     * fqcn = fqcnComponent 1*( DOT fqcnComponent )
     * fqcnComponent = ???
     * </pre>
    */
normalizerDescription returns [NormalizerDescription nd]
    {
        matchedProduction( "normalizerDescription()" );
        ElementTracker et = new ElementTracker();
    }
    :
    ( oid:STARTNUMERICOID { nd = new NormalizerDescription(numericoid(oid.getText())); } )
    (
        ( desc:DESC { et.track("DESC", desc); nd.setDescription(qdstring(desc.getText())); } )
        |
        ( fqcn:FQCN { et.track("FQCN", fqcn); nd.setFqcn(fqcn.getText()); } )
        |
        ( bytecode:BYTECODE { et.track("BYTECODE", bytecode); nd.setBytecode(bytecode.getText()); } )
        |
        ( extension:EXTENSION { 
            Extension ex = extension(extension.getText());
            et.track(ex.key, extension); 
            nd.addExtension(ex.key, ex.values); 
         } )
    )*
    RPAR
    {
        if( !isQuirksModeEnabled )
        {
            // semantic check: required elements
            if( !et.contains("FQCN") ) {
                throw new SemanticException( "FQCN is required", null, 0, 0 );
            }
        
            // semantic check: length should be divisible by 4
            if( nd.getBytecode() != null && ( nd.getBytecode().length() % 4 != 0 ) ) {
                throw new SemanticException( "BYTECODE must be divisible by 4", null, 0, 0 );
            }     
        }   
    }
    ;
    

    /**
     * Production for syntax checker descriptions. It is fault-tolerant
     * against element ordering.
     *
     * <pre>
     * SyntaxCheckerDescription = LPAREN WSP
     *       numericoid                           ; object identifier
     *       [ SP "DESC" SP qdstring ]            ; description
     *       SP "FQCN" SP fqcn                    ; fully qualified class name
     *       [ SP "BYTECODE" SP base64 ]          ; optional base64 encoded bytecode
     *       extensions WSP RPAREN                ; extensions
     * 
     * base64          = *(4base64-char)
     * base64-char     = ALPHA / DIGIT / "+" / "/"
     * fqcn = fqcnComponent 1*( DOT fqcnComponent )
     * fqcnComponent = ???
     * </pre>
    */
syntaxCheckerDescription returns [SyntaxCheckerDescription scd]
    {
        matchedProduction( "syntaxCheckerDescription()" );
        ElementTracker et = new ElementTracker();
    }
    :
    ( oid:STARTNUMERICOID { scd = new SyntaxCheckerDescription(numericoid(oid.getText())); } )
    (
        ( desc:DESC { et.track("DESC", desc); scd.setDescription(qdstring(desc.getText())); } )
        |
        ( fqcn:FQCN { et.track("FQCN", fqcn); scd.setFqcn(fqcn.getText()); } )
        |
        ( bytecode:BYTECODE { et.track("BYTECODE", bytecode); scd.setBytecode(bytecode.getText()); } )
        |
        ( extension:EXTENSION { 
            Extension ex = extension(extension.getText());
            et.track(ex.key, extension); 
            scd.addExtension(ex.key, ex.values); 
         } )
    )*
    RPAR
    {
        if( !isQuirksModeEnabled )
        {
            // semantic check: required elements
            if( !et.contains("FQCN") ) {
                throw new SemanticException( "FQCN is required", null, 0, 0 );
            }
        
            // semantic check: length should be divisible by 4
            if( scd.getBytecode() != null && ( scd.getBytecode().length() % 4 != 0 ) ) {
                throw new SemanticException( "BYTECODE must be divisible by 4", null, 0, 0 );
            }  
        }      
    }
    ;
    



noidlen [String s] returns [NoidLen noidlen]
    {
        matchedProduction( "noidlen()" );
        AntlrSchemaValueLexer lexer = new AntlrSchemaValueLexer(new StringReader(s));
        AntlrSchemaValueParser parser = new AntlrSchemaValueParser(lexer);
        parser.setParserMonitor(monitor);
        noidlen = isQuirksModeEnabled ? parser.quirksNoidlen() : parser.noidlen();
    }
    :
    ;


extension [String s] returns [Extension extension]
    {
        matchedProduction( "extension()" );
        AntlrSchemaExtensionLexer lexer = new AntlrSchemaExtensionLexer(new StringReader(s));
        AntlrSchemaExtensionParser parser = new AntlrSchemaExtensionParser(lexer);
        extension = parser.extension();
    }
    :
    ;


numericoid [String s] returns [String numericoid]
    {
        matchedProduction( "numericoid()");
        if(isQuirksModeEnabled)
        {
             numericoid = oid(s);
        }
        else
        {
	        AntlrSchemaValueLexer lexer = new AntlrSchemaValueLexer(new StringReader(s));
	        AntlrSchemaValueParser parser = new AntlrSchemaValueParser(lexer);
	        parser.setParserMonitor(monitor);
	        numericoid = parser.numericoid();
        }
    }
    :
    ;

oid [String s] returns [String oid]
    {
        matchedProduction( "oid()" );
        List<String> oids = oids(s);
        if( oids.size() != 1 ) 
        {
            throw new SemanticException( "Exactly one OID expected", null, 0, 0 );
        }
        oid = oids.get(0);
    }
    :
    ;

oids [String s] returns [List<String> oids]
    {
        matchedProduction( "oids()" );
        if(isQuirksModeEnabled)
        {
             oids = qdescrs(s);
        }
        else
        {
	        AntlrSchemaValueLexer lexer = new AntlrSchemaValueLexer(new StringReader(s));
	        AntlrSchemaValueParser parser = new AntlrSchemaValueParser(lexer);
	        parser.setParserMonitor(monitor);
	        oids = parser.oids();
	    }
    }
    :
    ;

qdescr [String s] returns [String qdescr]
    {
        matchedProduction( "qdescr()" );
        List<String> qdescrs = qdescrs(s);
        if( qdescrs.size() != 1 ) 
        {
            throw new SemanticException( "Exactly one qdescrs expected", null, 0, 0 );
        }
        qdescr = qdescrs.get(0);
    }
    :
    ;

qdescrs [String s] returns [List<String> qdescrs]
    {
        matchedProduction( "qdescrs()" );
        AntlrSchemaValueLexer lexer = new AntlrSchemaValueLexer(new StringReader(s));
        AntlrSchemaValueParser parser = new AntlrSchemaValueParser(lexer);
        parser.setParserMonitor(monitor);
        qdescrs = isQuirksModeEnabled ? parser.quirksQdescrs() : parser.qdescrs();
    }
    :
    ;

qdstring [String s] returns [String qdstring]
    {
        matchedProduction( "qdstring()" );
        List<String> qdstrings = qdstrings(s);
        if( qdstrings.size() != 1 ) 
        {
            throw new SemanticException( "Exactly one qdstrings expected", null, 0, 0 );
        }
        qdstring = qdstrings.get(0);
    }
    :
    ;

qdstrings [String s] returns [List<String> qdstrings]
    {
        matchedProduction( "qdstrings()" );
        AntlrSchemaQdstringLexer lexer = new AntlrSchemaQdstringLexer(new StringReader(s));
        AntlrSchemaQdstringParser parser = new AntlrSchemaQdstringParser(lexer);
        parser.setParserMonitor(monitor);
        qdstrings = parser.qdstrings();
    }
    :
    ;

ruleid [String s] returns [Integer ruleid]
    {
        matchedProduction( "ruleid()" );
        AntlrSchemaValueLexer lexer = new AntlrSchemaValueLexer(new StringReader(s));
        AntlrSchemaValueParser parser = new AntlrSchemaValueParser(lexer);
        parser.setParserMonitor(monitor);
        ruleid = parser.ruleid();
    }
    :
    ;

ruleids [String s] returns [List<Integer> ruleids]
    {
        matchedProduction( "ruleids()" );
        AntlrSchemaValueLexer lexer = new AntlrSchemaValueLexer(new StringReader(s));
        AntlrSchemaValueParser parser = new AntlrSchemaValueParser(lexer);
        parser.setParserMonitor(monitor);
        ruleids = parser.ruleids();
    }
    :
    ;


    
