cosmossdk.io/client/v2@v2.0.0-beta.1/autocli/flag/json_message.go (about)

     1  package flag
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"io"
     7  	"os"
     8  	"regexp"
     9  
    10  	"google.golang.org/protobuf/encoding/protojson"
    11  	"google.golang.org/protobuf/proto"
    12  	"google.golang.org/protobuf/reflect/protoreflect"
    13  
    14  	"cosmossdk.io/client/v2/internal/util"
    15  )
    16  
    17  var isJSONFileRegex = regexp.MustCompile(`\.json$`)
    18  
    19  type jsonMessageFlagType struct {
    20  	messageDesc protoreflect.MessageDescriptor
    21  }
    22  
    23  func (j jsonMessageFlagType) NewValue(_ context.Context, builder *Builder) Value {
    24  	return &jsonMessageFlagValue{
    25  		messageType:          util.ResolveMessageType(builder.TypeResolver, j.messageDesc),
    26  		jsonMarshalOptions:   protojson.MarshalOptions{Resolver: builder.TypeResolver},
    27  		jsonUnmarshalOptions: protojson.UnmarshalOptions{Resolver: builder.TypeResolver},
    28  	}
    29  }
    30  
    31  func (j jsonMessageFlagType) DefaultValue() string {
    32  	return ""
    33  }
    34  
    35  type jsonMessageFlagValue struct {
    36  	jsonMarshalOptions   protojson.MarshalOptions
    37  	jsonUnmarshalOptions protojson.UnmarshalOptions
    38  	messageType          protoreflect.MessageType
    39  	message              proto.Message
    40  }
    41  
    42  func (j *jsonMessageFlagValue) Get(protoreflect.Value) (protoreflect.Value, error) {
    43  	if j.message == nil {
    44  		return protoreflect.Value{}, nil
    45  	}
    46  	return protoreflect.ValueOfMessage(j.message.ProtoReflect()), nil
    47  }
    48  
    49  func (j *jsonMessageFlagValue) String() string {
    50  	if j.message == nil {
    51  		return ""
    52  	}
    53  
    54  	bz, err := j.jsonMarshalOptions.Marshal(j.message)
    55  	if err != nil {
    56  		return err.Error()
    57  	}
    58  	return string(bz)
    59  }
    60  
    61  func (j *jsonMessageFlagValue) Set(s string) error {
    62  	j.message = j.messageType.New().Interface()
    63  	var messageBytes []byte
    64  	if isJSONFileRegex.MatchString(s) {
    65  		jsonFile, err := os.Open(s)
    66  		if err != nil {
    67  			return err
    68  		}
    69  		messageBytes, err = io.ReadAll(jsonFile)
    70  		if err != nil {
    71  			return err
    72  		}
    73  	} else {
    74  		messageBytes = []byte(s)
    75  	}
    76  	return j.jsonUnmarshalOptions.Unmarshal(messageBytes, j.message)
    77  }
    78  
    79  func (j *jsonMessageFlagValue) Type() string {
    80  	return fmt.Sprintf("%s (json)", j.messageType.Descriptor().FullName())
    81  }