@@ -10,18 +10,28 @@ import (
1010 "google.golang.org/protobuf/encoding/protojson"
1111 protov2 "google.golang.org/protobuf/proto"
1212 "google.golang.org/protobuf/reflect/protoreflect"
13+ "google.golang.org/protobuf/types/dynamicpb"
1314 "google.golang.org/protobuf/types/known/anypb"
1415 "sigs.k8s.io/yaml"
1516
16- appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1"
1717 "cosmossdk.io/depinject"
18+ "cosmossdk.io/depinject/appconfig/v1alpha1"
1819 internal "cosmossdk.io/depinject/internal/appconfig"
1920)
2021
2122// LoadJSON loads an app config in JSON format.
2223func LoadJSON (bz []byte ) depinject.Config {
23- config := & appv1alpha1.Config {}
24- err := protojson.UnmarshalOptions {
24+ // in order to avoid a direct dependency on api types, but in order to also be able to support
25+ // either gogo or google.golang.org/protobuf types, we use protojson and dynamicpb to unmarshal
26+ // from JSON
27+ resolver := gogoproto .HybridResolver
28+ desc , err := resolver .FindDescriptorByName (protoreflect .FullName (gogoproto .MessageName (& v1alpha1.Config {})))
29+ if err != nil {
30+ return depinject .Error (err )
31+ }
32+
33+ config := dynamicpb .NewMessage (desc .(protoreflect.MessageDescriptor ))
34+ err = protojson.UnmarshalOptions {
2535 Resolver : dynamicTypeResolver {resolver : gogoproto .HybridResolver },
2636 }.Unmarshal (bz , config )
2737 if err != nil {
@@ -51,9 +61,27 @@ func WrapAny(config protoreflect.ProtoMessage) *anypb.Any {
5161 return cfg
5262}
5363
54- // Compose composes a v1alpha1 app config into a container option by resolving
55- // the required modules and composing their options.
56- func Compose (appConfig * appv1alpha1.Config ) depinject.Config {
64+ // Compose composes an app config into a container option by resolving
65+ // the required modules and composing their options. appConfig should be an instance
66+ // of cosmos.app.v1alpha1.Config (it doesn't matter whether you use gogo proto or
67+ // google.golang.org/protobuf types).
68+ func Compose (appConfig gogoproto.Message ) depinject.Config {
69+ appConfigConcrete , ok := appConfig .(* v1alpha1.Config )
70+ if ! ok {
71+ // we convert any other proto type that was passed (such as an api module type) to the concrete
72+ // type we're using here
73+ appConfigConcrete = & v1alpha1.Config {}
74+ bz , err := gogoproto .Marshal (appConfig )
75+ if err != nil {
76+ return depinject .Error (err )
77+ }
78+
79+ err = gogoproto .Unmarshal (bz , appConfigConcrete )
80+ if err != nil {
81+ return depinject .Error (err )
82+ }
83+ }
84+
5785 opts := []depinject.Config {
5886 depinject .Supply (appConfig ),
5987 }
@@ -63,7 +91,7 @@ func Compose(appConfig *appv1alpha1.Config) depinject.Config {
6391 return depinject .Error (err )
6492 }
6593
66- for _ , module := range appConfig .Modules {
94+ for _ , module := range appConfigConcrete .Modules {
6795 if module .Name == "" {
6896 return depinject .Error (fmt .Errorf ("module is missing name" ))
6997 }
@@ -84,10 +112,14 @@ func Compose(appConfig *appv1alpha1.Config) depinject.Config {
84112 init , ok := modules [msgName ]
85113 if ! ok {
86114 if msgDesc , err := gogoproto .HybridResolver .FindDescriptorByName (protoreflect .FullName (msgName )); err == nil {
87- modDesc := protov2 .GetExtension (msgDesc .Options (), appv1alpha1 .E_Module ).(* appv1alpha1.ModuleDescriptor )
115+ modDesc , err := internal .GetModuleDescriptor (msgDesc )
116+ if err != nil {
117+ return depinject .Error (err )
118+ }
119+
88120 if modDesc == nil {
89121 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" ,
90- module .Config .TypeUrl , appv1alpha1 .E_Module .TypeDescriptor (). FullName () , dumpRegisteredModules (modules )))
122+ module .Config .TypeUrl , v1alpha1 .E_Module .Name , dumpRegisteredModules (modules )))
91123 }
92124
93125 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" ,
@@ -122,7 +154,7 @@ func Compose(appConfig *appv1alpha1.Config) depinject.Config {
122154 }
123155 }
124156
125- for _ , binding := range appConfig .GolangBindings {
157+ for _ , binding := range appConfigConcrete .GolangBindings {
126158 opts = append (opts , depinject .BindInterface (binding .InterfaceType , binding .Implementation ))
127159 }
128160
0 commit comments