diff --git a/ast/mock_visitor_test.go b/ast/mock_visitor_test.go index 6c375aee..6cc5b83a 100644 --- a/ast/mock_visitor_test.go +++ b/ast/mock_visitor_test.go @@ -5,8 +5,9 @@ package ast import ( - gomock "github.com/golang/mock/gomock" reflect "reflect" + + gomock "github.com/golang/mock/gomock" ) // MockVisitor is a mock of Visitor interface diff --git a/gen/benchmark_test.go b/gen/benchmark_test.go index 7531f8a7..3566866a 100644 --- a/gen/benchmark_test.go +++ b/gen/benchmark_test.go @@ -9,6 +9,8 @@ import ( tc "go.uber.org/thriftrw/gen/internal/tests/containers" ts "go.uber.org/thriftrw/gen/internal/tests/structs" "go.uber.org/thriftrw/protocol" + "go.uber.org/thriftrw/protocol/binary" + "go.uber.org/thriftrw/protocol/stream" "go.uber.org/thriftrw/ptr" "go.uber.org/thriftrw/wire" ) @@ -18,6 +20,12 @@ type thriftType interface { FromWire(wire.Value) error } +type streamingThriftType interface { + thriftType + + Encode(stream.Writer) error +} + func BenchmarkRoundTrip(b *testing.B) { type benchCase struct { name string @@ -119,6 +127,19 @@ func BenchmarkRoundTrip(b *testing.B) { } } + benchmarkStreamEncode := func(b *testing.B, bb benchCase) { + var buff bytes.Buffer + + b.ResetTimer() + for i := 0; i < b.N; i++ { + buff.Reset() + + writer := binary.BorrowStreamWriter(&buff) + require.NoError(b, bb.give.(streamingThriftType).Encode(writer), "StreamEncode") + binary.ReturnStreamWriter(writer) + } + } + benchmarkDecode := func(b *testing.B, bb benchCase) { var buff bytes.Buffer w, err := bb.give.ToWire() @@ -144,6 +165,10 @@ func BenchmarkRoundTrip(b *testing.B) { benchmarkEncode(b, bb) }) + b.Run("Stream Encode", func(b *testing.B) { + benchmarkStreamEncode(b, bb) + }) + b.Run("Decode", func(b *testing.B) { benchmarkDecode(b, bb) }) diff --git a/gen/container_test.go b/gen/container_test.go index b7dcab69..2bbff729 100644 --- a/gen/container_test.go +++ b/gen/container_test.go @@ -180,6 +180,9 @@ func TestCollectionsOfPrimitives(t *testing.T) { for _, tt := range tests { assertRoundTrip(t, &tt.p, tt.v, tt.desc) assert.True(t, tt.p.Equals(&tt.p), tt.desc) + + testRoundTripCombos(t, &tt.p, tt.v, tt.desc) + assert.True(t, tt.p.Equals(&tt.p), tt.desc) } } @@ -351,6 +354,9 @@ func TestEnumContainers(t *testing.T) { for _, tt := range tests { assertRoundTrip(t, &tt.r, tt.v, "EnumContainers") assert.True(t, tt.r.Equals(&tt.r), "EnumContainers equal") + + testRoundTripCombos(t, &tt.r, tt.v, "EnumContainers") + assert.True(t, tt.r.Equals(&tt.r), "EnumContainers equal") } } @@ -506,6 +512,9 @@ func TestListOfStructs(t *testing.T) { for _, tt := range tests { assertRoundTrip(t, &tt.r, tt.v, "Graph") assert.True(t, tt.r.Equals(&tt.r), "Graph equal") + + testRoundTripCombos(t, &tt.r, tt.v, "Graph") + assert.True(t, tt.r.Equals(&tt.r), "Graph equal") } } @@ -949,6 +958,9 @@ func TestCrazyTown(t *testing.T) { for _, tt := range tests { assertRoundTrip(t, &tt.x, tt.v, tt.desc) assert.True(t, tt.x.Equals(&tt.x), tt.desc) + + testRoundTripCombos(t, &tt.x, tt.v, tt.desc) + assert.True(t, tt.x.Equals(&tt.x), tt.desc) } } diff --git a/gen/enum.go b/gen/enum.go index 1fd10c9f..0caa83a9 100644 --- a/gen/enum.go +++ b/gen/enum.go @@ -68,6 +68,7 @@ func enum(g Generator, spec *compile.EnumSpec) error { <$math := import "math"> <$strconv := import "strconv"> + <$stream := import "go.uber.org/thriftrw/protocol/stream"> <$wire := import "go.uber.org/thriftrw/wire"> <$enumName := goName .Spec> @@ -162,6 +163,20 @@ func enum(g Generator, spec *compile.EnumSpec) error { return &<$v> } + <$sw := newVar "sw"> + // Encode encodes <$enumName> directly to the wire. + // + // sWriter := BinaryStreamer.Writer(writer) + // + // var <$v> <$enumName> + // if err := <$v>.Encode(sWriter); err != nil { + // return err + // } + // return nil + func (<$v> <$enumName>) Encode(<$sw> <$stream>.Writer) error { + return <$sw>.WriteInt32(int32(<$v>)) + } + // ToWire translates <$enumName> into a Thrift-level intermediate // representation. This intermediate representation may be serialized // into bytes using a ThriftRW protocol implementation. diff --git a/gen/enum_test.go b/gen/enum_test.go index 93f41b09..b071b47f 100644 --- a/gen/enum_test.go +++ b/gen/enum_test.go @@ -108,6 +108,7 @@ func TestEnumDefaultWire(t *testing.T) { for _, tt := range tests { assertRoundTrip(t, &tt.e, tt.v, "EnumDefault") + testRoundTripCombos(t, &tt.e, tt.v, "EnumDefault") } } @@ -154,6 +155,7 @@ func TestEnumWithDuplicateValuesWire(t *testing.T) { for _, tt := range tests { assertRoundTrip(t, &tt.e, tt.v, "EnumWithDuplicateValues") + testRoundTripCombos(t, &tt.e, tt.v, "EnumWithDuplicateValues") } } @@ -185,6 +187,7 @@ func TestOptionalEnum(t *testing.T) { for _, tt := range tests { assertRoundTrip(t, &tt.s, tt.v, "StructWithOptionalEnum") + testRoundTripCombos(t, &tt.s, tt.v, "StructWithOptionalEnum") } } diff --git a/gen/field.go b/gen/field.go index 36b209dc..718dc32d 100644 --- a/gen/field.go +++ b/gen/field.go @@ -44,6 +44,7 @@ var reservedIdentifiers = map[string]struct{}{ "FromWire": {}, "String": {}, "Equals": {}, + "Encode": {}, } // fieldGroupGenerator is responsible for generating code for FieldGroups. @@ -95,6 +96,10 @@ func (f fieldGroupGenerator) Generate(g Generator) error { return err } + if err := f.Encode(g); err != nil { + return err + } + if err := f.String(g); err != nil { return err } @@ -467,6 +472,106 @@ func (f fieldGroupGenerator) FromWire(g Generator) error { `, f, TemplateFunc("constantValuePtr", ConstantValuePtr)) } +func (f fieldGroupGenerator) Encode(g Generator) error { + return g.DeclareFromTemplate( + ` + <$stream := import "go.uber.org/thriftrw/protocol/stream"> + + <$v := newVar "v"> + <$sw := newVar "sw"> + // Encode serializes a <.Name> struct directly into bytes, without going + // through an intemediary type. + // + // An error is returned if a <.Name> struct could not be encoded. + func (<$v> *<.Name>) Encode(<$sw> <$stream>.Writer) error { + <- $i := newVar "i" -> + + var ( + + <$i> int = 0 + err error + fh <$stream>.FieldHeader + <- end> + ) + + if err := <$sw>.WriteStructBegin(); err != nil { + return err + } + + <$structName := .Name> + + <- $fname := goName . -> + <- $f := printf "%s.%s" $v $fname -> + <$t := typeCode .Type> + <- if .Required -> + <- if and (not (isPrimitiveType .Type)) (not (isListType .Type)) -> + if <$f> == nil { + return .New("field <$fname> of <$structName> is required") + } + <- end> + fh = <$stream>.FieldHeader{ID: <.ID>, Type: <$t>,} + if err := <$sw>.WriteFieldBegin(fh); err != nil { + return err + } + if err := ; err != nil { + return err + } + if err := <$sw>.WriteFieldEnd(); err != nil { + return err + } + <$i>++ + <- else -> + <- if isNotNil .Default -> + <- $fval := printf "%s%s" $v $fname -> + <$fval> := <$f> + if <$fval> == nil { + <$fval> = + } + { + fh = <$stream>.FieldHeader{ID: <.ID>, Type: <$t>,} + if err := <$sw>.WriteFieldBegin(fh); err != nil { + return err + } + if err := ; err != nil { + return err + } + <- else -> + if <$f> != nil { + fh = <$stream>.FieldHeader{ID: <.ID>, Type: <$t>,} + if err := <$sw>.WriteFieldBegin(fh); err != nil { + return err + } + if err := ; err != nil { + return err + } + <- end> + if err := <$sw>.WriteFieldEnd(); err != nil { + return err + } + <$i>++ + } + <- end> + + + + + <$fmt := import "fmt"> + + if <$i> > 1 { + return <$fmt>.Errorf("<.Name> should have at most one field: got %v fields", <$i>) + } + + if <$i> != 1 { + return <$fmt>.Errorf("<.Name> should have exactly one field: got %v fields", <$i>) + } + + + + return <$sw>.WriteStructEnd() + } + `, f, TemplateFunc("constantValuePtr", ConstantValuePtr)) +} + func (f fieldGroupGenerator) String(g Generator) error { return g.DeclareFromTemplate( ` diff --git a/gen/generator.go b/gen/generator.go index ccae5fbc..79b91b61 100644 --- a/gen/generator.go +++ b/gen/generator.go @@ -129,6 +129,7 @@ type generator struct { w WireGenerator e equalsGenerator z zapGenerator + s StreamGenerator noZap bool decls []ast.Decl thriftImporter ThriftPackageImporter @@ -233,6 +234,8 @@ func (g *generator) TextTemplate(s string, data interface{}, opts ...TemplateOpt "typeReferencePtr": curryGenerator(typeReferencePtr, g), "fromWire": curryGenerator(g.w.FromWire, g), "fromWirePtr": curryGenerator(g.w.FromWirePtr, g), + "encode": curryGenerator(g.s.Encode, g), + "encodePtr": curryGenerator(g.s.EncodePtr, g), "toWire": curryGenerator(g.w.ToWire, g), "toWirePtr": curryGenerator(g.w.ToWirePtr, g), "typeCode": curryGenerator(TypeCode, g), diff --git a/gen/internal/tests/collision/collision.go b/gen/internal/tests/collision/collision.go index 277acaf1..7633ed73 100644 --- a/gen/internal/tests/collision/collision.go +++ b/gen/internal/tests/collision/collision.go @@ -9,6 +9,7 @@ import ( errors "errors" fmt "fmt" multierr "go.uber.org/multierr" + stream "go.uber.org/thriftrw/protocol/stream" thriftreflect "go.uber.org/thriftrw/thriftreflect" wire "go.uber.org/thriftrw/wire" zapcore "go.uber.org/zap/zapcore" @@ -137,6 +138,66 @@ func (v *AccessorConflict) FromWire(w wire.Value) error { return nil } +// Encode serializes a AccessorConflict struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a AccessorConflict struct could not be encoded. +func (v *AccessorConflict) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.Name != nil { + fh = stream.FieldHeader{ID: 1, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(*(v.Name)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.GetName2 != nil { + fh = stream.FieldHeader{ID: 2, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(*(v.GetName2)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.IsSetName2 != nil { + fh = stream.FieldHeader{ID: 3, Type: wire.TBool} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteBool(*(v.IsSetName2)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a AccessorConflict // struct. func (v *AccessorConflict) String() string { @@ -364,6 +425,52 @@ func (v *AccessorNoConflict) FromWire(w wire.Value) error { return nil } +// Encode serializes a AccessorNoConflict struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a AccessorNoConflict struct could not be encoded. +func (v *AccessorNoConflict) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.Getname != nil { + fh = stream.FieldHeader{ID: 1, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(*(v.Getname)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.GetName != nil { + fh = stream.FieldHeader{ID: 2, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(*(v.GetName)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a AccessorNoConflict // struct. func (v *AccessorNoConflict) String() string { @@ -471,6 +578,11 @@ func (v LittlePotatoe) String() string { return fmt.Sprint(x) } +func (v LittlePotatoe) Encode(sw stream.Writer) error { + x := (int64)(v) + return sw.WriteInt64(x) +} + // FromWire deserializes LittlePotatoe from its Thrift-level // representation. The Thrift-level representation may be obtained // from a ThriftRW protocol implementation. @@ -587,6 +699,19 @@ func (v MyEnum) Ptr() *MyEnum { return &v } +// Encode encodes MyEnum directly to the wire. +// +// sWriter := BinaryStreamer.Writer(writer) +// +// var v MyEnum +// if err := v.Encode(sWriter); err != nil { +// return err +// } +// return nil +func (v MyEnum) Encode(sw stream.Writer) error { + return sw.WriteInt32(int32(v)) +} + // ToWire translates MyEnum into a Thrift-level intermediate // representation. This intermediate representation may be serialized // into bytes using a ThriftRW protocol implementation. @@ -957,6 +1082,134 @@ func (v *PrimitiveContainers) FromWire(w wire.Value) error { return nil } +func _List_String_Encode(val []string, sw stream.Writer) error { + var ( + err error + ) + + lh := stream.ListHeader{ + Type: wire.TBinary, + Length: len(val), + } + if err := sw.WriteListBegin(lh); err != nil { + return err + } + + for _, v := range val { + if err := sw.WriteString(v); err != nil { + return err + } + } + return sw.WriteListEnd() +} + +func _Set_String_mapType_Encode(val map[string]struct{}, sw stream.Writer) error { + var err error + + sh := stream.SetHeader{ + Type: wire.TBinary, + Length: len(val), + } + + if err := sw.WriteSetBegin(sh); err != nil { + return err + } + + for v, _ := range val { + + if err := sw.WriteString(v); err != nil { + return err + } + } + return sw.WriteSetEnd() +} + +func _Map_String_String_Encode(val map[string]string, sw stream.Writer) error { + var ( + err error + ) + + mh := stream.MapHeader{ + KeyType: wire.TBinary, + ValueType: wire.TBinary, + Length: len(val), + } + if err := sw.WriteMapBegin(mh); err != nil { + return err + } + + for k, v := range val { + if err := sw.WriteString(k); err != nil { + return err + } + if err := sw.WriteString(v); err != nil { + return err + } + } + + return sw.WriteMapEnd() +} + +// Encode serializes a PrimitiveContainers struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a PrimitiveContainers struct could not be encoded. +func (v *PrimitiveContainers) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.A != nil { + fh = stream.FieldHeader{ID: 1, Type: wire.TList} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _List_String_Encode(v.A, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.B != nil { + fh = stream.FieldHeader{ID: 3, Type: wire.TSet} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _Set_String_mapType_Encode(v.B, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.C != nil { + fh = stream.FieldHeader{ID: 5, Type: wire.TMap} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _Map_String_String_Encode(v.C, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a PrimitiveContainers // struct. func (v *PrimitiveContainers) String() string { @@ -1247,6 +1500,48 @@ func (v *StructCollision) FromWire(w wire.Value) error { return nil } +// Encode serializes a StructCollision struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a StructCollision struct could not be encoded. +func (v *StructCollision) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + fh = stream.FieldHeader{ID: 1, Type: wire.TBool} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteBool(v.CollisionField); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + fh = stream.FieldHeader{ID: 2, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(v.CollisionField2); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a StructCollision // struct. func (v *StructCollision) String() string { @@ -1424,6 +1719,56 @@ func (v *UnionCollision) FromWire(w wire.Value) error { return nil } +// Encode serializes a UnionCollision struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a UnionCollision struct could not be encoded. +func (v *UnionCollision) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.CollisionField != nil { + fh = stream.FieldHeader{ID: 1, Type: wire.TBool} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteBool(*(v.CollisionField)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.CollisionField2 != nil { + fh = stream.FieldHeader{ID: 2, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(*(v.CollisionField2)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if i != 1 { + return fmt.Errorf("UnionCollision should have exactly one field: got %v fields", i) + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a UnionCollision // struct. func (v *UnionCollision) String() string { @@ -1616,6 +1961,45 @@ func (v *WithDefault) FromWire(w wire.Value) error { return nil } +// Encode serializes a WithDefault struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a WithDefault struct could not be encoded. +func (v *WithDefault) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + vPouet := v.Pouet + if vPouet == nil { + vPouet = &StructCollision2{ + CollisionField: false, + CollisionField2: "false indeed", + } + } + { + fh = stream.FieldHeader{ID: 1, Type: wire.TStruct} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := vPouet.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a WithDefault // struct. func (v *WithDefault) String() string { @@ -1701,6 +2085,11 @@ func (v LittlePotatoe2) String() string { return fmt.Sprint(x) } +func (v LittlePotatoe2) Encode(sw stream.Writer) error { + x := (float64)(v) + return sw.WriteDouble(x) +} + // FromWire deserializes LittlePotatoe2 from its Thrift-level // representation. The Thrift-level representation may be obtained // from a ThriftRW protocol implementation. @@ -1799,6 +2188,19 @@ func (v MyEnum2) Ptr() *MyEnum2 { return &v } +// Encode encodes MyEnum2 directly to the wire. +// +// sWriter := BinaryStreamer.Writer(writer) +// +// var v MyEnum2 +// if err := v.Encode(sWriter); err != nil { +// return err +// } +// return nil +func (v MyEnum2) Encode(sw stream.Writer) error { + return sw.WriteInt32(int32(v)) +} + // ToWire translates MyEnum2 into a Thrift-level intermediate // representation. This intermediate representation may be serialized // into bytes using a ThriftRW protocol implementation. @@ -2000,6 +2402,48 @@ func (v *StructCollision2) FromWire(w wire.Value) error { return nil } +// Encode serializes a StructCollision2 struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a StructCollision2 struct could not be encoded. +func (v *StructCollision2) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + fh = stream.FieldHeader{ID: 1, Type: wire.TBool} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteBool(v.CollisionField); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + fh = stream.FieldHeader{ID: 2, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(v.CollisionField2); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a StructCollision2 // struct. func (v *StructCollision2) String() string { @@ -2177,6 +2621,56 @@ func (v *UnionCollision2) FromWire(w wire.Value) error { return nil } +// Encode serializes a UnionCollision2 struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a UnionCollision2 struct could not be encoded. +func (v *UnionCollision2) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.CollisionField != nil { + fh = stream.FieldHeader{ID: 1, Type: wire.TBool} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteBool(*(v.CollisionField)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.CollisionField2 != nil { + fh = stream.FieldHeader{ID: 2, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(*(v.CollisionField2)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if i != 1 { + return fmt.Errorf("UnionCollision2 should have exactly one field: got %v fields", i) + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a UnionCollision2 // struct. func (v *UnionCollision2) String() string { diff --git a/gen/internal/tests/containers/containers.go b/gen/internal/tests/containers/containers.go index c43c54db..39e26b9e 100644 --- a/gen/internal/tests/containers/containers.go +++ b/gen/internal/tests/containers/containers.go @@ -13,6 +13,7 @@ import ( enums "go.uber.org/thriftrw/gen/internal/tests/enums" typedefs "go.uber.org/thriftrw/gen/internal/tests/typedefs" uuid_conflict "go.uber.org/thriftrw/gen/internal/tests/uuid_conflict" + stream "go.uber.org/thriftrw/protocol/stream" thriftreflect "go.uber.org/thriftrw/thriftreflect" wire "go.uber.org/thriftrw/wire" zapcore "go.uber.org/zap/zapcore" @@ -1226,6 +1227,573 @@ func (v *ContainersOfContainers) FromWire(w wire.Value) error { return nil } +func _List_I32_Encode(val []int32, sw stream.Writer) error { + var ( + err error + ) + + lh := stream.ListHeader{ + Type: wire.TI32, + Length: len(val), + } + if err := sw.WriteListBegin(lh); err != nil { + return err + } + + for _, v := range val { + if err := sw.WriteInt32(v); err != nil { + return err + } + } + return sw.WriteListEnd() +} + +func _List_List_I32_Encode(val [][]int32, sw stream.Writer) error { + var ( + err error + ) + + lh := stream.ListHeader{ + Type: wire.TList, + Length: len(val), + } + if err := sw.WriteListBegin(lh); err != nil { + return err + } + + for _, v := range val { + if err := _List_I32_Encode(v, sw); err != nil { + return err + } + } + return sw.WriteListEnd() +} + +func _Set_I32_mapType_Encode(val map[int32]struct{}, sw stream.Writer) error { + var err error + + sh := stream.SetHeader{ + Type: wire.TI32, + Length: len(val), + } + + if err := sw.WriteSetBegin(sh); err != nil { + return err + } + + for v, _ := range val { + + if err := sw.WriteInt32(v); err != nil { + return err + } + } + return sw.WriteSetEnd() +} + +func _List_Set_I32_mapType_Encode(val []map[int32]struct{}, sw stream.Writer) error { + var ( + err error + ) + + lh := stream.ListHeader{ + Type: wire.TSet, + Length: len(val), + } + if err := sw.WriteListBegin(lh); err != nil { + return err + } + + for _, v := range val { + if err := _Set_I32_mapType_Encode(v, sw); err != nil { + return err + } + } + return sw.WriteListEnd() +} + +func _Map_I32_I32_Encode(val map[int32]int32, sw stream.Writer) error { + var ( + err error + ) + + mh := stream.MapHeader{ + KeyType: wire.TI32, + ValueType: wire.TI32, + Length: len(val), + } + if err := sw.WriteMapBegin(mh); err != nil { + return err + } + + for k, v := range val { + if err := sw.WriteInt32(k); err != nil { + return err + } + if err := sw.WriteInt32(v); err != nil { + return err + } + } + + return sw.WriteMapEnd() +} + +func _List_Map_I32_I32_Encode(val []map[int32]int32, sw stream.Writer) error { + var ( + err error + ) + + lh := stream.ListHeader{ + Type: wire.TMap, + Length: len(val), + } + if err := sw.WriteListBegin(lh); err != nil { + return err + } + + for _, v := range val { + if err := _Map_I32_I32_Encode(v, sw); err != nil { + return err + } + } + return sw.WriteListEnd() +} + +func _Set_String_mapType_Encode(val map[string]struct{}, sw stream.Writer) error { + var err error + + sh := stream.SetHeader{ + Type: wire.TBinary, + Length: len(val), + } + + if err := sw.WriteSetBegin(sh); err != nil { + return err + } + + for v, _ := range val { + + if err := sw.WriteString(v); err != nil { + return err + } + } + return sw.WriteSetEnd() +} + +func _Set_Set_String_mapType_sliceType_Encode(val []map[string]struct{}, sw stream.Writer) error { + var err error + + sh := stream.SetHeader{ + Type: wire.TSet, + Length: len(val), + } + + if err := sw.WriteSetBegin(sh); err != nil { + return err + } + + for _, v := range val { + + if err := _Set_String_mapType_Encode(v, sw); err != nil { + return err + } + } + return sw.WriteSetEnd() +} + +func _List_String_Encode(val []string, sw stream.Writer) error { + var ( + err error + ) + + lh := stream.ListHeader{ + Type: wire.TBinary, + Length: len(val), + } + if err := sw.WriteListBegin(lh); err != nil { + return err + } + + for _, v := range val { + if err := sw.WriteString(v); err != nil { + return err + } + } + return sw.WriteListEnd() +} + +func _Set_List_String_sliceType_Encode(val [][]string, sw stream.Writer) error { + var err error + + sh := stream.SetHeader{ + Type: wire.TList, + Length: len(val), + } + + if err := sw.WriteSetBegin(sh); err != nil { + return err + } + + for _, v := range val { + + if err := _List_String_Encode(v, sw); err != nil { + return err + } + } + return sw.WriteSetEnd() +} + +func _Map_String_String_Encode(val map[string]string, sw stream.Writer) error { + var ( + err error + ) + + mh := stream.MapHeader{ + KeyType: wire.TBinary, + ValueType: wire.TBinary, + Length: len(val), + } + if err := sw.WriteMapBegin(mh); err != nil { + return err + } + + for k, v := range val { + if err := sw.WriteString(k); err != nil { + return err + } + if err := sw.WriteString(v); err != nil { + return err + } + } + + return sw.WriteMapEnd() +} + +func _Set_Map_String_String_sliceType_Encode(val []map[string]string, sw stream.Writer) error { + var err error + + sh := stream.SetHeader{ + Type: wire.TMap, + Length: len(val), + } + + if err := sw.WriteSetBegin(sh); err != nil { + return err + } + + for _, v := range val { + + if err := _Map_String_String_Encode(v, sw); err != nil { + return err + } + } + return sw.WriteSetEnd() +} + +func _Map_String_I32_Encode(val map[string]int32, sw stream.Writer) error { + var ( + err error + ) + + mh := stream.MapHeader{ + KeyType: wire.TBinary, + ValueType: wire.TI32, + Length: len(val), + } + if err := sw.WriteMapBegin(mh); err != nil { + return err + } + + for k, v := range val { + if err := sw.WriteString(k); err != nil { + return err + } + if err := sw.WriteInt32(v); err != nil { + return err + } + } + + return sw.WriteMapEnd() +} + +func _Map_Map_String_I32_I64_Encode(val []struct { + Key map[string]int32 + Value int64 +}, sw stream.Writer) error { + var ( + err error + ) + + mh := stream.MapHeader{ + KeyType: wire.TMap, + ValueType: wire.TI64, + Length: len(val), + } + if err := sw.WriteMapBegin(mh); err != nil { + return err + } + + for _, v := range val { + key := v.Key + if err := _Map_String_I32_Encode(key, sw); err != nil { + return err + } + value := v.Value + if err := sw.WriteInt64(value); err != nil { + return err + } + } + + return sw.WriteMapEnd() +} + +func _Set_I64_mapType_Encode(val map[int64]struct{}, sw stream.Writer) error { + var err error + + sh := stream.SetHeader{ + Type: wire.TI64, + Length: len(val), + } + + if err := sw.WriteSetBegin(sh); err != nil { + return err + } + + for v, _ := range val { + + if err := sw.WriteInt64(v); err != nil { + return err + } + } + return sw.WriteSetEnd() +} + +func _Map_List_I32_Set_I64_mapType_Encode(val []struct { + Key []int32 + Value map[int64]struct{} +}, sw stream.Writer) error { + var ( + err error + ) + + mh := stream.MapHeader{ + KeyType: wire.TList, + ValueType: wire.TSet, + Length: len(val), + } + if err := sw.WriteMapBegin(mh); err != nil { + return err + } + + for _, v := range val { + key := v.Key + if err := _List_I32_Encode(key, sw); err != nil { + return err + } + value := v.Value + if err := _Set_I64_mapType_Encode(value, sw); err != nil { + return err + } + } + + return sw.WriteMapEnd() +} + +func _List_Double_Encode(val []float64, sw stream.Writer) error { + var ( + err error + ) + + lh := stream.ListHeader{ + Type: wire.TDouble, + Length: len(val), + } + if err := sw.WriteListBegin(lh); err != nil { + return err + } + + for _, v := range val { + if err := sw.WriteDouble(v); err != nil { + return err + } + } + return sw.WriteListEnd() +} + +func _Map_Set_I32_mapType_List_Double_Encode(val []struct { + Key map[int32]struct{} + Value []float64 +}, sw stream.Writer) error { + var ( + err error + ) + + mh := stream.MapHeader{ + KeyType: wire.TSet, + ValueType: wire.TList, + Length: len(val), + } + if err := sw.WriteMapBegin(mh); err != nil { + return err + } + + for _, v := range val { + key := v.Key + if err := _Set_I32_mapType_Encode(key, sw); err != nil { + return err + } + value := v.Value + if err := _List_Double_Encode(value, sw); err != nil { + return err + } + } + + return sw.WriteMapEnd() +} + +// Encode serializes a ContainersOfContainers struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a ContainersOfContainers struct could not be encoded. +func (v *ContainersOfContainers) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.ListOfLists != nil { + fh = stream.FieldHeader{ID: 1, Type: wire.TList} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _List_List_I32_Encode(v.ListOfLists, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.ListOfSets != nil { + fh = stream.FieldHeader{ID: 2, Type: wire.TList} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _List_Set_I32_mapType_Encode(v.ListOfSets, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.ListOfMaps != nil { + fh = stream.FieldHeader{ID: 3, Type: wire.TList} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _List_Map_I32_I32_Encode(v.ListOfMaps, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.SetOfSets != nil { + fh = stream.FieldHeader{ID: 4, Type: wire.TSet} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _Set_Set_String_mapType_sliceType_Encode(v.SetOfSets, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.SetOfLists != nil { + fh = stream.FieldHeader{ID: 5, Type: wire.TSet} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _Set_List_String_sliceType_Encode(v.SetOfLists, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.SetOfMaps != nil { + fh = stream.FieldHeader{ID: 6, Type: wire.TSet} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _Set_Map_String_String_sliceType_Encode(v.SetOfMaps, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.MapOfMapToInt != nil { + fh = stream.FieldHeader{ID: 7, Type: wire.TMap} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _Map_Map_String_I32_I64_Encode(v.MapOfMapToInt, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.MapOfListToSet != nil { + fh = stream.FieldHeader{ID: 8, Type: wire.TMap} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _Map_List_I32_Set_I64_mapType_Encode(v.MapOfListToSet, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.MapOfSetToListOfDouble != nil { + fh = stream.FieldHeader{ID: 9, Type: wire.TMap} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _Map_Set_I32_mapType_List_Double_Encode(v.MapOfSetToListOfDouble, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a ContainersOfContainers // struct. func (v *ContainersOfContainers) String() string { @@ -2385,6 +2953,134 @@ func (v *EnumContainers) FromWire(w wire.Value) error { return nil } +func _List_EnumDefault_Encode(val []enums.EnumDefault, sw stream.Writer) error { + var ( + err error + ) + + lh := stream.ListHeader{ + Type: wire.TI32, + Length: len(val), + } + if err := sw.WriteListBegin(lh); err != nil { + return err + } + + for _, v := range val { + if err := v.Encode(sw); err != nil { + return err + } + } + return sw.WriteListEnd() +} + +func _Set_EnumWithValues_mapType_Encode(val map[enums.EnumWithValues]struct{}, sw stream.Writer) error { + var err error + + sh := stream.SetHeader{ + Type: wire.TI32, + Length: len(val), + } + + if err := sw.WriteSetBegin(sh); err != nil { + return err + } + + for v, _ := range val { + + if err := v.Encode(sw); err != nil { + return err + } + } + return sw.WriteSetEnd() +} + +func _Map_EnumWithDuplicateValues_I32_Encode(val map[enums.EnumWithDuplicateValues]int32, sw stream.Writer) error { + var ( + err error + ) + + mh := stream.MapHeader{ + KeyType: wire.TI32, + ValueType: wire.TI32, + Length: len(val), + } + if err := sw.WriteMapBegin(mh); err != nil { + return err + } + + for k, v := range val { + if err := k.Encode(sw); err != nil { + return err + } + if err := sw.WriteInt32(v); err != nil { + return err + } + } + + return sw.WriteMapEnd() +} + +// Encode serializes a EnumContainers struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a EnumContainers struct could not be encoded. +func (v *EnumContainers) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.ListOfEnums != nil { + fh = stream.FieldHeader{ID: 1, Type: wire.TList} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _List_EnumDefault_Encode(v.ListOfEnums, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.SetOfEnums != nil { + fh = stream.FieldHeader{ID: 2, Type: wire.TSet} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _Set_EnumWithValues_mapType_Encode(v.SetOfEnums, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.MapOfEnums != nil { + fh = stream.FieldHeader{ID: 3, Type: wire.TMap} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _Map_EnumWithDuplicateValues_I32_Encode(v.MapOfEnums, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a EnumContainers // struct. func (v *EnumContainers) String() string { @@ -2788,6 +3484,90 @@ func (v *ListOfConflictingEnums) FromWire(w wire.Value) error { return nil } +func _List_RecordType_Encode(val []enum_conflict.RecordType, sw stream.Writer) error { + var ( + err error + ) + + lh := stream.ListHeader{ + Type: wire.TI32, + Length: len(val), + } + if err := sw.WriteListBegin(lh); err != nil { + return err + } + + for _, v := range val { + if err := v.Encode(sw); err != nil { + return err + } + } + return sw.WriteListEnd() +} + +func _List_RecordType_1_Encode(val []enums.RecordType, sw stream.Writer) error { + var ( + err error + ) + + lh := stream.ListHeader{ + Type: wire.TI32, + Length: len(val), + } + if err := sw.WriteListBegin(lh); err != nil { + return err + } + + for _, v := range val { + if err := v.Encode(sw); err != nil { + return err + } + } + return sw.WriteListEnd() +} + +// Encode serializes a ListOfConflictingEnums struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a ListOfConflictingEnums struct could not be encoded. +func (v *ListOfConflictingEnums) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + fh = stream.FieldHeader{ID: 1, Type: wire.TList} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _List_RecordType_Encode(v.Records, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + fh = stream.FieldHeader{ID: 2, Type: wire.TList} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _List_RecordType_1_Encode(v.OtherRecords, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a ListOfConflictingEnums // struct. func (v *ListOfConflictingEnums) String() string { @@ -3119,6 +3899,90 @@ func (v *ListOfConflictingUUIDs) FromWire(w wire.Value) error { return nil } +func _List_UUID_Encode(val []*typedefs.UUID, sw stream.Writer) error { + var ( + err error + ) + + lh := stream.ListHeader{ + Type: wire.TStruct, + Length: len(val), + } + if err := sw.WriteListBegin(lh); err != nil { + return err + } + + for _, v := range val { + if err := v.Encode(sw); err != nil { + return err + } + } + return sw.WriteListEnd() +} + +func _List_UUID_1_Encode(val []uuid_conflict.UUID, sw stream.Writer) error { + var ( + err error + ) + + lh := stream.ListHeader{ + Type: wire.TBinary, + Length: len(val), + } + if err := sw.WriteListBegin(lh); err != nil { + return err + } + + for _, v := range val { + if err := v.Encode(sw); err != nil { + return err + } + } + return sw.WriteListEnd() +} + +// Encode serializes a ListOfConflictingUUIDs struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a ListOfConflictingUUIDs struct could not be encoded. +func (v *ListOfConflictingUUIDs) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + fh = stream.FieldHeader{ID: 1, Type: wire.TList} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _List_UUID_Encode(v.Uuids, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + fh = stream.FieldHeader{ID: 2, Type: wire.TList} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _List_UUID_1_Encode(v.OtherUUIDs, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a ListOfConflictingUUIDs // struct. func (v *ListOfConflictingUUIDs) String() string { @@ -3315,11 +4179,43 @@ func (v *ListOfOptionalPrimitives) FromWire(w wire.Value) error { return err } - } + } + } + } + + return nil +} + +// Encode serializes a ListOfOptionalPrimitives struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a ListOfOptionalPrimitives struct could not be encoded. +func (v *ListOfOptionalPrimitives) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.ListOfStrings != nil { + fh = stream.FieldHeader{ID: 1, Type: wire.TList} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _List_String_Encode(v.ListOfStrings, sw); err != nil { + return err } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ } - return nil + return sw.WriteStructEnd() } // String returns a readable string representation of a ListOfOptionalPrimitives @@ -3462,6 +4358,36 @@ func (v *ListOfRequiredPrimitives) FromWire(w wire.Value) error { return nil } +// Encode serializes a ListOfRequiredPrimitives struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a ListOfRequiredPrimitives struct could not be encoded. +func (v *ListOfRequiredPrimitives) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + fh = stream.FieldHeader{ID: 1, Type: wire.TList} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _List_String_Encode(v.ListOfStrings, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a ListOfRequiredPrimitives // struct. func (v *ListOfRequiredPrimitives) String() string { @@ -3759,6 +4685,109 @@ func (v *MapOfBinaryAndString) FromWire(w wire.Value) error { return nil } +func _Map_Binary_String_Encode(val []struct { + Key []byte + Value string +}, sw stream.Writer) error { + var ( + err error + ) + + mh := stream.MapHeader{ + KeyType: wire.TBinary, + ValueType: wire.TBinary, + Length: len(val), + } + if err := sw.WriteMapBegin(mh); err != nil { + return err + } + + for _, v := range val { + key := v.Key + if err := sw.WriteBinary(key); err != nil { + return err + } + value := v.Value + if err := sw.WriteString(value); err != nil { + return err + } + } + + return sw.WriteMapEnd() +} + +func _Map_String_Binary_Encode(val map[string][]byte, sw stream.Writer) error { + var ( + err error + ) + + mh := stream.MapHeader{ + KeyType: wire.TBinary, + ValueType: wire.TBinary, + Length: len(val), + } + if err := sw.WriteMapBegin(mh); err != nil { + return err + } + + for k, v := range val { + if err := sw.WriteString(k); err != nil { + return err + } + if err := sw.WriteBinary(v); err != nil { + return err + } + } + + return sw.WriteMapEnd() +} + +// Encode serializes a MapOfBinaryAndString struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a MapOfBinaryAndString struct could not be encoded. +func (v *MapOfBinaryAndString) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.BinaryToString != nil { + fh = stream.FieldHeader{ID: 1, Type: wire.TMap} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _Map_Binary_String_Encode(v.BinaryToString, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.StringToBinary != nil { + fh = stream.FieldHeader{ID: 2, Type: wire.TMap} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _Map_String_Binary_Encode(v.StringToBinary, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a MapOfBinaryAndString // struct. func (v *MapOfBinaryAndString) String() string { @@ -4360,6 +5389,223 @@ func (v *PrimitiveContainers) FromWire(w wire.Value) error { return nil } +func _List_Binary_Encode(val [][]byte, sw stream.Writer) error { + var ( + err error + ) + + lh := stream.ListHeader{ + Type: wire.TBinary, + Length: len(val), + } + if err := sw.WriteListBegin(lh); err != nil { + return err + } + + for _, v := range val { + if err := sw.WriteBinary(v); err != nil { + return err + } + } + return sw.WriteListEnd() +} + +func _List_I64_Encode(val []int64, sw stream.Writer) error { + var ( + err error + ) + + lh := stream.ListHeader{ + Type: wire.TI64, + Length: len(val), + } + if err := sw.WriteListBegin(lh); err != nil { + return err + } + + for _, v := range val { + if err := sw.WriteInt64(v); err != nil { + return err + } + } + return sw.WriteListEnd() +} + +func _Set_Byte_mapType_Encode(val map[int8]struct{}, sw stream.Writer) error { + var err error + + sh := stream.SetHeader{ + Type: wire.TI8, + Length: len(val), + } + + if err := sw.WriteSetBegin(sh); err != nil { + return err + } + + for v, _ := range val { + + if err := sw.WriteInt8(v); err != nil { + return err + } + } + return sw.WriteSetEnd() +} + +func _Map_I32_String_Encode(val map[int32]string, sw stream.Writer) error { + var ( + err error + ) + + mh := stream.MapHeader{ + KeyType: wire.TI32, + ValueType: wire.TBinary, + Length: len(val), + } + if err := sw.WriteMapBegin(mh); err != nil { + return err + } + + for k, v := range val { + if err := sw.WriteInt32(k); err != nil { + return err + } + if err := sw.WriteString(v); err != nil { + return err + } + } + + return sw.WriteMapEnd() +} + +func _Map_String_Bool_Encode(val map[string]bool, sw stream.Writer) error { + var ( + err error + ) + + mh := stream.MapHeader{ + KeyType: wire.TBinary, + ValueType: wire.TBool, + Length: len(val), + } + if err := sw.WriteMapBegin(mh); err != nil { + return err + } + + for k, v := range val { + if err := sw.WriteString(k); err != nil { + return err + } + if err := sw.WriteBool(v); err != nil { + return err + } + } + + return sw.WriteMapEnd() +} + +// Encode serializes a PrimitiveContainers struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a PrimitiveContainers struct could not be encoded. +func (v *PrimitiveContainers) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.ListOfBinary != nil { + fh = stream.FieldHeader{ID: 1, Type: wire.TList} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _List_Binary_Encode(v.ListOfBinary, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.ListOfInts != nil { + fh = stream.FieldHeader{ID: 2, Type: wire.TList} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _List_I64_Encode(v.ListOfInts, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.SetOfStrings != nil { + fh = stream.FieldHeader{ID: 3, Type: wire.TSet} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _Set_String_mapType_Encode(v.SetOfStrings, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.SetOfBytes != nil { + fh = stream.FieldHeader{ID: 4, Type: wire.TSet} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _Set_Byte_mapType_Encode(v.SetOfBytes, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.MapOfIntToString != nil { + fh = stream.FieldHeader{ID: 5, Type: wire.TMap} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _Map_I32_String_Encode(v.MapOfIntToString, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.MapOfStringToBool != nil { + fh = stream.FieldHeader{ID: 6, Type: wire.TMap} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _Map_String_Bool_Encode(v.MapOfStringToBool, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a PrimitiveContainers // struct. func (v *PrimitiveContainers) String() string { @@ -4880,6 +6126,92 @@ func (v *PrimitiveContainersRequired) FromWire(w wire.Value) error { return nil } +func _Map_I64_Double_Encode(val map[int64]float64, sw stream.Writer) error { + var ( + err error + ) + + mh := stream.MapHeader{ + KeyType: wire.TI64, + ValueType: wire.TDouble, + Length: len(val), + } + if err := sw.WriteMapBegin(mh); err != nil { + return err + } + + for k, v := range val { + if err := sw.WriteInt64(k); err != nil { + return err + } + if err := sw.WriteDouble(v); err != nil { + return err + } + } + + return sw.WriteMapEnd() +} + +// Encode serializes a PrimitiveContainersRequired struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a PrimitiveContainersRequired struct could not be encoded. +func (v *PrimitiveContainersRequired) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + fh = stream.FieldHeader{ID: 1, Type: wire.TList} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _List_String_Encode(v.ListOfStrings, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + if v.SetOfInts == nil { + return errors.New("field SetOfInts of PrimitiveContainersRequired is required") + } + fh = stream.FieldHeader{ID: 2, Type: wire.TSet} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _Set_I32_mapType_Encode(v.SetOfInts, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + if v.MapOfIntsToDoubles == nil { + return errors.New("field MapOfIntsToDoubles of PrimitiveContainersRequired is required") + } + fh = stream.FieldHeader{ID: 3, Type: wire.TMap} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _Map_I64_Double_Encode(v.MapOfIntsToDoubles, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a PrimitiveContainersRequired // struct. func (v *PrimitiveContainersRequired) String() string { diff --git a/gen/internal/tests/enum_conflict/enum_conflict.go b/gen/internal/tests/enum_conflict/enum_conflict.go index e8cdc302..0d9dad9b 100644 --- a/gen/internal/tests/enum_conflict/enum_conflict.go +++ b/gen/internal/tests/enum_conflict/enum_conflict.go @@ -9,6 +9,7 @@ import ( fmt "fmt" multierr "go.uber.org/multierr" enums "go.uber.org/thriftrw/gen/internal/tests/enums" + stream "go.uber.org/thriftrw/protocol/stream" thriftreflect "go.uber.org/thriftrw/thriftreflect" wire "go.uber.org/thriftrw/wire" zapcore "go.uber.org/zap/zapcore" @@ -95,6 +96,19 @@ func (v RecordType) Ptr() *RecordType { return &v } +// Encode encodes RecordType directly to the wire. +// +// sWriter := BinaryStreamer.Writer(writer) +// +// var v RecordType +// if err := v.Encode(sWriter); err != nil { +// return err +// } +// return nil +func (v RecordType) Encode(sw stream.Writer) error { + return sw.WriteInt32(int32(v)) +} + // ToWire translates RecordType into a Thrift-level intermediate // representation. This intermediate representation may be serialized // into bytes using a ThriftRW protocol implementation. @@ -333,6 +347,60 @@ func (v *Records) FromWire(w wire.Value) error { return nil } +// Encode serializes a Records struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a Records struct could not be encoded. +func (v *Records) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + vRecordType := v.RecordType + if vRecordType == nil { + vRecordType = _RecordType_ptr(DefaultRecordType) + } + { + fh = stream.FieldHeader{ID: 1, Type: wire.TI32} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := vRecordType.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + vOtherRecordType := v.OtherRecordType + if vOtherRecordType == nil { + vOtherRecordType = _RecordType_1_ptr(DefaultOtherRecordType) + } + { + fh = stream.FieldHeader{ID: 2, Type: wire.TI32} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := vOtherRecordType.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a Records // struct. func (v *Records) String() string { diff --git a/gen/internal/tests/enums/enums.go b/gen/internal/tests/enums/enums.go index b6cbb189..bf262a66 100644 --- a/gen/internal/tests/enums/enums.go +++ b/gen/internal/tests/enums/enums.go @@ -8,6 +8,7 @@ import ( json "encoding/json" fmt "fmt" multierr "go.uber.org/multierr" + stream "go.uber.org/thriftrw/protocol/stream" thriftreflect "go.uber.org/thriftrw/thriftreflect" wire "go.uber.org/thriftrw/wire" zapcore "go.uber.org/zap/zapcore" @@ -61,6 +62,19 @@ func (v EmptyEnum) Ptr() *EmptyEnum { return &v } +// Encode encodes EmptyEnum directly to the wire. +// +// sWriter := BinaryStreamer.Writer(writer) +// +// var v EmptyEnum +// if err := v.Encode(sWriter); err != nil { +// return err +// } +// return nil +func (v EmptyEnum) Encode(sw stream.Writer) error { + return sw.WriteInt32(int32(v)) +} + // ToWire translates EmptyEnum into a Thrift-level intermediate // representation. This intermediate representation may be serialized // into bytes using a ThriftRW protocol implementation. @@ -229,6 +243,19 @@ func (v EnumDefault) Ptr() *EnumDefault { return &v } +// Encode encodes EnumDefault directly to the wire. +// +// sWriter := BinaryStreamer.Writer(writer) +// +// var v EnumDefault +// if err := v.Encode(sWriter); err != nil { +// return err +// } +// return nil +func (v EnumDefault) Encode(sw stream.Writer) error { + return sw.WriteInt32(int32(v)) +} + // ToWire translates EnumDefault into a Thrift-level intermediate // representation. This intermediate representation may be serialized // into bytes using a ThriftRW protocol implementation. @@ -467,6 +494,19 @@ func (v EnumWithDuplicateName) Ptr() *EnumWithDuplicateName { return &v } +// Encode encodes EnumWithDuplicateName directly to the wire. +// +// sWriter := BinaryStreamer.Writer(writer) +// +// var v EnumWithDuplicateName +// if err := v.Encode(sWriter); err != nil { +// return err +// } +// return nil +func (v EnumWithDuplicateName) Encode(sw stream.Writer) error { + return sw.WriteInt32(int32(v)) +} + // ToWire translates EnumWithDuplicateName into a Thrift-level intermediate // representation. This intermediate representation may be serialized // into bytes using a ThriftRW protocol implementation. @@ -671,6 +711,19 @@ func (v EnumWithDuplicateValues) Ptr() *EnumWithDuplicateValues { return &v } +// Encode encodes EnumWithDuplicateValues directly to the wire. +// +// sWriter := BinaryStreamer.Writer(writer) +// +// var v EnumWithDuplicateValues +// if err := v.Encode(sWriter); err != nil { +// return err +// } +// return nil +func (v EnumWithDuplicateValues) Encode(sw stream.Writer) error { + return sw.WriteInt32(int32(v)) +} + // ToWire translates EnumWithDuplicateValues into a Thrift-level intermediate // representation. This intermediate representation may be serialized // into bytes using a ThriftRW protocol implementation. @@ -878,6 +931,19 @@ func (v EnumWithLabel) Ptr() *EnumWithLabel { return &v } +// Encode encodes EnumWithLabel directly to the wire. +// +// sWriter := BinaryStreamer.Writer(writer) +// +// var v EnumWithLabel +// if err := v.Encode(sWriter); err != nil { +// return err +// } +// return nil +func (v EnumWithLabel) Encode(sw stream.Writer) error { + return sw.WriteInt32(int32(v)) +} + // ToWire translates EnumWithLabel into a Thrift-level intermediate // representation. This intermediate representation may be serialized // into bytes using a ThriftRW protocol implementation. @@ -1074,6 +1140,19 @@ func (v EnumWithValues) Ptr() *EnumWithValues { return &v } +// Encode encodes EnumWithValues directly to the wire. +// +// sWriter := BinaryStreamer.Writer(writer) +// +// var v EnumWithValues +// if err := v.Encode(sWriter); err != nil { +// return err +// } +// return nil +func (v EnumWithValues) Encode(sw stream.Writer) error { + return sw.WriteInt32(int32(v)) +} + // ToWire translates EnumWithValues into a Thrift-level intermediate // representation. This intermediate representation may be serialized // into bytes using a ThriftRW protocol implementation. @@ -1266,6 +1345,19 @@ func (v RecordType) Ptr() *RecordType { return &v } +// Encode encodes RecordType directly to the wire. +// +// sWriter := BinaryStreamer.Writer(writer) +// +// var v RecordType +// if err := v.Encode(sWriter); err != nil { +// return err +// } +// return nil +func (v RecordType) Encode(sw stream.Writer) error { + return sw.WriteInt32(int32(v)) +} + // ToWire translates RecordType into a Thrift-level intermediate // representation. This intermediate representation may be serialized // into bytes using a ThriftRW protocol implementation. @@ -1441,6 +1533,19 @@ func (v RecordTypeValues) Ptr() *RecordTypeValues { return &v } +// Encode encodes RecordTypeValues directly to the wire. +// +// sWriter := BinaryStreamer.Writer(writer) +// +// var v RecordTypeValues +// if err := v.Encode(sWriter); err != nil { +// return err +// } +// return nil +func (v RecordTypeValues) Encode(sw stream.Writer) error { + return sw.WriteInt32(int32(v)) +} + // ToWire translates RecordTypeValues into a Thrift-level intermediate // representation. This intermediate representation may be serialized // into bytes using a ThriftRW protocol implementation. @@ -1621,6 +1726,38 @@ func (v *StructWithOptionalEnum) FromWire(w wire.Value) error { return nil } +// Encode serializes a StructWithOptionalEnum struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a StructWithOptionalEnum struct could not be encoded. +func (v *StructWithOptionalEnum) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.E != nil { + fh = stream.FieldHeader{ID: 1, Type: wire.TI32} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.E.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a StructWithOptionalEnum // struct. func (v *StructWithOptionalEnum) String() string { @@ -1775,6 +1912,19 @@ func (v LowerCaseEnum) Ptr() *LowerCaseEnum { return &v } +// Encode encodes LowerCaseEnum directly to the wire. +// +// sWriter := BinaryStreamer.Writer(writer) +// +// var v LowerCaseEnum +// if err := v.Encode(sWriter); err != nil { +// return err +// } +// return nil +func (v LowerCaseEnum) Encode(sw stream.Writer) error { + return sw.WriteInt32(int32(v)) +} + // ToWire translates LowerCaseEnum into a Thrift-level intermediate // representation. This intermediate representation may be serialized // into bytes using a ThriftRW protocol implementation. diff --git a/gen/internal/tests/exceptions/exceptions.go b/gen/internal/tests/exceptions/exceptions.go index c02c9f99..2e6d34c5 100644 --- a/gen/internal/tests/exceptions/exceptions.go +++ b/gen/internal/tests/exceptions/exceptions.go @@ -6,6 +6,7 @@ package exceptions import ( errors "errors" fmt "fmt" + stream "go.uber.org/thriftrw/protocol/stream" thriftreflect "go.uber.org/thriftrw/thriftreflect" wire "go.uber.org/thriftrw/wire" zapcore "go.uber.org/zap/zapcore" @@ -112,6 +113,50 @@ func (v *DoesNotExistException) FromWire(w wire.Value) error { return nil } +// Encode serializes a DoesNotExistException struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a DoesNotExistException struct could not be encoded. +func (v *DoesNotExistException) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + fh = stream.FieldHeader{ID: 1, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(v.Key); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + if v.Error2 != nil { + fh = stream.FieldHeader{ID: 2, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(*(v.Error2)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a DoesNotExistException // struct. func (v *DoesNotExistException) String() string { @@ -307,6 +352,50 @@ func (v *DoesNotExistException2) FromWire(w wire.Value) error { return nil } +// Encode serializes a DoesNotExistException2 struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a DoesNotExistException2 struct could not be encoded. +func (v *DoesNotExistException2) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + fh = stream.FieldHeader{ID: 1, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(v.Key); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + if v.Error2 != nil { + fh = stream.FieldHeader{ID: 2, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(*(v.Error2)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a DoesNotExistException2 // struct. func (v *DoesNotExistException2) String() string { @@ -447,6 +536,20 @@ func (v *EmptyException) FromWire(w wire.Value) error { return nil } +// Encode serializes a EmptyException struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a EmptyException struct could not be encoded. +func (v *EmptyException) Encode(sw stream.Writer) error { + var () + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a EmptyException // struct. func (v *EmptyException) String() string { diff --git a/gen/internal/tests/hyphenated-file/hyphenated-file.go b/gen/internal/tests/hyphenated-file/hyphenated-file.go index 521b4abc..7841c071 100644 --- a/gen/internal/tests/hyphenated-file/hyphenated-file.go +++ b/gen/internal/tests/hyphenated-file/hyphenated-file.go @@ -8,6 +8,7 @@ import ( fmt "fmt" multierr "go.uber.org/multierr" non_hyphenated "go.uber.org/thriftrw/gen/internal/tests/non_hyphenated" + stream "go.uber.org/thriftrw/protocol/stream" thriftreflect "go.uber.org/thriftrw/thriftreflect" wire "go.uber.org/thriftrw/wire" zapcore "go.uber.org/zap/zapcore" @@ -102,6 +103,39 @@ func (v *DocumentStruct) FromWire(w wire.Value) error { return nil } +// Encode serializes a DocumentStruct struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a DocumentStruct struct could not be encoded. +func (v *DocumentStruct) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.Second == nil { + return errors.New("field Second of DocumentStruct is required") + } + fh = stream.FieldHeader{ID: 1, Type: wire.TStruct} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.Second.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a DocumentStruct // struct. func (v *DocumentStruct) String() string { diff --git a/gen/internal/tests/hyphenated_file/hyphenated_file.go b/gen/internal/tests/hyphenated_file/hyphenated_file.go index a9255c44..8f9a33ad 100644 --- a/gen/internal/tests/hyphenated_file/hyphenated_file.go +++ b/gen/internal/tests/hyphenated_file/hyphenated_file.go @@ -8,6 +8,7 @@ import ( fmt "fmt" multierr "go.uber.org/multierr" non_hyphenated "go.uber.org/thriftrw/gen/internal/tests/non_hyphenated" + stream "go.uber.org/thriftrw/protocol/stream" thriftreflect "go.uber.org/thriftrw/thriftreflect" wire "go.uber.org/thriftrw/wire" zapcore "go.uber.org/zap/zapcore" @@ -102,6 +103,39 @@ func (v *DocumentStructure) FromWire(w wire.Value) error { return nil } +// Encode serializes a DocumentStructure struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a DocumentStructure struct could not be encoded. +func (v *DocumentStructure) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.R2 == nil { + return errors.New("field R2 of DocumentStructure is required") + } + fh = stream.FieldHeader{ID: 1, Type: wire.TStruct} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.R2.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a DocumentStructure // struct. func (v *DocumentStructure) String() string { diff --git a/gen/internal/tests/non_hyphenated/non_hyphenated.go b/gen/internal/tests/non_hyphenated/non_hyphenated.go index b1f02e6f..db5b0684 100644 --- a/gen/internal/tests/non_hyphenated/non_hyphenated.go +++ b/gen/internal/tests/non_hyphenated/non_hyphenated.go @@ -5,6 +5,7 @@ package non_hyphenated import ( fmt "fmt" + stream "go.uber.org/thriftrw/protocol/stream" thriftreflect "go.uber.org/thriftrw/thriftreflect" wire "go.uber.org/thriftrw/wire" zapcore "go.uber.org/zap/zapcore" @@ -65,6 +66,20 @@ func (v *First) FromWire(w wire.Value) error { return nil } +// Encode serializes a First struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a First struct could not be encoded. +func (v *First) Encode(sw stream.Writer) error { + var () + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a First // struct. func (v *First) String() string { @@ -155,6 +170,20 @@ func (v *Second) FromWire(w wire.Value) error { return nil } +// Encode serializes a Second struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a Second struct could not be encoded. +func (v *Second) Encode(sw stream.Writer) error { + var () + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a Second // struct. func (v *Second) String() string { diff --git a/gen/internal/tests/nozap/nozap.go b/gen/internal/tests/nozap/nozap.go index 9dbb633a..ded9ae35 100644 --- a/gen/internal/tests/nozap/nozap.go +++ b/gen/internal/tests/nozap/nozap.go @@ -8,6 +8,7 @@ import ( json "encoding/json" errors "errors" fmt "fmt" + stream "go.uber.org/thriftrw/protocol/stream" thriftreflect "go.uber.org/thriftrw/thriftreflect" wire "go.uber.org/thriftrw/wire" math "math" @@ -81,6 +82,19 @@ func (v EnumDefault) Ptr() *EnumDefault { return &v } +// Encode encodes EnumDefault directly to the wire. +// +// sWriter := BinaryStreamer.Writer(writer) +// +// var v EnumDefault +// if err := v.Encode(sWriter); err != nil { +// return err +// } +// return nil +func (v EnumDefault) Encode(sw stream.Writer) error { + return sw.WriteInt32(int32(v)) +} + // ToWire translates EnumDefault into a Thrift-level intermediate // representation. This intermediate representation may be serialized // into bytes using a ThriftRW protocol implementation. @@ -629,6 +643,233 @@ func (v *PrimitiveRequiredStruct) FromWire(w wire.Value) error { return nil } +func _List_String_Encode(val []string, sw stream.Writer) error { + var ( + err error + ) + + lh := stream.ListHeader{ + Type: wire.TBinary, + Length: len(val), + } + if err := sw.WriteListBegin(lh); err != nil { + return err + } + + for _, v := range val { + if err := sw.WriteString(v); err != nil { + return err + } + } + return sw.WriteListEnd() +} + +func _Set_I32_mapType_Encode(val map[int32]struct{}, sw stream.Writer) error { + var err error + + sh := stream.SetHeader{ + Type: wire.TI32, + Length: len(val), + } + + if err := sw.WriteSetBegin(sh); err != nil { + return err + } + + for v, _ := range val { + + if err := sw.WriteInt32(v); err != nil { + return err + } + } + return sw.WriteSetEnd() +} + +func _Map_I64_Double_Encode(val map[int64]float64, sw stream.Writer) error { + var ( + err error + ) + + mh := stream.MapHeader{ + KeyType: wire.TI64, + ValueType: wire.TDouble, + Length: len(val), + } + if err := sw.WriteMapBegin(mh); err != nil { + return err + } + + for k, v := range val { + if err := sw.WriteInt64(k); err != nil { + return err + } + if err := sw.WriteDouble(v); err != nil { + return err + } + } + + return sw.WriteMapEnd() +} + +// Encode serializes a PrimitiveRequiredStruct struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a PrimitiveRequiredStruct struct could not be encoded. +func (v *PrimitiveRequiredStruct) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + fh = stream.FieldHeader{ID: 1, Type: wire.TBool} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteBool(v.BoolField); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + fh = stream.FieldHeader{ID: 2, Type: wire.TI8} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteInt8(v.ByteField); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + fh = stream.FieldHeader{ID: 3, Type: wire.TI16} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteInt16(v.Int16Field); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + fh = stream.FieldHeader{ID: 4, Type: wire.TI32} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteInt32(v.Int32Field); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + fh = stream.FieldHeader{ID: 5, Type: wire.TI64} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteInt64(v.Int64Field); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + fh = stream.FieldHeader{ID: 6, Type: wire.TDouble} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteDouble(v.DoubleField); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + fh = stream.FieldHeader{ID: 7, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(v.StringField); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + if v.BinaryField == nil { + return errors.New("field BinaryField of PrimitiveRequiredStruct is required") + } + fh = stream.FieldHeader{ID: 8, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteBinary(v.BinaryField); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + fh = stream.FieldHeader{ID: 9, Type: wire.TList} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _List_String_Encode(v.ListOfStrings, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + if v.SetOfInts == nil { + return errors.New("field SetOfInts of PrimitiveRequiredStruct is required") + } + fh = stream.FieldHeader{ID: 10, Type: wire.TSet} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _Set_I32_mapType_Encode(v.SetOfInts, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + if v.MapOfIntsToDoubles == nil { + return errors.New("field MapOfIntsToDoubles of PrimitiveRequiredStruct is required") + } + fh = stream.FieldHeader{ID: 11, Type: wire.TMap} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _Map_I64_Double_Encode(v.MapOfIntsToDoubles, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a PrimitiveRequiredStruct // struct. func (v *PrimitiveRequiredStruct) String() string { @@ -892,6 +1133,11 @@ func (v *Primitives) String() string { return fmt.Sprint(x) } +func (v *Primitives) Encode(sw stream.Writer) error { + x := (*PrimitiveRequiredStruct)(v) + return x.Encode(sw) +} + // FromWire deserializes Primitives from its Thrift-level // representation. The Thrift-level representation may be obtained // from a ThriftRW protocol implementation. @@ -921,6 +1167,11 @@ func (v StringList) String() string { return fmt.Sprint(x) } +func (v StringList) Encode(sw stream.Writer) error { + x := ([]string)(v) + return _List_String_Encode(x, sw) +} + // FromWire deserializes StringList from its Thrift-level // representation. The Thrift-level representation may be obtained // from a ThriftRW protocol implementation. @@ -971,6 +1222,32 @@ func (_Map_String_String_MapItemList) ValueType() wire.Type { func (_Map_String_String_MapItemList) Close() {} +func _Map_String_String_Encode(val map[string]string, sw stream.Writer) error { + var ( + err error + ) + + mh := stream.MapHeader{ + KeyType: wire.TBinary, + ValueType: wire.TBinary, + Length: len(val), + } + if err := sw.WriteMapBegin(mh); err != nil { + return err + } + + for k, v := range val { + if err := sw.WriteString(k); err != nil { + return err + } + if err := sw.WriteString(v); err != nil { + return err + } + } + + return sw.WriteMapEnd() +} + func _Map_String_String_Read(m wire.MapItemList) (map[string]string, error) { if m.KeyType() != wire.TBinary { return nil, nil @@ -1032,6 +1309,11 @@ func (v StringMap) String() string { return fmt.Sprint(x) } +func (v StringMap) Encode(sw stream.Writer) error { + x := (map[string]string)(v) + return _Map_String_String_Encode(x, sw) +} + // FromWire deserializes StringMap from its Thrift-level // representation. The Thrift-level representation may be obtained // from a ThriftRW protocol implementation. diff --git a/gen/internal/tests/services/services.go b/gen/internal/tests/services/services.go index 3c43f5da..6f26fdda 100644 --- a/gen/internal/tests/services/services.go +++ b/gen/internal/tests/services/services.go @@ -11,6 +11,7 @@ import ( multierr "go.uber.org/multierr" exceptions "go.uber.org/thriftrw/gen/internal/tests/exceptions" unions "go.uber.org/thriftrw/gen/internal/tests/unions" + stream "go.uber.org/thriftrw/protocol/stream" thriftreflect "go.uber.org/thriftrw/thriftreflect" wire "go.uber.org/thriftrw/wire" zapcore "go.uber.org/zap/zapcore" @@ -119,6 +120,51 @@ func (v *ConflictingNamesSetValueArgs) FromWire(w wire.Value) error { return nil } +// Encode serializes a ConflictingNamesSetValueArgs struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a ConflictingNamesSetValueArgs struct could not be encoded. +func (v *ConflictingNamesSetValueArgs) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + fh = stream.FieldHeader{ID: 1, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(v.Key); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + if v.Value == nil { + return errors.New("field Value of ConflictingNamesSetValueArgs is required") + } + fh = stream.FieldHeader{ID: 2, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteBinary(v.Value); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a ConflictingNamesSetValueArgs // struct. func (v *ConflictingNamesSetValueArgs) String() string { @@ -267,6 +313,38 @@ func (v *InternalError) FromWire(w wire.Value) error { return nil } +// Encode serializes a InternalError struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a InternalError struct could not be encoded. +func (v *InternalError) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.Message != nil { + fh = stream.FieldHeader{ID: 1, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(*(v.Message)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a InternalError // struct. func (v *InternalError) String() string { @@ -369,6 +447,11 @@ func (v Key) String() string { return fmt.Sprint(x) } +func (v Key) Encode(sw stream.Writer) error { + x := (string)(v) + return sw.WriteString(x) +} + // FromWire deserializes Key from its Thrift-level // representation. The Thrift-level representation may be obtained // from a ThriftRW protocol implementation. @@ -456,6 +539,20 @@ func (v *Cache_Clear_Args) FromWire(w wire.Value) error { return nil } +// Encode serializes a Cache_Clear_Args struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a Cache_Clear_Args struct could not be encoded. +func (v *Cache_Clear_Args) Encode(sw stream.Writer) error { + var () + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a Cache_Clear_Args // struct. func (v *Cache_Clear_Args) String() string { @@ -603,6 +700,38 @@ func (v *Cache_ClearAfter_Args) FromWire(w wire.Value) error { return nil } +// Encode serializes a Cache_ClearAfter_Args struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a Cache_ClearAfter_Args struct could not be encoded. +func (v *Cache_ClearAfter_Args) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.DurationMS != nil { + fh = stream.FieldHeader{ID: 1, Type: wire.TI64} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteInt64(*(v.DurationMS)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a Cache_ClearAfter_Args // struct. func (v *Cache_ClearAfter_Args) String() string { @@ -795,6 +924,38 @@ func (v *ConflictingNames_SetValue_Args) FromWire(w wire.Value) error { return nil } +// Encode serializes a ConflictingNames_SetValue_Args struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a ConflictingNames_SetValue_Args struct could not be encoded. +func (v *ConflictingNames_SetValue_Args) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.Request != nil { + fh = stream.FieldHeader{ID: 1, Type: wire.TStruct} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.Request.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a ConflictingNames_SetValue_Args // struct. func (v *ConflictingNames_SetValue_Args) String() string { @@ -1003,6 +1164,20 @@ func (v *ConflictingNames_SetValue_Result) FromWire(w wire.Value) error { return nil } +// Encode serializes a ConflictingNames_SetValue_Result struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a ConflictingNames_SetValue_Result struct could not be encoded. +func (v *ConflictingNames_SetValue_Result) Encode(sw stream.Writer) error { + var () + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a ConflictingNames_SetValue_Result // struct. func (v *ConflictingNames_SetValue_Result) String() string { @@ -1140,6 +1315,38 @@ func (v *KeyValue_DeleteValue_Args) FromWire(w wire.Value) error { return nil } +// Encode serializes a KeyValue_DeleteValue_Args struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a KeyValue_DeleteValue_Args struct could not be encoded. +func (v *KeyValue_DeleteValue_Args) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.Key != nil { + fh = stream.FieldHeader{ID: 1, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.Key.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a KeyValue_DeleteValue_Args // struct. func (v *KeyValue_DeleteValue_Args) String() string { @@ -1449,6 +1656,56 @@ func (v *KeyValue_DeleteValue_Result) FromWire(w wire.Value) error { return nil } +// Encode serializes a KeyValue_DeleteValue_Result struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a KeyValue_DeleteValue_Result struct could not be encoded. +func (v *KeyValue_DeleteValue_Result) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.DoesNotExist != nil { + fh = stream.FieldHeader{ID: 1, Type: wire.TStruct} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.DoesNotExist.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.InternalError != nil { + fh = stream.FieldHeader{ID: 2, Type: wire.TStruct} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.InternalError.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if i > 1 { + return fmt.Errorf("KeyValue_DeleteValue_Result should have at most one field: got %v fields", i) + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a KeyValue_DeleteValue_Result // struct. func (v *KeyValue_DeleteValue_Result) String() string { @@ -1672,6 +1929,59 @@ func (v *KeyValue_GetManyValues_Args) FromWire(w wire.Value) error { return nil } +func _List_Key_Encode(val []Key, sw stream.Writer) error { + var ( + err error + ) + + lh := stream.ListHeader{ + Type: wire.TBinary, + Length: len(val), + } + if err := sw.WriteListBegin(lh); err != nil { + return err + } + + for _, v := range val { + if err := v.Encode(sw); err != nil { + return err + } + } + return sw.WriteListEnd() +} + +// Encode serializes a KeyValue_GetManyValues_Args struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a KeyValue_GetManyValues_Args struct could not be encoded. +func (v *KeyValue_GetManyValues_Args) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.Range != nil { + fh = stream.FieldHeader{ID: 1, Type: wire.TList} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _List_Key_Encode(v.Range, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a KeyValue_GetManyValues_Args // struct. func (v *KeyValue_GetManyValues_Args) String() string { @@ -2035,6 +2345,77 @@ func (v *KeyValue_GetManyValues_Result) FromWire(w wire.Value) error { return nil } +func _List_ArbitraryValue_Encode(val []*unions.ArbitraryValue, sw stream.Writer) error { + var ( + err error + ) + + lh := stream.ListHeader{ + Type: wire.TStruct, + Length: len(val), + } + if err := sw.WriteListBegin(lh); err != nil { + return err + } + + for _, v := range val { + if err := v.Encode(sw); err != nil { + return err + } + } + return sw.WriteListEnd() +} + +// Encode serializes a KeyValue_GetManyValues_Result struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a KeyValue_GetManyValues_Result struct could not be encoded. +func (v *KeyValue_GetManyValues_Result) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.Success != nil { + fh = stream.FieldHeader{ID: 0, Type: wire.TList} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _List_ArbitraryValue_Encode(v.Success, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.DoesNotExist != nil { + fh = stream.FieldHeader{ID: 1, Type: wire.TStruct} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.DoesNotExist.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if i != 1 { + return fmt.Errorf("KeyValue_GetManyValues_Result should have exactly one field: got %v fields", i) + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a KeyValue_GetManyValues_Result // struct. func (v *KeyValue_GetManyValues_Result) String() string { @@ -2242,6 +2623,38 @@ func (v *KeyValue_GetValue_Args) FromWire(w wire.Value) error { return nil } +// Encode serializes a KeyValue_GetValue_Args struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a KeyValue_GetValue_Args struct could not be encoded. +func (v *KeyValue_GetValue_Args) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.Key != nil { + fh = stream.FieldHeader{ID: 1, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.Key.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a KeyValue_GetValue_Args // struct. func (v *KeyValue_GetValue_Args) String() string { @@ -2526,6 +2939,56 @@ func (v *KeyValue_GetValue_Result) FromWire(w wire.Value) error { return nil } +// Encode serializes a KeyValue_GetValue_Result struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a KeyValue_GetValue_Result struct could not be encoded. +func (v *KeyValue_GetValue_Result) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.Success != nil { + fh = stream.FieldHeader{ID: 0, Type: wire.TStruct} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.Success.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.DoesNotExist != nil { + fh = stream.FieldHeader{ID: 1, Type: wire.TStruct} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.DoesNotExist.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if i != 1 { + return fmt.Errorf("KeyValue_GetValue_Result should have exactly one field: got %v fields", i) + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a KeyValue_GetValue_Result // struct. func (v *KeyValue_GetValue_Result) String() string { @@ -2724,6 +3187,52 @@ func (v *KeyValue_SetValue_Args) FromWire(w wire.Value) error { return nil } +// Encode serializes a KeyValue_SetValue_Args struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a KeyValue_SetValue_Args struct could not be encoded. +func (v *KeyValue_SetValue_Args) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.Key != nil { + fh = stream.FieldHeader{ID: 1, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.Key.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.Value != nil { + fh = stream.FieldHeader{ID: 2, Type: wire.TStruct} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.Value.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a KeyValue_SetValue_Args // struct. func (v *KeyValue_SetValue_Args) String() string { @@ -2960,6 +3469,20 @@ func (v *KeyValue_SetValue_Result) FromWire(w wire.Value) error { return nil } +// Encode serializes a KeyValue_SetValue_Result struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a KeyValue_SetValue_Result struct could not be encoded. +func (v *KeyValue_SetValue_Result) Encode(sw stream.Writer) error { + var () + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a KeyValue_SetValue_Result // struct. func (v *KeyValue_SetValue_Result) String() string { @@ -3120,6 +3643,51 @@ func (v *KeyValue_SetValueV2_Args) FromWire(w wire.Value) error { return nil } +// Encode serializes a KeyValue_SetValueV2_Args struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a KeyValue_SetValueV2_Args struct could not be encoded. +func (v *KeyValue_SetValueV2_Args) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + fh = stream.FieldHeader{ID: 1, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.Key.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + if v.Value == nil { + return errors.New("field Value of KeyValue_SetValueV2_Args is required") + } + fh = stream.FieldHeader{ID: 2, Type: wire.TStruct} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.Value.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a KeyValue_SetValueV2_Args // struct. func (v *KeyValue_SetValueV2_Args) String() string { @@ -3341,6 +3909,20 @@ func (v *KeyValue_SetValueV2_Result) FromWire(w wire.Value) error { return nil } +// Encode serializes a KeyValue_SetValueV2_Result struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a KeyValue_SetValueV2_Result struct could not be encoded. +func (v *KeyValue_SetValueV2_Result) Encode(sw stream.Writer) error { + var () + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a KeyValue_SetValueV2_Result // struct. func (v *KeyValue_SetValueV2_Result) String() string { @@ -3449,6 +4031,20 @@ func (v *KeyValue_Size_Args) FromWire(w wire.Value) error { return nil } +// Encode serializes a KeyValue_Size_Args struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a KeyValue_Size_Args struct could not be encoded. +func (v *KeyValue_Size_Args) Encode(sw stream.Writer) error { + var () + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a KeyValue_Size_Args // struct. func (v *KeyValue_Size_Args) String() string { @@ -3670,6 +4266,42 @@ func (v *KeyValue_Size_Result) FromWire(w wire.Value) error { return nil } +// Encode serializes a KeyValue_Size_Result struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a KeyValue_Size_Result struct could not be encoded. +func (v *KeyValue_Size_Result) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.Success != nil { + fh = stream.FieldHeader{ID: 0, Type: wire.TI64} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteInt64(*(v.Success)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if i != 1 { + return fmt.Errorf("KeyValue_Size_Result should have exactly one field: got %v fields", i) + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a KeyValue_Size_Result // struct. func (v *KeyValue_Size_Result) String() string { @@ -3803,6 +4435,20 @@ func (v *NonStandardServiceName_NonStandardFunctionName_Args) FromWire(w wire.Va return nil } +// Encode serializes a NonStandardServiceName_NonStandardFunctionName_Args struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a NonStandardServiceName_NonStandardFunctionName_Args struct could not be encoded. +func (v *NonStandardServiceName_NonStandardFunctionName_Args) Encode(sw stream.Writer) error { + var () + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a NonStandardServiceName_NonStandardFunctionName_Args // struct. func (v *NonStandardServiceName_NonStandardFunctionName_Args) String() string { @@ -3980,6 +4626,20 @@ func (v *NonStandardServiceName_NonStandardFunctionName_Result) FromWire(w wire. return nil } +// Encode serializes a NonStandardServiceName_NonStandardFunctionName_Result struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a NonStandardServiceName_NonStandardFunctionName_Result struct could not be encoded. +func (v *NonStandardServiceName_NonStandardFunctionName_Result) Encode(sw stream.Writer) error { + var () + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a NonStandardServiceName_NonStandardFunctionName_Result // struct. func (v *NonStandardServiceName_NonStandardFunctionName_Result) String() string { diff --git a/gen/internal/tests/set_to_slice/set_to_slice.go b/gen/internal/tests/set_to_slice/set_to_slice.go index 6b4b7c16..ff5ee925 100644 --- a/gen/internal/tests/set_to_slice/set_to_slice.go +++ b/gen/internal/tests/set_to_slice/set_to_slice.go @@ -7,6 +7,7 @@ import ( errors "errors" fmt "fmt" multierr "go.uber.org/multierr" + stream "go.uber.org/thriftrw/protocol/stream" thriftreflect "go.uber.org/thriftrw/thriftreflect" wire "go.uber.org/thriftrw/wire" zapcore "go.uber.org/zap/zapcore" @@ -59,6 +60,11 @@ func (v AnotherStringList) String() string { return fmt.Sprint(x) } +func (v AnotherStringList) Encode(sw stream.Writer) error { + x := (MyStringList)(v) + return x.Encode(sw) +} + // FromWire deserializes AnotherStringList from its Thrift-level // representation. The Thrift-level representation may be obtained // from a ThriftRW protocol implementation. @@ -557,6 +563,254 @@ func (v *Bar) FromWire(w wire.Value) error { return nil } +func _Set_I32_sliceType_Encode(val []int32, sw stream.Writer) error { + var err error + + sh := stream.SetHeader{ + Type: wire.TI32, + Length: len(val), + } + + if err := sw.WriteSetBegin(sh); err != nil { + return err + } + + for _, v := range val { + + if err := sw.WriteInt32(v); err != nil { + return err + } + } + return sw.WriteSetEnd() +} + +func _Set_String_sliceType_Encode(val []string, sw stream.Writer) error { + var err error + + sh := stream.SetHeader{ + Type: wire.TBinary, + Length: len(val), + } + + if err := sw.WriteSetBegin(sh); err != nil { + return err + } + + for _, v := range val { + + if err := sw.WriteString(v); err != nil { + return err + } + } + return sw.WriteSetEnd() +} + +func _Set_Foo_sliceType_Encode(val []*Foo, sw stream.Writer) error { + var err error + + sh := stream.SetHeader{ + Type: wire.TStruct, + Length: len(val), + } + + if err := sw.WriteSetBegin(sh); err != nil { + return err + } + + for _, v := range val { + + if err := v.Encode(sw); err != nil { + return err + } + } + return sw.WriteSetEnd() +} + +func _Set_Set_String_sliceType_sliceType_Encode(val [][]string, sw stream.Writer) error { + var err error + + sh := stream.SetHeader{ + Type: wire.TSet, + Length: len(val), + } + + if err := sw.WriteSetBegin(sh); err != nil { + return err + } + + for _, v := range val { + + if err := _Set_String_sliceType_Encode(v, sw); err != nil { + return err + } + } + return sw.WriteSetEnd() +} + +// Encode serializes a Bar struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a Bar struct could not be encoded. +func (v *Bar) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.RequiredInt32ListField == nil { + return errors.New("field RequiredInt32ListField of Bar is required") + } + fh = stream.FieldHeader{ID: 1, Type: wire.TSet} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _Set_I32_sliceType_Encode(v.RequiredInt32ListField, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + if v.OptionalStringListField != nil { + fh = stream.FieldHeader{ID: 2, Type: wire.TSet} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _Set_String_sliceType_Encode(v.OptionalStringListField, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.RequiredTypedefStringListField == nil { + return errors.New("field RequiredTypedefStringListField of Bar is required") + } + fh = stream.FieldHeader{ID: 3, Type: wire.TSet} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.RequiredTypedefStringListField.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + if v.OptionalTypedefStringListField != nil { + fh = stream.FieldHeader{ID: 4, Type: wire.TSet} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.OptionalTypedefStringListField.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.RequiredFooListField == nil { + return errors.New("field RequiredFooListField of Bar is required") + } + fh = stream.FieldHeader{ID: 5, Type: wire.TSet} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _Set_Foo_sliceType_Encode(v.RequiredFooListField, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + if v.OptionalFooListField != nil { + fh = stream.FieldHeader{ID: 6, Type: wire.TSet} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _Set_Foo_sliceType_Encode(v.OptionalFooListField, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.RequiredTypedefFooListField == nil { + return errors.New("field RequiredTypedefFooListField of Bar is required") + } + fh = stream.FieldHeader{ID: 7, Type: wire.TSet} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.RequiredTypedefFooListField.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + if v.OptionalTypedefFooListField != nil { + fh = stream.FieldHeader{ID: 8, Type: wire.TSet} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.OptionalTypedefFooListField.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.RequiredStringListListField == nil { + return errors.New("field RequiredStringListListField of Bar is required") + } + fh = stream.FieldHeader{ID: 9, Type: wire.TSet} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _Set_Set_String_sliceType_sliceType_Encode(v.RequiredStringListListField, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + if v.RequiredTypedefStringListListField == nil { + return errors.New("field RequiredTypedefStringListListField of Bar is required") + } + fh = stream.FieldHeader{ID: 10, Type: wire.TSet} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.RequiredTypedefStringListListField.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a Bar // struct. func (v *Bar) String() string { @@ -1009,6 +1263,36 @@ func (v *Foo) FromWire(w wire.Value) error { return nil } +// Encode serializes a Foo struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a Foo struct could not be encoded. +func (v *Foo) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + fh = stream.FieldHeader{ID: 1, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(v.StringField); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a Foo // struct. func (v *Foo) String() string { @@ -1076,6 +1360,11 @@ func (v FooList) String() string { return fmt.Sprint(x) } +func (v FooList) Encode(sw stream.Writer) error { + x := ([]*Foo)(v) + return _Set_Foo_sliceType_Encode(x, sw) +} + // FromWire deserializes FooList from its Thrift-level // representation. The Thrift-level representation may be obtained // from a ThriftRW protocol implementation. @@ -1111,6 +1400,11 @@ func (v MyStringList) String() string { return fmt.Sprint(x) } +func (v MyStringList) Encode(sw stream.Writer) error { + x := (StringList)(v) + return x.Encode(sw) +} + // FromWire deserializes MyStringList from its Thrift-level // representation. The Thrift-level representation may be obtained // from a ThriftRW protocol implementation. @@ -1146,6 +1440,11 @@ func (v StringList) String() string { return fmt.Sprint(x) } +func (v StringList) Encode(sw stream.Writer) error { + x := ([]string)(v) + return _Set_String_sliceType_Encode(x, sw) +} + // FromWire deserializes StringList from its Thrift-level // representation. The Thrift-level representation may be obtained // from a ThriftRW protocol implementation. @@ -1181,6 +1480,11 @@ func (v StringListList) String() string { return fmt.Sprint(x) } +func (v StringListList) Encode(sw stream.Writer) error { + x := ([][]string)(v) + return _Set_Set_String_sliceType_sliceType_Encode(x, sw) +} + // FromWire deserializes StringListList from its Thrift-level // representation. The Thrift-level representation may be obtained // from a ThriftRW protocol implementation. @@ -1226,6 +1530,27 @@ func (_Set_String_mapType_ValueList) ValueType() wire.Type { func (_Set_String_mapType_ValueList) Close() {} +func _Set_String_mapType_Encode(val map[string]struct{}, sw stream.Writer) error { + var err error + + sh := stream.SetHeader{ + Type: wire.TBinary, + Length: len(val), + } + + if err := sw.WriteSetBegin(sh); err != nil { + return err + } + + for v, _ := range val { + + if err := sw.WriteString(v); err != nil { + return err + } + } + return sw.WriteSetEnd() +} + func _Set_String_mapType_Read(s wire.ValueList) (map[string]struct{}, error) { if s.ValueType() != wire.TBinary { return nil, nil @@ -1286,6 +1611,11 @@ func (v StringSet) String() string { return fmt.Sprint(x) } +func (v StringSet) Encode(sw stream.Writer) error { + x := (map[string]struct{})(v) + return _Set_String_mapType_Encode(x, sw) +} + // FromWire deserializes StringSet from its Thrift-level // representation. The Thrift-level representation may be obtained // from a ThriftRW protocol implementation. diff --git a/gen/internal/tests/structs/structs.go b/gen/internal/tests/structs/structs.go index 7f2aeecc..40d2fa39 100644 --- a/gen/internal/tests/structs/structs.go +++ b/gen/internal/tests/structs/structs.go @@ -10,6 +10,7 @@ import ( fmt "fmt" multierr "go.uber.org/multierr" enums "go.uber.org/thriftrw/gen/internal/tests/enums" + stream "go.uber.org/thriftrw/protocol/stream" ptr "go.uber.org/thriftrw/ptr" thriftreflect "go.uber.org/thriftrw/thriftreflect" wire "go.uber.org/thriftrw/wire" @@ -96,6 +97,36 @@ func (v *ContactInfo) FromWire(w wire.Value) error { return nil } +// Encode serializes a ContactInfo struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a ContactInfo struct could not be encoded. +func (v *ContactInfo) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + fh = stream.FieldHeader{ID: 1, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(v.EmailAddress); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a ContactInfo // struct. func (v *ContactInfo) String() string { @@ -725,6 +756,307 @@ func (v *DefaultsStruct) FromWire(w wire.Value) error { return nil } +func _List_String_Encode(val []string, sw stream.Writer) error { + var ( + err error + ) + + lh := stream.ListHeader{ + Type: wire.TBinary, + Length: len(val), + } + if err := sw.WriteListBegin(lh); err != nil { + return err + } + + for _, v := range val { + if err := sw.WriteString(v); err != nil { + return err + } + } + return sw.WriteListEnd() +} + +func _List_Double_Encode(val []float64, sw stream.Writer) error { + var ( + err error + ) + + lh := stream.ListHeader{ + Type: wire.TDouble, + Length: len(val), + } + if err := sw.WriteListBegin(lh); err != nil { + return err + } + + for _, v := range val { + if err := sw.WriteDouble(v); err != nil { + return err + } + } + return sw.WriteListEnd() +} + +// Encode serializes a DefaultsStruct struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a DefaultsStruct struct could not be encoded. +func (v *DefaultsStruct) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + vRequiredPrimitive := v.RequiredPrimitive + if vRequiredPrimitive == nil { + vRequiredPrimitive = ptr.Int32(100) + } + { + fh = stream.FieldHeader{ID: 1, Type: wire.TI32} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteInt32(*(vRequiredPrimitive)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + vOptionalPrimitive := v.OptionalPrimitive + if vOptionalPrimitive == nil { + vOptionalPrimitive = ptr.Int32(200) + } + { + fh = stream.FieldHeader{ID: 2, Type: wire.TI32} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteInt32(*(vOptionalPrimitive)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + vRequiredEnum := v.RequiredEnum + if vRequiredEnum == nil { + vRequiredEnum = _EnumDefault_ptr(enums.EnumDefaultBar) + } + { + fh = stream.FieldHeader{ID: 3, Type: wire.TI32} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := vRequiredEnum.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + vOptionalEnum := v.OptionalEnum + if vOptionalEnum == nil { + vOptionalEnum = _EnumDefault_ptr(enums.EnumDefaultBaz) + } + { + fh = stream.FieldHeader{ID: 4, Type: wire.TI32} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := vOptionalEnum.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + vRequiredList := v.RequiredList + if vRequiredList == nil { + vRequiredList = []string{ + "hello", + "world", + } + } + { + fh = stream.FieldHeader{ID: 5, Type: wire.TList} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _List_String_Encode(vRequiredList, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + vOptionalList := v.OptionalList + if vOptionalList == nil { + vOptionalList = []float64{ + 1, + 2, + 3, + } + } + { + fh = stream.FieldHeader{ID: 6, Type: wire.TList} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _List_Double_Encode(vOptionalList, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + vRequiredStruct := v.RequiredStruct + if vRequiredStruct == nil { + vRequiredStruct = &Frame{ + Size: &Size{ + Height: 200, + Width: 100, + }, + TopLeft: &Point{ + X: 1, + Y: 2, + }, + } + } + { + fh = stream.FieldHeader{ID: 7, Type: wire.TStruct} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := vRequiredStruct.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + vOptionalStruct := v.OptionalStruct + if vOptionalStruct == nil { + vOptionalStruct = &Edge{ + EndPoint: &Point{ + X: 3, + Y: 4, + }, + StartPoint: &Point{ + X: 1, + Y: 2, + }, + } + } + { + fh = stream.FieldHeader{ID: 8, Type: wire.TStruct} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := vOptionalStruct.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + vRequiredBoolDefaultTrue := v.RequiredBoolDefaultTrue + if vRequiredBoolDefaultTrue == nil { + vRequiredBoolDefaultTrue = ptr.Bool(true) + } + { + fh = stream.FieldHeader{ID: 9, Type: wire.TBool} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteBool(*(vRequiredBoolDefaultTrue)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + vOptionalBoolDefaultTrue := v.OptionalBoolDefaultTrue + if vOptionalBoolDefaultTrue == nil { + vOptionalBoolDefaultTrue = ptr.Bool(true) + } + { + fh = stream.FieldHeader{ID: 10, Type: wire.TBool} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteBool(*(vOptionalBoolDefaultTrue)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + vRequiredBoolDefaultFalse := v.RequiredBoolDefaultFalse + if vRequiredBoolDefaultFalse == nil { + vRequiredBoolDefaultFalse = ptr.Bool(false) + } + { + fh = stream.FieldHeader{ID: 11, Type: wire.TBool} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteBool(*(vRequiredBoolDefaultFalse)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + vOptionalBoolDefaultFalse := v.OptionalBoolDefaultFalse + if vOptionalBoolDefaultFalse == nil { + vOptionalBoolDefaultFalse = ptr.Bool(false) + } + { + fh = stream.FieldHeader{ID: 12, Type: wire.TBool} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteBool(*(vOptionalBoolDefaultFalse)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a DefaultsStruct // struct. func (v *DefaultsStruct) String() string { @@ -1279,6 +1611,54 @@ func (v *Edge) FromWire(w wire.Value) error { return nil } +// Encode serializes a Edge struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a Edge struct could not be encoded. +func (v *Edge) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.StartPoint == nil { + return errors.New("field StartPoint of Edge is required") + } + fh = stream.FieldHeader{ID: 1, Type: wire.TStruct} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.StartPoint.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + if v.EndPoint == nil { + return errors.New("field EndPoint of Edge is required") + } + fh = stream.FieldHeader{ID: 2, Type: wire.TStruct} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.EndPoint.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a Edge // struct. func (v *Edge) String() string { @@ -1409,6 +1789,20 @@ func (v *EmptyStruct) FromWire(w wire.Value) error { return nil } +// Encode serializes a EmptyStruct struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a EmptyStruct struct could not be encoded. +func (v *EmptyStruct) Encode(sw stream.Writer) error { + var () + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a EmptyStruct // struct. func (v *EmptyStruct) String() string { @@ -1556,6 +1950,54 @@ func (v *Frame) FromWire(w wire.Value) error { return nil } +// Encode serializes a Frame struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a Frame struct could not be encoded. +func (v *Frame) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.TopLeft == nil { + return errors.New("field TopLeft of Frame is required") + } + fh = stream.FieldHeader{ID: 1, Type: wire.TStruct} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.TopLeft.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + if v.Size == nil { + return errors.New("field Size of Frame is required") + } + fh = stream.FieldHeader{ID: 2, Type: wire.TStruct} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.Size.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a Frame // struct. func (v *Frame) String() string { @@ -1814,6 +2256,100 @@ func (v *GoTags) FromWire(w wire.Value) error { return nil } +// Encode serializes a GoTags struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a GoTags struct could not be encoded. +func (v *GoTags) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + fh = stream.FieldHeader{ID: 1, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(v.Foo); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + if v.Bar != nil { + fh = stream.FieldHeader{ID: 2, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(*(v.Bar)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + fh = stream.FieldHeader{ID: 3, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(v.FooBar); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + fh = stream.FieldHeader{ID: 4, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(v.FooBarWithSpace); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + if v.FooBarWithOmitEmpty != nil { + fh = stream.FieldHeader{ID: 5, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(*(v.FooBarWithOmitEmpty)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + fh = stream.FieldHeader{ID: 6, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(v.FooBarWithRequired); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a GoTags // struct. func (v *GoTags) String() string { @@ -2097,7 +2633,58 @@ func (v *Graph) FromWire(w wire.Value) error { return errors.New("field Edges of Graph is required") } - return nil + return nil +} + +func _List_Edge_Encode(val []*Edge, sw stream.Writer) error { + var ( + err error + ) + + lh := stream.ListHeader{ + Type: wire.TStruct, + Length: len(val), + } + if err := sw.WriteListBegin(lh); err != nil { + return err + } + + for _, v := range val { + if err := v.Encode(sw); err != nil { + return err + } + } + return sw.WriteListEnd() +} + +// Encode serializes a Graph struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a Graph struct could not be encoded. +func (v *Graph) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + fh = stream.FieldHeader{ID: 1, Type: wire.TList} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _List_Edge_Encode(v.Edges, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + return sw.WriteStructEnd() } // String returns a readable string representation of a Graph @@ -2198,6 +2785,11 @@ func (v *List) String() string { return fmt.Sprint(x) } +func (v *List) Encode(sw stream.Writer) error { + x := (*Node)(v) + return x.Encode(sw) +} + // FromWire deserializes List from its Thrift-level // representation. The Thrift-level representation may be obtained // from a ThriftRW protocol implementation. @@ -2319,6 +2911,50 @@ func (v *Node) FromWire(w wire.Value) error { return nil } +// Encode serializes a Node struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a Node struct could not be encoded. +func (v *Node) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + fh = stream.FieldHeader{ID: 1, Type: wire.TI32} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteInt32(v.Value); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + if v.Tail != nil { + fh = stream.FieldHeader{ID: 2, Type: wire.TStruct} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.Tail.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a Node // struct. func (v *Node) String() string { @@ -2660,6 +3296,162 @@ func (v *NotOmitEmpty) FromWire(w wire.Value) error { return nil } +func _Map_String_String_Encode(val map[string]string, sw stream.Writer) error { + var ( + err error + ) + + mh := stream.MapHeader{ + KeyType: wire.TBinary, + ValueType: wire.TBinary, + Length: len(val), + } + if err := sw.WriteMapBegin(mh); err != nil { + return err + } + + for k, v := range val { + if err := sw.WriteString(k); err != nil { + return err + } + if err := sw.WriteString(v); err != nil { + return err + } + } + + return sw.WriteMapEnd() +} + +// Encode serializes a NotOmitEmpty struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a NotOmitEmpty struct could not be encoded. +func (v *NotOmitEmpty) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.NotOmitEmptyString != nil { + fh = stream.FieldHeader{ID: 1, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(*(v.NotOmitEmptyString)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.NotOmitEmptyInt != nil { + fh = stream.FieldHeader{ID: 2, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(*(v.NotOmitEmptyInt)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.NotOmitEmptyBool != nil { + fh = stream.FieldHeader{ID: 3, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(*(v.NotOmitEmptyBool)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.NotOmitEmptyList != nil { + fh = stream.FieldHeader{ID: 4, Type: wire.TList} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _List_String_Encode(v.NotOmitEmptyList, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.NotOmitEmptyMap != nil { + fh = stream.FieldHeader{ID: 5, Type: wire.TMap} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _Map_String_String_Encode(v.NotOmitEmptyMap, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.NotOmitEmptyListMixedWithOmitEmpty != nil { + fh = stream.FieldHeader{ID: 6, Type: wire.TList} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _List_String_Encode(v.NotOmitEmptyListMixedWithOmitEmpty, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.NotOmitEmptyListMixedWithOmitEmptyV2 != nil { + fh = stream.FieldHeader{ID: 7, Type: wire.TList} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _List_String_Encode(v.NotOmitEmptyListMixedWithOmitEmptyV2, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.OmitEmptyString != nil { + fh = stream.FieldHeader{ID: 8, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(*(v.OmitEmptyString)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a NotOmitEmpty // struct. func (v *NotOmitEmpty) String() string { @@ -3024,6 +3816,48 @@ func (v *Omit) FromWire(w wire.Value) error { return nil } +// Encode serializes a Omit struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a Omit struct could not be encoded. +func (v *Omit) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + fh = stream.FieldHeader{ID: 1, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(v.Serialized); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + fh = stream.FieldHeader{ID: 2, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(v.Hidden); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a Omit // struct. func (v *Omit) String() string { @@ -3167,6 +4001,38 @@ func (v *PersonalInfo) FromWire(w wire.Value) error { return nil } +// Encode serializes a PersonalInfo struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a PersonalInfo struct could not be encoded. +func (v *PersonalInfo) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.Age != nil { + fh = stream.FieldHeader{ID: 1, Type: wire.TI32} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteInt32(*(v.Age)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a PersonalInfo // struct. func (v *PersonalInfo) String() string { @@ -3329,6 +4195,48 @@ func (v *Point) FromWire(w wire.Value) error { return nil } +// Encode serializes a Point struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a Point struct could not be encoded. +func (v *Point) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + fh = stream.FieldHeader{ID: 1, Type: wire.TDouble} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteDouble(v.X); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + fh = stream.FieldHeader{ID: 2, Type: wire.TDouble} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteDouble(v.Y); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a Point // struct. func (v *Point) String() string { @@ -3581,29 +4489,159 @@ func (v *PrimitiveOptionalStruct) FromWire(w wire.Value) error { return err } - } - case 7: - if field.Value.Type() == wire.TBinary { - var x string - x, err = field.Value.GetString(), error(nil) - v.StringField = &x - if err != nil { - return err - } + } + case 7: + if field.Value.Type() == wire.TBinary { + var x string + x, err = field.Value.GetString(), error(nil) + v.StringField = &x + if err != nil { + return err + } + + } + case 8: + if field.Value.Type() == wire.TBinary { + v.BinaryField, err = field.Value.GetBinary(), error(nil) + if err != nil { + return err + } + + } + } + } + + return nil +} + +// Encode serializes a PrimitiveOptionalStruct struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a PrimitiveOptionalStruct struct could not be encoded. +func (v *PrimitiveOptionalStruct) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.BoolField != nil { + fh = stream.FieldHeader{ID: 1, Type: wire.TBool} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteBool(*(v.BoolField)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.ByteField != nil { + fh = stream.FieldHeader{ID: 2, Type: wire.TI8} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteInt8(*(v.ByteField)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.Int16Field != nil { + fh = stream.FieldHeader{ID: 3, Type: wire.TI16} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteInt16(*(v.Int16Field)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.Int32Field != nil { + fh = stream.FieldHeader{ID: 4, Type: wire.TI32} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteInt32(*(v.Int32Field)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.Int64Field != nil { + fh = stream.FieldHeader{ID: 5, Type: wire.TI64} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteInt64(*(v.Int64Field)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } - } - case 8: - if field.Value.Type() == wire.TBinary { - v.BinaryField, err = field.Value.GetBinary(), error(nil) - if err != nil { - return err - } + if v.DoubleField != nil { + fh = stream.FieldHeader{ID: 6, Type: wire.TDouble} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteDouble(*(v.DoubleField)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } - } + if v.StringField != nil { + fh = stream.FieldHeader{ID: 7, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(*(v.StringField)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err } + i++ } - return nil + if v.BinaryField != nil { + fh = stream.FieldHeader{ID: 8, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteBinary(v.BinaryField); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() } // String returns a readable string representation of a PrimitiveOptionalStruct @@ -4113,6 +5151,123 @@ func (v *PrimitiveRequiredStruct) FromWire(w wire.Value) error { return nil } +// Encode serializes a PrimitiveRequiredStruct struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a PrimitiveRequiredStruct struct could not be encoded. +func (v *PrimitiveRequiredStruct) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + fh = stream.FieldHeader{ID: 1, Type: wire.TBool} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteBool(v.BoolField); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + fh = stream.FieldHeader{ID: 2, Type: wire.TI8} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteInt8(v.ByteField); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + fh = stream.FieldHeader{ID: 3, Type: wire.TI16} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteInt16(v.Int16Field); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + fh = stream.FieldHeader{ID: 4, Type: wire.TI32} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteInt32(v.Int32Field); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + fh = stream.FieldHeader{ID: 5, Type: wire.TI64} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteInt64(v.Int64Field); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + fh = stream.FieldHeader{ID: 6, Type: wire.TDouble} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteDouble(v.DoubleField); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + fh = stream.FieldHeader{ID: 7, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(v.StringField); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + if v.BinaryField == nil { + return errors.New("field BinaryField of PrimitiveRequiredStruct is required") + } + fh = stream.FieldHeader{ID: 8, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteBinary(v.BinaryField); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a PrimitiveRequiredStruct // struct. func (v *PrimitiveRequiredStruct) String() string { @@ -4374,6 +5529,48 @@ func (v *Rename) FromWire(w wire.Value) error { return nil } +// Encode serializes a Rename struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a Rename struct could not be encoded. +func (v *Rename) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + fh = stream.FieldHeader{ID: 1, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(v.Default); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + fh = stream.FieldHeader{ID: 2, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(v.CamelCase); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a Rename // struct. func (v *Rename) String() string { @@ -4543,6 +5740,48 @@ func (v *Size) FromWire(w wire.Value) error { return nil } +// Encode serializes a Size struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a Size struct could not be encoded. +func (v *Size) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + fh = stream.FieldHeader{ID: 1, Type: wire.TDouble} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteDouble(v.Width); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + fh = stream.FieldHeader{ID: 2, Type: wire.TDouble} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteDouble(v.Height); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a Size // struct. func (v *Size) String() string { @@ -4743,6 +5982,80 @@ func (v *StructLabels) FromWire(w wire.Value) error { return nil } +// Encode serializes a StructLabels struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a StructLabels struct could not be encoded. +func (v *StructLabels) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.IsRequired != nil { + fh = stream.FieldHeader{ID: 1, Type: wire.TBool} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteBool(*(v.IsRequired)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.Foo != nil { + fh = stream.FieldHeader{ID: 2, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(*(v.Foo)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.Qux != nil { + fh = stream.FieldHeader{ID: 3, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(*(v.Qux)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.Quux != nil { + fh = stream.FieldHeader{ID: 4, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(*(v.Quux)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a StructLabels // struct. func (v *StructLabels) String() string { @@ -5004,6 +6317,64 @@ func (v *User) FromWire(w wire.Value) error { return nil } +// Encode serializes a User struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a User struct could not be encoded. +func (v *User) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + fh = stream.FieldHeader{ID: 1, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(v.Name); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + if v.Contact != nil { + fh = stream.FieldHeader{ID: 2, Type: wire.TStruct} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.Contact.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.Personal != nil { + fh = stream.FieldHeader{ID: 3, Type: wire.TStruct} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.Personal.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a User // struct. func (v *User) String() string { @@ -5143,6 +6514,32 @@ func (_Map_String_User_MapItemList) ValueType() wire.Type { func (_Map_String_User_MapItemList) Close() {} +func _Map_String_User_Encode(val map[string]*User, sw stream.Writer) error { + var ( + err error + ) + + mh := stream.MapHeader{ + KeyType: wire.TBinary, + ValueType: wire.TStruct, + Length: len(val), + } + if err := sw.WriteMapBegin(mh); err != nil { + return err + } + + for k, v := range val { + if err := sw.WriteString(k); err != nil { + return err + } + if err := v.Encode(sw); err != nil { + return err + } + } + + return sw.WriteMapEnd() +} + func _User_Read(w wire.Value) (*User, error) { var v User err := v.FromWire(w) @@ -5221,6 +6618,11 @@ func (v UserMap) String() string { return fmt.Sprint(x) } +func (v UserMap) Encode(sw stream.Writer) error { + x := (map[string]*User)(v) + return _Map_String_User_Encode(x, sw) +} + // FromWire deserializes UserMap from its Thrift-level // representation. The Thrift-level representation may be obtained // from a ThriftRW protocol implementation. @@ -5340,6 +6742,48 @@ func (v *ZapOptOutStruct) FromWire(w wire.Value) error { return nil } +// Encode serializes a ZapOptOutStruct struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a ZapOptOutStruct struct could not be encoded. +func (v *ZapOptOutStruct) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + fh = stream.FieldHeader{ID: 1, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(v.Name); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + fh = stream.FieldHeader{ID: 2, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(v.Optout); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a ZapOptOutStruct // struct. func (v *ZapOptOutStruct) String() string { diff --git a/gen/internal/tests/typedefs/typedefs.go b/gen/internal/tests/typedefs/typedefs.go index e5f10de1..b4fe19b6 100644 --- a/gen/internal/tests/typedefs/typedefs.go +++ b/gen/internal/tests/typedefs/typedefs.go @@ -11,6 +11,7 @@ import ( multierr "go.uber.org/multierr" enums "go.uber.org/thriftrw/gen/internal/tests/enums" structs "go.uber.org/thriftrw/gen/internal/tests/structs" + stream "go.uber.org/thriftrw/protocol/stream" thriftreflect "go.uber.org/thriftrw/thriftreflect" wire "go.uber.org/thriftrw/wire" zapcore "go.uber.org/zap/zapcore" @@ -46,6 +47,27 @@ func (_Set_Binary_sliceType_ValueList) ValueType() wire.Type { func (_Set_Binary_sliceType_ValueList) Close() {} +func _Set_Binary_sliceType_Encode(val [][]byte, sw stream.Writer) error { + var err error + + sh := stream.SetHeader{ + Type: wire.TBinary, + Length: len(val), + } + + if err := sw.WriteSetBegin(sh); err != nil { + return err + } + + for _, v := range val { + + if err := sw.WriteBinary(v); err != nil { + return err + } + } + return sw.WriteSetEnd() +} + func _Set_Binary_sliceType_Read(s wire.ValueList) ([][]byte, error) { if s.ValueType() != wire.TBinary { return nil, nil @@ -113,6 +135,11 @@ func (v BinarySet) String() string { return fmt.Sprint(x) } +func (v BinarySet) Encode(sw stream.Writer) error { + x := ([][]byte)(v) + return _Set_Binary_sliceType_Encode(x, sw) +} + // FromWire deserializes BinarySet from its Thrift-level // representation. The Thrift-level representation may be obtained // from a ThriftRW protocol implementation. @@ -235,6 +262,42 @@ func (v *DefaultPrimitiveTypedef) FromWire(w wire.Value) error { return nil } +// Encode serializes a DefaultPrimitiveTypedef struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a DefaultPrimitiveTypedef struct could not be encoded. +func (v *DefaultPrimitiveTypedef) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + vState := v.State + if vState == nil { + vState = _State_ptr("hello") + } + { + fh = stream.FieldHeader{ID: 1, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := vState.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a DefaultPrimitiveTypedef // struct. func (v *DefaultPrimitiveTypedef) String() string { @@ -352,6 +415,37 @@ func (_Map_Edge_Edge_MapItemList) ValueType() wire.Type { func (_Map_Edge_Edge_MapItemList) Close() {} +func _Map_Edge_Edge_Encode(val []struct { + Key *structs.Edge + Value *structs.Edge +}, sw stream.Writer) error { + var ( + err error + ) + + mh := stream.MapHeader{ + KeyType: wire.TStruct, + ValueType: wire.TStruct, + Length: len(val), + } + if err := sw.WriteMapBegin(mh); err != nil { + return err + } + + for _, v := range val { + key := v.Key + if err := key.Encode(sw); err != nil { + return err + } + value := v.Value + if err := value.Encode(sw); err != nil { + return err + } + } + + return sw.WriteMapEnd() +} + func _Edge_Read(w wire.Value) (*structs.Edge, error) { var v structs.Edge err := v.FromWire(w) @@ -482,6 +576,14 @@ func (v EdgeMap) String() string { return fmt.Sprint(x) } +func (v EdgeMap) Encode(sw stream.Writer) error { + x := ([]struct { + Key *structs.Edge + Value *structs.Edge + })(v) + return _Map_Edge_Edge_Encode(x, sw) +} + // FromWire deserializes EdgeMap from its Thrift-level // representation. The Thrift-level representation may be obtained // from a ThriftRW protocol implementation. @@ -623,6 +725,53 @@ func (v *Event) FromWire(w wire.Value) error { return nil } +// Encode serializes a Event struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a Event struct could not be encoded. +func (v *Event) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.UUID == nil { + return errors.New("field UUID of Event is required") + } + fh = stream.FieldHeader{ID: 1, Type: wire.TStruct} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.UUID.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + if v.Time != nil { + fh = stream.FieldHeader{ID: 2, Type: wire.TI64} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.Time.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a Event // struct. func (v *Event) String() string { @@ -743,6 +892,27 @@ func (_List_Event_ValueList) ValueType() wire.Type { func (_List_Event_ValueList) Close() {} +func _List_Event_Encode(val []*Event, sw stream.Writer) error { + var ( + err error + ) + + lh := stream.ListHeader{ + Type: wire.TStruct, + Length: len(val), + } + if err := sw.WriteListBegin(lh); err != nil { + return err + } + + for _, v := range val { + if err := v.Encode(sw); err != nil { + return err + } + } + return sw.WriteListEnd() +} + func _Event_Read(w wire.Value) (*Event, error) { var v Event err := v.FromWire(w) @@ -809,6 +979,11 @@ func (v EventGroup) String() string { return fmt.Sprint(x) } +func (v EventGroup) Encode(sw stream.Writer) error { + x := ([]*Event)(v) + return _List_Event_Encode(x, sw) +} + // FromWire deserializes EventGroup from its Thrift-level // representation. The Thrift-level representation may be obtained // from a ThriftRW protocol implementation. @@ -857,6 +1032,27 @@ func (_Set_Frame_sliceType_ValueList) ValueType() wire.Type { func (_Set_Frame_sliceType_ValueList) Close() {} +func _Set_Frame_sliceType_Encode(val []*structs.Frame, sw stream.Writer) error { + var err error + + sh := stream.SetHeader{ + Type: wire.TStruct, + Length: len(val), + } + + if err := sw.WriteSetBegin(sh); err != nil { + return err + } + + for _, v := range val { + + if err := v.Encode(sw); err != nil { + return err + } + } + return sw.WriteSetEnd() +} + func _Frame_Read(w wire.Value) (*structs.Frame, error) { var v structs.Frame err := v.FromWire(w) @@ -930,6 +1126,11 @@ func (v FrameGroup) String() string { return fmt.Sprint(x) } +func (v FrameGroup) Encode(sw stream.Writer) error { + x := ([]*structs.Frame)(v) + return _Set_Frame_sliceType_Encode(x, sw) +} + // FromWire deserializes FrameGroup from its Thrift-level // representation. The Thrift-level representation may be obtained // from a ThriftRW protocol implementation. @@ -976,6 +1177,11 @@ func (v MyEnum) String() string { return fmt.Sprint(x) } +func (v MyEnum) Encode(sw stream.Writer) error { + x := (enums.EnumWithValues)(v) + return x.Encode(sw) +} + // FromWire deserializes MyEnum from its Thrift-level // representation. The Thrift-level representation may be obtained // from a ThriftRW protocol implementation. @@ -1011,6 +1217,11 @@ func (v *MyUUID) String() string { return fmt.Sprint(x) } +func (v *MyUUID) Encode(sw stream.Writer) error { + x := (*UUID)(v) + return x.Encode(sw) +} + // FromWire deserializes MyUUID from its Thrift-level // representation. The Thrift-level representation may be obtained // from a ThriftRW protocol implementation. @@ -1044,6 +1255,11 @@ func (v PDF) String() string { return fmt.Sprint(x) } +func (v PDF) Encode(sw stream.Writer) error { + x := ([]byte)(v) + return sw.WriteBinary(x) +} + // FromWire deserializes PDF from its Thrift-level // representation. The Thrift-level representation may be obtained // from a ThriftRW protocol implementation. @@ -1105,6 +1321,37 @@ func (_Map_Point_Point_MapItemList) ValueType() wire.Type { func (_Map_Point_Point_MapItemList) Close() {} +func _Map_Point_Point_Encode(val []struct { + Key *structs.Point + Value *structs.Point +}, sw stream.Writer) error { + var ( + err error + ) + + mh := stream.MapHeader{ + KeyType: wire.TStruct, + ValueType: wire.TStruct, + Length: len(val), + } + if err := sw.WriteMapBegin(mh); err != nil { + return err + } + + for _, v := range val { + key := v.Key + if err := key.Encode(sw); err != nil { + return err + } + value := v.Value + if err := value.Encode(sw); err != nil { + return err + } + } + + return sw.WriteMapEnd() +} + func _Point_Read(w wire.Value) (*structs.Point, error) { var v structs.Point err := v.FromWire(w) @@ -1235,6 +1482,14 @@ func (v PointMap) String() string { return fmt.Sprint(x) } +func (v PointMap) Encode(sw stream.Writer) error { + x := ([]struct { + Key *structs.Point + Value *structs.Point + })(v) + return _Map_Point_Point_Encode(x, sw) +} + // FromWire deserializes PointMap from its Thrift-level // representation. The Thrift-level representation may be obtained // from a ThriftRW protocol implementation. @@ -1284,6 +1539,11 @@ func (v State) String() string { return fmt.Sprint(x) } +func (v State) Encode(sw stream.Writer) error { + x := (string)(v) + return sw.WriteString(x) +} + // FromWire deserializes State from its Thrift-level // representation. The Thrift-level representation may be obtained // from a ThriftRW protocol implementation. @@ -1334,6 +1594,32 @@ func (_Map_State_I64_MapItemList) ValueType() wire.Type { func (_Map_State_I64_MapItemList) Close() {} +func _Map_State_I64_Encode(val map[State]int64, sw stream.Writer) error { + var ( + err error + ) + + mh := stream.MapHeader{ + KeyType: wire.TBinary, + ValueType: wire.TI64, + Length: len(val), + } + if err := sw.WriteMapBegin(mh); err != nil { + return err + } + + for k, v := range val { + if err := k.Encode(sw); err != nil { + return err + } + if err := sw.WriteInt64(v); err != nil { + return err + } + } + + return sw.WriteMapEnd() +} + func _Map_State_I64_Read(m wire.MapItemList) (map[State]int64, error) { if m.KeyType() != wire.TBinary { return nil, nil @@ -1406,6 +1692,11 @@ func (v StateMap) String() string { return fmt.Sprint(x) } +func (v StateMap) Encode(sw stream.Writer) error { + x := (map[State]int64)(v) + return _Map_State_I64_Encode(x, sw) +} + // FromWire deserializes StateMap from its Thrift-level // representation. The Thrift-level representation may be obtained // from a ThriftRW protocol implementation. @@ -1449,6 +1740,11 @@ func (v Timestamp) String() string { return fmt.Sprint(x) } +func (v Timestamp) Encode(sw stream.Writer) error { + x := (int64)(v) + return sw.WriteInt64(x) +} + // FromWire deserializes Timestamp from its Thrift-level // representation. The Thrift-level representation may be obtained // from a ThriftRW protocol implementation. @@ -1587,6 +1883,62 @@ func (v *Transition) FromWire(w wire.Value) error { return nil } +// Encode serializes a Transition struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a Transition struct could not be encoded. +func (v *Transition) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + fh = stream.FieldHeader{ID: 1, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.FromState.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + fh = stream.FieldHeader{ID: 2, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.ToState.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + if v.Events != nil { + fh = stream.FieldHeader{ID: 3, Type: wire.TList} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.Events.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a Transition // struct. func (v *Transition) String() string { @@ -1766,6 +2118,39 @@ func (v *TransitiveTypedefField) FromWire(w wire.Value) error { return nil } +// Encode serializes a TransitiveTypedefField struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a TransitiveTypedefField struct could not be encoded. +func (v *TransitiveTypedefField) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.DefUUID == nil { + return errors.New("field DefUUID of TransitiveTypedefField is required") + } + fh = stream.FieldHeader{ID: 1, Type: wire.TStruct} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.DefUUID.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a TransitiveTypedefField // struct. func (v *TransitiveTypedefField) String() string { @@ -1838,6 +2223,11 @@ func (v *UUID) String() string { return fmt.Sprint(x) } +func (v *UUID) Encode(sw stream.Writer) error { + x := (*I128)(v) + return x.Encode(sw) +} + // FromWire deserializes UUID from its Thrift-level // representation. The Thrift-level representation may be obtained // from a ThriftRW protocol implementation. @@ -1955,6 +2345,48 @@ func (v *I128) FromWire(w wire.Value) error { return nil } +// Encode serializes a I128 struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a I128 struct could not be encoded. +func (v *I128) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + fh = stream.FieldHeader{ID: 1, Type: wire.TI64} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteInt64(v.High); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + fh = stream.FieldHeader{ID: 2, Type: wire.TI64} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteInt64(v.Low); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a I128 // struct. func (v *I128) String() string { diff --git a/gen/internal/tests/unions/unions.go b/gen/internal/tests/unions/unions.go index 0f17e9bd..1efc445c 100644 --- a/gen/internal/tests/unions/unions.go +++ b/gen/internal/tests/unions/unions.go @@ -8,6 +8,7 @@ import ( fmt "fmt" multierr "go.uber.org/multierr" typedefs "go.uber.org/thriftrw/gen/internal/tests/typedefs" + stream "go.uber.org/thriftrw/protocol/stream" thriftreflect "go.uber.org/thriftrw/thriftreflect" wire "go.uber.org/thriftrw/wire" zapcore "go.uber.org/zap/zapcore" @@ -315,6 +316,145 @@ func (v *ArbitraryValue) FromWire(w wire.Value) error { return nil } +func _List_ArbitraryValue_Encode(val []*ArbitraryValue, sw stream.Writer) error { + var ( + err error + ) + + lh := stream.ListHeader{ + Type: wire.TStruct, + Length: len(val), + } + if err := sw.WriteListBegin(lh); err != nil { + return err + } + + for _, v := range val { + if err := v.Encode(sw); err != nil { + return err + } + } + return sw.WriteListEnd() +} + +func _Map_String_ArbitraryValue_Encode(val map[string]*ArbitraryValue, sw stream.Writer) error { + var ( + err error + ) + + mh := stream.MapHeader{ + KeyType: wire.TBinary, + ValueType: wire.TStruct, + Length: len(val), + } + if err := sw.WriteMapBegin(mh); err != nil { + return err + } + + for k, v := range val { + if err := sw.WriteString(k); err != nil { + return err + } + if err := v.Encode(sw); err != nil { + return err + } + } + + return sw.WriteMapEnd() +} + +// Encode serializes a ArbitraryValue struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a ArbitraryValue struct could not be encoded. +func (v *ArbitraryValue) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.BoolValue != nil { + fh = stream.FieldHeader{ID: 1, Type: wire.TBool} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteBool(*(v.BoolValue)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.Int64Value != nil { + fh = stream.FieldHeader{ID: 2, Type: wire.TI64} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteInt64(*(v.Int64Value)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.StringValue != nil { + fh = stream.FieldHeader{ID: 3, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(*(v.StringValue)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.ListValue != nil { + fh = stream.FieldHeader{ID: 4, Type: wire.TList} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _List_ArbitraryValue_Encode(v.ListValue, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.MapValue != nil { + fh = stream.FieldHeader{ID: 5, Type: wire.TMap} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := _Map_String_ArbitraryValue_Encode(v.MapValue, sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if i != 1 { + return fmt.Errorf("ArbitraryValue should have exactly one field: got %v fields", i) + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a ArbitraryValue // struct. func (v *ArbitraryValue) String() string { @@ -675,6 +815,56 @@ func (v *Document) FromWire(w wire.Value) error { return nil } +// Encode serializes a Document struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a Document struct could not be encoded. +func (v *Document) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + if v.Pdf != nil { + fh = stream.FieldHeader{ID: 1, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.Pdf.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if v.PlainText != nil { + fh = stream.FieldHeader{ID: 2, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := sw.WriteString(*(v.PlainText)); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + } + + if i != 1 { + return fmt.Errorf("Document should have exactly one field: got %v fields", i) + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a Document // struct. func (v *Document) String() string { @@ -815,6 +1005,20 @@ func (v *EmptyUnion) FromWire(w wire.Value) error { return nil } +// Encode serializes a EmptyUnion struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a EmptyUnion struct could not be encoded. +func (v *EmptyUnion) Encode(sw stream.Writer) error { + var () + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a EmptyUnion // struct. func (v *EmptyUnion) String() string { diff --git a/gen/internal/tests/uuid_conflict/uuid_conflict.go b/gen/internal/tests/uuid_conflict/uuid_conflict.go index 3c3ddd26..e438f3de 100644 --- a/gen/internal/tests/uuid_conflict/uuid_conflict.go +++ b/gen/internal/tests/uuid_conflict/uuid_conflict.go @@ -8,6 +8,7 @@ import ( fmt "fmt" multierr "go.uber.org/multierr" typedefs "go.uber.org/thriftrw/gen/internal/tests/typedefs" + stream "go.uber.org/thriftrw/protocol/stream" thriftreflect "go.uber.org/thriftrw/thriftreflect" wire "go.uber.org/thriftrw/wire" zapcore "go.uber.org/zap/zapcore" @@ -35,6 +36,11 @@ func (v UUID) String() string { return fmt.Sprint(x) } +func (v UUID) Encode(sw stream.Writer) error { + x := (string)(v) + return sw.WriteString(x) +} + // FromWire deserializes UUID from its Thrift-level // representation. The Thrift-level representation may be obtained // from a ThriftRW protocol implementation. @@ -164,6 +170,51 @@ func (v *UUIDConflict) FromWire(w wire.Value) error { return nil } +// Encode serializes a UUIDConflict struct directly into bytes, without going +// through an intemediary type. +// +// An error is returned if a UUIDConflict struct could not be encoded. +func (v *UUIDConflict) Encode(sw stream.Writer) error { + var ( + i int = 0 + err error + fh stream.FieldHeader + ) + + if err := sw.WriteStructBegin(); err != nil { + return err + } + + fh = stream.FieldHeader{ID: 1, Type: wire.TBinary} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.LocalUUID.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + if v.ImportedUUID == nil { + return errors.New("field ImportedUUID of UUIDConflict is required") + } + fh = stream.FieldHeader{ID: 2, Type: wire.TStruct} + if err := sw.WriteFieldBegin(fh); err != nil { + return err + } + if err := v.ImportedUUID.Encode(sw); err != nil { + return err + } + if err := sw.WriteFieldEnd(); err != nil { + return err + } + i++ + + return sw.WriteStructEnd() +} + // String returns a readable string representation of a UUIDConflict // struct. func (v *UUIDConflict) String() string { diff --git a/gen/list.go b/gen/list.go index 765a0140..bc445e3b 100644 --- a/gen/list.go +++ b/gen/list.go @@ -140,6 +140,57 @@ func (l *listGenerator) Reader(g Generator, spec *compile.ListSpec) (string, err return name, wrapGenerateError(spec.ThriftName(), err) } +// Encoder generates a function to encode a list given a stream.Writer +// +// func $name(val []listType, sr *stream.Writer) error { +// ... +// } +// +// And returns its name. +func (l *listGenerator) Encode(g Generator, spec *compile.ListSpec) (string, error) { + name := encoderFuncName(g, spec) + err := g.EnsureDeclared( + ` + <$stream := import "go.uber.org/thriftrw/protocol/stream"> + + <$listType := typeReference .Spec> + <$sw := newVar "sw"> + <$lh := newVar "lh"> + <$o := newVar "o"> + <$k := newVar "k"> + <$v := newVar "v"> + <$val := newVar "val"> + func <.Name>(<$val> <$listType>, <$sw> <$stream>.Writer) error { + var ( + err error + ) + + <$vt := typeCode .Spec.ValueSpec> + <$lh> := <$stream>.ListHeader{ + Type: <$vt>, + Length: len(<$val>), + } + if err := <$sw>.WriteListBegin(<$lh>); err != nil { + return err + } + + for _, <$v> := range <$val> { + if err := ; err != nil { + return err + } + } + return <$sw>.WriteListEnd() + } + `, + struct { + Name string + Spec *compile.ListSpec + }{Name: name, Spec: spec}, + ) + + return name, wrapGenerateError(spec.ThriftName(), err) +} + // Equals generates a function to compare lists of the given type // // func $name(lhs, rhs $listType) bool { diff --git a/gen/list_test.go b/gen/list_test.go index 82eecd99..06bf084c 100644 --- a/gen/list_test.go +++ b/gen/list_test.go @@ -163,6 +163,7 @@ func TestRoundtripOptionalListFields(t *testing.T) { t.Run(tt.desc, func(t *testing.T) { // assertRoundTrip does more than we need as we only need to test wire.Value FromWire response. assertRoundTrip(t, tt.want, tt.give, tt.desc) + testRoundTripCombos(t, tt.want, tt.give, tt.desc) }) } } diff --git a/gen/map.go b/gen/map.go index ad7799a3..15f6891d 100644 --- a/gen/map.go +++ b/gen/map.go @@ -179,6 +179,70 @@ func (m *mapGenerator) Reader(g Generator, spec *compile.MapSpec) (string, error return name, wrapGenerateError(spec.ThriftName(), err) } +func (m *mapGenerator) Encode(g Generator, spec *compile.MapSpec) (string, error) { + name := encoderFuncName(g, spec) + err := g.EnsureDeclared( + ` + <$stream := import "go.uber.org/thriftrw/protocol/stream"> + + <$mapType := typeReference .Spec> + <$sw := newVar "sw"> + <$mh := newVar "mh"> + <$o := newVar "o"> + <$k := newVar "k"> + <$v := newVar "v"> + <$val := newVar "val"> + <$key := newVar "key"> + <$value := newVar "value"> + func <.Name>(<$val> <$mapType>, <$sw> <$stream>.Writer) error { + var ( + err error + ) + + <$kt := typeCode .Spec.KeySpec> + <$vt := typeCode .Spec.ValueSpec> + <$mh> := <$stream>.MapHeader{ + KeyType: <$kt>, + ValueType: <$vt>, + Length: len(<$val>), + } + if err := <$sw>.WriteMapBegin(<$mh>); err != nil { + return err + } + + + for <$k>, <$v> := range <$val> { + if err := ; err != nil { + return err + } + if err := ; err != nil { + return err + } + } + + for _, <$v> := range <$val> { + <$key> := + if err := ; err != nil { + return err + } + <$value> := + if err := ; err != nil { + return err + } + } + + return <$sw>.WriteMapEnd() + } + `, + struct { + Name string + Spec *compile.MapSpec + }{Name: name, Spec: spec}, + ) + + return name, wrapGenerateError(spec.ThriftName(), err) +} + // Equals generates a function to compare maps of the given type // // func $name(lhs, rhs $mapType) bool { diff --git a/gen/mock_zap_test.go b/gen/mock_zap_test.go index 25843a10..0468ce97 100644 --- a/gen/mock_zap_test.go +++ b/gen/mock_zap_test.go @@ -5,10 +5,11 @@ package gen import ( - gomock "github.com/golang/mock/gomock" - zapcore "go.uber.org/zap/zapcore" reflect "reflect" time "time" + + gomock "github.com/golang/mock/gomock" + zapcore "go.uber.org/zap/zapcore" ) // MockObjectEncoder is a mock of ObjectEncoder interface diff --git a/gen/roundtrip_test.go b/gen/roundtrip_test.go index 3579c830..9e9fef35 100644 --- a/gen/roundtrip_test.go +++ b/gen/roundtrip_test.go @@ -27,9 +27,11 @@ import ( "testing" "go.uber.org/thriftrw/protocol" + "go.uber.org/thriftrw/protocol/binary" "go.uber.org/thriftrw/wire" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) // assertRoundTrip checks if x.ToWire() results in the given Value and whether @@ -81,3 +83,54 @@ func assertBinaryRoundTrip(t *testing.T, w wire.Value, message string) (wire.Val return newV, true } + +func testRoundTripCombos(t *testing.T, x thriftType, v wire.Value, msg string) { + t.Helper() + + useStreaming := []struct { + encode bool + decode bool + }{ + {false, false}, + //{false, true}, + {true, false}, + //{true, true}, + } + + for _, streaming := range useStreaming { + name := fmt.Sprintf("%s: stream-encode: %v, stream-decode: %v", msg, streaming.encode, streaming.decode) + t.Run(name, func(t *testing.T) { + var buff bytes.Buffer + //streamer := binary.NewStreamWriter() + + xType := reflect.TypeOf(x) + if xType.Kind() == reflect.Ptr { + xType = xType.Elem() + } + + if streaming.encode { + w := binary.BorrowStreamWriter(&buff) + require.NoError(t, x.(streamingThriftType).Encode(w), "%v: failed to stream encode", msg) + binary.ReturnStreamWriter(w) + } else { + w, err := x.ToWire() + require.NoError(t, err, "failed to serialize: %v", x) + require.True(t, wire.ValuesAreEqual(v, w), "%v: %v.ToWire() != %v", msg, x, v) + require.NoError(t, protocol.Binary.Encode(w, &buff), "%v: failed to binary.Encode", msg) + } + + if streaming.decode { + + t.Skip() + } else { + newV, err := protocol.Binary.Decode(bytes.NewReader(buff.Bytes()), v.Type()) + require.NoError(t, err, "failed to deserialize") + + gotX := reflect.New(xType).Interface().(thriftType) + require.NoError(t, gotX.FromWire(newV), "FromWire") + assert.Equal(t, x, gotX) + } + }) + } + +} diff --git a/gen/set.go b/gen/set.go index 032df6ac..4b1a5412 100644 --- a/gen/set.go +++ b/gen/set.go @@ -142,6 +142,54 @@ func (s *setGenerator) Reader(g Generator, spec *compile.SetSpec) (string, error return name, wrapGenerateError(spec.ThriftName(), err) } +func (s *setGenerator) Encode(g Generator, spec *compile.SetSpec) (string, error) { + name := encoderFuncName(g, spec) + err := g.EnsureDeclared( + ` + <$stream := import "go.uber.org/thriftrw/protocol/stream"> + + <$setType := typeReference .Spec> + <$sw := newVar "sw"> + <$sh := newVar "sh"> + <$o := newVar "o"> + <$k := newVar "k"> + <$v := newVar "v"> + <$val := newVar "val"> + func <.Name>(<$val> <$setType>, <$sw> <$stream>.Writer) error { + var err error + + <$vt := typeCode .Spec.ValueSpec> + <$sh> := <$stream>.SetHeader{ + Type: <$vt>, + Length: len(<$val>), + } + + if err := <$sw>.WriteSetBegin(<$sh>); err != nil { + return err + } + + + for <$v>, _ := range <$val> { + + for _, <$v> := range <$val> { + + if err := ; err != nil { + return err + } + } + return <$sw>.WriteSetEnd() + } + `, + struct { + Name string + Spec *compile.SetSpec + }{Name: name, Spec: spec}, + ) + + return name, wrapGenerateError(spec.ThriftName(), err) + +} + // Equals generates a function to compare sets of the given type // // func $name(lhs, rhs $setType) bool { diff --git a/gen/stream.go b/gen/stream.go new file mode 100644 index 00000000..020e4b29 --- /dev/null +++ b/gen/stream.go @@ -0,0 +1,91 @@ +// Copyright (c) 2021 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package gen + +import ( + "fmt" + + "go.uber.org/thriftrw/compile" +) + +// StreamGenerator generates code that knows how to encode and decode Thrift +// objects in a streaming fashion. +type StreamGenerator struct { + mapG mapGenerator + setG setGenerator + listG listGenerator +} + +// Encode generates code that knows how to serialize Thrift types into bytes. +func (sg *StreamGenerator) Encode(g Generator, spec compile.TypeSpec, varName string, sw string) (string, error) { + switch s := spec.(type) { + case *compile.BoolSpec: + return fmt.Sprintf("%s.WriteBool(%s)", sw, varName), nil + case *compile.I8Spec: + return fmt.Sprintf("%s.WriteInt8(%s)", sw, varName), nil + case *compile.I16Spec: + return fmt.Sprintf("%s.WriteInt16(%s)", sw, varName), nil + case *compile.I32Spec: + return fmt.Sprintf("%s.WriteInt32(%s)", sw, varName), nil + case *compile.I64Spec: + return fmt.Sprintf("%s.WriteInt64(%s)", sw, varName), nil + case *compile.DoubleSpec: + return fmt.Sprintf("%s.WriteDouble(%s)", sw, varName), nil + case *compile.StringSpec: + return fmt.Sprintf("%s.WriteString(%s)", sw, varName), nil + case *compile.BinarySpec: + return fmt.Sprintf("%s.WriteBinary(%s)", sw, varName), nil + case *compile.MapSpec: + encoder, err := sg.mapG.Encode(g, s) + if err != nil { + return "", err + } + return fmt.Sprintf("%s(%s, %s)", encoder, varName, sw), nil + case *compile.ListSpec: + encoder, err := sg.listG.Encode(g, s) + if err != nil { + return "", err + } + return fmt.Sprintf("%s(%s, %s)", encoder, varName, sw), nil + case *compile.SetSpec: + encoder, err := sg.setG.Encode(g, s) + if err != nil { + return "", err + } + return fmt.Sprintf("%s(%s, %s)", encoder, varName, sw), nil + default: + return fmt.Sprintf("%s.Encode(%s)", varName, sw), nil + } +} + +// EncodePtr is the same as Encode except varName is expected to be a reference +// to a value of the given type. +func (sg *StreamGenerator) EncodePtr(g Generator, spec compile.TypeSpec, varName string, sw string) (string, error) { + switch spec.(type) { + case *compile.BoolSpec, *compile.I8Spec, *compile.I16Spec, *compile.I32Spec, + *compile.I64Spec, *compile.DoubleSpec, *compile.StringSpec: + return sg.Encode(g, spec, fmt.Sprintf("*(%s)", varName), sw) + default: + // Everything else is either a reference type or has an Encode method + // on it that does automatic dereferencing. + return sg.Encode(g, spec, varName, sw) + } +} diff --git a/gen/struct.go b/gen/struct.go index ebd3c5d3..1a0eb9bf 100644 --- a/gen/struct.go +++ b/gen/struct.go @@ -51,6 +51,28 @@ func (s *structGenerator) Reader(g Generator, spec *compile.StructSpec) (string, return name, wrapGenerateError(spec.ThriftName(), err) } +func (s *structGenerator) Encode(g Generator, spec *compile.StructSpec) (string, error) { + name := encoderFuncName(g, spec) + err := g.EnsureDeclared( + ` + <$stream := import "go.uber.org/thriftrw/protocol/stream"> + + <$val := newVar "val"> + <$sw := newVar "sw"> + <$t := typeReference .Spec> + func <.Name>(<$val> <$t>, <$sw> <$stream>.Writer) error { + return <$val>.Encode(<$sw>) + } + `, + struct { + Name string + Spec *compile.StructSpec + }{Name: name, Spec: spec}, + ) + + return name, wrapGenerateError(spec.ThriftName(), err) +} + func structure(g Generator, spec *compile.StructSpec) error { name, err := goName(spec) if err != nil { diff --git a/gen/struct_test.go b/gen/struct_test.go index d9d3c4da..161687e3 100644 --- a/gen/struct_test.go +++ b/gen/struct_test.go @@ -471,6 +471,7 @@ func TestStructRoundTripAndString(t *testing.T) { } else { assert.NotPanics(t, func() { _ = tt.x.String() }, "ToString: %v", tt.desc) } + testRoundTripCombos(t, tt.x, tt.v, tt.desc) } } @@ -651,7 +652,7 @@ func TestBasicException(t *testing.T) { for _, tt := range tests { assertRoundTrip(t, &tt.s, tt.v, "DoesNotExistException") - + testRoundTripCombos(t, &tt.s, tt.v, "DoesNotExistException") err := error(&tt.s) // should implement the error interface assert.Equal(t, "DoesNotExistException{Key: foo}", err.Error()) } @@ -672,7 +673,7 @@ func TestCollisionException(t *testing.T) { for _, tt := range tests { assertRoundTrip(t, &tt.s, tt.v, "DoesNotExistException2") - + testRoundTripCombos(t, &tt.s, tt.v, "DoesNotExistException2") assert.Equal(t, "Does_Not_Exist_Exception_Collision", tt.s.ErrorName(), "Thrift name of exception incorrect") diff --git a/gen/type.go b/gen/type.go index 9fd502b9..6dcd1669 100644 --- a/gen/type.go +++ b/gen/type.go @@ -208,6 +208,10 @@ func valueListName(g Generator, spec compile.TypeSpec) string { return fmt.Sprintf("_%s_ValueList", g.MangleType(spec)) } +func encoderFuncName(g Generator, spec compile.TypeSpec) string { + return fmt.Sprintf("_%s_Encode", g.MangleType(spec)) +} + // zapperName returns the name that should be used for wrapper types that // implement zap.ObjectMarshaler or zap.ArrayMarshaler for the provided // Thrift type. diff --git a/gen/typedef.go b/gen/typedef.go index b48e6342..8d26e643 100644 --- a/gen/typedef.go +++ b/gen/typedef.go @@ -57,6 +57,7 @@ func typedef(g Generator, spec *compile.TypedefSpec) error { err := g.DeclareFromTemplate( ` <$fmt := import "fmt"> + <$stream := import "go.uber.org/thriftrw/protocol/stream"> <$wire := import "go.uber.org/thriftrw/wire"> <$typedefType := typeReference .> @@ -64,6 +65,7 @@ func typedef(g Generator, spec *compile.TypedefSpec) error { <$v := newVar "v"> <$x := newVar "x"> + <$sw := newVar "sw"> <- if isPrimitiveType .> // Ptr returns a pointer to a <$typedefType> @@ -86,6 +88,11 @@ func typedef(g Generator, spec *compile.TypedefSpec) error { return <$fmt>.Sprint(<$x>) } + func (<$v> <$typedefType>) Encode(<$sw> <$stream>.Writer) error { + <$x> := ()(<$v>) + return + } + <$w := newVar "w"> // FromWire deserializes from its Thrift-level // representation. The Thrift-level representation may be obtained diff --git a/gen/typedef_test.go b/gen/typedef_test.go index 8e738df2..ad258961 100644 --- a/gen/typedef_test.go +++ b/gen/typedef_test.go @@ -89,6 +89,7 @@ func TestTypedefString(t *testing.T) { for _, tt := range tests { assertRoundTrip(t, &tt.x, tt.v, "State") + testRoundTripCombos(t, &tt.x, tt.v, "State") assert.True(t, tt.x.Equals(tt.x), "State equal") } } @@ -126,6 +127,7 @@ func TestTypedefBinary(t *testing.T) { for _, tt := range tests { assertRoundTrip(t, &tt.x, tt.v, "PDF") + testRoundTripCombos(t, &tt.x, tt.v, "PDF") assert.True(t, tt.x.Equals(tt.x)) } } @@ -162,6 +164,7 @@ func TestTypedefStruct(t *testing.T) { for _, tt := range tests { assertRoundTrip(t, tt.x, tt.v, "UUID") + testRoundTripCombos(t, tt.x, tt.v, "UUID") assert.True(t, tt.x.Equals(tt.x), "UUID equal") } } @@ -221,6 +224,7 @@ func TestTypedefContainer(t *testing.T) { for _, tt := range tests { assertRoundTrip(t, &tt.x, tt.v, "EventGroup") + testRoundTripCombos(t, &tt.x, tt.v, "EventGroup") assert.True(t, tt.x.Equals(tt.x), "EventGroup equal") } } @@ -304,6 +308,7 @@ func TestUnhashableSetAlias(t *testing.T) { for _, tt := range tests { assertRoundTrip(t, &tt.x, tt.v, "FrameGroup") + testRoundTripCombos(t, &tt.x, tt.v, "FrameGroup") assert.True(t, tt.x.Equals(tt.x), "FrameGroup equal") } } @@ -401,6 +406,7 @@ func TestUnhashableMapKeyAlias(t *testing.T) { for _, tt := range tests { assertRoundTrip(t, &tt.x, tt.v, "PointMap") + testRoundTripCombos(t, &tt.x, tt.v, "PointMap") assert.True(t, tt.x.Equals(tt.x), "PointMap equal") } } @@ -483,6 +489,7 @@ func TestBinarySet(t *testing.T) { for _, tt := range tests { assertRoundTrip(t, &tt.x, tt.v, "BinarySet") + testRoundTripCombos(t, &tt.x, tt.v, "BinarySet") assert.True(t, tt.x.Equals(tt.x), "BinarySet equal") } } @@ -563,17 +570,21 @@ func TestTypedefAnnotatedSetToSlice(t *testing.T) { s := "[foo]" assertRoundTrip(t, &a, l, "StringList") + testRoundTripCombos(t, &a, l, "StringList") assert.True(t, a.Equals(b)) assert.Equal(t, s, a.String()) assertRoundTrip(t, &c, l, "MyStringList") + testRoundTripCombos(t, &c, l, "MyStringList") assert.True(t, c.Equals(d)) assert.Equal(t, s, c.String()) assertRoundTrip(t, &e, l, "AnotherStringList") + testRoundTripCombos(t, &e, l, "AnotherStringList") assert.True(t, e.Equals(f)) assert.Equal(t, s, e.String()) assertRoundTrip(t, &g, ll, "StringListList") + testRoundTripCombos(t, &g, ll, "StringListList") assert.Equal(t, "[[foo]]", g.String()) } diff --git a/gen/util_for_test.go b/gen/util_for_test.go index 639e8fc8..45b7ae20 100644 --- a/gen/util_for_test.go +++ b/gen/util_for_test.go @@ -23,6 +23,7 @@ package gen import ( "fmt" + "go.uber.org/thriftrw/protocol/stream" "go.uber.org/thriftrw/wire" ) @@ -37,3 +38,13 @@ type thriftType interface { ToWire() (wire.Value, error) FromWire(wire.Value) error } + +// streamingThriftType is implemented by all generated types that know how to +// write and read themselves to the Thrift Protocol, skipping over the +// intermediary wire.Type +type streamingThriftType interface { + thriftType + + Encode(stream.Writer) error + //Decode(stream.Reader) error +} diff --git a/idl/internal/lex.go b/idl/internal/lex.go index f5ec60b1..9914bfe7 100644 --- a/idl/internal/lex.go +++ b/idl/internal/lex.go @@ -20,9 +20,6 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. - - - package internal import ( @@ -39,7 +36,6 @@ const thrift_error int = 0 const thrift_en_main int = 19 - type lexer struct { line int program *ast.Program @@ -16592,7 +16588,6 @@ func (lex *lexer) Lex(out *yySymType) int { } } - if lex.cs == thrift_error { lex.AppendError(fmt.Errorf("unknown token at index %d", lex.p)) } diff --git a/internal/envelope/envelopetest/client.go b/internal/envelope/envelopetest/client.go index fe5d99c1..17e11c11 100644 --- a/internal/envelope/envelopetest/client.go +++ b/internal/envelope/envelopetest/client.go @@ -25,9 +25,10 @@ package envelopetest import ( + reflect "reflect" + gomock "github.com/golang/mock/gomock" wire "go.uber.org/thriftrw/wire" - reflect "reflect" ) // MockTransport is a mock of Transport interface diff --git a/internal/envelope/envelopetest/server.go b/internal/envelope/envelopetest/server.go index 4c74d5c2..65e63ff6 100644 --- a/internal/envelope/envelopetest/server.go +++ b/internal/envelope/envelopetest/server.go @@ -25,9 +25,10 @@ package envelopetest import ( + reflect "reflect" + gomock "github.com/golang/mock/gomock" wire "go.uber.org/thriftrw/wire" - reflect "reflect" ) // MockHandler is a mock of Handler interface diff --git a/internal/envelope/exception/exception.go b/internal/envelope/exception/exception.go index cf408297..dcfb7bd7 100644 --- a/internal/envelope/exception/exception.go +++ b/internal/envelope/exception/exception.go @@ -27,13 +27,14 @@ import ( bytes "bytes" json "encoding/json" fmt "fmt" + math "math" + strconv "strconv" + strings "strings" + multierr "go.uber.org/multierr" thriftreflect "go.uber.org/thriftrw/thriftreflect" wire "go.uber.org/thriftrw/wire" zapcore "go.uber.org/zap/zapcore" - math "math" - strconv "strconv" - strings "strings" ) type ExceptionType int32 diff --git a/internal/envelope/mock_protocol_test.go b/internal/envelope/mock_protocol_test.go index 6f2cd2f6..5a5d1e57 100644 --- a/internal/envelope/mock_protocol_test.go +++ b/internal/envelope/mock_protocol_test.go @@ -5,10 +5,11 @@ package envelope import ( - gomock "github.com/golang/mock/gomock" - wire "go.uber.org/thriftrw/wire" io "io" reflect "reflect" + + gomock "github.com/golang/mock/gomock" + wire "go.uber.org/thriftrw/wire" ) // MockProtocol is a mock of Protocol interface diff --git a/internal/frame/mock_reader_test.go b/internal/frame/mock_reader_test.go index 91df2fd4..1ea72785 100644 --- a/internal/frame/mock_reader_test.go +++ b/internal/frame/mock_reader_test.go @@ -5,8 +5,9 @@ package frame import ( - gomock "github.com/golang/mock/gomock" reflect "reflect" + + gomock "github.com/golang/mock/gomock" ) // MockReader is a mock of Reader interface diff --git a/internal/frame/mock_writer_test.go b/internal/frame/mock_writer_test.go index c3c4700a..2e8870c4 100644 --- a/internal/frame/mock_writer_test.go +++ b/internal/frame/mock_writer_test.go @@ -5,8 +5,9 @@ package frame import ( - gomock "github.com/golang/mock/gomock" reflect "reflect" + + gomock "github.com/golang/mock/gomock" ) // MockWriter is a mock of Writer interface diff --git a/internal/plugin/handletest/mock.go b/internal/plugin/handletest/mock.go index d7fbffba..18a589ca 100644 --- a/internal/plugin/handletest/mock.go +++ b/internal/plugin/handletest/mock.go @@ -25,10 +25,11 @@ package handletest import ( + reflect "reflect" + gomock "github.com/golang/mock/gomock" plugin "go.uber.org/thriftrw/internal/plugin" api "go.uber.org/thriftrw/plugin/api" - reflect "reflect" ) // MockHandle is a mock of Handle interface diff --git a/plugin/api/api.go b/plugin/api/api.go index 57812320..e2a22b8c 100644 --- a/plugin/api/api.go +++ b/plugin/api/api.go @@ -29,13 +29,14 @@ import ( json "encoding/json" errors "errors" fmt "fmt" + math "math" + strconv "strconv" + strings "strings" + multierr "go.uber.org/multierr" thriftreflect "go.uber.org/thriftrw/thriftreflect" wire "go.uber.org/thriftrw/wire" zapcore "go.uber.org/zap/zapcore" - math "math" - strconv "strconv" - strings "strings" ) // API_VERSION is the version of the plugin API. diff --git a/plugin/plugintest/api.go b/plugin/plugintest/api.go index 8ca2fb96..e804110c 100644 --- a/plugin/plugintest/api.go +++ b/plugin/plugintest/api.go @@ -25,9 +25,10 @@ package plugintest import ( + reflect "reflect" + gomock "github.com/golang/mock/gomock" api "go.uber.org/thriftrw/plugin/api" - reflect "reflect" ) // MockPlugin is a mock of Plugin interface diff --git a/thrifttest/mock_protocol.go b/thrifttest/mock_protocol.go index 3d7ef8f7..4f0f4559 100644 --- a/thrifttest/mock_protocol.go +++ b/thrifttest/mock_protocol.go @@ -25,11 +25,12 @@ package thrifttest import ( + io "io" + reflect "reflect" + gomock "github.com/golang/mock/gomock" protocol "go.uber.org/thriftrw/protocol" wire "go.uber.org/thriftrw/wire" - io "io" - reflect "reflect" ) // MockProtocol is a mock of Protocol interface