xds: Use getWatchers more often in XdsDepManager

This provides better type and missing-map handling. Note that
getWatchers() now implicitly creates the map if it doesn't exist,
instead of just returning an empty map. That makes it a bit easier to
use and more importantly avoids accidents where a bug tries to modify
the immutable map.
diff --git a/xds/src/main/java/io/grpc/xds/XdsDependencyManager.java b/xds/src/main/java/io/grpc/xds/XdsDependencyManager.java
index 1ba4963..0c3e110 100644
--- a/xds/src/main/java/io/grpc/xds/XdsDependencyManager.java
+++ b/xds/src/main/java/io/grpc/xds/XdsDependencyManager.java
@@ -112,14 +112,7 @@
     XdsResourceType<T> type = watcher.type;
     String resourceName = watcher.resourceName;
 
-    @SuppressWarnings("unchecked")
-    TypeWatchers<T> typeWatchers = (TypeWatchers<T>)resourceWatchers.get(type);
-    if (typeWatchers == null) {
-      typeWatchers = new TypeWatchers<>(type);
-      resourceWatchers.put(type, typeWatchers);
-    }
-
-    typeWatchers.add(resourceName, watcher);
+    getWatchers(type).put(resourceName, watcher);
     xdsClient.watchXdsResource(type, resourceName, watcher, syncContext);
   }
 
@@ -158,16 +151,12 @@
     XdsResourceType<T> type = watcher.type;
     String resourceName = watcher.resourceName;
 
-    @SuppressWarnings("unchecked")
-    TypeWatchers<T> typeWatchers = (TypeWatchers<T>)resourceWatchers.get(type);
-    if (typeWatchers == null) {
-      logger.log(DEBUG, "Trying to cancel watcher {0}, but type not watched", watcher);
+    if (getWatchers(type).remove(resourceName) == null) {
+      logger.log(DEBUG, "Trying to cancel watcher {0}, but it isn't watched", watcher);
       return;
     }
 
-    typeWatchers.watchers.remove(resourceName);
     xdsClient.cancelXdsResourceWatch(type, resourceName, watcher);
-
   }
 
   private static void throwIfParentContextsNotEmpty(XdsWatcherBase<?> watcher) {
@@ -213,8 +202,8 @@
         return;
       }
       subscription.closed = true;
-      XdsWatcherBase<?> cdsWatcher =
-          resourceWatchers.get(CLUSTER_RESOURCE).watchers.get(clusterName);
+      XdsWatcherBase<XdsClusterResource.CdsUpdate> cdsWatcher
+          = getWatchers(CLUSTER_RESOURCE).get(clusterName);
       if (cdsWatcher == null) {
         return; // shutdown() called
       }
@@ -236,14 +225,12 @@
     switch (cdsUpdate.clusterType()) {
       case EDS:
         String edsServiceName = root.getEdsServiceName();
-        EdsWatcher edsWatcher =
-            (EdsWatcher) resourceWatchers.get(ENDPOINT_RESOURCE).watchers.get(edsServiceName);
+        EdsWatcher edsWatcher = (EdsWatcher) getWatchers(ENDPOINT_RESOURCE).get(edsServiceName);
         cancelEdsWatcher(edsWatcher, root);
         break;
       case AGGREGATE:
         for (String cluster : cdsUpdate.prioritizedClusterNames()) {
-          CdsWatcher clusterWatcher =
-              (CdsWatcher) resourceWatchers.get(CLUSTER_RESOURCE).watchers.get(cluster);
+          CdsWatcher clusterWatcher = (CdsWatcher) getWatchers(CLUSTER_RESOURCE).get(cluster);
           if (clusterWatcher != null) {
             cancelClusterWatcherTree(clusterWatcher, root);
           }
@@ -348,7 +335,8 @@
       XdsResourceType<T> resourceType) {
     TypeWatchers<?> typeWatchers = resourceWatchers.get(resourceType);
     if (typeWatchers == null) {
-      return Collections.emptyMap();
+      typeWatchers = new TypeWatchers<T>(resourceType);
+      resourceWatchers.put(resourceType, typeWatchers);
     }
     assert typeWatchers.resourceType == resourceType;
     @SuppressWarnings("unchecked")
@@ -470,25 +458,22 @@
 
   // Returns true if the watcher was added, false if it already exists
   private boolean addEdsWatcher(String edsServiceName, CdsWatcher parentContext) {
-    TypeWatchers<?> typeWatchers = resourceWatchers.get(XdsEndpointResource.getInstance());
-    if (typeWatchers == null || !typeWatchers.watchers.containsKey(edsServiceName)) {
-      addWatcher(new EdsWatcher(edsServiceName, parentContext));
-      return true;
+    EdsWatcher watcher
+        = (EdsWatcher) getWatchers(XdsEndpointResource.getInstance()).get(edsServiceName);
+    if (watcher != null) {
+      watcher.addParentContext(parentContext); // Is a set, so don't need to check for existence
+      return false;
     }
 
-    EdsWatcher watcher = (EdsWatcher) typeWatchers.watchers.get(edsServiceName);
-    watcher.addParentContext(parentContext); // Is a set, so don't need to check for existence
-    return false;
+    addWatcher(new EdsWatcher(edsServiceName, parentContext));
+    return true;
   }
 
   private void addClusterWatcher(String clusterName, Object parentContext, int depth) {
-    TypeWatchers<?> clusterWatchers = resourceWatchers.get(CLUSTER_RESOURCE);
-    if (clusterWatchers != null) {
-      CdsWatcher watcher = (CdsWatcher) clusterWatchers.watchers.get(clusterName);
-      if (watcher != null) {
-        watcher.parentContexts.put(parentContext, depth);
-        return;
-      }
+    CdsWatcher watcher = (CdsWatcher) getWatchers(CLUSTER_RESOURCE).get(clusterName);
+    if (watcher != null) {
+      watcher.parentContexts.put(parentContext, depth);
+      return;
     }
 
     addWatcher(new CdsWatcher(clusterName, parentContext, depth));
@@ -546,7 +531,7 @@
   }
 
   private CdsWatcher getCluster(String clusterName) {
-    return (CdsWatcher) resourceWatchers.get(CLUSTER_RESOURCE).watchers.get(clusterName);
+    return (CdsWatcher) getWatchers(CLUSTER_RESOURCE).get(clusterName);
   }
 
   private static class TypeWatchers<T extends ResourceUpdate> {
@@ -557,10 +542,6 @@
     TypeWatchers(XdsResourceType<T> resourceType) {
       this.resourceType = resourceType;
     }
-
-    public void add(String resourceName, XdsWatcherBase<T> watcher) {
-      watchers.put(resourceName, watcher);
-    }
   }
 
   public interface XdsConfigWatcher {
@@ -738,11 +719,11 @@
         logger.log(XdsLogger.XdsLogLevel.DEBUG, "Stop watching RDS resource {0}", rdsName);
 
         // Cleanup clusters (as appropriate) that had the old rds watcher as a parent
-        if (!oldRdsWatcher.hasDataValue() || resourceWatchers.get(CLUSTER_RESOURCE) == null) {
+        if (!oldRdsWatcher.hasDataValue()) {
           return;
         }
-        for (XdsWatcherBase<?> watcher :
-            resourceWatchers.get(CLUSTER_RESOURCE).watchers.values()) {
+        for (XdsWatcherBase<XdsClusterResource.CdsUpdate> watcher :
+            getWatchers(CLUSTER_RESOURCE).values()) {
           cancelCdsWatcher((CdsWatcher) watcher, oldRdsWatcher);
         }
       }
@@ -752,11 +733,7 @@
       if (rdsName == null) {
         return null;
       }
-      TypeWatchers<?> watchers = resourceWatchers.get(XdsRouteConfigureResource.getInstance());
-      if (watchers == null) {
-        return null;
-      }
-      return (RdsWatcher) watchers.watchers.get(rdsName);
+      return (RdsWatcher) getWatchers(XdsRouteConfigureResource.getInstance()).get(rdsName);
     }
 
     public RdsUpdateSupplier getRouteSource() {