001// $ANTLR 2.7.7 (20060906): "schema.g" -> "AntlrSchemaParser.java"$
002
003/*
004 *  Licensed to the Apache Software Foundation (ASF) under one
005 *  or more contributor license agreements.  See the NOTICE file
006 *  distributed with this work for additional information
007 *  regarding copyright ownership.  The ASF licenses this file
008 *  to you under the Apache License, Version 2.0 (the
009 *  "License"); you may not use this file except in compliance
010 *  with the License.  You may obtain a copy of the License at
011 *  
012 *    http://www.apache.org/licenses/LICENSE-2.0
013 *  
014 *  Unless required by applicable law or agreed to in writing,
015 *  software distributed under the License is distributed on an
016 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 *  KIND, either express or implied.  See the License for the
018 *  specific language governing permissions and limitations
019 *  under the License. 
020 *  
021 */
022package org.apache.directory.api.ldap.model.schema.syntaxes;
023
024import java.io.StringReader;
025import java.util.ArrayList;
026import java.util.HashMap;
027import java.util.List;
028import java.util.Map;
029
030import org.apache.directory.api.ldap.model.schema.parsers.LdapComparatorDescription;
031import org.apache.directory.api.ldap.model.schema.DitContentRule;
032import org.apache.directory.api.ldap.model.schema.DitStructureRule;
033import org.apache.directory.api.ldap.model.schema.LdapSyntax;
034import org.apache.directory.api.ldap.model.schema.MatchingRule;
035import org.apache.directory.api.ldap.model.schema.MutableMatchingRule;
036import org.apache.directory.api.ldap.model.schema.MatchingRuleUse;
037import org.apache.directory.api.ldap.model.schema.NameForm;
038import org.apache.directory.api.ldap.model.schema.parsers.NormalizerDescription;
039import org.apache.directory.api.ldap.model.schema.parsers.ParserMonitor;
040import org.apache.directory.api.ldap.model.schema.AttributeType;
041import org.apache.directory.api.ldap.model.schema.MutableAttributeType;
042import org.apache.directory.api.ldap.model.schema.ObjectClass;
043import org.apache.directory.api.ldap.model.schema.MutableObjectClass;
044import org.apache.directory.api.ldap.model.schema.parsers.SyntaxCheckerDescription;
045import org.apache.directory.api.ldap.model.schema.syntaxCheckers.OpenLdapObjectIdentifierMacro;
046import org.apache.directory.api.ldap.model.schema.ObjectClassTypeEnum;
047import org.apache.directory.api.ldap.model.schema.UsageEnum;
048
049
050import antlr.TokenBuffer;
051import antlr.TokenStreamException;
052import antlr.TokenStreamIOException;
053import antlr.ANTLRException;
054import antlr.LLkParser;
055import antlr.Token;
056import antlr.TokenStream;
057import antlr.RecognitionException;
058import antlr.NoViableAltException;
059import antlr.MismatchedTokenException;
060import antlr.SemanticException;
061import antlr.ParserSharedInputState;
062import antlr.collections.impl.BitSet;
063
064/**
065 * An antlr generated schema main parser.
066 *
067 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
068 */
069public class AntlrSchemaParser extends antlr.LLkParser       implements AntlrSchemaTokenTypes
070 {
071
072    private ParserMonitor monitor = null;
073    private boolean isQuirksModeEnabled = false;
074    public void setParserMonitor( ParserMonitor monitor )
075    {
076        this.monitor = monitor;
077    }
078    private void matchedProduction( String msg )
079    {
080        if ( null != monitor )
081        {
082            monitor.matchedProduction( msg );
083        }
084    }
085    public void setQuirksMode( boolean enabled )
086    {
087        this.isQuirksModeEnabled = enabled;
088    }
089    public boolean isQuirksMode()
090    {
091        return this.isQuirksModeEnabled;
092    }
093    static class Extension
094    {
095        String key = "";
096        List<String> values = new ArrayList<String>();
097        
098        public void addValue( String value )
099        {
100            this.values.add( value );
101        }
102    }
103    static class NoidLen
104    {
105        String noid = "";
106        long len = 0L;
107    }
108    static class ElementTracker
109    {
110        Map<String, Integer> elementMap = new HashMap<String, Integer>();
111        void track(String element, Token token) throws SemanticException 
112        {
113            if(elementMap.containsKey(element))
114            {
115                throw new SemanticException( element + " appears twice.", token.getFilename(), token.getLine() , token.getColumn() );
116            }
117            elementMap.put(element, Integer.valueOf(1));
118        }
119        boolean contains(String element) 
120        {
121            return elementMap.containsKey(element);
122        }
123    }
124
125
126protected AntlrSchemaParser(TokenBuffer tokenBuf, int k) {
127  super(tokenBuf,k);
128  tokenNames = _tokenNames;
129}
130
131public AntlrSchemaParser(TokenBuffer tokenBuf) {
132  this(tokenBuf,3);
133}
134
135protected AntlrSchemaParser(TokenStream lexer, int k) {
136  super(lexer,k);
137  tokenNames = _tokenNames;
138}
139
140public AntlrSchemaParser(TokenStream lexer) {
141  this(lexer,3);
142}
143
144public AntlrSchemaParser(ParserSharedInputState state) {
145  super(state,3);
146  tokenNames = _tokenNames;
147}
148
149        public final List<Object>  openLdapSchema() throws RecognitionException, TokenStreamException {
150                List<Object> list = new ArrayList<Object>();
151                
152                
153                AttributeType attributeType = null;
154                ObjectClass objectClass = null;
155                OpenLdapObjectIdentifierMacro oloid = null;
156                
157                
158                {
159                _loop155:
160                do {
161                        switch ( LA(1)) {
162                        case OBJECTIDENTIFIER:
163                        {
164                                oloid=openLdapObjectIdentifier();
165                                list.add( oloid );
166                                break;
167                        }
168                        case ATTRIBUTETYPE:
169                        {
170                                attributeType=openLdapAttributeType();
171                                list.add( attributeType );
172                                break;
173                        }
174                        case OBJECTCLASS:
175                        {
176                                objectClass=openLdapObjectClass();
177                                list.add( objectClass );
178                                break;
179                        }
180                        default:
181                        {
182                                break _loop155;
183                        }
184                        }
185                } while (true);
186                }
187                return list;
188        }
189        
190        public final OpenLdapObjectIdentifierMacro  openLdapObjectIdentifier() throws RecognitionException, TokenStreamException {
191                OpenLdapObjectIdentifierMacro oloid;
192                
193                Token  oi = null;
194                
195                matchedProduction( "openLdapObjectIdentifier()" );
196                
197                
198                {
199                oi = LT(1);
200                match(OBJECTIDENTIFIER);
201                
202                String[] nameAndValue = oi.getText().split( " " );
203                oloid = new OpenLdapObjectIdentifierMacro();
204                oloid.setName( nameAndValue[0] );
205                oloid.setRawOidOrNameSuffix( nameAndValue[1] );
206                
207                }
208                return oloid;
209        }
210        
211        public final AttributeType  openLdapAttributeType() throws RecognitionException, TokenStreamException {
212                AttributeType attributeType;
213                
214                
215                matchedProduction( "openLdapAttributeType()" );
216                
217                
218                {
219                match(ATTRIBUTETYPE);
220                {
221                attributeType=attributeTypeDescription();
222                }
223                }
224                return attributeType;
225        }
226        
227        public final ObjectClass  openLdapObjectClass() throws RecognitionException, TokenStreamException {
228                ObjectClass objectClass;
229                
230                
231                matchedProduction( "openLdapObjectClass()" );
232                
233                
234                {
235                match(OBJECTCLASS);
236                {
237                objectClass=objectClassDescription();
238                }
239                }
240                return objectClass;
241        }
242        
243/**
244     * Production for matching object class descriptions. It is fault-tolerant
245     * against element ordering.
246     *
247     * <pre>
248     * ObjectClassDescription = LPAREN WSP
249     *     numericoid                 ; object identifier
250     *     [ SP "NAME" SP qdescrs ]   ; short names (descriptors)
251     *     [ SP "DESC" SP qdstring ]  ; description
252     *     [ SP "OBSOLETE" ]          ; not active
253     *     [ SP "SUP" SP oids ]       ; superior object classes
254     *     [ SP kind ]                ; kind of class
255     *     [ SP "MUST" SP oids ]      ; attribute types
256     *     [ SP "MAY" SP oids ]       ; attribute types
257     *     extensions WSP RPAREN
258     *
259     * kind = "ABSTRACT" / "STRUCTURAL" / "AUXILIARY"
260     * 
261     * extensions = *( SP xstring SP qdstrings )
262     * xstring = "X" HYPHEN 1*( ALPHA / HYPHEN / USCORE ) 
263     * </pre>
264    */
265        public final MutableObjectClass  objectClassDescription() throws RecognitionException, TokenStreamException {
266                MutableObjectClass objectClass;
267                
268                Token  oid = null;
269                Token  name = null;
270                Token  desc = null;
271                Token  obsolete = null;
272                Token  sup = null;
273                Token  kind1 = null;
274                Token  kind2 = null;
275                Token  kind3 = null;
276                Token  must = null;
277                Token  may = null;
278                Token  extension = null;
279                
280                matchedProduction( "objectClassDescription()" );
281                ElementTracker et = new ElementTracker();
282                
283                
284                {
285                oid = LT(1);
286                match(STARTNUMERICOID);
287                objectClass = new MutableObjectClass(numericoid(oid.getText()));
288                }
289                {
290                _loop175:
291                do {
292                        switch ( LA(1)) {
293                        case NAME:
294                        {
295                                {
296                                name = LT(1);
297                                match(NAME);
298                                et.track("NAME", name); objectClass.setNames(qdescrs(name.getText()));
299                                }
300                                break;
301                        }
302                        case DESC:
303                        {
304                                {
305                                desc = LT(1);
306                                match(DESC);
307                                et.track("DESC", desc); objectClass.setDescription(qdstring(desc.getText()));
308                                }
309                                break;
310                        }
311                        case OBSOLETE:
312                        {
313                                {
314                                obsolete = LT(1);
315                                match(OBSOLETE);
316                                et.track("OBSOLETE", obsolete); objectClass.setObsolete( true );
317                                }
318                                break;
319                        }
320                        case SUP:
321                        {
322                                {
323                                sup = LT(1);
324                                match(SUP);
325                                et.track("SUP", sup); objectClass.setSuperiorOids(oids(sup.getText()));
326                                }
327                                break;
328                        }
329                        case ABSTRACT:
330                        case STRUCTURAL:
331                        case AUXILIARY:
332                        {
333                                {
334                                switch ( LA(1)) {
335                                case ABSTRACT:
336                                {
337                                        kind1 = LT(1);
338                                        match(ABSTRACT);
339                                        et.track("KIND", kind1); objectClass.setType( ObjectClassTypeEnum.ABSTRACT );
340                                        break;
341                                }
342                                case STRUCTURAL:
343                                {
344                                        kind2 = LT(1);
345                                        match(STRUCTURAL);
346                                        et.track("KIND", kind2); objectClass.setType( ObjectClassTypeEnum.STRUCTURAL );
347                                        break;
348                                }
349                                case AUXILIARY:
350                                {
351                                        kind3 = LT(1);
352                                        match(AUXILIARY);
353                                        et.track("KIND", kind3); objectClass.setType( ObjectClassTypeEnum.AUXILIARY );
354                                        break;
355                                }
356                                default:
357                                {
358                                        throw new NoViableAltException(LT(1), getFilename());
359                                }
360                                }
361                                }
362                                break;
363                        }
364                        case MUST:
365                        {
366                                {
367                                must = LT(1);
368                                match(MUST);
369                                et.track("MUST", must); objectClass.setMustAttributeTypeOids(oids(must.getText()));
370                                }
371                                break;
372                        }
373                        case MAY:
374                        {
375                                {
376                                may = LT(1);
377                                match(MAY);
378                                et.track("MAY", may); objectClass.setMayAttributeTypeOids(oids(may.getText()));
379                                }
380                                break;
381                        }
382                        case EXTENSION:
383                        {
384                                {
385                                extension = LT(1);
386                                match(EXTENSION);
387                                
388                                Extension ex = extension(extension.getText());
389                                et.track(ex.key, extension); 
390                                objectClass.addExtension(ex.key, ex.values); 
391                                
392                                }
393                                break;
394                        }
395                        default:
396                        {
397                                break _loop175;
398                        }
399                        }
400                } while (true);
401                }
402                match(RPAR);
403                return objectClass;
404        }
405        
406/**
407     * Production for matching attribute type descriptions. It is fault-tolerant
408     * against element ordering.
409     *
410     * <pre>
411     * AttributeTypeDescription = LPAREN WSP
412     *     numericoid                    ; object identifier
413     *     [ SP "NAME" SP qdescrs ]      ; short names (descriptors)
414     *     [ SP "DESC" SP qdstring ]     ; description
415     *     [ SP "OBSOLETE" ]             ; not active
416     *     [ SP "SUP" SP oid ]           ; supertype
417     *     [ SP "EQUALITY" SP oid ]      ; equality matching rule
418     *     [ SP "ORDERING" SP oid ]      ; ordering matching rule
419     *     [ SP "SUBSTR" SP oid ]        ; substrings matching rule
420     *     [ SP "SYNTAX" SP noidlen ]    ; value syntax
421     *     [ SP "SINGLE-VALUE" ]         ; single-value
422     *     [ SP "COLLECTIVE" ]           ; collective
423     *     [ SP "NO-USER-MODIFICATION" ] ; not user modifiable
424     *     [ SP "USAGE" SP usage ]       ; usage
425     *     extensions WSP RPAREN         ; extensions
426     * 
427     * usage = "userApplications"     /  ; user
428     *         "directoryOperation"   /  ; directory operational
429     *         "distributedOperation" /  ; DSA-shared operational
430     *         "dSAOperation"            ; DSA-specific operational     
431     * 
432     * extensions = *( SP xstring SP qdstrings )
433     * xstring = "X" HYPHEN 1*( ALPHA / HYPHEN / USCORE ) 
434     * </pre>
435    */
436        public final MutableAttributeType  attributeTypeDescription() throws RecognitionException, TokenStreamException {
437                MutableAttributeType attributeType;
438                
439                Token  oid = null;
440                Token  name = null;
441                Token  desc = null;
442                Token  obsolete = null;
443                Token  superior = null;
444                Token  equality = null;
445                Token  ordering = null;
446                Token  substring = null;
447                Token  syntax = null;
448                Token  singleValued = null;
449                Token  collective = null;
450                Token  noUserModification = null;
451                Token  usage1 = null;
452                Token  usage2 = null;
453                Token  usage3 = null;
454                Token  usage4 = null;
455                Token  extension = null;
456                
457                matchedProduction( "attributeTypeDescription()" );
458                ElementTracker et = new ElementTracker();
459                
460                
461                {
462                oid = LT(1);
463                match(STARTNUMERICOID);
464                attributeType = new MutableAttributeType(numericoid(oid.getText()));
465                }
466                {
467                _loop194:
468                do {
469                        switch ( LA(1)) {
470                        case NAME:
471                        {
472                                {
473                                name = LT(1);
474                                match(NAME);
475                                et.track("NAME", name); attributeType.setNames(qdescrs(name.getText()));
476                                }
477                                break;
478                        }
479                        case DESC:
480                        {
481                                {
482                                desc = LT(1);
483                                match(DESC);
484                                et.track("DESC", desc); attributeType.setDescription(qdstring(desc.getText()));
485                                }
486                                break;
487                        }
488                        case OBSOLETE:
489                        {
490                                {
491                                obsolete = LT(1);
492                                match(OBSOLETE);
493                                et.track("OBSOLETE", obsolete); attributeType.setObsolete( true );
494                                }
495                                break;
496                        }
497                        case SUP:
498                        {
499                                {
500                                superior = LT(1);
501                                match(SUP);
502                                et.track("SUP", superior); attributeType.setSuperiorOid(oid(superior.getText()));
503                                }
504                                break;
505                        }
506                        case EQUALITY:
507                        {
508                                {
509                                equality = LT(1);
510                                match(EQUALITY);
511                                et.track("EQUALITY", equality); attributeType.setEqualityOid(oid(equality.getText()));
512                                }
513                                break;
514                        }
515                        case ORDERING:
516                        {
517                                {
518                                ordering = LT(1);
519                                match(ORDERING);
520                                et.track("ORDERING", ordering); attributeType.setOrderingOid(oid(ordering.getText()));
521                                }
522                                break;
523                        }
524                        case SUBSTR:
525                        {
526                                {
527                                substring = LT(1);
528                                match(SUBSTR);
529                                et.track("SUBSTR", substring); attributeType.setSubstringOid(oid(substring.getText()));
530                                }
531                                break;
532                        }
533                        case SYNTAX:
534                        {
535                                {
536                                syntax = LT(1);
537                                match(SYNTAX);
538                                
539                                et.track("SYNTAX", syntax); 
540                                NoidLen noidlen = noidlen(syntax.getText());
541                                attributeType.setSyntaxOid(noidlen.noid); 
542                                attributeType.setSyntaxLength(noidlen.len);
543                                
544                                }
545                                break;
546                        }
547                        case SINGLE_VALUE:
548                        {
549                                {
550                                singleValued = LT(1);
551                                match(SINGLE_VALUE);
552                                et.track("SINGLE_VALUE", singleValued); attributeType.setSingleValued( true );
553                                }
554                                break;
555                        }
556                        case COLLECTIVE:
557                        {
558                                {
559                                collective = LT(1);
560                                match(COLLECTIVE);
561                                et.track("COLLECTIVE", collective); attributeType.setCollective( true );
562                                }
563                                break;
564                        }
565                        case NO_USER_MODIFICATION:
566                        {
567                                {
568                                noUserModification = LT(1);
569                                match(NO_USER_MODIFICATION);
570                                et.track("NO_USER_MODIFICATION", noUserModification); attributeType.setUserModifiable( false );
571                                }
572                                break;
573                        }
574                        case USAGE:
575                        {
576                                {
577                                if ((LA(1)==USAGE) && (LA(2)==WHSP||LA(2)==USER_APPLICATIONS)) {
578                                        usage1 = LT(1);
579                                        match(USAGE);
580                                        {
581                                        _loop192:
582                                        do {
583                                                if ((LA(1)==WHSP)) {
584                                                        match(WHSP);
585                                                }
586                                                else {
587                                                        break _loop192;
588                                                }
589                                                
590                                        } while (true);
591                                        }
592                                        match(USER_APPLICATIONS);
593                                        et.track("USAGE", usage1); attributeType.setUsage( UsageEnum.USER_APPLICATIONS );
594                                }
595                                else if ((LA(1)==USAGE) && (LA(2)==DIRECTORY_OPERATION)) {
596                                        usage2 = LT(1);
597                                        match(USAGE);
598                                        match(DIRECTORY_OPERATION);
599                                        et.track("USAGE", usage2); attributeType.setUsage( UsageEnum.DIRECTORY_OPERATION );
600                                }
601                                else if ((LA(1)==USAGE) && (LA(2)==DISTRIBUTED_OPERATION)) {
602                                        usage3 = LT(1);
603                                        match(USAGE);
604                                        match(DISTRIBUTED_OPERATION);
605                                        et.track("USAGE", usage3); attributeType.setUsage( UsageEnum.DISTRIBUTED_OPERATION );
606                                }
607                                else if ((LA(1)==USAGE) && (LA(2)==DSA_OPERATION)) {
608                                        usage4 = LT(1);
609                                        match(USAGE);
610                                        match(DSA_OPERATION);
611                                        et.track("USAGE", usage4); attributeType.setUsage( UsageEnum.DSA_OPERATION );
612                                }
613                                else {
614                                        throw new NoViableAltException(LT(1), getFilename());
615                                }
616                                
617                                }
618                                break;
619                        }
620                        case EXTENSION:
621                        {
622                                {
623                                extension = LT(1);
624                                match(EXTENSION);
625                                
626                                Extension ex = extension(extension.getText());
627                                et.track(ex.key, extension); 
628                                attributeType.addExtension(ex.key, ex.values); 
629                                
630                                }
631                                break;
632                        }
633                        default:
634                        {
635                                break _loop194;
636                        }
637                        }
638                } while (true);
639                }
640                match(RPAR);
641                
642                if( !isQuirksModeEnabled )
643                {
644                // semantic check: required elements
645                if( !et.contains("SYNTAX") && !et.contains("SUP") ) 
646                {
647                throw new SemanticException( "One of SYNTAX or SUP is required", null, 0, 0 );
648                }
649                
650                // COLLECTIVE requires USAGE userApplications
651                if ( attributeType.isCollective() && ( attributeType.getUsage() != UsageEnum.USER_APPLICATIONS ) )
652                {
653                throw new SemanticException( "COLLECTIVE requires USAGE userApplications", null, 0, 0 );
654                }
655                
656                // NO-USER-MODIFICATION requires an operational USAGE.
657                if ( !attributeType.isUserModifiable() && ( attributeType.getUsage() == UsageEnum.USER_APPLICATIONS ) )
658                {
659                throw new SemanticException( "NO-USER-MODIFICATION requires an operational USAGE", null, 0, 0 );
660                }
661                }
662                
663                return attributeType;
664        }
665        
666/**
667     * Production for matching ldap syntax descriptions. It is fault-tolerant
668     * against element ordering.
669     *
670     * <pre>
671     * SyntaxDescription = LPAREN WSP
672     *    numericoid                 ; object identifier
673     *    [ SP "DESC" SP qdstring ]  ; description
674     *    extensions WSP RPAREN      ; extensions
675     * </pre>
676    */
677        public final LdapSyntax  ldapSyntaxDescription() throws RecognitionException, TokenStreamException {
678                LdapSyntax ldapSyntax;
679                
680                Token  oid = null;
681                Token  name = null;
682                Token  desc = null;
683                Token  extension = null;
684                
685                matchedProduction( "ldapSyntaxDescription()" );
686                ElementTracker et = new ElementTracker();
687                
688                
689                {
690                oid = LT(1);
691                match(STARTNUMERICOID);
692                ldapSyntax = new LdapSyntax(numericoid(oid.getText()));
693                }
694                {
695                _loop201:
696                do {
697                        switch ( LA(1)) {
698                        case NAME:
699                        {
700                                {
701                                name = LT(1);
702                                match(NAME);
703                                et.track("NAME", name); ldapSyntax.setNames(qdescrs(name.getText()));
704                                }
705                                break;
706                        }
707                        case DESC:
708                        {
709                                {
710                                desc = LT(1);
711                                match(DESC);
712                                et.track("DESC", desc); ldapSyntax.setDescription(qdstring(desc.getText()));
713                                }
714                                break;
715                        }
716                        case EXTENSION:
717                        {
718                                {
719                                extension = LT(1);
720                                match(EXTENSION);
721                                
722                                Extension ex = extension(extension.getText());
723                                et.track(ex.key, extension); 
724                                ldapSyntax.addExtension(ex.key, ex.values); 
725                                
726                                }
727                                break;
728                        }
729                        default:
730                        {
731                                break _loop201;
732                        }
733                        }
734                } while (true);
735                }
736                match(RPAR);
737                return ldapSyntax;
738        }
739        
740/**
741     * Production for matching rule descriptions. It is fault-tolerant
742     * against element ordering.
743     *
744     * <pre>
745     * MatchingRuleDescription = LPAREN WSP
746     *    numericoid                 ; object identifier
747     *    [ SP "NAME" SP qdescrs ]   ; short names (descriptors)
748     *    [ SP "DESC" SP qdstring ]  ; description
749     *    [ SP "OBSOLETE" ]          ; not active
750     *    SP "SYNTAX" SP numericoid  ; assertion syntax
751     *    extensions WSP RPAREN      ; extensions
752     * </pre>
753    */
754        public final MutableMatchingRule  matchingRuleDescription() throws RecognitionException, TokenStreamException {
755                MutableMatchingRule matchingRule;
756                
757                Token  oid = null;
758                Token  name = null;
759                Token  desc = null;
760                Token  obsolete = null;
761                Token  syntax = null;
762                Token  extension = null;
763                
764                matchedProduction( "matchingRuleDescription()" );
765                ElementTracker et = new ElementTracker();
766                
767                
768                {
769                oid = LT(1);
770                match(STARTNUMERICOID);
771                matchingRule = new MutableMatchingRule(numericoid(oid.getText()));
772                }
773                {
774                _loop210:
775                do {
776                        switch ( LA(1)) {
777                        case NAME:
778                        {
779                                {
780                                name = LT(1);
781                                match(NAME);
782                                et.track("NAME", name); matchingRule.setNames(qdescrs(name.getText()));
783                                }
784                                break;
785                        }
786                        case DESC:
787                        {
788                                {
789                                desc = LT(1);
790                                match(DESC);
791                                et.track("DESC", desc); matchingRule.setDescription(qdstring(desc.getText()));
792                                }
793                                break;
794                        }
795                        case OBSOLETE:
796                        {
797                                {
798                                obsolete = LT(1);
799                                match(OBSOLETE);
800                                et.track("OBSOLETE", obsolete); matchingRule.setObsolete( true );
801                                }
802                                break;
803                        }
804                        case SYNTAX:
805                        {
806                                {
807                                syntax = LT(1);
808                                match(SYNTAX);
809                                et.track("SYNTAX", syntax); matchingRule.setSyntaxOid(numericoid(syntax.getText()));
810                                }
811                                break;
812                        }
813                        case EXTENSION:
814                        {
815                                {
816                                extension = LT(1);
817                                match(EXTENSION);
818                                
819                                Extension ex = extension(extension.getText());
820                                et.track(ex.key, extension); 
821                                matchingRule.addExtension(ex.key, ex.values); 
822                                
823                                }
824                                break;
825                        }
826                        default:
827                        {
828                                break _loop210;
829                        }
830                        }
831                } while (true);
832                }
833                match(RPAR);
834                
835                if( !isQuirksModeEnabled )
836                {    
837                // semantic check: required elements
838                if( !et.contains("SYNTAX") ) {
839                throw new SemanticException( "SYNTAX is required", null, 0, 0 );
840                }
841                }
842                
843                return matchingRule;
844        }
845        
846/**
847     * Production for matching rule use descriptions. It is fault-tolerant
848     * against element ordering.
849     *
850     * <pre>
851     * MatchingRuleUseDescription = LPAREN WSP
852     *    numericoid                 ; object identifier
853     *    [ SP "NAME" SP qdescrs ]   ; short names (descriptors)
854     *    [ SP "DESC" SP qdstring ]  ; description
855     *    [ SP "OBSOLETE" ]          ; not active
856     *    SP "APPLIES" SP oids       ; attribute types
857     *    extensions WSP RPAREN      ; extensions
858     * </pre>
859    */
860        public final MatchingRuleUse  matchingRuleUseDescription() throws RecognitionException, TokenStreamException {
861                MatchingRuleUse matchingRuleUse;
862                
863                Token  oid = null;
864                Token  name = null;
865                Token  desc = null;
866                Token  obsolete = null;
867                Token  applies = null;
868                Token  extension = null;
869                
870                matchedProduction( "matchingRuleUseDescription()" );
871                ElementTracker et = new ElementTracker();
872                
873                
874                {
875                oid = LT(1);
876                match(STARTNUMERICOID);
877                matchingRuleUse = new MatchingRuleUse(numericoid(oid.getText()));
878                }
879                {
880                _loop219:
881                do {
882                        switch ( LA(1)) {
883                        case NAME:
884                        {
885                                {
886                                name = LT(1);
887                                match(NAME);
888                                et.track("NAME", name); matchingRuleUse.setNames(qdescrs(name.getText()));
889                                }
890                                break;
891                        }
892                        case DESC:
893                        {
894                                {
895                                desc = LT(1);
896                                match(DESC);
897                                et.track("DESC", desc); matchingRuleUse.setDescription(qdstring(desc.getText()));
898                                }
899                                break;
900                        }
901                        case OBSOLETE:
902                        {
903                                {
904                                obsolete = LT(1);
905                                match(OBSOLETE);
906                                et.track("OBSOLETE", obsolete); matchingRuleUse.setObsolete( true );
907                                }
908                                break;
909                        }
910                        case APPLIES:
911                        {
912                                {
913                                applies = LT(1);
914                                match(APPLIES);
915                                et.track("APPLIES", applies); matchingRuleUse.setApplicableAttributeOids(oids(applies.getText()));
916                                }
917                                break;
918                        }
919                        case EXTENSION:
920                        {
921                                {
922                                extension = LT(1);
923                                match(EXTENSION);
924                                
925                                Extension ex = extension(extension.getText());
926                                et.track(ex.key, extension); 
927                                matchingRuleUse.addExtension(ex.key, ex.values); 
928                                
929                                }
930                                break;
931                        }
932                        default:
933                        {
934                                break _loop219;
935                        }
936                        }
937                } while (true);
938                }
939                match(RPAR);
940                
941                if( !isQuirksModeEnabled )
942                {
943                // semantic check: required elements
944                if( !et.contains("APPLIES") ) {
945                throw new SemanticException( "APPLIES is required", null, 0, 0 );
946                }
947                }
948                
949                return matchingRuleUse;
950        }
951        
952/**
953     * Production for DIT content rule descriptions. It is fault-tolerant
954     * against element ordering.
955     *
956     * <pre>
957     * DITContentRuleDescription = LPAREN WSP
958     *    numericoid                 ; object identifier
959     *    [ SP "NAME" SP qdescrs ]   ; short names (descriptors)
960     *    [ SP "DESC" SP qdstring ]  ; description
961     *    [ SP "OBSOLETE" ]          ; not active
962     *    [ SP "AUX" SP oids ]       ; auxiliary object classes
963     *    [ SP "MUST" SP oids ]      ; attribute types
964     *    [ SP "MAY" SP oids ]       ; attribute types
965     *    [ SP "NOT" SP oids ]       ; attribute types
966     *    extensions WSP RPAREN      ; extensions
967     * </pre>
968    */
969        public final DitContentRule  ditContentRuleDescription() throws RecognitionException, TokenStreamException {
970                DitContentRule ditContentRule;
971                
972                Token  oid = null;
973                Token  name = null;
974                Token  desc = null;
975                Token  obsolete = null;
976                Token  aux = null;
977                Token  must = null;
978                Token  may = null;
979                Token  not = null;
980                Token  extension = null;
981                
982                matchedProduction( "ditContentRuleDescription()" );
983                ElementTracker et = new ElementTracker();
984                
985                
986                {
987                oid = LT(1);
988                match(STARTNUMERICOID);
989                ditContentRule = new DitContentRule(numericoid(oid.getText()));
990                }
991                {
992                _loop231:
993                do {
994                        switch ( LA(1)) {
995                        case NAME:
996                        {
997                                {
998                                name = LT(1);
999                                match(NAME);
1000                                et.track("NAME", name); ditContentRule.setNames(qdescrs(name.getText()));
1001                                }
1002                                break;
1003                        }
1004                        case DESC:
1005                        {
1006                                {
1007                                desc = LT(1);
1008                                match(DESC);
1009                                et.track("DESC", desc); ditContentRule.setDescription(qdstring(desc.getText()));
1010                                }
1011                                break;
1012                        }
1013                        case OBSOLETE:
1014                        {
1015                                {
1016                                obsolete = LT(1);
1017                                match(OBSOLETE);
1018                                et.track("OBSOLETE", obsolete); ditContentRule.setObsolete( true );
1019                                }
1020                                break;
1021                        }
1022                        case AUX:
1023                        {
1024                                {
1025                                aux = LT(1);
1026                                match(AUX);
1027                                et.track("AUX", aux); ditContentRule.setAuxObjectClassOids(oids(aux.getText()));
1028                                }
1029                                break;
1030                        }
1031                        case MUST:
1032                        {
1033                                {
1034                                must = LT(1);
1035                                match(MUST);
1036                                et.track("MUST", must); ditContentRule.setMustAttributeTypeOids(oids(must.getText()));
1037                                }
1038                                break;
1039                        }
1040                        case MAY:
1041                        {
1042                                {
1043                                may = LT(1);
1044                                match(MAY);
1045                                et.track("MAY", may); ditContentRule.setMayAttributeTypeOids(oids(may.getText()));
1046                                }
1047                                break;
1048                        }
1049                        case NOT:
1050                        {
1051                                {
1052                                not = LT(1);
1053                                match(NOT);
1054                                et.track("NOT", not); ditContentRule.setNotAttributeTypeOids(oids(not.getText()));
1055                                }
1056                                break;
1057                        }
1058                        case EXTENSION:
1059                        {
1060                                {
1061                                extension = LT(1);
1062                                match(EXTENSION);
1063                                
1064                                Extension ex = extension(extension.getText());
1065                                et.track(ex.key, extension); 
1066                                ditContentRule.addExtension(ex.key, ex.values); 
1067                                
1068                                }
1069                                break;
1070                        }
1071                        default:
1072                        {
1073                                break _loop231;
1074                        }
1075                        }
1076                } while (true);
1077                }
1078                match(RPAR);
1079                return ditContentRule;
1080        }
1081        
1082/**
1083     * Production for DIT structure rules descriptions. It is fault-tolerant
1084     * against element ordering.
1085     *
1086     * <pre>
1087     * DITStructureRuleDescription = LPAREN WSP
1088     *   ruleid                     ; rule identifier
1089     *   [ SP "NAME" SP qdescrs ]   ; short names (descriptors)
1090     *   [ SP "DESC" SP qdstring ]  ; description
1091     *   [ SP "OBSOLETE" ]          ; not active
1092     *   SP "FORM" SP oid           ; NameForm
1093     *   [ SP "SUP" ruleids ]       ; superior rules
1094     *   extensions WSP RPAREN      ; extensions
1095     *
1096     * ruleids = ruleid / ( LPAREN WSP ruleidlist WSP RPAREN )
1097     * ruleidlist = ruleid *( SP ruleid )
1098     * ruleid = number
1099     * </pre>
1100    */
1101        public final DitStructureRule  ditStructureRuleDescription() throws RecognitionException, TokenStreamException {
1102                DitStructureRule ditStructureRule;
1103                
1104                Token  ruleid = null;
1105                Token  name = null;
1106                Token  desc = null;
1107                Token  obsolete = null;
1108                Token  form = null;
1109                Token  sup = null;
1110                Token  extension = null;
1111                
1112                matchedProduction( "ditStructureRuleDescription()" );
1113                ElementTracker et = new ElementTracker();
1114                
1115                
1116                {
1117                ruleid = LT(1);
1118                match(STARTNUMERICOID);
1119                ditStructureRule = new DitStructureRule(ruleid(ruleid.getText()));
1120                }
1121                {
1122                _loop241:
1123                do {
1124                        switch ( LA(1)) {
1125                        case NAME:
1126                        {
1127                                {
1128                                name = LT(1);
1129                                match(NAME);
1130                                et.track("NAME", name); ditStructureRule.setNames(qdescrs(name.getText()));
1131                                }
1132                                break;
1133                        }
1134                        case DESC:
1135                        {
1136                                {
1137                                desc = LT(1);
1138                                match(DESC);
1139                                et.track("DESC", desc); ditStructureRule.setDescription(qdstring(desc.getText()));
1140                                }
1141                                break;
1142                        }
1143                        case OBSOLETE:
1144                        {
1145                                {
1146                                obsolete = LT(1);
1147                                match(OBSOLETE);
1148                                et.track("OBSOLETE", obsolete); ditStructureRule.setObsolete( true );
1149                                }
1150                                break;
1151                        }
1152                        case FORM:
1153                        {
1154                                {
1155                                form = LT(1);
1156                                match(FORM);
1157                                et.track("FORM", form); ditStructureRule.setForm(oid(form.getText()));
1158                                }
1159                                break;
1160                        }
1161                        case SUP:
1162                        {
1163                                {
1164                                sup = LT(1);
1165                                match(SUP);
1166                                et.track("SUP", sup); ditStructureRule.setSuperRules(ruleids(sup.getText()));
1167                                }
1168                                break;
1169                        }
1170                        case EXTENSION:
1171                        {
1172                                {
1173                                extension = LT(1);
1174                                match(EXTENSION);
1175                                
1176                                Extension ex = extension(extension.getText());
1177                                et.track(ex.key, extension); 
1178                                ditStructureRule.addExtension(ex.key, ex.values); 
1179                                
1180                                }
1181                                break;
1182                        }
1183                        default:
1184                        {
1185                                break _loop241;
1186                        }
1187                        }
1188                } while (true);
1189                }
1190                match(RPAR);
1191                
1192                if( !isQuirksModeEnabled )
1193                {
1194                // semantic check: required elements
1195                if( !et.contains("FORM") ) {
1196                throw new SemanticException( "FORM is required", null, 0, 0 );
1197                }
1198                }
1199                
1200                return ditStructureRule;
1201        }
1202        
1203/**
1204     * Production for name form descriptions. It is fault-tolerant
1205     * against element ordering.
1206     *
1207     * <pre>
1208     * NameFormDescription = LPAREN WSP
1209     *    numericoid                 ; object identifier
1210     *    [ SP "NAME" SP qdescrs ]   ; short names (descriptors)
1211     *    [ SP "DESC" SP qdstring ]  ; description
1212     *    [ SP "OBSOLETE" ]          ; not active
1213     *    SP "OC" SP oid             ; structural object class
1214     *    SP "MUST" SP oids          ; attribute types
1215     *    [ SP "MAY" SP oids ]       ; attribute types
1216     *    extensions WSP RPAREN      ; extensions
1217     * </pre>
1218    */
1219        public final NameForm  nameFormDescription() throws RecognitionException, TokenStreamException {
1220                NameForm nameForm;
1221                
1222                Token  oid = null;
1223                Token  name = null;
1224                Token  desc = null;
1225                Token  obsolete = null;
1226                Token  oc = null;
1227                Token  must = null;
1228                Token  may = null;
1229                Token  extension = null;
1230                
1231                matchedProduction( "nameFormDescription()" );
1232                ElementTracker et = new ElementTracker();
1233                
1234                
1235                {
1236                oid = LT(1);
1237                match(STARTNUMERICOID);
1238                nameForm = new NameForm(numericoid(oid.getText()));
1239                }
1240                {
1241                _loop252:
1242                do {
1243                        switch ( LA(1)) {
1244                        case NAME:
1245                        {
1246                                {
1247                                name = LT(1);
1248                                match(NAME);
1249                                et.track("NAME", name); nameForm.setNames(qdescrs(name.getText()));
1250                                }
1251                                break;
1252                        }
1253                        case DESC:
1254                        {
1255                                {
1256                                desc = LT(1);
1257                                match(DESC);
1258                                et.track("DESC", desc); nameForm.setDescription(qdstring(desc.getText()));
1259                                }
1260                                break;
1261                        }
1262                        case OBSOLETE:
1263                        {
1264                                {
1265                                obsolete = LT(1);
1266                                match(OBSOLETE);
1267                                et.track("OBSOLETE", obsolete); nameForm.setObsolete( true );
1268                                }
1269                                break;
1270                        }
1271                        case OC:
1272                        {
1273                                {
1274                                oc = LT(1);
1275                                match(OC);
1276                                et.track("OC", oc); nameForm.setStructuralObjectClassOid(oid(oc.getText()));
1277                                }
1278                                break;
1279                        }
1280                        case MUST:
1281                        {
1282                                {
1283                                must = LT(1);
1284                                match(MUST);
1285                                et.track("MUST", must); nameForm.setMustAttributeTypeOids(oids(must.getText()));
1286                                }
1287                                break;
1288                        }
1289                        case MAY:
1290                        {
1291                                {
1292                                may = LT(1);
1293                                match(MAY);
1294                                et.track("MAY", may); nameForm.setMayAttributeTypeOids(oids(may.getText()));
1295                                }
1296                                break;
1297                        }
1298                        case EXTENSION:
1299                        {
1300                                {
1301                                extension = LT(1);
1302                                match(EXTENSION);
1303                                
1304                                Extension ex = extension(extension.getText());
1305                                et.track(ex.key, extension); 
1306                                nameForm.addExtension(ex.key, ex.values); 
1307                                
1308                                }
1309                                break;
1310                        }
1311                        default:
1312                        {
1313                                break _loop252;
1314                        }
1315                        }
1316                } while (true);
1317                }
1318                match(RPAR);
1319                
1320                if( !isQuirksModeEnabled )
1321                {
1322                // semantic check: required elements
1323                if( !et.contains("MUST") ) {
1324                throw new SemanticException( "MUST is required", null, 0, 0 );
1325                }
1326                if( !et.contains("OC") ) {
1327                throw new SemanticException( "OC is required", null, 0, 0 );
1328                }
1329                
1330                // semantic check: MUST and MAY must be disjoint
1331                //List<String> aList = new ArrayList<String>( nfd.getMustAttributeTypes() );
1332                //aList.retainAll( nfd.getMayAttributeTypes() );
1333                //if( !aList.isEmpty() ) 
1334                //{
1335                //    throw new SemanticException( "MUST and MAY must be disjoint, "+aList.get( 0 )+" appears in both", null, 0, 0 );
1336                //}
1337                }
1338                
1339                return nameForm;
1340        }
1341        
1342/**
1343     * Production for comparator descriptions. It is fault-tolerant
1344     * against element ordering.
1345     *
1346     * <pre>
1347     * LdapComparator = LPAREN WSP
1348     *       numericoid                           ; object identifier
1349     *       [ SP "DESC" SP qdstring ]            ; description
1350     *       SP "FQCN" SP fqcn                    ; fully qualified class name
1351     *       [ SP "BYTECODE" SP base64 ]          ; optional base64 encoded bytecode
1352     *       extensions WSP RPAREN                ; extensions
1353     * 
1354     * base64          = *(4base64-char)
1355     * base64-char     = ALPHA / DIGIT / "+" / "/"
1356     * fqcn = fqcnComponent 1*( DOT fqcnComponent )
1357     * fqcnComponent = ???
1358     * </pre>
1359    */
1360        public final LdapComparatorDescription  ldapComparator() throws RecognitionException, TokenStreamException {
1361                LdapComparatorDescription lcd;
1362                
1363                Token  oid = null;
1364                Token  desc = null;
1365                Token  fqcn = null;
1366                Token  bytecode = null;
1367                Token  extension = null;
1368                
1369                matchedProduction( "ldapComparator()" );
1370                ElementTracker et = new ElementTracker();
1371                
1372                
1373                {
1374                oid = LT(1);
1375                match(STARTNUMERICOID);
1376                lcd = new LdapComparatorDescription(numericoid(oid.getText()));
1377                }
1378                {
1379                _loop260:
1380                do {
1381                        switch ( LA(1)) {
1382                        case DESC:
1383                        {
1384                                {
1385                                desc = LT(1);
1386                                match(DESC);
1387                                et.track("DESC", desc); lcd.setDescription(qdstring(desc.getText()));
1388                                }
1389                                break;
1390                        }
1391                        case FQCN:
1392                        {
1393                                {
1394                                fqcn = LT(1);
1395                                match(FQCN);
1396                                et.track("FQCN", fqcn); lcd.setFqcn(fqcn.getText());
1397                                }
1398                                break;
1399                        }
1400                        case BYTECODE:
1401                        {
1402                                {
1403                                bytecode = LT(1);
1404                                match(BYTECODE);
1405                                et.track("BYTECODE", bytecode); lcd.setBytecode(bytecode.getText());
1406                                }
1407                                break;
1408                        }
1409                        case EXTENSION:
1410                        {
1411                                {
1412                                extension = LT(1);
1413                                match(EXTENSION);
1414                                
1415                                Extension ex = extension(extension.getText());
1416                                et.track(ex.key, extension); 
1417                                lcd.addExtension(ex.key, ex.values); 
1418                                
1419                                }
1420                                break;
1421                        }
1422                        default:
1423                        {
1424                                break _loop260;
1425                        }
1426                        }
1427                } while (true);
1428                }
1429                match(RPAR);
1430                
1431                if( !isQuirksModeEnabled )
1432                {
1433                // semantic check: required elements
1434                if( !et.contains("FQCN") ) {
1435                throw new SemanticException( "FQCN is required", null, 0, 0 );
1436                }
1437                
1438                // semantic check: length should be divisible by 4
1439                if( ( lcd.getBytecode() != null ) && ( lcd.getBytecode().length() % 4 != 0 ) ) {
1440                throw new SemanticException( "BYTECODE must be divisible by 4", null, 0, 0 );
1441                }
1442                }
1443                
1444                return lcd;
1445        }
1446        
1447/**
1448     * Production for normalizer descriptions. It is fault-tolerant
1449     * against element ordering.
1450     *
1451     * <pre>
1452     * NormalizerDescription = LPAREN WSP
1453     *       numericoid                           ; object identifier
1454     *       [ SP "DESC" SP qdstring ]            ; description
1455     *       SP "FQCN" SP fqcn                    ; fully qualified class name
1456     *       [ SP "BYTECODE" SP base64 ]          ; optional base64 encoded bytecode
1457     *       extensions WSP RPAREN                ; extensions
1458     * 
1459     * base64          = *(4base64-char)
1460     * base64-char     = ALPHA / DIGIT / "+" / "/"
1461     * fqcn = fqcnComponent 1*( DOT fqcnComponent )
1462     * fqcnComponent = ???
1463     * </pre>
1464    */
1465        public final NormalizerDescription  normalizerDescription() throws RecognitionException, TokenStreamException {
1466                NormalizerDescription nd;
1467                
1468                Token  oid = null;
1469                Token  desc = null;
1470                Token  fqcn = null;
1471                Token  bytecode = null;
1472                Token  extension = null;
1473                
1474                matchedProduction( "normalizerDescription()" );
1475                ElementTracker et = new ElementTracker();
1476                
1477                
1478                {
1479                oid = LT(1);
1480                match(STARTNUMERICOID);
1481                nd = new NormalizerDescription(numericoid(oid.getText()));
1482                }
1483                {
1484                _loop268:
1485                do {
1486                        switch ( LA(1)) {
1487                        case DESC:
1488                        {
1489                                {
1490                                desc = LT(1);
1491                                match(DESC);
1492                                et.track("DESC", desc); nd.setDescription(qdstring(desc.getText()));
1493                                }
1494                                break;
1495                        }
1496                        case FQCN:
1497                        {
1498                                {
1499                                fqcn = LT(1);
1500                                match(FQCN);
1501                                et.track("FQCN", fqcn); nd.setFqcn(fqcn.getText());
1502                                }
1503                                break;
1504                        }
1505                        case BYTECODE:
1506                        {
1507                                {
1508                                bytecode = LT(1);
1509                                match(BYTECODE);
1510                                et.track("BYTECODE", bytecode); nd.setBytecode(bytecode.getText());
1511                                }
1512                                break;
1513                        }
1514                        case EXTENSION:
1515                        {
1516                                {
1517                                extension = LT(1);
1518                                match(EXTENSION);
1519                                
1520                                Extension ex = extension(extension.getText());
1521                                et.track(ex.key, extension); 
1522                                nd.addExtension(ex.key, ex.values); 
1523                                
1524                                }
1525                                break;
1526                        }
1527                        default:
1528                        {
1529                                break _loop268;
1530                        }
1531                        }
1532                } while (true);
1533                }
1534                match(RPAR);
1535                
1536                if( !isQuirksModeEnabled )
1537                {
1538                // semantic check: required elements
1539                if( !et.contains("FQCN") ) {
1540                throw new SemanticException( "FQCN is required", null, 0, 0 );
1541                }
1542                
1543                // semantic check: length should be divisible by 4
1544                if( nd.getBytecode() != null && ( nd.getBytecode().length() % 4 != 0 ) ) {
1545                throw new SemanticException( "BYTECODE must be divisible by 4", null, 0, 0 );
1546                }     
1547                }   
1548                
1549                return nd;
1550        }
1551        
1552/**
1553     * Production for syntax checker descriptions. It is fault-tolerant
1554     * against element ordering.
1555     *
1556     * <pre>
1557     * SyntaxCheckerDescription = LPAREN WSP
1558     *       numericoid                           ; object identifier
1559     *       [ SP "DESC" SP qdstring ]            ; description
1560     *       SP "FQCN" SP fqcn                    ; fully qualified class name
1561     *       [ SP "BYTECODE" SP base64 ]          ; optional base64 encoded bytecode
1562     *       extensions WSP RPAREN                ; extensions
1563     * 
1564     * base64          = *(4base64-char)
1565     * base64-char     = ALPHA / DIGIT / "+" / "/"
1566     * fqcn = fqcnComponent 1*( DOT fqcnComponent )
1567     * fqcnComponent = ???
1568     * </pre>
1569    */
1570        public final SyntaxCheckerDescription  syntaxCheckerDescription() throws RecognitionException, TokenStreamException {
1571                SyntaxCheckerDescription scd;
1572                
1573                Token  oid = null;
1574                Token  desc = null;
1575                Token  fqcn = null;
1576                Token  bytecode = null;
1577                Token  extension = null;
1578                
1579                matchedProduction( "syntaxCheckerDescription()" );
1580                ElementTracker et = new ElementTracker();
1581                
1582                
1583                {
1584                oid = LT(1);
1585                match(STARTNUMERICOID);
1586                scd = new SyntaxCheckerDescription(numericoid(oid.getText()));
1587                }
1588                {
1589                _loop276:
1590                do {
1591                        switch ( LA(1)) {
1592                        case DESC:
1593                        {
1594                                {
1595                                desc = LT(1);
1596                                match(DESC);
1597                                et.track("DESC", desc); scd.setDescription(qdstring(desc.getText()));
1598                                }
1599                                break;
1600                        }
1601                        case FQCN:
1602                        {
1603                                {
1604                                fqcn = LT(1);
1605                                match(FQCN);
1606                                et.track("FQCN", fqcn); scd.setFqcn(fqcn.getText());
1607                                }
1608                                break;
1609                        }
1610                        case BYTECODE:
1611                        {
1612                                {
1613                                bytecode = LT(1);
1614                                match(BYTECODE);
1615                                et.track("BYTECODE", bytecode); scd.setBytecode(bytecode.getText());
1616                                }
1617                                break;
1618                        }
1619                        case EXTENSION:
1620                        {
1621                                {
1622                                extension = LT(1);
1623                                match(EXTENSION);
1624                                
1625                                Extension ex = extension(extension.getText());
1626                                et.track(ex.key, extension); 
1627                                scd.addExtension(ex.key, ex.values); 
1628                                
1629                                }
1630                                break;
1631                        }
1632                        default:
1633                        {
1634                                break _loop276;
1635                        }
1636                        }
1637                } while (true);
1638                }
1639                match(RPAR);
1640                
1641                if( !isQuirksModeEnabled )
1642                {
1643                // semantic check: required elements
1644                if( !et.contains("FQCN") ) {
1645                throw new SemanticException( "FQCN is required", null, 0, 0 );
1646                }
1647                
1648                // semantic check: length should be divisible by 4
1649                if( scd.getBytecode() != null && ( scd.getBytecode().length() % 4 != 0 ) ) {
1650                throw new SemanticException( "BYTECODE must be divisible by 4", null, 0, 0 );
1651                }  
1652                }      
1653                
1654                return scd;
1655        }
1656        
1657        public final NoidLen  noidlen(
1658                String s
1659        ) throws RecognitionException, TokenStreamException {
1660                NoidLen noidlen;
1661                
1662                
1663                matchedProduction( "noidlen()" );
1664                AntlrSchemaValueLexer lexer = new AntlrSchemaValueLexer(new StringReader(s));
1665                AntlrSchemaValueParser parser = new AntlrSchemaValueParser(lexer);
1666                parser.setParserMonitor(monitor);
1667                noidlen = isQuirksModeEnabled ? parser.quirksNoidlen() : parser.noidlen();
1668                
1669                
1670                return noidlen;
1671        }
1672        
1673        public final Extension  extension(
1674                String s
1675        ) throws RecognitionException, TokenStreamException {
1676                Extension extension;
1677                
1678                
1679                matchedProduction( "extension()" );
1680                AntlrSchemaExtensionLexer lexer = new AntlrSchemaExtensionLexer(new StringReader(s));
1681                AntlrSchemaExtensionParser parser = new AntlrSchemaExtensionParser(lexer);
1682                extension = parser.extension();
1683                
1684                
1685                return extension;
1686        }
1687        
1688        public final String  numericoid(
1689                String s
1690        ) throws RecognitionException, TokenStreamException {
1691                String numericoid;
1692                
1693                
1694                matchedProduction( "numericoid()");
1695                if(isQuirksModeEnabled)
1696                {
1697                numericoid = oid(s);
1698                }
1699                else
1700                {
1701                                AntlrSchemaValueLexer lexer = new AntlrSchemaValueLexer(new StringReader(s));
1702                                AntlrSchemaValueParser parser = new AntlrSchemaValueParser(lexer);
1703                                parser.setParserMonitor(monitor);
1704                                numericoid = parser.numericoid();
1705                }
1706                
1707                
1708                return numericoid;
1709        }
1710        
1711        public final String  oid(
1712                String s
1713        ) throws RecognitionException, TokenStreamException {
1714                String oid;
1715                
1716                
1717                matchedProduction( "oid()" );
1718                List<String> oids = oids(s);
1719                if( oids.size() != 1 ) 
1720                {
1721                throw new SemanticException( "Exactly one OID expected", null, 0, 0 );
1722                }
1723                oid = oids.get(0);
1724                
1725                
1726                return oid;
1727        }
1728        
1729        public final List<String>  oids(
1730                String s
1731        ) throws RecognitionException, TokenStreamException {
1732                List<String> oids;
1733                
1734                
1735                matchedProduction( "oids()" );
1736                if(isQuirksModeEnabled)
1737                {
1738                oids = qdescrs(s);
1739                }
1740                else
1741                {
1742                                AntlrSchemaValueLexer lexer = new AntlrSchemaValueLexer(new StringReader(s));
1743                                AntlrSchemaValueParser parser = new AntlrSchemaValueParser(lexer);
1744                                parser.setParserMonitor(monitor);
1745                                oids = parser.oids();
1746                            }
1747                
1748                
1749                return oids;
1750        }
1751        
1752        public final String  qdescr(
1753                String s
1754        ) throws RecognitionException, TokenStreamException {
1755                String qdescr;
1756                
1757                
1758                matchedProduction( "qdescr()" );
1759                List<String> qdescrs = qdescrs(s);
1760                if( qdescrs.size() != 1 ) 
1761                {
1762                throw new SemanticException( "Exactly one qdescrs expected", null, 0, 0 );
1763                }
1764                qdescr = qdescrs.get(0);
1765                
1766                
1767                return qdescr;
1768        }
1769        
1770        public final List<String>  qdescrs(
1771                String s
1772        ) throws RecognitionException, TokenStreamException {
1773                List<String> qdescrs;
1774                
1775                
1776                matchedProduction( "qdescrs()" );
1777                AntlrSchemaValueLexer lexer = new AntlrSchemaValueLexer(new StringReader(s));
1778                AntlrSchemaValueParser parser = new AntlrSchemaValueParser(lexer);
1779                parser.setParserMonitor(monitor);
1780                qdescrs = isQuirksModeEnabled ? parser.quirksQdescrs() : parser.qdescrs();
1781                
1782                
1783                return qdescrs;
1784        }
1785        
1786        public final String  qdstring(
1787                String s
1788        ) throws RecognitionException, TokenStreamException {
1789                String qdstring;
1790                
1791                
1792                matchedProduction( "qdstring()" );
1793                List<String> qdstrings = qdstrings(s);
1794                if( qdstrings.size() != 1 ) 
1795                {
1796                throw new SemanticException( "Exactly one qdstrings expected", null, 0, 0 );
1797                }
1798                qdstring = qdstrings.get(0);
1799                
1800                
1801                return qdstring;
1802        }
1803        
1804        public final List<String>  qdstrings(
1805                String s
1806        ) throws RecognitionException, TokenStreamException {
1807                List<String> qdstrings;
1808                
1809                
1810                matchedProduction( "qdstrings()" );
1811                AntlrSchemaQdstringLexer lexer = new AntlrSchemaQdstringLexer(new StringReader(s));
1812                AntlrSchemaQdstringParser parser = new AntlrSchemaQdstringParser(lexer);
1813                parser.setParserMonitor(monitor);
1814                qdstrings = parser.qdstrings();
1815                
1816                
1817                return qdstrings;
1818        }
1819        
1820        public final Integer  ruleid(
1821                String s
1822        ) throws RecognitionException, TokenStreamException {
1823                Integer ruleid;
1824                
1825                
1826                matchedProduction( "ruleid()" );
1827                AntlrSchemaValueLexer lexer = new AntlrSchemaValueLexer(new StringReader(s));
1828                AntlrSchemaValueParser parser = new AntlrSchemaValueParser(lexer);
1829                parser.setParserMonitor(monitor);
1830                ruleid = parser.ruleid();
1831                
1832                
1833                return ruleid;
1834        }
1835        
1836        public final List<Integer>  ruleids(
1837                String s
1838        ) throws RecognitionException, TokenStreamException {
1839                List<Integer> ruleids;
1840                
1841                
1842                matchedProduction( "ruleids()" );
1843                AntlrSchemaValueLexer lexer = new AntlrSchemaValueLexer(new StringReader(s));
1844                AntlrSchemaValueParser parser = new AntlrSchemaValueParser(lexer);
1845                parser.setParserMonitor(monitor);
1846                ruleids = parser.ruleids();
1847                
1848                
1849                return ruleids;
1850        }
1851        
1852        
1853        public static final String[] _tokenNames = {
1854                "<0>",
1855                "EOF",
1856                "<2>",
1857                "NULL_TREE_LOOKAHEAD",
1858                "WHSP",
1859                "LPAR",
1860                "RPAR",
1861                "QUOTE",
1862                "DOLLAR",
1863                "LBRACKET",
1864                "RBRACKET",
1865                "LEN",
1866                "SINGLE_VALUE",
1867                "COLLECTIVE",
1868                "NO_USER_MODIFICATION",
1869                "OBSOLETE",
1870                "ABSTRACT",
1871                "STRUCTURAL",
1872                "AUXILIARY",
1873                "OBJECTIDENTIFIER",
1874                "OBJECTCLASS",
1875                "ATTRIBUTETYPE",
1876                "STARTNUMERICOID",
1877                "NAME",
1878                "DESC",
1879                "SUP",
1880                "MUST",
1881                "MAY",
1882                "AUX",
1883                "NOT",
1884                "FORM",
1885                "OC",
1886                "EQUALITY",
1887                "ORDERING",
1888                "SUBSTR",
1889                "SYNTAX",
1890                "APPLIES",
1891                "EXTENSION",
1892                "FQCN",
1893                "BYTECODE",
1894                "AUX_OR_AUXILIARY",
1895                "VALUES",
1896                "VALUE",
1897                "UNQUOTED_STRING",
1898                "QUOTED_STRING",
1899                "FQCN_VALUE",
1900                "FQCN_IDENTIFIER",
1901                "FQCN_LETTER",
1902                "FQCN_LETTERORDIGIT",
1903                "BYTECODE_VALUE",
1904                "USAGE",
1905                "USER_APPLICATIONS",
1906                "DIRECTORY_OPERATION",
1907                "DISTRIBUTED_OPERATION",
1908                "DSA_OPERATION"
1909        };
1910        
1911        
1912        }