Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
songlinfeng
k8s-device-plugin
Commits
8a683270
Commit
8a683270
authored
Nov 25, 2025
by
songlinfeng
💬
Browse files
add k8s-device-plugin
parent
f5f6fd20
Changes
165
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
8177 additions
and
0 deletions
+8177
-0
vendor/github.com/gogo/protobuf/proto/discard.go
vendor/github.com/gogo/protobuf/proto/discard.go
+350
-0
vendor/github.com/gogo/protobuf/proto/duration.go
vendor/github.com/gogo/protobuf/proto/duration.go
+100
-0
vendor/github.com/gogo/protobuf/proto/duration_gogo.go
vendor/github.com/gogo/protobuf/proto/duration_gogo.go
+49
-0
vendor/github.com/gogo/protobuf/proto/encode.go
vendor/github.com/gogo/protobuf/proto/encode.go
+205
-0
vendor/github.com/gogo/protobuf/proto/encode_gogo.go
vendor/github.com/gogo/protobuf/proto/encode_gogo.go
+33
-0
vendor/github.com/gogo/protobuf/proto/equal.go
vendor/github.com/gogo/protobuf/proto/equal.go
+300
-0
vendor/github.com/gogo/protobuf/proto/extensions.go
vendor/github.com/gogo/protobuf/proto/extensions.go
+605
-0
vendor/github.com/gogo/protobuf/proto/extensions_gogo.go
vendor/github.com/gogo/protobuf/proto/extensions_gogo.go
+389
-0
vendor/github.com/gogo/protobuf/proto/lib.go
vendor/github.com/gogo/protobuf/proto/lib.go
+973
-0
vendor/github.com/gogo/protobuf/proto/lib_gogo.go
vendor/github.com/gogo/protobuf/proto/lib_gogo.go
+50
-0
vendor/github.com/gogo/protobuf/proto/message_set.go
vendor/github.com/gogo/protobuf/proto/message_set.go
+181
-0
vendor/github.com/gogo/protobuf/proto/pointer_reflect.go
vendor/github.com/gogo/protobuf/proto/pointer_reflect.go
+357
-0
vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go
...or/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go
+59
-0
vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go
vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go
+308
-0
vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go
vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go
+56
-0
vendor/github.com/gogo/protobuf/proto/properties.go
vendor/github.com/gogo/protobuf/proto/properties.go
+610
-0
vendor/github.com/gogo/protobuf/proto/properties_gogo.go
vendor/github.com/gogo/protobuf/proto/properties_gogo.go
+36
-0
vendor/github.com/gogo/protobuf/proto/skip_gogo.go
vendor/github.com/gogo/protobuf/proto/skip_gogo.go
+119
-0
vendor/github.com/gogo/protobuf/proto/table_marshal.go
vendor/github.com/gogo/protobuf/proto/table_marshal.go
+3009
-0
vendor/github.com/gogo/protobuf/proto/table_marshal_gogo.go
vendor/github.com/gogo/protobuf/proto/table_marshal_gogo.go
+388
-0
No files found.
Too many changes to show.
To preserve performance only
165 of 165+
files are displayed.
Plain diff
Email patch
vendor/github.com/gogo/protobuf/proto/discard.go
0 → 100644
View file @
8a683270
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2017 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
(
"fmt"
"reflect"
"strings"
"sync"
"sync/atomic"
)
type
generatedDiscarder
interface
{
XXX_DiscardUnknown
()
}
// DiscardUnknown recursively discards all unknown fields from this message
// and all embedded messages.
//
// When unmarshaling a message with unrecognized fields, the tags and values
// of such fields are preserved in the Message. This allows a later call to
// marshal to be able to produce a message that continues to have those
// unrecognized fields. To avoid this, DiscardUnknown is used to
// explicitly clear the unknown fields after unmarshaling.
//
// For proto2 messages, the unknown fields of message extensions are only
// discarded from messages that have been accessed via GetExtension.
func
DiscardUnknown
(
m
Message
)
{
if
m
,
ok
:=
m
.
(
generatedDiscarder
);
ok
{
m
.
XXX_DiscardUnknown
()
return
}
// TODO: Dynamically populate a InternalMessageInfo for legacy messages,
// but the master branch has no implementation for InternalMessageInfo,
// so it would be more work to replicate that approach.
discardLegacy
(
m
)
}
// DiscardUnknown recursively discards all unknown fields.
func
(
a
*
InternalMessageInfo
)
DiscardUnknown
(
m
Message
)
{
di
:=
atomicLoadDiscardInfo
(
&
a
.
discard
)
if
di
==
nil
{
di
=
getDiscardInfo
(
reflect
.
TypeOf
(
m
)
.
Elem
())
atomicStoreDiscardInfo
(
&
a
.
discard
,
di
)
}
di
.
discard
(
toPointer
(
&
m
))
}
type
discardInfo
struct
{
typ
reflect
.
Type
initialized
int32
// 0: only typ is valid, 1: everything is valid
lock
sync
.
Mutex
fields
[]
discardFieldInfo
unrecognized
field
}
type
discardFieldInfo
struct
{
field
field
// Offset of field, guaranteed to be valid
discard
func
(
src
pointer
)
}
var
(
discardInfoMap
=
map
[
reflect
.
Type
]
*
discardInfo
{}
discardInfoLock
sync
.
Mutex
)
func
getDiscardInfo
(
t
reflect
.
Type
)
*
discardInfo
{
discardInfoLock
.
Lock
()
defer
discardInfoLock
.
Unlock
()
di
:=
discardInfoMap
[
t
]
if
di
==
nil
{
di
=
&
discardInfo
{
typ
:
t
}
discardInfoMap
[
t
]
=
di
}
return
di
}
func
(
di
*
discardInfo
)
discard
(
src
pointer
)
{
if
src
.
isNil
()
{
return
// Nothing to do.
}
if
atomic
.
LoadInt32
(
&
di
.
initialized
)
==
0
{
di
.
computeDiscardInfo
()
}
for
_
,
fi
:=
range
di
.
fields
{
sfp
:=
src
.
offset
(
fi
.
field
)
fi
.
discard
(
sfp
)
}
// For proto2 messages, only discard unknown fields in message extensions
// that have been accessed via GetExtension.
if
em
,
err
:=
extendable
(
src
.
asPointerTo
(
di
.
typ
)
.
Interface
());
err
==
nil
{
// Ignore lock since DiscardUnknown is not concurrency safe.
emm
,
_
:=
em
.
extensionsRead
()
for
_
,
mx
:=
range
emm
{
if
m
,
ok
:=
mx
.
value
.
(
Message
);
ok
{
DiscardUnknown
(
m
)
}
}
}
if
di
.
unrecognized
.
IsValid
()
{
*
src
.
offset
(
di
.
unrecognized
)
.
toBytes
()
=
nil
}
}
func
(
di
*
discardInfo
)
computeDiscardInfo
()
{
di
.
lock
.
Lock
()
defer
di
.
lock
.
Unlock
()
if
di
.
initialized
!=
0
{
return
}
t
:=
di
.
typ
n
:=
t
.
NumField
()
for
i
:=
0
;
i
<
n
;
i
++
{
f
:=
t
.
Field
(
i
)
if
strings
.
HasPrefix
(
f
.
Name
,
"XXX_"
)
{
continue
}
dfi
:=
discardFieldInfo
{
field
:
toField
(
&
f
)}
tf
:=
f
.
Type
// Unwrap tf to get its most basic type.
var
isPointer
,
isSlice
bool
if
tf
.
Kind
()
==
reflect
.
Slice
&&
tf
.
Elem
()
.
Kind
()
!=
reflect
.
Uint8
{
isSlice
=
true
tf
=
tf
.
Elem
()
}
if
tf
.
Kind
()
==
reflect
.
Ptr
{
isPointer
=
true
tf
=
tf
.
Elem
()
}
if
isPointer
&&
isSlice
&&
tf
.
Kind
()
!=
reflect
.
Struct
{
panic
(
fmt
.
Sprintf
(
"%v.%s cannot be a slice of pointers to primitive types"
,
t
,
f
.
Name
))
}
switch
tf
.
Kind
()
{
case
reflect
.
Struct
:
switch
{
case
!
isPointer
:
panic
(
fmt
.
Sprintf
(
"%v.%s cannot be a direct struct value"
,
t
,
f
.
Name
))
case
isSlice
:
// E.g., []*pb.T
discardInfo
:=
getDiscardInfo
(
tf
)
dfi
.
discard
=
func
(
src
pointer
)
{
sps
:=
src
.
getPointerSlice
()
for
_
,
sp
:=
range
sps
{
if
!
sp
.
isNil
()
{
discardInfo
.
discard
(
sp
)
}
}
}
default
:
// E.g., *pb.T
discardInfo
:=
getDiscardInfo
(
tf
)
dfi
.
discard
=
func
(
src
pointer
)
{
sp
:=
src
.
getPointer
()
if
!
sp
.
isNil
()
{
discardInfo
.
discard
(
sp
)
}
}
}
case
reflect
.
Map
:
switch
{
case
isPointer
||
isSlice
:
panic
(
fmt
.
Sprintf
(
"%v.%s cannot be a pointer to a map or a slice of map values"
,
t
,
f
.
Name
))
default
:
// E.g., map[K]V
if
tf
.
Elem
()
.
Kind
()
==
reflect
.
Ptr
{
// Proto struct (e.g., *T)
dfi
.
discard
=
func
(
src
pointer
)
{
sm
:=
src
.
asPointerTo
(
tf
)
.
Elem
()
if
sm
.
Len
()
==
0
{
return
}
for
_
,
key
:=
range
sm
.
MapKeys
()
{
val
:=
sm
.
MapIndex
(
key
)
DiscardUnknown
(
val
.
Interface
()
.
(
Message
))
}
}
}
else
{
dfi
.
discard
=
func
(
pointer
)
{}
// Noop
}
}
case
reflect
.
Interface
:
// Must be oneof field.
switch
{
case
isPointer
||
isSlice
:
panic
(
fmt
.
Sprintf
(
"%v.%s cannot be a pointer to a interface or a slice of interface values"
,
t
,
f
.
Name
))
default
:
// E.g., interface{}
// TODO: Make this faster?
dfi
.
discard
=
func
(
src
pointer
)
{
su
:=
src
.
asPointerTo
(
tf
)
.
Elem
()
if
!
su
.
IsNil
()
{
sv
:=
su
.
Elem
()
.
Elem
()
.
Field
(
0
)
if
sv
.
Kind
()
==
reflect
.
Ptr
&&
sv
.
IsNil
()
{
return
}
switch
sv
.
Type
()
.
Kind
()
{
case
reflect
.
Ptr
:
// Proto struct (e.g., *T)
DiscardUnknown
(
sv
.
Interface
()
.
(
Message
))
}
}
}
}
default
:
continue
}
di
.
fields
=
append
(
di
.
fields
,
dfi
)
}
di
.
unrecognized
=
invalidField
if
f
,
ok
:=
t
.
FieldByName
(
"XXX_unrecognized"
);
ok
{
if
f
.
Type
!=
reflect
.
TypeOf
([]
byte
{})
{
panic
(
"expected XXX_unrecognized to be of type []byte"
)
}
di
.
unrecognized
=
toField
(
&
f
)
}
atomic
.
StoreInt32
(
&
di
.
initialized
,
1
)
}
func
discardLegacy
(
m
Message
)
{
v
:=
reflect
.
ValueOf
(
m
)
if
v
.
Kind
()
!=
reflect
.
Ptr
||
v
.
IsNil
()
{
return
}
v
=
v
.
Elem
()
if
v
.
Kind
()
!=
reflect
.
Struct
{
return
}
t
:=
v
.
Type
()
for
i
:=
0
;
i
<
v
.
NumField
();
i
++
{
f
:=
t
.
Field
(
i
)
if
strings
.
HasPrefix
(
f
.
Name
,
"XXX_"
)
{
continue
}
vf
:=
v
.
Field
(
i
)
tf
:=
f
.
Type
// Unwrap tf to get its most basic type.
var
isPointer
,
isSlice
bool
if
tf
.
Kind
()
==
reflect
.
Slice
&&
tf
.
Elem
()
.
Kind
()
!=
reflect
.
Uint8
{
isSlice
=
true
tf
=
tf
.
Elem
()
}
if
tf
.
Kind
()
==
reflect
.
Ptr
{
isPointer
=
true
tf
=
tf
.
Elem
()
}
if
isPointer
&&
isSlice
&&
tf
.
Kind
()
!=
reflect
.
Struct
{
panic
(
fmt
.
Sprintf
(
"%T.%s cannot be a slice of pointers to primitive types"
,
m
,
f
.
Name
))
}
switch
tf
.
Kind
()
{
case
reflect
.
Struct
:
switch
{
case
!
isPointer
:
panic
(
fmt
.
Sprintf
(
"%T.%s cannot be a direct struct value"
,
m
,
f
.
Name
))
case
isSlice
:
// E.g., []*pb.T
for
j
:=
0
;
j
<
vf
.
Len
();
j
++
{
discardLegacy
(
vf
.
Index
(
j
)
.
Interface
()
.
(
Message
))
}
default
:
// E.g., *pb.T
discardLegacy
(
vf
.
Interface
()
.
(
Message
))
}
case
reflect
.
Map
:
switch
{
case
isPointer
||
isSlice
:
panic
(
fmt
.
Sprintf
(
"%T.%s cannot be a pointer to a map or a slice of map values"
,
m
,
f
.
Name
))
default
:
// E.g., map[K]V
tv
:=
vf
.
Type
()
.
Elem
()
if
tv
.
Kind
()
==
reflect
.
Ptr
&&
tv
.
Implements
(
protoMessageType
)
{
// Proto struct (e.g., *T)
for
_
,
key
:=
range
vf
.
MapKeys
()
{
val
:=
vf
.
MapIndex
(
key
)
discardLegacy
(
val
.
Interface
()
.
(
Message
))
}
}
}
case
reflect
.
Interface
:
// Must be oneof field.
switch
{
case
isPointer
||
isSlice
:
panic
(
fmt
.
Sprintf
(
"%T.%s cannot be a pointer to a interface or a slice of interface values"
,
m
,
f
.
Name
))
default
:
// E.g., test_proto.isCommunique_Union interface
if
!
vf
.
IsNil
()
&&
f
.
Tag
.
Get
(
"protobuf_oneof"
)
!=
""
{
vf
=
vf
.
Elem
()
// E.g., *test_proto.Communique_Msg
if
!
vf
.
IsNil
()
{
vf
=
vf
.
Elem
()
// E.g., test_proto.Communique_Msg
vf
=
vf
.
Field
(
0
)
// E.g., Proto struct (e.g., *T) or primitive value
if
vf
.
Kind
()
==
reflect
.
Ptr
{
discardLegacy
(
vf
.
Interface
()
.
(
Message
))
}
}
}
}
}
}
if
vf
:=
v
.
FieldByName
(
"XXX_unrecognized"
);
vf
.
IsValid
()
{
if
vf
.
Type
()
!=
reflect
.
TypeOf
([]
byte
{})
{
panic
(
"expected XXX_unrecognized to be of type []byte"
)
}
vf
.
Set
(
reflect
.
ValueOf
([]
byte
(
nil
)))
}
// For proto2 messages, only discard unknown fields in message extensions
// that have been accessed via GetExtension.
if
em
,
err
:=
extendable
(
m
);
err
==
nil
{
// Ignore lock since discardLegacy is not concurrency safe.
emm
,
_
:=
em
.
extensionsRead
()
for
_
,
mx
:=
range
emm
{
if
m
,
ok
:=
mx
.
value
.
(
Message
);
ok
{
discardLegacy
(
m
)
}
}
}
}
vendor/github.com/gogo/protobuf/proto/duration.go
0 → 100644
View file @
8a683270
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2016 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
// This file implements conversions between google.protobuf.Duration
// and time.Duration.
import
(
"errors"
"fmt"
"time"
)
const
(
// Range of a Duration in seconds, as specified in
// google/protobuf/duration.proto. This is about 10,000 years in seconds.
maxSeconds
=
int64
(
10000
*
365.25
*
24
*
60
*
60
)
minSeconds
=
-
maxSeconds
)
// validateDuration determines whether the Duration is valid according to the
// definition in google/protobuf/duration.proto. A valid Duration
// may still be too large to fit into a time.Duration (the range of Duration
// is about 10,000 years, and the range of time.Duration is about 290).
func
validateDuration
(
d
*
duration
)
error
{
if
d
==
nil
{
return
errors
.
New
(
"duration: nil Duration"
)
}
if
d
.
Seconds
<
minSeconds
||
d
.
Seconds
>
maxSeconds
{
return
fmt
.
Errorf
(
"duration: %#v: seconds out of range"
,
d
)
}
if
d
.
Nanos
<=
-
1e9
||
d
.
Nanos
>=
1e9
{
return
fmt
.
Errorf
(
"duration: %#v: nanos out of range"
,
d
)
}
// Seconds and Nanos must have the same sign, unless d.Nanos is zero.
if
(
d
.
Seconds
<
0
&&
d
.
Nanos
>
0
)
||
(
d
.
Seconds
>
0
&&
d
.
Nanos
<
0
)
{
return
fmt
.
Errorf
(
"duration: %#v: seconds and nanos have different signs"
,
d
)
}
return
nil
}
// DurationFromProto converts a Duration to a time.Duration. DurationFromProto
// returns an error if the Duration is invalid or is too large to be
// represented in a time.Duration.
func
durationFromProto
(
p
*
duration
)
(
time
.
Duration
,
error
)
{
if
err
:=
validateDuration
(
p
);
err
!=
nil
{
return
0
,
err
}
d
:=
time
.
Duration
(
p
.
Seconds
)
*
time
.
Second
if
int64
(
d
/
time
.
Second
)
!=
p
.
Seconds
{
return
0
,
fmt
.
Errorf
(
"duration: %#v is out of range for time.Duration"
,
p
)
}
if
p
.
Nanos
!=
0
{
d
+=
time
.
Duration
(
p
.
Nanos
)
if
(
d
<
0
)
!=
(
p
.
Nanos
<
0
)
{
return
0
,
fmt
.
Errorf
(
"duration: %#v is out of range for time.Duration"
,
p
)
}
}
return
d
,
nil
}
// DurationProto converts a time.Duration to a Duration.
func
durationProto
(
d
time
.
Duration
)
*
duration
{
nanos
:=
d
.
Nanoseconds
()
secs
:=
nanos
/
1e9
nanos
-=
secs
*
1e9
return
&
duration
{
Seconds
:
secs
,
Nanos
:
int32
(
nanos
),
}
}
vendor/github.com/gogo/protobuf/proto/duration_gogo.go
0 → 100644
View file @
8a683270
// Protocol Buffers for Go with Gadgets
//
// Copyright (c) 2016, The GoGo Authors. All rights reserved.
// http://github.com/gogo/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.
//
// 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"
"time"
)
var
durationType
=
reflect
.
TypeOf
((
*
time
.
Duration
)(
nil
))
.
Elem
()
type
duration
struct
{
Seconds
int64
`protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"`
Nanos
int32
`protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"`
}
func
(
m
*
duration
)
Reset
()
{
*
m
=
duration
{}
}
func
(
*
duration
)
ProtoMessage
()
{}
func
(
*
duration
)
String
()
string
{
return
"duration<string>"
}
func
init
()
{
RegisterType
((
*
duration
)(
nil
),
"gogo.protobuf.proto.duration"
)
}
vendor/github.com/gogo/protobuf/proto/encode.go
0 → 100644
View file @
8a683270
// 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"
"reflect"
)
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"
)
// errOneofHasNil is the error returned if Marshal is called with
// a struct with a oneof field containing a nil element.
errOneofHasNil
=
errors
.
New
(
"proto: oneof field has nil value"
)
// ErrNil is the error returned if Marshal is called with nil.
ErrNil
=
errors
.
New
(
"proto: Marshal called with nil"
)
// ErrTooLarge is the error returned if Marshal is called with a
// message that encodes to >2GB.
ErrTooLarge
=
errors
.
New
(
"proto: message encodes to over 2 GB"
)
)
// 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
}
// SizeVarint returns the varint encoding size of an integer.
func
SizeVarint
(
x
uint64
)
int
{
switch
{
case
x
<
1
<<
7
:
return
1
case
x
<
1
<<
14
:
return
2
case
x
<
1
<<
21
:
return
3
case
x
<
1
<<
28
:
return
4
case
x
<
1
<<
35
:
return
5
case
x
<
1
<<
42
:
return
6
case
x
<
1
<<
49
:
return
7
case
x
<
1
<<
56
:
return
8
case
x
<
1
<<
63
:
return
9
}
return
10
}
// 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
}
// 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
}
// 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
))))
}
// 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
))))
}
// 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
}
// 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
}
// Marshaler is the interface representing objects that can marshal themselves.
type
Marshaler
interface
{
Marshal
()
([]
byte
,
error
)
}
// EncodeMessage writes the protocol buffer to the Buffer,
// prefixed by a varint-encoded length.
func
(
p
*
Buffer
)
EncodeMessage
(
pb
Message
)
error
{
siz
:=
Size
(
pb
)
sizVar
:=
SizeVarint
(
uint64
(
siz
))
p
.
grow
(
siz
+
sizVar
)
p
.
EncodeVarint
(
uint64
(
siz
))
return
p
.
Marshal
(
pb
)
}
// 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
}
vendor/github.com/gogo/protobuf/proto/encode_gogo.go
0 → 100644
View file @
8a683270
// Protocol Buffers for Go with Gadgets
//
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
// http://github.com/gogo/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.
//
// 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
func
NewRequiredNotSetError
(
field
string
)
*
RequiredNotSetError
{
return
&
RequiredNotSetError
{
field
}
}
vendor/github.com/gogo/protobuf/proto/equal.go
0 → 100644
View file @
8a683270
// 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.
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. If the message is defined
in a proto3 .proto file, fields are not "set"; specifically,
zero length proto3 "bytes" fields are equal (nil == {}).
- Two repeated fields are equal iff their lengths are the same,
and their corresponding elements are equal. Note a "bytes" field,
although represented by []byte, is not a repeated field and the
rule for the scalar fields described above applies.
- 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.
- Two map fields are equal iff their lengths are the same,
and they contain the same set of elements. Zero-length map
fields are 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
{
sprop
:=
GetProperties
(
v1
.
Type
())
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
}
f1
,
f2
=
f1
.
Elem
(),
f2
.
Elem
()
}
if
!
equalAny
(
f1
,
f2
,
sprop
.
Prop
[
i
])
{
return
false
}
}
if
em1
:=
v1
.
FieldByName
(
"XXX_InternalExtensions"
);
em1
.
IsValid
()
{
em2
:=
v2
.
FieldByName
(
"XXX_InternalExtensions"
)
if
!
equalExtensions
(
v1
.
Type
(),
em1
.
Interface
()
.
(
XXX_InternalExtensions
),
em2
.
Interface
()
.
(
XXX_InternalExtensions
))
{
return
false
}
}
if
em1
:=
v1
.
FieldByName
(
"XXX_extensions"
);
em1
.
IsValid
()
{
em2
:=
v2
.
FieldByName
(
"XXX_extensions"
)
if
!
equalExtMap
(
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
()
return
bytes
.
Equal
(
u1
,
u2
)
}
// v1 and v2 are known to have the same type.
// prop may be nil.
func
equalAny
(
v1
,
v2
reflect
.
Value
,
prop
*
Properties
)
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
,
nil
)
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
,
nil
)
{
return
false
}
}
return
true
case
reflect
.
Ptr
:
// Maps may have nil values in them, so check for nil.
if
v1
.
IsNil
()
&&
v2
.
IsNil
()
{
return
true
}
if
v1
.
IsNil
()
!=
v2
.
IsNil
()
{
return
false
}
return
equalAny
(
v1
.
Elem
(),
v2
.
Elem
(),
prop
)
case
reflect
.
Slice
:
if
v1
.
Type
()
.
Elem
()
.
Kind
()
==
reflect
.
Uint8
{
// short circuit: []byte
// Edge case: if this is in a proto3 message, a zero length
// bytes field is considered the zero value.
if
prop
!=
nil
&&
prop
.
proto3
&&
v1
.
Len
()
==
0
&&
v2
.
Len
()
==
0
{
return
true
}
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
),
prop
)
{
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.
// x1 and x2 are InternalExtensions.
func
equalExtensions
(
base
reflect
.
Type
,
x1
,
x2
XXX_InternalExtensions
)
bool
{
em1
,
_
:=
x1
.
extensionsRead
()
em2
,
_
:=
x2
.
extensionsRead
()
return
equalExtMap
(
base
,
em1
,
em2
)
}
func
equalExtMap
(
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 have only encoded form.
if
bytes
.
Equal
(
e1
.
enc
,
e2
.
enc
)
{
continue
}
// The bytes are different, but the extensions might still be
// equal. We need to decode them to compare.
}
if
m1
!=
nil
&&
m2
!=
nil
{
// Both are unencoded.
if
!
equalAny
(
reflect
.
ValueOf
(
m1
),
reflect
.
ValueOf
(
m2
),
nil
)
{
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
{
// If both have only encoded form and the bytes are the same,
// it is handled above. We get here when the bytes are different.
// We don't know how to decode it, so just compare them as byte
// slices.
log
.
Printf
(
"proto: don't know how to compare extension %d of %v"
,
extNum
,
base
)
return
false
}
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
),
nil
)
{
return
false
}
}
return
true
}
vendor/github.com/gogo/protobuf/proto/extensions.go
0 → 100644
View file @
8a683270
// 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"
"io"
"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 generated by the current
// proto compiler that may be extended.
type
extendableProto
interface
{
Message
ExtensionRangeArray
()
[]
ExtensionRange
extensionsWrite
()
map
[
int32
]
Extension
extensionsRead
()
(
map
[
int32
]
Extension
,
sync
.
Locker
)
}
// extendableProtoV1 is an interface implemented by a protocol buffer generated by the previous
// version of the proto compiler that may be extended.
type
extendableProtoV1
interface
{
Message
ExtensionRangeArray
()
[]
ExtensionRange
ExtensionMap
()
map
[
int32
]
Extension
}
// extensionAdapter is a wrapper around extendableProtoV1 that implements extendableProto.
type
extensionAdapter
struct
{
extendableProtoV1
}
func
(
e
extensionAdapter
)
extensionsWrite
()
map
[
int32
]
Extension
{
return
e
.
ExtensionMap
()
}
func
(
e
extensionAdapter
)
extensionsRead
()
(
map
[
int32
]
Extension
,
sync
.
Locker
)
{
return
e
.
ExtensionMap
(),
notLocker
{}
}
// notLocker is a sync.Locker whose Lock and Unlock methods are nops.
type
notLocker
struct
{}
func
(
n
notLocker
)
Lock
()
{}
func
(
n
notLocker
)
Unlock
()
{}
// extendable returns the extendableProto interface for the given generated proto message.
// If the proto message has the old extension format, it returns a wrapper that implements
// the extendableProto interface.
func
extendable
(
p
interface
{})
(
extendableProto
,
error
)
{
switch
p
:=
p
.
(
type
)
{
case
extendableProto
:
if
isNilPtr
(
p
)
{
return
nil
,
fmt
.
Errorf
(
"proto: nil %T is not extendable"
,
p
)
}
return
p
,
nil
case
extendableProtoV1
:
if
isNilPtr
(
p
)
{
return
nil
,
fmt
.
Errorf
(
"proto: nil %T is not extendable"
,
p
)
}
return
extensionAdapter
{
p
},
nil
case
extensionsBytes
:
return
slowExtensionAdapter
{
p
},
nil
}
// Don't allocate a specific error containing %T:
// this is the hot path for Clone and MarshalText.
return
nil
,
errNotExtendable
}
var
errNotExtendable
=
errors
.
New
(
"proto: not an extendable proto.Message"
)
func
isNilPtr
(
x
interface
{})
bool
{
v
:=
reflect
.
ValueOf
(
x
)
return
v
.
Kind
()
==
reflect
.
Ptr
&&
v
.
IsNil
()
}
// XXX_InternalExtensions is an internal representation of proto extensions.
//
// Each generated message struct type embeds an anonymous XXX_InternalExtensions field,
// thus gaining the unexported 'extensions' method, which can be called only from the proto package.
//
// The methods of XXX_InternalExtensions are not concurrency safe in general,
// but calls to logically read-only methods such as has and get may be executed concurrently.
type
XXX_InternalExtensions
struct
{
// The struct must be indirect so that if a user inadvertently copies a
// generated message and its embedded XXX_InternalExtensions, they
// avoid the mayhem of a copied mutex.
//
// The mutex serializes all logically read-only operations to p.extensionMap.
// It is up to the client to ensure that write operations to p.extensionMap are
// mutually exclusive with other accesses.
p
*
struct
{
mu
sync
.
Mutex
extensionMap
map
[
int32
]
Extension
}
}
// extensionsWrite returns the extension map, creating it on first use.
func
(
e
*
XXX_InternalExtensions
)
extensionsWrite
()
map
[
int32
]
Extension
{
if
e
.
p
==
nil
{
e
.
p
=
new
(
struct
{
mu
sync
.
Mutex
extensionMap
map
[
int32
]
Extension
})
e
.
p
.
extensionMap
=
make
(
map
[
int32
]
Extension
)
}
return
e
.
p
.
extensionMap
}
// extensionsRead returns the extensions map for read-only use. It may be nil.
// The caller must hold the returned mutex's lock when accessing Elements within the map.
func
(
e
*
XXX_InternalExtensions
)
extensionsRead
()
(
map
[
int32
]
Extension
,
sync
.
Locker
)
{
if
e
.
p
==
nil
{
return
nil
,
nil
}
return
e
.
p
.
extensionMap
,
&
e
.
p
.
mu
}
// 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
Filename
string
// name of the file in which the extension is defined
}
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
Message
,
id
int32
,
b
[]
byte
)
{
if
ebase
,
ok
:=
base
.
(
extensionsBytes
);
ok
{
clearExtension
(
base
,
id
)
ext
:=
ebase
.
GetExtensions
()
*
ext
=
append
(
*
ext
,
b
...
)
return
}
epb
,
err
:=
extendable
(
base
)
if
err
!=
nil
{
return
}
extmap
:=
epb
.
extensionsWrite
()
extmap
[
id
]
=
Extension
{
enc
:
b
}
}
// 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
{
var
pbi
interface
{}
=
pb
// Check the extended type.
if
ea
,
ok
:=
pbi
.
(
extensionAdapter
);
ok
{
pbi
=
ea
.
extendableProtoV1
}
if
ea
,
ok
:=
pbi
.
(
slowExtensionAdapter
);
ok
{
pbi
=
ea
.
extensionsBytes
}
if
a
,
b
:=
reflect
.
TypeOf
(
pbi
),
reflect
.
TypeOf
(
extension
.
ExtendedType
);
a
!=
b
{
return
fmt
.
Errorf
(
"proto: bad extended type; %v does not extend %v"
,
b
,
a
)
}
// 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
}
// HasExtension returns whether the given extension is present in pb.
func
HasExtension
(
pb
Message
,
extension
*
ExtensionDesc
)
bool
{
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
}
// TODO: Check types, field numbers, etc.?
epb
,
err
:=
extendable
(
pb
)
if
err
!=
nil
{
return
false
}
extmap
,
mu
:=
epb
.
extensionsRead
()
if
extmap
==
nil
{
return
false
}
mu
.
Lock
()
_
,
ok
:=
extmap
[
extension
.
Field
]
mu
.
Unlock
()
return
ok
}
// ClearExtension removes the given extension from pb.
func
ClearExtension
(
pb
Message
,
extension
*
ExtensionDesc
)
{
clearExtension
(
pb
,
extension
.
Field
)
}
func
clearExtension
(
pb
Message
,
fieldNum
int32
)
{
if
epb
,
ok
:=
pb
.
(
extensionsBytes
);
ok
{
offset
:=
0
for
offset
!=
-
1
{
offset
=
deleteExtension
(
epb
,
fieldNum
,
offset
)
}
return
}
epb
,
err
:=
extendable
(
pb
)
if
err
!=
nil
{
return
}
// TODO: Check types, field numbers, etc.?
extmap
:=
epb
.
extensionsWrite
()
delete
(
extmap
,
fieldNum
)
}
// GetExtension retrieves a proto2 extended field from pb.
//
// If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil),
// then GetExtension parses the encoded field and returns a Go value of the specified type.
// If the field is not present, then the default value is returned (if one is specified),
// otherwise ErrMissingExtension is reported.
//
// If the descriptor is not type complete (i.e., ExtensionDesc.ExtensionType is nil),
// then GetExtension returns the raw encoded bytes of the field extension.
func
GetExtension
(
pb
Message
,
extension
*
ExtensionDesc
)
(
interface
{},
error
)
{
if
epb
,
doki
:=
pb
.
(
extensionsBytes
);
doki
{
ext
:=
epb
.
GetExtensions
()
return
decodeExtensionFromBytes
(
extension
,
*
ext
)
}
epb
,
err
:=
extendable
(
pb
)
if
err
!=
nil
{
return
nil
,
err
}
if
extension
.
ExtendedType
!=
nil
{
// can only check type if this is a complete descriptor
if
cerr
:=
checkExtensionTypes
(
epb
,
extension
);
cerr
!=
nil
{
return
nil
,
cerr
}
}
emap
,
mu
:=
epb
.
extensionsRead
()
if
emap
==
nil
{
return
defaultExtensionValue
(
extension
)
}
mu
.
Lock
()
defer
mu
.
Unlock
()
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
}
if
extension
.
ExtensionType
==
nil
{
// incomplete descriptor
return
e
.
enc
,
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
}
// defaultExtensionValue returns the default value for extension.
// If no default for an extension is defined ErrMissingExtension is returned.
func
defaultExtensionValue
(
extension
*
ExtensionDesc
)
(
interface
{},
error
)
{
if
extension
.
ExtensionType
==
nil
{
// incomplete descriptor, so no default
return
nil
,
ErrMissingExtension
}
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
)
{
t
:=
reflect
.
TypeOf
(
extension
.
ExtensionType
)
unmarshal
:=
typeUnmarshaler
(
t
,
extension
.
Tag
)
// t is a pointer to a struct, pointer to basic type or a slice.
// Allocate space to store the pointer/slice.
value
:=
reflect
.
New
(
t
)
.
Elem
()
var
err
error
for
{
x
,
n
:=
decodeVarint
(
b
)
if
n
==
0
{
return
nil
,
io
.
ErrUnexpectedEOF
}
b
=
b
[
n
:
]
wire
:=
int
(
x
)
&
7
b
,
err
=
unmarshal
(
b
,
valToPointer
(
value
.
Addr
()),
wire
)
if
err
!=
nil
{
return
nil
,
err
}
if
len
(
b
)
==
0
{
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
,
err
:=
extendable
(
pb
)
if
err
!=
nil
{
return
nil
,
err
}
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
}
// ExtensionDescs returns a new slice containing pb's extension descriptors, in undefined order.
// For non-registered extensions, ExtensionDescs returns an incomplete descriptor containing
// just the Field field, which defines the extension's field number.
func
ExtensionDescs
(
pb
Message
)
([]
*
ExtensionDesc
,
error
)
{
epb
,
err
:=
extendable
(
pb
)
if
err
!=
nil
{
return
nil
,
err
}
registeredExtensions
:=
RegisteredExtensions
(
pb
)
emap
,
mu
:=
epb
.
extensionsRead
()
if
emap
==
nil
{
return
nil
,
nil
}
mu
.
Lock
()
defer
mu
.
Unlock
()
extensions
:=
make
([]
*
ExtensionDesc
,
0
,
len
(
emap
))
for
extid
,
e
:=
range
emap
{
desc
:=
e
.
desc
if
desc
==
nil
{
desc
=
registeredExtensions
[
extid
]
if
desc
==
nil
{
desc
=
&
ExtensionDesc
{
Field
:
extid
}
}
}
extensions
=
append
(
extensions
,
desc
)
}
return
extensions
,
nil
}
// SetExtension sets the specified extension of pb to the specified value.
func
SetExtension
(
pb
Message
,
extension
*
ExtensionDesc
,
value
interface
{})
error
{
if
epb
,
ok
:=
pb
.
(
extensionsBytes
);
ok
{
ClearExtension
(
pb
,
extension
)
newb
,
err
:=
encodeExtension
(
extension
,
value
)
if
err
!=
nil
{
return
err
}
bb
:=
epb
.
GetExtensions
()
*
bb
=
append
(
*
bb
,
newb
...
)
return
nil
}
epb
,
err
:=
extendable
(
pb
)
if
err
!=
nil
{
return
err
}
if
err
:=
checkExtensionTypes
(
epb
,
extension
);
err
!=
nil
{
return
err
}
typ
:=
reflect
.
TypeOf
(
extension
.
ExtensionType
)
if
typ
!=
reflect
.
TypeOf
(
value
)
{
return
fmt
.
Errorf
(
"proto: bad extension value type. got: %T, want: %T"
,
value
,
extension
.
ExtensionType
)
}
// 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
)
}
extmap
:=
epb
.
extensionsWrite
()
extmap
[
extension
.
Field
]
=
Extension
{
desc
:
extension
,
value
:
value
}
return
nil
}
// ClearAllExtensions clears all extensions from pb.
func
ClearAllExtensions
(
pb
Message
)
{
if
epb
,
doki
:=
pb
.
(
extensionsBytes
);
doki
{
ext
:=
epb
.
GetExtensions
()
*
ext
=
[]
byte
{}
return
}
epb
,
err
:=
extendable
(
pb
)
if
err
!=
nil
{
return
}
m
:=
epb
.
extensionsWrite
()
for
k
:=
range
m
{
delete
(
m
,
k
)
}
}
// 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/github.com/gogo/protobuf/proto/extensions_gogo.go
0 → 100644
View file @
8a683270
// Protocol Buffers for Go with Gadgets
//
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
// http://github.com/gogo/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.
//
// 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"
"io"
"reflect"
"sort"
"strings"
"sync"
)
type
extensionsBytes
interface
{
Message
ExtensionRangeArray
()
[]
ExtensionRange
GetExtensions
()
*
[]
byte
}
type
slowExtensionAdapter
struct
{
extensionsBytes
}
func
(
s
slowExtensionAdapter
)
extensionsWrite
()
map
[
int32
]
Extension
{
panic
(
"Please report a bug to github.com/gogo/protobuf if you see this message: Writing extensions is not supported for extensions stored in a byte slice field."
)
}
func
(
s
slowExtensionAdapter
)
extensionsRead
()
(
map
[
int32
]
Extension
,
sync
.
Locker
)
{
b
:=
s
.
GetExtensions
()
m
,
err
:=
BytesToExtensionsMap
(
*
b
)
if
err
!=
nil
{
panic
(
err
)
}
return
m
,
notLocker
{}
}
func
GetBoolExtension
(
pb
Message
,
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
{
if
err
:=
this
.
Encode
();
err
!=
nil
{
return
false
}
if
err
:=
that
.
Encode
();
err
!=
nil
{
return
false
}
return
bytes
.
Equal
(
this
.
enc
,
that
.
enc
)
}
func
(
this
*
Extension
)
Compare
(
that
*
Extension
)
int
{
if
err
:=
this
.
Encode
();
err
!=
nil
{
return
1
}
if
err
:=
that
.
Encode
();
err
!=
nil
{
return
-
1
}
return
bytes
.
Compare
(
this
.
enc
,
that
.
enc
)
}
func
SizeOfInternalExtension
(
m
extendableProto
)
(
n
int
)
{
info
:=
getMarshalInfo
(
reflect
.
TypeOf
(
m
))
return
info
.
sizeV1Extensions
(
m
.
extensionsWrite
())
}
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
StringFromInternalExtension
(
m
extendableProto
)
string
{
return
StringFromExtensionsMap
(
m
.
extensionsWrite
())
}
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
EncodeInternalExtension
(
m
extendableProto
,
data
[]
byte
)
(
n
int
,
err
error
)
{
return
EncodeExtensionMap
(
m
.
extensionsWrite
(),
data
)
}
func
EncodeInternalExtensionBackwards
(
m
extendableProto
,
data
[]
byte
)
(
n
int
,
err
error
)
{
return
EncodeExtensionMapBackwards
(
m
.
extensionsWrite
(),
data
)
}
func
EncodeExtensionMap
(
m
map
[
int32
]
Extension
,
data
[]
byte
)
(
n
int
,
err
error
)
{
o
:=
0
for
_
,
e
:=
range
m
{
if
err
:=
e
.
Encode
();
err
!=
nil
{
return
0
,
err
}
n
:=
copy
(
data
[
o
:
],
e
.
enc
)
if
n
!=
len
(
e
.
enc
)
{
return
0
,
io
.
ErrShortBuffer
}
o
+=
n
}
return
o
,
nil
}
func
EncodeExtensionMapBackwards
(
m
map
[
int32
]
Extension
,
data
[]
byte
)
(
n
int
,
err
error
)
{
o
:=
0
end
:=
len
(
data
)
for
_
,
e
:=
range
m
{
if
err
:=
e
.
Encode
();
err
!=
nil
{
return
0
,
err
}
n
:=
copy
(
data
[
end
-
len
(
e
.
enc
)
:
],
e
.
enc
)
if
n
!=
len
(
e
.
enc
)
{
return
0
,
io
.
ErrShortBuffer
}
end
-=
n
o
+=
n
}
return
o
,
nil
}
func
GetRawExtension
(
m
map
[
int32
]
Extension
,
id
int32
)
([]
byte
,
error
)
{
e
:=
m
[
id
]
if
err
:=
e
.
Encode
();
err
!=
nil
{
return
nil
,
err
}
return
e
.
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
AppendExtension
(
e
Message
,
tag
int32
,
buf
[]
byte
)
{
if
ee
,
eok
:=
e
.
(
extensionsBytes
);
eok
{
ext
:=
ee
.
GetExtensions
()
*
ext
=
append
(
*
ext
,
buf
...
)
return
}
if
ee
,
eok
:=
e
.
(
extendableProto
);
eok
{
m
:=
ee
.
extensionsWrite
()
ext
:=
m
[
int32
(
tag
)]
// may be missing
ext
.
enc
=
append
(
ext
.
enc
,
buf
...
)
m
[
int32
(
tag
)]
=
ext
}
}
func
encodeExtension
(
extension
*
ExtensionDesc
,
value
interface
{})
([]
byte
,
error
)
{
u
:=
getMarshalInfo
(
reflect
.
TypeOf
(
extension
.
ExtendedType
))
ei
:=
u
.
getExtElemInfo
(
extension
)
v
:=
value
p
:=
toAddrPointer
(
&
v
,
ei
.
isptr
)
siz
:=
ei
.
sizer
(
p
,
SizeVarint
(
ei
.
wiretag
))
buf
:=
make
([]
byte
,
0
,
siz
)
return
ei
.
marshaler
(
buf
,
p
,
ei
.
wiretag
,
false
)
}
func
decodeExtensionFromBytes
(
extension
*
ExtensionDesc
,
buf
[]
byte
)
(
interface
{},
error
)
{
o
:=
0
for
o
<
len
(
buf
)
{
tag
,
n
:=
DecodeVarint
((
buf
)[
o
:
])
fieldNum
:=
int32
(
tag
>>
3
)
wireType
:=
int
(
tag
&
0x7
)
if
o
+
n
>
len
(
buf
)
{
return
nil
,
fmt
.
Errorf
(
"unable to decode extension"
)
}
l
,
err
:=
size
((
buf
)[
o
+
n
:
],
wireType
)
if
err
!=
nil
{
return
nil
,
err
}
if
int32
(
fieldNum
)
==
extension
.
Field
{
if
o
+
n
+
l
>
len
(
buf
)
{
return
nil
,
fmt
.
Errorf
(
"unable to decode extension"
)
}
v
,
err
:=
decodeExtension
((
buf
)[
o
:
o
+
n
+
l
],
extension
)
if
err
!=
nil
{
return
nil
,
err
}
return
v
,
nil
}
o
+=
n
+
l
}
return
defaultExtensionValue
(
extension
)
}
func
(
this
*
Extension
)
Encode
()
error
{
if
this
.
enc
==
nil
{
var
err
error
this
.
enc
,
err
=
encodeExtension
(
this
.
desc
,
this
.
value
)
if
err
!=
nil
{
return
err
}
}
return
nil
}
func
(
this
Extension
)
GoString
()
string
{
if
err
:=
this
.
Encode
();
err
!=
nil
{
return
fmt
.
Sprintf
(
"error encoding extension: %v"
,
err
)
}
return
fmt
.
Sprintf
(
"proto.NewExtension(%#v)"
,
this
.
enc
)
}
func
SetUnsafeExtension
(
pb
Message
,
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
Message
,
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
)
}
func
NewUnsafeXXX_InternalExtensions
(
m
map
[
int32
]
Extension
)
XXX_InternalExtensions
{
x
:=
&
XXX_InternalExtensions
{
p
:
new
(
struct
{
mu
sync
.
Mutex
extensionMap
map
[
int32
]
Extension
}),
}
x
.
p
.
extensionMap
=
m
return
*
x
}
func
GetUnsafeExtensionsMap
(
extendable
Message
)
map
[
int32
]
Extension
{
pb
:=
extendable
.
(
extendableProto
)
return
pb
.
extensionsWrite
()
}
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
}
vendor/github.com/gogo/protobuf/proto/lib.go
0 → 100644
View file @
8a683270
// 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.
When the .proto file specifies `syntax="proto3"`, there are some differences:
- Non-repeated fields of non-message type are values instead of pointers.
- Enum types do not get an Enum method.
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),
Reps: []int64{1, 2, 3},
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"
)
// RequiredNotSetError is an error type returned by either Marshal or Unmarshal.
// Marshal reports this when a required field is not initialized.
// Unmarshal reports this when a required field is missing from the wire data.
type
RequiredNotSetError
struct
{
field
string
}
func
(
e
*
RequiredNotSetError
)
Error
()
string
{
if
e
.
field
==
""
{
return
fmt
.
Sprintf
(
"proto: required field not set"
)
}
return
fmt
.
Sprintf
(
"proto: required field %q not set"
,
e
.
field
)
}
func
(
e
*
RequiredNotSetError
)
RequiredNotSet
()
bool
{
return
true
}
type
invalidUTF8Error
struct
{
field
string
}
func
(
e
*
invalidUTF8Error
)
Error
()
string
{
if
e
.
field
==
""
{
return
"proto: invalid UTF-8 detected"
}
return
fmt
.
Sprintf
(
"proto: field %q contains invalid UTF-8"
,
e
.
field
)
}
func
(
e
*
invalidUTF8Error
)
InvalidUTF8
()
bool
{
return
true
}
// errInvalidUTF8 is a sentinel error to identify fields with invalid UTF-8.
// This error should not be exposed to the external API as such errors should
// be recreated with the field information.
var
errInvalidUTF8
=
&
invalidUTF8Error
{}
// isNonFatal reports whether the error is either a RequiredNotSet error
// or a InvalidUTF8 error.
func
isNonFatal
(
err
error
)
bool
{
if
re
,
ok
:=
err
.
(
interface
{
RequiredNotSet
()
bool
});
ok
&&
re
.
RequiredNotSet
()
{
return
true
}
if
re
,
ok
:=
err
.
(
interface
{
InvalidUTF8
()
bool
});
ok
&&
re
.
InvalidUTF8
()
{
return
true
}
return
false
}
type
nonFatal
struct
{
E
error
}
// Merge merges err into nf and reports whether it was successful.
// Otherwise it returns false for any fatal non-nil errors.
func
(
nf
*
nonFatal
)
Merge
(
err
error
)
(
ok
bool
)
{
if
err
==
nil
{
return
true
// not an error
}
if
!
isNonFatal
(
err
)
{
return
false
// fatal error
}
if
nf
.
E
==
nil
{
nf
.
E
=
err
// store first instance of non-fatal error
}
return
true
}
// Message is implemented by generated protocol buffer messages.
type
Message
interface
{
Reset
()
String
()
string
ProtoMessage
()
}
// 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
// read point
deterministic
bool
}
// 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
}
// SetDeterministic sets whether to use deterministic serialization.
//
// Deterministic serialization guarantees that for a given binary, equal
// messages will always be serialized to the same bytes. This implies:
//
// - Repeated serialization of a message will return the same bytes.
// - Different processes of the same binary (which may be executing on
// different machines) will serialize equal messages to the same bytes.
//
// Note that the deterministic serialization is NOT canonical across
// languages. It is not guaranteed to remain stable over time. It is unstable
// across different builds with schema changes due to unknown fields.
// Users who need canonical serialization (e.g., persistent storage in a
// canonical form, fingerprinting, etc.) should define their own
// canonicalization specification and implement their own serializer rather
// than relying on this API.
//
// If deterministic serialization is requested, map entries will be sorted
// by keys in lexographical order. This is an implementation detail and
// subject to change.
func
(
p
*
Buffer
)
SetDeterministic
(
deterministic
bool
)
{
p
.
deterministic
=
deterministic
}
/*
* 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
sindex
:=
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
=
sindex
}
// 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 struct.
func
setDefaults
(
v
reflect
.
Value
,
recur
,
zeros
bool
)
{
if
v
.
Kind
()
==
reflect
.
Ptr
{
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 []*T or []T
switch
f
.
Kind
()
{
case
reflect
.
Struct
:
setDefaults
(
f
,
recur
,
zeros
)
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
.
Kind
()
==
reflect
.
Ptr
&&
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
.
Struct
:
nestedMessage
=
true
// non-nullable
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
,
reflect
.
Struct
:
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
}
// mapKeys returns a sort.Interface to be used for sorting the map keys.
// Map fields may have key types of non-float scalars, strings and enums.
func
mapKeys
(
vs
[]
reflect
.
Value
)
sort
.
Interface
{
s
:=
mapKeySorter
{
vs
:
vs
}
// Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps.
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
()
}
case
reflect
.
Bool
:
s
.
less
=
func
(
a
,
b
reflect
.
Value
)
bool
{
return
!
a
.
Bool
()
&&
b
.
Bool
()
}
// false < true
case
reflect
.
String
:
s
.
less
=
func
(
a
,
b
reflect
.
Value
)
bool
{
return
a
.
String
()
<
b
.
String
()
}
default
:
panic
(
fmt
.
Sprintf
(
"unsupported map key type: %v"
,
vs
[
0
]
.
Kind
()))
}
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
}
const
(
// ProtoPackageIsVersion3 is referenced from generated protocol buffer files
// to assert that that code is compatible with this version of the proto package.
GoGoProtoPackageIsVersion3
=
true
// ProtoPackageIsVersion2 is referenced from generated protocol buffer files
// to assert that that code is compatible with this version of the proto package.
GoGoProtoPackageIsVersion2
=
true
// ProtoPackageIsVersion1 is referenced from generated protocol buffer files
// to assert that that code is compatible with this version of the proto package.
GoGoProtoPackageIsVersion1
=
true
)
// InternalMessageInfo is a type used internally by generated .pb.go files.
// This type is not intended to be used by non-generated code.
// This type is not subject to any compatibility guarantee.
type
InternalMessageInfo
struct
{
marshal
*
marshalInfo
unmarshal
*
unmarshalInfo
merge
*
mergeInfo
discard
*
discardInfo
}
vendor/github.com/gogo/protobuf/proto/lib_gogo.go
0 → 100644
View file @
8a683270
// Protocol Buffers for Go with Gadgets
//
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
// http://github.com/gogo/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.
//
// 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"
)
type
Sizer
interface
{
Size
()
int
}
type
ProtoSizer
interface
{
ProtoSize
()
int
}
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/github.com/gogo/protobuf/proto/message_set.go
0 → 100644
View file @
8a683270
// 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
(
"errors"
)
// 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.
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
{
return
ms
.
find
(
pb
)
!=
nil
}
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
:
]
}
// unmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
// It is called by Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
func
unmarshalMessageSet
(
buf
[]
byte
,
exts
interface
{})
error
{
var
m
map
[
int32
]
Extension
switch
exts
:=
exts
.
(
type
)
{
case
*
XXX_InternalExtensions
:
m
=
exts
.
extensionsWrite
()
case
map
[
int32
]
Extension
:
m
=
exts
default
:
return
errors
.
New
(
"proto: not an extension map"
)
}
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
}
vendor/github.com/gogo/protobuf/proto/pointer_reflect.go
0 → 100644
View file @
8a683270
// 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 purego appengine js
// 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
(
"reflect"
"sync"
)
const
unsafeAllowed
=
false
// A field identifies a field in a struct, accessible from a pointer.
// 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
)
// zeroField is a noop when calling pointer.offset.
var
zeroField
=
field
([]
int
{})
// IsValid reports whether the field identifier is valid.
func
(
f
field
)
IsValid
()
bool
{
return
f
!=
nil
}
// The pointer type is for the table-driven decoder.
// The implementation here uses a reflect.Value of pointer type to
// create a generic pointer. In pointer_unsafe.go we use unsafe
// instead of reflect to implement the same (but faster) interface.
type
pointer
struct
{
v
reflect
.
Value
}
// toPointer converts an interface of pointer type to a pointer
// that points to the same target.
func
toPointer
(
i
*
Message
)
pointer
{
return
pointer
{
v
:
reflect
.
ValueOf
(
*
i
)}
}
// toAddrPointer converts an interface to a pointer that points to
// the interface data.
func
toAddrPointer
(
i
*
interface
{},
isptr
bool
)
pointer
{
v
:=
reflect
.
ValueOf
(
*
i
)
u
:=
reflect
.
New
(
v
.
Type
())
u
.
Elem
()
.
Set
(
v
)
return
pointer
{
v
:
u
}
}
// valToPointer converts v to a pointer. v must be of pointer type.
func
valToPointer
(
v
reflect
.
Value
)
pointer
{
return
pointer
{
v
:
v
}
}
// offset converts from a pointer to a structure to a pointer to
// one of its fields.
func
(
p
pointer
)
offset
(
f
field
)
pointer
{
return
pointer
{
v
:
p
.
v
.
Elem
()
.
FieldByIndex
(
f
)
.
Addr
()}
}
func
(
p
pointer
)
isNil
()
bool
{
return
p
.
v
.
IsNil
()
}
// grow updates the slice s in place to make it one element longer.
// s must be addressable.
// Returns the (addressable) new element.
func
grow
(
s
reflect
.
Value
)
reflect
.
Value
{
n
,
m
:=
s
.
Len
(),
s
.
Cap
()
if
n
<
m
{
s
.
SetLen
(
n
+
1
)
}
else
{
s
.
Set
(
reflect
.
Append
(
s
,
reflect
.
Zero
(
s
.
Type
()
.
Elem
())))
}
return
s
.
Index
(
n
)
}
func
(
p
pointer
)
toInt64
()
*
int64
{
return
p
.
v
.
Interface
()
.
(
*
int64
)
}
func
(
p
pointer
)
toInt64Ptr
()
**
int64
{
return
p
.
v
.
Interface
()
.
(
**
int64
)
}
func
(
p
pointer
)
toInt64Slice
()
*
[]
int64
{
return
p
.
v
.
Interface
()
.
(
*
[]
int64
)
}
var
int32ptr
=
reflect
.
TypeOf
((
*
int32
)(
nil
))
func
(
p
pointer
)
toInt32
()
*
int32
{
return
p
.
v
.
Convert
(
int32ptr
)
.
Interface
()
.
(
*
int32
)
}
// The toInt32Ptr/Slice methods don't work because of enums.
// Instead, we must use set/get methods for the int32ptr/slice case.
/*
func (p pointer) toInt32Ptr() **int32 {
return p.v.Interface().(**int32)
}
func (p pointer) toInt32Slice() *[]int32 {
return p.v.Interface().(*[]int32)
}
*/
func
(
p
pointer
)
getInt32Ptr
()
*
int32
{
if
p
.
v
.
Type
()
.
Elem
()
.
Elem
()
==
reflect
.
TypeOf
(
int32
(
0
))
{
// raw int32 type
return
p
.
v
.
Elem
()
.
Interface
()
.
(
*
int32
)
}
// an enum
return
p
.
v
.
Elem
()
.
Convert
(
int32PtrType
)
.
Interface
()
.
(
*
int32
)
}
func
(
p
pointer
)
setInt32Ptr
(
v
int32
)
{
// Allocate value in a *int32. Possibly convert that to a *enum.
// Then assign it to a **int32 or **enum.
// Note: we can convert *int32 to *enum, but we can't convert
// **int32 to **enum!
p
.
v
.
Elem
()
.
Set
(
reflect
.
ValueOf
(
&
v
)
.
Convert
(
p
.
v
.
Type
()
.
Elem
()))
}
// getInt32Slice copies []int32 from p as a new slice.
// This behavior differs from the implementation in pointer_unsafe.go.
func
(
p
pointer
)
getInt32Slice
()
[]
int32
{
if
p
.
v
.
Type
()
.
Elem
()
.
Elem
()
==
reflect
.
TypeOf
(
int32
(
0
))
{
// raw int32 type
return
p
.
v
.
Elem
()
.
Interface
()
.
([]
int32
)
}
// an enum
// Allocate a []int32, then assign []enum's values into it.
// Note: we can't convert []enum to []int32.
slice
:=
p
.
v
.
Elem
()
s
:=
make
([]
int32
,
slice
.
Len
())
for
i
:=
0
;
i
<
slice
.
Len
();
i
++
{
s
[
i
]
=
int32
(
slice
.
Index
(
i
)
.
Int
())
}
return
s
}
// setInt32Slice copies []int32 into p as a new slice.
// This behavior differs from the implementation in pointer_unsafe.go.
func
(
p
pointer
)
setInt32Slice
(
v
[]
int32
)
{
if
p
.
v
.
Type
()
.
Elem
()
.
Elem
()
==
reflect
.
TypeOf
(
int32
(
0
))
{
// raw int32 type
p
.
v
.
Elem
()
.
Set
(
reflect
.
ValueOf
(
v
))
return
}
// an enum
// Allocate a []enum, then assign []int32's values into it.
// Note: we can't convert []enum to []int32.
slice
:=
reflect
.
MakeSlice
(
p
.
v
.
Type
()
.
Elem
(),
len
(
v
),
cap
(
v
))
for
i
,
x
:=
range
v
{
slice
.
Index
(
i
)
.
SetInt
(
int64
(
x
))
}
p
.
v
.
Elem
()
.
Set
(
slice
)
}
func
(
p
pointer
)
appendInt32Slice
(
v
int32
)
{
grow
(
p
.
v
.
Elem
())
.
SetInt
(
int64
(
v
))
}
func
(
p
pointer
)
toUint64
()
*
uint64
{
return
p
.
v
.
Interface
()
.
(
*
uint64
)
}
func
(
p
pointer
)
toUint64Ptr
()
**
uint64
{
return
p
.
v
.
Interface
()
.
(
**
uint64
)
}
func
(
p
pointer
)
toUint64Slice
()
*
[]
uint64
{
return
p
.
v
.
Interface
()
.
(
*
[]
uint64
)
}
func
(
p
pointer
)
toUint32
()
*
uint32
{
return
p
.
v
.
Interface
()
.
(
*
uint32
)
}
func
(
p
pointer
)
toUint32Ptr
()
**
uint32
{
return
p
.
v
.
Interface
()
.
(
**
uint32
)
}
func
(
p
pointer
)
toUint32Slice
()
*
[]
uint32
{
return
p
.
v
.
Interface
()
.
(
*
[]
uint32
)
}
func
(
p
pointer
)
toBool
()
*
bool
{
return
p
.
v
.
Interface
()
.
(
*
bool
)
}
func
(
p
pointer
)
toBoolPtr
()
**
bool
{
return
p
.
v
.
Interface
()
.
(
**
bool
)
}
func
(
p
pointer
)
toBoolSlice
()
*
[]
bool
{
return
p
.
v
.
Interface
()
.
(
*
[]
bool
)
}
func
(
p
pointer
)
toFloat64
()
*
float64
{
return
p
.
v
.
Interface
()
.
(
*
float64
)
}
func
(
p
pointer
)
toFloat64Ptr
()
**
float64
{
return
p
.
v
.
Interface
()
.
(
**
float64
)
}
func
(
p
pointer
)
toFloat64Slice
()
*
[]
float64
{
return
p
.
v
.
Interface
()
.
(
*
[]
float64
)
}
func
(
p
pointer
)
toFloat32
()
*
float32
{
return
p
.
v
.
Interface
()
.
(
*
float32
)
}
func
(
p
pointer
)
toFloat32Ptr
()
**
float32
{
return
p
.
v
.
Interface
()
.
(
**
float32
)
}
func
(
p
pointer
)
toFloat32Slice
()
*
[]
float32
{
return
p
.
v
.
Interface
()
.
(
*
[]
float32
)
}
func
(
p
pointer
)
toString
()
*
string
{
return
p
.
v
.
Interface
()
.
(
*
string
)
}
func
(
p
pointer
)
toStringPtr
()
**
string
{
return
p
.
v
.
Interface
()
.
(
**
string
)
}
func
(
p
pointer
)
toStringSlice
()
*
[]
string
{
return
p
.
v
.
Interface
()
.
(
*
[]
string
)
}
func
(
p
pointer
)
toBytes
()
*
[]
byte
{
return
p
.
v
.
Interface
()
.
(
*
[]
byte
)
}
func
(
p
pointer
)
toBytesSlice
()
*
[][]
byte
{
return
p
.
v
.
Interface
()
.
(
*
[][]
byte
)
}
func
(
p
pointer
)
toExtensions
()
*
XXX_InternalExtensions
{
return
p
.
v
.
Interface
()
.
(
*
XXX_InternalExtensions
)
}
func
(
p
pointer
)
toOldExtensions
()
*
map
[
int32
]
Extension
{
return
p
.
v
.
Interface
()
.
(
*
map
[
int32
]
Extension
)
}
func
(
p
pointer
)
getPointer
()
pointer
{
return
pointer
{
v
:
p
.
v
.
Elem
()}
}
func
(
p
pointer
)
setPointer
(
q
pointer
)
{
p
.
v
.
Elem
()
.
Set
(
q
.
v
)
}
func
(
p
pointer
)
appendPointer
(
q
pointer
)
{
grow
(
p
.
v
.
Elem
())
.
Set
(
q
.
v
)
}
// getPointerSlice copies []*T from p as a new []pointer.
// This behavior differs from the implementation in pointer_unsafe.go.
func
(
p
pointer
)
getPointerSlice
()
[]
pointer
{
if
p
.
v
.
IsNil
()
{
return
nil
}
n
:=
p
.
v
.
Elem
()
.
Len
()
s
:=
make
([]
pointer
,
n
)
for
i
:=
0
;
i
<
n
;
i
++
{
s
[
i
]
=
pointer
{
v
:
p
.
v
.
Elem
()
.
Index
(
i
)}
}
return
s
}
// setPointerSlice copies []pointer into p as a new []*T.
// This behavior differs from the implementation in pointer_unsafe.go.
func
(
p
pointer
)
setPointerSlice
(
v
[]
pointer
)
{
if
v
==
nil
{
p
.
v
.
Elem
()
.
Set
(
reflect
.
New
(
p
.
v
.
Elem
()
.
Type
())
.
Elem
())
return
}
s
:=
reflect
.
MakeSlice
(
p
.
v
.
Elem
()
.
Type
(),
0
,
len
(
v
))
for
_
,
p
:=
range
v
{
s
=
reflect
.
Append
(
s
,
p
.
v
)
}
p
.
v
.
Elem
()
.
Set
(
s
)
}
// getInterfacePointer returns a pointer that points to the
// interface data of the interface pointed by p.
func
(
p
pointer
)
getInterfacePointer
()
pointer
{
if
p
.
v
.
Elem
()
.
IsNil
()
{
return
pointer
{
v
:
p
.
v
.
Elem
()}
}
return
pointer
{
v
:
p
.
v
.
Elem
()
.
Elem
()
.
Elem
()
.
Field
(
0
)
.
Addr
()}
// *interface -> interface -> *struct -> struct
}
func
(
p
pointer
)
asPointerTo
(
t
reflect
.
Type
)
reflect
.
Value
{
// TODO: check that p.v.Type().Elem() == t?
return
p
.
v
}
func
atomicLoadUnmarshalInfo
(
p
**
unmarshalInfo
)
*
unmarshalInfo
{
atomicLock
.
Lock
()
defer
atomicLock
.
Unlock
()
return
*
p
}
func
atomicStoreUnmarshalInfo
(
p
**
unmarshalInfo
,
v
*
unmarshalInfo
)
{
atomicLock
.
Lock
()
defer
atomicLock
.
Unlock
()
*
p
=
v
}
func
atomicLoadMarshalInfo
(
p
**
marshalInfo
)
*
marshalInfo
{
atomicLock
.
Lock
()
defer
atomicLock
.
Unlock
()
return
*
p
}
func
atomicStoreMarshalInfo
(
p
**
marshalInfo
,
v
*
marshalInfo
)
{
atomicLock
.
Lock
()
defer
atomicLock
.
Unlock
()
*
p
=
v
}
func
atomicLoadMergeInfo
(
p
**
mergeInfo
)
*
mergeInfo
{
atomicLock
.
Lock
()
defer
atomicLock
.
Unlock
()
return
*
p
}
func
atomicStoreMergeInfo
(
p
**
mergeInfo
,
v
*
mergeInfo
)
{
atomicLock
.
Lock
()
defer
atomicLock
.
Unlock
()
*
p
=
v
}
func
atomicLoadDiscardInfo
(
p
**
discardInfo
)
*
discardInfo
{
atomicLock
.
Lock
()
defer
atomicLock
.
Unlock
()
return
*
p
}
func
atomicStoreDiscardInfo
(
p
**
discardInfo
,
v
*
discardInfo
)
{
atomicLock
.
Lock
()
defer
atomicLock
.
Unlock
()
*
p
=
v
}
var
atomicLock
sync
.
Mutex
vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go
0 → 100644
View file @
8a683270
// Protocol Buffers for Go with Gadgets
//
// Copyright (c) 2018, The GoGo Authors. All rights reserved.
// http://github.com/gogo/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.
//
// 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 purego appengine js
// 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
(
"reflect"
)
// TODO: untested, so probably incorrect.
func
(
p
pointer
)
getRef
()
pointer
{
return
pointer
{
v
:
p
.
v
.
Addr
()}
}
func
(
p
pointer
)
appendRef
(
v
pointer
,
typ
reflect
.
Type
)
{
slice
:=
p
.
getSlice
(
typ
)
elem
:=
v
.
asPointerTo
(
typ
)
.
Elem
()
newSlice
:=
reflect
.
Append
(
slice
,
elem
)
slice
.
Set
(
newSlice
)
}
func
(
p
pointer
)
getSlice
(
typ
reflect
.
Type
)
reflect
.
Value
{
sliceTyp
:=
reflect
.
SliceOf
(
typ
)
slice
:=
p
.
asPointerTo
(
sliceTyp
)
slice
=
slice
.
Elem
()
return
slice
}
vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go
0 → 100644
View file @
8a683270
// 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 !purego,!appengine,!js
// This file contains the implementation of the proto field accesses using package unsafe.
package
proto
import
(
"reflect"
"sync/atomic"
"unsafe"
)
const
unsafeAllowed
=
true
// A field identifies a field in a struct, accessible from a pointer.
// 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
)
// zeroField is a noop when calling pointer.offset.
const
zeroField
=
field
(
0
)
// IsValid reports whether the field identifier is valid.
func
(
f
field
)
IsValid
()
bool
{
return
f
!=
invalidField
}
// The pointer type below is for the new table-driven encoder/decoder.
// The implementation here uses unsafe.Pointer to create a generic pointer.
// In pointer_reflect.go we use reflect instead of unsafe to implement
// the same (but slower) interface.
type
pointer
struct
{
p
unsafe
.
Pointer
}
// size of pointer
var
ptrSize
=
unsafe
.
Sizeof
(
uintptr
(
0
))
// toPointer converts an interface of pointer type to a pointer
// that points to the same target.
func
toPointer
(
i
*
Message
)
pointer
{
// Super-tricky - read pointer out of data word of interface value.
// Saves ~25ns over the equivalent:
// return valToPointer(reflect.ValueOf(*i))
return
pointer
{
p
:
(
*
[
2
]
unsafe
.
Pointer
)(
unsafe
.
Pointer
(
i
))[
1
]}
}
// toAddrPointer converts an interface to a pointer that points to
// the interface data.
func
toAddrPointer
(
i
*
interface
{},
isptr
bool
)
pointer
{
// Super-tricky - read or get the address of data word of interface value.
if
isptr
{
// The interface is of pointer type, thus it is a direct interface.
// The data word is the pointer data itself. We take its address.
return
pointer
{
p
:
unsafe
.
Pointer
(
uintptr
(
unsafe
.
Pointer
(
i
))
+
ptrSize
)}
}
// The interface is not of pointer type. The data word is the pointer
// to the data.
return
pointer
{
p
:
(
*
[
2
]
unsafe
.
Pointer
)(
unsafe
.
Pointer
(
i
))[
1
]}
}
// valToPointer converts v to a pointer. v must be of pointer type.
func
valToPointer
(
v
reflect
.
Value
)
pointer
{
return
pointer
{
p
:
unsafe
.
Pointer
(
v
.
Pointer
())}
}
// offset converts from a pointer to a structure to a pointer to
// one of its fields.
func
(
p
pointer
)
offset
(
f
field
)
pointer
{
// For safety, we should panic if !f.IsValid, however calling panic causes
// this to no longer be inlineable, which is a serious performance cost.
/*
if !f.IsValid() {
panic("invalid field")
}
*/
return
pointer
{
p
:
unsafe
.
Pointer
(
uintptr
(
p
.
p
)
+
uintptr
(
f
))}
}
func
(
p
pointer
)
isNil
()
bool
{
return
p
.
p
==
nil
}
func
(
p
pointer
)
toInt64
()
*
int64
{
return
(
*
int64
)(
p
.
p
)
}
func
(
p
pointer
)
toInt64Ptr
()
**
int64
{
return
(
**
int64
)(
p
.
p
)
}
func
(
p
pointer
)
toInt64Slice
()
*
[]
int64
{
return
(
*
[]
int64
)(
p
.
p
)
}
func
(
p
pointer
)
toInt32
()
*
int32
{
return
(
*
int32
)(
p
.
p
)
}
// See pointer_reflect.go for why toInt32Ptr/Slice doesn't exist.
/*
func (p pointer) toInt32Ptr() **int32 {
return (**int32)(p.p)
}
func (p pointer) toInt32Slice() *[]int32 {
return (*[]int32)(p.p)
}
*/
func
(
p
pointer
)
getInt32Ptr
()
*
int32
{
return
*
(
**
int32
)(
p
.
p
)
}
func
(
p
pointer
)
setInt32Ptr
(
v
int32
)
{
*
(
**
int32
)(
p
.
p
)
=
&
v
}
// getInt32Slice loads a []int32 from p.
// The value returned is aliased with the original slice.
// This behavior differs from the implementation in pointer_reflect.go.
func
(
p
pointer
)
getInt32Slice
()
[]
int32
{
return
*
(
*
[]
int32
)(
p
.
p
)
}
// setInt32Slice stores a []int32 to p.
// The value set is aliased with the input slice.
// This behavior differs from the implementation in pointer_reflect.go.
func
(
p
pointer
)
setInt32Slice
(
v
[]
int32
)
{
*
(
*
[]
int32
)(
p
.
p
)
=
v
}
// TODO: Can we get rid of appendInt32Slice and use setInt32Slice instead?
func
(
p
pointer
)
appendInt32Slice
(
v
int32
)
{
s
:=
(
*
[]
int32
)(
p
.
p
)
*
s
=
append
(
*
s
,
v
)
}
func
(
p
pointer
)
toUint64
()
*
uint64
{
return
(
*
uint64
)(
p
.
p
)
}
func
(
p
pointer
)
toUint64Ptr
()
**
uint64
{
return
(
**
uint64
)(
p
.
p
)
}
func
(
p
pointer
)
toUint64Slice
()
*
[]
uint64
{
return
(
*
[]
uint64
)(
p
.
p
)
}
func
(
p
pointer
)
toUint32
()
*
uint32
{
return
(
*
uint32
)(
p
.
p
)
}
func
(
p
pointer
)
toUint32Ptr
()
**
uint32
{
return
(
**
uint32
)(
p
.
p
)
}
func
(
p
pointer
)
toUint32Slice
()
*
[]
uint32
{
return
(
*
[]
uint32
)(
p
.
p
)
}
func
(
p
pointer
)
toBool
()
*
bool
{
return
(
*
bool
)(
p
.
p
)
}
func
(
p
pointer
)
toBoolPtr
()
**
bool
{
return
(
**
bool
)(
p
.
p
)
}
func
(
p
pointer
)
toBoolSlice
()
*
[]
bool
{
return
(
*
[]
bool
)(
p
.
p
)
}
func
(
p
pointer
)
toFloat64
()
*
float64
{
return
(
*
float64
)(
p
.
p
)
}
func
(
p
pointer
)
toFloat64Ptr
()
**
float64
{
return
(
**
float64
)(
p
.
p
)
}
func
(
p
pointer
)
toFloat64Slice
()
*
[]
float64
{
return
(
*
[]
float64
)(
p
.
p
)
}
func
(
p
pointer
)
toFloat32
()
*
float32
{
return
(
*
float32
)(
p
.
p
)
}
func
(
p
pointer
)
toFloat32Ptr
()
**
float32
{
return
(
**
float32
)(
p
.
p
)
}
func
(
p
pointer
)
toFloat32Slice
()
*
[]
float32
{
return
(
*
[]
float32
)(
p
.
p
)
}
func
(
p
pointer
)
toString
()
*
string
{
return
(
*
string
)(
p
.
p
)
}
func
(
p
pointer
)
toStringPtr
()
**
string
{
return
(
**
string
)(
p
.
p
)
}
func
(
p
pointer
)
toStringSlice
()
*
[]
string
{
return
(
*
[]
string
)(
p
.
p
)
}
func
(
p
pointer
)
toBytes
()
*
[]
byte
{
return
(
*
[]
byte
)(
p
.
p
)
}
func
(
p
pointer
)
toBytesSlice
()
*
[][]
byte
{
return
(
*
[][]
byte
)(
p
.
p
)
}
func
(
p
pointer
)
toExtensions
()
*
XXX_InternalExtensions
{
return
(
*
XXX_InternalExtensions
)(
p
.
p
)
}
func
(
p
pointer
)
toOldExtensions
()
*
map
[
int32
]
Extension
{
return
(
*
map
[
int32
]
Extension
)(
p
.
p
)
}
// getPointerSlice loads []*T from p as a []pointer.
// The value returned is aliased with the original slice.
// This behavior differs from the implementation in pointer_reflect.go.
func
(
p
pointer
)
getPointerSlice
()
[]
pointer
{
// Super-tricky - p should point to a []*T where T is a
// message type. We load it as []pointer.
return
*
(
*
[]
pointer
)(
p
.
p
)
}
// setPointerSlice stores []pointer into p as a []*T.
// The value set is aliased with the input slice.
// This behavior differs from the implementation in pointer_reflect.go.
func
(
p
pointer
)
setPointerSlice
(
v
[]
pointer
)
{
// Super-tricky - p should point to a []*T where T is a
// message type. We store it as []pointer.
*
(
*
[]
pointer
)(
p
.
p
)
=
v
}
// getPointer loads the pointer at p and returns it.
func
(
p
pointer
)
getPointer
()
pointer
{
return
pointer
{
p
:
*
(
*
unsafe
.
Pointer
)(
p
.
p
)}
}
// setPointer stores the pointer q at p.
func
(
p
pointer
)
setPointer
(
q
pointer
)
{
*
(
*
unsafe
.
Pointer
)(
p
.
p
)
=
q
.
p
}
// append q to the slice pointed to by p.
func
(
p
pointer
)
appendPointer
(
q
pointer
)
{
s
:=
(
*
[]
unsafe
.
Pointer
)(
p
.
p
)
*
s
=
append
(
*
s
,
q
.
p
)
}
// getInterfacePointer returns a pointer that points to the
// interface data of the interface pointed by p.
func
(
p
pointer
)
getInterfacePointer
()
pointer
{
// Super-tricky - read pointer out of data word of interface value.
return
pointer
{
p
:
(
*
(
*
[
2
]
unsafe
.
Pointer
)(
p
.
p
))[
1
]}
}
// asPointerTo returns a reflect.Value that is a pointer to an
// object of type t stored at p.
func
(
p
pointer
)
asPointerTo
(
t
reflect
.
Type
)
reflect
.
Value
{
return
reflect
.
NewAt
(
t
,
p
.
p
)
}
func
atomicLoadUnmarshalInfo
(
p
**
unmarshalInfo
)
*
unmarshalInfo
{
return
(
*
unmarshalInfo
)(
atomic
.
LoadPointer
((
*
unsafe
.
Pointer
)(
unsafe
.
Pointer
(
p
))))
}
func
atomicStoreUnmarshalInfo
(
p
**
unmarshalInfo
,
v
*
unmarshalInfo
)
{
atomic
.
StorePointer
((
*
unsafe
.
Pointer
)(
unsafe
.
Pointer
(
p
)),
unsafe
.
Pointer
(
v
))
}
func
atomicLoadMarshalInfo
(
p
**
marshalInfo
)
*
marshalInfo
{
return
(
*
marshalInfo
)(
atomic
.
LoadPointer
((
*
unsafe
.
Pointer
)(
unsafe
.
Pointer
(
p
))))
}
func
atomicStoreMarshalInfo
(
p
**
marshalInfo
,
v
*
marshalInfo
)
{
atomic
.
StorePointer
((
*
unsafe
.
Pointer
)(
unsafe
.
Pointer
(
p
)),
unsafe
.
Pointer
(
v
))
}
func
atomicLoadMergeInfo
(
p
**
mergeInfo
)
*
mergeInfo
{
return
(
*
mergeInfo
)(
atomic
.
LoadPointer
((
*
unsafe
.
Pointer
)(
unsafe
.
Pointer
(
p
))))
}
func
atomicStoreMergeInfo
(
p
**
mergeInfo
,
v
*
mergeInfo
)
{
atomic
.
StorePointer
((
*
unsafe
.
Pointer
)(
unsafe
.
Pointer
(
p
)),
unsafe
.
Pointer
(
v
))
}
func
atomicLoadDiscardInfo
(
p
**
discardInfo
)
*
discardInfo
{
return
(
*
discardInfo
)(
atomic
.
LoadPointer
((
*
unsafe
.
Pointer
)(
unsafe
.
Pointer
(
p
))))
}
func
atomicStoreDiscardInfo
(
p
**
discardInfo
,
v
*
discardInfo
)
{
atomic
.
StorePointer
((
*
unsafe
.
Pointer
)(
unsafe
.
Pointer
(
p
)),
unsafe
.
Pointer
(
v
))
}
vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go
0 → 100644
View file @
8a683270
// Protocol Buffers for Go with Gadgets
//
// Copyright (c) 2018, The GoGo Authors. All rights reserved.
// http://github.com/gogo/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.
//
// 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 !purego,!appengine,!js
// This file contains the implementation of the proto field accesses using package unsafe.
package
proto
import
(
"reflect"
"unsafe"
)
func
(
p
pointer
)
getRef
()
pointer
{
return
pointer
{
p
:
(
unsafe
.
Pointer
)(
&
p
.
p
)}
}
func
(
p
pointer
)
appendRef
(
v
pointer
,
typ
reflect
.
Type
)
{
slice
:=
p
.
getSlice
(
typ
)
elem
:=
v
.
asPointerTo
(
typ
)
.
Elem
()
newSlice
:=
reflect
.
Append
(
slice
,
elem
)
slice
.
Set
(
newSlice
)
}
func
(
p
pointer
)
getSlice
(
typ
reflect
.
Type
)
reflect
.
Value
{
sliceTyp
:=
reflect
.
SliceOf
(
typ
)
slice
:=
p
.
asPointerTo
(
sliceTyp
)
slice
=
slice
.
Elem
()
return
slice
}
vendor/github.com/gogo/protobuf/proto/properties.go
0 → 100644
View file @
8a683270
// Protocol Buffers for Go with Gadgets
//
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
// http://github.com/gogo/protobuf
//
// 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"
"log"
"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
)
// 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
// 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)
JSONName
string
// name to use for JSON; determined by protoc
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
oneof
bool
// whether this is a oneof field
Default
string
// default value
HasDefault
bool
// whether an explicit default was provided
CustomType
string
CastType
string
StdTime
bool
StdDuration
bool
WktPointer
bool
stype
reflect
.
Type
// set for struct types only
ctype
reflect
.
Type
// set for custom types only
sprop
*
StructProperties
// set for struct types only
mtype
reflect
.
Type
// set for map types only
MapKeyProp
*
Properties
// set for map types only
MapValProp
*
Properties
// set for map types only
}
// 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"
}
s
+=
",name="
+
p
.
OrigName
if
p
.
JSONName
!=
p
.
OrigName
{
s
+=
",json="
+
p
.
JSONName
}
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
{
log
.
Printf
(
"proto: tag has too few fields: %q"
,
s
)
return
}
p
.
Wire
=
fields
[
0
]
switch
p
.
Wire
{
case
"varint"
:
p
.
WireType
=
WireVarint
case
"fixed32"
:
p
.
WireType
=
WireFixed32
case
"fixed64"
:
p
.
WireType
=
WireFixed64
case
"zigzag32"
:
p
.
WireType
=
WireVarint
case
"zigzag64"
:
p
.
WireType
=
WireVarint
case
"bytes"
,
"group"
:
p
.
WireType
=
WireBytes
// no numeric converter for non-numeric types
default
:
log
.
Printf
(
"proto: tag has unknown wire type: %q"
,
s
)
return
}
var
err
error
p
.
Tag
,
err
=
strconv
.
Atoi
(
fields
[
1
])
if
err
!=
nil
{
return
}
outer
:
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
,
"json="
)
:
p
.
JSONName
=
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
outer
}
case
strings
.
HasPrefix
(
f
,
"embedded="
)
:
p
.
OrigName
=
strings
.
Split
(
f
,
"="
)[
1
]
case
strings
.
HasPrefix
(
f
,
"customtype="
)
:
p
.
CustomType
=
strings
.
Split
(
f
,
"="
)[
1
]
case
strings
.
HasPrefix
(
f
,
"casttype="
)
:
p
.
CastType
=
strings
.
Split
(
f
,
"="
)[
1
]
case
f
==
"stdtime"
:
p
.
StdTime
=
true
case
f
==
"stdduration"
:
p
.
StdDuration
=
true
case
f
==
"wktptr"
:
p
.
WktPointer
=
true
}
}
}
var
protoMessageType
=
reflect
.
TypeOf
((
*
Message
)(
nil
))
.
Elem
()
// setFieldProps initializes the field properties for submessages and maps.
func
(
p
*
Properties
)
setFieldProps
(
typ
reflect
.
Type
,
f
*
reflect
.
StructField
,
lockGetProp
bool
)
{
isMap
:=
typ
.
Kind
()
==
reflect
.
Map
if
len
(
p
.
CustomType
)
>
0
&&
!
isMap
{
p
.
ctype
=
typ
p
.
setTag
(
lockGetProp
)
return
}
if
p
.
StdTime
&&
!
isMap
{
p
.
setTag
(
lockGetProp
)
return
}
if
p
.
StdDuration
&&
!
isMap
{
p
.
setTag
(
lockGetProp
)
return
}
if
p
.
WktPointer
&&
!
isMap
{
p
.
setTag
(
lockGetProp
)
return
}
switch
t1
:=
typ
;
t1
.
Kind
()
{
case
reflect
.
Struct
:
p
.
stype
=
typ
case
reflect
.
Ptr
:
if
t1
.
Elem
()
.
Kind
()
==
reflect
.
Struct
{
p
.
stype
=
t1
.
Elem
()
}
case
reflect
.
Slice
:
switch
t2
:=
t1
.
Elem
();
t2
.
Kind
()
{
case
reflect
.
Ptr
:
switch
t3
:=
t2
.
Elem
();
t3
.
Kind
()
{
case
reflect
.
Struct
:
p
.
stype
=
t3
}
case
reflect
.
Struct
:
p
.
stype
=
t2
}
case
reflect
.
Map
:
p
.
mtype
=
t1
p
.
MapKeyProp
=
&
Properties
{}
p
.
MapKeyProp
.
init
(
reflect
.
PtrTo
(
p
.
mtype
.
Key
()),
"Key"
,
f
.
Tag
.
Get
(
"protobuf_key"
),
nil
,
lockGetProp
)
p
.
MapValProp
=
&
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
.
MapValProp
.
CustomType
=
p
.
CustomType
p
.
MapValProp
.
StdDuration
=
p
.
StdDuration
p
.
MapValProp
.
StdTime
=
p
.
StdTime
p
.
MapValProp
.
WktPointer
=
p
.
WktPointer
p
.
MapValProp
.
init
(
vtype
,
"Value"
,
f
.
Tag
.
Get
(
"protobuf_val"
),
nil
,
lockGetProp
)
}
p
.
setTag
(
lockGetProp
)
}
func
(
p
*
Properties
)
setTag
(
lockGetProp
bool
)
{
if
p
.
stype
!=
nil
{
if
lockGetProp
{
p
.
sprop
=
GetProperties
(
p
.
stype
)
}
else
{
p
.
sprop
=
getPropertiesLocked
(
p
.
stype
)
}
}
}
var
(
marshalerType
=
reflect
.
TypeOf
((
*
Marshaler
)(
nil
))
.
Elem
()
)
// 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
tag
==
""
{
return
}
p
.
Parse
(
tag
)
p
.
setFieldProps
(
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
{
return
sprop
}
propertiesMu
.
Lock
()
sprop
=
getPropertiesLocked
(
t
)
propertiesMu
.
Unlock
()
return
sprop
}
type
(
oneofFuncsIface
interface
{
XXX_OneofFuncs
()
(
func
(
Message
,
*
Buffer
)
error
,
func
(
Message
,
int
,
int
,
*
Buffer
)
(
bool
,
error
),
func
(
Message
)
int
,
[]
interface
{})
}
oneofWrappersIface
interface
{
XXX_OneofWrappers
()
[]
interface
{}
}
)
// getPropertiesLocked requires that propertiesMu is held.
func
getPropertiesLocked
(
t
reflect
.
Type
)
*
StructProperties
{
if
prop
,
ok
:=
propertiesMap
[
t
];
ok
{
return
prop
}
prop
:=
new
(
StructProperties
)
// in case of recursive protos, fill this in now.
propertiesMap
[
t
]
=
prop
// build properties
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
)
oneof
:=
f
.
Tag
.
Get
(
"protobuf_oneof"
)
// special case
if
oneof
!=
""
{
isOneofMessage
=
true
// Oneof fields don't use the traditional protobuf tag.
p
.
OrigName
=
oneof
}
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
"
)
}
}
// Re-order prop.order.
sort
.
Sort
(
prop
)
if
isOneofMessage
{
var
oots
[]
interface
{}
switch
m
:=
reflect
.
Zero
(
reflect
.
PtrTo
(
t
))
.
Interface
()
.
(
type
)
{
case
oneofFuncsIface
:
_
,
_
,
_
,
oots
=
m
.
XXX_OneofFuncs
()
case
oneofWrappersIface
:
oots
=
m
.
XXX_OneofWrappers
()
}
if
len
(
oots
)
>
0
{
// 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
}
// 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
}
// EnumValueMap returns the mapping from names to integers of the
// enum type enumType, or a nil if not found.
func
EnumValueMap
(
enumType
string
)
map
[
string
]
int32
{
return
enumValueMaps
[
enumType
]
}
// A registry of all linked message types.
// The string is a fully-qualified proto name ("pkg.Message").
var
(
protoTypedNils
=
make
(
map
[
string
]
Message
)
// a map from proto names to typed nil pointers
protoMapTypes
=
make
(
map
[
string
]
reflect
.
Type
)
// a map from proto names to map types
revProtoTypes
=
make
(
map
[
reflect
.
Type
]
string
)
)
// RegisterType is called from generated code and maps from the fully qualified
// proto name to the type (pointer to struct) of the protocol buffer.
func
RegisterType
(
x
Message
,
name
string
)
{
if
_
,
ok
:=
protoTypedNils
[
name
];
ok
{
// TODO: Some day, make this a panic.
log
.
Printf
(
"proto: duplicate proto type registered: %s"
,
name
)
return
}
t
:=
reflect
.
TypeOf
(
x
)
if
v
:=
reflect
.
ValueOf
(
x
);
v
.
Kind
()
==
reflect
.
Ptr
&&
v
.
Pointer
()
==
0
{
// Generated code always calls RegisterType with nil x.
// This check is just for extra safety.
protoTypedNils
[
name
]
=
x
}
else
{
protoTypedNils
[
name
]
=
reflect
.
Zero
(
t
)
.
Interface
()
.
(
Message
)
}
revProtoTypes
[
t
]
=
name
}
// RegisterMapType is called from generated code and maps from the fully qualified
// proto name to the native map type of the proto map definition.
func
RegisterMapType
(
x
interface
{},
name
string
)
{
if
reflect
.
TypeOf
(
x
)
.
Kind
()
!=
reflect
.
Map
{
panic
(
fmt
.
Sprintf
(
"RegisterMapType(%T, %q); want map"
,
x
,
name
))
}
if
_
,
ok
:=
protoMapTypes
[
name
];
ok
{
log
.
Printf
(
"proto: duplicate proto type registered: %s"
,
name
)
return
}
t
:=
reflect
.
TypeOf
(
x
)
protoMapTypes
[
name
]
=
t
revProtoTypes
[
t
]
=
name
}
// MessageName returns the fully-qualified proto name for the given message type.
func
MessageName
(
x
Message
)
string
{
type
xname
interface
{
XXX_MessageName
()
string
}
if
m
,
ok
:=
x
.
(
xname
);
ok
{
return
m
.
XXX_MessageName
()
}
return
revProtoTypes
[
reflect
.
TypeOf
(
x
)]
}
// MessageType returns the message type (pointer to struct) for a named message.
// The type is not guaranteed to implement proto.Message if the name refers to a
// map entry.
func
MessageType
(
name
string
)
reflect
.
Type
{
if
t
,
ok
:=
protoTypedNils
[
name
];
ok
{
return
reflect
.
TypeOf
(
t
)
}
return
protoMapTypes
[
name
]
}
// A registry of all linked proto files.
var
(
protoFiles
=
make
(
map
[
string
][]
byte
)
// file name => fileDescriptor
)
// RegisterFile is called from generated code and maps from the
// full file name of a .proto file to its compressed FileDescriptorProto.
func
RegisterFile
(
filename
string
,
fileDescriptor
[]
byte
)
{
protoFiles
[
filename
]
=
fileDescriptor
}
// FileDescriptor returns the compressed FileDescriptorProto for a .proto file.
func
FileDescriptor
(
filename
string
)
[]
byte
{
return
protoFiles
[
filename
]
}
vendor/github.com/gogo/protobuf/proto/properties_gogo.go
0 → 100644
View file @
8a683270
// Protocol Buffers for Go with Gadgets
//
// Copyright (c) 2018, The GoGo Authors. All rights reserved.
// http://github.com/gogo/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.
//
// 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"
)
var
sizerType
=
reflect
.
TypeOf
((
*
Sizer
)(
nil
))
.
Elem
()
var
protosizerType
=
reflect
.
TypeOf
((
*
ProtoSizer
)(
nil
))
.
Elem
()
vendor/github.com/gogo/protobuf/proto/skip_gogo.go
0 → 100644
View file @
8a683270
// Protocol Buffers for Go with Gadgets
//
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
// http://github.com/gogo/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.
//
// 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
(
"fmt"
"io"
)
func
Skip
(
data
[]
byte
)
(
n
int
,
err
error
)
{
l
:=
len
(
data
)
index
:=
0
for
index
<
l
{
var
wire
uint64
for
shift
:=
uint
(
0
);
;
shift
+=
7
{
if
index
>=
l
{
return
0
,
io
.
ErrUnexpectedEOF
}
b
:=
data
[
index
]
index
++
wire
|=
(
uint64
(
b
)
&
0x7F
)
<<
shift
if
b
<
0x80
{
break
}
}
wireType
:=
int
(
wire
&
0x7
)
switch
wireType
{
case
0
:
for
{
if
index
>=
l
{
return
0
,
io
.
ErrUnexpectedEOF
}
index
++
if
data
[
index
-
1
]
<
0x80
{
break
}
}
return
index
,
nil
case
1
:
index
+=
8
return
index
,
nil
case
2
:
var
length
int
for
shift
:=
uint
(
0
);
;
shift
+=
7
{
if
index
>=
l
{
return
0
,
io
.
ErrUnexpectedEOF
}
b
:=
data
[
index
]
index
++
length
|=
(
int
(
b
)
&
0x7F
)
<<
shift
if
b
<
0x80
{
break
}
}
index
+=
length
return
index
,
nil
case
3
:
for
{
var
innerWire
uint64
var
start
int
=
index
for
shift
:=
uint
(
0
);
;
shift
+=
7
{
if
index
>=
l
{
return
0
,
io
.
ErrUnexpectedEOF
}
b
:=
data
[
index
]
index
++
innerWire
|=
(
uint64
(
b
)
&
0x7F
)
<<
shift
if
b
<
0x80
{
break
}
}
innerWireType
:=
int
(
innerWire
&
0x7
)
if
innerWireType
==
4
{
break
}
next
,
err
:=
Skip
(
data
[
start
:
])
if
err
!=
nil
{
return
0
,
err
}
index
=
start
+
next
}
return
index
,
nil
case
4
:
return
index
,
nil
case
5
:
index
+=
4
return
index
,
nil
default
:
return
0
,
fmt
.
Errorf
(
"proto: illegal wireType %d"
,
wireType
)
}
}
panic
(
"unreachable"
)
}
vendor/github.com/gogo/protobuf/proto/table_marshal.go
0 → 100644
View file @
8a683270
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2016 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
(
"errors"
"fmt"
"math"
"reflect"
"sort"
"strconv"
"strings"
"sync"
"sync/atomic"
"unicode/utf8"
)
// a sizer takes a pointer to a field and the size of its tag, computes the size of
// the encoded data.
type
sizer
func
(
pointer
,
int
)
int
// a marshaler takes a byte slice, a pointer to a field, and its tag (in wire format),
// marshals the field to the end of the slice, returns the slice and error (if any).
type
marshaler
func
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
deterministic
bool
)
([]
byte
,
error
)
// marshalInfo is the information used for marshaling a message.
type
marshalInfo
struct
{
typ
reflect
.
Type
fields
[]
*
marshalFieldInfo
unrecognized
field
// offset of XXX_unrecognized
extensions
field
// offset of XXX_InternalExtensions
v1extensions
field
// offset of XXX_extensions
sizecache
field
// offset of XXX_sizecache
initialized
int32
// 0 -- only typ is set, 1 -- fully initialized
messageset
bool
// uses message set wire format
hasmarshaler
bool
// has custom marshaler
sync
.
RWMutex
// protect extElems map, also for initialization
extElems
map
[
int32
]
*
marshalElemInfo
// info of extension elements
hassizer
bool
// has custom sizer
hasprotosizer
bool
// has custom protosizer
bytesExtensions
field
// offset of XXX_extensions where the field type is []byte
}
// marshalFieldInfo is the information used for marshaling a field of a message.
type
marshalFieldInfo
struct
{
field
field
wiretag
uint64
// tag in wire format
tagsize
int
// size of tag in wire format
sizer
sizer
marshaler
marshaler
isPointer
bool
required
bool
// field is required
name
string
// name of the field, for error reporting
oneofElems
map
[
reflect
.
Type
]
*
marshalElemInfo
// info of oneof elements
}
// marshalElemInfo is the information used for marshaling an extension or oneof element.
type
marshalElemInfo
struct
{
wiretag
uint64
// tag in wire format
tagsize
int
// size of tag in wire format
sizer
sizer
marshaler
marshaler
isptr
bool
// elem is pointer typed, thus interface of this type is a direct interface (extension only)
}
var
(
marshalInfoMap
=
map
[
reflect
.
Type
]
*
marshalInfo
{}
marshalInfoLock
sync
.
Mutex
uint8SliceType
=
reflect
.
TypeOf
(([]
uint8
)(
nil
))
.
Kind
()
)
// getMarshalInfo returns the information to marshal a given type of message.
// The info it returns may not necessarily initialized.
// t is the type of the message (NOT the pointer to it).
func
getMarshalInfo
(
t
reflect
.
Type
)
*
marshalInfo
{
marshalInfoLock
.
Lock
()
u
,
ok
:=
marshalInfoMap
[
t
]
if
!
ok
{
u
=
&
marshalInfo
{
typ
:
t
}
marshalInfoMap
[
t
]
=
u
}
marshalInfoLock
.
Unlock
()
return
u
}
// Size is the entry point from generated code,
// and should be ONLY called by generated code.
// It computes the size of encoded data of msg.
// a is a pointer to a place to store cached marshal info.
func
(
a
*
InternalMessageInfo
)
Size
(
msg
Message
)
int
{
u
:=
getMessageMarshalInfo
(
msg
,
a
)
ptr
:=
toPointer
(
&
msg
)
if
ptr
.
isNil
()
{
// We get here if msg is a typed nil ((*SomeMessage)(nil)),
// so it satisfies the interface, and msg == nil wouldn't
// catch it. We don't want crash in this case.
return
0
}
return
u
.
size
(
ptr
)
}
// Marshal is the entry point from generated code,
// and should be ONLY called by generated code.
// It marshals msg to the end of b.
// a is a pointer to a place to store cached marshal info.
func
(
a
*
InternalMessageInfo
)
Marshal
(
b
[]
byte
,
msg
Message
,
deterministic
bool
)
([]
byte
,
error
)
{
u
:=
getMessageMarshalInfo
(
msg
,
a
)
ptr
:=
toPointer
(
&
msg
)
if
ptr
.
isNil
()
{
// We get here if msg is a typed nil ((*SomeMessage)(nil)),
// so it satisfies the interface, and msg == nil wouldn't
// catch it. We don't want crash in this case.
return
b
,
ErrNil
}
return
u
.
marshal
(
b
,
ptr
,
deterministic
)
}
func
getMessageMarshalInfo
(
msg
interface
{},
a
*
InternalMessageInfo
)
*
marshalInfo
{
// u := a.marshal, but atomically.
// We use an atomic here to ensure memory consistency.
u
:=
atomicLoadMarshalInfo
(
&
a
.
marshal
)
if
u
==
nil
{
// Get marshal information from type of message.
t
:=
reflect
.
ValueOf
(
msg
)
.
Type
()
if
t
.
Kind
()
!=
reflect
.
Ptr
{
panic
(
fmt
.
Sprintf
(
"cannot handle non-pointer message type %v"
,
t
))
}
u
=
getMarshalInfo
(
t
.
Elem
())
// Store it in the cache for later users.
// a.marshal = u, but atomically.
atomicStoreMarshalInfo
(
&
a
.
marshal
,
u
)
}
return
u
}
// size is the main function to compute the size of the encoded data of a message.
// ptr is the pointer to the message.
func
(
u
*
marshalInfo
)
size
(
ptr
pointer
)
int
{
if
atomic
.
LoadInt32
(
&
u
.
initialized
)
==
0
{
u
.
computeMarshalInfo
()
}
// If the message can marshal itself, let it do it, for compatibility.
// NOTE: This is not efficient.
if
u
.
hasmarshaler
{
// Uses the message's Size method if available
if
u
.
hassizer
{
s
:=
ptr
.
asPointerTo
(
u
.
typ
)
.
Interface
()
.
(
Sizer
)
return
s
.
Size
()
}
// Uses the message's ProtoSize method if available
if
u
.
hasprotosizer
{
s
:=
ptr
.
asPointerTo
(
u
.
typ
)
.
Interface
()
.
(
ProtoSizer
)
return
s
.
ProtoSize
()
}
m
:=
ptr
.
asPointerTo
(
u
.
typ
)
.
Interface
()
.
(
Marshaler
)
b
,
_
:=
m
.
Marshal
()
return
len
(
b
)
}
n
:=
0
for
_
,
f
:=
range
u
.
fields
{
if
f
.
isPointer
&&
ptr
.
offset
(
f
.
field
)
.
getPointer
()
.
isNil
()
{
// nil pointer always marshals to nothing
continue
}
n
+=
f
.
sizer
(
ptr
.
offset
(
f
.
field
),
f
.
tagsize
)
}
if
u
.
extensions
.
IsValid
()
{
e
:=
ptr
.
offset
(
u
.
extensions
)
.
toExtensions
()
if
u
.
messageset
{
n
+=
u
.
sizeMessageSet
(
e
)
}
else
{
n
+=
u
.
sizeExtensions
(
e
)
}
}
if
u
.
v1extensions
.
IsValid
()
{
m
:=
*
ptr
.
offset
(
u
.
v1extensions
)
.
toOldExtensions
()
n
+=
u
.
sizeV1Extensions
(
m
)
}
if
u
.
bytesExtensions
.
IsValid
()
{
s
:=
*
ptr
.
offset
(
u
.
bytesExtensions
)
.
toBytes
()
n
+=
len
(
s
)
}
if
u
.
unrecognized
.
IsValid
()
{
s
:=
*
ptr
.
offset
(
u
.
unrecognized
)
.
toBytes
()
n
+=
len
(
s
)
}
// cache the result for use in marshal
if
u
.
sizecache
.
IsValid
()
{
atomic
.
StoreInt32
(
ptr
.
offset
(
u
.
sizecache
)
.
toInt32
(),
int32
(
n
))
}
return
n
}
// cachedsize gets the size from cache. If there is no cache (i.e. message is not generated),
// fall back to compute the size.
func
(
u
*
marshalInfo
)
cachedsize
(
ptr
pointer
)
int
{
if
u
.
sizecache
.
IsValid
()
{
return
int
(
atomic
.
LoadInt32
(
ptr
.
offset
(
u
.
sizecache
)
.
toInt32
()))
}
return
u
.
size
(
ptr
)
}
// marshal is the main function to marshal a message. It takes a byte slice and appends
// the encoded data to the end of the slice, returns the slice and error (if any).
// ptr is the pointer to the message.
// If deterministic is true, map is marshaled in deterministic order.
func
(
u
*
marshalInfo
)
marshal
(
b
[]
byte
,
ptr
pointer
,
deterministic
bool
)
([]
byte
,
error
)
{
if
atomic
.
LoadInt32
(
&
u
.
initialized
)
==
0
{
u
.
computeMarshalInfo
()
}
// If the message can marshal itself, let it do it, for compatibility.
// NOTE: This is not efficient.
if
u
.
hasmarshaler
{
m
:=
ptr
.
asPointerTo
(
u
.
typ
)
.
Interface
()
.
(
Marshaler
)
b1
,
err
:=
m
.
Marshal
()
b
=
append
(
b
,
b1
...
)
return
b
,
err
}
var
err
,
errLater
error
// The old marshaler encodes extensions at beginning.
if
u
.
extensions
.
IsValid
()
{
e
:=
ptr
.
offset
(
u
.
extensions
)
.
toExtensions
()
if
u
.
messageset
{
b
,
err
=
u
.
appendMessageSet
(
b
,
e
,
deterministic
)
}
else
{
b
,
err
=
u
.
appendExtensions
(
b
,
e
,
deterministic
)
}
if
err
!=
nil
{
return
b
,
err
}
}
if
u
.
v1extensions
.
IsValid
()
{
m
:=
*
ptr
.
offset
(
u
.
v1extensions
)
.
toOldExtensions
()
b
,
err
=
u
.
appendV1Extensions
(
b
,
m
,
deterministic
)
if
err
!=
nil
{
return
b
,
err
}
}
if
u
.
bytesExtensions
.
IsValid
()
{
s
:=
*
ptr
.
offset
(
u
.
bytesExtensions
)
.
toBytes
()
b
=
append
(
b
,
s
...
)
}
for
_
,
f
:=
range
u
.
fields
{
if
f
.
required
{
if
f
.
isPointer
&&
ptr
.
offset
(
f
.
field
)
.
getPointer
()
.
isNil
()
{
// Required field is not set.
// We record the error but keep going, to give a complete marshaling.
if
errLater
==
nil
{
errLater
=
&
RequiredNotSetError
{
f
.
name
}
}
continue
}
}
if
f
.
isPointer
&&
ptr
.
offset
(
f
.
field
)
.
getPointer
()
.
isNil
()
{
// nil pointer always marshals to nothing
continue
}
b
,
err
=
f
.
marshaler
(
b
,
ptr
.
offset
(
f
.
field
),
f
.
wiretag
,
deterministic
)
if
err
!=
nil
{
if
err1
,
ok
:=
err
.
(
*
RequiredNotSetError
);
ok
{
// Required field in submessage is not set.
// We record the error but keep going, to give a complete marshaling.
if
errLater
==
nil
{
errLater
=
&
RequiredNotSetError
{
f
.
name
+
"."
+
err1
.
field
}
}
continue
}
if
err
==
errRepeatedHasNil
{
err
=
errors
.
New
(
"proto: repeated field "
+
f
.
name
+
" has nil element"
)
}
if
err
==
errInvalidUTF8
{
if
errLater
==
nil
{
fullName
:=
revProtoTypes
[
reflect
.
PtrTo
(
u
.
typ
)]
+
"."
+
f
.
name
errLater
=
&
invalidUTF8Error
{
fullName
}
}
continue
}
return
b
,
err
}
}
if
u
.
unrecognized
.
IsValid
()
{
s
:=
*
ptr
.
offset
(
u
.
unrecognized
)
.
toBytes
()
b
=
append
(
b
,
s
...
)
}
return
b
,
errLater
}
// computeMarshalInfo initializes the marshal info.
func
(
u
*
marshalInfo
)
computeMarshalInfo
()
{
u
.
Lock
()
defer
u
.
Unlock
()
if
u
.
initialized
!=
0
{
// non-atomic read is ok as it is protected by the lock
return
}
t
:=
u
.
typ
u
.
unrecognized
=
invalidField
u
.
extensions
=
invalidField
u
.
v1extensions
=
invalidField
u
.
bytesExtensions
=
invalidField
u
.
sizecache
=
invalidField
isOneofMessage
:=
false
if
reflect
.
PtrTo
(
t
)
.
Implements
(
sizerType
)
{
u
.
hassizer
=
true
}
if
reflect
.
PtrTo
(
t
)
.
Implements
(
protosizerType
)
{
u
.
hasprotosizer
=
true
}
// If the message can marshal itself, let it do it, for compatibility.
// NOTE: This is not efficient.
if
reflect
.
PtrTo
(
t
)
.
Implements
(
marshalerType
)
{
u
.
hasmarshaler
=
true
atomic
.
StoreInt32
(
&
u
.
initialized
,
1
)
return
}
n
:=
t
.
NumField
()
// deal with XXX fields first
for
i
:=
0
;
i
<
t
.
NumField
();
i
++
{
f
:=
t
.
Field
(
i
)
if
f
.
Tag
.
Get
(
"protobuf_oneof"
)
!=
""
{
isOneofMessage
=
true
}
if
!
strings
.
HasPrefix
(
f
.
Name
,
"XXX_"
)
{
continue
}
switch
f
.
Name
{
case
"XXX_sizecache"
:
u
.
sizecache
=
toField
(
&
f
)
case
"XXX_unrecognized"
:
u
.
unrecognized
=
toField
(
&
f
)
case
"XXX_InternalExtensions"
:
u
.
extensions
=
toField
(
&
f
)
u
.
messageset
=
f
.
Tag
.
Get
(
"protobuf_messageset"
)
==
"1"
case
"XXX_extensions"
:
if
f
.
Type
.
Kind
()
==
reflect
.
Map
{
u
.
v1extensions
=
toField
(
&
f
)
}
else
{
u
.
bytesExtensions
=
toField
(
&
f
)
}
case
"XXX_NoUnkeyedLiteral"
:
// nothing to do
default
:
panic
(
"unknown XXX field: "
+
f
.
Name
)
}
n
--
}
// get oneof implementers
var
oneofImplementers
[]
interface
{}
// gogo: isOneofMessage is needed for embedded oneof messages, without a marshaler and unmarshaler
if
isOneofMessage
{
switch
m
:=
reflect
.
Zero
(
reflect
.
PtrTo
(
t
))
.
Interface
()
.
(
type
)
{
case
oneofFuncsIface
:
_
,
_
,
_
,
oneofImplementers
=
m
.
XXX_OneofFuncs
()
case
oneofWrappersIface
:
oneofImplementers
=
m
.
XXX_OneofWrappers
()
}
}
// normal fields
fields
:=
make
([]
marshalFieldInfo
,
n
)
// batch allocation
u
.
fields
=
make
([]
*
marshalFieldInfo
,
0
,
n
)
for
i
,
j
:=
0
,
0
;
i
<
t
.
NumField
();
i
++
{
f
:=
t
.
Field
(
i
)
if
strings
.
HasPrefix
(
f
.
Name
,
"XXX_"
)
{
continue
}
field
:=
&
fields
[
j
]
j
++
field
.
name
=
f
.
Name
u
.
fields
=
append
(
u
.
fields
,
field
)
if
f
.
Tag
.
Get
(
"protobuf_oneof"
)
!=
""
{
field
.
computeOneofFieldInfo
(
&
f
,
oneofImplementers
)
continue
}
if
f
.
Tag
.
Get
(
"protobuf"
)
==
""
{
// field has no tag (not in generated message), ignore it
u
.
fields
=
u
.
fields
[
:
len
(
u
.
fields
)
-
1
]
j
--
continue
}
field
.
computeMarshalFieldInfo
(
&
f
)
}
// fields are marshaled in tag order on the wire.
sort
.
Sort
(
byTag
(
u
.
fields
))
atomic
.
StoreInt32
(
&
u
.
initialized
,
1
)
}
// helper for sorting fields by tag
type
byTag
[]
*
marshalFieldInfo
func
(
a
byTag
)
Len
()
int
{
return
len
(
a
)
}
func
(
a
byTag
)
Swap
(
i
,
j
int
)
{
a
[
i
],
a
[
j
]
=
a
[
j
],
a
[
i
]
}
func
(
a
byTag
)
Less
(
i
,
j
int
)
bool
{
return
a
[
i
]
.
wiretag
<
a
[
j
]
.
wiretag
}
// getExtElemInfo returns the information to marshal an extension element.
// The info it returns is initialized.
func
(
u
*
marshalInfo
)
getExtElemInfo
(
desc
*
ExtensionDesc
)
*
marshalElemInfo
{
// get from cache first
u
.
RLock
()
e
,
ok
:=
u
.
extElems
[
desc
.
Field
]
u
.
RUnlock
()
if
ok
{
return
e
}
t
:=
reflect
.
TypeOf
(
desc
.
ExtensionType
)
// pointer or slice to basic type or struct
tags
:=
strings
.
Split
(
desc
.
Tag
,
","
)
tag
,
err
:=
strconv
.
Atoi
(
tags
[
1
])
if
err
!=
nil
{
panic
(
"tag is not an integer"
)
}
wt
:=
wiretype
(
tags
[
0
])
sizr
,
marshalr
:=
typeMarshaler
(
t
,
tags
,
false
,
false
)
e
=
&
marshalElemInfo
{
wiretag
:
uint64
(
tag
)
<<
3
|
wt
,
tagsize
:
SizeVarint
(
uint64
(
tag
)
<<
3
),
sizer
:
sizr
,
marshaler
:
marshalr
,
isptr
:
t
.
Kind
()
==
reflect
.
Ptr
,
}
// update cache
u
.
Lock
()
if
u
.
extElems
==
nil
{
u
.
extElems
=
make
(
map
[
int32
]
*
marshalElemInfo
)
}
u
.
extElems
[
desc
.
Field
]
=
e
u
.
Unlock
()
return
e
}
// computeMarshalFieldInfo fills up the information to marshal a field.
func
(
fi
*
marshalFieldInfo
)
computeMarshalFieldInfo
(
f
*
reflect
.
StructField
)
{
// parse protobuf tag of the field.
// tag has format of "bytes,49,opt,name=foo,def=hello!"
tags
:=
strings
.
Split
(
f
.
Tag
.
Get
(
"protobuf"
),
","
)
if
tags
[
0
]
==
""
{
return
}
tag
,
err
:=
strconv
.
Atoi
(
tags
[
1
])
if
err
!=
nil
{
panic
(
"tag is not an integer"
)
}
wt
:=
wiretype
(
tags
[
0
])
if
tags
[
2
]
==
"req"
{
fi
.
required
=
true
}
fi
.
setTag
(
f
,
tag
,
wt
)
fi
.
setMarshaler
(
f
,
tags
)
}
func
(
fi
*
marshalFieldInfo
)
computeOneofFieldInfo
(
f
*
reflect
.
StructField
,
oneofImplementers
[]
interface
{})
{
fi
.
field
=
toField
(
f
)
fi
.
wiretag
=
math
.
MaxInt32
// Use a large tag number, make oneofs sorted at the end. This tag will not appear on the wire.
fi
.
isPointer
=
true
fi
.
sizer
,
fi
.
marshaler
=
makeOneOfMarshaler
(
fi
,
f
)
fi
.
oneofElems
=
make
(
map
[
reflect
.
Type
]
*
marshalElemInfo
)
ityp
:=
f
.
Type
// interface type
for
_
,
o
:=
range
oneofImplementers
{
t
:=
reflect
.
TypeOf
(
o
)
if
!
t
.
Implements
(
ityp
)
{
continue
}
sf
:=
t
.
Elem
()
.
Field
(
0
)
// oneof implementer is a struct with a single field
tags
:=
strings
.
Split
(
sf
.
Tag
.
Get
(
"protobuf"
),
","
)
tag
,
err
:=
strconv
.
Atoi
(
tags
[
1
])
if
err
!=
nil
{
panic
(
"tag is not an integer"
)
}
wt
:=
wiretype
(
tags
[
0
])
sizr
,
marshalr
:=
typeMarshaler
(
sf
.
Type
,
tags
,
false
,
true
)
// oneof should not omit any zero value
fi
.
oneofElems
[
t
.
Elem
()]
=
&
marshalElemInfo
{
wiretag
:
uint64
(
tag
)
<<
3
|
wt
,
tagsize
:
SizeVarint
(
uint64
(
tag
)
<<
3
),
sizer
:
sizr
,
marshaler
:
marshalr
,
}
}
}
// wiretype returns the wire encoding of the type.
func
wiretype
(
encoding
string
)
uint64
{
switch
encoding
{
case
"fixed32"
:
return
WireFixed32
case
"fixed64"
:
return
WireFixed64
case
"varint"
,
"zigzag32"
,
"zigzag64"
:
return
WireVarint
case
"bytes"
:
return
WireBytes
case
"group"
:
return
WireStartGroup
}
panic
(
"unknown wire type "
+
encoding
)
}
// setTag fills up the tag (in wire format) and its size in the info of a field.
func
(
fi
*
marshalFieldInfo
)
setTag
(
f
*
reflect
.
StructField
,
tag
int
,
wt
uint64
)
{
fi
.
field
=
toField
(
f
)
fi
.
wiretag
=
uint64
(
tag
)
<<
3
|
wt
fi
.
tagsize
=
SizeVarint
(
uint64
(
tag
)
<<
3
)
}
// setMarshaler fills up the sizer and marshaler in the info of a field.
func
(
fi
*
marshalFieldInfo
)
setMarshaler
(
f
*
reflect
.
StructField
,
tags
[]
string
)
{
switch
f
.
Type
.
Kind
()
{
case
reflect
.
Map
:
// map field
fi
.
isPointer
=
true
fi
.
sizer
,
fi
.
marshaler
=
makeMapMarshaler
(
f
)
return
case
reflect
.
Ptr
,
reflect
.
Slice
:
fi
.
isPointer
=
true
}
fi
.
sizer
,
fi
.
marshaler
=
typeMarshaler
(
f
.
Type
,
tags
,
true
,
false
)
}
// typeMarshaler returns the sizer and marshaler of a given field.
// t is the type of the field.
// tags is the generated "protobuf" tag of the field.
// If nozero is true, zero value is not marshaled to the wire.
// If oneof is true, it is a oneof field.
func
typeMarshaler
(
t
reflect
.
Type
,
tags
[]
string
,
nozero
,
oneof
bool
)
(
sizer
,
marshaler
)
{
encoding
:=
tags
[
0
]
pointer
:=
false
slice
:=
false
if
t
.
Kind
()
==
reflect
.
Slice
&&
t
.
Elem
()
.
Kind
()
!=
reflect
.
Uint8
{
slice
=
true
t
=
t
.
Elem
()
}
if
t
.
Kind
()
==
reflect
.
Ptr
{
pointer
=
true
t
=
t
.
Elem
()
}
packed
:=
false
proto3
:=
false
ctype
:=
false
isTime
:=
false
isDuration
:=
false
isWktPointer
:=
false
validateUTF8
:=
true
for
i
:=
2
;
i
<
len
(
tags
);
i
++
{
if
tags
[
i
]
==
"packed"
{
packed
=
true
}
if
tags
[
i
]
==
"proto3"
{
proto3
=
true
}
if
strings
.
HasPrefix
(
tags
[
i
],
"customtype="
)
{
ctype
=
true
}
if
tags
[
i
]
==
"stdtime"
{
isTime
=
true
}
if
tags
[
i
]
==
"stdduration"
{
isDuration
=
true
}
if
tags
[
i
]
==
"wktptr"
{
isWktPointer
=
true
}
}
validateUTF8
=
validateUTF8
&&
proto3
if
!
proto3
&&
!
pointer
&&
!
slice
{
nozero
=
false
}
if
ctype
{
if
reflect
.
PtrTo
(
t
)
.
Implements
(
customType
)
{
if
slice
{
return
makeMessageRefSliceMarshaler
(
getMarshalInfo
(
t
))
}
if
pointer
{
return
makeCustomPtrMarshaler
(
getMarshalInfo
(
t
))
}
return
makeCustomMarshaler
(
getMarshalInfo
(
t
))
}
else
{
panic
(
fmt
.
Sprintf
(
"custom type: type: %v, does not implement the proto.custom interface"
,
t
))
}
}
if
isTime
{
if
pointer
{
if
slice
{
return
makeTimePtrSliceMarshaler
(
getMarshalInfo
(
t
))
}
return
makeTimePtrMarshaler
(
getMarshalInfo
(
t
))
}
if
slice
{
return
makeTimeSliceMarshaler
(
getMarshalInfo
(
t
))
}
return
makeTimeMarshaler
(
getMarshalInfo
(
t
))
}
if
isDuration
{
if
pointer
{
if
slice
{
return
makeDurationPtrSliceMarshaler
(
getMarshalInfo
(
t
))
}
return
makeDurationPtrMarshaler
(
getMarshalInfo
(
t
))
}
if
slice
{
return
makeDurationSliceMarshaler
(
getMarshalInfo
(
t
))
}
return
makeDurationMarshaler
(
getMarshalInfo
(
t
))
}
if
isWktPointer
{
switch
t
.
Kind
()
{
case
reflect
.
Float64
:
if
pointer
{
if
slice
{
return
makeStdDoubleValuePtrSliceMarshaler
(
getMarshalInfo
(
t
))
}
return
makeStdDoubleValuePtrMarshaler
(
getMarshalInfo
(
t
))
}
if
slice
{
return
makeStdDoubleValueSliceMarshaler
(
getMarshalInfo
(
t
))
}
return
makeStdDoubleValueMarshaler
(
getMarshalInfo
(
t
))
case
reflect
.
Float32
:
if
pointer
{
if
slice
{
return
makeStdFloatValuePtrSliceMarshaler
(
getMarshalInfo
(
t
))
}
return
makeStdFloatValuePtrMarshaler
(
getMarshalInfo
(
t
))
}
if
slice
{
return
makeStdFloatValueSliceMarshaler
(
getMarshalInfo
(
t
))
}
return
makeStdFloatValueMarshaler
(
getMarshalInfo
(
t
))
case
reflect
.
Int64
:
if
pointer
{
if
slice
{
return
makeStdInt64ValuePtrSliceMarshaler
(
getMarshalInfo
(
t
))
}
return
makeStdInt64ValuePtrMarshaler
(
getMarshalInfo
(
t
))
}
if
slice
{
return
makeStdInt64ValueSliceMarshaler
(
getMarshalInfo
(
t
))
}
return
makeStdInt64ValueMarshaler
(
getMarshalInfo
(
t
))
case
reflect
.
Uint64
:
if
pointer
{
if
slice
{
return
makeStdUInt64ValuePtrSliceMarshaler
(
getMarshalInfo
(
t
))
}
return
makeStdUInt64ValuePtrMarshaler
(
getMarshalInfo
(
t
))
}
if
slice
{
return
makeStdUInt64ValueSliceMarshaler
(
getMarshalInfo
(
t
))
}
return
makeStdUInt64ValueMarshaler
(
getMarshalInfo
(
t
))
case
reflect
.
Int32
:
if
pointer
{
if
slice
{
return
makeStdInt32ValuePtrSliceMarshaler
(
getMarshalInfo
(
t
))
}
return
makeStdInt32ValuePtrMarshaler
(
getMarshalInfo
(
t
))
}
if
slice
{
return
makeStdInt32ValueSliceMarshaler
(
getMarshalInfo
(
t
))
}
return
makeStdInt32ValueMarshaler
(
getMarshalInfo
(
t
))
case
reflect
.
Uint32
:
if
pointer
{
if
slice
{
return
makeStdUInt32ValuePtrSliceMarshaler
(
getMarshalInfo
(
t
))
}
return
makeStdUInt32ValuePtrMarshaler
(
getMarshalInfo
(
t
))
}
if
slice
{
return
makeStdUInt32ValueSliceMarshaler
(
getMarshalInfo
(
t
))
}
return
makeStdUInt32ValueMarshaler
(
getMarshalInfo
(
t
))
case
reflect
.
Bool
:
if
pointer
{
if
slice
{
return
makeStdBoolValuePtrSliceMarshaler
(
getMarshalInfo
(
t
))
}
return
makeStdBoolValuePtrMarshaler
(
getMarshalInfo
(
t
))
}
if
slice
{
return
makeStdBoolValueSliceMarshaler
(
getMarshalInfo
(
t
))
}
return
makeStdBoolValueMarshaler
(
getMarshalInfo
(
t
))
case
reflect
.
String
:
if
pointer
{
if
slice
{
return
makeStdStringValuePtrSliceMarshaler
(
getMarshalInfo
(
t
))
}
return
makeStdStringValuePtrMarshaler
(
getMarshalInfo
(
t
))
}
if
slice
{
return
makeStdStringValueSliceMarshaler
(
getMarshalInfo
(
t
))
}
return
makeStdStringValueMarshaler
(
getMarshalInfo
(
t
))
case
uint8SliceType
:
if
pointer
{
if
slice
{
return
makeStdBytesValuePtrSliceMarshaler
(
getMarshalInfo
(
t
))
}
return
makeStdBytesValuePtrMarshaler
(
getMarshalInfo
(
t
))
}
if
slice
{
return
makeStdBytesValueSliceMarshaler
(
getMarshalInfo
(
t
))
}
return
makeStdBytesValueMarshaler
(
getMarshalInfo
(
t
))
default
:
panic
(
fmt
.
Sprintf
(
"unknown wktpointer type %#v"
,
t
))
}
}
switch
t
.
Kind
()
{
case
reflect
.
Bool
:
if
pointer
{
return
sizeBoolPtr
,
appendBoolPtr
}
if
slice
{
if
packed
{
return
sizeBoolPackedSlice
,
appendBoolPackedSlice
}
return
sizeBoolSlice
,
appendBoolSlice
}
if
nozero
{
return
sizeBoolValueNoZero
,
appendBoolValueNoZero
}
return
sizeBoolValue
,
appendBoolValue
case
reflect
.
Uint32
:
switch
encoding
{
case
"fixed32"
:
if
pointer
{
return
sizeFixed32Ptr
,
appendFixed32Ptr
}
if
slice
{
if
packed
{
return
sizeFixed32PackedSlice
,
appendFixed32PackedSlice
}
return
sizeFixed32Slice
,
appendFixed32Slice
}
if
nozero
{
return
sizeFixed32ValueNoZero
,
appendFixed32ValueNoZero
}
return
sizeFixed32Value
,
appendFixed32Value
case
"varint"
:
if
pointer
{
return
sizeVarint32Ptr
,
appendVarint32Ptr
}
if
slice
{
if
packed
{
return
sizeVarint32PackedSlice
,
appendVarint32PackedSlice
}
return
sizeVarint32Slice
,
appendVarint32Slice
}
if
nozero
{
return
sizeVarint32ValueNoZero
,
appendVarint32ValueNoZero
}
return
sizeVarint32Value
,
appendVarint32Value
}
case
reflect
.
Int32
:
switch
encoding
{
case
"fixed32"
:
if
pointer
{
return
sizeFixedS32Ptr
,
appendFixedS32Ptr
}
if
slice
{
if
packed
{
return
sizeFixedS32PackedSlice
,
appendFixedS32PackedSlice
}
return
sizeFixedS32Slice
,
appendFixedS32Slice
}
if
nozero
{
return
sizeFixedS32ValueNoZero
,
appendFixedS32ValueNoZero
}
return
sizeFixedS32Value
,
appendFixedS32Value
case
"varint"
:
if
pointer
{
return
sizeVarintS32Ptr
,
appendVarintS32Ptr
}
if
slice
{
if
packed
{
return
sizeVarintS32PackedSlice
,
appendVarintS32PackedSlice
}
return
sizeVarintS32Slice
,
appendVarintS32Slice
}
if
nozero
{
return
sizeVarintS32ValueNoZero
,
appendVarintS32ValueNoZero
}
return
sizeVarintS32Value
,
appendVarintS32Value
case
"zigzag32"
:
if
pointer
{
return
sizeZigzag32Ptr
,
appendZigzag32Ptr
}
if
slice
{
if
packed
{
return
sizeZigzag32PackedSlice
,
appendZigzag32PackedSlice
}
return
sizeZigzag32Slice
,
appendZigzag32Slice
}
if
nozero
{
return
sizeZigzag32ValueNoZero
,
appendZigzag32ValueNoZero
}
return
sizeZigzag32Value
,
appendZigzag32Value
}
case
reflect
.
Uint64
:
switch
encoding
{
case
"fixed64"
:
if
pointer
{
return
sizeFixed64Ptr
,
appendFixed64Ptr
}
if
slice
{
if
packed
{
return
sizeFixed64PackedSlice
,
appendFixed64PackedSlice
}
return
sizeFixed64Slice
,
appendFixed64Slice
}
if
nozero
{
return
sizeFixed64ValueNoZero
,
appendFixed64ValueNoZero
}
return
sizeFixed64Value
,
appendFixed64Value
case
"varint"
:
if
pointer
{
return
sizeVarint64Ptr
,
appendVarint64Ptr
}
if
slice
{
if
packed
{
return
sizeVarint64PackedSlice
,
appendVarint64PackedSlice
}
return
sizeVarint64Slice
,
appendVarint64Slice
}
if
nozero
{
return
sizeVarint64ValueNoZero
,
appendVarint64ValueNoZero
}
return
sizeVarint64Value
,
appendVarint64Value
}
case
reflect
.
Int64
:
switch
encoding
{
case
"fixed64"
:
if
pointer
{
return
sizeFixedS64Ptr
,
appendFixedS64Ptr
}
if
slice
{
if
packed
{
return
sizeFixedS64PackedSlice
,
appendFixedS64PackedSlice
}
return
sizeFixedS64Slice
,
appendFixedS64Slice
}
if
nozero
{
return
sizeFixedS64ValueNoZero
,
appendFixedS64ValueNoZero
}
return
sizeFixedS64Value
,
appendFixedS64Value
case
"varint"
:
if
pointer
{
return
sizeVarintS64Ptr
,
appendVarintS64Ptr
}
if
slice
{
if
packed
{
return
sizeVarintS64PackedSlice
,
appendVarintS64PackedSlice
}
return
sizeVarintS64Slice
,
appendVarintS64Slice
}
if
nozero
{
return
sizeVarintS64ValueNoZero
,
appendVarintS64ValueNoZero
}
return
sizeVarintS64Value
,
appendVarintS64Value
case
"zigzag64"
:
if
pointer
{
return
sizeZigzag64Ptr
,
appendZigzag64Ptr
}
if
slice
{
if
packed
{
return
sizeZigzag64PackedSlice
,
appendZigzag64PackedSlice
}
return
sizeZigzag64Slice
,
appendZigzag64Slice
}
if
nozero
{
return
sizeZigzag64ValueNoZero
,
appendZigzag64ValueNoZero
}
return
sizeZigzag64Value
,
appendZigzag64Value
}
case
reflect
.
Float32
:
if
pointer
{
return
sizeFloat32Ptr
,
appendFloat32Ptr
}
if
slice
{
if
packed
{
return
sizeFloat32PackedSlice
,
appendFloat32PackedSlice
}
return
sizeFloat32Slice
,
appendFloat32Slice
}
if
nozero
{
return
sizeFloat32ValueNoZero
,
appendFloat32ValueNoZero
}
return
sizeFloat32Value
,
appendFloat32Value
case
reflect
.
Float64
:
if
pointer
{
return
sizeFloat64Ptr
,
appendFloat64Ptr
}
if
slice
{
if
packed
{
return
sizeFloat64PackedSlice
,
appendFloat64PackedSlice
}
return
sizeFloat64Slice
,
appendFloat64Slice
}
if
nozero
{
return
sizeFloat64ValueNoZero
,
appendFloat64ValueNoZero
}
return
sizeFloat64Value
,
appendFloat64Value
case
reflect
.
String
:
if
validateUTF8
{
if
pointer
{
return
sizeStringPtr
,
appendUTF8StringPtr
}
if
slice
{
return
sizeStringSlice
,
appendUTF8StringSlice
}
if
nozero
{
return
sizeStringValueNoZero
,
appendUTF8StringValueNoZero
}
return
sizeStringValue
,
appendUTF8StringValue
}
if
pointer
{
return
sizeStringPtr
,
appendStringPtr
}
if
slice
{
return
sizeStringSlice
,
appendStringSlice
}
if
nozero
{
return
sizeStringValueNoZero
,
appendStringValueNoZero
}
return
sizeStringValue
,
appendStringValue
case
reflect
.
Slice
:
if
slice
{
return
sizeBytesSlice
,
appendBytesSlice
}
if
oneof
{
// Oneof bytes field may also have "proto3" tag.
// We want to marshal it as a oneof field. Do this
// check before the proto3 check.
return
sizeBytesOneof
,
appendBytesOneof
}
if
proto3
{
return
sizeBytes3
,
appendBytes3
}
return
sizeBytes
,
appendBytes
case
reflect
.
Struct
:
switch
encoding
{
case
"group"
:
if
slice
{
return
makeGroupSliceMarshaler
(
getMarshalInfo
(
t
))
}
return
makeGroupMarshaler
(
getMarshalInfo
(
t
))
case
"bytes"
:
if
pointer
{
if
slice
{
return
makeMessageSliceMarshaler
(
getMarshalInfo
(
t
))
}
return
makeMessageMarshaler
(
getMarshalInfo
(
t
))
}
else
{
if
slice
{
return
makeMessageRefSliceMarshaler
(
getMarshalInfo
(
t
))
}
return
makeMessageRefMarshaler
(
getMarshalInfo
(
t
))
}
}
}
panic
(
fmt
.
Sprintf
(
"unknown or mismatched type: type: %v, wire type: %v"
,
t
,
encoding
))
}
// Below are functions to size/marshal a specific type of a field.
// They are stored in the field's info, and called by function pointers.
// They have type sizer or marshaler.
func
sizeFixed32Value
(
_
pointer
,
tagsize
int
)
int
{
return
4
+
tagsize
}
func
sizeFixed32ValueNoZero
(
ptr
pointer
,
tagsize
int
)
int
{
v
:=
*
ptr
.
toUint32
()
if
v
==
0
{
return
0
}
return
4
+
tagsize
}
func
sizeFixed32Ptr
(
ptr
pointer
,
tagsize
int
)
int
{
p
:=
*
ptr
.
toUint32Ptr
()
if
p
==
nil
{
return
0
}
return
4
+
tagsize
}
func
sizeFixed32Slice
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
*
ptr
.
toUint32Slice
()
return
(
4
+
tagsize
)
*
len
(
s
)
}
func
sizeFixed32PackedSlice
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
*
ptr
.
toUint32Slice
()
if
len
(
s
)
==
0
{
return
0
}
return
4
*
len
(
s
)
+
SizeVarint
(
uint64
(
4
*
len
(
s
)))
+
tagsize
}
func
sizeFixedS32Value
(
_
pointer
,
tagsize
int
)
int
{
return
4
+
tagsize
}
func
sizeFixedS32ValueNoZero
(
ptr
pointer
,
tagsize
int
)
int
{
v
:=
*
ptr
.
toInt32
()
if
v
==
0
{
return
0
}
return
4
+
tagsize
}
func
sizeFixedS32Ptr
(
ptr
pointer
,
tagsize
int
)
int
{
p
:=
ptr
.
getInt32Ptr
()
if
p
==
nil
{
return
0
}
return
4
+
tagsize
}
func
sizeFixedS32Slice
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
ptr
.
getInt32Slice
()
return
(
4
+
tagsize
)
*
len
(
s
)
}
func
sizeFixedS32PackedSlice
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
ptr
.
getInt32Slice
()
if
len
(
s
)
==
0
{
return
0
}
return
4
*
len
(
s
)
+
SizeVarint
(
uint64
(
4
*
len
(
s
)))
+
tagsize
}
func
sizeFloat32Value
(
_
pointer
,
tagsize
int
)
int
{
return
4
+
tagsize
}
func
sizeFloat32ValueNoZero
(
ptr
pointer
,
tagsize
int
)
int
{
v
:=
math
.
Float32bits
(
*
ptr
.
toFloat32
())
if
v
==
0
{
return
0
}
return
4
+
tagsize
}
func
sizeFloat32Ptr
(
ptr
pointer
,
tagsize
int
)
int
{
p
:=
*
ptr
.
toFloat32Ptr
()
if
p
==
nil
{
return
0
}
return
4
+
tagsize
}
func
sizeFloat32Slice
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
*
ptr
.
toFloat32Slice
()
return
(
4
+
tagsize
)
*
len
(
s
)
}
func
sizeFloat32PackedSlice
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
*
ptr
.
toFloat32Slice
()
if
len
(
s
)
==
0
{
return
0
}
return
4
*
len
(
s
)
+
SizeVarint
(
uint64
(
4
*
len
(
s
)))
+
tagsize
}
func
sizeFixed64Value
(
_
pointer
,
tagsize
int
)
int
{
return
8
+
tagsize
}
func
sizeFixed64ValueNoZero
(
ptr
pointer
,
tagsize
int
)
int
{
v
:=
*
ptr
.
toUint64
()
if
v
==
0
{
return
0
}
return
8
+
tagsize
}
func
sizeFixed64Ptr
(
ptr
pointer
,
tagsize
int
)
int
{
p
:=
*
ptr
.
toUint64Ptr
()
if
p
==
nil
{
return
0
}
return
8
+
tagsize
}
func
sizeFixed64Slice
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
*
ptr
.
toUint64Slice
()
return
(
8
+
tagsize
)
*
len
(
s
)
}
func
sizeFixed64PackedSlice
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
*
ptr
.
toUint64Slice
()
if
len
(
s
)
==
0
{
return
0
}
return
8
*
len
(
s
)
+
SizeVarint
(
uint64
(
8
*
len
(
s
)))
+
tagsize
}
func
sizeFixedS64Value
(
_
pointer
,
tagsize
int
)
int
{
return
8
+
tagsize
}
func
sizeFixedS64ValueNoZero
(
ptr
pointer
,
tagsize
int
)
int
{
v
:=
*
ptr
.
toInt64
()
if
v
==
0
{
return
0
}
return
8
+
tagsize
}
func
sizeFixedS64Ptr
(
ptr
pointer
,
tagsize
int
)
int
{
p
:=
*
ptr
.
toInt64Ptr
()
if
p
==
nil
{
return
0
}
return
8
+
tagsize
}
func
sizeFixedS64Slice
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
*
ptr
.
toInt64Slice
()
return
(
8
+
tagsize
)
*
len
(
s
)
}
func
sizeFixedS64PackedSlice
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
*
ptr
.
toInt64Slice
()
if
len
(
s
)
==
0
{
return
0
}
return
8
*
len
(
s
)
+
SizeVarint
(
uint64
(
8
*
len
(
s
)))
+
tagsize
}
func
sizeFloat64Value
(
_
pointer
,
tagsize
int
)
int
{
return
8
+
tagsize
}
func
sizeFloat64ValueNoZero
(
ptr
pointer
,
tagsize
int
)
int
{
v
:=
math
.
Float64bits
(
*
ptr
.
toFloat64
())
if
v
==
0
{
return
0
}
return
8
+
tagsize
}
func
sizeFloat64Ptr
(
ptr
pointer
,
tagsize
int
)
int
{
p
:=
*
ptr
.
toFloat64Ptr
()
if
p
==
nil
{
return
0
}
return
8
+
tagsize
}
func
sizeFloat64Slice
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
*
ptr
.
toFloat64Slice
()
return
(
8
+
tagsize
)
*
len
(
s
)
}
func
sizeFloat64PackedSlice
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
*
ptr
.
toFloat64Slice
()
if
len
(
s
)
==
0
{
return
0
}
return
8
*
len
(
s
)
+
SizeVarint
(
uint64
(
8
*
len
(
s
)))
+
tagsize
}
func
sizeVarint32Value
(
ptr
pointer
,
tagsize
int
)
int
{
v
:=
*
ptr
.
toUint32
()
return
SizeVarint
(
uint64
(
v
))
+
tagsize
}
func
sizeVarint32ValueNoZero
(
ptr
pointer
,
tagsize
int
)
int
{
v
:=
*
ptr
.
toUint32
()
if
v
==
0
{
return
0
}
return
SizeVarint
(
uint64
(
v
))
+
tagsize
}
func
sizeVarint32Ptr
(
ptr
pointer
,
tagsize
int
)
int
{
p
:=
*
ptr
.
toUint32Ptr
()
if
p
==
nil
{
return
0
}
return
SizeVarint
(
uint64
(
*
p
))
+
tagsize
}
func
sizeVarint32Slice
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
*
ptr
.
toUint32Slice
()
n
:=
0
for
_
,
v
:=
range
s
{
n
+=
SizeVarint
(
uint64
(
v
))
+
tagsize
}
return
n
}
func
sizeVarint32PackedSlice
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
*
ptr
.
toUint32Slice
()
if
len
(
s
)
==
0
{
return
0
}
n
:=
0
for
_
,
v
:=
range
s
{
n
+=
SizeVarint
(
uint64
(
v
))
}
return
n
+
SizeVarint
(
uint64
(
n
))
+
tagsize
}
func
sizeVarintS32Value
(
ptr
pointer
,
tagsize
int
)
int
{
v
:=
*
ptr
.
toInt32
()
return
SizeVarint
(
uint64
(
v
))
+
tagsize
}
func
sizeVarintS32ValueNoZero
(
ptr
pointer
,
tagsize
int
)
int
{
v
:=
*
ptr
.
toInt32
()
if
v
==
0
{
return
0
}
return
SizeVarint
(
uint64
(
v
))
+
tagsize
}
func
sizeVarintS32Ptr
(
ptr
pointer
,
tagsize
int
)
int
{
p
:=
ptr
.
getInt32Ptr
()
if
p
==
nil
{
return
0
}
return
SizeVarint
(
uint64
(
*
p
))
+
tagsize
}
func
sizeVarintS32Slice
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
ptr
.
getInt32Slice
()
n
:=
0
for
_
,
v
:=
range
s
{
n
+=
SizeVarint
(
uint64
(
v
))
+
tagsize
}
return
n
}
func
sizeVarintS32PackedSlice
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
ptr
.
getInt32Slice
()
if
len
(
s
)
==
0
{
return
0
}
n
:=
0
for
_
,
v
:=
range
s
{
n
+=
SizeVarint
(
uint64
(
v
))
}
return
n
+
SizeVarint
(
uint64
(
n
))
+
tagsize
}
func
sizeVarint64Value
(
ptr
pointer
,
tagsize
int
)
int
{
v
:=
*
ptr
.
toUint64
()
return
SizeVarint
(
v
)
+
tagsize
}
func
sizeVarint64ValueNoZero
(
ptr
pointer
,
tagsize
int
)
int
{
v
:=
*
ptr
.
toUint64
()
if
v
==
0
{
return
0
}
return
SizeVarint
(
v
)
+
tagsize
}
func
sizeVarint64Ptr
(
ptr
pointer
,
tagsize
int
)
int
{
p
:=
*
ptr
.
toUint64Ptr
()
if
p
==
nil
{
return
0
}
return
SizeVarint
(
*
p
)
+
tagsize
}
func
sizeVarint64Slice
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
*
ptr
.
toUint64Slice
()
n
:=
0
for
_
,
v
:=
range
s
{
n
+=
SizeVarint
(
v
)
+
tagsize
}
return
n
}
func
sizeVarint64PackedSlice
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
*
ptr
.
toUint64Slice
()
if
len
(
s
)
==
0
{
return
0
}
n
:=
0
for
_
,
v
:=
range
s
{
n
+=
SizeVarint
(
v
)
}
return
n
+
SizeVarint
(
uint64
(
n
))
+
tagsize
}
func
sizeVarintS64Value
(
ptr
pointer
,
tagsize
int
)
int
{
v
:=
*
ptr
.
toInt64
()
return
SizeVarint
(
uint64
(
v
))
+
tagsize
}
func
sizeVarintS64ValueNoZero
(
ptr
pointer
,
tagsize
int
)
int
{
v
:=
*
ptr
.
toInt64
()
if
v
==
0
{
return
0
}
return
SizeVarint
(
uint64
(
v
))
+
tagsize
}
func
sizeVarintS64Ptr
(
ptr
pointer
,
tagsize
int
)
int
{
p
:=
*
ptr
.
toInt64Ptr
()
if
p
==
nil
{
return
0
}
return
SizeVarint
(
uint64
(
*
p
))
+
tagsize
}
func
sizeVarintS64Slice
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
*
ptr
.
toInt64Slice
()
n
:=
0
for
_
,
v
:=
range
s
{
n
+=
SizeVarint
(
uint64
(
v
))
+
tagsize
}
return
n
}
func
sizeVarintS64PackedSlice
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
*
ptr
.
toInt64Slice
()
if
len
(
s
)
==
0
{
return
0
}
n
:=
0
for
_
,
v
:=
range
s
{
n
+=
SizeVarint
(
uint64
(
v
))
}
return
n
+
SizeVarint
(
uint64
(
n
))
+
tagsize
}
func
sizeZigzag32Value
(
ptr
pointer
,
tagsize
int
)
int
{
v
:=
*
ptr
.
toInt32
()
return
SizeVarint
(
uint64
((
uint32
(
v
)
<<
1
)
^
uint32
((
int32
(
v
)
>>
31
))))
+
tagsize
}
func
sizeZigzag32ValueNoZero
(
ptr
pointer
,
tagsize
int
)
int
{
v
:=
*
ptr
.
toInt32
()
if
v
==
0
{
return
0
}
return
SizeVarint
(
uint64
((
uint32
(
v
)
<<
1
)
^
uint32
((
int32
(
v
)
>>
31
))))
+
tagsize
}
func
sizeZigzag32Ptr
(
ptr
pointer
,
tagsize
int
)
int
{
p
:=
ptr
.
getInt32Ptr
()
if
p
==
nil
{
return
0
}
v
:=
*
p
return
SizeVarint
(
uint64
((
uint32
(
v
)
<<
1
)
^
uint32
((
int32
(
v
)
>>
31
))))
+
tagsize
}
func
sizeZigzag32Slice
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
ptr
.
getInt32Slice
()
n
:=
0
for
_
,
v
:=
range
s
{
n
+=
SizeVarint
(
uint64
((
uint32
(
v
)
<<
1
)
^
uint32
((
int32
(
v
)
>>
31
))))
+
tagsize
}
return
n
}
func
sizeZigzag32PackedSlice
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
ptr
.
getInt32Slice
()
if
len
(
s
)
==
0
{
return
0
}
n
:=
0
for
_
,
v
:=
range
s
{
n
+=
SizeVarint
(
uint64
((
uint32
(
v
)
<<
1
)
^
uint32
((
int32
(
v
)
>>
31
))))
}
return
n
+
SizeVarint
(
uint64
(
n
))
+
tagsize
}
func
sizeZigzag64Value
(
ptr
pointer
,
tagsize
int
)
int
{
v
:=
*
ptr
.
toInt64
()
return
SizeVarint
(
uint64
(
v
<<
1
)
^
uint64
((
int64
(
v
)
>>
63
)))
+
tagsize
}
func
sizeZigzag64ValueNoZero
(
ptr
pointer
,
tagsize
int
)
int
{
v
:=
*
ptr
.
toInt64
()
if
v
==
0
{
return
0
}
return
SizeVarint
(
uint64
(
v
<<
1
)
^
uint64
((
int64
(
v
)
>>
63
)))
+
tagsize
}
func
sizeZigzag64Ptr
(
ptr
pointer
,
tagsize
int
)
int
{
p
:=
*
ptr
.
toInt64Ptr
()
if
p
==
nil
{
return
0
}
v
:=
*
p
return
SizeVarint
(
uint64
(
v
<<
1
)
^
uint64
((
int64
(
v
)
>>
63
)))
+
tagsize
}
func
sizeZigzag64Slice
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
*
ptr
.
toInt64Slice
()
n
:=
0
for
_
,
v
:=
range
s
{
n
+=
SizeVarint
(
uint64
(
v
<<
1
)
^
uint64
((
int64
(
v
)
>>
63
)))
+
tagsize
}
return
n
}
func
sizeZigzag64PackedSlice
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
*
ptr
.
toInt64Slice
()
if
len
(
s
)
==
0
{
return
0
}
n
:=
0
for
_
,
v
:=
range
s
{
n
+=
SizeVarint
(
uint64
(
v
<<
1
)
^
uint64
((
int64
(
v
)
>>
63
)))
}
return
n
+
SizeVarint
(
uint64
(
n
))
+
tagsize
}
func
sizeBoolValue
(
_
pointer
,
tagsize
int
)
int
{
return
1
+
tagsize
}
func
sizeBoolValueNoZero
(
ptr
pointer
,
tagsize
int
)
int
{
v
:=
*
ptr
.
toBool
()
if
!
v
{
return
0
}
return
1
+
tagsize
}
func
sizeBoolPtr
(
ptr
pointer
,
tagsize
int
)
int
{
p
:=
*
ptr
.
toBoolPtr
()
if
p
==
nil
{
return
0
}
return
1
+
tagsize
}
func
sizeBoolSlice
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
*
ptr
.
toBoolSlice
()
return
(
1
+
tagsize
)
*
len
(
s
)
}
func
sizeBoolPackedSlice
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
*
ptr
.
toBoolSlice
()
if
len
(
s
)
==
0
{
return
0
}
return
len
(
s
)
+
SizeVarint
(
uint64
(
len
(
s
)))
+
tagsize
}
func
sizeStringValue
(
ptr
pointer
,
tagsize
int
)
int
{
v
:=
*
ptr
.
toString
()
return
len
(
v
)
+
SizeVarint
(
uint64
(
len
(
v
)))
+
tagsize
}
func
sizeStringValueNoZero
(
ptr
pointer
,
tagsize
int
)
int
{
v
:=
*
ptr
.
toString
()
if
v
==
""
{
return
0
}
return
len
(
v
)
+
SizeVarint
(
uint64
(
len
(
v
)))
+
tagsize
}
func
sizeStringPtr
(
ptr
pointer
,
tagsize
int
)
int
{
p
:=
*
ptr
.
toStringPtr
()
if
p
==
nil
{
return
0
}
v
:=
*
p
return
len
(
v
)
+
SizeVarint
(
uint64
(
len
(
v
)))
+
tagsize
}
func
sizeStringSlice
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
*
ptr
.
toStringSlice
()
n
:=
0
for
_
,
v
:=
range
s
{
n
+=
len
(
v
)
+
SizeVarint
(
uint64
(
len
(
v
)))
+
tagsize
}
return
n
}
func
sizeBytes
(
ptr
pointer
,
tagsize
int
)
int
{
v
:=
*
ptr
.
toBytes
()
if
v
==
nil
{
return
0
}
return
len
(
v
)
+
SizeVarint
(
uint64
(
len
(
v
)))
+
tagsize
}
func
sizeBytes3
(
ptr
pointer
,
tagsize
int
)
int
{
v
:=
*
ptr
.
toBytes
()
if
len
(
v
)
==
0
{
return
0
}
return
len
(
v
)
+
SizeVarint
(
uint64
(
len
(
v
)))
+
tagsize
}
func
sizeBytesOneof
(
ptr
pointer
,
tagsize
int
)
int
{
v
:=
*
ptr
.
toBytes
()
return
len
(
v
)
+
SizeVarint
(
uint64
(
len
(
v
)))
+
tagsize
}
func
sizeBytesSlice
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
*
ptr
.
toBytesSlice
()
n
:=
0
for
_
,
v
:=
range
s
{
n
+=
len
(
v
)
+
SizeVarint
(
uint64
(
len
(
v
)))
+
tagsize
}
return
n
}
// appendFixed32 appends an encoded fixed32 to b.
func
appendFixed32
(
b
[]
byte
,
v
uint32
)
[]
byte
{
b
=
append
(
b
,
byte
(
v
),
byte
(
v
>>
8
),
byte
(
v
>>
16
),
byte
(
v
>>
24
))
return
b
}
// appendFixed64 appends an encoded fixed64 to b.
func
appendFixed64
(
b
[]
byte
,
v
uint64
)
[]
byte
{
b
=
append
(
b
,
byte
(
v
),
byte
(
v
>>
8
),
byte
(
v
>>
16
),
byte
(
v
>>
24
),
byte
(
v
>>
32
),
byte
(
v
>>
40
),
byte
(
v
>>
48
),
byte
(
v
>>
56
))
return
b
}
// appendVarint appends an encoded varint to b.
func
appendVarint
(
b
[]
byte
,
v
uint64
)
[]
byte
{
// TODO: make 1-byte (maybe 2-byte) case inline-able, once we
// have non-leaf inliner.
switch
{
case
v
<
1
<<
7
:
b
=
append
(
b
,
byte
(
v
))
case
v
<
1
<<
14
:
b
=
append
(
b
,
byte
(
v
&
0x7f
|
0x80
),
byte
(
v
>>
7
))
case
v
<
1
<<
21
:
b
=
append
(
b
,
byte
(
v
&
0x7f
|
0x80
),
byte
((
v
>>
7
)
&
0x7f
|
0x80
),
byte
(
v
>>
14
))
case
v
<
1
<<
28
:
b
=
append
(
b
,
byte
(
v
&
0x7f
|
0x80
),
byte
((
v
>>
7
)
&
0x7f
|
0x80
),
byte
((
v
>>
14
)
&
0x7f
|
0x80
),
byte
(
v
>>
21
))
case
v
<
1
<<
35
:
b
=
append
(
b
,
byte
(
v
&
0x7f
|
0x80
),
byte
((
v
>>
7
)
&
0x7f
|
0x80
),
byte
((
v
>>
14
)
&
0x7f
|
0x80
),
byte
((
v
>>
21
)
&
0x7f
|
0x80
),
byte
(
v
>>
28
))
case
v
<
1
<<
42
:
b
=
append
(
b
,
byte
(
v
&
0x7f
|
0x80
),
byte
((
v
>>
7
)
&
0x7f
|
0x80
),
byte
((
v
>>
14
)
&
0x7f
|
0x80
),
byte
((
v
>>
21
)
&
0x7f
|
0x80
),
byte
((
v
>>
28
)
&
0x7f
|
0x80
),
byte
(
v
>>
35
))
case
v
<
1
<<
49
:
b
=
append
(
b
,
byte
(
v
&
0x7f
|
0x80
),
byte
((
v
>>
7
)
&
0x7f
|
0x80
),
byte
((
v
>>
14
)
&
0x7f
|
0x80
),
byte
((
v
>>
21
)
&
0x7f
|
0x80
),
byte
((
v
>>
28
)
&
0x7f
|
0x80
),
byte
((
v
>>
35
)
&
0x7f
|
0x80
),
byte
(
v
>>
42
))
case
v
<
1
<<
56
:
b
=
append
(
b
,
byte
(
v
&
0x7f
|
0x80
),
byte
((
v
>>
7
)
&
0x7f
|
0x80
),
byte
((
v
>>
14
)
&
0x7f
|
0x80
),
byte
((
v
>>
21
)
&
0x7f
|
0x80
),
byte
((
v
>>
28
)
&
0x7f
|
0x80
),
byte
((
v
>>
35
)
&
0x7f
|
0x80
),
byte
((
v
>>
42
)
&
0x7f
|
0x80
),
byte
(
v
>>
49
))
case
v
<
1
<<
63
:
b
=
append
(
b
,
byte
(
v
&
0x7f
|
0x80
),
byte
((
v
>>
7
)
&
0x7f
|
0x80
),
byte
((
v
>>
14
)
&
0x7f
|
0x80
),
byte
((
v
>>
21
)
&
0x7f
|
0x80
),
byte
((
v
>>
28
)
&
0x7f
|
0x80
),
byte
((
v
>>
35
)
&
0x7f
|
0x80
),
byte
((
v
>>
42
)
&
0x7f
|
0x80
),
byte
((
v
>>
49
)
&
0x7f
|
0x80
),
byte
(
v
>>
56
))
default
:
b
=
append
(
b
,
byte
(
v
&
0x7f
|
0x80
),
byte
((
v
>>
7
)
&
0x7f
|
0x80
),
byte
((
v
>>
14
)
&
0x7f
|
0x80
),
byte
((
v
>>
21
)
&
0x7f
|
0x80
),
byte
((
v
>>
28
)
&
0x7f
|
0x80
),
byte
((
v
>>
35
)
&
0x7f
|
0x80
),
byte
((
v
>>
42
)
&
0x7f
|
0x80
),
byte
((
v
>>
49
)
&
0x7f
|
0x80
),
byte
((
v
>>
56
)
&
0x7f
|
0x80
),
1
)
}
return
b
}
func
appendFixed32Value
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
*
ptr
.
toUint32
()
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendFixed32
(
b
,
v
)
return
b
,
nil
}
func
appendFixed32ValueNoZero
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
*
ptr
.
toUint32
()
if
v
==
0
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendFixed32
(
b
,
v
)
return
b
,
nil
}
func
appendFixed32Ptr
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
p
:=
*
ptr
.
toUint32Ptr
()
if
p
==
nil
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendFixed32
(
b
,
*
p
)
return
b
,
nil
}
func
appendFixed32Slice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
s
:=
*
ptr
.
toUint32Slice
()
for
_
,
v
:=
range
s
{
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendFixed32
(
b
,
v
)
}
return
b
,
nil
}
func
appendFixed32PackedSlice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
s
:=
*
ptr
.
toUint32Slice
()
if
len
(
s
)
==
0
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
&^
7
|
WireBytes
)
b
=
appendVarint
(
b
,
uint64
(
4
*
len
(
s
)))
for
_
,
v
:=
range
s
{
b
=
appendFixed32
(
b
,
v
)
}
return
b
,
nil
}
func
appendFixedS32Value
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
*
ptr
.
toInt32
()
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendFixed32
(
b
,
uint32
(
v
))
return
b
,
nil
}
func
appendFixedS32ValueNoZero
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
*
ptr
.
toInt32
()
if
v
==
0
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendFixed32
(
b
,
uint32
(
v
))
return
b
,
nil
}
func
appendFixedS32Ptr
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
p
:=
ptr
.
getInt32Ptr
()
if
p
==
nil
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendFixed32
(
b
,
uint32
(
*
p
))
return
b
,
nil
}
func
appendFixedS32Slice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
s
:=
ptr
.
getInt32Slice
()
for
_
,
v
:=
range
s
{
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendFixed32
(
b
,
uint32
(
v
))
}
return
b
,
nil
}
func
appendFixedS32PackedSlice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
s
:=
ptr
.
getInt32Slice
()
if
len
(
s
)
==
0
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
&^
7
|
WireBytes
)
b
=
appendVarint
(
b
,
uint64
(
4
*
len
(
s
)))
for
_
,
v
:=
range
s
{
b
=
appendFixed32
(
b
,
uint32
(
v
))
}
return
b
,
nil
}
func
appendFloat32Value
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
math
.
Float32bits
(
*
ptr
.
toFloat32
())
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendFixed32
(
b
,
v
)
return
b
,
nil
}
func
appendFloat32ValueNoZero
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
math
.
Float32bits
(
*
ptr
.
toFloat32
())
if
v
==
0
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendFixed32
(
b
,
v
)
return
b
,
nil
}
func
appendFloat32Ptr
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
p
:=
*
ptr
.
toFloat32Ptr
()
if
p
==
nil
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendFixed32
(
b
,
math
.
Float32bits
(
*
p
))
return
b
,
nil
}
func
appendFloat32Slice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
s
:=
*
ptr
.
toFloat32Slice
()
for
_
,
v
:=
range
s
{
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendFixed32
(
b
,
math
.
Float32bits
(
v
))
}
return
b
,
nil
}
func
appendFloat32PackedSlice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
s
:=
*
ptr
.
toFloat32Slice
()
if
len
(
s
)
==
0
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
&^
7
|
WireBytes
)
b
=
appendVarint
(
b
,
uint64
(
4
*
len
(
s
)))
for
_
,
v
:=
range
s
{
b
=
appendFixed32
(
b
,
math
.
Float32bits
(
v
))
}
return
b
,
nil
}
func
appendFixed64Value
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
*
ptr
.
toUint64
()
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendFixed64
(
b
,
v
)
return
b
,
nil
}
func
appendFixed64ValueNoZero
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
*
ptr
.
toUint64
()
if
v
==
0
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendFixed64
(
b
,
v
)
return
b
,
nil
}
func
appendFixed64Ptr
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
p
:=
*
ptr
.
toUint64Ptr
()
if
p
==
nil
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendFixed64
(
b
,
*
p
)
return
b
,
nil
}
func
appendFixed64Slice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
s
:=
*
ptr
.
toUint64Slice
()
for
_
,
v
:=
range
s
{
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendFixed64
(
b
,
v
)
}
return
b
,
nil
}
func
appendFixed64PackedSlice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
s
:=
*
ptr
.
toUint64Slice
()
if
len
(
s
)
==
0
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
&^
7
|
WireBytes
)
b
=
appendVarint
(
b
,
uint64
(
8
*
len
(
s
)))
for
_
,
v
:=
range
s
{
b
=
appendFixed64
(
b
,
v
)
}
return
b
,
nil
}
func
appendFixedS64Value
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
*
ptr
.
toInt64
()
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendFixed64
(
b
,
uint64
(
v
))
return
b
,
nil
}
func
appendFixedS64ValueNoZero
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
*
ptr
.
toInt64
()
if
v
==
0
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendFixed64
(
b
,
uint64
(
v
))
return
b
,
nil
}
func
appendFixedS64Ptr
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
p
:=
*
ptr
.
toInt64Ptr
()
if
p
==
nil
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendFixed64
(
b
,
uint64
(
*
p
))
return
b
,
nil
}
func
appendFixedS64Slice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
s
:=
*
ptr
.
toInt64Slice
()
for
_
,
v
:=
range
s
{
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendFixed64
(
b
,
uint64
(
v
))
}
return
b
,
nil
}
func
appendFixedS64PackedSlice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
s
:=
*
ptr
.
toInt64Slice
()
if
len
(
s
)
==
0
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
&^
7
|
WireBytes
)
b
=
appendVarint
(
b
,
uint64
(
8
*
len
(
s
)))
for
_
,
v
:=
range
s
{
b
=
appendFixed64
(
b
,
uint64
(
v
))
}
return
b
,
nil
}
func
appendFloat64Value
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
math
.
Float64bits
(
*
ptr
.
toFloat64
())
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendFixed64
(
b
,
v
)
return
b
,
nil
}
func
appendFloat64ValueNoZero
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
math
.
Float64bits
(
*
ptr
.
toFloat64
())
if
v
==
0
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendFixed64
(
b
,
v
)
return
b
,
nil
}
func
appendFloat64Ptr
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
p
:=
*
ptr
.
toFloat64Ptr
()
if
p
==
nil
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendFixed64
(
b
,
math
.
Float64bits
(
*
p
))
return
b
,
nil
}
func
appendFloat64Slice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
s
:=
*
ptr
.
toFloat64Slice
()
for
_
,
v
:=
range
s
{
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendFixed64
(
b
,
math
.
Float64bits
(
v
))
}
return
b
,
nil
}
func
appendFloat64PackedSlice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
s
:=
*
ptr
.
toFloat64Slice
()
if
len
(
s
)
==
0
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
&^
7
|
WireBytes
)
b
=
appendVarint
(
b
,
uint64
(
8
*
len
(
s
)))
for
_
,
v
:=
range
s
{
b
=
appendFixed64
(
b
,
math
.
Float64bits
(
v
))
}
return
b
,
nil
}
func
appendVarint32Value
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
*
ptr
.
toUint32
()
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
v
))
return
b
,
nil
}
func
appendVarint32ValueNoZero
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
*
ptr
.
toUint32
()
if
v
==
0
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
v
))
return
b
,
nil
}
func
appendVarint32Ptr
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
p
:=
*
ptr
.
toUint32Ptr
()
if
p
==
nil
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
*
p
))
return
b
,
nil
}
func
appendVarint32Slice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
s
:=
*
ptr
.
toUint32Slice
()
for
_
,
v
:=
range
s
{
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
v
))
}
return
b
,
nil
}
func
appendVarint32PackedSlice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
s
:=
*
ptr
.
toUint32Slice
()
if
len
(
s
)
==
0
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
&^
7
|
WireBytes
)
// compute size
n
:=
0
for
_
,
v
:=
range
s
{
n
+=
SizeVarint
(
uint64
(
v
))
}
b
=
appendVarint
(
b
,
uint64
(
n
))
for
_
,
v
:=
range
s
{
b
=
appendVarint
(
b
,
uint64
(
v
))
}
return
b
,
nil
}
func
appendVarintS32Value
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
*
ptr
.
toInt32
()
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
v
))
return
b
,
nil
}
func
appendVarintS32ValueNoZero
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
*
ptr
.
toInt32
()
if
v
==
0
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
v
))
return
b
,
nil
}
func
appendVarintS32Ptr
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
p
:=
ptr
.
getInt32Ptr
()
if
p
==
nil
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
*
p
))
return
b
,
nil
}
func
appendVarintS32Slice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
s
:=
ptr
.
getInt32Slice
()
for
_
,
v
:=
range
s
{
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
v
))
}
return
b
,
nil
}
func
appendVarintS32PackedSlice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
s
:=
ptr
.
getInt32Slice
()
if
len
(
s
)
==
0
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
&^
7
|
WireBytes
)
// compute size
n
:=
0
for
_
,
v
:=
range
s
{
n
+=
SizeVarint
(
uint64
(
v
))
}
b
=
appendVarint
(
b
,
uint64
(
n
))
for
_
,
v
:=
range
s
{
b
=
appendVarint
(
b
,
uint64
(
v
))
}
return
b
,
nil
}
func
appendVarint64Value
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
*
ptr
.
toUint64
()
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
v
)
return
b
,
nil
}
func
appendVarint64ValueNoZero
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
*
ptr
.
toUint64
()
if
v
==
0
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
v
)
return
b
,
nil
}
func
appendVarint64Ptr
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
p
:=
*
ptr
.
toUint64Ptr
()
if
p
==
nil
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
*
p
)
return
b
,
nil
}
func
appendVarint64Slice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
s
:=
*
ptr
.
toUint64Slice
()
for
_
,
v
:=
range
s
{
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
v
)
}
return
b
,
nil
}
func
appendVarint64PackedSlice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
s
:=
*
ptr
.
toUint64Slice
()
if
len
(
s
)
==
0
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
&^
7
|
WireBytes
)
// compute size
n
:=
0
for
_
,
v
:=
range
s
{
n
+=
SizeVarint
(
v
)
}
b
=
appendVarint
(
b
,
uint64
(
n
))
for
_
,
v
:=
range
s
{
b
=
appendVarint
(
b
,
v
)
}
return
b
,
nil
}
func
appendVarintS64Value
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
*
ptr
.
toInt64
()
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
v
))
return
b
,
nil
}
func
appendVarintS64ValueNoZero
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
*
ptr
.
toInt64
()
if
v
==
0
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
v
))
return
b
,
nil
}
func
appendVarintS64Ptr
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
p
:=
*
ptr
.
toInt64Ptr
()
if
p
==
nil
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
*
p
))
return
b
,
nil
}
func
appendVarintS64Slice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
s
:=
*
ptr
.
toInt64Slice
()
for
_
,
v
:=
range
s
{
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
v
))
}
return
b
,
nil
}
func
appendVarintS64PackedSlice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
s
:=
*
ptr
.
toInt64Slice
()
if
len
(
s
)
==
0
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
&^
7
|
WireBytes
)
// compute size
n
:=
0
for
_
,
v
:=
range
s
{
n
+=
SizeVarint
(
uint64
(
v
))
}
b
=
appendVarint
(
b
,
uint64
(
n
))
for
_
,
v
:=
range
s
{
b
=
appendVarint
(
b
,
uint64
(
v
))
}
return
b
,
nil
}
func
appendZigzag32Value
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
*
ptr
.
toInt32
()
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
((
uint32
(
v
)
<<
1
)
^
uint32
((
int32
(
v
)
>>
31
))))
return
b
,
nil
}
func
appendZigzag32ValueNoZero
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
*
ptr
.
toInt32
()
if
v
==
0
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
((
uint32
(
v
)
<<
1
)
^
uint32
((
int32
(
v
)
>>
31
))))
return
b
,
nil
}
func
appendZigzag32Ptr
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
p
:=
ptr
.
getInt32Ptr
()
if
p
==
nil
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
v
:=
*
p
b
=
appendVarint
(
b
,
uint64
((
uint32
(
v
)
<<
1
)
^
uint32
((
int32
(
v
)
>>
31
))))
return
b
,
nil
}
func
appendZigzag32Slice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
s
:=
ptr
.
getInt32Slice
()
for
_
,
v
:=
range
s
{
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
((
uint32
(
v
)
<<
1
)
^
uint32
((
int32
(
v
)
>>
31
))))
}
return
b
,
nil
}
func
appendZigzag32PackedSlice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
s
:=
ptr
.
getInt32Slice
()
if
len
(
s
)
==
0
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
&^
7
|
WireBytes
)
// compute size
n
:=
0
for
_
,
v
:=
range
s
{
n
+=
SizeVarint
(
uint64
((
uint32
(
v
)
<<
1
)
^
uint32
((
int32
(
v
)
>>
31
))))
}
b
=
appendVarint
(
b
,
uint64
(
n
))
for
_
,
v
:=
range
s
{
b
=
appendVarint
(
b
,
uint64
((
uint32
(
v
)
<<
1
)
^
uint32
((
int32
(
v
)
>>
31
))))
}
return
b
,
nil
}
func
appendZigzag64Value
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
*
ptr
.
toInt64
()
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
v
<<
1
)
^
uint64
((
int64
(
v
)
>>
63
)))
return
b
,
nil
}
func
appendZigzag64ValueNoZero
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
*
ptr
.
toInt64
()
if
v
==
0
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
v
<<
1
)
^
uint64
((
int64
(
v
)
>>
63
)))
return
b
,
nil
}
func
appendZigzag64Ptr
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
p
:=
*
ptr
.
toInt64Ptr
()
if
p
==
nil
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
v
:=
*
p
b
=
appendVarint
(
b
,
uint64
(
v
<<
1
)
^
uint64
((
int64
(
v
)
>>
63
)))
return
b
,
nil
}
func
appendZigzag64Slice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
s
:=
*
ptr
.
toInt64Slice
()
for
_
,
v
:=
range
s
{
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
v
<<
1
)
^
uint64
((
int64
(
v
)
>>
63
)))
}
return
b
,
nil
}
func
appendZigzag64PackedSlice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
s
:=
*
ptr
.
toInt64Slice
()
if
len
(
s
)
==
0
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
&^
7
|
WireBytes
)
// compute size
n
:=
0
for
_
,
v
:=
range
s
{
n
+=
SizeVarint
(
uint64
(
v
<<
1
)
^
uint64
((
int64
(
v
)
>>
63
)))
}
b
=
appendVarint
(
b
,
uint64
(
n
))
for
_
,
v
:=
range
s
{
b
=
appendVarint
(
b
,
uint64
(
v
<<
1
)
^
uint64
((
int64
(
v
)
>>
63
)))
}
return
b
,
nil
}
func
appendBoolValue
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
*
ptr
.
toBool
()
b
=
appendVarint
(
b
,
wiretag
)
if
v
{
b
=
append
(
b
,
1
)
}
else
{
b
=
append
(
b
,
0
)
}
return
b
,
nil
}
func
appendBoolValueNoZero
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
*
ptr
.
toBool
()
if
!
v
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
append
(
b
,
1
)
return
b
,
nil
}
func
appendBoolPtr
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
p
:=
*
ptr
.
toBoolPtr
()
if
p
==
nil
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
if
*
p
{
b
=
append
(
b
,
1
)
}
else
{
b
=
append
(
b
,
0
)
}
return
b
,
nil
}
func
appendBoolSlice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
s
:=
*
ptr
.
toBoolSlice
()
for
_
,
v
:=
range
s
{
b
=
appendVarint
(
b
,
wiretag
)
if
v
{
b
=
append
(
b
,
1
)
}
else
{
b
=
append
(
b
,
0
)
}
}
return
b
,
nil
}
func
appendBoolPackedSlice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
s
:=
*
ptr
.
toBoolSlice
()
if
len
(
s
)
==
0
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
&^
7
|
WireBytes
)
b
=
appendVarint
(
b
,
uint64
(
len
(
s
)))
for
_
,
v
:=
range
s
{
if
v
{
b
=
append
(
b
,
1
)
}
else
{
b
=
append
(
b
,
0
)
}
}
return
b
,
nil
}
func
appendStringValue
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
*
ptr
.
toString
()
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
len
(
v
)))
b
=
append
(
b
,
v
...
)
return
b
,
nil
}
func
appendStringValueNoZero
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
*
ptr
.
toString
()
if
v
==
""
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
len
(
v
)))
b
=
append
(
b
,
v
...
)
return
b
,
nil
}
func
appendStringPtr
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
p
:=
*
ptr
.
toStringPtr
()
if
p
==
nil
{
return
b
,
nil
}
v
:=
*
p
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
len
(
v
)))
b
=
append
(
b
,
v
...
)
return
b
,
nil
}
func
appendStringSlice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
s
:=
*
ptr
.
toStringSlice
()
for
_
,
v
:=
range
s
{
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
len
(
v
)))
b
=
append
(
b
,
v
...
)
}
return
b
,
nil
}
func
appendUTF8StringValue
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
var
invalidUTF8
bool
v
:=
*
ptr
.
toString
()
if
!
utf8
.
ValidString
(
v
)
{
invalidUTF8
=
true
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
len
(
v
)))
b
=
append
(
b
,
v
...
)
if
invalidUTF8
{
return
b
,
errInvalidUTF8
}
return
b
,
nil
}
func
appendUTF8StringValueNoZero
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
var
invalidUTF8
bool
v
:=
*
ptr
.
toString
()
if
v
==
""
{
return
b
,
nil
}
if
!
utf8
.
ValidString
(
v
)
{
invalidUTF8
=
true
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
len
(
v
)))
b
=
append
(
b
,
v
...
)
if
invalidUTF8
{
return
b
,
errInvalidUTF8
}
return
b
,
nil
}
func
appendUTF8StringPtr
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
var
invalidUTF8
bool
p
:=
*
ptr
.
toStringPtr
()
if
p
==
nil
{
return
b
,
nil
}
v
:=
*
p
if
!
utf8
.
ValidString
(
v
)
{
invalidUTF8
=
true
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
len
(
v
)))
b
=
append
(
b
,
v
...
)
if
invalidUTF8
{
return
b
,
errInvalidUTF8
}
return
b
,
nil
}
func
appendUTF8StringSlice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
var
invalidUTF8
bool
s
:=
*
ptr
.
toStringSlice
()
for
_
,
v
:=
range
s
{
if
!
utf8
.
ValidString
(
v
)
{
invalidUTF8
=
true
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
len
(
v
)))
b
=
append
(
b
,
v
...
)
}
if
invalidUTF8
{
return
b
,
errInvalidUTF8
}
return
b
,
nil
}
func
appendBytes
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
*
ptr
.
toBytes
()
if
v
==
nil
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
len
(
v
)))
b
=
append
(
b
,
v
...
)
return
b
,
nil
}
func
appendBytes3
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
*
ptr
.
toBytes
()
if
len
(
v
)
==
0
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
len
(
v
)))
b
=
append
(
b
,
v
...
)
return
b
,
nil
}
func
appendBytesOneof
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
v
:=
*
ptr
.
toBytes
()
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
len
(
v
)))
b
=
append
(
b
,
v
...
)
return
b
,
nil
}
func
appendBytesSlice
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
_
bool
)
([]
byte
,
error
)
{
s
:=
*
ptr
.
toBytesSlice
()
for
_
,
v
:=
range
s
{
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
len
(
v
)))
b
=
append
(
b
,
v
...
)
}
return
b
,
nil
}
// makeGroupMarshaler returns the sizer and marshaler for a group.
// u is the marshal info of the underlying message.
func
makeGroupMarshaler
(
u
*
marshalInfo
)
(
sizer
,
marshaler
)
{
return
func
(
ptr
pointer
,
tagsize
int
)
int
{
p
:=
ptr
.
getPointer
()
if
p
.
isNil
()
{
return
0
}
return
u
.
size
(
p
)
+
2
*
tagsize
},
func
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
deterministic
bool
)
([]
byte
,
error
)
{
p
:=
ptr
.
getPointer
()
if
p
.
isNil
()
{
return
b
,
nil
}
var
err
error
b
=
appendVarint
(
b
,
wiretag
)
// start group
b
,
err
=
u
.
marshal
(
b
,
p
,
deterministic
)
b
=
appendVarint
(
b
,
wiretag
+
(
WireEndGroup
-
WireStartGroup
))
// end group
return
b
,
err
}
}
// makeGroupSliceMarshaler returns the sizer and marshaler for a group slice.
// u is the marshal info of the underlying message.
func
makeGroupSliceMarshaler
(
u
*
marshalInfo
)
(
sizer
,
marshaler
)
{
return
func
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
ptr
.
getPointerSlice
()
n
:=
0
for
_
,
v
:=
range
s
{
if
v
.
isNil
()
{
continue
}
n
+=
u
.
size
(
v
)
+
2
*
tagsize
}
return
n
},
func
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
deterministic
bool
)
([]
byte
,
error
)
{
s
:=
ptr
.
getPointerSlice
()
var
err
error
var
nerr
nonFatal
for
_
,
v
:=
range
s
{
if
v
.
isNil
()
{
return
b
,
errRepeatedHasNil
}
b
=
appendVarint
(
b
,
wiretag
)
// start group
b
,
err
=
u
.
marshal
(
b
,
v
,
deterministic
)
b
=
appendVarint
(
b
,
wiretag
+
(
WireEndGroup
-
WireStartGroup
))
// end group
if
!
nerr
.
Merge
(
err
)
{
if
err
==
ErrNil
{
err
=
errRepeatedHasNil
}
return
b
,
err
}
}
return
b
,
nerr
.
E
}
}
// makeMessageMarshaler returns the sizer and marshaler for a message field.
// u is the marshal info of the message.
func
makeMessageMarshaler
(
u
*
marshalInfo
)
(
sizer
,
marshaler
)
{
return
func
(
ptr
pointer
,
tagsize
int
)
int
{
p
:=
ptr
.
getPointer
()
if
p
.
isNil
()
{
return
0
}
siz
:=
u
.
size
(
p
)
return
siz
+
SizeVarint
(
uint64
(
siz
))
+
tagsize
},
func
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
deterministic
bool
)
([]
byte
,
error
)
{
p
:=
ptr
.
getPointer
()
if
p
.
isNil
()
{
return
b
,
nil
}
b
=
appendVarint
(
b
,
wiretag
)
siz
:=
u
.
cachedsize
(
p
)
b
=
appendVarint
(
b
,
uint64
(
siz
))
return
u
.
marshal
(
b
,
p
,
deterministic
)
}
}
// makeMessageSliceMarshaler returns the sizer and marshaler for a message slice.
// u is the marshal info of the message.
func
makeMessageSliceMarshaler
(
u
*
marshalInfo
)
(
sizer
,
marshaler
)
{
return
func
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
ptr
.
getPointerSlice
()
n
:=
0
for
_
,
v
:=
range
s
{
if
v
.
isNil
()
{
continue
}
siz
:=
u
.
size
(
v
)
n
+=
siz
+
SizeVarint
(
uint64
(
siz
))
+
tagsize
}
return
n
},
func
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
deterministic
bool
)
([]
byte
,
error
)
{
s
:=
ptr
.
getPointerSlice
()
var
err
error
var
nerr
nonFatal
for
_
,
v
:=
range
s
{
if
v
.
isNil
()
{
return
b
,
errRepeatedHasNil
}
b
=
appendVarint
(
b
,
wiretag
)
siz
:=
u
.
cachedsize
(
v
)
b
=
appendVarint
(
b
,
uint64
(
siz
))
b
,
err
=
u
.
marshal
(
b
,
v
,
deterministic
)
if
!
nerr
.
Merge
(
err
)
{
if
err
==
ErrNil
{
err
=
errRepeatedHasNil
}
return
b
,
err
}
}
return
b
,
nerr
.
E
}
}
// makeMapMarshaler returns the sizer and marshaler for a map field.
// f is the pointer to the reflect data structure of the field.
func
makeMapMarshaler
(
f
*
reflect
.
StructField
)
(
sizer
,
marshaler
)
{
// figure out key and value type
t
:=
f
.
Type
keyType
:=
t
.
Key
()
valType
:=
t
.
Elem
()
tags
:=
strings
.
Split
(
f
.
Tag
.
Get
(
"protobuf"
),
","
)
keyTags
:=
strings
.
Split
(
f
.
Tag
.
Get
(
"protobuf_key"
),
","
)
valTags
:=
strings
.
Split
(
f
.
Tag
.
Get
(
"protobuf_val"
),
","
)
stdOptions
:=
false
for
_
,
t
:=
range
tags
{
if
strings
.
HasPrefix
(
t
,
"customtype="
)
{
valTags
=
append
(
valTags
,
t
)
}
if
t
==
"stdtime"
{
valTags
=
append
(
valTags
,
t
)
stdOptions
=
true
}
if
t
==
"stdduration"
{
valTags
=
append
(
valTags
,
t
)
stdOptions
=
true
}
if
t
==
"wktptr"
{
valTags
=
append
(
valTags
,
t
)
}
}
keySizer
,
keyMarshaler
:=
typeMarshaler
(
keyType
,
keyTags
,
false
,
false
)
// don't omit zero value in map
valSizer
,
valMarshaler
:=
typeMarshaler
(
valType
,
valTags
,
false
,
false
)
// don't omit zero value in map
keyWireTag
:=
1
<<
3
|
wiretype
(
keyTags
[
0
])
valWireTag
:=
2
<<
3
|
wiretype
(
valTags
[
0
])
// We create an interface to get the addresses of the map key and value.
// If value is pointer-typed, the interface is a direct interface, the
// idata itself is the value. Otherwise, the idata is the pointer to the
// value.
// Key cannot be pointer-typed.
valIsPtr
:=
valType
.
Kind
()
==
reflect
.
Ptr
// If value is a message with nested maps, calling
// valSizer in marshal may be quadratic. We should use
// cached version in marshal (but not in size).
// If value is not message type, we don't have size cache,
// but it cannot be nested either. Just use valSizer.
valCachedSizer
:=
valSizer
if
valIsPtr
&&
!
stdOptions
&&
valType
.
Elem
()
.
Kind
()
==
reflect
.
Struct
{
u
:=
getMarshalInfo
(
valType
.
Elem
())
valCachedSizer
=
func
(
ptr
pointer
,
tagsize
int
)
int
{
// Same as message sizer, but use cache.
p
:=
ptr
.
getPointer
()
if
p
.
isNil
()
{
return
0
}
siz
:=
u
.
cachedsize
(
p
)
return
siz
+
SizeVarint
(
uint64
(
siz
))
+
tagsize
}
}
return
func
(
ptr
pointer
,
tagsize
int
)
int
{
m
:=
ptr
.
asPointerTo
(
t
)
.
Elem
()
// the map
n
:=
0
for
_
,
k
:=
range
m
.
MapKeys
()
{
ki
:=
k
.
Interface
()
vi
:=
m
.
MapIndex
(
k
)
.
Interface
()
kaddr
:=
toAddrPointer
(
&
ki
,
false
)
// pointer to key
vaddr
:=
toAddrPointer
(
&
vi
,
valIsPtr
)
// pointer to value
siz
:=
keySizer
(
kaddr
,
1
)
+
valSizer
(
vaddr
,
1
)
// tag of key = 1 (size=1), tag of val = 2 (size=1)
n
+=
siz
+
SizeVarint
(
uint64
(
siz
))
+
tagsize
}
return
n
},
func
(
b
[]
byte
,
ptr
pointer
,
tag
uint64
,
deterministic
bool
)
([]
byte
,
error
)
{
m
:=
ptr
.
asPointerTo
(
t
)
.
Elem
()
// the map
var
err
error
keys
:=
m
.
MapKeys
()
if
len
(
keys
)
>
1
&&
deterministic
{
sort
.
Sort
(
mapKeys
(
keys
))
}
var
nerr
nonFatal
for
_
,
k
:=
range
keys
{
ki
:=
k
.
Interface
()
vi
:=
m
.
MapIndex
(
k
)
.
Interface
()
kaddr
:=
toAddrPointer
(
&
ki
,
false
)
// pointer to key
vaddr
:=
toAddrPointer
(
&
vi
,
valIsPtr
)
// pointer to value
b
=
appendVarint
(
b
,
tag
)
siz
:=
keySizer
(
kaddr
,
1
)
+
valCachedSizer
(
vaddr
,
1
)
// tag of key = 1 (size=1), tag of val = 2 (size=1)
b
=
appendVarint
(
b
,
uint64
(
siz
))
b
,
err
=
keyMarshaler
(
b
,
kaddr
,
keyWireTag
,
deterministic
)
if
!
nerr
.
Merge
(
err
)
{
return
b
,
err
}
b
,
err
=
valMarshaler
(
b
,
vaddr
,
valWireTag
,
deterministic
)
if
err
!=
ErrNil
&&
!
nerr
.
Merge
(
err
)
{
// allow nil value in map
return
b
,
err
}
}
return
b
,
nerr
.
E
}
}
// makeOneOfMarshaler returns the sizer and marshaler for a oneof field.
// fi is the marshal info of the field.
// f is the pointer to the reflect data structure of the field.
func
makeOneOfMarshaler
(
fi
*
marshalFieldInfo
,
f
*
reflect
.
StructField
)
(
sizer
,
marshaler
)
{
// Oneof field is an interface. We need to get the actual data type on the fly.
t
:=
f
.
Type
return
func
(
ptr
pointer
,
_
int
)
int
{
p
:=
ptr
.
getInterfacePointer
()
if
p
.
isNil
()
{
return
0
}
v
:=
ptr
.
asPointerTo
(
t
)
.
Elem
()
.
Elem
()
.
Elem
()
// *interface -> interface -> *struct -> struct
telem
:=
v
.
Type
()
e
:=
fi
.
oneofElems
[
telem
]
return
e
.
sizer
(
p
,
e
.
tagsize
)
},
func
(
b
[]
byte
,
ptr
pointer
,
_
uint64
,
deterministic
bool
)
([]
byte
,
error
)
{
p
:=
ptr
.
getInterfacePointer
()
if
p
.
isNil
()
{
return
b
,
nil
}
v
:=
ptr
.
asPointerTo
(
t
)
.
Elem
()
.
Elem
()
.
Elem
()
// *interface -> interface -> *struct -> struct
telem
:=
v
.
Type
()
if
telem
.
Field
(
0
)
.
Type
.
Kind
()
==
reflect
.
Ptr
&&
p
.
getPointer
()
.
isNil
()
{
return
b
,
errOneofHasNil
}
e
:=
fi
.
oneofElems
[
telem
]
return
e
.
marshaler
(
b
,
p
,
e
.
wiretag
,
deterministic
)
}
}
// sizeExtensions computes the size of encoded data for a XXX_InternalExtensions field.
func
(
u
*
marshalInfo
)
sizeExtensions
(
ext
*
XXX_InternalExtensions
)
int
{
m
,
mu
:=
ext
.
extensionsRead
()
if
m
==
nil
{
return
0
}
mu
.
Lock
()
n
:=
0
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.
ei
:=
u
.
getExtElemInfo
(
e
.
desc
)
v
:=
e
.
value
p
:=
toAddrPointer
(
&
v
,
ei
.
isptr
)
n
+=
ei
.
sizer
(
p
,
ei
.
tagsize
)
}
mu
.
Unlock
()
return
n
}
// appendExtensions marshals a XXX_InternalExtensions field to the end of byte slice b.
func
(
u
*
marshalInfo
)
appendExtensions
(
b
[]
byte
,
ext
*
XXX_InternalExtensions
,
deterministic
bool
)
([]
byte
,
error
)
{
m
,
mu
:=
ext
.
extensionsRead
()
if
m
==
nil
{
return
b
,
nil
}
mu
.
Lock
()
defer
mu
.
Unlock
()
var
err
error
var
nerr
nonFatal
// Fast-path for common cases: zero or one extensions.
// Don't bother sorting the keys.
if
len
(
m
)
<=
1
{
for
_
,
e
:=
range
m
{
if
e
.
value
==
nil
||
e
.
desc
==
nil
{
// Extension is only in its encoded form.
b
=
append
(
b
,
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.
ei
:=
u
.
getExtElemInfo
(
e
.
desc
)
v
:=
e
.
value
p
:=
toAddrPointer
(
&
v
,
ei
.
isptr
)
b
,
err
=
ei
.
marshaler
(
b
,
p
,
ei
.
wiretag
,
deterministic
)
if
!
nerr
.
Merge
(
err
)
{
return
b
,
err
}
}
return
b
,
nerr
.
E
}
// Sort the keys to provide a deterministic encoding.
// Not sure this is required, but the old code does it.
keys
:=
make
([]
int
,
0
,
len
(
m
))
for
k
:=
range
m
{
keys
=
append
(
keys
,
int
(
k
))
}
sort
.
Ints
(
keys
)
for
_
,
k
:=
range
keys
{
e
:=
m
[
int32
(
k
)]
if
e
.
value
==
nil
||
e
.
desc
==
nil
{
// Extension is only in its encoded form.
b
=
append
(
b
,
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.
ei
:=
u
.
getExtElemInfo
(
e
.
desc
)
v
:=
e
.
value
p
:=
toAddrPointer
(
&
v
,
ei
.
isptr
)
b
,
err
=
ei
.
marshaler
(
b
,
p
,
ei
.
wiretag
,
deterministic
)
if
!
nerr
.
Merge
(
err
)
{
return
b
,
err
}
}
return
b
,
nerr
.
E
}
// message set format is:
// message MessageSet {
// repeated group Item = 1 {
// required int32 type_id = 2;
// required string message = 3;
// };
// }
// sizeMessageSet computes the size of encoded data for a XXX_InternalExtensions field
// in message set format (above).
func
(
u
*
marshalInfo
)
sizeMessageSet
(
ext
*
XXX_InternalExtensions
)
int
{
m
,
mu
:=
ext
.
extensionsRead
()
if
m
==
nil
{
return
0
}
mu
.
Lock
()
n
:=
0
for
id
,
e
:=
range
m
{
n
+=
2
// start group, end group. tag = 1 (size=1)
n
+=
SizeVarint
(
uint64
(
id
))
+
1
// type_id, tag = 2 (size=1)
if
e
.
value
==
nil
||
e
.
desc
==
nil
{
// Extension is only in its encoded form.
msgWithLen
:=
skipVarint
(
e
.
enc
)
// skip old tag, but leave the length varint
siz
:=
len
(
msgWithLen
)
n
+=
siz
+
1
// message, tag = 3 (size=1)
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.
ei
:=
u
.
getExtElemInfo
(
e
.
desc
)
v
:=
e
.
value
p
:=
toAddrPointer
(
&
v
,
ei
.
isptr
)
n
+=
ei
.
sizer
(
p
,
1
)
// message, tag = 3 (size=1)
}
mu
.
Unlock
()
return
n
}
// appendMessageSet marshals a XXX_InternalExtensions field in message set format (above)
// to the end of byte slice b.
func
(
u
*
marshalInfo
)
appendMessageSet
(
b
[]
byte
,
ext
*
XXX_InternalExtensions
,
deterministic
bool
)
([]
byte
,
error
)
{
m
,
mu
:=
ext
.
extensionsRead
()
if
m
==
nil
{
return
b
,
nil
}
mu
.
Lock
()
defer
mu
.
Unlock
()
var
err
error
var
nerr
nonFatal
// Fast-path for common cases: zero or one extensions.
// Don't bother sorting the keys.
if
len
(
m
)
<=
1
{
for
id
,
e
:=
range
m
{
b
=
append
(
b
,
1
<<
3
|
WireStartGroup
)
b
=
append
(
b
,
2
<<
3
|
WireVarint
)
b
=
appendVarint
(
b
,
uint64
(
id
))
if
e
.
value
==
nil
||
e
.
desc
==
nil
{
// Extension is only in its encoded form.
msgWithLen
:=
skipVarint
(
e
.
enc
)
// skip old tag, but leave the length varint
b
=
append
(
b
,
3
<<
3
|
WireBytes
)
b
=
append
(
b
,
msgWithLen
...
)
b
=
append
(
b
,
1
<<
3
|
WireEndGroup
)
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.
ei
:=
u
.
getExtElemInfo
(
e
.
desc
)
v
:=
e
.
value
p
:=
toAddrPointer
(
&
v
,
ei
.
isptr
)
b
,
err
=
ei
.
marshaler
(
b
,
p
,
3
<<
3
|
WireBytes
,
deterministic
)
if
!
nerr
.
Merge
(
err
)
{
return
b
,
err
}
b
=
append
(
b
,
1
<<
3
|
WireEndGroup
)
}
return
b
,
nerr
.
E
}
// Sort the keys to provide a deterministic encoding.
keys
:=
make
([]
int
,
0
,
len
(
m
))
for
k
:=
range
m
{
keys
=
append
(
keys
,
int
(
k
))
}
sort
.
Ints
(
keys
)
for
_
,
id
:=
range
keys
{
e
:=
m
[
int32
(
id
)]
b
=
append
(
b
,
1
<<
3
|
WireStartGroup
)
b
=
append
(
b
,
2
<<
3
|
WireVarint
)
b
=
appendVarint
(
b
,
uint64
(
id
))
if
e
.
value
==
nil
||
e
.
desc
==
nil
{
// Extension is only in its encoded form.
msgWithLen
:=
skipVarint
(
e
.
enc
)
// skip old tag, but leave the length varint
b
=
append
(
b
,
3
<<
3
|
WireBytes
)
b
=
append
(
b
,
msgWithLen
...
)
b
=
append
(
b
,
1
<<
3
|
WireEndGroup
)
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.
ei
:=
u
.
getExtElemInfo
(
e
.
desc
)
v
:=
e
.
value
p
:=
toAddrPointer
(
&
v
,
ei
.
isptr
)
b
,
err
=
ei
.
marshaler
(
b
,
p
,
3
<<
3
|
WireBytes
,
deterministic
)
b
=
append
(
b
,
1
<<
3
|
WireEndGroup
)
if
!
nerr
.
Merge
(
err
)
{
return
b
,
err
}
}
return
b
,
nerr
.
E
}
// sizeV1Extensions computes the size of encoded data for a V1-API extension field.
func
(
u
*
marshalInfo
)
sizeV1Extensions
(
m
map
[
int32
]
Extension
)
int
{
if
m
==
nil
{
return
0
}
n
:=
0
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.
ei
:=
u
.
getExtElemInfo
(
e
.
desc
)
v
:=
e
.
value
p
:=
toAddrPointer
(
&
v
,
ei
.
isptr
)
n
+=
ei
.
sizer
(
p
,
ei
.
tagsize
)
}
return
n
}
// appendV1Extensions marshals a V1-API extension field to the end of byte slice b.
func
(
u
*
marshalInfo
)
appendV1Extensions
(
b
[]
byte
,
m
map
[
int32
]
Extension
,
deterministic
bool
)
([]
byte
,
error
)
{
if
m
==
nil
{
return
b
,
nil
}
// Sort the keys to provide a deterministic encoding.
keys
:=
make
([]
int
,
0
,
len
(
m
))
for
k
:=
range
m
{
keys
=
append
(
keys
,
int
(
k
))
}
sort
.
Ints
(
keys
)
var
err
error
var
nerr
nonFatal
for
_
,
k
:=
range
keys
{
e
:=
m
[
int32
(
k
)]
if
e
.
value
==
nil
||
e
.
desc
==
nil
{
// Extension is only in its encoded form.
b
=
append
(
b
,
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.
ei
:=
u
.
getExtElemInfo
(
e
.
desc
)
v
:=
e
.
value
p
:=
toAddrPointer
(
&
v
,
ei
.
isptr
)
b
,
err
=
ei
.
marshaler
(
b
,
p
,
ei
.
wiretag
,
deterministic
)
if
!
nerr
.
Merge
(
err
)
{
return
b
,
err
}
}
return
b
,
nerr
.
E
}
// newMarshaler is the interface representing objects that can marshal themselves.
//
// This exists to support protoc-gen-go generated messages.
// The proto package will stop type-asserting to this interface in the future.
//
// DO NOT DEPEND ON THIS.
type
newMarshaler
interface
{
XXX_Size
()
int
XXX_Marshal
(
b
[]
byte
,
deterministic
bool
)
([]
byte
,
error
)
}
// Size returns the encoded size of a protocol buffer message.
// This is the main entry point.
func
Size
(
pb
Message
)
int
{
if
m
,
ok
:=
pb
.
(
newMarshaler
);
ok
{
return
m
.
XXX_Size
()
}
if
m
,
ok
:=
pb
.
(
Marshaler
);
ok
{
// If the message can marshal itself, let it do it, for compatibility.
// NOTE: This is not efficient.
b
,
_
:=
m
.
Marshal
()
return
len
(
b
)
}
// in case somehow we didn't generate the wrapper
if
pb
==
nil
{
return
0
}
var
info
InternalMessageInfo
return
info
.
Size
(
pb
)
}
// Marshal takes a protocol buffer message
// and encodes it into the wire format, returning the data.
// This is the main entry point.
func
Marshal
(
pb
Message
)
([]
byte
,
error
)
{
if
m
,
ok
:=
pb
.
(
newMarshaler
);
ok
{
siz
:=
m
.
XXX_Size
()
b
:=
make
([]
byte
,
0
,
siz
)
return
m
.
XXX_Marshal
(
b
,
false
)
}
if
m
,
ok
:=
pb
.
(
Marshaler
);
ok
{
// If the message can marshal itself, let it do it, for compatibility.
// NOTE: This is not efficient.
return
m
.
Marshal
()
}
// in case somehow we didn't generate the wrapper
if
pb
==
nil
{
return
nil
,
ErrNil
}
var
info
InternalMessageInfo
siz
:=
info
.
Size
(
pb
)
b
:=
make
([]
byte
,
0
,
siz
)
return
info
.
Marshal
(
b
,
pb
,
false
)
}
// Marshal takes a protocol buffer message
// and encodes it into the wire format, writing the result to the
// Buffer.
// This is an alternative entry point. It is not necessary to use
// a Buffer for most applications.
func
(
p
*
Buffer
)
Marshal
(
pb
Message
)
error
{
var
err
error
if
p
.
deterministic
{
if
_
,
ok
:=
pb
.
(
Marshaler
);
ok
{
return
fmt
.
Errorf
(
"proto: deterministic not supported by the Marshal method of %T"
,
pb
)
}
}
if
m
,
ok
:=
pb
.
(
newMarshaler
);
ok
{
siz
:=
m
.
XXX_Size
()
p
.
grow
(
siz
)
// make sure buf has enough capacity
pp
:=
p
.
buf
[
len
(
p
.
buf
)
:
len
(
p
.
buf
)
:
len
(
p
.
buf
)
+
siz
]
pp
,
err
=
m
.
XXX_Marshal
(
pp
,
p
.
deterministic
)
p
.
buf
=
append
(
p
.
buf
,
pp
...
)
return
err
}
if
m
,
ok
:=
pb
.
(
Marshaler
);
ok
{
// If the message can marshal itself, let it do it, for compatibility.
// NOTE: This is not efficient.
var
b
[]
byte
b
,
err
=
m
.
Marshal
()
p
.
buf
=
append
(
p
.
buf
,
b
...
)
return
err
}
// in case somehow we didn't generate the wrapper
if
pb
==
nil
{
return
ErrNil
}
var
info
InternalMessageInfo
siz
:=
info
.
Size
(
pb
)
p
.
grow
(
siz
)
// make sure buf has enough capacity
p
.
buf
,
err
=
info
.
Marshal
(
p
.
buf
,
pb
,
p
.
deterministic
)
return
err
}
// grow grows the buffer's capacity, if necessary, to guarantee space for
// another n bytes. After grow(n), at least n bytes can be written to the
// buffer without another allocation.
func
(
p
*
Buffer
)
grow
(
n
int
)
{
need
:=
len
(
p
.
buf
)
+
n
if
need
<=
cap
(
p
.
buf
)
{
return
}
newCap
:=
len
(
p
.
buf
)
*
2
if
newCap
<
need
{
newCap
=
need
}
p
.
buf
=
append
(
make
([]
byte
,
0
,
newCap
),
p
.
buf
...
)
}
vendor/github.com/gogo/protobuf/proto/table_marshal_gogo.go
0 → 100644
View file @
8a683270
// Protocol Buffers for Go with Gadgets
//
// Copyright (c) 2018, The GoGo Authors. All rights reserved.
// http://github.com/gogo/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.
//
// 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"
"time"
)
// makeMessageRefMarshaler differs a bit from makeMessageMarshaler
// It marshal a message T instead of a *T
func
makeMessageRefMarshaler
(
u
*
marshalInfo
)
(
sizer
,
marshaler
)
{
return
func
(
ptr
pointer
,
tagsize
int
)
int
{
siz
:=
u
.
size
(
ptr
)
return
siz
+
SizeVarint
(
uint64
(
siz
))
+
tagsize
},
func
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
deterministic
bool
)
([]
byte
,
error
)
{
b
=
appendVarint
(
b
,
wiretag
)
siz
:=
u
.
cachedsize
(
ptr
)
b
=
appendVarint
(
b
,
uint64
(
siz
))
return
u
.
marshal
(
b
,
ptr
,
deterministic
)
}
}
// makeMessageRefSliceMarshaler differs quite a lot from makeMessageSliceMarshaler
// It marshals a slice of messages []T instead of []*T
func
makeMessageRefSliceMarshaler
(
u
*
marshalInfo
)
(
sizer
,
marshaler
)
{
return
func
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
ptr
.
getSlice
(
u
.
typ
)
n
:=
0
for
i
:=
0
;
i
<
s
.
Len
();
i
++
{
elem
:=
s
.
Index
(
i
)
e
:=
elem
.
Interface
()
v
:=
toAddrPointer
(
&
e
,
false
)
siz
:=
u
.
size
(
v
)
n
+=
siz
+
SizeVarint
(
uint64
(
siz
))
+
tagsize
}
return
n
},
func
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
deterministic
bool
)
([]
byte
,
error
)
{
s
:=
ptr
.
getSlice
(
u
.
typ
)
var
err
,
errreq
error
for
i
:=
0
;
i
<
s
.
Len
();
i
++
{
elem
:=
s
.
Index
(
i
)
e
:=
elem
.
Interface
()
v
:=
toAddrPointer
(
&
e
,
false
)
b
=
appendVarint
(
b
,
wiretag
)
siz
:=
u
.
size
(
v
)
b
=
appendVarint
(
b
,
uint64
(
siz
))
b
,
err
=
u
.
marshal
(
b
,
v
,
deterministic
)
if
err
!=
nil
{
if
_
,
ok
:=
err
.
(
*
RequiredNotSetError
);
ok
{
// Required field in submessage is not set.
// We record the error but keep going, to give a complete marshaling.
if
errreq
==
nil
{
errreq
=
err
}
continue
}
if
err
==
ErrNil
{
err
=
errRepeatedHasNil
}
return
b
,
err
}
}
return
b
,
errreq
}
}
func
makeCustomPtrMarshaler
(
u
*
marshalInfo
)
(
sizer
,
marshaler
)
{
return
func
(
ptr
pointer
,
tagsize
int
)
int
{
if
ptr
.
isNil
()
{
return
0
}
m
:=
ptr
.
asPointerTo
(
reflect
.
PtrTo
(
u
.
typ
))
.
Elem
()
.
Interface
()
.
(
custom
)
siz
:=
m
.
Size
()
return
tagsize
+
SizeVarint
(
uint64
(
siz
))
+
siz
},
func
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
deterministic
bool
)
([]
byte
,
error
)
{
if
ptr
.
isNil
()
{
return
b
,
nil
}
m
:=
ptr
.
asPointerTo
(
reflect
.
PtrTo
(
u
.
typ
))
.
Elem
()
.
Interface
()
.
(
custom
)
siz
:=
m
.
Size
()
buf
,
err
:=
m
.
Marshal
()
if
err
!=
nil
{
return
nil
,
err
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
siz
))
b
=
append
(
b
,
buf
...
)
return
b
,
nil
}
}
func
makeCustomMarshaler
(
u
*
marshalInfo
)
(
sizer
,
marshaler
)
{
return
func
(
ptr
pointer
,
tagsize
int
)
int
{
m
:=
ptr
.
asPointerTo
(
u
.
typ
)
.
Interface
()
.
(
custom
)
siz
:=
m
.
Size
()
return
tagsize
+
SizeVarint
(
uint64
(
siz
))
+
siz
},
func
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
deterministic
bool
)
([]
byte
,
error
)
{
m
:=
ptr
.
asPointerTo
(
u
.
typ
)
.
Interface
()
.
(
custom
)
siz
:=
m
.
Size
()
buf
,
err
:=
m
.
Marshal
()
if
err
!=
nil
{
return
nil
,
err
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
siz
))
b
=
append
(
b
,
buf
...
)
return
b
,
nil
}
}
func
makeTimeMarshaler
(
u
*
marshalInfo
)
(
sizer
,
marshaler
)
{
return
func
(
ptr
pointer
,
tagsize
int
)
int
{
t
:=
ptr
.
asPointerTo
(
u
.
typ
)
.
Interface
()
.
(
*
time
.
Time
)
ts
,
err
:=
timestampProto
(
*
t
)
if
err
!=
nil
{
return
0
}
siz
:=
Size
(
ts
)
return
tagsize
+
SizeVarint
(
uint64
(
siz
))
+
siz
},
func
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
deterministic
bool
)
([]
byte
,
error
)
{
t
:=
ptr
.
asPointerTo
(
u
.
typ
)
.
Interface
()
.
(
*
time
.
Time
)
ts
,
err
:=
timestampProto
(
*
t
)
if
err
!=
nil
{
return
nil
,
err
}
buf
,
err
:=
Marshal
(
ts
)
if
err
!=
nil
{
return
nil
,
err
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
len
(
buf
)))
b
=
append
(
b
,
buf
...
)
return
b
,
nil
}
}
func
makeTimePtrMarshaler
(
u
*
marshalInfo
)
(
sizer
,
marshaler
)
{
return
func
(
ptr
pointer
,
tagsize
int
)
int
{
if
ptr
.
isNil
()
{
return
0
}
t
:=
ptr
.
asPointerTo
(
reflect
.
PtrTo
(
u
.
typ
))
.
Elem
()
.
Interface
()
.
(
*
time
.
Time
)
ts
,
err
:=
timestampProto
(
*
t
)
if
err
!=
nil
{
return
0
}
siz
:=
Size
(
ts
)
return
tagsize
+
SizeVarint
(
uint64
(
siz
))
+
siz
},
func
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
deterministic
bool
)
([]
byte
,
error
)
{
if
ptr
.
isNil
()
{
return
b
,
nil
}
t
:=
ptr
.
asPointerTo
(
reflect
.
PtrTo
(
u
.
typ
))
.
Elem
()
.
Interface
()
.
(
*
time
.
Time
)
ts
,
err
:=
timestampProto
(
*
t
)
if
err
!=
nil
{
return
nil
,
err
}
buf
,
err
:=
Marshal
(
ts
)
if
err
!=
nil
{
return
nil
,
err
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
len
(
buf
)))
b
=
append
(
b
,
buf
...
)
return
b
,
nil
}
}
func
makeTimeSliceMarshaler
(
u
*
marshalInfo
)
(
sizer
,
marshaler
)
{
return
func
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
ptr
.
getSlice
(
u
.
typ
)
n
:=
0
for
i
:=
0
;
i
<
s
.
Len
();
i
++
{
elem
:=
s
.
Index
(
i
)
t
:=
elem
.
Interface
()
.
(
time
.
Time
)
ts
,
err
:=
timestampProto
(
t
)
if
err
!=
nil
{
return
0
}
siz
:=
Size
(
ts
)
n
+=
siz
+
SizeVarint
(
uint64
(
siz
))
+
tagsize
}
return
n
},
func
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
deterministic
bool
)
([]
byte
,
error
)
{
s
:=
ptr
.
getSlice
(
u
.
typ
)
for
i
:=
0
;
i
<
s
.
Len
();
i
++
{
elem
:=
s
.
Index
(
i
)
t
:=
elem
.
Interface
()
.
(
time
.
Time
)
ts
,
err
:=
timestampProto
(
t
)
if
err
!=
nil
{
return
nil
,
err
}
siz
:=
Size
(
ts
)
buf
,
err
:=
Marshal
(
ts
)
if
err
!=
nil
{
return
nil
,
err
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
siz
))
b
=
append
(
b
,
buf
...
)
}
return
b
,
nil
}
}
func
makeTimePtrSliceMarshaler
(
u
*
marshalInfo
)
(
sizer
,
marshaler
)
{
return
func
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
ptr
.
getSlice
(
reflect
.
PtrTo
(
u
.
typ
))
n
:=
0
for
i
:=
0
;
i
<
s
.
Len
();
i
++
{
elem
:=
s
.
Index
(
i
)
t
:=
elem
.
Interface
()
.
(
*
time
.
Time
)
ts
,
err
:=
timestampProto
(
*
t
)
if
err
!=
nil
{
return
0
}
siz
:=
Size
(
ts
)
n
+=
siz
+
SizeVarint
(
uint64
(
siz
))
+
tagsize
}
return
n
},
func
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
deterministic
bool
)
([]
byte
,
error
)
{
s
:=
ptr
.
getSlice
(
reflect
.
PtrTo
(
u
.
typ
))
for
i
:=
0
;
i
<
s
.
Len
();
i
++
{
elem
:=
s
.
Index
(
i
)
t
:=
elem
.
Interface
()
.
(
*
time
.
Time
)
ts
,
err
:=
timestampProto
(
*
t
)
if
err
!=
nil
{
return
nil
,
err
}
siz
:=
Size
(
ts
)
buf
,
err
:=
Marshal
(
ts
)
if
err
!=
nil
{
return
nil
,
err
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
siz
))
b
=
append
(
b
,
buf
...
)
}
return
b
,
nil
}
}
func
makeDurationMarshaler
(
u
*
marshalInfo
)
(
sizer
,
marshaler
)
{
return
func
(
ptr
pointer
,
tagsize
int
)
int
{
d
:=
ptr
.
asPointerTo
(
u
.
typ
)
.
Interface
()
.
(
*
time
.
Duration
)
dur
:=
durationProto
(
*
d
)
siz
:=
Size
(
dur
)
return
tagsize
+
SizeVarint
(
uint64
(
siz
))
+
siz
},
func
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
deterministic
bool
)
([]
byte
,
error
)
{
d
:=
ptr
.
asPointerTo
(
u
.
typ
)
.
Interface
()
.
(
*
time
.
Duration
)
dur
:=
durationProto
(
*
d
)
buf
,
err
:=
Marshal
(
dur
)
if
err
!=
nil
{
return
nil
,
err
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
len
(
buf
)))
b
=
append
(
b
,
buf
...
)
return
b
,
nil
}
}
func
makeDurationPtrMarshaler
(
u
*
marshalInfo
)
(
sizer
,
marshaler
)
{
return
func
(
ptr
pointer
,
tagsize
int
)
int
{
if
ptr
.
isNil
()
{
return
0
}
d
:=
ptr
.
asPointerTo
(
reflect
.
PtrTo
(
u
.
typ
))
.
Elem
()
.
Interface
()
.
(
*
time
.
Duration
)
dur
:=
durationProto
(
*
d
)
siz
:=
Size
(
dur
)
return
tagsize
+
SizeVarint
(
uint64
(
siz
))
+
siz
},
func
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
deterministic
bool
)
([]
byte
,
error
)
{
if
ptr
.
isNil
()
{
return
b
,
nil
}
d
:=
ptr
.
asPointerTo
(
reflect
.
PtrTo
(
u
.
typ
))
.
Elem
()
.
Interface
()
.
(
*
time
.
Duration
)
dur
:=
durationProto
(
*
d
)
buf
,
err
:=
Marshal
(
dur
)
if
err
!=
nil
{
return
nil
,
err
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
len
(
buf
)))
b
=
append
(
b
,
buf
...
)
return
b
,
nil
}
}
func
makeDurationSliceMarshaler
(
u
*
marshalInfo
)
(
sizer
,
marshaler
)
{
return
func
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
ptr
.
getSlice
(
u
.
typ
)
n
:=
0
for
i
:=
0
;
i
<
s
.
Len
();
i
++
{
elem
:=
s
.
Index
(
i
)
d
:=
elem
.
Interface
()
.
(
time
.
Duration
)
dur
:=
durationProto
(
d
)
siz
:=
Size
(
dur
)
n
+=
siz
+
SizeVarint
(
uint64
(
siz
))
+
tagsize
}
return
n
},
func
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
deterministic
bool
)
([]
byte
,
error
)
{
s
:=
ptr
.
getSlice
(
u
.
typ
)
for
i
:=
0
;
i
<
s
.
Len
();
i
++
{
elem
:=
s
.
Index
(
i
)
d
:=
elem
.
Interface
()
.
(
time
.
Duration
)
dur
:=
durationProto
(
d
)
siz
:=
Size
(
dur
)
buf
,
err
:=
Marshal
(
dur
)
if
err
!=
nil
{
return
nil
,
err
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
siz
))
b
=
append
(
b
,
buf
...
)
}
return
b
,
nil
}
}
func
makeDurationPtrSliceMarshaler
(
u
*
marshalInfo
)
(
sizer
,
marshaler
)
{
return
func
(
ptr
pointer
,
tagsize
int
)
int
{
s
:=
ptr
.
getSlice
(
reflect
.
PtrTo
(
u
.
typ
))
n
:=
0
for
i
:=
0
;
i
<
s
.
Len
();
i
++
{
elem
:=
s
.
Index
(
i
)
d
:=
elem
.
Interface
()
.
(
*
time
.
Duration
)
dur
:=
durationProto
(
*
d
)
siz
:=
Size
(
dur
)
n
+=
siz
+
SizeVarint
(
uint64
(
siz
))
+
tagsize
}
return
n
},
func
(
b
[]
byte
,
ptr
pointer
,
wiretag
uint64
,
deterministic
bool
)
([]
byte
,
error
)
{
s
:=
ptr
.
getSlice
(
reflect
.
PtrTo
(
u
.
typ
))
for
i
:=
0
;
i
<
s
.
Len
();
i
++
{
elem
:=
s
.
Index
(
i
)
d
:=
elem
.
Interface
()
.
(
*
time
.
Duration
)
dur
:=
durationProto
(
*
d
)
siz
:=
Size
(
dur
)
buf
,
err
:=
Marshal
(
dur
)
if
err
!=
nil
{
return
nil
,
err
}
b
=
appendVarint
(
b
,
wiretag
)
b
=
appendVarint
(
b
,
uint64
(
siz
))
b
=
append
(
b
,
buf
...
)
}
return
b
,
nil
}
}
Prev
1
2
3
4
5
6
7
…
9
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