1 // Copyright 2014 The Bazel Authors. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 package com.google.devtools.common.options; 15 16 import java.util.Objects; 17 18 /** 19 * The position of an option in the interpretation order. Options are interpreted using a 20 * last-option-wins system for single valued options, and are listed in that order for 21 * multiple-valued options. 22 * 23 * <p>The position of the option is in category order, and within the priority category in index 24 * order. 25 */ 26 public class OptionPriority implements Comparable<OptionPriority> { 27 private final PriorityCategory priorityCategory; 28 private final int index; 29 private final boolean locked; 30 31 private OptionPriority(PriorityCategory priorityCategory, int index, boolean locked) { 32 this.priorityCategory = priorityCategory; 33 this.index = index; 34 this.locked = locked; 35 } 36 37 /** Get the first OptionPriority for that category. */ 38 static OptionPriority lowestOptionPriorityAtCategory(PriorityCategory category) { 39 return new OptionPriority(category, 0, false); 40 } 41 42 /** 43 * Get the priority for the option following this one. In normal, incremental option parsing, the 44 * returned priority would compareTo as after the current one. Does not increment locked 45 * priorities. 46 */ 47 static OptionPriority nextOptionPriority(OptionPriority priority) { 48 if (priority.locked) { 49 return priority; 50 } 51 return new OptionPriority(priority.priorityCategory, priority.index + 1, false); 52 } 53 54 /** 55 * Return a priority for this option that will avoid priority increases by calls to 56 * nextOptionPriority. 57 * 58 * <p>Some options are expanded in-place, and need to be all parsed at the priority of the 59 * original option. In this case, parsing one of these after another should not cause the option 60 * to be considered as higher priority than the ones before it (this would cause overlap between 61 * the expansion of --expansion_flag and a option following it in the same list of options). 62 */ 63 public static OptionPriority getLockedPriority(OptionPriority priority) { 64 return new OptionPriority(priority.priorityCategory, priority.index, true); 65 } 66 67 public PriorityCategory getPriorityCategory() { 68 return priorityCategory; 69 } 70 71 @Override 72 public int compareTo(OptionPriority o) { 73 if (priorityCategory.equals(o.priorityCategory)) { 74 return index - o.index; 75 } 76 return priorityCategory.ordinal() - o.priorityCategory.ordinal(); 77 } 78 79 @Override 80 public boolean equals(Object o) { 81 if (o instanceof OptionPriority) { 82 OptionPriority other = (OptionPriority) o; 83 return other.priorityCategory.equals(priorityCategory) && other.index == index; 84 } 85 return false; 86 } 87 88 @Override 89 public int hashCode() { 90 return Objects.hash(priorityCategory, index); 91 } 92 93 @Override 94 public String toString() { 95 return String.format("OptionPriority(%s,%s)", priorityCategory, index); 96 } 97 98 /** 99 * The priority of option values, in order of increasing priority. 100 * 101 * <p>In general, new values for options can only override values with a lower or equal priority. 102 * Option values provided in annotations in an options class are implicitly at the priority {@code 103 * DEFAULT}. 104 * 105 * <p>The ordering of the priorities is the source-code order. This is consistent with the 106 * automatically generated {@code compareTo} method as specified by the Java Language 107 * Specification. DO NOT change the source-code order of these values, or you will break code that 108 * relies on the ordering. 109 */ 110 public enum PriorityCategory { 111 112 /** 113 * The priority of values specified in the {@link Option} annotation. This should never be 114 * specified in calls to {@link OptionsParser#parse}. 115 */ 116 DEFAULT, 117 118 /** 119 * Overrides default options at runtime, while still allowing the values to be overridden 120 * manually. 121 */ 122 COMPUTED_DEFAULT, 123 124 /** For options coming from a configuration file or rc file. */ 125 RC_FILE, 126 127 /** For options coming from the command line. */ 128 COMMAND_LINE, 129 130 /** For options coming from invocation policy. */ 131 INVOCATION_POLICY, 132 133 /** 134 * This priority can be used to unconditionally override any user-provided options. This should 135 * be used rarely and with caution! 136 */ 137 SOFTWARE_REQUIREMENT 138 } 139 } 140