content: /*
   * 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.util.trace;
  
  import org.checkerframework.checker.nullness.qual.Nullable;
  import org.slf4j.Logger;
  
  import static java.util.Objects.requireNonNull;
  
  /**
   * Small extension to {@link Logger} with some performance improvements.
   *
   * <p>{@link Logger#info(String format, Object[] params)} is expensive
   * to call, since the caller must always allocate and fill in the array
   * <code>params</code>, even when the <code>level</code> will prevent a message
   * being logged. On the other hand, {@link Logger#info(String msg)}
   * and {@link Logger#info(String msg, Object o)} do not have this
   * problem.
   *
   * <p>As a workaround this class provides
   * {@link #info(String msg, Object o1, Object o2)} etc. (The varargs feature of
   * java 1.5 half-solves this problem, by automatically wrapping args in an
   * array, but it does so without testing the level.)
   *
   * <p>Usage: replace:
   *
   * <blockquote><code>static final Logger tracer =
   * CalciteTracer.getMyTracer();</code></blockquote>
   *
   * <p>by:
   *
   * <blockquote><code>static final CalciteLogger tracer =
   *     new CalciteLogger(CalciteTrace.getMyTracer());</code></blockquote>
   */
  public class CalciteLogger {
    //~ Instance fields --------------------------------------------------------
  
    private final Logger logger; // delegate
  
    //~ Constructors -----------------------------------------------------------
  
    public CalciteLogger(Logger logger) {
      this.logger = requireNonNull(logger, "logger");
    }
  
    //~ Methods ----------------------------------------------------------------
  
    // WARN
  
    /**
     * Logs a WARN message with two Object parameters.
     */
    public void warn(String format, @Nullable Object arg1, @Nullable Object arg2) {
      // slf4j already avoids the array creation for 1 or 2 arg invocations
      logger.warn(format, arg1, arg2);
    }
  
    /**
     * Conditionally logs a WARN message with three Object parameters.
     */
    public void warn(String format, @Nullable Object arg1, @Nullable Object arg2,
        @Nullable Object arg3) {
      if (logger.isWarnEnabled()) {
        logger.warn(format, arg1, arg2, arg3);
      }
    }
  
    /**
     * Conditionally logs a WARN message with four Object parameters.
     */
    public void warn(String format, @Nullable Object arg1, @Nullable Object arg2,
        @Nullable Object arg3, @Nullable Object arg4) {
      if (logger.isWarnEnabled()) {
        logger.warn(format, arg1, arg2, arg3, arg4);
      }
    }
  
    public void warn(String format, Object... args) {
      if (logger.isWarnEnabled()) {
        logger.warn(format, args);
      }
    }
  
    // INFO
  
    /**
     * Logs an INFO message with two Object parameters.
     */
    public void info(String format, @Nullable Object arg1, @Nullable Object arg2) {
      // slf4j already avoids the array creation for 1 or 2 arg invocations
      logger.info(format, arg1, arg2);
    }
  
    /**
     * Conditionally logs an INFO message with three Object parameters.
     */
    public void info(String format, @Nullable Object arg1, @Nullable Object arg2,
        @Nullable Object arg3) {
      if (logger.isInfoEnabled()) {
        logger.info(format, arg1, arg2, arg3);
      }
    }
  
    /**
     * Conditionally logs an INFO message with four Object parameters.
     */
    public void info(String format, @Nullable Object arg1, @Nullable Object arg2,
        @Nullable Object arg3, @Nullable Object arg4) {
      if (logger.isInfoEnabled()) {
        logger.info(format, arg1, arg2, arg3, arg4);
      }
    }
  
    public void info(String format, Object... args) {
      if (logger.isInfoEnabled()) {
        logger.info(format, args);
      }
    }
  
    // DEBUG
  
    /**
     * Logs a DEBUG message with two Object parameters.
     */
    public void debug(String format, @Nullable Object arg1, @Nullable Object arg2) {
      // slf4j already avoids the array creation for 1 or 2 arg invocations
      logger.debug(format, arg1, arg2);
    }
  
    /**
     * Conditionally logs a DEBUG message with three Object parameters.
     */
    public void debug(String format, @Nullable Object arg1, @Nullable Object arg2,
        @Nullable Object arg3) {
      if (logger.isDebugEnabled()) {
        logger.debug(format, arg1, arg2, arg3);
      }
    }
  
    /**
     * Conditionally logs a DEBUG message with four Object parameters.
     */
    public void debug(String format, @Nullable Object arg1, @Nullable Object arg2,
        @Nullable Object arg3, @Nullable Object arg4) {
      if (logger.isDebugEnabled()) {
        logger.debug(format, arg1, arg2, arg3, arg4);
      }
    }
  
    public void debug(String format, Object... args) {
      if (logger.isDebugEnabled()) {
        logger.debug(format, args);
      }
    }
  
    // TRACE
  
    /**
     * Logs a TRACE message with two Object parameters.
     */
    public void trace(String format, @Nullable Object arg1, @Nullable Object arg2) {
      // slf4j already avoids the array creation for 1 or 2 arg invocations
      logger.trace(format, arg1, arg2);
    }
  
    /**
     * Conditionally logs a TRACE message with three Object parameters.
     */
    public void trace(String format, @Nullable Object arg1, @Nullable Object arg2,
        @Nullable Object arg3) {
      if (logger.isTraceEnabled()) {
        logger.trace(format, arg1, arg2, arg3);
      }
    }
  
    /**
     * Conditionally logs a TRACE message with four Object parameters.
     */
    public void trace(String format, @Nullable Object arg1, @Nullable Object arg2,
        @Nullable Object arg3, @Nullable Object arg4) {
      if (logger.isTraceEnabled()) {
        logger.trace(format, arg1, arg2, arg3, arg4);
      }
    }
  
    public void trace(String format, @Nullable Object... args) {
      if (logger.isTraceEnabled()) {
        logger.trace(format, args);
      }
    }
  
    // We expose and delegate the commonly used part of the Logger interface.
    // For everything else, just expose the delegate. (Could use reflection.)
    public Logger getLogger() {
      return logger;
    }
  
    // Hold-over from the previous j.u.logging implementation
  
    public void warn(String msg) {
      logger.warn(msg);
    }
  
    public void info(String msg) {
      logger.info(msg);
    }
  }
  