mirror of
https://github.com/prometheus/prometheus.git
synced 2025-03-05 20:59:13 -08:00
Remove Google Code files, add GitHub files for protobuf lib.
This commit is contained in:
parent
af627bb2b9
commit
740a99a9ac
|
@ -1,7 +1,7 @@
|
||||||
# Go support for Protocol Buffers - Google's data interchange format
|
# Go support for Protocol Buffers - Google's data interchange format
|
||||||
#
|
#
|
||||||
# Copyright 2010 The Go Authors. All rights reserved.
|
# Copyright 2010 The Go Authors. All rights reserved.
|
||||||
# http://code.google.com/p/goprotobuf/
|
# https://github.com/golang/protobuf
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
# modification, are permitted provided that the following conditions are
|
# modification, are permitted provided that the following conditions are
|
||||||
|
@ -37,4 +37,7 @@ test: install generate-test-pbs
|
||||||
|
|
||||||
|
|
||||||
generate-test-pbs:
|
generate-test-pbs:
|
||||||
make install && cd testdata && make
|
make install
|
||||||
|
make -C testdata
|
||||||
|
make -C proto3_proto
|
||||||
|
make
|
|
@ -1,7 +1,7 @@
|
||||||
// Go support for Protocol Buffers - Google's data interchange format
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
//
|
//
|
||||||
// Copyright 2010 The Go Authors. All rights reserved.
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
// http://code.google.com/p/goprotobuf/
|
// https://github.com/golang/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
@ -45,7 +45,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
. "./testdata"
|
. "./testdata"
|
||||||
. "code.google.com/p/goprotobuf/proto"
|
. "github.com/golang/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
var globalO *Buffer
|
var globalO *Buffer
|
||||||
|
@ -1833,6 +1833,86 @@ func fuzzUnmarshal(t *testing.T, data []byte) {
|
||||||
Unmarshal(data, pb)
|
Unmarshal(data, pb)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMapFieldMarshal(t *testing.T) {
|
||||||
|
m := &MessageWithMap{
|
||||||
|
NameMapping: map[int32]string{
|
||||||
|
1: "Rob",
|
||||||
|
4: "Ian",
|
||||||
|
8: "Dave",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
b, err := Marshal(m)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Marshal: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// b should be the concatenation of these three byte sequences in some order.
|
||||||
|
parts := []string{
|
||||||
|
"\n\a\b\x01\x12\x03Rob",
|
||||||
|
"\n\a\b\x04\x12\x03Ian",
|
||||||
|
"\n\b\b\x08\x12\x04Dave",
|
||||||
|
}
|
||||||
|
ok := false
|
||||||
|
for i := range parts {
|
||||||
|
for j := range parts {
|
||||||
|
if j == i {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for k := range parts {
|
||||||
|
if k == i || k == j {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
try := parts[i] + parts[j] + parts[k]
|
||||||
|
if bytes.Equal(b, []byte(try)) {
|
||||||
|
ok = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("Incorrect Marshal output.\n got %q\nwant %q (or a permutation of that)", b, parts[0]+parts[1]+parts[2])
|
||||||
|
}
|
||||||
|
t.Logf("FYI b: %q", b)
|
||||||
|
|
||||||
|
(new(Buffer)).DebugPrint("Dump of b", b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMapFieldRoundTrips(t *testing.T) {
|
||||||
|
m := &MessageWithMap{
|
||||||
|
NameMapping: map[int32]string{
|
||||||
|
1: "Rob",
|
||||||
|
4: "Ian",
|
||||||
|
8: "Dave",
|
||||||
|
},
|
||||||
|
MsgMapping: map[int64]*FloatingPoint{
|
||||||
|
0x7001: &FloatingPoint{F: Float64(2.0)},
|
||||||
|
},
|
||||||
|
ByteMapping: map[bool][]byte{
|
||||||
|
false: []byte("that's not right!"),
|
||||||
|
true: []byte("aye, 'tis true!"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
b, err := Marshal(m)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Marshal: %v", err)
|
||||||
|
}
|
||||||
|
t.Logf("FYI b: %q", b)
|
||||||
|
m2 := new(MessageWithMap)
|
||||||
|
if err := Unmarshal(b, m2); err != nil {
|
||||||
|
t.Fatalf("Unmarshal: %v", err)
|
||||||
|
}
|
||||||
|
for _, pair := range [][2]interface{}{
|
||||||
|
{m.NameMapping, m2.NameMapping},
|
||||||
|
{m.MsgMapping, m2.MsgMapping},
|
||||||
|
{m.ByteMapping, m2.ByteMapping},
|
||||||
|
} {
|
||||||
|
if !reflect.DeepEqual(pair[0], pair[1]) {
|
||||||
|
t.Errorf("Map did not survive a round trip.\ninitial: %v\n final: %v", pair[0], pair[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Benchmarks
|
// Benchmarks
|
||||||
|
|
||||||
func testMsg() *GoTest {
|
func testMsg() *GoTest {
|
|
@ -1,7 +1,7 @@
|
||||||
// Go support for Protocol Buffers - Google's data interchange format
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
//
|
//
|
||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
// http://code.google.com/p/goprotobuf/
|
// https://github.com/golang/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
// Protocol buffer deep copy.
|
// Protocol buffer deep copy and merge.
|
||||||
// TODO: MessageSet and RawMessage.
|
// TODO: MessageSet and RawMessage.
|
||||||
|
|
||||||
package proto
|
package proto
|
||||||
|
@ -113,6 +113,29 @@ func mergeAny(out, in reflect.Value) {
|
||||||
case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
|
case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
|
||||||
reflect.String, reflect.Uint32, reflect.Uint64:
|
reflect.String, reflect.Uint32, reflect.Uint64:
|
||||||
out.Set(in)
|
out.Set(in)
|
||||||
|
case reflect.Map:
|
||||||
|
if in.Len() == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if out.IsNil() {
|
||||||
|
out.Set(reflect.MakeMap(in.Type()))
|
||||||
|
}
|
||||||
|
// For maps with value types of *T or []byte we need to deep copy each value.
|
||||||
|
elemKind := in.Type().Elem().Kind()
|
||||||
|
for _, key := range in.MapKeys() {
|
||||||
|
var val reflect.Value
|
||||||
|
switch elemKind {
|
||||||
|
case reflect.Ptr:
|
||||||
|
val = reflect.New(in.Type().Elem().Elem())
|
||||||
|
mergeAny(val, in.MapIndex(key))
|
||||||
|
case reflect.Slice:
|
||||||
|
val = in.MapIndex(key)
|
||||||
|
val = reflect.ValueOf(append([]byte{}, val.Bytes()...))
|
||||||
|
default:
|
||||||
|
val = in.MapIndex(key)
|
||||||
|
}
|
||||||
|
out.SetMapIndex(key, val)
|
||||||
|
}
|
||||||
case reflect.Ptr:
|
case reflect.Ptr:
|
||||||
if in.IsNil() {
|
if in.IsNil() {
|
||||||
return
|
return
|
||||||
|
@ -125,6 +148,14 @@ func mergeAny(out, in reflect.Value) {
|
||||||
if in.IsNil() {
|
if in.IsNil() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if in.Type().Elem().Kind() == reflect.Uint8 {
|
||||||
|
// []byte is a scalar bytes field, not a repeated field.
|
||||||
|
// Make a deep copy.
|
||||||
|
// Append to []byte{} instead of []byte(nil) so that we never end up
|
||||||
|
// with a nil result.
|
||||||
|
out.SetBytes(append([]byte{}, in.Bytes()...))
|
||||||
|
return
|
||||||
|
}
|
||||||
n := in.Len()
|
n := in.Len()
|
||||||
if out.IsNil() {
|
if out.IsNil() {
|
||||||
out.Set(reflect.MakeSlice(in.Type(), 0, n))
|
out.Set(reflect.MakeSlice(in.Type(), 0, n))
|
||||||
|
@ -133,9 +164,6 @@ func mergeAny(out, in reflect.Value) {
|
||||||
case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
|
case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
|
||||||
reflect.String, reflect.Uint32, reflect.Uint64:
|
reflect.String, reflect.Uint32, reflect.Uint64:
|
||||||
out.Set(reflect.AppendSlice(out, in))
|
out.Set(reflect.AppendSlice(out, in))
|
||||||
case reflect.Uint8:
|
|
||||||
// []byte is a scalar bytes field.
|
|
||||||
out.Set(in)
|
|
||||||
default:
|
default:
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
x := reflect.Indirect(reflect.New(in.Type().Elem()))
|
x := reflect.Indirect(reflect.New(in.Type().Elem()))
|
|
@ -1,7 +1,7 @@
|
||||||
// Go support for Protocol Buffers - Google's data interchange format
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
//
|
//
|
||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
// http://code.google.com/p/goprotobuf/
|
// https://github.com/golang/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
@ -34,7 +34,7 @@ package proto_test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.google.com/p/goprotobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
|
|
||||||
pb "./testdata"
|
pb "./testdata"
|
||||||
)
|
)
|
||||||
|
@ -79,6 +79,22 @@ func TestClone(t *testing.T) {
|
||||||
if proto.Equal(m, cloneTestMessage) {
|
if proto.Equal(m, cloneTestMessage) {
|
||||||
t.Error("Mutating clone changed the original")
|
t.Error("Mutating clone changed the original")
|
||||||
}
|
}
|
||||||
|
// Byte fields and repeated fields should be copied.
|
||||||
|
if &m.Pet[0] == &cloneTestMessage.Pet[0] {
|
||||||
|
t.Error("Pet: repeated field not copied")
|
||||||
|
}
|
||||||
|
if &m.Others[0] == &cloneTestMessage.Others[0] {
|
||||||
|
t.Error("Others: repeated field not copied")
|
||||||
|
}
|
||||||
|
if &m.Others[0].Value[0] == &cloneTestMessage.Others[0].Value[0] {
|
||||||
|
t.Error("Others[0].Value: bytes field not copied")
|
||||||
|
}
|
||||||
|
if &m.RepBytes[0] == &cloneTestMessage.RepBytes[0] {
|
||||||
|
t.Error("RepBytes: repeated field not copied")
|
||||||
|
}
|
||||||
|
if &m.RepBytes[0][0] == &cloneTestMessage.RepBytes[0][0] {
|
||||||
|
t.Error("RepBytes[0]: bytes field not copied")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCloneNil(t *testing.T) {
|
func TestCloneNil(t *testing.T) {
|
||||||
|
@ -173,6 +189,31 @@ var mergeTests = []struct {
|
||||||
dst: &pb.OtherMessage{Value: []byte("bar")},
|
dst: &pb.OtherMessage{Value: []byte("bar")},
|
||||||
want: &pb.OtherMessage{Value: []byte("foo")},
|
want: &pb.OtherMessage{Value: []byte("foo")},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
src: &pb.MessageWithMap{
|
||||||
|
NameMapping: map[int32]string{6: "Nigel"},
|
||||||
|
MsgMapping: map[int64]*pb.FloatingPoint{
|
||||||
|
0x4001: &pb.FloatingPoint{F: proto.Float64(2.0)},
|
||||||
|
},
|
||||||
|
ByteMapping: map[bool][]byte{true: []byte("wowsa")},
|
||||||
|
},
|
||||||
|
dst: &pb.MessageWithMap{
|
||||||
|
NameMapping: map[int32]string{
|
||||||
|
6: "Bruce", // should be overwritten
|
||||||
|
7: "Andrew",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: &pb.MessageWithMap{
|
||||||
|
NameMapping: map[int32]string{
|
||||||
|
6: "Nigel",
|
||||||
|
7: "Andrew",
|
||||||
|
},
|
||||||
|
MsgMapping: map[int64]*pb.FloatingPoint{
|
||||||
|
0x4001: &pb.FloatingPoint{F: proto.Float64(2.0)},
|
||||||
|
},
|
||||||
|
ByteMapping: map[bool][]byte{true: []byte("wowsa")},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMerge(t *testing.T) {
|
func TestMerge(t *testing.T) {
|
|
@ -1,7 +1,7 @@
|
||||||
// Go support for Protocol Buffers - Google's data interchange format
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
//
|
//
|
||||||
// Copyright 2010 The Go Authors. All rights reserved.
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
// http://code.google.com/p/goprotobuf/
|
// https://github.com/golang/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
@ -178,7 +178,7 @@ func (p *Buffer) DecodeZigzag32() (x uint64, err error) {
|
||||||
func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) {
|
func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) {
|
||||||
n, err := p.DecodeVarint()
|
n, err := p.DecodeVarint()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
nb := int(n)
|
nb := int(n)
|
||||||
|
@ -362,7 +362,7 @@ func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group
|
||||||
}
|
}
|
||||||
tag := int(u >> 3)
|
tag := int(u >> 3)
|
||||||
if tag <= 0 {
|
if tag <= 0 {
|
||||||
return fmt.Errorf("proto: %s: illegal tag %d", st, tag)
|
return fmt.Errorf("proto: %s: illegal tag %d (wire type %d)", st, tag, wire)
|
||||||
}
|
}
|
||||||
fieldnum, ok := prop.decoderTags.get(tag)
|
fieldnum, ok := prop.decoderTags.get(tag)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -465,6 +465,15 @@ func (o *Buffer) dec_bool(p *Properties, base structPointer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) dec_proto3_bool(p *Properties, base structPointer) error {
|
||||||
|
u, err := p.valDec(o)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*structPointer_BoolVal(base, p.field) = u != 0
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Decode an int32.
|
// Decode an int32.
|
||||||
func (o *Buffer) dec_int32(p *Properties, base structPointer) error {
|
func (o *Buffer) dec_int32(p *Properties, base structPointer) error {
|
||||||
u, err := p.valDec(o)
|
u, err := p.valDec(o)
|
||||||
|
@ -475,6 +484,15 @@ func (o *Buffer) dec_int32(p *Properties, base structPointer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) dec_proto3_int32(p *Properties, base structPointer) error {
|
||||||
|
u, err := p.valDec(o)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
word32Val_Set(structPointer_Word32Val(base, p.field), uint32(u))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Decode an int64.
|
// Decode an int64.
|
||||||
func (o *Buffer) dec_int64(p *Properties, base structPointer) error {
|
func (o *Buffer) dec_int64(p *Properties, base structPointer) error {
|
||||||
u, err := p.valDec(o)
|
u, err := p.valDec(o)
|
||||||
|
@ -485,15 +503,31 @@ func (o *Buffer) dec_int64(p *Properties, base structPointer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) dec_proto3_int64(p *Properties, base structPointer) error {
|
||||||
|
u, err := p.valDec(o)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
word64Val_Set(structPointer_Word64Val(base, p.field), o, u)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Decode a string.
|
// Decode a string.
|
||||||
func (o *Buffer) dec_string(p *Properties, base structPointer) error {
|
func (o *Buffer) dec_string(p *Properties, base structPointer) error {
|
||||||
s, err := o.DecodeStringBytes()
|
s, err := o.DecodeStringBytes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
sp := new(string)
|
*structPointer_String(base, p.field) = &s
|
||||||
*sp = s
|
return nil
|
||||||
*structPointer_String(base, p.field) = sp
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) dec_proto3_string(p *Properties, base structPointer) error {
|
||||||
|
s, err := o.DecodeStringBytes()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*structPointer_StringVal(base, p.field) = s
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -632,6 +666,72 @@ func (o *Buffer) dec_slice_slice_byte(p *Properties, base structPointer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Decode a map field.
|
||||||
|
func (o *Buffer) dec_new_map(p *Properties, base structPointer) error {
|
||||||
|
raw, err := o.DecodeRawBytes(false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
oi := o.index // index at the end of this map entry
|
||||||
|
o.index -= len(raw) // move buffer back to start of map entry
|
||||||
|
|
||||||
|
mptr := structPointer_Map(base, p.field, p.mtype) // *map[K]V
|
||||||
|
if mptr.Elem().IsNil() {
|
||||||
|
mptr.Elem().Set(reflect.MakeMap(mptr.Type().Elem()))
|
||||||
|
}
|
||||||
|
v := mptr.Elem() // map[K]V
|
||||||
|
|
||||||
|
// Prepare addressable doubly-indirect placeholders for the key and value types.
|
||||||
|
// See enc_new_map for why.
|
||||||
|
keyptr := reflect.New(reflect.PtrTo(p.mtype.Key())).Elem() // addressable *K
|
||||||
|
keybase := toStructPointer(keyptr.Addr()) // **K
|
||||||
|
|
||||||
|
var valbase structPointer
|
||||||
|
var valptr reflect.Value
|
||||||
|
switch p.mtype.Elem().Kind() {
|
||||||
|
case reflect.Slice:
|
||||||
|
// []byte
|
||||||
|
var dummy []byte
|
||||||
|
valptr = reflect.ValueOf(&dummy) // *[]byte
|
||||||
|
valbase = toStructPointer(valptr) // *[]byte
|
||||||
|
case reflect.Ptr:
|
||||||
|
// message; valptr is **Msg; need to allocate the intermediate pointer
|
||||||
|
valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V
|
||||||
|
valptr.Set(reflect.New(valptr.Type().Elem()))
|
||||||
|
valbase = toStructPointer(valptr)
|
||||||
|
default:
|
||||||
|
// everything else
|
||||||
|
valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V
|
||||||
|
valbase = toStructPointer(valptr.Addr()) // **V
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode.
|
||||||
|
// This parses a restricted wire format, namely the encoding of a message
|
||||||
|
// with two fields. See enc_new_map for the format.
|
||||||
|
for o.index < oi {
|
||||||
|
// tagcode for key and value properties are always a single byte
|
||||||
|
// because they have tags 1 and 2.
|
||||||
|
tagcode := o.buf[o.index]
|
||||||
|
o.index++
|
||||||
|
switch tagcode {
|
||||||
|
case p.mkeyprop.tagcode[0]:
|
||||||
|
if err := p.mkeyprop.dec(o, p.mkeyprop, keybase); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case p.mvalprop.tagcode[0]:
|
||||||
|
if err := p.mvalprop.dec(o, p.mvalprop, valbase); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// TODO: Should we silently skip this instead?
|
||||||
|
return fmt.Errorf("proto: bad map data tag %d", raw[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
v.SetMapIndex(keyptr.Elem(), valptr.Elem())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Decode a group.
|
// Decode a group.
|
||||||
func (o *Buffer) dec_struct_group(p *Properties, base structPointer) error {
|
func (o *Buffer) dec_struct_group(p *Properties, base structPointer) error {
|
||||||
bas := structPointer_GetStructPointer(base, p.field)
|
bas := structPointer_GetStructPointer(base, p.field)
|
|
@ -1,7 +1,7 @@
|
||||||
// Go support for Protocol Buffers - Google's data interchange format
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
//
|
//
|
||||||
// Copyright 2010 The Go Authors. All rights reserved.
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
// http://code.google.com/p/goprotobuf/
|
// https://github.com/golang/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
@ -247,7 +247,7 @@ func (p *Buffer) Marshal(pb Message) error {
|
||||||
return ErrNil
|
return ErrNil
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = p.enc_struct(t.Elem(), GetProperties(t.Elem()), base)
|
err = p.enc_struct(GetProperties(t.Elem()), base)
|
||||||
}
|
}
|
||||||
|
|
||||||
if collectStats {
|
if collectStats {
|
||||||
|
@ -271,7 +271,7 @@ func Size(pb Message) (n int) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
n = size_struct(t.Elem(), GetProperties(t.Elem()), base)
|
n = size_struct(GetProperties(t.Elem()), base)
|
||||||
}
|
}
|
||||||
|
|
||||||
if collectStats {
|
if collectStats {
|
||||||
|
@ -298,6 +298,16 @@ func (o *Buffer) enc_bool(p *Properties, base structPointer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) enc_proto3_bool(p *Properties, base structPointer) error {
|
||||||
|
v := *structPointer_BoolVal(base, p.field)
|
||||||
|
if !v {
|
||||||
|
return ErrNil
|
||||||
|
}
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
p.valEnc(o, 1)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func size_bool(p *Properties, base structPointer) int {
|
func size_bool(p *Properties, base structPointer) int {
|
||||||
v := *structPointer_Bool(base, p.field)
|
v := *structPointer_Bool(base, p.field)
|
||||||
if v == nil {
|
if v == nil {
|
||||||
|
@ -306,6 +316,14 @@ func size_bool(p *Properties, base structPointer) int {
|
||||||
return len(p.tagcode) + 1 // each bool takes exactly one byte
|
return len(p.tagcode) + 1 // each bool takes exactly one byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func size_proto3_bool(p *Properties, base structPointer) int {
|
||||||
|
v := *structPointer_BoolVal(base, p.field)
|
||||||
|
if !v {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return len(p.tagcode) + 1 // each bool takes exactly one byte
|
||||||
|
}
|
||||||
|
|
||||||
// Encode an int32.
|
// Encode an int32.
|
||||||
func (o *Buffer) enc_int32(p *Properties, base structPointer) error {
|
func (o *Buffer) enc_int32(p *Properties, base structPointer) error {
|
||||||
v := structPointer_Word32(base, p.field)
|
v := structPointer_Word32(base, p.field)
|
||||||
|
@ -318,6 +336,17 @@ func (o *Buffer) enc_int32(p *Properties, base structPointer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) enc_proto3_int32(p *Properties, base structPointer) error {
|
||||||
|
v := structPointer_Word32Val(base, p.field)
|
||||||
|
x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range
|
||||||
|
if x == 0 {
|
||||||
|
return ErrNil
|
||||||
|
}
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
p.valEnc(o, uint64(x))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func size_int32(p *Properties, base structPointer) (n int) {
|
func size_int32(p *Properties, base structPointer) (n int) {
|
||||||
v := structPointer_Word32(base, p.field)
|
v := structPointer_Word32(base, p.field)
|
||||||
if word32_IsNil(v) {
|
if word32_IsNil(v) {
|
||||||
|
@ -329,6 +358,17 @@ func size_int32(p *Properties, base structPointer) (n int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func size_proto3_int32(p *Properties, base structPointer) (n int) {
|
||||||
|
v := structPointer_Word32Val(base, p.field)
|
||||||
|
x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range
|
||||||
|
if x == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
n += len(p.tagcode)
|
||||||
|
n += p.valSize(uint64(x))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Encode a uint32.
|
// Encode a uint32.
|
||||||
// Exactly the same as int32, except for no sign extension.
|
// Exactly the same as int32, except for no sign extension.
|
||||||
func (o *Buffer) enc_uint32(p *Properties, base structPointer) error {
|
func (o *Buffer) enc_uint32(p *Properties, base structPointer) error {
|
||||||
|
@ -342,6 +382,17 @@ func (o *Buffer) enc_uint32(p *Properties, base structPointer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) enc_proto3_uint32(p *Properties, base structPointer) error {
|
||||||
|
v := structPointer_Word32Val(base, p.field)
|
||||||
|
x := word32Val_Get(v)
|
||||||
|
if x == 0 {
|
||||||
|
return ErrNil
|
||||||
|
}
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
p.valEnc(o, uint64(x))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func size_uint32(p *Properties, base structPointer) (n int) {
|
func size_uint32(p *Properties, base structPointer) (n int) {
|
||||||
v := structPointer_Word32(base, p.field)
|
v := structPointer_Word32(base, p.field)
|
||||||
if word32_IsNil(v) {
|
if word32_IsNil(v) {
|
||||||
|
@ -353,6 +404,17 @@ func size_uint32(p *Properties, base structPointer) (n int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func size_proto3_uint32(p *Properties, base structPointer) (n int) {
|
||||||
|
v := structPointer_Word32Val(base, p.field)
|
||||||
|
x := word32Val_Get(v)
|
||||||
|
if x == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
n += len(p.tagcode)
|
||||||
|
n += p.valSize(uint64(x))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Encode an int64.
|
// Encode an int64.
|
||||||
func (o *Buffer) enc_int64(p *Properties, base structPointer) error {
|
func (o *Buffer) enc_int64(p *Properties, base structPointer) error {
|
||||||
v := structPointer_Word64(base, p.field)
|
v := structPointer_Word64(base, p.field)
|
||||||
|
@ -365,6 +427,17 @@ func (o *Buffer) enc_int64(p *Properties, base structPointer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) enc_proto3_int64(p *Properties, base structPointer) error {
|
||||||
|
v := structPointer_Word64Val(base, p.field)
|
||||||
|
x := word64Val_Get(v)
|
||||||
|
if x == 0 {
|
||||||
|
return ErrNil
|
||||||
|
}
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
p.valEnc(o, x)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func size_int64(p *Properties, base structPointer) (n int) {
|
func size_int64(p *Properties, base structPointer) (n int) {
|
||||||
v := structPointer_Word64(base, p.field)
|
v := structPointer_Word64(base, p.field)
|
||||||
if word64_IsNil(v) {
|
if word64_IsNil(v) {
|
||||||
|
@ -376,6 +449,17 @@ func size_int64(p *Properties, base structPointer) (n int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func size_proto3_int64(p *Properties, base structPointer) (n int) {
|
||||||
|
v := structPointer_Word64Val(base, p.field)
|
||||||
|
x := word64Val_Get(v)
|
||||||
|
if x == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
n += len(p.tagcode)
|
||||||
|
n += p.valSize(x)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Encode a string.
|
// Encode a string.
|
||||||
func (o *Buffer) enc_string(p *Properties, base structPointer) error {
|
func (o *Buffer) enc_string(p *Properties, base structPointer) error {
|
||||||
v := *structPointer_String(base, p.field)
|
v := *structPointer_String(base, p.field)
|
||||||
|
@ -388,6 +472,16 @@ func (o *Buffer) enc_string(p *Properties, base structPointer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) enc_proto3_string(p *Properties, base structPointer) error {
|
||||||
|
v := *structPointer_StringVal(base, p.field)
|
||||||
|
if v == "" {
|
||||||
|
return ErrNil
|
||||||
|
}
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
o.EncodeStringBytes(v)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func size_string(p *Properties, base structPointer) (n int) {
|
func size_string(p *Properties, base structPointer) (n int) {
|
||||||
v := *structPointer_String(base, p.field)
|
v := *structPointer_String(base, p.field)
|
||||||
if v == nil {
|
if v == nil {
|
||||||
|
@ -399,6 +493,16 @@ func size_string(p *Properties, base structPointer) (n int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func size_proto3_string(p *Properties, base structPointer) (n int) {
|
||||||
|
v := *structPointer_StringVal(base, p.field)
|
||||||
|
if v == "" {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
n += len(p.tagcode)
|
||||||
|
n += sizeStringBytes(v)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// All protocol buffer fields are nillable, but be careful.
|
// All protocol buffer fields are nillable, but be careful.
|
||||||
func isNil(v reflect.Value) bool {
|
func isNil(v reflect.Value) bool {
|
||||||
switch v.Kind() {
|
switch v.Kind() {
|
||||||
|
@ -429,7 +533,7 @@ func (o *Buffer) enc_struct_message(p *Properties, base structPointer) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
o.buf = append(o.buf, p.tagcode...)
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
return o.enc_len_struct(p.stype, p.sprop, structp, &state)
|
return o.enc_len_struct(p.sprop, structp, &state)
|
||||||
}
|
}
|
||||||
|
|
||||||
func size_struct_message(p *Properties, base structPointer) int {
|
func size_struct_message(p *Properties, base structPointer) int {
|
||||||
|
@ -448,7 +552,7 @@ func size_struct_message(p *Properties, base structPointer) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
n0 := len(p.tagcode)
|
n0 := len(p.tagcode)
|
||||||
n1 := size_struct(p.stype, p.sprop, structp)
|
n1 := size_struct(p.sprop, structp)
|
||||||
n2 := sizeVarint(uint64(n1)) // size of encoded length
|
n2 := sizeVarint(uint64(n1)) // size of encoded length
|
||||||
return n0 + n1 + n2
|
return n0 + n1 + n2
|
||||||
}
|
}
|
||||||
|
@ -462,7 +566,7 @@ func (o *Buffer) enc_struct_group(p *Properties, base structPointer) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
|
o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
|
||||||
err := o.enc_struct(p.stype, p.sprop, b)
|
err := o.enc_struct(p.sprop, b)
|
||||||
if err != nil && !state.shouldContinue(err, nil) {
|
if err != nil && !state.shouldContinue(err, nil) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -477,7 +581,7 @@ func size_struct_group(p *Properties, base structPointer) (n int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
n += sizeVarint(uint64((p.Tag << 3) | WireStartGroup))
|
n += sizeVarint(uint64((p.Tag << 3) | WireStartGroup))
|
||||||
n += size_struct(p.stype, p.sprop, b)
|
n += size_struct(p.sprop, b)
|
||||||
n += sizeVarint(uint64((p.Tag << 3) | WireEndGroup))
|
n += sizeVarint(uint64((p.Tag << 3) | WireEndGroup))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -551,6 +655,16 @@ func (o *Buffer) enc_slice_byte(p *Properties, base structPointer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) enc_proto3_slice_byte(p *Properties, base structPointer) error {
|
||||||
|
s := *structPointer_Bytes(base, p.field)
|
||||||
|
if len(s) == 0 {
|
||||||
|
return ErrNil
|
||||||
|
}
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
o.EncodeRawBytes(s)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func size_slice_byte(p *Properties, base structPointer) (n int) {
|
func size_slice_byte(p *Properties, base structPointer) (n int) {
|
||||||
s := *structPointer_Bytes(base, p.field)
|
s := *structPointer_Bytes(base, p.field)
|
||||||
if s == nil {
|
if s == nil {
|
||||||
|
@ -561,6 +675,16 @@ func size_slice_byte(p *Properties, base structPointer) (n int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func size_proto3_slice_byte(p *Properties, base structPointer) (n int) {
|
||||||
|
s := *structPointer_Bytes(base, p.field)
|
||||||
|
if len(s) == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
n += len(p.tagcode)
|
||||||
|
n += sizeRawBytes(s)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Encode a slice of int32s ([]int32).
|
// Encode a slice of int32s ([]int32).
|
||||||
func (o *Buffer) enc_slice_int32(p *Properties, base structPointer) error {
|
func (o *Buffer) enc_slice_int32(p *Properties, base structPointer) error {
|
||||||
s := structPointer_Word32Slice(base, p.field)
|
s := structPointer_Word32Slice(base, p.field)
|
||||||
|
@ -831,7 +955,7 @@ func (o *Buffer) enc_slice_struct_message(p *Properties, base structPointer) err
|
||||||
}
|
}
|
||||||
|
|
||||||
o.buf = append(o.buf, p.tagcode...)
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
err := o.enc_len_struct(p.stype, p.sprop, structp, &state)
|
err := o.enc_len_struct(p.sprop, structp, &state)
|
||||||
if err != nil && !state.shouldContinue(err, nil) {
|
if err != nil && !state.shouldContinue(err, nil) {
|
||||||
if err == ErrNil {
|
if err == ErrNil {
|
||||||
return ErrRepeatedHasNil
|
return ErrRepeatedHasNil
|
||||||
|
@ -861,7 +985,7 @@ func size_slice_struct_message(p *Properties, base structPointer) (n int) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
n0 := size_struct(p.stype, p.sprop, structp)
|
n0 := size_struct(p.sprop, structp)
|
||||||
n1 := sizeVarint(uint64(n0)) // size of encoded length
|
n1 := sizeVarint(uint64(n0)) // size of encoded length
|
||||||
n += n0 + n1
|
n += n0 + n1
|
||||||
}
|
}
|
||||||
|
@ -882,7 +1006,7 @@ func (o *Buffer) enc_slice_struct_group(p *Properties, base structPointer) error
|
||||||
|
|
||||||
o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
|
o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
|
||||||
|
|
||||||
err := o.enc_struct(p.stype, p.sprop, b)
|
err := o.enc_struct(p.sprop, b)
|
||||||
|
|
||||||
if err != nil && !state.shouldContinue(err, nil) {
|
if err != nil && !state.shouldContinue(err, nil) {
|
||||||
if err == ErrNil {
|
if err == ErrNil {
|
||||||
|
@ -908,7 +1032,7 @@ func size_slice_struct_group(p *Properties, base structPointer) (n int) {
|
||||||
return // return size up to this point
|
return // return size up to this point
|
||||||
}
|
}
|
||||||
|
|
||||||
n += size_struct(p.stype, p.sprop, b)
|
n += size_struct(p.sprop, b)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -945,12 +1069,112 @@ func size_map(p *Properties, base structPointer) int {
|
||||||
return sizeExtensionMap(v)
|
return sizeExtensionMap(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Encode a map field.
|
||||||
|
func (o *Buffer) enc_new_map(p *Properties, base structPointer) error {
|
||||||
|
var state errorState // XXX: or do we need to plumb this through?
|
||||||
|
|
||||||
|
/*
|
||||||
|
A map defined as
|
||||||
|
map<key_type, value_type> map_field = N;
|
||||||
|
is encoded in the same way as
|
||||||
|
message MapFieldEntry {
|
||||||
|
key_type key = 1;
|
||||||
|
value_type value = 2;
|
||||||
|
}
|
||||||
|
repeated MapFieldEntry map_field = N;
|
||||||
|
*/
|
||||||
|
|
||||||
|
v := structPointer_Map(base, p.field, p.mtype).Elem() // map[K]V
|
||||||
|
if v.Len() == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype)
|
||||||
|
|
||||||
|
enc := func() error {
|
||||||
|
if err := p.mkeyprop.enc(o, p.mkeyprop, keybase); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := p.mvalprop.enc(o, p.mvalprop, valbase); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
keys := v.MapKeys()
|
||||||
|
sort.Sort(mapKeys(keys))
|
||||||
|
for _, key := range keys {
|
||||||
|
val := v.MapIndex(key)
|
||||||
|
|
||||||
|
keycopy.Set(key)
|
||||||
|
valcopy.Set(val)
|
||||||
|
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
if err := o.enc_len_thing(enc, &state); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func size_new_map(p *Properties, base structPointer) int {
|
||||||
|
v := structPointer_Map(base, p.field, p.mtype).Elem() // map[K]V
|
||||||
|
|
||||||
|
keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype)
|
||||||
|
|
||||||
|
n := 0
|
||||||
|
for _, key := range v.MapKeys() {
|
||||||
|
val := v.MapIndex(key)
|
||||||
|
keycopy.Set(key)
|
||||||
|
valcopy.Set(val)
|
||||||
|
|
||||||
|
// Tag codes are two bytes per map entry.
|
||||||
|
n += 2
|
||||||
|
n += p.mkeyprop.size(p.mkeyprop, keybase)
|
||||||
|
n += p.mvalprop.size(p.mvalprop, valbase)
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
// mapEncodeScratch returns a new reflect.Value matching the map's value type,
|
||||||
|
// and a structPointer suitable for passing to an encoder or sizer.
|
||||||
|
func mapEncodeScratch(mapType reflect.Type) (keycopy, valcopy reflect.Value, keybase, valbase structPointer) {
|
||||||
|
// Prepare addressable doubly-indirect placeholders for the key and value types.
|
||||||
|
// This is needed because the element-type encoders expect **T, but the map iteration produces T.
|
||||||
|
|
||||||
|
keycopy = reflect.New(mapType.Key()).Elem() // addressable K
|
||||||
|
keyptr := reflect.New(reflect.PtrTo(keycopy.Type())).Elem() // addressable *K
|
||||||
|
keyptr.Set(keycopy.Addr()) //
|
||||||
|
keybase = toStructPointer(keyptr.Addr()) // **K
|
||||||
|
|
||||||
|
// Value types are more varied and require special handling.
|
||||||
|
switch mapType.Elem().Kind() {
|
||||||
|
case reflect.Slice:
|
||||||
|
// []byte
|
||||||
|
var dummy []byte
|
||||||
|
valcopy = reflect.ValueOf(&dummy).Elem() // addressable []byte
|
||||||
|
valbase = toStructPointer(valcopy.Addr())
|
||||||
|
case reflect.Ptr:
|
||||||
|
// message; the generated field type is map[K]*Msg (so V is *Msg),
|
||||||
|
// so we only need one level of indirection.
|
||||||
|
valcopy = reflect.New(mapType.Elem()).Elem() // addressable V
|
||||||
|
valbase = toStructPointer(valcopy.Addr())
|
||||||
|
default:
|
||||||
|
// everything else
|
||||||
|
valcopy = reflect.New(mapType.Elem()).Elem() // addressable V
|
||||||
|
valptr := reflect.New(reflect.PtrTo(valcopy.Type())).Elem() // addressable *V
|
||||||
|
valptr.Set(valcopy.Addr()) //
|
||||||
|
valbase = toStructPointer(valptr.Addr()) // **V
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Encode a struct.
|
// Encode a struct.
|
||||||
func (o *Buffer) enc_struct(t reflect.Type, prop *StructProperties, base structPointer) error {
|
func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
|
||||||
var state errorState
|
var state errorState
|
||||||
// Encode fields in tag order so that decoders may use optimizations
|
// Encode fields in tag order so that decoders may use optimizations
|
||||||
// that depend on the ordering.
|
// that depend on the ordering.
|
||||||
// http://code.google.com/apis/protocolbuffers/docs/encoding.html#order
|
// https://developers.google.com/protocol-buffers/docs/encoding#order
|
||||||
for _, i := range prop.order {
|
for _, i := range prop.order {
|
||||||
p := prop.Prop[i]
|
p := prop.Prop[i]
|
||||||
if p.enc != nil {
|
if p.enc != nil {
|
||||||
|
@ -978,7 +1202,7 @@ func (o *Buffer) enc_struct(t reflect.Type, prop *StructProperties, base structP
|
||||||
return state.err
|
return state.err
|
||||||
}
|
}
|
||||||
|
|
||||||
func size_struct(t reflect.Type, prop *StructProperties, base structPointer) (n int) {
|
func size_struct(prop *StructProperties, base structPointer) (n int) {
|
||||||
for _, i := range prop.order {
|
for _, i := range prop.order {
|
||||||
p := prop.Prop[i]
|
p := prop.Prop[i]
|
||||||
if p.size != nil {
|
if p.size != nil {
|
||||||
|
@ -998,11 +1222,16 @@ func size_struct(t reflect.Type, prop *StructProperties, base structPointer) (n
|
||||||
var zeroes [20]byte // longer than any conceivable sizeVarint
|
var zeroes [20]byte // longer than any conceivable sizeVarint
|
||||||
|
|
||||||
// Encode a struct, preceded by its encoded length (as a varint).
|
// Encode a struct, preceded by its encoded length (as a varint).
|
||||||
func (o *Buffer) enc_len_struct(t reflect.Type, prop *StructProperties, base structPointer, state *errorState) error {
|
func (o *Buffer) enc_len_struct(prop *StructProperties, base structPointer, state *errorState) error {
|
||||||
|
return o.enc_len_thing(func() error { return o.enc_struct(prop, base) }, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode something, preceded by its encoded length (as a varint).
|
||||||
|
func (o *Buffer) enc_len_thing(enc func() error, state *errorState) error {
|
||||||
iLen := len(o.buf)
|
iLen := len(o.buf)
|
||||||
o.buf = append(o.buf, 0, 0, 0, 0) // reserve four bytes for length
|
o.buf = append(o.buf, 0, 0, 0, 0) // reserve four bytes for length
|
||||||
iMsg := len(o.buf)
|
iMsg := len(o.buf)
|
||||||
err := o.enc_struct(t, prop, base)
|
err := enc()
|
||||||
if err != nil && !state.shouldContinue(err, nil) {
|
if err != nil && !state.shouldContinue(err, nil) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
// Go support for Protocol Buffers - Google's data interchange format
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
//
|
//
|
||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
// http://code.google.com/p/goprotobuf/
|
// https://github.com/golang/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
@ -57,7 +57,7 @@ Equality is defined in this way:
|
||||||
although represented by []byte, is not a repeated field)
|
although represented by []byte, is not a repeated field)
|
||||||
- Two unset fields are equal.
|
- Two unset fields are equal.
|
||||||
- Two unknown field sets are equal if their current
|
- Two unknown field sets are equal if their current
|
||||||
encoded state is equal. (TODO)
|
encoded state is equal.
|
||||||
- Two extension sets are equal iff they have corresponding
|
- Two extension sets are equal iff they have corresponding
|
||||||
elements that are pairwise equal.
|
elements that are pairwise equal.
|
||||||
- Every other combination of things are not equal.
|
- Every other combination of things are not equal.
|
||||||
|
@ -154,6 +154,21 @@ func equalAny(v1, v2 reflect.Value) bool {
|
||||||
return v1.Float() == v2.Float()
|
return v1.Float() == v2.Float()
|
||||||
case reflect.Int32, reflect.Int64:
|
case reflect.Int32, reflect.Int64:
|
||||||
return v1.Int() == v2.Int()
|
return v1.Int() == v2.Int()
|
||||||
|
case reflect.Map:
|
||||||
|
if v1.Len() != v2.Len() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, key := range v1.MapKeys() {
|
||||||
|
val2 := v2.MapIndex(key)
|
||||||
|
if !val2.IsValid() {
|
||||||
|
// This key was not found in the second map.
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !equalAny(v1.MapIndex(key), val2) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
case reflect.Ptr:
|
case reflect.Ptr:
|
||||||
return equalAny(v1.Elem(), v2.Elem())
|
return equalAny(v1.Elem(), v2.Elem())
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
|
@ -1,7 +1,7 @@
|
||||||
// Go support for Protocol Buffers - Google's data interchange format
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
//
|
//
|
||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
// http://code.google.com/p/goprotobuf/
|
// https://github.com/golang/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
@ -35,7 +35,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
pb "./testdata"
|
pb "./testdata"
|
||||||
. "code.google.com/p/goprotobuf/proto"
|
. "github.com/golang/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Four identical base messages.
|
// Four identical base messages.
|
||||||
|
@ -155,6 +155,31 @@ var EqualTests = []struct {
|
||||||
},
|
},
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"map same",
|
||||||
|
&pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
|
||||||
|
&pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"map different entry",
|
||||||
|
&pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
|
||||||
|
&pb.MessageWithMap{NameMapping: map[int32]string{2: "Rob"}},
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"map different key only",
|
||||||
|
&pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
|
||||||
|
&pb.MessageWithMap{NameMapping: map[int32]string{2: "Ken"}},
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"map different value only",
|
||||||
|
&pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
|
||||||
|
&pb.MessageWithMap{NameMapping: map[int32]string{1: "Rob"}},
|
||||||
|
false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEqual(t *testing.T) {
|
func TestEqual(t *testing.T) {
|
|
@ -1,7 +1,7 @@
|
||||||
// Go support for Protocol Buffers - Google's data interchange format
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
//
|
//
|
||||||
// Copyright 2010 The Go Authors. All rights reserved.
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
// http://code.google.com/p/goprotobuf/
|
// https://github.com/golang/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
@ -227,7 +227,8 @@ func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, er
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
e, ok := pb.ExtensionMap()[extension.Field]
|
emap := pb.ExtensionMap()
|
||||||
|
e, ok := emap[extension.Field]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, ErrMissingExtension
|
return nil, ErrMissingExtension
|
||||||
}
|
}
|
||||||
|
@ -252,6 +253,7 @@ func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, er
|
||||||
e.value = v
|
e.value = v
|
||||||
e.desc = extension
|
e.desc = extension
|
||||||
e.enc = nil
|
e.enc = nil
|
||||||
|
emap[extension.Field] = e
|
||||||
return e.value, nil
|
return e.value, nil
|
||||||
}
|
}
|
||||||
|
|
137
Godeps/_workspace/src/github.com/golang/protobuf/proto/extensions_test.go
generated
vendored
Normal file
137
Godeps/_workspace/src/github.com/golang/protobuf/proto/extensions_test.go
generated
vendored
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
|
//
|
||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// https://github.com/golang/protobuf
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package proto_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
pb "./testdata"
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetExtensionsWithMissingExtensions(t *testing.T) {
|
||||||
|
msg := &pb.MyMessage{}
|
||||||
|
ext1 := &pb.Ext{}
|
||||||
|
if err := proto.SetExtension(msg, pb.E_Ext_More, ext1); err != nil {
|
||||||
|
t.Fatalf("Could not set ext1: %s", ext1)
|
||||||
|
}
|
||||||
|
exts, err := proto.GetExtensions(msg, []*proto.ExtensionDesc{
|
||||||
|
pb.E_Ext_More,
|
||||||
|
pb.E_Ext_Text,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("GetExtensions() failed: %s", err)
|
||||||
|
}
|
||||||
|
if exts[0] != ext1 {
|
||||||
|
t.Errorf("ext1 not in returned extensions: %T %v", exts[0], exts[0])
|
||||||
|
}
|
||||||
|
if exts[1] != nil {
|
||||||
|
t.Errorf("ext2 in returned extensions: %T %v", exts[1], exts[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExtensionsRoundTrip(t *testing.T) {
|
||||||
|
msg := &pb.MyMessage{}
|
||||||
|
ext1 := &pb.Ext{
|
||||||
|
Data: proto.String("hi"),
|
||||||
|
}
|
||||||
|
ext2 := &pb.Ext{
|
||||||
|
Data: proto.String("there"),
|
||||||
|
}
|
||||||
|
exists := proto.HasExtension(msg, pb.E_Ext_More)
|
||||||
|
if exists {
|
||||||
|
t.Error("Extension More present unexpectedly")
|
||||||
|
}
|
||||||
|
if err := proto.SetExtension(msg, pb.E_Ext_More, ext1); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if err := proto.SetExtension(msg, pb.E_Ext_More, ext2); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
e, err := proto.GetExtension(msg, pb.E_Ext_More)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
x, ok := e.(*pb.Ext)
|
||||||
|
if !ok {
|
||||||
|
t.Errorf("e has type %T, expected testdata.Ext", e)
|
||||||
|
} else if *x.Data != "there" {
|
||||||
|
t.Errorf("SetExtension failed to overwrite, got %+v, not 'there'", x)
|
||||||
|
}
|
||||||
|
proto.ClearExtension(msg, pb.E_Ext_More)
|
||||||
|
if _, err = proto.GetExtension(msg, pb.E_Ext_More); err != proto.ErrMissingExtension {
|
||||||
|
t.Errorf("got %v, expected ErrMissingExtension", e)
|
||||||
|
}
|
||||||
|
if _, err := proto.GetExtension(msg, pb.E_X215); err == nil {
|
||||||
|
t.Error("expected bad extension error, got nil")
|
||||||
|
}
|
||||||
|
if err := proto.SetExtension(msg, pb.E_X215, 12); err == nil {
|
||||||
|
t.Error("expected extension err")
|
||||||
|
}
|
||||||
|
if err := proto.SetExtension(msg, pb.E_Ext_More, 12); err == nil {
|
||||||
|
t.Error("expected some sort of type mismatch error, got nil")
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
// Go support for Protocol Buffers - Google's data interchange format
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
//
|
//
|
||||||
// Copyright 2010 The Go Authors. All rights reserved.
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
// http://code.google.com/p/goprotobuf/
|
// https://github.com/golang/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
|
|
||||||
- Names are turned from camel_case to CamelCase for export.
|
- Names are turned from camel_case to CamelCase for export.
|
||||||
- There are no methods on v to set fields; just treat
|
- There are no methods on v to set fields; just treat
|
||||||
them as structure fields.
|
them as structure fields.
|
||||||
- There are getters that return a field's value if set,
|
- There are getters that return a field's value if set,
|
||||||
and return the field's default value if unset.
|
and return the field's default value if unset.
|
||||||
The getters work even if the receiver is a nil message.
|
The getters work even if the receiver is a nil message.
|
||||||
|
@ -50,17 +50,16 @@
|
||||||
That is, optional or required field int32 f becomes F *int32.
|
That is, optional or required field int32 f becomes F *int32.
|
||||||
- Repeated fields are slices.
|
- Repeated fields are slices.
|
||||||
- Helper functions are available to aid the setting of fields.
|
- Helper functions are available to aid the setting of fields.
|
||||||
Helpers for getting values are superseded by the
|
msg.Foo = proto.String("hello") // set field
|
||||||
GetFoo methods and their use is deprecated.
|
|
||||||
msg.Foo = proto.String("hello") // set field
|
|
||||||
- Constants are defined to hold the default values of all fields that
|
- Constants are defined to hold the default values of all fields that
|
||||||
have them. They have the form Default_StructName_FieldName.
|
have them. They have the form Default_StructName_FieldName.
|
||||||
Because the getter methods handle defaulted values,
|
Because the getter methods handle defaulted values,
|
||||||
direct use of these constants should be rare.
|
direct use of these constants should be rare.
|
||||||
- Enums are given type names and maps from names to values.
|
- Enums are given type names and maps from names to values.
|
||||||
Enum values are prefixed with the enum's type name. Enum types have
|
Enum values are prefixed by the enclosing message's name, or by the
|
||||||
a String method, and a Enum method to assist in message construction.
|
enum's type name if it is a top-level enum. Enum types have a String
|
||||||
- Nested groups and enums have type names prefixed with the name of
|
method, and a Enum method to assist in message construction.
|
||||||
|
- Nested messages, groups and enums have type names prefixed with the name of
|
||||||
the surrounding message type.
|
the surrounding message type.
|
||||||
- Extensions are given descriptor names that start with E_,
|
- Extensions are given descriptor names that start with E_,
|
||||||
followed by an underscore-delimited list of the nested messages
|
followed by an underscore-delimited list of the nested messages
|
||||||
|
@ -74,7 +73,7 @@
|
||||||
|
|
||||||
package example;
|
package example;
|
||||||
|
|
||||||
enum FOO { X = 17; };
|
enum FOO { X = 17; }
|
||||||
|
|
||||||
message Test {
|
message Test {
|
||||||
required string label = 1;
|
required string label = 1;
|
||||||
|
@ -89,7 +88,8 @@
|
||||||
|
|
||||||
package example
|
package example
|
||||||
|
|
||||||
import "code.google.com/p/goprotobuf/proto"
|
import proto "github.com/golang/protobuf/proto"
|
||||||
|
import math "math"
|
||||||
|
|
||||||
type FOO int32
|
type FOO int32
|
||||||
const (
|
const (
|
||||||
|
@ -110,6 +110,14 @@
|
||||||
func (x FOO) String() string {
|
func (x FOO) String() string {
|
||||||
return proto.EnumName(FOO_name, int32(x))
|
return proto.EnumName(FOO_name, int32(x))
|
||||||
}
|
}
|
||||||
|
func (x *FOO) UnmarshalJSON(data []byte) error {
|
||||||
|
value, err := proto.UnmarshalJSONEnum(FOO_value, data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*x = FOO(value)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type Test struct {
|
type Test struct {
|
||||||
Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"`
|
Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"`
|
||||||
|
@ -118,41 +126,41 @@
|
||||||
Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"`
|
Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
}
|
}
|
||||||
func (this *Test) Reset() { *this = Test{} }
|
func (m *Test) Reset() { *m = Test{} }
|
||||||
func (this *Test) String() string { return proto.CompactTextString(this) }
|
func (m *Test) String() string { return proto.CompactTextString(m) }
|
||||||
|
func (*Test) ProtoMessage() {}
|
||||||
const Default_Test_Type int32 = 77
|
const Default_Test_Type int32 = 77
|
||||||
|
|
||||||
func (this *Test) GetLabel() string {
|
func (m *Test) GetLabel() string {
|
||||||
if this != nil && this.Label != nil {
|
if m != nil && m.Label != nil {
|
||||||
return *this.Label
|
return *m.Label
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Test) GetType() int32 {
|
func (m *Test) GetType() int32 {
|
||||||
if this != nil && this.Type != nil {
|
if m != nil && m.Type != nil {
|
||||||
return *this.Type
|
return *m.Type
|
||||||
}
|
}
|
||||||
return Default_Test_Type
|
return Default_Test_Type
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Test) GetOptionalgroup() *Test_OptionalGroup {
|
func (m *Test) GetOptionalgroup() *Test_OptionalGroup {
|
||||||
if this != nil {
|
if m != nil {
|
||||||
return this.Optionalgroup
|
return m.Optionalgroup
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type Test_OptionalGroup struct {
|
type Test_OptionalGroup struct {
|
||||||
RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"`
|
RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
|
||||||
}
|
}
|
||||||
func (this *Test_OptionalGroup) Reset() { *this = Test_OptionalGroup{} }
|
func (m *Test_OptionalGroup) Reset() { *m = Test_OptionalGroup{} }
|
||||||
func (this *Test_OptionalGroup) String() string { return proto.CompactTextString(this) }
|
func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) }
|
||||||
|
|
||||||
func (this *Test_OptionalGroup) GetRequiredField() string {
|
func (m *Test_OptionalGroup) GetRequiredField() string {
|
||||||
if this != nil && this.RequiredField != nil {
|
if m != nil && m.RequiredField != nil {
|
||||||
return *this.RequiredField
|
return *m.RequiredField
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -168,15 +176,15 @@
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"code.google.com/p/goprotobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
"./example.pb"
|
pb "./example.pb"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
test := &example.Test{
|
test := &pb.Test{
|
||||||
Label: proto.String("hello"),
|
Label: proto.String("hello"),
|
||||||
Type: proto.Int32(17),
|
Type: proto.Int32(17),
|
||||||
Optionalgroup: &example.Test_OptionalGroup{
|
Optionalgroup: &pb.Test_OptionalGroup{
|
||||||
RequiredField: proto.String("good bye"),
|
RequiredField: proto.String("good bye"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -184,7 +192,7 @@
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("marshaling error: ", err)
|
log.Fatal("marshaling error: ", err)
|
||||||
}
|
}
|
||||||
newTest := new(example.Test)
|
newTest := &pb.Test{}
|
||||||
err = proto.Unmarshal(data, newTest)
|
err = proto.Unmarshal(data, newTest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("unmarshaling error: ", err)
|
log.Fatal("unmarshaling error: ", err)
|
||||||
|
@ -323,9 +331,7 @@ func Float64(v float64) *float64 {
|
||||||
// Uint32 is a helper routine that allocates a new uint32 value
|
// Uint32 is a helper routine that allocates a new uint32 value
|
||||||
// to store v and returns a pointer to it.
|
// to store v and returns a pointer to it.
|
||||||
func Uint32(v uint32) *uint32 {
|
func Uint32(v uint32) *uint32 {
|
||||||
p := new(uint32)
|
return &v
|
||||||
*p = v
|
|
||||||
return p
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uint64 is a helper routine that allocates a new uint64 value
|
// Uint64 is a helper routine that allocates a new uint64 value
|
||||||
|
@ -738,3 +744,16 @@ func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
|
||||||
|
|
||||||
return dm
|
return dm
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Map fields may have key types of non-float scalars, strings and enums.
|
||||||
|
// The easiest way to sort them in some deterministic order is to use fmt.
|
||||||
|
// If this turns out to be inefficient we can always consider other options,
|
||||||
|
// such as doing a Schwartzian transform.
|
||||||
|
|
||||||
|
type mapKeys []reflect.Value
|
||||||
|
|
||||||
|
func (s mapKeys) Len() int { return len(s) }
|
||||||
|
func (s mapKeys) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||||
|
func (s mapKeys) Less(i, j int) bool {
|
||||||
|
return fmt.Sprint(s[i].Interface()) < fmt.Sprint(s[j].Interface())
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
// Go support for Protocol Buffers - Google's data interchange format
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
//
|
//
|
||||||
// Copyright 2010 The Go Authors. All rights reserved.
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
// http://code.google.com/p/goprotobuf/
|
// https://github.com/golang/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
@ -36,7 +36,10 @@ package proto
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
)
|
)
|
||||||
|
@ -211,6 +214,61 @@ func UnmarshalMessageSet(buf []byte, m map[int32]Extension) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MarshalMessageSetJSON encodes the extension map represented by m in JSON format.
|
||||||
|
// It is called by generated MarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
|
||||||
|
func MarshalMessageSetJSON(m map[int32]Extension) ([]byte, error) {
|
||||||
|
var b bytes.Buffer
|
||||||
|
b.WriteByte('{')
|
||||||
|
|
||||||
|
// Process the map in key order for deterministic output.
|
||||||
|
ids := make([]int32, 0, len(m))
|
||||||
|
for id := range m {
|
||||||
|
ids = append(ids, id)
|
||||||
|
}
|
||||||
|
sort.Sort(int32Slice(ids)) // int32Slice defined in text.go
|
||||||
|
|
||||||
|
for i, id := range ids {
|
||||||
|
ext := m[id]
|
||||||
|
if i > 0 {
|
||||||
|
b.WriteByte(',')
|
||||||
|
}
|
||||||
|
|
||||||
|
msd, ok := messageSetMap[id]
|
||||||
|
if !ok {
|
||||||
|
// Unknown type; we can't render it, so skip it.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fmt.Fprintf(&b, `"[%s]":`, msd.name)
|
||||||
|
|
||||||
|
x := ext.value
|
||||||
|
if x == nil {
|
||||||
|
x = reflect.New(msd.t.Elem()).Interface()
|
||||||
|
if err := Unmarshal(ext.enc, x.(Message)); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
d, err := json.Marshal(x)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
b.Write(d)
|
||||||
|
}
|
||||||
|
b.WriteByte('}')
|
||||||
|
return b.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalMessageSetJSON decodes the extension map encoded in buf in JSON format.
|
||||||
|
// It is called by generated UnmarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
|
||||||
|
func UnmarshalMessageSetJSON(buf []byte, m map[int32]Extension) error {
|
||||||
|
// Common-case fast path.
|
||||||
|
if len(buf) == 0 || bytes.Equal(buf, []byte("{}")) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is fairly tricky, and it's not clear that it is needed.
|
||||||
|
return errors.New("TODO: UnmarshalMessageSetJSON not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
// A global registry of types that can be used in a MessageSet.
|
// A global registry of types that can be used in a MessageSet.
|
||||||
|
|
||||||
var messageSetMap = make(map[int32]messageSetDesc)
|
var messageSetMap = make(map[int32]messageSetDesc)
|
||||||
|
@ -221,9 +279,9 @@ type messageSetDesc struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterMessageSetType is called from the generated code.
|
// RegisterMessageSetType is called from the generated code.
|
||||||
func RegisterMessageSetType(i messageTypeIder, name string) {
|
func RegisterMessageSetType(m Message, fieldNum int32, name string) {
|
||||||
messageSetMap[i.MessageTypeId()] = messageSetDesc{
|
messageSetMap[fieldNum] = messageSetDesc{
|
||||||
t: reflect.TypeOf(i),
|
t: reflect.TypeOf(m),
|
||||||
name: name,
|
name: name,
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
// Go support for Protocol Buffers - Google's data interchange format
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
//
|
//
|
||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
// http://code.google.com/p/goprotobuf/
|
// https://github.com/golang/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
|
@ -1,7 +1,7 @@
|
||||||
// Go support for Protocol Buffers - Google's data interchange format
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
//
|
//
|
||||||
// Copyright 2012 The Go Authors. All rights reserved.
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
// http://code.google.com/p/goprotobuf/
|
// https://github.com/golang/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
// +build appengine,!appenginevm
|
// +build appengine
|
||||||
|
|
||||||
// This file contains an implementation of proto field accesses using package reflect.
|
// This file contains an implementation of proto field accesses using package reflect.
|
||||||
// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can
|
// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can
|
||||||
|
@ -114,6 +114,11 @@ func structPointer_Bool(p structPointer, f field) **bool {
|
||||||
return structPointer_ifield(p, f).(**bool)
|
return structPointer_ifield(p, f).(**bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BoolVal returns the address of a bool field in the struct.
|
||||||
|
func structPointer_BoolVal(p structPointer, f field) *bool {
|
||||||
|
return structPointer_ifield(p, f).(*bool)
|
||||||
|
}
|
||||||
|
|
||||||
// BoolSlice returns the address of a []bool field in the struct.
|
// BoolSlice returns the address of a []bool field in the struct.
|
||||||
func structPointer_BoolSlice(p structPointer, f field) *[]bool {
|
func structPointer_BoolSlice(p structPointer, f field) *[]bool {
|
||||||
return structPointer_ifield(p, f).(*[]bool)
|
return structPointer_ifield(p, f).(*[]bool)
|
||||||
|
@ -124,6 +129,11 @@ func structPointer_String(p structPointer, f field) **string {
|
||||||
return structPointer_ifield(p, f).(**string)
|
return structPointer_ifield(p, f).(**string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StringVal returns the address of a string field in the struct.
|
||||||
|
func structPointer_StringVal(p structPointer, f field) *string {
|
||||||
|
return structPointer_ifield(p, f).(*string)
|
||||||
|
}
|
||||||
|
|
||||||
// StringSlice returns the address of a []string field in the struct.
|
// StringSlice returns the address of a []string field in the struct.
|
||||||
func structPointer_StringSlice(p structPointer, f field) *[]string {
|
func structPointer_StringSlice(p structPointer, f field) *[]string {
|
||||||
return structPointer_ifield(p, f).(*[]string)
|
return structPointer_ifield(p, f).(*[]string)
|
||||||
|
@ -134,6 +144,11 @@ func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
|
||||||
return structPointer_ifield(p, f).(*map[int32]Extension)
|
return structPointer_ifield(p, f).(*map[int32]Extension)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Map returns the reflect.Value for the address of a map field in the struct.
|
||||||
|
func structPointer_Map(p structPointer, f field, typ reflect.Type) reflect.Value {
|
||||||
|
return structPointer_field(p, f).Addr()
|
||||||
|
}
|
||||||
|
|
||||||
// SetStructPointer writes a *struct field in the struct.
|
// SetStructPointer writes a *struct field in the struct.
|
||||||
func structPointer_SetStructPointer(p structPointer, f field, q structPointer) {
|
func structPointer_SetStructPointer(p structPointer, f field, q structPointer) {
|
||||||
structPointer_field(p, f).Set(q.v)
|
structPointer_field(p, f).Set(q.v)
|
||||||
|
@ -235,6 +250,49 @@ func structPointer_Word32(p structPointer, f field) word32 {
|
||||||
return word32{structPointer_field(p, f)}
|
return word32{structPointer_field(p, f)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A word32Val represents a field of type int32, uint32, float32, or enum.
|
||||||
|
// That is, v.Type() is int32, uint32, float32, or enum and v is assignable.
|
||||||
|
type word32Val struct {
|
||||||
|
v reflect.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set sets *p to x.
|
||||||
|
func word32Val_Set(p word32Val, x uint32) {
|
||||||
|
switch p.v.Type() {
|
||||||
|
case int32Type:
|
||||||
|
p.v.SetInt(int64(x))
|
||||||
|
return
|
||||||
|
case uint32Type:
|
||||||
|
p.v.SetUint(uint64(x))
|
||||||
|
return
|
||||||
|
case float32Type:
|
||||||
|
p.v.SetFloat(float64(math.Float32frombits(x)))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// must be enum
|
||||||
|
p.v.SetInt(int64(int32(x)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get gets the bits pointed at by p, as a uint32.
|
||||||
|
func word32Val_Get(p word32Val) uint32 {
|
||||||
|
elem := p.v
|
||||||
|
switch elem.Kind() {
|
||||||
|
case reflect.Int32:
|
||||||
|
return uint32(elem.Int())
|
||||||
|
case reflect.Uint32:
|
||||||
|
return uint32(elem.Uint())
|
||||||
|
case reflect.Float32:
|
||||||
|
return math.Float32bits(float32(elem.Float()))
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Word32Val returns a reference to a int32, uint32, float32, or enum field in the struct.
|
||||||
|
func structPointer_Word32Val(p structPointer, f field) word32Val {
|
||||||
|
return word32Val{structPointer_field(p, f)}
|
||||||
|
}
|
||||||
|
|
||||||
// A word32Slice is a slice of 32-bit values.
|
// A word32Slice is a slice of 32-bit values.
|
||||||
// That is, v.Type() is []int32, []uint32, []float32, or []enum.
|
// That is, v.Type() is []int32, []uint32, []float32, or []enum.
|
||||||
type word32Slice struct {
|
type word32Slice struct {
|
||||||
|
@ -339,6 +397,43 @@ func structPointer_Word64(p structPointer, f field) word64 {
|
||||||
return word64{structPointer_field(p, f)}
|
return word64{structPointer_field(p, f)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// word64Val is like word32Val but for 64-bit values.
|
||||||
|
type word64Val struct {
|
||||||
|
v reflect.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func word64Val_Set(p word64Val, o *Buffer, x uint64) {
|
||||||
|
switch p.v.Type() {
|
||||||
|
case int64Type:
|
||||||
|
p.v.SetInt(int64(x))
|
||||||
|
return
|
||||||
|
case uint64Type:
|
||||||
|
p.v.SetUint(x)
|
||||||
|
return
|
||||||
|
case float64Type:
|
||||||
|
p.v.SetFloat(math.Float64frombits(x))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
func word64Val_Get(p word64Val) uint64 {
|
||||||
|
elem := p.v
|
||||||
|
switch elem.Kind() {
|
||||||
|
case reflect.Int64:
|
||||||
|
return uint64(elem.Int())
|
||||||
|
case reflect.Uint64:
|
||||||
|
return elem.Uint()
|
||||||
|
case reflect.Float64:
|
||||||
|
return math.Float64bits(elem.Float())
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPointer_Word64Val(p structPointer, f field) word64Val {
|
||||||
|
return word64Val{structPointer_field(p, f)}
|
||||||
|
}
|
||||||
|
|
||||||
type word64Slice struct {
|
type word64Slice struct {
|
||||||
v reflect.Value
|
v reflect.Value
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
// Go support for Protocol Buffers - Google's data interchange format
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
//
|
//
|
||||||
// Copyright 2012 The Go Authors. All rights reserved.
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
// http://code.google.com/p/goprotobuf/
|
// https://github.com/golang/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
// +build !appengine appenginevm
|
// +build !appengine
|
||||||
|
|
||||||
// This file contains the implementation of the proto field accesses using package unsafe.
|
// This file contains the implementation of the proto field accesses using package unsafe.
|
||||||
|
|
||||||
|
@ -100,6 +100,11 @@ func structPointer_Bool(p structPointer, f field) **bool {
|
||||||
return (**bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
return (**bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BoolVal returns the address of a bool field in the struct.
|
||||||
|
func structPointer_BoolVal(p structPointer, f field) *bool {
|
||||||
|
return (*bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
|
}
|
||||||
|
|
||||||
// BoolSlice returns the address of a []bool field in the struct.
|
// BoolSlice returns the address of a []bool field in the struct.
|
||||||
func structPointer_BoolSlice(p structPointer, f field) *[]bool {
|
func structPointer_BoolSlice(p structPointer, f field) *[]bool {
|
||||||
return (*[]bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
return (*[]bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
|
@ -110,6 +115,11 @@ func structPointer_String(p structPointer, f field) **string {
|
||||||
return (**string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
return (**string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StringVal returns the address of a string field in the struct.
|
||||||
|
func structPointer_StringVal(p structPointer, f field) *string {
|
||||||
|
return (*string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
|
}
|
||||||
|
|
||||||
// StringSlice returns the address of a []string field in the struct.
|
// StringSlice returns the address of a []string field in the struct.
|
||||||
func structPointer_StringSlice(p structPointer, f field) *[]string {
|
func structPointer_StringSlice(p structPointer, f field) *[]string {
|
||||||
return (*[]string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
return (*[]string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
|
@ -120,6 +130,11 @@ func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
|
||||||
return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Map returns the reflect.Value for the address of a map field in the struct.
|
||||||
|
func structPointer_Map(p structPointer, f field, typ reflect.Type) reflect.Value {
|
||||||
|
return reflect.NewAt(typ, unsafe.Pointer(uintptr(p)+uintptr(f)))
|
||||||
|
}
|
||||||
|
|
||||||
// SetStructPointer writes a *struct field in the struct.
|
// SetStructPointer writes a *struct field in the struct.
|
||||||
func structPointer_SetStructPointer(p structPointer, f field, q structPointer) {
|
func structPointer_SetStructPointer(p structPointer, f field, q structPointer) {
|
||||||
*(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f))) = q
|
*(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f))) = q
|
||||||
|
@ -170,6 +185,24 @@ func structPointer_Word32(p structPointer, f field) word32 {
|
||||||
return word32((**uint32)(unsafe.Pointer(uintptr(p) + uintptr(f))))
|
return word32((**uint32)(unsafe.Pointer(uintptr(p) + uintptr(f))))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A word32Val is the address of a 32-bit value field.
|
||||||
|
type word32Val *uint32
|
||||||
|
|
||||||
|
// Set sets *p to x.
|
||||||
|
func word32Val_Set(p word32Val, x uint32) {
|
||||||
|
*p = x
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get gets the value pointed at by p.
|
||||||
|
func word32Val_Get(p word32Val) uint32 {
|
||||||
|
return *p
|
||||||
|
}
|
||||||
|
|
||||||
|
// Word32Val returns the address of a *int32, *uint32, *float32, or *enum field in the struct.
|
||||||
|
func structPointer_Word32Val(p structPointer, f field) word32Val {
|
||||||
|
return word32Val((*uint32)(unsafe.Pointer(uintptr(p) + uintptr(f))))
|
||||||
|
}
|
||||||
|
|
||||||
// A word32Slice is a slice of 32-bit values.
|
// A word32Slice is a slice of 32-bit values.
|
||||||
type word32Slice []uint32
|
type word32Slice []uint32
|
||||||
|
|
||||||
|
@ -206,6 +239,21 @@ func structPointer_Word64(p structPointer, f field) word64 {
|
||||||
return word64((**uint64)(unsafe.Pointer(uintptr(p) + uintptr(f))))
|
return word64((**uint64)(unsafe.Pointer(uintptr(p) + uintptr(f))))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// word64Val is like word32Val but for 64-bit values.
|
||||||
|
type word64Val *uint64
|
||||||
|
|
||||||
|
func word64Val_Set(p word64Val, o *Buffer, x uint64) {
|
||||||
|
*p = x
|
||||||
|
}
|
||||||
|
|
||||||
|
func word64Val_Get(p word64Val) uint64 {
|
||||||
|
return *p
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPointer_Word64Val(p structPointer, f field) word64Val {
|
||||||
|
return word64Val((*uint64)(unsafe.Pointer(uintptr(p) + uintptr(f))))
|
||||||
|
}
|
||||||
|
|
||||||
// word64Slice is like word32Slice but for 64-bit values.
|
// word64Slice is like word32Slice but for 64-bit values.
|
||||||
type word64Slice []uint64
|
type word64Slice []uint64
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Go support for Protocol Buffers - Google's data interchange format
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
//
|
//
|
||||||
// Copyright 2010 The Go Authors. All rights reserved.
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
// http://code.google.com/p/goprotobuf/
|
// https://github.com/golang/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
@ -155,6 +155,7 @@ type Properties struct {
|
||||||
Repeated bool
|
Repeated bool
|
||||||
Packed bool // relevant for repeated primitives only
|
Packed bool // relevant for repeated primitives only
|
||||||
Enum string // set for enum types only
|
Enum string // set for enum types only
|
||||||
|
proto3 bool // whether this is known to be a proto3 field; set for []byte only
|
||||||
|
|
||||||
Default string // default value
|
Default string // default value
|
||||||
HasDefault bool // whether an explicit default was provided
|
HasDefault bool // whether an explicit default was provided
|
||||||
|
@ -170,6 +171,10 @@ type Properties struct {
|
||||||
isMarshaler bool
|
isMarshaler bool
|
||||||
isUnmarshaler bool
|
isUnmarshaler bool
|
||||||
|
|
||||||
|
mtype reflect.Type // set for map types only
|
||||||
|
mkeyprop *Properties // set for map types only
|
||||||
|
mvalprop *Properties // set for map types only
|
||||||
|
|
||||||
size sizer
|
size sizer
|
||||||
valSize valueSizer // set for bool and numeric types only
|
valSize valueSizer // set for bool and numeric types only
|
||||||
|
|
||||||
|
@ -200,6 +205,9 @@ func (p *Properties) String() string {
|
||||||
if p.OrigName != p.Name {
|
if p.OrigName != p.Name {
|
||||||
s += ",name=" + p.OrigName
|
s += ",name=" + p.OrigName
|
||||||
}
|
}
|
||||||
|
if p.proto3 {
|
||||||
|
s += ",proto3"
|
||||||
|
}
|
||||||
if len(p.Enum) > 0 {
|
if len(p.Enum) > 0 {
|
||||||
s += ",enum=" + p.Enum
|
s += ",enum=" + p.Enum
|
||||||
}
|
}
|
||||||
|
@ -274,6 +282,8 @@ func (p *Properties) Parse(s string) {
|
||||||
p.OrigName = f[5:]
|
p.OrigName = f[5:]
|
||||||
case strings.HasPrefix(f, "enum="):
|
case strings.HasPrefix(f, "enum="):
|
||||||
p.Enum = f[5:]
|
p.Enum = f[5:]
|
||||||
|
case f == "proto3":
|
||||||
|
p.proto3 = true
|
||||||
case strings.HasPrefix(f, "def="):
|
case strings.HasPrefix(f, "def="):
|
||||||
p.HasDefault = true
|
p.HasDefault = true
|
||||||
p.Default = f[4:] // rest of string
|
p.Default = f[4:] // rest of string
|
||||||
|
@ -293,19 +303,50 @@ func logNoSliceEnc(t1, t2 reflect.Type) {
|
||||||
var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem()
|
var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem()
|
||||||
|
|
||||||
// Initialize the fields for encoding and decoding.
|
// Initialize the fields for encoding and decoding.
|
||||||
func (p *Properties) setEncAndDec(typ reflect.Type, lockGetProp bool) {
|
func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lockGetProp bool) {
|
||||||
p.enc = nil
|
p.enc = nil
|
||||||
p.dec = nil
|
p.dec = nil
|
||||||
p.size = nil
|
p.size = nil
|
||||||
|
|
||||||
switch t1 := typ; t1.Kind() {
|
switch t1 := typ; t1.Kind() {
|
||||||
default:
|
default:
|
||||||
fmt.Fprintf(os.Stderr, "proto: no coders for %T\n", t1)
|
fmt.Fprintf(os.Stderr, "proto: no coders for %v\n", t1)
|
||||||
|
|
||||||
|
// proto3 scalar types
|
||||||
|
|
||||||
|
case reflect.Bool:
|
||||||
|
p.enc = (*Buffer).enc_proto3_bool
|
||||||
|
p.dec = (*Buffer).dec_proto3_bool
|
||||||
|
p.size = size_proto3_bool
|
||||||
|
case reflect.Int32:
|
||||||
|
p.enc = (*Buffer).enc_proto3_int32
|
||||||
|
p.dec = (*Buffer).dec_proto3_int32
|
||||||
|
p.size = size_proto3_int32
|
||||||
|
case reflect.Uint32:
|
||||||
|
p.enc = (*Buffer).enc_proto3_uint32
|
||||||
|
p.dec = (*Buffer).dec_proto3_int32 // can reuse
|
||||||
|
p.size = size_proto3_uint32
|
||||||
|
case reflect.Int64, reflect.Uint64:
|
||||||
|
p.enc = (*Buffer).enc_proto3_int64
|
||||||
|
p.dec = (*Buffer).dec_proto3_int64
|
||||||
|
p.size = size_proto3_int64
|
||||||
|
case reflect.Float32:
|
||||||
|
p.enc = (*Buffer).enc_proto3_uint32 // can just treat them as bits
|
||||||
|
p.dec = (*Buffer).dec_proto3_int32
|
||||||
|
p.size = size_proto3_uint32
|
||||||
|
case reflect.Float64:
|
||||||
|
p.enc = (*Buffer).enc_proto3_int64 // can just treat them as bits
|
||||||
|
p.dec = (*Buffer).dec_proto3_int64
|
||||||
|
p.size = size_proto3_int64
|
||||||
|
case reflect.String:
|
||||||
|
p.enc = (*Buffer).enc_proto3_string
|
||||||
|
p.dec = (*Buffer).dec_proto3_string
|
||||||
|
p.size = size_proto3_string
|
||||||
|
|
||||||
case reflect.Ptr:
|
case reflect.Ptr:
|
||||||
switch t2 := t1.Elem(); t2.Kind() {
|
switch t2 := t1.Elem(); t2.Kind() {
|
||||||
default:
|
default:
|
||||||
fmt.Fprintf(os.Stderr, "proto: no encoder function for %T -> %T\n", t1, t2)
|
fmt.Fprintf(os.Stderr, "proto: no encoder function for %v -> %v\n", t1, t2)
|
||||||
break
|
break
|
||||||
case reflect.Bool:
|
case reflect.Bool:
|
||||||
p.enc = (*Buffer).enc_bool
|
p.enc = (*Buffer).enc_bool
|
||||||
|
@ -399,6 +440,10 @@ func (p *Properties) setEncAndDec(typ reflect.Type, lockGetProp bool) {
|
||||||
p.enc = (*Buffer).enc_slice_byte
|
p.enc = (*Buffer).enc_slice_byte
|
||||||
p.dec = (*Buffer).dec_slice_byte
|
p.dec = (*Buffer).dec_slice_byte
|
||||||
p.size = size_slice_byte
|
p.size = size_slice_byte
|
||||||
|
if p.proto3 {
|
||||||
|
p.enc = (*Buffer).enc_proto3_slice_byte
|
||||||
|
p.size = size_proto3_slice_byte
|
||||||
|
}
|
||||||
case reflect.Float32, reflect.Float64:
|
case reflect.Float32, reflect.Float64:
|
||||||
switch t2.Bits() {
|
switch t2.Bits() {
|
||||||
case 32:
|
case 32:
|
||||||
|
@ -461,6 +506,23 @@ func (p *Properties) setEncAndDec(typ reflect.Type, lockGetProp bool) {
|
||||||
p.size = size_slice_slice_byte
|
p.size = size_slice_slice_byte
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case reflect.Map:
|
||||||
|
p.enc = (*Buffer).enc_new_map
|
||||||
|
p.dec = (*Buffer).dec_new_map
|
||||||
|
p.size = size_new_map
|
||||||
|
|
||||||
|
p.mtype = t1
|
||||||
|
p.mkeyprop = &Properties{}
|
||||||
|
p.mkeyprop.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp)
|
||||||
|
p.mvalprop = &Properties{}
|
||||||
|
vtype := p.mtype.Elem()
|
||||||
|
if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice {
|
||||||
|
// The value type is not a message (*T) or bytes ([]byte),
|
||||||
|
// so we need encoders for the pointer to this type.
|
||||||
|
vtype = reflect.PtrTo(vtype)
|
||||||
|
}
|
||||||
|
p.mvalprop.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// precalculate tag code
|
// precalculate tag code
|
||||||
|
@ -529,7 +591,7 @@ func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructF
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p.Parse(tag)
|
p.Parse(tag)
|
||||||
p.setEncAndDec(typ, lockGetProp)
|
p.setEncAndDec(typ, f, lockGetProp)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -538,7 +600,11 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetProperties returns the list of properties for the type represented by t.
|
// GetProperties returns the list of properties for the type represented by t.
|
||||||
|
// t must represent a generated struct type of a protocol message.
|
||||||
func GetProperties(t reflect.Type) *StructProperties {
|
func GetProperties(t reflect.Type) *StructProperties {
|
||||||
|
if t.Kind() != reflect.Struct {
|
||||||
|
panic("proto: type must have kind struct")
|
||||||
|
}
|
||||||
mutex.Lock()
|
mutex.Lock()
|
||||||
sprop := getPropertiesLocked(t)
|
sprop := getPropertiesLocked(t)
|
||||||
mutex.Unlock()
|
mutex.Unlock()
|
44
Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto/Makefile
generated
vendored
Normal file
44
Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto/Makefile
generated
vendored
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# Go support for Protocol Buffers - Google's data interchange format
|
||||||
|
#
|
||||||
|
# Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
# https://github.com/golang/protobuf
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are
|
||||||
|
# met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above
|
||||||
|
# copyright notice, this list of conditions and the following disclaimer
|
||||||
|
# in the documentation and/or other materials provided with the
|
||||||
|
# distribution.
|
||||||
|
# * Neither the name of Google Inc. nor the names of its
|
||||||
|
# contributors may be used to endorse or promote products derived from
|
||||||
|
# this software without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
|
include ../../Make.protobuf
|
||||||
|
|
||||||
|
all: regenerate
|
||||||
|
|
||||||
|
regenerate:
|
||||||
|
rm -f proto3.pb.go
|
||||||
|
make proto3.pb.go
|
||||||
|
|
||||||
|
# The following rules are just aids to development. Not needed for typical testing.
|
||||||
|
|
||||||
|
diff: regenerate
|
||||||
|
git diff proto3.pb.go
|
|
@ -1,7 +1,7 @@
|
||||||
// Go support for Protocol Buffers - Google's data interchange format
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
//
|
//
|
||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
// http://code.google.com/p/goprotobuf/
|
// https://github.com/golang/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
@ -29,32 +29,30 @@
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
package proto_test
|
syntax = "proto3";
|
||||||
|
|
||||||
import (
|
package proto3_proto;
|
||||||
"testing"
|
|
||||||
|
|
||||||
pb "./testdata"
|
message Message {
|
||||||
"code.google.com/p/goprotobuf/proto"
|
enum Humour {
|
||||||
)
|
UNKNOWN = 0;
|
||||||
|
PUNS = 1;
|
||||||
|
SLAPSTICK = 2;
|
||||||
|
BILL_BAILEY = 3;
|
||||||
|
}
|
||||||
|
|
||||||
func TestGetExtensionsWithMissingExtensions(t *testing.T) {
|
string name = 1;
|
||||||
msg := &pb.MyMessage{}
|
Humour hilarity = 2;
|
||||||
ext1 := &pb.Ext{}
|
uint32 height_in_cm = 3;
|
||||||
if err := proto.SetExtension(msg, pb.E_Ext_More, ext1); err != nil {
|
bytes data = 4;
|
||||||
t.Fatalf("Could not set ext1: %s", ext1)
|
int64 result_count = 7;
|
||||||
}
|
bool true_scotsman = 8;
|
||||||
exts, err := proto.GetExtensions(msg, []*proto.ExtensionDesc{
|
float score = 9;
|
||||||
pb.E_Ext_More,
|
|
||||||
pb.E_Ext_Text,
|
repeated uint64 key = 5;
|
||||||
})
|
Nested nested = 6;
|
||||||
if err != nil {
|
}
|
||||||
t.Fatalf("GetExtensions() failed: %s", err)
|
|
||||||
}
|
message Nested {
|
||||||
if exts[0] != ext1 {
|
string bunny = 1;
|
||||||
t.Errorf("ext1 not in returned extensions: %T %v", exts[0], exts[0])
|
|
||||||
}
|
|
||||||
if exts[1] != nil {
|
|
||||||
t.Errorf("ext2 in returned extensions: %T %v", exts[1], exts[1])
|
|
||||||
}
|
|
||||||
}
|
}
|
93
Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_test.go
generated
vendored
Normal file
93
Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_test.go
generated
vendored
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
|
//
|
||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// https://github.com/golang/protobuf
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package proto_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
pb "./proto3_proto"
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestProto3ZeroValues(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
desc string
|
||||||
|
m proto.Message
|
||||||
|
}{
|
||||||
|
{"zero message", &pb.Message{}},
|
||||||
|
{"empty bytes field", &pb.Message{Data: []byte{}}},
|
||||||
|
}
|
||||||
|
for _, test := range tests {
|
||||||
|
b, err := proto.Marshal(test.m)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("%s: proto.Marshal: %v", test.desc, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if len(b) > 0 {
|
||||||
|
t.Errorf("%s: Encoding is non-empty: %q", test.desc, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
// Go support for Protocol Buffers - Google's data interchange format
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
//
|
//
|
||||||
// Copyright 2012 The Go Authors. All rights reserved.
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
// http://code.google.com/p/goprotobuf/
|
// https://github.com/golang/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
|
@ -1,7 +1,7 @@
|
||||||
// Go support for Protocol Buffers - Google's data interchange format
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
//
|
//
|
||||||
// Copyright 2012 The Go Authors. All rights reserved.
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
// http://code.google.com/p/goprotobuf/
|
// https://github.com/golang/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
@ -35,8 +35,9 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
proto3pb "./proto3_proto"
|
||||||
pb "./testdata"
|
pb "./testdata"
|
||||||
. "code.google.com/p/goprotobuf/proto"
|
. "github.com/golang/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
var messageWithExtension1 = &pb.MyMessage{Count: Int32(7)}
|
var messageWithExtension1 = &pb.MyMessage{Count: Int32(7)}
|
||||||
|
@ -102,6 +103,20 @@ var SizeTests = []struct {
|
||||||
{"unrecognized", &pb.MoreRepeated{XXX_unrecognized: []byte{13<<3 | 0, 4}}},
|
{"unrecognized", &pb.MoreRepeated{XXX_unrecognized: []byte{13<<3 | 0, 4}}},
|
||||||
{"extension (unencoded)", messageWithExtension1},
|
{"extension (unencoded)", messageWithExtension1},
|
||||||
{"extension (encoded)", messageWithExtension3},
|
{"extension (encoded)", messageWithExtension3},
|
||||||
|
// proto3 message
|
||||||
|
{"proto3 empty", &proto3pb.Message{}},
|
||||||
|
{"proto3 bool", &proto3pb.Message{TrueScotsman: true}},
|
||||||
|
{"proto3 int64", &proto3pb.Message{ResultCount: 1}},
|
||||||
|
{"proto3 uint32", &proto3pb.Message{HeightInCm: 123}},
|
||||||
|
{"proto3 float", &proto3pb.Message{Score: 12.6}},
|
||||||
|
{"proto3 string", &proto3pb.Message{Name: "Snezana"}},
|
||||||
|
{"proto3 bytes", &proto3pb.Message{Data: []byte("wowsa")}},
|
||||||
|
{"proto3 bytes, empty", &proto3pb.Message{Data: []byte{}}},
|
||||||
|
{"proto3 enum", &proto3pb.Message{Hilarity: proto3pb.Message_PUNS}},
|
||||||
|
|
||||||
|
{"map field", &pb.MessageWithMap{NameMapping: map[int32]string{1: "Rob", 7: "Andrew"}}},
|
||||||
|
{"map field with message", &pb.MessageWithMap{MsgMapping: map[int64]*pb.FloatingPoint{0x7001: &pb.FloatingPoint{F: Float64(2.0)}}}},
|
||||||
|
{"map field with bytes", &pb.MessageWithMap{ByteMapping: map[bool][]byte{true: []byte("this time for sure")}}},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSize(t *testing.T) {
|
func TestSize(t *testing.T) {
|
|
@ -1,7 +1,7 @@
|
||||||
# Go support for Protocol Buffers - Google's data interchange format
|
# Go support for Protocol Buffers - Google's data interchange format
|
||||||
#
|
#
|
||||||
# Copyright 2010 The Go Authors. All rights reserved.
|
# Copyright 2010 The Go Authors. All rights reserved.
|
||||||
# http://code.google.com/p/goprotobuf/
|
# https://github.com/golang/protobuf
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
# modification, are permitted provided that the following conditions are
|
# modification, are permitted provided that the following conditions are
|
||||||
|
@ -37,11 +37,11 @@ all: regenerate
|
||||||
regenerate:
|
regenerate:
|
||||||
rm -f test.pb.go
|
rm -f test.pb.go
|
||||||
make test.pb.go
|
make test.pb.go
|
||||||
|
|
||||||
# The following rules are just aids to development. Not needed for typical testing.
|
# The following rules are just aids to development. Not needed for typical testing.
|
||||||
|
|
||||||
diff: regenerate
|
diff: regenerate
|
||||||
hg diff test.pb.go
|
git diff test.pb.go
|
||||||
|
|
||||||
restore:
|
restore:
|
||||||
cp test.pb.go.golden test.pb.go
|
cp test.pb.go.golden test.pb.go
|
|
@ -1,7 +1,7 @@
|
||||||
// Go support for Protocol Buffers - Google's data interchange format
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
//
|
//
|
||||||
// Copyright 2012 The Go Authors. All rights reserved.
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
// http://code.google.com/p/goprotobuf/
|
// https://github.com/golang/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
|
@ -33,10 +33,11 @@ It has these top-level messages:
|
||||||
GroupOld
|
GroupOld
|
||||||
GroupNew
|
GroupNew
|
||||||
FloatingPoint
|
FloatingPoint
|
||||||
|
MessageWithMap
|
||||||
*/
|
*/
|
||||||
package testdata
|
package testdata
|
||||||
|
|
||||||
import proto "code.google.com/p/goprotobuf/proto"
|
import proto "github.com/golang/protobuf/proto"
|
||||||
import math "math"
|
import math "math"
|
||||||
|
|
||||||
// Reference imports to suppress errors if they are not otherwise used.
|
// Reference imports to suppress errors if they are not otherwise used.
|
||||||
|
@ -1416,6 +1417,12 @@ func (m *MyMessageSet) Marshal() ([]byte, error) {
|
||||||
func (m *MyMessageSet) Unmarshal(buf []byte) error {
|
func (m *MyMessageSet) Unmarshal(buf []byte) error {
|
||||||
return proto.UnmarshalMessageSet(buf, m.ExtensionMap())
|
return proto.UnmarshalMessageSet(buf, m.ExtensionMap())
|
||||||
}
|
}
|
||||||
|
func (m *MyMessageSet) MarshalJSON() ([]byte, error) {
|
||||||
|
return proto.MarshalMessageSetJSON(m.XXX_extensions)
|
||||||
|
}
|
||||||
|
func (m *MyMessageSet) UnmarshalJSON(buf []byte) error {
|
||||||
|
return proto.UnmarshalMessageSetJSON(buf, m.XXX_extensions)
|
||||||
|
}
|
||||||
|
|
||||||
// ensure MyMessageSet satisfies proto.Marshaler and proto.Unmarshaler
|
// ensure MyMessageSet satisfies proto.Marshaler and proto.Unmarshaler
|
||||||
var _ proto.Marshaler = (*MyMessageSet)(nil)
|
var _ proto.Marshaler = (*MyMessageSet)(nil)
|
||||||
|
@ -1879,6 +1886,38 @@ func (m *FloatingPoint) GetF() float64 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MessageWithMap struct {
|
||||||
|
NameMapping map[int32]string `protobuf:"bytes,1,rep,name=name_mapping" json:"name_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
|
||||||
|
MsgMapping map[int64]*FloatingPoint `protobuf:"bytes,2,rep,name=msg_mapping" json:"msg_mapping,omitempty" protobuf_key:"zigzag64,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
|
||||||
|
ByteMapping map[bool][]byte `protobuf:"bytes,3,rep,name=byte_mapping" json:"byte_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
|
||||||
|
XXX_unrecognized []byte `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MessageWithMap) Reset() { *m = MessageWithMap{} }
|
||||||
|
func (m *MessageWithMap) String() string { return proto.CompactTextString(m) }
|
||||||
|
func (*MessageWithMap) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (m *MessageWithMap) GetNameMapping() map[int32]string {
|
||||||
|
if m != nil {
|
||||||
|
return m.NameMapping
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MessageWithMap) GetMsgMapping() map[int64]*FloatingPoint {
|
||||||
|
if m != nil {
|
||||||
|
return m.MsgMapping
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MessageWithMap) GetByteMapping() map[bool][]byte {
|
||||||
|
if m != nil {
|
||||||
|
return m.ByteMapping
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
var E_Greeting = &proto.ExtensionDesc{
|
var E_Greeting = &proto.ExtensionDesc{
|
||||||
ExtendedType: (*MyMessage)(nil),
|
ExtendedType: (*MyMessage)(nil),
|
||||||
ExtensionType: ([]string)(nil),
|
ExtensionType: ([]string)(nil),
|
|
@ -1,7 +1,7 @@
|
||||||
// Go support for Protocol Buffers - Google's data interchange format
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
//
|
//
|
||||||
// Copyright 2010 The Go Authors. All rights reserved.
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
// http://code.google.com/p/goprotobuf/
|
// https://github.com/golang/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
@ -426,3 +426,9 @@ message GroupNew {
|
||||||
message FloatingPoint {
|
message FloatingPoint {
|
||||||
required double f = 1;
|
required double f = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message MessageWithMap {
|
||||||
|
map<int32, string> name_mapping = 1;
|
||||||
|
map<sint64, FloatingPoint> msg_mapping = 2;
|
||||||
|
map<bool, bytes> byte_mapping = 3;
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
// Go support for Protocol Buffers - Google's data interchange format
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
//
|
//
|
||||||
// Copyright 2010 The Go Authors. All rights reserved.
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
// http://code.google.com/p/goprotobuf/
|
// https://github.com/golang/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
@ -36,6 +36,7 @@ package proto
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
|
@ -74,13 +75,6 @@ type textWriter struct {
|
||||||
w writer
|
w writer
|
||||||
}
|
}
|
||||||
|
|
||||||
// textMarshaler is implemented by Messages that can marshal themsleves.
|
|
||||||
// It is identical to encoding.TextMarshaler, introduced in go 1.2,
|
|
||||||
// which will eventually replace it.
|
|
||||||
type textMarshaler interface {
|
|
||||||
MarshalText() (text []byte, err error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *textWriter) WriteString(s string) (n int, err error) {
|
func (w *textWriter) WriteString(s string) (n int, err error) {
|
||||||
if !strings.Contains(s, "\n") {
|
if !strings.Contains(s, "\n") {
|
||||||
if !w.compact && w.complete {
|
if !w.compact && w.complete {
|
||||||
|
@ -250,6 +244,100 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if fv.Kind() == reflect.Map {
|
||||||
|
// Map fields are rendered as a repeated struct with key/value fields.
|
||||||
|
keys := fv.MapKeys() // TODO: should we sort these for deterministic output?
|
||||||
|
sort.Sort(mapKeys(keys))
|
||||||
|
for _, key := range keys {
|
||||||
|
val := fv.MapIndex(key)
|
||||||
|
if err := writeName(w, props); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !w.compact {
|
||||||
|
if err := w.WriteByte(' '); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// open struct
|
||||||
|
if err := w.WriteByte('<'); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !w.compact {
|
||||||
|
if err := w.WriteByte('\n'); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
w.indent()
|
||||||
|
// key
|
||||||
|
if _, err := w.WriteString("key:"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !w.compact {
|
||||||
|
if err := w.WriteByte(' '); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := writeAny(w, key, props.mkeyprop); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := w.WriteByte('\n'); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// value
|
||||||
|
if _, err := w.WriteString("value:"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !w.compact {
|
||||||
|
if err := w.WriteByte(' '); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := writeAny(w, val, props.mvalprop); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := w.WriteByte('\n'); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// close struct
|
||||||
|
w.unindent()
|
||||||
|
if err := w.WriteByte('>'); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := w.WriteByte('\n'); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if props.proto3 && fv.Kind() == reflect.Slice && fv.Len() == 0 {
|
||||||
|
// empty bytes field
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice {
|
||||||
|
// proto3 non-repeated scalar field; skip if zero value
|
||||||
|
switch fv.Kind() {
|
||||||
|
case reflect.Bool:
|
||||||
|
if !fv.Bool() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
case reflect.Int32, reflect.Int64:
|
||||||
|
if fv.Int() == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
case reflect.Uint32, reflect.Uint64:
|
||||||
|
if fv.Uint() == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
if fv.Float() == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
case reflect.String:
|
||||||
|
if fv.String() == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err := writeName(w, props); err != nil {
|
if err := writeName(w, props); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -358,7 +446,7 @@ func writeAny(w *textWriter, v reflect.Value, props *Properties) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.indent()
|
w.indent()
|
||||||
if tm, ok := v.Interface().(textMarshaler); ok {
|
if tm, ok := v.Interface().(encoding.TextMarshaler); ok {
|
||||||
text, err := tm.MarshalText()
|
text, err := tm.MarshalText()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -653,7 +741,7 @@ func marshalText(w io.Writer, pb Message, compact bool) error {
|
||||||
compact: compact,
|
compact: compact,
|
||||||
}
|
}
|
||||||
|
|
||||||
if tm, ok := pb.(textMarshaler); ok {
|
if tm, ok := pb.(encoding.TextMarshaler); ok {
|
||||||
text, err := tm.MarshalText()
|
text, err := tm.MarshalText()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
|
@ -1,7 +1,7 @@
|
||||||
// Go support for Protocol Buffers - Google's data interchange format
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
//
|
//
|
||||||
// Copyright 2010 The Go Authors. All rights reserved.
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
// http://code.google.com/p/goprotobuf/
|
// https://github.com/golang/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
@ -35,6 +35,7 @@ package proto
|
||||||
// TODO: message sets.
|
// TODO: message sets.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
@ -43,13 +44,6 @@ import (
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
|
|
||||||
// textUnmarshaler is implemented by Messages that can unmarshal themsleves.
|
|
||||||
// It is identical to encoding.TextUnmarshaler, introduced in go 1.2,
|
|
||||||
// which will eventually replace it.
|
|
||||||
type textUnmarshaler interface {
|
|
||||||
UnmarshalText(text []byte) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type ParseError struct {
|
type ParseError struct {
|
||||||
Message string
|
Message string
|
||||||
Line int // 1-based line number
|
Line int // 1-based line number
|
||||||
|
@ -361,8 +355,20 @@ func (p *textParser) next() *token {
|
||||||
return &p.cur
|
return &p.cur
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return an error indicating which required field was not set.
|
func (p *textParser) consumeToken(s string) error {
|
||||||
func (p *textParser) missingRequiredFieldError(sv reflect.Value) *ParseError {
|
tok := p.next()
|
||||||
|
if tok.err != nil {
|
||||||
|
return tok.err
|
||||||
|
}
|
||||||
|
if tok.value != s {
|
||||||
|
p.back()
|
||||||
|
return p.errorf("expected %q, found %q", s, tok.value)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a RequiredNotSetError indicating which required field was not set.
|
||||||
|
func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSetError {
|
||||||
st := sv.Type()
|
st := sv.Type()
|
||||||
sprops := GetProperties(st)
|
sprops := GetProperties(st)
|
||||||
for i := 0; i < st.NumField(); i++ {
|
for i := 0; i < st.NumField(); i++ {
|
||||||
|
@ -372,10 +378,10 @@ func (p *textParser) missingRequiredFieldError(sv reflect.Value) *ParseError {
|
||||||
|
|
||||||
props := sprops.Prop[i]
|
props := sprops.Prop[i]
|
||||||
if props.Required {
|
if props.Required {
|
||||||
return p.errorf("message %v missing required field %q", st, props.OrigName)
|
return &RequiredNotSetError{fmt.Sprintf("%v.%v", st, props.OrigName)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return p.errorf("message %v missing required field", st) // should not happen
|
return &RequiredNotSetError{fmt.Sprintf("%v.<unknown field name>", st)} // should not happen
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the index in the struct for the named field, as well as the parsed tag properties.
|
// Returns the index in the struct for the named field, as well as the parsed tag properties.
|
||||||
|
@ -415,6 +421,10 @@ func (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseEr
|
||||||
if typ.Elem().Kind() != reflect.Ptr {
|
if typ.Elem().Kind() != reflect.Ptr {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
} else if typ.Kind() == reflect.String {
|
||||||
|
// The proto3 exception is for a string field,
|
||||||
|
// which requires a colon.
|
||||||
|
break
|
||||||
}
|
}
|
||||||
needColon = false
|
needColon = false
|
||||||
}
|
}
|
||||||
|
@ -426,9 +436,11 @@ func (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseEr
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *textParser) readStruct(sv reflect.Value, terminator string) *ParseError {
|
func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
|
||||||
st := sv.Type()
|
st := sv.Type()
|
||||||
reqCount := GetProperties(st).reqCount
|
reqCount := GetProperties(st).reqCount
|
||||||
|
var reqFieldErr error
|
||||||
|
fieldSet := make(map[string]bool)
|
||||||
// A struct is a sequence of "name: value", terminated by one of
|
// A struct is a sequence of "name: value", terminated by one of
|
||||||
// '>' or '}', or the end of the input. A name may also be
|
// '>' or '}', or the end of the input. A name may also be
|
||||||
// "[extension]".
|
// "[extension]".
|
||||||
|
@ -489,7 +501,10 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) *ParseError
|
||||||
ext = reflect.New(typ.Elem()).Elem()
|
ext = reflect.New(typ.Elem()).Elem()
|
||||||
}
|
}
|
||||||
if err := p.readAny(ext, props); err != nil {
|
if err := p.readAny(ext, props); err != nil {
|
||||||
return err
|
if _, ok := err.(*RequiredNotSetError); !ok {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
reqFieldErr = err
|
||||||
}
|
}
|
||||||
ep := sv.Addr().Interface().(extendableProto)
|
ep := sv.Addr().Interface().(extendableProto)
|
||||||
if !rep {
|
if !rep {
|
||||||
|
@ -507,17 +522,71 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) *ParseError
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// This is a normal, non-extension field.
|
// This is a normal, non-extension field.
|
||||||
fi, props, ok := structFieldByName(st, tok.value)
|
name := tok.value
|
||||||
|
fi, props, ok := structFieldByName(st, name)
|
||||||
if !ok {
|
if !ok {
|
||||||
return p.errorf("unknown field name %q in %v", tok.value, st)
|
return p.errorf("unknown field name %q in %v", name, st)
|
||||||
}
|
}
|
||||||
|
|
||||||
dst := sv.Field(fi)
|
dst := sv.Field(fi)
|
||||||
isDstNil := isNil(dst)
|
|
||||||
|
if dst.Kind() == reflect.Map {
|
||||||
|
// Consume any colon.
|
||||||
|
if err := p.checkForColon(props, dst.Type()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct the map if it doesn't already exist.
|
||||||
|
if dst.IsNil() {
|
||||||
|
dst.Set(reflect.MakeMap(dst.Type()))
|
||||||
|
}
|
||||||
|
key := reflect.New(dst.Type().Key()).Elem()
|
||||||
|
val := reflect.New(dst.Type().Elem()).Elem()
|
||||||
|
|
||||||
|
// The map entry should be this sequence of tokens:
|
||||||
|
// < key : KEY value : VALUE >
|
||||||
|
// Technically the "key" and "value" could come in any order,
|
||||||
|
// but in practice they won't.
|
||||||
|
|
||||||
|
tok := p.next()
|
||||||
|
var terminator string
|
||||||
|
switch tok.value {
|
||||||
|
case "<":
|
||||||
|
terminator = ">"
|
||||||
|
case "{":
|
||||||
|
terminator = "}"
|
||||||
|
default:
|
||||||
|
return p.errorf("expected '{' or '<', found %q", tok.value)
|
||||||
|
}
|
||||||
|
if err := p.consumeToken("key"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := p.consumeToken(":"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := p.readAny(key, props.mkeyprop); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := p.consumeToken("value"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := p.readAny(val, props.mvalprop); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := p.consumeToken(terminator); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
dst.SetMapIndex(key, val)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
// Check that it's not already set if it's not a repeated field.
|
// Check that it's not already set if it's not a repeated field.
|
||||||
if !props.Repeated && !isDstNil {
|
if !props.Repeated && fieldSet[name] {
|
||||||
return p.errorf("non-repeated field %q was repeated", tok.value)
|
return p.errorf("non-repeated field %q was repeated", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := p.checkForColon(props, st.Field(fi).Type); err != nil {
|
if err := p.checkForColon(props, st.Field(fi).Type); err != nil {
|
||||||
|
@ -525,11 +594,13 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) *ParseError
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse into the field.
|
// Parse into the field.
|
||||||
|
fieldSet[name] = true
|
||||||
if err := p.readAny(dst, props); err != nil {
|
if err := p.readAny(dst, props); err != nil {
|
||||||
return err
|
if _, ok := err.(*RequiredNotSetError); !ok {
|
||||||
}
|
return err
|
||||||
|
}
|
||||||
if props.Required {
|
reqFieldErr = err
|
||||||
|
} else if props.Required {
|
||||||
reqCount--
|
reqCount--
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -547,10 +618,10 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) *ParseError
|
||||||
if reqCount > 0 {
|
if reqCount > 0 {
|
||||||
return p.missingRequiredFieldError(sv)
|
return p.missingRequiredFieldError(sv)
|
||||||
}
|
}
|
||||||
return nil
|
return reqFieldErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *textParser) readAny(v reflect.Value, props *Properties) *ParseError {
|
func (p *textParser) readAny(v reflect.Value, props *Properties) error {
|
||||||
tok := p.next()
|
tok := p.next()
|
||||||
if tok.err != nil {
|
if tok.err != nil {
|
||||||
return tok.err
|
return tok.err
|
||||||
|
@ -652,7 +723,7 @@ func (p *textParser) readAny(v reflect.Value, props *Properties) *ParseError {
|
||||||
default:
|
default:
|
||||||
return p.errorf("expected '{' or '<', found %q", tok.value)
|
return p.errorf("expected '{' or '<', found %q", tok.value)
|
||||||
}
|
}
|
||||||
// TODO: Handle nested messages which implement textUnmarshaler.
|
// TODO: Handle nested messages which implement encoding.TextUnmarshaler.
|
||||||
return p.readStruct(fv, terminator)
|
return p.readStruct(fv, terminator)
|
||||||
case reflect.Uint32:
|
case reflect.Uint32:
|
||||||
if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil {
|
if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil {
|
||||||
|
@ -670,8 +741,10 @@ func (p *textParser) readAny(v reflect.Value, props *Properties) *ParseError {
|
||||||
|
|
||||||
// UnmarshalText reads a protocol buffer in Text format. UnmarshalText resets pb
|
// UnmarshalText reads a protocol buffer in Text format. UnmarshalText resets pb
|
||||||
// before starting to unmarshal, so any existing data in pb is always removed.
|
// before starting to unmarshal, so any existing data in pb is always removed.
|
||||||
|
// If a required field is not set and no other error occurs,
|
||||||
|
// UnmarshalText returns *RequiredNotSetError.
|
||||||
func UnmarshalText(s string, pb Message) error {
|
func UnmarshalText(s string, pb Message) error {
|
||||||
if um, ok := pb.(textUnmarshaler); ok {
|
if um, ok := pb.(encoding.TextUnmarshaler); ok {
|
||||||
err := um.UnmarshalText([]byte(s))
|
err := um.UnmarshalText([]byte(s))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
// Go support for Protocol Buffers - Google's data interchange format
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
//
|
//
|
||||||
// Copyright 2010 The Go Authors. All rights reserved.
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
// http://code.google.com/p/goprotobuf/
|
// https://github.com/golang/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
@ -36,8 +36,9 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
proto3pb "./proto3_proto"
|
||||||
. "./testdata"
|
. "./testdata"
|
||||||
. "code.google.com/p/goprotobuf/proto"
|
. "github.com/golang/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UnmarshalTextTest struct {
|
type UnmarshalTextTest struct {
|
||||||
|
@ -294,8 +295,11 @@ var unMarshalTextTests = []UnmarshalTextTest{
|
||||||
|
|
||||||
// Missing required field
|
// Missing required field
|
||||||
{
|
{
|
||||||
in: ``,
|
in: `name: "Pawel"`,
|
||||||
err: `line 1.0: message testdata.MyMessage missing required field "count"`,
|
err: `proto: required field "testdata.MyMessage.count" not set`,
|
||||||
|
out: &MyMessage{
|
||||||
|
Name: String("Pawel"),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
// Repeated non-repeated field
|
// Repeated non-repeated field
|
||||||
|
@ -408,6 +412,9 @@ func TestUnmarshalText(t *testing.T) {
|
||||||
} else if err.Error() != test.err {
|
} else if err.Error() != test.err {
|
||||||
t.Errorf("Test %d: Incorrect error.\nHave: %v\nWant: %v",
|
t.Errorf("Test %d: Incorrect error.\nHave: %v\nWant: %v",
|
||||||
i, err.Error(), test.err)
|
i, err.Error(), test.err)
|
||||||
|
} else if _, ok := err.(*RequiredNotSetError); ok && test.out != nil && !reflect.DeepEqual(pb, test.out) {
|
||||||
|
t.Errorf("Test %d: Incorrect populated \nHave: %v\nWant: %v",
|
||||||
|
i, pb, test.out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -437,6 +444,48 @@ func TestRepeatedEnum(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestProto3TextParsing(t *testing.T) {
|
||||||
|
m := new(proto3pb.Message)
|
||||||
|
const in = `name: "Wallace" true_scotsman: true`
|
||||||
|
want := &proto3pb.Message{
|
||||||
|
Name: "Wallace",
|
||||||
|
TrueScotsman: true,
|
||||||
|
}
|
||||||
|
if err := UnmarshalText(in, m); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !Equal(m, want) {
|
||||||
|
t.Errorf("\n got %v\nwant %v", m, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMapParsing(t *testing.T) {
|
||||||
|
m := new(MessageWithMap)
|
||||||
|
const in = `name_mapping:<key:1234 value:"Feist"> name_mapping:<key:1 value:"Beatles">` +
|
||||||
|
`msg_mapping:<key:-4 value:<f: 2.0>>` +
|
||||||
|
`msg_mapping<key:-2 value<f: 4.0>>` + // no colon after "value"
|
||||||
|
`byte_mapping:<key:true value:"so be it">`
|
||||||
|
want := &MessageWithMap{
|
||||||
|
NameMapping: map[int32]string{
|
||||||
|
1: "Beatles",
|
||||||
|
1234: "Feist",
|
||||||
|
},
|
||||||
|
MsgMapping: map[int64]*FloatingPoint{
|
||||||
|
-4: {F: Float64(2.0)},
|
||||||
|
-2: {F: Float64(4.0)},
|
||||||
|
},
|
||||||
|
ByteMapping: map[bool][]byte{
|
||||||
|
true: []byte("so be it"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if err := UnmarshalText(in, m); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !Equal(m, want) {
|
||||||
|
t.Errorf("\n got %v\nwant %v", m, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var benchInput string
|
var benchInput string
|
||||||
|
|
||||||
func init() {
|
func init() {
|
|
@ -1,7 +1,7 @@
|
||||||
// Go support for Protocol Buffers - Google's data interchange format
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
//
|
//
|
||||||
// Copyright 2010 The Go Authors. All rights reserved.
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
// http://code.google.com/p/goprotobuf/
|
// https://github.com/golang/protobuf
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
@ -39,8 +39,9 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.google.com/p/goprotobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
|
|
||||||
|
proto3pb "./proto3_proto"
|
||||||
pb "./testdata"
|
pb "./testdata"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -406,3 +407,30 @@ Message <nil>
|
||||||
t.Errorf(" got: %s\nwant: %s", s, want)
|
t.Errorf(" got: %s\nwant: %s", s, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestProto3Text(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
m proto.Message
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
// zero message
|
||||||
|
{&proto3pb.Message{}, ``},
|
||||||
|
// zero message except for an empty byte slice
|
||||||
|
{&proto3pb.Message{Data: []byte{}}, ``},
|
||||||
|
// trivial case
|
||||||
|
{&proto3pb.Message{Name: "Rob", HeightInCm: 175}, `name:"Rob" height_in_cm:175`},
|
||||||
|
// empty map
|
||||||
|
{&pb.MessageWithMap{}, ``},
|
||||||
|
// non-empty map; current map format is the same as a repeated struct
|
||||||
|
{
|
||||||
|
&pb.MessageWithMap{NameMapping: map[int32]string{1234: "Feist"}},
|
||||||
|
`name_mapping:<key:1234 value:"Feist" >`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, test := range tests {
|
||||||
|
got := strings.TrimSpace(test.m.String())
|
||||||
|
if got != test.want {
|
||||||
|
t.Errorf("\n got %s\nwant %s", got, test.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue