code: void fillJSDocInfo(Node externs, Node root) {
      NodeTraversal.traverseRoots(
          compiler, new JSDocInfoCollector(compiler.getTypeRegistry()), externs, root);
  
      // Create references to parameters in the JSDoc.
      for (Symbol sym : getAllSymbols()) {
        JSDocInfo info = sym.getJSDocInfo();
        if (info == null) {
          continue;
        }
  
        for (Marker marker : info.getMarkers()) {
          SourcePosition<Node> pos = marker.getNameNode();
          if (pos == null) {
            continue;
          }
  
          Node paramNode = pos.getItem();
          String name = paramNode.getString();
          Symbol param = getParameterInFunction(sym, name);
          if (param == null) {
            // There is no reference to this parameter in the actual JavaScript
            // code, so we'll try to create a special JsDoc-only symbol in
            // a JsDoc-only scope.
            SourcePosition<Node> typePos = marker.getType();
            JSType type = null;
            if (typePos != null) {
              type = typePos.getItem().getJSType();
            }
  
            if (sym.docScope == null) {
              sym.docScope =
                  new SymbolScope(
                      null /* root */, null /* parent scope */, null /* type of this */, sym);
            }
  
            // Check to make sure there's no existing symbol. In theory, this
            // should never happen, but we check anyway and fail silently
            // if our assumptions are wrong. (We do not want to put the symbol
            // table into an invalid state).
            Symbol existingSymbol = isAnySymbolDeclared(name, paramNode, sym.docScope);
            if (existingSymbol == null) {
              declareSymbol(name, type, type == null, sym.docScope, paramNode, null /* info */);
            }
          } else {
            param.defineReferenceAt(paramNode);
          }
        }
      }
    }
docs: Index JSDocInfo.