Adopt class MethodDeclInfo to use @AutoValue

- Resolve TODO
- Encapsulate bridge/substitute the computation of access, naming, descriptor, signature computation to MethodDeclInfo.
- Apply Law of Demeter shortening.

PiperOrigin-RevId: 293922626
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/langmodel/MethodDeclInfo.java b/src/tools/android/java/com/google/devtools/build/android/desugar/langmodel/MethodDeclInfo.java
index 920b120..942276c 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/langmodel/MethodDeclInfo.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/langmodel/MethodDeclInfo.java
@@ -16,43 +16,151 @@
 
 package com.google.devtools.build.android.desugar.langmodel;
 
+import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
+import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
+import static org.objectweb.asm.Opcodes.ACC_STATIC;
+import static org.objectweb.asm.Opcodes.ACC_SYNTHETIC;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.collect.ImmutableList;
+import javax.annotation.Nullable;
 import org.objectweb.asm.ClassVisitor;
 import org.objectweb.asm.MethodVisitor;
 import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
 
 /** A unit data object represents a class or interface declaration. */
-// TODO(deltazulu): Consider @AutoValue-ize this class. (String[] as attribute is not supported).
-public final class MethodDeclInfo implements TypeMappable<MethodDeclInfo> {
-  public final MethodKey methodKey;
-  public final int ownerAccess;
-  public final int memberAccess;
-  public final String signature;
-  public final String[] exceptions;
+@AutoValue
+public abstract class MethodDeclInfo implements TypeMappable<MethodDeclInfo> {
 
-  public MethodDeclInfo(
+  public abstract MethodKey methodKey();
+
+  public abstract int ownerAccess();
+
+  public abstract int memberAccess();
+
+  @Nullable
+  public abstract String signature();
+
+  public abstract ImmutableList<String> exceptions();
+
+  public static MethodDeclInfo create(
+      MethodKey methodKey,
+      int ownerAccess,
+      int memberAccess,
+      @Nullable String signature,
+      @Nullable String[] exceptions) {
+    return create(
+        methodKey,
+        ownerAccess,
+        memberAccess,
+        signature,
+        exceptions == null ? ImmutableList.of() : ImmutableList.copyOf(exceptions));
+  }
+
+  private static MethodDeclInfo create(
       MethodKey methodKey,
       int ownerAccess,
       int memberAccess,
       String signature,
-      String[] exceptions) {
-    this.methodKey = methodKey;
-    this.ownerAccess = ownerAccess;
-    this.memberAccess = memberAccess;
-    this.signature = signature;
-    this.exceptions = exceptions;
+      ImmutableList<String> exceptions) {
+    return new AutoValue_MethodDeclInfo(
+        methodKey, ownerAccess, memberAccess, signature, exceptions);
+  }
+
+  public final ClassName owner() {
+    return methodKey().owner();
+  }
+
+  public final String ownerName() {
+    return methodKey().ownerName();
+  }
+
+  public final String name() {
+    return methodKey().name();
+  }
+
+  public final String descriptor() {
+    return methodKey().descriptor();
+  }
+
+  public final Type returnType() {
+    return methodKey().getReturnType();
+  }
+
+  public final ImmutableList<Type> argumentTypes() {
+    return ImmutableList.copyOf(methodKey().getArgumentTypes());
+  }
+
+  public final String[] exceptionArray() {
+    return exceptions().toArray(new String[0]);
+  }
+
+  /** The synthetic constructor for a private constructor. */
+  public final MethodDeclInfo bridgeOfConstructor(ClassName nestCompanion) {
+    return create(
+        methodKey().bridgeOfConstructor(nestCompanion),
+        ownerAccess(),
+        (memberAccess() & ~ACC_PRIVATE) | ACC_SYNTHETIC,
+        /* signature= */ null,
+        exceptions());
+  }
+
+  /** The synthetic bridge method for a private static method in a class. */
+  public final MethodDeclInfo bridgeOfClassStaticMethod() {
+    return create(
+        methodKey().bridgeOfClassStaticMethod(),
+        ownerAccess(),
+        ACC_STATIC | ACC_SYNTHETIC,
+        /* signature= */ null,
+        exceptions());
+  }
+
+  /** The synthetic bridge method for a private instance method in a class. */
+  public final MethodDeclInfo bridgeOfClassInstanceMethod() {
+    return create(
+        methodKey().bridgeOfClassInstanceMethod(),
+        ownerAccess(),
+        /* memberAccess= */ ACC_STATIC | ACC_SYNTHETIC,
+        /* signature= */ null,
+        exceptions());
+  }
+
+  /** The substitute method for a private static method in an interface. */
+  public final MethodDeclInfo substituteOfInterfaceStaticMethod() {
+    return create(
+        methodKey().substituteOfInterfaceStaticMethod(),
+        ownerAccess(),
+        (memberAccess() & ~0xf) | ACC_PUBLIC | ACC_STATIC,
+        /* signature= */ null,
+        exceptions());
+  }
+
+  /** The substitute method for a private instance method in an interface. */
+  public final MethodDeclInfo substituteOfInterfaceInstanceMethod() {
+    return create(
+        methodKey().substituteOfInterfaceInstanceMethod(),
+        ownerAccess(),
+        (memberAccess() & ~0xf) | ACC_PUBLIC | ACC_STATIC, // Unset static and access modifier bits.
+        /* signature= */ null,
+        exceptions());
   }
 
   public final MethodVisitor accept(ClassVisitor cv) {
     return cv.visitMethod(
-        memberAccess, methodKey.descriptor(), methodKey.descriptor(), signature, exceptions);
+        memberAccess(),
+        methodKey().name(),
+        methodKey().descriptor(),
+        signature(),
+        exceptionArray());
   }
 
   public final <R, P> R accept(MethodDeclVisitor<R, ? super MethodDeclInfo, P> visitor, P param) {
-    if (methodKey.isConstructor()) {
+    if (methodKey().isConstructor()) {
       return visitor.visitClassConstructor(this, param);
     }
-    boolean isInterface = (ownerAccess & Opcodes.ACC_INTERFACE) != 0;
-    boolean isStatic = (memberAccess & Opcodes.ACC_STATIC) != 0;
+    boolean isInterface = (ownerAccess() & Opcodes.ACC_INTERFACE) != 0;
+    boolean isStatic = (memberAccess() & Opcodes.ACC_STATIC) != 0;
     if (isInterface) {
       return isStatic
           ? visitor.visitInterfaceStaticMethod(this, param)
@@ -66,7 +174,11 @@
 
   @Override
   public MethodDeclInfo acceptTypeMapper(TypeMapper typeMapper) {
-    return new MethodDeclInfo(
-        methodKey.acceptTypeMapper(typeMapper), ownerAccess, memberAccess, signature, exceptions);
+    return create(
+        methodKey().acceptTypeMapper(typeMapper),
+        ownerAccess(),
+        memberAccess(),
+        signature(),
+        exceptions());
   }
 }
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/nest/MethodAccessorEmitter.java b/src/tools/android/java/com/google/devtools/build/android/desugar/nest/MethodAccessorEmitter.java
index c9e29b8..4ff019d 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/nest/MethodAccessorEmitter.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/nest/MethodAccessorEmitter.java
@@ -16,15 +16,10 @@
 
 package com.google.devtools.build.android.desugar.nest;
 
-import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
-import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
-import static org.objectweb.asm.Opcodes.ACC_STATIC;
-import static org.objectweb.asm.Opcodes.ACC_SYNTHETIC;
-
+import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.android.desugar.langmodel.ClassName;
 import com.google.devtools.build.android.desugar.langmodel.MethodDeclInfo;
 import com.google.devtools.build.android.desugar.langmodel.MethodDeclVisitor;
-import com.google.devtools.build.android.desugar.langmodel.MethodKey;
 import org.objectweb.asm.ClassVisitor;
 import org.objectweb.asm.MethodVisitor;
 import org.objectweb.asm.Opcodes;
@@ -60,29 +55,23 @@
    */
   @Override
   public MethodVisitor visitClassConstructor(MethodDeclInfo methodDeclInfo, ClassVisitor cv) {
-    ClassName nestCompanion = nestDigest.nestCompanion(methodDeclInfo.methodKey.owner());
-    MethodKey constructorBridge = methodDeclInfo.methodKey.bridgeOfConstructor(nestCompanion);
-    MethodVisitor mv =
-        cv.visitMethod(
-            (methodDeclInfo.memberAccess & ~ACC_PRIVATE) | ACC_SYNTHETIC,
-            constructorBridge.name(),
-            constructorBridge.descriptor(),
-            /* signature= */ null,
-            methodDeclInfo.exceptions);
+    ClassName nestCompanion = nestDigest.nestCompanion(methodDeclInfo.owner());
+    MethodDeclInfo constructorBridge = methodDeclInfo.bridgeOfConstructor(nestCompanion);
+    MethodVisitor mv = constructorBridge.accept(cv);
     mv.visitCode();
     mv.visitVarInsn(Opcodes.ALOAD, 0);
 
-    Type[] constructorBridgeArgTypes = constructorBridge.getArgumentTypes();
+    ImmutableList<Type> constructorBridgeArgTypes = constructorBridge.argumentTypes();
     // Exclude last placeholder element loading.
-    for (int i = 0, slotOffset = 1; i < constructorBridgeArgTypes.length - 1; i++) {
-      mv.visitVarInsn(constructorBridgeArgTypes[i].getOpcode(Opcodes.ILOAD), slotOffset);
-      slotOffset += constructorBridgeArgTypes[i].getSize();
+    for (int i = 0, slotOffset = 1; i < constructorBridgeArgTypes.size() - 1; i++) {
+      mv.visitVarInsn(constructorBridgeArgTypes.get(i).getOpcode(Opcodes.ILOAD), slotOffset);
+      slotOffset += constructorBridgeArgTypes.get(i).getSize();
     }
     mv.visitMethodInsn(
         Opcodes.INVOKESPECIAL,
-        methodDeclInfo.methodKey.ownerName(),
-        methodDeclInfo.methodKey.name(),
-        methodDeclInfo.methodKey.descriptor(),
+        methodDeclInfo.ownerName(),
+        methodDeclInfo.name(),
+        methodDeclInfo.descriptor(),
         /* isInterface= */ false);
     mv.visitInsn(Opcodes.RETURN);
     int slot = 0;
@@ -110,28 +99,22 @@
    */
   @Override
   public MethodVisitor visitClassStaticMethod(MethodDeclInfo methodDeclInfo, ClassVisitor cv) {
-    MethodKey bridgeMethod = methodDeclInfo.methodKey.bridgeOfClassStaticMethod();
-    MethodVisitor mv =
-        cv.visitMethod(
-            ACC_STATIC | ACC_SYNTHETIC,
-            bridgeMethod.name(),
-            bridgeMethod.descriptor(),
-            /* signature= */ null,
-            methodDeclInfo.exceptions);
+    MethodDeclInfo bridgeMethod = methodDeclInfo.bridgeOfClassStaticMethod();
+    MethodVisitor mv = bridgeMethod.accept(cv);
     mv.visitCode();
     int slotOffset = 0;
-    for (Type argType : bridgeMethod.getArgumentTypes()) {
+    for (Type argType : bridgeMethod.argumentTypes()) {
       mv.visitVarInsn(argType.getOpcode(Opcodes.ILOAD), slotOffset);
       slotOffset += argType.getSize();
     }
 
     mv.visitMethodInsn(
         Opcodes.INVOKESTATIC,
-        methodDeclInfo.methodKey.ownerName(),
-        methodDeclInfo.methodKey.name(),
-        methodDeclInfo.methodKey.descriptor(),
+        methodDeclInfo.ownerName(),
+        methodDeclInfo.name(),
+        methodDeclInfo.descriptor(),
         /* isInterface= */ false);
-    mv.visitInsn(bridgeMethod.getReturnType().getOpcode(Opcodes.IRETURN));
+    mv.visitInsn(bridgeMethod.returnType().getOpcode(Opcodes.IRETURN));
     mv.visitMaxs(slotOffset, slotOffset);
     mv.visitEnd();
     return mv;
@@ -153,28 +136,22 @@
    */
   @Override
   public MethodVisitor visitClassInstanceMethod(MethodDeclInfo methodDeclInfo, ClassVisitor cv) {
-    MethodKey bridgeMethod = methodDeclInfo.methodKey.bridgeOfClassInstanceMethod();
-    MethodVisitor mv =
-        cv.visitMethod(
-            ACC_STATIC | ACC_SYNTHETIC,
-            bridgeMethod.name(),
-            bridgeMethod.descriptor(),
-            /* signature= */ null,
-            methodDeclInfo.exceptions);
+    MethodDeclInfo bridgeMethod = methodDeclInfo.bridgeOfClassInstanceMethod();
+    MethodVisitor mv = bridgeMethod.accept(cv);
     mv.visitCode();
     int slotOffset = 0;
-    for (Type argType : bridgeMethod.getArgumentTypes()) {
+    for (Type argType : bridgeMethod.argumentTypes()) {
       mv.visitVarInsn(argType.getOpcode(Opcodes.ILOAD), slotOffset);
       slotOffset += argType.getSize();
     }
 
     mv.visitMethodInsn(
         Opcodes.INVOKESPECIAL,
-        methodDeclInfo.methodKey.ownerName(),
-        methodDeclInfo.methodKey.name(),
-        methodDeclInfo.methodKey.descriptor(),
+        methodDeclInfo.ownerName(),
+        methodDeclInfo.name(),
+        methodDeclInfo.descriptor(),
         /* isInterface= */ false);
-    mv.visitInsn(bridgeMethod.getReturnType().getOpcode(Opcodes.IRETURN));
+    mv.visitInsn(bridgeMethod.returnType().getOpcode(Opcodes.IRETURN));
     mv.visitMaxs(slotOffset, slotOffset);
     mv.visitEnd();
     return mv;
@@ -212,15 +189,7 @@
    */
   @Override
   public MethodVisitor visitInterfaceStaticMethod(MethodDeclInfo methodDeclInfo, ClassVisitor cv) {
-    MethodKey methodSubstitute = methodDeclInfo.methodKey.substituteOfInterfaceStaticMethod();
-
-    // Unset static and access modifier bits.
-    return cv.visitMethod(
-        (methodDeclInfo.memberAccess & ~0xf) | ACC_PUBLIC | ACC_STATIC,
-        methodSubstitute.name(),
-        methodSubstitute.descriptor(),
-        /* signature= */ null,
-        methodDeclInfo.exceptions);
+    return methodDeclInfo.substituteOfInterfaceStaticMethod().accept(cv);
   }
 
   /**
@@ -254,14 +223,6 @@
   @Override
   public MethodVisitor visitInterfaceInstanceMethod(
       MethodDeclInfo methodDeclInfo, ClassVisitor cv) {
-    MethodKey methodSubstitute = methodDeclInfo.methodKey.substituteOfInterfaceInstanceMethod();
-
-    // Unset static and access modifier bits.
-    return cv.visitMethod(
-        (methodDeclInfo.memberAccess & ~0xf) | ACC_PUBLIC | ACC_STATIC,
-        methodSubstitute.name(),
-        methodSubstitute.descriptor(),
-        /* signature= */ null,
-        methodDeclInfo.exceptions);
+    return methodDeclInfo.substituteOfInterfaceInstanceMethod().accept(cv);
   }
 }
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/nest/NestBridgeRefConverter.java b/src/tools/android/java/com/google/devtools/build/android/desugar/nest/NestBridgeRefConverter.java
index 9844ed6..499f994 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/nest/NestBridgeRefConverter.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/nest/NestBridgeRefConverter.java
@@ -133,8 +133,7 @@
 
     @Override
     public MethodKey visitInvokeStatic(MethodKey methodKey, MethodVisitor mv) {
-      final MethodKey bridgeMethodKey;
-      bridgeMethodKey = methodKey.bridgeOfClassStaticMethod();
+      MethodKey bridgeMethodKey = methodKey.bridgeOfClassStaticMethod();
       mv.visitMethodInsn(
           Opcodes.INVOKESTATIC,
           bridgeMethodKey.ownerName(),
@@ -146,8 +145,7 @@
 
     @Override
     public MethodKey visitInterfaceInvokeStatic(MethodKey methodKey, MethodVisitor mv) {
-      final MethodKey methodBridge;
-      methodBridge = methodKey.substituteOfInterfaceStaticMethod();
+      final MethodKey methodBridge = methodKey.substituteOfInterfaceStaticMethod();
       mv.visitMethodInsn(
           Opcodes.INVOKESTATIC,
           methodBridge.ownerName(),
@@ -159,8 +157,7 @@
 
     @Override
     public MethodKey visitInvokeInterface(MethodKey methodKey, MethodVisitor mv) {
-      final MethodKey methodBridge;
-      methodBridge = methodKey.substituteOfInterfaceInstanceMethod();
+      final MethodKey methodBridge = methodKey.substituteOfInterfaceInstanceMethod();
       mv.visitMethodInsn(
           Opcodes.INVOKESTATIC,
           methodBridge.ownerName(),
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/nest/NestDesugaring.java b/src/tools/android/java/com/google/devtools/build/android/desugar/nest/NestDesugaring.java
index 7d0c7de..4b8ef72 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/nest/NestDesugaring.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/nest/NestDesugaring.java
@@ -110,7 +110,7 @@
     MethodKey methodKey = MethodKey.create(className, name, descriptor);
     if (nestDigest.hasAnyTrackingReason(methodKey)) {
       MethodDeclInfo methodDeclInfo =
-          new MethodDeclInfo(methodKey, classAccess, access, signature, exceptions);
+          MethodDeclInfo.create(methodKey, classAccess, access, signature, exceptions);
       // For interfaces, the following .accept converts the original method into a
       // visibility-broadened renamed method in-place while preserving the method body
       // implementation; for classes, the following .accept generates synthetic bridge methods and