Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
go-libp2p
Commits
8f79df77
Commit
8f79df77
authored
Nov 15, 2015
by
Jeromy
Browse files
vendor in gogo protobuf
parent
f3d96ac5
Changes
152
Hide whitespace changes
Inline
Side-by-side
Too many changes to show.
To preserve performance only
152 of 152+
files are displayed.
Plain diff
Email patch
vendor/QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto/all_test.go
0 → 100644
View file @
8f79df77
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2010 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
(
"bytes"
"encoding/json"
"errors"
"fmt"
"math"
"math/rand"
"reflect"
"runtime/debug"
"strings"
"testing"
"time"
.
"QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto"
.
"QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto/testdata"
)
var
globalO
*
Buffer
func
old
()
*
Buffer
{
if
globalO
==
nil
{
globalO
=
NewBuffer
(
nil
)
}
globalO
.
Reset
()
return
globalO
}
func
equalbytes
(
b1
,
b2
[]
byte
,
t
*
testing
.
T
)
{
if
len
(
b1
)
!=
len
(
b2
)
{
t
.
Errorf
(
"wrong lengths: 2*%d != %d"
,
len
(
b1
),
len
(
b2
))
return
}
for
i
:=
0
;
i
<
len
(
b1
);
i
++
{
if
b1
[
i
]
!=
b2
[
i
]
{
t
.
Errorf
(
"bad byte[%d]:%x %x: %s %s"
,
i
,
b1
[
i
],
b2
[
i
],
b1
,
b2
)
}
}
}
func
initGoTestField
()
*
GoTestField
{
f
:=
new
(
GoTestField
)
f
.
Label
=
String
(
"label"
)
f
.
Type
=
String
(
"type"
)
return
f
}
// These are all structurally equivalent but the tag numbers differ.
// (It's remarkable that required, optional, and repeated all have
// 8 letters.)
func
initGoTest_RequiredGroup
()
*
GoTest_RequiredGroup
{
return
&
GoTest_RequiredGroup
{
RequiredField
:
String
(
"required"
),
}
}
func
initGoTest_OptionalGroup
()
*
GoTest_OptionalGroup
{
return
&
GoTest_OptionalGroup
{
RequiredField
:
String
(
"optional"
),
}
}
func
initGoTest_RepeatedGroup
()
*
GoTest_RepeatedGroup
{
return
&
GoTest_RepeatedGroup
{
RequiredField
:
String
(
"repeated"
),
}
}
func
initGoTest
(
setdefaults
bool
)
*
GoTest
{
pb
:=
new
(
GoTest
)
if
setdefaults
{
pb
.
F_BoolDefaulted
=
Bool
(
Default_GoTest_F_BoolDefaulted
)
pb
.
F_Int32Defaulted
=
Int32
(
Default_GoTest_F_Int32Defaulted
)
pb
.
F_Int64Defaulted
=
Int64
(
Default_GoTest_F_Int64Defaulted
)
pb
.
F_Fixed32Defaulted
=
Uint32
(
Default_GoTest_F_Fixed32Defaulted
)
pb
.
F_Fixed64Defaulted
=
Uint64
(
Default_GoTest_F_Fixed64Defaulted
)
pb
.
F_Uint32Defaulted
=
Uint32
(
Default_GoTest_F_Uint32Defaulted
)
pb
.
F_Uint64Defaulted
=
Uint64
(
Default_GoTest_F_Uint64Defaulted
)
pb
.
F_FloatDefaulted
=
Float32
(
Default_GoTest_F_FloatDefaulted
)
pb
.
F_DoubleDefaulted
=
Float64
(
Default_GoTest_F_DoubleDefaulted
)
pb
.
F_StringDefaulted
=
String
(
Default_GoTest_F_StringDefaulted
)
pb
.
F_BytesDefaulted
=
Default_GoTest_F_BytesDefaulted
pb
.
F_Sint32Defaulted
=
Int32
(
Default_GoTest_F_Sint32Defaulted
)
pb
.
F_Sint64Defaulted
=
Int64
(
Default_GoTest_F_Sint64Defaulted
)
}
pb
.
Kind
=
GoTest_TIME
.
Enum
()
pb
.
RequiredField
=
initGoTestField
()
pb
.
F_BoolRequired
=
Bool
(
true
)
pb
.
F_Int32Required
=
Int32
(
3
)
pb
.
F_Int64Required
=
Int64
(
6
)
pb
.
F_Fixed32Required
=
Uint32
(
32
)
pb
.
F_Fixed64Required
=
Uint64
(
64
)
pb
.
F_Uint32Required
=
Uint32
(
3232
)
pb
.
F_Uint64Required
=
Uint64
(
6464
)
pb
.
F_FloatRequired
=
Float32
(
3232
)
pb
.
F_DoubleRequired
=
Float64
(
6464
)
pb
.
F_StringRequired
=
String
(
"string"
)
pb
.
F_BytesRequired
=
[]
byte
(
"bytes"
)
pb
.
F_Sint32Required
=
Int32
(
-
32
)
pb
.
F_Sint64Required
=
Int64
(
-
64
)
pb
.
Requiredgroup
=
initGoTest_RequiredGroup
()
return
pb
}
func
fail
(
msg
string
,
b
*
bytes
.
Buffer
,
s
string
,
t
*
testing
.
T
)
{
data
:=
b
.
Bytes
()
ld
:=
len
(
data
)
ls
:=
len
(
s
)
/
2
fmt
.
Printf
(
"fail %s ld=%d ls=%d
\n
"
,
msg
,
ld
,
ls
)
// find the interesting spot - n
n
:=
ls
if
ld
<
ls
{
n
=
ld
}
j
:=
0
for
i
:=
0
;
i
<
n
;
i
++
{
bs
:=
hex
(
s
[
j
])
*
16
+
hex
(
s
[
j
+
1
])
j
+=
2
if
data
[
i
]
==
bs
{
continue
}
n
=
i
break
}
l
:=
n
-
10
if
l
<
0
{
l
=
0
}
h
:=
n
+
10
// find the interesting spot - n
fmt
.
Printf
(
"is[%d]:"
,
l
)
for
i
:=
l
;
i
<
h
;
i
++
{
if
i
>=
ld
{
fmt
.
Printf
(
" --"
)
continue
}
fmt
.
Printf
(
" %.2x"
,
data
[
i
])
}
fmt
.
Printf
(
"
\n
"
)
fmt
.
Printf
(
"sb[%d]:"
,
l
)
for
i
:=
l
;
i
<
h
;
i
++
{
if
i
>=
ls
{
fmt
.
Printf
(
" --"
)
continue
}
bs
:=
hex
(
s
[
j
])
*
16
+
hex
(
s
[
j
+
1
])
j
+=
2
fmt
.
Printf
(
" %.2x"
,
bs
)
}
fmt
.
Printf
(
"
\n
"
)
t
.
Fail
()
// t.Errorf("%s: \ngood: %s\nbad: %x", msg, s, b.Bytes())
// Print the output in a partially-decoded format; can
// be helpful when updating the test. It produces the output
// that is pasted, with minor edits, into the argument to verify().
// data := b.Bytes()
// nesting := 0
// for b.Len() > 0 {
// start := len(data) - b.Len()
// var u uint64
// u, err := DecodeVarint(b)
// if err != nil {
// fmt.Printf("decode error on varint:", err)
// return
// }
// wire := u & 0x7
// tag := u >> 3
// switch wire {
// case WireVarint:
// v, err := DecodeVarint(b)
// if err != nil {
// fmt.Printf("decode error on varint:", err)
// return
// }
// fmt.Printf("\t\t\"%x\" // field %d, encoding %d, value %d\n",
// data[start:len(data)-b.Len()], tag, wire, v)
// case WireFixed32:
// v, err := DecodeFixed32(b)
// if err != nil {
// fmt.Printf("decode error on fixed32:", err)
// return
// }
// fmt.Printf("\t\t\"%x\" // field %d, encoding %d, value %d\n",
// data[start:len(data)-b.Len()], tag, wire, v)
// case WireFixed64:
// v, err := DecodeFixed64(b)
// if err != nil {
// fmt.Printf("decode error on fixed64:", err)
// return
// }
// fmt.Printf("\t\t\"%x\" // field %d, encoding %d, value %d\n",
// data[start:len(data)-b.Len()], tag, wire, v)
// case WireBytes:
// nb, err := DecodeVarint(b)
// if err != nil {
// fmt.Printf("decode error on bytes:", err)
// return
// }
// after_tag := len(data) - b.Len()
// str := make([]byte, nb)
// _, err = b.Read(str)
// if err != nil {
// fmt.Printf("decode error on bytes:", err)
// return
// }
// fmt.Printf("\t\t\"%x\" \"%x\" // field %d, encoding %d (FIELD)\n",
// data[start:after_tag], str, tag, wire)
// case WireStartGroup:
// nesting++
// fmt.Printf("\t\t\"%x\"\t\t// start group field %d level %d\n",
// data[start:len(data)-b.Len()], tag, nesting)
// case WireEndGroup:
// fmt.Printf("\t\t\"%x\"\t\t// end group field %d level %d\n",
// data[start:len(data)-b.Len()], tag, nesting)
// nesting--
// default:
// fmt.Printf("unrecognized wire type %d\n", wire)
// return
// }
// }
}
func
hex
(
c
uint8
)
uint8
{
if
'0'
<=
c
&&
c
<=
'9'
{
return
c
-
'0'
}
if
'a'
<=
c
&&
c
<=
'f'
{
return
10
+
c
-
'a'
}
if
'A'
<=
c
&&
c
<=
'F'
{
return
10
+
c
-
'A'
}
return
0
}
func
equal
(
b
[]
byte
,
s
string
,
t
*
testing
.
T
)
bool
{
if
2
*
len
(
b
)
!=
len
(
s
)
{
// fail(fmt.Sprintf("wrong lengths: 2*%d != %d", len(b), len(s)), b, s, t)
fmt
.
Printf
(
"wrong lengths: 2*%d != %d
\n
"
,
len
(
b
),
len
(
s
))
return
false
}
for
i
,
j
:=
0
,
0
;
i
<
len
(
b
);
i
,
j
=
i
+
1
,
j
+
2
{
x
:=
hex
(
s
[
j
])
*
16
+
hex
(
s
[
j
+
1
])
if
b
[
i
]
!=
x
{
// fail(fmt.Sprintf("bad byte[%d]:%x %x", i, b[i], x), b, s, t)
fmt
.
Printf
(
"bad byte[%d]:%x %x"
,
i
,
b
[
i
],
x
)
return
false
}
}
return
true
}
func
overify
(
t
*
testing
.
T
,
pb
*
GoTest
,
expected
string
)
{
o
:=
old
()
err
:=
o
.
Marshal
(
pb
)
if
err
!=
nil
{
fmt
.
Printf
(
"overify marshal-1 err = %v"
,
err
)
o
.
DebugPrint
(
""
,
o
.
Bytes
())
t
.
Fatalf
(
"expected = %s"
,
expected
)
}
if
!
equal
(
o
.
Bytes
(),
expected
,
t
)
{
o
.
DebugPrint
(
"overify neq 1"
,
o
.
Bytes
())
t
.
Fatalf
(
"expected = %s"
,
expected
)
}
// Now test Unmarshal by recreating the original buffer.
pbd
:=
new
(
GoTest
)
err
=
o
.
Unmarshal
(
pbd
)
if
err
!=
nil
{
t
.
Fatalf
(
"overify unmarshal err = %v"
,
err
)
o
.
DebugPrint
(
""
,
o
.
Bytes
())
t
.
Fatalf
(
"string = %s"
,
expected
)
}
o
.
Reset
()
err
=
o
.
Marshal
(
pbd
)
if
err
!=
nil
{
t
.
Errorf
(
"overify marshal-2 err = %v"
,
err
)
o
.
DebugPrint
(
""
,
o
.
Bytes
())
t
.
Fatalf
(
"string = %s"
,
expected
)
}
if
!
equal
(
o
.
Bytes
(),
expected
,
t
)
{
o
.
DebugPrint
(
"overify neq 2"
,
o
.
Bytes
())
t
.
Fatalf
(
"string = %s"
,
expected
)
}
}
// Simple tests for numeric encode/decode primitives (varint, etc.)
func
TestNumericPrimitives
(
t
*
testing
.
T
)
{
for
i
:=
uint64
(
0
);
i
<
1e6
;
i
+=
111
{
o
:=
old
()
if
o
.
EncodeVarint
(
i
)
!=
nil
{
t
.
Error
(
"EncodeVarint"
)
break
}
x
,
e
:=
o
.
DecodeVarint
()
if
e
!=
nil
{
t
.
Fatal
(
"DecodeVarint"
)
}
if
x
!=
i
{
t
.
Fatal
(
"varint decode fail:"
,
i
,
x
)
}
o
=
old
()
if
o
.
EncodeFixed32
(
i
)
!=
nil
{
t
.
Fatal
(
"encFixed32"
)
}
x
,
e
=
o
.
DecodeFixed32
()
if
e
!=
nil
{
t
.
Fatal
(
"decFixed32"
)
}
if
x
!=
i
{
t
.
Fatal
(
"fixed32 decode fail:"
,
i
,
x
)
}
o
=
old
()
if
o
.
EncodeFixed64
(
i
*
1234567
)
!=
nil
{
t
.
Error
(
"encFixed64"
)
break
}
x
,
e
=
o
.
DecodeFixed64
()
if
e
!=
nil
{
t
.
Error
(
"decFixed64"
)
break
}
if
x
!=
i
*
1234567
{
t
.
Error
(
"fixed64 decode fail:"
,
i
*
1234567
,
x
)
break
}
o
=
old
()
i32
:=
int32
(
i
-
12345
)
if
o
.
EncodeZigzag32
(
uint64
(
i32
))
!=
nil
{
t
.
Fatal
(
"EncodeZigzag32"
)
}
x
,
e
=
o
.
DecodeZigzag32
()
if
e
!=
nil
{
t
.
Fatal
(
"DecodeZigzag32"
)
}
if
x
!=
uint64
(
uint32
(
i32
))
{
t
.
Fatal
(
"zigzag32 decode fail:"
,
i32
,
x
)
}
o
=
old
()
i64
:=
int64
(
i
-
12345
)
if
o
.
EncodeZigzag64
(
uint64
(
i64
))
!=
nil
{
t
.
Fatal
(
"EncodeZigzag64"
)
}
x
,
e
=
o
.
DecodeZigzag64
()
if
e
!=
nil
{
t
.
Fatal
(
"DecodeZigzag64"
)
}
if
x
!=
uint64
(
i64
)
{
t
.
Fatal
(
"zigzag64 decode fail:"
,
i64
,
x
)
}
}
}
// fakeMarshaler is a simple struct implementing Marshaler and Message interfaces.
type
fakeMarshaler
struct
{
b
[]
byte
err
error
}
func
(
f
*
fakeMarshaler
)
Marshal
()
([]
byte
,
error
)
{
return
f
.
b
,
f
.
err
}
func
(
f
*
fakeMarshaler
)
String
()
string
{
return
fmt
.
Sprintf
(
"Bytes: %v Error: %v"
,
f
.
b
,
f
.
err
)
}
func
(
f
*
fakeMarshaler
)
ProtoMessage
()
{}
func
(
f
*
fakeMarshaler
)
Reset
()
{}
type
msgWithFakeMarshaler
struct
{
M
*
fakeMarshaler
`protobuf:"bytes,1,opt,name=fake"`
}
func
(
m
*
msgWithFakeMarshaler
)
String
()
string
{
return
CompactTextString
(
m
)
}
func
(
m
*
msgWithFakeMarshaler
)
ProtoMessage
()
{}
func
(
m
*
msgWithFakeMarshaler
)
Reset
()
{}
// Simple tests for proto messages that implement the Marshaler interface.
func
TestMarshalerEncoding
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
name
string
m
Message
want
[]
byte
wantErr
error
}{
{
name
:
"Marshaler that fails"
,
m
:
&
fakeMarshaler
{
err
:
errors
.
New
(
"some marshal err"
),
b
:
[]
byte
{
5
,
6
,
7
},
},
// Since there's an error, nothing should be written to buffer.
want
:
nil
,
wantErr
:
errors
.
New
(
"some marshal err"
),
},
{
name
:
"Marshaler that fails with RequiredNotSetError"
,
m
:
&
msgWithFakeMarshaler
{
M
:
&
fakeMarshaler
{
err
:
&
RequiredNotSetError
{},
b
:
[]
byte
{
5
,
6
,
7
},
},
},
// Since there's an error that can be continued after,
// the buffer should be written.
want
:
[]
byte
{
10
,
3
,
// for &msgWithFakeMarshaler
5
,
6
,
7
,
// for &fakeMarshaler
},
wantErr
:
&
RequiredNotSetError
{},
},
{
name
:
"Marshaler that succeeds"
,
m
:
&
fakeMarshaler
{
b
:
[]
byte
{
0
,
1
,
2
,
3
,
4
,
127
,
255
},
},
want
:
[]
byte
{
0
,
1
,
2
,
3
,
4
,
127
,
255
},
wantErr
:
nil
,
},
}
for
_
,
test
:=
range
tests
{
b
:=
NewBuffer
(
nil
)
err
:=
b
.
Marshal
(
test
.
m
)
if
_
,
ok
:=
err
.
(
*
RequiredNotSetError
);
ok
{
// We're not in package proto, so we can only assert the type in this case.
err
=
&
RequiredNotSetError
{}
}
if
!
reflect
.
DeepEqual
(
test
.
wantErr
,
err
)
{
t
.
Errorf
(
"%s: got err %v wanted %v"
,
test
.
name
,
err
,
test
.
wantErr
)
}
if
!
reflect
.
DeepEqual
(
test
.
want
,
b
.
Bytes
())
{
t
.
Errorf
(
"%s: got bytes %v wanted %v"
,
test
.
name
,
b
.
Bytes
(),
test
.
want
)
}
}
}
// Simple tests for bytes
func
TestBytesPrimitives
(
t
*
testing
.
T
)
{
o
:=
old
()
bytes
:=
[]
byte
{
'n'
,
'o'
,
'w'
,
' '
,
'i'
,
's'
,
' '
,
't'
,
'h'
,
'e'
,
' '
,
't'
,
'i'
,
'm'
,
'e'
}
if
o
.
EncodeRawBytes
(
bytes
)
!=
nil
{
t
.
Error
(
"EncodeRawBytes"
)
}
decb
,
e
:=
o
.
DecodeRawBytes
(
false
)
if
e
!=
nil
{
t
.
Error
(
"DecodeRawBytes"
)
}
equalbytes
(
bytes
,
decb
,
t
)
}
// Simple tests for strings
func
TestStringPrimitives
(
t
*
testing
.
T
)
{
o
:=
old
()
s
:=
"now is the time"
if
o
.
EncodeStringBytes
(
s
)
!=
nil
{
t
.
Error
(
"enc_string"
)
}
decs
,
e
:=
o
.
DecodeStringBytes
()
if
e
!=
nil
{
t
.
Error
(
"dec_string"
)
}
if
s
!=
decs
{
t
.
Error
(
"string encode/decode fail:"
,
s
,
decs
)
}
}
// Do we catch the "required bit not set" case?
func
TestRequiredBit
(
t
*
testing
.
T
)
{
o
:=
old
()
pb
:=
new
(
GoTest
)
err
:=
o
.
Marshal
(
pb
)
if
err
==
nil
{
t
.
Error
(
"did not catch missing required fields"
)
}
else
if
strings
.
Index
(
err
.
Error
(),
"Kind"
)
<
0
{
t
.
Error
(
"wrong error type:"
,
err
)
}
}
// Check that all fields are nil.
// Clearly silly, and a residue from a more interesting test with an earlier,
// different initialization property, but it once caught a compiler bug so
// it lives.
func
checkInitialized
(
pb
*
GoTest
,
t
*
testing
.
T
)
{
if
pb
.
F_BoolDefaulted
!=
nil
{
t
.
Error
(
"New or Reset did not set boolean:"
,
*
pb
.
F_BoolDefaulted
)
}
if
pb
.
F_Int32Defaulted
!=
nil
{
t
.
Error
(
"New or Reset did not set int32:"
,
*
pb
.
F_Int32Defaulted
)
}
if
pb
.
F_Int64Defaulted
!=
nil
{
t
.
Error
(
"New or Reset did not set int64:"
,
*
pb
.
F_Int64Defaulted
)
}
if
pb
.
F_Fixed32Defaulted
!=
nil
{
t
.
Error
(
"New or Reset did not set fixed32:"
,
*
pb
.
F_Fixed32Defaulted
)
}
if
pb
.
F_Fixed64Defaulted
!=
nil
{
t
.
Error
(
"New or Reset did not set fixed64:"
,
*
pb
.
F_Fixed64Defaulted
)
}
if
pb
.
F_Uint32Defaulted
!=
nil
{
t
.
Error
(
"New or Reset did not set uint32:"
,
*
pb
.
F_Uint32Defaulted
)
}
if
pb
.
F_Uint64Defaulted
!=
nil
{
t
.
Error
(
"New or Reset did not set uint64:"
,
*
pb
.
F_Uint64Defaulted
)
}
if
pb
.
F_FloatDefaulted
!=
nil
{
t
.
Error
(
"New or Reset did not set float:"
,
*
pb
.
F_FloatDefaulted
)
}
if
pb
.
F_DoubleDefaulted
!=
nil
{
t
.
Error
(
"New or Reset did not set double:"
,
*
pb
.
F_DoubleDefaulted
)
}
if
pb
.
F_StringDefaulted
!=
nil
{
t
.
Error
(
"New or Reset did not set string:"
,
*
pb
.
F_StringDefaulted
)
}
if
pb
.
F_BytesDefaulted
!=
nil
{
t
.
Error
(
"New or Reset did not set bytes:"
,
string
(
pb
.
F_BytesDefaulted
))
}
if
pb
.
F_Sint32Defaulted
!=
nil
{
t
.
Error
(
"New or Reset did not set int32:"
,
*
pb
.
F_Sint32Defaulted
)
}
if
pb
.
F_Sint64Defaulted
!=
nil
{
t
.
Error
(
"New or Reset did not set int64:"
,
*
pb
.
F_Sint64Defaulted
)
}
}
// Does Reset() reset?
func
TestReset
(
t
*
testing
.
T
)
{
pb
:=
initGoTest
(
true
)
// muck with some values
pb
.
F_BoolDefaulted
=
Bool
(
false
)
pb
.
F_Int32Defaulted
=
Int32
(
237
)
pb
.
F_Int64Defaulted
=
Int64
(
12346
)
pb
.
F_Fixed32Defaulted
=
Uint32
(
32000
)
pb
.
F_Fixed64Defaulted
=
Uint64
(
666
)
pb
.
F_Uint32Defaulted
=
Uint32
(
323232
)
pb
.
F_Uint64Defaulted
=
nil
pb
.
F_FloatDefaulted
=
nil
pb
.
F_DoubleDefaulted
=
Float64
(
0
)
pb
.
F_StringDefaulted
=
String
(
"gotcha"
)
pb
.
F_BytesDefaulted
=
[]
byte
(
"asdfasdf"
)
pb
.
F_Sint32Defaulted
=
Int32
(
123
)
pb
.
F_Sint64Defaulted
=
Int64
(
789
)
pb
.
Reset
()
checkInitialized
(
pb
,
t
)
}
// All required fields set, no defaults provided.
func
TestEncodeDecode1
(
t
*
testing
.
T
)
{
pb
:=
initGoTest
(
false
)
overify
(
t
,
pb
,
"0807"
+
// field 1, encoding 0, value 7
"220d"
+
"0a056c6162656c120474797065"
+
// field 4, encoding 2 (GoTestField)
"5001"
+
// field 10, encoding 0, value 1
"5803"
+
// field 11, encoding 0, value 3
"6006"
+
// field 12, encoding 0, value 6
"6d20000000"
+
// field 13, encoding 5, value 0x20
"714000000000000000"
+
// field 14, encoding 1, value 0x40
"78a019"
+
// field 15, encoding 0, value 0xca0 = 3232
"8001c032"
+
// field 16, encoding 0, value 0x1940 = 6464
"8d0100004a45"
+
// field 17, encoding 5, value 3232.0
"9101000000000040b940"
+
// field 18, encoding 1, value 6464.0
"9a0106"
+
"737472696e67"
+
// field 19, encoding 2, string "string"
"b304"
+
// field 70, encoding 3, start group
"ba0408"
+
"7265717569726564"
+
// field 71, encoding 2, string "required"
"b404"
+
// field 70, encoding 4, end group
"aa0605"
+
"6279746573"
+
// field 101, encoding 2, string "bytes"
"b0063f"
+
// field 102, encoding 0, 0x3f zigzag32
"b8067f"
)
// field 103, encoding 0, 0x7f zigzag64
}
// All required fields set, defaults provided.
func
TestEncodeDecode2
(
t
*
testing
.
T
)
{
pb
:=
initGoTest
(
true
)
overify
(
t
,
pb
,
"0807"
+
// field 1, encoding 0, value 7
"220d"
+
"0a056c6162656c120474797065"
+
// field 4, encoding 2 (GoTestField)
"5001"
+
// field 10, encoding 0, value 1
"5803"
+
// field 11, encoding 0, value 3
"6006"
+
// field 12, encoding 0, value 6
"6d20000000"
+
// field 13, encoding 5, value 32
"714000000000000000"
+
// field 14, encoding 1, value 64
"78a019"
+
// field 15, encoding 0, value 3232
"8001c032"
+
// field 16, encoding 0, value 6464
"8d0100004a45"
+
// field 17, encoding 5, value 3232.0
"9101000000000040b940"
+
// field 18, encoding 1, value 6464.0
"9a0106"
+
"737472696e67"
+
// field 19, encoding 2 string "string"
"c00201"
+
// field 40, encoding 0, value 1
"c80220"
+
// field 41, encoding 0, value 32
"d00240"
+
// field 42, encoding 0, value 64
"dd0240010000"
+
// field 43, encoding 5, value 320
"e1028002000000000000"
+
// field 44, encoding 1, value 640
"e8028019"
+
// field 45, encoding 0, value 3200
"f0028032"
+
// field 46, encoding 0, value 6400
"fd02e0659948"
+
// field 47, encoding 5, value 314159.0
"81030000000050971041"
+
// field 48, encoding 1, value 271828.0
"8a0310"
+
"68656c6c6f2c2022776f726c6421220a"
+
// field 49, encoding 2 string "hello, \"world!\"\n"
"b304"
+
// start group field 70 level 1
"ba0408"
+
"7265717569726564"
+
// field 71, encoding 2, string "required"
"b404"
+
// end group field 70 level 1
"aa0605"
+
"6279746573"
+
// field 101, encoding 2 string "bytes"
"b0063f"
+
// field 102, encoding 0, 0x3f zigzag32
"b8067f"
+
// field 103, encoding 0, 0x7f zigzag64
"8a1907"
+
"4269676e6f7365"
+
// field 401, encoding 2, string "Bignose"
"90193f"
+
// field 402, encoding 0, value 63
"98197f"
)
// field 403, encoding 0, value 127
}
// All default fields set to their default value by hand
func
TestEncodeDecode3
(
t
*
testing
.
T
)
{
pb
:=
initGoTest
(
false
)
pb
.
F_BoolDefaulted
=
Bool
(
true
)
pb
.
F_Int32Defaulted
=
Int32
(
32
)
pb
.
F_Int64Defaulted
=
Int64
(
64
)
pb
.
F_Fixed32Defaulted
=
Uint32
(
320
)
pb
.
F_Fixed64Defaulted
=
Uint64
(
640
)
pb
.
F_Uint32Defaulted
=
Uint32
(
3200
)
pb
.
F_Uint64Defaulted
=
Uint64
(
6400
)
pb
.
F_FloatDefaulted
=
Float32
(
314159
)
pb
.
F_DoubleDefaulted
=
Float64
(
271828
)
pb
.
F_StringDefaulted
=
String
(
"hello,
\"
world!
\"\n
"
)
pb
.
F_BytesDefaulted
=
[]
byte
(
"Bignose"
)
pb
.
F_Sint32Defaulted
=
Int32
(
-
32
)
pb
.
F_Sint64Defaulted
=
Int64
(
-
64
)
overify
(
t
,
pb
,
"0807"
+
// field 1, encoding 0, value 7
"220d"
+
"0a056c6162656c120474797065"
+
// field 4, encoding 2 (GoTestField)
"5001"
+
// field 10, encoding 0, value 1
"5803"
+
// field 11, encoding 0, value 3
"6006"
+
// field 12, encoding 0, value 6
"6d20000000"
+
// field 13, encoding 5, value 32
"714000000000000000"
+
// field 14, encoding 1, value 64
"78a019"
+
// field 15, encoding 0, value 3232
"8001c032"
+
// field 16, encoding 0, value 6464
"8d0100004a45"
+
// field 17, encoding 5, value 3232.0
"9101000000000040b940"
+
// field 18, encoding 1, value 6464.0
"9a0106"
+
"737472696e67"
+
// field 19, encoding 2 string "string"
"c00201"
+
// field 40, encoding 0, value 1
"c80220"
+
// field 41, encoding 0, value 32
"d00240"
+
// field 42, encoding 0, value 64
"dd0240010000"
+
// field 43, encoding 5, value 320
"e1028002000000000000"
+
// field 44, encoding 1, value 640
"e8028019"
+
// field 45, encoding 0, value 3200
"f0028032"
+
// field 46, encoding 0, value 6400
"fd02e0659948"
+
// field 47, encoding 5, value 314159.0
"81030000000050971041"
+
// field 48, encoding 1, value 271828.0
"8a0310"
+
"68656c6c6f2c2022776f726c6421220a"
+
// field 49, encoding 2 string "hello, \"world!\"\n"
"b304"
+
// start group field 70 level 1
"ba0408"
+
"7265717569726564"
+
// field 71, encoding 2, string "required"
"b404"
+
// end group field 70 level 1
"aa0605"
+
"6279746573"
+
// field 101, encoding 2 string "bytes"
"b0063f"
+
// field 102, encoding 0, 0x3f zigzag32
"b8067f"
+
// field 103, encoding 0, 0x7f zigzag64
"8a1907"
+
"4269676e6f7365"
+
// field 401, encoding 2, string "Bignose"
"90193f"
+
// field 402, encoding 0, value 63
"98197f"
)
// field 403, encoding 0, value 127
}
// All required fields set, defaults provided, all non-defaulted optional fields have values.
func
TestEncodeDecode4
(
t
*
testing
.
T
)
{
pb
:=
initGoTest
(
true
)
pb
.
Table
=
String
(
"hello"
)
pb
.
Param
=
Int32
(
7
)
pb
.
OptionalField
=
initGoTestField
()
pb
.
F_BoolOptional
=
Bool
(
true
)
pb
.
F_Int32Optional
=
Int32
(
32
)
pb
.
F_Int64Optional
=
Int64
(
64
)
pb
.
F_Fixed32Optional
=
Uint32
(
3232
)
pb
.
F_Fixed64Optional
=
Uint64
(
6464
)
pb
.
F_Uint32Optional
=
Uint32
(
323232
)
pb
.
F_Uint64Optional
=
Uint64
(
646464
)
pb
.
F_FloatOptional
=
Float32
(
32.
)
pb
.
F_DoubleOptional
=
Float64
(
64.
)
pb
.
F_StringOptional
=
String
(
"hello"
)
pb
.
F_BytesOptional
=
[]
byte
(
"Bignose"
)
pb
.
F_Sint32Optional
=
Int32
(
-
32
)
pb
.
F_Sint64Optional
=
Int64
(
-
64
)
pb
.
Optionalgroup
=
initGoTest_OptionalGroup
()
overify
(
t
,
pb
,
"0807"
+
// field 1, encoding 0, value 7
"1205"
+
"68656c6c6f"
+
// field 2, encoding 2, string "hello"
"1807"
+
// field 3, encoding 0, value 7
"220d"
+
"0a056c6162656c120474797065"
+
// field 4, encoding 2 (GoTestField)
"320d"
+
"0a056c6162656c120474797065"
+
// field 6, encoding 2 (GoTestField)
"5001"
+
// field 10, encoding 0, value 1
"5803"
+
// field 11, encoding 0, value 3
"6006"
+
// field 12, encoding 0, value 6
"6d20000000"
+
// field 13, encoding 5, value 32
"714000000000000000"
+
// field 14, encoding 1, value 64
"78a019"
+
// field 15, encoding 0, value 3232
"8001c032"
+
// field 16, encoding 0, value 6464
"8d0100004a45"
+
// field 17, encoding 5, value 3232.0
"9101000000000040b940"
+
// field 18, encoding 1, value 6464.0
"9a0106"
+
"737472696e67"
+
// field 19, encoding 2 string "string"
"f00101"
+
// field 30, encoding 0, value 1
"f80120"
+
// field 31, encoding 0, value 32
"800240"
+
// field 32, encoding 0, value 64
"8d02a00c0000"
+
// field 33, encoding 5, value 3232
"91024019000000000000"
+
// field 34, encoding 1, value 6464
"9802a0dd13"
+
// field 35, encoding 0, value 323232
"a002c0ba27"
+
// field 36, encoding 0, value 646464
"ad0200000042"
+
// field 37, encoding 5, value 32.0
"b1020000000000005040"
+
// field 38, encoding 1, value 64.0
"ba0205"
+
"68656c6c6f"
+
// field 39, encoding 2, string "hello"
"c00201"
+
// field 40, encoding 0, value 1
"c80220"
+
// field 41, encoding 0, value 32
"d00240"
+
// field 42, encoding 0, value 64
"dd0240010000"
+
// field 43, encoding 5, value 320
"e1028002000000000000"
+
// field 44, encoding 1, value 640
"e8028019"
+
// field 45, encoding 0, value 3200
"f0028032"
+
// field 46, encoding 0, value 6400
"fd02e0659948"
+
// field 47, encoding 5, value 314159.0
"81030000000050971041"
+
// field 48, encoding 1, value 271828.0
"8a0310"
+
"68656c6c6f2c2022776f726c6421220a"
+
// field 49, encoding 2 string "hello, \"world!\"\n"
"b304"
+
// start group field 70 level 1
"ba0408"
+
"7265717569726564"
+
// field 71, encoding 2, string "required"
"b404"
+
// end group field 70 level 1
"d305"
+
// start group field 90 level 1
"da0508"
+
"6f7074696f6e616c"
+
// field 91, encoding 2, string "optional"
"d405"
+
// end group field 90 level 1
"aa0605"
+
"6279746573"
+
// field 101, encoding 2 string "bytes"
"b0063f"
+
// field 102, encoding 0, 0x3f zigzag32
"b8067f"
+
// field 103, encoding 0, 0x7f zigzag64
"ea1207"
+
"4269676e6f7365"
+
// field 301, encoding 2, string "Bignose"
"f0123f"
+
// field 302, encoding 0, value 63
"f8127f"
+
// field 303, encoding 0, value 127
"8a1907"
+
"4269676e6f7365"
+
// field 401, encoding 2, string "Bignose"
"90193f"
+
// field 402, encoding 0, value 63
"98197f"
)
// field 403, encoding 0, value 127
}
// All required fields set, defaults provided, all repeated fields given two values.
func
TestEncodeDecode5
(
t
*
testing
.
T
)
{
pb
:=
initGoTest
(
true
)
pb
.
RepeatedField
=
[]
*
GoTestField
{
initGoTestField
(),
initGoTestField
()}
pb
.
F_BoolRepeated
=
[]
bool
{
false
,
true
}
pb
.
F_Int32Repeated
=
[]
int32
{
32
,
33
}
pb
.
F_Int64Repeated
=
[]
int64
{
64
,
65
}
pb
.
F_Fixed32Repeated
=
[]
uint32
{
3232
,
3333
}
pb
.
F_Fixed64Repeated
=
[]
uint64
{
6464
,
6565
}
pb
.
F_Uint32Repeated
=
[]
uint32
{
323232
,
333333
}
pb
.
F_Uint64Repeated
=
[]
uint64
{
646464
,
656565
}
pb
.
F_FloatRepeated
=
[]
float32
{
32.
,
33.
}
pb
.
F_DoubleRepeated
=
[]
float64
{
64.
,
65.
}
pb
.
F_StringRepeated
=
[]
string
{
"hello"
,
"sailor"
}
pb
.
F_BytesRepeated
=
[][]
byte
{[]
byte
(
"big"
),
[]
byte
(
"nose"
)}
pb
.
F_Sint32Repeated
=
[]
int32
{
32
,
-
32
}
pb
.
F_Sint64Repeated
=
[]
int64
{
64
,
-
64
}
pb
.
Repeatedgroup
=
[]
*
GoTest_RepeatedGroup
{
initGoTest_RepeatedGroup
(),
initGoTest_RepeatedGroup
()}
overify
(
t
,
pb
,
"0807"
+
// field 1, encoding 0, value 7
"220d"
+
"0a056c6162656c120474797065"
+
// field 4, encoding 2 (GoTestField)
"2a0d"
+
"0a056c6162656c120474797065"
+
// field 5, encoding 2 (GoTestField)
"2a0d"
+
"0a056c6162656c120474797065"
+
// field 5, encoding 2 (GoTestField)
"5001"
+
// field 10, encoding 0, value 1
"5803"
+
// field 11, encoding 0, value 3
"6006"
+
// field 12, encoding 0, value 6
"6d20000000"
+
// field 13, encoding 5, value 32
"714000000000000000"
+
// field 14, encoding 1, value 64
"78a019"
+
// field 15, encoding 0, value 3232
"8001c032"
+
// field 16, encoding 0, value 6464
"8d0100004a45"
+
// field 17, encoding 5, value 3232.0
"9101000000000040b940"
+
// field 18, encoding 1, value 6464.0
"9a0106"
+
"737472696e67"
+
// field 19, encoding 2 string "string"
"a00100"
+
// field 20, encoding 0, value 0
"a00101"
+
// field 20, encoding 0, value 1
"a80120"
+
// field 21, encoding 0, value 32
"a80121"
+
// field 21, encoding 0, value 33
"b00140"
+
// field 22, encoding 0, value 64
"b00141"
+
// field 22, encoding 0, value 65
"bd01a00c0000"
+
// field 23, encoding 5, value 3232
"bd01050d0000"
+
// field 23, encoding 5, value 3333
"c1014019000000000000"
+
// field 24, encoding 1, value 6464
"c101a519000000000000"
+
// field 24, encoding 1, value 6565
"c801a0dd13"
+
// field 25, encoding 0, value 323232
"c80195ac14"
+
// field 25, encoding 0, value 333333
"d001c0ba27"
+
// field 26, encoding 0, value 646464
"d001b58928"
+
// field 26, encoding 0, value 656565
"dd0100000042"
+
// field 27, encoding 5, value 32.0
"dd0100000442"
+
// field 27, encoding 5, value 33.0
"e1010000000000005040"
+
// field 28, encoding 1, value 64.0
"e1010000000000405040"
+
// field 28, encoding 1, value 65.0
"ea0105"
+
"68656c6c6f"
+
// field 29, encoding 2, string "hello"
"ea0106"
+
"7361696c6f72"
+
// field 29, encoding 2, string "sailor"
"c00201"
+
// field 40, encoding 0, value 1
"c80220"
+
// field 41, encoding 0, value 32
"d00240"
+
// field 42, encoding 0, value 64
"dd0240010000"
+
// field 43, encoding 5, value 320
"e1028002000000000000"
+
// field 44, encoding 1, value 640
"e8028019"
+
// field 45, encoding 0, value 3200
"f0028032"
+
// field 46, encoding 0, value 6400
"fd02e0659948"
+
// field 47, encoding 5, value 314159.0
"81030000000050971041"
+
// field 48, encoding 1, value 271828.0
"8a0310"
+
"68656c6c6f2c2022776f726c6421220a"
+
// field 49, encoding 2 string "hello, \"world!\"\n"
"b304"
+
// start group field 70 level 1
"ba0408"
+
"7265717569726564"
+
// field 71, encoding 2, string "required"
"b404"
+
// end group field 70 level 1
"8305"
+
// start group field 80 level 1
"8a0508"
+
"7265706561746564"
+
// field 81, encoding 2, string "repeated"
"8405"
+
// end group field 80 level 1
"8305"
+
// start group field 80 level 1
"8a0508"
+
"7265706561746564"
+
// field 81, encoding 2, string "repeated"
"8405"
+
// end group field 80 level 1
"aa0605"
+
"6279746573"
+
// field 101, encoding 2 string "bytes"
"b0063f"
+
// field 102, encoding 0, 0x3f zigzag32
"b8067f"
+
// field 103, encoding 0, 0x7f zigzag64
"ca0c03"
+
"626967"
+
// field 201, encoding 2, string "big"
"ca0c04"
+
"6e6f7365"
+
// field 201, encoding 2, string "nose"
"d00c40"
+
// field 202, encoding 0, value 32
"d00c3f"
+
// field 202, encoding 0, value -32
"d80c8001"
+
// field 203, encoding 0, value 64
"d80c7f"
+
// field 203, encoding 0, value -64
"8a1907"
+
"4269676e6f7365"
+
// field 401, encoding 2, string "Bignose"
"90193f"
+
// field 402, encoding 0, value 63
"98197f"
)
// field 403, encoding 0, value 127
}
// All required fields set, all packed repeated fields given two values.
func
TestEncodeDecode6
(
t
*
testing
.
T
)
{
pb
:=
initGoTest
(
false
)
pb
.
F_BoolRepeatedPacked
=
[]
bool
{
false
,
true
}
pb
.
F_Int32RepeatedPacked
=
[]
int32
{
32
,
33
}
pb
.
F_Int64RepeatedPacked
=
[]
int64
{
64
,
65
}
pb
.
F_Fixed32RepeatedPacked
=
[]
uint32
{
3232
,
3333
}
pb
.
F_Fixed64RepeatedPacked
=
[]
uint64
{
6464
,
6565
}
pb
.
F_Uint32RepeatedPacked
=
[]
uint32
{
323232
,
333333
}
pb
.
F_Uint64RepeatedPacked
=
[]
uint64
{
646464
,
656565
}
pb
.
F_FloatRepeatedPacked
=
[]
float32
{
32.
,
33.
}
pb
.
F_DoubleRepeatedPacked
=
[]
float64
{
64.
,
65.
}
pb
.
F_Sint32RepeatedPacked
=
[]
int32
{
32
,
-
32
}
pb
.
F_Sint64RepeatedPacked
=
[]
int64
{
64
,
-
64
}
overify
(
t
,
pb
,
"0807"
+
// field 1, encoding 0, value 7
"220d"
+
"0a056c6162656c120474797065"
+
// field 4, encoding 2 (GoTestField)
"5001"
+
// field 10, encoding 0, value 1
"5803"
+
// field 11, encoding 0, value 3
"6006"
+
// field 12, encoding 0, value 6
"6d20000000"
+
// field 13, encoding 5, value 32
"714000000000000000"
+
// field 14, encoding 1, value 64
"78a019"
+
// field 15, encoding 0, value 3232
"8001c032"
+
// field 16, encoding 0, value 6464
"8d0100004a45"
+
// field 17, encoding 5, value 3232.0
"9101000000000040b940"
+
// field 18, encoding 1, value 6464.0
"9a0106"
+
"737472696e67"
+
// field 19, encoding 2 string "string"
"9203020001"
+
// field 50, encoding 2, 2 bytes, value 0, value 1
"9a03022021"
+
// field 51, encoding 2, 2 bytes, value 32, value 33
"a203024041"
+
// field 52, encoding 2, 2 bytes, value 64, value 65
"aa0308"
+
// field 53, encoding 2, 8 bytes
"a00c0000050d0000"
+
// value 3232, value 3333
"b20310"
+
// field 54, encoding 2, 16 bytes
"4019000000000000a519000000000000"
+
// value 6464, value 6565
"ba0306"
+
// field 55, encoding 2, 6 bytes
"a0dd1395ac14"
+
// value 323232, value 333333
"c20306"
+
// field 56, encoding 2, 6 bytes
"c0ba27b58928"
+
// value 646464, value 656565
"ca0308"
+
// field 57, encoding 2, 8 bytes
"0000004200000442"
+
// value 32.0, value 33.0
"d20310"
+
// field 58, encoding 2, 16 bytes
"00000000000050400000000000405040"
+
// value 64.0, value 65.0
"b304"
+
// start group field 70 level 1
"ba0408"
+
"7265717569726564"
+
// field 71, encoding 2, string "required"
"b404"
+
// end group field 70 level 1
"aa0605"
+
"6279746573"
+
// field 101, encoding 2 string "bytes"
"b0063f"
+
// field 102, encoding 0, 0x3f zigzag32
"b8067f"
+
// field 103, encoding 0, 0x7f zigzag64
"b21f02"
+
// field 502, encoding 2, 2 bytes
"403f"
+
// value 32, value -32
"ba1f03"
+
// field 503, encoding 2, 3 bytes
"80017f"
)
// value 64, value -64
}
// Test that we can encode empty bytes fields.
func
TestEncodeDecodeBytes1
(
t
*
testing
.
T
)
{
pb
:=
initGoTest
(
false
)
// Create our bytes
pb
.
F_BytesRequired
=
[]
byte
{}
pb
.
F_BytesRepeated
=
[][]
byte
{{}}
pb
.
F_BytesOptional
=
[]
byte
{}
d
,
err
:=
Marshal
(
pb
)
if
err
!=
nil
{
t
.
Error
(
err
)
}
pbd
:=
new
(
GoTest
)
if
err
:=
Unmarshal
(
d
,
pbd
);
err
!=
nil
{
t
.
Error
(
err
)
}
if
pbd
.
F_BytesRequired
==
nil
||
len
(
pbd
.
F_BytesRequired
)
!=
0
{
t
.
Error
(
"required empty bytes field is incorrect"
)
}
if
pbd
.
F_BytesRepeated
==
nil
||
len
(
pbd
.
F_BytesRepeated
)
==
1
&&
pbd
.
F_BytesRepeated
[
0
]
==
nil
{
t
.
Error
(
"repeated empty bytes field is incorrect"
)
}
if
pbd
.
F_BytesOptional
==
nil
||
len
(
pbd
.
F_BytesOptional
)
!=
0
{
t
.
Error
(
"optional empty bytes field is incorrect"
)
}
}
// Test that we encode nil-valued fields of a repeated bytes field correctly.
// Since entries in a repeated field cannot be nil, nil must mean empty value.
func
TestEncodeDecodeBytes2
(
t
*
testing
.
T
)
{
pb
:=
initGoTest
(
false
)
// Create our bytes
pb
.
F_BytesRepeated
=
[][]
byte
{
nil
}
d
,
err
:=
Marshal
(
pb
)
if
err
!=
nil
{
t
.
Error
(
err
)
}
pbd
:=
new
(
GoTest
)
if
err
:=
Unmarshal
(
d
,
pbd
);
err
!=
nil
{
t
.
Error
(
err
)
}
if
len
(
pbd
.
F_BytesRepeated
)
!=
1
||
pbd
.
F_BytesRepeated
[
0
]
==
nil
{
t
.
Error
(
"Unexpected value for repeated bytes field"
)
}
}
// All required fields set, defaults provided, all repeated fields given two values.
func
TestSkippingUnrecognizedFields
(
t
*
testing
.
T
)
{
o
:=
old
()
pb
:=
initGoTestField
()
// Marshal it normally.
o
.
Marshal
(
pb
)
// Now new a GoSkipTest record.
skip
:=
&
GoSkipTest
{
SkipInt32
:
Int32
(
32
),
SkipFixed32
:
Uint32
(
3232
),
SkipFixed64
:
Uint64
(
6464
),
SkipString
:
String
(
"skipper"
),
Skipgroup
:
&
GoSkipTest_SkipGroup
{
GroupInt32
:
Int32
(
75
),
GroupString
:
String
(
"wxyz"
),
},
}
// Marshal it into same buffer.
o
.
Marshal
(
skip
)
pbd
:=
new
(
GoTestField
)
o
.
Unmarshal
(
pbd
)
// The __unrecognized field should be a marshaling of GoSkipTest
skipd
:=
new
(
GoSkipTest
)
o
.
SetBuf
(
pbd
.
XXX_unrecognized
)
o
.
Unmarshal
(
skipd
)
if
*
skipd
.
SkipInt32
!=
*
skip
.
SkipInt32
{
t
.
Error
(
"skip int32"
,
skipd
.
SkipInt32
)
}
if
*
skipd
.
SkipFixed32
!=
*
skip
.
SkipFixed32
{
t
.
Error
(
"skip fixed32"
,
skipd
.
SkipFixed32
)
}
if
*
skipd
.
SkipFixed64
!=
*
skip
.
SkipFixed64
{
t
.
Error
(
"skip fixed64"
,
skipd
.
SkipFixed64
)
}
if
*
skipd
.
SkipString
!=
*
skip
.
SkipString
{
t
.
Error
(
"skip string"
,
*
skipd
.
SkipString
)
}
if
*
skipd
.
Skipgroup
.
GroupInt32
!=
*
skip
.
Skipgroup
.
GroupInt32
{
t
.
Error
(
"skip group int32"
,
skipd
.
Skipgroup
.
GroupInt32
)
}
if
*
skipd
.
Skipgroup
.
GroupString
!=
*
skip
.
Skipgroup
.
GroupString
{
t
.
Error
(
"skip group string"
,
*
skipd
.
Skipgroup
.
GroupString
)
}
}
// Check that unrecognized fields of a submessage are preserved.
func
TestSubmessageUnrecognizedFields
(
t
*
testing
.
T
)
{
nm
:=
&
NewMessage
{
Nested
:
&
NewMessage_Nested
{
Name
:
String
(
"Nigel"
),
FoodGroup
:
String
(
"carbs"
),
},
}
b
,
err
:=
Marshal
(
nm
)
if
err
!=
nil
{
t
.
Fatalf
(
"Marshal of NewMessage: %v"
,
err
)
}
// Unmarshal into an OldMessage.
om
:=
new
(
OldMessage
)
if
err
:=
Unmarshal
(
b
,
om
);
err
!=
nil
{
t
.
Fatalf
(
"Unmarshal to OldMessage: %v"
,
err
)
}
exp
:=
&
OldMessage
{
Nested
:
&
OldMessage_Nested
{
Name
:
String
(
"Nigel"
),
// normal protocol buffer users should not do this
XXX_unrecognized
:
[]
byte
(
"
\x12\x05
carbs"
),
},
}
if
!
Equal
(
om
,
exp
)
{
t
.
Errorf
(
"om = %v, want %v"
,
om
,
exp
)
}
// Clone the OldMessage.
om
=
Clone
(
om
)
.
(
*
OldMessage
)
if
!
Equal
(
om
,
exp
)
{
t
.
Errorf
(
"Clone(om) = %v, want %v"
,
om
,
exp
)
}
// Marshal the OldMessage, then unmarshal it into an empty NewMessage.
if
b
,
err
=
Marshal
(
om
);
err
!=
nil
{
t
.
Fatalf
(
"Marshal of OldMessage: %v"
,
err
)
}
t
.
Logf
(
"Marshal(%v) -> %q"
,
om
,
b
)
nm2
:=
new
(
NewMessage
)
if
err
:=
Unmarshal
(
b
,
nm2
);
err
!=
nil
{
t
.
Fatalf
(
"Unmarshal to NewMessage: %v"
,
err
)
}
if
!
Equal
(
nm
,
nm2
)
{
t
.
Errorf
(
"NewMessage round-trip: %v => %v"
,
nm
,
nm2
)
}
}
// Check that an int32 field can be upgraded to an int64 field.
func
TestNegativeInt32
(
t
*
testing
.
T
)
{
om
:=
&
OldMessage
{
Num
:
Int32
(
-
1
),
}
b
,
err
:=
Marshal
(
om
)
if
err
!=
nil
{
t
.
Fatalf
(
"Marshal of OldMessage: %v"
,
err
)
}
// Check the size. It should be 11 bytes;
// 1 for the field/wire type, and 10 for the negative number.
if
len
(
b
)
!=
11
{
t
.
Errorf
(
"%v marshaled as %q, wanted 11 bytes"
,
om
,
b
)
}
// Unmarshal into a NewMessage.
nm
:=
new
(
NewMessage
)
if
err
:=
Unmarshal
(
b
,
nm
);
err
!=
nil
{
t
.
Fatalf
(
"Unmarshal to NewMessage: %v"
,
err
)
}
want
:=
&
NewMessage
{
Num
:
Int64
(
-
1
),
}
if
!
Equal
(
nm
,
want
)
{
t
.
Errorf
(
"nm = %v, want %v"
,
nm
,
want
)
}
}
// Check that we can grow an array (repeated field) to have many elements.
// This test doesn't depend only on our encoding; for variety, it makes sure
// we create, encode, and decode the correct contents explicitly. It's therefore
// a bit messier.
// This test also uses (and hence tests) the Marshal/Unmarshal functions
// instead of the methods.
func
TestBigRepeated
(
t
*
testing
.
T
)
{
pb
:=
initGoTest
(
true
)
// Create the arrays
const
N
=
50
// Internally the library starts much smaller.
pb
.
Repeatedgroup
=
make
([]
*
GoTest_RepeatedGroup
,
N
)
pb
.
F_Sint64Repeated
=
make
([]
int64
,
N
)
pb
.
F_Sint32Repeated
=
make
([]
int32
,
N
)
pb
.
F_BytesRepeated
=
make
([][]
byte
,
N
)
pb
.
F_StringRepeated
=
make
([]
string
,
N
)
pb
.
F_DoubleRepeated
=
make
([]
float64
,
N
)
pb
.
F_FloatRepeated
=
make
([]
float32
,
N
)
pb
.
F_Uint64Repeated
=
make
([]
uint64
,
N
)
pb
.
F_Uint32Repeated
=
make
([]
uint32
,
N
)
pb
.
F_Fixed64Repeated
=
make
([]
uint64
,
N
)
pb
.
F_Fixed32Repeated
=
make
([]
uint32
,
N
)
pb
.
F_Int64Repeated
=
make
([]
int64
,
N
)
pb
.
F_Int32Repeated
=
make
([]
int32
,
N
)
pb
.
F_BoolRepeated
=
make
([]
bool
,
N
)
pb
.
RepeatedField
=
make
([]
*
GoTestField
,
N
)
// Fill in the arrays with checkable values.
igtf
:=
initGoTestField
()
igtrg
:=
initGoTest_RepeatedGroup
()
for
i
:=
0
;
i
<
N
;
i
++
{
pb
.
Repeatedgroup
[
i
]
=
igtrg
pb
.
F_Sint64Repeated
[
i
]
=
int64
(
i
)
pb
.
F_Sint32Repeated
[
i
]
=
int32
(
i
)
s
:=
fmt
.
Sprint
(
i
)
pb
.
F_BytesRepeated
[
i
]
=
[]
byte
(
s
)
pb
.
F_StringRepeated
[
i
]
=
s
pb
.
F_DoubleRepeated
[
i
]
=
float64
(
i
)
pb
.
F_FloatRepeated
[
i
]
=
float32
(
i
)
pb
.
F_Uint64Repeated
[
i
]
=
uint64
(
i
)
pb
.
F_Uint32Repeated
[
i
]
=
uint32
(
i
)
pb
.
F_Fixed64Repeated
[
i
]
=
uint64
(
i
)
pb
.
F_Fixed32Repeated
[
i
]
=
uint32
(
i
)
pb
.
F_Int64Repeated
[
i
]
=
int64
(
i
)
pb
.
F_Int32Repeated
[
i
]
=
int32
(
i
)
pb
.
F_BoolRepeated
[
i
]
=
i
%
2
==
0
pb
.
RepeatedField
[
i
]
=
igtf
}
// Marshal.
buf
,
_
:=
Marshal
(
pb
)
// Now test Unmarshal by recreating the original buffer.
pbd
:=
new
(
GoTest
)
Unmarshal
(
buf
,
pbd
)
// Check the checkable values
for
i
:=
uint64
(
0
);
i
<
N
;
i
++
{
if
pbd
.
Repeatedgroup
[
i
]
==
nil
{
// TODO: more checking?
t
.
Error
(
"pbd.Repeatedgroup bad"
)
}
var
x
uint64
x
=
uint64
(
pbd
.
F_Sint64Repeated
[
i
])
if
x
!=
i
{
t
.
Error
(
"pbd.F_Sint64Repeated bad"
,
x
,
i
)
}
x
=
uint64
(
pbd
.
F_Sint32Repeated
[
i
])
if
x
!=
i
{
t
.
Error
(
"pbd.F_Sint32Repeated bad"
,
x
,
i
)
}
s
:=
fmt
.
Sprint
(
i
)
equalbytes
(
pbd
.
F_BytesRepeated
[
i
],
[]
byte
(
s
),
t
)
if
pbd
.
F_StringRepeated
[
i
]
!=
s
{
t
.
Error
(
"pbd.F_Sint32Repeated bad"
,
pbd
.
F_StringRepeated
[
i
],
i
)
}
x
=
uint64
(
pbd
.
F_DoubleRepeated
[
i
])
if
x
!=
i
{
t
.
Error
(
"pbd.F_DoubleRepeated bad"
,
x
,
i
)
}
x
=
uint64
(
pbd
.
F_FloatRepeated
[
i
])
if
x
!=
i
{
t
.
Error
(
"pbd.F_FloatRepeated bad"
,
x
,
i
)
}
x
=
pbd
.
F_Uint64Repeated
[
i
]
if
x
!=
i
{
t
.
Error
(
"pbd.F_Uint64Repeated bad"
,
x
,
i
)
}
x
=
uint64
(
pbd
.
F_Uint32Repeated
[
i
])
if
x
!=
i
{
t
.
Error
(
"pbd.F_Uint32Repeated bad"
,
x
,
i
)
}
x
=
pbd
.
F_Fixed64Repeated
[
i
]
if
x
!=
i
{
t
.
Error
(
"pbd.F_Fixed64Repeated bad"
,
x
,
i
)
}
x
=
uint64
(
pbd
.
F_Fixed32Repeated
[
i
])
if
x
!=
i
{
t
.
Error
(
"pbd.F_Fixed32Repeated bad"
,
x
,
i
)
}
x
=
uint64
(
pbd
.
F_Int64Repeated
[
i
])
if
x
!=
i
{
t
.
Error
(
"pbd.F_Int64Repeated bad"
,
x
,
i
)
}
x
=
uint64
(
pbd
.
F_Int32Repeated
[
i
])
if
x
!=
i
{
t
.
Error
(
"pbd.F_Int32Repeated bad"
,
x
,
i
)
}
if
pbd
.
F_BoolRepeated
[
i
]
!=
(
i
%
2
==
0
)
{
t
.
Error
(
"pbd.F_BoolRepeated bad"
,
x
,
i
)
}
if
pbd
.
RepeatedField
[
i
]
==
nil
{
// TODO: more checking?
t
.
Error
(
"pbd.RepeatedField bad"
)
}
}
}
// Verify we give a useful message when decoding to the wrong structure type.
func
TestTypeMismatch
(
t
*
testing
.
T
)
{
pb1
:=
initGoTest
(
true
)
// Marshal
o
:=
old
()
o
.
Marshal
(
pb1
)
// Now Unmarshal it to the wrong type.
pb2
:=
initGoTestField
()
err
:=
o
.
Unmarshal
(
pb2
)
if
err
==
nil
{
t
.
Error
(
"expected error, got no error"
)
}
else
if
!
strings
.
Contains
(
err
.
Error
(),
"bad wiretype"
)
{
t
.
Error
(
"expected bad wiretype error, got"
,
err
)
}
}
func
encodeDecode
(
t
*
testing
.
T
,
in
,
out
Message
,
msg
string
)
{
buf
,
err
:=
Marshal
(
in
)
if
err
!=
nil
{
t
.
Fatalf
(
"failed marshaling %v: %v"
,
msg
,
err
)
}
if
err
:=
Unmarshal
(
buf
,
out
);
err
!=
nil
{
t
.
Fatalf
(
"failed unmarshaling %v: %v"
,
msg
,
err
)
}
}
func
TestPackedNonPackedDecoderSwitching
(
t
*
testing
.
T
)
{
np
,
p
:=
new
(
NonPackedTest
),
new
(
PackedTest
)
// non-packed -> packed
np
.
A
=
[]
int32
{
0
,
1
,
1
,
2
,
3
,
5
}
encodeDecode
(
t
,
np
,
p
,
"non-packed -> packed"
)
if
!
reflect
.
DeepEqual
(
np
.
A
,
p
.
B
)
{
t
.
Errorf
(
"failed non-packed -> packed; np.A=%+v, p.B=%+v"
,
np
.
A
,
p
.
B
)
}
// packed -> non-packed
np
.
Reset
()
p
.
B
=
[]
int32
{
3
,
1
,
4
,
1
,
5
,
9
}
encodeDecode
(
t
,
p
,
np
,
"packed -> non-packed"
)
if
!
reflect
.
DeepEqual
(
p
.
B
,
np
.
A
)
{
t
.
Errorf
(
"failed packed -> non-packed; p.B=%+v, np.A=%+v"
,
p
.
B
,
np
.
A
)
}
}
func
TestProto1RepeatedGroup
(
t
*
testing
.
T
)
{
pb
:=
&
MessageList
{
Message
:
[]
*
MessageList_Message
{
{
Name
:
String
(
"blah"
),
Count
:
Int32
(
7
),
},
// NOTE: pb.Message[1] is a nil
nil
,
},
}
o
:=
old
()
err
:=
o
.
Marshal
(
pb
)
if
err
==
nil
||
!
strings
.
Contains
(
err
.
Error
(),
"repeated field Message has nil"
)
{
t
.
Fatalf
(
"unexpected or no error when marshaling: %v"
,
err
)
}
}
// Test that enums work. Checks for a bug introduced by making enums
// named types instead of int32: newInt32FromUint64 would crash with
// a type mismatch in reflect.PointTo.
func
TestEnum
(
t
*
testing
.
T
)
{
pb
:=
new
(
GoEnum
)
pb
.
Foo
=
FOO_FOO1
.
Enum
()
o
:=
old
()
if
err
:=
o
.
Marshal
(
pb
);
err
!=
nil
{
t
.
Fatal
(
"error encoding enum:"
,
err
)
}
pb1
:=
new
(
GoEnum
)
if
err
:=
o
.
Unmarshal
(
pb1
);
err
!=
nil
{
t
.
Fatal
(
"error decoding enum:"
,
err
)
}
if
*
pb1
.
Foo
!=
FOO_FOO1
{
t
.
Error
(
"expected 7 but got "
,
*
pb1
.
Foo
)
}
}
// Enum types have String methods. Check that enum fields can be printed.
// We don't care what the value actually is, just as long as it doesn't crash.
func
TestPrintingNilEnumFields
(
t
*
testing
.
T
)
{
pb
:=
new
(
GoEnum
)
_
=
fmt
.
Sprintf
(
"%+v"
,
pb
)
}
// Verify that absent required fields cause Marshal/Unmarshal to return errors.
func
TestRequiredFieldEnforcement
(
t
*
testing
.
T
)
{
pb
:=
new
(
GoTestField
)
_
,
err
:=
Marshal
(
pb
)
if
err
==
nil
{
t
.
Error
(
"marshal: expected error, got nil"
)
}
else
if
strings
.
Index
(
err
.
Error
(),
"Label"
)
<
0
{
t
.
Errorf
(
"marshal: bad error type: %v"
,
err
)
}
// A slightly sneaky, yet valid, proto. It encodes the same required field twice,
// so simply counting the required fields is insufficient.
// field 1, encoding 2, value "hi"
buf
:=
[]
byte
(
"
\x0A\x02
hi
\x0A\x02
hi"
)
err
=
Unmarshal
(
buf
,
pb
)
if
err
==
nil
{
t
.
Error
(
"unmarshal: expected error, got nil"
)
}
else
if
strings
.
Index
(
err
.
Error
(),
"{Unknown}"
)
<
0
{
t
.
Errorf
(
"unmarshal: bad error type: %v"
,
err
)
}
}
func
TestTypedNilMarshal
(
t
*
testing
.
T
)
{
// A typed nil should return ErrNil and not crash.
_
,
err
:=
Marshal
((
*
GoEnum
)(
nil
))
if
err
!=
ErrNil
{
t
.
Errorf
(
"Marshal: got err %v, want ErrNil"
,
err
)
}
}
// A type that implements the Marshaler interface, but is not nillable.
type
nonNillableInt
uint64
func
(
nni
nonNillableInt
)
Marshal
()
([]
byte
,
error
)
{
return
EncodeVarint
(
uint64
(
nni
)),
nil
}
type
NNIMessage
struct
{
nni
nonNillableInt
}
func
(
*
NNIMessage
)
Reset
()
{}
func
(
*
NNIMessage
)
String
()
string
{
return
""
}
func
(
*
NNIMessage
)
ProtoMessage
()
{}
// A type that implements the Marshaler interface and is nillable.
type
nillableMessage
struct
{
x
uint64
}
func
(
nm
*
nillableMessage
)
Marshal
()
([]
byte
,
error
)
{
return
EncodeVarint
(
nm
.
x
),
nil
}
type
NMMessage
struct
{
nm
*
nillableMessage
}
func
(
*
NMMessage
)
Reset
()
{}
func
(
*
NMMessage
)
String
()
string
{
return
""
}
func
(
*
NMMessage
)
ProtoMessage
()
{}
// Verify a type that uses the Marshaler interface, but has a nil pointer.
func
TestNilMarshaler
(
t
*
testing
.
T
)
{
// Try a struct with a Marshaler field that is nil.
// It should be directly marshable.
nmm
:=
new
(
NMMessage
)
if
_
,
err
:=
Marshal
(
nmm
);
err
!=
nil
{
t
.
Error
(
"unexpected error marshaling nmm: "
,
err
)
}
// Try a struct with a Marshaler field that is not nillable.
nnim
:=
new
(
NNIMessage
)
nnim
.
nni
=
7
var
_
Marshaler
=
nnim
.
nni
// verify it is truly a Marshaler
if
_
,
err
:=
Marshal
(
nnim
);
err
!=
nil
{
t
.
Error
(
"unexpected error marshaling nnim: "
,
err
)
}
}
func
TestAllSetDefaults
(
t
*
testing
.
T
)
{
// Exercise SetDefaults with all scalar field types.
m
:=
&
Defaults
{
// NaN != NaN, so override that here.
F_Nan
:
Float32
(
1.7
),
}
expected
:=
&
Defaults
{
F_Bool
:
Bool
(
true
),
F_Int32
:
Int32
(
32
),
F_Int64
:
Int64
(
64
),
F_Fixed32
:
Uint32
(
320
),
F_Fixed64
:
Uint64
(
640
),
F_Uint32
:
Uint32
(
3200
),
F_Uint64
:
Uint64
(
6400
),
F_Float
:
Float32
(
314159
),
F_Double
:
Float64
(
271828
),
F_String
:
String
(
`hello, "world!"`
+
"
\n
"
),
F_Bytes
:
[]
byte
(
"Bignose"
),
F_Sint32
:
Int32
(
-
32
),
F_Sint64
:
Int64
(
-
64
),
F_Enum
:
Defaults_GREEN
.
Enum
(),
F_Pinf
:
Float32
(
float32
(
math
.
Inf
(
1
))),
F_Ninf
:
Float32
(
float32
(
math
.
Inf
(
-
1
))),
F_Nan
:
Float32
(
1.7
),
StrZero
:
String
(
""
),
}
SetDefaults
(
m
)
if
!
Equal
(
m
,
expected
)
{
t
.
Errorf
(
"SetDefaults failed
\n
got %v
\n
want %v"
,
m
,
expected
)
}
}
func
TestSetDefaultsWithSetField
(
t
*
testing
.
T
)
{
// Check that a set value is not overridden.
m
:=
&
Defaults
{
F_Int32
:
Int32
(
12
),
}
SetDefaults
(
m
)
if
v
:=
m
.
GetF_Int32
();
v
!=
12
{
t
.
Errorf
(
"m.FInt32 = %v, want 12"
,
v
)
}
}
func
TestSetDefaultsWithSubMessage
(
t
*
testing
.
T
)
{
m
:=
&
OtherMessage
{
Key
:
Int64
(
123
),
Inner
:
&
InnerMessage
{
Host
:
String
(
"gopher"
),
},
}
expected
:=
&
OtherMessage
{
Key
:
Int64
(
123
),
Inner
:
&
InnerMessage
{
Host
:
String
(
"gopher"
),
Port
:
Int32
(
4000
),
},
}
SetDefaults
(
m
)
if
!
Equal
(
m
,
expected
)
{
t
.
Errorf
(
"
\n
got %v
\n
want %v"
,
m
,
expected
)
}
}
func
TestSetDefaultsWithRepeatedSubMessage
(
t
*
testing
.
T
)
{
m
:=
&
MyMessage
{
RepInner
:
[]
*
InnerMessage
{{}},
}
expected
:=
&
MyMessage
{
RepInner
:
[]
*
InnerMessage
{{
Port
:
Int32
(
4000
),
}},
}
SetDefaults
(
m
)
if
!
Equal
(
m
,
expected
)
{
t
.
Errorf
(
"
\n
got %v
\n
want %v"
,
m
,
expected
)
}
}
func
TestSetDefaultWithRepeatedNonMessage
(
t
*
testing
.
T
)
{
m
:=
&
MyMessage
{
Pet
:
[]
string
{
"turtle"
,
"wombat"
},
}
expected
:=
Clone
(
m
)
SetDefaults
(
m
)
if
!
Equal
(
m
,
expected
)
{
t
.
Errorf
(
"
\n
got %v
\n
want %v"
,
m
,
expected
)
}
}
func
TestMaximumTagNumber
(
t
*
testing
.
T
)
{
m
:=
&
MaxTag
{
LastField
:
String
(
"natural goat essence"
),
}
buf
,
err
:=
Marshal
(
m
)
if
err
!=
nil
{
t
.
Fatalf
(
"proto.Marshal failed: %v"
,
err
)
}
m2
:=
new
(
MaxTag
)
if
err
:=
Unmarshal
(
buf
,
m2
);
err
!=
nil
{
t
.
Fatalf
(
"proto.Unmarshal failed: %v"
,
err
)
}
if
got
,
want
:=
m2
.
GetLastField
(),
*
m
.
LastField
;
got
!=
want
{
t
.
Errorf
(
"got %q, want %q"
,
got
,
want
)
}
}
func
TestJSON
(
t
*
testing
.
T
)
{
m
:=
&
MyMessage
{
Count
:
Int32
(
4
),
Pet
:
[]
string
{
"bunny"
,
"kitty"
},
Inner
:
&
InnerMessage
{
Host
:
String
(
"cauchy"
),
},
Bikeshed
:
MyMessage_GREEN
.
Enum
(),
}
const
expected
=
`{"count":4,"pet":["bunny","kitty"],"inner":{"host":"cauchy"},"bikeshed":1}`
b
,
err
:=
json
.
Marshal
(
m
)
if
err
!=
nil
{
t
.
Fatalf
(
"json.Marshal failed: %v"
,
err
)
}
s
:=
string
(
b
)
if
s
!=
expected
{
t
.
Errorf
(
"got %s
\n
want %s"
,
s
,
expected
)
}
received
:=
new
(
MyMessage
)
if
err
:=
json
.
Unmarshal
(
b
,
received
);
err
!=
nil
{
t
.
Fatalf
(
"json.Unmarshal failed: %v"
,
err
)
}
if
!
Equal
(
received
,
m
)
{
t
.
Fatalf
(
"got %s, want %s"
,
received
,
m
)
}
// Test unmarshalling of JSON with symbolic enum name.
const
old
=
`{"count":4,"pet":["bunny","kitty"],"inner":{"host":"cauchy"},"bikeshed":"GREEN"}`
received
.
Reset
()
if
err
:=
json
.
Unmarshal
([]
byte
(
old
),
received
);
err
!=
nil
{
t
.
Fatalf
(
"json.Unmarshal failed: %v"
,
err
)
}
if
!
Equal
(
received
,
m
)
{
t
.
Fatalf
(
"got %s, want %s"
,
received
,
m
)
}
}
func
TestBadWireType
(
t
*
testing
.
T
)
{
b
:=
[]
byte
{
7
<<
3
|
6
}
// field 7, wire type 6
pb
:=
new
(
OtherMessage
)
if
err
:=
Unmarshal
(
b
,
pb
);
err
==
nil
{
t
.
Errorf
(
"Unmarshal did not fail"
)
}
else
if
!
strings
.
Contains
(
err
.
Error
(),
"unknown wire type"
)
{
t
.
Errorf
(
"wrong error: %v"
,
err
)
}
}
func
TestBytesWithInvalidLength
(
t
*
testing
.
T
)
{
// If a byte sequence has an invalid (negative) length, Unmarshal should not panic.
b
:=
[]
byte
{
2
<<
3
|
WireBytes
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0
}
Unmarshal
(
b
,
new
(
MyMessage
))
}
func
TestLengthOverflow
(
t
*
testing
.
T
)
{
// Overflowing a length should not panic.
b
:=
[]
byte
{
2
<<
3
|
WireBytes
,
1
,
1
,
3
<<
3
|
WireBytes
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0x7f
,
0x01
}
Unmarshal
(
b
,
new
(
MyMessage
))
}
func
TestVarintOverflow
(
t
*
testing
.
T
)
{
// Overflowing a 64-bit length should not be allowed.
b
:=
[]
byte
{
1
<<
3
|
WireVarint
,
0x01
,
3
<<
3
|
WireBytes
,
0x80
,
0x80
,
0x80
,
0x80
,
0x80
,
0x80
,
0x80
,
0x80
,
0x80
,
0x80
,
0x01
}
if
err
:=
Unmarshal
(
b
,
new
(
MyMessage
));
err
==
nil
{
t
.
Fatalf
(
"Overflowed uint64 length without error"
)
}
}
func
TestUnmarshalFuzz
(
t
*
testing
.
T
)
{
const
N
=
1000
seed
:=
time
.
Now
()
.
UnixNano
()
t
.
Logf
(
"RNG seed is %d"
,
seed
)
rng
:=
rand
.
New
(
rand
.
NewSource
(
seed
))
buf
:=
make
([]
byte
,
20
)
for
i
:=
0
;
i
<
N
;
i
++
{
for
j
:=
range
buf
{
buf
[
j
]
=
byte
(
rng
.
Intn
(
256
))
}
fuzzUnmarshal
(
t
,
buf
)
}
}
func
TestMergeMessages
(
t
*
testing
.
T
)
{
pb
:=
&
MessageList
{
Message
:
[]
*
MessageList_Message
{{
Name
:
String
(
"x"
),
Count
:
Int32
(
1
)}}}
data
,
err
:=
Marshal
(
pb
)
if
err
!=
nil
{
t
.
Fatalf
(
"Marshal: %v"
,
err
)
}
pb1
:=
new
(
MessageList
)
if
err
:=
Unmarshal
(
data
,
pb1
);
err
!=
nil
{
t
.
Fatalf
(
"first Unmarshal: %v"
,
err
)
}
if
err
:=
Unmarshal
(
data
,
pb1
);
err
!=
nil
{
t
.
Fatalf
(
"second Unmarshal: %v"
,
err
)
}
if
len
(
pb1
.
Message
)
!=
1
{
t
.
Errorf
(
"two Unmarshals produced %d Messages, want 1"
,
len
(
pb1
.
Message
))
}
pb2
:=
new
(
MessageList
)
if
err
:=
UnmarshalMerge
(
data
,
pb2
);
err
!=
nil
{
t
.
Fatalf
(
"first UnmarshalMerge: %v"
,
err
)
}
if
err
:=
UnmarshalMerge
(
data
,
pb2
);
err
!=
nil
{
t
.
Fatalf
(
"second UnmarshalMerge: %v"
,
err
)
}
if
len
(
pb2
.
Message
)
!=
2
{
t
.
Errorf
(
"two UnmarshalMerges produced %d Messages, want 2"
,
len
(
pb2
.
Message
))
}
}
func
TestExtensionMarshalOrder
(
t
*
testing
.
T
)
{
m
:=
&
MyMessage
{
Count
:
Int
(
123
)}
if
err
:=
SetExtension
(
m
,
E_Ext_More
,
&
Ext
{
Data
:
String
(
"alpha"
)});
err
!=
nil
{
t
.
Fatalf
(
"SetExtension: %v"
,
err
)
}
if
err
:=
SetExtension
(
m
,
E_Ext_Text
,
String
(
"aleph"
));
err
!=
nil
{
t
.
Fatalf
(
"SetExtension: %v"
,
err
)
}
if
err
:=
SetExtension
(
m
,
E_Ext_Number
,
Int32
(
1
));
err
!=
nil
{
t
.
Fatalf
(
"SetExtension: %v"
,
err
)
}
// Serialize m several times, and check we get the same bytes each time.
var
orig
[]
byte
for
i
:=
0
;
i
<
100
;
i
++
{
b
,
err
:=
Marshal
(
m
)
if
err
!=
nil
{
t
.
Fatalf
(
"Marshal: %v"
,
err
)
}
if
i
==
0
{
orig
=
b
continue
}
if
!
bytes
.
Equal
(
b
,
orig
)
{
t
.
Errorf
(
"Bytes differ on attempt #%d"
,
i
)
}
}
}
// Many extensions, because small maps might not iterate differently on each iteration.
var
exts
=
[]
*
ExtensionDesc
{
E_X201
,
E_X202
,
E_X203
,
E_X204
,
E_X205
,
E_X206
,
E_X207
,
E_X208
,
E_X209
,
E_X210
,
E_X211
,
E_X212
,
E_X213
,
E_X214
,
E_X215
,
E_X216
,
E_X217
,
E_X218
,
E_X219
,
E_X220
,
E_X221
,
E_X222
,
E_X223
,
E_X224
,
E_X225
,
E_X226
,
E_X227
,
E_X228
,
E_X229
,
E_X230
,
E_X231
,
E_X232
,
E_X233
,
E_X234
,
E_X235
,
E_X236
,
E_X237
,
E_X238
,
E_X239
,
E_X240
,
E_X241
,
E_X242
,
E_X243
,
E_X244
,
E_X245
,
E_X246
,
E_X247
,
E_X248
,
E_X249
,
E_X250
,
}
func
TestMessageSetMarshalOrder
(
t
*
testing
.
T
)
{
m
:=
&
MyMessageSet
{}
for
_
,
x
:=
range
exts
{
if
err
:=
SetExtension
(
m
,
x
,
&
Empty
{});
err
!=
nil
{
t
.
Fatalf
(
"SetExtension: %v"
,
err
)
}
}
buf
,
err
:=
Marshal
(
m
)
if
err
!=
nil
{
t
.
Fatalf
(
"Marshal: %v"
,
err
)
}
// Serialize m several times, and check we get the same bytes each time.
for
i
:=
0
;
i
<
10
;
i
++
{
b1
,
err
:=
Marshal
(
m
)
if
err
!=
nil
{
t
.
Fatalf
(
"Marshal: %v"
,
err
)
}
if
!
bytes
.
Equal
(
b1
,
buf
)
{
t
.
Errorf
(
"Bytes differ on re-Marshal #%d"
,
i
)
}
m2
:=
&
MyMessageSet
{}
if
err
:=
Unmarshal
(
buf
,
m2
);
err
!=
nil
{
t
.
Errorf
(
"Unmarshal: %v"
,
err
)
}
b2
,
err
:=
Marshal
(
m2
)
if
err
!=
nil
{
t
.
Errorf
(
"re-Marshal: %v"
,
err
)
}
if
!
bytes
.
Equal
(
b2
,
buf
)
{
t
.
Errorf
(
"Bytes differ on round-trip #%d"
,
i
)
}
}
}
func
TestUnmarshalMergesMessages
(
t
*
testing
.
T
)
{
// If a nested message occurs twice in the input,
// the fields should be merged when decoding.
a
:=
&
OtherMessage
{
Key
:
Int64
(
123
),
Inner
:
&
InnerMessage
{
Host
:
String
(
"polhode"
),
Port
:
Int32
(
1234
),
},
}
aData
,
err
:=
Marshal
(
a
)
if
err
!=
nil
{
t
.
Fatalf
(
"Marshal(a): %v"
,
err
)
}
b
:=
&
OtherMessage
{
Weight
:
Float32
(
1.2
),
Inner
:
&
InnerMessage
{
Host
:
String
(
"herpolhode"
),
Connected
:
Bool
(
true
),
},
}
bData
,
err
:=
Marshal
(
b
)
if
err
!=
nil
{
t
.
Fatalf
(
"Marshal(b): %v"
,
err
)
}
want
:=
&
OtherMessage
{
Key
:
Int64
(
123
),
Weight
:
Float32
(
1.2
),
Inner
:
&
InnerMessage
{
Host
:
String
(
"herpolhode"
),
Port
:
Int32
(
1234
),
Connected
:
Bool
(
true
),
},
}
got
:=
new
(
OtherMessage
)
if
err
:=
Unmarshal
(
append
(
aData
,
bData
...
),
got
);
err
!=
nil
{
t
.
Fatalf
(
"Unmarshal: %v"
,
err
)
}
if
!
Equal
(
got
,
want
)
{
t
.
Errorf
(
"
\n
got %v
\n
want %v"
,
got
,
want
)
}
}
func
TestEncodingSizes
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
m
Message
n
int
}{
{
&
Defaults
{
F_Int32
:
Int32
(
math
.
MaxInt32
)},
6
},
{
&
Defaults
{
F_Int32
:
Int32
(
math
.
MinInt32
)},
11
},
{
&
Defaults
{
F_Uint32
:
Uint32
(
uint32
(
math
.
MaxInt32
)
+
1
)},
6
},
{
&
Defaults
{
F_Uint32
:
Uint32
(
math
.
MaxUint32
)},
6
},
}
for
_
,
test
:=
range
tests
{
b
,
err
:=
Marshal
(
test
.
m
)
if
err
!=
nil
{
t
.
Errorf
(
"Marshal(%v): %v"
,
test
.
m
,
err
)
continue
}
if
len
(
b
)
!=
test
.
n
{
t
.
Errorf
(
"Marshal(%v) yielded %d bytes, want %d bytes"
,
test
.
m
,
len
(
b
),
test
.
n
)
}
}
}
func
TestRequiredNotSetError
(
t
*
testing
.
T
)
{
pb
:=
initGoTest
(
false
)
pb
.
RequiredField
.
Label
=
nil
pb
.
F_Int32Required
=
nil
pb
.
F_Int64Required
=
nil
expected
:=
"0807"
+
// field 1, encoding 0, value 7
"2206"
+
"120474797065"
+
// field 4, encoding 2 (GoTestField)
"5001"
+
// field 10, encoding 0, value 1
"6d20000000"
+
// field 13, encoding 5, value 0x20
"714000000000000000"
+
// field 14, encoding 1, value 0x40
"78a019"
+
// field 15, encoding 0, value 0xca0 = 3232
"8001c032"
+
// field 16, encoding 0, value 0x1940 = 6464
"8d0100004a45"
+
// field 17, encoding 5, value 3232.0
"9101000000000040b940"
+
// field 18, encoding 1, value 6464.0
"9a0106"
+
"737472696e67"
+
// field 19, encoding 2, string "string"
"b304"
+
// field 70, encoding 3, start group
"ba0408"
+
"7265717569726564"
+
// field 71, encoding 2, string "required"
"b404"
+
// field 70, encoding 4, end group
"aa0605"
+
"6279746573"
+
// field 101, encoding 2, string "bytes"
"b0063f"
+
// field 102, encoding 0, 0x3f zigzag32
"b8067f"
// field 103, encoding 0, 0x7f zigzag64
o
:=
old
()
bytes
,
err
:=
Marshal
(
pb
)
if
_
,
ok
:=
err
.
(
*
RequiredNotSetError
);
!
ok
{
fmt
.
Printf
(
"marshal-1 err = %v, want *RequiredNotSetError"
,
err
)
o
.
DebugPrint
(
""
,
bytes
)
t
.
Fatalf
(
"expected = %s"
,
expected
)
}
if
strings
.
Index
(
err
.
Error
(),
"RequiredField.Label"
)
<
0
{
t
.
Errorf
(
"marshal-1 wrong err msg: %v"
,
err
)
}
if
!
equal
(
bytes
,
expected
,
t
)
{
o
.
DebugPrint
(
"neq 1"
,
bytes
)
t
.
Fatalf
(
"expected = %s"
,
expected
)
}
// Now test Unmarshal by recreating the original buffer.
pbd
:=
new
(
GoTest
)
err
=
Unmarshal
(
bytes
,
pbd
)
if
_
,
ok
:=
err
.
(
*
RequiredNotSetError
);
!
ok
{
t
.
Fatalf
(
"unmarshal err = %v, want *RequiredNotSetError"
,
err
)
o
.
DebugPrint
(
""
,
bytes
)
t
.
Fatalf
(
"string = %s"
,
expected
)
}
if
strings
.
Index
(
err
.
Error
(),
"RequiredField.{Unknown}"
)
<
0
{
t
.
Errorf
(
"unmarshal wrong err msg: %v"
,
err
)
}
bytes
,
err
=
Marshal
(
pbd
)
if
_
,
ok
:=
err
.
(
*
RequiredNotSetError
);
!
ok
{
t
.
Errorf
(
"marshal-2 err = %v, want *RequiredNotSetError"
,
err
)
o
.
DebugPrint
(
""
,
bytes
)
t
.
Fatalf
(
"string = %s"
,
expected
)
}
if
strings
.
Index
(
err
.
Error
(),
"RequiredField.Label"
)
<
0
{
t
.
Errorf
(
"marshal-2 wrong err msg: %v"
,
err
)
}
if
!
equal
(
bytes
,
expected
,
t
)
{
o
.
DebugPrint
(
"neq 2"
,
bytes
)
t
.
Fatalf
(
"string = %s"
,
expected
)
}
}
func
fuzzUnmarshal
(
t
*
testing
.
T
,
data
[]
byte
)
{
defer
func
()
{
if
e
:=
recover
();
e
!=
nil
{
t
.
Errorf
(
"These bytes caused a panic: %+v"
,
data
)
t
.
Logf
(
"Stack:
\n
%s"
,
debug
.
Stack
())
t
.
FailNow
()
}
}()
pb
:=
new
(
MyMessage
)
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\x03
Rob"
,
"
\n\a\b\x04\x12\x03
Ian"
,
"
\n\b\b\x08\x12\x04
Dave"
,
}
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
\n
want %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
:
{
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.
\n
initial: %v
\n
final: %v"
,
pair
[
0
],
pair
[
1
])
}
}
}
func
TestMapFieldWithNil
(
t
*
testing
.
T
)
{
m
:=
&
MessageWithMap
{
MsgMapping
:
map
[
int64
]
*
FloatingPoint
{
1
:
nil
,
},
}
b
,
err
:=
Marshal
(
m
)
if
err
==
nil
{
t
.
Fatalf
(
"Marshal of bad map should have failed, got these bytes: %v"
,
b
)
}
}
func
TestOneof
(
t
*
testing
.
T
)
{
m
:=
&
Communique
{}
b
,
err
:=
Marshal
(
m
)
if
err
!=
nil
{
t
.
Fatalf
(
"Marshal of empty message with oneof: %v"
,
err
)
}
if
len
(
b
)
!=
0
{
t
.
Errorf
(
"Marshal of empty message yielded too many bytes: %v"
,
b
)
}
m
=
&
Communique
{
Union
:
&
Communique_Name
{
"Barry"
},
}
// Round-trip.
b
,
err
=
Marshal
(
m
)
if
err
!=
nil
{
t
.
Fatalf
(
"Marshal of message with oneof: %v"
,
err
)
}
if
len
(
b
)
!=
7
{
// name tag/wire (1) + name len (1) + name (5)
t
.
Errorf
(
"Incorrect marshal of message with oneof: %v"
,
b
)
}
m
.
Reset
()
if
err
:=
Unmarshal
(
b
,
m
);
err
!=
nil
{
t
.
Fatalf
(
"Unmarshal of message with oneof: %v"
,
err
)
}
if
x
,
ok
:=
m
.
Union
.
(
*
Communique_Name
);
!
ok
||
x
.
Name
!=
"Barry"
{
t
.
Errorf
(
"After round trip, Union = %+v"
,
m
.
Union
)
}
if
name
:=
m
.
GetName
();
name
!=
"Barry"
{
t
.
Errorf
(
"After round trip, GetName = %q, want %q"
,
name
,
"Barry"
)
}
// Let's try with a message in the oneof.
m
.
Union
=
&
Communique_Msg
{
&
Strings
{
StringField
:
String
(
"deep deep string"
)}}
b
,
err
=
Marshal
(
m
)
if
err
!=
nil
{
t
.
Fatalf
(
"Marshal of message with oneof set to message: %v"
,
err
)
}
if
len
(
b
)
!=
20
{
// msg tag/wire (1) + msg len (1) + msg (1 + 1 + 16)
t
.
Errorf
(
"Incorrect marshal of message with oneof set to message: %v"
,
b
)
}
m
.
Reset
()
if
err
:=
Unmarshal
(
b
,
m
);
err
!=
nil
{
t
.
Fatalf
(
"Unmarshal of message with oneof set to message: %v"
,
err
)
}
ss
,
ok
:=
m
.
Union
.
(
*
Communique_Msg
)
if
!
ok
||
ss
.
Msg
.
GetStringField
()
!=
"deep deep string"
{
t
.
Errorf
(
"After round trip with oneof set to message, Union = %+v"
,
m
.
Union
)
}
}
func
TestInefficientPackedBool
(
t
*
testing
.
T
)
{
// https://github.com/golang/protobuf/issues/76
inp
:=
[]
byte
{
0x12
,
0x02
,
// 0x12 = 2<<3|2; 2 bytes
// Usually a bool should take a single byte,
// but it is permitted to be any varint.
0xb9
,
0x30
,
}
if
err
:=
Unmarshal
(
inp
,
new
(
MoreRepeated
));
err
!=
nil
{
t
.
Error
(
err
)
}
}
// Benchmarks
func
testMsg
()
*
GoTest
{
pb
:=
initGoTest
(
true
)
const
N
=
1000
// Internally the library starts much smaller.
pb
.
F_Int32Repeated
=
make
([]
int32
,
N
)
pb
.
F_DoubleRepeated
=
make
([]
float64
,
N
)
for
i
:=
0
;
i
<
N
;
i
++
{
pb
.
F_Int32Repeated
[
i
]
=
int32
(
i
)
pb
.
F_DoubleRepeated
[
i
]
=
float64
(
i
)
}
return
pb
}
func
bytesMsg
()
*
GoTest
{
pb
:=
initGoTest
(
true
)
buf
:=
make
([]
byte
,
4000
)
for
i
:=
range
buf
{
buf
[
i
]
=
byte
(
i
)
}
pb
.
F_BytesDefaulted
=
buf
return
pb
}
func
benchmarkMarshal
(
b
*
testing
.
B
,
pb
Message
,
marshal
func
(
Message
)
([]
byte
,
error
))
{
d
,
_
:=
marshal
(
pb
)
b
.
SetBytes
(
int64
(
len
(
d
)))
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
marshal
(
pb
)
}
}
func
benchmarkBufferMarshal
(
b
*
testing
.
B
,
pb
Message
)
{
p
:=
NewBuffer
(
nil
)
benchmarkMarshal
(
b
,
pb
,
func
(
pb0
Message
)
([]
byte
,
error
)
{
p
.
Reset
()
err
:=
p
.
Marshal
(
pb0
)
return
p
.
Bytes
(),
err
})
}
func
benchmarkSize
(
b
*
testing
.
B
,
pb
Message
)
{
benchmarkMarshal
(
b
,
pb
,
func
(
pb0
Message
)
([]
byte
,
error
)
{
Size
(
pb
)
return
nil
,
nil
})
}
func
newOf
(
pb
Message
)
Message
{
in
:=
reflect
.
ValueOf
(
pb
)
if
in
.
IsNil
()
{
return
pb
}
return
reflect
.
New
(
in
.
Type
()
.
Elem
())
.
Interface
()
.
(
Message
)
}
func
benchmarkUnmarshal
(
b
*
testing
.
B
,
pb
Message
,
unmarshal
func
([]
byte
,
Message
)
error
)
{
d
,
_
:=
Marshal
(
pb
)
b
.
SetBytes
(
int64
(
len
(
d
)))
pbd
:=
newOf
(
pb
)
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
unmarshal
(
d
,
pbd
)
}
}
func
benchmarkBufferUnmarshal
(
b
*
testing
.
B
,
pb
Message
)
{
p
:=
NewBuffer
(
nil
)
benchmarkUnmarshal
(
b
,
pb
,
func
(
d
[]
byte
,
pb0
Message
)
error
{
p
.
SetBuf
(
d
)
return
p
.
Unmarshal
(
pb0
)
})
}
// Benchmark{Marshal,BufferMarshal,Size,Unmarshal,BufferUnmarshal}{,Bytes}
func
BenchmarkMarshal
(
b
*
testing
.
B
)
{
benchmarkMarshal
(
b
,
testMsg
(),
Marshal
)
}
func
BenchmarkBufferMarshal
(
b
*
testing
.
B
)
{
benchmarkBufferMarshal
(
b
,
testMsg
())
}
func
BenchmarkSize
(
b
*
testing
.
B
)
{
benchmarkSize
(
b
,
testMsg
())
}
func
BenchmarkUnmarshal
(
b
*
testing
.
B
)
{
benchmarkUnmarshal
(
b
,
testMsg
(),
Unmarshal
)
}
func
BenchmarkBufferUnmarshal
(
b
*
testing
.
B
)
{
benchmarkBufferUnmarshal
(
b
,
testMsg
())
}
func
BenchmarkMarshalBytes
(
b
*
testing
.
B
)
{
benchmarkMarshal
(
b
,
bytesMsg
(),
Marshal
)
}
func
BenchmarkBufferMarshalBytes
(
b
*
testing
.
B
)
{
benchmarkBufferMarshal
(
b
,
bytesMsg
())
}
func
BenchmarkSizeBytes
(
b
*
testing
.
B
)
{
benchmarkSize
(
b
,
bytesMsg
())
}
func
BenchmarkUnmarshalBytes
(
b
*
testing
.
B
)
{
benchmarkUnmarshal
(
b
,
bytesMsg
(),
Unmarshal
)
}
func
BenchmarkBufferUnmarshalBytes
(
b
*
testing
.
B
)
{
benchmarkBufferUnmarshal
(
b
,
bytesMsg
())
}
func
BenchmarkUnmarshalUnrecognizedFields
(
b
*
testing
.
B
)
{
b
.
StopTimer
()
pb
:=
initGoTestField
()
skip
:=
&
GoSkipTest
{
SkipInt32
:
Int32
(
32
),
SkipFixed32
:
Uint32
(
3232
),
SkipFixed64
:
Uint64
(
6464
),
SkipString
:
String
(
"skipper"
),
Skipgroup
:
&
GoSkipTest_SkipGroup
{
GroupInt32
:
Int32
(
75
),
GroupString
:
String
(
"wxyz"
),
},
}
pbd
:=
new
(
GoTestField
)
p
:=
NewBuffer
(
nil
)
p
.
Marshal
(
pb
)
p
.
Marshal
(
skip
)
p2
:=
NewBuffer
(
nil
)
b
.
StartTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
p2
.
SetBuf
(
p
.
Bytes
())
p2
.
Unmarshal
(
pbd
)
}
}
vendor/QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto/clone.go
0 → 100644
View file @
8f79df77
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2011 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.
// Protocol buffer deep copy and merge.
// TODO: MessageSet and RawMessage.
package
proto
import
(
"log"
"reflect"
"strings"
)
// Clone returns a deep copy of a protocol buffer.
func
Clone
(
pb
Message
)
Message
{
in
:=
reflect
.
ValueOf
(
pb
)
if
in
.
IsNil
()
{
return
pb
}
out
:=
reflect
.
New
(
in
.
Type
()
.
Elem
())
// out is empty so a merge is a deep copy.
mergeStruct
(
out
.
Elem
(),
in
.
Elem
())
return
out
.
Interface
()
.
(
Message
)
}
// Merge merges src into dst.
// Required and optional fields that are set in src will be set to that value in dst.
// Elements of repeated fields will be appended.
// Merge panics if src and dst are not the same type, or if dst is nil.
func
Merge
(
dst
,
src
Message
)
{
in
:=
reflect
.
ValueOf
(
src
)
out
:=
reflect
.
ValueOf
(
dst
)
if
out
.
IsNil
()
{
panic
(
"proto: nil destination"
)
}
if
in
.
Type
()
!=
out
.
Type
()
{
// Explicit test prior to mergeStruct so that mistyped nils will fail
panic
(
"proto: type mismatch"
)
}
if
in
.
IsNil
()
{
// Merging nil into non-nil is a quiet no-op
return
}
mergeStruct
(
out
.
Elem
(),
in
.
Elem
())
}
func
mergeStruct
(
out
,
in
reflect
.
Value
)
{
sprop
:=
GetProperties
(
in
.
Type
())
for
i
:=
0
;
i
<
in
.
NumField
();
i
++
{
f
:=
in
.
Type
()
.
Field
(
i
)
if
strings
.
HasPrefix
(
f
.
Name
,
"XXX_"
)
{
continue
}
mergeAny
(
out
.
Field
(
i
),
in
.
Field
(
i
),
false
,
sprop
.
Prop
[
i
])
}
if
emIn
,
ok
:=
in
.
Addr
()
.
Interface
()
.
(
extensionsMap
);
ok
{
emOut
:=
out
.
Addr
()
.
Interface
()
.
(
extensionsMap
)
mergeExtension
(
emOut
.
ExtensionMap
(),
emIn
.
ExtensionMap
())
}
else
if
emIn
,
ok
:=
in
.
Addr
()
.
Interface
()
.
(
extensionsBytes
);
ok
{
emOut
:=
out
.
Addr
()
.
Interface
()
.
(
extensionsBytes
)
bIn
:=
emIn
.
GetExtensions
()
bOut
:=
emOut
.
GetExtensions
()
*
bOut
=
append
(
*
bOut
,
*
bIn
...
)
}
uf
:=
in
.
FieldByName
(
"XXX_unrecognized"
)
if
!
uf
.
IsValid
()
{
return
}
uin
:=
uf
.
Bytes
()
if
len
(
uin
)
>
0
{
out
.
FieldByName
(
"XXX_unrecognized"
)
.
SetBytes
(
append
([]
byte
(
nil
),
uin
...
))
}
}
// mergeAny performs a merge between two values of the same type.
// viaPtr indicates whether the values were indirected through a pointer (implying proto2).
// prop is set if this is a struct field (it may be nil).
func
mergeAny
(
out
,
in
reflect
.
Value
,
viaPtr
bool
,
prop
*
Properties
)
{
if
in
.
Type
()
==
protoMessageType
{
if
!
in
.
IsNil
()
{
if
out
.
IsNil
()
{
out
.
Set
(
reflect
.
ValueOf
(
Clone
(
in
.
Interface
()
.
(
Message
))))
}
else
{
Merge
(
out
.
Interface
()
.
(
Message
),
in
.
Interface
()
.
(
Message
))
}
}
return
}
switch
in
.
Kind
()
{
case
reflect
.
Bool
,
reflect
.
Float32
,
reflect
.
Float64
,
reflect
.
Int32
,
reflect
.
Int64
,
reflect
.
String
,
reflect
.
Uint32
,
reflect
.
Uint64
:
if
!
viaPtr
&&
isProto3Zero
(
in
)
{
return
}
out
.
Set
(
in
)
case
reflect
.
Interface
:
// Probably a oneof field; copy non-nil values.
if
in
.
IsNil
()
{
return
}
// Allocate destination if it is not set, or set to a different type.
// Otherwise we will merge as normal.
if
out
.
IsNil
()
||
out
.
Elem
()
.
Type
()
!=
in
.
Elem
()
.
Type
()
{
out
.
Set
(
reflect
.
New
(
in
.
Elem
()
.
Elem
()
.
Type
()))
// interface -> *T -> T -> new(T)
}
mergeAny
(
out
.
Elem
(),
in
.
Elem
(),
false
,
nil
)
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
),
false
,
nil
)
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
:
if
in
.
IsNil
()
{
return
}
if
out
.
IsNil
()
{
out
.
Set
(
reflect
.
New
(
in
.
Elem
()
.
Type
()))
}
mergeAny
(
out
.
Elem
(),
in
.
Elem
(),
true
,
nil
)
case
reflect
.
Slice
:
if
in
.
IsNil
()
{
return
}
if
in
.
Type
()
.
Elem
()
.
Kind
()
==
reflect
.
Uint8
{
// []byte is a scalar bytes field, not a repeated field.
// Edge case: if this is in a proto3 message, a zero length
// bytes field is considered the zero value, and should not
// be merged.
if
prop
!=
nil
&&
prop
.
proto3
&&
in
.
Len
()
==
0
{
return
}
// 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
()
if
out
.
IsNil
()
{
out
.
Set
(
reflect
.
MakeSlice
(
in
.
Type
(),
0
,
n
))
}
switch
in
.
Type
()
.
Elem
()
.
Kind
()
{
case
reflect
.
Bool
,
reflect
.
Float32
,
reflect
.
Float64
,
reflect
.
Int32
,
reflect
.
Int64
,
reflect
.
String
,
reflect
.
Uint32
,
reflect
.
Uint64
:
out
.
Set
(
reflect
.
AppendSlice
(
out
,
in
))
default
:
for
i
:=
0
;
i
<
n
;
i
++
{
x
:=
reflect
.
Indirect
(
reflect
.
New
(
in
.
Type
()
.
Elem
()))
mergeAny
(
x
,
in
.
Index
(
i
),
false
,
nil
)
out
.
Set
(
reflect
.
Append
(
out
,
x
))
}
}
case
reflect
.
Struct
:
mergeStruct
(
out
,
in
)
default
:
// unknown type, so not a protocol buffer
log
.
Printf
(
"proto: don't know how to copy %v"
,
in
)
}
}
func
mergeExtension
(
out
,
in
map
[
int32
]
Extension
)
{
for
extNum
,
eIn
:=
range
in
{
eOut
:=
Extension
{
desc
:
eIn
.
desc
}
if
eIn
.
value
!=
nil
{
v
:=
reflect
.
New
(
reflect
.
TypeOf
(
eIn
.
value
))
.
Elem
()
mergeAny
(
v
,
reflect
.
ValueOf
(
eIn
.
value
),
false
,
nil
)
eOut
.
value
=
v
.
Interface
()
}
if
eIn
.
enc
!=
nil
{
eOut
.
enc
=
make
([]
byte
,
len
(
eIn
.
enc
))
copy
(
eOut
.
enc
,
eIn
.
enc
)
}
out
[
extNum
]
=
eOut
}
}
vendor/QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto/clone_test.go
0 → 100644
View file @
8f79df77
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2011 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"
"QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto"
proto3pb
"QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto/proto3_proto"
pb
"QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto/testdata"
)
var
cloneTestMessage
=
&
pb
.
MyMessage
{
Count
:
proto
.
Int32
(
42
),
Name
:
proto
.
String
(
"Dave"
),
Pet
:
[]
string
{
"bunny"
,
"kitty"
,
"horsey"
},
Inner
:
&
pb
.
InnerMessage
{
Host
:
proto
.
String
(
"niles"
),
Port
:
proto
.
Int32
(
9099
),
Connected
:
proto
.
Bool
(
true
),
},
Others
:
[]
*
pb
.
OtherMessage
{
{
Value
:
[]
byte
(
"some bytes"
),
},
},
Somegroup
:
&
pb
.
MyMessage_SomeGroup
{
GroupField
:
proto
.
Int32
(
6
),
},
RepBytes
:
[][]
byte
{[]
byte
(
"sham"
),
[]
byte
(
"wow"
)},
}
func
init
()
{
ext
:=
&
pb
.
Ext
{
Data
:
proto
.
String
(
"extension"
),
}
if
err
:=
proto
.
SetExtension
(
cloneTestMessage
,
pb
.
E_Ext_More
,
ext
);
err
!=
nil
{
panic
(
"SetExtension: "
+
err
.
Error
())
}
}
func
TestClone
(
t
*
testing
.
T
)
{
m
:=
proto
.
Clone
(
cloneTestMessage
)
.
(
*
pb
.
MyMessage
)
if
!
proto
.
Equal
(
m
,
cloneTestMessage
)
{
t
.
Errorf
(
"Clone(%v) = %v"
,
cloneTestMessage
,
m
)
}
// Verify it was a deep copy.
*
m
.
Inner
.
Port
++
if
proto
.
Equal
(
m
,
cloneTestMessage
)
{
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
)
{
var
m
*
pb
.
MyMessage
if
c
:=
proto
.
Clone
(
m
);
!
proto
.
Equal
(
m
,
c
)
{
t
.
Errorf
(
"Clone(%v) = %v"
,
m
,
c
)
}
}
var
mergeTests
=
[]
struct
{
src
,
dst
,
want
proto
.
Message
}{
{
src
:
&
pb
.
MyMessage
{
Count
:
proto
.
Int32
(
42
),
},
dst
:
&
pb
.
MyMessage
{
Name
:
proto
.
String
(
"Dave"
),
},
want
:
&
pb
.
MyMessage
{
Count
:
proto
.
Int32
(
42
),
Name
:
proto
.
String
(
"Dave"
),
},
},
{
src
:
&
pb
.
MyMessage
{
Inner
:
&
pb
.
InnerMessage
{
Host
:
proto
.
String
(
"hey"
),
Connected
:
proto
.
Bool
(
true
),
},
Pet
:
[]
string
{
"horsey"
},
Others
:
[]
*
pb
.
OtherMessage
{
{
Value
:
[]
byte
(
"some bytes"
),
},
},
},
dst
:
&
pb
.
MyMessage
{
Inner
:
&
pb
.
InnerMessage
{
Host
:
proto
.
String
(
"niles"
),
Port
:
proto
.
Int32
(
9099
),
},
Pet
:
[]
string
{
"bunny"
,
"kitty"
},
Others
:
[]
*
pb
.
OtherMessage
{
{
Key
:
proto
.
Int64
(
31415926535
),
},
{
// Explicitly test a src=nil field
Inner
:
nil
,
},
},
},
want
:
&
pb
.
MyMessage
{
Inner
:
&
pb
.
InnerMessage
{
Host
:
proto
.
String
(
"hey"
),
Connected
:
proto
.
Bool
(
true
),
Port
:
proto
.
Int32
(
9099
),
},
Pet
:
[]
string
{
"bunny"
,
"kitty"
,
"horsey"
},
Others
:
[]
*
pb
.
OtherMessage
{
{
Key
:
proto
.
Int64
(
31415926535
),
},
{},
{
Value
:
[]
byte
(
"some bytes"
),
},
},
},
},
{
src
:
&
pb
.
MyMessage
{
RepBytes
:
[][]
byte
{[]
byte
(
"wow"
)},
},
dst
:
&
pb
.
MyMessage
{
Somegroup
:
&
pb
.
MyMessage_SomeGroup
{
GroupField
:
proto
.
Int32
(
6
),
},
RepBytes
:
[][]
byte
{[]
byte
(
"sham"
)},
},
want
:
&
pb
.
MyMessage
{
Somegroup
:
&
pb
.
MyMessage_SomeGroup
{
GroupField
:
proto
.
Int32
(
6
),
},
RepBytes
:
[][]
byte
{[]
byte
(
"sham"
),
[]
byte
(
"wow"
)},
},
},
// Check that a scalar bytes field replaces rather than appends.
{
src
:
&
pb
.
OtherMessage
{
Value
:
[]
byte
(
"foo"
)},
dst
:
&
pb
.
OtherMessage
{
Value
:
[]
byte
(
"bar"
)},
want
:
&
pb
.
OtherMessage
{
Value
:
[]
byte
(
"foo"
)},
},
{
src
:
&
pb
.
MessageWithMap
{
NameMapping
:
map
[
int32
]
string
{
6
:
"Nigel"
},
MsgMapping
:
map
[
int64
]
*
pb
.
FloatingPoint
{
0x4001
:
{
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
:
{
F
:
proto
.
Float64
(
2.0
)},
},
ByteMapping
:
map
[
bool
][]
byte
{
true
:
[]
byte
(
"wowsa"
)},
},
},
// proto3 shouldn't merge zero values,
// in the same way that proto2 shouldn't merge nils.
{
src
:
&
proto3pb
.
Message
{
Name
:
"Aaron"
,
Data
:
[]
byte
(
""
),
// zero value, but not nil
},
dst
:
&
proto3pb
.
Message
{
HeightInCm
:
176
,
Data
:
[]
byte
(
"texas!"
),
},
want
:
&
proto3pb
.
Message
{
Name
:
"Aaron"
,
HeightInCm
:
176
,
Data
:
[]
byte
(
"texas!"
),
},
},
// Oneof fields should merge by assignment.
{
src
:
&
pb
.
Communique
{
Union
:
&
pb
.
Communique_Number
{
Number
:
41
},
},
dst
:
&
pb
.
Communique
{
Union
:
&
pb
.
Communique_Name
{
Name
:
"Bobby Tables"
},
},
want
:
&
pb
.
Communique
{
Union
:
&
pb
.
Communique_Number
{
Number
:
41
},
},
},
// Oneof nil is the same as not set.
{
src
:
&
pb
.
Communique
{},
dst
:
&
pb
.
Communique
{
Union
:
&
pb
.
Communique_Name
{
Name
:
"Bobby Tables"
},
},
want
:
&
pb
.
Communique
{
Union
:
&
pb
.
Communique_Name
{
Name
:
"Bobby Tables"
},
},
},
}
func
TestMerge
(
t
*
testing
.
T
)
{
for
_
,
m
:=
range
mergeTests
{
got
:=
proto
.
Clone
(
m
.
dst
)
proto
.
Merge
(
got
,
m
.
src
)
if
!
proto
.
Equal
(
got
,
m
.
want
)
{
t
.
Errorf
(
"Merge(%v, %v)
\n
got %v
\n
want %v
\n
"
,
m
.
dst
,
m
.
src
,
got
,
m
.
want
)
}
}
}
vendor/QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto/decode.go
0 → 100644
View file @
8f79df77
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2010 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
/*
* Routines for decoding protocol buffer data to construct in-memory representations.
*/
import
(
"errors"
"fmt"
"io"
"os"
"reflect"
)
// errOverflow is returned when an integer is too large to be represented.
var
errOverflow
=
errors
.
New
(
"proto: integer overflow"
)
// ErrInternalBadWireType is returned by generated code when an incorrect
// wire type is encountered. It does not get returned to user code.
var
ErrInternalBadWireType
=
errors
.
New
(
"proto: internal error: bad wiretype for oneof"
)
// The fundamental decoders that interpret bytes on the wire.
// Those that take integer types all return uint64 and are
// therefore of type valueDecoder.
// DecodeVarint reads a varint-encoded integer from the slice.
// It returns the integer and the number of bytes consumed, or
// zero if there is not enough.
// This is the format for the
// int32, int64, uint32, uint64, bool, and enum
// protocol buffer types.
func
DecodeVarint
(
buf
[]
byte
)
(
x
uint64
,
n
int
)
{
// x, n already 0
for
shift
:=
uint
(
0
);
shift
<
64
;
shift
+=
7
{
if
n
>=
len
(
buf
)
{
return
0
,
0
}
b
:=
uint64
(
buf
[
n
])
n
++
x
|=
(
b
&
0x7F
)
<<
shift
if
(
b
&
0x80
)
==
0
{
return
x
,
n
}
}
// The number is too large to represent in a 64-bit value.
return
0
,
0
}
// DecodeVarint reads a varint-encoded integer from the Buffer.
// This is the format for the
// int32, int64, uint32, uint64, bool, and enum
// protocol buffer types.
func
(
p
*
Buffer
)
DecodeVarint
()
(
x
uint64
,
err
error
)
{
// x, err already 0
i
:=
p
.
index
l
:=
len
(
p
.
buf
)
for
shift
:=
uint
(
0
);
shift
<
64
;
shift
+=
7
{
if
i
>=
l
{
err
=
io
.
ErrUnexpectedEOF
return
}
b
:=
p
.
buf
[
i
]
i
++
x
|=
(
uint64
(
b
)
&
0x7F
)
<<
shift
if
b
<
0x80
{
p
.
index
=
i
return
}
}
// The number is too large to represent in a 64-bit value.
err
=
errOverflow
return
}
// DecodeFixed64 reads a 64-bit integer from the Buffer.
// This is the format for the
// fixed64, sfixed64, and double protocol buffer types.
func
(
p
*
Buffer
)
DecodeFixed64
()
(
x
uint64
,
err
error
)
{
// x, err already 0
i
:=
p
.
index
+
8
if
i
<
0
||
i
>
len
(
p
.
buf
)
{
err
=
io
.
ErrUnexpectedEOF
return
}
p
.
index
=
i
x
=
uint64
(
p
.
buf
[
i
-
8
])
x
|=
uint64
(
p
.
buf
[
i
-
7
])
<<
8
x
|=
uint64
(
p
.
buf
[
i
-
6
])
<<
16
x
|=
uint64
(
p
.
buf
[
i
-
5
])
<<
24
x
|=
uint64
(
p
.
buf
[
i
-
4
])
<<
32
x
|=
uint64
(
p
.
buf
[
i
-
3
])
<<
40
x
|=
uint64
(
p
.
buf
[
i
-
2
])
<<
48
x
|=
uint64
(
p
.
buf
[
i
-
1
])
<<
56
return
}
// DecodeFixed32 reads a 32-bit integer from the Buffer.
// This is the format for the
// fixed32, sfixed32, and float protocol buffer types.
func
(
p
*
Buffer
)
DecodeFixed32
()
(
x
uint64
,
err
error
)
{
// x, err already 0
i
:=
p
.
index
+
4
if
i
<
0
||
i
>
len
(
p
.
buf
)
{
err
=
io
.
ErrUnexpectedEOF
return
}
p
.
index
=
i
x
=
uint64
(
p
.
buf
[
i
-
4
])
x
|=
uint64
(
p
.
buf
[
i
-
3
])
<<
8
x
|=
uint64
(
p
.
buf
[
i
-
2
])
<<
16
x
|=
uint64
(
p
.
buf
[
i
-
1
])
<<
24
return
}
// DecodeZigzag64 reads a zigzag-encoded 64-bit integer
// from the Buffer.
// This is the format used for the sint64 protocol buffer type.
func
(
p
*
Buffer
)
DecodeZigzag64
()
(
x
uint64
,
err
error
)
{
x
,
err
=
p
.
DecodeVarint
()
if
err
!=
nil
{
return
}
x
=
(
x
>>
1
)
^
uint64
((
int64
(
x
&
1
)
<<
63
)
>>
63
)
return
}
// DecodeZigzag32 reads a zigzag-encoded 32-bit integer
// from the Buffer.
// This is the format used for the sint32 protocol buffer type.
func
(
p
*
Buffer
)
DecodeZigzag32
()
(
x
uint64
,
err
error
)
{
x
,
err
=
p
.
DecodeVarint
()
if
err
!=
nil
{
return
}
x
=
uint64
((
uint32
(
x
)
>>
1
)
^
uint32
((
int32
(
x
&
1
)
<<
31
)
>>
31
))
return
}
// These are not ValueDecoders: they produce an array of bytes or a string.
// bytes, embedded messages
// DecodeRawBytes reads a count-delimited byte buffer from the Buffer.
// This is the format used for the bytes protocol buffer
// type and for embedded messages.
func
(
p
*
Buffer
)
DecodeRawBytes
(
alloc
bool
)
(
buf
[]
byte
,
err
error
)
{
n
,
err
:=
p
.
DecodeVarint
()
if
err
!=
nil
{
return
nil
,
err
}
nb
:=
int
(
n
)
if
nb
<
0
{
return
nil
,
fmt
.
Errorf
(
"proto: bad byte length %d"
,
nb
)
}
end
:=
p
.
index
+
nb
if
end
<
p
.
index
||
end
>
len
(
p
.
buf
)
{
return
nil
,
io
.
ErrUnexpectedEOF
}
if
!
alloc
{
// todo: check if can get more uses of alloc=false
buf
=
p
.
buf
[
p
.
index
:
end
]
p
.
index
+=
nb
return
}
buf
=
make
([]
byte
,
nb
)
copy
(
buf
,
p
.
buf
[
p
.
index
:
])
p
.
index
+=
nb
return
}
// DecodeStringBytes reads an encoded string from the Buffer.
// This is the format used for the proto2 string type.
func
(
p
*
Buffer
)
DecodeStringBytes
()
(
s
string
,
err
error
)
{
buf
,
err
:=
p
.
DecodeRawBytes
(
false
)
if
err
!=
nil
{
return
}
return
string
(
buf
),
nil
}
// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
// If the protocol buffer has extensions, and the field matches, add it as an extension.
// Otherwise, if the XXX_unrecognized field exists, append the skipped data there.
func
(
o
*
Buffer
)
skipAndSave
(
t
reflect
.
Type
,
tag
,
wire
int
,
base
structPointer
,
unrecField
field
)
error
{
oi
:=
o
.
index
err
:=
o
.
skip
(
t
,
tag
,
wire
)
if
err
!=
nil
{
return
err
}
if
!
unrecField
.
IsValid
()
{
return
nil
}
ptr
:=
structPointer_Bytes
(
base
,
unrecField
)
// Add the skipped field to struct field
obuf
:=
o
.
buf
o
.
buf
=
*
ptr
o
.
EncodeVarint
(
uint64
(
tag
<<
3
|
wire
))
*
ptr
=
append
(
o
.
buf
,
obuf
[
oi
:
o
.
index
]
...
)
o
.
buf
=
obuf
return
nil
}
// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
func
(
o
*
Buffer
)
skip
(
t
reflect
.
Type
,
tag
,
wire
int
)
error
{
var
u
uint64
var
err
error
switch
wire
{
case
WireVarint
:
_
,
err
=
o
.
DecodeVarint
()
case
WireFixed64
:
_
,
err
=
o
.
DecodeFixed64
()
case
WireBytes
:
_
,
err
=
o
.
DecodeRawBytes
(
false
)
case
WireFixed32
:
_
,
err
=
o
.
DecodeFixed32
()
case
WireStartGroup
:
for
{
u
,
err
=
o
.
DecodeVarint
()
if
err
!=
nil
{
break
}
fwire
:=
int
(
u
&
0x7
)
if
fwire
==
WireEndGroup
{
break
}
ftag
:=
int
(
u
>>
3
)
err
=
o
.
skip
(
t
,
ftag
,
fwire
)
if
err
!=
nil
{
break
}
}
default
:
err
=
fmt
.
Errorf
(
"proto: can't skip unknown wire type %d for %s"
,
wire
,
t
)
}
return
err
}
// Unmarshaler is the interface representing objects that can
// unmarshal themselves. The method should reset the receiver before
// decoding starts. The argument points to data that may be
// overwritten, so implementations should not keep references to the
// buffer.
type
Unmarshaler
interface
{
Unmarshal
([]
byte
)
error
}
// Unmarshal parses the protocol buffer representation in buf and places the
// decoded result in pb. If the struct underlying pb does not match
// the data in buf, the results can be unpredictable.
//
// Unmarshal resets pb before starting to unmarshal, so any
// existing data in pb is always removed. Use UnmarshalMerge
// to preserve and append to existing data.
func
Unmarshal
(
buf
[]
byte
,
pb
Message
)
error
{
pb
.
Reset
()
return
UnmarshalMerge
(
buf
,
pb
)
}
// UnmarshalMerge parses the protocol buffer representation in buf and
// writes the decoded result to pb. If the struct underlying pb does not match
// the data in buf, the results can be unpredictable.
//
// UnmarshalMerge merges into existing data in pb.
// Most code should use Unmarshal instead.
func
UnmarshalMerge
(
buf
[]
byte
,
pb
Message
)
error
{
// If the object can unmarshal itself, let it.
if
u
,
ok
:=
pb
.
(
Unmarshaler
);
ok
{
return
u
.
Unmarshal
(
buf
)
}
return
NewBuffer
(
buf
)
.
Unmarshal
(
pb
)
}
// DecodeMessage reads a count-delimited message from the Buffer.
func
(
p
*
Buffer
)
DecodeMessage
(
pb
Message
)
error
{
enc
,
err
:=
p
.
DecodeRawBytes
(
false
)
if
err
!=
nil
{
return
err
}
return
NewBuffer
(
enc
)
.
Unmarshal
(
pb
)
}
// DecodeGroup reads a tag-delimited group from the Buffer.
func
(
p
*
Buffer
)
DecodeGroup
(
pb
Message
)
error
{
typ
,
base
,
err
:=
getbase
(
pb
)
if
err
!=
nil
{
return
err
}
return
p
.
unmarshalType
(
typ
.
Elem
(),
GetProperties
(
typ
.
Elem
()),
true
,
base
)
}
// Unmarshal parses the protocol buffer representation in the
// Buffer and places the decoded result in pb. If the struct
// underlying pb does not match the data in the buffer, the results can be
// unpredictable.
func
(
p
*
Buffer
)
Unmarshal
(
pb
Message
)
error
{
// If the object can unmarshal itself, let it.
if
u
,
ok
:=
pb
.
(
Unmarshaler
);
ok
{
err
:=
u
.
Unmarshal
(
p
.
buf
[
p
.
index
:
])
p
.
index
=
len
(
p
.
buf
)
return
err
}
typ
,
base
,
err
:=
getbase
(
pb
)
if
err
!=
nil
{
return
err
}
err
=
p
.
unmarshalType
(
typ
.
Elem
(),
GetProperties
(
typ
.
Elem
()),
false
,
base
)
if
collectStats
{
stats
.
Decode
++
}
return
err
}
// unmarshalType does the work of unmarshaling a structure.
func
(
o
*
Buffer
)
unmarshalType
(
st
reflect
.
Type
,
prop
*
StructProperties
,
is_group
bool
,
base
structPointer
)
error
{
var
state
errorState
required
,
reqFields
:=
prop
.
reqCount
,
uint64
(
0
)
var
err
error
for
err
==
nil
&&
o
.
index
<
len
(
o
.
buf
)
{
oi
:=
o
.
index
var
u
uint64
u
,
err
=
o
.
DecodeVarint
()
if
err
!=
nil
{
break
}
wire
:=
int
(
u
&
0x7
)
if
wire
==
WireEndGroup
{
if
is_group
{
return
nil
// input is satisfied
}
return
fmt
.
Errorf
(
"proto: %s: wiretype end group for non-group"
,
st
)
}
tag
:=
int
(
u
>>
3
)
if
tag
<=
0
{
return
fmt
.
Errorf
(
"proto: %s: illegal tag %d (wire type %d)"
,
st
,
tag
,
wire
)
}
fieldnum
,
ok
:=
prop
.
decoderTags
.
get
(
tag
)
if
!
ok
{
// Maybe it's an extension?
if
prop
.
extendable
{
if
e
:=
structPointer_Interface
(
base
,
st
)
.
(
extendableProto
);
isExtensionField
(
e
,
int32
(
tag
))
{
if
err
=
o
.
skip
(
st
,
tag
,
wire
);
err
==
nil
{
if
ee
,
eok
:=
e
.
(
extensionsMap
);
eok
{
ext
:=
ee
.
ExtensionMap
()[
int32
(
tag
)]
// may be missing
ext
.
enc
=
append
(
ext
.
enc
,
o
.
buf
[
oi
:
o
.
index
]
...
)
ee
.
ExtensionMap
()[
int32
(
tag
)]
=
ext
}
else
if
ee
,
eok
:=
e
.
(
extensionsBytes
);
eok
{
ext
:=
ee
.
GetExtensions
()
*
ext
=
append
(
*
ext
,
o
.
buf
[
oi
:
o
.
index
]
...
)
}
}
continue
}
}
// Maybe it's a oneof?
if
prop
.
oneofUnmarshaler
!=
nil
{
m
:=
structPointer_Interface
(
base
,
st
)
.
(
Message
)
// First return value indicates whether tag is a oneof field.
ok
,
err
=
prop
.
oneofUnmarshaler
(
m
,
tag
,
wire
,
o
)
if
err
==
ErrInternalBadWireType
{
// Map the error to something more descriptive.
// Do the formatting here to save generated code space.
err
=
fmt
.
Errorf
(
"bad wiretype for oneof field in %T"
,
m
)
}
if
ok
{
continue
}
}
err
=
o
.
skipAndSave
(
st
,
tag
,
wire
,
base
,
prop
.
unrecField
)
continue
}
p
:=
prop
.
Prop
[
fieldnum
]
if
p
.
dec
==
nil
{
fmt
.
Fprintf
(
os
.
Stderr
,
"proto: no protobuf decoder for %s.%s
\n
"
,
st
,
st
.
Field
(
fieldnum
)
.
Name
)
continue
}
dec
:=
p
.
dec
if
wire
!=
WireStartGroup
&&
wire
!=
p
.
WireType
{
if
wire
==
WireBytes
&&
p
.
packedDec
!=
nil
{
// a packable field
dec
=
p
.
packedDec
}
else
{
err
=
fmt
.
Errorf
(
"proto: bad wiretype for field %s.%s: got wiretype %d, want %d"
,
st
,
st
.
Field
(
fieldnum
)
.
Name
,
wire
,
p
.
WireType
)
continue
}
}
decErr
:=
dec
(
o
,
p
,
base
)
if
decErr
!=
nil
&&
!
state
.
shouldContinue
(
decErr
,
p
)
{
err
=
decErr
}
if
err
==
nil
&&
p
.
Required
{
// Successfully decoded a required field.
if
tag
<=
64
{
// use bitmap for fields 1-64 to catch field reuse.
var
mask
uint64
=
1
<<
uint64
(
tag
-
1
)
if
reqFields
&
mask
==
0
{
// new required field
reqFields
|=
mask
required
--
}
}
else
{
// This is imprecise. It can be fooled by a required field
// with a tag > 64 that is encoded twice; that's very rare.
// A fully correct implementation would require allocating
// a data structure, which we would like to avoid.
required
--
}
}
}
if
err
==
nil
{
if
is_group
{
return
io
.
ErrUnexpectedEOF
}
if
state
.
err
!=
nil
{
return
state
.
err
}
if
required
>
0
{
// Not enough information to determine the exact field. If we use extra
// CPU, we could determine the field only if the missing required field
// has a tag <= 64 and we check reqFields.
return
&
RequiredNotSetError
{
"{Unknown}"
}
}
}
return
err
}
// Individual type decoders
// For each,
// u is the decoded value,
// v is a pointer to the field (pointer) in the struct
// Sizes of the pools to allocate inside the Buffer.
// The goal is modest amortization and allocation
// on at least 16-byte boundaries.
const
(
boolPoolSize
=
16
uint32PoolSize
=
8
uint64PoolSize
=
4
)
// Decode a bool.
func
(
o
*
Buffer
)
dec_bool
(
p
*
Properties
,
base
structPointer
)
error
{
u
,
err
:=
p
.
valDec
(
o
)
if
err
!=
nil
{
return
err
}
if
len
(
o
.
bools
)
==
0
{
o
.
bools
=
make
([]
bool
,
boolPoolSize
)
}
o
.
bools
[
0
]
=
u
!=
0
*
structPointer_Bool
(
base
,
p
.
field
)
=
&
o
.
bools
[
0
]
o
.
bools
=
o
.
bools
[
1
:
]
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.
func
(
o
*
Buffer
)
dec_int32
(
p
*
Properties
,
base
structPointer
)
error
{
u
,
err
:=
p
.
valDec
(
o
)
if
err
!=
nil
{
return
err
}
word32_Set
(
structPointer_Word32
(
base
,
p
.
field
),
o
,
uint32
(
u
))
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.
func
(
o
*
Buffer
)
dec_int64
(
p
*
Properties
,
base
structPointer
)
error
{
u
,
err
:=
p
.
valDec
(
o
)
if
err
!=
nil
{
return
err
}
word64_Set
(
structPointer_Word64
(
base
,
p
.
field
),
o
,
u
)
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.
func
(
o
*
Buffer
)
dec_string
(
p
*
Properties
,
base
structPointer
)
error
{
s
,
err
:=
o
.
DecodeStringBytes
()
if
err
!=
nil
{
return
err
}
*
structPointer_String
(
base
,
p
.
field
)
=
&
s
return
nil
}
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
}
// Decode a slice of bytes ([]byte).
func
(
o
*
Buffer
)
dec_slice_byte
(
p
*
Properties
,
base
structPointer
)
error
{
b
,
err
:=
o
.
DecodeRawBytes
(
true
)
if
err
!=
nil
{
return
err
}
*
structPointer_Bytes
(
base
,
p
.
field
)
=
b
return
nil
}
// Decode a slice of bools ([]bool).
func
(
o
*
Buffer
)
dec_slice_bool
(
p
*
Properties
,
base
structPointer
)
error
{
u
,
err
:=
p
.
valDec
(
o
)
if
err
!=
nil
{
return
err
}
v
:=
structPointer_BoolSlice
(
base
,
p
.
field
)
*
v
=
append
(
*
v
,
u
!=
0
)
return
nil
}
// Decode a slice of bools ([]bool) in packed format.
func
(
o
*
Buffer
)
dec_slice_packed_bool
(
p
*
Properties
,
base
structPointer
)
error
{
v
:=
structPointer_BoolSlice
(
base
,
p
.
field
)
nn
,
err
:=
o
.
DecodeVarint
()
if
err
!=
nil
{
return
err
}
nb
:=
int
(
nn
)
// number of bytes of encoded bools
fin
:=
o
.
index
+
nb
if
fin
<
o
.
index
{
return
errOverflow
}
y
:=
*
v
for
o
.
index
<
fin
{
u
,
err
:=
p
.
valDec
(
o
)
if
err
!=
nil
{
return
err
}
y
=
append
(
y
,
u
!=
0
)
}
*
v
=
y
return
nil
}
// Decode a slice of int32s ([]int32).
func
(
o
*
Buffer
)
dec_slice_int32
(
p
*
Properties
,
base
structPointer
)
error
{
u
,
err
:=
p
.
valDec
(
o
)
if
err
!=
nil
{
return
err
}
structPointer_Word32Slice
(
base
,
p
.
field
)
.
Append
(
uint32
(
u
))
return
nil
}
// Decode a slice of int32s ([]int32) in packed format.
func
(
o
*
Buffer
)
dec_slice_packed_int32
(
p
*
Properties
,
base
structPointer
)
error
{
v
:=
structPointer_Word32Slice
(
base
,
p
.
field
)
nn
,
err
:=
o
.
DecodeVarint
()
if
err
!=
nil
{
return
err
}
nb
:=
int
(
nn
)
// number of bytes of encoded int32s
fin
:=
o
.
index
+
nb
if
fin
<
o
.
index
{
return
errOverflow
}
for
o
.
index
<
fin
{
u
,
err
:=
p
.
valDec
(
o
)
if
err
!=
nil
{
return
err
}
v
.
Append
(
uint32
(
u
))
}
return
nil
}
// Decode a slice of int64s ([]int64).
func
(
o
*
Buffer
)
dec_slice_int64
(
p
*
Properties
,
base
structPointer
)
error
{
u
,
err
:=
p
.
valDec
(
o
)
if
err
!=
nil
{
return
err
}
structPointer_Word64Slice
(
base
,
p
.
field
)
.
Append
(
u
)
return
nil
}
// Decode a slice of int64s ([]int64) in packed format.
func
(
o
*
Buffer
)
dec_slice_packed_int64
(
p
*
Properties
,
base
structPointer
)
error
{
v
:=
structPointer_Word64Slice
(
base
,
p
.
field
)
nn
,
err
:=
o
.
DecodeVarint
()
if
err
!=
nil
{
return
err
}
nb
:=
int
(
nn
)
// number of bytes of encoded int64s
fin
:=
o
.
index
+
nb
if
fin
<
o
.
index
{
return
errOverflow
}
for
o
.
index
<
fin
{
u
,
err
:=
p
.
valDec
(
o
)
if
err
!=
nil
{
return
err
}
v
.
Append
(
u
)
}
return
nil
}
// Decode a slice of strings ([]string).
func
(
o
*
Buffer
)
dec_slice_string
(
p
*
Properties
,
base
structPointer
)
error
{
s
,
err
:=
o
.
DecodeStringBytes
()
if
err
!=
nil
{
return
err
}
v
:=
structPointer_StringSlice
(
base
,
p
.
field
)
*
v
=
append
(
*
v
,
s
)
return
nil
}
// Decode a slice of slice of bytes ([][]byte).
func
(
o
*
Buffer
)
dec_slice_slice_byte
(
p
*
Properties
,
base
structPointer
)
error
{
b
,
err
:=
o
.
DecodeRawBytes
(
true
)
if
err
!=
nil
{
return
err
}
v
:=
structPointer_BytesSlice
(
base
,
p
.
field
)
*
v
=
append
(
*
v
,
b
)
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_NewAt
(
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
])
}
}
keyelem
,
valelem
:=
keyptr
.
Elem
(),
valptr
.
Elem
()
if
!
keyelem
.
IsValid
()
||
!
valelem
.
IsValid
()
{
// We did not decode the key or the value in the map entry.
// Either way, it's an invalid map entry.
return
fmt
.
Errorf
(
"proto: bad map data: missing key/val"
)
}
v
.
SetMapIndex
(
keyelem
,
valelem
)
return
nil
}
// Decode a group.
func
(
o
*
Buffer
)
dec_struct_group
(
p
*
Properties
,
base
structPointer
)
error
{
bas
:=
structPointer_GetStructPointer
(
base
,
p
.
field
)
if
structPointer_IsNil
(
bas
)
{
// allocate new nested message
bas
=
toStructPointer
(
reflect
.
New
(
p
.
stype
))
structPointer_SetStructPointer
(
base
,
p
.
field
,
bas
)
}
return
o
.
unmarshalType
(
p
.
stype
,
p
.
sprop
,
true
,
bas
)
}
// Decode an embedded message.
func
(
o
*
Buffer
)
dec_struct_message
(
p
*
Properties
,
base
structPointer
)
(
err
error
)
{
raw
,
e
:=
o
.
DecodeRawBytes
(
false
)
if
e
!=
nil
{
return
e
}
bas
:=
structPointer_GetStructPointer
(
base
,
p
.
field
)
if
structPointer_IsNil
(
bas
)
{
// allocate new nested message
bas
=
toStructPointer
(
reflect
.
New
(
p
.
stype
))
structPointer_SetStructPointer
(
base
,
p
.
field
,
bas
)
}
// If the object can unmarshal itself, let it.
if
p
.
isUnmarshaler
{
iv
:=
structPointer_Interface
(
bas
,
p
.
stype
)
return
iv
.
(
Unmarshaler
)
.
Unmarshal
(
raw
)
}
obuf
:=
o
.
buf
oi
:=
o
.
index
o
.
buf
=
raw
o
.
index
=
0
err
=
o
.
unmarshalType
(
p
.
stype
,
p
.
sprop
,
false
,
bas
)
o
.
buf
=
obuf
o
.
index
=
oi
return
err
}
// Decode a slice of embedded messages.
func
(
o
*
Buffer
)
dec_slice_struct_message
(
p
*
Properties
,
base
structPointer
)
error
{
return
o
.
dec_slice_struct
(
p
,
false
,
base
)
}
// Decode a slice of embedded groups.
func
(
o
*
Buffer
)
dec_slice_struct_group
(
p
*
Properties
,
base
structPointer
)
error
{
return
o
.
dec_slice_struct
(
p
,
true
,
base
)
}
// Decode a slice of structs ([]*struct).
func
(
o
*
Buffer
)
dec_slice_struct
(
p
*
Properties
,
is_group
bool
,
base
structPointer
)
error
{
v
:=
reflect
.
New
(
p
.
stype
)
bas
:=
toStructPointer
(
v
)
structPointer_StructPointerSlice
(
base
,
p
.
field
)
.
Append
(
bas
)
if
is_group
{
err
:=
o
.
unmarshalType
(
p
.
stype
,
p
.
sprop
,
is_group
,
bas
)
return
err
}
raw
,
err
:=
o
.
DecodeRawBytes
(
false
)
if
err
!=
nil
{
return
err
}
// If the object can unmarshal itself, let it.
if
p
.
isUnmarshaler
{
iv
:=
v
.
Interface
()
return
iv
.
(
Unmarshaler
)
.
Unmarshal
(
raw
)
}
obuf
:=
o
.
buf
oi
:=
o
.
index
o
.
buf
=
raw
o
.
index
=
0
err
=
o
.
unmarshalType
(
p
.
stype
,
p
.
sprop
,
is_group
,
bas
)
o
.
buf
=
obuf
o
.
index
=
oi
return
err
}
vendor/QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto/decode_gogo.go
0 → 100644
View file @
8f79df77
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
// http://github.com/gogo/protobuf/gogoproto
//
// 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.
//
// 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
import
(
"reflect"
)
// Decode a reference to a struct pointer.
func
(
o
*
Buffer
)
dec_ref_struct_message
(
p
*
Properties
,
base
structPointer
)
(
err
error
)
{
raw
,
e
:=
o
.
DecodeRawBytes
(
false
)
if
e
!=
nil
{
return
e
}
// If the object can unmarshal itself, let it.
if
p
.
isUnmarshaler
{
panic
(
"not supported, since this is a pointer receiver"
)
}
obuf
:=
o
.
buf
oi
:=
o
.
index
o
.
buf
=
raw
o
.
index
=
0
bas
:=
structPointer_FieldPointer
(
base
,
p
.
field
)
err
=
o
.
unmarshalType
(
p
.
stype
,
p
.
sprop
,
false
,
bas
)
o
.
buf
=
obuf
o
.
index
=
oi
return
err
}
// Decode a slice of references to struct pointers ([]struct).
func
(
o
*
Buffer
)
dec_slice_ref_struct
(
p
*
Properties
,
is_group
bool
,
base
structPointer
)
error
{
newBas
:=
appendStructPointer
(
base
,
p
.
field
,
p
.
sstype
)
if
is_group
{
panic
(
"not supported, maybe in future, if requested."
)
}
raw
,
err
:=
o
.
DecodeRawBytes
(
false
)
if
err
!=
nil
{
return
err
}
// If the object can unmarshal itself, let it.
if
p
.
isUnmarshaler
{
panic
(
"not supported, since this is not a pointer receiver."
)
}
obuf
:=
o
.
buf
oi
:=
o
.
index
o
.
buf
=
raw
o
.
index
=
0
err
=
o
.
unmarshalType
(
p
.
stype
,
p
.
sprop
,
is_group
,
newBas
)
o
.
buf
=
obuf
o
.
index
=
oi
return
err
}
// Decode a slice of references to struct pointers.
func
(
o
*
Buffer
)
dec_slice_ref_struct_message
(
p
*
Properties
,
base
structPointer
)
error
{
return
o
.
dec_slice_ref_struct
(
p
,
false
,
base
)
}
func
setPtrCustomType
(
base
structPointer
,
f
field
,
v
interface
{})
{
if
v
==
nil
{
return
}
structPointer_SetStructPointer
(
base
,
f
,
structPointer
(
reflect
.
ValueOf
(
v
)
.
Pointer
()))
}
func
setCustomType
(
base
structPointer
,
f
field
,
value
interface
{})
{
if
value
==
nil
{
return
}
v
:=
reflect
.
ValueOf
(
value
)
.
Elem
()
t
:=
reflect
.
TypeOf
(
value
)
.
Elem
()
kind
:=
t
.
Kind
()
switch
kind
{
case
reflect
.
Slice
:
slice
:=
reflect
.
MakeSlice
(
t
,
v
.
Len
(),
v
.
Cap
())
reflect
.
Copy
(
slice
,
v
)
oldHeader
:=
structPointer_GetSliceHeader
(
base
,
f
)
oldHeader
.
Data
=
slice
.
Pointer
()
oldHeader
.
Len
=
v
.
Len
()
oldHeader
.
Cap
=
v
.
Cap
()
default
:
l
:=
1
size
:=
reflect
.
TypeOf
(
value
)
.
Elem
()
.
Size
()
if
kind
==
reflect
.
Array
{
l
=
reflect
.
TypeOf
(
value
)
.
Elem
()
.
Len
()
size
=
reflect
.
TypeOf
(
value
)
.
Size
()
}
total
:=
int
(
size
)
*
l
structPointer_Copy
(
toStructPointer
(
reflect
.
ValueOf
(
value
)),
structPointer_Add
(
base
,
f
),
total
)
}
}
func
(
o
*
Buffer
)
dec_custom_bytes
(
p
*
Properties
,
base
structPointer
)
error
{
b
,
err
:=
o
.
DecodeRawBytes
(
true
)
if
err
!=
nil
{
return
err
}
i
:=
reflect
.
New
(
p
.
ctype
.
Elem
())
.
Interface
()
custom
:=
(
i
)
.
(
Unmarshaler
)
if
err
:=
custom
.
Unmarshal
(
b
);
err
!=
nil
{
return
err
}
setPtrCustomType
(
base
,
p
.
field
,
custom
)
return
nil
}
func
(
o
*
Buffer
)
dec_custom_ref_bytes
(
p
*
Properties
,
base
structPointer
)
error
{
b
,
err
:=
o
.
DecodeRawBytes
(
true
)
if
err
!=
nil
{
return
err
}
i
:=
reflect
.
New
(
p
.
ctype
)
.
Interface
()
custom
:=
(
i
)
.
(
Unmarshaler
)
if
err
:=
custom
.
Unmarshal
(
b
);
err
!=
nil
{
return
err
}
if
custom
!=
nil
{
setCustomType
(
base
,
p
.
field
,
custom
)
}
return
nil
}
// Decode a slice of bytes ([]byte) into a slice of custom types.
func
(
o
*
Buffer
)
dec_custom_slice_bytes
(
p
*
Properties
,
base
structPointer
)
error
{
b
,
err
:=
o
.
DecodeRawBytes
(
true
)
if
err
!=
nil
{
return
err
}
i
:=
reflect
.
New
(
p
.
ctype
.
Elem
())
.
Interface
()
custom
:=
(
i
)
.
(
Unmarshaler
)
if
err
:=
custom
.
Unmarshal
(
b
);
err
!=
nil
{
return
err
}
newBas
:=
appendStructPointer
(
base
,
p
.
field
,
p
.
ctype
)
setCustomType
(
newBas
,
0
,
custom
)
return
nil
}
vendor/QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto/encode.go
0 → 100644
View file @
8f79df77
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2010 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
/*
* Routines for encoding data into the wire format for protocol buffers.
*/
import
(
"errors"
"fmt"
"reflect"
"sort"
)
// RequiredNotSetError is the error returned if Marshal is called with
// a protocol buffer struct whose required fields have not
// all been initialized. It is also the error returned if Unmarshal is
// called with an encoded protocol buffer that does not include all the
// required fields.
//
// When printed, RequiredNotSetError reports the first unset required field in a
// message. If the field cannot be precisely determined, it is reported as
// "{Unknown}".
type
RequiredNotSetError
struct
{
field
string
}
func
(
e
*
RequiredNotSetError
)
Error
()
string
{
return
fmt
.
Sprintf
(
"proto: required field %q not set"
,
e
.
field
)
}
var
(
// errRepeatedHasNil is the error returned if Marshal is called with
// a struct with a repeated field containing a nil element.
errRepeatedHasNil
=
errors
.
New
(
"proto: repeated field has nil element"
)
// ErrNil is the error returned if Marshal is called with nil.
ErrNil
=
errors
.
New
(
"proto: Marshal called with nil"
)
)
// The fundamental encoders that put bytes on the wire.
// Those that take integer types all accept uint64 and are
// therefore of type valueEncoder.
const
maxVarintBytes
=
10
// maximum length of a varint
// EncodeVarint returns the varint encoding of x.
// This is the format for the
// int32, int64, uint32, uint64, bool, and enum
// protocol buffer types.
// Not used by the package itself, but helpful to clients
// wishing to use the same encoding.
func
EncodeVarint
(
x
uint64
)
[]
byte
{
var
buf
[
maxVarintBytes
]
byte
var
n
int
for
n
=
0
;
x
>
127
;
n
++
{
buf
[
n
]
=
0x80
|
uint8
(
x
&
0x7F
)
x
>>=
7
}
buf
[
n
]
=
uint8
(
x
)
n
++
return
buf
[
0
:
n
]
}
// EncodeVarint writes a varint-encoded integer to the Buffer.
// This is the format for the
// int32, int64, uint32, uint64, bool, and enum
// protocol buffer types.
func
(
p
*
Buffer
)
EncodeVarint
(
x
uint64
)
error
{
for
x
>=
1
<<
7
{
p
.
buf
=
append
(
p
.
buf
,
uint8
(
x
&
0x7f
|
0x80
))
x
>>=
7
}
p
.
buf
=
append
(
p
.
buf
,
uint8
(
x
))
return
nil
}
func
sizeVarint
(
x
uint64
)
(
n
int
)
{
for
{
n
++
x
>>=
7
if
x
==
0
{
break
}
}
return
n
}
// EncodeFixed64 writes a 64-bit integer to the Buffer.
// This is the format for the
// fixed64, sfixed64, and double protocol buffer types.
func
(
p
*
Buffer
)
EncodeFixed64
(
x
uint64
)
error
{
p
.
buf
=
append
(
p
.
buf
,
uint8
(
x
),
uint8
(
x
>>
8
),
uint8
(
x
>>
16
),
uint8
(
x
>>
24
),
uint8
(
x
>>
32
),
uint8
(
x
>>
40
),
uint8
(
x
>>
48
),
uint8
(
x
>>
56
))
return
nil
}
func
sizeFixed64
(
x
uint64
)
int
{
return
8
}
// EncodeFixed32 writes a 32-bit integer to the Buffer.
// This is the format for the
// fixed32, sfixed32, and float protocol buffer types.
func
(
p
*
Buffer
)
EncodeFixed32
(
x
uint64
)
error
{
p
.
buf
=
append
(
p
.
buf
,
uint8
(
x
),
uint8
(
x
>>
8
),
uint8
(
x
>>
16
),
uint8
(
x
>>
24
))
return
nil
}
func
sizeFixed32
(
x
uint64
)
int
{
return
4
}
// EncodeZigzag64 writes a zigzag-encoded 64-bit integer
// to the Buffer.
// This is the format used for the sint64 protocol buffer type.
func
(
p
*
Buffer
)
EncodeZigzag64
(
x
uint64
)
error
{
// use signed number to get arithmetic right shift.
return
p
.
EncodeVarint
(
uint64
((
x
<<
1
)
^
uint64
((
int64
(
x
)
>>
63
))))
}
func
sizeZigzag64
(
x
uint64
)
int
{
return
sizeVarint
(
uint64
((
x
<<
1
)
^
uint64
((
int64
(
x
)
>>
63
))))
}
// EncodeZigzag32 writes a zigzag-encoded 32-bit integer
// to the Buffer.
// This is the format used for the sint32 protocol buffer type.
func
(
p
*
Buffer
)
EncodeZigzag32
(
x
uint64
)
error
{
// use signed number to get arithmetic right shift.
return
p
.
EncodeVarint
(
uint64
((
uint32
(
x
)
<<
1
)
^
uint32
((
int32
(
x
)
>>
31
))))
}
func
sizeZigzag32
(
x
uint64
)
int
{
return
sizeVarint
(
uint64
((
uint32
(
x
)
<<
1
)
^
uint32
((
int32
(
x
)
>>
31
))))
}
// EncodeRawBytes writes a count-delimited byte buffer to the Buffer.
// This is the format used for the bytes protocol buffer
// type and for embedded messages.
func
(
p
*
Buffer
)
EncodeRawBytes
(
b
[]
byte
)
error
{
p
.
EncodeVarint
(
uint64
(
len
(
b
)))
p
.
buf
=
append
(
p
.
buf
,
b
...
)
return
nil
}
func
sizeRawBytes
(
b
[]
byte
)
int
{
return
sizeVarint
(
uint64
(
len
(
b
)))
+
len
(
b
)
}
// EncodeStringBytes writes an encoded string to the Buffer.
// This is the format used for the proto2 string type.
func
(
p
*
Buffer
)
EncodeStringBytes
(
s
string
)
error
{
p
.
EncodeVarint
(
uint64
(
len
(
s
)))
p
.
buf
=
append
(
p
.
buf
,
s
...
)
return
nil
}
func
sizeStringBytes
(
s
string
)
int
{
return
sizeVarint
(
uint64
(
len
(
s
)))
+
len
(
s
)
}
// Marshaler is the interface representing objects that can marshal themselves.
type
Marshaler
interface
{
Marshal
()
([]
byte
,
error
)
}
// Marshal takes the protocol buffer
// and encodes it into the wire format, returning the data.
func
Marshal
(
pb
Message
)
([]
byte
,
error
)
{
// Can the object marshal itself?
if
m
,
ok
:=
pb
.
(
Marshaler
);
ok
{
return
m
.
Marshal
()
}
p
:=
NewBuffer
(
nil
)
err
:=
p
.
Marshal
(
pb
)
var
state
errorState
if
err
!=
nil
&&
!
state
.
shouldContinue
(
err
,
nil
)
{
return
nil
,
err
}
if
p
.
buf
==
nil
&&
err
==
nil
{
// Return a non-nil slice on success.
return
[]
byte
{},
nil
}
return
p
.
buf
,
err
}
// EncodeMessage writes the protocol buffer to the Buffer,
// prefixed by a varint-encoded length.
func
(
p
*
Buffer
)
EncodeMessage
(
pb
Message
)
error
{
t
,
base
,
err
:=
getbase
(
pb
)
if
structPointer_IsNil
(
base
)
{
return
ErrNil
}
if
err
==
nil
{
var
state
errorState
err
=
p
.
enc_len_struct
(
GetProperties
(
t
.
Elem
()),
base
,
&
state
)
}
return
err
}
// Marshal takes the protocol buffer
// and encodes it into the wire format, writing the result to the
// Buffer.
func
(
p
*
Buffer
)
Marshal
(
pb
Message
)
error
{
// Can the object marshal itself?
if
m
,
ok
:=
pb
.
(
Marshaler
);
ok
{
data
,
err
:=
m
.
Marshal
()
if
err
!=
nil
{
return
err
}
p
.
buf
=
append
(
p
.
buf
,
data
...
)
return
nil
}
t
,
base
,
err
:=
getbase
(
pb
)
if
structPointer_IsNil
(
base
)
{
return
ErrNil
}
if
err
==
nil
{
err
=
p
.
enc_struct
(
GetProperties
(
t
.
Elem
()),
base
)
}
if
collectStats
{
stats
.
Encode
++
}
return
err
}
// Size returns the encoded size of a protocol buffer.
func
Size
(
pb
Message
)
(
n
int
)
{
// Can the object marshal itself? If so, Size is slow.
// TODO: add Size to Marshaler, or add a Sizer interface.
if
m
,
ok
:=
pb
.
(
Marshaler
);
ok
{
b
,
_
:=
m
.
Marshal
()
return
len
(
b
)
}
t
,
base
,
err
:=
getbase
(
pb
)
if
structPointer_IsNil
(
base
)
{
return
0
}
if
err
==
nil
{
n
=
size_struct
(
GetProperties
(
t
.
Elem
()),
base
)
}
if
collectStats
{
stats
.
Size
++
}
return
}
// Individual type encoders.
// Encode a bool.
func
(
o
*
Buffer
)
enc_bool
(
p
*
Properties
,
base
structPointer
)
error
{
v
:=
*
structPointer_Bool
(
base
,
p
.
field
)
if
v
==
nil
{
return
ErrNil
}
x
:=
0
if
*
v
{
x
=
1
}
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
p
.
valEnc
(
o
,
uint64
(
x
))
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
{
v
:=
*
structPointer_Bool
(
base
,
p
.
field
)
if
v
==
nil
{
return
0
}
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
&&
!
p
.
oneof
{
return
0
}
return
len
(
p
.
tagcode
)
+
1
// each bool takes exactly one byte
}
// Encode an int32.
func
(
o
*
Buffer
)
enc_int32
(
p
*
Properties
,
base
structPointer
)
error
{
v
:=
structPointer_Word32
(
base
,
p
.
field
)
if
word32_IsNil
(
v
)
{
return
ErrNil
}
x
:=
int32
(
word32_Get
(
v
))
// permit sign extension to use full 64-bit range
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
p
.
valEnc
(
o
,
uint64
(
x
))
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
)
{
v
:=
structPointer_Word32
(
base
,
p
.
field
)
if
word32_IsNil
(
v
)
{
return
0
}
x
:=
int32
(
word32_Get
(
v
))
// permit sign extension to use full 64-bit range
n
+=
len
(
p
.
tagcode
)
n
+=
p
.
valSize
(
uint64
(
x
))
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
&&
!
p
.
oneof
{
return
0
}
n
+=
len
(
p
.
tagcode
)
n
+=
p
.
valSize
(
uint64
(
x
))
return
}
// Encode a uint32.
// Exactly the same as int32, except for no sign extension.
func
(
o
*
Buffer
)
enc_uint32
(
p
*
Properties
,
base
structPointer
)
error
{
v
:=
structPointer_Word32
(
base
,
p
.
field
)
if
word32_IsNil
(
v
)
{
return
ErrNil
}
x
:=
word32_Get
(
v
)
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
p
.
valEnc
(
o
,
uint64
(
x
))
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
)
{
v
:=
structPointer_Word32
(
base
,
p
.
field
)
if
word32_IsNil
(
v
)
{
return
0
}
x
:=
word32_Get
(
v
)
n
+=
len
(
p
.
tagcode
)
n
+=
p
.
valSize
(
uint64
(
x
))
return
}
func
size_proto3_uint32
(
p
*
Properties
,
base
structPointer
)
(
n
int
)
{
v
:=
structPointer_Word32Val
(
base
,
p
.
field
)
x
:=
word32Val_Get
(
v
)
if
x
==
0
&&
!
p
.
oneof
{
return
0
}
n
+=
len
(
p
.
tagcode
)
n
+=
p
.
valSize
(
uint64
(
x
))
return
}
// Encode an int64.
func
(
o
*
Buffer
)
enc_int64
(
p
*
Properties
,
base
structPointer
)
error
{
v
:=
structPointer_Word64
(
base
,
p
.
field
)
if
word64_IsNil
(
v
)
{
return
ErrNil
}
x
:=
word64_Get
(
v
)
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
p
.
valEnc
(
o
,
x
)
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
)
{
v
:=
structPointer_Word64
(
base
,
p
.
field
)
if
word64_IsNil
(
v
)
{
return
0
}
x
:=
word64_Get
(
v
)
n
+=
len
(
p
.
tagcode
)
n
+=
p
.
valSize
(
x
)
return
}
func
size_proto3_int64
(
p
*
Properties
,
base
structPointer
)
(
n
int
)
{
v
:=
structPointer_Word64Val
(
base
,
p
.
field
)
x
:=
word64Val_Get
(
v
)
if
x
==
0
&&
!
p
.
oneof
{
return
0
}
n
+=
len
(
p
.
tagcode
)
n
+=
p
.
valSize
(
x
)
return
}
// Encode a string.
func
(
o
*
Buffer
)
enc_string
(
p
*
Properties
,
base
structPointer
)
error
{
v
:=
*
structPointer_String
(
base
,
p
.
field
)
if
v
==
nil
{
return
ErrNil
}
x
:=
*
v
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
o
.
EncodeStringBytes
(
x
)
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
)
{
v
:=
*
structPointer_String
(
base
,
p
.
field
)
if
v
==
nil
{
return
0
}
x
:=
*
v
n
+=
len
(
p
.
tagcode
)
n
+=
sizeStringBytes
(
x
)
return
}
func
size_proto3_string
(
p
*
Properties
,
base
structPointer
)
(
n
int
)
{
v
:=
*
structPointer_StringVal
(
base
,
p
.
field
)
if
v
==
""
&&
!
p
.
oneof
{
return
0
}
n
+=
len
(
p
.
tagcode
)
n
+=
sizeStringBytes
(
v
)
return
}
// All protocol buffer fields are nillable, but be careful.
func
isNil
(
v
reflect
.
Value
)
bool
{
switch
v
.
Kind
()
{
case
reflect
.
Interface
,
reflect
.
Map
,
reflect
.
Ptr
,
reflect
.
Slice
:
return
v
.
IsNil
()
}
return
false
}
// Encode a message struct.
func
(
o
*
Buffer
)
enc_struct_message
(
p
*
Properties
,
base
structPointer
)
error
{
var
state
errorState
structp
:=
structPointer_GetStructPointer
(
base
,
p
.
field
)
if
structPointer_IsNil
(
structp
)
{
return
ErrNil
}
// Can the object marshal itself?
if
p
.
isMarshaler
{
m
:=
structPointer_Interface
(
structp
,
p
.
stype
)
.
(
Marshaler
)
data
,
err
:=
m
.
Marshal
()
if
err
!=
nil
&&
!
state
.
shouldContinue
(
err
,
nil
)
{
return
err
}
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
o
.
EncodeRawBytes
(
data
)
return
state
.
err
}
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
return
o
.
enc_len_struct
(
p
.
sprop
,
structp
,
&
state
)
}
func
size_struct_message
(
p
*
Properties
,
base
structPointer
)
int
{
structp
:=
structPointer_GetStructPointer
(
base
,
p
.
field
)
if
structPointer_IsNil
(
structp
)
{
return
0
}
// Can the object marshal itself?
if
p
.
isMarshaler
{
m
:=
structPointer_Interface
(
structp
,
p
.
stype
)
.
(
Marshaler
)
data
,
_
:=
m
.
Marshal
()
n0
:=
len
(
p
.
tagcode
)
n1
:=
sizeRawBytes
(
data
)
return
n0
+
n1
}
n0
:=
len
(
p
.
tagcode
)
n1
:=
size_struct
(
p
.
sprop
,
structp
)
n2
:=
sizeVarint
(
uint64
(
n1
))
// size of encoded length
return
n0
+
n1
+
n2
}
// Encode a group struct.
func
(
o
*
Buffer
)
enc_struct_group
(
p
*
Properties
,
base
structPointer
)
error
{
var
state
errorState
b
:=
structPointer_GetStructPointer
(
base
,
p
.
field
)
if
structPointer_IsNil
(
b
)
{
return
ErrNil
}
o
.
EncodeVarint
(
uint64
((
p
.
Tag
<<
3
)
|
WireStartGroup
))
err
:=
o
.
enc_struct
(
p
.
sprop
,
b
)
if
err
!=
nil
&&
!
state
.
shouldContinue
(
err
,
nil
)
{
return
err
}
o
.
EncodeVarint
(
uint64
((
p
.
Tag
<<
3
)
|
WireEndGroup
))
return
state
.
err
}
func
size_struct_group
(
p
*
Properties
,
base
structPointer
)
(
n
int
)
{
b
:=
structPointer_GetStructPointer
(
base
,
p
.
field
)
if
structPointer_IsNil
(
b
)
{
return
0
}
n
+=
sizeVarint
(
uint64
((
p
.
Tag
<<
3
)
|
WireStartGroup
))
n
+=
size_struct
(
p
.
sprop
,
b
)
n
+=
sizeVarint
(
uint64
((
p
.
Tag
<<
3
)
|
WireEndGroup
))
return
}
// Encode a slice of bools ([]bool).
func
(
o
*
Buffer
)
enc_slice_bool
(
p
*
Properties
,
base
structPointer
)
error
{
s
:=
*
structPointer_BoolSlice
(
base
,
p
.
field
)
l
:=
len
(
s
)
if
l
==
0
{
return
ErrNil
}
for
_
,
x
:=
range
s
{
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
v
:=
uint64
(
0
)
if
x
{
v
=
1
}
p
.
valEnc
(
o
,
v
)
}
return
nil
}
func
size_slice_bool
(
p
*
Properties
,
base
structPointer
)
int
{
s
:=
*
structPointer_BoolSlice
(
base
,
p
.
field
)
l
:=
len
(
s
)
if
l
==
0
{
return
0
}
return
l
*
(
len
(
p
.
tagcode
)
+
1
)
// each bool takes exactly one byte
}
// Encode a slice of bools ([]bool) in packed format.
func
(
o
*
Buffer
)
enc_slice_packed_bool
(
p
*
Properties
,
base
structPointer
)
error
{
s
:=
*
structPointer_BoolSlice
(
base
,
p
.
field
)
l
:=
len
(
s
)
if
l
==
0
{
return
ErrNil
}
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
o
.
EncodeVarint
(
uint64
(
l
))
// each bool takes exactly one byte
for
_
,
x
:=
range
s
{
v
:=
uint64
(
0
)
if
x
{
v
=
1
}
p
.
valEnc
(
o
,
v
)
}
return
nil
}
func
size_slice_packed_bool
(
p
*
Properties
,
base
structPointer
)
(
n
int
)
{
s
:=
*
structPointer_BoolSlice
(
base
,
p
.
field
)
l
:=
len
(
s
)
if
l
==
0
{
return
0
}
n
+=
len
(
p
.
tagcode
)
n
+=
sizeVarint
(
uint64
(
l
))
n
+=
l
// each bool takes exactly one byte
return
}
// Encode a slice of bytes ([]byte).
func
(
o
*
Buffer
)
enc_slice_byte
(
p
*
Properties
,
base
structPointer
)
error
{
s
:=
*
structPointer_Bytes
(
base
,
p
.
field
)
if
s
==
nil
{
return
ErrNil
}
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
o
.
EncodeRawBytes
(
s
)
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
)
{
s
:=
*
structPointer_Bytes
(
base
,
p
.
field
)
if
s
==
nil
&&
!
p
.
oneof
{
return
0
}
n
+=
len
(
p
.
tagcode
)
n
+=
sizeRawBytes
(
s
)
return
}
func
size_proto3_slice_byte
(
p
*
Properties
,
base
structPointer
)
(
n
int
)
{
s
:=
*
structPointer_Bytes
(
base
,
p
.
field
)
if
len
(
s
)
==
0
&&
!
p
.
oneof
{
return
0
}
n
+=
len
(
p
.
tagcode
)
n
+=
sizeRawBytes
(
s
)
return
}
// Encode a slice of int32s ([]int32).
func
(
o
*
Buffer
)
enc_slice_int32
(
p
*
Properties
,
base
structPointer
)
error
{
s
:=
structPointer_Word32Slice
(
base
,
p
.
field
)
l
:=
s
.
Len
()
if
l
==
0
{
return
ErrNil
}
for
i
:=
0
;
i
<
l
;
i
++
{
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
x
:=
int32
(
s
.
Index
(
i
))
// permit sign extension to use full 64-bit range
p
.
valEnc
(
o
,
uint64
(
x
))
}
return
nil
}
func
size_slice_int32
(
p
*
Properties
,
base
structPointer
)
(
n
int
)
{
s
:=
structPointer_Word32Slice
(
base
,
p
.
field
)
l
:=
s
.
Len
()
if
l
==
0
{
return
0
}
for
i
:=
0
;
i
<
l
;
i
++
{
n
+=
len
(
p
.
tagcode
)
x
:=
int32
(
s
.
Index
(
i
))
// permit sign extension to use full 64-bit range
n
+=
p
.
valSize
(
uint64
(
x
))
}
return
}
// Encode a slice of int32s ([]int32) in packed format.
func
(
o
*
Buffer
)
enc_slice_packed_int32
(
p
*
Properties
,
base
structPointer
)
error
{
s
:=
structPointer_Word32Slice
(
base
,
p
.
field
)
l
:=
s
.
Len
()
if
l
==
0
{
return
ErrNil
}
// TODO: Reuse a Buffer.
buf
:=
NewBuffer
(
nil
)
for
i
:=
0
;
i
<
l
;
i
++
{
x
:=
int32
(
s
.
Index
(
i
))
// permit sign extension to use full 64-bit range
p
.
valEnc
(
buf
,
uint64
(
x
))
}
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
o
.
EncodeVarint
(
uint64
(
len
(
buf
.
buf
)))
o
.
buf
=
append
(
o
.
buf
,
buf
.
buf
...
)
return
nil
}
func
size_slice_packed_int32
(
p
*
Properties
,
base
structPointer
)
(
n
int
)
{
s
:=
structPointer_Word32Slice
(
base
,
p
.
field
)
l
:=
s
.
Len
()
if
l
==
0
{
return
0
}
var
bufSize
int
for
i
:=
0
;
i
<
l
;
i
++
{
x
:=
int32
(
s
.
Index
(
i
))
// permit sign extension to use full 64-bit range
bufSize
+=
p
.
valSize
(
uint64
(
x
))
}
n
+=
len
(
p
.
tagcode
)
n
+=
sizeVarint
(
uint64
(
bufSize
))
n
+=
bufSize
return
}
// Encode a slice of uint32s ([]uint32).
// Exactly the same as int32, except for no sign extension.
func
(
o
*
Buffer
)
enc_slice_uint32
(
p
*
Properties
,
base
structPointer
)
error
{
s
:=
structPointer_Word32Slice
(
base
,
p
.
field
)
l
:=
s
.
Len
()
if
l
==
0
{
return
ErrNil
}
for
i
:=
0
;
i
<
l
;
i
++
{
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
x
:=
s
.
Index
(
i
)
p
.
valEnc
(
o
,
uint64
(
x
))
}
return
nil
}
func
size_slice_uint32
(
p
*
Properties
,
base
structPointer
)
(
n
int
)
{
s
:=
structPointer_Word32Slice
(
base
,
p
.
field
)
l
:=
s
.
Len
()
if
l
==
0
{
return
0
}
for
i
:=
0
;
i
<
l
;
i
++
{
n
+=
len
(
p
.
tagcode
)
x
:=
s
.
Index
(
i
)
n
+=
p
.
valSize
(
uint64
(
x
))
}
return
}
// Encode a slice of uint32s ([]uint32) in packed format.
// Exactly the same as int32, except for no sign extension.
func
(
o
*
Buffer
)
enc_slice_packed_uint32
(
p
*
Properties
,
base
structPointer
)
error
{
s
:=
structPointer_Word32Slice
(
base
,
p
.
field
)
l
:=
s
.
Len
()
if
l
==
0
{
return
ErrNil
}
// TODO: Reuse a Buffer.
buf
:=
NewBuffer
(
nil
)
for
i
:=
0
;
i
<
l
;
i
++
{
p
.
valEnc
(
buf
,
uint64
(
s
.
Index
(
i
)))
}
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
o
.
EncodeVarint
(
uint64
(
len
(
buf
.
buf
)))
o
.
buf
=
append
(
o
.
buf
,
buf
.
buf
...
)
return
nil
}
func
size_slice_packed_uint32
(
p
*
Properties
,
base
structPointer
)
(
n
int
)
{
s
:=
structPointer_Word32Slice
(
base
,
p
.
field
)
l
:=
s
.
Len
()
if
l
==
0
{
return
0
}
var
bufSize
int
for
i
:=
0
;
i
<
l
;
i
++
{
bufSize
+=
p
.
valSize
(
uint64
(
s
.
Index
(
i
)))
}
n
+=
len
(
p
.
tagcode
)
n
+=
sizeVarint
(
uint64
(
bufSize
))
n
+=
bufSize
return
}
// Encode a slice of int64s ([]int64).
func
(
o
*
Buffer
)
enc_slice_int64
(
p
*
Properties
,
base
structPointer
)
error
{
s
:=
structPointer_Word64Slice
(
base
,
p
.
field
)
l
:=
s
.
Len
()
if
l
==
0
{
return
ErrNil
}
for
i
:=
0
;
i
<
l
;
i
++
{
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
p
.
valEnc
(
o
,
s
.
Index
(
i
))
}
return
nil
}
func
size_slice_int64
(
p
*
Properties
,
base
structPointer
)
(
n
int
)
{
s
:=
structPointer_Word64Slice
(
base
,
p
.
field
)
l
:=
s
.
Len
()
if
l
==
0
{
return
0
}
for
i
:=
0
;
i
<
l
;
i
++
{
n
+=
len
(
p
.
tagcode
)
n
+=
p
.
valSize
(
s
.
Index
(
i
))
}
return
}
// Encode a slice of int64s ([]int64) in packed format.
func
(
o
*
Buffer
)
enc_slice_packed_int64
(
p
*
Properties
,
base
structPointer
)
error
{
s
:=
structPointer_Word64Slice
(
base
,
p
.
field
)
l
:=
s
.
Len
()
if
l
==
0
{
return
ErrNil
}
// TODO: Reuse a Buffer.
buf
:=
NewBuffer
(
nil
)
for
i
:=
0
;
i
<
l
;
i
++
{
p
.
valEnc
(
buf
,
s
.
Index
(
i
))
}
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
o
.
EncodeVarint
(
uint64
(
len
(
buf
.
buf
)))
o
.
buf
=
append
(
o
.
buf
,
buf
.
buf
...
)
return
nil
}
func
size_slice_packed_int64
(
p
*
Properties
,
base
structPointer
)
(
n
int
)
{
s
:=
structPointer_Word64Slice
(
base
,
p
.
field
)
l
:=
s
.
Len
()
if
l
==
0
{
return
0
}
var
bufSize
int
for
i
:=
0
;
i
<
l
;
i
++
{
bufSize
+=
p
.
valSize
(
s
.
Index
(
i
))
}
n
+=
len
(
p
.
tagcode
)
n
+=
sizeVarint
(
uint64
(
bufSize
))
n
+=
bufSize
return
}
// Encode a slice of slice of bytes ([][]byte).
func
(
o
*
Buffer
)
enc_slice_slice_byte
(
p
*
Properties
,
base
structPointer
)
error
{
ss
:=
*
structPointer_BytesSlice
(
base
,
p
.
field
)
l
:=
len
(
ss
)
if
l
==
0
{
return
ErrNil
}
for
i
:=
0
;
i
<
l
;
i
++
{
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
o
.
EncodeRawBytes
(
ss
[
i
])
}
return
nil
}
func
size_slice_slice_byte
(
p
*
Properties
,
base
structPointer
)
(
n
int
)
{
ss
:=
*
structPointer_BytesSlice
(
base
,
p
.
field
)
l
:=
len
(
ss
)
if
l
==
0
{
return
0
}
n
+=
l
*
len
(
p
.
tagcode
)
for
i
:=
0
;
i
<
l
;
i
++
{
n
+=
sizeRawBytes
(
ss
[
i
])
}
return
}
// Encode a slice of strings ([]string).
func
(
o
*
Buffer
)
enc_slice_string
(
p
*
Properties
,
base
structPointer
)
error
{
ss
:=
*
structPointer_StringSlice
(
base
,
p
.
field
)
l
:=
len
(
ss
)
for
i
:=
0
;
i
<
l
;
i
++
{
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
o
.
EncodeStringBytes
(
ss
[
i
])
}
return
nil
}
func
size_slice_string
(
p
*
Properties
,
base
structPointer
)
(
n
int
)
{
ss
:=
*
structPointer_StringSlice
(
base
,
p
.
field
)
l
:=
len
(
ss
)
n
+=
l
*
len
(
p
.
tagcode
)
for
i
:=
0
;
i
<
l
;
i
++
{
n
+=
sizeStringBytes
(
ss
[
i
])
}
return
}
// Encode a slice of message structs ([]*struct).
func
(
o
*
Buffer
)
enc_slice_struct_message
(
p
*
Properties
,
base
structPointer
)
error
{
var
state
errorState
s
:=
structPointer_StructPointerSlice
(
base
,
p
.
field
)
l
:=
s
.
Len
()
for
i
:=
0
;
i
<
l
;
i
++
{
structp
:=
s
.
Index
(
i
)
if
structPointer_IsNil
(
structp
)
{
return
errRepeatedHasNil
}
// Can the object marshal itself?
if
p
.
isMarshaler
{
m
:=
structPointer_Interface
(
structp
,
p
.
stype
)
.
(
Marshaler
)
data
,
err
:=
m
.
Marshal
()
if
err
!=
nil
&&
!
state
.
shouldContinue
(
err
,
nil
)
{
return
err
}
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
o
.
EncodeRawBytes
(
data
)
continue
}
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
err
:=
o
.
enc_len_struct
(
p
.
sprop
,
structp
,
&
state
)
if
err
!=
nil
&&
!
state
.
shouldContinue
(
err
,
nil
)
{
if
err
==
ErrNil
{
return
errRepeatedHasNil
}
return
err
}
}
return
state
.
err
}
func
size_slice_struct_message
(
p
*
Properties
,
base
structPointer
)
(
n
int
)
{
s
:=
structPointer_StructPointerSlice
(
base
,
p
.
field
)
l
:=
s
.
Len
()
n
+=
l
*
len
(
p
.
tagcode
)
for
i
:=
0
;
i
<
l
;
i
++
{
structp
:=
s
.
Index
(
i
)
if
structPointer_IsNil
(
structp
)
{
return
// return the size up to this point
}
// Can the object marshal itself?
if
p
.
isMarshaler
{
m
:=
structPointer_Interface
(
structp
,
p
.
stype
)
.
(
Marshaler
)
data
,
_
:=
m
.
Marshal
()
n
+=
len
(
p
.
tagcode
)
n
+=
sizeRawBytes
(
data
)
continue
}
n0
:=
size_struct
(
p
.
sprop
,
structp
)
n1
:=
sizeVarint
(
uint64
(
n0
))
// size of encoded length
n
+=
n0
+
n1
}
return
}
// Encode a slice of group structs ([]*struct).
func
(
o
*
Buffer
)
enc_slice_struct_group
(
p
*
Properties
,
base
structPointer
)
error
{
var
state
errorState
s
:=
structPointer_StructPointerSlice
(
base
,
p
.
field
)
l
:=
s
.
Len
()
for
i
:=
0
;
i
<
l
;
i
++
{
b
:=
s
.
Index
(
i
)
if
structPointer_IsNil
(
b
)
{
return
errRepeatedHasNil
}
o
.
EncodeVarint
(
uint64
((
p
.
Tag
<<
3
)
|
WireStartGroup
))
err
:=
o
.
enc_struct
(
p
.
sprop
,
b
)
if
err
!=
nil
&&
!
state
.
shouldContinue
(
err
,
nil
)
{
if
err
==
ErrNil
{
return
errRepeatedHasNil
}
return
err
}
o
.
EncodeVarint
(
uint64
((
p
.
Tag
<<
3
)
|
WireEndGroup
))
}
return
state
.
err
}
func
size_slice_struct_group
(
p
*
Properties
,
base
structPointer
)
(
n
int
)
{
s
:=
structPointer_StructPointerSlice
(
base
,
p
.
field
)
l
:=
s
.
Len
()
n
+=
l
*
sizeVarint
(
uint64
((
p
.
Tag
<<
3
)
|
WireStartGroup
))
n
+=
l
*
sizeVarint
(
uint64
((
p
.
Tag
<<
3
)
|
WireEndGroup
))
for
i
:=
0
;
i
<
l
;
i
++
{
b
:=
s
.
Index
(
i
)
if
structPointer_IsNil
(
b
)
{
return
// return size up to this point
}
n
+=
size_struct
(
p
.
sprop
,
b
)
}
return
}
// Encode an extension map.
func
(
o
*
Buffer
)
enc_map
(
p
*
Properties
,
base
structPointer
)
error
{
v
:=
*
structPointer_ExtMap
(
base
,
p
.
field
)
if
err
:=
encodeExtensionMap
(
v
);
err
!=
nil
{
return
err
}
// Fast-path for common cases: zero or one extensions.
if
len
(
v
)
<=
1
{
for
_
,
e
:=
range
v
{
o
.
buf
=
append
(
o
.
buf
,
e
.
enc
...
)
}
return
nil
}
// Sort keys to provide a deterministic encoding.
keys
:=
make
([]
int
,
0
,
len
(
v
))
for
k
:=
range
v
{
keys
=
append
(
keys
,
int
(
k
))
}
sort
.
Ints
(
keys
)
for
_
,
k
:=
range
keys
{
o
.
buf
=
append
(
o
.
buf
,
v
[
int32
(
k
)]
.
enc
...
)
}
return
nil
}
func
size_map
(
p
*
Properties
,
base
structPointer
)
int
{
v
:=
*
structPointer_ExtMap
(
base
,
p
.
field
)
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_NewAt
(
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
)
// The only illegal map entry values are nil message pointers.
if
val
.
Kind
()
==
reflect
.
Ptr
&&
val
.
IsNil
()
{
return
errors
.
New
(
"proto: map has nil element"
)
}
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_NewAt
(
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 for key and val are the responsibility of the sub-sizer.
keysize
:=
p
.
mkeyprop
.
size
(
p
.
mkeyprop
,
keybase
)
valsize
:=
p
.
mvalprop
.
size
(
p
.
mvalprop
,
valbase
)
entry
:=
keysize
+
valsize
// Add on tag code and length of map entry itself.
n
+=
len
(
p
.
tagcode
)
+
sizeVarint
(
uint64
(
entry
))
+
entry
}
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.
func
(
o
*
Buffer
)
enc_struct
(
prop
*
StructProperties
,
base
structPointer
)
error
{
var
state
errorState
// Encode fields in tag order so that decoders may use optimizations
// that depend on the ordering.
// https://developers.google.com/protocol-buffers/docs/encoding#order
for
_
,
i
:=
range
prop
.
order
{
p
:=
prop
.
Prop
[
i
]
if
p
.
enc
!=
nil
{
err
:=
p
.
enc
(
o
,
p
,
base
)
if
err
!=
nil
{
if
err
==
ErrNil
{
if
p
.
Required
&&
state
.
err
==
nil
{
state
.
err
=
&
RequiredNotSetError
{
p
.
Name
}
}
}
else
if
err
==
errRepeatedHasNil
{
// Give more context to nil values in repeated fields.
return
errors
.
New
(
"repeated field "
+
p
.
OrigName
+
" has nil element"
)
}
else
if
!
state
.
shouldContinue
(
err
,
p
)
{
return
err
}
}
}
}
// Do oneof fields.
if
prop
.
oneofMarshaler
!=
nil
{
m
:=
structPointer_Interface
(
base
,
prop
.
stype
)
.
(
Message
)
if
err
:=
prop
.
oneofMarshaler
(
m
,
o
);
err
!=
nil
{
return
err
}
}
// Add unrecognized fields at the end.
if
prop
.
unrecField
.
IsValid
()
{
v
:=
*
structPointer_Bytes
(
base
,
prop
.
unrecField
)
if
len
(
v
)
>
0
{
o
.
buf
=
append
(
o
.
buf
,
v
...
)
}
}
return
state
.
err
}
func
size_struct
(
prop
*
StructProperties
,
base
structPointer
)
(
n
int
)
{
for
_
,
i
:=
range
prop
.
order
{
p
:=
prop
.
Prop
[
i
]
if
p
.
size
!=
nil
{
n
+=
p
.
size
(
p
,
base
)
}
}
// Add unrecognized fields at the end.
if
prop
.
unrecField
.
IsValid
()
{
v
:=
*
structPointer_Bytes
(
base
,
prop
.
unrecField
)
n
+=
len
(
v
)
}
// Factor in any oneof fields.
// TODO: This could be faster and use less reflection.
if
prop
.
oneofMarshaler
!=
nil
{
sv
:=
reflect
.
ValueOf
(
structPointer_Interface
(
base
,
prop
.
stype
))
.
Elem
()
for
i
:=
0
;
i
<
prop
.
stype
.
NumField
();
i
++
{
fv
:=
sv
.
Field
(
i
)
if
fv
.
Kind
()
!=
reflect
.
Interface
||
fv
.
IsNil
()
{
continue
}
if
prop
.
stype
.
Field
(
i
)
.
Tag
.
Get
(
"protobuf_oneof"
)
==
""
{
continue
}
spv
:=
fv
.
Elem
()
// interface -> *T
sv
:=
spv
.
Elem
()
// *T -> T
sf
:=
sv
.
Type
()
.
Field
(
0
)
// StructField inside T
var
prop
Properties
prop
.
Init
(
sf
.
Type
,
"whatever"
,
sf
.
Tag
.
Get
(
"protobuf"
),
&
sf
)
n
+=
prop
.
size
(
&
prop
,
toStructPointer
(
spv
))
}
}
return
}
var
zeroes
[
20
]
byte
// longer than any conceivable sizeVarint
// Encode a struct, preceded by its encoded length (as a varint).
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
)
o
.
buf
=
append
(
o
.
buf
,
0
,
0
,
0
,
0
)
// reserve four bytes for length
iMsg
:=
len
(
o
.
buf
)
err
:=
enc
()
if
err
!=
nil
&&
!
state
.
shouldContinue
(
err
,
nil
)
{
return
err
}
lMsg
:=
len
(
o
.
buf
)
-
iMsg
lLen
:=
sizeVarint
(
uint64
(
lMsg
))
switch
x
:=
lLen
-
(
iMsg
-
iLen
);
{
case
x
>
0
:
// actual length is x bytes larger than the space we reserved
// Move msg x bytes right.
o
.
buf
=
append
(
o
.
buf
,
zeroes
[
:
x
]
...
)
copy
(
o
.
buf
[
iMsg
+
x
:
],
o
.
buf
[
iMsg
:
iMsg
+
lMsg
])
case
x
<
0
:
// actual length is x bytes smaller than the space we reserved
// Move msg x bytes left.
copy
(
o
.
buf
[
iMsg
+
x
:
],
o
.
buf
[
iMsg
:
iMsg
+
lMsg
])
o
.
buf
=
o
.
buf
[
:
len
(
o
.
buf
)
+
x
]
// x is negative
}
// Encode the length in the reserved space.
o
.
buf
=
o
.
buf
[
:
iLen
]
o
.
EncodeVarint
(
uint64
(
lMsg
))
o
.
buf
=
o
.
buf
[
:
len
(
o
.
buf
)
+
lMsg
]
return
state
.
err
}
// errorState maintains the first error that occurs and updates that error
// with additional context.
type
errorState
struct
{
err
error
}
// shouldContinue reports whether encoding should continue upon encountering the
// given error. If the error is RequiredNotSetError, shouldContinue returns true
// and, if this is the first appearance of that error, remembers it for future
// reporting.
//
// If prop is not nil, it may update any error with additional context about the
// field with the error.
func
(
s
*
errorState
)
shouldContinue
(
err
error
,
prop
*
Properties
)
bool
{
// Ignore unset required fields.
reqNotSet
,
ok
:=
err
.
(
*
RequiredNotSetError
)
if
!
ok
{
return
false
}
if
s
.
err
==
nil
{
if
prop
!=
nil
{
err
=
&
RequiredNotSetError
{
prop
.
Name
+
"."
+
reqNotSet
.
field
}
}
s
.
err
=
err
}
return
true
}
vendor/QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto/encode_gogo.go
0 → 100644
View file @
8f79df77
// Extensions for Protocol Buffers to create more go like structures.
//
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
// http://github.com/gogo/protobuf/gogoproto
//
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2010 The Go Authors. All rights reserved.
// http://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
import
(
"reflect"
)
func
NewRequiredNotSetError
(
field
string
)
*
RequiredNotSetError
{
return
&
RequiredNotSetError
{
field
}
}
type
Sizer
interface
{
Size
()
int
}
func
(
o
*
Buffer
)
enc_ext_slice_byte
(
p
*
Properties
,
base
structPointer
)
error
{
s
:=
*
structPointer_Bytes
(
base
,
p
.
field
)
if
s
==
nil
{
return
ErrNil
}
o
.
buf
=
append
(
o
.
buf
,
s
...
)
return
nil
}
func
size_ext_slice_byte
(
p
*
Properties
,
base
structPointer
)
(
n
int
)
{
s
:=
*
structPointer_Bytes
(
base
,
p
.
field
)
if
s
==
nil
{
return
0
}
n
+=
len
(
s
)
return
}
// Encode a reference to bool pointer.
func
(
o
*
Buffer
)
enc_ref_bool
(
p
*
Properties
,
base
structPointer
)
error
{
v
:=
*
structPointer_BoolVal
(
base
,
p
.
field
)
x
:=
0
if
v
{
x
=
1
}
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
p
.
valEnc
(
o
,
uint64
(
x
))
return
nil
}
func
size_ref_bool
(
p
*
Properties
,
base
structPointer
)
int
{
return
len
(
p
.
tagcode
)
+
1
// each bool takes exactly one byte
}
// Encode a reference to int32 pointer.
func
(
o
*
Buffer
)
enc_ref_int32
(
p
*
Properties
,
base
structPointer
)
error
{
v
:=
structPointer_Word32Val
(
base
,
p
.
field
)
x
:=
int32
(
word32Val_Get
(
v
))
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
p
.
valEnc
(
o
,
uint64
(
x
))
return
nil
}
func
size_ref_int32
(
p
*
Properties
,
base
structPointer
)
(
n
int
)
{
v
:=
structPointer_Word32Val
(
base
,
p
.
field
)
x
:=
int32
(
word32Val_Get
(
v
))
n
+=
len
(
p
.
tagcode
)
n
+=
p
.
valSize
(
uint64
(
x
))
return
}
func
(
o
*
Buffer
)
enc_ref_uint32
(
p
*
Properties
,
base
structPointer
)
error
{
v
:=
structPointer_Word32Val
(
base
,
p
.
field
)
x
:=
word32Val_Get
(
v
)
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
p
.
valEnc
(
o
,
uint64
(
x
))
return
nil
}
func
size_ref_uint32
(
p
*
Properties
,
base
structPointer
)
(
n
int
)
{
v
:=
structPointer_Word32Val
(
base
,
p
.
field
)
x
:=
word32Val_Get
(
v
)
n
+=
len
(
p
.
tagcode
)
n
+=
p
.
valSize
(
uint64
(
x
))
return
}
// Encode a reference to an int64 pointer.
func
(
o
*
Buffer
)
enc_ref_int64
(
p
*
Properties
,
base
structPointer
)
error
{
v
:=
structPointer_Word64Val
(
base
,
p
.
field
)
x
:=
word64Val_Get
(
v
)
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
p
.
valEnc
(
o
,
x
)
return
nil
}
func
size_ref_int64
(
p
*
Properties
,
base
structPointer
)
(
n
int
)
{
v
:=
structPointer_Word64Val
(
base
,
p
.
field
)
x
:=
word64Val_Get
(
v
)
n
+=
len
(
p
.
tagcode
)
n
+=
p
.
valSize
(
x
)
return
}
// Encode a reference to a string pointer.
func
(
o
*
Buffer
)
enc_ref_string
(
p
*
Properties
,
base
structPointer
)
error
{
v
:=
*
structPointer_StringVal
(
base
,
p
.
field
)
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
o
.
EncodeStringBytes
(
v
)
return
nil
}
func
size_ref_string
(
p
*
Properties
,
base
structPointer
)
(
n
int
)
{
v
:=
*
structPointer_StringVal
(
base
,
p
.
field
)
n
+=
len
(
p
.
tagcode
)
n
+=
sizeStringBytes
(
v
)
return
}
// Encode a reference to a message struct.
func
(
o
*
Buffer
)
enc_ref_struct_message
(
p
*
Properties
,
base
structPointer
)
error
{
var
state
errorState
structp
:=
structPointer_GetRefStructPointer
(
base
,
p
.
field
)
if
structPointer_IsNil
(
structp
)
{
return
ErrNil
}
// Can the object marshal itself?
if
p
.
isMarshaler
{
m
:=
structPointer_Interface
(
structp
,
p
.
stype
)
.
(
Marshaler
)
data
,
err
:=
m
.
Marshal
()
if
err
!=
nil
&&
!
state
.
shouldContinue
(
err
,
nil
)
{
return
err
}
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
o
.
EncodeRawBytes
(
data
)
return
nil
}
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
return
o
.
enc_len_struct
(
p
.
sprop
,
structp
,
&
state
)
}
//TODO this is only copied, please fix this
func
size_ref_struct_message
(
p
*
Properties
,
base
structPointer
)
int
{
structp
:=
structPointer_GetRefStructPointer
(
base
,
p
.
field
)
if
structPointer_IsNil
(
structp
)
{
return
0
}
// Can the object marshal itself?
if
p
.
isMarshaler
{
m
:=
structPointer_Interface
(
structp
,
p
.
stype
)
.
(
Marshaler
)
data
,
_
:=
m
.
Marshal
()
n0
:=
len
(
p
.
tagcode
)
n1
:=
sizeRawBytes
(
data
)
return
n0
+
n1
}
n0
:=
len
(
p
.
tagcode
)
n1
:=
size_struct
(
p
.
sprop
,
structp
)
n2
:=
sizeVarint
(
uint64
(
n1
))
// size of encoded length
return
n0
+
n1
+
n2
}
// Encode a slice of references to message struct pointers ([]struct).
func
(
o
*
Buffer
)
enc_slice_ref_struct_message
(
p
*
Properties
,
base
structPointer
)
error
{
var
state
errorState
ss
:=
structPointer_GetStructPointer
(
base
,
p
.
field
)
ss1
:=
structPointer_GetRefStructPointer
(
ss
,
field
(
0
))
size
:=
p
.
stype
.
Size
()
l
:=
structPointer_Len
(
base
,
p
.
field
)
for
i
:=
0
;
i
<
l
;
i
++
{
structp
:=
structPointer_Add
(
ss1
,
field
(
uintptr
(
i
)
*
size
))
if
structPointer_IsNil
(
structp
)
{
return
errRepeatedHasNil
}
// Can the object marshal itself?
if
p
.
isMarshaler
{
m
:=
structPointer_Interface
(
structp
,
p
.
stype
)
.
(
Marshaler
)
data
,
err
:=
m
.
Marshal
()
if
err
!=
nil
&&
!
state
.
shouldContinue
(
err
,
nil
)
{
return
err
}
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
o
.
EncodeRawBytes
(
data
)
continue
}
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
err
:=
o
.
enc_len_struct
(
p
.
sprop
,
structp
,
&
state
)
if
err
!=
nil
&&
!
state
.
shouldContinue
(
err
,
nil
)
{
if
err
==
ErrNil
{
return
errRepeatedHasNil
}
return
err
}
}
return
state
.
err
}
//TODO this is only copied, please fix this
func
size_slice_ref_struct_message
(
p
*
Properties
,
base
structPointer
)
(
n
int
)
{
ss
:=
structPointer_GetStructPointer
(
base
,
p
.
field
)
ss1
:=
structPointer_GetRefStructPointer
(
ss
,
field
(
0
))
size
:=
p
.
stype
.
Size
()
l
:=
structPointer_Len
(
base
,
p
.
field
)
n
+=
l
*
len
(
p
.
tagcode
)
for
i
:=
0
;
i
<
l
;
i
++
{
structp
:=
structPointer_Add
(
ss1
,
field
(
uintptr
(
i
)
*
size
))
if
structPointer_IsNil
(
structp
)
{
return
// return the size up to this point
}
// Can the object marshal itself?
if
p
.
isMarshaler
{
m
:=
structPointer_Interface
(
structp
,
p
.
stype
)
.
(
Marshaler
)
data
,
_
:=
m
.
Marshal
()
n
+=
len
(
p
.
tagcode
)
n
+=
sizeRawBytes
(
data
)
continue
}
n0
:=
size_struct
(
p
.
sprop
,
structp
)
n1
:=
sizeVarint
(
uint64
(
n0
))
// size of encoded length
n
+=
n0
+
n1
}
return
}
func
(
o
*
Buffer
)
enc_custom_bytes
(
p
*
Properties
,
base
structPointer
)
error
{
i
:=
structPointer_InterfaceRef
(
base
,
p
.
field
,
p
.
ctype
)
if
i
==
nil
{
return
ErrNil
}
custom
:=
i
.
(
Marshaler
)
data
,
err
:=
custom
.
Marshal
()
if
err
!=
nil
{
return
err
}
if
data
==
nil
{
return
ErrNil
}
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
o
.
EncodeRawBytes
(
data
)
return
nil
}
func
size_custom_bytes
(
p
*
Properties
,
base
structPointer
)
(
n
int
)
{
n
+=
len
(
p
.
tagcode
)
i
:=
structPointer_InterfaceRef
(
base
,
p
.
field
,
p
.
ctype
)
if
i
==
nil
{
return
0
}
custom
:=
i
.
(
Marshaler
)
data
,
_
:=
custom
.
Marshal
()
n
+=
sizeRawBytes
(
data
)
return
}
func
(
o
*
Buffer
)
enc_custom_ref_bytes
(
p
*
Properties
,
base
structPointer
)
error
{
custom
:=
structPointer_InterfaceAt
(
base
,
p
.
field
,
p
.
ctype
)
.
(
Marshaler
)
data
,
err
:=
custom
.
Marshal
()
if
err
!=
nil
{
return
err
}
if
data
==
nil
{
return
ErrNil
}
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
o
.
EncodeRawBytes
(
data
)
return
nil
}
func
size_custom_ref_bytes
(
p
*
Properties
,
base
structPointer
)
(
n
int
)
{
n
+=
len
(
p
.
tagcode
)
i
:=
structPointer_InterfaceAt
(
base
,
p
.
field
,
p
.
ctype
)
if
i
==
nil
{
return
0
}
custom
:=
i
.
(
Marshaler
)
data
,
_
:=
custom
.
Marshal
()
n
+=
sizeRawBytes
(
data
)
return
}
func
(
o
*
Buffer
)
enc_custom_slice_bytes
(
p
*
Properties
,
base
structPointer
)
error
{
inter
:=
structPointer_InterfaceRef
(
base
,
p
.
field
,
p
.
ctype
)
if
inter
==
nil
{
return
ErrNil
}
slice
:=
reflect
.
ValueOf
(
inter
)
l
:=
slice
.
Len
()
for
i
:=
0
;
i
<
l
;
i
++
{
v
:=
slice
.
Index
(
i
)
custom
:=
v
.
Interface
()
.
(
Marshaler
)
data
,
err
:=
custom
.
Marshal
()
if
err
!=
nil
{
return
err
}
o
.
buf
=
append
(
o
.
buf
,
p
.
tagcode
...
)
o
.
EncodeRawBytes
(
data
)
}
return
nil
}
func
size_custom_slice_bytes
(
p
*
Properties
,
base
structPointer
)
(
n
int
)
{
inter
:=
structPointer_InterfaceRef
(
base
,
p
.
field
,
p
.
ctype
)
if
inter
==
nil
{
return
0
}
slice
:=
reflect
.
ValueOf
(
inter
)
l
:=
slice
.
Len
()
n
+=
l
*
len
(
p
.
tagcode
)
for
i
:=
0
;
i
<
l
;
i
++
{
v
:=
slice
.
Index
(
i
)
custom
:=
v
.
Interface
()
.
(
Marshaler
)
data
,
_
:=
custom
.
Marshal
()
n
+=
sizeRawBytes
(
data
)
}
return
}
vendor/QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto/equal.go
0 → 100644
View file @
8f79df77
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2011 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.
// Protocol buffer comparison.
// TODO: MessageSet.
package
proto
import
(
"bytes"
"log"
"reflect"
"strings"
)
/*
Equal returns true iff protocol buffers a and b are equal.
The arguments must both be pointers to protocol buffer structs.
Equality is defined in this way:
- Two messages are equal iff they are the same type,
corresponding fields are equal, unknown field sets
are equal, and extensions sets are equal.
- Two set scalar fields are equal iff their values are equal.
If the fields are of a floating-point type, remember that
NaN != x for all x, including NaN.
- Two repeated fields are equal iff their lengths are the same,
and their corresponding elements are equal (a "bytes" field,
although represented by []byte, is not a repeated field)
- Two unset fields are equal.
- Two unknown field sets are equal if their current
encoded state is equal.
- Two extension sets are equal iff they have corresponding
elements that are pairwise equal.
- Every other combination of things are not equal.
The return value is undefined if a and b are not protocol buffers.
*/
func
Equal
(
a
,
b
Message
)
bool
{
if
a
==
nil
||
b
==
nil
{
return
a
==
b
}
v1
,
v2
:=
reflect
.
ValueOf
(
a
),
reflect
.
ValueOf
(
b
)
if
v1
.
Type
()
!=
v2
.
Type
()
{
return
false
}
if
v1
.
Kind
()
==
reflect
.
Ptr
{
if
v1
.
IsNil
()
{
return
v2
.
IsNil
()
}
if
v2
.
IsNil
()
{
return
false
}
v1
,
v2
=
v1
.
Elem
(),
v2
.
Elem
()
}
if
v1
.
Kind
()
!=
reflect
.
Struct
{
return
false
}
return
equalStruct
(
v1
,
v2
)
}
// v1 and v2 are known to have the same type.
func
equalStruct
(
v1
,
v2
reflect
.
Value
)
bool
{
for
i
:=
0
;
i
<
v1
.
NumField
();
i
++
{
f
:=
v1
.
Type
()
.
Field
(
i
)
if
strings
.
HasPrefix
(
f
.
Name
,
"XXX_"
)
{
continue
}
f1
,
f2
:=
v1
.
Field
(
i
),
v2
.
Field
(
i
)
if
f
.
Type
.
Kind
()
==
reflect
.
Ptr
{
if
n1
,
n2
:=
f1
.
IsNil
(),
f2
.
IsNil
();
n1
&&
n2
{
// both unset
continue
}
else
if
n1
!=
n2
{
// set/unset mismatch
return
false
}
b1
,
ok
:=
f1
.
Interface
()
.
(
raw
)
if
ok
{
b2
:=
f2
.
Interface
()
.
(
raw
)
// RawMessage
if
!
bytes
.
Equal
(
b1
.
Bytes
(),
b2
.
Bytes
())
{
return
false
}
continue
}
f1
,
f2
=
f1
.
Elem
(),
f2
.
Elem
()
}
if
!
equalAny
(
f1
,
f2
)
{
return
false
}
}
if
em1
:=
v1
.
FieldByName
(
"XXX_extensions"
);
em1
.
IsValid
()
{
em2
:=
v2
.
FieldByName
(
"XXX_extensions"
)
if
!
equalExtensions
(
v1
.
Type
(),
em1
.
Interface
()
.
(
map
[
int32
]
Extension
),
em2
.
Interface
()
.
(
map
[
int32
]
Extension
))
{
return
false
}
}
uf
:=
v1
.
FieldByName
(
"XXX_unrecognized"
)
if
!
uf
.
IsValid
()
{
return
true
}
u1
:=
uf
.
Bytes
()
u2
:=
v2
.
FieldByName
(
"XXX_unrecognized"
)
.
Bytes
()
if
!
bytes
.
Equal
(
u1
,
u2
)
{
return
false
}
return
true
}
// v1 and v2 are known to have the same type.
func
equalAny
(
v1
,
v2
reflect
.
Value
)
bool
{
if
v1
.
Type
()
==
protoMessageType
{
m1
,
_
:=
v1
.
Interface
()
.
(
Message
)
m2
,
_
:=
v2
.
Interface
()
.
(
Message
)
return
Equal
(
m1
,
m2
)
}
switch
v1
.
Kind
()
{
case
reflect
.
Bool
:
return
v1
.
Bool
()
==
v2
.
Bool
()
case
reflect
.
Float32
,
reflect
.
Float64
:
return
v1
.
Float
()
==
v2
.
Float
()
case
reflect
.
Int32
,
reflect
.
Int64
:
return
v1
.
Int
()
==
v2
.
Int
()
case
reflect
.
Interface
:
// Probably a oneof field; compare the inner values.
n1
,
n2
:=
v1
.
IsNil
(),
v2
.
IsNil
()
if
n1
||
n2
{
return
n1
==
n2
}
e1
,
e2
:=
v1
.
Elem
(),
v2
.
Elem
()
if
e1
.
Type
()
!=
e2
.
Type
()
{
return
false
}
return
equalAny
(
e1
,
e2
)
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
:
return
equalAny
(
v1
.
Elem
(),
v2
.
Elem
())
case
reflect
.
Slice
:
if
v1
.
Type
()
.
Elem
()
.
Kind
()
==
reflect
.
Uint8
{
// short circuit: []byte
if
v1
.
IsNil
()
!=
v2
.
IsNil
()
{
return
false
}
return
bytes
.
Equal
(
v1
.
Interface
()
.
([]
byte
),
v2
.
Interface
()
.
([]
byte
))
}
if
v1
.
Len
()
!=
v2
.
Len
()
{
return
false
}
for
i
:=
0
;
i
<
v1
.
Len
();
i
++
{
if
!
equalAny
(
v1
.
Index
(
i
),
v2
.
Index
(
i
))
{
return
false
}
}
return
true
case
reflect
.
String
:
return
v1
.
Interface
()
.
(
string
)
==
v2
.
Interface
()
.
(
string
)
case
reflect
.
Struct
:
return
equalStruct
(
v1
,
v2
)
case
reflect
.
Uint32
,
reflect
.
Uint64
:
return
v1
.
Uint
()
==
v2
.
Uint
()
}
// unknown type, so not a protocol buffer
log
.
Printf
(
"proto: don't know how to compare %v"
,
v1
)
return
false
}
// base is the struct type that the extensions are based on.
// em1 and em2 are extension maps.
func
equalExtensions
(
base
reflect
.
Type
,
em1
,
em2
map
[
int32
]
Extension
)
bool
{
if
len
(
em1
)
!=
len
(
em2
)
{
return
false
}
for
extNum
,
e1
:=
range
em1
{
e2
,
ok
:=
em2
[
extNum
]
if
!
ok
{
return
false
}
m1
,
m2
:=
e1
.
value
,
e2
.
value
if
m1
!=
nil
&&
m2
!=
nil
{
// Both are unencoded.
if
!
equalAny
(
reflect
.
ValueOf
(
m1
),
reflect
.
ValueOf
(
m2
))
{
return
false
}
continue
}
// At least one is encoded. To do a semantically correct comparison
// we need to unmarshal them first.
var
desc
*
ExtensionDesc
if
m
:=
extensionMaps
[
base
];
m
!=
nil
{
desc
=
m
[
extNum
]
}
if
desc
==
nil
{
log
.
Printf
(
"proto: don't know how to compare extension %d of %v"
,
extNum
,
base
)
continue
}
var
err
error
if
m1
==
nil
{
m1
,
err
=
decodeExtension
(
e1
.
enc
,
desc
)
}
if
m2
==
nil
&&
err
==
nil
{
m2
,
err
=
decodeExtension
(
e2
.
enc
,
desc
)
}
if
err
!=
nil
{
// The encoded form is invalid.
log
.
Printf
(
"proto: badly encoded extension %d of %v: %v"
,
extNum
,
base
,
err
)
return
false
}
if
!
equalAny
(
reflect
.
ValueOf
(
m1
),
reflect
.
ValueOf
(
m2
))
{
return
false
}
}
return
true
}
vendor/QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto/equal_test.go
0 → 100644
View file @
8f79df77
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2011 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"
.
"QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto"
pb
"QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto/testdata"
)
// Four identical base messages.
// The init function adds extensions to some of them.
var
messageWithoutExtension
=
&
pb
.
MyMessage
{
Count
:
Int32
(
7
)}
var
messageWithExtension1a
=
&
pb
.
MyMessage
{
Count
:
Int32
(
7
)}
var
messageWithExtension1b
=
&
pb
.
MyMessage
{
Count
:
Int32
(
7
)}
var
messageWithExtension2
=
&
pb
.
MyMessage
{
Count
:
Int32
(
7
)}
// Two messages with non-message extensions.
var
messageWithInt32Extension1
=
&
pb
.
MyMessage
{
Count
:
Int32
(
8
)}
var
messageWithInt32Extension2
=
&
pb
.
MyMessage
{
Count
:
Int32
(
8
)}
func
init
()
{
ext1
:=
&
pb
.
Ext
{
Data
:
String
(
"Kirk"
)}
ext2
:=
&
pb
.
Ext
{
Data
:
String
(
"Picard"
)}
// messageWithExtension1a has ext1, but never marshals it.
if
err
:=
SetExtension
(
messageWithExtension1a
,
pb
.
E_Ext_More
,
ext1
);
err
!=
nil
{
panic
(
"SetExtension on 1a failed: "
+
err
.
Error
())
}
// messageWithExtension1b is the unmarshaled form of messageWithExtension1a.
if
err
:=
SetExtension
(
messageWithExtension1b
,
pb
.
E_Ext_More
,
ext1
);
err
!=
nil
{
panic
(
"SetExtension on 1b failed: "
+
err
.
Error
())
}
buf
,
err
:=
Marshal
(
messageWithExtension1b
)
if
err
!=
nil
{
panic
(
"Marshal of 1b failed: "
+
err
.
Error
())
}
messageWithExtension1b
.
Reset
()
if
err
:=
Unmarshal
(
buf
,
messageWithExtension1b
);
err
!=
nil
{
panic
(
"Unmarshal of 1b failed: "
+
err
.
Error
())
}
// messageWithExtension2 has ext2.
if
err
:=
SetExtension
(
messageWithExtension2
,
pb
.
E_Ext_More
,
ext2
);
err
!=
nil
{
panic
(
"SetExtension on 2 failed: "
+
err
.
Error
())
}
if
err
:=
SetExtension
(
messageWithInt32Extension1
,
pb
.
E_Ext_Number
,
Int32
(
23
));
err
!=
nil
{
panic
(
"SetExtension on Int32-1 failed: "
+
err
.
Error
())
}
if
err
:=
SetExtension
(
messageWithInt32Extension1
,
pb
.
E_Ext_Number
,
Int32
(
24
));
err
!=
nil
{
panic
(
"SetExtension on Int32-2 failed: "
+
err
.
Error
())
}
}
var
EqualTests
=
[]
struct
{
desc
string
a
,
b
Message
exp
bool
}{
{
"different types"
,
&
pb
.
GoEnum
{},
&
pb
.
GoTestField
{},
false
},
{
"equal empty"
,
&
pb
.
GoEnum
{},
&
pb
.
GoEnum
{},
true
},
{
"nil vs nil"
,
nil
,
nil
,
true
},
{
"typed nil vs typed nil"
,
(
*
pb
.
GoEnum
)(
nil
),
(
*
pb
.
GoEnum
)(
nil
),
true
},
{
"typed nil vs empty"
,
(
*
pb
.
GoEnum
)(
nil
),
&
pb
.
GoEnum
{},
false
},
{
"different typed nil"
,
(
*
pb
.
GoEnum
)(
nil
),
(
*
pb
.
GoTestField
)(
nil
),
false
},
{
"one set field, one unset field"
,
&
pb
.
GoTestField
{
Label
:
String
(
"foo"
)},
&
pb
.
GoTestField
{},
false
},
{
"one set field zero, one unset field"
,
&
pb
.
GoTest
{
Param
:
Int32
(
0
)},
&
pb
.
GoTest
{},
false
},
{
"different set fields"
,
&
pb
.
GoTestField
{
Label
:
String
(
"foo"
)},
&
pb
.
GoTestField
{
Label
:
String
(
"bar"
)},
false
},
{
"equal set"
,
&
pb
.
GoTestField
{
Label
:
String
(
"foo"
)},
&
pb
.
GoTestField
{
Label
:
String
(
"foo"
)},
true
},
{
"repeated, one set"
,
&
pb
.
GoTest
{
F_Int32Repeated
:
[]
int32
{
2
,
3
}},
&
pb
.
GoTest
{},
false
},
{
"repeated, different length"
,
&
pb
.
GoTest
{
F_Int32Repeated
:
[]
int32
{
2
,
3
}},
&
pb
.
GoTest
{
F_Int32Repeated
:
[]
int32
{
2
}},
false
},
{
"repeated, different value"
,
&
pb
.
GoTest
{
F_Int32Repeated
:
[]
int32
{
2
}},
&
pb
.
GoTest
{
F_Int32Repeated
:
[]
int32
{
3
}},
false
},
{
"repeated, equal"
,
&
pb
.
GoTest
{
F_Int32Repeated
:
[]
int32
{
2
,
4
}},
&
pb
.
GoTest
{
F_Int32Repeated
:
[]
int32
{
2
,
4
}},
true
},
{
"repeated, nil equal nil"
,
&
pb
.
GoTest
{
F_Int32Repeated
:
nil
},
&
pb
.
GoTest
{
F_Int32Repeated
:
nil
},
true
},
{
"repeated, nil equal empty"
,
&
pb
.
GoTest
{
F_Int32Repeated
:
nil
},
&
pb
.
GoTest
{
F_Int32Repeated
:
[]
int32
{}},
true
},
{
"repeated, empty equal nil"
,
&
pb
.
GoTest
{
F_Int32Repeated
:
[]
int32
{}},
&
pb
.
GoTest
{
F_Int32Repeated
:
nil
},
true
},
{
"nested, different"
,
&
pb
.
GoTest
{
RequiredField
:
&
pb
.
GoTestField
{
Label
:
String
(
"foo"
)}},
&
pb
.
GoTest
{
RequiredField
:
&
pb
.
GoTestField
{
Label
:
String
(
"bar"
)}},
false
,
},
{
"nested, equal"
,
&
pb
.
GoTest
{
RequiredField
:
&
pb
.
GoTestField
{
Label
:
String
(
"wow"
)}},
&
pb
.
GoTest
{
RequiredField
:
&
pb
.
GoTestField
{
Label
:
String
(
"wow"
)}},
true
,
},
{
"bytes"
,
&
pb
.
OtherMessage
{
Value
:
[]
byte
(
"foo"
)},
&
pb
.
OtherMessage
{
Value
:
[]
byte
(
"foo"
)},
true
},
{
"bytes, empty"
,
&
pb
.
OtherMessage
{
Value
:
[]
byte
{}},
&
pb
.
OtherMessage
{
Value
:
[]
byte
{}},
true
},
{
"bytes, empty vs nil"
,
&
pb
.
OtherMessage
{
Value
:
[]
byte
{}},
&
pb
.
OtherMessage
{
Value
:
nil
},
false
},
{
"repeated bytes"
,
&
pb
.
MyMessage
{
RepBytes
:
[][]
byte
{[]
byte
(
"sham"
),
[]
byte
(
"wow"
)}},
&
pb
.
MyMessage
{
RepBytes
:
[][]
byte
{[]
byte
(
"sham"
),
[]
byte
(
"wow"
)}},
true
,
},
{
"extension vs. no extension"
,
messageWithoutExtension
,
messageWithExtension1a
,
false
},
{
"extension vs. same extension"
,
messageWithExtension1a
,
messageWithExtension1b
,
true
},
{
"extension vs. different extension"
,
messageWithExtension1a
,
messageWithExtension2
,
false
},
{
"int32 extension vs. itself"
,
messageWithInt32Extension1
,
messageWithInt32Extension1
,
true
},
{
"int32 extension vs. a different int32"
,
messageWithInt32Extension1
,
messageWithInt32Extension2
,
false
},
{
"message with group"
,
&
pb
.
MyMessage
{
Count
:
Int32
(
1
),
Somegroup
:
&
pb
.
MyMessage_SomeGroup
{
GroupField
:
Int32
(
5
),
},
},
&
pb
.
MyMessage
{
Count
:
Int32
(
1
),
Somegroup
:
&
pb
.
MyMessage_SomeGroup
{
GroupField
:
Int32
(
5
),
},
},
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
,
},
{
"oneof same"
,
&
pb
.
Communique
{
Union
:
&
pb
.
Communique_Number
{
Number
:
41
}},
&
pb
.
Communique
{
Union
:
&
pb
.
Communique_Number
{
Number
:
41
}},
true
,
},
{
"oneof one nil"
,
&
pb
.
Communique
{
Union
:
&
pb
.
Communique_Number
{
Number
:
41
}},
&
pb
.
Communique
{},
false
,
},
{
"oneof different"
,
&
pb
.
Communique
{
Union
:
&
pb
.
Communique_Number
{
Number
:
41
}},
&
pb
.
Communique
{
Union
:
&
pb
.
Communique_Name
{
Name
:
"Bobby Tables"
}},
false
,
},
}
func
TestEqual
(
t
*
testing
.
T
)
{
for
_
,
tc
:=
range
EqualTests
{
if
res
:=
Equal
(
tc
.
a
,
tc
.
b
);
res
!=
tc
.
exp
{
t
.
Errorf
(
"%v: Equal(%v, %v) = %v, want %v"
,
tc
.
desc
,
tc
.
a
,
tc
.
b
,
res
,
tc
.
exp
)
}
}
}
vendor/QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto/extensions.go
0 → 100644
View file @
8f79df77
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2010 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
/*
* Types and routines for supporting protocol buffer extensions.
*/
import
(
"errors"
"fmt"
"reflect"
"strconv"
"sync"
)
// ErrMissingExtension is the error returned by GetExtension if the named extension is not in the message.
var
ErrMissingExtension
=
errors
.
New
(
"proto: missing extension"
)
// ExtensionRange represents a range of message extensions for a protocol buffer.
// Used in code generated by the protocol compiler.
type
ExtensionRange
struct
{
Start
,
End
int32
// both inclusive
}
// extendableProto is an interface implemented by any protocol buffer that may be extended.
type
extendableProto
interface
{
Message
ExtensionRangeArray
()
[]
ExtensionRange
}
type
extensionsMap
interface
{
extendableProto
ExtensionMap
()
map
[
int32
]
Extension
}
type
extensionsBytes
interface
{
extendableProto
GetExtensions
()
*
[]
byte
}
var
extendableProtoType
=
reflect
.
TypeOf
((
*
extendableProto
)(
nil
))
.
Elem
()
// ExtensionDesc represents an extension specification.
// Used in generated code from the protocol compiler.
type
ExtensionDesc
struct
{
ExtendedType
Message
// nil pointer to the type that is being extended
ExtensionType
interface
{}
// nil pointer to the extension type
Field
int32
// field number
Name
string
// fully-qualified name of extension, for text formatting
Tag
string
// protobuf tag style
}
func
(
ed
*
ExtensionDesc
)
repeated
()
bool
{
t
:=
reflect
.
TypeOf
(
ed
.
ExtensionType
)
return
t
.
Kind
()
==
reflect
.
Slice
&&
t
.
Elem
()
.
Kind
()
!=
reflect
.
Uint8
}
// Extension represents an extension in a message.
type
Extension
struct
{
// When an extension is stored in a message using SetExtension
// only desc and value are set. When the message is marshaled
// enc will be set to the encoded form of the message.
//
// When a message is unmarshaled and contains extensions, each
// extension will have only enc set. When such an extension is
// accessed using GetExtension (or GetExtensions) desc and value
// will be set.
desc
*
ExtensionDesc
value
interface
{}
enc
[]
byte
}
// SetRawExtension is for testing only.
func
SetRawExtension
(
base
extendableProto
,
id
int32
,
b
[]
byte
)
{
if
ebase
,
ok
:=
base
.
(
extensionsMap
);
ok
{
ebase
.
ExtensionMap
()[
id
]
=
Extension
{
enc
:
b
}
}
else
if
ebase
,
ok
:=
base
.
(
extensionsBytes
);
ok
{
clearExtension
(
base
,
id
)
ext
:=
ebase
.
GetExtensions
()
*
ext
=
append
(
*
ext
,
b
...
)
}
else
{
panic
(
"unreachable"
)
}
}
// isExtensionField returns true iff the given field number is in an extension range.
func
isExtensionField
(
pb
extendableProto
,
field
int32
)
bool
{
for
_
,
er
:=
range
pb
.
ExtensionRangeArray
()
{
if
er
.
Start
<=
field
&&
field
<=
er
.
End
{
return
true
}
}
return
false
}
// checkExtensionTypes checks that the given extension is valid for pb.
func
checkExtensionTypes
(
pb
extendableProto
,
extension
*
ExtensionDesc
)
error
{
// Check the extended type.
if
a
,
b
:=
reflect
.
TypeOf
(
pb
),
reflect
.
TypeOf
(
extension
.
ExtendedType
);
a
!=
b
{
return
errors
.
New
(
"proto: bad extended type; "
+
b
.
String
()
+
" does not extend "
+
a
.
String
())
}
// Check the range.
if
!
isExtensionField
(
pb
,
extension
.
Field
)
{
return
errors
.
New
(
"proto: bad extension number; not in declared ranges"
)
}
return
nil
}
// extPropKey is sufficient to uniquely identify an extension.
type
extPropKey
struct
{
base
reflect
.
Type
field
int32
}
var
extProp
=
struct
{
sync
.
RWMutex
m
map
[
extPropKey
]
*
Properties
}{
m
:
make
(
map
[
extPropKey
]
*
Properties
),
}
func
extensionProperties
(
ed
*
ExtensionDesc
)
*
Properties
{
key
:=
extPropKey
{
base
:
reflect
.
TypeOf
(
ed
.
ExtendedType
),
field
:
ed
.
Field
}
extProp
.
RLock
()
if
prop
,
ok
:=
extProp
.
m
[
key
];
ok
{
extProp
.
RUnlock
()
return
prop
}
extProp
.
RUnlock
()
extProp
.
Lock
()
defer
extProp
.
Unlock
()
// Check again.
if
prop
,
ok
:=
extProp
.
m
[
key
];
ok
{
return
prop
}
prop
:=
new
(
Properties
)
prop
.
Init
(
reflect
.
TypeOf
(
ed
.
ExtensionType
),
"unknown_name"
,
ed
.
Tag
,
nil
)
extProp
.
m
[
key
]
=
prop
return
prop
}
// encodeExtensionMap encodes any unmarshaled (unencoded) extensions in m.
func
encodeExtensionMap
(
m
map
[
int32
]
Extension
)
error
{
for
k
,
e
:=
range
m
{
err
:=
encodeExtension
(
&
e
)
if
err
!=
nil
{
return
err
}
m
[
k
]
=
e
}
return
nil
}
func
encodeExtension
(
e
*
Extension
)
error
{
if
e
.
value
==
nil
||
e
.
desc
==
nil
{
// Extension is only in its encoded form.
return
nil
}
// We don't skip extensions that have an encoded form set,
// because the extension value may have been mutated after
// the last time this function was called.
et
:=
reflect
.
TypeOf
(
e
.
desc
.
ExtensionType
)
props
:=
extensionProperties
(
e
.
desc
)
p
:=
NewBuffer
(
nil
)
// If e.value has type T, the encoder expects a *struct{ X T }.
// Pass a *T with a zero field and hope it all works out.
x
:=
reflect
.
New
(
et
)
x
.
Elem
()
.
Set
(
reflect
.
ValueOf
(
e
.
value
))
if
err
:=
props
.
enc
(
p
,
props
,
toStructPointer
(
x
));
err
!=
nil
{
return
err
}
e
.
enc
=
p
.
buf
return
nil
}
func
sizeExtensionMap
(
m
map
[
int32
]
Extension
)
(
n
int
)
{
for
_
,
e
:=
range
m
{
if
e
.
value
==
nil
||
e
.
desc
==
nil
{
// Extension is only in its encoded form.
n
+=
len
(
e
.
enc
)
continue
}
// We don't skip extensions that have an encoded form set,
// because the extension value may have been mutated after
// the last time this function was called.
et
:=
reflect
.
TypeOf
(
e
.
desc
.
ExtensionType
)
props
:=
extensionProperties
(
e
.
desc
)
// If e.value has type T, the encoder expects a *struct{ X T }.
// Pass a *T with a zero field and hope it all works out.
x
:=
reflect
.
New
(
et
)
x
.
Elem
()
.
Set
(
reflect
.
ValueOf
(
e
.
value
))
n
+=
props
.
size
(
props
,
toStructPointer
(
x
))
}
return
}
// HasExtension returns whether the given extension is present in pb.
func
HasExtension
(
pb
extendableProto
,
extension
*
ExtensionDesc
)
bool
{
// TODO: Check types, field numbers, etc.?
if
epb
,
doki
:=
pb
.
(
extensionsMap
);
doki
{
_
,
ok
:=
epb
.
ExtensionMap
()[
extension
.
Field
]
return
ok
}
else
if
epb
,
doki
:=
pb
.
(
extensionsBytes
);
doki
{
ext
:=
epb
.
GetExtensions
()
buf
:=
*
ext
o
:=
0
for
o
<
len
(
buf
)
{
tag
,
n
:=
DecodeVarint
(
buf
[
o
:
])
fieldNum
:=
int32
(
tag
>>
3
)
if
int32
(
fieldNum
)
==
extension
.
Field
{
return
true
}
wireType
:=
int
(
tag
&
0x7
)
o
+=
n
l
,
err
:=
size
(
buf
[
o
:
],
wireType
)
if
err
!=
nil
{
return
false
}
o
+=
l
}
return
false
}
panic
(
"unreachable"
)
}
func
deleteExtension
(
pb
extensionsBytes
,
theFieldNum
int32
,
offset
int
)
int
{
ext
:=
pb
.
GetExtensions
()
for
offset
<
len
(
*
ext
)
{
tag
,
n1
:=
DecodeVarint
((
*
ext
)[
offset
:
])
fieldNum
:=
int32
(
tag
>>
3
)
wireType
:=
int
(
tag
&
0x7
)
n2
,
err
:=
size
((
*
ext
)[
offset
+
n1
:
],
wireType
)
if
err
!=
nil
{
panic
(
err
)
}
newOffset
:=
offset
+
n1
+
n2
if
fieldNum
==
theFieldNum
{
*
ext
=
append
((
*
ext
)[
:
offset
],
(
*
ext
)[
newOffset
:
]
...
)
return
offset
}
offset
=
newOffset
}
return
-
1
}
func
clearExtension
(
pb
extendableProto
,
fieldNum
int32
)
{
if
epb
,
doki
:=
pb
.
(
extensionsMap
);
doki
{
delete
(
epb
.
ExtensionMap
(),
fieldNum
)
}
else
if
epb
,
doki
:=
pb
.
(
extensionsBytes
);
doki
{
offset
:=
0
for
offset
!=
-
1
{
offset
=
deleteExtension
(
epb
,
fieldNum
,
offset
)
}
}
else
{
panic
(
"unreachable"
)
}
}
// ClearExtension removes the given extension from pb.
func
ClearExtension
(
pb
extendableProto
,
extension
*
ExtensionDesc
)
{
// TODO: Check types, field numbers, etc.?
clearExtension
(
pb
,
extension
.
Field
)
}
// GetExtension parses and returns the given extension of pb.
// If the extension is not present it returns ErrMissingExtension.
func
GetExtension
(
pb
extendableProto
,
extension
*
ExtensionDesc
)
(
interface
{},
error
)
{
if
err
:=
checkExtensionTypes
(
pb
,
extension
);
err
!=
nil
{
return
nil
,
err
}
if
epb
,
doki
:=
pb
.
(
extensionsMap
);
doki
{
emap
:=
epb
.
ExtensionMap
()
e
,
ok
:=
emap
[
extension
.
Field
]
if
!
ok
{
// defaultExtensionValue returns the default value or
// ErrMissingExtension if there is no default.
return
defaultExtensionValue
(
extension
)
}
if
e
.
value
!=
nil
{
// Already decoded. Check the descriptor, though.
if
e
.
desc
!=
extension
{
// This shouldn't happen. If it does, it means that
// GetExtension was called twice with two different
// descriptors with the same field number.
return
nil
,
errors
.
New
(
"proto: descriptor conflict"
)
}
return
e
.
value
,
nil
}
v
,
err
:=
decodeExtension
(
e
.
enc
,
extension
)
if
err
!=
nil
{
return
nil
,
err
}
// Remember the decoded version and drop the encoded version.
// That way it is safe to mutate what we return.
e
.
value
=
v
e
.
desc
=
extension
e
.
enc
=
nil
emap
[
extension
.
Field
]
=
e
return
e
.
value
,
nil
}
else
if
epb
,
doki
:=
pb
.
(
extensionsBytes
);
doki
{
ext
:=
epb
.
GetExtensions
()
o
:=
0
for
o
<
len
(
*
ext
)
{
tag
,
n
:=
DecodeVarint
((
*
ext
)[
o
:
])
fieldNum
:=
int32
(
tag
>>
3
)
wireType
:=
int
(
tag
&
0x7
)
l
,
err
:=
size
((
*
ext
)[
o
+
n
:
],
wireType
)
if
err
!=
nil
{
return
nil
,
err
}
if
int32
(
fieldNum
)
==
extension
.
Field
{
v
,
err
:=
decodeExtension
((
*
ext
)[
o
:
o
+
n
+
l
],
extension
)
if
err
!=
nil
{
return
nil
,
err
}
return
v
,
nil
}
o
+=
n
+
l
}
return
defaultExtensionValue
(
extension
)
}
panic
(
"unreachable"
)
}
// defaultExtensionValue returns the default value for extension.
// If no default for an extension is defined ErrMissingExtension is returned.
func
defaultExtensionValue
(
extension
*
ExtensionDesc
)
(
interface
{},
error
)
{
t
:=
reflect
.
TypeOf
(
extension
.
ExtensionType
)
props
:=
extensionProperties
(
extension
)
sf
,
_
,
err
:=
fieldDefault
(
t
,
props
)
if
err
!=
nil
{
return
nil
,
err
}
if
sf
==
nil
||
sf
.
value
==
nil
{
// There is no default value.
return
nil
,
ErrMissingExtension
}
if
t
.
Kind
()
!=
reflect
.
Ptr
{
// We do not need to return a Ptr, we can directly return sf.value.
return
sf
.
value
,
nil
}
// We need to return an interface{} that is a pointer to sf.value.
value
:=
reflect
.
New
(
t
)
.
Elem
()
value
.
Set
(
reflect
.
New
(
value
.
Type
()
.
Elem
()))
if
sf
.
kind
==
reflect
.
Int32
{
// We may have an int32 or an enum, but the underlying data is int32.
// Since we can't set an int32 into a non int32 reflect.value directly
// set it as a int32.
value
.
Elem
()
.
SetInt
(
int64
(
sf
.
value
.
(
int32
)))
}
else
{
value
.
Elem
()
.
Set
(
reflect
.
ValueOf
(
sf
.
value
))
}
return
value
.
Interface
(),
nil
}
// decodeExtension decodes an extension encoded in b.
func
decodeExtension
(
b
[]
byte
,
extension
*
ExtensionDesc
)
(
interface
{},
error
)
{
o
:=
NewBuffer
(
b
)
t
:=
reflect
.
TypeOf
(
extension
.
ExtensionType
)
rep
:=
extension
.
repeated
()
props
:=
extensionProperties
(
extension
)
// t is a pointer to a struct, pointer to basic type or a slice.
// Allocate a "field" to store the pointer/slice itself; the
// pointer/slice will be stored here. We pass
// the address of this field to props.dec.
// This passes a zero field and a *t and lets props.dec
// interpret it as a *struct{ x t }.
value
:=
reflect
.
New
(
t
)
.
Elem
()
for
{
// Discard wire type and field number varint. It isn't needed.
if
_
,
err
:=
o
.
DecodeVarint
();
err
!=
nil
{
return
nil
,
err
}
if
err
:=
props
.
dec
(
o
,
props
,
toStructPointer
(
value
.
Addr
()));
err
!=
nil
{
return
nil
,
err
}
if
!
rep
||
o
.
index
>=
len
(
o
.
buf
)
{
break
}
}
return
value
.
Interface
(),
nil
}
// GetExtensions returns a slice of the extensions present in pb that are also listed in es.
// The returned slice has the same length as es; missing extensions will appear as nil elements.
func
GetExtensions
(
pb
Message
,
es
[]
*
ExtensionDesc
)
(
extensions
[]
interface
{},
err
error
)
{
epb
,
ok
:=
pb
.
(
extendableProto
)
if
!
ok
{
err
=
errors
.
New
(
"proto: not an extendable proto"
)
return
}
extensions
=
make
([]
interface
{},
len
(
es
))
for
i
,
e
:=
range
es
{
extensions
[
i
],
err
=
GetExtension
(
epb
,
e
)
if
err
==
ErrMissingExtension
{
err
=
nil
}
if
err
!=
nil
{
return
}
}
return
}
// SetExtension sets the specified extension of pb to the specified value.
func
SetExtension
(
pb
extendableProto
,
extension
*
ExtensionDesc
,
value
interface
{})
error
{
if
err
:=
checkExtensionTypes
(
pb
,
extension
);
err
!=
nil
{
return
err
}
typ
:=
reflect
.
TypeOf
(
extension
.
ExtensionType
)
if
typ
!=
reflect
.
TypeOf
(
value
)
{
return
errors
.
New
(
"proto: bad extension value type"
)
}
// nil extension values need to be caught early, because the
// encoder can't distinguish an ErrNil due to a nil extension
// from an ErrNil due to a missing field. Extensions are
// always optional, so the encoder would just swallow the error
// and drop all the extensions from the encoded message.
if
reflect
.
ValueOf
(
value
)
.
IsNil
()
{
return
fmt
.
Errorf
(
"proto: SetExtension called with nil value of type %T"
,
value
)
}
return
setExtension
(
pb
,
extension
,
value
)
}
func
setExtension
(
pb
extendableProto
,
extension
*
ExtensionDesc
,
value
interface
{})
error
{
if
epb
,
doki
:=
pb
.
(
extensionsMap
);
doki
{
epb
.
ExtensionMap
()[
extension
.
Field
]
=
Extension
{
desc
:
extension
,
value
:
value
}
}
else
if
epb
,
doki
:=
pb
.
(
extensionsBytes
);
doki
{
ClearExtension
(
pb
,
extension
)
ext
:=
epb
.
GetExtensions
()
et
:=
reflect
.
TypeOf
(
extension
.
ExtensionType
)
props
:=
extensionProperties
(
extension
)
p
:=
NewBuffer
(
nil
)
x
:=
reflect
.
New
(
et
)
x
.
Elem
()
.
Set
(
reflect
.
ValueOf
(
value
))
if
err
:=
props
.
enc
(
p
,
props
,
toStructPointer
(
x
));
err
!=
nil
{
return
err
}
*
ext
=
append
(
*
ext
,
p
.
buf
...
)
}
return
nil
}
// A global registry of extensions.
// The generated code will register the generated descriptors by calling RegisterExtension.
var
extensionMaps
=
make
(
map
[
reflect
.
Type
]
map
[
int32
]
*
ExtensionDesc
)
// RegisterExtension is called from the generated code.
func
RegisterExtension
(
desc
*
ExtensionDesc
)
{
st
:=
reflect
.
TypeOf
(
desc
.
ExtendedType
)
.
Elem
()
m
:=
extensionMaps
[
st
]
if
m
==
nil
{
m
=
make
(
map
[
int32
]
*
ExtensionDesc
)
extensionMaps
[
st
]
=
m
}
if
_
,
ok
:=
m
[
desc
.
Field
];
ok
{
panic
(
"proto: duplicate extension registered: "
+
st
.
String
()
+
" "
+
strconv
.
Itoa
(
int
(
desc
.
Field
)))
}
m
[
desc
.
Field
]
=
desc
}
// RegisteredExtensions returns a map of the registered extensions of a
// protocol buffer struct, indexed by the extension number.
// The argument pb should be a nil pointer to the struct type.
func
RegisteredExtensions
(
pb
Message
)
map
[
int32
]
*
ExtensionDesc
{
return
extensionMaps
[
reflect
.
TypeOf
(
pb
)
.
Elem
()]
}
vendor/QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto/extensions_gogo.go
0 → 100644
View file @
8f79df77
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
// http://github.com/gogo/protobuf/gogoproto
//
// 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.
//
// 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
import
(
"bytes"
"errors"
"fmt"
"reflect"
"sort"
"strings"
)
func
GetBoolExtension
(
pb
extendableProto
,
extension
*
ExtensionDesc
,
ifnotset
bool
)
bool
{
if
reflect
.
ValueOf
(
pb
)
.
IsNil
()
{
return
ifnotset
}
value
,
err
:=
GetExtension
(
pb
,
extension
)
if
err
!=
nil
{
return
ifnotset
}
if
value
==
nil
{
return
ifnotset
}
if
value
.
(
*
bool
)
==
nil
{
return
ifnotset
}
return
*
(
value
.
(
*
bool
))
}
func
(
this
*
Extension
)
Equal
(
that
*
Extension
)
bool
{
return
bytes
.
Equal
(
this
.
enc
,
that
.
enc
)
}
func
SizeOfExtensionMap
(
m
map
[
int32
]
Extension
)
(
n
int
)
{
return
sizeExtensionMap
(
m
)
}
type
sortableMapElem
struct
{
field
int32
ext
Extension
}
func
newSortableExtensionsFromMap
(
m
map
[
int32
]
Extension
)
sortableExtensions
{
s
:=
make
(
sortableExtensions
,
0
,
len
(
m
))
for
k
,
v
:=
range
m
{
s
=
append
(
s
,
&
sortableMapElem
{
field
:
k
,
ext
:
v
})
}
return
s
}
type
sortableExtensions
[]
*
sortableMapElem
func
(
this
sortableExtensions
)
Len
()
int
{
return
len
(
this
)
}
func
(
this
sortableExtensions
)
Swap
(
i
,
j
int
)
{
this
[
i
],
this
[
j
]
=
this
[
j
],
this
[
i
]
}
func
(
this
sortableExtensions
)
Less
(
i
,
j
int
)
bool
{
return
this
[
i
]
.
field
<
this
[
j
]
.
field
}
func
(
this
sortableExtensions
)
String
()
string
{
sort
.
Sort
(
this
)
ss
:=
make
([]
string
,
len
(
this
))
for
i
:=
range
this
{
ss
[
i
]
=
fmt
.
Sprintf
(
"%d: %v"
,
this
[
i
]
.
field
,
this
[
i
]
.
ext
)
}
return
"map["
+
strings
.
Join
(
ss
,
","
)
+
"]"
}
func
StringFromExtensionsMap
(
m
map
[
int32
]
Extension
)
string
{
return
newSortableExtensionsFromMap
(
m
)
.
String
()
}
func
StringFromExtensionsBytes
(
ext
[]
byte
)
string
{
m
,
err
:=
BytesToExtensionsMap
(
ext
)
if
err
!=
nil
{
panic
(
err
)
}
return
StringFromExtensionsMap
(
m
)
}
func
EncodeExtensionMap
(
m
map
[
int32
]
Extension
,
data
[]
byte
)
(
n
int
,
err
error
)
{
if
err
:=
encodeExtensionMap
(
m
);
err
!=
nil
{
return
0
,
err
}
keys
:=
make
([]
int
,
0
,
len
(
m
))
for
k
:=
range
m
{
keys
=
append
(
keys
,
int
(
k
))
}
sort
.
Ints
(
keys
)
for
_
,
k
:=
range
keys
{
n
+=
copy
(
data
[
n
:
],
m
[
int32
(
k
)]
.
enc
)
}
return
n
,
nil
}
func
GetRawExtension
(
m
map
[
int32
]
Extension
,
id
int32
)
([]
byte
,
error
)
{
if
m
[
id
]
.
value
==
nil
||
m
[
id
]
.
desc
==
nil
{
return
m
[
id
]
.
enc
,
nil
}
if
err
:=
encodeExtensionMap
(
m
);
err
!=
nil
{
return
nil
,
err
}
return
m
[
id
]
.
enc
,
nil
}
func
size
(
buf
[]
byte
,
wire
int
)
(
int
,
error
)
{
switch
wire
{
case
WireVarint
:
_
,
n
:=
DecodeVarint
(
buf
)
return
n
,
nil
case
WireFixed64
:
return
8
,
nil
case
WireBytes
:
v
,
n
:=
DecodeVarint
(
buf
)
return
int
(
v
)
+
n
,
nil
case
WireFixed32
:
return
4
,
nil
case
WireStartGroup
:
offset
:=
0
for
{
u
,
n
:=
DecodeVarint
(
buf
[
offset
:
])
fwire
:=
int
(
u
&
0x7
)
offset
+=
n
if
fwire
==
WireEndGroup
{
return
offset
,
nil
}
s
,
err
:=
size
(
buf
[
offset
:
],
wire
)
if
err
!=
nil
{
return
0
,
err
}
offset
+=
s
}
}
return
0
,
fmt
.
Errorf
(
"proto: can't get size for unknown wire type %d"
,
wire
)
}
func
BytesToExtensionsMap
(
buf
[]
byte
)
(
map
[
int32
]
Extension
,
error
)
{
m
:=
make
(
map
[
int32
]
Extension
)
i
:=
0
for
i
<
len
(
buf
)
{
tag
,
n
:=
DecodeVarint
(
buf
[
i
:
])
if
n
<=
0
{
return
nil
,
fmt
.
Errorf
(
"unable to decode varint"
)
}
fieldNum
:=
int32
(
tag
>>
3
)
wireType
:=
int
(
tag
&
0x7
)
l
,
err
:=
size
(
buf
[
i
+
n
:
],
wireType
)
if
err
!=
nil
{
return
nil
,
err
}
end
:=
i
+
int
(
l
)
+
n
m
[
int32
(
fieldNum
)]
=
Extension
{
enc
:
buf
[
i
:
end
]}
i
=
end
}
return
m
,
nil
}
func
NewExtension
(
e
[]
byte
)
Extension
{
ee
:=
Extension
{
enc
:
make
([]
byte
,
len
(
e
))}
copy
(
ee
.
enc
,
e
)
return
ee
}
func
(
this
Extension
)
GoString
()
string
{
if
this
.
enc
==
nil
{
if
err
:=
encodeExtension
(
&
this
);
err
!=
nil
{
panic
(
err
)
}
}
return
fmt
.
Sprintf
(
"proto.NewExtension(%#v)"
,
this
.
enc
)
}
func
SetUnsafeExtension
(
pb
extendableProto
,
fieldNum
int32
,
value
interface
{})
error
{
typ
:=
reflect
.
TypeOf
(
pb
)
.
Elem
()
ext
,
ok
:=
extensionMaps
[
typ
]
if
!
ok
{
return
fmt
.
Errorf
(
"proto: bad extended type; %s is not extendable"
,
typ
.
String
())
}
desc
,
ok
:=
ext
[
fieldNum
]
if
!
ok
{
return
errors
.
New
(
"proto: bad extension number; not in declared ranges"
)
}
return
setExtension
(
pb
,
desc
,
value
)
}
func
GetUnsafeExtension
(
pb
extendableProto
,
fieldNum
int32
)
(
interface
{},
error
)
{
typ
:=
reflect
.
TypeOf
(
pb
)
.
Elem
()
ext
,
ok
:=
extensionMaps
[
typ
]
if
!
ok
{
return
nil
,
fmt
.
Errorf
(
"proto: bad extended type; %s is not extendable"
,
typ
.
String
())
}
desc
,
ok
:=
ext
[
fieldNum
]
if
!
ok
{
return
nil
,
fmt
.
Errorf
(
"unregistered field number %d"
,
fieldNum
)
}
return
GetExtension
(
pb
,
desc
)
}
vendor/QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto/extensions_test.go
0 → 100644
View file @
8f79df77
// 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
(
"fmt"
"reflect"
"testing"
"QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto"
pb
"QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto/testdata"
)
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
TestGetExtensionDefaults
(
t
*
testing
.
T
)
{
var
setFloat64
float64
=
1
var
setFloat32
float32
=
2
var
setInt32
int32
=
3
var
setInt64
int64
=
4
var
setUint32
uint32
=
5
var
setUint64
uint64
=
6
var
setBool
=
true
var
setBool2
=
false
var
setString
=
"Goodnight string"
var
setBytes
=
[]
byte
(
"Goodnight bytes"
)
var
setEnum
=
pb
.
DefaultsMessage_TWO
type
testcase
struct
{
ext
*
proto
.
ExtensionDesc
// Extension we are testing.
want
interface
{}
// Expected value of extension, or nil (meaning that GetExtension will fail).
def
interface
{}
// Expected value of extension after ClearExtension().
}
tests
:=
[]
testcase
{
{
pb
.
E_NoDefaultDouble
,
setFloat64
,
nil
},
{
pb
.
E_NoDefaultFloat
,
setFloat32
,
nil
},
{
pb
.
E_NoDefaultInt32
,
setInt32
,
nil
},
{
pb
.
E_NoDefaultInt64
,
setInt64
,
nil
},
{
pb
.
E_NoDefaultUint32
,
setUint32
,
nil
},
{
pb
.
E_NoDefaultUint64
,
setUint64
,
nil
},
{
pb
.
E_NoDefaultSint32
,
setInt32
,
nil
},
{
pb
.
E_NoDefaultSint64
,
setInt64
,
nil
},
{
pb
.
E_NoDefaultFixed32
,
setUint32
,
nil
},
{
pb
.
E_NoDefaultFixed64
,
setUint64
,
nil
},
{
pb
.
E_NoDefaultSfixed32
,
setInt32
,
nil
},
{
pb
.
E_NoDefaultSfixed64
,
setInt64
,
nil
},
{
pb
.
E_NoDefaultBool
,
setBool
,
nil
},
{
pb
.
E_NoDefaultBool
,
setBool2
,
nil
},
{
pb
.
E_NoDefaultString
,
setString
,
nil
},
{
pb
.
E_NoDefaultBytes
,
setBytes
,
nil
},
{
pb
.
E_NoDefaultEnum
,
setEnum
,
nil
},
{
pb
.
E_DefaultDouble
,
setFloat64
,
float64
(
3.1415
)},
{
pb
.
E_DefaultFloat
,
setFloat32
,
float32
(
3.14
)},
{
pb
.
E_DefaultInt32
,
setInt32
,
int32
(
42
)},
{
pb
.
E_DefaultInt64
,
setInt64
,
int64
(
43
)},
{
pb
.
E_DefaultUint32
,
setUint32
,
uint32
(
44
)},
{
pb
.
E_DefaultUint64
,
setUint64
,
uint64
(
45
)},
{
pb
.
E_DefaultSint32
,
setInt32
,
int32
(
46
)},
{
pb
.
E_DefaultSint64
,
setInt64
,
int64
(
47
)},
{
pb
.
E_DefaultFixed32
,
setUint32
,
uint32
(
48
)},
{
pb
.
E_DefaultFixed64
,
setUint64
,
uint64
(
49
)},
{
pb
.
E_DefaultSfixed32
,
setInt32
,
int32
(
50
)},
{
pb
.
E_DefaultSfixed64
,
setInt64
,
int64
(
51
)},
{
pb
.
E_DefaultBool
,
setBool
,
true
},
{
pb
.
E_DefaultBool
,
setBool2
,
true
},
{
pb
.
E_DefaultString
,
setString
,
"Hello, string"
},
{
pb
.
E_DefaultBytes
,
setBytes
,
[]
byte
(
"Hello, bytes"
)},
{
pb
.
E_DefaultEnum
,
setEnum
,
pb
.
DefaultsMessage_ONE
},
}
checkVal
:=
func
(
test
testcase
,
msg
*
pb
.
DefaultsMessage
,
valWant
interface
{})
error
{
val
,
err
:=
proto
.
GetExtension
(
msg
,
test
.
ext
)
if
err
!=
nil
{
if
valWant
!=
nil
{
return
fmt
.
Errorf
(
"GetExtension(): %s"
,
err
)
}
if
want
:=
proto
.
ErrMissingExtension
;
err
!=
want
{
return
fmt
.
Errorf
(
"Unexpected error: got %v, want %v"
,
err
,
want
)
}
return
nil
}
// All proto2 extension values are either a pointer to a value or a slice of values.
ty
:=
reflect
.
TypeOf
(
val
)
tyWant
:=
reflect
.
TypeOf
(
test
.
ext
.
ExtensionType
)
if
got
,
want
:=
ty
,
tyWant
;
got
!=
want
{
return
fmt
.
Errorf
(
"unexpected reflect.TypeOf(): got %v want %v"
,
got
,
want
)
}
tye
:=
ty
.
Elem
()
tyeWant
:=
tyWant
.
Elem
()
if
got
,
want
:=
tye
,
tyeWant
;
got
!=
want
{
return
fmt
.
Errorf
(
"unexpected reflect.TypeOf().Elem(): got %v want %v"
,
got
,
want
)
}
// Check the name of the type of the value.
// If it is an enum it will be type int32 with the name of the enum.
if
got
,
want
:=
tye
.
Name
(),
tye
.
Name
();
got
!=
want
{
return
fmt
.
Errorf
(
"unexpected reflect.TypeOf().Elem().Name(): got %v want %v"
,
got
,
want
)
}
// Check that value is what we expect.
// If we have a pointer in val, get the value it points to.
valExp
:=
val
if
ty
.
Kind
()
==
reflect
.
Ptr
{
valExp
=
reflect
.
ValueOf
(
val
)
.
Elem
()
.
Interface
()
}
if
got
,
want
:=
valExp
,
valWant
;
!
reflect
.
DeepEqual
(
got
,
want
)
{
return
fmt
.
Errorf
(
"unexpected reflect.DeepEqual(): got %v want %v"
,
got
,
want
)
}
return
nil
}
setTo
:=
func
(
test
testcase
)
interface
{}
{
setTo
:=
reflect
.
ValueOf
(
test
.
want
)
if
typ
:=
reflect
.
TypeOf
(
test
.
ext
.
ExtensionType
);
typ
.
Kind
()
==
reflect
.
Ptr
{
setTo
=
reflect
.
New
(
typ
)
.
Elem
()
setTo
.
Set
(
reflect
.
New
(
setTo
.
Type
()
.
Elem
()))
setTo
.
Elem
()
.
Set
(
reflect
.
ValueOf
(
test
.
want
))
}
return
setTo
.
Interface
()
}
for
_
,
test
:=
range
tests
{
msg
:=
&
pb
.
DefaultsMessage
{}
name
:=
test
.
ext
.
Name
// Check the initial value.
if
err
:=
checkVal
(
test
,
msg
,
test
.
def
);
err
!=
nil
{
t
.
Errorf
(
"%s: %v"
,
name
,
err
)
}
// Set the per-type value and check value.
name
=
fmt
.
Sprintf
(
"%s (set to %T %v)"
,
name
,
test
.
want
,
test
.
want
)
if
err
:=
proto
.
SetExtension
(
msg
,
test
.
ext
,
setTo
(
test
));
err
!=
nil
{
t
.
Errorf
(
"%s: SetExtension(): %v"
,
name
,
err
)
continue
}
if
err
:=
checkVal
(
test
,
msg
,
test
.
want
);
err
!=
nil
{
t
.
Errorf
(
"%s: %v"
,
name
,
err
)
continue
}
// Set and check the value.
name
+=
" (cleared)"
proto
.
ClearExtension
(
msg
,
test
.
ext
)
if
err
:=
checkVal
(
test
,
msg
,
test
.
def
);
err
!=
nil
{
t
.
Errorf
(
"%s: %v"
,
name
,
err
)
}
}
}
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"
)
}
}
func
TestNilExtension
(
t
*
testing
.
T
)
{
msg
:=
&
pb
.
MyMessage
{
Count
:
proto
.
Int32
(
1
),
}
if
err
:=
proto
.
SetExtension
(
msg
,
pb
.
E_Ext_Text
,
proto
.
String
(
"hello"
));
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
err
:=
proto
.
SetExtension
(
msg
,
pb
.
E_Ext_More
,
(
*
pb
.
Ext
)(
nil
));
err
==
nil
{
t
.
Error
(
"expected SetExtension to fail due to a nil extension"
)
}
else
if
want
:=
"proto: SetExtension called with nil value of type *testdata.Ext"
;
err
.
Error
()
!=
want
{
t
.
Errorf
(
"expected error %v, got %v"
,
want
,
err
)
}
// Note: if the behavior of Marshal is ever changed to ignore nil extensions, update
// this test to verify that E_Ext_Text is properly propagated through marshal->unmarshal.
}
vendor/QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto/lib.go
0 → 100644
View file @
8f79df77
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2010 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 converts data structures to and from the wire format of
protocol buffers. It works in concert with the Go source code generated
for .proto files by the protocol compiler.
A summary of the properties of the protocol buffer interface
for a protocol buffer variable v:
- Names are turned from camel_case to CamelCase for export.
- There are no methods on v to set fields; just treat
them as structure fields.
- There are getters that return a field's value if set,
and return the field's default value if unset.
The getters work even if the receiver is a nil message.
- The zero value for a struct is its correct initialization state.
All desired fields must be set before marshaling.
- A Reset() method will restore a protobuf struct to its zero state.
- Non-repeated fields are pointers to the values; nil means unset.
That is, optional or required field int32 f becomes F *int32.
- Repeated fields are slices.
- Helper functions are available to aid the setting of fields.
msg.Foo = proto.String("hello") // set field
- Constants are defined to hold the default values of all fields that
have them. They have the form Default_StructName_FieldName.
Because the getter methods handle defaulted values,
direct use of these constants should be rare.
- Enums are given type names and maps from names to values.
Enum values are prefixed by the enclosing message's name, or by the
enum's type name if it is a top-level enum. Enum types have a String
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.
- Extensions are given descriptor names that start with E_,
followed by an underscore-delimited list of the nested messages
that contain it (if any) followed by the CamelCased name of the
extension field itself. HasExtension, ClearExtension, GetExtension
and SetExtension are functions for manipulating extensions.
- Oneof field sets are given a single field in their message,
with distinguished wrapper types for each possible field value.
- Marshal and Unmarshal are functions to encode and decode the wire format.
The simplest way to describe this is to see an example.
Given file test.proto, containing
package example;
enum FOO { X = 17; }
message Test {
required string label = 1;
optional int32 type = 2 [default=77];
repeated int64 reps = 3;
optional group OptionalGroup = 4 {
required string RequiredField = 5;
}
oneof union {
int32 number = 6;
string name = 7;
}
}
The resulting file, test.pb.go, is:
package example
import proto "github.com/gogo/protobuf/proto"
import math "math"
type FOO int32
const (
FOO_X FOO = 17
)
var FOO_name = map[int32]string{
17: "X",
}
var FOO_value = map[string]int32{
"X": 17,
}
func (x FOO) Enum() *FOO {
p := new(FOO)
*p = x
return p
}
func (x FOO) String() string {
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 {
Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"`
Type *int32 `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"`
Reps []int64 `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"`
Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"`
// Types that are valid to be assigned to Union:
// *Test_Number
// *Test_Name
Union isTest_Union `protobuf_oneof:"union"`
XXX_unrecognized []byte `json:"-"`
}
func (m *Test) Reset() { *m = Test{} }
func (m *Test) String() string { return proto.CompactTextString(m) }
func (*Test) ProtoMessage() {}
type isTest_Union interface {
isTest_Union()
}
type Test_Number struct {
Number int32 `protobuf:"varint,6,opt,name=number"`
}
type Test_Name struct {
Name string `protobuf:"bytes,7,opt,name=name"`
}
func (*Test_Number) isTest_Union() {}
func (*Test_Name) isTest_Union() {}
func (m *Test) GetUnion() isTest_Union {
if m != nil {
return m.Union
}
return nil
}
const Default_Test_Type int32 = 77
func (m *Test) GetLabel() string {
if m != nil && m.Label != nil {
return *m.Label
}
return ""
}
func (m *Test) GetType() int32 {
if m != nil && m.Type != nil {
return *m.Type
}
return Default_Test_Type
}
func (m *Test) GetOptionalgroup() *Test_OptionalGroup {
if m != nil {
return m.Optionalgroup
}
return nil
}
type Test_OptionalGroup struct {
RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"`
}
func (m *Test_OptionalGroup) Reset() { *m = Test_OptionalGroup{} }
func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) }
func (m *Test_OptionalGroup) GetRequiredField() string {
if m != nil && m.RequiredField != nil {
return *m.RequiredField
}
return ""
}
func (m *Test) GetNumber() int32 {
if x, ok := m.GetUnion().(*Test_Number); ok {
return x.Number
}
return 0
}
func (m *Test) GetName() string {
if x, ok := m.GetUnion().(*Test_Name); ok {
return x.Name
}
return ""
}
func init() {
proto.RegisterEnum("example.FOO", FOO_name, FOO_value)
}
To create and play with a Test object:
package main
import (
"log"
"github.com/gogo/protobuf/proto"
pb "./example.pb"
)
func main() {
test := &pb.Test{
Label: proto.String("hello"),
Type: proto.Int32(17),
Optionalgroup: &pb.Test_OptionalGroup{
RequiredField: proto.String("good bye"),
},
Union: &pb.Test_Name{"fred"},
}
data, err := proto.Marshal(test)
if err != nil {
log.Fatal("marshaling error: ", err)
}
newTest := &pb.Test{}
err = proto.Unmarshal(data, newTest)
if err != nil {
log.Fatal("unmarshaling error: ", err)
}
// Now test and newTest contain the same data.
if test.GetLabel() != newTest.GetLabel() {
log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel())
}
// Use a type switch to determine which oneof was set.
switch u := test.Union.(type) {
case *pb.Test_Number: // u.Number contains the number.
case *pb.Test_Name: // u.Name contains the string.
}
// etc.
}
*/
package
proto
import
(
"encoding/json"
"fmt"
"log"
"reflect"
"sort"
"strconv"
"sync"
)
// Message is implemented by generated protocol buffer messages.
type
Message
interface
{
Reset
()
String
()
string
ProtoMessage
()
}
// Stats records allocation details about the protocol buffer encoders
// and decoders. Useful for tuning the library itself.
type
Stats
struct
{
Emalloc
uint64
// mallocs in encode
Dmalloc
uint64
// mallocs in decode
Encode
uint64
// number of encodes
Decode
uint64
// number of decodes
Chit
uint64
// number of cache hits
Cmiss
uint64
// number of cache misses
Size
uint64
// number of sizes
}
// Set to true to enable stats collection.
const
collectStats
=
false
var
stats
Stats
// GetStats returns a copy of the global Stats structure.
func
GetStats
()
Stats
{
return
stats
}
// A Buffer is a buffer manager for marshaling and unmarshaling
// protocol buffers. It may be reused between invocations to
// reduce memory usage. It is not necessary to use a Buffer;
// the global functions Marshal and Unmarshal create a
// temporary Buffer and are fine for most applications.
type
Buffer
struct
{
buf
[]
byte
// encode/decode byte stream
index
int
// write point
// pools of basic types to amortize allocation.
bools
[]
bool
uint32s
[]
uint32
uint64s
[]
uint64
// extra pools, only used with pointer_reflect.go
int32s
[]
int32
int64s
[]
int64
float32s
[]
float32
float64s
[]
float64
}
// NewBuffer allocates a new Buffer and initializes its internal data to
// the contents of the argument slice.
func
NewBuffer
(
e
[]
byte
)
*
Buffer
{
return
&
Buffer
{
buf
:
e
}
}
// Reset resets the Buffer, ready for marshaling a new protocol buffer.
func
(
p
*
Buffer
)
Reset
()
{
p
.
buf
=
p
.
buf
[
0
:
0
]
// for reading/writing
p
.
index
=
0
// for reading
}
// SetBuf replaces the internal buffer with the slice,
// ready for unmarshaling the contents of the slice.
func
(
p
*
Buffer
)
SetBuf
(
s
[]
byte
)
{
p
.
buf
=
s
p
.
index
=
0
}
// Bytes returns the contents of the Buffer.
func
(
p
*
Buffer
)
Bytes
()
[]
byte
{
return
p
.
buf
}
/*
* Helper routines for simplifying the creation of optional fields of basic type.
*/
// Bool is a helper routine that allocates a new bool value
// to store v and returns a pointer to it.
func
Bool
(
v
bool
)
*
bool
{
return
&
v
}
// Int32 is a helper routine that allocates a new int32 value
// to store v and returns a pointer to it.
func
Int32
(
v
int32
)
*
int32
{
return
&
v
}
// Int is a helper routine that allocates a new int32 value
// to store v and returns a pointer to it, but unlike Int32
// its argument value is an int.
func
Int
(
v
int
)
*
int32
{
p
:=
new
(
int32
)
*
p
=
int32
(
v
)
return
p
}
// Int64 is a helper routine that allocates a new int64 value
// to store v and returns a pointer to it.
func
Int64
(
v
int64
)
*
int64
{
return
&
v
}
// Float32 is a helper routine that allocates a new float32 value
// to store v and returns a pointer to it.
func
Float32
(
v
float32
)
*
float32
{
return
&
v
}
// Float64 is a helper routine that allocates a new float64 value
// to store v and returns a pointer to it.
func
Float64
(
v
float64
)
*
float64
{
return
&
v
}
// Uint32 is a helper routine that allocates a new uint32 value
// to store v and returns a pointer to it.
func
Uint32
(
v
uint32
)
*
uint32
{
return
&
v
}
// Uint64 is a helper routine that allocates a new uint64 value
// to store v and returns a pointer to it.
func
Uint64
(
v
uint64
)
*
uint64
{
return
&
v
}
// String is a helper routine that allocates a new string value
// to store v and returns a pointer to it.
func
String
(
v
string
)
*
string
{
return
&
v
}
// EnumName is a helper function to simplify printing protocol buffer enums
// by name. Given an enum map and a value, it returns a useful string.
func
EnumName
(
m
map
[
int32
]
string
,
v
int32
)
string
{
s
,
ok
:=
m
[
v
]
if
ok
{
return
s
}
return
strconv
.
Itoa
(
int
(
v
))
}
// UnmarshalJSONEnum is a helper function to simplify recovering enum int values
// from their JSON-encoded representation. Given a map from the enum's symbolic
// names to its int values, and a byte buffer containing the JSON-encoded
// value, it returns an int32 that can be cast to the enum type by the caller.
//
// The function can deal with both JSON representations, numeric and symbolic.
func
UnmarshalJSONEnum
(
m
map
[
string
]
int32
,
data
[]
byte
,
enumName
string
)
(
int32
,
error
)
{
if
data
[
0
]
==
'"'
{
// New style: enums are strings.
var
repr
string
if
err
:=
json
.
Unmarshal
(
data
,
&
repr
);
err
!=
nil
{
return
-
1
,
err
}
val
,
ok
:=
m
[
repr
]
if
!
ok
{
return
0
,
fmt
.
Errorf
(
"unrecognized enum %s value %q"
,
enumName
,
repr
)
}
return
val
,
nil
}
// Old style: enums are ints.
var
val
int32
if
err
:=
json
.
Unmarshal
(
data
,
&
val
);
err
!=
nil
{
return
0
,
fmt
.
Errorf
(
"cannot unmarshal %#q into enum %s"
,
data
,
enumName
)
}
return
val
,
nil
}
// DebugPrint dumps the encoded data in b in a debugging format with a header
// including the string s. Used in testing but made available for general debugging.
func
(
p
*
Buffer
)
DebugPrint
(
s
string
,
b
[]
byte
)
{
var
u
uint64
obuf
:=
p
.
buf
index
:=
p
.
index
p
.
buf
=
b
p
.
index
=
0
depth
:=
0
fmt
.
Printf
(
"
\n
--- %s ---
\n
"
,
s
)
out
:
for
{
for
i
:=
0
;
i
<
depth
;
i
++
{
fmt
.
Print
(
" "
)
}
index
:=
p
.
index
if
index
==
len
(
p
.
buf
)
{
break
}
op
,
err
:=
p
.
DecodeVarint
()
if
err
!=
nil
{
fmt
.
Printf
(
"%3d: fetching op err %v
\n
"
,
index
,
err
)
break
out
}
tag
:=
op
>>
3
wire
:=
op
&
7
switch
wire
{
default
:
fmt
.
Printf
(
"%3d: t=%3d unknown wire=%d
\n
"
,
index
,
tag
,
wire
)
break
out
case
WireBytes
:
var
r
[]
byte
r
,
err
=
p
.
DecodeRawBytes
(
false
)
if
err
!=
nil
{
break
out
}
fmt
.
Printf
(
"%3d: t=%3d bytes [%d]"
,
index
,
tag
,
len
(
r
))
if
len
(
r
)
<=
6
{
for
i
:=
0
;
i
<
len
(
r
);
i
++
{
fmt
.
Printf
(
" %.2x"
,
r
[
i
])
}
}
else
{
for
i
:=
0
;
i
<
3
;
i
++
{
fmt
.
Printf
(
" %.2x"
,
r
[
i
])
}
fmt
.
Printf
(
" .."
)
for
i
:=
len
(
r
)
-
3
;
i
<
len
(
r
);
i
++
{
fmt
.
Printf
(
" %.2x"
,
r
[
i
])
}
}
fmt
.
Printf
(
"
\n
"
)
case
WireFixed32
:
u
,
err
=
p
.
DecodeFixed32
()
if
err
!=
nil
{
fmt
.
Printf
(
"%3d: t=%3d fix32 err %v
\n
"
,
index
,
tag
,
err
)
break
out
}
fmt
.
Printf
(
"%3d: t=%3d fix32 %d
\n
"
,
index
,
tag
,
u
)
case
WireFixed64
:
u
,
err
=
p
.
DecodeFixed64
()
if
err
!=
nil
{
fmt
.
Printf
(
"%3d: t=%3d fix64 err %v
\n
"
,
index
,
tag
,
err
)
break
out
}
fmt
.
Printf
(
"%3d: t=%3d fix64 %d
\n
"
,
index
,
tag
,
u
)
case
WireVarint
:
u
,
err
=
p
.
DecodeVarint
()
if
err
!=
nil
{
fmt
.
Printf
(
"%3d: t=%3d varint err %v
\n
"
,
index
,
tag
,
err
)
break
out
}
fmt
.
Printf
(
"%3d: t=%3d varint %d
\n
"
,
index
,
tag
,
u
)
case
WireStartGroup
:
fmt
.
Printf
(
"%3d: t=%3d start
\n
"
,
index
,
tag
)
depth
++
case
WireEndGroup
:
depth
--
fmt
.
Printf
(
"%3d: t=%3d end
\n
"
,
index
,
tag
)
}
}
if
depth
!=
0
{
fmt
.
Printf
(
"%3d: start-end not balanced %d
\n
"
,
p
.
index
,
depth
)
}
fmt
.
Printf
(
"
\n
"
)
p
.
buf
=
obuf
p
.
index
=
index
}
// SetDefaults sets unset protocol buffer fields to their default values.
// It only modifies fields that are both unset and have defined defaults.
// It recursively sets default values in any non-nil sub-messages.
func
SetDefaults
(
pb
Message
)
{
setDefaults
(
reflect
.
ValueOf
(
pb
),
true
,
false
)
}
// v is a pointer to a struct.
func
setDefaults
(
v
reflect
.
Value
,
recur
,
zeros
bool
)
{
v
=
v
.
Elem
()
defaultMu
.
RLock
()
dm
,
ok
:=
defaults
[
v
.
Type
()]
defaultMu
.
RUnlock
()
if
!
ok
{
dm
=
buildDefaultMessage
(
v
.
Type
())
defaultMu
.
Lock
()
defaults
[
v
.
Type
()]
=
dm
defaultMu
.
Unlock
()
}
for
_
,
sf
:=
range
dm
.
scalars
{
f
:=
v
.
Field
(
sf
.
index
)
if
!
f
.
IsNil
()
{
// field already set
continue
}
dv
:=
sf
.
value
if
dv
==
nil
&&
!
zeros
{
// no explicit default, and don't want to set zeros
continue
}
fptr
:=
f
.
Addr
()
.
Interface
()
// **T
// TODO: Consider batching the allocations we do here.
switch
sf
.
kind
{
case
reflect
.
Bool
:
b
:=
new
(
bool
)
if
dv
!=
nil
{
*
b
=
dv
.
(
bool
)
}
*
(
fptr
.
(
**
bool
))
=
b
case
reflect
.
Float32
:
f
:=
new
(
float32
)
if
dv
!=
nil
{
*
f
=
dv
.
(
float32
)
}
*
(
fptr
.
(
**
float32
))
=
f
case
reflect
.
Float64
:
f
:=
new
(
float64
)
if
dv
!=
nil
{
*
f
=
dv
.
(
float64
)
}
*
(
fptr
.
(
**
float64
))
=
f
case
reflect
.
Int32
:
// might be an enum
if
ft
:=
f
.
Type
();
ft
!=
int32PtrType
{
// enum
f
.
Set
(
reflect
.
New
(
ft
.
Elem
()))
if
dv
!=
nil
{
f
.
Elem
()
.
SetInt
(
int64
(
dv
.
(
int32
)))
}
}
else
{
// int32 field
i
:=
new
(
int32
)
if
dv
!=
nil
{
*
i
=
dv
.
(
int32
)
}
*
(
fptr
.
(
**
int32
))
=
i
}
case
reflect
.
Int64
:
i
:=
new
(
int64
)
if
dv
!=
nil
{
*
i
=
dv
.
(
int64
)
}
*
(
fptr
.
(
**
int64
))
=
i
case
reflect
.
String
:
s
:=
new
(
string
)
if
dv
!=
nil
{
*
s
=
dv
.
(
string
)
}
*
(
fptr
.
(
**
string
))
=
s
case
reflect
.
Uint8
:
// exceptional case: []byte
var
b
[]
byte
if
dv
!=
nil
{
db
:=
dv
.
([]
byte
)
b
=
make
([]
byte
,
len
(
db
))
copy
(
b
,
db
)
}
else
{
b
=
[]
byte
{}
}
*
(
fptr
.
(
*
[]
byte
))
=
b
case
reflect
.
Uint32
:
u
:=
new
(
uint32
)
if
dv
!=
nil
{
*
u
=
dv
.
(
uint32
)
}
*
(
fptr
.
(
**
uint32
))
=
u
case
reflect
.
Uint64
:
u
:=
new
(
uint64
)
if
dv
!=
nil
{
*
u
=
dv
.
(
uint64
)
}
*
(
fptr
.
(
**
uint64
))
=
u
default
:
log
.
Printf
(
"proto: can't set default for field %v (sf.kind=%v)"
,
f
,
sf
.
kind
)
}
}
for
_
,
ni
:=
range
dm
.
nested
{
f
:=
v
.
Field
(
ni
)
// f is *T or []*T or map[T]*T
switch
f
.
Kind
()
{
case
reflect
.
Ptr
:
if
f
.
IsNil
()
{
continue
}
setDefaults
(
f
,
recur
,
zeros
)
case
reflect
.
Slice
:
for
i
:=
0
;
i
<
f
.
Len
();
i
++
{
e
:=
f
.
Index
(
i
)
if
e
.
IsNil
()
{
continue
}
setDefaults
(
e
,
recur
,
zeros
)
}
case
reflect
.
Map
:
for
_
,
k
:=
range
f
.
MapKeys
()
{
e
:=
f
.
MapIndex
(
k
)
if
e
.
IsNil
()
{
continue
}
setDefaults
(
e
,
recur
,
zeros
)
}
}
}
}
var
(
// defaults maps a protocol buffer struct type to a slice of the fields,
// with its scalar fields set to their proto-declared non-zero default values.
defaultMu
sync
.
RWMutex
defaults
=
make
(
map
[
reflect
.
Type
]
defaultMessage
)
int32PtrType
=
reflect
.
TypeOf
((
*
int32
)(
nil
))
)
// defaultMessage represents information about the default values of a message.
type
defaultMessage
struct
{
scalars
[]
scalarField
nested
[]
int
// struct field index of nested messages
}
type
scalarField
struct
{
index
int
// struct field index
kind
reflect
.
Kind
// element type (the T in *T or []T)
value
interface
{}
// the proto-declared default value, or nil
}
// t is a struct type.
func
buildDefaultMessage
(
t
reflect
.
Type
)
(
dm
defaultMessage
)
{
sprop
:=
GetProperties
(
t
)
for
_
,
prop
:=
range
sprop
.
Prop
{
fi
,
ok
:=
sprop
.
decoderTags
.
get
(
prop
.
Tag
)
if
!
ok
{
// XXX_unrecognized
continue
}
ft
:=
t
.
Field
(
fi
)
.
Type
sf
,
nested
,
err
:=
fieldDefault
(
ft
,
prop
)
switch
{
case
err
!=
nil
:
log
.
Print
(
err
)
case
nested
:
dm
.
nested
=
append
(
dm
.
nested
,
fi
)
case
sf
!=
nil
:
sf
.
index
=
fi
dm
.
scalars
=
append
(
dm
.
scalars
,
*
sf
)
}
}
return
dm
}
// fieldDefault returns the scalarField for field type ft.
// sf will be nil if the field can not have a default.
// nestedMessage will be true if this is a nested message.
// Note that sf.index is not set on return.
func
fieldDefault
(
ft
reflect
.
Type
,
prop
*
Properties
)
(
sf
*
scalarField
,
nestedMessage
bool
,
err
error
)
{
var
canHaveDefault
bool
switch
ft
.
Kind
()
{
case
reflect
.
Ptr
:
if
ft
.
Elem
()
.
Kind
()
==
reflect
.
Struct
{
nestedMessage
=
true
}
else
{
canHaveDefault
=
true
// proto2 scalar field
}
case
reflect
.
Slice
:
switch
ft
.
Elem
()
.
Kind
()
{
case
reflect
.
Ptr
:
nestedMessage
=
true
// repeated message
case
reflect
.
Uint8
:
canHaveDefault
=
true
// bytes field
}
case
reflect
.
Map
:
if
ft
.
Elem
()
.
Kind
()
==
reflect
.
Ptr
{
nestedMessage
=
true
// map with message values
}
}
if
!
canHaveDefault
{
if
nestedMessage
{
return
nil
,
true
,
nil
}
return
nil
,
false
,
nil
}
// We now know that ft is a pointer or slice.
sf
=
&
scalarField
{
kind
:
ft
.
Elem
()
.
Kind
()}
// scalar fields without defaults
if
!
prop
.
HasDefault
{
return
sf
,
false
,
nil
}
// a scalar field: either *T or []byte
switch
ft
.
Elem
()
.
Kind
()
{
case
reflect
.
Bool
:
x
,
err
:=
strconv
.
ParseBool
(
prop
.
Default
)
if
err
!=
nil
{
return
nil
,
false
,
fmt
.
Errorf
(
"proto: bad default bool %q: %v"
,
prop
.
Default
,
err
)
}
sf
.
value
=
x
case
reflect
.
Float32
:
x
,
err
:=
strconv
.
ParseFloat
(
prop
.
Default
,
32
)
if
err
!=
nil
{
return
nil
,
false
,
fmt
.
Errorf
(
"proto: bad default float32 %q: %v"
,
prop
.
Default
,
err
)
}
sf
.
value
=
float32
(
x
)
case
reflect
.
Float64
:
x
,
err
:=
strconv
.
ParseFloat
(
prop
.
Default
,
64
)
if
err
!=
nil
{
return
nil
,
false
,
fmt
.
Errorf
(
"proto: bad default float64 %q: %v"
,
prop
.
Default
,
err
)
}
sf
.
value
=
x
case
reflect
.
Int32
:
x
,
err
:=
strconv
.
ParseInt
(
prop
.
Default
,
10
,
32
)
if
err
!=
nil
{
return
nil
,
false
,
fmt
.
Errorf
(
"proto: bad default int32 %q: %v"
,
prop
.
Default
,
err
)
}
sf
.
value
=
int32
(
x
)
case
reflect
.
Int64
:
x
,
err
:=
strconv
.
ParseInt
(
prop
.
Default
,
10
,
64
)
if
err
!=
nil
{
return
nil
,
false
,
fmt
.
Errorf
(
"proto: bad default int64 %q: %v"
,
prop
.
Default
,
err
)
}
sf
.
value
=
x
case
reflect
.
String
:
sf
.
value
=
prop
.
Default
case
reflect
.
Uint8
:
// []byte (not *uint8)
sf
.
value
=
[]
byte
(
prop
.
Default
)
case
reflect
.
Uint32
:
x
,
err
:=
strconv
.
ParseUint
(
prop
.
Default
,
10
,
32
)
if
err
!=
nil
{
return
nil
,
false
,
fmt
.
Errorf
(
"proto: bad default uint32 %q: %v"
,
prop
.
Default
,
err
)
}
sf
.
value
=
uint32
(
x
)
case
reflect
.
Uint64
:
x
,
err
:=
strconv
.
ParseUint
(
prop
.
Default
,
10
,
64
)
if
err
!=
nil
{
return
nil
,
false
,
fmt
.
Errorf
(
"proto: bad default uint64 %q: %v"
,
prop
.
Default
,
err
)
}
sf
.
value
=
x
default
:
return
nil
,
false
,
fmt
.
Errorf
(
"proto: unhandled def kind %v"
,
ft
.
Elem
()
.
Kind
())
}
return
sf
,
false
,
nil
}
// 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.
func
mapKeys
(
vs
[]
reflect
.
Value
)
sort
.
Interface
{
s
:=
mapKeySorter
{
vs
:
vs
,
// default Less function: textual comparison
less
:
func
(
a
,
b
reflect
.
Value
)
bool
{
return
fmt
.
Sprint
(
a
.
Interface
())
<
fmt
.
Sprint
(
b
.
Interface
())
},
}
// Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps;
// numeric keys are sorted numerically.
if
len
(
vs
)
==
0
{
return
s
}
switch
vs
[
0
]
.
Kind
()
{
case
reflect
.
Int32
,
reflect
.
Int64
:
s
.
less
=
func
(
a
,
b
reflect
.
Value
)
bool
{
return
a
.
Int
()
<
b
.
Int
()
}
case
reflect
.
Uint32
,
reflect
.
Uint64
:
s
.
less
=
func
(
a
,
b
reflect
.
Value
)
bool
{
return
a
.
Uint
()
<
b
.
Uint
()
}
}
return
s
}
type
mapKeySorter
struct
{
vs
[]
reflect
.
Value
less
func
(
a
,
b
reflect
.
Value
)
bool
}
func
(
s
mapKeySorter
)
Len
()
int
{
return
len
(
s
.
vs
)
}
func
(
s
mapKeySorter
)
Swap
(
i
,
j
int
)
{
s
.
vs
[
i
],
s
.
vs
[
j
]
=
s
.
vs
[
j
],
s
.
vs
[
i
]
}
func
(
s
mapKeySorter
)
Less
(
i
,
j
int
)
bool
{
return
s
.
less
(
s
.
vs
[
i
],
s
.
vs
[
j
])
}
// isProto3Zero reports whether v is a zero proto3 value.
func
isProto3Zero
(
v
reflect
.
Value
)
bool
{
switch
v
.
Kind
()
{
case
reflect
.
Bool
:
return
!
v
.
Bool
()
case
reflect
.
Int32
,
reflect
.
Int64
:
return
v
.
Int
()
==
0
case
reflect
.
Uint32
,
reflect
.
Uint64
:
return
v
.
Uint
()
==
0
case
reflect
.
Float32
,
reflect
.
Float64
:
return
v
.
Float
()
==
0
case
reflect
.
String
:
return
v
.
String
()
==
""
}
return
false
}
vendor/QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto/lib_gogo.go
0 → 100644
View file @
8f79df77
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
// http://github.com/gogo/protobuf/gogoproto
//
// 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.
//
// 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
import
(
"encoding/json"
"strconv"
)
func
MarshalJSONEnum
(
m
map
[
int32
]
string
,
value
int32
)
([]
byte
,
error
)
{
s
,
ok
:=
m
[
value
]
if
!
ok
{
s
=
strconv
.
Itoa
(
int
(
value
))
}
return
json
.
Marshal
(
s
)
}
vendor/QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto/message_set.go
0 → 100644
View file @
8f79df77
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2010 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
/*
* Support for message sets.
*/
import
(
"bytes"
"encoding/json"
"errors"
"fmt"
"reflect"
"sort"
)
// ErrNoMessageTypeId occurs when a protocol buffer does not have a message type ID.
// A message type ID is required for storing a protocol buffer in a message set.
var
ErrNoMessageTypeId
=
errors
.
New
(
"proto does not have a message type ID"
)
// The first two types (_MessageSet_Item and MessageSet)
// model what the protocol compiler produces for the following protocol message:
// message MessageSet {
// repeated group Item = 1 {
// required int32 type_id = 2;
// required string message = 3;
// };
// }
// That is the MessageSet wire format. We can't use a proto to generate these
// because that would introduce a circular dependency between it and this package.
//
// When a proto1 proto has a field that looks like:
// optional message<MessageSet> info = 3;
// the protocol compiler produces a field in the generated struct that looks like:
// Info *_proto_.MessageSet `protobuf:"bytes,3,opt,name=info"`
// The package is automatically inserted so there is no need for that proto file to
// import this package.
type
_MessageSet_Item
struct
{
TypeId
*
int32
`protobuf:"varint,2,req,name=type_id"`
Message
[]
byte
`protobuf:"bytes,3,req,name=message"`
}
type
MessageSet
struct
{
Item
[]
*
_MessageSet_Item
`protobuf:"group,1,rep"`
XXX_unrecognized
[]
byte
// TODO: caching?
}
// Make sure MessageSet is a Message.
var
_
Message
=
(
*
MessageSet
)(
nil
)
// messageTypeIder is an interface satisfied by a protocol buffer type
// that may be stored in a MessageSet.
type
messageTypeIder
interface
{
MessageTypeId
()
int32
}
func
(
ms
*
MessageSet
)
find
(
pb
Message
)
*
_MessageSet_Item
{
mti
,
ok
:=
pb
.
(
messageTypeIder
)
if
!
ok
{
return
nil
}
id
:=
mti
.
MessageTypeId
()
for
_
,
item
:=
range
ms
.
Item
{
if
*
item
.
TypeId
==
id
{
return
item
}
}
return
nil
}
func
(
ms
*
MessageSet
)
Has
(
pb
Message
)
bool
{
if
ms
.
find
(
pb
)
!=
nil
{
return
true
}
return
false
}
func
(
ms
*
MessageSet
)
Unmarshal
(
pb
Message
)
error
{
if
item
:=
ms
.
find
(
pb
);
item
!=
nil
{
return
Unmarshal
(
item
.
Message
,
pb
)
}
if
_
,
ok
:=
pb
.
(
messageTypeIder
);
!
ok
{
return
ErrNoMessageTypeId
}
return
nil
// TODO: return error instead?
}
func
(
ms
*
MessageSet
)
Marshal
(
pb
Message
)
error
{
msg
,
err
:=
Marshal
(
pb
)
if
err
!=
nil
{
return
err
}
if
item
:=
ms
.
find
(
pb
);
item
!=
nil
{
// reuse existing item
item
.
Message
=
msg
return
nil
}
mti
,
ok
:=
pb
.
(
messageTypeIder
)
if
!
ok
{
return
ErrNoMessageTypeId
}
mtid
:=
mti
.
MessageTypeId
()
ms
.
Item
=
append
(
ms
.
Item
,
&
_MessageSet_Item
{
TypeId
:
&
mtid
,
Message
:
msg
,
})
return
nil
}
func
(
ms
*
MessageSet
)
Reset
()
{
*
ms
=
MessageSet
{}
}
func
(
ms
*
MessageSet
)
String
()
string
{
return
CompactTextString
(
ms
)
}
func
(
*
MessageSet
)
ProtoMessage
()
{}
// Support for the message_set_wire_format message option.
func
skipVarint
(
buf
[]
byte
)
[]
byte
{
i
:=
0
for
;
buf
[
i
]
&
0x80
!=
0
;
i
++
{
}
return
buf
[
i
+
1
:
]
}
// MarshalMessageSet encodes the extension map represented by m in the message set wire format.
// It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option.
func
MarshalMessageSet
(
m
map
[
int32
]
Extension
)
([]
byte
,
error
)
{
if
err
:=
encodeExtensionMap
(
m
);
err
!=
nil
{
return
nil
,
err
}
// Sort extension IDs to provide a deterministic encoding.
// See also enc_map in encode.go.
ids
:=
make
([]
int
,
0
,
len
(
m
))
for
id
:=
range
m
{
ids
=
append
(
ids
,
int
(
id
))
}
sort
.
Ints
(
ids
)
ms
:=
&
MessageSet
{
Item
:
make
([]
*
_MessageSet_Item
,
0
,
len
(
m
))}
for
_
,
id
:=
range
ids
{
e
:=
m
[
int32
(
id
)]
// Remove the wire type and field number varint, as well as the length varint.
msg
:=
skipVarint
(
skipVarint
(
e
.
enc
))
ms
.
Item
=
append
(
ms
.
Item
,
&
_MessageSet_Item
{
TypeId
:
Int32
(
int32
(
id
)),
Message
:
msg
,
})
}
return
Marshal
(
ms
)
}
// UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
// It is called by generated Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
func
UnmarshalMessageSet
(
buf
[]
byte
,
m
map
[
int32
]
Extension
)
error
{
ms
:=
new
(
MessageSet
)
if
err
:=
Unmarshal
(
buf
,
ms
);
err
!=
nil
{
return
err
}
for
_
,
item
:=
range
ms
.
Item
{
id
:=
*
item
.
TypeId
msg
:=
item
.
Message
// Restore wire type and field number varint, plus length varint.
// Be careful to preserve duplicate items.
b
:=
EncodeVarint
(
uint64
(
id
)
<<
3
|
WireBytes
)
if
ext
,
ok
:=
m
[
id
];
ok
{
// Existing data; rip off the tag and length varint
// so we join the new data correctly.
// We can assume that ext.enc is set because we are unmarshaling.
o
:=
ext
.
enc
[
len
(
b
)
:
]
// skip wire type and field number
_
,
n
:=
DecodeVarint
(
o
)
// calculate length of length varint
o
=
o
[
n
:
]
// skip length varint
msg
=
append
(
o
,
msg
...
)
// join old data and new data
}
b
=
append
(
b
,
EncodeVarint
(
uint64
(
len
(
msg
)))
...
)
b
=
append
(
b
,
msg
...
)
m
[
id
]
=
Extension
{
enc
:
b
}
}
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.
var
messageSetMap
=
make
(
map
[
int32
]
messageSetDesc
)
type
messageSetDesc
struct
{
t
reflect
.
Type
// pointer to struct
name
string
}
// RegisterMessageSetType is called from the generated code.
func
RegisterMessageSetType
(
m
Message
,
fieldNum
int32
,
name
string
)
{
messageSetMap
[
fieldNum
]
=
messageSetDesc
{
t
:
reflect
.
TypeOf
(
m
),
name
:
name
,
}
}
vendor/QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto/message_set_test.go
0 → 100644
View file @
8f79df77
// 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
import
(
"bytes"
"testing"
)
func
TestUnmarshalMessageSetWithDuplicate
(
t
*
testing
.
T
)
{
// Check that a repeated message set entry will be concatenated.
in
:=
&
MessageSet
{
Item
:
[]
*
_MessageSet_Item
{
{
TypeId
:
Int32
(
12345
),
Message
:
[]
byte
(
"hoo"
)},
{
TypeId
:
Int32
(
12345
),
Message
:
[]
byte
(
"hah"
)},
},
}
b
,
err
:=
Marshal
(
in
)
if
err
!=
nil
{
t
.
Fatalf
(
"Marshal: %v"
,
err
)
}
t
.
Logf
(
"Marshaled bytes: %q"
,
b
)
m
:=
make
(
map
[
int32
]
Extension
)
if
err
:=
UnmarshalMessageSet
(
b
,
m
);
err
!=
nil
{
t
.
Fatalf
(
"UnmarshalMessageSet: %v"
,
err
)
}
ext
,
ok
:=
m
[
12345
]
if
!
ok
{
t
.
Fatalf
(
"Didn't retrieve extension 12345; map is %v"
,
m
)
}
// Skip wire type/field number and length varints.
got
:=
skipVarint
(
skipVarint
(
ext
.
enc
))
if
want
:=
[]
byte
(
"hoohah"
);
!
bytes
.
Equal
(
got
,
want
)
{
t
.
Errorf
(
"Combined extension is %q, want %q"
,
got
,
want
)
}
}
vendor/QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto/pointer_reflect.go
0 → 100644
View file @
8f79df77
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2012 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.
// +build appengine
// 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
// be used on App Engine.
package
proto
import
(
"math"
"reflect"
)
// A structPointer is a pointer to a struct.
type
structPointer
struct
{
v
reflect
.
Value
}
// toStructPointer returns a structPointer equivalent to the given reflect value.
// The reflect value must itself be a pointer to a struct.
func
toStructPointer
(
v
reflect
.
Value
)
structPointer
{
return
structPointer
{
v
}
}
// IsNil reports whether p is nil.
func
structPointer_IsNil
(
p
structPointer
)
bool
{
return
p
.
v
.
IsNil
()
}
// Interface returns the struct pointer as an interface value.
func
structPointer_Interface
(
p
structPointer
,
_
reflect
.
Type
)
interface
{}
{
return
p
.
v
.
Interface
()
}
// A field identifies a field in a struct, accessible from a structPointer.
// In this implementation, a field is identified by the sequence of field indices
// passed to reflect's FieldByIndex.
type
field
[]
int
// toField returns a field equivalent to the given reflect field.
func
toField
(
f
*
reflect
.
StructField
)
field
{
return
f
.
Index
}
// invalidField is an invalid field identifier.
var
invalidField
=
field
(
nil
)
// IsValid reports whether the field identifier is valid.
func
(
f
field
)
IsValid
()
bool
{
return
f
!=
nil
}
// field returns the given field in the struct as a reflect value.
func
structPointer_field
(
p
structPointer
,
f
field
)
reflect
.
Value
{
// Special case: an extension map entry with a value of type T
// passes a *T to the struct-handling code with a zero field,
// expecting that it will be treated as equivalent to *struct{ X T },
// which has the same memory layout. We have to handle that case
// specially, because reflect will panic if we call FieldByIndex on a
// non-struct.
if
f
==
nil
{
return
p
.
v
.
Elem
()
}
return
p
.
v
.
Elem
()
.
FieldByIndex
(
f
)
}
// ifield returns the given field in the struct as an interface value.
func
structPointer_ifield
(
p
structPointer
,
f
field
)
interface
{}
{
return
structPointer_field
(
p
,
f
)
.
Addr
()
.
Interface
()
}
// Bytes returns the address of a []byte field in the struct.
func
structPointer_Bytes
(
p
structPointer
,
f
field
)
*
[]
byte
{
return
structPointer_ifield
(
p
,
f
)
.
(
*
[]
byte
)
}
// BytesSlice returns the address of a [][]byte field in the struct.
func
structPointer_BytesSlice
(
p
structPointer
,
f
field
)
*
[][]
byte
{
return
structPointer_ifield
(
p
,
f
)
.
(
*
[][]
byte
)
}
// Bool returns the address of a *bool field in the struct.
func
structPointer_Bool
(
p
structPointer
,
f
field
)
**
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.
func
structPointer_BoolSlice
(
p
structPointer
,
f
field
)
*
[]
bool
{
return
structPointer_ifield
(
p
,
f
)
.
(
*
[]
bool
)
}
// String returns the address of a *string field in the struct.
func
structPointer_String
(
p
structPointer
,
f
field
)
**
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.
func
structPointer_StringSlice
(
p
structPointer
,
f
field
)
*
[]
string
{
return
structPointer_ifield
(
p
,
f
)
.
(
*
[]
string
)
}
// ExtMap returns the address of an extension map field in the struct.
func
structPointer_ExtMap
(
p
structPointer
,
f
field
)
*
map
[
int32
]
Extension
{
return
structPointer_ifield
(
p
,
f
)
.
(
*
map
[
int32
]
Extension
)
}
// NewAt returns the reflect.Value for a pointer to a field in the struct.
func
structPointer_NewAt
(
p
structPointer
,
f
field
,
typ
reflect
.
Type
)
reflect
.
Value
{
return
structPointer_field
(
p
,
f
)
.
Addr
()
}
// SetStructPointer writes a *struct field in the struct.
func
structPointer_SetStructPointer
(
p
structPointer
,
f
field
,
q
structPointer
)
{
structPointer_field
(
p
,
f
)
.
Set
(
q
.
v
)
}
// GetStructPointer reads a *struct field in the struct.
func
structPointer_GetStructPointer
(
p
structPointer
,
f
field
)
structPointer
{
return
structPointer
{
structPointer_field
(
p
,
f
)}
}
// StructPointerSlice the address of a []*struct field in the struct.
func
structPointer_StructPointerSlice
(
p
structPointer
,
f
field
)
structPointerSlice
{
return
structPointerSlice
{
structPointer_field
(
p
,
f
)}
}
// A structPointerSlice represents the address of a slice of pointers to structs
// (themselves messages or groups). That is, v.Type() is *[]*struct{...}.
type
structPointerSlice
struct
{
v
reflect
.
Value
}
func
(
p
structPointerSlice
)
Len
()
int
{
return
p
.
v
.
Len
()
}
func
(
p
structPointerSlice
)
Index
(
i
int
)
structPointer
{
return
structPointer
{
p
.
v
.
Index
(
i
)}
}
func
(
p
structPointerSlice
)
Append
(
q
structPointer
)
{
p
.
v
.
Set
(
reflect
.
Append
(
p
.
v
,
q
.
v
))
}
var
(
int32Type
=
reflect
.
TypeOf
(
int32
(
0
))
uint32Type
=
reflect
.
TypeOf
(
uint32
(
0
))
float32Type
=
reflect
.
TypeOf
(
float32
(
0
))
int64Type
=
reflect
.
TypeOf
(
int64
(
0
))
uint64Type
=
reflect
.
TypeOf
(
uint64
(
0
))
float64Type
=
reflect
.
TypeOf
(
float64
(
0
))
)
// A word32 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
word32
struct
{
v
reflect
.
Value
}
// IsNil reports whether p is nil.
func
word32_IsNil
(
p
word32
)
bool
{
return
p
.
v
.
IsNil
()
}
// Set sets p to point at a newly allocated word with bits set to x.
func
word32_Set
(
p
word32
,
o
*
Buffer
,
x
uint32
)
{
t
:=
p
.
v
.
Type
()
.
Elem
()
switch
t
{
case
int32Type
:
if
len
(
o
.
int32s
)
==
0
{
o
.
int32s
=
make
([]
int32
,
uint32PoolSize
)
}
o
.
int32s
[
0
]
=
int32
(
x
)
p
.
v
.
Set
(
reflect
.
ValueOf
(
&
o
.
int32s
[
0
]))
o
.
int32s
=
o
.
int32s
[
1
:
]
return
case
uint32Type
:
if
len
(
o
.
uint32s
)
==
0
{
o
.
uint32s
=
make
([]
uint32
,
uint32PoolSize
)
}
o
.
uint32s
[
0
]
=
x
p
.
v
.
Set
(
reflect
.
ValueOf
(
&
o
.
uint32s
[
0
]))
o
.
uint32s
=
o
.
uint32s
[
1
:
]
return
case
float32Type
:
if
len
(
o
.
float32s
)
==
0
{
o
.
float32s
=
make
([]
float32
,
uint32PoolSize
)
}
o
.
float32s
[
0
]
=
math
.
Float32frombits
(
x
)
p
.
v
.
Set
(
reflect
.
ValueOf
(
&
o
.
float32s
[
0
]))
o
.
float32s
=
o
.
float32s
[
1
:
]
return
}
// must be enum
p
.
v
.
Set
(
reflect
.
New
(
t
))
p
.
v
.
Elem
()
.
SetInt
(
int64
(
int32
(
x
)))
}
// Get gets the bits pointed at by p, as a uint32.
func
word32_Get
(
p
word32
)
uint32
{
elem
:=
p
.
v
.
Elem
()
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"
)
}
// Word32 returns a reference to a *int32, *uint32, *float32, or *enum field in the struct.
func
structPointer_Word32
(
p
structPointer
,
f
field
)
word32
{
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.
// That is, v.Type() is []int32, []uint32, []float32, or []enum.
type
word32Slice
struct
{
v
reflect
.
Value
}
func
(
p
word32Slice
)
Append
(
x
uint32
)
{
n
,
m
:=
p
.
v
.
Len
(),
p
.
v
.
Cap
()
if
n
<
m
{
p
.
v
.
SetLen
(
n
+
1
)
}
else
{
t
:=
p
.
v
.
Type
()
.
Elem
()
p
.
v
.
Set
(
reflect
.
Append
(
p
.
v
,
reflect
.
Zero
(
t
)))
}
elem
:=
p
.
v
.
Index
(
n
)
switch
elem
.
Kind
()
{
case
reflect
.
Int32
:
elem
.
SetInt
(
int64
(
int32
(
x
)))
case
reflect
.
Uint32
:
elem
.
SetUint
(
uint64
(
x
))
case
reflect
.
Float32
:
elem
.
SetFloat
(
float64
(
math
.
Float32frombits
(
x
)))
}
}
func
(
p
word32Slice
)
Len
()
int
{
return
p
.
v
.
Len
()
}
func
(
p
word32Slice
)
Index
(
i
int
)
uint32
{
elem
:=
p
.
v
.
Index
(
i
)
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"
)
}
// Word32Slice returns a reference to a []int32, []uint32, []float32, or []enum field in the struct.
func
structPointer_Word32Slice
(
p
structPointer
,
f
field
)
word32Slice
{
return
word32Slice
{
structPointer_field
(
p
,
f
)}
}
// word64 is like word32 but for 64-bit values.
type
word64
struct
{
v
reflect
.
Value
}
func
word64_Set
(
p
word64
,
o
*
Buffer
,
x
uint64
)
{
t
:=
p
.
v
.
Type
()
.
Elem
()
switch
t
{
case
int64Type
:
if
len
(
o
.
int64s
)
==
0
{
o
.
int64s
=
make
([]
int64
,
uint64PoolSize
)
}
o
.
int64s
[
0
]
=
int64
(
x
)
p
.
v
.
Set
(
reflect
.
ValueOf
(
&
o
.
int64s
[
0
]))
o
.
int64s
=
o
.
int64s
[
1
:
]
return
case
uint64Type
:
if
len
(
o
.
uint64s
)
==
0
{
o
.
uint64s
=
make
([]
uint64
,
uint64PoolSize
)
}
o
.
uint64s
[
0
]
=
x
p
.
v
.
Set
(
reflect
.
ValueOf
(
&
o
.
uint64s
[
0
]))
o
.
uint64s
=
o
.
uint64s
[
1
:
]
return
case
float64Type
:
if
len
(
o
.
float64s
)
==
0
{
o
.
float64s
=
make
([]
float64
,
uint64PoolSize
)
}
o
.
float64s
[
0
]
=
math
.
Float64frombits
(
x
)
p
.
v
.
Set
(
reflect
.
ValueOf
(
&
o
.
float64s
[
0
]))
o
.
float64s
=
o
.
float64s
[
1
:
]
return
}
panic
(
"unreachable"
)
}
func
word64_IsNil
(
p
word64
)
bool
{
return
p
.
v
.
IsNil
()
}
func
word64_Get
(
p
word64
)
uint64
{
elem
:=
p
.
v
.
Elem
()
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_Word64
(
p
structPointer
,
f
field
)
word64
{
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
{
v
reflect
.
Value
}
func
(
p
word64Slice
)
Append
(
x
uint64
)
{
n
,
m
:=
p
.
v
.
Len
(),
p
.
v
.
Cap
()
if
n
<
m
{
p
.
v
.
SetLen
(
n
+
1
)
}
else
{
t
:=
p
.
v
.
Type
()
.
Elem
()
p
.
v
.
Set
(
reflect
.
Append
(
p
.
v
,
reflect
.
Zero
(
t
)))
}
elem
:=
p
.
v
.
Index
(
n
)
switch
elem
.
Kind
()
{
case
reflect
.
Int64
:
elem
.
SetInt
(
int64
(
int64
(
x
)))
case
reflect
.
Uint64
:
elem
.
SetUint
(
uint64
(
x
))
case
reflect
.
Float64
:
elem
.
SetFloat
(
float64
(
math
.
Float64frombits
(
x
)))
}
}
func
(
p
word64Slice
)
Len
()
int
{
return
p
.
v
.
Len
()
}
func
(
p
word64Slice
)
Index
(
i
int
)
uint64
{
elem
:=
p
.
v
.
Index
(
i
)
switch
elem
.
Kind
()
{
case
reflect
.
Int64
:
return
uint64
(
elem
.
Int
())
case
reflect
.
Uint64
:
return
uint64
(
elem
.
Uint
())
case
reflect
.
Float64
:
return
math
.
Float64bits
(
float64
(
elem
.
Float
()))
}
panic
(
"unreachable"
)
}
func
structPointer_Word64Slice
(
p
structPointer
,
f
field
)
word64Slice
{
return
word64Slice
{
structPointer_field
(
p
,
f
)}
}
vendor/QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto/pointer_unsafe.go
0 → 100644
View file @
8f79df77
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2012 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.
// +build !appengine
// This file contains the implementation of the proto field accesses using package unsafe.
package
proto
import
(
"reflect"
"unsafe"
)
// NOTE: These type_Foo functions would more idiomatically be methods,
// but Go does not allow methods on pointer types, and we must preserve
// some pointer type for the garbage collector. We use these
// funcs with clunky names as our poor approximation to methods.
//
// An alternative would be
// type structPointer struct { p unsafe.Pointer }
// but that does not registerize as well.
// A structPointer is a pointer to a struct.
type
structPointer
unsafe
.
Pointer
// toStructPointer returns a structPointer equivalent to the given reflect value.
func
toStructPointer
(
v
reflect
.
Value
)
structPointer
{
return
structPointer
(
unsafe
.
Pointer
(
v
.
Pointer
()))
}
// IsNil reports whether p is nil.
func
structPointer_IsNil
(
p
structPointer
)
bool
{
return
p
==
nil
}
// Interface returns the struct pointer, assumed to have element type t,
// as an interface value.
func
structPointer_Interface
(
p
structPointer
,
t
reflect
.
Type
)
interface
{}
{
return
reflect
.
NewAt
(
t
,
unsafe
.
Pointer
(
p
))
.
Interface
()
}
// A field identifies a field in a struct, accessible from a structPointer.
// In this implementation, a field is identified by its byte offset from the start of the struct.
type
field
uintptr
// toField returns a field equivalent to the given reflect field.
func
toField
(
f
*
reflect
.
StructField
)
field
{
return
field
(
f
.
Offset
)
}
// invalidField is an invalid field identifier.
const
invalidField
=
^
field
(
0
)
// IsValid reports whether the field identifier is valid.
func
(
f
field
)
IsValid
()
bool
{
return
f
!=
^
field
(
0
)
}
// Bytes returns the address of a []byte field in the struct.
func
structPointer_Bytes
(
p
structPointer
,
f
field
)
*
[]
byte
{
return
(
*
[]
byte
)(
unsafe
.
Pointer
(
uintptr
(
p
)
+
uintptr
(
f
)))
}
// BytesSlice returns the address of a [][]byte field in the struct.
func
structPointer_BytesSlice
(
p
structPointer
,
f
field
)
*
[][]
byte
{
return
(
*
[][]
byte
)(
unsafe
.
Pointer
(
uintptr
(
p
)
+
uintptr
(
f
)))
}
// Bool returns the address of a *bool field in the struct.
func
structPointer_Bool
(
p
structPointer
,
f
field
)
**
bool
{
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.
func
structPointer_BoolSlice
(
p
structPointer
,
f
field
)
*
[]
bool
{
return
(
*
[]
bool
)(
unsafe
.
Pointer
(
uintptr
(
p
)
+
uintptr
(
f
)))
}
// String returns the address of a *string field in the struct.
func
structPointer_String
(
p
structPointer
,
f
field
)
**
string
{
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.
func
structPointer_StringSlice
(
p
structPointer
,
f
field
)
*
[]
string
{
return
(
*
[]
string
)(
unsafe
.
Pointer
(
uintptr
(
p
)
+
uintptr
(
f
)))
}
// ExtMap returns the address of an extension map field in the struct.
func
structPointer_ExtMap
(
p
structPointer
,
f
field
)
*
map
[
int32
]
Extension
{
return
(
*
map
[
int32
]
Extension
)(
unsafe
.
Pointer
(
uintptr
(
p
)
+
uintptr
(
f
)))
}
// NewAt returns the reflect.Value for a pointer to a field in the struct.
func
structPointer_NewAt
(
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.
func
structPointer_SetStructPointer
(
p
structPointer
,
f
field
,
q
structPointer
)
{
*
(
*
structPointer
)(
unsafe
.
Pointer
(
uintptr
(
p
)
+
uintptr
(
f
)))
=
q
}
// GetStructPointer reads a *struct field in the struct.
func
structPointer_GetStructPointer
(
p
structPointer
,
f
field
)
structPointer
{
return
*
(
*
structPointer
)(
unsafe
.
Pointer
(
uintptr
(
p
)
+
uintptr
(
f
)))
}
// StructPointerSlice the address of a []*struct field in the struct.
func
structPointer_StructPointerSlice
(
p
structPointer
,
f
field
)
*
structPointerSlice
{
return
(
*
structPointerSlice
)(
unsafe
.
Pointer
(
uintptr
(
p
)
+
uintptr
(
f
)))
}
// A structPointerSlice represents a slice of pointers to structs (themselves submessages or groups).
type
structPointerSlice
[]
structPointer
func
(
v
*
structPointerSlice
)
Len
()
int
{
return
len
(
*
v
)
}
func
(
v
*
structPointerSlice
)
Index
(
i
int
)
structPointer
{
return
(
*
v
)[
i
]
}
func
(
v
*
structPointerSlice
)
Append
(
p
structPointer
)
{
*
v
=
append
(
*
v
,
p
)
}
// A word32 is the address of a "pointer to 32-bit value" field.
type
word32
**
uint32
// IsNil reports whether *v is nil.
func
word32_IsNil
(
p
word32
)
bool
{
return
*
p
==
nil
}
// Set sets *v to point at a newly allocated word set to x.
func
word32_Set
(
p
word32
,
o
*
Buffer
,
x
uint32
)
{
if
len
(
o
.
uint32s
)
==
0
{
o
.
uint32s
=
make
([]
uint32
,
uint32PoolSize
)
}
o
.
uint32s
[
0
]
=
x
*
p
=
&
o
.
uint32s
[
0
]
o
.
uint32s
=
o
.
uint32s
[
1
:
]
}
// Get gets the value pointed at by *v.
func
word32_Get
(
p
word32
)
uint32
{
return
**
p
}
// Word32 returns the address of a *int32, *uint32, *float32, or *enum field in the struct.
func
structPointer_Word32
(
p
structPointer
,
f
field
)
word32
{
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.
type
word32Slice
[]
uint32
func
(
v
*
word32Slice
)
Append
(
x
uint32
)
{
*
v
=
append
(
*
v
,
x
)
}
func
(
v
*
word32Slice
)
Len
()
int
{
return
len
(
*
v
)
}
func
(
v
*
word32Slice
)
Index
(
i
int
)
uint32
{
return
(
*
v
)[
i
]
}
// Word32Slice returns the address of a []int32, []uint32, []float32, or []enum field in the struct.
func
structPointer_Word32Slice
(
p
structPointer
,
f
field
)
*
word32Slice
{
return
(
*
word32Slice
)(
unsafe
.
Pointer
(
uintptr
(
p
)
+
uintptr
(
f
)))
}
// word64 is like word32 but for 64-bit values.
type
word64
**
uint64
func
word64_Set
(
p
word64
,
o
*
Buffer
,
x
uint64
)
{
if
len
(
o
.
uint64s
)
==
0
{
o
.
uint64s
=
make
([]
uint64
,
uint64PoolSize
)
}
o
.
uint64s
[
0
]
=
x
*
p
=
&
o
.
uint64s
[
0
]
o
.
uint64s
=
o
.
uint64s
[
1
:
]
}
func
word64_IsNil
(
p
word64
)
bool
{
return
*
p
==
nil
}
func
word64_Get
(
p
word64
)
uint64
{
return
**
p
}
func
structPointer_Word64
(
p
structPointer
,
f
field
)
word64
{
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.
type
word64Slice
[]
uint64
func
(
v
*
word64Slice
)
Append
(
x
uint64
)
{
*
v
=
append
(
*
v
,
x
)
}
func
(
v
*
word64Slice
)
Len
()
int
{
return
len
(
*
v
)
}
func
(
v
*
word64Slice
)
Index
(
i
int
)
uint64
{
return
(
*
v
)[
i
]
}
func
structPointer_Word64Slice
(
p
structPointer
,
f
field
)
*
word64Slice
{
return
(
*
word64Slice
)(
unsafe
.
Pointer
(
uintptr
(
p
)
+
uintptr
(
f
)))
}
vendor/QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto/pointer_unsafe_gogo.go
0 → 100644
View file @
8f79df77
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
// http://github.com/gogo/protobuf/gogoproto
//
// 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.
//
// 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.
// +build !appengine
// This file contains the implementation of the proto field accesses using package unsafe.
package
proto
import
(
"reflect"
"unsafe"
)
func
structPointer_InterfaceAt
(
p
structPointer
,
f
field
,
t
reflect
.
Type
)
interface
{}
{
point
:=
unsafe
.
Pointer
(
uintptr
(
p
)
+
uintptr
(
f
))
r
:=
reflect
.
NewAt
(
t
,
point
)
return
r
.
Interface
()
}
func
structPointer_InterfaceRef
(
p
structPointer
,
f
field
,
t
reflect
.
Type
)
interface
{}
{
point
:=
unsafe
.
Pointer
(
uintptr
(
p
)
+
uintptr
(
f
))
r
:=
reflect
.
NewAt
(
t
,
point
)
if
r
.
Elem
()
.
IsNil
()
{
return
nil
}
return
r
.
Elem
()
.
Interface
()
}
func
copyUintPtr
(
oldptr
,
newptr
uintptr
,
size
int
)
{
oldbytes
:=
make
([]
byte
,
0
)
oldslice
:=
(
*
reflect
.
SliceHeader
)(
unsafe
.
Pointer
(
&
oldbytes
))
oldslice
.
Data
=
oldptr
oldslice
.
Len
=
size
oldslice
.
Cap
=
size
newbytes
:=
make
([]
byte
,
0
)
newslice
:=
(
*
reflect
.
SliceHeader
)(
unsafe
.
Pointer
(
&
newbytes
))
newslice
.
Data
=
newptr
newslice
.
Len
=
size
newslice
.
Cap
=
size
copy
(
newbytes
,
oldbytes
)
}
func
structPointer_Copy
(
oldptr
structPointer
,
newptr
structPointer
,
size
int
)
{
copyUintPtr
(
uintptr
(
oldptr
),
uintptr
(
newptr
),
size
)
}
func
appendStructPointer
(
base
structPointer
,
f
field
,
typ
reflect
.
Type
)
structPointer
{
size
:=
typ
.
Elem
()
.
Size
()
oldHeader
:=
structPointer_GetSliceHeader
(
base
,
f
)
newLen
:=
oldHeader
.
Len
+
1
slice
:=
reflect
.
MakeSlice
(
typ
,
newLen
,
newLen
)
bas
:=
toStructPointer
(
slice
)
for
i
:=
0
;
i
<
oldHeader
.
Len
;
i
++
{
newElemptr
:=
uintptr
(
bas
)
+
uintptr
(
i
)
*
size
oldElemptr
:=
oldHeader
.
Data
+
uintptr
(
i
)
*
size
copyUintPtr
(
oldElemptr
,
newElemptr
,
int
(
size
))
}
oldHeader
.
Data
=
uintptr
(
bas
)
oldHeader
.
Len
=
newLen
oldHeader
.
Cap
=
newLen
return
structPointer
(
unsafe
.
Pointer
(
uintptr
(
unsafe
.
Pointer
(
bas
))
+
uintptr
(
uintptr
(
newLen
-
1
)
*
size
)))
}
func
structPointer_FieldPointer
(
p
structPointer
,
f
field
)
structPointer
{
return
structPointer
(
unsafe
.
Pointer
(
uintptr
(
p
)
+
uintptr
(
f
)))
}
func
structPointer_GetRefStructPointer
(
p
structPointer
,
f
field
)
structPointer
{
return
structPointer
((
*
structPointer
)(
unsafe
.
Pointer
(
uintptr
(
p
)
+
uintptr
(
f
))))
}
func
structPointer_GetSliceHeader
(
p
structPointer
,
f
field
)
*
reflect
.
SliceHeader
{
return
(
*
reflect
.
SliceHeader
)(
unsafe
.
Pointer
(
uintptr
(
p
)
+
uintptr
(
f
)))
}
func
structPointer_Add
(
p
structPointer
,
size
field
)
structPointer
{
return
structPointer
(
unsafe
.
Pointer
(
uintptr
(
p
)
+
uintptr
(
size
)))
}
func
structPointer_Len
(
p
structPointer
,
f
field
)
int
{
return
len
(
*
(
*
[]
interface
{})(
unsafe
.
Pointer
(
structPointer_GetRefStructPointer
(
p
,
f
))))
}
vendor/QmfH4HuZyN1p2wQLWWkXC91Z76435xKrBVfLQ2MY8ayG5R/gogo-protobuf/proto/properties.go
0 → 100644
View file @
8f79df77
// Extensions for Protocol Buffers to create more go like structures.
//
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
// http://github.com/gogo/protobuf/gogoproto
//
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2010 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
/*
* Routines for encoding data into the wire format for protocol buffers.
*/
import
(
"fmt"
"os"
"reflect"
"sort"
"strconv"
"strings"
"sync"
)
const
debug
bool
=
false
// Constants that identify the encoding of a value on the wire.
const
(
WireVarint
=
0
WireFixed64
=
1
WireBytes
=
2
WireStartGroup
=
3
WireEndGroup
=
4
WireFixed32
=
5
)
const
startSize
=
10
// initial slice/string sizes
// Encoders are defined in encode.go
// An encoder outputs the full representation of a field, including its
// tag and encoder type.
type
encoder
func
(
p
*
Buffer
,
prop
*
Properties
,
base
structPointer
)
error
// A valueEncoder encodes a single integer in a particular encoding.
type
valueEncoder
func
(
o
*
Buffer
,
x
uint64
)
error
// Sizers are defined in encode.go
// A sizer returns the encoded size of a field, including its tag and encoder
// type.
type
sizer
func
(
prop
*
Properties
,
base
structPointer
)
int
// A valueSizer returns the encoded size of a single integer in a particular
// encoding.
type
valueSizer
func
(
x
uint64
)
int
// Decoders are defined in decode.go
// A decoder creates a value from its wire representation.
// Unrecognized subelements are saved in unrec.
type
decoder
func
(
p
*
Buffer
,
prop
*
Properties
,
base
structPointer
)
error
// A valueDecoder decodes a single integer in a particular encoding.
type
valueDecoder
func
(
o
*
Buffer
)
(
x
uint64
,
err
error
)
// A oneofMarshaler does the marshaling for all oneof fields in a message.
type
oneofMarshaler
func
(
Message
,
*
Buffer
)
error
// A oneofUnmarshaler does the unmarshaling for a oneof field in a message.
type
oneofUnmarshaler
func
(
Message
,
int
,
int
,
*
Buffer
)
(
bool
,
error
)
// tagMap is an optimization over map[int]int for typical protocol buffer
// use-cases. Encoded protocol buffers are often in tag order with small tag
// numbers.
type
tagMap
struct
{
fastTags
[]
int
slowTags
map
[
int
]
int
}
// tagMapFastLimit is the upper bound on the tag number that will be stored in
// the tagMap slice rather than its map.
const
tagMapFastLimit
=
1024
func
(
p
*
tagMap
)
get
(
t
int
)
(
int
,
bool
)
{
if
t
>
0
&&
t
<
tagMapFastLimit
{
if
t
>=
len
(
p
.
fastTags
)
{
return
0
,
false
}
fi
:=
p
.
fastTags
[
t
]
return
fi
,
fi
>=
0
}
fi
,
ok
:=
p
.
slowTags
[
t
]
return
fi
,
ok
}
func
(
p
*
tagMap
)
put
(
t
int
,
fi
int
)
{
if
t
>
0
&&
t
<
tagMapFastLimit
{
for
len
(
p
.
fastTags
)
<
t
+
1
{
p
.
fastTags
=
append
(
p
.
fastTags
,
-
1
)
}
p
.
fastTags
[
t
]
=
fi
return
}
if
p
.
slowTags
==
nil
{
p
.
slowTags
=
make
(
map
[
int
]
int
)
}
p
.
slowTags
[
t
]
=
fi
}
// StructProperties represents properties for all the fields of a struct.
// decoderTags and decoderOrigNames should only be used by the decoder.
type
StructProperties
struct
{
Prop
[]
*
Properties
// properties for each field
reqCount
int
// required count
decoderTags
tagMap
// map from proto tag to struct field number
decoderOrigNames
map
[
string
]
int
// map from original name to struct field number
order
[]
int
// list of struct field numbers in tag order
unrecField
field
// field id of the XXX_unrecognized []byte field
extendable
bool
// is this an extendable proto
oneofMarshaler
oneofMarshaler
oneofUnmarshaler
oneofUnmarshaler
stype
reflect
.
Type
// OneofTypes contains information about the oneof fields in this message.
// It is keyed by the original name of a field.
OneofTypes
map
[
string
]
*
OneofProperties
}
// OneofProperties represents information about a specific field in a oneof.
type
OneofProperties
struct
{
Type
reflect
.
Type
// pointer to generated struct type for this oneof field
Field
int
// struct field number of the containing oneof in the message
Prop
*
Properties
}
// Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec.
// See encode.go, (*Buffer).enc_struct.
func
(
sp
*
StructProperties
)
Len
()
int
{
return
len
(
sp
.
order
)
}
func
(
sp
*
StructProperties
)
Less
(
i
,
j
int
)
bool
{
return
sp
.
Prop
[
sp
.
order
[
i
]]
.
Tag
<
sp
.
Prop
[
sp
.
order
[
j
]]
.
Tag
}
func
(
sp
*
StructProperties
)
Swap
(
i
,
j
int
)
{
sp
.
order
[
i
],
sp
.
order
[
j
]
=
sp
.
order
[
j
],
sp
.
order
[
i
]
}
// Properties represents the protocol-specific behavior of a single struct field.
type
Properties
struct
{
Name
string
// name of the field, for error messages
OrigName
string
// original name before protocol compiler (always set)
Wire
string
WireType
int
Tag
int
Required
bool
Optional
bool
Repeated
bool
Packed
bool
// relevant for repeated primitives only
Enum
string
// set for enum types only
proto3
bool
// whether this is known to be a proto3 field; set for []byte only
oneof
bool
// whether this is a oneof field
Default
string
// default value
HasDefault
bool
// whether an explicit default was provided
CustomType
string
def_uint64
uint64
enc
encoder
valEnc
valueEncoder
// set for bool and numeric types only
field
field
tagcode
[]
byte
// encoding of EncodeVarint((Tag<<3)|WireType)
tagbuf
[
8
]
byte
stype
reflect
.
Type
// set for struct types only
sstype
reflect
.
Type
// set for slices of structs types only
ctype
reflect
.
Type
// set for custom types only
sprop
*
StructProperties
// set for struct types only
isMarshaler
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
valSize
valueSizer
// set for bool and numeric types only
dec
decoder
valDec
valueDecoder
// set for bool and numeric types only
// If this is a packable field, this will be the decoder for the packed version of the field.
packedDec
decoder
}
// String formats the properties in the protobuf struct field tag style.
func
(
p
*
Properties
)
String
()
string
{
s
:=
p
.
Wire
s
=
","
s
+=
strconv
.
Itoa
(
p
.
Tag
)
if
p
.
Required
{
s
+=
",req"
}
if
p
.
Optional
{
s
+=
",opt"
}
if
p
.
Repeated
{
s
+=
",rep"
}
if
p
.
Packed
{
s
+=
",packed"
}
if
p
.
OrigName
!=
p
.
Name
{
s
+=
",name="
+
p
.
OrigName
}
if
p
.
proto3
{
s
+=
",proto3"
}
if
p
.
oneof
{
s
+=
",oneof"
}
if
len
(
p
.
Enum
)
>
0
{
s
+=
",enum="
+
p
.
Enum
}
if
p
.
HasDefault
{
s
+=
",def="
+
p
.
Default
}
return
s
}
// Parse populates p by parsing a string in the protobuf struct field tag style.
func
(
p
*
Properties
)
Parse
(
s
string
)
{
// "bytes,49,opt,name=foo,def=hello!"
fields
:=
strings
.
Split
(
s
,
","
)
// breaks def=, but handled below.
if
len
(
fields
)
<
2
{
fmt
.
Fprintf
(
os
.
Stderr
,
"proto: tag has too few fields: %q
\n
"
,
s
)
return
}
p
.
Wire
=
fields
[
0
]
switch
p
.
Wire
{
case
"varint"
:
p
.
WireType
=
WireVarint
p
.
valEnc
=
(
*
Buffer
)
.
EncodeVarint
p
.
valDec
=
(
*
Buffer
)
.
DecodeVarint
p
.
valSize
=
sizeVarint
case
"fixed32"
:
p
.
WireType
=
WireFixed32
p
.
valEnc
=
(
*
Buffer
)
.
EncodeFixed32
p
.
valDec
=
(
*
Buffer
)
.
DecodeFixed32
p
.
valSize
=
sizeFixed32
case
"fixed64"
:
p
.
WireType
=
WireFixed64
p
.
valEnc
=
(
*
Buffer
)
.
EncodeFixed64
p
.
valDec
=
(
*
Buffer
)
.
DecodeFixed64
p
.
valSize
=
sizeFixed64
case
"zigzag32"
:
p
.
WireType
=
WireVarint
p
.
valEnc
=
(
*
Buffer
)
.
EncodeZigzag32
p
.
valDec
=
(
*
Buffer
)
.
DecodeZigzag32
p
.
valSize
=
sizeZigzag32
case
"zigzag64"
:
p
.
WireType
=
WireVarint
p
.
valEnc
=
(
*
Buffer
)
.
EncodeZigzag64
p
.
valDec
=
(
*
Buffer
)
.
DecodeZigzag64
p
.
valSize
=
sizeZigzag64
case
"bytes"
,
"group"
:
p
.
WireType
=
WireBytes
// no numeric converter for non-numeric types
default
:
fmt
.
Fprintf
(
os
.
Stderr
,
"proto: tag has unknown wire type: %q
\n
"
,
s
)
return
}
var
err
error
p
.
Tag
,
err
=
strconv
.
Atoi
(
fields
[
1
])
if
err
!=
nil
{
return
}
for
i
:=
2
;
i
<
len
(
fields
);
i
++
{
f
:=
fields
[
i
]
switch
{
case
f
==
"req"
:
p
.
Required
=
true
case
f
==
"opt"
:
p
.
Optional
=
true
case
f
==
"rep"
:
p
.
Repeated
=
true
case
f
==
"packed"
:
p
.
Packed
=
true
case
strings
.
HasPrefix
(
f
,
"name="
)
:
p
.
OrigName
=
f
[
5
:
]
case
strings
.
HasPrefix
(
f
,
"enum="
)
:
p
.
Enum
=
f
[
5
:
]
case
f
==
"proto3"
:
p
.
proto3
=
true
case
f
==
"oneof"
:
p
.
oneof
=
true
case
strings
.
HasPrefix
(
f
,
"def="
)
:
p
.
HasDefault
=
true
p
.
Default
=
f
[
4
:
]
// rest of string
if
i
+
1
<
len
(
fields
)
{
// Commas aren't escaped, and def is always last.
p
.
Default
+=
","
+
strings
.
Join
(
fields
[
i
+
1
:
],
","
)
break
}
case
strings
.
HasPrefix
(
f
,
"embedded="
)
:
p
.
OrigName
=
strings
.
Split
(
f
,
"="
)[
1
]
case
strings
.
HasPrefix
(
f
,
"customtype="
)
:
p
.
CustomType
=
strings
.
Split
(
f
,
"="
)[
1
]
}
}
}
func
logNoSliceEnc
(
t1
,
t2
reflect
.
Type
)
{
fmt
.
Fprintf
(
os
.
Stderr
,
"proto: no slice oenc for %T = []%T
\n
"
,
t1
,
t2
)
}
var
protoMessageType
=
reflect
.
TypeOf
((
*
Message
)(
nil
))
.
Elem
()
// Initialize the fields for encoding and decoding.
func
(
p
*
Properties
)
setEncAndDec
(
typ
reflect
.
Type
,
f
*
reflect
.
StructField
,
lockGetProp
bool
)
{
p
.
enc
=
nil
p
.
dec
=
nil
p
.
size
=
nil
if
len
(
p
.
CustomType
)
>
0
{
p
.
setCustomEncAndDec
(
typ
)
p
.
setTag
(
lockGetProp
)
return
}
switch
t1
:=
typ
;
t1
.
Kind
()
{
default
:
fmt
.
Fprintf
(
os
.
Stderr
,
"proto: no coders for %v
\n
"
,
t1
)
// proto3 scalar types
case
reflect
.
Bool
:
if
p
.
proto3
{
p
.
enc
=
(
*
Buffer
)
.
enc_proto3_bool
p
.
dec
=
(
*
Buffer
)
.
dec_proto3_bool
p
.
size
=
size_proto3_bool
}
else
{
p
.
enc
=
(
*
Buffer
)
.
enc_ref_bool
p
.
dec
=
(
*
Buffer
)
.
dec_proto3_bool
p
.
size
=
size_ref_bool
}
case
reflect
.
Int32
:
if
p
.
proto3
{
p
.
enc
=
(
*
Buffer
)
.
enc_proto3_int32
p
.
dec
=
(
*
Buffer
)
.
dec_proto3_int32
p
.
size
=
size_proto3_int32
}
else
{
p
.
enc
=
(
*
Buffer
)
.
enc_ref_int32
p
.
dec
=
(
*
Buffer
)
.
dec_proto3_int32
p
.
size
=
size_ref_int32
}
case
reflect
.
Uint32
:
if
p
.
proto3
{
p
.
enc
=
(
*
Buffer
)
.
enc_proto3_uint32
p
.
dec
=
(
*
Buffer
)
.
dec_proto3_int32
// can reuse
p
.
size
=
size_proto3_uint32
}
else
{
p
.
enc
=
(
*
Buffer
)
.
enc_ref_uint32
p
.
dec
=
(
*
Buffer
)
.
dec_proto3_int32
// can reuse
p
.
size
=
size_ref_uint32
}
case
reflect
.
Int64
,
reflect
.
Uint64
:
if
p
.
proto3
{
p
.
enc
=
(
*
Buffer
)
.
enc_proto3_int64
p
.
dec
=
(
*
Buffer
)
.
dec_proto3_int64
p
.
size
=
size_proto3_int64
}
else
{
p
.
enc
=
(
*
Buffer
)
.
enc_ref_int64
p
.
dec
=
(
*
Buffer
)
.
dec_proto3_int64
p
.
size
=
size_ref_int64
}
case
reflect
.
Float32
:
if
p
.
proto3
{
p
.
enc
=
(
*
Buffer
)
.
enc_proto3_uint32
// can just treat them as bits
p
.
dec
=
(
*
Buffer
)
.
dec_proto3_int32
p
.
size
=
size_proto3_uint32
}
else
{
p
.
enc
=
(
*
Buffer
)
.
enc_ref_uint32
// can just treat them as bits
p
.
dec
=
(
*
Buffer
)
.
dec_proto3_int32
p
.
size
=
size_ref_uint32
}
case
reflect
.
Float64
:
if
p
.
proto3
{
p
.
enc
=
(
*
Buffer
)
.
enc_proto3_int64
// can just treat them as bits
p
.
dec
=
(
*
Buffer
)
.
dec_proto3_int64
p
.
size
=
size_proto3_int64
}
else
{
p
.
enc
=
(
*
Buffer
)
.
enc_ref_int64
// can just treat them as bits
p
.
dec
=
(
*
Buffer
)
.
dec_proto3_int64
p
.
size
=
size_ref_int64
}
case
reflect
.
String
:
if
p
.
proto3
{
p
.
enc
=
(
*
Buffer
)
.
enc_proto3_string
p
.
dec
=
(
*
Buffer
)
.
dec_proto3_string
p
.
size
=
size_proto3_string
}
else
{
p
.
enc
=
(
*
Buffer
)
.
enc_ref_string
p
.
dec
=
(
*
Buffer
)
.
dec_proto3_string
p
.
size
=
size_ref_string
}
case
reflect
.
Struct
:
p
.
stype
=
typ
p
.
isMarshaler
=
isMarshaler
(
typ
)
p
.
isUnmarshaler
=
isUnmarshaler
(
typ
)
if
p
.
Wire
==
"bytes"
{
p
.
enc
=
(
*
Buffer
)
.
enc_ref_struct_message
p
.
dec
=
(
*
Buffer
)
.
dec_ref_struct_message
p
.
size
=
size_ref_struct_message
}
else
{
fmt
.
Fprintf
(
os
.
Stderr
,
"proto: no coders for struct %T
\n
"
,
typ
)
}
case
reflect
.
Ptr
:
switch
t2
:=
t1
.
Elem
();
t2
.
Kind
()
{
default
:
fmt
.
Fprintf
(
os
.
Stderr
,
"proto: no encoder function for %v -> %v
\n
"
,
t1
,
t2
)
break
case
reflect
.
Bool
:
p
.
enc
=
(
*
Buffer
)
.
enc_bool
p
.
dec
=
(
*
Buffer
)
.
dec_bool
p
.
size
=
size_bool
case
reflect
.
Int32
:
p
.
enc
=
(
*
Buffer
)
.
enc_int32
p
.
dec
=
(
*
Buffer
)
.
dec_int32
p
.
size
=
size_int32
case
reflect
.
Uint32
:
p
.
enc
=
(
*
Buffer
)
.
enc_uint32
p
.
dec
=
(
*
Buffer
)
.
dec_int32
// can reuse
p
.
size
=
size_uint32
case
reflect
.
Int64
,
reflect
.
Uint64
:
p
.
enc
=
(
*
Buffer
)
.
enc_int64
p
.
dec
=
(
*
Buffer
)
.
dec_int64
p
.
size
=
size_int64
case
reflect
.
Float32
:
p
.
enc
=
(
*
Buffer
)
.
enc_uint32
// can just treat them as bits
p
.
dec
=
(
*
Buffer
)
.
dec_int32
p
.
size
=
size_uint32
case
reflect
.
Float64
:
p
.
enc
=
(
*
Buffer
)
.
enc_int64
// can just treat them as bits
p
.
dec
=
(
*
Buffer
)
.
dec_int64
p
.
size
=
size_int64
case
reflect
.
String
:
p
.
enc
=
(
*
Buffer
)
.
enc_string
p
.
dec
=
(
*
Buffer
)
.
dec_string
p
.
size
=
size_string
case
reflect
.
Struct
:
p
.
stype
=
t1
.
Elem
()
p
.
isMarshaler
=
isMarshaler
(
t1
)
p
.
isUnmarshaler
=
isUnmarshaler
(
t1
)
if
p
.
Wire
==
"bytes"
{
p
.
enc
=
(
*
Buffer
)
.
enc_struct_message
p
.
dec
=
(
*
Buffer
)
.
dec_struct_message
p
.
size
=
size_struct_message
}
else
{
p
.
enc
=
(
*
Buffer
)
.
enc_struct_group
p
.
dec
=
(
*
Buffer
)
.
dec_struct_group
p
.
size
=
size_struct_group
}
}
case
reflect
.
Slice
:
switch
t2
:=
t1
.
Elem
();
t2
.
Kind
()
{
default
:
logNoSliceEnc
(
t1
,
t2
)
break
case
reflect
.
Bool
:
if
p
.
Packed
{
p
.
enc
=
(
*
Buffer
)
.
enc_slice_packed_bool
p
.
size
=
size_slice_packed_bool
}
else
{
p
.
enc
=
(
*
Buffer
)
.
enc_slice_bool
p
.
size
=
size_slice_bool
}
p
.
dec
=
(
*
Buffer
)
.
dec_slice_bool
p
.
packedDec
=
(
*
Buffer
)
.
dec_slice_packed_bool
case
reflect
.
Int32
:
if
p
.
Packed
{
p
.
enc
=
(
*
Buffer
)
.
enc_slice_packed_int32
p
.
size
=
size_slice_packed_int32
}
else
{
p
.
enc
=
(
*
Buffer
)
.
enc_slice_int32
p
.
size
=
size_slice_int32
}
p
.
dec
=
(
*
Buffer
)
.
dec_slice_int32
p
.
packedDec
=
(
*
Buffer
)
.
dec_slice_packed_int32
case
reflect
.
Uint32
:
if
p
.
Packed
{
p
.
enc
=
(
*
Buffer
)
.
enc_slice_packed_uint32
p
.
size
=
size_slice_packed_uint32
}
else
{
p
.
enc
=
(
*
Buffer
)
.
enc_slice_uint32
p
.
size
=
size_slice_uint32
}
p
.
dec
=
(
*
Buffer
)
.
dec_slice_int32
p
.
packedDec
=
(
*
Buffer
)
.
dec_slice_packed_int32
case
reflect
.
Int64
,
reflect
.
Uint64
:
if
p
.
Packed
{
p
.
enc
=
(
*
Buffer
)
.
enc_slice_packed_int64
p
.
size
=
size_slice_packed_int64
}
else
{
p
.
enc
=
(
*
Buffer
)
.
enc_slice_int64
p
.
size
=
size_slice_int64
}
p
.
dec
=
(
*
Buffer
)
.
dec_slice_int64
p
.
packedDec
=
(
*
Buffer
)
.
dec_slice_packed_int64
case
reflect
.
Uint8
:
p
.
enc
=
(
*
Buffer
)
.
enc_slice_byte
p
.
dec
=
(
*
Buffer
)
.
dec_slice_byte
p
.
size
=
size_slice_byte
// This is a []byte, which is either a bytes field,
// or the value of a map field. In the latter case,
// we always encode an empty []byte, so we should not
// use the proto3 enc/size funcs.
// f == nil iff this is the key/value of a map field.
if
p
.
proto3
&&
f
!=
nil
{
p
.
enc
=
(
*
Buffer
)
.
enc_proto3_slice_byte
p
.
size
=
size_proto3_slice_byte
}
case
reflect
.
Float32
,
reflect
.
Float64
:
switch
t2
.
Bits
()
{
case
32
:
// can just treat them as bits
if
p
.
Packed
{
p
.
enc
=
(
*
Buffer
)
.
enc_slice_packed_uint32
p
.
size
=
size_slice_packed_uint32
}
else
{
p
.
enc
=
(
*
Buffer
)
.
enc_slice_uint32
p
.
size
=
size_slice_uint32
}
p
.
dec
=
(
*
Buffer
)
.
dec_slice_int32
p
.
packedDec
=
(
*
Buffer
)
.
dec_slice_packed_int32
case
64
:
// can just treat them as bits
if
p
.
Packed
{
p
.
enc
=
(
*
Buffer
)
.
enc_slice_packed_int64
p
.
size
=
size_slice_packed_int64
}
else
{
p
.
enc
=
(
*
Buffer
)
.
enc_slice_int64
p
.
size
=
size_slice_int64
}
p
.
dec
=
(
*
Buffer
)
.
dec_slice_int64
p
.
packedDec
=
(
*
Buffer
)
.
dec_slice_packed_int64
default
:
logNoSliceEnc
(
t1
,
t2
)
break
}
case
reflect
.
String
:
p
.
enc
=
(
*
Buffer
)
.
enc_slice_string
p
.
dec
=
(
*
Buffer
)
.
dec_slice_string
p
.
size
=
size_slice_string
case
reflect
.
Ptr
:
switch
t3
:=
t2
.
Elem
();
t3
.
Kind
()
{
default
:
fmt
.
Fprintf
(
os
.
Stderr
,
"proto: no ptr oenc for %T -> %T -> %T
\n
"
,
t1
,
t2
,
t3
)
break
case
reflect
.
Struct
:
p
.
stype
=
t2
.
Elem
()
p
.
isMarshaler
=
isMarshaler
(
t2
)
p
.
isUnmarshaler
=
isUnmarshaler
(
t2
)
if
p
.
Wire
==
"bytes"
{
p
.
enc
=
(
*
Buffer
)
.
enc_slice_struct_message
p
.
dec
=
(
*
Buffer
)
.
dec_slice_struct_message
p
.
size
=
size_slice_struct_message
}
else
{
p
.
enc
=
(
*
Buffer
)
.
enc_slice_struct_group
p
.
dec
=
(
*
Buffer
)
.
dec_slice_struct_group
p
.
size
=
size_slice_struct_group
}
}
case
reflect
.
Slice
:
switch
t2
.
Elem
()
.
Kind
()
{
default
:
fmt
.
Fprintf
(
os
.
Stderr
,
"proto: no slice elem oenc for %T -> %T -> %T
\n
"
,
t1
,
t2
,
t2
.
Elem
())
break
case
reflect
.
Uint8
:
p
.
enc
=
(
*
Buffer
)
.
enc_slice_slice_byte
p
.
dec
=
(
*
Buffer
)
.
dec_slice_slice_byte
p
.
size
=
size_slice_slice_byte
}
case
reflect
.
Struct
:
p
.
setSliceOfNonPointerStructs
(
t1
)
}
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
)
}
p
.
setTag
(
lockGetProp
)
}
func
(
p
*
Properties
)
setTag
(
lockGetProp
bool
)
{
// precalculate tag code
wire
:=
p
.
WireType
if
p
.
Packed
{
wire
=
WireBytes
}
x
:=
uint32
(
p
.
Tag
)
<<
3
|
uint32
(
wire
)
i
:=
0
for
i
=
0
;
x
>
127
;
i
++
{
p
.
tagbuf
[
i
]
=
0x80
|
uint8
(
x
&
0x7F
)
x
>>=
7
}
p
.
tagbuf
[
i
]
=
uint8
(
x
)
p
.
tagcode
=
p
.
tagbuf
[
0
:
i
+
1
]
if
p
.
stype
!=
nil
{
if
lockGetProp
{
p
.
sprop
=
GetProperties
(
p
.
stype
)
}
else
{
p
.
sprop
=
getPropertiesLocked
(
p
.
stype
)
}
}
}
var
(
marshalerType
=
reflect
.
TypeOf
((
*
Marshaler
)(
nil
))
.
Elem
()
unmarshalerType
=
reflect
.
TypeOf
((
*
Unmarshaler
)(
nil
))
.
Elem
()
)
// isMarshaler reports whether type t implements Marshaler.
func
isMarshaler
(
t
reflect
.
Type
)
bool
{
return
t
.
Implements
(
marshalerType
)
}
// isUnmarshaler reports whether type t implements Unmarshaler.
func
isUnmarshaler
(
t
reflect
.
Type
)
bool
{
return
t
.
Implements
(
unmarshalerType
)
}
// Init populates the properties from a protocol buffer struct tag.
func
(
p
*
Properties
)
Init
(
typ
reflect
.
Type
,
name
,
tag
string
,
f
*
reflect
.
StructField
)
{
p
.
init
(
typ
,
name
,
tag
,
f
,
true
)
}
func
(
p
*
Properties
)
init
(
typ
reflect
.
Type
,
name
,
tag
string
,
f
*
reflect
.
StructField
,
lockGetProp
bool
)
{
// "bytes,49,opt,def=hello!"
p
.
Name
=
name
p
.
OrigName
=
name
if
f
!=
nil
{
p
.
field
=
toField
(
f
)
}
if
tag
==
""
{
return
}
p
.
Parse
(
tag
)
p
.
setEncAndDec
(
typ
,
f
,
lockGetProp
)
}
var
(
propertiesMu
sync
.
RWMutex
propertiesMap
=
make
(
map
[
reflect
.
Type
]
*
StructProperties
)
)
// 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
{
if
t
.
Kind
()
!=
reflect
.
Struct
{
panic
(
"proto: type must have kind struct"
)
}
// Most calls to GetProperties in a long-running program will be
// retrieving details for types we have seen before.
propertiesMu
.
RLock
()
sprop
,
ok
:=
propertiesMap
[
t
]
propertiesMu
.
RUnlock
()
if
ok
{
if
collectStats
{
stats
.
Chit
++
}
return
sprop
}
propertiesMu
.
Lock
()
sprop
=
getPropertiesLocked
(
t
)
propertiesMu
.
Unlock
()
return
sprop
}
// getPropertiesLocked requires that propertiesMu is held.
func
getPropertiesLocked
(
t
reflect
.
Type
)
*
StructProperties
{
if
prop
,
ok
:=
propertiesMap
[
t
];
ok
{
if
collectStats
{
stats
.
Chit
++
}
return
prop
}
if
collectStats
{
stats
.
Cmiss
++
}
prop
:=
new
(
StructProperties
)
// in case of recursive protos, fill this in now.
propertiesMap
[
t
]
=
prop
// build properties
prop
.
extendable
=
reflect
.
PtrTo
(
t
)
.
Implements
(
extendableProtoType
)
prop
.
unrecField
=
invalidField
prop
.
Prop
=
make
([]
*
Properties
,
t
.
NumField
())
prop
.
order
=
make
([]
int
,
t
.
NumField
())
isOneofMessage
:=
false
for
i
:=
0
;
i
<
t
.
NumField
();
i
++
{
f
:=
t
.
Field
(
i
)
p
:=
new
(
Properties
)
name
:=
f
.
Name
p
.
init
(
f
.
Type
,
name
,
f
.
Tag
.
Get
(
"protobuf"
),
&
f
,
false
)
if
f
.
Name
==
"XXX_extensions"
{
// special case
if
len
(
f
.
Tag
.
Get
(
"protobuf"
))
>
0
{
p
.
enc
=
(
*
Buffer
)
.
enc_ext_slice_byte
p
.
dec
=
nil
// not needed
p
.
size
=
size_ext_slice_byte
}
else
{
p
.
enc
=
(
*
Buffer
)
.
enc_map
p
.
dec
=
nil
// not needed
p
.
size
=
size_map
}
}
if
f
.
Name
==
"XXX_unrecognized"
{
// special case
prop
.
unrecField
=
toField
(
&
f
)
}
oneof
:=
f
.
Tag
.
Get
(
"protobuf_oneof"
)
!=
""
// special case
if
oneof
{
isOneofMessage
=
true
}
prop
.
Prop
[
i
]
=
p
prop
.
order
[
i
]
=
i
if
debug
{
print
(
i
,
" "
,
f
.
Name
,
" "
,
t
.
String
(),
" "
)
if
p
.
Tag
>
0
{
print
(
p
.
String
())
}
print
(
"
\n
"
)
}
if
p
.
enc
==
nil
&&
!
strings
.
HasPrefix
(
f
.
Name
,
"XXX_"
)
&&
!
oneof
{
fmt
.
Fprintln
(
os
.
Stderr
,
"proto: no encoder for"
,
f
.
Name
,
f
.
Type
.
String
(),
"[GetProperties]"
)
}
}
// Re-order prop.order.
sort
.
Sort
(
prop
)
type
oneofMessage
interface
{
XXX_OneofFuncs
()
(
func
(
Message
,
*
Buffer
)
error
,
func
(
Message
,
int
,
int
,
*
Buffer
)
(
bool
,
error
),
[]
interface
{})
}
if
om
,
ok
:=
reflect
.
Zero
(
reflect
.
PtrTo
(
t
))
.
Interface
()
.
(
oneofMessage
);
isOneofMessage
&&
ok
{
var
oots
[]
interface
{}
prop
.
oneofMarshaler
,
prop
.
oneofUnmarshaler
,
oots
=
om
.
XXX_OneofFuncs
()
prop
.
stype
=
t
// Interpret oneof metadata.
prop
.
OneofTypes
=
make
(
map
[
string
]
*
OneofProperties
)
for
_
,
oot
:=
range
oots
{
oop
:=
&
OneofProperties
{
Type
:
reflect
.
ValueOf
(
oot
)
.
Type
(),
// *T
Prop
:
new
(
Properties
),
}
sft
:=
oop
.
Type
.
Elem
()
.
Field
(
0
)
oop
.
Prop
.
Name
=
sft
.
Name
oop
.
Prop
.
Parse
(
sft
.
Tag
.
Get
(
"protobuf"
))
// There will be exactly one interface field that
// this new value is assignable to.
for
i
:=
0
;
i
<
t
.
NumField
();
i
++
{
f
:=
t
.
Field
(
i
)
if
f
.
Type
.
Kind
()
!=
reflect
.
Interface
{
continue
}
if
!
oop
.
Type
.
AssignableTo
(
f
.
Type
)
{
continue
}
oop
.
Field
=
i
break
}
prop
.
OneofTypes
[
oop
.
Prop
.
OrigName
]
=
oop
}
}
// build required counts
// build tags
reqCount
:=
0
prop
.
decoderOrigNames
=
make
(
map
[
string
]
int
)
for
i
,
p
:=
range
prop
.
Prop
{
if
strings
.
HasPrefix
(
p
.
Name
,
"XXX_"
)
{
// Internal fields should not appear in tags/origNames maps.
// They are handled specially when encoding and decoding.
continue
}
if
p
.
Required
{
reqCount
++
}
prop
.
decoderTags
.
put
(
p
.
Tag
,
i
)
prop
.
decoderOrigNames
[
p
.
OrigName
]
=
i
}
prop
.
reqCount
=
reqCount
return
prop
}
// Return the Properties object for the x[0]'th field of the structure.
func
propByIndex
(
t
reflect
.
Type
,
x
[]
int
)
*
Properties
{
if
len
(
x
)
!=
1
{
fmt
.
Fprintf
(
os
.
Stderr
,
"proto: field index dimension %d (not 1) for type %s
\n
"
,
len
(
x
),
t
)
return
nil
}
prop
:=
GetProperties
(
t
)
return
prop
.
Prop
[
x
[
0
]]
}
// Get the address and type of a pointer to a struct from an interface.
func
getbase
(
pb
Message
)
(
t
reflect
.
Type
,
b
structPointer
,
err
error
)
{
if
pb
==
nil
{
err
=
ErrNil
return
}
// get the reflect type of the pointer to the struct.
t
=
reflect
.
TypeOf
(
pb
)
// get the address of the struct.
value
:=
reflect
.
ValueOf
(
pb
)
b
=
toStructPointer
(
value
)
return
}
// A global registry of enum types.
// The generated code will register the generated maps by calling RegisterEnum.
var
enumValueMaps
=
make
(
map
[
string
]
map
[
string
]
int32
)
var
enumStringMaps
=
make
(
map
[
string
]
map
[
int32
]
string
)
// RegisterEnum is called from the generated code to install the enum descriptor
// maps into the global table to aid parsing text format protocol buffers.
func
RegisterEnum
(
typeName
string
,
unusedNameMap
map
[
int32
]
string
,
valueMap
map
[
string
]
int32
)
{
if
_
,
ok
:=
enumValueMaps
[
typeName
];
ok
{
panic
(
"proto: duplicate enum registered: "
+
typeName
)
}
enumValueMaps
[
typeName
]
=
valueMap
if
_
,
ok
:=
enumStringMaps
[
typeName
];
ok
{
panic
(
"proto: duplicate enum registered: "
+
typeName
)
}
enumStringMaps
[
typeName
]
=
unusedNameMap
}
Prev
1
2
3
4
5
6
7
8
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment