code: private FieldAccess genCodeForFieldAccess(
        SoyType baseType, FieldAccessNode fieldAccessNode, String fieldName) {
      Preconditions.checkNotNull(baseType);
      // For unions, attempt to generate the field access code for each member
      // type, and then see if they all agree.
      if (baseType.getKind() == SoyType.Kind.UNION) {
        // TODO(msamuel): We will need to generate fallback code for each variant.
        UnionType unionType = (UnionType) baseType;
        FieldAccess fieldAccess = null;
        for (SoyType memberType : unionType.getMembers()) {
          if (memberType.getKind() != SoyType.Kind.NULL) {
            FieldAccess fieldAccessForType =
                genCodeForFieldAccess(memberType, fieldAccessNode, fieldName);
            if (fieldAccess == null) {
              fieldAccess = fieldAccessForType;
            } else if (!fieldAccess.equals(fieldAccessForType)) {
              errorReporter.report(
                  fieldAccessNode.getSourceLocation(), UNION_ACCESSOR_MISMATCH, fieldName, baseType);
            }
          }
        }
        return fieldAccess;
      }
  
      if (baseType.getKind() == SoyType.Kind.PROTO) {
        SoyProtoType protoType = (SoyProtoType) baseType;
        FieldDescriptor desc = protoType.getFieldDescriptor(fieldName);
        Preconditions.checkNotNull(
            desc,
            "Error in proto %s, field not found: %s",
            protoType.getDescriptor().getFullName(),
            fieldName);
        return FieldAccess.protoCall(fieldName, desc);
      }
  
      return FieldAccess.id(fieldName);
    }
docs: Generates the code for a field access, e.g. {@code .foo} or {@code .getFoo()}.
  
  @param baseType The type of the object that contains the field.
  @param fieldAccessNode The field access node.
  @param fieldName The field name.