code: func (dw *DocumentsWriter) updateDocument(doc []model.IndexableField,
  	analyzer analysis.Analyzer, delTerm *Term) (bool, error) {
  
  	hasEvents, err := dw.preUpdate()
  	if err != nil {
  		return false, err
  	}
  
  	flushingDWPT, err := func() (*DocumentsWriterPerThread, error) {
  		perThread := dw.flushControl.obtainAndLock()
  		defer dw.flushControl.perThreadPool.release(perThread)
  
  		if !perThread.isActive {
  			dw.ensureOpen()
  			panic("perThread is not active but we are still open")
  		}
  		dw.ensureInitialized(perThread)
  		assert(perThread.dwpt != nil)
  		dwpt := perThread.dwpt
  		dwptNuMDocs := dwpt.numDocsInRAM
  
  		err := func() error {
  			defer func() {
  				// We don't know whether the document actually counted as
  				// being indexed, so we must subtract here to accumulate our
  				// separate counter:
  				atomic.AddInt32(&dw.numDocsInRAM, int32(dwpt.numDocsInRAM-dwptNuMDocs))
  				if dwpt.checkAndResetHasAborted() {
  					if len(dwpt.filesToDelete) > 0 {
  						dw.putEvent(newDeleteNewFilesEvent(dwpt.filesToDelete))
  					}
  					dw.subtractFlushedNumDocs(dwptNuMDocs)
  					dw.flushControl.doOnAbort(perThread)
  				}
  			}()
  
  			err := dwpt.updateDocument(doc, analyzer, delTerm)
  			if err != nil {
  				return err
  			}
  			return nil
  		}()
  		if err != nil {
  			return nil, err
  		}
  
  		isUpdate := delTerm != nil
  		return dw.flushControl.doAfterDocument(perThread, isUpdate), nil
  	}()
  	if err != nil {
  		return false, err
  	}
  
  	return dw.postUpdate(flushingDWPT, hasEvents)
  }
docs: // L428