dig.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821
  1. // Copyright (c) 2019 Uber Technologies, Inc.
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy
  4. // of this software and associated documentation files (the "Software"), to deal
  5. // in the Software without restriction, including without limitation the rights
  6. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. // copies of the Software, and to permit persons to whom the Software is
  8. // furnished to do so, subject to the following conditions:
  9. //
  10. // The above copyright notice and this permission notice shall be included in
  11. // all copies or substantial portions of the Software.
  12. //
  13. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. // THE SOFTWARE.
  20. package dig
  21. import (
  22. "errors"
  23. "fmt"
  24. "math/rand"
  25. "reflect"
  26. "sort"
  27. "strconv"
  28. "strings"
  29. "time"
  30. "go.uber.org/dig/internal/digreflect"
  31. "go.uber.org/dig/internal/dot"
  32. )
  33. const (
  34. _optionalTag = "optional"
  35. _nameTag = "name"
  36. )
  37. // Unique identification of an object in the graph.
  38. type key struct {
  39. t reflect.Type
  40. // Only one of name or group will be set.
  41. name string
  42. group string
  43. }
  44. // Option configures a Container. It's included for future functionality;
  45. // currently, there are no concrete implementations.
  46. type Option interface {
  47. applyOption(*Container)
  48. }
  49. type optionFunc func(*Container)
  50. func (f optionFunc) applyOption(c *Container) { f(c) }
  51. type provideOptions struct {
  52. Name string
  53. Group string
  54. }
  55. func (o *provideOptions) Validate() error {
  56. if len(o.Group) > 0 && len(o.Name) > 0 {
  57. return errf(
  58. "cannot use named values with value groups",
  59. "name:%q provided with group:%q", o.Name, o.Group)
  60. }
  61. // Names must be representable inside a backquoted string. The only
  62. // limitation for raw string literals as per
  63. // https://golang.org/ref/spec#raw_string_lit is that they cannot contain
  64. // backquotes.
  65. if strings.ContainsRune(o.Name, '`') {
  66. return errf("invalid dig.Name(%q): names cannot contain backquotes", o.Name)
  67. }
  68. if strings.ContainsRune(o.Group, '`') {
  69. return errf("invalid dig.Group(%q): group names cannot contain backquotes", o.Group)
  70. }
  71. return nil
  72. }
  73. // A ProvideOption modifies the default behavior of Provide.
  74. type ProvideOption interface {
  75. applyProvideOption(*provideOptions)
  76. }
  77. type provideOptionFunc func(*provideOptions)
  78. func (f provideOptionFunc) applyProvideOption(opts *provideOptions) { f(opts) }
  79. // Name is a ProvideOption that specifies that all values produced by a
  80. // constructor should have the given name. See also the package documentation
  81. // about Named Values.
  82. //
  83. // Given,
  84. //
  85. // func NewReadOnlyConnection(...) (*Connection, error)
  86. // func NewReadWriteConnection(...) (*Connection, error)
  87. //
  88. // The following will provide two connections to the container: one under the
  89. // name "ro" and the other under the name "rw".
  90. //
  91. // c.Provide(NewReadOnlyConnection, dig.Name("ro"))
  92. // c.Provide(NewReadWriteConnection, dig.Name("rw"))
  93. //
  94. // This option cannot be provided for constructors which produce result
  95. // objects.
  96. func Name(name string) ProvideOption {
  97. return provideOptionFunc(func(opts *provideOptions) {
  98. opts.Name = name
  99. })
  100. }
  101. // Group is a ProvideOption that specifies that all values produced by a
  102. // constructor should be added to the specified group. See also the package
  103. // documentation about Value Groups.
  104. //
  105. // This option cannot be provided for constructors which produce result
  106. // objects.
  107. func Group(group string) ProvideOption {
  108. return provideOptionFunc(func(opts *provideOptions) {
  109. opts.Group = group
  110. })
  111. }
  112. // An InvokeOption modifies the default behavior of Invoke. It's included for
  113. // future functionality; currently, there are no concrete implementations.
  114. type InvokeOption interface {
  115. unimplemented()
  116. }
  117. // Container is a directed acyclic graph of types and their dependencies.
  118. type Container struct {
  119. // Mapping from key to all the nodes that can provide a value for that
  120. // key.
  121. providers map[key][]*node
  122. // All nodes in the container.
  123. nodes []*node
  124. // Values that have already been generated in the container.
  125. values map[key]reflect.Value
  126. // Values groups that have already been generated in the container.
  127. groups map[key][]reflect.Value
  128. // Source of randomness.
  129. rand *rand.Rand
  130. // Flag indicating whether the graph has been checked for cycles.
  131. isVerifiedAcyclic bool
  132. // Defer acyclic check on provide until Invoke.
  133. deferAcyclicVerification bool
  134. // invokerFn calls a function with arguments provided to Provide or Invoke.
  135. invokerFn invokerFn
  136. }
  137. // containerWriter provides write access to the Container's underlying data
  138. // store.
  139. type containerWriter interface {
  140. // setValue sets the value with the given name and type in the container.
  141. // If a value with the same name and type already exists, it will be
  142. // overwritten.
  143. setValue(name string, t reflect.Type, v reflect.Value)
  144. // submitGroupedValue submits a value to the value group with the provided
  145. // name.
  146. submitGroupedValue(name string, t reflect.Type, v reflect.Value)
  147. }
  148. // containerStore provides access to the Container's underlying data store.
  149. type containerStore interface {
  150. containerWriter
  151. // Returns a slice containing all known types.
  152. knownTypes() []reflect.Type
  153. // Retrieves the value with the provided name and type, if any.
  154. getValue(name string, t reflect.Type) (v reflect.Value, ok bool)
  155. // Retrieves all values for the provided group and type.
  156. //
  157. // The order in which the values are returned is undefined.
  158. getValueGroup(name string, t reflect.Type) []reflect.Value
  159. // Returns the providers that can produce a value with the given name and
  160. // type.
  161. getValueProviders(name string, t reflect.Type) []provider
  162. // Returns the providers that can produce values for the given group and
  163. // type.
  164. getGroupProviders(name string, t reflect.Type) []provider
  165. createGraph() *dot.Graph
  166. // Returns invokerFn function to use when calling arguments.
  167. invoker() invokerFn
  168. }
  169. // provider encapsulates a user-provided constructor.
  170. type provider interface {
  171. // ID is a unique numerical identifier for this provider.
  172. ID() dot.CtorID
  173. // Location returns where this constructor was defined.
  174. Location() *digreflect.Func
  175. // ParamList returns information about the direct dependencies of this
  176. // constructor.
  177. ParamList() paramList
  178. // ResultList returns information about the values produced by this
  179. // constructor.
  180. ResultList() resultList
  181. // Calls the underlying constructor, reading values from the
  182. // containerStore as needed.
  183. //
  184. // The values produced by this provider should be submitted into the
  185. // containerStore.
  186. Call(containerStore) error
  187. }
  188. // New constructs a Container.
  189. func New(opts ...Option) *Container {
  190. c := &Container{
  191. providers: make(map[key][]*node),
  192. values: make(map[key]reflect.Value),
  193. groups: make(map[key][]reflect.Value),
  194. rand: rand.New(rand.NewSource(time.Now().UnixNano())),
  195. invokerFn: defaultInvoker,
  196. }
  197. for _, opt := range opts {
  198. opt.applyOption(c)
  199. }
  200. return c
  201. }
  202. // DeferAcyclicVerification is an Option to override the default behavior
  203. // of container.Provide, deferring the dependency graph validation to no longer
  204. // run after each call to container.Provide. The container will instead verify
  205. // the graph on first `Invoke`.
  206. //
  207. // Applications adding providers to a container in a tight loop may experience
  208. // performance improvements by initializing the container with this option.
  209. func DeferAcyclicVerification() Option {
  210. return optionFunc(func(c *Container) {
  211. c.deferAcyclicVerification = true
  212. })
  213. }
  214. // Changes the source of randomness for the container.
  215. //
  216. // This will help provide determinism during tests.
  217. func setRand(r *rand.Rand) Option {
  218. return optionFunc(func(c *Container) {
  219. c.rand = r
  220. })
  221. }
  222. // DryRun is an Option which, when set to true, disables invocation of functions supplied to
  223. // Provide and Invoke. Use this to build no-op containers.
  224. func DryRun(dry bool) Option {
  225. return optionFunc(func(c *Container) {
  226. if dry {
  227. c.invokerFn = dryInvoker
  228. } else {
  229. c.invokerFn = defaultInvoker
  230. }
  231. })
  232. }
  233. // invokerFn specifies how the container calls user-supplied functions.
  234. type invokerFn func(fn reflect.Value, args []reflect.Value) (results []reflect.Value)
  235. func defaultInvoker(fn reflect.Value, args []reflect.Value) []reflect.Value {
  236. return fn.Call(args)
  237. }
  238. // Generates zero values for results without calling the supplied function.
  239. func dryInvoker(fn reflect.Value, _ []reflect.Value) []reflect.Value {
  240. ft := fn.Type()
  241. results := make([]reflect.Value, ft.NumOut())
  242. for i := 0; i < ft.NumOut(); i++ {
  243. results[i] = reflect.Zero(fn.Type().Out(i))
  244. }
  245. return results
  246. }
  247. func (c *Container) knownTypes() []reflect.Type {
  248. typeSet := make(map[reflect.Type]struct{}, len(c.providers))
  249. for k := range c.providers {
  250. typeSet[k.t] = struct{}{}
  251. }
  252. types := make([]reflect.Type, 0, len(typeSet))
  253. for t := range typeSet {
  254. types = append(types, t)
  255. }
  256. sort.Sort(byTypeName(types))
  257. return types
  258. }
  259. func (c *Container) getValue(name string, t reflect.Type) (v reflect.Value, ok bool) {
  260. v, ok = c.values[key{name: name, t: t}]
  261. return
  262. }
  263. func (c *Container) setValue(name string, t reflect.Type, v reflect.Value) {
  264. c.values[key{name: name, t: t}] = v
  265. }
  266. func (c *Container) getValueGroup(name string, t reflect.Type) []reflect.Value {
  267. items := c.groups[key{group: name, t: t}]
  268. // shuffle the list so users don't rely on the ordering of grouped values
  269. return shuffledCopy(c.rand, items)
  270. }
  271. func (c *Container) submitGroupedValue(name string, t reflect.Type, v reflect.Value) {
  272. k := key{group: name, t: t}
  273. c.groups[k] = append(c.groups[k], v)
  274. }
  275. func (c *Container) getValueProviders(name string, t reflect.Type) []provider {
  276. return c.getProviders(key{name: name, t: t})
  277. }
  278. func (c *Container) getGroupProviders(name string, t reflect.Type) []provider {
  279. return c.getProviders(key{group: name, t: t})
  280. }
  281. func (c *Container) getProviders(k key) []provider {
  282. nodes := c.providers[k]
  283. providers := make([]provider, len(nodes))
  284. for i, n := range nodes {
  285. providers[i] = n
  286. }
  287. return providers
  288. }
  289. // invokerFn return a function to run when calling function provided to Provide or Invoke. Used for
  290. // running container in dry mode.
  291. func (c *Container) invoker() invokerFn {
  292. return c.invokerFn
  293. }
  294. // Provide teaches the container how to build values of one or more types and
  295. // expresses their dependencies.
  296. //
  297. // The first argument of Provide is a function that accepts zero or more
  298. // parameters and returns one or more results. The function may optionally
  299. // return an error to indicate that it failed to build the value. This
  300. // function will be treated as the constructor for all the types it returns.
  301. // This function will be called AT MOST ONCE when a type produced by it, or a
  302. // type that consumes this function's output, is requested via Invoke. If the
  303. // same types are requested multiple times, the previously produced value will
  304. // be reused.
  305. //
  306. // In addition to accepting constructors that accept dependencies as separate
  307. // arguments and produce results as separate return values, Provide also
  308. // accepts constructors that specify dependencies as dig.In structs and/or
  309. // specify results as dig.Out structs.
  310. func (c *Container) Provide(constructor interface{}, opts ...ProvideOption) error {
  311. ctype := reflect.TypeOf(constructor)
  312. if ctype == nil {
  313. return errors.New("can't provide an untyped nil")
  314. }
  315. if ctype.Kind() != reflect.Func {
  316. return errf("must provide constructor function, got %v (type %v)", constructor, ctype)
  317. }
  318. var options provideOptions
  319. for _, o := range opts {
  320. o.applyProvideOption(&options)
  321. }
  322. if err := options.Validate(); err != nil {
  323. return err
  324. }
  325. if err := c.provide(constructor, options); err != nil {
  326. return errProvide{
  327. Func: digreflect.InspectFunc(constructor),
  328. Reason: err,
  329. }
  330. }
  331. return nil
  332. }
  333. // Invoke runs the given function after instantiating its dependencies.
  334. //
  335. // Any arguments that the function has are treated as its dependencies. The
  336. // dependencies are instantiated in an unspecified order along with any
  337. // dependencies that they might have.
  338. //
  339. // The function may return an error to indicate failure. The error will be
  340. // returned to the caller as-is.
  341. func (c *Container) Invoke(function interface{}, opts ...InvokeOption) error {
  342. ftype := reflect.TypeOf(function)
  343. if ftype == nil {
  344. return errors.New("can't invoke an untyped nil")
  345. }
  346. if ftype.Kind() != reflect.Func {
  347. return errf("can't invoke non-function %v (type %v)", function, ftype)
  348. }
  349. pl, err := newParamList(ftype)
  350. if err != nil {
  351. return err
  352. }
  353. if err := shallowCheckDependencies(c, pl); err != nil {
  354. return errMissingDependencies{
  355. Func: digreflect.InspectFunc(function),
  356. Reason: err,
  357. }
  358. }
  359. if !c.isVerifiedAcyclic {
  360. if err := c.verifyAcyclic(); err != nil {
  361. return err
  362. }
  363. }
  364. args, err := pl.BuildList(c)
  365. if err != nil {
  366. return errArgumentsFailed{
  367. Func: digreflect.InspectFunc(function),
  368. Reason: err,
  369. }
  370. }
  371. returned := c.invokerFn(reflect.ValueOf(function), args)
  372. if len(returned) == 0 {
  373. return nil
  374. }
  375. if last := returned[len(returned)-1]; isError(last.Type()) {
  376. if err, _ := last.Interface().(error); err != nil {
  377. return err
  378. }
  379. }
  380. return nil
  381. }
  382. func (c *Container) verifyAcyclic() error {
  383. visited := make(map[key]struct{})
  384. for _, n := range c.nodes {
  385. if err := detectCycles(n, c, nil /* path */, visited); err != nil {
  386. return errf("cycle detected in dependency graph", err)
  387. }
  388. }
  389. c.isVerifiedAcyclic = true
  390. return nil
  391. }
  392. func (c *Container) provide(ctor interface{}, opts provideOptions) error {
  393. n, err := newNode(
  394. ctor,
  395. nodeOptions{
  396. ResultName: opts.Name,
  397. ResultGroup: opts.Group,
  398. },
  399. )
  400. if err != nil {
  401. return err
  402. }
  403. keys, err := c.findAndValidateResults(n)
  404. if err != nil {
  405. return err
  406. }
  407. ctype := reflect.TypeOf(ctor)
  408. if len(keys) == 0 {
  409. return errf("%v must provide at least one non-error type", ctype)
  410. }
  411. for k := range keys {
  412. c.isVerifiedAcyclic = false
  413. oldProviders := c.providers[k]
  414. c.providers[k] = append(c.providers[k], n)
  415. if c.deferAcyclicVerification {
  416. continue
  417. }
  418. if err := verifyAcyclic(c, n, k); err != nil {
  419. c.providers[k] = oldProviders
  420. return err
  421. }
  422. c.isVerifiedAcyclic = true
  423. }
  424. c.nodes = append(c.nodes, n)
  425. return nil
  426. }
  427. // Builds a collection of all result types produced by this node.
  428. func (c *Container) findAndValidateResults(n *node) (map[key]struct{}, error) {
  429. var err error
  430. keyPaths := make(map[key]string)
  431. walkResult(n.ResultList(), connectionVisitor{
  432. c: c,
  433. n: n,
  434. err: &err,
  435. keyPaths: keyPaths,
  436. })
  437. if err != nil {
  438. return nil, err
  439. }
  440. keys := make(map[key]struct{}, len(keyPaths))
  441. for k := range keyPaths {
  442. keys[k] = struct{}{}
  443. }
  444. return keys, nil
  445. }
  446. // Visits the results of a node and compiles a collection of all the keys
  447. // produced by that node.
  448. type connectionVisitor struct {
  449. c *Container
  450. n *node
  451. // If this points to a non-nil value, we've already encountered an error
  452. // and should stop traversing.
  453. err *error
  454. // Map of keys provided to path that provided this. The path is a string
  455. // documenting which positional return value or dig.Out attribute is
  456. // providing this particular key.
  457. //
  458. // For example, "[0].Foo" indicates that the value was provided by the Foo
  459. // attribute of the dig.Out returned as the first result of the
  460. // constructor.
  461. keyPaths map[key]string
  462. // We track the path to the current result here. For example, this will
  463. // be, ["[1]", "Foo", "Bar"] when we're visiting Bar in,
  464. //
  465. // func() (io.Writer, struct {
  466. // dig.Out
  467. //
  468. // Foo struct {
  469. // dig.Out
  470. //
  471. // Bar io.Reader
  472. // }
  473. // })
  474. currentResultPath []string
  475. }
  476. func (cv connectionVisitor) AnnotateWithField(f resultObjectField) resultVisitor {
  477. cv.currentResultPath = append(cv.currentResultPath, f.FieldName)
  478. return cv
  479. }
  480. func (cv connectionVisitor) AnnotateWithPosition(i int) resultVisitor {
  481. cv.currentResultPath = append(cv.currentResultPath, fmt.Sprintf("[%d]", i))
  482. return cv
  483. }
  484. func (cv connectionVisitor) Visit(res result) resultVisitor {
  485. // Already failed. Stop looking.
  486. if *cv.err != nil {
  487. return nil
  488. }
  489. path := strings.Join(cv.currentResultPath, ".")
  490. switch r := res.(type) {
  491. case resultSingle:
  492. k := key{name: r.Name, t: r.Type}
  493. if conflict, ok := cv.keyPaths[k]; ok {
  494. *cv.err = errf(
  495. "cannot provide %v from %v", k, path,
  496. "already provided by %v", conflict,
  497. )
  498. return nil
  499. }
  500. if ps := cv.c.providers[k]; len(ps) > 0 {
  501. cons := make([]string, len(ps))
  502. for i, p := range ps {
  503. cons[i] = fmt.Sprint(p.Location())
  504. }
  505. *cv.err = errf(
  506. "cannot provide %v from %v", k, path,
  507. "already provided by %v", strings.Join(cons, "; "),
  508. )
  509. return nil
  510. }
  511. cv.keyPaths[k] = path
  512. case resultGrouped:
  513. // we don't really care about the path for this since conflicts are
  514. // okay for group results. We'll track it for the sake of having a
  515. // value there.
  516. k := key{group: r.Group, t: r.Type}
  517. cv.keyPaths[k] = path
  518. }
  519. return cv
  520. }
  521. // node is a node in the dependency graph. Each node maps to a single
  522. // constructor provided by the user.
  523. //
  524. // Nodes can produce zero or more values that they store into the container.
  525. // For the Provide path, we verify that nodes produce at least one value,
  526. // otherwise the function will never be called.
  527. type node struct {
  528. ctor interface{}
  529. ctype reflect.Type
  530. // Location where this function was defined.
  531. location *digreflect.Func
  532. // id uniquely identifies the constructor that produces a node.
  533. id dot.CtorID
  534. // Whether the constructor owned by this node was already called.
  535. called bool
  536. // Type information about constructor parameters.
  537. paramList paramList
  538. // Type information about constructor results.
  539. resultList resultList
  540. }
  541. type nodeOptions struct {
  542. // If specified, all values produced by this node have the provided name
  543. // or belong to the specified value group
  544. ResultName string
  545. ResultGroup string
  546. }
  547. func newNode(ctor interface{}, opts nodeOptions) (*node, error) {
  548. cval := reflect.ValueOf(ctor)
  549. ctype := cval.Type()
  550. cptr := cval.Pointer()
  551. params, err := newParamList(ctype)
  552. if err != nil {
  553. return nil, err
  554. }
  555. results, err := newResultList(
  556. ctype,
  557. resultOptions{
  558. Name: opts.ResultName,
  559. Group: opts.ResultGroup,
  560. },
  561. )
  562. if err != nil {
  563. return nil, err
  564. }
  565. return &node{
  566. ctor: ctor,
  567. ctype: ctype,
  568. location: digreflect.InspectFunc(ctor),
  569. id: dot.CtorID(cptr),
  570. paramList: params,
  571. resultList: results,
  572. }, err
  573. }
  574. func (n *node) Location() *digreflect.Func { return n.location }
  575. func (n *node) ParamList() paramList { return n.paramList }
  576. func (n *node) ResultList() resultList { return n.resultList }
  577. func (n *node) ID() dot.CtorID { return n.id }
  578. // Call calls this node's constructor if it hasn't already been called and
  579. // injects any values produced by it into the provided container.
  580. func (n *node) Call(c containerStore) error {
  581. if n.called {
  582. return nil
  583. }
  584. if err := shallowCheckDependencies(c, n.paramList); err != nil {
  585. return errMissingDependencies{
  586. Func: n.location,
  587. Reason: err,
  588. }
  589. }
  590. args, err := n.paramList.BuildList(c)
  591. if err != nil {
  592. return errArgumentsFailed{
  593. Func: n.location,
  594. Reason: err,
  595. }
  596. }
  597. receiver := newStagingContainerWriter()
  598. results := c.invoker()(reflect.ValueOf(n.ctor), args)
  599. if err := n.resultList.ExtractList(receiver, results); err != nil {
  600. return errConstructorFailed{Func: n.location, Reason: err}
  601. }
  602. receiver.Commit(c)
  603. n.called = true
  604. return nil
  605. }
  606. // Checks if a field of an In struct is optional.
  607. func isFieldOptional(f reflect.StructField) (bool, error) {
  608. tag := f.Tag.Get(_optionalTag)
  609. if tag == "" {
  610. return false, nil
  611. }
  612. optional, err := strconv.ParseBool(tag)
  613. if err != nil {
  614. err = errf(
  615. "invalid value %q for %q tag on field %v",
  616. tag, _optionalTag, f.Name, err)
  617. }
  618. return optional, err
  619. }
  620. // Checks that all direct dependencies of the provided param are present in
  621. // the container. Returns an error if not.
  622. func shallowCheckDependencies(c containerStore, p param) error {
  623. var err errMissingTypes
  624. var addMissingNodes []*dot.Param
  625. walkParam(p, paramVisitorFunc(func(p param) bool {
  626. ps, ok := p.(paramSingle)
  627. if !ok {
  628. return true
  629. }
  630. if ns := c.getValueProviders(ps.Name, ps.Type); len(ns) == 0 && !ps.Optional {
  631. err = append(err, newErrMissingTypes(c, key{name: ps.Name, t: ps.Type})...)
  632. addMissingNodes = append(addMissingNodes, ps.DotParam()...)
  633. }
  634. return true
  635. }))
  636. if len(err) > 0 {
  637. return err
  638. }
  639. return nil
  640. }
  641. // stagingContainerWriter is a containerWriter that records the changes that
  642. // would be made to a containerWriter and defers them until Commit is called.
  643. type stagingContainerWriter struct {
  644. values map[key]reflect.Value
  645. groups map[key][]reflect.Value
  646. }
  647. var _ containerWriter = (*stagingContainerWriter)(nil)
  648. func newStagingContainerWriter() *stagingContainerWriter {
  649. return &stagingContainerWriter{
  650. values: make(map[key]reflect.Value),
  651. groups: make(map[key][]reflect.Value),
  652. }
  653. }
  654. func (sr *stagingContainerWriter) setValue(name string, t reflect.Type, v reflect.Value) {
  655. sr.values[key{t: t, name: name}] = v
  656. }
  657. func (sr *stagingContainerWriter) submitGroupedValue(group string, t reflect.Type, v reflect.Value) {
  658. k := key{t: t, group: group}
  659. sr.groups[k] = append(sr.groups[k], v)
  660. }
  661. // Commit commits the received results to the provided containerWriter.
  662. func (sr *stagingContainerWriter) Commit(cw containerWriter) {
  663. for k, v := range sr.values {
  664. cw.setValue(k.name, k.t, v)
  665. }
  666. for k, vs := range sr.groups {
  667. for _, v := range vs {
  668. cw.submitGroupedValue(k.group, k.t, v)
  669. }
  670. }
  671. }
  672. type byTypeName []reflect.Type
  673. func (bs byTypeName) Len() int {
  674. return len(bs)
  675. }
  676. func (bs byTypeName) Less(i int, j int) bool {
  677. return fmt.Sprint(bs[i]) < fmt.Sprint(bs[j])
  678. }
  679. func (bs byTypeName) Swap(i int, j int) {
  680. bs[i], bs[j] = bs[j], bs[i]
  681. }
  682. func shuffledCopy(rand *rand.Rand, items []reflect.Value) []reflect.Value {
  683. newItems := make([]reflect.Value, len(items))
  684. for i, j := range rand.Perm(len(items)) {
  685. newItems[i] = items[j]
  686. }
  687. return newItems
  688. }