Upgrade to Pro — share decks privately, control downloads, hide ads and more …

AutoValue Extensions (Square NYC, March 2016)

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

AutoValue Extensions (Square NYC, March 2016)

Google's AutoValue library provides easy value types in Java through code generation and its forthcoming release has a powerful new feature: extensions. This talk will introduce the extensions feature, cover useful extensions for Android, and offer tips for building your own.

Video: https://www.youtube.com/watch?v=Kl2xZufgW14

Avatar for Jake Wharton

Jake Wharton PRO

March 10, 2016
Tweet

More Decks by Jake Wharton

Other Decks in Programming

Transcript

  1. AutoValue @AutoValue public abstract class Payment {
 public abstract long

    id();
 public abstract long amount();
 public abstract Currency currency();
 public abstract String note();
 }X
  2. AutoValue @AutoValue
 public abstract class Payment { 
 public static

    Payment create(
 long id, long amount, Currency currency, String note) {
 return new AutoValue_Payment(id, amount, currency, note);
 }Z
 
 public abstract long id();
 public abstract long amount();
 public abstract Currency currency();
 public abstract String note();
 }X
  3. AutoValue @AutoValue
 public abstract class Payment { 
 public static

    Payment create(
 long id, long amount, Currency currency, String note) {
 return new AutoValue_Payment(id, amount, currency, note);
 }Z
 
 public abstract long id();
 public abstract long amount();
 public abstract Currency currency();
 public abstract String note();
 }X
  4. AutoValue Extensions @AutoValue
 public abstract class Payment { 
 public

    static Payment create(
 long id, long amount, Currency currency, String note) {
 return new AutoValue_Payment(id, amount, currency, note);
 }Z
 
 public abstract long id();
 public abstract long amount();
 public abstract Currency currency();
 public abstract String note();
 }X final class AutoValue_Payment extends Payment {
 private final long id;
 private final long amount;
 private final Currency currency;
 private final String note;
 
 AutoValue_Payment(long id, long amount, Currency currency, String note) {
 this.id = id;
 this.amount = amount;
 this.currency = currency;
 this.note = note;
 }Q
 
 @Override public long id() {
 return id;
 }Y
 @Override public long amount() {
 return amount;
 }Z
 @Override public Currency currency() {
 return currency;
 }U
 @Override public String note() {
 return note;
 }W
 
 @Override public String toString() {
 return "Payment{" +
 "id=" + id +
 ", amount=" + amount +
 ", currency=" + currency +
 ", note='" + note + '\'' +
 '}';
 }E
 
 @Override public boolean equals(Object o) {
 if (this == o) return true;
 if (!(o instanceof Payment)) return false;
 Payment other = (Payment) o;
 return id == other.id
 && amount == other.amount
 && currency.equals(other.currency)
 && note.equals(other.note);
 }R
 
 @Override public int hashCode() {
 int result = (int) (id ^ (id >>> 32));
 result = 31 * result + (int) (amount ^ (amount >>> 32));
 result = 31 * result + currency.hashCode();
 result = 31 * result + note.hashCode();
 return result;
 }T
 }X
  5. @AutoValue public abstract class Payment {
 public abstract long id();


    public abstract long amount();
 public abstract Currency currency();
 public abstract String note();
 }X AutoValue Extensions
  6. @AutoValue public abstract class Payment {
 public abstract long id();


    public abstract long amount();
 public abstract Currency currency();
 public abstract String note();
 }X Ok, awesome! Now how do I use it with ? Parcelable AutoValue Extensions
  7. @AutoValue public abstract class Payment {
 public abstract long id();


    public abstract long amount();
 public abstract Currency currency();
 public abstract String note();
 }X Ok, awesome! Now how do I use it with ? Parcelable Gson AutoValue Extensions
  8. @AutoValue public abstract class Payment {
 public abstract long id();


    public abstract long amount();
 public abstract Currency currency();
 public abstract String note();
 }X Ok, awesome! Now how do I use it with ? Parcelable Gson Cursors AutoValue Extensions
  9. @AutoValue public abstract class Payment {
 public abstract long id();


    public abstract long amount();
 public abstract Currency currency();
 public abstract String note();
 }X Ok, awesome! Now how do I use it with ? Parcelable Gson Cursors (whatever) AutoValue Extensions
  10. @AutoValue public abstract class Payment {
 public abstract long id();


    public abstract long amount();
 public abstract Currency currency();
 public abstract String note();
 }X Ok, awesome! Now how do I use it with ? Parcelable Gson Cursors (whatever) AutoValue Extensions
  11. AutoValue @AutoValue public abstract class Payment3{
 public abstract long id();


    public abstract long amount();
 public abstract Currency currency();
 public abstract String note();
 }X AutoValue Extensions
  12. AutoValue Extensions @AutoValue public abstract class Payment1implements2Parcelable3{3
 public abstract long

    id();
 public abstract long amount();
 public abstract Currency currency();
 public abstract String note();
 }X /* abstract properties */
  13. AutoValue Extensions @AutoValue public abstract class Payment1implements2Parcelable3{3 /* abstract properties

    */ }X final class AutoValue_Payment1extends2Payment { /* value type implementation */ }Y
  14. AutoValue Extensions final class AutoValue_Payment1extends2$AutoValue_Payment { /* parcelable implementation */

    }Z abstract class $AutoValue_Payment1extends2Payment { /* value type implementation */ }Y @AutoValue public abstract class Payment1implements2Parcelable { /* abstract properties */ }X
  15. final class AutoValue_Payment1extends2$AutoValue_Payment { /* parcelable implementation */ }Z /*

    abstract properties */ abstract class $AutoValue_Payment1extends2Payment { /* value type implementation */ }Y AutoValue Extensions @AutoValue public abstract class Payment1implements2Parcelable3{3
 public abstract long id();
 public abstract long amount();
 public abstract Currency currency();
 public abstract String note();
 }X /* abstract properties */
  16. final class AutoValue_Payment1extends2$AutoValue_Payment { /* parcelable implementation */ }Z /*

    abstract properties */ abstract class $AutoValue_Payment1extends2Payment { /* value type implementation */ }Y AutoValue Extensions @AutoValue public abstract class Payment1implements2Parcelable3{3
 public abstract long id();
 public abstract long amount();
 public abstract Currency currency();
 @Redacted public abstract String note();
 }X /* abstract properties */
  17. AutoValue Extensions final class AutoValue_Payment1extends2$AutoValue_Payment { /* parcelable implementation */

    }Z abstract class $AutoValue_Payment1extends2Payment { /* value type implementation */ }Y @AutoValue public abstract class Payment1implements2Parcelable { /* abstract properties */ }X
  18. AutoValue Extensions final class AutoValue_Payment1extends2$AutoValue_Payment { /* parcelable implementation */

    }Z abstract class $AutoValue_Payment1extends2$$AutoValue_Payment { /* value type implementation (without toString) */ }Y abstract class $$AutoValue_Payment1extends2Payment { /* redacted toString implementation */ }Y @AutoValue public abstract class Payment1implements2Parcelable { /* abstract properties */ }X
  19. AutoValue Extensions final class AutoValue_Payment1extends2$AutoValue_Payment { /* parcelable implementation */

    }Z abstract class $AutoValue_Payment1extends2$$AutoValue_Payment { /* value type implementation (without toString) */ }Y abstract class $$AutoValue_Payment1extends2Payment { /* redacted toString implementation */ }Y @AutoValue public abstract class Payment1implements2Parcelable { /* abstract properties */ }X
  20. AutoValue Extensions final class AutoValue_Payment1extends2$AutoValue_Payment { /* parcelable implementation */

    }Z abstract class $AutoValue_Payment1extends2$$AutoValue_Payment { /* value type implementation (without toString) */ }Y abstract class $$AutoValue_Payment1extends2Payment { /* redacted toString implementation */ }Y @AutoValue public abstract class Payment1implements2Parcelable { /* abstract properties */ }X
  21. AutoValue Extensions final class AutoValue_Payment1extends2$AutoValue_Payment { /* parcelable implementation */

    }Z abstract class $AutoValue_Payment1extends2$$AutoValue_Payment { /* value type implementation (without toString) */ }Y abstract class $$AutoValue_Payment1extends2Payment { /* redacted toString implementation */ }Y @AutoValue public abstract class Payment1implements2Parcelable { /* abstract properties */ }X
  22. AutoValue Extensions final class AutoValue_Payment1extends2$AutoValue_Payment { /* parcelable implementation */

    }Z abstract class $AutoValue_Payment1extends2$$AutoValue_Payment { /* value type implementation (without toString) */ }Y abstract class $$AutoValue_Payment1extends2Payment { /* redacted toString implementation */ }Y @AutoValue public abstract class Payment1implements2Parcelable { /* abstract properties */ }X
  23. Available Extensions • Parcelable: github.com/rharter/auto-value-parcel • Redacted: github.com/square/auto-value-redacted • Gson:

    github.com/rharter/auto-value-gson • Moshi: github.com/rharter/auto-value-moshi • Cursor: github.com/gabrielittner/auto-value-cursor • "with"ers: github.com/gabrielittner/auto-value-with
  24. Extension API public abstract class AutoValueExtension {
 public boolean applicable(Context

    context) {
 return false;
 }
 
 public boolean mustBeFinal(Context context) {
 return false;
 }
 
 public Set<String> consumeProperties(Context context) {
 return Collections.emptySet();
 }
 
 public abstract String generateClass(Context context, String className, String classToExtend, boolean isFinal);
 }
  25. Extension API public abstract class AutoValueExtension {
 public boolean applicable(Context

    context) {
 return false;
 }X
 
 public boolean mustBeFinal(Context context) {
 return false;
 }
 
 public Set<String> consumeProperties(Context context) {
 return Collections.emptySet();
 }
 
 public abstract String generateClass(Context context, String className, String classToExtend, boolean isFinal);
 }
  26. Extension API public boolean applicable(Context context) Parcelable extension Parcelable extension

    @AutoValue public abstract class Payment {} @AutoValue public abstract class Payment implements Parcelable {} false
  27. Extension API public boolean applicable(Context context) Parcelable extension Parcelable extension

    @AutoValue public abstract class Payment {} @AutoValue public abstract class Payment implements Parcelable {} false true
  28. Extension API public boolean applicable(Context context) Parcelable extension Parcelable extension

    Redacted extension @AutoValue public abstract class Payment {} @AutoValue public abstract class Payment implements Parcelable {} @AutoValue public abstract class Payment { public abstract String note(); } false true
  29. Extension API public boolean applicable(Context context) Parcelable extension Parcelable extension

    Redacted extension @AutoValue public abstract class Payment {} @AutoValue public abstract class Payment implements Parcelable {} @AutoValue public abstract class Payment { public abstract String note(); } false true false
  30. Extension API public boolean applicable(Context context) Parcelable extension Parcelable extension

    Redacted extension Redacted extension @AutoValue public abstract class Payment {} @AutoValue public abstract class Payment implements Parcelable {} @AutoValue public abstract class Payment { public abstract String note(); } @AutoValue public abstract class Payment { @Redacted public abstract String note(); } false true false
  31. Extension API public boolean applicable(Context context) Parcelable extension Parcelable extension

    Redacted extension Redacted extension @AutoValue public abstract class Payment {} @AutoValue public abstract class Payment implements Parcelable {} @AutoValue public abstract class Payment { public abstract String note(); } @AutoValue public abstract class Payment { @Redacted public abstract String note(); } false true false true
  32. Extension API public boolean applicable(Context context) false true final class

    AutoValue_Payment1extends2Payment { /* value type implementation */ }Y @AutoValue public abstract class Payment1{3 /* abstract properties */ }X final class AutoValue_Payment1extends2$AutoValue_Payment { /* value type implementation */ }Y abstract class $AutoValue_Payment1extends2Payment { /* extension implementation */ }Y @AutoValue public abstract class Payment1{3 /* abstract properties */ }X
  33. Extension API public abstract class AutoValueExtension {
 public boolean applicable(Context

    context) {
 return false;
 }X
 
 public boolean mustBeFinal(Context context) {
 return false;
 }
 
 public Set<String> consumeProperties(Context context) {
 return Collections.emptySet();
 }
 
 public abstract String generateClass(Context context, String className, String classToExtend, boolean isFinal);
 }
  34. Extension API public abstract class AutoValueExtension {
 public boolean applicable(Context

    context) {
 return false;
 }
 
 public boolean mustBeFinal(Context context) {
 return false;
 }
 
 public Set<String> consumeProperties(Context context) {
 return Collections.emptySet();
 }
 
 public abstract String generateClass(Context context, String className, String classToExtend, boolean isFinal);
 }
  35. Extension API public boolean mustBeFinal(Context context) false true final class

    AutoValue_Payment1extends2$AutoValue_Payment { /* extension implementation */ }Y abstract class $AutoValue_Payment1extends2Payment { /* value type implementation */ }Y @AutoValue public abstract class Payment1{3 /* abstract properties */ }X final class AutoValue_Payment1extends2$AutoValue_Payment { /* value type implementation */ }Y abstract class $AutoValue_Payment1extends2Payment { /* extension implementation */ }Y @AutoValue public abstract class Payment1{3 /* abstract properties */ }X
  36. Extension API public boolean mustBeFinal(Context context) false true final class

    AutoValue_Payment1extends2$AutoValue_Payment { /* extension implementation */ }Y abstract class $AutoValue_Payment1extends2Payment { /* value type implementation */ }Y @AutoValue public abstract class Payment1{3 /* abstract properties */ }X final class AutoValue_Payment1extends2$AutoValue_Payment { /* value type implementation */ }Y abstract class $AutoValue_Payment1extends2Payment { /* extension implementation */ }Y @AutoValue public abstract class Payment1{3 /* abstract properties */ }X
  37. Extension API public abstract class AutoValueExtension {
 public boolean applicable(Context

    context) {
 return false;
 }
 
 public boolean mustBeFinal(Context context) {
 return false;
 }
 
 public Set<String> consumeProperties(Context context) {
 return Collections.emptySet();
 }
 
 public abstract String generateClass(Context context, String className, String classToExtend, boolean isFinal);
 }
  38. Extension API public abstract class AutoValueExtension {
 public boolean applicable(Context

    context) {
 return false;
 }
 
 public boolean mustBeFinal(Context context) {
 return false;
 }
 
 public Set<String> consumeProperties(Context context) {
 return Collections.emptySet();
 }
 
 public abstract String generateClass(Context context, String className, String classToExtend, boolean isFinal);
 }
  39. Extension API public Set<String> consumeProperties(Context context) @AutoValue public abstract class

    Payment implements Parcelable { public abstract String note(); }
  40. Extension API public Set<String> consumeProperties(Context context) @AutoValue public abstract class

    Payment implements Parcelable { public abstract String note(); } Extension [ ]
  41. Extension API public Set<String> consumeProperties(Context context) @AutoValue public abstract class

    Payment implements Parcelable { public abstract String note(); } Extension [ ] [ "note", "describeContents" ]
  42. Extension API public Set<String> consumeProperties(Context context) @AutoValue public abstract class

    Payment implements Parcelable { public abstract String note(); } Extension [ ] [ "note", "describeContents" ] @AutoValue public abstract class Payment implements Parcelable { public abstract String note(); } Extension [ "describeContents" ] [ "note" ]
  43. Extension API public abstract class AutoValueExtension {
 public boolean applicable(Context

    context) {
 return false;
 }
 
 public boolean mustBeFinal(Context context) {
 return false;
 }
 
 public Set<String> consumeProperties(Context context) {
 return Collections.emptySet();
 }
 
 public abstract String generateClass(Context context, String className, String classToExtend, boolean isFinal);
 }
  44. Extension API public abstract class AutoValueExtension {
 public boolean applicable(Context

    context) {
 return false;
 }
 
 public boolean mustBeFinal(Context context) {
 return false;
 }
 
 public Set<String> consumeProperties(Context context) {
 return Collections.emptySet();
 }
 
 public abstract String generateClass(Context context, String className, String classToExtend, boolean isFinal);
 }
  45. Building Extensions • Model it after the existing extensions •

    Try to play nice with other extensions • JavaPoet: github.com/square/javapoet • Truth: github.com/google/truth • compile-testing: github.com/google/compile-testing • auto/service: github.com/google/auto
  46. 1.2-SNAPSHOT?!? Big Bang Heat death of universe AutoValue 1.1 released

    (10 months ago) Extensions merged (9 months ago) AutoValue 1.2 released ?????? (not to scale)