xref: /aosp_15_r20/external/auto/value/userguide/builders-howto.md (revision 1c2bbba85eccddce6de79cbbf1645fda32e723f0)
1*1c2bbba8SAndroid Build Coastguard Worker# How do I... (Builder edition)
2*1c2bbba8SAndroid Build Coastguard Worker
3*1c2bbba8SAndroid Build Coastguard Worker
4*1c2bbba8SAndroid Build Coastguard WorkerThis page answers common how-to questions that may come up when using AutoValue
5*1c2bbba8SAndroid Build Coastguard Worker**with the builder option**. You should read and understand [AutoValue with
6*1c2bbba8SAndroid Build Coastguard Workerbuilders](builders.md) first.
7*1c2bbba8SAndroid Build Coastguard Worker
8*1c2bbba8SAndroid Build Coastguard WorkerIf you are not using a builder, see [Introduction](index.md) and
9*1c2bbba8SAndroid Build Coastguard Worker[How do I...](howto.md) instead.
10*1c2bbba8SAndroid Build Coastguard Worker
11*1c2bbba8SAndroid Build Coastguard Worker## Contents
12*1c2bbba8SAndroid Build Coastguard Worker
13*1c2bbba8SAndroid Build Coastguard WorkerHow do I...
14*1c2bbba8SAndroid Build Coastguard Worker
15*1c2bbba8SAndroid Build Coastguard Worker*   ... [use (or not use) `set` **prefixes**?](#beans)
16*1c2bbba8SAndroid Build Coastguard Worker*   ... [use different **names** besides
17*1c2bbba8SAndroid Build Coastguard Worker    `builder()`/`Builder`/`build()`?](#build_names)
18*1c2bbba8SAndroid Build Coastguard Worker*   ... [specify a **default** value for a property?](#default)
19*1c2bbba8SAndroid Build Coastguard Worker*   ... [initialize a builder to the same property values as an **existing**
20*1c2bbba8SAndroid Build Coastguard Worker    value instance](#to_builder)
21*1c2bbba8SAndroid Build Coastguard Worker*   ... [include `with-` methods on my value class for creating slightly
22*1c2bbba8SAndroid Build Coastguard Worker    **altered** instances?](#withers)
23*1c2bbba8SAndroid Build Coastguard Worker*   ... [**validate** property values?](#validate)
24*1c2bbba8SAndroid Build Coastguard Worker*   ... [**normalize** (modify) a property value at `build` time?](#normalize)
25*1c2bbba8SAndroid Build Coastguard Worker*   ... [expose **both** a builder and a factory method?](#both)
26*1c2bbba8SAndroid Build Coastguard Worker*   ... [handle `Optional` properties?](#optional)
27*1c2bbba8SAndroid Build Coastguard Worker*   ... [use a **collection**-valued property?](#collection)
28*1c2bbba8SAndroid Build Coastguard Worker    *   ... [let my builder **accumulate** values for a collection-valued
29*1c2bbba8SAndroid Build Coastguard Worker        property (not require them all at once)?](#accumulate)
30*1c2bbba8SAndroid Build Coastguard Worker    *   ... [accumulate values for a collection-valued property, without
31*1c2bbba8SAndroid Build Coastguard Worker        **"breaking the chain"**?](#add)
32*1c2bbba8SAndroid Build Coastguard Worker    *   ... [offer **both** accumulation and set-at-once methods for the same
33*1c2bbba8SAndroid Build Coastguard Worker        collection-valued property?](#collection_both)
34*1c2bbba8SAndroid Build Coastguard Worker*   ... [access nested builders while building?](#nested_builders)
35*1c2bbba8SAndroid Build Coastguard Worker*   ... [create a "step builder"?](#step)
36*1c2bbba8SAndroid Build Coastguard Worker*   ... [create a builder for something other than an `@AutoValue`?](#autobuilder)
37*1c2bbba8SAndroid Build Coastguard Worker*   ... [use a different build method for a
38*1c2bbba8SAndroid Build Coastguard Worker    property?](#build_method)
39*1c2bbba8SAndroid Build Coastguard Worker
40*1c2bbba8SAndroid Build Coastguard Worker## <a name="beans"></a>... use (or not use) `set` prefixes?
41*1c2bbba8SAndroid Build Coastguard Worker
42*1c2bbba8SAndroid Build Coastguard WorkerJust as you can choose whether to use JavaBeans-style names for property getters
43*1c2bbba8SAndroid Build Coastguard Worker(`getFoo()` or just `foo()`) in your value class, you have the same choice for
44*1c2bbba8SAndroid Build Coastguard Workersetters in builders too (`setFoo(value)` or just `foo(value)`). As with getters,
45*1c2bbba8SAndroid Build Coastguard Workeryou must use these prefixes consistently or not at all.
46*1c2bbba8SAndroid Build Coastguard Worker
47*1c2bbba8SAndroid Build Coastguard WorkerUsing `get`/`is` prefixes for getters and using the `set` prefix for setters are
48*1c2bbba8SAndroid Build Coastguard Workerindependent choices. For example, it is fine to use the `set` prefixes on all
49*1c2bbba8SAndroid Build Coastguard Workeryour builder methods, but omit the `get`/`is` prefixes from all your accessors.
50*1c2bbba8SAndroid Build Coastguard Worker
51*1c2bbba8SAndroid Build Coastguard WorkerHere is the `Animal` example using `get` prefixes but not `set` prefixes:
52*1c2bbba8SAndroid Build Coastguard Worker
53*1c2bbba8SAndroid Build Coastguard Worker```java
54*1c2bbba8SAndroid Build Coastguard Worker@AutoValue
55*1c2bbba8SAndroid Build Coastguard Workerabstract class Animal {
56*1c2bbba8SAndroid Build Coastguard Worker  abstract String getName();
57*1c2bbba8SAndroid Build Coastguard Worker  abstract int getNumberOfLegs();
58*1c2bbba8SAndroid Build Coastguard Worker
59*1c2bbba8SAndroid Build Coastguard Worker  static Builder builder() {
60*1c2bbba8SAndroid Build Coastguard Worker    return new AutoValue_Animal.Builder();
61*1c2bbba8SAndroid Build Coastguard Worker  }
62*1c2bbba8SAndroid Build Coastguard Worker
63*1c2bbba8SAndroid Build Coastguard Worker  @AutoValue.Builder
64*1c2bbba8SAndroid Build Coastguard Worker  abstract static class Builder {
65*1c2bbba8SAndroid Build Coastguard Worker    abstract Builder name(String value);
66*1c2bbba8SAndroid Build Coastguard Worker    abstract Builder numberOfLegs(int value);
67*1c2bbba8SAndroid Build Coastguard Worker    abstract Animal build();
68*1c2bbba8SAndroid Build Coastguard Worker  }
69*1c2bbba8SAndroid Build Coastguard Worker}
70*1c2bbba8SAndroid Build Coastguard Worker```
71*1c2bbba8SAndroid Build Coastguard Worker
72*1c2bbba8SAndroid Build Coastguard Worker## <a name="build_names"></a>... use different names besides `builder()`/`Builder`/`build()`?
73*1c2bbba8SAndroid Build Coastguard Worker
74*1c2bbba8SAndroid Build Coastguard WorkerUse whichever names you like; AutoValue doesn't actually care.
75*1c2bbba8SAndroid Build Coastguard Worker
76*1c2bbba8SAndroid Build Coastguard Worker(We would gently recommend these names as conventional.)
77*1c2bbba8SAndroid Build Coastguard Worker
78*1c2bbba8SAndroid Build Coastguard Worker## <a name="default"></a>... specify a default value for a property?
79*1c2bbba8SAndroid Build Coastguard Worker
80*1c2bbba8SAndroid Build Coastguard WorkerWhat should happen when a caller does not supply a value for a property before
81*1c2bbba8SAndroid Build Coastguard Workercalling `build()`? If the property in question is [nullable](howto.md#nullable),
82*1c2bbba8SAndroid Build Coastguard Workerit will simply default to `null` as you would expect. And if it is
83*1c2bbba8SAndroid Build Coastguard Worker[Optional](#optional) it will default to an empty `Optional` as you might also
84*1c2bbba8SAndroid Build Coastguard Workerexpect. But if it isn't either of those things (including if it is a
85*1c2bbba8SAndroid Build Coastguard Workerprimitive-valued property, which *can't* be null), then `build()` will throw an
86*1c2bbba8SAndroid Build Coastguard Workerunchecked exception. This includes collection properties, which must be given a
87*1c2bbba8SAndroid Build Coastguard Workervalue. They don't default to empty unless there is a
88*1c2bbba8SAndroid Build Coastguard Worker[collection builder](#accumulate).
89*1c2bbba8SAndroid Build Coastguard Worker
90*1c2bbba8SAndroid Build Coastguard WorkerBut this requirement to supply a value presents a problem, since one of the main
91*1c2bbba8SAndroid Build Coastguard Worker*advantages* of a builder in the first place is that callers can specify only
92*1c2bbba8SAndroid Build Coastguard Workerthe properties they care about!
93*1c2bbba8SAndroid Build Coastguard Worker
94*1c2bbba8SAndroid Build Coastguard WorkerThe solution is to provide a default value for such properties. Fortunately this
95*1c2bbba8SAndroid Build Coastguard Workeris easy: just set it on the newly-constructed builder instance before returning
96*1c2bbba8SAndroid Build Coastguard Workerit from the `builder()` method.
97*1c2bbba8SAndroid Build Coastguard Worker
98*1c2bbba8SAndroid Build Coastguard WorkerHere is the `Animal` example with the default number of legs being 4:
99*1c2bbba8SAndroid Build Coastguard Worker
100*1c2bbba8SAndroid Build Coastguard Worker```java
101*1c2bbba8SAndroid Build Coastguard Worker@AutoValue
102*1c2bbba8SAndroid Build Coastguard Workerabstract class Animal {
103*1c2bbba8SAndroid Build Coastguard Worker  abstract String name();
104*1c2bbba8SAndroid Build Coastguard Worker  abstract int numberOfLegs();
105*1c2bbba8SAndroid Build Coastguard Worker
106*1c2bbba8SAndroid Build Coastguard Worker  static Builder builder() {
107*1c2bbba8SAndroid Build Coastguard Worker    return new AutoValue_Animal.Builder()
108*1c2bbba8SAndroid Build Coastguard Worker        .setNumberOfLegs(4);
109*1c2bbba8SAndroid Build Coastguard Worker  }
110*1c2bbba8SAndroid Build Coastguard Worker
111*1c2bbba8SAndroid Build Coastguard Worker  @AutoValue.Builder
112*1c2bbba8SAndroid Build Coastguard Worker  abstract static class Builder {
113*1c2bbba8SAndroid Build Coastguard Worker    abstract Builder setName(String value);
114*1c2bbba8SAndroid Build Coastguard Worker    abstract Builder setNumberOfLegs(int value);
115*1c2bbba8SAndroid Build Coastguard Worker    abstract Animal build();
116*1c2bbba8SAndroid Build Coastguard Worker  }
117*1c2bbba8SAndroid Build Coastguard Worker}
118*1c2bbba8SAndroid Build Coastguard Worker```
119*1c2bbba8SAndroid Build Coastguard Worker
120*1c2bbba8SAndroid Build Coastguard WorkerOccasionally you may want to supply a default value, but only if the property is
121*1c2bbba8SAndroid Build Coastguard Workernot set explicitly. This is covered in the section on
122*1c2bbba8SAndroid Build Coastguard Worker[normalization](#normalize).
123*1c2bbba8SAndroid Build Coastguard Worker
124*1c2bbba8SAndroid Build Coastguard Worker## <a name="to_builder"></a>... initialize a builder to the same property values as an existing value instance
125*1c2bbba8SAndroid Build Coastguard Worker
126*1c2bbba8SAndroid Build Coastguard WorkerSuppose your caller has an existing instance of your value class, and wants to
127*1c2bbba8SAndroid Build Coastguard Workerchange only one or two of its properties. Of course, it's immutable, but it
128*1c2bbba8SAndroid Build Coastguard Workerwould be convenient if they could easily get a `Builder` instance representing
129*1c2bbba8SAndroid Build Coastguard Workerthe same property values, which they could then modify and use to create a new
130*1c2bbba8SAndroid Build Coastguard Workervalue instance.
131*1c2bbba8SAndroid Build Coastguard Worker
132*1c2bbba8SAndroid Build Coastguard WorkerTo give them this ability, just add an abstract `toBuilder` method, returning
133*1c2bbba8SAndroid Build Coastguard Workeryour abstract builder type, to your value class. AutoValue will implement it.
134*1c2bbba8SAndroid Build Coastguard Worker
135*1c2bbba8SAndroid Build Coastguard Worker```java
136*1c2bbba8SAndroid Build Coastguard Worker  public abstract Builder toBuilder();
137*1c2bbba8SAndroid Build Coastguard Worker```
138*1c2bbba8SAndroid Build Coastguard Worker
139*1c2bbba8SAndroid Build Coastguard Worker## <a name="withers"></a>... include `with-` methods on my value class for creating slightly altered instances?
140*1c2bbba8SAndroid Build Coastguard Worker
141*1c2bbba8SAndroid Build Coastguard WorkerThis is a somewhat common pattern among immutable classes. You can't have
142*1c2bbba8SAndroid Build Coastguard Workersetters, but you can have methods that act similarly to setters by returning a
143*1c2bbba8SAndroid Build Coastguard Workernew immutable instance that has one property changed.
144*1c2bbba8SAndroid Build Coastguard Worker
145*1c2bbba8SAndroid Build Coastguard WorkerIf you're already using the builder option, you can add these methods by hand:
146*1c2bbba8SAndroid Build Coastguard Worker
147*1c2bbba8SAndroid Build Coastguard Worker```java
148*1c2bbba8SAndroid Build Coastguard Worker@AutoValue
149*1c2bbba8SAndroid Build Coastguard Workerpublic abstract class Animal {
150*1c2bbba8SAndroid Build Coastguard Worker  public abstract String name();
151*1c2bbba8SAndroid Build Coastguard Worker  public abstract int numberOfLegs();
152*1c2bbba8SAndroid Build Coastguard Worker
153*1c2bbba8SAndroid Build Coastguard Worker  public static Builder builder() {
154*1c2bbba8SAndroid Build Coastguard Worker    return new AutoValue_Animal.Builder();
155*1c2bbba8SAndroid Build Coastguard Worker  }
156*1c2bbba8SAndroid Build Coastguard Worker
157*1c2bbba8SAndroid Build Coastguard Worker  abstract Builder toBuilder();
158*1c2bbba8SAndroid Build Coastguard Worker
159*1c2bbba8SAndroid Build Coastguard Worker  public final Animal withName(String name) {
160*1c2bbba8SAndroid Build Coastguard Worker    return toBuilder().setName(name).build();
161*1c2bbba8SAndroid Build Coastguard Worker  }
162*1c2bbba8SAndroid Build Coastguard Worker
163*1c2bbba8SAndroid Build Coastguard Worker  @AutoValue.Builder
164*1c2bbba8SAndroid Build Coastguard Worker  public abstract static class Builder {
165*1c2bbba8SAndroid Build Coastguard Worker    public abstract Builder setName(String value);
166*1c2bbba8SAndroid Build Coastguard Worker    public abstract Builder setNumberOfLegs(int value);
167*1c2bbba8SAndroid Build Coastguard Worker    public abstract Animal build();
168*1c2bbba8SAndroid Build Coastguard Worker  }
169*1c2bbba8SAndroid Build Coastguard Worker}
170*1c2bbba8SAndroid Build Coastguard Worker```
171*1c2bbba8SAndroid Build Coastguard Worker
172*1c2bbba8SAndroid Build Coastguard WorkerNote that it's your free choice what to make public (`toBuilder`, `withName`,
173*1c2bbba8SAndroid Build Coastguard Workerneither, or both).
174*1c2bbba8SAndroid Build Coastguard Worker
175*1c2bbba8SAndroid Build Coastguard Worker## <a name="validate"></a>... validate property values?
176*1c2bbba8SAndroid Build Coastguard Worker
177*1c2bbba8SAndroid Build Coastguard WorkerValidating properties is a little less straightforward than it is in the
178*1c2bbba8SAndroid Build Coastguard Worker[non-builder case](howto.md#validate).
179*1c2bbba8SAndroid Build Coastguard Worker
180*1c2bbba8SAndroid Build Coastguard WorkerWhat you need to do is *split* your "build" method into two methods:
181*1c2bbba8SAndroid Build Coastguard Worker
182*1c2bbba8SAndroid Build Coastguard Worker*   the non-visible, abstract method that AutoValue implements
183*1c2bbba8SAndroid Build Coastguard Worker*   and the visible, *concrete* method you provide, which calls the generated
184*1c2bbba8SAndroid Build Coastguard Worker    method and performs validation.
185*1c2bbba8SAndroid Build Coastguard Worker
186*1c2bbba8SAndroid Build Coastguard WorkerWe recommend naming these methods `autoBuild` and `build`, but any names will
187*1c2bbba8SAndroid Build Coastguard Workerwork. It ends up looking like this:
188*1c2bbba8SAndroid Build Coastguard Worker
189*1c2bbba8SAndroid Build Coastguard Worker```java
190*1c2bbba8SAndroid Build Coastguard Worker@AutoValue
191*1c2bbba8SAndroid Build Coastguard Workerpublic abstract class Animal {
192*1c2bbba8SAndroid Build Coastguard Worker  public abstract String name();
193*1c2bbba8SAndroid Build Coastguard Worker  public abstract int numberOfLegs();
194*1c2bbba8SAndroid Build Coastguard Worker
195*1c2bbba8SAndroid Build Coastguard Worker  public static Builder builder() {
196*1c2bbba8SAndroid Build Coastguard Worker    return new AutoValue_Animal.Builder();
197*1c2bbba8SAndroid Build Coastguard Worker  }
198*1c2bbba8SAndroid Build Coastguard Worker
199*1c2bbba8SAndroid Build Coastguard Worker  @AutoValue.Builder
200*1c2bbba8SAndroid Build Coastguard Worker  public abstract static class Builder {
201*1c2bbba8SAndroid Build Coastguard Worker    public abstract Builder setName(String value);
202*1c2bbba8SAndroid Build Coastguard Worker    public abstract Builder setNumberOfLegs(int value);
203*1c2bbba8SAndroid Build Coastguard Worker
204*1c2bbba8SAndroid Build Coastguard Worker    abstract Animal autoBuild();  // not public
205*1c2bbba8SAndroid Build Coastguard Worker
206*1c2bbba8SAndroid Build Coastguard Worker    public final Animal build() {
207*1c2bbba8SAndroid Build Coastguard Worker      Animal animal = autoBuild();
208*1c2bbba8SAndroid Build Coastguard Worker      Preconditions.checkState(animal.numberOfLegs() >= 0, "Negative legs");
209*1c2bbba8SAndroid Build Coastguard Worker      return animal;
210*1c2bbba8SAndroid Build Coastguard Worker    }
211*1c2bbba8SAndroid Build Coastguard Worker  }
212*1c2bbba8SAndroid Build Coastguard Worker}
213*1c2bbba8SAndroid Build Coastguard Worker```
214*1c2bbba8SAndroid Build Coastguard Worker
215*1c2bbba8SAndroid Build Coastguard Worker## <a name="normalize"></a>... normalize (modify) a property value at `build` time?
216*1c2bbba8SAndroid Build Coastguard Worker
217*1c2bbba8SAndroid Build Coastguard WorkerSuppose you want to convert the animal's name to lower case.
218*1c2bbba8SAndroid Build Coastguard Worker
219*1c2bbba8SAndroid Build Coastguard WorkerYou'll need to add a *getter* to your builder, as shown:
220*1c2bbba8SAndroid Build Coastguard Worker
221*1c2bbba8SAndroid Build Coastguard Worker```java
222*1c2bbba8SAndroid Build Coastguard Worker@AutoValue
223*1c2bbba8SAndroid Build Coastguard Workerpublic abstract class Animal {
224*1c2bbba8SAndroid Build Coastguard Worker  public abstract String name();
225*1c2bbba8SAndroid Build Coastguard Worker  public abstract int numberOfLegs();
226*1c2bbba8SAndroid Build Coastguard Worker
227*1c2bbba8SAndroid Build Coastguard Worker  public static Builder builder() {
228*1c2bbba8SAndroid Build Coastguard Worker    return new AutoValue_Animal.Builder();
229*1c2bbba8SAndroid Build Coastguard Worker  }
230*1c2bbba8SAndroid Build Coastguard Worker
231*1c2bbba8SAndroid Build Coastguard Worker  @AutoValue.Builder
232*1c2bbba8SAndroid Build Coastguard Worker  public abstract static class Builder {
233*1c2bbba8SAndroid Build Coastguard Worker    public abstract Builder setName(String value);
234*1c2bbba8SAndroid Build Coastguard Worker    public abstract Builder setNumberOfLegs(int value);
235*1c2bbba8SAndroid Build Coastguard Worker
236*1c2bbba8SAndroid Build Coastguard Worker    abstract String name(); // must match method name in Animal
237*1c2bbba8SAndroid Build Coastguard Worker
238*1c2bbba8SAndroid Build Coastguard Worker    abstract Animal autoBuild(); // not public
239*1c2bbba8SAndroid Build Coastguard Worker
240*1c2bbba8SAndroid Build Coastguard Worker    public final Animal build() {
241*1c2bbba8SAndroid Build Coastguard Worker      setName(name().toLowerCase());
242*1c2bbba8SAndroid Build Coastguard Worker      return autoBuild();
243*1c2bbba8SAndroid Build Coastguard Worker    }
244*1c2bbba8SAndroid Build Coastguard Worker  }
245*1c2bbba8SAndroid Build Coastguard Worker}
246*1c2bbba8SAndroid Build Coastguard Worker```
247*1c2bbba8SAndroid Build Coastguard Worker
248*1c2bbba8SAndroid Build Coastguard WorkerThe getter in your builder must have the same signature as the abstract property
249*1c2bbba8SAndroid Build Coastguard Workeraccessor method in the value class. It will return the value that has been set
250*1c2bbba8SAndroid Build Coastguard Workeron the `Builder`. If no value has been set for a
251*1c2bbba8SAndroid Build Coastguard Workernon-[nullable](howto.md#nullable) property, `IllegalStateException` is thrown.
252*1c2bbba8SAndroid Build Coastguard Worker
253*1c2bbba8SAndroid Build Coastguard WorkerGetters should generally only be used within the `Builder` as shown, so they are
254*1c2bbba8SAndroid Build Coastguard Workernot public.
255*1c2bbba8SAndroid Build Coastguard Worker
256*1c2bbba8SAndroid Build Coastguard Worker<p id="optional-getter">As an alternative to returning the same type as the
257*1c2bbba8SAndroid Build Coastguard Workerproperty accessor method, the builder getter can return an Optional wrapping of
258*1c2bbba8SAndroid Build Coastguard Workerthat type. This can be used if you want to supply a default, but only if the
259*1c2bbba8SAndroid Build Coastguard Workerproperty has not been set. (The [usual way](#default) of supplying defaults
260*1c2bbba8SAndroid Build Coastguard Workermeans that the property always appears to have been set.) For example, suppose
261*1c2bbba8SAndroid Build Coastguard Workeryou wanted the default name of your Animal to be something like "4-legged
262*1c2bbba8SAndroid Build Coastguard Workercreature", where 4 is the `numberOfLegs()` property. You might write this:
263*1c2bbba8SAndroid Build Coastguard Worker
264*1c2bbba8SAndroid Build Coastguard Worker```java
265*1c2bbba8SAndroid Build Coastguard Worker@AutoValue
266*1c2bbba8SAndroid Build Coastguard Workerpublic abstract class Animal {
267*1c2bbba8SAndroid Build Coastguard Worker  public abstract String name();
268*1c2bbba8SAndroid Build Coastguard Worker  public abstract int numberOfLegs();
269*1c2bbba8SAndroid Build Coastguard Worker
270*1c2bbba8SAndroid Build Coastguard Worker  public static Builder builder() {
271*1c2bbba8SAndroid Build Coastguard Worker    return new AutoValue_Animal.Builder();
272*1c2bbba8SAndroid Build Coastguard Worker  }
273*1c2bbba8SAndroid Build Coastguard Worker
274*1c2bbba8SAndroid Build Coastguard Worker  @AutoValue.Builder
275*1c2bbba8SAndroid Build Coastguard Worker  public abstract static class Builder {
276*1c2bbba8SAndroid Build Coastguard Worker    public abstract Builder setName(String value);
277*1c2bbba8SAndroid Build Coastguard Worker    public abstract Builder setNumberOfLegs(int value);
278*1c2bbba8SAndroid Build Coastguard Worker
279*1c2bbba8SAndroid Build Coastguard Worker    abstract Optional<String> name();
280*1c2bbba8SAndroid Build Coastguard Worker    abstract int numberOfLegs();
281*1c2bbba8SAndroid Build Coastguard Worker
282*1c2bbba8SAndroid Build Coastguard Worker    abstract Animal autoBuild(); // not public
283*1c2bbba8SAndroid Build Coastguard Worker
284*1c2bbba8SAndroid Build Coastguard Worker    public final Animal build() {
285*1c2bbba8SAndroid Build Coastguard Worker      if (name().isEmpty()) {
286*1c2bbba8SAndroid Build Coastguard Worker        setName(numberOfLegs() + "-legged creature");
287*1c2bbba8SAndroid Build Coastguard Worker      }
288*1c2bbba8SAndroid Build Coastguard Worker      return autoBuild();
289*1c2bbba8SAndroid Build Coastguard Worker    }
290*1c2bbba8SAndroid Build Coastguard Worker  }
291*1c2bbba8SAndroid Build Coastguard Worker}
292*1c2bbba8SAndroid Build Coastguard Worker```
293*1c2bbba8SAndroid Build Coastguard Worker
294*1c2bbba8SAndroid Build Coastguard WorkerNotice that this will throw `IllegalStateException` if the `numberOfLegs`
295*1c2bbba8SAndroid Build Coastguard Workerproperty hasn't been set either.
296*1c2bbba8SAndroid Build Coastguard Worker
297*1c2bbba8SAndroid Build Coastguard WorkerThe Optional wrapping can be any of the Optional types mentioned in the
298*1c2bbba8SAndroid Build Coastguard Worker[section](#optional) on `Optional` properties. If your property has type `int`
299*1c2bbba8SAndroid Build Coastguard Workerit can be wrapped as either `Optional<Integer>` or `OptionalInt`, and likewise
300*1c2bbba8SAndroid Build Coastguard Workerfor `long` and `double`.
301*1c2bbba8SAndroid Build Coastguard Worker
302*1c2bbba8SAndroid Build Coastguard Worker## <a name="both"></a>... expose *both* a builder *and* a factory method?
303*1c2bbba8SAndroid Build Coastguard Worker
304*1c2bbba8SAndroid Build Coastguard WorkerIf you use the builder option, AutoValue will not generate a visible constructor
305*1c2bbba8SAndroid Build Coastguard Workerfor the generated concrete value class. If it's important to offer your caller
306*1c2bbba8SAndroid Build Coastguard Workerthe choice of a factory method as well as the builder, then your factory method
307*1c2bbba8SAndroid Build Coastguard Workerimplementation will have to invoke the builder itself.
308*1c2bbba8SAndroid Build Coastguard Worker
309*1c2bbba8SAndroid Build Coastguard Worker## <a name="optional"></a>... handle `Optional` properties?
310*1c2bbba8SAndroid Build Coastguard Worker
311*1c2bbba8SAndroid Build Coastguard WorkerProperties of type `Optional` benefit from special treatment. If you have a
312*1c2bbba8SAndroid Build Coastguard Workerproperty of type `Optional<String>`, say, then it will default to an empty
313*1c2bbba8SAndroid Build Coastguard Worker`Optional` without needing to [specify](#default) a default explicitly. And,
314*1c2bbba8SAndroid Build Coastguard Workerinstead of or as well as the normal `setFoo(Optional<String>)` method, you can
315*1c2bbba8SAndroid Build Coastguard Workerhave `setFoo(String)`. Then `setFoo(s)` is equivalent to
316*1c2bbba8SAndroid Build Coastguard Worker`setFoo(Optional.of(s))`. (If it is `setFoo(@Nullable String)`, then `setFoo(s)`
317*1c2bbba8SAndroid Build Coastguard Workeris equivalent to `setFoo(Optional.ofNullable(s))`.)
318*1c2bbba8SAndroid Build Coastguard Worker
319*1c2bbba8SAndroid Build Coastguard WorkerHere, `Optional` means either [`java.util.Optional`] from Java (Java 8 or
320*1c2bbba8SAndroid Build Coastguard Workerlater), or [`com.google.common.base.Optional`] from Guava. Java 8 also
321*1c2bbba8SAndroid Build Coastguard Workerintroduced related classes in `java.util` called [`OptionalInt`],
322*1c2bbba8SAndroid Build Coastguard Worker[`OptionalLong`], and [`OptionalDouble`]. You can use those in the same way. For
323*1c2bbba8SAndroid Build Coastguard Workerexample a property of type `OptionalInt` will default to `OptionalInt.empty()`
324*1c2bbba8SAndroid Build Coastguard Workerand you can set it with either `setFoo(OptionalInt)` or `setFoo(int)`.
325*1c2bbba8SAndroid Build Coastguard Worker
326*1c2bbba8SAndroid Build Coastguard Worker```java
327*1c2bbba8SAndroid Build Coastguard Worker@AutoValue
328*1c2bbba8SAndroid Build Coastguard Workerpublic abstract class Animal {
329*1c2bbba8SAndroid Build Coastguard Worker  public abstract Optional<String> name();
330*1c2bbba8SAndroid Build Coastguard Worker
331*1c2bbba8SAndroid Build Coastguard Worker  public static Builder builder() {
332*1c2bbba8SAndroid Build Coastguard Worker    return new AutoValue_Animal.Builder();
333*1c2bbba8SAndroid Build Coastguard Worker  }
334*1c2bbba8SAndroid Build Coastguard Worker
335*1c2bbba8SAndroid Build Coastguard Worker  @AutoValue.Builder
336*1c2bbba8SAndroid Build Coastguard Worker  public abstract static class Builder {
337*1c2bbba8SAndroid Build Coastguard Worker    // You can have either or both of these two methods:
338*1c2bbba8SAndroid Build Coastguard Worker    public abstract Builder setName(Optional<String> value);
339*1c2bbba8SAndroid Build Coastguard Worker    public abstract Builder setName(String value);
340*1c2bbba8SAndroid Build Coastguard Worker    public abstract Animal build();
341*1c2bbba8SAndroid Build Coastguard Worker  }
342*1c2bbba8SAndroid Build Coastguard Worker}
343*1c2bbba8SAndroid Build Coastguard Worker```
344*1c2bbba8SAndroid Build Coastguard Worker
345*1c2bbba8SAndroid Build Coastguard Worker[`java.util.Optional`]: https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html
346*1c2bbba8SAndroid Build Coastguard Worker[`com.google.common.base.Optional`]: https://guava.dev/releases/snapshot/api/docs/com/google/common/base/Optional.html
347*1c2bbba8SAndroid Build Coastguard Worker[`OptionalDouble`]: https://docs.oracle.com/javase/8/docs/api/java/util/OptionalDouble.html
348*1c2bbba8SAndroid Build Coastguard Worker[`OptionalInt`]: https://docs.oracle.com/javase/8/docs/api/java/util/OptionalInt.html
349*1c2bbba8SAndroid Build Coastguard Worker[`OptionalLong`]: https://docs.oracle.com/javase/8/docs/api/java/util/OptionalLong.html
350*1c2bbba8SAndroid Build Coastguard Worker
351*1c2bbba8SAndroid Build Coastguard Worker## <a name="collection"></a>... use a collection-valued property?
352*1c2bbba8SAndroid Build Coastguard Worker
353*1c2bbba8SAndroid Build Coastguard WorkerValue objects should be immutable, so if a property of one is a collection then
354*1c2bbba8SAndroid Build Coastguard Workerthat collection should be immutable too. We recommend using Guava's [immutable
355*1c2bbba8SAndroid Build Coastguard Workercollections] to make that explicit. AutoValue's builder support includes a few
356*1c2bbba8SAndroid Build Coastguard Workerspecial arrangements to make this more convenient.
357*1c2bbba8SAndroid Build Coastguard Worker
358*1c2bbba8SAndroid Build Coastguard WorkerIn the examples here we use `ImmutableSet`, but the same principles apply to all
359*1c2bbba8SAndroid Build Coastguard Workerof Guava's immutable collection types, like `ImmutableList`,
360*1c2bbba8SAndroid Build Coastguard Worker`ImmutableMultimap`, and so on.
361*1c2bbba8SAndroid Build Coastguard Worker
362*1c2bbba8SAndroid Build Coastguard WorkerWe recommend using the immutable type (like `ImmutableSet<String>`) as your
363*1c2bbba8SAndroid Build Coastguard Workeractual property type. However, it can be a pain for callers to always have to
364*1c2bbba8SAndroid Build Coastguard Workerconstruct `ImmutableSet` instances to pass into your builder. So AutoValue
365*1c2bbba8SAndroid Build Coastguard Workerallows your builder method to accept an argument of any type that
366*1c2bbba8SAndroid Build Coastguard Worker`ImmutableSet.copyOf` accepts.
367*1c2bbba8SAndroid Build Coastguard Worker
368*1c2bbba8SAndroid Build Coastguard WorkerIf our `Animal` acquires an `ImmutableSet<String>` that is the countries it
369*1c2bbba8SAndroid Build Coastguard Workerlives in, that can be set from a `Set<String>` or a `Collection<String>` or an
370*1c2bbba8SAndroid Build Coastguard Worker`Iterable<String>` or a `String[]` or any other compatible type. You can even
371*1c2bbba8SAndroid Build Coastguard Workeroffer multiple choices, as in this example:
372*1c2bbba8SAndroid Build Coastguard Worker
373*1c2bbba8SAndroid Build Coastguard Worker```java
374*1c2bbba8SAndroid Build Coastguard Worker@AutoValue
375*1c2bbba8SAndroid Build Coastguard Workerpublic abstract class Animal {
376*1c2bbba8SAndroid Build Coastguard Worker  public abstract String name();
377*1c2bbba8SAndroid Build Coastguard Worker  public abstract int numberOfLegs();
378*1c2bbba8SAndroid Build Coastguard Worker  public abstract ImmutableSet<String> countries();
379*1c2bbba8SAndroid Build Coastguard Worker
380*1c2bbba8SAndroid Build Coastguard Worker  public static Builder builder() {
381*1c2bbba8SAndroid Build Coastguard Worker    return new AutoValue_Animal.Builder();
382*1c2bbba8SAndroid Build Coastguard Worker  }
383*1c2bbba8SAndroid Build Coastguard Worker
384*1c2bbba8SAndroid Build Coastguard Worker  @AutoValue.Builder
385*1c2bbba8SAndroid Build Coastguard Worker  public abstract static class Builder {
386*1c2bbba8SAndroid Build Coastguard Worker    public abstract Builder setName(String value);
387*1c2bbba8SAndroid Build Coastguard Worker    public abstract Builder setNumberOfLegs(int value);
388*1c2bbba8SAndroid Build Coastguard Worker    public abstract Builder setCountries(Set<String> value);
389*1c2bbba8SAndroid Build Coastguard Worker    public abstract Builder setCountries(String... value);
390*1c2bbba8SAndroid Build Coastguard Worker    public abstract Animal build();
391*1c2bbba8SAndroid Build Coastguard Worker  }
392*1c2bbba8SAndroid Build Coastguard Worker}
393*1c2bbba8SAndroid Build Coastguard Worker```
394*1c2bbba8SAndroid Build Coastguard Worker
395*1c2bbba8SAndroid Build Coastguard Worker[immutable collections]: https://github.com/google/guava/wiki/ImmutableCollectionsExplained
396*1c2bbba8SAndroid Build Coastguard Worker
397*1c2bbba8SAndroid Build Coastguard Worker### <a name="accumulate"></a>... let my builder *accumulate* values for a collection-valued property (not require them all at once)?
398*1c2bbba8SAndroid Build Coastguard Worker
399*1c2bbba8SAndroid Build Coastguard WorkerInstead of defining a setter for an immutable collection `foos`, you can define
400*1c2bbba8SAndroid Build Coastguard Workera method `foosBuilder()` that returns the associated builder type for that
401*1c2bbba8SAndroid Build Coastguard Workercollection. In this example, we have an `ImmutableSet<String>` which can be
402*1c2bbba8SAndroid Build Coastguard Workerbuilt using the `countriesBuilder()` method:
403*1c2bbba8SAndroid Build Coastguard Worker
404*1c2bbba8SAndroid Build Coastguard Worker```java
405*1c2bbba8SAndroid Build Coastguard Worker@AutoValue
406*1c2bbba8SAndroid Build Coastguard Workerpublic abstract class Animal {
407*1c2bbba8SAndroid Build Coastguard Worker  public abstract String name();
408*1c2bbba8SAndroid Build Coastguard Worker  public abstract int numberOfLegs();
409*1c2bbba8SAndroid Build Coastguard Worker  public abstract ImmutableSet<String> countries();
410*1c2bbba8SAndroid Build Coastguard Worker
411*1c2bbba8SAndroid Build Coastguard Worker  public static Builder builder() {
412*1c2bbba8SAndroid Build Coastguard Worker    return new AutoValue_Animal.Builder();
413*1c2bbba8SAndroid Build Coastguard Worker  }
414*1c2bbba8SAndroid Build Coastguard Worker
415*1c2bbba8SAndroid Build Coastguard Worker  @AutoValue.Builder
416*1c2bbba8SAndroid Build Coastguard Worker  public abstract static class Builder {
417*1c2bbba8SAndroid Build Coastguard Worker    public abstract Builder setName(String value);
418*1c2bbba8SAndroid Build Coastguard Worker    public abstract Builder setNumberOfLegs(int value);
419*1c2bbba8SAndroid Build Coastguard Worker    public abstract ImmutableSet.Builder<String> countriesBuilder();
420*1c2bbba8SAndroid Build Coastguard Worker    public abstract Animal build();
421*1c2bbba8SAndroid Build Coastguard Worker  }
422*1c2bbba8SAndroid Build Coastguard Worker}
423*1c2bbba8SAndroid Build Coastguard Worker```
424*1c2bbba8SAndroid Build Coastguard Worker
425*1c2bbba8SAndroid Build Coastguard WorkerThe name of this method must be exactly the property name (`countries` here)
426*1c2bbba8SAndroid Build Coastguard Workerfollowed by the string `Builder`. Even if the properties follow the
427*1c2bbba8SAndroid Build Coastguard Worker`getCountries()` convention, the builder method must be `countriesBuilder()`
428*1c2bbba8SAndroid Build Coastguard Workerand not `getCountriesBuilder()`.
429*1c2bbba8SAndroid Build Coastguard Worker
430*1c2bbba8SAndroid Build Coastguard WorkerIt's also possible to have a method like `countriesBuilder` with a single
431*1c2bbba8SAndroid Build Coastguard Workerargument, provided that the `Builder` class has a public constructor or a
432*1c2bbba8SAndroid Build Coastguard Workerstatic `builder` method, with one parameter that the argument can be assigned
433*1c2bbba8SAndroid Build Coastguard Workerto. For example, if `countries()` were an `ImmutableSortedSet<String>` and you
434*1c2bbba8SAndroid Build Coastguard Workerwanted to supply a `Comparator` to `ImmutableSortedSet.Builder`, you could
435*1c2bbba8SAndroid Build Coastguard Workerwrite:
436*1c2bbba8SAndroid Build Coastguard Worker
437*1c2bbba8SAndroid Build Coastguard Worker```java
438*1c2bbba8SAndroid Build Coastguard Worker    public abstract ImmutableSortedSet.Builder<String>
439*1c2bbba8SAndroid Build Coastguard Worker        countriesBuilder(Comparator<String> comparator);
440*1c2bbba8SAndroid Build Coastguard Worker```
441*1c2bbba8SAndroid Build Coastguard Worker
442*1c2bbba8SAndroid Build Coastguard WorkerThat works because `ImmutableSortedSet.Builder` has a constructor that
443*1c2bbba8SAndroid Build Coastguard Workeraccepts a `Comparator` parameter.
444*1c2bbba8SAndroid Build Coastguard Worker
445*1c2bbba8SAndroid Build Coastguard WorkerYou may notice a small problem with these examples: the caller can no longer
446*1c2bbba8SAndroid Build Coastguard Workercreate their instance in a single chained statement:
447*1c2bbba8SAndroid Build Coastguard Worker
448*1c2bbba8SAndroid Build Coastguard Worker```java
449*1c2bbba8SAndroid Build Coastguard Worker  // This DOES NOT work!
450*1c2bbba8SAndroid Build Coastguard Worker  Animal dog = Animal.builder()
451*1c2bbba8SAndroid Build Coastguard Worker      .setName("dog")
452*1c2bbba8SAndroid Build Coastguard Worker      .setNumberOfLegs(4)
453*1c2bbba8SAndroid Build Coastguard Worker      .countriesBuilder()
454*1c2bbba8SAndroid Build Coastguard Worker          .add("Guam")
455*1c2bbba8SAndroid Build Coastguard Worker          .add("Laos")
456*1c2bbba8SAndroid Build Coastguard Worker      .build();
457*1c2bbba8SAndroid Build Coastguard Worker```
458*1c2bbba8SAndroid Build Coastguard Worker
459*1c2bbba8SAndroid Build Coastguard WorkerInstead they are forced to hold the builder itself in a temporary variable:
460*1c2bbba8SAndroid Build Coastguard Worker
461*1c2bbba8SAndroid Build Coastguard Worker```java
462*1c2bbba8SAndroid Build Coastguard Worker  // This DOES work... but we have to "break the chain"!
463*1c2bbba8SAndroid Build Coastguard Worker  Animal.Builder builder = Animal.builder()
464*1c2bbba8SAndroid Build Coastguard Worker      .setName("dog")
465*1c2bbba8SAndroid Build Coastguard Worker      .setNumberOfLegs(4);
466*1c2bbba8SAndroid Build Coastguard Worker  builder.countriesBuilder()
467*1c2bbba8SAndroid Build Coastguard Worker      .add("Guam")
468*1c2bbba8SAndroid Build Coastguard Worker      .add("Laos");
469*1c2bbba8SAndroid Build Coastguard Worker  Animal dog = builder.build();
470*1c2bbba8SAndroid Build Coastguard Worker```
471*1c2bbba8SAndroid Build Coastguard Worker
472*1c2bbba8SAndroid Build Coastguard WorkerOne solution for this problem is just below.
473*1c2bbba8SAndroid Build Coastguard Worker
474*1c2bbba8SAndroid Build Coastguard Worker### <a name="add"></a>... accumulate values for a collection-valued property, without "breaking the chain"?
475*1c2bbba8SAndroid Build Coastguard Worker
476*1c2bbba8SAndroid Build Coastguard WorkerAnother option is to keep `countriesBuilder()` itself non-public, and only use
477*1c2bbba8SAndroid Build Coastguard Workerit to implement a public `addCountry` method:
478*1c2bbba8SAndroid Build Coastguard Worker
479*1c2bbba8SAndroid Build Coastguard Worker```java
480*1c2bbba8SAndroid Build Coastguard Worker@AutoValue
481*1c2bbba8SAndroid Build Coastguard Workerpublic abstract class Animal {
482*1c2bbba8SAndroid Build Coastguard Worker  public abstract String name();
483*1c2bbba8SAndroid Build Coastguard Worker  public abstract int numberOfLegs();
484*1c2bbba8SAndroid Build Coastguard Worker  public abstract ImmutableSet<String> countries();
485*1c2bbba8SAndroid Build Coastguard Worker
486*1c2bbba8SAndroid Build Coastguard Worker  public static Builder builder() {
487*1c2bbba8SAndroid Build Coastguard Worker    return new AutoValue_Animal.Builder();
488*1c2bbba8SAndroid Build Coastguard Worker  }
489*1c2bbba8SAndroid Build Coastguard Worker
490*1c2bbba8SAndroid Build Coastguard Worker  @AutoValue.Builder
491*1c2bbba8SAndroid Build Coastguard Worker  public abstract static class Builder {
492*1c2bbba8SAndroid Build Coastguard Worker    public abstract Builder setName(String value);
493*1c2bbba8SAndroid Build Coastguard Worker    public abstract Builder setNumberOfLegs(int value);
494*1c2bbba8SAndroid Build Coastguard Worker
495*1c2bbba8SAndroid Build Coastguard Worker    abstract ImmutableSet.Builder<String> countriesBuilder();
496*1c2bbba8SAndroid Build Coastguard Worker    public final Builder addCountry(String value) {
497*1c2bbba8SAndroid Build Coastguard Worker      countriesBuilder().add(value);
498*1c2bbba8SAndroid Build Coastguard Worker      return this;
499*1c2bbba8SAndroid Build Coastguard Worker    }
500*1c2bbba8SAndroid Build Coastguard Worker
501*1c2bbba8SAndroid Build Coastguard Worker    public abstract Animal build();
502*1c2bbba8SAndroid Build Coastguard Worker  }
503*1c2bbba8SAndroid Build Coastguard Worker}
504*1c2bbba8SAndroid Build Coastguard Worker```
505*1c2bbba8SAndroid Build Coastguard Worker
506*1c2bbba8SAndroid Build Coastguard WorkerNow the caller can do this:
507*1c2bbba8SAndroid Build Coastguard Worker
508*1c2bbba8SAndroid Build Coastguard Worker```java
509*1c2bbba8SAndroid Build Coastguard Worker  // This DOES work!
510*1c2bbba8SAndroid Build Coastguard Worker  Animal dog = Animal.builder()
511*1c2bbba8SAndroid Build Coastguard Worker      .setName("dog")
512*1c2bbba8SAndroid Build Coastguard Worker      .setNumberOfLegs(4)
513*1c2bbba8SAndroid Build Coastguard Worker      .addCountry("Guam")
514*1c2bbba8SAndroid Build Coastguard Worker      .addCountry("Laos") // however many times needed
515*1c2bbba8SAndroid Build Coastguard Worker      .build();
516*1c2bbba8SAndroid Build Coastguard Worker```
517*1c2bbba8SAndroid Build Coastguard Worker
518*1c2bbba8SAndroid Build Coastguard Worker### <a name="collection_both"></a>... offer both accumulation and set-at-once methods for the same collection-valued property?
519*1c2bbba8SAndroid Build Coastguard Worker
520*1c2bbba8SAndroid Build Coastguard WorkerYes, you can provide both methods, letting your caller choose the style they
521*1c2bbba8SAndroid Build Coastguard Workerprefer.
522*1c2bbba8SAndroid Build Coastguard Worker
523*1c2bbba8SAndroid Build Coastguard WorkerThe same caller can mix the two styles only in limited ways; once `foosBuilder`
524*1c2bbba8SAndroid Build Coastguard Workerhas been called, any subsequent call to `setFoos` will throw an unchecked
525*1c2bbba8SAndroid Build Coastguard Workerexception. On the other hand, calling `setFoos` first is okay; a later call to
526*1c2bbba8SAndroid Build Coastguard Worker`foosBuilder` will return a builder already populated with the
527*1c2bbba8SAndroid Build Coastguard Workerpreviously-supplied elements.
528*1c2bbba8SAndroid Build Coastguard Worker
529*1c2bbba8SAndroid Build Coastguard Worker## <a name="nested_builders"></a>... access nested builders while building?
530*1c2bbba8SAndroid Build Coastguard Worker
531*1c2bbba8SAndroid Build Coastguard WorkerOften a property of an `@AutoValue` class is itself an immutable class,
532*1c2bbba8SAndroid Build Coastguard Workerperhaps another `@AutoValue`. In such cases your builder can expose a builder
533*1c2bbba8SAndroid Build Coastguard Workerfor that nested class. This is very similar to exposing a builder for a
534*1c2bbba8SAndroid Build Coastguard Workercollection property, as described [earlier](#accumulate).
535*1c2bbba8SAndroid Build Coastguard Worker
536*1c2bbba8SAndroid Build Coastguard WorkerSuppose the `Animal` class has a property of type `Species`:
537*1c2bbba8SAndroid Build Coastguard Worker
538*1c2bbba8SAndroid Build Coastguard Worker```java
539*1c2bbba8SAndroid Build Coastguard Worker@AutoValue
540*1c2bbba8SAndroid Build Coastguard Workerpublic abstract class Animal {
541*1c2bbba8SAndroid Build Coastguard Worker  public abstract String name();
542*1c2bbba8SAndroid Build Coastguard Worker  public abstract Species species();
543*1c2bbba8SAndroid Build Coastguard Worker
544*1c2bbba8SAndroid Build Coastguard Worker  public static Builder builder() {
545*1c2bbba8SAndroid Build Coastguard Worker    return new AutoValue_Animal.Builder();
546*1c2bbba8SAndroid Build Coastguard Worker  }
547*1c2bbba8SAndroid Build Coastguard Worker
548*1c2bbba8SAndroid Build Coastguard Worker  @AutoValue.Builder
549*1c2bbba8SAndroid Build Coastguard Worker  public abstract static class Builder {
550*1c2bbba8SAndroid Build Coastguard Worker    public abstract Builder setName(String name);
551*1c2bbba8SAndroid Build Coastguard Worker    public abstract Species.Builder speciesBuilder();
552*1c2bbba8SAndroid Build Coastguard Worker    public abstract Animal build();
553*1c2bbba8SAndroid Build Coastguard Worker  }
554*1c2bbba8SAndroid Build Coastguard Worker}
555*1c2bbba8SAndroid Build Coastguard Worker
556*1c2bbba8SAndroid Build Coastguard Worker@AutoValue
557*1c2bbba8SAndroid Build Coastguard Workerpublic abstract class Species {
558*1c2bbba8SAndroid Build Coastguard Worker  public abstract String genus();
559*1c2bbba8SAndroid Build Coastguard Worker  public abstract String epithet();
560*1c2bbba8SAndroid Build Coastguard Worker
561*1c2bbba8SAndroid Build Coastguard Worker  public static Builder builder() {
562*1c2bbba8SAndroid Build Coastguard Worker    return new AutoValue_Species.Builder();
563*1c2bbba8SAndroid Build Coastguard Worker  }
564*1c2bbba8SAndroid Build Coastguard Worker
565*1c2bbba8SAndroid Build Coastguard Worker  @AutoValue.Builder
566*1c2bbba8SAndroid Build Coastguard Worker  public abstract static class Builder {
567*1c2bbba8SAndroid Build Coastguard Worker    public abstract Builder setGenus(String genus);
568*1c2bbba8SAndroid Build Coastguard Worker    public abstract Builder setEpithet(String epithet);
569*1c2bbba8SAndroid Build Coastguard Worker    public abstract Species build();
570*1c2bbba8SAndroid Build Coastguard Worker  }
571*1c2bbba8SAndroid Build Coastguard Worker}
572*1c2bbba8SAndroid Build Coastguard Worker```
573*1c2bbba8SAndroid Build Coastguard Worker
574*1c2bbba8SAndroid Build Coastguard WorkerNow you can access the builder of the nested `Species` while you are building
575*1c2bbba8SAndroid Build Coastguard Workerthe `Animal`:
576*1c2bbba8SAndroid Build Coastguard Worker
577*1c2bbba8SAndroid Build Coastguard Worker```java
578*1c2bbba8SAndroid Build Coastguard Worker  Animal.Builder catBuilder = Animal.builder()
579*1c2bbba8SAndroid Build Coastguard Worker      .setName("cat");
580*1c2bbba8SAndroid Build Coastguard Worker  catBuilder.speciesBuilder()
581*1c2bbba8SAndroid Build Coastguard Worker      .setGenus("Felis")
582*1c2bbba8SAndroid Build Coastguard Worker      .setEpithet("catus");
583*1c2bbba8SAndroid Build Coastguard Worker  Animal cat = catBuilder.build();
584*1c2bbba8SAndroid Build Coastguard Worker```
585*1c2bbba8SAndroid Build Coastguard Worker
586*1c2bbba8SAndroid Build Coastguard WorkerAlthough the nested class in the example (`Species`) is also an `@AutoValue`
587*1c2bbba8SAndroid Build Coastguard Workerclass, it does not have to be. For example, it could be a [protobuf]. The
588*1c2bbba8SAndroid Build Coastguard Workerrequirements are:
589*1c2bbba8SAndroid Build Coastguard Worker
590*1c2bbba8SAndroid Build Coastguard Worker* The nested class must have a way to make a new builder. This can be
591*1c2bbba8SAndroid Build Coastguard Worker  `new Species.Builder()`, or `Species.builder()`, or `Species.newBuilder()`.
592*1c2bbba8SAndroid Build Coastguard Worker
593*1c2bbba8SAndroid Build Coastguard Worker* There must be a way to build an instance from the builder: `Species.Builder`
594*1c2bbba8SAndroid Build Coastguard Worker  must have a method `Species build()`.
595*1c2bbba8SAndroid Build Coastguard Worker
596*1c2bbba8SAndroid Build Coastguard Worker* If there is a need to convert `Species` back into its builder, then `Species`
597*1c2bbba8SAndroid Build Coastguard Worker  must have a method `Species.Builder toBuilder()`.
598*1c2bbba8SAndroid Build Coastguard Worker
599*1c2bbba8SAndroid Build Coastguard Worker  In the example, if `Animal` has an abstract [`toBuilder()`](#to_builder)
600*1c2bbba8SAndroid Build Coastguard Worker  method then `Species` must also have a `toBuilder()` method. That also applies
601*1c2bbba8SAndroid Build Coastguard Worker  if there is an abstract `setSpecies` method in addition to the
602*1c2bbba8SAndroid Build Coastguard Worker  `speciesBuilder` method.
603*1c2bbba8SAndroid Build Coastguard Worker
604*1c2bbba8SAndroid Build Coastguard Worker  As an alternative to having a method `Species.Builder toBuilder()` in
605*1c2bbba8SAndroid Build Coastguard Worker  `Species`, `Species.Builder` can have a method called `addAll` or `putAll`
606*1c2bbba8SAndroid Build Coastguard Worker  that accepts an argument of type `Species`. This is how AutoValue handles
607*1c2bbba8SAndroid Build Coastguard Worker  `ImmutableSet` for example. `ImmutableSet` does not have a `toBuilder()`
608*1c2bbba8SAndroid Build Coastguard Worker  method, but `ImmutableSet.Builder` does have an `addAll` method that accepts
609*1c2bbba8SAndroid Build Coastguard Worker  an `ImmutableSet`. So given `ImmutableSet<String> strings`, we can achieve the
610*1c2bbba8SAndroid Build Coastguard Worker  effect of `strings.toBuilder()` by doing:
611*1c2bbba8SAndroid Build Coastguard Worker
612*1c2bbba8SAndroid Build Coastguard Worker  ```
613*1c2bbba8SAndroid Build Coastguard Worker  ImmutableSet.Builder<String> builder = ImmutableSet.builder();
614*1c2bbba8SAndroid Build Coastguard Worker  builder.addAll(strings);
615*1c2bbba8SAndroid Build Coastguard Worker  ```
616*1c2bbba8SAndroid Build Coastguard Worker
617*1c2bbba8SAndroid Build Coastguard WorkerThere are no requirements on the name of the builder class. Instead of
618*1c2bbba8SAndroid Build Coastguard Worker`Species.Builder`, it could be `Species.Factory` or `SpeciesBuilder`.
619*1c2bbba8SAndroid Build Coastguard Worker
620*1c2bbba8SAndroid Build Coastguard WorkerIf `speciesBuilder()` is never called then the final `species()` property will
621*1c2bbba8SAndroid Build Coastguard Workerbe set as if by `speciesBuilder().build()`. In the example, that would result
622*1c2bbba8SAndroid Build Coastguard Workerin an exception because the required properties of `Species` have not been set.
623*1c2bbba8SAndroid Build Coastguard Worker
624*1c2bbba8SAndroid Build Coastguard Worker## <a name="step"></a>... create a "step builder"?
625*1c2bbba8SAndroid Build Coastguard Worker
626*1c2bbba8SAndroid Build Coastguard WorkerA [_step builder_](http://rdafbn.blogspot.com/2012/07/step-builder-pattern_28.html)
627*1c2bbba8SAndroid Build Coastguard Workeris a collection of builder interfaces that take you step by step through the
628*1c2bbba8SAndroid Build Coastguard Workersetting of each of a list of required properties. This means you can be sure at
629*1c2bbba8SAndroid Build Coastguard Workercompile time that all the properties are set before you build, at the expense of
630*1c2bbba8SAndroid Build Coastguard Workersome extra code and a bit less flexibility.
631*1c2bbba8SAndroid Build Coastguard Worker
632*1c2bbba8SAndroid Build Coastguard WorkerHere is an example:
633*1c2bbba8SAndroid Build Coastguard Worker
634*1c2bbba8SAndroid Build Coastguard Worker```java
635*1c2bbba8SAndroid Build Coastguard Worker@AutoValue
636*1c2bbba8SAndroid Build Coastguard Workerpublic abstract class Stepped {
637*1c2bbba8SAndroid Build Coastguard Worker  public abstract String foo();
638*1c2bbba8SAndroid Build Coastguard Worker  public abstract String bar();
639*1c2bbba8SAndroid Build Coastguard Worker  public abstract int baz();
640*1c2bbba8SAndroid Build Coastguard Worker
641*1c2bbba8SAndroid Build Coastguard Worker  public static FooStep builder() {
642*1c2bbba8SAndroid Build Coastguard Worker    return new AutoValue_Stepped.Builder();
643*1c2bbba8SAndroid Build Coastguard Worker  }
644*1c2bbba8SAndroid Build Coastguard Worker
645*1c2bbba8SAndroid Build Coastguard Worker  public interface FooStep {
646*1c2bbba8SAndroid Build Coastguard Worker    BarStep setFoo(String foo);
647*1c2bbba8SAndroid Build Coastguard Worker  }
648*1c2bbba8SAndroid Build Coastguard Worker
649*1c2bbba8SAndroid Build Coastguard Worker  public interface BarStep {
650*1c2bbba8SAndroid Build Coastguard Worker    BazStep setBar(String bar);
651*1c2bbba8SAndroid Build Coastguard Worker  }
652*1c2bbba8SAndroid Build Coastguard Worker
653*1c2bbba8SAndroid Build Coastguard Worker  public interface BazStep {
654*1c2bbba8SAndroid Build Coastguard Worker    Build setBaz(int baz);
655*1c2bbba8SAndroid Build Coastguard Worker  }
656*1c2bbba8SAndroid Build Coastguard Worker
657*1c2bbba8SAndroid Build Coastguard Worker  public interface Build {
658*1c2bbba8SAndroid Build Coastguard Worker    Stepped build();
659*1c2bbba8SAndroid Build Coastguard Worker  }
660*1c2bbba8SAndroid Build Coastguard Worker
661*1c2bbba8SAndroid Build Coastguard Worker  @AutoValue.Builder
662*1c2bbba8SAndroid Build Coastguard Worker  abstract static class Builder implements FooStep, BarStep, BazStep, Build {}
663*1c2bbba8SAndroid Build Coastguard Worker}
664*1c2bbba8SAndroid Build Coastguard Worker```
665*1c2bbba8SAndroid Build Coastguard Worker
666*1c2bbba8SAndroid Build Coastguard WorkerIt might be used like this:
667*1c2bbba8SAndroid Build Coastguard Worker
668*1c2bbba8SAndroid Build Coastguard Worker```java
669*1c2bbba8SAndroid Build Coastguard WorkerStepped stepped = Stepped.builder().setFoo("foo").setBar("bar").setBaz(3).build();
670*1c2bbba8SAndroid Build Coastguard Worker```
671*1c2bbba8SAndroid Build Coastguard Worker
672*1c2bbba8SAndroid Build Coastguard WorkerThe idea is that the only way to build an instance of `Stepped`
673*1c2bbba8SAndroid Build Coastguard Workeris to go through the steps imposed by the `FooStep`, `BarStep`, and
674*1c2bbba8SAndroid Build Coastguard Worker`BazStep` interfaces to set the properties in order, with a final build step.
675*1c2bbba8SAndroid Build Coastguard Worker
676*1c2bbba8SAndroid Build Coastguard WorkerOnce you have set the `baz` property there is nothing else to do except build,
677*1c2bbba8SAndroid Build Coastguard Workerso you could also combine the `setBaz` and `build` methods like this:
678*1c2bbba8SAndroid Build Coastguard Worker
679*1c2bbba8SAndroid Build Coastguard Worker```java
680*1c2bbba8SAndroid Build Coastguard Worker  ...
681*1c2bbba8SAndroid Build Coastguard Worker
682*1c2bbba8SAndroid Build Coastguard Worker  public interface BazStep {
683*1c2bbba8SAndroid Build Coastguard Worker    Stepped setBazAndBuild(int baz);
684*1c2bbba8SAndroid Build Coastguard Worker  }
685*1c2bbba8SAndroid Build Coastguard Worker
686*1c2bbba8SAndroid Build Coastguard Worker  @AutoValue.Builder
687*1c2bbba8SAndroid Build Coastguard Worker  abstract static class Builder implements FooStep, BarStep, BazStep {
688*1c2bbba8SAndroid Build Coastguard Worker    abstract Builder setBaz(int baz);
689*1c2bbba8SAndroid Build Coastguard Worker    abstract Stepped build();
690*1c2bbba8SAndroid Build Coastguard Worker
691*1c2bbba8SAndroid Build Coastguard Worker    @Override
692*1c2bbba8SAndroid Build Coastguard Worker    public Stepped setBazAndBuild(int baz) {
693*1c2bbba8SAndroid Build Coastguard Worker      return setBaz(baz).build();
694*1c2bbba8SAndroid Build Coastguard Worker    }
695*1c2bbba8SAndroid Build Coastguard Worker  }
696*1c2bbba8SAndroid Build Coastguard Worker```
697*1c2bbba8SAndroid Build Coastguard Worker
698*1c2bbba8SAndroid Build Coastguard Worker## <a name="autobuilder"></a> ... create a builder for something other than an `@AutoValue`?
699*1c2bbba8SAndroid Build Coastguard Worker
700*1c2bbba8SAndroid Build Coastguard WorkerSometimes you want to make a builder like the kind described here, but have it
701*1c2bbba8SAndroid Build Coastguard Workerbuild something other than an `@AutoValue` class, or even call a static method.
702*1c2bbba8SAndroid Build Coastguard WorkerIn that case you can use `@AutoBuilder`. See
703*1c2bbba8SAndroid Build Coastguard Worker[its documentation](autobuilder.md).
704*1c2bbba8SAndroid Build Coastguard Worker
705*1c2bbba8SAndroid Build Coastguard WorkerSometimes you want to use a different build method for your property. This is
706*1c2bbba8SAndroid Build Coastguard Workerespecially applicable for `ImmutableMap`, which has two different build methods.
707*1c2bbba8SAndroid Build Coastguard Worker`builder.buildOrThrow()` is used as the default build method for AutoValue. You
708*1c2bbba8SAndroid Build Coastguard Workermight prefer to use `builder.buildKeepingLast()` instead, so if the same key is
709*1c2bbba8SAndroid Build Coastguard Workerput more than once then the last value is retained rather than throwing an
710*1c2bbba8SAndroid Build Coastguard Workerexception. AutoValue doesn't currently have a way to request this, but here is a
711*1c2bbba8SAndroid Build Coastguard Workerworkaround if you need it. Let's say you have a class like this:
712*1c2bbba8SAndroid Build Coastguard Worker
713*1c2bbba8SAndroid Build Coastguard Worker```java
714*1c2bbba8SAndroid Build Coastguard Worker  @AutoValue
715*1c2bbba8SAndroid Build Coastguard Worker  public abstract class Foo {
716*1c2bbba8SAndroid Build Coastguard Worker    public abstract ImmutableMap<Integer, String> map();
717*1c2bbba8SAndroid Build Coastguard Worker    ...
718*1c2bbba8SAndroid Build Coastguard Worker
719*1c2bbba8SAndroid Build Coastguard Worker    @AutoValue.Builder
720*1c2bbba8SAndroid Build Coastguard Worker    public abstract static class Builder {
721*1c2bbba8SAndroid Build Coastguard Worker      public abstract ImmutableMap.Builder<Integer, String> mapBuilder();
722*1c2bbba8SAndroid Build Coastguard Worker      public abstract Foo build();
723*1c2bbba8SAndroid Build Coastguard Worker    }
724*1c2bbba8SAndroid Build Coastguard Worker  }
725*1c2bbba8SAndroid Build Coastguard Worker```
726*1c2bbba8SAndroid Build Coastguard Worker
727*1c2bbba8SAndroid Build Coastguard WorkerInstead, you could write this:
728*1c2bbba8SAndroid Build Coastguard Worker
729*1c2bbba8SAndroid Build Coastguard Worker```java
730*1c2bbba8SAndroid Build Coastguard Worker  @AutoValue
731*1c2bbba8SAndroid Build Coastguard Worker  public abstract class Foo {
732*1c2bbba8SAndroid Build Coastguard Worker    public abstract ImmutableMap<Integer, String> map();
733*1c2bbba8SAndroid Build Coastguard Worker
734*1c2bbba8SAndroid Build Coastguard Worker    // #start
735*1c2bbba8SAndroid Build Coastguard Worker    // Needed only if your class has toBuilder() method
736*1c2bbba8SAndroid Build Coastguard Worker    public Builder toBuilder() {
737*1c2bbba8SAndroid Build Coastguard Worker      Builder builder = autoToBuilder();
738*1c2bbba8SAndroid Build Coastguard Worker      builder.mapBuilder().putAll(map());
739*1c2bbba8SAndroid Build Coastguard Worker      return builder;
740*1c2bbba8SAndroid Build Coastguard Worker    }
741*1c2bbba8SAndroid Build Coastguard Worker
742*1c2bbba8SAndroid Build Coastguard Worker    abstract Builder autoToBuilder(); // not public
743*1c2bbba8SAndroid Build Coastguard Worker    // #end
744*1c2bbba8SAndroid Build Coastguard Worker
745*1c2bbba8SAndroid Build Coastguard Worker    @AutoValue.Builder
746*1c2bbba8SAndroid Build Coastguard Worker    public abstract static class Builder {
747*1c2bbba8SAndroid Build Coastguard Worker
748*1c2bbba8SAndroid Build Coastguard Worker      private final ImmutableMap.Builder<Integer, String> mapBuilder = ImmutableMap.builder();
749*1c2bbba8SAndroid Build Coastguard Worker
750*1c2bbba8SAndroid Build Coastguard Worker      public ImmutableMap.Builder<Integer, String> mapBuilder() {
751*1c2bbba8SAndroid Build Coastguard Worker        return mapBuilder;
752*1c2bbba8SAndroid Build Coastguard Worker      }
753*1c2bbba8SAndroid Build Coastguard Worker
754*1c2bbba8SAndroid Build Coastguard Worker      abstract Builder setMap(ImmutableMap<Integer, String> map); // not public
755*1c2bbba8SAndroid Build Coastguard Worker
756*1c2bbba8SAndroid Build Coastguard Worker      abstract Foo autoBuild(); // not public
757*1c2bbba8SAndroid Build Coastguard Worker
758*1c2bbba8SAndroid Build Coastguard Worker      public Foo build() {
759*1c2bbba8SAndroid Build Coastguard Worker        setMap(mapBuilder.buildKeepingLast());
760*1c2bbba8SAndroid Build Coastguard Worker        return autoBuild();
761*1c2bbba8SAndroid Build Coastguard Worker      }
762*1c2bbba8SAndroid Build Coastguard Worker    }
763*1c2bbba8SAndroid Build Coastguard Worker  }
764*1c2bbba8SAndroid Build Coastguard Worker```
765*1c2bbba8SAndroid Build Coastguard Worker
766*1c2bbba8SAndroid Build Coastguard Worker[protobuf]: https://developers.google.com/protocol-buffers/docs/reference/java-generated#builders
767