code: private NullSafeAccumulator visitNullSafeNode(ExprNode node) {
      switch (node.getKind()) {
        case FIELD_ACCESS_NODE:
          {
            FieldAccessNode fieldAccess = (FieldAccessNode) node;
            NullSafeAccumulator base = visitNullSafeNode(fieldAccess.getBaseExprChild());
            FieldAccess access =
                genCodeForFieldAccess(
                    fieldAccess.getBaseExprChild().getType(),
                    fieldAccess,
                    fieldAccess.getFieldName());
            return base.dotAccess(access, fieldAccess.isNullSafe());
          }
  
        case ITEM_ACCESS_NODE:
          {
            ItemAccessNode itemAccess = (ItemAccessNode) node;
            NullSafeAccumulator base = visitNullSafeNode(itemAccess.getBaseExprChild());
            ExprNode keyNode = itemAccess.getKeyExprChild();
            SoyType baseType = itemAccess.getBaseExprChild().getType();
            return SoyTypes.isKindOrUnionOfKind(SoyTypes.removeNull(baseType), Kind.MAP)
                ? base.mapGetAccess(genMapKeyCode(keyNode), itemAccess.isNullSafe()) // soy.Map
                : base.bracketAccess(
                    // The key type may not match JsCompiler's type system (passing number as enum, or
                    // nullable proto field).  I could instead cast this to the map's key type.
                    visit(keyNode).castAs("?"), itemAccess.isNullSafe()); // vanilla bracket access
          }
  
        default:
          return new NullSafeAccumulator(visit(node));
      }
    }
docs: See {@link NullSafeAccumulator} for discussion.