All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dev.cel.common.CelValidationResult Maven / Gradle / Ivy

// Copyright 2022 Google LLC
//
// 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
//
//      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 dev.cel.common;

import static com.google.common.collect.ImmutableList.toImmutableList;
import static java.util.Comparator.comparing;

import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.annotations.Immutable;
import com.google.errorprone.annotations.InlineMe;
import dev.cel.common.annotations.Internal;
import org.jspecify.nullness.Nullable;

/**
 * CelValidationResult encapsulates the {@code CelAbstractSyntaxTree} and {@code CelIssue} set which
 * may be generated during the parse and check phases.
 */
@Immutable
public final class CelValidationResult {

  private static final Joiner JOINER = Joiner.on('\n');

  @SuppressWarnings("Immutable")
  private final @Nullable Throwable failure;

  private final @Nullable CelAbstractSyntaxTree ast;
  private final CelSource source;
  private final ImmutableList issues;
  private final boolean hasError;

  /** Internal: Consumers should not be creating an instance of this class directly. */
  @Internal
  public CelValidationResult(CelSource source, ImmutableList issues) {
    this(/* ast= */ null, source, issues, /* failure= */ null);
  }

  /** Internal: Consumers should not be creating an instance of this class directly. */
  @Internal
  public CelValidationResult(CelSource source, Throwable failure, ImmutableList issues) {
    this(/* ast= */ null, source, issues, failure);
  }

  /** Internal: Consumers should not be creating an instance of this class on their own */
  @Internal
  public CelValidationResult(CelAbstractSyntaxTree ast, ImmutableList issues) {
    this(ast, ast.getSource(), issues, /* failure= */ null);
  }

  private CelValidationResult(
      @Nullable CelAbstractSyntaxTree ast,
      CelSource source,
      ImmutableList issues,
      @Nullable Throwable failure) {
    this.ast = ast;
    this.source = source;
    this.issues = ImmutableList.sortedCopyOf(comparing(CelIssue::getSourceLocation), issues);
    this.hasError = issues.stream().anyMatch(CelValidationResult::issueIsError) || failure != null;
    this.failure = failure;
  }

  /**
   * Returns the validated {@code CelAbstractSyntaxTree} if one exists.
   *
   * 

When {@link #hasError} returns {@code true}, this accessor will throw a {@link * CelValidationException} containing the error set which prevented AST generation. */ @CanIgnoreReturnValue public CelAbstractSyntaxTree getAst() throws CelValidationException { if (hasError) { if (failure != null) { throw new CelValidationException(source, getErrors(), failure.getMessage(), failure); } throw new CelValidationException(source, getErrors()); } return ast; } /** Return the {@code CelSource} associated with the result. */ public CelSource getSource() { return source; } /** * Whether a {@code CelIssue} with an {@link CelIssue.Severity#ERROR} severity was encountered * during validation. */ public boolean hasError() { return hasError; } /** Return the set of {@code CelIssue}s with an {@code ERROR} severity. */ public ImmutableList getErrors() { return issues.stream().filter(CelValidationResult::issueIsError).collect(toImmutableList()); } /** Return all {@code CelIssue}s encountered durint validation. */ public ImmutableList getAllIssues() { return issues; } /** Convert all issues to a human-readable string. */ public String getIssueString() { return JOINER.join(Iterables.transform(issues, iss -> iss.toDisplayString(source))); } /** * Convert the {@code CelIssue} set to a debug string. * * @deprecated Use {@link #getIssueString()} instead. */ @Deprecated @InlineMe(replacement = "this.getIssueString()") public String getDebugString() { return getIssueString(); } /** Convert the {@code CelIssue}s with {@code ERROR} severity to an error string. */ public String getErrorString() { return JOINER.join(Iterables.transform(getErrors(), error -> error.toDisplayString(source))); } private static boolean issueIsError(CelIssue iss) { return iss.getSeverity() == CelIssue.Severity.ERROR; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy