code: func (w *Wrapper) Generate() error {
  	if !w.initCalled {
  		return errors.New("Init() must be called before Generate()")
  	}
  	if w.Parallelism < 1 {
  		return fmt.Errorf("parallelism cannot be < 1; got %d", w.Parallelism)
  	}
  	parallelism := len(w.packages)
  	if w.Parallelism < parallelism {
  		parallelism = w.Parallelism
  	}
  
  	pkgChan := make(chan *PackageInfo)
  
  	errChan := make(chan error, parallelism)
  	var wg sync.WaitGroup
  	wg.Add(parallelism)
  	for i := 0; i < parallelism; i++ {
  		go func() {
  			for pkg := range pkgChan {
  				fmt.Printf("Generating package %s\n", pkg.ComputedPackage)
  				if err := Generate(pkg, w.ImportDirs, w.ProtocCommand, w.ProtocFlags, w.PrintOnly); err != nil {
  					errChan <- fmt.Errorf("error generating package %s: %v\n", pkg.ComputedPackage, err)
  				}
  			}
  			wg.Done()
  		}()
  	}
  
  	var err error
  OUTER:
  	for _, pkg := range w.packagesInOrder() {
  		select {
  		case pkgChan <- pkg:
  		case err = <-errChan:
  			break OUTER
  		}
  	}
  	close(pkgChan)
  	wg.Wait()
  	select {
  	case err = <-errChan:
  	default:
  	}
  	return err
  }
docs: // Generate actually generates the output files.