/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you 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.apache.calcite.sql.type;

import org.apache.calcite.sql.SqlCallBinding;
import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.SqlOperandCountRange;

/**
 * SqlSingleOperandTypeChecker is an extension of {@link SqlOperandTypeChecker}
 * for implementations which are capable of checking the type of a single
 * operand in isolation. This isn't meaningful for all type-checking rules (e.g.
 * SameOperandTypeChecker requires two operands to have matching types, so
 * checking one in isolation is meaningless).
 */
public interface SqlSingleOperandTypeChecker extends SqlOperandTypeChecker {
  //~ Methods ----------------------------------------------------------------

  /**
   * Checks the type of a single operand against a particular ordinal position
   * within a formal operator signature. Note that the actual ordinal position
   * of the operand being checked may be <em>different</em> from the position
   * of the formal operand.
   *
   * <p>For example, when validating the actual call
   *
   * <blockquote>
   * <pre>C(X, Y, Z)</pre>
   * </blockquote>
   *
   * <p>the strategy for validating the operand Z might involve checking its
   * type against the formal signature OP(W). In this case,
   * <code>iFormalOperand</code> would be zero, even though the position of Z
   * within call C is two.
   *
   * <p>Caution that we could not(shouldn't) implement implicit type coercion for this checker,
   * implicit type coercion has side effect(modify the AST), if this single operand checker is
   * subsumed in a composite rule(OR or AND), we can not make any side effect if we
   * can not make sure that all the single operands type check are passed(with type coercion).
   * But there is an exception: only if the call has just one operand, for this case,
   * use {@link SqlOperandTypeChecker#checkOperandTypes} instead.
   *
   * @param callBinding    description of the call being checked; this is only
   *                       provided for context when throwing an exception; the
   *                       implementation should <em>NOT</em> examine the
   *                       operands of the call as part of the check
   * @param operand        the actual operand to be checked
   * @param iFormalOperand the 0-based formal operand ordinal
   * @param throwOnFailure whether to throw an exception if check fails
   *                       (otherwise returns false in that case)
   * @return whether check succeeded
   */
  boolean checkSingleOperandType(
      SqlCallBinding callBinding,
      SqlNode operand,
      int iFormalOperand,
      boolean throwOnFailure);

  @Override default boolean checkOperandTypes(SqlCallBinding callBinding,
      boolean throwOnFailure) {
    return checkSingleOperandType(callBinding, callBinding.operand(0), 0,
        throwOnFailure);
  }

  @Override default SqlOperandCountRange getOperandCountRange() {
    return SqlOperandCountRanges.of(1);
  }

  /** Composes this with another single-operand checker using AND. */
  default SqlSingleOperandTypeChecker and(
      SqlSingleOperandTypeChecker checker) {
    return OperandTypes.and(this, checker);
  }

  /** Composes this with another single-operand checker using OR. */
  default SqlSingleOperandTypeChecker or(
      SqlSingleOperandTypeChecker checker) {
    return OperandTypes.or(this, checker);
  }
}
