• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 Google, 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  */
16 package dagger.internal.codegen.writer;
17 
18 import com.google.common.collect.AbstractIterator;
19 import java.io.IOException;
20 import java.util.Iterator;
21 
22 final class IndentingAppendable implements Appendable {
23   private final String indentation;
24   private final Appendable delegate;
25   private boolean requiresIndent = true;
26 
IndentingAppendable(Appendable delegate)27   IndentingAppendable(Appendable delegate) {
28     this("  ", delegate);
29   }
30 
IndentingAppendable(String indentation, Appendable delegate)31   IndentingAppendable(String indentation, Appendable delegate) {
32     this.indentation = indentation;
33     this.delegate = delegate;
34   }
35 
36   @Override
append(CharSequence csq)37   public Appendable append(CharSequence csq) throws IOException {
38     return append(csq, 0, csq.length());
39   }
40 
41   @Override
append(CharSequence csq, int start, int end)42   public Appendable append(CharSequence csq, int start, int end) throws IOException {
43     Iterator<CharSequence> lines = lines(csq, start, end);
44     while (lines.hasNext()) {
45       CharSequence line = lines.next();
46       maybeIndent();
47       delegate.append(line);
48       if (line.charAt(line.length() - 1) == '\n') {
49         requiresIndent = true;
50       }
51     }
52     return this;
53   }
54 
55   @Override
append(char c)56   public Appendable append(char c) throws IOException {
57     maybeIndent();
58     delegate.append(c);
59     if (c == '\n') {
60       requiresIndent = true;
61     }
62     return this;
63   }
64 
maybeIndent()65   void maybeIndent() throws IOException {
66     if (requiresIndent) {
67       delegate.append(indentation);
68     }
69     requiresIndent = false;
70   }
71 
lines( final CharSequence csq, final int start, final int end)72   private static Iterator<CharSequence> lines(
73       final CharSequence csq, final int start, final int end) {
74     return new AbstractIterator<CharSequence>() {
75       int index = start;
76 
77       @Override protected CharSequence computeNext() {
78         int nextStart = index;
79         while (index < end && csq.charAt(index) != '\n') {
80           index++;
81         }
82         if (index < end && csq.charAt(index) == '\n') {
83           index++;
84         }
85         int nextEnd = index;
86         return nextStart >= end
87             ? endOfData()
88             : csq.subSequence(nextStart, nextEnd);
89       }
90     };
91   }
92 }
93