@@ -3,10 +3,13 @@ package cli
33import (
44 "fmt"
55 "log/slog"
6+ "strconv"
67
78 pythonv1 "buf.build/gen/go/stealthrocket/dispatch-proto/protocolbuffers/go/dispatch/sdk/python/v1"
8- "google.golang.org/protobuf/proto"
99 "google.golang.org/protobuf/types/known/anypb"
10+ "google.golang.org/protobuf/types/known/durationpb"
11+ "google.golang.org/protobuf/types/known/emptypb"
12+ "google.golang.org/protobuf/types/known/timestamppb"
1013 "google.golang.org/protobuf/types/known/wrapperspb"
1114)
1215
@@ -15,51 +18,72 @@ func anyString(any *anypb.Any) string {
1518 return "nil"
1619 }
1720
18- var s string
19- var err error
20- switch any .TypeUrl {
21- case "buf.build/stealthrocket/dispatch-proto/dispatch.sdk.python.v1.Pickled" :
22- var pickled proto.Message
23- pickled , err = any .UnmarshalNew ()
24- if err == nil {
25- if p , ok := pickled .(* pythonv1.Pickled ); ok {
26- s , err = pythonPickleString (p .PickledValue )
27- } else {
28- err = fmt .Errorf ("invalid pickled message: %T" , p )
29- }
30- }
31- case "type.googleapis.com/google.protobuf.BytesValue" :
32- s , err = anyBytesString (any )
33- default :
34- // TODO: support unpacking other types of serialized values
35- err = fmt .Errorf ("not implemented: %s" , any .TypeUrl )
36- }
21+ m , err := any .UnmarshalNew ()
3722 if err != nil {
38- slog .Debug ("cannot parse input/output value" , "error" , err )
39- return fmt .Sprintf ("%s(?)" , any .TypeUrl )
23+ return unsupportedAny (any , err )
4024 }
41- return s
42- }
4325
44- func anyBytesString (any * anypb.Any ) (string , error ) {
45- m , err := anypb .UnmarshalNew (any , proto.UnmarshalOptions {})
46- if err != nil {
47- return "" , err
48- }
49- bv , ok := m .(* wrapperspb.BytesValue )
50- if ! ok {
51- return "" , fmt .Errorf ("invalid bytes value: %T" , m )
26+ switch mm := m .(type ) {
27+ case * wrapperspb.BytesValue :
28+ // The Python SDK originally wrapped pickled values in a
29+ // wrapperspb.BytesValue. Try to unpickle the bytes first,
30+ // and return literal bytes if they cannot be unpickled.
31+ s , err := pythonPickleString (mm .Value )
32+ if err != nil {
33+ s = fmt .Sprintf ("bytes(%s)" , truncateBytes (mm .Value ))
34+ }
35+ return s
36+
37+ case * wrapperspb.Int32Value :
38+ return strconv .FormatInt (int64 (mm .Value ), 10 )
39+
40+ case * wrapperspb.Int64Value :
41+ return strconv .FormatInt (mm .Value , 10 )
42+
43+ case * wrapperspb.UInt32Value :
44+ return strconv .FormatUint (uint64 (mm .Value ), 10 )
45+
46+ case * wrapperspb.UInt64Value :
47+ return strconv .FormatUint (mm .Value , 10 )
48+
49+ case * wrapperspb.StringValue :
50+ return fmt .Sprintf ("%q" , mm .Value )
51+
52+ case * wrapperspb.BoolValue :
53+ return strconv .FormatBool (mm .Value )
54+
55+ case * wrapperspb.FloatValue :
56+ return fmt .Sprintf ("%v" , mm .Value )
57+
58+ case * wrapperspb.DoubleValue :
59+ return fmt .Sprintf ("%v" , mm .Value )
60+
61+ case * emptypb.Empty :
62+ return "empty()"
63+
64+ case * timestamppb.Timestamp :
65+ return mm .AsTime ().String ()
66+
67+ case * durationpb.Duration :
68+ return mm .AsDuration ().String ()
69+
70+ case * pythonv1.Pickled :
71+ s , err := pythonPickleString (mm .PickledValue )
72+ if err != nil {
73+ return unsupportedAny (any , fmt .Errorf ("pickle error: %w" , err ))
74+ }
75+ return s
76+
77+ default :
78+ return unsupportedAny (any , fmt .Errorf ("not implemented: %T" , m ))
5279 }
53- b := bv . Value
80+ }
5481
55- // The Python SDK originally wrapped pickled values in a
56- // wrapperspb.BytesValue. Try to unpickle the bytes first,
57- // and return literal bytes if they cannot be unpickled.
58- s , err := pythonPickleString (b )
82+ func unsupportedAny (any * anypb.Any , err error ) string {
5983 if err != nil {
60- s = string ( truncateBytes ( b ) )
84+ slog . Debug ( "cannot parse input/output value" , "error" , err )
6185 }
62- return s , nil
86+ return fmt . Sprintf ( "%s(?)" , any . TypeUrl )
6387}
6488
6589func truncateBytes (b []byte ) []byte {
0 commit comments