/* This file is part of SableCC ( http://sablecc.org ).
 *
 * See the NOTICE file distributed with this work for copyright information.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.sablecc.sablecc.alphabet;

import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeSet;

import org.sablecc.sablecc.exception.InternalException;

/**
 * An instance of this class stores the result of merging two alphabets. It
 * allows for retrieving the new alphabet. It also maps each symbol, in a merged
 * alphabet, to the equivalent set of symbols in the new alphabet.
 */
public final class AlphabetMergeResult {

    /** The new alphabet. */
    private final Alphabet newAlphabet;

    /**
     * The symbol map. It maps each old symbol (in a merged alphabet) to a set
     * of new symbols that cover the same intervals.
     */
    private final SortedMap<Symbol, SortedSet<Symbol>> mergedAlphabetSymbolMap;

    /**
     * Constructs an instance to store the result of merging an alphabet with
     * itself.
     */
    AlphabetMergeResult(
            Alphabet alphabet) {

        if (alphabet == null) {
            throw new InternalException("alphabet may not be null");
        }

        this.newAlphabet = alphabet;
        this.mergedAlphabetSymbolMap = null;
    }

    /**
     * Constructs an instance to store the result of merging two distinct
     * alphabets.
     */
    AlphabetMergeResult(
            Alphabet newAlphabet,
            SortedMap<Symbol, SortedSet<Symbol>> mergedAlphabetSymbolMap) {

        if (newAlphabet == null) {
            throw new InternalException("newAlphabet may not be null");
        }

        if (mergedAlphabetSymbolMap == null) {
            throw new InternalException(
                    "mergedAlphabetSymbolMap may not be null");
        }

        this.newAlphabet = newAlphabet;
        this.mergedAlphabetSymbolMap = mergedAlphabetSymbolMap;
    }

    /**
     * Returns the new alphabet resulting from the merge.
     */
    public Alphabet getNewAlphabet() {

        return this.newAlphabet;
    }

    /**
     * Returns the set of new symbols covering the same intervals as the
     * provided old symbol.
     */
    public SortedSet<Symbol> getNewSymbols(
            Symbol oldSymbol) {

        if (oldSymbol == null) {
            throw new InternalException("oldSymbol may not be null");
        }

        // special case for an alphabet merged with itslef
        if (this.mergedAlphabetSymbolMap == null) {

            TreeSet<Symbol> set = new TreeSet<Symbol>();
            set.add(oldSymbol);
            return set;
        }

        if (!this.mergedAlphabetSymbolMap.containsKey(oldSymbol)) {
            throw new InternalException("oldSymbol is not valid");
        }

        return this.mergedAlphabetSymbolMap.get(oldSymbol);
    }
}

@@ -787,16 +787,42 @@
 tedSet;%0A
+import java.util.TreeMap;%0A
 import j
@@ -835,24 +835,24 @@
 il.TreeSet;%0A
-
 %0Aimport org.
@@ -1791,52 +1791,353 @@
 et;%0A
-        this.mergedAlphabetSymbolMap = null;
+%0A        // map each symbol to a set containing itself%0A        this.mergedAlphabetSymbolMap = new TreeMap%3CSymbol, SortedSet%3CSymbol%3E%3E();%0A%0A        for (Symbol symbol : alphabet.getSymbols()) %7B%0A            TreeSet%3CSymbol%3E set = new TreeSet%3CSymbol%3E();%0A            set.add(symbol);%0A            this.mergedAlphabetSymbolMap.put(symbol, set);%0A        %7D
 %0A   
@@ -3149,32 +3149,32 @@
 mbol == null) %7B%0A
+
             thro
@@ -3242,244 +3242,8 @@
  %7D%0A%0A
-        // special case for an alphabet merged with itslef%0A        if (this.mergedAlphabetSymbolMap == null) %7B%0A%0A            TreeSet%3CSymbol%3E set = new TreeSet%3CSymbol%3E();%0A            set.add(oldSymbol);%0A            return set;%0A        %7D%0A%0A
     

Create sets once at construction time.