1/*
2 * Copyright (C) 2014 Square, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package dagger.internal.codegen.writer;
17
18import java.util.Formatter;
19
20/**
21 * Represents a string literal as found in Java source code.
22 */
23public final class StringLiteral {
24  /** Returns a new {@link StringLiteral} instance for the intended value of the literal. */
25  public static StringLiteral forValue(String value) {
26    return new StringLiteral(value, stringLiteral(value));
27  }
28
29  /** Returns the string literal representing {@code data}, including wrapping quotes. */
30  private static String stringLiteral(String value) {
31    StringBuilder result = new StringBuilder();
32    result.append('"');
33    for (int i = 0; i < value.length(); i++) {
34      char c = value.charAt(i);
35      switch (c) {
36        case '"':
37          result.append("\\\"");
38          break;
39        case '\\':
40          result.append("\\\\");
41          break;
42        case '\b':
43          result.append("\\b");
44          break;
45        case '\t':
46          result.append("\\t");
47          break;
48        case '\n':
49          result.append("\\n");
50          break;
51        case '\f':
52          result.append("\\f");
53          break;
54        case '\r':
55          result.append("\\r");
56          break;
57        default:
58          if (Character.isISOControl(c)) {
59            new Formatter(result).format("\\u%04x", (int) c);
60          } else {
61            result.append(c);
62          }
63      }
64    }
65    result.append('"');
66    return result.toString();
67  }
68
69  private final String value;
70  private final String literal;
71
72  private StringLiteral(String value, String literal) {
73    this.value = value;
74    this.literal = literal;
75  }
76
77  public String value() {
78    return value;
79  }
80
81  public String literal() {
82    return literal;
83  }
84
85  @Override
86  public String toString() {
87    return literal;
88  }
89
90  @Override
91  public boolean equals(Object obj) {
92    if (obj == this) {
93      return true;
94    } else if (obj instanceof StringLiteral) {
95      return this.value.equals(((StringLiteral) obj).value);
96    } else {
97      return false;
98    }
99  }
100
101  @Override
102  public int hashCode() {
103    return value.hashCode();
104  }
105}
106