87 lines
2.0 KiB
Go
87 lines
2.0 KiB
Go
package flag
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"regexp"
|
|
|
|
"google.golang.org/protobuf/encoding/protojson"
|
|
"google.golang.org/protobuf/proto"
|
|
"google.golang.org/protobuf/reflect/protoreflect"
|
|
|
|
"cosmossdk.io/client/v2/internal/util"
|
|
)
|
|
|
|
var isJSONFileRegex = regexp.MustCompile(`\.json$`)
|
|
|
|
type jsonMessageFlagType struct {
|
|
messageDesc protoreflect.MessageDescriptor
|
|
}
|
|
|
|
func (j jsonMessageFlagType) NewValue(_ *context.Context, builder *Builder) Value {
|
|
return &jsonMessageFlagValue{
|
|
messageType: util.ResolveMessageType(builder.TypeResolver, j.messageDesc),
|
|
jsonMarshalOptions: protojson.MarshalOptions{Resolver: builder.TypeResolver},
|
|
jsonUnmarshalOptions: protojson.UnmarshalOptions{Resolver: builder.TypeResolver},
|
|
}
|
|
}
|
|
|
|
func (j jsonMessageFlagType) DefaultValue() string {
|
|
return ""
|
|
}
|
|
|
|
type jsonMessageFlagValue struct {
|
|
jsonMarshalOptions protojson.MarshalOptions
|
|
jsonUnmarshalOptions protojson.UnmarshalOptions
|
|
messageType protoreflect.MessageType
|
|
message proto.Message
|
|
}
|
|
|
|
func (j *jsonMessageFlagValue) Get(protoreflect.Value) (protoreflect.Value, error) {
|
|
if j.message == nil {
|
|
return protoreflect.Value{}, nil
|
|
}
|
|
return protoreflect.ValueOfMessage(j.message.ProtoReflect()), nil
|
|
}
|
|
|
|
func (j *jsonMessageFlagValue) String() string {
|
|
if j.message == nil {
|
|
return ""
|
|
}
|
|
|
|
bz, err := j.jsonMarshalOptions.Marshal(j.message)
|
|
if err != nil {
|
|
return err.Error()
|
|
}
|
|
return string(bz)
|
|
}
|
|
|
|
func (j *jsonMessageFlagValue) Set(s string) error {
|
|
j.message = j.messageType.New().Interface()
|
|
var messageBytes []byte
|
|
if isJSONFileRegex.MatchString(s) {
|
|
jsonFile, err := os.Open(s)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
messageBytes, err = io.ReadAll(jsonFile)
|
|
if err != nil {
|
|
_ = jsonFile.Close()
|
|
return err
|
|
}
|
|
err = jsonFile.Close()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
messageBytes = []byte(s)
|
|
}
|
|
return j.jsonUnmarshalOptions.Unmarshal(messageBytes, j.message)
|
|
}
|
|
|
|
func (j *jsonMessageFlagValue) Type() string {
|
|
return fmt.Sprintf("%s (json)", j.messageType.Descriptor().FullName())
|
|
}
|