// Generate calls all the service generators associated with this plugin and // consolidates their output. // // Any conflicts in the generated files will result in a failure. func (msg MultiServiceGenerator) Generate(req *api.GenerateServiceRequest) (*api.GenerateServiceResponse, error) { var ( lock sync.Mutex files = make(map[string][]byte) usedPaths = make(map[string]string) // path -> plugin name ) err := concurrent.Range(msg, func(_ int, sg ServiceGenerator) error { res, err := sg.Generate(req) if err != nil { return err } lock.Lock() defer lock.Unlock() pluginName := sg.Handle().Name() for path, contents := range res.Files { if takenBy, taken := usedPaths[path]; taken { return fmt.Errorf("plugin conflict: cannot write file %q for plugin %q: "+ "plugin %q already wrote to that file", path, pluginName, takenBy) } usedPaths[path] = pluginName files[path] = contents } return nil }) return &api.GenerateServiceResponse{Files: files}, err }
// Handle gets a MultiHandle to all the plugins in this list or nil if the // list is empty. // // The returned handle MUST be closed by the caller if error was nil. func (fs Flags) Handle() (MultiHandle, error) { var ( lock sync.Mutex multi MultiHandle ) err := concurrent.Range(fs, func(_ int, f Flag) error { h, err := f.Handle() if err != nil { return err } lock.Lock() defer lock.Unlock() multi = append(multi, h) return nil }) if err == nil { return multi, nil } return nil, internal.CombineErrors(err, multi.Close()) }
// Close closes all Handles associated with this MultiHandle. func (mh MultiHandle) Close() error { return concurrent.Range(mh, func(_ int, h Handle) error { return h.Close() }) }