getCachedContext static method

Implementation

static PredictionContext getCachedContext(
  PredictionContext context,
  PredictionContextCache contextCache,
  Map<PredictionContext, PredictionContext> visited,
) {
  if (context.isEmpty) {
    return context;
  }

  var existing = visited[context];
  if (existing != null) {
    return existing;
  }

  existing = contextCache[context];
  if (existing != null) {
    visited[context] = existing;
    return existing;
  }

  var changed = false;
  var parents = <PredictionContext>[];
  for (var i = 0; i < parents.length; i++) {
    final parent = getCachedContext(
      context.getParent(i)!,
      contextCache,
      visited,
    );
    if (changed || parent != context.getParent(i)) {
      if (!changed) {
        parents = <PredictionContext>[];
        for (var j = 0; j < context.length; j++) {
          parents.add(context.getParent(j)!);
        }

        changed = true;
      }

      parents[i] = parent;
    }
  }

  if (!changed) {
    contextCache.add(context);
    visited[context] = context;
    return context;
  }

  PredictionContext updated;
  if (parents.isEmpty) {
    updated = EmptyPredictionContext.Instance;
  } else if (parents.length == 1) {
    updated = SingletonPredictionContext.create(
        parents[0], context.getReturnState(0));
  } else {
    final arrayPredictionContext = context as ArrayPredictionContext;
    updated = ArrayPredictionContext(
      parents,
      arrayPredictionContext.returnStates,
    );
  }

  contextCache.add(updated);
  visited[updated] = updated;
  visited[context] = updated;

  return updated;
}