1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-06-28 18:25:23 +00:00

added custom loader for components

This commit is contained in:
Shelikhoo 2021-09-04 19:06:49 +01:00
parent 1ec9a41ee8
commit 7e9f4acd9b
No known key found for this signature in database
GPG Key ID: C4D5E79D22B25316
2 changed files with 20 additions and 12 deletions

View File

@ -1,6 +1,9 @@
package registry package registry
import "github.com/v2fly/v2ray-core/v4/common/protoext" import (
"github.com/golang/protobuf/proto"
"github.com/v2fly/v2ray-core/v4/common/protoext"
)
//go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen
@ -8,12 +11,15 @@ type implementationSet struct {
AliasLookup map[string]*implementation AliasLookup map[string]*implementation
} }
type CustomLoader func(data []byte, dataType string) (proto.Message, error)
type implementation struct { type implementation struct {
FullName string FullName string
Alias []string Alias []string
Loader CustomLoader
} }
func (i *implementationSet) RegisterImplementation(name string, opt *protoext.MessageOpt) { func (i *implementationSet) RegisterImplementation(name string, opt *protoext.MessageOpt, loader CustomLoader) {
alias := opt.GetShortName() alias := opt.GetShortName()
impl := &implementation{ impl := &implementation{
@ -26,12 +32,12 @@ func (i *implementationSet) RegisterImplementation(name string, opt *protoext.Me
} }
} }
func (i *implementationSet) FindImplementationByAlias(alias string) (string, error) { func (i *implementationSet) FindImplementationByAlias(alias string) (string, CustomLoader, error) {
impl, found := i.AliasLookup[alias] impl, found := i.AliasLookup[alias]
if found { if found {
return impl.FullName, nil return impl.FullName, impl.Loader, nil
} }
return "", newError("cannot find implementation by alias") return "", nil, newError("cannot find implementation by alias")
} }
func newImplementationSet() *implementationSet { func newImplementationSet() *implementationSet {

View File

@ -9,20 +9,20 @@ type implementationRegistry struct {
implSet map[string]*implementationSet implSet map[string]*implementationSet
} }
func (i *implementationRegistry) RegisterImplementation(name string, opt *protoext.MessageOpt) { func (i *implementationRegistry) RegisterImplementation(name string, opt *protoext.MessageOpt, loader CustomLoader) {
interfaceType := opt.GetType()[0] interfaceType := opt.GetType()[0]
implSet, found := i.implSet[interfaceType] implSet, found := i.implSet[interfaceType]
if !found { if !found {
implSet = newImplementationSet() implSet = newImplementationSet()
i.implSet[interfaceType] = implSet i.implSet[interfaceType] = implSet
} }
implSet.RegisterImplementation(name, opt) implSet.RegisterImplementation(name, opt, loader)
} }
func (i *implementationRegistry) FindImplementationByAlias(interfaceType, alias string) (string, error) { func (i *implementationRegistry) FindImplementationByAlias(interfaceType, alias string) (string, CustomLoader, error) {
implSet, found := i.implSet[interfaceType] implSet, found := i.implSet[interfaceType]
if !found { if !found {
return "", newError("cannot find implemention unknown interface type") return "", nil, newError("cannot find implemention unknown interface type")
} }
return implSet.FindImplementationByAlias(alias) return implSet.FindImplementationByAlias(alias)
} }
@ -33,17 +33,19 @@ func newImplementationRegistry() *implementationRegistry {
var globalImplementationRegistry = newImplementationRegistry() var globalImplementationRegistry = newImplementationRegistry()
func RegisterImplementation(proto proto.Message) error { // RegisterImplementation register an implementation of a type of interface
// loader(CustomLoader) is a private API, its interface is subject to breaking changes
func RegisterImplementation(proto proto.Message, loader CustomLoader) error {
msgDesc := proto.ProtoReflect().Type().Descriptor() msgDesc := proto.ProtoReflect().Type().Descriptor()
fullName := string(msgDesc.FullName()) fullName := string(msgDesc.FullName())
msgOpts, err := protoext.GetMessageOptions(msgDesc) msgOpts, err := protoext.GetMessageOptions(msgDesc)
if err != nil { if err != nil {
return newError("unable to find message options").Base(err) return newError("unable to find message options").Base(err)
} }
globalImplementationRegistry.RegisterImplementation(fullName, msgOpts) globalImplementationRegistry.RegisterImplementation(fullName, msgOpts, loader)
return nil return nil
} }
func FindImplementationByAlias(interfaceType, alias string) (string, error) { func FindImplementationByAlias(interfaceType, alias string) (string, CustomLoader, error) {
return globalImplementationRegistry.FindImplementationByAlias(interfaceType, alias) return globalImplementationRegistry.FindImplementationByAlias(interfaceType, alias)
} }