/*
 * 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.logging.log4j.util;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Indicates that a particular annotated construct was written with certain performance constraints in mind that
 * should be considered when modifying or testing. Descriptive values should be similar to the conventions used by
 * {@link SuppressWarnings}. For example, code that should not be allocating objects (like iterators) could use the
 * description "allocation".
 *
 * @since 2.6
 */
// Not @Documented: Do not (yet) make this annotation part of the public API of annotated elements.
// No @Target: No restrictions yet on what code elements may be annotated or not.
@Retention(RetentionPolicy.CLASS) // Currently no need to reflectively discover this annotation at runtime.
public @interface PerformanceSensitive {
    /**
     * Is this ever used?
     * @return An array of strings.
     */
    String[] value() default "";
}
