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
 *  
 *    https://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.name;

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.exception.LdapInvalidDnException;
import javax.naming.NameParser;
import org.apache.directory.api.ldap.model.entry.Value;
import org.apache.directory.api.ldap.model.schema.SchemaManager;
import org.apache.directory.api.ldap.model.schema.AttributeType;
import org.apache.directory.api.util.ExpansibleByteBuffer;
import org.apache.directory.api.util.Strings;
import org.apache.directory.api.util.Unicode;
}

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

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

COMMA : ',' ;
EQUALS : '=' ;
PLUS : '+' ;
HYPHEN : '-' ;
UNDERSCORE : '_' ;
DQUOTE : '"' ;
SEMI : ';' ;
LANGLE : '<' ;
RANGLE : '>' ;
SPACE : ' ' ;

NUMERICOID_OR_ALPHA_OR_DIGIT 
    : ( NUMERICOID ) => NUMERICOID { $setType(NUMERICOID); }
    | ( DIGIT ) => DIGIT { $setType(DIGIT); }
    | ( ALPHA ) => ALPHA { $setType(ALPHA); }
    ;
protected NUMERICOID : ( "oid." )? NUMBER ( DOT NUMBER )+ ;
protected DOT: '.' ;
protected NUMBER: DIGIT | ( LDIGIT ( DIGIT )+ ) ;
protected LDIGIT : '1'..'9' ;
protected DIGIT : '0'..'9' ;
protected ALPHA : 'a'..'z' ;

HEXPAIR_OR_ESCESC_ESCSHARP_OR_ESC 
    : (ESC HEX HEX) => HEXPAIR { $setType(HEXPAIR); }
    | ESCESC { $setType(ESCESC); }
    | ESCSHARP { $setType(ESCSHARP); }
    | ESC { $setType(ESC); }
    ;
protected HEXPAIR : ESC! HEX HEX ;
protected ESC : '\\';
protected ESCESC : ESC ESC;
protected ESCSHARP : ESC SHARP;
protected HEX: DIGIT | 'a'..'f' ;

HEXVALUE_OR_SHARP
    : (SHARP ( HEX HEX )+) => HEXVALUE { $setType(HEXVALUE); }
    | SHARP { $setType(SHARP); }
    ;
protected HEXVALUE : SHARP! ( HEX HEX )+ ;
protected SHARP: '#' ;

UTFMB : '\u0080'..'\uFFFE' ;

/**
 * RFC 4514, Section 3:
 * <pre>
 * LUTF1 = %x01-1F / %x21 / %x24-2A / %x2D-3A /
 *    %x3D / %x3F-5B / %x5D-7F
 *
 * To avoid nondeterminism the following 
 * rules are excluded. These rules are 
 * explicitly added in the productions.
 *   EQUALS (0x3D)
 *   HYPHEN (0x2D)
 *   UNDERSCORE (0x5F)
 *   DIGIT (0x30-0x39)
 *   ALPHA (0x41-0x5A and 0x61-0x7A)
 * </pre>
 *
 * @param _createToken If a Token is to be to created
 * @throws RecognitionException If the token is invalid
 * @throws TokenStreamException When we weren't able to fetch a token
 * @throws CharStreamException If we can't process the stream
 */
CHAR_REST : 
    '\u0001'..'\u001F' |
    '\u0021' |
    '\u0024'..'\u002A' |
    '\u002E'..'\u002F' |
    '\u003A' |
    '\u003F'..'\u0040' |
    '\u005B' |
    '\u005D'..'\u005E' | 
    '\u0060' | 
    '\u007B'..'\u007F' 
    ;


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

{
    private void matchedProduction( String msg )
    {
    }

    /**
     * This class is used to store the decoded value
     */
    private static class UpAndNormValue
    {
        // The value as a byte array
        ExpansibleByteBuffer bytes = new ExpansibleByteBuffer();

        // The user provided value
        StringBuilder upValue = new StringBuilder();

        // The normalized value
        StringBuilder normValue = new StringBuilder();

        // A flag set to false if we have a binary value
        boolean isHR = true;
    }
}


/**
 * Parses a Dn string.
 *
 * RFC 4514, Section 3
 * <pre>
 * distinguishedName = [ relativeDistinguishedName
 *     *( COMMA relativeDistinguishedName ) ]
 * </pre>
 *
 * RFC 2253, Section 3
 * <pre>
 * distinguishedName = [name] 
 * name       = name-component *("," name-component)
 * </pre>
 *
 * RFC 1779, Section 2.3
 * <pre>
 * &lt;name&gt; ::= &lt;name-component&gt; ( &lt;spaced-separator&gt; )
 *        | &lt;name-component&gt; &lt;spaced-separator&gt; &lt;name&gt;
 * &lt;spaced-separator&gt; ::= &lt;optional-space&gt;
 *             &lt;separator&gt;
 *             &lt;optional-space&gt;
 * &lt;separator&gt; ::=  "," | ";"
 * &lt;optional-space&gt; ::= ( &lt;CR&gt; ) *( " " )
 * </pre>
 *
 * @param schemaManager The SchemaManager
 * @param dn The Dn to update
 * @throws RecognitionException If the token is invalid
 * @throws TokenStreamException When we weren't able to fetch a token
 */
distinguishedName [SchemaManager schemaManager, Dn dn]
    {
        matchedProduction( "distinguishedName()" );
        Rdn rdn = new Rdn( schemaManager );
    }
    :
    (
        relativeDistinguishedName[schemaManager, rdn] 
        { 
            try
            { 
                dn.add( rdn );
                
            }
            catch ( LdapInvalidDnException lide )
            {
                // Do nothing, can't get an exception here
            } 
        }
        (
            ( COMMA | SEMI )
            {
                rdn = new Rdn( schemaManager );
            }
            relativeDistinguishedName[schemaManager, rdn] 
            { 
                try
                { 
                    dn.add( rdn ); 
                }
                catch ( LdapInvalidDnException lide )
                {
                    // Do nothing, can't get an exception here
                } 
            }
        )*
        EOF
    )?
    ;


/**
 * Parses a Dn string.
 *
 * RFC 4514, Section 3
 * <pre>
 * distinguishedName = [ relativeDistinguishedName
 *     *( COMMA relativeDistinguishedName ) ]
 * </pre>
 *
 * RFC 2253, Section 3
 * <pre>
 * distinguishedName = [name] 
 * name       = name-component *("," name-component)
 * </pre>
 *
 * RFC 1779, Section 2.3
 * <pre>
 * &lt;name&gt; ::= &lt;name-component&gt; ( &lt;spaced-separator&gt; )
 *        | &lt;name-component&gt; &lt;spaced-separator&gt; &lt;name&gt;
 * &lt;spaced-separator&gt; ::= &lt;optional-space&gt;
 *             &lt;separator&gt;
 *             &lt;optional-space&gt;
 * &lt;separator&gt; ::=  "," | ";"
 * &lt;optional-space&gt; ::= ( &lt;CR&gt; ) *( " " )
 * </pre>
 *
 * @param schemaManager The SchemaManager
 * @param rdns The list of Rdns to update
 * @return The normalized Dn
 * @throws RecognitionException If the token is invalid
 * @throws TokenStreamException When we weren't able to fetch a token
 */
relativeDistinguishedNames [SchemaManager schemaManager, List<Rdn> rdns] returns [String normNameStr]
    {
        matchedProduction( "relativeDistinguishedNames()" );
        Rdn rdn = new Rdn( schemaManager );
        StringBuilder dnNormSb = new StringBuilder();
    }
    :
    (
        relativeDistinguishedName[ schemaManager, rdn] 
        { 
            rdns.add( rdn );
            dnNormSb.append( rdn.getNormName() );
            rdn = new Rdn( schemaManager );
        }
        (
            ( COMMA | SEMI )
            relativeDistinguishedName[schemaManager, rdn] 
            { 
                rdns.add( rdn ); 
	            dnNormSb.append( ',' );
	            dnNormSb.append( rdn.getNormName() );
                rdn = new Rdn( schemaManager );
				}
        )*
        EOF
    )?
    {
        normNameStr = dnNormSb.toString();
    }
    ;

/**
 * Parses a Rdn string.
 *
 * RFC 4514, Section 3
 * <pre>
 * relativeDistinguishedName = attributeTypeAndValue
 *     *( PLUS attributeTypeAndValue )
 * </pre>
 *
 * RFC 2253, Section 3
 * <pre>
 * name-component = attributeTypeAndValue *("+" attributeTypeAndValue)
 * </pre>
 *
 * RFC 1779, Section 2.3
 * <pre>
 * &lt;name-component&gt; ::= &lt;attribute&gt;
 *     | &lt;attribute&gt; &lt;optional-space&gt; "+"
 *       &lt;optional-space&gt; &lt;name-component&gt;
 * </pre>
 *
 * @param schemaManager The SchemaManager
 * @param rdn The Rdn to update
 * @throws RecognitionException If the token is invalid
 * @throws TokenStreamException When we weren't able to fetch a token
 */
relativeDistinguishedName [SchemaManager schemaManager, Rdn rdn]
    {
        matchedProduction( "relativeDistinguishedName()" );
        String tmp;

        // The rdnStr variable is used to gather the full RDN string
        // as provided
        StringBuilder rdnStr = new StringBuilder();
        StringBuilder rdnNormStr = new StringBuilder();
        int avaPos = 0;
        Ava currentAva;
        AttributeType attributeType;
        Value val;
    }
    :
    (
        tmp = attributeTypeAndValue[schemaManager, rdn] 
        {
            rdnStr.append( tmp );
            currentAva = rdn.getAva( avaPos );
            
            attributeType = currentAva.getAttributeType();
            
            if ( schemaManager == null )
            {
                rdnNormStr.append( currentAva.getNormType() );
                rdnNormStr.append( '=' );
            }
            
            val = currentAva.getValue();
            
            if ( ( schemaManager == null ) && ( val != null ) )
            {
                if ( val.getNormalized() != null )
                {
                    rdnNormStr.append( val.getNormalized() );
                }
                else
                {
                    // We can't tell if the value is HR or not. 
                    // Use the Value User Provided value
                    rdnNormStr.append( val.getUpValue() );
                }
            }
        }
        (
            PLUS 
            { 
                rdnStr.append( '+' ); 
                
                if ( schemaManager == null )
                {
                    rdnNormStr.append( '+' );
                }
                
                avaPos++;
            }

            tmp = attributeTypeAndValue[schemaManager, rdn] 
            {
                rdnStr.append( tmp );
                currentAva = rdn.getAva( avaPos );
                attributeType = currentAva.getAttributeType();
            
                if ( schemaManager == null )
                {
                    rdnNormStr.append( tmp );
                    rdnNormStr.append( '=' );
                }
            
                val = currentAva.getValue();
            
                if ( ( schemaManager == null ) && ( val != null ) )
                {
	                if ( val.getNormalized() != null )
	                {
	                    rdnNormStr.append( val.getNormalized() );
	                }
                    else
                    {
                        // We can't tell if the value is HR or not. 
                        // Use the Value User Provided value
                        rdnNormStr.append( val.getUpValue() );
                    }
                }
            }
        )*
    )
    {
        rdn.hashCode();
        rdn.setUpName( rdnStr.toString() );
        
        if ( schemaManager != null )
        {
            // process the multi-value RDN, ordering them by attributes
            boolean isFirst = true;
            
            for ( Ava ava : rdn )
            {
                if ( isFirst )
                {
                    isFirst = false;
                }
                else
                {
                    rdnNormStr.append( '+' );
                }
                
                rdnNormStr.append( ava.getAttributeType().getOid() );
                rdnNormStr.append( '=' );
                
                val = ava.getValue();

                if ( ( val != null ) && ( val.getNormalized() != null ) )
                {
                    rdnNormStr.append( val.getNormalized() );
                }
            }
        }
        
        rdn.setNormName( rdnNormStr.toString() );
    }
    ;
    

/**
 * RFC 4514, Section 3
 * <pre>
 * attributeTypeAndValue = attributeType EQUALS attributeValue
 * </pre>
 *
 * RFC 2253, Section 3
 * <pre>
 * attributeTypeAndValue = attributeType "=" attributeValue
 * </pre>
 *
 * @param schemaManager The SchemaManager
 * @param rdn The Rdn to update
 * @return The user provided Ava
 * @throws RecognitionException If the token is invalid
 * @throws TokenStreamException When we weren't able to fetch a token
 */
attributeTypeAndValue [SchemaManager schemaManager, Rdn rdn] returns [String upNameStr]
    {
        matchedProduction( "attributeTypeAndValue()" );
        String type = null;
        UpAndNormValue value = new UpAndNormValue();
        StringBuilder rdnUpName = new StringBuilder();
    }
    :
    (
        ( SPACE { rdnUpName.append( ' ' ); } )*
        type = attributeType { rdnUpName.append( type ); }
        ( SPACE { rdnUpName.append( ' ' ); } )*
        EQUALS { rdnUpName.append( '=' ); }
        ( SPACE  { rdnUpName.append( ' ' ); } )*
        attributeValue[value] 
        {
            try
            {
                // We have to remove the ending spaces that may have been added, as the tutf1 rule
                // cannot be processed
                rdnUpName.append( value.upValue );
                AttributeType attributeType = null;
                Ava ava = null;

                if ( schemaManager != null )
                {
                    if ( ( type.startsWith( "oid." ) ) || ( type.startsWith( "OID." ) ) )
                    {
                        type = type.substring( 4 );
                    }

                    attributeType = schemaManager.getAttributeType( type );
                }

                if ( ( ( attributeType != null ) && attributeType.isHR() ) || value.isHR )
                {
                    int valueLength = value.upValue.length();
                    int pos = value.bytes.position();
                    
                    for ( int i = valueLength - 1; i >= 0; i-- )
                    {
                        if ( value.upValue.charAt( i ) == ' ' ) 
                        {
                            if ( i == 0 )
                            {
                                // The value is empty
                                ava = new Ava( schemaManager, type, rdnUpName.toString(), ( String ) null );
                                break;
                            }
                            else if ( value.upValue.charAt( i - 1 ) != '\\' )
                            {
                                // This is a trailing space, get rid of it
                                value.upValue.deleteCharAt( i );
                                pos--;
                                value.bytes.position( pos );
                            }
                            else
                            {
                                // This is an escaped space, get out
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }

                    if ( ava == null )
                    {
                        ava = new Ava( schemaManager, type, rdnUpName.toString(), Strings.utf8ToString( value.bytes.copyOfUsedBytes() ) );
                    }
                }
                else
                {
                    ava = new Ava( schemaManager, type, rdnUpName.toString(), value.bytes.copyOfUsedBytes() );
                }
           
                rdn.addAVA( schemaManager, ava );
            }
            catch ( LdapInvalidDnException e )
            {
                throw new SemanticException( e.getMessage() );
            } 
        }
        ( SPACE { rdnUpName.append( ' ' ); } )*
    )
    {
        upNameStr = rdnUpName.toString();
    }
    ;
    

/**
 * RFC 4514 Section 3
 *
 * <pre>
 * attributeType = descr / numericoid
 * </pre>
 *
 * @return The AttributeType
 * @throws RecognitionException If the token is invalid
 * @throws TokenStreamException When we weren't able to fetch a token
 */
attributeType returns [String attributeType]
    {
        matchedProduction( "attributeType()" );
    }
    :
    (
        attributeType = descr
        |
        attributeType = numericoid
    )
    ;


/**
 * RFC 4512 Section 1.4
 *
 * <pre>
 * descr = keystring
 * keystring = leadkeychar *keychar
 * leadkeychar = ALPHA
 * keychar = ALPHA / DIGIT / HYPHEN
 * </pre>
 *
 * We additionally add UNDERSCORE because some servers allow them.
 *
 * @return The description
 * @throws RecognitionException If the token is invalid
 * @throws TokenStreamException When we weren't able to fetch a token
 */
descr returns [String descr]
    {
        matchedProduction( "descr()" );
        StringBuilder descrSb = new StringBuilder();
    }
    :
    leadkeychar:ALPHA { descrSb.append( leadkeychar.getText() ); }
    (
        alpha:ALPHA { descrSb.append( alpha.getText() ); }
        |
        digit:DIGIT { descrSb.append( digit.getText() ); }
        |
        HYPHEN { descrSb.append( '-' ); }
        |
        UNDERSCORE { descrSb.append( '_' ); }
    )*
    {
        descr = descrSb.toString();
    }
    ;


/**
 * RFC 4512 Section 1.4
 *
 * <pre>
 * numericoid = number 1*( DOT number )
 * number  = DIGIT / ( LDIGIT 1*DIGIT )
 * DIGIT   = %x30 / LDIGIT       ; "0"-"9"
 * LDIGIT  = %x31-39             ; "1"-"9"
 * </pre>
 *
 * @return The numeric OID
 * @throws RecognitionException If the token is invalid
 * @throws TokenStreamException When we weren't able to fetch a token
 */
numericoid returns [String numericoid = ""]
    {
        matchedProduction( "numericoid()" );
    }
    :
    noid:NUMERICOID { numericoid = noid.getText(); }
    ;


/**
 * RFC 4514, Section 3
 * <pre>
 * attributeValue = string / hexstring
 * </pre>
 *
 * RFC 2253, Section 3
 * <pre>
 * attributeValue = string
 * string     = *( stringchar / pair )
 *              / "#" hexstring
 *              / QUOTATION *( quotechar / pair ) QUOTATION ; only from v2
 *
 * We still accept both forms, which means we can have a value surrounded by '"'
 * </pre>
 *
 * @param value The value to update
 * @throws RecognitionException If the token is invalid
 * @throws TokenStreamException When we weren't able to fetch a token
 */
attributeValue [UpAndNormValue value] 
    {
        matchedProduction( "attributeValue()" );
    }
    :
    (
        // Special for RFC 2253
        quotestring [value]
        |
        string [value]
        |
        hexstring [value]
    )?
    ;


/**
 * RFC 2253, Section 3
 * <pre>
 *              / QUOTATION *( quotechar / pair ) QUOTATION ; only from v2
 * quotechar     = &lt;any character except "\" or QUOTATION &gt;
 * </pre>
 *
 * @param value The value to update
 * @throws RecognitionException If the token is invalid
 * @throws TokenStreamException When we weren't able to fetch a token
 */
quotestring [UpAndNormValue value] 
    {
        matchedProduction( "quotestring()" );
    }
    :
    (
        DQUOTE { value.upValue.append( '"' ); }
        (
            (
                s:~(DQUOTE|ESC|ESCESC|ESCSHARP|HEXPAIR) 
                {
                    value.upValue.append( s.getText() );
                    value.bytes.append( Strings.getBytesUtf8( s.getText() ) );
                }
            )
            |
            pair [value] 
        )*
        DQUOTE { value.upValue.append( '"' ); }
    )
    ;


/**
 * RFC 4514 Section 3
 *
 * <pre>
 * hexstring = SHARP 1*hexpair
 *
 * If in &lt;hexstring&gt; form, a BER representation can be obtained from
 * converting each &lt;hexpair&gt; of the &lt;hexstring&gt; to the octet indicated
 * by the &lt;hexpair&gt;.
 * </pre>
 *
 * @param value The value to update
 * @throws RecognitionException If the token is invalid
 * @throws TokenStreamException When we weren't able to fetch a token
 */ 
hexstring [UpAndNormValue value]
    {
        matchedProduction( "hexstring()" );
    }
    :
    hexValue:HEXVALUE
    {
        String hexStr = hexValue.getText();
        value.upValue.append( '#' ).append( hexStr );
        value.bytes.append( Strings.toByteArray( hexStr ) );
        value.isHR = false; 
    }
    ;


/**
 * RFC 4514 Section 3
 *
 * <pre>
 * ; The following characters are to be escaped when they appear
 * ; in the value to be encoded: ESC, one of &lt;escaped&gt;, &lt;leading&gt;
 * ; SHARP or SPACE, trailing SPACE, and NULL.
 * string =   [ ( leadchar / pair ) [ *( stringchar / pair ) ( trailchar / pair ) ] ]
 * leadchar = LUTF1 | UTFMB
 * stringchar = SUTF1 / UTFMB
 * trailchar = TUTF1 / UTFMB
 * </pre>
 *
 * @param value The value to update
 * @throws RecognitionException If the token is invalid
 * @throws TokenStreamException When we weren't able to fetch a token
 */ 
string [UpAndNormValue value]
    {
        matchedProduction( "string()" );
    }
    :
    (
        // Note that we don't distinguish between sutf1 and tutf1, as it would be ambiguous.
        // The final spaces will be handled later.
        ( lutf1 [value] | utfmb [value] | pair [value] ) ( sutf1 [value] | utfmb [value] | pair [value] )*
    )
    ;


/**
 * RFC 4514, Section 3:
 * <pre>
 * LUTF1 = %x01-1F / %x21 / %x24-2A / %x2D-3A /
 *    %x3D / %x3F-5B / %x5D-7F
 *
 * The rule CHAR_REST doesn't contain the following charcters,
 * so we must check them additionally
 *   EQUALS (0x3D)
 *   HYPHEN (0x2D)
 *   UNDERSCORE (0x5F)
 *   DIGIT (0x30-0x39)
 *   ALPHA (0x41-0x5A and 0x61-0x7A)
 * </pre>
 *
 * @param value The value to update
 * @throws RecognitionException If the token is invalid
 * @throws TokenStreamException When we weren't able to fetch a token
 */
lutf1 [UpAndNormValue value]
    {
        matchedProduction( "lutf1()" );
    }
    :
    rest:CHAR_REST 
    { 
        char c = rest.getText().charAt( 0 );
        value.upValue.append( c );
        value.bytes.append( ( byte ) c );
    }
    |
    EQUALS
    { 
        value.upValue.append( '=' );
        value.bytes.append( '=' );
    }
    |
    HYPHEN
    { 
        value.upValue.append( '-' );
        value.bytes.append( '-' );
    }
    |
    UNDERSCORE
    { 
        value.upValue.append( '_' );
        value.bytes.append( '_' );
    }
    |
    digit:DIGIT
    { 
        char c = digit.getText().charAt( 0 );
        value.upValue.append( c );
        value.bytes.append( ( byte ) c );
    }
    |
    alpha:ALPHA
    { 
        char c = alpha.getText().charAt( 0 );
        value.upValue.append( c );
        value.bytes.append( ( byte ) c  );
    }
    | 
    // Another hack : having a String like 127.0.0.1 in the value
    // will not match a DIGIT, because it's swallowed by the NUMERICOID
    // token
    numericoid:NUMERICOID  
    {
        String number = numericoid.getText();
        value.upValue.append( number );
        value.bytes.append( Strings.getBytesUtf8( number ) );
    }
    ;


/**
 * RFC 4514, Section 3:
 * <pre>
 * SUTF1 = %x01-21 / %x23-2A / %x2D-3A /
 *    %x3D / %x3F-5B / %x5D-7F
 *
 * The rule CHAR_REST doesn't contain the following charcters,
 * so we must check them additionally
 *   EQUALS (0x3D)
 *   HYPHEN (0x2D)
 *   UNDERSCORE (0x5F)
 *   DIGIT (0x30-0x39)
 *   ALPHA (0x41-0x5A and 0x61-0x7A)
 *   SHARP (0x23)
 *   SPACE (0x20)
 * </pre>
 *
 * @param value The value to update
 * @throws RecognitionException If the token is invalid
 * @throws TokenStreamException When we weren't able to fetch a token
 */
sutf1 [UpAndNormValue value]
    {
        matchedProduction( "sutf1()" );
    }
    :
    rest:CHAR_REST
    { 
        char c = rest.getText().charAt( 0 );
        value.upValue.append( c );
        value.bytes.append( ( byte ) c );
    }
    |
    EQUALS
    { 
        value.upValue.append( '=' );
        value.bytes.append( '=' );
    }
    |
    HYPHEN
    { 
        value.upValue.append( '-' );
        value.bytes.append( '-' );
    }
    |
    UNDERSCORE
    { 
        value.upValue.append( '_' );
        value.bytes.append( '_' );
    }
    |
    digit:DIGIT
    { 
        char c = digit.getText().charAt( 0 );
        value.upValue.append( c );
        value.bytes.append( ( byte ) c );
    }
    |
    alpha:ALPHA
    { 
        char c = alpha.getText().charAt( 0 );
        value.upValue.append( c );
        value.bytes.append( ( byte ) c );
    }
    |
    SHARP
    { 
        value.upValue.append( '#' );
        value.bytes.append( '#' );
    }
    | 
    SPACE
    { 
        value.upValue.append( ' ' );
        value.bytes.append( ' ' );
    }
    | 
    // This is a hack to deal with #NN included into the value, due to 
    // some collision with the HEXVALUE token. In this case, we should
    // consider that a hex value is in fact a String
    hex:HEXVALUE
    {
        String hexStr = hex.getText();
        value.upValue.append( '#' ).append( hexStr );
        value.bytes.append( '#' );
        value.bytes.append( Strings.getBytesUtf8( hexStr ) );
    }
    | 
    // Another hack : having a String like 127.0.0.1 in the value
    // will not match a DIGIT, because it's swallowed by the NUMERICOID
    // token
    numericoid:NUMERICOID  
    {
        String number = numericoid.getText();
        value.upValue.append( number );
        value.bytes.append( Strings.getBytesUtf8( number ) );
    }
    ;

/**
 * Process a UTFMB char
 *
 * @param value The value to update
 * @throws RecognitionException If the token is invalid
 * @throws TokenStreamException When we weren't able to fetch a token
 */
utfmb [UpAndNormValue value]
    {
        matchedProduction( "utfmb()" );
    }
    :
    s:UTFMB
    { 
        char c = s.getText().charAt( 0 );
        value.upValue.append( c );
        value.bytes.append( Unicode.charToBytes( c ) );
    }
    ;


/**
 * RFC 4514, Section 3
 * <pre>
 * pair = ESC ( ESC / special / hexpair )
 * special = escaped / SPACE / SHARP / EQUALS
 * escaped = DQUOTE / PLUS / COMMA / SEMI / LANGLE / RANGLE
 * hexpair = HEX HEX
 *
 * If in &lt;string&gt; form, a LDAP string representation asserted value can
 * be obtained by replacing (left to right, non-recursively) each &lt;pair&gt;
 * appearing in the &lt;string&gt; as follows:
 *   replace &lt;ESC&gt;&lt;ESC&gt; with &lt;ESC&gt;;
 *   replace &lt;ESC&gt;&lt;special&gt; with &lt;special&gt;;
 *   replace &lt;ESC&gt;&lt;hexpair&gt; with the octet indicated by the &lt;hexpair&gt;.
 * </pre>
 * 
 * RFC 2253, Section 3
 * <pre>
 * pair       = "\" ( special / "\" / QUOTATION / hexpair )
 * special    = "," / "=" / "+" / "&lt;" /  "&gt;" / "#" / ";"
 * </pre>
 * 
 * RFC 1779, Section 2.3
 * <pre>
 * &lt;pair&gt; ::= "\" ( &lt;special&gt; | "\" | '"')
 * &lt;special&gt; ::= "," | "=" | &lt;CR&gt; | "+" | "&lt;" |  "&gt;"
 *           | "#" | ";"
 * </pre>
 * 
 * @param value The value to update
 * @throws RecognitionException If the token is invalid
 * @throws TokenStreamException When we weren't able to fetch a token
 */ 
pair [UpAndNormValue value]
    {
        matchedProduction( "pair()" );
        char specialChar;
    }
    :
    (
        ESCESC 
        { 
            value.upValue.append( "\\\\" );
            value.bytes.append( '\\' );
        } 
    )
    |
    (
        ESCSHARP 
        { 
            value.upValue.append( "\\#" );
            value.bytes.append( '#' );
        } 
    )
    |
    ( 
        ESC
        specialChar = special 
        { 
            value.upValue.append( '\\' ).append( specialChar );
            value.bytes.append( specialChar );
        }
    )
    |
    (
        // A String like "\C4", corresponding to the hex value 0xC4. 
        hexpair:HEXPAIR
        {
            value.upValue.append( '\\' ).append( hexpair.getText() );
            value.bytes.append( Strings.toByteArray( hexpair.getText() ) );
        }
    )
    ;


/**
 * RFC 4514 Section 3
 * 
 * <pre>
 * special = escaped / SPACE / SHARP / EQUALS
 * escaped = DQUOTE / PLUS / COMMA / SEMI / LANGLE / RANGLE
 * </pre>
 *
 * @return The special char
 * @throws RecognitionException If the token is invalid
 * @throws TokenStreamException When we weren't able to fetch a token
 */
special returns [char special]
    {
        matchedProduction( "()" );
    }
    :
    (
        DQUOTE { special = '"'; }
        |
        PLUS { special = '+'; }
        |
        COMMA { special = ','; }
        |
        SEMI { special = ';'; }
        |
        LANGLE { special = '<'; }
        |
        RANGLE { special = '>'; }
        |
        SPACE { special = ' '; }
        |
        SHARP { special = '#'; }
        |
        EQUALS { special = '='; }
    )
    ;

