func Generate(req *plugin.CodeGeneratorRequest) *plugin.CodeGeneratorResponse { // Begin by allocating a generator. The request and response structures are stored there // so we can do error handling easily - the response structure contains the field to // report failure. g := generator.New() g.Request = req g.CommandLineParameters(g.Request.GetParameter()) // Create a wrapped version of the Descriptors and EnumDescriptors that // point to the file that defines them. g.WrapTypes() g.SetPackageNames() g.BuildTypeNameMap() g.GenerateAllFiles() gtest := generator.New() data, err := proto.Marshal(req) if err != nil { g.Error(err, "failed to marshal modified proto") } if err := proto.Unmarshal(data, gtest.Request); err != nil { g.Error(err, "parsing modified proto") } if len(gtest.Request.FileToGenerate) == 0 { gtest.Fail("no files to generate") } gtest.CommandLineParameters(gtest.Request.GetParameter()) // Create a wrapped version of the Descriptors and EnumDescriptors that // point to the file that defines them. gtest.WrapTypes() gtest.SetPackageNames() gtest.BuildTypeNameMap() gtest.GeneratePlugin(testgen.NewPlugin()) for i := 0; i < len(gtest.Response.File); i++ { if strings.Contains(*gtest.Response.File[i].Content, `//These tests are generated by github.com/andres-erbsen/protobuf/plugin/testgen`) { gtest.Response.File[i].Name = proto.String(strings.Replace(*gtest.Response.File[i].Name, ".pb.go", "pb_test.go", -1)) g.Response.File = append(g.Response.File, gtest.Response.File[i]) } } for i := 0; i < len(g.Response.File); i++ { formatted, err := format.Source([]byte(g.Response.File[i].GetContent())) if err != nil { g.Error(err, "go format error") } fmts := string(formatted) g.Response.File[i].Content = &fmts } return g.Response }
func TestZeroLengthOptionalBytes(t *testing.T) { roundtrip := func(f *Foo) *Foo { data, err := proto.Marshal(f) if err != nil { panic(err) } newF := &Foo{} err = proto.Unmarshal(data, newF) if err != nil { panic(err) } return newF } f := &Foo{} roundtrippedF := roundtrip(f) if roundtrippedF.Bar != nil { t.Fatalf("should be nil") } f.Bar = []byte{} roundtrippedF = roundtrip(f) if roundtrippedF.Bar == nil { t.Fatalf("should not be nil") } if len(roundtrippedF.Bar) != 0 { t.Fatalf("should be empty") } }
func TestGetExtensionStability(t *testing.T) { check := func(m *pb.MyMessage) bool { ext1, err := proto.GetExtension(m, pb.E_Ext_More) if err != nil { t.Fatalf("GetExtension() failed: %s", err) } ext2, err := proto.GetExtension(m, pb.E_Ext_More) if err != nil { t.Fatalf("GetExtension() failed: %s", err) } return ext1 == ext2 } msg := &pb.MyMessage{Count: proto.Int32(4)} ext0 := &pb.Ext{} if err := proto.SetExtension(msg, pb.E_Ext_More, ext0); err != nil { t.Fatalf("Could not set ext1: %s", ext0) } if !check(msg) { t.Errorf("GetExtension() not stable before marshaling") } bb, err := proto.Marshal(msg) if err != nil { t.Fatalf("Marshal() failed: %s", err) } msg1 := &pb.MyMessage{} err = proto.Unmarshal(bb, msg1) if err != nil { t.Fatalf("Unmarshal() failed: %s", err) } if !check(msg1) { t.Errorf("GetExtension() not stable after unmarshaling") } }
//See another version of this test in proto/extensions_test.go func TestGetExtensionStability(t *testing.T) { check := func(m *NoExtensionsMap) bool { ext1, err := proto.GetExtension(m, E_FieldB1) if err != nil { t.Fatalf("GetExtension() failed: %s", err) } ext2, err := proto.GetExtension(m, E_FieldB1) if err != nil { t.Fatalf("GetExtension() failed: %s", err) } return ext1.(*NinOptNative).Equal(ext2) } msg := &NoExtensionsMap{Field1: proto.Int64(2)} ext0 := &NinOptNative{Field1: proto.Float64(1)} if err := proto.SetExtension(msg, E_FieldB1, ext0); err != nil { t.Fatalf("Could not set ext1: %s", ext0) } if !check(msg) { t.Errorf("GetExtension() not stable before marshaling") } bb, err := proto.Marshal(msg) if err != nil { t.Fatalf("Marshal() failed: %s", err) } msg1 := &NoExtensionsMap{} err = proto.Unmarshal(bb, msg1) if err != nil { t.Fatalf("Unmarshal() failed: %s", err) } if !check(msg1) { t.Errorf("GetExtension() not stable after unmarshaling") } }
func testSize(m interface { proto.Message Size() int }, desc string, expected int) ([]byte, error) { data, err := proto.Marshal(m) if err != nil { return nil, err } protoSize := proto.Size(m) mSize := m.Size() lenData := len(data) if protoSize != mSize || protoSize != lenData || mSize != lenData { return nil, fmt.Errorf("%s proto.Size(m){%d} != m.Size(){%d} != len(data){%d}", desc, protoSize, mSize, lenData) } if got := protoSize; got != expected { return nil, fmt.Errorf("%s proto.Size(m) got %d expected %d", desc, got, expected) } if got := mSize; got != expected { return nil, fmt.Errorf("%s m.Size() got %d expected %d", desc, got, expected) } if got := lenData; got != expected { return nil, fmt.Errorf("%s len(data) got %d expected %d", desc, got, expected) } return data, nil }
func (this *uint32Writer) WriteMsg(msg proto.Message) (err error) { var data []byte if m, ok := msg.(marshaler); ok { n := m.Size() if n >= len(this.buffer) { this.buffer = make([]byte, n) } _, err = m.MarshalTo(this.buffer) if err != nil { return err } data = this.buffer[:n] } else { data, err = proto.Marshal(msg) if err != nil { return err } } length := uint32(len(data)) if err := binary.Write(this.w, this.byteOrder, &length); err != nil { return err } _, err = this.w.Write(data) return err }
func TestRoundTripProto3(t *testing.T) { m := &pb.Message{ Name: "David", // (2 | 1<<3): 0x0a 0x05 "David" Hilarity: pb.Message_PUNS, // (0 | 2<<3): 0x10 0x01 HeightInCm: 178, // (0 | 3<<3): 0x18 0xb2 0x01 Data: []byte("roboto"), // (2 | 4<<3): 0x20 0x06 "roboto" ResultCount: 47, // (0 | 7<<3): 0x38 0x2f TrueScotsman: true, // (0 | 8<<3): 0x40 0x01 Score: 8.1, // (5 | 9<<3): 0x4d <8.1> Key: []uint64{1, 0xdeadbeef}, Nested: &pb.Nested{ Bunny: "Monty", }, } t.Logf(" m: %v", m) b, err := proto.Marshal(m) if err != nil { t.Fatalf("proto.Marshal: %v", err) } t.Logf(" b: %q", b) m2 := new(pb.Message) if err := proto.Unmarshal(b, m2); err != nil { t.Fatalf("proto.Unmarshal: %v", err) } t.Logf("m2: %v", m2) if !proto.Equal(m, m2) { t.Errorf("proto.Equal returned false:\n m: %v\nm2: %v", m, m2) } }
func TestUnmarshalPartiallyPopulatedOptionalFieldsFails(t *testing.T) { // Fill in all fields, then randomly remove one. dataOut := &test.NinOptNative{ Field1: proto.Float64(0), Field2: proto.Float32(0), Field3: proto.Int32(0), Field4: proto.Int64(0), Field5: proto.Uint32(0), Field6: proto.Uint64(0), Field7: proto.Int32(0), Field8: proto.Int64(0), Field9: proto.Uint32(0), Field10: proto.Int32(0), Field11: proto.Uint64(0), Field12: proto.Int64(0), Field13: proto.Bool(false), Field14: proto.String("0"), Field15: []byte("0"), } r := rand.New(rand.NewSource(time.Now().UnixNano())) fieldName := "Field" + strconv.Itoa(r.Intn(15)+1) field := reflect.ValueOf(dataOut).Elem().FieldByName(fieldName) fieldType := field.Type() field.Set(reflect.Zero(fieldType)) encodedMessage, err := proto.Marshal(dataOut) if err != nil { t.Fatalf("Unexpected error when marshalling dataOut: %v", err) } dataIn := NidOptNative{} err = proto.Unmarshal(encodedMessage, &dataIn) if err.Error() != `proto: required field "`+fieldName+`" not set` { t.Fatalf(`err.Error() != "proto: required field "`+fieldName+`" not set"; was "%s" instead`, err.Error()) } }
func TestKeyserverStepProto(t *testing.T) { popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedKeyserverStep(popr, false) data, err := github_com_andres_erbsen_protobuf_proto.Marshal(p) if err != nil { panic(err) } msg := &KeyserverStep{} if err := github_com_andres_erbsen_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } littlefuzz := make([]byte, len(data)) copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) } if !p.Equal(msg) { t.Fatalf("%#v !Proto %#v", msg, p) } if len(littlefuzz) > 0 { fuzzamount := 100 for i := 0; i < fuzzamount; i++ { littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) littlefuzz = append(littlefuzz, byte(popr.Intn(256))) } // shouldn't panic _ = github_com_andres_erbsen_protobuf_proto.Unmarshal(littlefuzz, msg) } }
func (this *varintWriter) WriteMsg(msg proto.Message) (err error) { var data []byte if m, ok := msg.(marshaler); ok { n := m.Size() if n >= len(this.buffer) { this.buffer = make([]byte, n) } _, err = m.MarshalTo(this.buffer) if err != nil { return err } data = this.buffer[:n] } else { data, err = proto.Marshal(msg) if err != nil { return err } } length := uint64(len(data)) n := binary.PutUvarint(this.lenBuf, length) _, err = this.w.Write(this.lenBuf[:n]) if err != nil { return err } _, err = this.w.Write(data) return err }
func TestMessageProto(t *testing.T) { seed := time.Now().UnixNano() popr := math_rand.New(math_rand.NewSource(seed)) p := NewPopulatedMessage(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { t.Fatalf("seed = %d, err = %v", seed, err) } msg := &Message{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { t.Fatalf("seed = %d, err = %v", seed, err) } littlefuzz := make([]byte, len(data)) copy(littlefuzz, data) for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err) } if !p.Equal(msg) { t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) } if len(littlefuzz) > 0 { fuzzamount := 100 for i := 0; i < fuzzamount; i++ { littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) littlefuzz = append(littlefuzz, byte(popr.Intn(256))) } // shouldn't panic _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) } }
func newTestMessage() *pb.MyMessage { msg := &pb.MyMessage{ Count: proto.Int32(42), Name: proto.String("Dave"), Quote: proto.String(`"I didn't want to go."`), Pet: []string{"bunny", "kitty", "horsey"}, Inner: &pb.InnerMessage{ Host: proto.String("footrest.syd"), Port: proto.Int32(7001), Connected: proto.Bool(true), }, Others: []*pb.OtherMessage{ { Key: proto.Int64(0xdeadbeef), Value: []byte{1, 65, 7, 12}, }, { Weight: proto.Float32(6.022), Inner: &pb.InnerMessage{ Host: proto.String("lesha.mtv"), Port: proto.Int32(8002), }, }, }, Bikeshed: pb.MyMessage_BLUE.Enum(), Somegroup: &pb.MyMessage_SomeGroup{ GroupField: proto.Int32(8), }, // One normally wouldn't do this. // This is an undeclared tag 13, as a varint (wire type 0) with value 4. XXX_unrecognized: []byte{13<<3 | 0, 4}, } ext := &pb.Ext{ Data: proto.String("Big gobs for big rats"), } if err := proto.SetExtension(msg, pb.E_Ext_More, ext); err != nil { panic(err) } greetings := []string{"adg", "easy", "cow"} if err := proto.SetExtension(msg, pb.E_Greeting, greetings); err != nil { panic(err) } // Add an unknown extension. We marshal a pb.Ext, and fake the ID. b, err := proto.Marshal(&pb.Ext{Data: proto.String("3G skiing")}) if err != nil { panic(err) } b = append(proto.EncodeVarint(201<<3|proto.WireBytes), b...) proto.SetRawExtension(msg, 201, b) // Extensions can be plain fields, too, so let's test that. b = append(proto.EncodeVarint(202<<3|proto.WireVarint), 19) proto.SetRawExtension(msg, 202, b) return msg }
func TestIssue42Order(t *testing.T) { unordered := NewPopulatedUnorderedFields(math_rand.New(math_rand.NewSource(time.Now().UnixNano())), false) udata, err := proto.Marshal(unordered) if err != nil { t.Fatal(err) } ordered := &OrderedFields{} if err := proto.Unmarshal(udata, ordered); err != nil { t.Fatal(err) } data, err := proto.Marshal(ordered) if err != nil { t.Fatal(err) } if !bytes.Equal(udata, data) { t.Fatalf("expected data to be marshaled in the same order, please sort fields before marshaling") } }
func TestOldNewOldNew(t *testing.T) { popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) older := NewPopulatedOldWithGroup(popr, true) data1, err := proto.Marshal(older) if err != nil { panic(err) } newer := &NewNoGroup{} if err := proto.Unmarshal(data1, newer); err != nil { panic(err) } data2, err := proto.Marshal(newer) if err != nil { panic(err) } bluer := &OldWithGroup{} if err := proto.Unmarshal(data2, bluer); err != nil { panic(err) } if err := older.VerboseEqual(bluer); err != nil { t.Fatalf("%#v !VerboseProto %#v, since %v", older, bluer, err) } data3, err := proto.Marshal(bluer) if err != nil { panic(err) } purple := &NewNoGroup{} if err := proto.Unmarshal(data3, purple); err != nil { panic(err) } data4, err := proto.Marshal(purple) if err != nil { panic(err) } magenta := &OldWithGroup{} if err := proto.Unmarshal(data4, magenta); err != nil { panic(err) } if err := older.VerboseEqual(magenta); err != nil { t.Fatalf("%#v !VerboseProto %#v, since %v", older, magenta, err) } }
//http://code.google.com/p/goprotobuf/issues/detail?id=39 func TestBugUint32VarintSize(t *testing.T) { temp := uint32(math.MaxUint32) n := &NinOptNative{} n.Field5 = &temp data, err := proto.Marshal(n) if err != nil { panic(err) } if len(data) != 6 { t.Fatalf("data should be length 6, but its %#v", data) } }
func TestMarshalToSucceedsWhenRequiredFieldIsPresent(t *testing.T) { data := RequiredExample{ TheRequiredString: proto.String("present"), } buf, err := proto.Marshal(&data) if err != nil { t.Fatalf("err != nil; was %v instead", err) } if len(buf) == 0 { t.Fatalf(`len(buf) == 0; expected nonzero`) } }
func Write(resp *plugin.CodeGeneratorResponse) { g := generator.New() // Send back the results. data, err := proto.Marshal(resp) if err != nil { g.Error(err, "failed to marshal output proto") } _, err = os.Stdout.Write(data) if err != nil { g.Error(err, "failed to write output proto") } }
func TestMarshalToErrorsWhenRequiredFieldIsNotPresent(t *testing.T) { data := RequiredExample{} buf, err := proto.Marshal(&data) if err == nil { t.Fatalf("err == nil; was %v instead", err) } if err.Error() != `proto: required field "theRequiredString" not set` { t.Fatalf(`err.Error() != "proto: required field "theRequiredString" not set"; was "%s" instead`, err.Error()) } if len(buf) != 0 { t.Fatalf(`len(buf) != 0; was %d instead`, len(buf)) } }
func TestUnmarshalPopulatedOptionalFieldsAsRequiredSucceeds(t *testing.T) { r := rand.New(rand.NewSource(time.Now().UnixNano())) dataOut := test.NewPopulatedNidOptNative(r, true) encodedMessage, err := proto.Marshal(dataOut) if err != nil { t.Fatalf("Unexpected error when marshalling dataOut: %v", err) } dataIn := NidOptNative{} err = proto.Unmarshal(encodedMessage, &dataIn) if err != nil { t.Fatalf("err != nil; was %v instead", err) } }
func TestBugZeroLengthSliceSize(t *testing.T) { n := &NinRepPackedNative{ Field8: []int64{}, } size := n.Size() data, err := proto.Marshal(n) if err != nil { panic(err) } if len(data) != size { t.Fatalf("expected %v, but got %v", len(data), size) } }
func TestNewOld(t *testing.T) { popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) newer := NewPopulatedNewNoGroup(popr, true) data1, err := proto.Marshal(newer) if err != nil { panic(err) } older := &OldWithGroup{} if err := proto.Unmarshal(data1, older); err != nil { panic(err) } data2, err := proto.Marshal(older) if err != nil { panic(err) } bluer := &NewNoGroup{} if err := proto.Unmarshal(data2, bluer); err != nil { panic(err) } if err := newer.VerboseEqual(bluer); err != nil { t.Fatalf("%#v !VerboseProto %#v, since %v", newer, bluer, err) } }
func TestUnmarshalSucceedsWhenRequiredIsNotPresent(t *testing.T) { dataOut := RequiredExample{ TheRequiredString: proto.String("present"), } encodedMessage, err := proto.Marshal(&dataOut) if err != nil { t.Fatalf("Unexpected error when marshalling dataOut: %v", err) } dataIn := RequiredExample{} err = proto.Unmarshal(encodedMessage, &dataIn) if err != nil { t.Fatalf("err != nil; was %v instead", err) } }
func (this *codec) Marshal(v interface{}) ([]byte, error) { if m, ok := v.(marshaler); ok { n := m.Size() if n > len(this.buf) { this.buf = make([]byte, n) } _, err := m.MarshalTo(this.buf) if err != nil { return nil, err } return this.buf[:n], nil } return proto.Marshal(v.(proto.Message)) }
func TestNothingVerboseEqual(t *testing.T) { popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedNothing(popr, false) data, err := github_com_andres_erbsen_protobuf_proto.Marshal(p) if err != nil { panic(err) } msg := &Nothing{} if err := github_com_andres_erbsen_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } }
func TestFloatingPointVerboseEqual(t *testing.T) { popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedFloatingPoint(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } msg := &FloatingPoint{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } }
func TestMarshalFailsWithoutAllFieldsSet(t *testing.T) { r := rand.New(rand.NewSource(time.Now().UnixNano())) dataOut := NewPopulatedNinOptNative(r, true) fieldName := "Field" + strconv.Itoa(r.Intn(15)+1) field := reflect.ValueOf(dataOut).Elem().FieldByName(fieldName) fieldType := field.Type() field.Set(reflect.Zero(fieldType)) encodedMessage, err := proto.Marshal(dataOut) if err.Error() != `proto: required field "`+fieldName+`" not set` { t.Fatalf(`err.Error() != "proto: required field "`+fieldName+`" not set"; was "%s" instead`, err.Error()) } if len(encodedMessage) > 0 { t.Fatalf("Got some bytes from marshal, expected none.") } }
func TestInt64Merge(t *testing.T) { popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedIntMerge(popr, true) p2 := NewPopulatedIntMerge(popr, true) data, err := proto.Marshal(p2) if err != nil { t.Fatal(err) } if err := proto.UnmarshalMerge(data, p); err != nil { t.Fatal(err) } if !p.Equal(p2) { t.Fatalf("exptected %#v but got %#v", p2, p) } }
func TestRepeatedOptional(t *testing.T) { repeated := &FooWithRepeated{Bar: [][]byte{[]byte("a"), []byte("b")}} data, err := proto.Marshal(repeated) if err != nil { panic(err) } optional := &Foo{} err = proto.Unmarshal(data, optional) if err != nil { panic(err) } if !bytes.Equal(optional.Bar, []byte("b")) { t.Fatalf("should return the last entry") } }
func TestBugUuid(t *testing.T) { u := &CustomContainer{CustomStruct: NidOptCustom{Id: Uuid{}}} data, err := proto.Marshal(u) if err != nil { panic(err) } u2 := &CustomContainer{} err = proto.Unmarshal(data, u2) if err != nil { panic(err) } t.Logf("%+v", u2) if u2.CustomStruct.Id != nil { t.Fatalf("should be nil") } }
func BenchmarkMessageProtoMarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 pops := make([]*Message, 10000) for i := 0; i < 10000; i++ { pops[i] = NewPopulatedMessage(popr, false) } b.ResetTimer() for i := 0; i < b.N; i++ { data, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000]) if err != nil { panic(err) } total += len(data) } b.SetBytes(int64(total / b.N)) }