15d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin/*
25d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * Copyright (C) 2014 Google, Inc.
35d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin *
45d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * Licensed under the Apache License, Version 2.0 (the "License");
55d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * you may not use this file except in compliance with the License.
65d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * You may obtain a copy of the License at
75d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin *
85d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * http://www.apache.org/licenses/LICENSE-2.0
95d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin *
105d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * Unless required by applicable law or agreed to in writing, software
115d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * distributed under the License is distributed on an "AS IS" BASIS,
125d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * See the License for the specific language governing permissions and
145d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * limitations under the License.
155d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin */
165d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinpackage dagger.internal.codegen.writer;
175d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin
1887182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffinimport com.google.common.collect.FluentIterable;
195d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport com.google.common.collect.Iterables;
205d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport com.google.common.collect.Maps;
2187182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffinimport com.google.common.collect.Sets;
225d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport java.io.IOException;
235d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport java.util.Map.Entry;
245d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport java.util.Set;
255d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport java.util.SortedMap;
265d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin
275d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport static dagger.internal.codegen.writer.Writables.toStringWritable;
285d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin
295d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinpublic final class AnnotationWriter implements Writable, HasClassReferences {
305d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin  private final ClassName annotationName;
3187182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin  private final Set<HasClassReferences> memberReferences = Sets.newLinkedHashSet();
325d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin  private final SortedMap<String, Writable> memberMap = Maps.newTreeMap();
335d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin
345d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin  AnnotationWriter(ClassName annotationName) {
355d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin    this.annotationName = annotationName;
365d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin  }
375d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin
385d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin  public void setValue(String value) {
395d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin    setMember("value", value);
405d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin  }
415d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin
425d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin  public void setMember(String name, int value) {
435d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin    memberMap.put(name, toStringWritable(value));
445d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin  }
455d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin
465d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin  public void setMember(String name, String value) {
475d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin    memberMap.put(name, toStringWritable(StringLiteral.forValue(value)));
485d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin  }
495d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin
5087182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin  public <T extends Enum<T>> void setMember(String name, T value) {
5187182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin    Snippet snippet = Snippet.format("%s.%s", ClassName.fromClass(value.getClass()), value);
5287182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin    memberMap.put(name, snippet);
5387182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin    memberReferences.add(snippet);
5487182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin  }
5587182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin
565d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin  @Override
575d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin  public Appendable write(Appendable appendable, Context context) throws IOException {
585d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin    appendable.append('@');
595d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin    annotationName.write(appendable, context);
605d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin    if (!memberMap.isEmpty()) {
615d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin      appendable.append('(');
625d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin      if (memberMap.size() == 1) {
635d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin        Entry<String, Writable> onlyEntry = Iterables.getOnlyElement(memberMap.entrySet());
645d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin        if (!onlyEntry.getKey().equals("value")) {
655d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin          appendable.append(onlyEntry.getKey()).append(" = ");
665d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin        }
675d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin        onlyEntry.getValue().write(appendable, context);
685d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin      }
695d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin      appendable.append(')');
705d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin    }
715d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin    return appendable;
725d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin  }
735d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin
745d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin  @Override
755d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin  public Set<ClassName> referencedClasses() {
7687182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin    return FluentIterable.from(memberReferences)
7787182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin        .append(annotationName)
7887182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin        .transformAndConcat(HasClassReferences.COMBINER)
7987182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin        .toSet();
805d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin  }
815d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin}
82