<commit_before>package org.lamport.tla.toolbox.spec.parser;

import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.lamport.tla.toolbox.Activator;
import org.lamport.tla.toolbox.tool.SpecEvent;
import org.lamport.tla.toolbox.tool.SpecLifecycleParticipant;
import org.lamport.tla.toolbox.util.ResourceHelper;

import tla2sany.semantic.ModuleNode;

/**
 * Singleton class for broadcasting new parse results to listeners. Get the
 * instance of this class by calling {@link ParseResultBroadcaster#getParseResultBroadcaster()}.
 * 
 * Classes that want to broadcast the result of parsing of a module should call
 * {@link ParseResultBroadcaster#broadcastParseResult(ParseResult)}.
 * 
 * Classes that want to listen for new parse results should implement
 * {@link IParseResultListener} and should add themselves by calling
 * {@link ParseResultBroadcaster#addParseResultListener(IParseResultListener)} and remove
 * themselves by calling {@link ParseResultBroadcaster#removeParseResultListener(IParseResultListener)}.
 * 
 * Classes can also get the most recent {@link ParseResult} for a given module
 * by calling {@link ParseResultBroadcaster#getParseResult(IPath)}.
 * 
 * All {@link ParseResult}s are for those produced while the currently opened spec
 * was open. Note that this includes any {@link ParseResult}s produced for modules
 * saved by TLC.
 * 
 * When the spec is closed, all information in this class should be cleared
 * by calling {@link ParseResultBroadcaster#clear()}.
 * 
 * @author <NAME>
 *
 */
public class ParseResultBroadcaster
{

    private static ParseResultBroadcaster instance;
    private List<IParseResultListener> listeners;
    /**
     * Map from {@link IPath} to the most recent
     * {@link ParseResult} containing that module that
     * exists at that full file system path.
     */
    private Map<IPath, ParseResult> parseResults;

    /**
     * This is a singleton class, so the constructor
     * should not be called by clients. Instead, use
     * {@link ParseResultBroadcaster#getParseResultBroadcaster()}.
     */
    private ParseResultBroadcaster()
    {
        listeners = new LinkedList<IParseResultListener>();
        parseResults = new HashMap<IPath, ParseResult>();
        Activator.getSpecManager().addSpecLifecycleParticipant(new SpecLifecycleParticipant() {
			/* (non-Javadoc)
			 * @see org.lamport.tla.toolbox.tool.SpecLifecycleParticipant#eventOccured(org.lamport.tla.toolbox.tool.SpecEvent)
			 */
			public boolean eventOccured(SpecEvent event) {
				if (event.getType() == SpecEvent.TYPE_CLOSE) {
					/*
					 * We clear any information that the parse result
					 * broadcaster has when the spec is closed because the
					 * parse result broadcasters saves a map of module names
					 * to parse results. These module names are unique
					 * within a spec but not unique globally so information
					 * in the class should not persist across changes of
					 * specs.
					 */
					ParseResultBroadcaster.this.clear();
				}
				return true;
			}
		});
    }
<commit_msg>TLA+ Syntax Parser throws java.util.ConcurrentModificationException<commit_after>package org.lamport.tla.toolbox.spec.parser;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.lamport.tla.toolbox.Activator;
import org.lamport.tla.toolbox.tool.SpecEvent;
import org.lamport.tla.toolbox.tool.SpecLifecycleParticipant;
import org.lamport.tla.toolbox.util.ResourceHelper;

import tla2sany.semantic.ModuleNode;

/**
 * Singleton class for broadcasting new parse results to listeners. Get the
 * instance of this class by calling {@link ParseResultBroadcaster#getParseResultBroadcaster()}.
 * 
 * Classes that want to broadcast the result of parsing of a module should call
 * {@link ParseResultBroadcaster#broadcastParseResult(ParseResult)}.
 * 
 * Classes that want to listen for new parse results should implement
 * {@link IParseResultListener} and should add themselves by calling
 * {@link ParseResultBroadcaster#addParseResultListener(IParseResultListener)} and remove
 * themselves by calling {@link ParseResultBroadcaster#removeParseResultListener(IParseResultListener)}.
 * 
 * Classes can also get the most recent {@link ParseResult} for a given module
 * by calling {@link ParseResultBroadcaster#getParseResult(IPath)}.
 * 
 * All {@link ParseResult}s are for those produced while the currently opened spec
 * was open. Note that this includes any {@link ParseResult}s produced for modules
 * saved by TLC.
 * 
 * When the spec is closed, all information in this class should be cleared
 * by calling {@link ParseResultBroadcaster#clear()}.
 * 
 * @author <NAME>
 *
 */
public class ParseResultBroadcaster
{

    private static ParseResultBroadcaster instance;
    private final List<IParseResultListener> listeners;
    /**
     * Map from {@link IPath} to the most recent
     * {@link ParseResult} containing that module that
     * exists at that full file system path.
     */
    private Map<IPath, ParseResult> parseResults;

    /**
     * This is a singleton class, so the constructor
     * should not be called by clients. Instead, use
     * {@link ParseResultBroadcaster#getParseResultBroadcaster()}.
     */
    private ParseResultBroadcaster()
    {
        listeners = new CopyOnWriteArrayList<IParseResultListener>();
        parseResults = new HashMap<IPath, ParseResult>();
        Activator.getSpecManager().addSpecLifecycleParticipant(new SpecLifecycleParticipant() {
			/* (non-Javadoc)
			 * @see org.lamport.tla.toolbox.tool.SpecLifecycleParticipant#eventOccured(org.lamport.tla.toolbox.tool.SpecEvent)
			 */
			public boolean eventOccured(SpecEvent event) {
				if (event.getType() == SpecEvent.TYPE_CLOSE) {
					/*
					 * We clear any information that the parse result
					 * broadcaster has when the spec is closed because the
					 * parse result broadcasters saves a map of module names
					 * to parse results. These module names are unique
					 * within a spec but not unique globally so information
					 * in the class should not persist across changes of
					 * specs.
					 */
					ParseResultBroadcaster.this.clear();
				}
				return true;
			}
		});
    }

{'fraction_non_alphanumeric': 0.08444649163212037, 'fraction_numerical': 0.00030707815138952864, 'mean_word_length': 4.006917755572636, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4560192', 'n_tokens_mistral': 1938, 'n_tokens_neox': 1729, 'n_words': 569}