code: void fillNamespaceReferences() {
      for (Symbol symbol : getAllSymbols()) {
        String qName = symbol.getName();
        int rootIndex = qName.indexOf('.');
        if (rootIndex == -1) {
          continue;
        }
  
        Symbol root = symbol.scope.getQualifiedSlot(qName.substring(0, rootIndex));
        if (root == null) {
          // In theory, this should never happen, but we fail quietly anyway
          // just to be safe.
          continue;
        }
  
        for (Reference ref : getReferences(symbol)) {
          Node currentNode = ref.getNode();
          if (!currentNode.isQualifiedName()) {
            continue;
          }
  
          while (currentNode.isGetProp()) {
            currentNode = currentNode.getFirstChild();
  
            String name = currentNode.getQualifiedName();
            if (name != null) {
              Symbol namespace = isAnySymbolDeclared(name, currentNode, root.scope);
              if (namespace == null) {
                namespace = root.scope.getQualifiedSlot(name);
              }
  
              if (namespace == null && root.scope.isGlobalScope()) {
                namespace =
                    declareSymbol(
                        name,
                        registry.getNativeType(JSTypeNative.UNKNOWN_TYPE),
                        true,
                        root.scope,
                        currentNode,
                        null /* JsDoc info */);
              }
  
              if (namespace != null) {
                namespace.defineReferenceAt(currentNode);
              }
            }
          }
        }
      }
    }
docs: Not all symbol tables record references to "namespace" objects. For example, if you have:
  goog.dom.DomHelper = function() {}; The symbol table may not record that as a reference to
  "goog.dom", because that would be redundant.