*/
package org.opendaylight.yangtools.yang.parser.stmt.reactor;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableCollection;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import java.util.ArrayList;
private final StatementIdentifier identifier;
private final StatementSourceReference statementDeclSource;
- private final Multimap<ModelProcessingPhase, OnPhaseFinished> phaseListeners =
- Multimaps.newListMultimap(new EnumMap<>(ModelProcessingPhase.class), () -> new ArrayList<>(1));
-
- private final Multimap<ModelProcessingPhase, ContextMutation> phaseMutation =
- Multimaps.newListMultimap(new EnumMap<>(ModelProcessingPhase.class), () -> new ArrayList<>(1));
-
- private final Map<StatementIdentifier, StatementContextBase<?, ?, ?>> substatements = new LinkedHashMap<>(1);
-
- private final Collection<StatementContextBase<?, ?, ?>> declared = new ArrayList<>(1);
- private final Collection<StatementContextBase<?, ?, ?>> effective = new ArrayList<>(1);
- private final Collection<StatementContextBase<?, ?, ?>> effectOfStatement = new ArrayList<>(1);
+ private Multimap<ModelProcessingPhase, OnPhaseFinished> phaseListeners = ImmutableMultimap.of();
+ private Multimap<ModelProcessingPhase, ContextMutation> phaseMutation = ImmutableMultimap.of();
+ private Map<StatementIdentifier, StatementContextBase<?, ?, ?>> substatements = ImmutableMap.of();
+ private Collection<StatementContextBase<?, ?, ?>> declared = ImmutableList.of();
+ private Collection<StatementContextBase<?, ?, ?>> effective = ImmutableList.of();
+ private Collection<StatementContextBase<?, ?, ?>> effectOfStatement = ImmutableList.of();
private SupportedByFeatures supportedByFeatures = SupportedByFeatures.UNDEFINED;
private CopyHistory copyHistory = CopyHistory.original();
@Override
public void addAsEffectOfStatement(final StatementContextBase<?, ?, ?> ctx) {
+ if (effectOfStatement.isEmpty()) {
+ effectOfStatement = new ArrayList<>(1);
+ }
effectOfStatement.add(ctx);
}
+
+ @Override
+ public void addAsEffectOfStatement(final Collection<StatementContextBase<?, ?, ?>> ctxs) {
+ if (ctxs.isEmpty()) {
+ return;
+ }
+
+ if (effectOfStatement.isEmpty()) {
+ effectOfStatement = new ArrayList<>(ctxs.size());
+ }
+ effectOfStatement.addAll(ctxs);
+ }
+
@Override
public SupportedByFeatures getSupportedByFeatures() {
return supportedByFeatures;
return identifier.getArgument();
}
- /**
- * @return collection of declared substatements
- */
+ private static final <T> Collection<T> maybeWrap(final Collection<T> input) {
+ if (input instanceof ImmutableCollection) {
+ return input;
+ }
+
+ return Collections.unmodifiableCollection(input);
+ }
+
@Override
public Collection<StatementContextBase<?, ?, ?>> declaredSubstatements() {
- return Collections.unmodifiableCollection(declared);
+ return maybeWrap(declared);
}
/**
- * @return collection of substatements
+ * @return collection of all substatements
*/
@Override
public Collection<StatementContextBase<?, ?, ?>> substatements() {
- return Collections.unmodifiableCollection(substatements.values());
+ return maybeWrap(substatements.values());
}
- /**
- * @return collection of effective substatements
- */
@Override
public Collection<StatementContextBase<?, ?, ?>> effectiveSubstatements() {
- return Collections.unmodifiableCollection(effective);
+ return maybeWrap(effective);
}
public void removeStatementsFromEffectiveSubstatements(final Collection<StatementContextBase<?, ?, ?>> substatements) {
- effective.removeAll(substatements);
+ if (!effective.isEmpty()) {
+ effective.removeAll(substatements);
+ shrinkEffective();
+ }
+ }
+
+ private void shrinkEffective() {
+ if (effective.isEmpty()) {
+ effective = ImmutableList.of();
+ }
}
public void removeStatementFromEffectiveSubstatements(final StatementDefinition refineSubstatementDef) {
+ if (effective.isEmpty()) {
+ return;
+ }
+
final Iterator<StatementContextBase<?, ?, ?>> iterator = effective.iterator();
while (iterator.hasNext()) {
final StatementContextBase<?, ?, ?> next = iterator.next();
iterator.remove();
}
}
+
+ shrinkEffective();
}
/**
* if statement parameter is null
*/
public void addEffectiveSubstatement(final StatementContextBase<?, ?, ?> substatement) {
+ Preconditions.checkNotNull(substatement, "StatementContextBase effective substatement cannot be null at: %s",
+ getStatementSourceReference());
+ beforeAddEffectiveStatement(1);
+ effective.add(substatement);
+ }
+ /**
+ * adds effective statement to collection of substatements
+ *
+ * @param substatements substatements
+ * @throws IllegalStateException
+ * if added in declared phase
+ * @throws NullPointerException
+ * if statement parameter is null
+ */
+ public void addEffectiveSubstatements(final Collection<StatementContextBase<?, ?, ?>> substatements) {
+ if (substatements.isEmpty()) {
+ return;
+ }
+
+ substatements.forEach(Preconditions::checkNotNull);
+ beforeAddEffectiveStatement(substatements.size());
+ effective.addAll(substatements);
+ }
+
+ private void beforeAddEffectiveStatement(final int toAdd) {
final ModelProcessingPhase inProgressPhase = getRoot().getSourceContext().getInProgressPhase();
Preconditions.checkState(inProgressPhase == ModelProcessingPhase.FULL_DECLARATION
|| inProgressPhase == ModelProcessingPhase.EFFECTIVE_MODEL,
"Effective statement cannot be added in declared phase at: %s", getStatementSourceReference());
- effective.add(Preconditions.checkNotNull(substatement,
- "StatementContextBase effective substatement cannot be null at: %s", getStatementSourceReference()));
+ if (effective.isEmpty()) {
+ effective = new ArrayList<>(toAdd);
+ }
}
/**
Preconditions.checkState(inProgressPhase != ModelProcessingPhase.EFFECTIVE_MODEL,
"Declared statement cannot be added in effective phase at: %s", getStatementSourceReference());
+ if (declared.isEmpty()) {
+ declared = new ArrayList<>(1);
+ }
declared.add(Preconditions.checkNotNull(substatement,
"StatementContextBase declared substatement cannot be null at: %s", getStatementSourceReference()));
}
/**
- * builds new substatement from statement definition context and statement source reference
+ * builds a new substatement from statement definition context and statement source reference
*
* @param def definition context
* @param ref source reference
}
if (potential == null) {
potential = new SubstatementContext(StatementContextBase.this, this);
+ if (substatements.isEmpty()) {
+ substatements = new LinkedHashMap<>(1);
+ }
substatements.put(createIdentifier(), potential);
getDefinition().onStatementAdded(potential);
}
Preconditions.checkState(sourceContext.getInProgressPhase() != ModelProcessingPhase.EFFECTIVE_MODEL,
"Declared statements list cannot be cleared in effective phase at: %s", getStatementSourceReference());
- declared.clear();
+ declared = ImmutableList.of();
}
/**
* when an error occured in source parsing
*/
boolean tryToCompletePhase(final ModelProcessingPhase phase) {
- final Iterator<ContextMutation> openMutations = phaseMutation.get(phase).iterator();
+
boolean finished = true;
- while (openMutations.hasNext()) {
- final ContextMutation current = openMutations.next();
- if (current.isFinished()) {
- openMutations.remove();
- } else {
- finished = false;
+ final Collection<ContextMutation> openMutations = phaseMutation.get(phase);
+ if (!openMutations.isEmpty()) {
+ final Iterator<ContextMutation> it = openMutations.iterator();
+ while (it.hasNext()) {
+ final ContextMutation current = it.next();
+ if (current.isFinished()) {
+ it.remove();
+ } else {
+ finished = false;
+ }
+ }
+
+ if (openMutations.isEmpty()) {
+ phaseMutation.removeAll(phase);
+ if (phaseMutation.isEmpty()) {
+ phaseMutation = ImmutableMultimap.of();
+ }
}
}
+
for (final StatementContextBase<?, ?, ?> child : declared) {
finished &= child.tryToCompletePhase(phase);
}
*/
private void onPhaseCompleted(final ModelProcessingPhase phase) {
completedPhase = phase;
- final Iterator<OnPhaseFinished> listener = phaseListeners.get(completedPhase).iterator();
+
+ final Collection<OnPhaseFinished> listeners = phaseListeners.get(phase);
+ if (listeners.isEmpty()) {
+ return;
+ }
+
+ final Iterator<OnPhaseFinished> listener = listeners.iterator();
while (listener.hasNext()) {
final OnPhaseFinished next = listener.next();
if (next.phaseFinished(this, phase)) {
listener.remove();
}
}
+
+ if (listeners.isEmpty()) {
+ phaseListeners.removeAll(phase);
+ if (phaseListeners.isEmpty()) {
+ phaseListeners = ImmutableMultimap.of();
+ }
+ }
}
/**
return getRoot().getSourceContext().newInferenceAction(phase);
}
+ private static <T> Multimap<ModelProcessingPhase, T> newMultimap() {
+ return Multimaps.newListMultimap(new EnumMap<>(ModelProcessingPhase.class), () -> new ArrayList<>(1));
+ }
+
/**
* adds {@link OnPhaseFinished} listener for a {@link ModelProcessingPhase} end
*
}
finishedPhase = finishedPhase.getPreviousPhase();
}
+ if (phaseListeners.isEmpty()) {
+ phaseListeners = newMultimap();
+ }
+
phaseListeners.put(phase, listener);
}
}
finishedPhase = finishedPhase.getPreviousPhase();
}
+
+ if (phaseMutation.isEmpty()) {
+ phaseMutation = newMultimap();
+ }
phaseMutation.put(phase, mutation);
}
final StmtContext<?, ?, ?> stmt) {
addContextToNamespace(namespace, (K) key, stmt);
}
+
+ @Override
+ public final String toString() {
+ return addToStringAttributes(MoreObjects.toStringHelper(this).omitNullValues()).toString();
+ }
+
+ protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
+ return toStringHelper.add("definition", definition).add("id", identifier);
+ }
}