chore: set depinject to main (#23700)

This commit is contained in:
Tyler 2025-02-14 09:06:40 -08:00 committed by GitHub
parent edcb427a6e
commit 13b450a2ad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
41 changed files with 6757 additions and 501 deletions

37
depinject/CHANGELOG.md Normal file
View File

@ -0,0 +1,37 @@
<!--
Guiding Principles:
Changelogs are for humans, not machines.
There should be an entry for every single version.
The same types of changes should be grouped.
Versions and sections should be linkable.
The latest version comes first.
The release date of each version is displayed.
Mention whether you follow Semantic Versioning.
Usage:
Change log entries are to be added to the Unreleased section from newest to oldest.
Each entry must include the Github issue reference in the following format:
* [#<issue-number>] Changelog message.
-->
# Changelog
## [Unreleased]
## 1.1.0
* [#22438](https://github.com/cosmos/cosmos-sdk/pull/22438) Unexported fields on `In` structs are now silently ignored instead of failing.
## 1.0.0
* [#20540](https://github.com/cosmos/cosmos-sdk/pull/20540) Add support for defining `appconfig` module configuration types using `github.com/cosmos/gogoproto/proto` in addition to `google.golang.org/protobuf` so that users can use gogo proto across their stack.
* Move `cosmossdk.io/core/appconfig` to `cosmossdk.io/depinject/appconfig`.
## 1.0.0-alpha.x
Depinject is still in alpha stage even though its API is already quite stable.
There is no changelog during this stage.

View File

@ -12,15 +12,15 @@ sidebar_position: 1
`depinject` is particularly useful for developing blockchain applications:
* With multiple interdependent components, modules, or services. Helping manage their dependencies effectively.
* That require decoupling of these components, making it easier to test, modify, or replace individual parts without affecting the entire system.
* That are wanting to simplify the setup and initialisation of modules and their dependencies by reducing boilerplate code and automating dependency management.
* With multiple interdependent components, modules, or services. Helping manage their dependencies effectively.
* That require decoupling of these components, making it easier to test, modify, or replace individual parts without affecting the entire system.
* That are wanting to simplify the setup and initialisation of modules and their dependencies by reducing boilerplate code and automating dependency management.
By using `depinject`, developers can achieve:
* Cleaner and more organised code.
* Improved modularity and maintainability.
* A more maintainable and modular structure for their blockchain applications, ultimately enhancing development velocity and code quality.
* Cleaner and more organised code.
* Improved modularity and maintainability.
* A more maintainable and modular structure for their blockchain applications, ultimately enhancing development velocity and code quality.
* [Go Doc](https://pkg.go.dev/cosmossdk.io/depinject)
@ -38,41 +38,44 @@ Example:
package main
import (
"fmt"
"fmt"
"cosmossdk.io/depinject"
"cosmossdk.io/depinject"
)
type AnotherInt int
func main() {
var (
x int
y AnotherInt
)
func GetInt() int { return 1 }
func GetAnotherInt() AnotherInt { return 2 }
fmt.Printf("Before (%v, %v)\n", x, y)
depinject.Inject(
depinject.Provide(
func() int { return 1 },
func() AnotherInt { return AnotherInt(2) },
),
&x,
&y,
)
fmt.Printf("After (%v, %v)\n", x, y)
func main() {
var (
x int
y AnotherInt
)
fmt.Printf("Before (%v, %v)\n", x, y)
depinject.Inject(
depinject.Provide(
GetInt,
GetAnotherInt,
),
&x,
&y,
)
fmt.Printf("After (%v, %v)\n", x, y)
}
```
In this example, `depinject.Provide` registers two provider functions that return `int` and `AnotherInt` values. The `depinject.Inject` function is then used to inject these values into the variables `x` and `y`.
Provider functions serve as the basis for the dependency tree. They are analysed to identify their inputs as dependencies and their outputs as dependents. These dependents can either be used by another provider function or be stored outside the DI container (e.g., `&x` and `&y` in the example above).
Provider functions serve as the basis for the dependency tree. They are analysed to identify their inputs as dependencies and their outputs as dependents. These dependents can either be used by another provider function or be stored outside the DI container (e.g., `&x` and `&y` in the example above). Provider functions must be exported.
### Interface type resolution
`depinject` supports the use of interface types as inputs to provider functions, which helps decouple dependencies between modules. This approach is particularly useful for managing complex systems with multiple modules, such as the Cosmos SDK, where dependencies need to be flexible and maintainable.
For example, `x/bank` expects an [AccountKeeper](https://pkg.go.dev/github.com/cosmos/cosmos-sdk/x/bank/types#AccountKeeper) interface as [input to ProvideModule](https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/x/bank/module.go#L208-L260). `SimApp` uses the implementation in `x/auth`, but the modular design allows for easy changes to the implementation if needed.
For example, `x/bank` expects an [AccountKeeper](https://pkg.go.dev/cosmossdk.io/x/bank/types#AccountKeeper) interface as [input to ProvideModule](https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/x/bank/module.go#L208-L260). `SimApp` uses the implementation in `x/auth`, but the modular design allows for easy changes to the implementation if needed.
Consider the following example:
@ -80,11 +83,11 @@ Consider the following example:
package duck
type Duck interface {
quack()
quack()
}
type AlsoDuck interface {
quack()
quack()
}
type Mallard struct{}
@ -94,7 +97,23 @@ func (duck Mallard) quack() {}
func (duck Canvasback) quack() {}
type Pond struct {
Duck AlsoDuck
Duck AlsoDuck
}
```
And the following provider functions:
```go
func GetMallard() duck.Mallard {
return Mallard{}
}
func GetPond(duck Duck) Pond {
return Pond{Duck: duck}
}
func GetCanvasback() Canvasback {
return Canvasback{}
}
```
@ -105,10 +124,9 @@ var pond Pond
depinject.Inject(
depinject.Provide(
func() Mallard { return Mallard{} },
func(duck Duck) Pond {
return Pond{Duck: duck}
}),
GetMallard,
GetPond,
),
&pond)
```
@ -120,13 +138,12 @@ However, if there are multiple implementations of the `Duck` interface, as in th
var pond Pond
depinject.Inject(
depinject.Provide(
func() Mallard { return Mallard{} },
func() Canvasback { return Canvasback{} },
func(duck Duck) Pond {
return Pond{Duck: duck}
}),
&pond)
depinject.Provide(
GetMallard,
GetCanvasback,
GetPond,
),
&pond)
```
A specific binding preference for `Duck` is required.
@ -137,20 +154,21 @@ In the above situation registering a binding for a given interface binding may l
```go
depinject.Inject(
depinject.Configs(
depinject.BindInterface(
"duck.Duck",
"duck.Mallard"),
depinject.Provide(
func() Mallard { return Mallard{} },
func() Canvasback { return Canvasback{} },
func(duck Duck) APond {
return Pond{Duck: duck}
})),
&pond)
depinject.Configs(
depinject.BindInterface(
"duck/duck.Duck",
"duck/duck.Mallard",
),
depinject.Provide(
GetMallard,
GetCanvasback,
GetPond,
),
),
&pond)
```
Now `depinject` has enough information to provide `Mallard` as an input to `APond`.
Now `depinject` has enough information to provide `Mallard` as an input to `APond`.
### Full example in real app
@ -159,7 +177,7 @@ When using `depinject.Inject`, the injected types must be pointers.
:::
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/simapp/app_v2.go#L219-L244
https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/simapp/app_di.go#L187-L206
```
## Debugging

View File

@ -0,0 +1,232 @@
# Wiring up app modules for use with appconfig
The `appconfig` framework allows Cosmos SDK modules to be composed declaratively using a configuration file without
requiring the app developer to understand the details of inter-module dependencies.
## 1. Create a module config protobuf message
The first step in creating a module that works with `appconfig`, is to create a protobuf message for the module configuration. The best practices for defining the module configuration message are:
* Use a dedicated protobuf package for the module configuration message instead of placing it in the API protobuf package. For example, the module configuration for bank would go in `cosmos.bank.module.v1` instead of just `cosmos.bank.v1`. This decouples the state machine version from the API version.
* The module configuration message is usually called simply `Module`, ex. `cosmos.bank.module.v1.Module`.
* Create a new protobuf package and configuration message for each state machine breaking version of the module, ex. `cosmos.bank.module.v2.Module`, etc.
The module configuration message should include any parameters which should be initialized at application startup. For example, the auth module needs to know the bech32 prefix of the app and the permissions of module accounts.
In the future, it may be possible to update the app config through a governance proposal at runtime.
All module configuration messages should define a module descriptor, using the `cosmos.app.v1alpha1.module` message option.
Here is an example module configuration message for the `auth` module:
```protobuf
package cosmos.auth.module.v1;
import "cosmos/app/v1alpha1/module.proto";
message Module {
option (cosmos.app.v1alpha1.module) = {
go_import: "github.com/cosmos/cosmos-sdk/x/auth"
};
string bech32_prefix = 1;
repeated ModuleAccountPermission module_account_permissions = 2;
}
```
## 2. Register module depinject providers and invokers
Once we have a module config object, we need to register depinject providers and invokers for the module using the `cosmossdk.io/core/appmodule` package.
At the most basic level, we must define an `init` function in the package listed as the `go_import` in the module descriptor. This `init` function must call `appconfig.RegisterModule` with an empty instance of the config object and some options for initializing the module, ex:
```go
func init() {
appconfig.RegisterModule(&modulev1.Module{},
// options
)
}
```
### `depinject` Provider and Invoker Basics
A `depinject` "provider" is a function which takes dependencies from other modules as inputs and returns outputs for
other modules to use as dependencies. A `depinject` "invoker" is function which takes optional dependencies as inputs,
returns no outputs, and is run at the end of initializing the dependency graph. Providers are much more common than
invokers and should be the preferred method of wiring up modules when possible. Providers and invokers can be registered
for modules by using `appconfig.Provide` and `appconfig.Invoke` to create options which get passed
to `appconfig.RegisterModule` in the module `init` function, ex:
```go
func init() {
appconfig.RegisterModule(&modulev1.Module{},
appconfig.Provide(provideSomething, provideSomethingElse),
appconfig.Invoke(invokeSomething),
)
}
```
### `depinject` Types
`depinject` constructor functions support these classes of input and output parameter types:
* regular golang types (with special treatment of interface types as input parameters)
* structs with `depinject.In` and `depinject.Out` embedded
* `depinject.OnePerModuleType`s
* `depinject.ManyPerContainerType`s
* `depinject.ModuleKey` (which can only be defined as an input type)
* `error` (which gets special treatment as an output type)
#### Regular Golang Types
Regular golang types (besides the special cases described above) can be provided as both input and output parameters
to providers and invokers. For `depinject` to match an output parameter of one provider to an input parameter of
another, there must be an exact match for the type unless the input parameter is an input type. For instance, if
a provider defines a dependency on `Foo` and some module provides `*Foo`, these two types will not match and there
will be an error.
#### Interface Input Types
When interfaces are used as input parameters to providers and invokers, `depinject` will search the container for
all types that implement this interface. If there is an unambiguously matching type, then this type will be used
to satisfy that interface. If there is a conflict between two types matching the interface, the app developer
can use `golang_bindings` options in their app config in order to resolve the conflict.
#### Structs with embedded `depinject.In` and `depinject.Out`
Structs that have `depinject.In` or `depinject.Out` as an embedded field are treated specially by `depinject`, where
all of these structs fields are treated as input or output parameters, respectively. These structs allow custom options
to be defined using struct field tags. Currently, the only supported custom option is `optional:"true"` which marks
a field as optional.
#### `depinject.OnePerModuleType`s
Any type which implements the `depinject.OnePerModuleType` interface can be provided at most once by every module.
These types can be collected as an input parameter to some provider or invoker by defining an input parameter which
is a map of module names as strings to this parameter type. For example if `Foo` is a `OnePerModuleType`, then
`map[string]Foo` can be declared as an input parameter by some provider (which obviously cannot provide an instance of
`Foo` itself because that would cause a circular dependency).
`OnePerModuleType`s should be used whenever different modules may provide the type *and* there is a need to provide
an ordering of these types based on the module name. Generally, in blockchains there is always a need for deterministic
orderings so using module names to provide that ordering is generally a good strategy for this use case. Ordering based
on module names can either be done implicitly by sorting the module names or explicitly as a parameter in the module
configuration object.
#### `depinject.ManyPerContainerType`s
`ManyPerContainerType`s can be provided by as many providers in as many modules as the user would like. If a type `Bar`
is a `ManyPerContainerType`, a provider may define an output parameter of `Bar` or `[]Bar` to provide `Bar` instances
to the container. A provider may define an input parameter of `[]Bar` to get all of the `Bar` instances in the
container (such a provider may not also return `Bar` as that would cause a circular dependency). The ordering of `Bar`
instances in the `[]Bar` input type should be assumed to be deterministic.
`ManyPerContainerType`s should be used only when 1) ordering is unimportant or 2) the ordering can be defined by
some parameter on the type. For instance, if `Bar` had a field `Name string`, that is supposed to be unique in the
container then that could be used to provide an ordering. An example of a type that could work as a
`ManyPerContainerType` in this way is a wrapper around `*cobra.Command`, ex.
`type QueryCommand struct {*cobra.Command}`. This could be used to collect all the query commands in an app and then
cobra would take care of ordering. If this type of ordering is not available, a `OnePerModuleType` is probably a better
bet.
#### Module-scoped Providers/`depinject.ModuleKey` as an input
If `depinject.ModuleKey` is used as input parameter for a provider, the provider function will be treated as a
"module-scoped provider" which means that the provider function will be called exactly once every time
one of its outputs is needed by a module so that the provider can provide a unique instance of the dependency to
each module.
Module-scoped dependencies should be used to provide dependencies which are private and unique to each module. Examples
of these are store keys and param subspaces.
#### `error` as an output parameter
`error` can be used as the last output parameter on any provider or invoker. If a provider or invoker with an `error`
parameter returns a non-nil value for `error`, `depinject` will fail and propagate this error up to the caller.
### Provider Invocation Details
Providers are called lazily as they are needed and will be invoked at most once (except for "module-scoped providers"
described above) if and only if at least one of their outputs is needed somewhere in the dependency graph. Providers
will only get called if all of their non-optional inputs can successfully be resolved by some other module, otherwise an
error will occur. Modules should proactively mark dependencies as `optional` if the module can still be successfully
built without this dependency.
### Invoker Invocation Details
Invokers are called at the end of container initialization after all providers that were needed to build the graph
were called. All the dependencies of invokers are automatically marked as optional so invokers should `nil` check
every input parameter. Invokers may cause additional providers to get run if they have a dependency that wasn't built
yet. But if a dependency to an invoker cannot be provided for some reason, the invoker will still get called but with
`nil` for that input. This allows invokers to still work with the lazy invocation model of providers which only
builds things which are actually necessary as a dependency for some module or the caller.
Invokers should generally be used sparingly to perform some initialization logic which can't be done in the initial
provider, usually because of a circular dependency, and which may be optional.
### Best practices
* make dependencies `optional` whenever possible!
* interface types should be used whenever possible to avoid tight couplings between two modules.
* `OnePerModuleType`s should be used when there is something occurs at most once per module and the module name is a
convenient way for providing a deterministic order.
* `ManyPerContainerType`s should be used only when there is an obvious way to create an ordering from the types or
when ordering *really* doesn't matter (which is rare).
* module-scoped providers should be used for private, module-scoped dependencies
* use different providers for unrelated or loosely components or to resolve circular dependencies (see below)
* use invokers sparingly and always `nil`-check the inputs.
### Resolving Circular Dependencies
Circular dependencies are inevitable to crop up and there are ways to avoid them. While `depinject` cannot handle
circular dependency graphs of providers, many of the above tools are designed to enable satisfying circular dependencies
between modules.
One of the key tactics for resolving circular dependencies is to use different providers and/or invokers to allow a
circular dependency between components. For example, say the slashing keeper depends on the keeper module but the
staking keeper also depends on the staking module indirectly (in the form of "staking hooks"). The slashing module
can declare a dependency directly on the staking keeper (using an interface to avoid actually importing the staking
keeper package). It can also provide an instance of the slashing keeper wrapped as staking hooks in a `OnePerModuleType`
we'll call `StakingHooksWrapper`. Now, if the staking module directly depended on the staking hooks wrappers
(`map[string]StakingHooksWrapper`) we would have a circular dependency graph and `depinject` would fail. To fix this,
the staking module can define an invoker which depends on `map[string]StakingHooksWrapper` and the staking keeper
(which was provided by the staking module already in a separate provided). In this way `depinject` will be able to
satisfy this dependency graph which allows staking and slashing to depend on each other in this order:
* provide staking keeper -> slashing keeper
* provide slashing keeper wrapped as `StakingHooksWrapper`
* get `map[string]StakingHooksWrapper` and the staking keeper and wire them together
## 3. Testing and Debugging The Module
In order to test and debug the module configuration, we need to build an app config, generally defined in a YAML file.
This configuration should be passed first to `appconfig.LoadYAML` to get an `depinject.Config` instance.Then the
`depinject.Config` can be passed to `depinject.Inject` and we can try to resolve dependencies in the app config.
Alternatively, the `depinject.Config` can be created via [pure Go code](https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/simapp/app_config.go).
Ex:
```go
//go:embed app.yaml
var appConfig []byte
var AppConfig = appconfig.LoadYAML(appConfig)
func TestModule(t *testing.T) {
var keeper Keeper
assert.NilError(t, depinject.Inject(AppConfig, &keeper))
}
```
### Debugging `depinject` Graphs
Whenever there is an error in a `depinject` graph, by default `depinject` will dump a bunch of logging output to the
console, print the error message, and save the dependency graph in [GraphViz](https://graphviz.org) DOT format to
the file `debug_container.dot`. Inspecting the GraphViz output by converting it to an SVG and viewing it in a web
browser or using some other GraphViz tool is *highly recommended*.
If `depinject` does not return an error but there is still some weird issue wiring up modules, inspecting the GraphViz
and logging output is still *highly recommended* and can be done using `depinject.InjectDebug` with the debug option
`depinject.Debug`.
App developers should attempt to familiarize themselves with the GraphViz graph of their app to see which modules
depend on which other modules.

View File

@ -0,0 +1,173 @@
package appconfig
import (
"errors"
"fmt"
"reflect"
"strings"
gogoproto "github.com/cosmos/gogoproto/proto"
"google.golang.org/protobuf/encoding/protojson"
protov2 "google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/types/dynamicpb"
"google.golang.org/protobuf/types/known/anypb"
"sigs.k8s.io/yaml"
"cosmossdk.io/depinject"
"cosmossdk.io/depinject/appconfig/v1alpha1"
internal "cosmossdk.io/depinject/internal/appconfig"
)
// LoadJSON loads an app config in JSON format.
func LoadJSON(bz []byte) depinject.Config {
// in order to avoid a direct dependency on api types, but in order to also be able to support
// either gogo or google.golang.org/protobuf types, we use protojson and dynamicpb to unmarshal
// from JSON
resolver := gogoproto.HybridResolver
desc, err := resolver.FindDescriptorByName(protoreflect.FullName(gogoproto.MessageName(&v1alpha1.Config{})))
if err != nil {
return depinject.Error(err)
}
config := dynamicpb.NewMessage(desc.(protoreflect.MessageDescriptor))
err = protojson.UnmarshalOptions{
Resolver: dynamicTypeResolver{resolver: gogoproto.HybridResolver},
}.Unmarshal(bz, config)
if err != nil {
return depinject.Error(err)
}
return Compose(config)
}
// LoadYAML loads an app config in YAML format.
func LoadYAML(bz []byte) depinject.Config {
j, err := yaml.YAMLToJSON(bz)
if err != nil {
return depinject.Error(err)
}
return LoadJSON(j)
}
// WrapAny marshals a proto message into a proto Any instance
func WrapAny(config gogoproto.Message) *anypb.Any {
pbz, err := gogoproto.Marshal(config)
if err != nil {
panic(err)
}
return &anypb.Any{
TypeUrl: "/" + gogoproto.MessageName(config),
Value: pbz,
}
}
// Compose composes an app config into a container option by resolving
// the required modules and composing their options. appConfig should be an instance
// of cosmos.app.v1alpha1.Config (it doesn't matter whether you use gogo proto or
// google.golang.org/protobuf types).
func Compose(appConfig gogoproto.Message) depinject.Config {
appConfigConcrete, ok := appConfig.(*v1alpha1.Config)
if !ok {
// we convert any other proto type that was passed (such as an api module type) to the concrete
// type we're using here
appConfigConcrete = &v1alpha1.Config{}
bz, err := gogoproto.Marshal(appConfig)
if err != nil {
return depinject.Error(err)
}
err = gogoproto.Unmarshal(bz, appConfigConcrete)
if err != nil {
return depinject.Error(err)
}
}
opts := []depinject.Config{
depinject.Supply(appConfig),
}
modules, err := internal.ModulesByModuleTypeName()
if err != nil {
return depinject.Error(err)
}
for _, module := range appConfigConcrete.Modules {
if module.Name == "" {
return depinject.Error(errors.New("module is missing name"))
}
if module.Config == nil {
return depinject.Error(fmt.Errorf("module %q is missing a config object", module.Name))
}
msgName := module.Config.TypeUrl
// strip type URL prefix
if slashIdx := strings.LastIndex(msgName, "/"); slashIdx >= 0 {
msgName = msgName[slashIdx+1:]
}
if msgName == "" {
return depinject.Error(fmt.Errorf("module %q is missing a type URL", module.Name))
}
init, ok := modules[msgName]
if !ok {
if msgDesc, err := gogoproto.HybridResolver.FindDescriptorByName(protoreflect.FullName(msgName)); err == nil {
modDesc, err := internal.GetModuleDescriptor(msgDesc)
if err != nil {
return depinject.Error(err)
}
if modDesc == nil {
return depinject.Error(fmt.Errorf("no module registered for type URL %s and that protobuf type does not have the option %s\n\n%s",
module.Config.TypeUrl, v1alpha1.E_Module.Name, dumpRegisteredModules(modules)))
}
return depinject.Error(fmt.Errorf("no module registered for type URL %s, did you forget to import %s: find more information on how to make a module ready for app wiring: https://docs.cosmos.network/main/building-modules/depinject\n\n%s",
module.Config.TypeUrl, modDesc.GoImport, dumpRegisteredModules(modules)))
}
}
var config gogoproto.Message
if configInit, ok := init.ConfigProtoMessage.(protov2.Message); ok {
config = configInit.ProtoReflect().Type().New().Interface().(gogoproto.Message)
} else {
config = reflect.New(init.ConfigGoType.Elem()).Interface().(gogoproto.Message)
}
// as of gogo v1.5.0 this should work with either gogoproto or golang v2 proto
err = gogoproto.Unmarshal(module.Config.Value, config)
if err != nil {
return depinject.Error(err)
}
opts = append(opts, depinject.Supply(config))
for _, provider := range init.Providers {
opts = append(opts, depinject.ProvideInModule(module.Name, provider))
}
for _, invoker := range init.Invokers {
opts = append(opts, depinject.InvokeInModule(module.Name, invoker))
}
for _, binding := range module.GolangBindings {
opts = append(opts, depinject.BindInterfaceInModule(module.Name, binding.InterfaceType, binding.Implementation))
}
}
for _, binding := range appConfigConcrete.GolangBindings {
opts = append(opts, depinject.BindInterface(binding.InterfaceType, binding.Implementation))
}
return depinject.Configs(opts...)
}
func dumpRegisteredModules(modules map[string]*internal.ModuleInitializer) string {
var mods []string
for name := range modules {
mods = append(mods, " "+name)
}
return fmt.Sprintf("registered modules are:\n%s", strings.Join(mods, "\n"))
}

View File

@ -0,0 +1,244 @@
package appconfig_test
import (
"bytes"
"fmt"
"io"
"reflect"
"sort"
"testing"
"gotest.tools/v3/assert"
"cosmossdk.io/depinject"
"cosmossdk.io/depinject/appconfig"
internal "cosmossdk.io/depinject/internal/appconfig"
"cosmossdk.io/depinject/internal/appconfig/testpb"
testpbgogo "cosmossdk.io/depinject/internal/appconfiggogo/testpb"
)
func expectContainerErrorContains(t *testing.T, option depinject.Config, contains string) {
t.Helper()
err := depinject.Inject(option)
assert.ErrorContains(t, err, contains)
}
func TestCompose(t *testing.T) {
opt := appconfig.LoadJSON([]byte(`{"modules":[{}]}`))
expectContainerErrorContains(t, opt, "module is missing name")
opt = appconfig.LoadJSON([]byte(`{"modules":[{"name": "a"}]}`))
expectContainerErrorContains(t, opt, `module "a" is missing a config object`)
opt = appconfig.LoadYAML([]byte(`
modules:
- name: a
config:
"@type": testpb.ModuleFoo
`))
expectContainerErrorContains(t, opt, `unable to resolve`)
opt = appconfig.LoadYAML([]byte(`
modules:
- name: a
config:
"@type": cosmos.app.v1alpha1.Config # this is not actually a module config type!
`))
expectContainerErrorContains(t, opt, "does not have the option cosmos.app.v1alpha1.module")
expectContainerErrorContains(t, opt, "registered modules are")
expectContainerErrorContains(t, opt, "testpb.TestModuleA")
opt = appconfig.LoadYAML([]byte(`
modules:
- name: a
config:
"@type": testpb.TestUnregisteredModule
`))
expectContainerErrorContains(t, opt, "did you forget to import cosmossdk.io/core/internal/testpb")
expectContainerErrorContains(t, opt, "registered modules are")
expectContainerErrorContains(t, opt, "testpb.TestModuleA")
var app App
opt = appconfig.LoadYAML([]byte(`
modules:
- name: runtime
config:
"@type": testpb.TestRuntimeModule
- name: a
config:
"@type": testpb.TestModuleA
- name: b
config:
"@type": /testpb.TestModuleB
- name: c
config:
"@type": /testpb.TestModuleGogo
`))
assert.NilError(t, depinject.Inject(opt, &app))
buf := &bytes.Buffer{}
app(buf)
const expected = `got store key a
got store key b
running module handler a
result: hello
running module handler b
result: goodbye
`
assert.Equal(t, expected, buf.String())
opt = appconfig.LoadYAML([]byte(`
golang_bindings:
- interfaceType: interfaceType/package.name
implementation: implementationType/package.name
- interfaceType: interfaceType/package.nameTwo
implementation: implementationType/package.nameTwo
modules:
- name: a
config:
"@type": testpb.TestModuleA
golang_bindings:
- interfaceType: interfaceType/package.name
implementation: implementationType/package.name
- interfaceType: interfaceType/package.nameTwo
implementation: implementationType/package.nameTwo
`))
assert.NilError(t, depinject.Inject(opt))
// module registration failures:
appconfig.RegisterModule(&testpb.TestNoModuleOptionModule{})
opt = appconfig.LoadYAML([]byte(`
modules:
- name: a
config:
"@type": testpb.TestNoGoImportModule
`))
expectContainerErrorContains(t, opt, "module should have the option cosmos.app.v1alpha1.module")
internal.ModuleRegistry = map[reflect.Type]*internal.ModuleInitializer{} // reset module registry
appconfig.RegisterModule(&testpb.TestNoGoImportModule{})
opt = appconfig.LoadYAML([]byte(`
modules:
- name: a
config:
"@type": testpb.TestNoGoImportModule
`))
expectContainerErrorContains(t, opt, "module should have ModuleDescriptor.go_import specified")
}
//
// Test Module Initialization Logic
//
func init() {
appconfig.RegisterModule(&testpb.TestRuntimeModule{},
appconfig.Provide(ProvideRuntimeState, ProvideStoreKey, ProvideApp),
)
appconfig.RegisterModule(&testpb.TestModuleA{},
appconfig.Provide(ProvideModuleA),
)
appconfig.RegisterModule(&testpb.TestModuleB{},
appconfig.Provide(ProvideModuleB),
)
appconfig.RegisterModule(&testpbgogo.TestModuleGogo{},
appconfig.Provide(ProvideModuleC),
)
}
func ProvideRuntimeState() *RuntimeState {
return &RuntimeState{}
}
func ProvideStoreKey(key depinject.ModuleKey, state *RuntimeState) StoreKey {
sk := StoreKey{name: key.Name()}
state.storeKeys = append(state.storeKeys, sk)
return sk
}
func ProvideApp(state *RuntimeState, handlers map[string]Handler) App {
return func(w io.Writer) {
sort.Slice(state.storeKeys, func(i, j int) bool {
return state.storeKeys[i].name < state.storeKeys[j].name
})
for _, key := range state.storeKeys {
_, _ = fmt.Fprintf(w, "got store key %s\n", key.name)
}
var modNames []string
for modName := range handlers {
modNames = append(modNames, modName)
}
sort.Strings(modNames)
for _, name := range modNames {
_, _ = fmt.Fprintf(w, "running module handler %s\n", name)
_, _ = fmt.Fprintf(w, "result: %s\n", handlers[name].DoSomething())
}
}
}
type App func(writer io.Writer)
type RuntimeState struct {
storeKeys []StoreKey
}
type StoreKey struct{ name string }
type Handler struct {
DoSomething func() string
}
func (h Handler) IsOnePerModuleType() {}
func ProvideModuleA(key StoreKey) (KeeperA, Handler) {
return keeperA{key: key}, Handler{DoSomething: func() string {
return "hello"
}}
}
type keeperA struct {
key StoreKey
}
type KeeperA interface {
Foo()
}
func (k keeperA) Foo() {}
func ProvideModuleB(key StoreKey, a KeeperA) (KeeperB, Handler) {
return keeperB{key: key, a: a}, Handler{
DoSomething: func() string {
return "goodbye"
},
}
}
type keeperB struct {
key StoreKey
a KeeperA
}
type KeeperB interface {
isKeeperB()
}
func (k keeperB) isKeeperB() {}
func ProvideModuleC(key StoreKey, b KeeperB) KeeperC {
return keeperC{key: key}
}
type keeperC struct {
key StoreKey
}
type KeeperC interface {
isKeeperC()
}
func (k keeperC) isKeeperC() {}

View File

@ -0,0 +1,3 @@
// Package appconfig defines functionality for loading declarative Cosmos SDK
// app configurations.
package appconfig

View File

@ -0,0 +1,82 @@
package appconfig
import (
"strings"
"google.golang.org/protobuf/reflect/protodesc"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry"
"google.golang.org/protobuf/types/dynamicpb"
)
// dynamic resolver allows marshaling gogo proto messages from the gogoproto.HybridResolver as long as those
// files have been imported before calling LoadJSON. There is similar code in autocli, this should probably
// eventually be moved into a library.
type dynamicTypeResolver struct {
resolver protodesc.Resolver
}
func (r dynamicTypeResolver) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) {
ext, err := protoregistry.GlobalTypes.FindExtensionByName(field)
if err == nil {
return ext, nil
}
desc, err := r.resolver.FindDescriptorByName(field)
if err != nil {
return nil, err
}
return dynamicpb.NewExtensionType(desc.(protoreflect.ExtensionTypeDescriptor)), nil
}
func (r dynamicTypeResolver) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) {
ext, err := protoregistry.GlobalTypes.FindExtensionByNumber(message, field)
if err == nil {
return ext, nil
}
desc, err := r.resolver.FindDescriptorByName(message)
if err != nil {
return nil, err
}
messageDesc := desc.(protoreflect.MessageDescriptor)
exts := messageDesc.Extensions()
n := exts.Len()
for i := 0; i < n; i++ {
ext := exts.Get(i)
if ext.Number() == field {
return dynamicpb.NewExtensionType(ext), nil
}
}
return nil, protoregistry.NotFound
}
func (r dynamicTypeResolver) FindMessageByName(message protoreflect.FullName) (protoreflect.MessageType, error) {
typ, err := protoregistry.GlobalTypes.FindMessageByName(message)
if err == nil {
return typ, nil
}
desc, err := r.resolver.FindDescriptorByName(message)
if err != nil {
return nil, err
}
return dynamicpb.NewMessageType(desc.(protoreflect.MessageDescriptor)), nil
}
func (r dynamicTypeResolver) FindMessageByURL(url string) (protoreflect.MessageType, error) {
if i := strings.LastIndexByte(url, '/'); i >= 0 {
url = url[i+1:]
}
return r.FindMessageByName(protoreflect.FullName(url))
}
var (
_ protoregistry.MessageTypeResolver = dynamicTypeResolver{}
_ protoregistry.ExtensionTypeResolver = dynamicTypeResolver{}
)

View File

@ -0,0 +1,106 @@
package appconfig
import (
"fmt"
"reflect"
"github.com/cosmos/gogoproto/proto"
internal "cosmossdk.io/depinject/internal/appconfig"
)
var Register = RegisterModule
// RegisterModule registers a module with the global module registry. The provided
// protobuf message is used only to uniquely identify the protobuf module config
// type. The instance of the protobuf message used in the actual configuration
// will be injected into the container and can be requested by a provider
// function. All module initialization should be handled by the provided options.
//
// Config is a protobuf message type. It should define the cosmos.app.v1alpha.module
// option and must explicitly specify go_packageto make debugging easier for users.
//
// If you want to customize an existing module, you need to overwrite by calling
// RegisterModule again with the same config (proto API type) and new Provide or
// Invoke options. Example:
//
// - Create a new struct and wrap the existing module inside it:
//
// type MyBankAppModule struct {
// bank.AppModule // core bank module
// // additional helper fields
// cdc codec.Codec
// }
//
// - Overwrite function that you want to customize (eg DefaultGenesis).
// - Create a new Provide function (to provide new Module implementation for the proto module):
//
// func ProvideBankModule(in bank.ModuleInputs) BankModuleOutputs {
// // original provider that initializes the bank keeper
// pm := bank.ProvideModule(in)
// m := NewMyBankAppModule(in.Cdc, pm.BankKeeper, in.AccountKeeper)
// return BankModuleOutputs{
// BankKeeper: pm.BankKeeper,
// Module: m,
// }
// }
//
// - Re-register the bank module by using the original proto api module, and the new provider:
//
// appconfig.RegisterModule(
// &bankmodulev1.Module{}, // from cosmossdk.io/api/cosmos/bank/module/v1
// appconfig.Provide(ProvideBankModule),
// appconfig.Invoke(bank.InvokeSetSendRestrictions),
// )
func RegisterModule(config any, options ...Option) {
protoConfig, ok := config.(proto.Message)
if !ok {
panic(fmt.Errorf("expected config to be a proto.Message, got %T", config))
}
ty := reflect.TypeOf(config)
init := &internal.ModuleInitializer{
ConfigProtoMessage: protoConfig,
ConfigGoType: ty,
}
internal.ModuleRegistry[ty] = init
for _, option := range options {
init.Error = option.apply(init)
if init.Error != nil {
return
}
}
}
// Option is a functional option for implementing modules.
type Option interface {
apply(*internal.ModuleInitializer) error
}
type funcOption func(initializer *internal.ModuleInitializer) error
func (f funcOption) apply(initializer *internal.ModuleInitializer) error {
return f(initializer)
}
// Provide registers providers with the dependency injection system that will be
// run within the module scope (depinject.ProvideInModule). See cosmossdk.io/depinject for
// documentation on the dependency injection system.
func Provide(providers ...interface{}) Option {
return funcOption(func(initializer *internal.ModuleInitializer) error {
initializer.Providers = append(initializer.Providers, providers...)
return nil
})
}
// Invoke registers invokers to run with depinject (depinject.InvokeInModule). Each invoker will be called
// at the end of dependency graph configuration in the order in which it was defined. Invokers may not define output
// parameters, although they may return an error, and all of their input parameters will be marked as optional so that
// invokers impose no additional constraints on the dependency graph. Invoker functions should nil-check all inputs.
func Invoke(invokers ...interface{}) Option {
return funcOption(func(initializer *internal.ModuleInitializer) error {
initializer.Invokers = append(initializer.Invokers, invokers...)
return nil
})
}

View File

@ -0,0 +1,942 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: cosmos/app/v1alpha1/config.proto
package v1alpha1
import (
fmt "fmt"
proto "github.com/cosmos/gogoproto/proto"
any "github.com/cosmos/gogoproto/types/any"
io "io"
math "math"
math_bits "math/bits"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
// Config represents the configuration for a Cosmos SDK ABCI app.
// It is intended that all state machine logic including the version of
// baseapp and tx handlers (and possibly even Tendermint) that an app needs
// can be described in a config object. For compatibility, the framework should
// allow a mixture of declarative and imperative app wiring, however, apps
// that strive for the maximum ease of maintainability should be able to describe
// their state machine with a config object alone.
type Config struct {
// modules are the module configurations for the app.
Modules []*ModuleConfig `protobuf:"bytes,1,rep,name=modules,proto3" json:"modules,omitempty"`
// golang_bindings specifies explicit interface to implementation type bindings which
// depinject uses to resolve interface inputs to provider functions. The scope of this
// field's configuration is global (not module specific).
GolangBindings []*GolangBinding `protobuf:"bytes,2,rep,name=golang_bindings,json=golangBindings,proto3" json:"golang_bindings,omitempty"`
}
func (m *Config) Reset() { *m = Config{} }
func (m *Config) String() string { return proto.CompactTextString(m) }
func (*Config) ProtoMessage() {}
func (*Config) Descriptor() ([]byte, []int) {
return fileDescriptor_5af1d229673256fa, []int{0}
}
func (m *Config) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *Config) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_Config.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *Config) XXX_Merge(src proto.Message) {
xxx_messageInfo_Config.Merge(m, src)
}
func (m *Config) XXX_Size() int {
return m.Size()
}
func (m *Config) XXX_DiscardUnknown() {
xxx_messageInfo_Config.DiscardUnknown(m)
}
var xxx_messageInfo_Config proto.InternalMessageInfo
func (m *Config) GetModules() []*ModuleConfig {
if m != nil {
return m.Modules
}
return nil
}
func (m *Config) GetGolangBindings() []*GolangBinding {
if m != nil {
return m.GolangBindings
}
return nil
}
// ModuleConfig is a module configuration for an app.
type ModuleConfig struct {
// name is the unique name of the module within the app. It should be a name
// that persists between different versions of a module so that modules
// can be smoothly upgraded to new versions.
//
// For example, for the module cosmos.bank.module.v1.Module, we may chose
// to simply name the module "bank" in the app. When we upgrade to
// cosmos.bank.module.v2.Module, the app-specific name "bank" stays the same
// and the framework knows that the v2 module should receive all the same state
// that the v1 module had. Note: modules should provide info on which versions
// they can migrate from in the ModuleDescriptor.can_migration_from field.
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
// config is the config object for the module. Module config messages should
// define a ModuleDescriptor using the cosmos.app.v1alpha1.is_module extension.
Config *any.Any `protobuf:"bytes,2,opt,name=config,proto3" json:"config,omitempty"`
// golang_bindings specifies explicit interface to implementation type bindings which
// depinject uses to resolve interface inputs to provider functions. The scope of this
// field's configuration is module specific.
GolangBindings []*GolangBinding `protobuf:"bytes,3,rep,name=golang_bindings,json=golangBindings,proto3" json:"golang_bindings,omitempty"`
}
func (m *ModuleConfig) Reset() { *m = ModuleConfig{} }
func (m *ModuleConfig) String() string { return proto.CompactTextString(m) }
func (*ModuleConfig) ProtoMessage() {}
func (*ModuleConfig) Descriptor() ([]byte, []int) {
return fileDescriptor_5af1d229673256fa, []int{1}
}
func (m *ModuleConfig) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *ModuleConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_ModuleConfig.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *ModuleConfig) XXX_Merge(src proto.Message) {
xxx_messageInfo_ModuleConfig.Merge(m, src)
}
func (m *ModuleConfig) XXX_Size() int {
return m.Size()
}
func (m *ModuleConfig) XXX_DiscardUnknown() {
xxx_messageInfo_ModuleConfig.DiscardUnknown(m)
}
var xxx_messageInfo_ModuleConfig proto.InternalMessageInfo
func (m *ModuleConfig) GetName() string {
if m != nil {
return m.Name
}
return ""
}
func (m *ModuleConfig) GetConfig() *any.Any {
if m != nil {
return m.Config
}
return nil
}
func (m *ModuleConfig) GetGolangBindings() []*GolangBinding {
if m != nil {
return m.GolangBindings
}
return nil
}
// GolangBinding is an explicit interface type to implementing type binding for dependency injection.
type GolangBinding struct {
// interface_type is the interface type which will be bound to a specific implementation type
InterfaceType string `protobuf:"bytes,1,opt,name=interface_type,json=interfaceType,proto3" json:"interface_type,omitempty"`
// implementation is the implementing type which will be supplied when an input of type interface is requested
Implementation string `protobuf:"bytes,2,opt,name=implementation,proto3" json:"implementation,omitempty"`
}
func (m *GolangBinding) Reset() { *m = GolangBinding{} }
func (m *GolangBinding) String() string { return proto.CompactTextString(m) }
func (*GolangBinding) ProtoMessage() {}
func (*GolangBinding) Descriptor() ([]byte, []int) {
return fileDescriptor_5af1d229673256fa, []int{2}
}
func (m *GolangBinding) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *GolangBinding) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_GolangBinding.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *GolangBinding) XXX_Merge(src proto.Message) {
xxx_messageInfo_GolangBinding.Merge(m, src)
}
func (m *GolangBinding) XXX_Size() int {
return m.Size()
}
func (m *GolangBinding) XXX_DiscardUnknown() {
xxx_messageInfo_GolangBinding.DiscardUnknown(m)
}
var xxx_messageInfo_GolangBinding proto.InternalMessageInfo
func (m *GolangBinding) GetInterfaceType() string {
if m != nil {
return m.InterfaceType
}
return ""
}
func (m *GolangBinding) GetImplementation() string {
if m != nil {
return m.Implementation
}
return ""
}
func init() {
proto.RegisterType((*Config)(nil), "cosmos.app.v1alpha1.Config")
proto.RegisterType((*ModuleConfig)(nil), "cosmos.app.v1alpha1.ModuleConfig")
proto.RegisterType((*GolangBinding)(nil), "cosmos.app.v1alpha1.GolangBinding")
}
func init() { proto.RegisterFile("cosmos/app/v1alpha1/config.proto", fileDescriptor_5af1d229673256fa) }
var fileDescriptor_5af1d229673256fa = []byte{
// 333 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x92, 0x31, 0x4f, 0x02, 0x31,
0x1c, 0xc5, 0x29, 0x18, 0x0c, 0x45, 0x30, 0xa9, 0x0e, 0xa7, 0xc3, 0xe5, 0x24, 0xd1, 0x60, 0x62,
0xda, 0x80, 0xa3, 0x93, 0x30, 0x38, 0x18, 0x97, 0x8b, 0x93, 0x83, 0xa4, 0xdc, 0x95, 0x5a, 0xbd,
0x6b, 0x1b, 0x5a, 0x4c, 0xee, 0x5b, 0x18, 0x77, 0xbf, 0x8f, 0x23, 0xa3, 0xa3, 0x81, 0x2f, 0x62,
0x6c, 0x3d, 0x82, 0x86, 0xc9, 0xad, 0xfd, 0xe7, 0xf7, 0x7f, 0x7d, 0xaf, 0x79, 0x30, 0x4a, 0x94,
0xc9, 0x95, 0x21, 0x54, 0x6b, 0xf2, 0xdc, 0xa3, 0x99, 0x7e, 0xa0, 0x3d, 0x92, 0x28, 0x39, 0x11,
0x1c, 0xeb, 0xa9, 0xb2, 0x0a, 0xed, 0x79, 0x02, 0x53, 0xad, 0x71, 0x49, 0x1c, 0x1e, 0x70, 0xa5,
0x78, 0xc6, 0x88, 0x43, 0xc6, 0xb3, 0x09, 0xa1, 0xb2, 0xf0, 0x7c, 0xe7, 0x15, 0xc0, 0xfa, 0xd0,
0x09, 0xa0, 0x0b, 0xb8, 0x9d, 0xab, 0x74, 0x96, 0x31, 0x13, 0x80, 0xa8, 0xd6, 0x6d, 0xf6, 0x8f,
0xf0, 0x06, 0x31, 0x7c, 0xe3, 0x18, 0xbf, 0x13, 0x97, 0x1b, 0xe8, 0x1a, 0xee, 0x72, 0x95, 0x51,
0xc9, 0x47, 0x63, 0x21, 0x53, 0x21, 0xb9, 0x09, 0xaa, 0x4e, 0xa4, 0xb3, 0x51, 0xe4, 0xca, 0xb1,
0x03, 0x8f, 0xc6, 0x6d, 0xbe, 0x7e, 0x35, 0x9d, 0x37, 0x00, 0x77, 0xd6, 0x9f, 0x41, 0x08, 0x6e,
0x49, 0x9a, 0xb3, 0x00, 0x44, 0xa0, 0xdb, 0x88, 0xdd, 0x19, 0x9d, 0xc1, 0xba, 0x4f, 0x1e, 0x54,
0x23, 0xd0, 0x6d, 0xf6, 0xf7, 0xb1, 0x4f, 0x89, 0xcb, 0x94, 0xf8, 0x52, 0x16, 0xf1, 0x0f, 0xb3,
0xc9, 0x5f, 0xed, 0xdf, 0xfe, 0xee, 0x61, 0xeb, 0x17, 0x80, 0x8e, 0x61, 0x5b, 0x48, 0xcb, 0xa6,
0x13, 0x9a, 0xb0, 0x91, 0x2d, 0x74, 0xe9, 0xb4, 0xb5, 0x9a, 0xde, 0x16, 0x9a, 0xa1, 0x13, 0xd8,
0x16, 0xb9, 0xce, 0x58, 0xce, 0xa4, 0xa5, 0x56, 0x28, 0xe9, 0xac, 0x37, 0xe2, 0x3f, 0xd3, 0xc1,
0xf0, 0x7d, 0x11, 0x82, 0xf9, 0x22, 0x04, 0x9f, 0x8b, 0x10, 0xbc, 0x2c, 0xc3, 0xca, 0x7c, 0x19,
0x56, 0x3e, 0x96, 0x61, 0xe5, 0xee, 0xd4, 0x9b, 0x35, 0xe9, 0x13, 0x16, 0x8a, 0xa4, 0x4c, 0x0b,
0xf9, 0xc8, 0x12, 0xfb, 0x5d, 0x08, 0x1f, 0x74, 0x55, 0x8b, 0x71, 0xdd, 0xfd, 0xc3, 0xf9, 0x57,
0x00, 0x00, 0x00, 0xff, 0xff, 0xd5, 0xfa, 0x9f, 0xcf, 0x34, 0x02, 0x00, 0x00,
}
func (m *Config) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Config) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *Config) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.GolangBindings) > 0 {
for iNdEx := len(m.GolangBindings) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.GolangBindings[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintConfig(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x12
}
}
if len(m.Modules) > 0 {
for iNdEx := len(m.Modules) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.Modules[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintConfig(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0xa
}
}
return len(dAtA) - i, nil
}
func (m *ModuleConfig) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *ModuleConfig) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *ModuleConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.GolangBindings) > 0 {
for iNdEx := len(m.GolangBindings) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.GolangBindings[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintConfig(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x1a
}
}
if m.Config != nil {
{
size, err := m.Config.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintConfig(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x12
}
if len(m.Name) > 0 {
i -= len(m.Name)
copy(dAtA[i:], m.Name)
i = encodeVarintConfig(dAtA, i, uint64(len(m.Name)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *GolangBinding) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *GolangBinding) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *GolangBinding) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.Implementation) > 0 {
i -= len(m.Implementation)
copy(dAtA[i:], m.Implementation)
i = encodeVarintConfig(dAtA, i, uint64(len(m.Implementation)))
i--
dAtA[i] = 0x12
}
if len(m.InterfaceType) > 0 {
i -= len(m.InterfaceType)
copy(dAtA[i:], m.InterfaceType)
i = encodeVarintConfig(dAtA, i, uint64(len(m.InterfaceType)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func encodeVarintConfig(dAtA []byte, offset int, v uint64) int {
offset -= sovConfig(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *Config) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if len(m.Modules) > 0 {
for _, e := range m.Modules {
l = e.Size()
n += 1 + l + sovConfig(uint64(l))
}
}
if len(m.GolangBindings) > 0 {
for _, e := range m.GolangBindings {
l = e.Size()
n += 1 + l + sovConfig(uint64(l))
}
}
return n
}
func (m *ModuleConfig) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Name)
if l > 0 {
n += 1 + l + sovConfig(uint64(l))
}
if m.Config != nil {
l = m.Config.Size()
n += 1 + l + sovConfig(uint64(l))
}
if len(m.GolangBindings) > 0 {
for _, e := range m.GolangBindings {
l = e.Size()
n += 1 + l + sovConfig(uint64(l))
}
}
return n
}
func (m *GolangBinding) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.InterfaceType)
if l > 0 {
n += 1 + l + sovConfig(uint64(l))
}
l = len(m.Implementation)
if l > 0 {
n += 1 + l + sovConfig(uint64(l))
}
return n
}
func sovConfig(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozConfig(x uint64) (n int) {
return sovConfig(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *Config) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowConfig
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Config: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Config: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Modules", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowConfig
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthConfig
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthConfig
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Modules = append(m.Modules, &ModuleConfig{})
if err := m.Modules[len(m.Modules)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field GolangBindings", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowConfig
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthConfig
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthConfig
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.GolangBindings = append(m.GolangBindings, &GolangBinding{})
if err := m.GolangBindings[len(m.GolangBindings)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipConfig(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthConfig
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *ModuleConfig) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowConfig
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: ModuleConfig: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: ModuleConfig: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowConfig
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthConfig
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthConfig
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Name = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Config", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowConfig
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthConfig
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthConfig
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Config == nil {
m.Config = &any.Any{}
}
if err := m.Config.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field GolangBindings", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowConfig
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthConfig
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthConfig
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.GolangBindings = append(m.GolangBindings, &GolangBinding{})
if err := m.GolangBindings[len(m.GolangBindings)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipConfig(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthConfig
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *GolangBinding) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowConfig
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: GolangBinding: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: GolangBinding: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field InterfaceType", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowConfig
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthConfig
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthConfig
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.InterfaceType = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Implementation", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowConfig
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthConfig
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthConfig
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Implementation = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipConfig(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthConfig
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipConfig(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowConfig
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowConfig
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowConfig
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthConfig
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupConfig
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthConfig
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthConfig = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowConfig = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupConfig = fmt.Errorf("proto: unexpected end of group")
)

View File

@ -0,0 +1,893 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: cosmos/app/v1alpha1/module.proto
package v1alpha1
import (
fmt "fmt"
proto "github.com/cosmos/gogoproto/proto"
descriptorpb "google.golang.org/protobuf/types/descriptorpb"
io "io"
math "math"
math_bits "math/bits"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
// ModuleDescriptor describes an app module.
type ModuleDescriptor struct {
// go_import names the package that should be imported by an app to load the
// module in the runtime module registry. It is required to make debugging
// of configuration errors easier for users.
GoImport string `protobuf:"bytes,1,opt,name=go_import,json=goImport,proto3" json:"go_import,omitempty"`
// use_package refers to a protobuf package that this module
// uses and exposes to the world. In an app, only one module should "use"
// or own a single protobuf package. It is assumed that the module uses
// all of the .proto files in a single package.
UsePackage []*PackageReference `protobuf:"bytes,2,rep,name=use_package,json=usePackage,proto3" json:"use_package,omitempty"`
// can_migrate_from defines which module versions this module can migrate
// state from. The framework will check that one module version is able to
// migrate from a previous module version before attempting to update its
// config. It is assumed that modules can transitively migrate from earlier
// versions. For instance if v3 declares it can migrate from v2, and v2
// declares it can migrate from v1, the framework knows how to migrate
// from v1 to v3, assuming all 3 module versions are registered at runtime.
CanMigrateFrom []*MigrateFromInfo `protobuf:"bytes,3,rep,name=can_migrate_from,json=canMigrateFrom,proto3" json:"can_migrate_from,omitempty"`
}
func (m *ModuleDescriptor) Reset() { *m = ModuleDescriptor{} }
func (m *ModuleDescriptor) String() string { return proto.CompactTextString(m) }
func (*ModuleDescriptor) ProtoMessage() {}
func (*ModuleDescriptor) Descriptor() ([]byte, []int) {
return fileDescriptor_0e7eb8b9b8dcd164, []int{0}
}
func (m *ModuleDescriptor) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *ModuleDescriptor) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_ModuleDescriptor.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *ModuleDescriptor) XXX_Merge(src proto.Message) {
xxx_messageInfo_ModuleDescriptor.Merge(m, src)
}
func (m *ModuleDescriptor) XXX_Size() int {
return m.Size()
}
func (m *ModuleDescriptor) XXX_DiscardUnknown() {
xxx_messageInfo_ModuleDescriptor.DiscardUnknown(m)
}
var xxx_messageInfo_ModuleDescriptor proto.InternalMessageInfo
func (m *ModuleDescriptor) GetGoImport() string {
if m != nil {
return m.GoImport
}
return ""
}
func (m *ModuleDescriptor) GetUsePackage() []*PackageReference {
if m != nil {
return m.UsePackage
}
return nil
}
func (m *ModuleDescriptor) GetCanMigrateFrom() []*MigrateFromInfo {
if m != nil {
return m.CanMigrateFrom
}
return nil
}
// PackageReference is a reference to a protobuf package used by a module.
type PackageReference struct {
// name is the fully-qualified name of the package.
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
// revision is the optional revision of the package that is being used.
// Protobuf packages used in Cosmos should generally have a major version
// as the last part of the package name, ex. foo.bar.baz.v1.
// The revision of a package can be thought of as the minor version of a
// package which has additional backwards compatible definitions that weren't
// present in a previous version.
//
// A package should indicate its revision with a source code comment
// above the package declaration in one of its files containing the
// text "Revision N" where N is an integer revision. All packages start
// at revision 0 the first time they are released in a module.
//
// When a new version of a module is released and items are added to existing
// .proto files, these definitions should contain comments of the form
// "Since: Revision N" where N is an integer revision.
//
// When the module runtime starts up, it will check the pinned proto
// image and panic if there are runtime protobuf definitions that are not
// in the pinned descriptor which do not have
// a "Since Revision N" comment or have a "Since Revision N" comment where
// N is <= to the revision specified here. This indicates that the protobuf
// files have been updated, but the pinned file descriptor hasn't.
//
// If there are items in the pinned file descriptor with a revision
// greater than the value indicated here, this will also cause a panic
// as it may mean that the pinned descriptor for a legacy module has been
// improperly updated or that there is some other versioning discrepancy.
// Runtime protobuf definitions will also be checked for compatibility
// with pinned file descriptors to make sure there are no incompatible changes.
//
// This behavior ensures that:
// - pinned proto images are up-to-date
// - protobuf files are carefully annotated with revision comments which
// are important good client UX
// - protobuf files are changed in backwards and forwards compatible ways
Revision uint32 `protobuf:"varint,2,opt,name=revision,proto3" json:"revision,omitempty"`
}
func (m *PackageReference) Reset() { *m = PackageReference{} }
func (m *PackageReference) String() string { return proto.CompactTextString(m) }
func (*PackageReference) ProtoMessage() {}
func (*PackageReference) Descriptor() ([]byte, []int) {
return fileDescriptor_0e7eb8b9b8dcd164, []int{1}
}
func (m *PackageReference) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *PackageReference) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_PackageReference.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *PackageReference) XXX_Merge(src proto.Message) {
xxx_messageInfo_PackageReference.Merge(m, src)
}
func (m *PackageReference) XXX_Size() int {
return m.Size()
}
func (m *PackageReference) XXX_DiscardUnknown() {
xxx_messageInfo_PackageReference.DiscardUnknown(m)
}
var xxx_messageInfo_PackageReference proto.InternalMessageInfo
func (m *PackageReference) GetName() string {
if m != nil {
return m.Name
}
return ""
}
func (m *PackageReference) GetRevision() uint32 {
if m != nil {
return m.Revision
}
return 0
}
// MigrateFromInfo is information on a module version that a newer module
// can migrate from.
type MigrateFromInfo struct {
// module is the fully-qualified protobuf name of the module config object
// for the previous module version, ex: "cosmos.group.module.v1.Module".
Module string `protobuf:"bytes,1,opt,name=module,proto3" json:"module,omitempty"`
}
func (m *MigrateFromInfo) Reset() { *m = MigrateFromInfo{} }
func (m *MigrateFromInfo) String() string { return proto.CompactTextString(m) }
func (*MigrateFromInfo) ProtoMessage() {}
func (*MigrateFromInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_0e7eb8b9b8dcd164, []int{2}
}
func (m *MigrateFromInfo) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *MigrateFromInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_MigrateFromInfo.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *MigrateFromInfo) XXX_Merge(src proto.Message) {
xxx_messageInfo_MigrateFromInfo.Merge(m, src)
}
func (m *MigrateFromInfo) XXX_Size() int {
return m.Size()
}
func (m *MigrateFromInfo) XXX_DiscardUnknown() {
xxx_messageInfo_MigrateFromInfo.DiscardUnknown(m)
}
var xxx_messageInfo_MigrateFromInfo proto.InternalMessageInfo
func (m *MigrateFromInfo) GetModule() string {
if m != nil {
return m.Module
}
return ""
}
var E_Module = &proto.ExtensionDesc{
ExtendedType: (*descriptorpb.MessageOptions)(nil),
ExtensionType: (*ModuleDescriptor)(nil),
Field: 57193479,
Name: "cosmos.app.v1alpha1.module",
Tag: "bytes,57193479,opt,name=module",
Filename: "cosmos/app/v1alpha1/module.proto",
}
func init() {
proto.RegisterType((*ModuleDescriptor)(nil), "cosmos.app.v1alpha1.ModuleDescriptor")
proto.RegisterType((*PackageReference)(nil), "cosmos.app.v1alpha1.PackageReference")
proto.RegisterType((*MigrateFromInfo)(nil), "cosmos.app.v1alpha1.MigrateFromInfo")
proto.RegisterExtension(E_Module)
}
func init() { proto.RegisterFile("cosmos/app/v1alpha1/module.proto", fileDescriptor_0e7eb8b9b8dcd164) }
var fileDescriptor_0e7eb8b9b8dcd164 = []byte{
// 368 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x52, 0xcd, 0xaa, 0x13, 0x31,
0x18, 0x6d, 0xee, 0x95, 0xcb, 0x6d, 0x8a, 0x5a, 0x22, 0xc8, 0xd0, 0xc2, 0x38, 0x14, 0x85, 0x76,
0x93, 0xa1, 0xba, 0x73, 0x59, 0xa5, 0xd0, 0x45, 0x55, 0x66, 0xe9, 0x66, 0x48, 0x33, 0xdf, 0xc4,
0xd8, 0x4e, 0xbe, 0x90, 0xcc, 0xf4, 0x15, 0xdc, 0xfa, 0x0c, 0xbe, 0x8c, 0x2e, 0xbb, 0x74, 0x29,
0xed, 0xc6, 0xc7, 0x10, 0xe7, 0xa7, 0x48, 0xa9, 0xbb, 0x9c, 0x93, 0x93, 0x73, 0xf2, 0x1d, 0x3e,
0x1a, 0x49, 0xf4, 0x05, 0xfa, 0x58, 0x58, 0x1b, 0xef, 0xe7, 0x62, 0x67, 0x3f, 0x89, 0x79, 0x5c,
0x60, 0x56, 0xed, 0x80, 0x5b, 0x87, 0x25, 0xb2, 0x27, 0x8d, 0x82, 0x0b, 0x6b, 0x79, 0xa7, 0x18,
0x45, 0x0a, 0x51, 0xed, 0x20, 0xae, 0x25, 0x9b, 0x2a, 0x8f, 0x33, 0xf0, 0xd2, 0x69, 0x5b, 0xa2,
0x6b, 0x9e, 0x4d, 0xbe, 0x13, 0x3a, 0x5c, 0xd7, 0x3e, 0x6f, 0xcf, 0x57, 0x6c, 0x4c, 0xfb, 0x0a,
0x53, 0x5d, 0x58, 0x74, 0x65, 0x40, 0x22, 0x32, 0xed, 0x27, 0xf7, 0x0a, 0x57, 0x35, 0x66, 0x4b,
0x3a, 0xa8, 0x3c, 0xa4, 0x56, 0xc8, 0xad, 0x50, 0x10, 0xdc, 0x44, 0xb7, 0xd3, 0xc1, 0xcb, 0x17,
0xfc, 0x4a, 0x3c, 0xff, 0xd0, 0x68, 0x12, 0xc8, 0xc1, 0x81, 0x91, 0x90, 0xd0, 0xca, 0x43, 0x4b,
0xb2, 0x77, 0x74, 0x28, 0x85, 0x49, 0x0b, 0xad, 0x9c, 0x28, 0x21, 0xcd, 0x1d, 0x16, 0xc1, 0x6d,
0x6d, 0xf6, 0xfc, 0xaa, 0xd9, 0xba, 0x11, 0x2e, 0x1d, 0x16, 0x2b, 0x93, 0x63, 0xf2, 0x48, 0x0a,
0xf3, 0x0f, 0x37, 0x59, 0xd0, 0xe1, 0x65, 0x1e, 0x63, 0xf4, 0x81, 0x11, 0x05, 0xb4, 0x33, 0xd4,
0x67, 0x36, 0xa2, 0xf7, 0x0e, 0xf6, 0xda, 0x6b, 0x34, 0xc1, 0x4d, 0x44, 0xa6, 0x0f, 0x93, 0x33,
0x9e, 0xcc, 0xe8, 0xe3, 0x8b, 0x18, 0xf6, 0x94, 0xde, 0x35, 0x3d, 0xb7, 0x26, 0x2d, 0x7a, 0x2d,
0x3a, 0x9e, 0x3d, 0xe3, 0x4d, 0xcb, 0xbc, 0x6b, 0x99, 0xaf, 0xc1, 0x7b, 0xa1, 0xe0, 0xbd, 0x2d,
0x35, 0x1a, 0x1f, 0x7c, 0xf9, 0xfd, 0x6d, 0x1c, 0x91, 0xff, 0xb6, 0x74, 0x59, 0x7f, 0x17, 0xb1,
0x78, 0xf3, 0xe3, 0x18, 0x92, 0xc3, 0x31, 0x24, 0xbf, 0x8e, 0x21, 0xf9, 0x7a, 0x0a, 0x7b, 0x87,
0x53, 0xd8, 0xfb, 0x79, 0x0a, 0x7b, 0x1f, 0x67, 0x8d, 0x8f, 0xcf, 0xb6, 0x5c, 0x63, 0x9c, 0x81,
0xd5, 0xe6, 0x33, 0xc8, 0xf2, 0xef, 0x7a, 0x48, 0x34, 0xb9, 0x56, 0xe7, 0x25, 0xd9, 0xdc, 0xd5,
0xbf, 0x7a, 0xf5, 0x27, 0x00, 0x00, 0xff, 0xff, 0xf5, 0x00, 0xca, 0xe6, 0x42, 0x02, 0x00, 0x00,
}
func (m *ModuleDescriptor) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *ModuleDescriptor) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *ModuleDescriptor) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.CanMigrateFrom) > 0 {
for iNdEx := len(m.CanMigrateFrom) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.CanMigrateFrom[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintModule(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x1a
}
}
if len(m.UsePackage) > 0 {
for iNdEx := len(m.UsePackage) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.UsePackage[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintModule(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x12
}
}
if len(m.GoImport) > 0 {
i -= len(m.GoImport)
copy(dAtA[i:], m.GoImport)
i = encodeVarintModule(dAtA, i, uint64(len(m.GoImport)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *PackageReference) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *PackageReference) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *PackageReference) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.Revision != 0 {
i = encodeVarintModule(dAtA, i, uint64(m.Revision))
i--
dAtA[i] = 0x10
}
if len(m.Name) > 0 {
i -= len(m.Name)
copy(dAtA[i:], m.Name)
i = encodeVarintModule(dAtA, i, uint64(len(m.Name)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *MigrateFromInfo) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *MigrateFromInfo) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *MigrateFromInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.Module) > 0 {
i -= len(m.Module)
copy(dAtA[i:], m.Module)
i = encodeVarintModule(dAtA, i, uint64(len(m.Module)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func encodeVarintModule(dAtA []byte, offset int, v uint64) int {
offset -= sovModule(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *ModuleDescriptor) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.GoImport)
if l > 0 {
n += 1 + l + sovModule(uint64(l))
}
if len(m.UsePackage) > 0 {
for _, e := range m.UsePackage {
l = e.Size()
n += 1 + l + sovModule(uint64(l))
}
}
if len(m.CanMigrateFrom) > 0 {
for _, e := range m.CanMigrateFrom {
l = e.Size()
n += 1 + l + sovModule(uint64(l))
}
}
return n
}
func (m *PackageReference) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Name)
if l > 0 {
n += 1 + l + sovModule(uint64(l))
}
if m.Revision != 0 {
n += 1 + sovModule(uint64(m.Revision))
}
return n
}
func (m *MigrateFromInfo) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Module)
if l > 0 {
n += 1 + l + sovModule(uint64(l))
}
return n
}
func sovModule(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozModule(x uint64) (n int) {
return sovModule(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *ModuleDescriptor) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowModule
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: ModuleDescriptor: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: ModuleDescriptor: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field GoImport", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowModule
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthModule
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthModule
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.GoImport = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field UsePackage", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowModule
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthModule
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthModule
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.UsePackage = append(m.UsePackage, &PackageReference{})
if err := m.UsePackage[len(m.UsePackage)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field CanMigrateFrom", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowModule
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthModule
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthModule
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.CanMigrateFrom = append(m.CanMigrateFrom, &MigrateFromInfo{})
if err := m.CanMigrateFrom[len(m.CanMigrateFrom)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipModule(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthModule
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *PackageReference) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowModule
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: PackageReference: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: PackageReference: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowModule
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthModule
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthModule
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Name = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Revision", wireType)
}
m.Revision = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowModule
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Revision |= uint32(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipModule(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthModule
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *MigrateFromInfo) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowModule
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: MigrateFromInfo: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: MigrateFromInfo: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Module", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowModule
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthModule
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthModule
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Module = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipModule(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthModule
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipModule(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowModule
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowModule
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowModule
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthModule
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupModule
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthModule
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthModule = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowModule = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupModule = fmt.Errorf("proto: unexpected end of group")
)

View File

@ -0,0 +1,538 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: cosmos/app/v1alpha1/query.proto
package v1alpha1
import (
context "context"
fmt "fmt"
grpc1 "github.com/cosmos/gogoproto/grpc"
proto "github.com/cosmos/gogoproto/proto"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
io "io"
math "math"
math_bits "math/bits"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
// QueryConfigRequest is the Query/Config request type.
type QueryConfigRequest struct {
}
func (m *QueryConfigRequest) Reset() { *m = QueryConfigRequest{} }
func (m *QueryConfigRequest) String() string { return proto.CompactTextString(m) }
func (*QueryConfigRequest) ProtoMessage() {}
func (*QueryConfigRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_bd84655af543ba53, []int{0}
}
func (m *QueryConfigRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *QueryConfigRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_QueryConfigRequest.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *QueryConfigRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_QueryConfigRequest.Merge(m, src)
}
func (m *QueryConfigRequest) XXX_Size() int {
return m.Size()
}
func (m *QueryConfigRequest) XXX_DiscardUnknown() {
xxx_messageInfo_QueryConfigRequest.DiscardUnknown(m)
}
var xxx_messageInfo_QueryConfigRequest proto.InternalMessageInfo
// QueryConfigResponse is the Query/Config response type.
type QueryConfigResponse struct {
// config is the current app config.
Config *Config `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"`
}
func (m *QueryConfigResponse) Reset() { *m = QueryConfigResponse{} }
func (m *QueryConfigResponse) String() string { return proto.CompactTextString(m) }
func (*QueryConfigResponse) ProtoMessage() {}
func (*QueryConfigResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_bd84655af543ba53, []int{1}
}
func (m *QueryConfigResponse) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *QueryConfigResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_QueryConfigResponse.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *QueryConfigResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_QueryConfigResponse.Merge(m, src)
}
func (m *QueryConfigResponse) XXX_Size() int {
return m.Size()
}
func (m *QueryConfigResponse) XXX_DiscardUnknown() {
xxx_messageInfo_QueryConfigResponse.DiscardUnknown(m)
}
var xxx_messageInfo_QueryConfigResponse proto.InternalMessageInfo
func (m *QueryConfigResponse) GetConfig() *Config {
if m != nil {
return m.Config
}
return nil
}
func init() {
proto.RegisterType((*QueryConfigRequest)(nil), "cosmos.app.v1alpha1.QueryConfigRequest")
proto.RegisterType((*QueryConfigResponse)(nil), "cosmos.app.v1alpha1.QueryConfigResponse")
}
func init() { proto.RegisterFile("cosmos/app/v1alpha1/query.proto", fileDescriptor_bd84655af543ba53) }
var fileDescriptor_bd84655af543ba53 = []byte{
// 222 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4f, 0xce, 0x2f, 0xce,
0xcd, 0x2f, 0xd6, 0x4f, 0x2c, 0x28, 0xd0, 0x2f, 0x33, 0x4c, 0xcc, 0x29, 0xc8, 0x48, 0x34, 0xd4,
0x2f, 0x2c, 0x4d, 0x2d, 0xaa, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x86, 0x28, 0xd0,
0x4b, 0x2c, 0x28, 0xd0, 0x83, 0x29, 0x90, 0x52, 0xc0, 0xa6, 0x2b, 0x39, 0x3f, 0x2f, 0x2d, 0x33,
0x1d, 0xa2, 0x4d, 0x49, 0x84, 0x4b, 0x28, 0x10, 0x64, 0x8a, 0x33, 0x58, 0x30, 0x28, 0xb5, 0xb0,
0x34, 0xb5, 0xb8, 0x44, 0xc9, 0x8b, 0x4b, 0x18, 0x45, 0xb4, 0xb8, 0x20, 0x3f, 0xaf, 0x38, 0x55,
0xc8, 0x98, 0x8b, 0x0d, 0xa2, 0x59, 0x82, 0x51, 0x81, 0x51, 0x83, 0xdb, 0x48, 0x5a, 0x0f, 0x8b,
0xa5, 0x7a, 0x50, 0x4d, 0x50, 0xa5, 0x46, 0x99, 0x5c, 0xac, 0x60, 0xb3, 0x84, 0x12, 0xb8, 0xd8,
0x20, 0x52, 0x42, 0xea, 0x58, 0xf5, 0x61, 0xba, 0x43, 0x4a, 0x83, 0xb0, 0x42, 0x88, 0xd3, 0x94,
0x98, 0x3b, 0x98, 0x18, 0x9d, 0x9c, 0x4f, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1,
0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21,
0x4a, 0x13, 0x62, 0x4e, 0x71, 0x4a, 0xb6, 0x5e, 0x66, 0xbe, 0x7e, 0x4a, 0x6a, 0x41, 0x66, 0x5e,
0x56, 0x6a, 0x72, 0x09, 0x28, 0x60, 0x20, 0xce, 0x84, 0x07, 0x4f, 0x12, 0x1b, 0x38, 0x60, 0x8c,
0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x72, 0xe6, 0x07, 0x7f, 0x72, 0x01, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// QueryClient is the client API for Query service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type QueryClient interface {
// Config returns the current app config.
Config(ctx context.Context, in *QueryConfigRequest, opts ...grpc.CallOption) (*QueryConfigResponse, error)
}
type queryClient struct {
cc grpc1.ClientConn
}
func NewQueryClient(cc grpc1.ClientConn) QueryClient {
return &queryClient{cc}
}
// Deprecated: Do not use.
func (c *queryClient) Config(ctx context.Context, in *QueryConfigRequest, opts ...grpc.CallOption) (*QueryConfigResponse, error) {
out := new(QueryConfigResponse)
err := c.cc.Invoke(ctx, "/cosmos.app.v1alpha1.Query/Config", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// QueryServer is the server API for Query service.
type QueryServer interface {
// Config returns the current app config.
Config(context.Context, *QueryConfigRequest) (*QueryConfigResponse, error)
}
// UnimplementedQueryServer can be embedded to have forward compatible implementations.
type UnimplementedQueryServer struct {
}
func (*UnimplementedQueryServer) Config(ctx context.Context, req *QueryConfigRequest) (*QueryConfigResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Config not implemented")
}
func RegisterQueryServer(s grpc1.Server, srv QueryServer) {
s.RegisterService(&_Query_serviceDesc, srv)
}
func _Query_Config_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(QueryConfigRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(QueryServer).Config(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/cosmos.app.v1alpha1.Query/Config",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(QueryServer).Config(ctx, req.(*QueryConfigRequest))
}
return interceptor(ctx, in, info, handler)
}
var Query_serviceDesc = _Query_serviceDesc
var _Query_serviceDesc = grpc.ServiceDesc{
ServiceName: "cosmos.app.v1alpha1.Query",
HandlerType: (*QueryServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "Config",
Handler: _Query_Config_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "cosmos/app/v1alpha1/query.proto",
}
func (m *QueryConfigRequest) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *QueryConfigRequest) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *QueryConfigRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
return len(dAtA) - i, nil
}
func (m *QueryConfigResponse) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *QueryConfigResponse) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *QueryConfigResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.Config != nil {
{
size, err := m.Config.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintQuery(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func encodeVarintQuery(dAtA []byte, offset int, v uint64) int {
offset -= sovQuery(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *QueryConfigRequest) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
return n
}
func (m *QueryConfigResponse) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.Config != nil {
l = m.Config.Size()
n += 1 + l + sovQuery(uint64(l))
}
return n
}
func sovQuery(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozQuery(x uint64) (n int) {
return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *QueryConfigRequest) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: QueryConfigRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: QueryConfigRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
default:
iNdEx = preIndex
skippy, err := skipQuery(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthQuery
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *QueryConfigResponse) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: QueryConfigResponse: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: QueryConfigResponse: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Config", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthQuery
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthQuery
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Config == nil {
m.Config = &Config{}
}
if err := m.Config.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipQuery(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthQuery
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipQuery(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowQuery
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowQuery
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowQuery
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthQuery
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupQuery
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthQuery
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group")
)

View File

@ -5,21 +5,11 @@ import (
"reflect"
"testing"
"github.com/regen-network/gocuke"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"cosmossdk.io/depinject"
)
func TestBindInterface(t *testing.T) {
gocuke.NewRunner(t, &bindingSuite{}).
Path("features/bindings.feature").
Step(`we try to resolve a "Duck" in global scope`, (*bindingSuite).WeTryToResolveADuckInGlobalScope).
Step(`module "(\w+)" wants a "Duck"`, (*bindingSuite).ModuleWantsADuck).
Run()
}
type Duck interface {
quack()
}
@ -45,115 +35,281 @@ type Pond struct {
Ducks []DuckWrapper
}
type bindingSuite struct {
gocuke.TestingT // this gets injected by gocuke
func IsResolvedInGlobalScope(t *testing.T, pond Pond, typeName string) {
t.Helper()
configs []depinject.Config
pond *Pond
err error
}
func (s bindingSuite) AnInterfaceDuck() {
// we don't need to do anything because this is defined at the type level
}
func (s bindingSuite) TwoImplementationsMallardAndCanvasback() {
// we don't need to do anything because this is defined at the type level
}
func ProvideMallard() Mallard { return Mallard{} }
func ProvideCanvasback() Canvasback { return Canvasback{} }
func ProvideMarbled() Marbled { return Marbled{} }
func (s *bindingSuite) IsProvided(a string) {
switch a {
case "Mallard":
s.addConfig(depinject.Provide(ProvideMallard))
case "Canvasback":
s.addConfig(depinject.Provide(ProvideCanvasback))
case "Marbled":
s.addConfig(depinject.Provide(ProvideMarbled))
default:
s.Fatalf("unexpected duck type %s", a)
}
}
func (s *bindingSuite) addConfig(config depinject.Config) {
s.configs = append(s.configs, config)
}
func ProvideDuckWrapper(duck Duck) DuckWrapper {
return DuckWrapper{Module: "", Duck: duck}
}
func (s *bindingSuite) WeTryToResolveADuckInGlobalScope() {
s.addConfig(depinject.Provide(ProvideDuckWrapper))
}
func ResolvePond(ducks []DuckWrapper) Pond { return Pond{Ducks: ducks} }
func (s *bindingSuite) resolvePond() *Pond {
if s.pond != nil {
return s.pond
}
s.addConfig(depinject.Provide(ResolvePond))
var pond Pond
s.err = depinject.Inject(depinject.Configs(s.configs...), &pond)
s.pond = &pond
return s.pond
}
func (s *bindingSuite) IsResolvedInGlobalScope(typeName string) {
pond := s.resolvePond()
found := false
for _, dw := range pond.Ducks {
if dw.Module == "" {
require.Contains(s, reflect.TypeOf(dw.Duck).Name(), typeName)
require.Contains(t, reflect.TypeOf(dw.Duck).Name(), typeName)
found = true
}
}
assert.True(s, found)
require.True(t, found)
}
func (s *bindingSuite) ThereIsAError(expectedErrorMsg string) {
s.resolvePond()
assert.ErrorContains(s, s.err, expectedErrorMsg)
func IsResolvedModuleScope(t *testing.T, pond Pond, module, duckType string) {
t.Helper()
moduleFound := false
for _, dw := range pond.Ducks {
if dw.Module == module {
require.Contains(t, reflect.TypeOf(dw.Duck).Name(), duckType)
moduleFound = true
}
}
require.True(t, moduleFound)
}
func (s *bindingSuite) ThereIsNoError() {
s.resolvePond()
assert.NoError(s, s.err)
}
func ProvideMallard() Mallard { return Mallard{} }
func fullTypeName(typeName string) string {
return fmt.Sprintf("cosmossdk.io/depinject_test/depinject_test.%s", typeName)
}
func ProvideCanvasback() Canvasback { return Canvasback{} }
func (s *bindingSuite) ThereIsAGlobalBindingForA(preferredType, interfaceType string) {
s.addConfig(depinject.BindInterface(fullTypeName(interfaceType), fullTypeName(preferredType)))
}
func ProvideMarbled() Marbled { return Marbled{} }
func (s *bindingSuite) ThereIsABindingForAInModule(preferredType, interfaceType, moduleName string) {
s.addConfig(depinject.BindInterfaceInModule(moduleName, fullTypeName(interfaceType), fullTypeName(preferredType)))
func ProvideDuckWrapper(duck Duck) DuckWrapper {
return DuckWrapper{Module: "", Duck: duck}
}
func ProvideModuleDuck(duck Duck, key depinject.OwnModuleKey) DuckWrapper {
return DuckWrapper{Module: depinject.ModuleKey(key).Name(), Duck: duck}
}
func (s *bindingSuite) ModuleWantsADuck(module string) {
s.addConfig(depinject.ProvideInModule(module, ProvideModuleDuck))
func ResolvePond(ducks []DuckWrapper) Pond { return Pond{Ducks: ducks} }
func fullTypeName(typeName string) string {
return fmt.Sprintf("cosmossdk.io/depinject_test/depinject_test.%s", typeName)
}
func (s *bindingSuite) ModuleResolvesA(module, duckType string) {
pond := s.resolvePond()
moduleFound := false
for _, dw := range pond.Ducks {
if dw.Module == module {
assert.Contains(s, reflect.TypeOf(dw.Duck).Name(), duckType)
moduleFound = true
}
}
assert.True(s, moduleFound)
func TestProvideNoBinding(t *testing.T) {
t.Parallel()
configs := depinject.Configs(
depinject.Provide(
ProvideMallard,
ProvideDuckWrapper,
ResolvePond,
),
)
var pond Pond
err := depinject.Inject(configs, &pond)
require.NoError(t, err)
IsResolvedInGlobalScope(t, pond, "Mallard")
}
func TestProvideNoBindingImplementationErrorAmbiguous(t *testing.T) {
t.Parallel()
configs := depinject.Configs(
depinject.Provide(
ProvideMallard,
ProvideCanvasback,
ProvideDuckWrapper,
ResolvePond,
),
)
var pond Pond
err := depinject.Inject(configs, &pond)
require.ErrorContains(t, err, "Multiple implementations found")
}
func TestBindInterface(t *testing.T) {
t.Parallel()
configs := depinject.Configs(
depinject.BindInterface(fullTypeName("Duck"), fullTypeName("Mallard")),
depinject.Provide(
ProvideMallard,
ProvideDuckWrapper,
ResolvePond,
),
)
var pond Pond
err := depinject.Inject(configs, &pond)
require.NoError(t, err)
}
func TestBindInterfaceBoundTypeNotProvided(t *testing.T) {
t.Parallel()
configs := depinject.Configs(
depinject.BindInterface(fullTypeName("Duck"), fullTypeName("Marbled")),
depinject.Provide(
ProvideMallard,
ProvideDuckWrapper,
ResolvePond,
),
)
var pond Pond
err := depinject.Inject(configs, &pond)
require.ErrorContains(t, err, "No type for explicit binding")
}
func TestBindInterfaceOverwriteImplicitTypeResolution(t *testing.T) {
t.Parallel()
configs := depinject.Configs(
depinject.BindInterface(fullTypeName("Duck"), fullTypeName("Marbled")), // overwrite Canvasback
depinject.Provide(
ProvideCanvasback,
ProvideDuckWrapper,
ResolvePond,
),
)
var pond Pond
err := depinject.Inject(configs, &pond)
require.ErrorContains(t, err, "No type for explicit binding")
// same in module scope
moduleName := "A"
configs = depinject.Configs(
depinject.BindInterfaceInModule(moduleName, fullTypeName("Duck"), fullTypeName("Marbled")), // overwrite Canvasback
depinject.Provide(
ProvideCanvasback,
ResolvePond,
),
depinject.ProvideInModule(moduleName, ProvideModuleDuck),
)
err = depinject.Inject(configs, &pond)
require.ErrorContains(t, err, "No type for explicit binding")
}
func TestBindingInterfaceGlobalScopeApplyToGlobalAndModuleScope(t *testing.T) {
t.Parallel()
configs := depinject.Configs(
depinject.BindInterface(fullTypeName("Duck"), fullTypeName("Mallard")), // order is important
depinject.Provide(
ProvideMallard,
ProvideCanvasback,
ProvideDuckWrapper,
ResolvePond,
),
)
var pond Pond
err := depinject.Inject(configs, &pond)
require.NoError(t, err)
IsResolvedInGlobalScope(t, pond, "Mallard")
// same in module scope
moduleName := "A"
configs = depinject.Configs(
depinject.BindInterface(fullTypeName("Duck"), fullTypeName("Mallard")),
depinject.Provide(
ProvideMallard,
ProvideCanvasback,
ResolvePond,
),
depinject.ProvideInModule(moduleName, ProvideModuleDuck),
)
err = depinject.Inject(configs, &pond)
require.NoError(t, err)
IsResolvedModuleScope(t, pond, moduleName, "Mallard")
}
func TestBindingInterfaceModuleScopeApplyOnlyModuleScope(t *testing.T) {
t.Parallel()
moduleName := "A"
configs := depinject.Configs(
depinject.BindInterfaceInModule(moduleName, fullTypeName("Duck"), fullTypeName("Canvasback")),
depinject.Provide(
ProvideMallard,
ProvideCanvasback,
ProvideDuckWrapper,
ResolvePond,
),
)
var pond Pond
err := depinject.Inject(configs, &pond)
require.ErrorContains(t, err, "Multiple implementations found")
configs = depinject.Configs(
depinject.BindInterfaceInModule(moduleName, fullTypeName("Duck"), fullTypeName("Canvasback")),
depinject.Provide(
ProvideMallard,
ProvideCanvasback,
ResolvePond,
),
depinject.ProvideInModule(moduleName, ProvideModuleDuck),
)
err = depinject.Inject(configs, &pond)
require.NoError(t, err)
IsResolvedModuleScope(t, pond, moduleName, "Canvasback")
}
func TestBindingInterfaceModuleScopeApplyCorrectModule(t *testing.T) {
t.Parallel()
moduleName := "A"
configs := depinject.Configs(
depinject.BindInterfaceInModule(moduleName, fullTypeName("Duck"), fullTypeName("Canvasback")),
depinject.Provide(
ProvideMallard,
ProvideCanvasback,
ProvideDuckWrapper,
ResolvePond,
),
depinject.ProvideInModule("B", ProvideModuleDuck),
)
var pond Pond
err := depinject.Inject(configs, &pond)
require.ErrorContains(t, err, "Multiple implementations found")
}
func TestBindingInterfaceTwoModuleScopedAndGlobalBinding(t *testing.T) {
t.Parallel()
moduleA, moduleB, moduleC := "A", "B", "C"
configs := depinject.Configs(
depinject.BindInterface(fullTypeName("Duck"), fullTypeName("Marbled")),
depinject.BindInterfaceInModule(moduleA, fullTypeName("Duck"), fullTypeName("Canvasback")),
depinject.BindInterfaceInModule(moduleB, fullTypeName("Duck"), fullTypeName("Mallard")),
depinject.Provide(
ProvideMallard,
ProvideCanvasback,
ProvideMarbled,
ProvideDuckWrapper,
ResolvePond,
),
depinject.ProvideInModule(moduleA, ProvideModuleDuck),
depinject.ProvideInModule(moduleB, ProvideModuleDuck),
depinject.ProvideInModule(moduleC, ProvideModuleDuck),
)
var pond Pond
err := depinject.Inject(configs, &pond)
require.NoError(t, err)
IsResolvedModuleScope(t, pond, moduleA, "Canvasback")
IsResolvedModuleScope(t, pond, moduleB, "Mallard")
IsResolvedModuleScope(t, pond, moduleC, "Marbled")
IsResolvedInGlobalScope(t, pond, "Marbled")
}
func TestIgnoredField(t *testing.T) {
t.Parallel()
cfg := struct {
depinject.In
TheDuck Duck
privateField bool
AnotherDuck Duck
}{}
err := depinject.Inject(depinject.Provide(ProvideMallard), &cfg)
require.NoError(t, err)
}

View File

@ -1,12 +1,11 @@
package depinject
import (
"fmt"
"reflect"
"slices"
"strings"
"unicode"
"github.com/cockroachdb/errors"
)
// isExportedType checks if the type is exported and not in an internal
@ -21,12 +20,12 @@ func isExportedType(typ reflect.Type) error {
pkgPath := typ.PkgPath()
if name != "" && pkgPath != "" {
if unicode.IsLower([]rune(name)[0]) {
return errors.Errorf("type must be exported: %s", typ)
return fmt.Errorf("type must be exported: %s", typ)
}
pkgParts := strings.Split(pkgPath, "/")
if slices.Contains(pkgParts, "internal") {
return errors.Errorf("type must not come from an internal package: %s", typ)
return fmt.Errorf("type must not come from an internal package: %s", typ)
}
return nil

View File

@ -1,9 +1,10 @@
package depinject
import (
"errors"
"fmt"
"reflect"
"github.com/cockroachdb/errors"
"runtime"
)
// Config is a functional configuration of a container.
@ -33,7 +34,7 @@ func Provide(providers ...interface{}) Config {
func ProvideInModule(moduleName string, providers ...interface{}) Config {
return containerConfig(func(ctr *container) error {
if moduleName == "" {
return errors.Errorf("expected non-empty module name")
return errors.New("expected non-empty module name")
}
return provide(ctr, ctr.moduleKeyContext.createOrGetModuleKey(moduleName), providers)
@ -44,11 +45,11 @@ func provide(ctr *container, key *moduleKey, providers []interface{}) error {
for _, c := range providers {
rc, err := extractProviderDescriptor(c)
if err != nil {
return errors.WithStack(err)
return fmt.Errorf("%w\n%s", err, getStackTrace())
}
_, err = ctr.addNode(&rc, key)
if err != nil {
return errors.WithStack(err)
return fmt.Errorf("%w\n%s", err, getStackTrace())
}
}
return nil
@ -80,7 +81,7 @@ func Invoke(invokers ...interface{}) Config {
func InvokeInModule(moduleName string, invokers ...interface{}) Config {
return containerConfig(func(ctr *container) error {
if moduleName == "" {
return errors.Errorf("expected non-empty module name")
return errors.New("expected non-empty module name")
}
return invoke(ctr, ctr.moduleKeyContext.createOrGetModuleKey(moduleName), invokers)
@ -91,7 +92,7 @@ func invoke(ctr *container, key *moduleKey, invokers []interface{}) error {
for _, c := range invokers {
rc, err := extractInvokerDescriptor(c)
if err != nil {
return errors.WithStack(err)
return fmt.Errorf("%w\n%s", err, getStackTrace())
}
err = ctr.addInvoker(&rc, key)
if err != nil {
@ -151,7 +152,7 @@ func Supply(values ...interface{}) Config {
for _, v := range values {
err := ctr.supply(reflect.ValueOf(v), loc)
if err != nil {
return errors.WithStack(err)
return fmt.Errorf("%w\n%s", err, getStackTrace())
}
}
return nil
@ -162,7 +163,7 @@ func Supply(values ...interface{}) Config {
// fail immediately.
func Error(err error) Config {
return containerConfig(func(*container) error {
return errors.WithStack(err)
return fmt.Errorf("%w\n%s", err, getStackTrace())
})
}
@ -172,7 +173,7 @@ func Configs(opts ...Config) Config {
for _, opt := range opts {
err := opt.apply(ctr)
if err != nil {
return errors.WithStack(err)
return fmt.Errorf("%w\n%s", err, getStackTrace())
}
}
return nil
@ -186,3 +187,9 @@ func (c containerConfig) apply(ctr *container) error {
}
var _ Config = (*containerConfig)(nil)
func getStackTrace() string {
var stack [4096]byte
n := runtime.Stack(stack[:], false)
return string(stack[:n])
}

View File

@ -2,11 +2,10 @@ package depinject
import (
"bytes"
stderrors "errors"
"fmt"
"reflect"
"github.com/cockroachdb/errors"
"cosmossdk.io/depinject/internal/graphviz"
)
@ -62,7 +61,7 @@ func (c *container) call(provider *providerDescriptor, moduleKey *moduleKey) ([]
markGraphNodeAsFailed(graphNode)
if c.callerMap[loc] {
return nil, errors.Errorf("cyclic dependency: %s -> %s", loc.Name(), loc.Name())
return nil, fmt.Errorf("cyclic dependency: %s -> %s", loc.Name(), loc.Name())
}
c.callerMap[loc] = true
@ -72,6 +71,9 @@ func (c *container) call(provider *providerDescriptor, moduleKey *moduleKey) ([]
c.indentLogger()
inVals := make([]reflect.Value, len(provider.Inputs))
for i, in := range provider.Inputs {
if in.Ignored {
continue
}
val, err := c.resolve(in, moduleKey, loc)
if err != nil {
return nil, err
@ -86,7 +88,7 @@ func (c *container) call(provider *providerDescriptor, moduleKey *moduleKey) ([]
out, err := provider.Fn(inVals)
if err != nil {
return nil, errors.Wrapf(err, "error calling provider %s", loc)
return nil, fmt.Errorf("error calling provider %s: %w", loc, err)
}
markGraphNodeAsUsed(graphNode)
@ -235,9 +237,6 @@ func (c *container) addNode(provider *providerDescriptor, key *moduleKey) (inter
typeGraphNode = vr.typeGraphNode()
} else {
typeGraphNode = c.typeGraphNode(typ)
if err != nil {
return nil, err
}
}
c.addGraphEdge(typeGraphNode, providerGraphNode)
@ -298,7 +297,7 @@ func (c *container) addNode(provider *providerDescriptor, key *moduleKey) (inter
}
if hasOwnModuleKeyParam {
return nil, errors.Errorf("%T and %T must not be declared as dependencies on the same provided",
return nil, fmt.Errorf("%T and %T must not be declared as dependencies on the same provided",
ModuleKey{}, OwnModuleKey{})
}
@ -319,7 +318,7 @@ func (c *container) addNode(provider *providerDescriptor, key *moduleKey) (inter
existing, ok := c.resolverByType(typ)
if ok {
return nil, errors.Errorf("duplicate provision of type %v by module-scoped provider %s\n\talready provided by %s",
return nil, fmt.Errorf("duplicate provision of type %v by module-scoped provider %s\n\talready provided by %s",
typ, provider.Location, existing.describeLocation())
}
@ -380,7 +379,7 @@ func (c *container) resolve(in providerInput, moduleKey *moduleKey, caller Locat
if in.Type == moduleKeyType {
if moduleKey == nil {
return reflect.Value{}, errors.Errorf("trying to resolve %T for %s but not inside of any module's scope", moduleKey, caller)
return reflect.Value{}, fmt.Errorf("trying to resolve %T for %s but not inside of any module's scope", moduleKey, caller)
}
c.logf("Providing ModuleKey %s", moduleKey.name)
markGraphNodeAsUsed(typeGraphNode)
@ -389,7 +388,7 @@ func (c *container) resolve(in providerInput, moduleKey *moduleKey, caller Locat
if in.Type == ownModuleKeyType {
if moduleKey == nil {
return reflect.Value{}, errors.Errorf("trying to resolve %T for %s but not inside of any module's scope", moduleKey, caller)
return reflect.Value{}, fmt.Errorf("trying to resolve %T for %s but not inside of any module's scope", moduleKey, caller)
}
c.logf("Providing OwnModuleKey %s", moduleKey.name)
markGraphNodeAsUsed(typeGraphNode)
@ -408,7 +407,7 @@ func (c *container) resolve(in providerInput, moduleKey *moduleKey, caller Locat
}
markGraphNodeAsFailed(typeGraphNode)
return reflect.Value{}, errors.Errorf("can't resolve type %v for %s:\n%s",
return reflect.Value{}, fmt.Errorf("can't resolve type %v for %s:\n%s",
fullyQualifiedTypeName(in.Type), caller, c.formatResolveStack())
}
@ -441,7 +440,7 @@ func (c *container) build(loc Location, outputs ...interface{}) error {
Outputs: nil,
Fn: func(values []reflect.Value) ([]reflect.Value, error) {
if len(values) != len(outputs) {
return nil, fmt.Errorf("internal error, unexpected number of values")
return nil, stderrors.New("internal error, unexpected number of values")
}
for i, output := range outputs {
@ -477,7 +476,7 @@ func (c *container) build(loc Location, outputs ...interface{}) error {
sn, ok := node.(*simpleProvider)
if !ok {
return errors.Errorf("cannot run module-scoped provider as an invoker")
return stderrors.New("cannot run module-scoped provider as an invoker")
}
c.logf("Building container")

View File

@ -1,6 +1,7 @@
package depinject_test
import (
"errors"
"fmt"
"os"
"testing"
@ -212,7 +213,7 @@ func TestUnexportedField(t *testing.T) {
"depinject.Out struct",
)
require.ErrorContains(t,
require.NoError(t,
depinject.Inject(
scenarioConfigDependency,
&handlers,
@ -220,7 +221,6 @@ func TestUnexportedField(t *testing.T) {
&a,
&c,
),
"depinject.In struct",
)
require.ErrorContains(t,
@ -300,7 +300,7 @@ func TestCyclic(t *testing.T) {
}
func TestErrorOption(t *testing.T) {
err := depinject.Inject(depinject.Error(fmt.Errorf("an error")))
err := depinject.Inject(depinject.Error(errors.New("an error")))
require.Error(t, err)
}
@ -606,7 +606,7 @@ func ProvideTestOutput() (TestOutput, error) {
}
func ProvideTestOutputErr() (TestOutput, error) {
return TestOutput{}, fmt.Errorf("error")
return TestOutput{}, errors.New("error")
}
func TestStructArgs(t *testing.T) {

View File

@ -3,8 +3,6 @@ package depinject
import (
"fmt"
"reflect"
"github.com/cockroachdb/errors"
)
// ErrMultipleImplicitInterfaceBindings defines an error condition where an attempt was made to implicitly bind
@ -63,6 +61,6 @@ func (err ErrNoTypeForExplicitBindingFound) Error() string {
}
func duplicateDefinitionError(typ reflect.Type, duplicateLoc Location, existingLoc string) error {
return errors.Errorf("duplicate provision of type %v by %s\n\talready provided by %s",
return fmt.Errorf("duplicate provision of type %v by %s\n\talready provided by %s",
typ, duplicateLoc, existingLoc)
}

View File

@ -1,94 +0,0 @@
Feature: interface type resolution
Background:
Given an interface Duck
And two implementations Mallard and Canvasback
Rule: interface types resolve to a concrete type implicitly if there is only one matching implementation
Example: only one implementation
Given "Mallard" is provided
When we try to resolve a "Duck" in global scope
Then "Mallard" is resolved in global scope
Example: two implementations
Given "Mallard" is provided
* "Canvasback" is provided
When we try to resolve a "Duck" in global scope
Then there is a "Multiple implementations found" error
Rule: bindings must point to a real type
Example: a bound type is not provided
Given "Mallard" is provided
And there is a global binding for a "Marbled" "Duck"
When we try to resolve a "Duck" in global scope
Then there is a "No type for explicit binding" error
Rule: bindings supersede implicit type resolution
Example: global scope
Given "Canvasback" is provided
And there is a global binding for a "Mallard" "Duck"
When we try to resolve a "Duck" in global scope
Then there is a "No type for explicit binding" error
Example: module scope
Given "Canvasback" is provided
And there is a binding for a "Mallard" "Duck" in module "A"
When module "A" wants a "Duck"
Then there is a "No type for explicit binding" error
Rule: bindings in global scope apply to both global and module-scoped resolution (if there is no module-scoped binding)
Example: global resolution
Given "Mallard" is provided
And "Canvasback" is provided
And there is a global binding for a "Mallard" "Duck"
When we try to resolve a "Duck" in global scope
Then "Mallard" is resolved in global scope
Example: module-scoped resolution
Given "Mallard" is provided
And "Canvasback" is provided
And there is a global binding for a "Mallard" "Duck"
When module "A" wants a "Duck"
Then module "A" resolves a "Mallard"
Rule: module-scoped bindings only apply to module-scoped resolution
Example: a module-scoped binding doesn't work for global scope
Given "Mallard" is provided
* "Canvasback" is provided
* there is a binding for a "Canvasback" "Duck" in module "A"
When we try to resolve a "Duck" in global scope
Then there is a "Multiple implementations found" error
Example: a module-scoped binding works for that module
Given "Mallard" is provided
* "Canvasback" is provided
* there is a binding for a "Canvasback" "Duck" in module "A"
When module "A" wants a "Duck"
Then module "A" resolves a "Canvasback"
Example: a module-scoped binding doesn't work for another module
Given "Mallard" is provided
* "Canvasback" is provided
* there is a binding for a "Canvasback" "Duck" in module "A"
When module "B" wants a "Duck"
Then there is a "Multiple implementations found" error
# this case is called a "journey" scenario which tests a bunch of things together
# most tests should be short and to the point like the ones above but one or two long ones
# are good to test more things together &/or do integration tests
Example: two module-scoped binding and a global binding
Given "Mallard" is provided
* "Canvasback" is provided
* "Marbled" is provided
* there is a global binding for a "Marbled" "Duck"
* there is a binding for a "Canvasback" "Duck" in module "A"
* there is a binding for a "Mallard" "Duck" in module "B"
When module "A" wants a "Duck"
* module "B" wants a "Duck"
* module "C" wants a "Duck"
* we try to resolve a "Duck" in global scope
Then there is no error
* module "A" resolves a "Canvasback"
* module "B" resolves a "Mallard"
* module "C" resolves a "Marbled"
* "Marbled" is resolved in global scope

View File

@ -1,30 +0,0 @@
Feature: invokers
Invokers are functions the will always get called, have strictly optional
dependencies and no return outputs (other than error).
Background:
Rule: invokers get called even if their dependencies can't be resolved
Example: no providers
Given an invoker requesting an int and string pointer
When the container is built
Then the invoker will get the int parameter set to 0
And the invoker will get the string pointer parameter set to nil
Rule: invokers get called with dependencies if they are provided
Example: int and string pointer providers
Given an invoker requesting an int and string pointer
And an int provider returning 5
And a string pointer provider pointing to "foo"
When the container is built
Then the invoker will get the int parameter set to 5
And the invoker will get the string pointer parameter set to "foo"
Rule: invokers get module scoped dependencies
Example: module-scoped int
Given an invoker requesting an int and string pointer run in module "foo"
And a module-scoped int provider which returns the length of the module name
When the container is built
Then the invoker will get the int parameter set to 3
And the invoker will get the string pointer parameter set to nil

View File

@ -3,32 +3,29 @@ module cosmossdk.io/depinject
go 1.23
require (
github.com/cockroachdb/errors v1.10.0
github.com/regen-network/gocuke v0.6.2
github.com/stretchr/testify v1.8.4
gotest.tools/v3 v3.4.0
github.com/cosmos/cosmos-proto v1.0.0-beta.5
github.com/cosmos/gogoproto v1.7.0
github.com/stretchr/testify v1.10.0
google.golang.org/grpc v1.70.0
google.golang.org/protobuf v1.36.4
gotest.tools/v3 v3.5.1
sigs.k8s.io/yaml v1.4.0
)
require (
github.com/alecthomas/participle/v2 v2.0.0-alpha7 // indirect
github.com/cockroachdb/apd/v3 v3.1.0 // indirect
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
github.com/cockroachdb/redact v1.1.5 // indirect
github.com/cucumber/common/gherkin/go/v22 v22.0.0 // indirect
github.com/cucumber/common/messages/go/v17 v17.1.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/getsentry/sentry-go v0.21.0 // indirect
github.com/gofrs/uuid v4.2.0+incompatible // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/lib/pq v1.10.6 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.10.0 // indirect
golang.org/x/sys v0.9.0 // indirect
golang.org/x/text v0.10.0 // indirect
github.com/rogpeppe/go-internal v1.11.0 // indirect
github.com/tendermint/go-amino v0.16.0 // indirect
golang.org/x/net v0.34.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/text v0.21.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250122153221-138b5a5a4fd4 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
pgregory.net/rapid v0.6.2 // indirect
)
// keep grpc 1.67.1 to avoid go minimum version bump (depinject should be compatible with 0.47, 0.50 and 0.52)
replace google.golang.org/grpc => google.golang.org/grpc v1.67.1

View File

@ -1,102 +1,61 @@
github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c=
github.com/alecthomas/participle/v2 v2.0.0-alpha7/go.mod h1:NumScqsC42o9x+dGj8/YqsIfhrIQjFEOFovxotbBirA=
github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1 h1:GDQdwm/gAcJcLAKQQZGOJ4knlw+7rfEQQcmwTbt4p5E=
github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ=
github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w=
github.com/cockroachdb/apd/v3 v3.1.0/go.mod h1:6qgPBMXjATAdD/VefbRP9NoSLKjbB4LCoA7gN4LpHs4=
github.com/cockroachdb/errors v1.10.0 h1:lfxS8zZz1+OjtV4MtNWgboi/W5tyLEB6VQZBXN+0VUU=
github.com/cockroachdb/errors v1.10.0/go.mod h1:lknhIsEVQ9Ss/qKDBQS/UqFSvPQjOwNq2qyKAxtHRqE=
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE=
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs=
github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30=
github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg=
github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA=
github.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRApmI9hjHH05nefC0Ojec=
github.com/cosmos/gogoproto v1.7.0 h1:79USr0oyXAbxg3rspGh/m4SWNyoz/GLaAh0QlCe2fro=
github.com/cosmos/gogoproto v1.7.0/go.mod h1:yWChEv5IUEYURQasfyBW5ffkMHR/90hiHgbNgrtp4j0=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0=
github.com/cucumber/common/gherkin/go/v22 v22.0.0/go.mod h1:3mJT10B2GGn3MvVPd3FwR7m2u4tLhSRhWUqJU4KN4Fg=
github.com/cucumber/common/messages/go/v17 v17.1.1 h1:RNqopvIFyLWnKv0LfATh34SWBhXeoFTJnSrgm9cT/Ts=
github.com/cucumber/common/messages/go/v17 v17.1.1/go.mod h1:bpGxb57tDE385Rb2EohgUadLkAbhoC4IyCFi89u/JQI=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/getsentry/sentry-go v0.21.0 h1:c9l5F1nPF30JIppulk4veau90PK6Smu3abgVtVQWon4=
github.com/getsentry/sentry-go v0.21.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0=
github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs=
github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/regen-network/gocuke v0.6.2 h1:pHviZ0kKAq2U2hN2q3smKNxct6hS0mGByFMHGnWA97M=
github.com/regen-network/gocuke v0.6.2/go.mod h1:zYaqIHZobHyd0xOrHGPQjbhGJsuZ1oElx150u2o1xuk=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E=
github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250122153221-138b5a5a4fd4 h1:yrTuav+chrF0zF/joFGICKTzYv7mh/gr9AgEXrVU8ao=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250122153221-138b5a5a4fd4/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50=
google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o=
gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g=
pgregory.net/rapid v0.6.2 h1:ErW5sL+UKtfBfUTsWHDCoeB+eZKLKMxrSd1VJY6W4bw=
pgregory.net/rapid v0.6.2/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04=
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=

View File

@ -4,8 +4,6 @@ import (
"fmt"
"reflect"
"github.com/cockroachdb/errors"
"cosmossdk.io/depinject/internal/graphviz"
)
@ -85,7 +83,7 @@ func (g *sliceGroupResolver) resolve(c *container, _ *moduleKey, caller Location
}
func (g *groupResolver) resolve(_ *container, _ *moduleKey, _ Location) (reflect.Value, error) {
return reflect.Value{}, errors.Errorf("%v is an many-per-container type and cannot be used as an input value, instead use %v", g.typ, g.sliceType)
return reflect.Value{}, fmt.Errorf("%v is a many-per-container type and cannot be used as an input value, instead use %v", g.typ, g.sliceType)
}
func (g *groupResolver) addNode(n *simpleProvider, i int) error {

View File

@ -0,0 +1,9 @@
version: v1
managed:
enabled: true
go_package_prefix:
default: cosmossdk.io/depinject
plugins:
- name: go-pulsar
out: .
opt: paths=source_relative,Mcosmos/app/v1alpha1/module.proto=cosmossdk.io/depinject/appconfig/v1alpha1

View File

@ -0,0 +1,28 @@
# Generated by buf. DO NOT EDIT.
version: v1
deps:
- remote: buf.build
owner: cosmos
repository: cosmos-proto
commit: 04467658e59e44bbb22fe568206e1f70
digest: shake256:73a640bd60e0c523b0f8237ff34eab67c45a38b64bbbde1d80224819d272dbf316ac183526bd245f994af6608b025f5130483d0133c5edd385531326b5990466
- remote: buf.build
owner: cosmos
repository: cosmos-sdk
commit: cf13c7d232dd405180c2af616fa8a075
digest: shake256:769a38e306a98339b549bc96991c97fae8bd3ceb1a7646c7bfe9a74e406ab068372970fbc5abda1891e2f3c36527cf2d3a25f631739d36900787226e564bb612
- remote: buf.build
owner: cosmos
repository: gogo-proto
commit: 5e5b9fdd01804356895f8f79a6f1ddc1
digest: shake256:0b85da49e2e5f9ebc4806eae058e2f56096ff3b1c59d1fb7c190413dd15f45dd456f0b69ced9059341c80795d2b6c943de15b120a9e0308b499e43e4b5fc2952
- remote: buf.build
owner: googleapis
repository: googleapis
commit: 28151c0d0a1641bf938a7672c500e01d
digest: shake256:49215edf8ef57f7863004539deff8834cfb2195113f0b890dd1f67815d9353e28e668019165b9d872395871eeafcbab3ccfdb2b5f11734d3cca95be9e8d139de
- remote: buf.build
owner: protocolbuffers
repository: wellknowntypes
commit: 657250e6a39648cbb169d079a60bd9ba
digest: shake256:00de25001b8dd2e29d85fc4bcc3ede7aed886d76d67f5e0f7a9b320b90f871d3eb73507d50818d823a0512f3f8db77a11c043685528403e31ff3fef18323a9fb

View File

@ -0,0 +1,11 @@
version: v1
deps:
- buf.build/cosmos/cosmos-sdk
lint:
use:
- DEFAULT
except:
- PACKAGE_VERSION_SUFFIX
breaking:
ignore:
- testpb

View File

@ -0,0 +1,113 @@
package internal
import (
"fmt"
"reflect"
gogoproto "github.com/cosmos/gogoproto/proto"
"github.com/cosmos/gogoproto/protoc-gen-gogo/descriptor"
"google.golang.org/protobuf/encoding/protowire"
protov2 "google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protodesc"
"google.golang.org/protobuf/reflect/protoreflect"
"cosmossdk.io/depinject/appconfig/v1alpha1"
)
// ModuleRegistry is the registry of module initializers indexed by their golang
// type to avoid any issues with protobuf descriptor initialization.
var ModuleRegistry = map[reflect.Type]*ModuleInitializer{}
// ModuleInitializer describes how to initialize a module.
type ModuleInitializer struct {
ConfigGoType reflect.Type
ConfigProtoMessage gogoproto.Message
Error error
Providers []interface{}
Invokers []interface{}
}
// ModulesByModuleTypeName should be used to retrieve modules by their module type name.
// This is done lazily after module registration to deal with non-deterministic issues
// that can occur with respect to protobuf descriptor initialization.
func ModulesByModuleTypeName() (map[string]*ModuleInitializer, error) {
res := map[string]*ModuleInitializer{}
for _, initializer := range ModuleRegistry {
// as of gogoproto v1.5.0 this should work with either gogoproto or golang v2 proto
fullName := gogoproto.MessageName(initializer.ConfigProtoMessage)
if desc, err := gogoproto.HybridResolver.FindDescriptorByName(protoreflect.FullName(fullName)); err == nil {
modDesc, err := GetModuleDescriptor(desc)
if err != nil {
return nil, err
}
if modDesc == nil {
return nil, fmt.Errorf(
"protobuf type %s registered as a module should have the option %s",
desc.FullName(),
v1alpha1.E_Module.Name)
}
if modDesc.GoImport == "" {
return nil, fmt.Errorf(
"protobuf type %s registered as a module should have ModuleDescriptor.go_import specified",
fullName,
)
}
}
if _, ok := res[fullName]; ok {
return nil, fmt.Errorf("duplicate module registration for %s", fullName)
}
res[fullName] = initializer
}
return res, nil
}
// GetModuleDescriptor returns the cosmos.app.v1alpha1.ModuleDescriptor or nil if one isn't found.
// Errors are returned in unexpected cases.
func GetModuleDescriptor(desc protoreflect.Descriptor) (*v1alpha1.ModuleDescriptor, error) {
// we need to take a somewhat round about way to get the extension here
// our most complete type registry has a mix of gogoproto and protoreflect types
// so we start with a protoreflect descriptor, convert it to a gogo descriptor
// and then get the extension by its raw field value to avoid any unmarshaling errors
rawV2Desc := protodesc.ToDescriptorProto(desc.(protoreflect.MessageDescriptor))
bz, err := protov2.Marshal(rawV2Desc)
if err != nil {
return nil, err
}
var gogoDesc descriptor.DescriptorProto
err = gogoproto.Unmarshal(bz, &gogoDesc)
if err != nil {
return nil, err
}
opts := gogoDesc.Options
if !gogoproto.HasExtension(opts, v1alpha1.E_Module) {
return nil, nil
}
bz, err = gogoproto.GetRawExtension(gogoproto.GetUnsafeExtensionsMap(opts), v1alpha1.E_Module.Field)
if err != nil {
return nil, err
}
// we have to skip the field tag and length prefix itself to actually get the raw bytes we want
// this is really overly complex, but other methods caused runtime errors because of validation
// that gogo does that appears simply not necessary
_, _, n := protowire.ConsumeTag(bz)
bz, _ = protowire.ConsumeBytes(bz[n:])
var ext v1alpha1.ModuleDescriptor
err = gogoproto.Unmarshal(bz, &ext)
if err != nil {
return nil, err
}
return &ext, nil
}

View File

@ -0,0 +1,38 @@
syntax = "proto3";
package testpb;
import "cosmos/app/v1alpha1/module.proto";
option go_package = "cosmossdk.io/depinject/internal/appconfig/testpb";
message TestRuntimeModule {
option (cosmos.app.v1alpha1.module) = {
go_import: "cosmossdk.io/core/internal/testpb"
};
}
message TestModuleA {
option (cosmos.app.v1alpha1.module) = {
go_import: "cosmossdk.io/core/internal/testpb"
};
}
message TestModuleB {
option (cosmos.app.v1alpha1.module) = {
go_import: "cosmossdk.io/core/internal/testpb"
};
}
message TestUnregisteredModule {
option (cosmos.app.v1alpha1.module) = {
go_import: "cosmossdk.io/core/internal/testpb"
};
}
message TestNoModuleOptionModule {}
message TestNoGoImportModule {
option (cosmos.app.v1alpha1.module) = {
};
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
version: v1
plugins:
- name: gocosmos
out: .
opt: paths=source_relative,Mcosmos/app/v1alpha1/module.proto=cosmossdk.io/depinject/appconfig/v1alpha1

View File

@ -0,0 +1,28 @@
# Generated by buf. DO NOT EDIT.
version: v1
deps:
- remote: buf.build
owner: cosmos
repository: cosmos-proto
commit: 04467658e59e44bbb22fe568206e1f70
digest: shake256:73a640bd60e0c523b0f8237ff34eab67c45a38b64bbbde1d80224819d272dbf316ac183526bd245f994af6608b025f5130483d0133c5edd385531326b5990466
- remote: buf.build
owner: cosmos
repository: cosmos-sdk
commit: cf13c7d232dd405180c2af616fa8a075
digest: shake256:769a38e306a98339b549bc96991c97fae8bd3ceb1a7646c7bfe9a74e406ab068372970fbc5abda1891e2f3c36527cf2d3a25f631739d36900787226e564bb612
- remote: buf.build
owner: cosmos
repository: gogo-proto
commit: 5e5b9fdd01804356895f8f79a6f1ddc1
digest: shake256:0b85da49e2e5f9ebc4806eae058e2f56096ff3b1c59d1fb7c190413dd15f45dd456f0b69ced9059341c80795d2b6c943de15b120a9e0308b499e43e4b5fc2952
- remote: buf.build
owner: googleapis
repository: googleapis
commit: 28151c0d0a1641bf938a7672c500e01d
digest: shake256:49215edf8ef57f7863004539deff8834cfb2195113f0b890dd1f67815d9353e28e668019165b9d872395871eeafcbab3ccfdb2b5f11734d3cca95be9e8d139de
- remote: buf.build
owner: protocolbuffers
repository: wellknowntypes
commit: 657250e6a39648cbb169d079a60bd9ba
digest: shake256:00de25001b8dd2e29d85fc4bcc3ede7aed886d76d67f5e0f7a9b320b90f871d3eb73507d50818d823a0512f3f8db77a11c043685528403e31ff3fef18323a9fb

View File

@ -0,0 +1,11 @@
version: v1
deps:
- buf.build/cosmos/cosmos-sdk
lint:
use:
- DEFAULT
except:
- PACKAGE_VERSION_SUFFIX
breaking:
ignore:
- testpb

View File

@ -0,0 +1,266 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: testpb/test.proto
package testpb
import (
_ "cosmossdk.io/depinject/appconfig/v1alpha1"
fmt "fmt"
proto "github.com/cosmos/gogoproto/proto"
io "io"
math "math"
math_bits "math/bits"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
type TestModuleGogo struct {
}
func (m *TestModuleGogo) Reset() { *m = TestModuleGogo{} }
func (m *TestModuleGogo) String() string { return proto.CompactTextString(m) }
func (*TestModuleGogo) ProtoMessage() {}
func (*TestModuleGogo) Descriptor() ([]byte, []int) {
return fileDescriptor_41c67e33ca9d1f26, []int{0}
}
func (m *TestModuleGogo) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *TestModuleGogo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_TestModuleGogo.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *TestModuleGogo) XXX_Merge(src proto.Message) {
xxx_messageInfo_TestModuleGogo.Merge(m, src)
}
func (m *TestModuleGogo) XXX_Size() int {
return m.Size()
}
func (m *TestModuleGogo) XXX_DiscardUnknown() {
xxx_messageInfo_TestModuleGogo.DiscardUnknown(m)
}
var xxx_messageInfo_TestModuleGogo proto.InternalMessageInfo
func init() {
proto.RegisterType((*TestModuleGogo)(nil), "testpb.TestModuleGogo")
}
func init() { proto.RegisterFile("testpb/test.proto", fileDescriptor_41c67e33ca9d1f26) }
var fileDescriptor_41c67e33ca9d1f26 = []byte{
// 186 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2c, 0x49, 0x2d, 0x2e,
0x29, 0x48, 0xd2, 0x07, 0x51, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0x6c, 0x10, 0x21, 0x29,
0x85, 0xe4, 0xfc, 0xe2, 0xdc, 0xfc, 0x62, 0xfd, 0xc4, 0x82, 0x02, 0xfd, 0x32, 0xc3, 0xc4, 0x9c,
0x82, 0x8c, 0x44, 0x43, 0xfd, 0xdc, 0xfc, 0x94, 0xd2, 0x9c, 0x54, 0x88, 0x4a, 0x25, 0x4f, 0x2e,
0xbe, 0x90, 0xd4, 0xe2, 0x12, 0x5f, 0xb0, 0x98, 0x7b, 0x7e, 0x7a, 0xbe, 0x95, 0xf9, 0xae, 0x03,
0xd3, 0x6e, 0x31, 0x1a, 0x72, 0xe9, 0x43, 0xf4, 0x16, 0xa7, 0x64, 0xeb, 0x65, 0xe6, 0xeb, 0x27,
0xe7, 0x17, 0xa5, 0xea, 0x67, 0xe6, 0x95, 0xa4, 0x16, 0xe5, 0x25, 0xe6, 0x80, 0xcc, 0x4b, 0xce,
0xcf, 0x4b, 0xcb, 0x4c, 0x4f, 0xcf, 0x4f, 0xcf, 0xd7, 0x87, 0x58, 0xe6, 0xe4, 0x77, 0xe2, 0x91,
0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c, 0xc7, 0x70, 0xe1,
0xb1, 0x1c, 0xc3, 0x8d, 0xc7, 0x72, 0x0c, 0x51, 0x26, 0x28, 0x46, 0xa5, 0xa4, 0x16, 0x64, 0xe6,
0x65, 0xa5, 0x26, 0x97, 0xe0, 0x37, 0x2f, 0x89, 0x0d, 0xec, 0x42, 0x63, 0x40, 0x00, 0x00, 0x00,
0xff, 0xff, 0x1e, 0xdb, 0x22, 0xe2, 0xe0, 0x00, 0x00, 0x00,
}
func (m *TestModuleGogo) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *TestModuleGogo) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *TestModuleGogo) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
return len(dAtA) - i, nil
}
func encodeVarintTest(dAtA []byte, offset int, v uint64) int {
offset -= sovTest(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *TestModuleGogo) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
return n
}
func sovTest(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozTest(x uint64) (n int) {
return sovTest(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *TestModuleGogo) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTest
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: TestModuleGogo: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: TestModuleGogo: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
default:
iNdEx = preIndex
skippy, err := skipTest(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthTest
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipTest(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowTest
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowTest
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowTest
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthTest
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupTest
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthTest
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthTest = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowTest = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupTest = fmt.Errorf("proto: unexpected end of group")
)

View File

@ -0,0 +1,13 @@
syntax = "proto3";
package testpb;
import "cosmos/app/v1alpha1/module.proto";
option go_package = "cosmossdk.io/depinject/internal/appconfiggogo/testpb";
message TestModuleGogo {
option (cosmos.app.v1alpha1.module) = {
go_import: "cosmossdk.io/core/internal/appconfiggogo/testpb"
};
}

View File

@ -1,7 +1,7 @@
package codegen
import (
"fmt"
"errors"
"go/ast"
"go/token"
"strconv"
@ -61,7 +61,7 @@ func NewFileGen(file *ast.File, codegenPkgPath string) (*FileGen, error) {
if spec.Name != nil {
name := spec.Name.Name
if name == "." {
return nil, fmt.Errorf(". package imports are not allowed")
return nil, errors.New(". package imports are not allowed")
}
info = &importInfo{importPrefix: name, ImportSpec: spec}

View File

@ -20,6 +20,5 @@ func IterateMapOrdered[K cmp.Ordered, V any](m map[K]V, forEach func(k K, v V) e
// OrderedMapKeys returns the map keys in ascending order.
func OrderedMapKeys[K cmp.Ordered, V any](m map[K]V) []K {
keys := maps.Keys(m)
return slices.Sorted(keys)
return slices.Sorted(maps.Keys(m))
}

View File

@ -3,32 +3,14 @@ package depinject_test
import (
"testing"
"github.com/regen-network/gocuke"
"gotest.tools/v3/assert"
"github.com/stretchr/testify/require"
"cosmossdk.io/depinject"
)
func TestInvoke(t *testing.T) {
gocuke.NewRunner(t, &InvokeSuite{}).
Path("features/invoke.feature").
Step("an int provider returning 5", (*InvokeSuite).AnIntProviderReturning5).
Step(`a string pointer provider pointing to "foo"`, (*InvokeSuite).AStringPointerProviderPointingToFoo).
Run()
}
type InvokeSuite struct {
gocuke.TestingT
configs []depinject.Config
i int
sp *string
}
func (s *InvokeSuite) AnInvokerRequestingAnIntAndStringPointer() {
s.configs = append(s.configs,
depinject.Supply(s),
depinject.Invoke((*InvokeSuite).IntStringPointerInvoker),
)
i int
sp *string
}
func (s *InvokeSuite) IntStringPointerInvoker(i int, sp *string) {
@ -36,53 +18,67 @@ func (s *InvokeSuite) IntStringPointerInvoker(i int, sp *string) {
s.sp = sp
}
func (s *InvokeSuite) TheContainerIsBuilt() {
assert.NilError(s, depinject.Inject(depinject.Configs(s.configs...)))
}
func (s *InvokeSuite) TheInvokerWillGetTheIntParameterSetTo(a int64) {
assert.Equal(s, int(a), s.i)
}
func (s *InvokeSuite) TheInvokerWillGetTheStringPointerParameterSetToNil() {
if s.sp != nil {
s.Fatalf("expected a nil string pointer, got %s", *s.sp)
}
func ProvideLenModuleKey(key depinject.ModuleKey) int {
return len(key.Name())
}
func IntProvider5() int { return 5 }
func (s *InvokeSuite) AnIntProviderReturning5() {
s.configs = append(s.configs, depinject.Provide(IntProvider5))
}
func StringPtrProviderFoo() *string {
x := "foo"
return &x
}
func (s *InvokeSuite) AStringPointerProviderPointingToFoo() {
s.configs = append(s.configs, depinject.Provide(StringPtrProviderFoo))
}
func TestInvokerNoResolvableDependencies(t *testing.T) {
t.Parallel()
func (s *InvokeSuite) TheInvokerWillGetTheStringPointerParameterSetTo(a string) {
if s.sp == nil {
s.Fatalf("expected a non-nil string pointer")
}
assert.Equal(s, a, *s.sp)
}
func (s *InvokeSuite) AnInvokerRequestingAnIntAndStringPointerRunInModule(a string) {
s.configs = append(s.configs,
depinject.Supply(s),
depinject.InvokeInModule(a, (*InvokeSuite).IntStringPointerInvoker),
invokerSuite := &InvokeSuite{}
configs := depinject.Configs(
depinject.Supply(invokerSuite),
depinject.Invoke((*InvokeSuite).IntStringPointerInvoker),
)
err := depinject.Inject(configs)
require.NoError(t, err)
// invokers get called even if their dependencies can't be resolved
// values are still zeroed
require.Equal(t, 0, invokerSuite.i)
require.Equal(t, (*string)(nil), invokerSuite.sp)
}
func ProvideLenModuleKey(key depinject.ModuleKey) int {
return len(key.Name())
func TestInvokerProvidedDependencies(t *testing.T) {
t.Parallel()
invokerSuite := &InvokeSuite{}
configs := depinject.Configs(
depinject.Supply(invokerSuite),
depinject.Provide(IntProvider5, StringPtrProviderFoo),
depinject.Invoke((*InvokeSuite).IntStringPointerInvoker),
)
err := depinject.Inject(configs)
require.NoError(t, err)
require.Equal(t, 5, invokerSuite.i)
require.Equal(t, "foo", *invokerSuite.sp)
}
func (s *InvokeSuite) AModulescopedIntProviderWhichReturnsTheLengthOfTheModuleName() {
s.configs = append(s.configs, depinject.Provide(ProvideLenModuleKey))
func TestInvokerScopedDependencies(t *testing.T) {
t.Parallel()
moduleName := "test"
invokerSuite := &InvokeSuite{}
configs := depinject.Configs(
depinject.Supply(invokerSuite),
depinject.Provide(ProvideLenModuleKey),
depinject.InvokeInModule(moduleName, (*InvokeSuite).IntStringPointerInvoker),
)
err := depinject.Inject(configs)
require.NoError(t, err)
require.Equal(t, len(moduleName), invokerSuite.i)
require.Equal(t, (*string)(nil), invokerSuite.sp)
}

View File

@ -90,7 +90,7 @@ const _vendor = "/vendor/"
func splitFuncName(function string) (pname, fname string) {
if len(function) == 0 {
return
return "", ""
}
// We have something like "path.to/my/pkg.MyFunction". If the function is

View File

@ -4,8 +4,6 @@ import (
"fmt"
"reflect"
"github.com/cockroachdb/errors"
"cosmossdk.io/depinject/internal/graphviz"
)
@ -46,7 +44,7 @@ type mapOfOnePerModuleResolver struct {
}
func (o *onePerModuleResolver) resolve(_ *container, _ *moduleKey, _ Location) (reflect.Value, error) {
return reflect.Value{}, errors.Errorf("%v is a one-per-module type and thus can't be used as an input parameter, instead use %v", o.typ, o.mapType)
return reflect.Value{}, fmt.Errorf("%v is a one-per-module type and thus can't be used as an input parameter, instead use %v", o.typ, o.mapType)
}
func (o *onePerModuleResolver) describeLocation() string {
@ -72,7 +70,7 @@ func (o *mapOfOnePerModuleResolver) resolve(c *container, _ *moduleKey, caller L
}
idx := o.idxMap[key]
if len(values) <= idx {
return reflect.Value{}, errors.Errorf("expected value of type %T at index %d", o.typ, idx)
return reflect.Value{}, fmt.Errorf("expected value of type %T at index %d", o.typ, idx)
}
value := values[idx]
res.SetMapIndex(reflect.ValueOf(key.name), value)
@ -87,11 +85,11 @@ func (o *mapOfOnePerModuleResolver) resolve(c *container, _ *moduleKey, caller L
func (o *onePerModuleResolver) addNode(n *simpleProvider, i int) error {
if n.moduleKey == nil {
return errors.Errorf("cannot define a provider with one-per-module dependency %v which isn't provided in a module", o.typ)
return fmt.Errorf("cannot define a provider with one-per-module dependency %v which isn't provided in a module", o.typ)
}
if existing, ok := o.providers[n.moduleKey]; ok {
return errors.Errorf("duplicate provision for one-per-module type %v in module %s: %s\n\talready provided by %s",
return fmt.Errorf("duplicate provision for one-per-module type %v in module %s: %s\n\talready provided by %s",
o.typ, n.moduleKey.name, n.provider.Location, existing.provider.Location)
}
@ -102,7 +100,7 @@ func (o *onePerModuleResolver) addNode(n *simpleProvider, i int) error {
}
func (o *mapOfOnePerModuleResolver) addNode(s *simpleProvider, _ int) error {
return errors.Errorf("%v is a one-per-module type and thus %v can't be used as an output parameter in %s", o.typ, o.mapType, s.provider.Location)
return fmt.Errorf("%v is a one-per-module type and thus %v can't be used as an output parameter in %s", o.typ, o.mapType, s.provider.Location)
}
func (o onePerModuleResolver) typeGraphNode() *graphviz.Node {

View File

@ -1,12 +1,11 @@
package depinject
import (
"fmt"
"reflect"
"slices"
"strings"
"unicode"
"github.com/cockroachdb/errors"
)
// providerDescriptor defines a special provider type that is defined by
@ -32,6 +31,7 @@ type providerDescriptor struct {
type providerInput struct {
Type reflect.Type
Optional bool
Ignored bool
}
type providerOutput struct {
@ -65,32 +65,32 @@ func doExtractProviderDescriptor(ctr interface{}) (providerDescriptor, error) {
val := reflect.ValueOf(ctr)
typ := val.Type()
if typ.Kind() != reflect.Func {
return providerDescriptor{}, errors.Errorf("expected a Func type, got %v", typ)
return providerDescriptor{}, fmt.Errorf("expected a Func type, got %v", typ)
}
loc := LocationFromPC(val.Pointer()).(*location)
nameParts := strings.Split(loc.name, ".")
if len(nameParts) == 0 {
return providerDescriptor{}, errors.Errorf("missing function name %s", loc)
return providerDescriptor{}, fmt.Errorf("missing function name %s", loc)
}
lastNamePart := nameParts[len(nameParts)-1]
if unicode.IsLower([]rune(lastNamePart)[0]) {
return providerDescriptor{}, errors.Errorf("function must be exported: %s", loc)
return providerDescriptor{}, fmt.Errorf("function must be exported: %s", loc)
}
if strings.Contains(lastNamePart, "-") {
return providerDescriptor{}, errors.Errorf("function can't be used as a provider (it might be a bound instance method): %s", loc)
return providerDescriptor{}, fmt.Errorf("function can't be used as a provider (it might be a bound instance method): %s", loc)
}
pkgParts := strings.Split(loc.pkg, "/")
if slices.Contains(pkgParts, "internal") {
return providerDescriptor{}, errors.Errorf("function must not be in an internal package: %s", loc)
return providerDescriptor{}, fmt.Errorf("function must not be in an internal package: %s", loc)
}
if typ.IsVariadic() {
return providerDescriptor{}, errors.Errorf("variadic function can't be used as a provider: %s", loc)
return providerDescriptor{}, fmt.Errorf("variadic function can't be used as a provider: %s", loc)
}
numIn := typ.NumIn()
@ -108,7 +108,7 @@ func doExtractProviderDescriptor(ctr interface{}) (providerDescriptor, error) {
t := typ.Out(i)
if t == errType {
if i != numOut-1 {
return providerDescriptor{}, errors.Errorf("output error parameter is not last parameter in function %s", loc)
return providerDescriptor{}, fmt.Errorf("output error parameter is not last parameter in function %s", loc)
}
errIdx = i
} else {

View File

@ -45,7 +45,7 @@ func StructInAndOut(_ float32, _ StructIn, _ byte) (int16, StructOut, int32, err
return int16(0), StructOut{}, int32(0), nil
}
func BadErrorPosition() (error, int) { return nil, 0 } //nolint:revive,stylecheck // Deliberately has error as first of multiple arguments.
func BadErrorPosition() (error, int) { return nil, 0 } //nolint:stylecheck // Deliberately has error as first of multiple arguments.
func BadOptionalFn(_ BadOptional) int { return 0 }

View File

@ -3,14 +3,12 @@ package depinject
import (
"fmt"
"reflect"
"github.com/cockroachdb/errors"
)
// In can be embedded in another struct to inform the container that the
// fields of the struct should be treated as dependency inputs.
// This allows a struct to be used to specify dependencies rather than
// positional parameters.
// positional parameters. Unexpected fields will be ignored.
//
// Fields of the struct may support the following tags:
//
@ -121,13 +119,14 @@ func structArgsInTypes(typ reflect.Type) ([]providerInput, error) {
if optTag == "true" {
optional = true
} else {
return nil, errors.Errorf("bad optional tag %q (should be \"true\") in %v", optTag, typ)
return nil, fmt.Errorf("bad optional tag %q (should be \"true\") in %v", optTag, typ)
}
}
res = append(res, providerInput{
Type: f.Type,
Optional: optional,
Ignored: !f.IsExported(),
})
}
return res, nil
@ -168,13 +167,15 @@ func buildIn(typ reflect.Type, values []reflect.Value) (reflect.Value, int, erro
j := 0
res := reflect.New(typ)
for i := 0; i < numFields; i++ {
if !res.Elem().Field(i).CanSet() {
// private field, skip
j++
continue
}
f := typ.Field(i)
if f.Type.AssignableTo(isInType) {
continue
}
if !res.Elem().Field(i).CanSet() {
return reflect.Value{}, 0, fmt.Errorf("depinject.In struct %s on package %s can't have unexported field", res.Elem().String(), f.PkgPath)
}
if !values[j].CanInterface() {
return reflect.Value{}, 0, fmt.Errorf("depinject.Out struct %s on package %s can't have unexported field", res.Elem().String(), f.PkgPath)
}