19808faf78deb962e7cced3d1abf517b0bb5ac9fcDamien Martin-Guillerez// Copyright 2014 The Bazel Authors. All rights reserved.
2e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez//
3e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez// Licensed under the Apache License, Version 2.0 (the "License");
4e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez// you may not use this file except in compliance with the License.
5e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez// You may obtain a copy of the License at
6e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez//
7e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez//    http://www.apache.org/licenses/LICENSE-2.0
8e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez//
9e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez// Unless required by applicable law or agreed to in writing, software
10e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez// distributed under the License is distributed on an "AS IS" BASIS,
11e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez// See the License for the specific language governing permissions and
13e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez// limitations under the License.
14e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez
15e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerezpackage com.google.devtools.common.options;
16e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez
17e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerezimport java.util.Arrays;
18e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez
19e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez/**
20e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez * A converter superclass for converters that parse enums.
21e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez *
22c7a523a3dd90d31cba1a59c0b8646718b41a5c28gregce * <p>Just subclass this class, creating a zero argument constructor that
23e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez * calls {@link #EnumConverter(Class, String)}.
24e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez *
25fea1cce4d906f348555653f7d4783a2f1e2f49a4Googler * <p>This class compares the input string to the string returned by the toString()
26e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez * method of each enum member in a case-insensitive way. Usually, this is the
27e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez * name of the symbol, but beware if you override toString()!
28e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez */
29e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerezpublic abstract class EnumConverter<T extends Enum<T>>
30e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez    implements Converter<T> {
31e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez
32e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez  private final Class<T> enumType;
33e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez  private final String typeName;
34e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez
35e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez  /**
36e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez   * Creates a new enum converter. You *must* implement a zero-argument
37e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez   * constructor that delegates to this constructor, passing in the appropriate
38e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez   * parameters.
39e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez   *
40e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez   * @param enumType The type of your enumeration; usually a class literal
41e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez   *                 like MyEnum.class
42e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez   * @param typeName The intuitive name of your enumeration, for example, the
43e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez   *                 type name for CompilationMode might be "compilation mode".
44e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez   */
45e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez  protected EnumConverter(Class<T> enumType, String typeName) {
46e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez    this.enumType = enumType;
47e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez    this.typeName = typeName;
48e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez  }
49e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez
50e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez  /**
51e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez   * Implements {@link #convert(String)}.
52e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez   */
53e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez  @Override
54fea1cce4d906f348555653f7d4783a2f1e2f49a4Googler  public T convert(String input) throws OptionsParsingException {
55e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez    for (T value : enumType.getEnumConstants()) {
56e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez      if (value.toString().equalsIgnoreCase(input)) {
57e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez        return value;
58e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez      }
59e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez    }
60e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez    throw new OptionsParsingException("Not a valid " + typeName + ": '"
61e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez                                      + input + "' (should be "
62e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez                                      + getTypeDescription() + ")");
63e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez  }
64e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez
65e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez  /**
66e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez   * Implements {@link #getTypeDescription()}.
67e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez   */
68e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez  @Override
69e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez  public final String getTypeDescription() {
70e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez    return Converters.joinEnglishList(
71e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez        Arrays.asList(enumType.getEnumConstants())).toLowerCase();
72e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez  }
73e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez
74e3f722934d1544379bd385e3053d515d3763095cDamien Martin-Guillerez}
75