mirror of https://github.com/docker/docs.git
Merge pull request #1148 from vieux/add_container_mesos
add container name in mesos task label and update mesos-go
This commit is contained in:
commit
918c7a0466
|
|
@ -5,11 +5,6 @@
|
|||
"./..."
|
||||
],
|
||||
"Deps": [
|
||||
{
|
||||
"ImportPath": "code.google.com/p/go-uuid/uuid",
|
||||
"Comment": "null-15",
|
||||
"Rev": "35bc42037350f0078e3c974c6ea690f1926603ab"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/Sirupsen/logrus",
|
||||
"Comment": "v0.6.4-6-g539d4dc",
|
||||
|
|
@ -56,7 +51,7 @@
|
|||
},
|
||||
{
|
||||
"ImportPath": "github.com/gogo/protobuf/proto",
|
||||
"Rev": "bc946d07d1016848dfd2507f90f0859c9471681e"
|
||||
"Rev": "8edb24c179ed858a38f18920d9005c2dde05ec17"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/golang/glog",
|
||||
|
|
@ -77,35 +72,35 @@
|
|||
},
|
||||
{
|
||||
"ImportPath": "github.com/mesos/mesos-go/auth",
|
||||
"Rev": "83b52d7f648d2a2fa91330123d348d4090be2aed"
|
||||
"Rev": "d23a18b51b1ddf4072a223b38cc8d05cffb1ea42"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mesos/mesos-go/detector",
|
||||
"Rev": "83b52d7f648d2a2fa91330123d348d4090be2aed"
|
||||
"Rev": "d23a18b51b1ddf4072a223b38cc8d05cffb1ea42"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mesos/mesos-go/mesosproto",
|
||||
"Rev": "83b52d7f648d2a2fa91330123d348d4090be2aed"
|
||||
"Rev": "d23a18b51b1ddf4072a223b38cc8d05cffb1ea42"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mesos/mesos-go/mesosutil",
|
||||
"Rev": "83b52d7f648d2a2fa91330123d348d4090be2aed"
|
||||
"Rev": "d23a18b51b1ddf4072a223b38cc8d05cffb1ea42"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mesos/mesos-go/messenger",
|
||||
"Rev": "83b52d7f648d2a2fa91330123d348d4090be2aed"
|
||||
"Rev": "d23a18b51b1ddf4072a223b38cc8d05cffb1ea42"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mesos/mesos-go/scheduler",
|
||||
"Rev": "83b52d7f648d2a2fa91330123d348d4090be2aed"
|
||||
"Rev": "d23a18b51b1ddf4072a223b38cc8d05cffb1ea42"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mesos/mesos-go/upid",
|
||||
"Rev": "83b52d7f648d2a2fa91330123d348d4090be2aed"
|
||||
"Rev": "d23a18b51b1ddf4072a223b38cc8d05cffb1ea42"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/skarademir/naturalsort",
|
||||
"Rev": "69a5d87bef620f77ee8508db30c846b3b84b111e"
|
||||
"ImportPath": "github.com/pborman/uuid",
|
||||
"Rev": "ca53cad383cad2479bbba7f7a1a05797ec1386e4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/samalba/dockerclient",
|
||||
|
|
@ -115,6 +110,10 @@
|
|||
"ImportPath": "github.com/samuel/go-zookeeper/zk",
|
||||
"Rev": "fa6674abf3f4580b946a01bf7a1ce4ba8766205b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/skarademir/naturalsort",
|
||||
"Rev": "69a5d87bef620f77ee8508db30c846b3b84b111e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/stretchr/objx",
|
||||
"Rev": "cbeaeb16a013161a98496fad62933b1d21786672"
|
||||
|
|
|
|||
|
|
@ -37,4 +37,7 @@ test: install generate-test-pbs
|
|||
|
||||
|
||||
generate-test-pbs:
|
||||
make install && cd testdata && make
|
||||
make install
|
||||
make -C testdata
|
||||
protoc-min-version --version="3.0.0" --proto_path=.:../../../../ --gogo_out=. proto3_proto/proto3.proto
|
||||
make
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
. "./testdata"
|
||||
. "github.com/gogo/protobuf/proto"
|
||||
. "github.com/gogo/protobuf/proto/testdata"
|
||||
)
|
||||
|
||||
var globalO *Buffer
|
||||
|
|
@ -1252,7 +1252,8 @@ func TestProto1RepeatedGroup(t *testing.T) {
|
|||
}
|
||||
|
||||
o := old()
|
||||
if err := o.Marshal(pb); err != ErrRepeatedHasNil {
|
||||
err := o.Marshal(pb)
|
||||
if err == nil || !strings.Contains(err.Error(), "repeated field Message has nil") {
|
||||
t.Fatalf("unexpected or no error when marshaling: %v", err)
|
||||
}
|
||||
}
|
||||
|
|
@ -1441,6 +1442,17 @@ func TestSetDefaultsWithRepeatedSubMessage(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestSetDefaultWithRepeatedNonMessage(t *testing.T) {
|
||||
m := &MyMessage{
|
||||
Pet: []string{"turtle", "wombat"},
|
||||
}
|
||||
expected := Clone(m)
|
||||
SetDefaults(m)
|
||||
if !Equal(m, expected) {
|
||||
t.Errorf("\n got %v\nwant %v", m, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMaximumTagNumber(t *testing.T) {
|
||||
m := &MaxTag{
|
||||
LastField: String("natural goat essence"),
|
||||
|
|
@ -1833,6 +1845,98 @@ func fuzzUnmarshal(t *testing.T, data []byte) {
|
|||
Unmarshal(data, pb)
|
||||
}
|
||||
|
||||
func TestMapFieldMarshal(t *testing.T) {
|
||||
m := &MessageWithMap{
|
||||
NameMapping: map[int32]string{
|
||||
1: "Rob",
|
||||
4: "Ian",
|
||||
8: "Dave",
|
||||
},
|
||||
}
|
||||
b, err := Marshal(m)
|
||||
if err != nil {
|
||||
t.Fatalf("Marshal: %v", err)
|
||||
}
|
||||
|
||||
// b should be the concatenation of these three byte sequences in some order.
|
||||
parts := []string{
|
||||
"\n\a\b\x01\x12\x03Rob",
|
||||
"\n\a\b\x04\x12\x03Ian",
|
||||
"\n\b\b\x08\x12\x04Dave",
|
||||
}
|
||||
ok := false
|
||||
for i := range parts {
|
||||
for j := range parts {
|
||||
if j == i {
|
||||
continue
|
||||
}
|
||||
for k := range parts {
|
||||
if k == i || k == j {
|
||||
continue
|
||||
}
|
||||
try := parts[i] + parts[j] + parts[k]
|
||||
if bytes.Equal(b, []byte(try)) {
|
||||
ok = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
t.Fatalf("Incorrect Marshal output.\n got %q\nwant %q (or a permutation of that)", b, parts[0]+parts[1]+parts[2])
|
||||
}
|
||||
t.Logf("FYI b: %q", b)
|
||||
|
||||
(new(Buffer)).DebugPrint("Dump of b", b)
|
||||
}
|
||||
|
||||
func TestMapFieldRoundTrips(t *testing.T) {
|
||||
m := &MessageWithMap{
|
||||
NameMapping: map[int32]string{
|
||||
1: "Rob",
|
||||
4: "Ian",
|
||||
8: "Dave",
|
||||
},
|
||||
MsgMapping: map[int64]*FloatingPoint{
|
||||
0x7001: {F: Float64(2.0)},
|
||||
},
|
||||
ByteMapping: map[bool][]byte{
|
||||
false: []byte("that's not right!"),
|
||||
true: []byte("aye, 'tis true!"),
|
||||
},
|
||||
}
|
||||
b, err := Marshal(m)
|
||||
if err != nil {
|
||||
t.Fatalf("Marshal: %v", err)
|
||||
}
|
||||
t.Logf("FYI b: %q", b)
|
||||
m2 := new(MessageWithMap)
|
||||
if err := Unmarshal(b, m2); err != nil {
|
||||
t.Fatalf("Unmarshal: %v", err)
|
||||
}
|
||||
for _, pair := range [][2]interface{}{
|
||||
{m.NameMapping, m2.NameMapping},
|
||||
{m.MsgMapping, m2.MsgMapping},
|
||||
{m.ByteMapping, m2.ByteMapping},
|
||||
} {
|
||||
if !reflect.DeepEqual(pair[0], pair[1]) {
|
||||
t.Errorf("Map did not survive a round trip.\ninitial: %v\n final: %v", pair[0], pair[1])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMapFieldWithNil(t *testing.T) {
|
||||
m := &MessageWithMap{
|
||||
MsgMapping: map[int64]*FloatingPoint{
|
||||
1: nil,
|
||||
},
|
||||
}
|
||||
b, err := Marshal(m)
|
||||
if err == nil {
|
||||
t.Fatalf("Marshal of bad map should have failed, got these bytes: %v", b)
|
||||
}
|
||||
}
|
||||
|
||||
// Benchmarks
|
||||
|
||||
func testMsg() *GoTest {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Protocol buffer deep copy.
|
||||
// Protocol buffer deep copy and merge.
|
||||
// TODO: MessageSet and RawMessage.
|
||||
|
||||
package proto
|
||||
|
|
@ -75,12 +75,13 @@ func Merge(dst, src Message) {
|
|||
}
|
||||
|
||||
func mergeStruct(out, in reflect.Value) {
|
||||
sprop := GetProperties(in.Type())
|
||||
for i := 0; i < in.NumField(); i++ {
|
||||
f := in.Type().Field(i)
|
||||
if strings.HasPrefix(f.Name, "XXX_") {
|
||||
continue
|
||||
}
|
||||
mergeAny(out.Field(i), in.Field(i))
|
||||
mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i])
|
||||
}
|
||||
|
||||
if emIn, ok := in.Addr().Interface().(extensionsMap); ok {
|
||||
|
|
@ -103,7 +104,10 @@ func mergeStruct(out, in reflect.Value) {
|
|||
}
|
||||
}
|
||||
|
||||
func mergeAny(out, in reflect.Value) {
|
||||
// mergeAny performs a merge between two values of the same type.
|
||||
// viaPtr indicates whether the values were indirected through a pointer (implying proto2).
|
||||
// prop is set if this is a struct field (it may be nil).
|
||||
func mergeAny(out, in reflect.Value, viaPtr bool, prop *Properties) {
|
||||
if in.Type() == protoMessageType {
|
||||
if !in.IsNil() {
|
||||
if out.IsNil() {
|
||||
|
|
@ -117,7 +121,33 @@ func mergeAny(out, in reflect.Value) {
|
|||
switch in.Kind() {
|
||||
case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
|
||||
reflect.String, reflect.Uint32, reflect.Uint64:
|
||||
if !viaPtr && isProto3Zero(in) {
|
||||
return
|
||||
}
|
||||
out.Set(in)
|
||||
case reflect.Map:
|
||||
if in.Len() == 0 {
|
||||
return
|
||||
}
|
||||
if out.IsNil() {
|
||||
out.Set(reflect.MakeMap(in.Type()))
|
||||
}
|
||||
// For maps with value types of *T or []byte we need to deep copy each value.
|
||||
elemKind := in.Type().Elem().Kind()
|
||||
for _, key := range in.MapKeys() {
|
||||
var val reflect.Value
|
||||
switch elemKind {
|
||||
case reflect.Ptr:
|
||||
val = reflect.New(in.Type().Elem().Elem())
|
||||
mergeAny(val, in.MapIndex(key), false, nil)
|
||||
case reflect.Slice:
|
||||
val = in.MapIndex(key)
|
||||
val = reflect.ValueOf(append([]byte{}, val.Bytes()...))
|
||||
default:
|
||||
val = in.MapIndex(key)
|
||||
}
|
||||
out.SetMapIndex(key, val)
|
||||
}
|
||||
case reflect.Ptr:
|
||||
if in.IsNil() {
|
||||
return
|
||||
|
|
@ -125,13 +155,21 @@ func mergeAny(out, in reflect.Value) {
|
|||
if out.IsNil() {
|
||||
out.Set(reflect.New(in.Elem().Type()))
|
||||
}
|
||||
mergeAny(out.Elem(), in.Elem())
|
||||
mergeAny(out.Elem(), in.Elem(), true, nil)
|
||||
case reflect.Slice:
|
||||
if in.IsNil() {
|
||||
return
|
||||
}
|
||||
if in.Type().Elem().Kind() == reflect.Uint8 {
|
||||
// []byte is a scalar bytes field, not a repeated field.
|
||||
|
||||
// Edge case: if this is in a proto3 message, a zero length
|
||||
// bytes field is considered the zero value, and should not
|
||||
// be merged.
|
||||
if prop != nil && prop.proto3 && in.Len() == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Make a deep copy.
|
||||
// Append to []byte{} instead of []byte(nil) so that we never end up
|
||||
// with a nil result.
|
||||
|
|
@ -149,7 +187,7 @@ func mergeAny(out, in reflect.Value) {
|
|||
default:
|
||||
for i := 0; i < n; i++ {
|
||||
x := reflect.Indirect(reflect.New(in.Type().Elem()))
|
||||
mergeAny(x, in.Index(i))
|
||||
mergeAny(x, in.Index(i), false, nil)
|
||||
out.Set(reflect.Append(out, x))
|
||||
}
|
||||
}
|
||||
|
|
@ -166,7 +204,7 @@ func mergeExtension(out, in map[int32]Extension) {
|
|||
eOut := Extension{desc: eIn.desc}
|
||||
if eIn.value != nil {
|
||||
v := reflect.New(reflect.TypeOf(eIn.value)).Elem()
|
||||
mergeAny(v, reflect.ValueOf(eIn.value))
|
||||
mergeAny(v, reflect.ValueOf(eIn.value), false, nil)
|
||||
eOut.value = v.Interface()
|
||||
}
|
||||
if eIn.enc != nil {
|
||||
|
|
|
|||
|
|
@ -36,7 +36,8 @@ import (
|
|||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
|
||||
pb "./testdata"
|
||||
proto3pb "github.com/gogo/protobuf/proto/proto3_proto"
|
||||
pb "github.com/gogo/protobuf/proto/testdata"
|
||||
)
|
||||
|
||||
var cloneTestMessage = &pb.MyMessage{
|
||||
|
|
@ -189,6 +190,48 @@ var mergeTests = []struct {
|
|||
dst: &pb.OtherMessage{Value: []byte("bar")},
|
||||
want: &pb.OtherMessage{Value: []byte("foo")},
|
||||
},
|
||||
{
|
||||
src: &pb.MessageWithMap{
|
||||
NameMapping: map[int32]string{6: "Nigel"},
|
||||
MsgMapping: map[int64]*pb.FloatingPoint{
|
||||
0x4001: {F: proto.Float64(2.0)},
|
||||
},
|
||||
ByteMapping: map[bool][]byte{true: []byte("wowsa")},
|
||||
},
|
||||
dst: &pb.MessageWithMap{
|
||||
NameMapping: map[int32]string{
|
||||
6: "Bruce", // should be overwritten
|
||||
7: "Andrew",
|
||||
},
|
||||
},
|
||||
want: &pb.MessageWithMap{
|
||||
NameMapping: map[int32]string{
|
||||
6: "Nigel",
|
||||
7: "Andrew",
|
||||
},
|
||||
MsgMapping: map[int64]*pb.FloatingPoint{
|
||||
0x4001: {F: proto.Float64(2.0)},
|
||||
},
|
||||
ByteMapping: map[bool][]byte{true: []byte("wowsa")},
|
||||
},
|
||||
},
|
||||
// proto3 shouldn't merge zero values,
|
||||
// in the same way that proto2 shouldn't merge nils.
|
||||
{
|
||||
src: &proto3pb.Message{
|
||||
Name: "Aaron",
|
||||
Data: []byte(""), // zero value, but not nil
|
||||
},
|
||||
dst: &proto3pb.Message{
|
||||
HeightInCm: 176,
|
||||
Data: []byte("texas!"),
|
||||
},
|
||||
want: &proto3pb.Message{
|
||||
Name: "Aaron",
|
||||
HeightInCm: 176,
|
||||
Data: []byte("texas!"),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestMerge(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ func (p *Buffer) DecodeZigzag32() (x uint64, err error) {
|
|||
func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) {
|
||||
n, err := p.DecodeVarint()
|
||||
if err != nil {
|
||||
return
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nb := int(n)
|
||||
|
|
@ -470,6 +470,15 @@ func (o *Buffer) dec_bool(p *Properties, base structPointer) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (o *Buffer) dec_proto3_bool(p *Properties, base structPointer) error {
|
||||
u, err := p.valDec(o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*structPointer_BoolVal(base, p.field) = u != 0
|
||||
return nil
|
||||
}
|
||||
|
||||
// Decode an int32.
|
||||
func (o *Buffer) dec_int32(p *Properties, base structPointer) error {
|
||||
u, err := p.valDec(o)
|
||||
|
|
@ -480,6 +489,15 @@ func (o *Buffer) dec_int32(p *Properties, base structPointer) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (o *Buffer) dec_proto3_int32(p *Properties, base structPointer) error {
|
||||
u, err := p.valDec(o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
word32Val_Set(structPointer_Word32Val(base, p.field), uint32(u))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Decode an int64.
|
||||
func (o *Buffer) dec_int64(p *Properties, base structPointer) error {
|
||||
u, err := p.valDec(o)
|
||||
|
|
@ -490,15 +508,31 @@ func (o *Buffer) dec_int64(p *Properties, base structPointer) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (o *Buffer) dec_proto3_int64(p *Properties, base structPointer) error {
|
||||
u, err := p.valDec(o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
word64Val_Set(structPointer_Word64Val(base, p.field), o, u)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Decode a string.
|
||||
func (o *Buffer) dec_string(p *Properties, base structPointer) error {
|
||||
s, err := o.DecodeStringBytes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sp := new(string)
|
||||
*sp = s
|
||||
*structPointer_String(base, p.field) = sp
|
||||
*structPointer_String(base, p.field) = &s
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Buffer) dec_proto3_string(p *Properties, base structPointer) error {
|
||||
s, err := o.DecodeStringBytes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*structPointer_StringVal(base, p.field) = s
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -637,6 +671,78 @@ func (o *Buffer) dec_slice_slice_byte(p *Properties, base structPointer) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Decode a map field.
|
||||
func (o *Buffer) dec_new_map(p *Properties, base structPointer) error {
|
||||
raw, err := o.DecodeRawBytes(false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
oi := o.index // index at the end of this map entry
|
||||
o.index -= len(raw) // move buffer back to start of map entry
|
||||
|
||||
mptr := structPointer_Map(base, p.field, p.mtype) // *map[K]V
|
||||
if mptr.Elem().IsNil() {
|
||||
mptr.Elem().Set(reflect.MakeMap(mptr.Type().Elem()))
|
||||
}
|
||||
v := mptr.Elem() // map[K]V
|
||||
|
||||
// Prepare addressable doubly-indirect placeholders for the key and value types.
|
||||
// See enc_new_map for why.
|
||||
keyptr := reflect.New(reflect.PtrTo(p.mtype.Key())).Elem() // addressable *K
|
||||
keybase := toStructPointer(keyptr.Addr()) // **K
|
||||
|
||||
var valbase structPointer
|
||||
var valptr reflect.Value
|
||||
switch p.mtype.Elem().Kind() {
|
||||
case reflect.Slice:
|
||||
// []byte
|
||||
var dummy []byte
|
||||
valptr = reflect.ValueOf(&dummy) // *[]byte
|
||||
valbase = toStructPointer(valptr) // *[]byte
|
||||
case reflect.Ptr:
|
||||
// message; valptr is **Msg; need to allocate the intermediate pointer
|
||||
valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V
|
||||
valptr.Set(reflect.New(valptr.Type().Elem()))
|
||||
valbase = toStructPointer(valptr)
|
||||
default:
|
||||
// everything else
|
||||
valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V
|
||||
valbase = toStructPointer(valptr.Addr()) // **V
|
||||
}
|
||||
|
||||
// Decode.
|
||||
// This parses a restricted wire format, namely the encoding of a message
|
||||
// with two fields. See enc_new_map for the format.
|
||||
for o.index < oi {
|
||||
// tagcode for key and value properties are always a single byte
|
||||
// because they have tags 1 and 2.
|
||||
tagcode := o.buf[o.index]
|
||||
o.index++
|
||||
switch tagcode {
|
||||
case p.mkeyprop.tagcode[0]:
|
||||
if err := p.mkeyprop.dec(o, p.mkeyprop, keybase); err != nil {
|
||||
return err
|
||||
}
|
||||
case p.mvalprop.tagcode[0]:
|
||||
if err := p.mvalprop.dec(o, p.mvalprop, valbase); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
// TODO: Should we silently skip this instead?
|
||||
return fmt.Errorf("proto: bad map data tag %d", raw[0])
|
||||
}
|
||||
}
|
||||
keyelem, valelem := keyptr.Elem(), valptr.Elem()
|
||||
if !keyelem.IsValid() || !valelem.IsValid() {
|
||||
// We did not decode the key or the value in the map entry.
|
||||
// Either way, it's an invalid map entry.
|
||||
return fmt.Errorf("proto: bad map data: missing key/val")
|
||||
}
|
||||
|
||||
v.SetMapIndex(keyelem, valelem)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Decode a group.
|
||||
func (o *Buffer) dec_struct_group(p *Properties, base structPointer) error {
|
||||
bas := structPointer_GetStructPointer(base, p.field)
|
||||
|
|
|
|||
|
|
@ -30,51 +30,6 @@ import (
|
|||
"reflect"
|
||||
)
|
||||
|
||||
// Decode a reference to a bool pointer.
|
||||
func (o *Buffer) dec_ref_bool(p *Properties, base structPointer) error {
|
||||
u, err := p.valDec(o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(o.bools) == 0 {
|
||||
o.bools = make([]bool, boolPoolSize)
|
||||
}
|
||||
o.bools[0] = u != 0
|
||||
*structPointer_RefBool(base, p.field) = o.bools[0]
|
||||
o.bools = o.bools[1:]
|
||||
return nil
|
||||
}
|
||||
|
||||
// Decode a reference to an int32 pointer.
|
||||
func (o *Buffer) dec_ref_int32(p *Properties, base structPointer) error {
|
||||
u, err := p.valDec(o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
refWord32_Set(structPointer_RefWord32(base, p.field), o, uint32(u))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Decode a reference to an int64 pointer.
|
||||
func (o *Buffer) dec_ref_int64(p *Properties, base structPointer) error {
|
||||
u, err := p.valDec(o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
refWord64_Set(structPointer_RefWord64(base, p.field), o, u)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Decode a reference to a string pointer.
|
||||
func (o *Buffer) dec_ref_string(p *Properties, base structPointer) error {
|
||||
s, err := o.DecodeStringBytes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*structPointer_RefString(base, p.field) = s
|
||||
return nil
|
||||
}
|
||||
|
||||
// Decode a reference to a struct pointer.
|
||||
func (o *Buffer) dec_ref_struct_message(p *Properties, base structPointer) (err error) {
|
||||
raw, e := o.DecodeRawBytes(false)
|
||||
|
|
|
|||
|
|
@ -60,9 +60,9 @@ func (e *RequiredNotSetError) Error() string {
|
|||
}
|
||||
|
||||
var (
|
||||
// ErrRepeatedHasNil is the error returned if Marshal is called with
|
||||
// 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")
|
||||
errRepeatedHasNil = errors.New("proto: repeated field has nil element")
|
||||
|
||||
// ErrNil is the error returned if Marshal is called with nil.
|
||||
ErrNil = errors.New("proto: Marshal called with nil")
|
||||
|
|
@ -298,6 +298,16 @@ func (o *Buffer) enc_bool(p *Properties, base structPointer) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (o *Buffer) enc_proto3_bool(p *Properties, base structPointer) error {
|
||||
v := *structPointer_BoolVal(base, p.field)
|
||||
if !v {
|
||||
return ErrNil
|
||||
}
|
||||
o.buf = append(o.buf, p.tagcode...)
|
||||
p.valEnc(o, 1)
|
||||
return nil
|
||||
}
|
||||
|
||||
func size_bool(p *Properties, base structPointer) int {
|
||||
v := *structPointer_Bool(base, p.field)
|
||||
if v == nil {
|
||||
|
|
@ -306,6 +316,14 @@ func size_bool(p *Properties, base structPointer) int {
|
|||
return len(p.tagcode) + 1 // each bool takes exactly one byte
|
||||
}
|
||||
|
||||
func size_proto3_bool(p *Properties, base structPointer) int {
|
||||
v := *structPointer_BoolVal(base, p.field)
|
||||
if !v {
|
||||
return 0
|
||||
}
|
||||
return len(p.tagcode) + 1 // each bool takes exactly one byte
|
||||
}
|
||||
|
||||
// Encode an int32.
|
||||
func (o *Buffer) enc_int32(p *Properties, base structPointer) error {
|
||||
v := structPointer_Word32(base, p.field)
|
||||
|
|
@ -318,6 +336,17 @@ func (o *Buffer) enc_int32(p *Properties, base structPointer) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (o *Buffer) enc_proto3_int32(p *Properties, base structPointer) error {
|
||||
v := structPointer_Word32Val(base, p.field)
|
||||
x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range
|
||||
if x == 0 {
|
||||
return ErrNil
|
||||
}
|
||||
o.buf = append(o.buf, p.tagcode...)
|
||||
p.valEnc(o, uint64(x))
|
||||
return nil
|
||||
}
|
||||
|
||||
func size_int32(p *Properties, base structPointer) (n int) {
|
||||
v := structPointer_Word32(base, p.field)
|
||||
if word32_IsNil(v) {
|
||||
|
|
@ -329,6 +358,17 @@ func size_int32(p *Properties, base structPointer) (n int) {
|
|||
return
|
||||
}
|
||||
|
||||
func size_proto3_int32(p *Properties, base structPointer) (n int) {
|
||||
v := structPointer_Word32Val(base, p.field)
|
||||
x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range
|
||||
if x == 0 {
|
||||
return 0
|
||||
}
|
||||
n += len(p.tagcode)
|
||||
n += p.valSize(uint64(x))
|
||||
return
|
||||
}
|
||||
|
||||
// Encode a uint32.
|
||||
// Exactly the same as int32, except for no sign extension.
|
||||
func (o *Buffer) enc_uint32(p *Properties, base structPointer) error {
|
||||
|
|
@ -342,6 +382,17 @@ func (o *Buffer) enc_uint32(p *Properties, base structPointer) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (o *Buffer) enc_proto3_uint32(p *Properties, base structPointer) error {
|
||||
v := structPointer_Word32Val(base, p.field)
|
||||
x := word32Val_Get(v)
|
||||
if x == 0 {
|
||||
return ErrNil
|
||||
}
|
||||
o.buf = append(o.buf, p.tagcode...)
|
||||
p.valEnc(o, uint64(x))
|
||||
return nil
|
||||
}
|
||||
|
||||
func size_uint32(p *Properties, base structPointer) (n int) {
|
||||
v := structPointer_Word32(base, p.field)
|
||||
if word32_IsNil(v) {
|
||||
|
|
@ -353,6 +404,17 @@ func size_uint32(p *Properties, base structPointer) (n int) {
|
|||
return
|
||||
}
|
||||
|
||||
func size_proto3_uint32(p *Properties, base structPointer) (n int) {
|
||||
v := structPointer_Word32Val(base, p.field)
|
||||
x := word32Val_Get(v)
|
||||
if x == 0 {
|
||||
return 0
|
||||
}
|
||||
n += len(p.tagcode)
|
||||
n += p.valSize(uint64(x))
|
||||
return
|
||||
}
|
||||
|
||||
// Encode an int64.
|
||||
func (o *Buffer) enc_int64(p *Properties, base structPointer) error {
|
||||
v := structPointer_Word64(base, p.field)
|
||||
|
|
@ -365,6 +427,17 @@ func (o *Buffer) enc_int64(p *Properties, base structPointer) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (o *Buffer) enc_proto3_int64(p *Properties, base structPointer) error {
|
||||
v := structPointer_Word64Val(base, p.field)
|
||||
x := word64Val_Get(v)
|
||||
if x == 0 {
|
||||
return ErrNil
|
||||
}
|
||||
o.buf = append(o.buf, p.tagcode...)
|
||||
p.valEnc(o, x)
|
||||
return nil
|
||||
}
|
||||
|
||||
func size_int64(p *Properties, base structPointer) (n int) {
|
||||
v := structPointer_Word64(base, p.field)
|
||||
if word64_IsNil(v) {
|
||||
|
|
@ -376,6 +449,17 @@ func size_int64(p *Properties, base structPointer) (n int) {
|
|||
return
|
||||
}
|
||||
|
||||
func size_proto3_int64(p *Properties, base structPointer) (n int) {
|
||||
v := structPointer_Word64Val(base, p.field)
|
||||
x := word64Val_Get(v)
|
||||
if x == 0 {
|
||||
return 0
|
||||
}
|
||||
n += len(p.tagcode)
|
||||
n += p.valSize(x)
|
||||
return
|
||||
}
|
||||
|
||||
// Encode a string.
|
||||
func (o *Buffer) enc_string(p *Properties, base structPointer) error {
|
||||
v := *structPointer_String(base, p.field)
|
||||
|
|
@ -388,6 +472,16 @@ func (o *Buffer) enc_string(p *Properties, base structPointer) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (o *Buffer) enc_proto3_string(p *Properties, base structPointer) error {
|
||||
v := *structPointer_StringVal(base, p.field)
|
||||
if v == "" {
|
||||
return ErrNil
|
||||
}
|
||||
o.buf = append(o.buf, p.tagcode...)
|
||||
o.EncodeStringBytes(v)
|
||||
return nil
|
||||
}
|
||||
|
||||
func size_string(p *Properties, base structPointer) (n int) {
|
||||
v := *structPointer_String(base, p.field)
|
||||
if v == nil {
|
||||
|
|
@ -399,6 +493,16 @@ func size_string(p *Properties, base structPointer) (n int) {
|
|||
return
|
||||
}
|
||||
|
||||
func size_proto3_string(p *Properties, base structPointer) (n int) {
|
||||
v := *structPointer_StringVal(base, p.field)
|
||||
if v == "" {
|
||||
return 0
|
||||
}
|
||||
n += len(p.tagcode)
|
||||
n += sizeStringBytes(v)
|
||||
return
|
||||
}
|
||||
|
||||
// All protocol buffer fields are nillable, but be careful.
|
||||
func isNil(v reflect.Value) bool {
|
||||
switch v.Kind() {
|
||||
|
|
@ -551,6 +655,16 @@ func (o *Buffer) enc_slice_byte(p *Properties, base structPointer) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (o *Buffer) enc_proto3_slice_byte(p *Properties, base structPointer) error {
|
||||
s := *structPointer_Bytes(base, p.field)
|
||||
if len(s) == 0 {
|
||||
return ErrNil
|
||||
}
|
||||
o.buf = append(o.buf, p.tagcode...)
|
||||
o.EncodeRawBytes(s)
|
||||
return nil
|
||||
}
|
||||
|
||||
func size_slice_byte(p *Properties, base structPointer) (n int) {
|
||||
s := *structPointer_Bytes(base, p.field)
|
||||
if s == nil {
|
||||
|
|
@ -561,6 +675,16 @@ func size_slice_byte(p *Properties, base structPointer) (n int) {
|
|||
return
|
||||
}
|
||||
|
||||
func size_proto3_slice_byte(p *Properties, base structPointer) (n int) {
|
||||
s := *structPointer_Bytes(base, p.field)
|
||||
if len(s) == 0 {
|
||||
return 0
|
||||
}
|
||||
n += len(p.tagcode)
|
||||
n += sizeRawBytes(s)
|
||||
return
|
||||
}
|
||||
|
||||
// Encode a slice of int32s ([]int32).
|
||||
func (o *Buffer) enc_slice_int32(p *Properties, base structPointer) error {
|
||||
s := structPointer_Word32Slice(base, p.field)
|
||||
|
|
@ -815,7 +939,7 @@ func (o *Buffer) enc_slice_struct_message(p *Properties, base structPointer) err
|
|||
for i := 0; i < l; i++ {
|
||||
structp := s.Index(i)
|
||||
if structPointer_IsNil(structp) {
|
||||
return ErrRepeatedHasNil
|
||||
return errRepeatedHasNil
|
||||
}
|
||||
|
||||
// Can the object marshal itself?
|
||||
|
|
@ -834,7 +958,7 @@ func (o *Buffer) enc_slice_struct_message(p *Properties, base structPointer) err
|
|||
err := o.enc_len_struct(p.sprop, structp, &state)
|
||||
if err != nil && !state.shouldContinue(err, nil) {
|
||||
if err == ErrNil {
|
||||
return ErrRepeatedHasNil
|
||||
return errRepeatedHasNil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
@ -877,7 +1001,7 @@ func (o *Buffer) enc_slice_struct_group(p *Properties, base structPointer) error
|
|||
for i := 0; i < l; i++ {
|
||||
b := s.Index(i)
|
||||
if structPointer_IsNil(b) {
|
||||
return ErrRepeatedHasNil
|
||||
return errRepeatedHasNil
|
||||
}
|
||||
|
||||
o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
|
||||
|
|
@ -886,7 +1010,7 @@ func (o *Buffer) enc_slice_struct_group(p *Properties, base structPointer) error
|
|||
|
||||
if err != nil && !state.shouldContinue(err, nil) {
|
||||
if err == ErrNil {
|
||||
return ErrRepeatedHasNil
|
||||
return errRepeatedHasNil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
@ -945,6 +1069,113 @@ func size_map(p *Properties, base structPointer) int {
|
|||
return sizeExtensionMap(v)
|
||||
}
|
||||
|
||||
// Encode a map field.
|
||||
func (o *Buffer) enc_new_map(p *Properties, base structPointer) error {
|
||||
var state errorState // XXX: or do we need to plumb this through?
|
||||
|
||||
/*
|
||||
A map defined as
|
||||
map<key_type, value_type> map_field = N;
|
||||
is encoded in the same way as
|
||||
message MapFieldEntry {
|
||||
key_type key = 1;
|
||||
value_type value = 2;
|
||||
}
|
||||
repeated MapFieldEntry map_field = N;
|
||||
*/
|
||||
|
||||
v := structPointer_Map(base, p.field, p.mtype).Elem() // map[K]V
|
||||
if v.Len() == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype)
|
||||
|
||||
enc := func() error {
|
||||
if err := p.mkeyprop.enc(o, p.mkeyprop, keybase); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := p.mvalprop.enc(o, p.mvalprop, valbase); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
keys := v.MapKeys()
|
||||
sort.Sort(mapKeys(keys))
|
||||
for _, key := range keys {
|
||||
val := v.MapIndex(key)
|
||||
|
||||
// The only illegal map entry values are nil message pointers.
|
||||
if val.Kind() == reflect.Ptr && val.IsNil() {
|
||||
return errors.New("proto: map has nil element")
|
||||
}
|
||||
|
||||
keycopy.Set(key)
|
||||
valcopy.Set(val)
|
||||
|
||||
o.buf = append(o.buf, p.tagcode...)
|
||||
if err := o.enc_len_thing(enc, &state); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func size_new_map(p *Properties, base structPointer) int {
|
||||
v := structPointer_Map(base, p.field, p.mtype).Elem() // map[K]V
|
||||
|
||||
keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype)
|
||||
|
||||
n := 0
|
||||
for _, key := range v.MapKeys() {
|
||||
val := v.MapIndex(key)
|
||||
keycopy.Set(key)
|
||||
valcopy.Set(val)
|
||||
|
||||
// Tag codes for key and val are the responsibility of the sub-sizer.
|
||||
keysize := p.mkeyprop.size(p.mkeyprop, keybase)
|
||||
valsize := p.mvalprop.size(p.mvalprop, valbase)
|
||||
entry := keysize + valsize
|
||||
// Add on tag code and length of map entry itself.
|
||||
n += len(p.tagcode) + sizeVarint(uint64(entry)) + entry
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// mapEncodeScratch returns a new reflect.Value matching the map's value type,
|
||||
// and a structPointer suitable for passing to an encoder or sizer.
|
||||
func mapEncodeScratch(mapType reflect.Type) (keycopy, valcopy reflect.Value, keybase, valbase structPointer) {
|
||||
// Prepare addressable doubly-indirect placeholders for the key and value types.
|
||||
// This is needed because the element-type encoders expect **T, but the map iteration produces T.
|
||||
|
||||
keycopy = reflect.New(mapType.Key()).Elem() // addressable K
|
||||
keyptr := reflect.New(reflect.PtrTo(keycopy.Type())).Elem() // addressable *K
|
||||
keyptr.Set(keycopy.Addr()) //
|
||||
keybase = toStructPointer(keyptr.Addr()) // **K
|
||||
|
||||
// Value types are more varied and require special handling.
|
||||
switch mapType.Elem().Kind() {
|
||||
case reflect.Slice:
|
||||
// []byte
|
||||
var dummy []byte
|
||||
valcopy = reflect.ValueOf(&dummy).Elem() // addressable []byte
|
||||
valbase = toStructPointer(valcopy.Addr())
|
||||
case reflect.Ptr:
|
||||
// message; the generated field type is map[K]*Msg (so V is *Msg),
|
||||
// so we only need one level of indirection.
|
||||
valcopy = reflect.New(mapType.Elem()).Elem() // addressable V
|
||||
valbase = toStructPointer(valcopy.Addr())
|
||||
default:
|
||||
// everything else
|
||||
valcopy = reflect.New(mapType.Elem()).Elem() // addressable V
|
||||
valptr := reflect.New(reflect.PtrTo(valcopy.Type())).Elem() // addressable *V
|
||||
valptr.Set(valcopy.Addr()) //
|
||||
valbase = toStructPointer(valptr.Addr()) // **V
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Encode a struct.
|
||||
func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
|
||||
var state errorState
|
||||
|
|
@ -960,6 +1191,9 @@ func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
|
|||
if p.Required && state.err == nil {
|
||||
state.err = &RequiredNotSetError{p.Name}
|
||||
}
|
||||
} else if err == errRepeatedHasNil {
|
||||
// Give more context to nil values in repeated fields.
|
||||
return errors.New("repeated field " + p.OrigName + " has nil element")
|
||||
} else if !state.shouldContinue(err, p) {
|
||||
return err
|
||||
}
|
||||
|
|
@ -999,10 +1233,15 @@ var zeroes [20]byte // longer than any conceivable sizeVarint
|
|||
|
||||
// Encode a struct, preceded by its encoded length (as a varint).
|
||||
func (o *Buffer) enc_len_struct(prop *StructProperties, base structPointer, state *errorState) error {
|
||||
return o.enc_len_thing(func() error { return o.enc_struct(prop, base) }, state)
|
||||
}
|
||||
|
||||
// Encode something, preceded by its encoded length (as a varint).
|
||||
func (o *Buffer) enc_len_thing(enc func() error, state *errorState) error {
|
||||
iLen := len(o.buf)
|
||||
o.buf = append(o.buf, 0, 0, 0, 0) // reserve four bytes for length
|
||||
iMsg := len(o.buf)
|
||||
err := o.enc_struct(prop, base)
|
||||
err := enc()
|
||||
if err != nil && !state.shouldContinue(err, nil) {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,10 @@ import (
|
|||
"reflect"
|
||||
)
|
||||
|
||||
func NewRequiredNotSetError(field string) *RequiredNotSetError {
|
||||
return &RequiredNotSetError{field}
|
||||
}
|
||||
|
||||
type Sizer interface {
|
||||
Size() int
|
||||
}
|
||||
|
|
@ -64,12 +68,9 @@ func size_ext_slice_byte(p *Properties, base structPointer) (n int) {
|
|||
|
||||
// Encode a reference to bool pointer.
|
||||
func (o *Buffer) enc_ref_bool(p *Properties, base structPointer) error {
|
||||
v := structPointer_RefBool(base, p.field)
|
||||
if v == nil {
|
||||
return ErrNil
|
||||
}
|
||||
v := *structPointer_BoolVal(base, p.field)
|
||||
x := 0
|
||||
if *v {
|
||||
if v {
|
||||
x = 1
|
||||
}
|
||||
o.buf = append(o.buf, p.tagcode...)
|
||||
|
|
@ -78,53 +79,37 @@ func (o *Buffer) enc_ref_bool(p *Properties, base structPointer) error {
|
|||
}
|
||||
|
||||
func size_ref_bool(p *Properties, base structPointer) int {
|
||||
v := structPointer_RefBool(base, p.field)
|
||||
if v == nil {
|
||||
return 0
|
||||
}
|
||||
return len(p.tagcode) + 1 // each bool takes exactly one byte
|
||||
}
|
||||
|
||||
// Encode a reference to int32 pointer.
|
||||
func (o *Buffer) enc_ref_int32(p *Properties, base structPointer) error {
|
||||
v := structPointer_RefWord32(base, p.field)
|
||||
if refWord32_IsNil(v) {
|
||||
return ErrNil
|
||||
}
|
||||
x := int32(refWord32_Get(v))
|
||||
v := structPointer_Word32Val(base, p.field)
|
||||
x := int32(word32Val_Get(v))
|
||||
o.buf = append(o.buf, p.tagcode...)
|
||||
p.valEnc(o, uint64(x))
|
||||
return nil
|
||||
}
|
||||
|
||||
func size_ref_int32(p *Properties, base structPointer) (n int) {
|
||||
v := structPointer_RefWord32(base, p.field)
|
||||
if refWord32_IsNil(v) {
|
||||
return 0
|
||||
}
|
||||
x := int32(refWord32_Get(v))
|
||||
v := structPointer_Word32Val(base, p.field)
|
||||
x := int32(word32Val_Get(v))
|
||||
n += len(p.tagcode)
|
||||
n += p.valSize(uint64(x))
|
||||
return
|
||||
}
|
||||
|
||||
func (o *Buffer) enc_ref_uint32(p *Properties, base structPointer) error {
|
||||
v := structPointer_RefWord32(base, p.field)
|
||||
if refWord32_IsNil(v) {
|
||||
return ErrNil
|
||||
}
|
||||
x := refWord32_Get(v)
|
||||
v := structPointer_Word32Val(base, p.field)
|
||||
x := word32Val_Get(v)
|
||||
o.buf = append(o.buf, p.tagcode...)
|
||||
p.valEnc(o, uint64(x))
|
||||
return nil
|
||||
}
|
||||
|
||||
func size_ref_uint32(p *Properties, base structPointer) (n int) {
|
||||
v := structPointer_RefWord32(base, p.field)
|
||||
if refWord32_IsNil(v) {
|
||||
return 0
|
||||
}
|
||||
x := refWord32_Get(v)
|
||||
v := structPointer_Word32Val(base, p.field)
|
||||
x := word32Val_Get(v)
|
||||
n += len(p.tagcode)
|
||||
n += p.valSize(uint64(x))
|
||||
return
|
||||
|
|
@ -132,22 +117,16 @@ func size_ref_uint32(p *Properties, base structPointer) (n int) {
|
|||
|
||||
// Encode a reference to an int64 pointer.
|
||||
func (o *Buffer) enc_ref_int64(p *Properties, base structPointer) error {
|
||||
v := structPointer_RefWord64(base, p.field)
|
||||
if refWord64_IsNil(v) {
|
||||
return ErrNil
|
||||
}
|
||||
x := refWord64_Get(v)
|
||||
v := structPointer_Word64Val(base, p.field)
|
||||
x := word64Val_Get(v)
|
||||
o.buf = append(o.buf, p.tagcode...)
|
||||
p.valEnc(o, x)
|
||||
return nil
|
||||
}
|
||||
|
||||
func size_ref_int64(p *Properties, base structPointer) (n int) {
|
||||
v := structPointer_RefWord64(base, p.field)
|
||||
if refWord64_IsNil(v) {
|
||||
return 0
|
||||
}
|
||||
x := refWord64_Get(v)
|
||||
v := structPointer_Word64Val(base, p.field)
|
||||
x := word64Val_Get(v)
|
||||
n += len(p.tagcode)
|
||||
n += p.valSize(x)
|
||||
return
|
||||
|
|
@ -155,24 +134,16 @@ func size_ref_int64(p *Properties, base structPointer) (n int) {
|
|||
|
||||
// Encode a reference to a string pointer.
|
||||
func (o *Buffer) enc_ref_string(p *Properties, base structPointer) error {
|
||||
v := structPointer_RefString(base, p.field)
|
||||
if v == nil {
|
||||
return ErrNil
|
||||
}
|
||||
x := *v
|
||||
v := *structPointer_StringVal(base, p.field)
|
||||
o.buf = append(o.buf, p.tagcode...)
|
||||
o.EncodeStringBytes(x)
|
||||
o.EncodeStringBytes(v)
|
||||
return nil
|
||||
}
|
||||
|
||||
func size_ref_string(p *Properties, base structPointer) (n int) {
|
||||
v := structPointer_RefString(base, p.field)
|
||||
if v == nil {
|
||||
return 0
|
||||
}
|
||||
x := *v
|
||||
v := *structPointer_StringVal(base, p.field)
|
||||
n += len(p.tagcode)
|
||||
n += sizeStringBytes(x)
|
||||
n += sizeStringBytes(v)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -232,7 +203,7 @@ func (o *Buffer) enc_slice_ref_struct_message(p *Properties, base structPointer)
|
|||
for i := 0; i < l; i++ {
|
||||
structp := structPointer_Add(ss1, field(uintptr(i)*size))
|
||||
if structPointer_IsNil(structp) {
|
||||
return ErrRepeatedHasNil
|
||||
return errRepeatedHasNil
|
||||
}
|
||||
|
||||
// Can the object marshal itself?
|
||||
|
|
@ -251,7 +222,7 @@ func (o *Buffer) enc_slice_ref_struct_message(p *Properties, base structPointer)
|
|||
err := o.enc_len_struct(p.sprop, structp, &state)
|
||||
if err != nil && !state.shouldContinue(err, nil) {
|
||||
if err == ErrNil {
|
||||
return ErrRepeatedHasNil
|
||||
return errRepeatedHasNil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,6 +154,21 @@ func equalAny(v1, v2 reflect.Value) bool {
|
|||
return v1.Float() == v2.Float()
|
||||
case reflect.Int32, reflect.Int64:
|
||||
return v1.Int() == v2.Int()
|
||||
case reflect.Map:
|
||||
if v1.Len() != v2.Len() {
|
||||
return false
|
||||
}
|
||||
for _, key := range v1.MapKeys() {
|
||||
val2 := v2.MapIndex(key)
|
||||
if !val2.IsValid() {
|
||||
// This key was not found in the second map.
|
||||
return false
|
||||
}
|
||||
if !equalAny(v1.MapIndex(key), val2) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
case reflect.Ptr:
|
||||
return equalAny(v1.Elem(), v2.Elem())
|
||||
case reflect.Slice:
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ package proto_test
|
|||
import (
|
||||
"testing"
|
||||
|
||||
pb "./testdata"
|
||||
. "github.com/gogo/protobuf/proto"
|
||||
pb "github.com/gogo/protobuf/proto/testdata"
|
||||
)
|
||||
|
||||
// Four identical base messages.
|
||||
|
|
@ -155,6 +155,31 @@ var EqualTests = []struct {
|
|||
},
|
||||
true,
|
||||
},
|
||||
|
||||
{
|
||||
"map same",
|
||||
&pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
|
||||
&pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"map different entry",
|
||||
&pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
|
||||
&pb.MessageWithMap{NameMapping: map[int32]string{2: "Rob"}},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"map different key only",
|
||||
&pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
|
||||
&pb.MessageWithMap{NameMapping: map[int32]string{2: "Ken"}},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"map different value only",
|
||||
&pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
|
||||
&pb.MessageWithMap{NameMapping: map[int32]string{1: "Rob"}},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
func TestEqual(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ package proto
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
|
@ -310,7 +311,9 @@ func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, er
|
|||
emap := epb.ExtensionMap()
|
||||
e, ok := emap[extension.Field]
|
||||
if !ok {
|
||||
return nil, ErrMissingExtension
|
||||
// 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.
|
||||
|
|
@ -355,10 +358,46 @@ func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, er
|
|||
}
|
||||
o += n + l
|
||||
}
|
||||
return defaultExtensionValue(extension)
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
// defaultExtensionValue returns the default value for extension.
|
||||
// If no default for an extension is defined ErrMissingExtension is returned.
|
||||
func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) {
|
||||
t := reflect.TypeOf(extension.ExtensionType)
|
||||
props := extensionProperties(extension)
|
||||
|
||||
sf, _, err := fieldDefault(t, props)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if sf == nil || sf.value == nil {
|
||||
// There is no default value.
|
||||
return nil, ErrMissingExtension
|
||||
}
|
||||
|
||||
if t.Kind() != reflect.Ptr {
|
||||
// We do not need to return a Ptr, we can directly return sf.value.
|
||||
return sf.value, nil
|
||||
}
|
||||
|
||||
// We need to return an interface{} that is a pointer to sf.value.
|
||||
value := reflect.New(t).Elem()
|
||||
value.Set(reflect.New(value.Type().Elem()))
|
||||
if sf.kind == reflect.Int32 {
|
||||
// We may have an int32 or an enum, but the underlying data is int32.
|
||||
// Since we can't set an int32 into a non int32 reflect.value directly
|
||||
// set it as a int32.
|
||||
value.Elem().SetInt(int64(sf.value.(int32)))
|
||||
} else {
|
||||
value.Elem().Set(reflect.ValueOf(sf.value))
|
||||
}
|
||||
return value.Interface(), nil
|
||||
}
|
||||
|
||||
// decodeExtension decodes an extension encoded in b.
|
||||
func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
|
||||
o := NewBuffer(b)
|
||||
|
|
@ -423,6 +462,14 @@ func SetExtension(pb extendableProto, extension *ExtensionDesc, value interface{
|
|||
if typ != reflect.TypeOf(value) {
|
||||
return errors.New("proto: bad extension value type")
|
||||
}
|
||||
// nil extension values need to be caught early, because the
|
||||
// encoder can't distinguish an ErrNil due to a nil extension
|
||||
// from an ErrNil due to a missing field. Extensions are
|
||||
// always optional, so the encoder would just swallow the error
|
||||
// and drop all the extensions from the encoded message.
|
||||
if reflect.ValueOf(value).IsNil() {
|
||||
return fmt.Errorf("proto: SetExtension called with nil value of type %T", value)
|
||||
}
|
||||
return setExtension(pb, extension, value)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,10 +32,12 @@
|
|||
package proto_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
pb "./testdata"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
pb "github.com/gogo/protobuf/proto/testdata"
|
||||
)
|
||||
|
||||
func TestGetExtensionsWithMissingExtensions(t *testing.T) {
|
||||
|
|
@ -92,3 +94,199 @@ func TestGetExtensionStability(t *testing.T) {
|
|||
t.Errorf("GetExtension() not stable after unmarshaling")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetExtensionDefaults(t *testing.T) {
|
||||
var setFloat64 float64 = 1
|
||||
var setFloat32 float32 = 2
|
||||
var setInt32 int32 = 3
|
||||
var setInt64 int64 = 4
|
||||
var setUint32 uint32 = 5
|
||||
var setUint64 uint64 = 6
|
||||
var setBool = true
|
||||
var setBool2 = false
|
||||
var setString = "Goodnight string"
|
||||
var setBytes = []byte("Goodnight bytes")
|
||||
var setEnum = pb.DefaultsMessage_TWO
|
||||
|
||||
type testcase struct {
|
||||
ext *proto.ExtensionDesc // Extension we are testing.
|
||||
want interface{} // Expected value of extension, or nil (meaning that GetExtension will fail).
|
||||
def interface{} // Expected value of extension after ClearExtension().
|
||||
}
|
||||
tests := []testcase{
|
||||
{pb.E_NoDefaultDouble, setFloat64, nil},
|
||||
{pb.E_NoDefaultFloat, setFloat32, nil},
|
||||
{pb.E_NoDefaultInt32, setInt32, nil},
|
||||
{pb.E_NoDefaultInt64, setInt64, nil},
|
||||
{pb.E_NoDefaultUint32, setUint32, nil},
|
||||
{pb.E_NoDefaultUint64, setUint64, nil},
|
||||
{pb.E_NoDefaultSint32, setInt32, nil},
|
||||
{pb.E_NoDefaultSint64, setInt64, nil},
|
||||
{pb.E_NoDefaultFixed32, setUint32, nil},
|
||||
{pb.E_NoDefaultFixed64, setUint64, nil},
|
||||
{pb.E_NoDefaultSfixed32, setInt32, nil},
|
||||
{pb.E_NoDefaultSfixed64, setInt64, nil},
|
||||
{pb.E_NoDefaultBool, setBool, nil},
|
||||
{pb.E_NoDefaultBool, setBool2, nil},
|
||||
{pb.E_NoDefaultString, setString, nil},
|
||||
{pb.E_NoDefaultBytes, setBytes, nil},
|
||||
{pb.E_NoDefaultEnum, setEnum, nil},
|
||||
{pb.E_DefaultDouble, setFloat64, float64(3.1415)},
|
||||
{pb.E_DefaultFloat, setFloat32, float32(3.14)},
|
||||
{pb.E_DefaultInt32, setInt32, int32(42)},
|
||||
{pb.E_DefaultInt64, setInt64, int64(43)},
|
||||
{pb.E_DefaultUint32, setUint32, uint32(44)},
|
||||
{pb.E_DefaultUint64, setUint64, uint64(45)},
|
||||
{pb.E_DefaultSint32, setInt32, int32(46)},
|
||||
{pb.E_DefaultSint64, setInt64, int64(47)},
|
||||
{pb.E_DefaultFixed32, setUint32, uint32(48)},
|
||||
{pb.E_DefaultFixed64, setUint64, uint64(49)},
|
||||
{pb.E_DefaultSfixed32, setInt32, int32(50)},
|
||||
{pb.E_DefaultSfixed64, setInt64, int64(51)},
|
||||
{pb.E_DefaultBool, setBool, true},
|
||||
{pb.E_DefaultBool, setBool2, true},
|
||||
{pb.E_DefaultString, setString, "Hello, string"},
|
||||
{pb.E_DefaultBytes, setBytes, []byte("Hello, bytes")},
|
||||
{pb.E_DefaultEnum, setEnum, pb.DefaultsMessage_ONE},
|
||||
}
|
||||
|
||||
checkVal := func(test testcase, msg *pb.DefaultsMessage, valWant interface{}) error {
|
||||
val, err := proto.GetExtension(msg, test.ext)
|
||||
if err != nil {
|
||||
if valWant != nil {
|
||||
return fmt.Errorf("GetExtension(): %s", err)
|
||||
}
|
||||
if want := proto.ErrMissingExtension; err != want {
|
||||
return fmt.Errorf("Unexpected error: got %v, want %v", err, want)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// All proto2 extension values are either a pointer to a value or a slice of values.
|
||||
ty := reflect.TypeOf(val)
|
||||
tyWant := reflect.TypeOf(test.ext.ExtensionType)
|
||||
if got, want := ty, tyWant; got != want {
|
||||
return fmt.Errorf("unexpected reflect.TypeOf(): got %v want %v", got, want)
|
||||
}
|
||||
tye := ty.Elem()
|
||||
tyeWant := tyWant.Elem()
|
||||
if got, want := tye, tyeWant; got != want {
|
||||
return fmt.Errorf("unexpected reflect.TypeOf().Elem(): got %v want %v", got, want)
|
||||
}
|
||||
|
||||
// Check the name of the type of the value.
|
||||
// If it is an enum it will be type int32 with the name of the enum.
|
||||
if got, want := tye.Name(), tye.Name(); got != want {
|
||||
return fmt.Errorf("unexpected reflect.TypeOf().Elem().Name(): got %v want %v", got, want)
|
||||
}
|
||||
|
||||
// Check that value is what we expect.
|
||||
// If we have a pointer in val, get the value it points to.
|
||||
valExp := val
|
||||
if ty.Kind() == reflect.Ptr {
|
||||
valExp = reflect.ValueOf(val).Elem().Interface()
|
||||
}
|
||||
if got, want := valExp, valWant; !reflect.DeepEqual(got, want) {
|
||||
return fmt.Errorf("unexpected reflect.DeepEqual(): got %v want %v", got, want)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
setTo := func(test testcase) interface{} {
|
||||
setTo := reflect.ValueOf(test.want)
|
||||
if typ := reflect.TypeOf(test.ext.ExtensionType); typ.Kind() == reflect.Ptr {
|
||||
setTo = reflect.New(typ).Elem()
|
||||
setTo.Set(reflect.New(setTo.Type().Elem()))
|
||||
setTo.Elem().Set(reflect.ValueOf(test.want))
|
||||
}
|
||||
return setTo.Interface()
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
msg := &pb.DefaultsMessage{}
|
||||
name := test.ext.Name
|
||||
|
||||
// Check the initial value.
|
||||
if err := checkVal(test, msg, test.def); err != nil {
|
||||
t.Errorf("%s: %v", name, err)
|
||||
}
|
||||
|
||||
// Set the per-type value and check value.
|
||||
name = fmt.Sprintf("%s (set to %T %v)", name, test.want, test.want)
|
||||
if err := proto.SetExtension(msg, test.ext, setTo(test)); err != nil {
|
||||
t.Errorf("%s: SetExtension(): %v", name, err)
|
||||
continue
|
||||
}
|
||||
if err := checkVal(test, msg, test.want); err != nil {
|
||||
t.Errorf("%s: %v", name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Set and check the value.
|
||||
name += " (cleared)"
|
||||
proto.ClearExtension(msg, test.ext)
|
||||
if err := checkVal(test, msg, test.def); err != nil {
|
||||
t.Errorf("%s: %v", name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtensionsRoundTrip(t *testing.T) {
|
||||
msg := &pb.MyMessage{}
|
||||
ext1 := &pb.Ext{
|
||||
Data: proto.String("hi"),
|
||||
}
|
||||
ext2 := &pb.Ext{
|
||||
Data: proto.String("there"),
|
||||
}
|
||||
exists := proto.HasExtension(msg, pb.E_Ext_More)
|
||||
if exists {
|
||||
t.Error("Extension More present unexpectedly")
|
||||
}
|
||||
if err := proto.SetExtension(msg, pb.E_Ext_More, ext1); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if err := proto.SetExtension(msg, pb.E_Ext_More, ext2); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
e, err := proto.GetExtension(msg, pb.E_Ext_More)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
x, ok := e.(*pb.Ext)
|
||||
if !ok {
|
||||
t.Errorf("e has type %T, expected testdata.Ext", e)
|
||||
} else if *x.Data != "there" {
|
||||
t.Errorf("SetExtension failed to overwrite, got %+v, not 'there'", x)
|
||||
}
|
||||
proto.ClearExtension(msg, pb.E_Ext_More)
|
||||
if _, err = proto.GetExtension(msg, pb.E_Ext_More); err != proto.ErrMissingExtension {
|
||||
t.Errorf("got %v, expected ErrMissingExtension", e)
|
||||
}
|
||||
if _, err := proto.GetExtension(msg, pb.E_X215); err == nil {
|
||||
t.Error("expected bad extension error, got nil")
|
||||
}
|
||||
if err := proto.SetExtension(msg, pb.E_X215, 12); err == nil {
|
||||
t.Error("expected extension err")
|
||||
}
|
||||
if err := proto.SetExtension(msg, pb.E_Ext_More, 12); err == nil {
|
||||
t.Error("expected some sort of type mismatch error, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNilExtension(t *testing.T) {
|
||||
msg := &pb.MyMessage{
|
||||
Count: proto.Int32(1),
|
||||
}
|
||||
if err := proto.SetExtension(msg, pb.E_Ext_Text, proto.String("hello")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := proto.SetExtension(msg, pb.E_Ext_More, (*pb.Ext)(nil)); err == nil {
|
||||
t.Error("expected SetExtension to fail due to a nil extension")
|
||||
} else if want := "proto: SetExtension called with nil value of type *testdata.Ext"; err.Error() != want {
|
||||
t.Errorf("expected error %v, got %v", want, err)
|
||||
}
|
||||
// Note: if the behavior of Marshal is ever changed to ignore nil extensions, update
|
||||
// this test to verify that E_Ext_Text is properly propagated through marshal->unmarshal.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,17 +50,16 @@
|
|||
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.
|
||||
Helpers for getting values are superseded by the
|
||||
GetFoo methods and their use is deprecated.
|
||||
msg.Foo = proto.String("hello") // set field
|
||||
- Constants are defined to hold the default values of all fields that
|
||||
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 with the enum's type name. Enum types have
|
||||
a String method, and a Enum method to assist in message construction.
|
||||
- Nested groups and enums have type names prefixed with the name of
|
||||
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
|
||||
|
|
@ -74,7 +73,7 @@
|
|||
|
||||
package example;
|
||||
|
||||
enum FOO { X = 17; };
|
||||
enum FOO { X = 17; }
|
||||
|
||||
message Test {
|
||||
required string label = 1;
|
||||
|
|
@ -89,7 +88,8 @@
|
|||
|
||||
package example
|
||||
|
||||
import "github.com/gogo/protobuf/proto"
|
||||
import proto "github.com/gogo/protobuf/proto"
|
||||
import math "math"
|
||||
|
||||
type FOO int32
|
||||
const (
|
||||
|
|
@ -110,6 +110,14 @@
|
|||
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"`
|
||||
|
|
@ -118,41 +126,41 @@
|
|||
Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
func (this *Test) Reset() { *this = Test{} }
|
||||
func (this *Test) String() string { return proto.CompactTextString(this) }
|
||||
func (m *Test) Reset() { *m = Test{} }
|
||||
func (m *Test) String() string { return proto.CompactTextString(m) }
|
||||
func (*Test) ProtoMessage() {}
|
||||
const Default_Test_Type int32 = 77
|
||||
|
||||
func (this *Test) GetLabel() string {
|
||||
if this != nil && this.Label != nil {
|
||||
return *this.Label
|
||||
func (m *Test) GetLabel() string {
|
||||
if m != nil && m.Label != nil {
|
||||
return *m.Label
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (this *Test) GetType() int32 {
|
||||
if this != nil && this.Type != nil {
|
||||
return *this.Type
|
||||
func (m *Test) GetType() int32 {
|
||||
if m != nil && m.Type != nil {
|
||||
return *m.Type
|
||||
}
|
||||
return Default_Test_Type
|
||||
}
|
||||
|
||||
func (this *Test) GetOptionalgroup() *Test_OptionalGroup {
|
||||
if this != nil {
|
||||
return this.Optionalgroup
|
||||
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"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
func (this *Test_OptionalGroup) Reset() { *this = Test_OptionalGroup{} }
|
||||
func (this *Test_OptionalGroup) String() string { return proto.CompactTextString(this) }
|
||||
func (m *Test_OptionalGroup) Reset() { *m = Test_OptionalGroup{} }
|
||||
func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) }
|
||||
|
||||
func (this *Test_OptionalGroup) GetRequiredField() string {
|
||||
if this != nil && this.RequiredField != nil {
|
||||
return *this.RequiredField
|
||||
func (m *Test_OptionalGroup) GetRequiredField() string {
|
||||
if m != nil && m.RequiredField != nil {
|
||||
return *m.RequiredField
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
|
@ -169,14 +177,14 @@
|
|||
"log"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"./example.pb"
|
||||
pb "./example.pb"
|
||||
)
|
||||
|
||||
func main() {
|
||||
test := &example.Test{
|
||||
test := &pb.Test{
|
||||
Label: proto.String("hello"),
|
||||
Type: proto.Int32(17),
|
||||
Optionalgroup: &example.Test_OptionalGroup{
|
||||
Optionalgroup: &pb.Test_OptionalGroup{
|
||||
RequiredField: proto.String("good bye"),
|
||||
},
|
||||
}
|
||||
|
|
@ -184,7 +192,7 @@
|
|||
if err != nil {
|
||||
log.Fatal("marshaling error: ", err)
|
||||
}
|
||||
newTest := new(example.Test)
|
||||
newTest := &pb.Test{}
|
||||
err = proto.Unmarshal(data, newTest)
|
||||
if err != nil {
|
||||
log.Fatal("unmarshaling error: ", err)
|
||||
|
|
@ -323,9 +331,7 @@ func Float64(v float64) *float64 {
|
|||
// Uint32 is a helper routine that allocates a new uint32 value
|
||||
// to store v and returns a pointer to it.
|
||||
func Uint32(v uint32) *uint32 {
|
||||
p := new(uint32)
|
||||
*p = v
|
||||
return p
|
||||
return &v
|
||||
}
|
||||
|
||||
// Uint64 is a helper routine that allocates a new uint64 value
|
||||
|
|
@ -379,13 +385,13 @@ func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32,
|
|||
|
||||
// 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 (o *Buffer) DebugPrint(s string, b []byte) {
|
||||
func (p *Buffer) DebugPrint(s string, b []byte) {
|
||||
var u uint64
|
||||
|
||||
obuf := o.buf
|
||||
index := o.index
|
||||
o.buf = b
|
||||
o.index = 0
|
||||
obuf := p.buf
|
||||
index := p.index
|
||||
p.buf = b
|
||||
p.index = 0
|
||||
depth := 0
|
||||
|
||||
fmt.Printf("\n--- %s ---\n", s)
|
||||
|
|
@ -396,12 +402,12 @@ out:
|
|||
fmt.Print(" ")
|
||||
}
|
||||
|
||||
index := o.index
|
||||
if index == len(o.buf) {
|
||||
index := p.index
|
||||
if index == len(p.buf) {
|
||||
break
|
||||
}
|
||||
|
||||
op, err := o.DecodeVarint()
|
||||
op, err := p.DecodeVarint()
|
||||
if err != nil {
|
||||
fmt.Printf("%3d: fetching op err %v\n", index, err)
|
||||
break out
|
||||
|
|
@ -418,7 +424,7 @@ out:
|
|||
case WireBytes:
|
||||
var r []byte
|
||||
|
||||
r, err = o.DecodeRawBytes(false)
|
||||
r, err = p.DecodeRawBytes(false)
|
||||
if err != nil {
|
||||
break out
|
||||
}
|
||||
|
|
@ -439,7 +445,7 @@ out:
|
|||
fmt.Printf("\n")
|
||||
|
||||
case WireFixed32:
|
||||
u, err = o.DecodeFixed32()
|
||||
u, err = p.DecodeFixed32()
|
||||
if err != nil {
|
||||
fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err)
|
||||
break out
|
||||
|
|
@ -447,7 +453,7 @@ out:
|
|||
fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u)
|
||||
|
||||
case WireFixed64:
|
||||
u, err = o.DecodeFixed64()
|
||||
u, err = p.DecodeFixed64()
|
||||
if err != nil {
|
||||
fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err)
|
||||
break out
|
||||
|
|
@ -456,7 +462,7 @@ out:
|
|||
break
|
||||
|
||||
case WireVarint:
|
||||
u, err = o.DecodeVarint()
|
||||
u, err = p.DecodeVarint()
|
||||
if err != nil {
|
||||
fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err)
|
||||
break out
|
||||
|
|
@ -482,12 +488,12 @@ out:
|
|||
}
|
||||
|
||||
if depth != 0 {
|
||||
fmt.Printf("%3d: start-end not balanced %d\n", o.index, depth)
|
||||
fmt.Printf("%3d: start-end not balanced %d\n", p.index, depth)
|
||||
}
|
||||
fmt.Printf("\n")
|
||||
|
||||
o.buf = obuf
|
||||
o.index = index
|
||||
p.buf = obuf
|
||||
p.index = index
|
||||
}
|
||||
|
||||
// SetDefaults sets unset protocol buffer fields to their default values.
|
||||
|
|
@ -601,13 +607,15 @@ func setDefaults(v reflect.Value, recur, zeros bool) {
|
|||
|
||||
for _, ni := range dm.nested {
|
||||
f := v.Field(ni)
|
||||
// f is *T or []*T or map[T]*T
|
||||
switch f.Kind() {
|
||||
case reflect.Ptr:
|
||||
if f.IsNil() {
|
||||
continue
|
||||
}
|
||||
// f is *T or []*T
|
||||
if f.Kind() == reflect.Ptr {
|
||||
setDefaults(f, recur, zeros)
|
||||
} else {
|
||||
|
||||
case reflect.Slice:
|
||||
for i := 0; i < f.Len(); i++ {
|
||||
e := f.Index(i)
|
||||
if e.IsNil() {
|
||||
|
|
@ -615,6 +623,15 @@ func setDefaults(v reflect.Value, recur, zeros bool) {
|
|||
}
|
||||
setDefaults(e, recur, zeros)
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
for _, k := range f.MapKeys() {
|
||||
e := f.MapIndex(k)
|
||||
if e.IsNil() {
|
||||
continue
|
||||
}
|
||||
setDefaults(e, recur, zeros)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -640,10 +657,6 @@ type scalarField struct {
|
|||
value interface{} // the proto-declared default value, or nil
|
||||
}
|
||||
|
||||
func ptrToStruct(t reflect.Type) bool {
|
||||
return t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct
|
||||
}
|
||||
|
||||
// t is a struct type.
|
||||
func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
|
||||
sprop := GetProperties(t)
|
||||
|
|
@ -655,21 +668,62 @@ func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
|
|||
}
|
||||
ft := t.Field(fi).Type
|
||||
|
||||
// nested messages
|
||||
if ptrToStruct(ft) || (ft.Kind() == reflect.Slice && ptrToStruct(ft.Elem())) {
|
||||
sf, nested, err := fieldDefault(ft, prop)
|
||||
switch {
|
||||
case err != nil:
|
||||
log.Print(err)
|
||||
case nested:
|
||||
dm.nested = append(dm.nested, fi)
|
||||
continue
|
||||
case sf != nil:
|
||||
sf.index = fi
|
||||
dm.scalars = append(dm.scalars, *sf)
|
||||
}
|
||||
}
|
||||
|
||||
sf := scalarField{
|
||||
index: fi,
|
||||
kind: ft.Elem().Kind(),
|
||||
return dm
|
||||
}
|
||||
|
||||
// fieldDefault returns the scalarField for field type ft.
|
||||
// sf will be nil if the field can not have a default.
|
||||
// nestedMessage will be true if this is a nested message.
|
||||
// Note that sf.index is not set on return.
|
||||
func fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMessage bool, err error) {
|
||||
var canHaveDefault bool
|
||||
switch ft.Kind() {
|
||||
case reflect.Ptr:
|
||||
if ft.Elem().Kind() == reflect.Struct {
|
||||
nestedMessage = true
|
||||
} else {
|
||||
canHaveDefault = true // proto2 scalar field
|
||||
}
|
||||
|
||||
case reflect.Slice:
|
||||
switch ft.Elem().Kind() {
|
||||
case reflect.Ptr:
|
||||
nestedMessage = true // repeated message
|
||||
case reflect.Uint8:
|
||||
canHaveDefault = true // bytes field
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
if ft.Elem().Kind() == reflect.Ptr {
|
||||
nestedMessage = true // map with message values
|
||||
}
|
||||
}
|
||||
|
||||
if !canHaveDefault {
|
||||
if nestedMessage {
|
||||
return nil, true, nil
|
||||
}
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
// We now know that ft is a pointer or slice.
|
||||
sf = &scalarField{kind: ft.Elem().Kind()}
|
||||
|
||||
// scalar fields without defaults
|
||||
if !prop.HasDefault {
|
||||
dm.scalars = append(dm.scalars, sf)
|
||||
continue
|
||||
return sf, false, nil
|
||||
}
|
||||
|
||||
// a scalar field: either *T or []byte
|
||||
|
|
@ -677,36 +731,31 @@ func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
|
|||
case reflect.Bool:
|
||||
x, err := strconv.ParseBool(prop.Default)
|
||||
if err != nil {
|
||||
log.Printf("proto: bad default bool %q: %v", prop.Default, err)
|
||||
continue
|
||||
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 {
|
||||
log.Printf("proto: bad default float32 %q: %v", prop.Default, err)
|
||||
continue
|
||||
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 {
|
||||
log.Printf("proto: bad default float64 %q: %v", prop.Default, err)
|
||||
continue
|
||||
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 {
|
||||
log.Printf("proto: bad default int32 %q: %v", prop.Default, err)
|
||||
continue
|
||||
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 {
|
||||
log.Printf("proto: bad default int64 %q: %v", prop.Default, err)
|
||||
continue
|
||||
return nil, false, fmt.Errorf("proto: bad default int64 %q: %v", prop.Default, err)
|
||||
}
|
||||
sf.value = x
|
||||
case reflect.String:
|
||||
|
|
@ -717,24 +766,48 @@ func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
|
|||
case reflect.Uint32:
|
||||
x, err := strconv.ParseUint(prop.Default, 10, 32)
|
||||
if err != nil {
|
||||
log.Printf("proto: bad default uint32 %q: %v", prop.Default, err)
|
||||
continue
|
||||
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 {
|
||||
log.Printf("proto: bad default uint64 %q: %v", prop.Default, err)
|
||||
continue
|
||||
return nil, false, fmt.Errorf("proto: bad default uint64 %q: %v", prop.Default, err)
|
||||
}
|
||||
sf.value = x
|
||||
default:
|
||||
log.Printf("proto: unhandled def kind %v", ft.Elem().Kind())
|
||||
continue
|
||||
return nil, false, fmt.Errorf("proto: unhandled def kind %v", ft.Elem().Kind())
|
||||
}
|
||||
|
||||
dm.scalars = append(dm.scalars, sf)
|
||||
return sf, false, nil
|
||||
}
|
||||
|
||||
return dm
|
||||
// Map fields may have key types of non-float scalars, strings and enums.
|
||||
// The easiest way to sort them in some deterministic order is to use fmt.
|
||||
// If this turns out to be inefficient we can always consider other options,
|
||||
// such as doing a Schwartzian transform.
|
||||
|
||||
type mapKeys []reflect.Value
|
||||
|
||||
func (s mapKeys) Len() int { return len(s) }
|
||||
func (s mapKeys) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
func (s mapKeys) Less(i, j int) bool {
|
||||
return fmt.Sprint(s[i].Interface()) < fmt.Sprint(s[j].Interface())
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// +build appengine,!appenginevm
|
||||
// +build appengine
|
||||
|
||||
// This file contains an implementation of proto field accesses using package reflect.
|
||||
// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can
|
||||
|
|
@ -114,6 +114,11 @@ func structPointer_Bool(p structPointer, f field) **bool {
|
|||
return structPointer_ifield(p, f).(**bool)
|
||||
}
|
||||
|
||||
// BoolVal returns the address of a bool field in the struct.
|
||||
func structPointer_BoolVal(p structPointer, f field) *bool {
|
||||
return structPointer_ifield(p, f).(*bool)
|
||||
}
|
||||
|
||||
// BoolSlice returns the address of a []bool field in the struct.
|
||||
func structPointer_BoolSlice(p structPointer, f field) *[]bool {
|
||||
return structPointer_ifield(p, f).(*[]bool)
|
||||
|
|
@ -124,6 +129,11 @@ func structPointer_String(p structPointer, f field) **string {
|
|||
return structPointer_ifield(p, f).(**string)
|
||||
}
|
||||
|
||||
// StringVal returns the address of a string field in the struct.
|
||||
func structPointer_StringVal(p structPointer, f field) *string {
|
||||
return structPointer_ifield(p, f).(*string)
|
||||
}
|
||||
|
||||
// StringSlice returns the address of a []string field in the struct.
|
||||
func structPointer_StringSlice(p structPointer, f field) *[]string {
|
||||
return structPointer_ifield(p, f).(*[]string)
|
||||
|
|
@ -134,6 +144,11 @@ func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
|
|||
return structPointer_ifield(p, f).(*map[int32]Extension)
|
||||
}
|
||||
|
||||
// Map returns the reflect.Value for the address of a map field in the struct.
|
||||
func structPointer_Map(p structPointer, f field, typ reflect.Type) reflect.Value {
|
||||
return structPointer_field(p, f).Addr()
|
||||
}
|
||||
|
||||
// SetStructPointer writes a *struct field in the struct.
|
||||
func structPointer_SetStructPointer(p structPointer, f field, q structPointer) {
|
||||
structPointer_field(p, f).Set(q.v)
|
||||
|
|
@ -235,6 +250,49 @@ func structPointer_Word32(p structPointer, f field) word32 {
|
|||
return word32{structPointer_field(p, f)}
|
||||
}
|
||||
|
||||
// A word32Val represents a field of type int32, uint32, float32, or enum.
|
||||
// That is, v.Type() is int32, uint32, float32, or enum and v is assignable.
|
||||
type word32Val struct {
|
||||
v reflect.Value
|
||||
}
|
||||
|
||||
// Set sets *p to x.
|
||||
func word32Val_Set(p word32Val, x uint32) {
|
||||
switch p.v.Type() {
|
||||
case int32Type:
|
||||
p.v.SetInt(int64(x))
|
||||
return
|
||||
case uint32Type:
|
||||
p.v.SetUint(uint64(x))
|
||||
return
|
||||
case float32Type:
|
||||
p.v.SetFloat(float64(math.Float32frombits(x)))
|
||||
return
|
||||
}
|
||||
|
||||
// must be enum
|
||||
p.v.SetInt(int64(int32(x)))
|
||||
}
|
||||
|
||||
// Get gets the bits pointed at by p, as a uint32.
|
||||
func word32Val_Get(p word32Val) uint32 {
|
||||
elem := p.v
|
||||
switch elem.Kind() {
|
||||
case reflect.Int32:
|
||||
return uint32(elem.Int())
|
||||
case reflect.Uint32:
|
||||
return uint32(elem.Uint())
|
||||
case reflect.Float32:
|
||||
return math.Float32bits(float32(elem.Float()))
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
// Word32Val returns a reference to a int32, uint32, float32, or enum field in the struct.
|
||||
func structPointer_Word32Val(p structPointer, f field) word32Val {
|
||||
return word32Val{structPointer_field(p, f)}
|
||||
}
|
||||
|
||||
// A word32Slice is a slice of 32-bit values.
|
||||
// That is, v.Type() is []int32, []uint32, []float32, or []enum.
|
||||
type word32Slice struct {
|
||||
|
|
@ -339,6 +397,43 @@ func structPointer_Word64(p structPointer, f field) word64 {
|
|||
return word64{structPointer_field(p, f)}
|
||||
}
|
||||
|
||||
// word64Val is like word32Val but for 64-bit values.
|
||||
type word64Val struct {
|
||||
v reflect.Value
|
||||
}
|
||||
|
||||
func word64Val_Set(p word64Val, o *Buffer, x uint64) {
|
||||
switch p.v.Type() {
|
||||
case int64Type:
|
||||
p.v.SetInt(int64(x))
|
||||
return
|
||||
case uint64Type:
|
||||
p.v.SetUint(x)
|
||||
return
|
||||
case float64Type:
|
||||
p.v.SetFloat(math.Float64frombits(x))
|
||||
return
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
func word64Val_Get(p word64Val) uint64 {
|
||||
elem := p.v
|
||||
switch elem.Kind() {
|
||||
case reflect.Int64:
|
||||
return uint64(elem.Int())
|
||||
case reflect.Uint64:
|
||||
return elem.Uint()
|
||||
case reflect.Float64:
|
||||
return math.Float64bits(elem.Float())
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
func structPointer_Word64Val(p structPointer, f field) word64Val {
|
||||
return word64Val{structPointer_field(p, f)}
|
||||
}
|
||||
|
||||
type word64Slice struct {
|
||||
v reflect.Value
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// +build !appengine appenginevm
|
||||
// +build !appengine
|
||||
|
||||
// This file contains the implementation of the proto field accesses using package unsafe.
|
||||
|
||||
|
|
@ -100,6 +100,11 @@ func structPointer_Bool(p structPointer, f field) **bool {
|
|||
return (**bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||
}
|
||||
|
||||
// BoolVal returns the address of a bool field in the struct.
|
||||
func structPointer_BoolVal(p structPointer, f field) *bool {
|
||||
return (*bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||
}
|
||||
|
||||
// BoolSlice returns the address of a []bool field in the struct.
|
||||
func structPointer_BoolSlice(p structPointer, f field) *[]bool {
|
||||
return (*[]bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||
|
|
@ -110,6 +115,11 @@ func structPointer_String(p structPointer, f field) **string {
|
|||
return (**string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||
}
|
||||
|
||||
// StringVal returns the address of a string field in the struct.
|
||||
func structPointer_StringVal(p structPointer, f field) *string {
|
||||
return (*string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||
}
|
||||
|
||||
// StringSlice returns the address of a []string field in the struct.
|
||||
func structPointer_StringSlice(p structPointer, f field) *[]string {
|
||||
return (*[]string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||
|
|
@ -120,6 +130,11 @@ func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
|
|||
return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||
}
|
||||
|
||||
// Map returns the reflect.Value for the address of a map field in the struct.
|
||||
func structPointer_Map(p structPointer, f field, typ reflect.Type) reflect.Value {
|
||||
return reflect.NewAt(typ, unsafe.Pointer(uintptr(p)+uintptr(f)))
|
||||
}
|
||||
|
||||
// SetStructPointer writes a *struct field in the struct.
|
||||
func structPointer_SetStructPointer(p structPointer, f field, q structPointer) {
|
||||
*(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f))) = q
|
||||
|
|
@ -170,6 +185,24 @@ func structPointer_Word32(p structPointer, f field) word32 {
|
|||
return word32((**uint32)(unsafe.Pointer(uintptr(p) + uintptr(f))))
|
||||
}
|
||||
|
||||
// A word32Val is the address of a 32-bit value field.
|
||||
type word32Val *uint32
|
||||
|
||||
// Set sets *p to x.
|
||||
func word32Val_Set(p word32Val, x uint32) {
|
||||
*p = x
|
||||
}
|
||||
|
||||
// Get gets the value pointed at by p.
|
||||
func word32Val_Get(p word32Val) uint32 {
|
||||
return *p
|
||||
}
|
||||
|
||||
// Word32Val returns the address of a *int32, *uint32, *float32, or *enum field in the struct.
|
||||
func structPointer_Word32Val(p structPointer, f field) word32Val {
|
||||
return word32Val((*uint32)(unsafe.Pointer(uintptr(p) + uintptr(f))))
|
||||
}
|
||||
|
||||
// A word32Slice is a slice of 32-bit values.
|
||||
type word32Slice []uint32
|
||||
|
||||
|
|
@ -206,6 +239,21 @@ func structPointer_Word64(p structPointer, f field) word64 {
|
|||
return word64((**uint64)(unsafe.Pointer(uintptr(p) + uintptr(f))))
|
||||
}
|
||||
|
||||
// word64Val is like word32Val but for 64-bit values.
|
||||
type word64Val *uint64
|
||||
|
||||
func word64Val_Set(p word64Val, o *Buffer, x uint64) {
|
||||
*p = x
|
||||
}
|
||||
|
||||
func word64Val_Get(p word64Val) uint64 {
|
||||
return *p
|
||||
}
|
||||
|
||||
func structPointer_Word64Val(p structPointer, f field) word64Val {
|
||||
return word64Val((*uint64)(unsafe.Pointer(uintptr(p) + uintptr(f))))
|
||||
}
|
||||
|
||||
// word64Slice is like word32Slice but for 64-bit values.
|
||||
type word64Slice []uint64
|
||||
|
||||
|
|
|
|||
|
|
@ -87,16 +87,6 @@ func appendStructPointer(base structPointer, f field, typ reflect.Type) structPo
|
|||
return structPointer(unsafe.Pointer(uintptr(unsafe.Pointer(bas)) + uintptr(uintptr(newLen-1)*size)))
|
||||
}
|
||||
|
||||
// RefBool returns a *bool field in the struct.
|
||||
func structPointer_RefBool(p structPointer, f field) *bool {
|
||||
return (*bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||
}
|
||||
|
||||
// RefString returns the address of a string field in the struct.
|
||||
func structPointer_RefString(p structPointer, f field) *string {
|
||||
return (*string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||
}
|
||||
|
||||
func structPointer_FieldPointer(p structPointer, f field) structPointer {
|
||||
return structPointer(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||
}
|
||||
|
|
@ -116,51 +106,3 @@ func structPointer_Add(p structPointer, size field) structPointer {
|
|||
func structPointer_Len(p structPointer, f field) int {
|
||||
return len(*(*[]interface{})(unsafe.Pointer(structPointer_GetRefStructPointer(p, f))))
|
||||
}
|
||||
|
||||
// refWord32 is the address of a 32-bit value field.
|
||||
type refWord32 *uint32
|
||||
|
||||
func refWord32_IsNil(p refWord32) bool {
|
||||
return p == nil
|
||||
}
|
||||
|
||||
func refWord32_Set(p refWord32, o *Buffer, x uint32) {
|
||||
if len(o.uint32s) == 0 {
|
||||
o.uint32s = make([]uint32, uint32PoolSize)
|
||||
}
|
||||
o.uint32s[0] = x
|
||||
*p = o.uint32s[0]
|
||||
o.uint32s = o.uint32s[1:]
|
||||
}
|
||||
|
||||
func refWord32_Get(p refWord32) uint32 {
|
||||
return *p
|
||||
}
|
||||
|
||||
func structPointer_RefWord32(p structPointer, f field) refWord32 {
|
||||
return refWord32((*uint32)(unsafe.Pointer(uintptr(p) + uintptr(f))))
|
||||
}
|
||||
|
||||
// refWord64 is like refWord32 but for 32-bit values.
|
||||
type refWord64 *uint64
|
||||
|
||||
func refWord64_Set(p refWord64, o *Buffer, x uint64) {
|
||||
if len(o.uint64s) == 0 {
|
||||
o.uint64s = make([]uint64, uint64PoolSize)
|
||||
}
|
||||
o.uint64s[0] = x
|
||||
*p = o.uint64s[0]
|
||||
o.uint64s = o.uint64s[1:]
|
||||
}
|
||||
|
||||
func refWord64_IsNil(p refWord64) bool {
|
||||
return p == nil
|
||||
}
|
||||
|
||||
func refWord64_Get(p refWord64) uint64 {
|
||||
return *p
|
||||
}
|
||||
|
||||
func structPointer_RefWord64(p structPointer, f field) refWord64 {
|
||||
return refWord64((*uint64)(unsafe.Pointer(uintptr(p) + uintptr(f))))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -160,6 +160,7 @@ type Properties struct {
|
|||
Repeated bool
|
||||
Packed bool // relevant for repeated primitives only
|
||||
Enum string // set for enum types only
|
||||
proto3 bool // whether this is known to be a proto3 field; set for []byte only
|
||||
|
||||
Default string // default value
|
||||
HasDefault bool // whether an explicit default was provided
|
||||
|
|
@ -178,6 +179,10 @@ type Properties struct {
|
|||
isMarshaler bool
|
||||
isUnmarshaler bool
|
||||
|
||||
mtype reflect.Type // set for map types only
|
||||
mkeyprop *Properties // set for map types only
|
||||
mvalprop *Properties // set for map types only
|
||||
|
||||
size sizer
|
||||
valSize valueSizer // set for bool and numeric types only
|
||||
|
||||
|
|
@ -208,6 +213,9 @@ func (p *Properties) String() string {
|
|||
if p.OrigName != p.Name {
|
||||
s += ",name=" + p.OrigName
|
||||
}
|
||||
if p.proto3 {
|
||||
s += ",proto3"
|
||||
}
|
||||
if len(p.Enum) > 0 {
|
||||
s += ",enum=" + p.Enum
|
||||
}
|
||||
|
|
@ -282,6 +290,8 @@ func (p *Properties) Parse(s string) {
|
|||
p.OrigName = f[5:]
|
||||
case strings.HasPrefix(f, "enum="):
|
||||
p.Enum = f[5:]
|
||||
case f == "proto3":
|
||||
p.proto3 = true
|
||||
case strings.HasPrefix(f, "def="):
|
||||
p.HasDefault = true
|
||||
p.Default = f[4:] // rest of string
|
||||
|
|
@ -305,7 +315,7 @@ func logNoSliceEnc(t1, t2 reflect.Type) {
|
|||
var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem()
|
||||
|
||||
// Initialize the fields for encoding and decoding.
|
||||
func (p *Properties) setEncAndDec(typ reflect.Type, lockGetProp bool) {
|
||||
func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lockGetProp bool) {
|
||||
p.enc = nil
|
||||
p.dec = nil
|
||||
p.size = nil
|
||||
|
|
@ -316,13 +326,96 @@ func (p *Properties) setEncAndDec(typ reflect.Type, lockGetProp bool) {
|
|||
}
|
||||
switch t1 := typ; t1.Kind() {
|
||||
default:
|
||||
if !p.setNonNullableEncAndDec(t1) {
|
||||
fmt.Fprintf(os.Stderr, "proto: no coders for %v\n", t1)
|
||||
|
||||
// proto3 scalar types
|
||||
|
||||
case reflect.Bool:
|
||||
if p.proto3 {
|
||||
p.enc = (*Buffer).enc_proto3_bool
|
||||
p.dec = (*Buffer).dec_proto3_bool
|
||||
p.size = size_proto3_bool
|
||||
} else {
|
||||
p.enc = (*Buffer).enc_ref_bool
|
||||
p.dec = (*Buffer).dec_proto3_bool
|
||||
p.size = size_ref_bool
|
||||
}
|
||||
case reflect.Int32:
|
||||
if p.proto3 {
|
||||
p.enc = (*Buffer).enc_proto3_int32
|
||||
p.dec = (*Buffer).dec_proto3_int32
|
||||
p.size = size_proto3_int32
|
||||
} else {
|
||||
p.enc = (*Buffer).enc_ref_int32
|
||||
p.dec = (*Buffer).dec_proto3_int32
|
||||
p.size = size_ref_int32
|
||||
}
|
||||
case reflect.Uint32:
|
||||
if p.proto3 {
|
||||
p.enc = (*Buffer).enc_proto3_uint32
|
||||
p.dec = (*Buffer).dec_proto3_int32 // can reuse
|
||||
p.size = size_proto3_uint32
|
||||
} else {
|
||||
p.enc = (*Buffer).enc_ref_uint32
|
||||
p.dec = (*Buffer).dec_proto3_int32 // can reuse
|
||||
p.size = size_ref_uint32
|
||||
}
|
||||
case reflect.Int64, reflect.Uint64:
|
||||
if p.proto3 {
|
||||
p.enc = (*Buffer).enc_proto3_int64
|
||||
p.dec = (*Buffer).dec_proto3_int64
|
||||
p.size = size_proto3_int64
|
||||
} else {
|
||||
p.enc = (*Buffer).enc_ref_int64
|
||||
p.dec = (*Buffer).dec_proto3_int64
|
||||
p.size = size_ref_int64
|
||||
}
|
||||
case reflect.Float32:
|
||||
if p.proto3 {
|
||||
p.enc = (*Buffer).enc_proto3_uint32 // can just treat them as bits
|
||||
p.dec = (*Buffer).dec_proto3_int32
|
||||
p.size = size_proto3_uint32
|
||||
} else {
|
||||
p.enc = (*Buffer).enc_ref_uint32 // can just treat them as bits
|
||||
p.dec = (*Buffer).dec_proto3_int32
|
||||
p.size = size_ref_uint32
|
||||
}
|
||||
case reflect.Float64:
|
||||
if p.proto3 {
|
||||
p.enc = (*Buffer).enc_proto3_int64 // can just treat them as bits
|
||||
p.dec = (*Buffer).dec_proto3_int64
|
||||
p.size = size_proto3_int64
|
||||
} else {
|
||||
p.enc = (*Buffer).enc_ref_int64 // can just treat them as bits
|
||||
p.dec = (*Buffer).dec_proto3_int64
|
||||
p.size = size_ref_int64
|
||||
}
|
||||
case reflect.String:
|
||||
if p.proto3 {
|
||||
p.enc = (*Buffer).enc_proto3_string
|
||||
p.dec = (*Buffer).dec_proto3_string
|
||||
p.size = size_proto3_string
|
||||
} else {
|
||||
p.enc = (*Buffer).enc_ref_string
|
||||
p.dec = (*Buffer).dec_proto3_string
|
||||
p.size = size_ref_string
|
||||
}
|
||||
case reflect.Struct:
|
||||
p.stype = typ
|
||||
p.isMarshaler = isMarshaler(typ)
|
||||
p.isUnmarshaler = isUnmarshaler(typ)
|
||||
if p.Wire == "bytes" {
|
||||
p.enc = (*Buffer).enc_ref_struct_message
|
||||
p.dec = (*Buffer).dec_ref_struct_message
|
||||
p.size = size_ref_struct_message
|
||||
} else {
|
||||
fmt.Fprintf(os.Stderr, "proto: no coders for struct %T\n", typ)
|
||||
}
|
||||
|
||||
case reflect.Ptr:
|
||||
switch t2 := t1.Elem(); t2.Kind() {
|
||||
default:
|
||||
fmt.Fprintf(os.Stderr, "proto: no encoder function for %T -> %T\n", t1, t2)
|
||||
fmt.Fprintf(os.Stderr, "proto: no encoder function for %v -> %v\n", t1, t2)
|
||||
break
|
||||
case reflect.Bool:
|
||||
p.enc = (*Buffer).enc_bool
|
||||
|
|
@ -416,6 +509,15 @@ func (p *Properties) setEncAndDec(typ reflect.Type, lockGetProp bool) {
|
|||
p.enc = (*Buffer).enc_slice_byte
|
||||
p.dec = (*Buffer).dec_slice_byte
|
||||
p.size = size_slice_byte
|
||||
// This is a []byte, which is either a bytes field,
|
||||
// or the value of a map field. In the latter case,
|
||||
// we always encode an empty []byte, so we should not
|
||||
// use the proto3 enc/size funcs.
|
||||
// f == nil iff this is the key/value of a map field.
|
||||
if p.proto3 && f != nil {
|
||||
p.enc = (*Buffer).enc_proto3_slice_byte
|
||||
p.size = size_proto3_slice_byte
|
||||
}
|
||||
case reflect.Float32, reflect.Float64:
|
||||
switch t2.Bits() {
|
||||
case 32:
|
||||
|
|
@ -480,6 +582,23 @@ func (p *Properties) setEncAndDec(typ reflect.Type, lockGetProp bool) {
|
|||
case reflect.Struct:
|
||||
p.setSliceOfNonPointerStructs(t1)
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
p.enc = (*Buffer).enc_new_map
|
||||
p.dec = (*Buffer).dec_new_map
|
||||
p.size = size_new_map
|
||||
|
||||
p.mtype = t1
|
||||
p.mkeyprop = &Properties{}
|
||||
p.mkeyprop.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp)
|
||||
p.mvalprop = &Properties{}
|
||||
vtype := p.mtype.Elem()
|
||||
if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice {
|
||||
// The value type is not a message (*T) or bytes ([]byte),
|
||||
// so we need encoders for the pointer to this type.
|
||||
vtype = reflect.PtrTo(vtype)
|
||||
}
|
||||
p.mvalprop.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
|
||||
}
|
||||
p.setTag(lockGetProp)
|
||||
}
|
||||
|
|
@ -539,11 +658,11 @@ func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructF
|
|||
return
|
||||
}
|
||||
p.Parse(tag)
|
||||
p.setEncAndDec(typ, lockGetProp)
|
||||
p.setEncAndDec(typ, f, lockGetProp)
|
||||
}
|
||||
|
||||
var (
|
||||
mutex sync.Mutex
|
||||
propertiesMu sync.RWMutex
|
||||
propertiesMap = make(map[reflect.Type]*StructProperties)
|
||||
)
|
||||
|
||||
|
|
@ -553,13 +672,26 @@ func GetProperties(t reflect.Type) *StructProperties {
|
|||
if t.Kind() != reflect.Struct {
|
||||
panic("proto: type must have kind struct")
|
||||
}
|
||||
mutex.Lock()
|
||||
sprop := getPropertiesLocked(t)
|
||||
mutex.Unlock()
|
||||
|
||||
// Most calls to GetProperties in a long-running program will be
|
||||
// retrieving details for types we have seen before.
|
||||
propertiesMu.RLock()
|
||||
sprop, ok := propertiesMap[t]
|
||||
propertiesMu.RUnlock()
|
||||
if ok {
|
||||
if collectStats {
|
||||
stats.Chit++
|
||||
}
|
||||
return sprop
|
||||
}
|
||||
|
||||
// getPropertiesLocked requires that mutex is held.
|
||||
propertiesMu.Lock()
|
||||
sprop = getPropertiesLocked(t)
|
||||
propertiesMu.Unlock()
|
||||
return sprop
|
||||
}
|
||||
|
||||
// getPropertiesLocked requires that propertiesMu is held.
|
||||
func getPropertiesLocked(t reflect.Type) *StructProperties {
|
||||
if prop, ok := propertiesMap[t]; ok {
|
||||
if collectStats {
|
||||
|
|
|
|||
|
|
@ -49,53 +49,6 @@ func (p *Properties) setCustomEncAndDec(typ reflect.Type) {
|
|||
}
|
||||
}
|
||||
|
||||
func (p *Properties) setNonNullableEncAndDec(typ reflect.Type) bool {
|
||||
switch typ.Kind() {
|
||||
case reflect.Bool:
|
||||
p.enc = (*Buffer).enc_ref_bool
|
||||
p.dec = (*Buffer).dec_ref_bool
|
||||
p.size = size_ref_bool
|
||||
case reflect.Int32:
|
||||
p.enc = (*Buffer).enc_ref_int32
|
||||
p.dec = (*Buffer).dec_ref_int32
|
||||
p.size = size_ref_int32
|
||||
case reflect.Uint32:
|
||||
p.enc = (*Buffer).enc_ref_uint32
|
||||
p.dec = (*Buffer).dec_ref_int32
|
||||
p.size = size_ref_uint32
|
||||
case reflect.Int64, reflect.Uint64:
|
||||
p.enc = (*Buffer).enc_ref_int64
|
||||
p.dec = (*Buffer).dec_ref_int64
|
||||
p.size = size_ref_int64
|
||||
case reflect.Float32:
|
||||
p.enc = (*Buffer).enc_ref_uint32 // can just treat them as bits
|
||||
p.dec = (*Buffer).dec_ref_int32
|
||||
p.size = size_ref_uint32
|
||||
case reflect.Float64:
|
||||
p.enc = (*Buffer).enc_ref_int64 // can just treat them as bits
|
||||
p.dec = (*Buffer).dec_ref_int64
|
||||
p.size = size_ref_int64
|
||||
case reflect.String:
|
||||
p.dec = (*Buffer).dec_ref_string
|
||||
p.enc = (*Buffer).enc_ref_string
|
||||
p.size = size_ref_string
|
||||
case reflect.Struct:
|
||||
p.stype = typ
|
||||
p.isMarshaler = isMarshaler(typ)
|
||||
p.isUnmarshaler = isUnmarshaler(typ)
|
||||
if p.Wire == "bytes" {
|
||||
p.enc = (*Buffer).enc_ref_struct_message
|
||||
p.dec = (*Buffer).dec_ref_struct_message
|
||||
p.size = size_ref_struct_message
|
||||
} else {
|
||||
fmt.Fprintf(os.Stderr, "proto: no coders for struct %T\n", typ)
|
||||
}
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (p *Properties) setSliceOfNonPointerStructs(typ reflect.Type) {
|
||||
t2 := typ.Elem()
|
||||
p.sstype = typ
|
||||
|
|
|
|||
122
Godeps/_workspace/src/github.com/gogo/protobuf/proto/proto3_proto/proto3.pb.go
generated
vendored
Normal file
122
Godeps/_workspace/src/github.com/gogo/protobuf/proto/proto3_proto/proto3.pb.go
generated
vendored
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
// Code generated by protoc-gen-gogo.
|
||||
// source: proto3_proto/proto3.proto
|
||||
// DO NOT EDIT!
|
||||
|
||||
/*
|
||||
Package proto3_proto is a generated protocol buffer package.
|
||||
|
||||
It is generated from these files:
|
||||
proto3_proto/proto3.proto
|
||||
|
||||
It has these top-level messages:
|
||||
Message
|
||||
Nested
|
||||
MessageWithMap
|
||||
*/
|
||||
package proto3_proto
|
||||
|
||||
import proto "github.com/gogo/protobuf/proto"
|
||||
import testdata "github.com/gogo/protobuf/proto/testdata"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
|
||||
type Message_Humour int32
|
||||
|
||||
const (
|
||||
Message_UNKNOWN Message_Humour = 0
|
||||
Message_PUNS Message_Humour = 1
|
||||
Message_SLAPSTICK Message_Humour = 2
|
||||
Message_BILL_BAILEY Message_Humour = 3
|
||||
)
|
||||
|
||||
var Message_Humour_name = map[int32]string{
|
||||
0: "UNKNOWN",
|
||||
1: "PUNS",
|
||||
2: "SLAPSTICK",
|
||||
3: "BILL_BAILEY",
|
||||
}
|
||||
var Message_Humour_value = map[string]int32{
|
||||
"UNKNOWN": 0,
|
||||
"PUNS": 1,
|
||||
"SLAPSTICK": 2,
|
||||
"BILL_BAILEY": 3,
|
||||
}
|
||||
|
||||
func (x Message_Humour) String() string {
|
||||
return proto.EnumName(Message_Humour_name, int32(x))
|
||||
}
|
||||
|
||||
type Message struct {
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Hilarity Message_Humour `protobuf:"varint,2,opt,name=hilarity,proto3,enum=proto3_proto.Message_Humour" json:"hilarity,omitempty"`
|
||||
HeightInCm uint32 `protobuf:"varint,3,opt,name=height_in_cm,proto3" json:"height_in_cm,omitempty"`
|
||||
Data []byte `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"`
|
||||
ResultCount int64 `protobuf:"varint,7,opt,name=result_count,proto3" json:"result_count,omitempty"`
|
||||
TrueScotsman bool `protobuf:"varint,8,opt,name=true_scotsman,proto3" json:"true_scotsman,omitempty"`
|
||||
Score float32 `protobuf:"fixed32,9,opt,name=score,proto3" json:"score,omitempty"`
|
||||
Key []uint64 `protobuf:"varint,5,rep,name=key" json:"key,omitempty"`
|
||||
Nested *Nested `protobuf:"bytes,6,opt,name=nested" json:"nested,omitempty"`
|
||||
Terrain map[string]*Nested `protobuf:"bytes,10,rep,name=terrain" json:"terrain,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value"`
|
||||
Proto2Field *testdata.SubDefaults `protobuf:"bytes,11,opt,name=proto2_field" json:"proto2_field,omitempty"`
|
||||
Proto2Value map[string]*testdata.SubDefaults `protobuf:"bytes,13,rep,name=proto2_value" json:"proto2_value,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value"`
|
||||
}
|
||||
|
||||
func (m *Message) Reset() { *m = Message{} }
|
||||
func (m *Message) String() string { return proto.CompactTextString(m) }
|
||||
func (*Message) ProtoMessage() {}
|
||||
|
||||
func (m *Message) GetNested() *Nested {
|
||||
if m != nil {
|
||||
return m.Nested
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Message) GetTerrain() map[string]*Nested {
|
||||
if m != nil {
|
||||
return m.Terrain
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Message) GetProto2Field() *testdata.SubDefaults {
|
||||
if m != nil {
|
||||
return m.Proto2Field
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Message) GetProto2Value() map[string]*testdata.SubDefaults {
|
||||
if m != nil {
|
||||
return m.Proto2Value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Nested struct {
|
||||
Bunny string `protobuf:"bytes,1,opt,name=bunny,proto3" json:"bunny,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Nested) Reset() { *m = Nested{} }
|
||||
func (m *Nested) String() string { return proto.CompactTextString(m) }
|
||||
func (*Nested) ProtoMessage() {}
|
||||
|
||||
type MessageWithMap struct {
|
||||
ByteMapping map[bool][]byte `protobuf:"bytes,1,rep,name=byte_mapping" json:"byte_mapping,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
}
|
||||
|
||||
func (m *MessageWithMap) Reset() { *m = MessageWithMap{} }
|
||||
func (m *MessageWithMap) String() string { return proto.CompactTextString(m) }
|
||||
func (*MessageWithMap) ProtoMessage() {}
|
||||
|
||||
func (m *MessageWithMap) GetByteMapping() map[bool][]byte {
|
||||
if m != nil {
|
||||
return m.ByteMapping
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterEnum("proto3_proto.Message_Humour", Message_Humour_name, Message_Humour_value)
|
||||
}
|
||||
68
Godeps/_workspace/src/github.com/gogo/protobuf/proto/proto3_proto/proto3.proto
generated
vendored
Normal file
68
Godeps/_workspace/src/github.com/gogo/protobuf/proto/proto3_proto/proto3.proto
generated
vendored
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto3_proto;
|
||||
|
||||
import "github.com/gogo/protobuf/proto/testdata/test.proto";
|
||||
|
||||
message Message {
|
||||
enum Humour {
|
||||
UNKNOWN = 0;
|
||||
PUNS = 1;
|
||||
SLAPSTICK = 2;
|
||||
BILL_BAILEY = 3;
|
||||
}
|
||||
|
||||
string name = 1;
|
||||
Humour hilarity = 2;
|
||||
uint32 height_in_cm = 3;
|
||||
bytes data = 4;
|
||||
int64 result_count = 7;
|
||||
bool true_scotsman = 8;
|
||||
float score = 9;
|
||||
|
||||
repeated uint64 key = 5;
|
||||
Nested nested = 6;
|
||||
|
||||
map<string, Nested> terrain = 10;
|
||||
testdata.SubDefaults proto2_field = 11;
|
||||
map<string, testdata.SubDefaults> proto2_value = 13;
|
||||
}
|
||||
|
||||
message Nested {
|
||||
string bunny = 1;
|
||||
}
|
||||
|
||||
message MessageWithMap {
|
||||
map<bool, bytes> byte_mapping = 1;
|
||||
}
|
||||
125
Godeps/_workspace/src/github.com/gogo/protobuf/proto/proto3_test.go
generated
vendored
Normal file
125
Godeps/_workspace/src/github.com/gogo/protobuf/proto/proto3_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
pb "github.com/gogo/protobuf/proto/proto3_proto"
|
||||
tpb "github.com/gogo/protobuf/proto/testdata"
|
||||
)
|
||||
|
||||
func TestProto3ZeroValues(t *testing.T) {
|
||||
tests := []struct {
|
||||
desc string
|
||||
m proto.Message
|
||||
}{
|
||||
{"zero message", &pb.Message{}},
|
||||
{"empty bytes field", &pb.Message{Data: []byte{}}},
|
||||
}
|
||||
for _, test := range tests {
|
||||
b, err := proto.Marshal(test.m)
|
||||
if err != nil {
|
||||
t.Errorf("%s: proto.Marshal: %v", test.desc, err)
|
||||
continue
|
||||
}
|
||||
if len(b) > 0 {
|
||||
t.Errorf("%s: Encoding is non-empty: %q", test.desc, b)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRoundTripProto3(t *testing.T) {
|
||||
m := &pb.Message{
|
||||
Name: "David", // (2 | 1<<3): 0x0a 0x05 "David"
|
||||
Hilarity: pb.Message_PUNS, // (0 | 2<<3): 0x10 0x01
|
||||
HeightInCm: 178, // (0 | 3<<3): 0x18 0xb2 0x01
|
||||
Data: []byte("roboto"), // (2 | 4<<3): 0x20 0x06 "roboto"
|
||||
ResultCount: 47, // (0 | 7<<3): 0x38 0x2f
|
||||
TrueScotsman: true, // (0 | 8<<3): 0x40 0x01
|
||||
Score: 8.1, // (5 | 9<<3): 0x4d <8.1>
|
||||
|
||||
Key: []uint64{1, 0xdeadbeef},
|
||||
Nested: &pb.Nested{
|
||||
Bunny: "Monty",
|
||||
},
|
||||
}
|
||||
t.Logf(" m: %v", m)
|
||||
|
||||
b, err := proto.Marshal(m)
|
||||
if err != nil {
|
||||
t.Fatalf("proto.Marshal: %v", err)
|
||||
}
|
||||
t.Logf(" b: %q", b)
|
||||
|
||||
m2 := new(pb.Message)
|
||||
if err := proto.Unmarshal(b, m2); err != nil {
|
||||
t.Fatalf("proto.Unmarshal: %v", err)
|
||||
}
|
||||
t.Logf("m2: %v", m2)
|
||||
|
||||
if !proto.Equal(m, m2) {
|
||||
t.Errorf("proto.Equal returned false:\n m: %v\nm2: %v", m, m2)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProto3SetDefaults(t *testing.T) {
|
||||
in := &pb.Message{
|
||||
Terrain: map[string]*pb.Nested{
|
||||
"meadow": new(pb.Nested),
|
||||
},
|
||||
Proto2Field: new(tpb.SubDefaults),
|
||||
Proto2Value: map[string]*tpb.SubDefaults{
|
||||
"badlands": new(tpb.SubDefaults),
|
||||
},
|
||||
}
|
||||
|
||||
got := proto.Clone(in).(*pb.Message)
|
||||
proto.SetDefaults(got)
|
||||
|
||||
// There are no defaults in proto3. Everything should be the zero value, but
|
||||
// we need to remember to set defaults for nested proto2 messages.
|
||||
want := &pb.Message{
|
||||
Terrain: map[string]*pb.Nested{
|
||||
"meadow": new(pb.Nested),
|
||||
},
|
||||
Proto2Field: &tpb.SubDefaults{N: proto.Int64(7)},
|
||||
Proto2Value: map[string]*tpb.SubDefaults{
|
||||
"badlands": {N: proto.Int64(7)},
|
||||
},
|
||||
}
|
||||
|
||||
if !proto.Equal(got, want) {
|
||||
t.Errorf("with in = %v\nproto.SetDefaults(in) =>\ngot %v\nwant %v", in, got, want)
|
||||
}
|
||||
}
|
||||
|
|
@ -33,10 +33,12 @@ package proto_test
|
|||
|
||||
import (
|
||||
"log"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
pb "./testdata"
|
||||
. "github.com/gogo/protobuf/proto"
|
||||
proto3pb "github.com/gogo/protobuf/proto/proto3_proto"
|
||||
pb "github.com/gogo/protobuf/proto/testdata"
|
||||
)
|
||||
|
||||
var messageWithExtension1 = &pb.MyMessage{Count: Int32(7)}
|
||||
|
|
@ -102,6 +104,26 @@ var SizeTests = []struct {
|
|||
{"unrecognized", &pb.MoreRepeated{XXX_unrecognized: []byte{13<<3 | 0, 4}}},
|
||||
{"extension (unencoded)", messageWithExtension1},
|
||||
{"extension (encoded)", messageWithExtension3},
|
||||
// proto3 message
|
||||
{"proto3 empty", &proto3pb.Message{}},
|
||||
{"proto3 bool", &proto3pb.Message{TrueScotsman: true}},
|
||||
{"proto3 int64", &proto3pb.Message{ResultCount: 1}},
|
||||
{"proto3 uint32", &proto3pb.Message{HeightInCm: 123}},
|
||||
{"proto3 float", &proto3pb.Message{Score: 12.6}},
|
||||
{"proto3 string", &proto3pb.Message{Name: "Snezana"}},
|
||||
{"proto3 bytes", &proto3pb.Message{Data: []byte("wowsa")}},
|
||||
{"proto3 bytes, empty", &proto3pb.Message{Data: []byte{}}},
|
||||
{"proto3 enum", &proto3pb.Message{Hilarity: proto3pb.Message_PUNS}},
|
||||
{"proto3 map field with empty bytes", &proto3pb.MessageWithMap{ByteMapping: map[bool][]byte{false: {}}}},
|
||||
|
||||
{"map field", &pb.MessageWithMap{NameMapping: map[int32]string{1: "Rob", 7: "Andrew"}}},
|
||||
{"map field with message", &pb.MessageWithMap{MsgMapping: map[int64]*pb.FloatingPoint{0x7001: {F: Float64(2.0)}}}},
|
||||
{"map field with bytes", &pb.MessageWithMap{ByteMapping: map[bool][]byte{true: []byte("this time for sure")}}},
|
||||
{"map field with empty bytes", &pb.MessageWithMap{ByteMapping: map[bool][]byte{true: {}}}},
|
||||
|
||||
{"map field with big entry", &pb.MessageWithMap{NameMapping: map[int32]string{8: strings.Repeat("x", 125)}}},
|
||||
{"map field with big key and val", &pb.MessageWithMap{StrToStr: map[string]string{strings.Repeat("x", 70): strings.Repeat("y", 70)}}},
|
||||
{"map field with big numeric key", &pb.MessageWithMap{NameMapping: map[int32]string{0xf00d: "om nom nom"}}},
|
||||
}
|
||||
|
||||
func TestSize(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ func Skip(data []byte) (n int, err error) {
|
|||
return index, nil
|
||||
case 3:
|
||||
for {
|
||||
var wire uint64
|
||||
var innerWire uint64
|
||||
var start int = index
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if index >= l {
|
||||
|
|
@ -88,13 +88,13 @@ func Skip(data []byte) (n int, err error) {
|
|||
}
|
||||
b := data[index]
|
||||
index++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
innerWire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
innerWireType := int(innerWire & 0x7)
|
||||
if innerWireType == 4 {
|
||||
break
|
||||
}
|
||||
next, err := Skip(data[start:])
|
||||
|
|
|
|||
|
|
@ -32,16 +32,6 @@
|
|||
all: regenerate
|
||||
|
||||
regenerate:
|
||||
rm -f test.pb.go
|
||||
protoc --gogo_out=. test.proto
|
||||
go install github.com/gogo/protobuf/protoc-gen-gogo/version/protoc-min-version
|
||||
protoc-min-version --version="3.0.0" --gogo_out=. test.proto
|
||||
|
||||
# The following rules are just aids to development. Not needed for typical testing.
|
||||
|
||||
diff: regenerate
|
||||
hg diff test.pb.go
|
||||
|
||||
restore:
|
||||
cp test.pb.go.golden test.pb.go
|
||||
|
||||
preserve:
|
||||
cp test.pb.go test.pb.go.golden
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ It has these top-level messages:
|
|||
OtherMessage
|
||||
MyMessage
|
||||
Ext
|
||||
DefaultsMessage
|
||||
MyMessageSet
|
||||
Empty
|
||||
MessageList
|
||||
|
|
@ -33,6 +34,7 @@ It has these top-level messages:
|
|||
GroupOld
|
||||
GroupNew
|
||||
FloatingPoint
|
||||
MessageWithMap
|
||||
*/
|
||||
package testdata
|
||||
|
||||
|
|
@ -180,6 +182,42 @@ func (x *MyMessage_Color) UnmarshalJSON(data []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
type DefaultsMessage_DefaultsEnum int32
|
||||
|
||||
const (
|
||||
DefaultsMessage_ZERO DefaultsMessage_DefaultsEnum = 0
|
||||
DefaultsMessage_ONE DefaultsMessage_DefaultsEnum = 1
|
||||
DefaultsMessage_TWO DefaultsMessage_DefaultsEnum = 2
|
||||
)
|
||||
|
||||
var DefaultsMessage_DefaultsEnum_name = map[int32]string{
|
||||
0: "ZERO",
|
||||
1: "ONE",
|
||||
2: "TWO",
|
||||
}
|
||||
var DefaultsMessage_DefaultsEnum_value = map[string]int32{
|
||||
"ZERO": 0,
|
||||
"ONE": 1,
|
||||
"TWO": 2,
|
||||
}
|
||||
|
||||
func (x DefaultsMessage_DefaultsEnum) Enum() *DefaultsMessage_DefaultsEnum {
|
||||
p := new(DefaultsMessage_DefaultsEnum)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
func (x DefaultsMessage_DefaultsEnum) String() string {
|
||||
return proto.EnumName(DefaultsMessage_DefaultsEnum_name, int32(x))
|
||||
}
|
||||
func (x *DefaultsMessage_DefaultsEnum) UnmarshalJSON(data []byte) error {
|
||||
value, err := proto.UnmarshalJSONEnum(DefaultsMessage_DefaultsEnum_value, data, "DefaultsMessage_DefaultsEnum")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*x = DefaultsMessage_DefaultsEnum(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
type Defaults_Color int32
|
||||
|
||||
const (
|
||||
|
|
@ -1401,6 +1439,29 @@ var E_Ext_Number = &proto.ExtensionDesc{
|
|||
Tag: "varint,105,opt,name=number",
|
||||
}
|
||||
|
||||
type DefaultsMessage struct {
|
||||
XXX_extensions map[int32]proto.Extension `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *DefaultsMessage) Reset() { *m = DefaultsMessage{} }
|
||||
func (m *DefaultsMessage) String() string { return proto.CompactTextString(m) }
|
||||
func (*DefaultsMessage) ProtoMessage() {}
|
||||
|
||||
var extRange_DefaultsMessage = []proto.ExtensionRange{
|
||||
{100, 536870911},
|
||||
}
|
||||
|
||||
func (*DefaultsMessage) ExtensionRangeArray() []proto.ExtensionRange {
|
||||
return extRange_DefaultsMessage
|
||||
}
|
||||
func (m *DefaultsMessage) ExtensionMap() map[int32]proto.Extension {
|
||||
if m.XXX_extensions == nil {
|
||||
m.XXX_extensions = make(map[int32]proto.Extension)
|
||||
}
|
||||
return m.XXX_extensions
|
||||
}
|
||||
|
||||
type MyMessageSet struct {
|
||||
XXX_extensions map[int32]proto.Extension `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
|
|
@ -1885,6 +1946,46 @@ func (m *FloatingPoint) GetF() float64 {
|
|||
return 0
|
||||
}
|
||||
|
||||
type MessageWithMap struct {
|
||||
NameMapping map[int32]string `protobuf:"bytes,1,rep,name=name_mapping" json:"name_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
|
||||
MsgMapping map[int64]*FloatingPoint `protobuf:"bytes,2,rep,name=msg_mapping" json:"msg_mapping,omitempty" protobuf_key:"zigzag64,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
|
||||
ByteMapping map[bool][]byte `protobuf:"bytes,3,rep,name=byte_mapping" json:"byte_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
|
||||
StrToStr map[string]string `protobuf:"bytes,4,rep,name=str_to_str" json:"str_to_str,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *MessageWithMap) Reset() { *m = MessageWithMap{} }
|
||||
func (m *MessageWithMap) String() string { return proto.CompactTextString(m) }
|
||||
func (*MessageWithMap) ProtoMessage() {}
|
||||
|
||||
func (m *MessageWithMap) GetNameMapping() map[int32]string {
|
||||
if m != nil {
|
||||
return m.NameMapping
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MessageWithMap) GetMsgMapping() map[int64]*FloatingPoint {
|
||||
if m != nil {
|
||||
return m.MsgMapping
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MessageWithMap) GetByteMapping() map[bool][]byte {
|
||||
if m != nil {
|
||||
return m.ByteMapping
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MessageWithMap) GetStrToStr() map[string]string {
|
||||
if m != nil {
|
||||
return m.StrToStr
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var E_Greeting = &proto.ExtensionDesc{
|
||||
ExtendedType: (*MyMessage)(nil),
|
||||
ExtensionType: ([]string)(nil),
|
||||
|
|
@ -1893,6 +1994,262 @@ var E_Greeting = &proto.ExtensionDesc{
|
|||
Tag: "bytes,106,rep,name=greeting",
|
||||
}
|
||||
|
||||
var E_NoDefaultDouble = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*float64)(nil),
|
||||
Field: 101,
|
||||
Name: "testdata.no_default_double",
|
||||
Tag: "fixed64,101,opt,name=no_default_double",
|
||||
}
|
||||
|
||||
var E_NoDefaultFloat = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*float32)(nil),
|
||||
Field: 102,
|
||||
Name: "testdata.no_default_float",
|
||||
Tag: "fixed32,102,opt,name=no_default_float",
|
||||
}
|
||||
|
||||
var E_NoDefaultInt32 = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*int32)(nil),
|
||||
Field: 103,
|
||||
Name: "testdata.no_default_int32",
|
||||
Tag: "varint,103,opt,name=no_default_int32",
|
||||
}
|
||||
|
||||
var E_NoDefaultInt64 = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*int64)(nil),
|
||||
Field: 104,
|
||||
Name: "testdata.no_default_int64",
|
||||
Tag: "varint,104,opt,name=no_default_int64",
|
||||
}
|
||||
|
||||
var E_NoDefaultUint32 = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*uint32)(nil),
|
||||
Field: 105,
|
||||
Name: "testdata.no_default_uint32",
|
||||
Tag: "varint,105,opt,name=no_default_uint32",
|
||||
}
|
||||
|
||||
var E_NoDefaultUint64 = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*uint64)(nil),
|
||||
Field: 106,
|
||||
Name: "testdata.no_default_uint64",
|
||||
Tag: "varint,106,opt,name=no_default_uint64",
|
||||
}
|
||||
|
||||
var E_NoDefaultSint32 = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*int32)(nil),
|
||||
Field: 107,
|
||||
Name: "testdata.no_default_sint32",
|
||||
Tag: "zigzag32,107,opt,name=no_default_sint32",
|
||||
}
|
||||
|
||||
var E_NoDefaultSint64 = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*int64)(nil),
|
||||
Field: 108,
|
||||
Name: "testdata.no_default_sint64",
|
||||
Tag: "zigzag64,108,opt,name=no_default_sint64",
|
||||
}
|
||||
|
||||
var E_NoDefaultFixed32 = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*uint32)(nil),
|
||||
Field: 109,
|
||||
Name: "testdata.no_default_fixed32",
|
||||
Tag: "fixed32,109,opt,name=no_default_fixed32",
|
||||
}
|
||||
|
||||
var E_NoDefaultFixed64 = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*uint64)(nil),
|
||||
Field: 110,
|
||||
Name: "testdata.no_default_fixed64",
|
||||
Tag: "fixed64,110,opt,name=no_default_fixed64",
|
||||
}
|
||||
|
||||
var E_NoDefaultSfixed32 = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*int32)(nil),
|
||||
Field: 111,
|
||||
Name: "testdata.no_default_sfixed32",
|
||||
Tag: "fixed32,111,opt,name=no_default_sfixed32",
|
||||
}
|
||||
|
||||
var E_NoDefaultSfixed64 = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*int64)(nil),
|
||||
Field: 112,
|
||||
Name: "testdata.no_default_sfixed64",
|
||||
Tag: "fixed64,112,opt,name=no_default_sfixed64",
|
||||
}
|
||||
|
||||
var E_NoDefaultBool = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*bool)(nil),
|
||||
Field: 113,
|
||||
Name: "testdata.no_default_bool",
|
||||
Tag: "varint,113,opt,name=no_default_bool",
|
||||
}
|
||||
|
||||
var E_NoDefaultString = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*string)(nil),
|
||||
Field: 114,
|
||||
Name: "testdata.no_default_string",
|
||||
Tag: "bytes,114,opt,name=no_default_string",
|
||||
}
|
||||
|
||||
var E_NoDefaultBytes = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: ([]byte)(nil),
|
||||
Field: 115,
|
||||
Name: "testdata.no_default_bytes",
|
||||
Tag: "bytes,115,opt,name=no_default_bytes",
|
||||
}
|
||||
|
||||
var E_NoDefaultEnum = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*DefaultsMessage_DefaultsEnum)(nil),
|
||||
Field: 116,
|
||||
Name: "testdata.no_default_enum",
|
||||
Tag: "varint,116,opt,name=no_default_enum,enum=testdata.DefaultsMessage_DefaultsEnum",
|
||||
}
|
||||
|
||||
var E_DefaultDouble = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*float64)(nil),
|
||||
Field: 201,
|
||||
Name: "testdata.default_double",
|
||||
Tag: "fixed64,201,opt,name=default_double,def=3.1415",
|
||||
}
|
||||
|
||||
var E_DefaultFloat = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*float32)(nil),
|
||||
Field: 202,
|
||||
Name: "testdata.default_float",
|
||||
Tag: "fixed32,202,opt,name=default_float,def=3.14",
|
||||
}
|
||||
|
||||
var E_DefaultInt32 = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*int32)(nil),
|
||||
Field: 203,
|
||||
Name: "testdata.default_int32",
|
||||
Tag: "varint,203,opt,name=default_int32,def=42",
|
||||
}
|
||||
|
||||
var E_DefaultInt64 = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*int64)(nil),
|
||||
Field: 204,
|
||||
Name: "testdata.default_int64",
|
||||
Tag: "varint,204,opt,name=default_int64,def=43",
|
||||
}
|
||||
|
||||
var E_DefaultUint32 = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*uint32)(nil),
|
||||
Field: 205,
|
||||
Name: "testdata.default_uint32",
|
||||
Tag: "varint,205,opt,name=default_uint32,def=44",
|
||||
}
|
||||
|
||||
var E_DefaultUint64 = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*uint64)(nil),
|
||||
Field: 206,
|
||||
Name: "testdata.default_uint64",
|
||||
Tag: "varint,206,opt,name=default_uint64,def=45",
|
||||
}
|
||||
|
||||
var E_DefaultSint32 = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*int32)(nil),
|
||||
Field: 207,
|
||||
Name: "testdata.default_sint32",
|
||||
Tag: "zigzag32,207,opt,name=default_sint32,def=46",
|
||||
}
|
||||
|
||||
var E_DefaultSint64 = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*int64)(nil),
|
||||
Field: 208,
|
||||
Name: "testdata.default_sint64",
|
||||
Tag: "zigzag64,208,opt,name=default_sint64,def=47",
|
||||
}
|
||||
|
||||
var E_DefaultFixed32 = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*uint32)(nil),
|
||||
Field: 209,
|
||||
Name: "testdata.default_fixed32",
|
||||
Tag: "fixed32,209,opt,name=default_fixed32,def=48",
|
||||
}
|
||||
|
||||
var E_DefaultFixed64 = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*uint64)(nil),
|
||||
Field: 210,
|
||||
Name: "testdata.default_fixed64",
|
||||
Tag: "fixed64,210,opt,name=default_fixed64,def=49",
|
||||
}
|
||||
|
||||
var E_DefaultSfixed32 = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*int32)(nil),
|
||||
Field: 211,
|
||||
Name: "testdata.default_sfixed32",
|
||||
Tag: "fixed32,211,opt,name=default_sfixed32,def=50",
|
||||
}
|
||||
|
||||
var E_DefaultSfixed64 = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*int64)(nil),
|
||||
Field: 212,
|
||||
Name: "testdata.default_sfixed64",
|
||||
Tag: "fixed64,212,opt,name=default_sfixed64,def=51",
|
||||
}
|
||||
|
||||
var E_DefaultBool = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*bool)(nil),
|
||||
Field: 213,
|
||||
Name: "testdata.default_bool",
|
||||
Tag: "varint,213,opt,name=default_bool,def=1",
|
||||
}
|
||||
|
||||
var E_DefaultString = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*string)(nil),
|
||||
Field: 214,
|
||||
Name: "testdata.default_string",
|
||||
Tag: "bytes,214,opt,name=default_string,def=Hello, string",
|
||||
}
|
||||
|
||||
var E_DefaultBytes = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: ([]byte)(nil),
|
||||
Field: 215,
|
||||
Name: "testdata.default_bytes",
|
||||
Tag: "bytes,215,opt,name=default_bytes,def=Hello, bytes",
|
||||
}
|
||||
|
||||
var E_DefaultEnum = &proto.ExtensionDesc{
|
||||
ExtendedType: (*DefaultsMessage)(nil),
|
||||
ExtensionType: (*DefaultsMessage_DefaultsEnum)(nil),
|
||||
Field: 216,
|
||||
Name: "testdata.default_enum",
|
||||
Tag: "varint,216,opt,name=default_enum,enum=testdata.DefaultsMessage_DefaultsEnum,def=1",
|
||||
}
|
||||
|
||||
var E_X201 = &proto.ExtensionDesc{
|
||||
ExtendedType: (*MyMessageSet)(nil),
|
||||
ExtensionType: (*Empty)(nil),
|
||||
|
|
@ -2297,12 +2654,45 @@ func init() {
|
|||
proto.RegisterEnum("testdata.FOO", FOO_name, FOO_value)
|
||||
proto.RegisterEnum("testdata.GoTest_KIND", GoTest_KIND_name, GoTest_KIND_value)
|
||||
proto.RegisterEnum("testdata.MyMessage_Color", MyMessage_Color_name, MyMessage_Color_value)
|
||||
proto.RegisterEnum("testdata.DefaultsMessage_DefaultsEnum", DefaultsMessage_DefaultsEnum_name, DefaultsMessage_DefaultsEnum_value)
|
||||
proto.RegisterEnum("testdata.Defaults_Color", Defaults_Color_name, Defaults_Color_value)
|
||||
proto.RegisterEnum("testdata.RepeatedEnum_Color", RepeatedEnum_Color_name, RepeatedEnum_Color_value)
|
||||
proto.RegisterExtension(E_Ext_More)
|
||||
proto.RegisterExtension(E_Ext_Text)
|
||||
proto.RegisterExtension(E_Ext_Number)
|
||||
proto.RegisterExtension(E_Greeting)
|
||||
proto.RegisterExtension(E_NoDefaultDouble)
|
||||
proto.RegisterExtension(E_NoDefaultFloat)
|
||||
proto.RegisterExtension(E_NoDefaultInt32)
|
||||
proto.RegisterExtension(E_NoDefaultInt64)
|
||||
proto.RegisterExtension(E_NoDefaultUint32)
|
||||
proto.RegisterExtension(E_NoDefaultUint64)
|
||||
proto.RegisterExtension(E_NoDefaultSint32)
|
||||
proto.RegisterExtension(E_NoDefaultSint64)
|
||||
proto.RegisterExtension(E_NoDefaultFixed32)
|
||||
proto.RegisterExtension(E_NoDefaultFixed64)
|
||||
proto.RegisterExtension(E_NoDefaultSfixed32)
|
||||
proto.RegisterExtension(E_NoDefaultSfixed64)
|
||||
proto.RegisterExtension(E_NoDefaultBool)
|
||||
proto.RegisterExtension(E_NoDefaultString)
|
||||
proto.RegisterExtension(E_NoDefaultBytes)
|
||||
proto.RegisterExtension(E_NoDefaultEnum)
|
||||
proto.RegisterExtension(E_DefaultDouble)
|
||||
proto.RegisterExtension(E_DefaultFloat)
|
||||
proto.RegisterExtension(E_DefaultInt32)
|
||||
proto.RegisterExtension(E_DefaultInt64)
|
||||
proto.RegisterExtension(E_DefaultUint32)
|
||||
proto.RegisterExtension(E_DefaultUint64)
|
||||
proto.RegisterExtension(E_DefaultSint32)
|
||||
proto.RegisterExtension(E_DefaultSint64)
|
||||
proto.RegisterExtension(E_DefaultFixed32)
|
||||
proto.RegisterExtension(E_DefaultFixed64)
|
||||
proto.RegisterExtension(E_DefaultSfixed32)
|
||||
proto.RegisterExtension(E_DefaultSfixed64)
|
||||
proto.RegisterExtension(E_DefaultBool)
|
||||
proto.RegisterExtension(E_DefaultString)
|
||||
proto.RegisterExtension(E_DefaultBytes)
|
||||
proto.RegisterExtension(E_DefaultEnum)
|
||||
proto.RegisterExtension(E_X201)
|
||||
proto.RegisterExtension(E_X202)
|
||||
proto.RegisterExtension(E_X203)
|
||||
|
|
|
|||
|
|
@ -277,6 +277,51 @@ extend MyMessage {
|
|||
repeated string greeting = 106;
|
||||
}
|
||||
|
||||
message DefaultsMessage {
|
||||
enum DefaultsEnum {
|
||||
ZERO = 0;
|
||||
ONE = 1;
|
||||
TWO = 2;
|
||||
};
|
||||
extensions 100 to max;
|
||||
}
|
||||
|
||||
extend DefaultsMessage {
|
||||
optional double no_default_double = 101;
|
||||
optional float no_default_float = 102;
|
||||
optional int32 no_default_int32 = 103;
|
||||
optional int64 no_default_int64 = 104;
|
||||
optional uint32 no_default_uint32 = 105;
|
||||
optional uint64 no_default_uint64 = 106;
|
||||
optional sint32 no_default_sint32 = 107;
|
||||
optional sint64 no_default_sint64 = 108;
|
||||
optional fixed32 no_default_fixed32 = 109;
|
||||
optional fixed64 no_default_fixed64 = 110;
|
||||
optional sfixed32 no_default_sfixed32 = 111;
|
||||
optional sfixed64 no_default_sfixed64 = 112;
|
||||
optional bool no_default_bool = 113;
|
||||
optional string no_default_string = 114;
|
||||
optional bytes no_default_bytes = 115;
|
||||
optional DefaultsMessage.DefaultsEnum no_default_enum = 116;
|
||||
|
||||
optional double default_double = 201 [default = 3.1415];
|
||||
optional float default_float = 202 [default = 3.14];
|
||||
optional int32 default_int32 = 203 [default = 42];
|
||||
optional int64 default_int64 = 204 [default = 43];
|
||||
optional uint32 default_uint32 = 205 [default = 44];
|
||||
optional uint64 default_uint64 = 206 [default = 45];
|
||||
optional sint32 default_sint32 = 207 [default = 46];
|
||||
optional sint64 default_sint64 = 208 [default = 47];
|
||||
optional fixed32 default_fixed32 = 209 [default = 48];
|
||||
optional fixed64 default_fixed64 = 210 [default = 49];
|
||||
optional sfixed32 default_sfixed32 = 211 [default = 50];
|
||||
optional sfixed64 default_sfixed64 = 212 [default = 51];
|
||||
optional bool default_bool = 213 [default = true];
|
||||
optional string default_string = 214 [default = "Hello, string"];
|
||||
optional bytes default_bytes = 215 [default = "Hello, bytes"];
|
||||
optional DefaultsMessage.DefaultsEnum default_enum = 216 [default = ONE];
|
||||
}
|
||||
|
||||
message MyMessageSet {
|
||||
option message_set_wire_format = true;
|
||||
extensions 100 to max;
|
||||
|
|
@ -426,3 +471,10 @@ message GroupNew {
|
|||
message FloatingPoint {
|
||||
required double f = 1;
|
||||
}
|
||||
|
||||
message MessageWithMap {
|
||||
map<int32, string> name_mapping = 1;
|
||||
map<sint64, FloatingPoint> msg_mapping = 2;
|
||||
map<bool, bytes> byte_mapping = 3;
|
||||
map<string, string> str_to_str = 4;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ import (
|
|||
"io"
|
||||
"log"
|
||||
"math"
|
||||
"os"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
|
|
@ -253,6 +252,84 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
|
|||
}
|
||||
continue
|
||||
}
|
||||
if fv.Kind() == reflect.Map {
|
||||
// Map fields are rendered as a repeated struct with key/value fields.
|
||||
keys := fv.MapKeys() // TODO: should we sort these for deterministic output?
|
||||
sort.Sort(mapKeys(keys))
|
||||
for _, key := range keys {
|
||||
val := fv.MapIndex(key)
|
||||
if err := writeName(w, props); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte(' '); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// open struct
|
||||
if err := w.WriteByte('<'); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
w.indent()
|
||||
// key
|
||||
if _, err := w.WriteString("key:"); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte(' '); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := writeAny(w, key, props.mkeyprop); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
// nil values aren't legal, but we can avoid panicking because of them.
|
||||
if val.Kind() != reflect.Ptr || !val.IsNil() {
|
||||
// value
|
||||
if _, err := w.WriteString("value:"); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte(' '); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := writeAny(w, val, props.mvalprop); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// close struct
|
||||
w.unindent()
|
||||
if err := w.WriteByte('>'); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
if props.proto3 && fv.Kind() == reflect.Slice && fv.Len() == 0 {
|
||||
// empty bytes field
|
||||
continue
|
||||
}
|
||||
if props.proto3 && fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice {
|
||||
// proto3 non-repeated scalar field; skip if zero value
|
||||
if isProto3Zero(fv) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if err := writeName(w, props); err != nil {
|
||||
return err
|
||||
|
|
@ -354,7 +431,7 @@ func writeAny(w *textWriter, v reflect.Value, props *Properties) error {
|
|||
switch v.Kind() {
|
||||
case reflect.Slice:
|
||||
// Should only be a []byte; repeated fields are handled in writeStruct.
|
||||
if err := writeString(w, string(v.Interface().([]byte))); err != nil {
|
||||
if err := writeString(w, string(v.Bytes())); err != nil {
|
||||
return err
|
||||
}
|
||||
case reflect.String:
|
||||
|
|
@ -607,10 +684,7 @@ func writeExtensions(w *textWriter, pv reflect.Value) error {
|
|||
|
||||
pb, err := GetExtension(ep, desc)
|
||||
if err != nil {
|
||||
if _, err := fmt.Fprintln(os.Stderr, "proto: failed getting extension: ", err); err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
return fmt.Errorf("failed getting extension: %v", err)
|
||||
}
|
||||
|
||||
// Repeated extensions will appear as a slice.
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ func (p *textParser) advance() {
|
|||
}
|
||||
unq, err := unquoteC(p.s[1:i], rune(p.s[0]))
|
||||
if err != nil {
|
||||
p.errorf("invalid quoted string %v", p.s[0:i+1])
|
||||
p.errorf("invalid quoted string %s: %v", p.s[0:i+1], err)
|
||||
return
|
||||
}
|
||||
p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)]
|
||||
|
|
@ -360,6 +360,18 @@ func (p *textParser) next() *token {
|
|||
return &p.cur
|
||||
}
|
||||
|
||||
func (p *textParser) consumeToken(s string) error {
|
||||
tok := p.next()
|
||||
if tok.err != nil {
|
||||
return tok.err
|
||||
}
|
||||
if tok.value != s {
|
||||
p.back()
|
||||
return p.errorf("expected %q, found %q", s, tok.value)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Return a RequiredNotSetError indicating which required field was not set.
|
||||
func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSetError {
|
||||
st := sv.Type()
|
||||
|
|
@ -414,6 +426,10 @@ func (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseEr
|
|||
if typ.Elem().Kind() != reflect.Ptr {
|
||||
break
|
||||
}
|
||||
} else if typ.Kind() == reflect.String {
|
||||
// The proto3 exception is for a string field,
|
||||
// which requires a colon.
|
||||
break
|
||||
}
|
||||
needColon = false
|
||||
}
|
||||
|
|
@ -519,6 +535,66 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
|
|||
|
||||
dst := sv.Field(fi)
|
||||
|
||||
if dst.Kind() == reflect.Map {
|
||||
// Consume any colon.
|
||||
if err := p.checkForColon(props, dst.Type()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Construct the map if it doesn't already exist.
|
||||
if dst.IsNil() {
|
||||
dst.Set(reflect.MakeMap(dst.Type()))
|
||||
}
|
||||
key := reflect.New(dst.Type().Key()).Elem()
|
||||
val := reflect.New(dst.Type().Elem()).Elem()
|
||||
|
||||
// The map entry should be this sequence of tokens:
|
||||
// < key : KEY value : VALUE >
|
||||
// Technically the "key" and "value" could come in any order,
|
||||
// but in practice they won't.
|
||||
|
||||
tok := p.next()
|
||||
var terminator string
|
||||
switch tok.value {
|
||||
case "<":
|
||||
terminator = ">"
|
||||
case "{":
|
||||
terminator = "}"
|
||||
default:
|
||||
return p.errorf("expected '{' or '<', found %q", tok.value)
|
||||
}
|
||||
if err := p.consumeToken("key"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := p.consumeToken(":"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := p.readAny(key, props.mkeyprop); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := p.consumeOptionalSeparator(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := p.consumeToken("value"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := p.readAny(val, props.mvalprop); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := p.consumeOptionalSeparator(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := p.consumeToken(terminator); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dst.SetMapIndex(key, val)
|
||||
continue
|
||||
}
|
||||
|
||||
// Check that it's not already set if it's not a repeated field.
|
||||
if !props.Repeated && fieldSet[name] {
|
||||
return p.errorf("non-repeated field %q was repeated", name)
|
||||
|
|
@ -540,14 +616,10 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
|
|||
}
|
||||
}
|
||||
|
||||
// For backward compatibility, permit a semicolon or comma after a field.
|
||||
tok = p.next()
|
||||
if tok.err != nil {
|
||||
return tok.err
|
||||
}
|
||||
if tok.value != ";" && tok.value != "," {
|
||||
p.back()
|
||||
if err := p.consumeOptionalSeparator(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if reqCount > 0 {
|
||||
|
|
@ -556,6 +628,19 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
|
|||
return reqFieldErr
|
||||
}
|
||||
|
||||
// consumeOptionalSeparator consumes an optional semicolon or comma.
|
||||
// It is used in readStruct to provide backward compatibility.
|
||||
func (p *textParser) consumeOptionalSeparator() error {
|
||||
tok := p.next()
|
||||
if tok.err != nil {
|
||||
return tok.err
|
||||
}
|
||||
if tok.value != ";" && tok.value != "," {
|
||||
p.back()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *textParser) readAny(v reflect.Value, props *Properties) error {
|
||||
tok := p.next()
|
||||
if tok.err != nil {
|
||||
|
|
|
|||
|
|
@ -36,8 +36,9 @@ import (
|
|||
"reflect"
|
||||
"testing"
|
||||
|
||||
. "./testdata"
|
||||
. "github.com/gogo/protobuf/proto"
|
||||
proto3pb "github.com/gogo/protobuf/proto/proto3_proto"
|
||||
. "github.com/gogo/protobuf/proto/testdata"
|
||||
)
|
||||
|
||||
type UnmarshalTextTest struct {
|
||||
|
|
@ -151,7 +152,7 @@ var unMarshalTextTests = []UnmarshalTextTest{
|
|||
// Bad quoted string
|
||||
{
|
||||
in: `inner: < host: "\0" >` + "\n",
|
||||
err: `line 1.15: invalid quoted string "\0"`,
|
||||
err: `line 1.15: invalid quoted string "\0": \0 requires 2 following digits`,
|
||||
},
|
||||
|
||||
// Number too large for int64
|
||||
|
|
@ -443,6 +444,48 @@ func TestRepeatedEnum(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestProto3TextParsing(t *testing.T) {
|
||||
m := new(proto3pb.Message)
|
||||
const in = `name: "Wallace" true_scotsman: true`
|
||||
want := &proto3pb.Message{
|
||||
Name: "Wallace",
|
||||
TrueScotsman: true,
|
||||
}
|
||||
if err := UnmarshalText(in, m); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !Equal(m, want) {
|
||||
t.Errorf("\n got %v\nwant %v", m, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMapParsing(t *testing.T) {
|
||||
m := new(MessageWithMap)
|
||||
const in = `name_mapping:<key:1234 value:"Feist"> name_mapping:<key:1 value:"Beatles">` +
|
||||
`msg_mapping:<key:-4, value:<f: 2.0>,>` + // separating commas are okay
|
||||
`msg_mapping<key:-2 value<f: 4.0>>` + // no colon after "value"
|
||||
`byte_mapping:<key:true value:"so be it">`
|
||||
want := &MessageWithMap{
|
||||
NameMapping: map[int32]string{
|
||||
1: "Beatles",
|
||||
1234: "Feist",
|
||||
},
|
||||
MsgMapping: map[int64]*FloatingPoint{
|
||||
-4: {F: Float64(2.0)},
|
||||
-2: {F: Float64(4.0)},
|
||||
},
|
||||
ByteMapping: map[bool][]byte{
|
||||
true: []byte("so be it"),
|
||||
},
|
||||
}
|
||||
if err := UnmarshalText(in, m); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !Equal(m, want) {
|
||||
t.Errorf("\n got %v\nwant %v", m, want)
|
||||
}
|
||||
}
|
||||
|
||||
var benchInput string
|
||||
|
||||
func init() {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,8 @@ import (
|
|||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
|
||||
pb "./testdata"
|
||||
proto3pb "github.com/gogo/protobuf/proto/proto3_proto"
|
||||
pb "github.com/gogo/protobuf/proto/testdata"
|
||||
)
|
||||
|
||||
// textMessage implements the methods that allow it to marshal and unmarshal
|
||||
|
|
@ -406,3 +407,35 @@ Message <nil>
|
|||
t.Errorf(" got: %s\nwant: %s", s, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProto3Text(t *testing.T) {
|
||||
tests := []struct {
|
||||
m proto.Message
|
||||
want string
|
||||
}{
|
||||
// zero message
|
||||
{&proto3pb.Message{}, ``},
|
||||
// zero message except for an empty byte slice
|
||||
{&proto3pb.Message{Data: []byte{}}, ``},
|
||||
// trivial case
|
||||
{&proto3pb.Message{Name: "Rob", HeightInCm: 175}, `name:"Rob" height_in_cm:175`},
|
||||
// empty map
|
||||
{&pb.MessageWithMap{}, ``},
|
||||
// non-empty map; current map format is the same as a repeated struct
|
||||
{
|
||||
&pb.MessageWithMap{NameMapping: map[int32]string{1234: "Feist"}},
|
||||
`name_mapping:<key:1234 value:"Feist" >`,
|
||||
},
|
||||
// map with nil value; not well-defined, but we shouldn't crash
|
||||
{
|
||||
&pb.MessageWithMap{MsgMapping: map[int64]*pb.FloatingPoint{7: nil}},
|
||||
`msg_mapping:<key:7 >`,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
got := strings.TrimSpace(test.m.String())
|
||||
if got != test.want {
|
||||
t.Errorf("\n got %s\nwant %s", got, test.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -285,7 +285,7 @@ func (self *authenticateeProcess) mechanisms(ctx context.Context, from *upid.UPI
|
|||
|
||||
message := &mesos.AuthenticationStartMessage{
|
||||
Mechanism: proto.String(selectedMech),
|
||||
Data: proto.String(string(data)), // may be nil, depends on init step
|
||||
Data: data, // may be nil, depends on init step
|
||||
}
|
||||
|
||||
if err := self.transport.Send(ctx, from, message); err != nil {
|
||||
|
|
|
|||
1
Godeps/_workspace/src/github.com/mesos/mesos-go/auth/sasl/authenticatee_test.go
generated
vendored
1
Godeps/_workspace/src/github.com/mesos/mesos-go/auth/sasl/authenticatee_test.go
generated
vendored
|
|
@ -73,7 +73,6 @@ func TestAuthticatee_validLogin(t *testing.T) {
|
|||
|
||||
transport.On("Send", mock.Anything, &server, &mesos.AuthenticationStartMessage{
|
||||
Mechanism: proto.String(crammd5.Name),
|
||||
Data: proto.String(""), // may be nil, depends on init step
|
||||
}).Return(nil).Run(func(_ mock.Arguments) {
|
||||
transport.Recv(&server, &mesos.AuthenticationStepMessage{
|
||||
Data: []byte(`lsd;lfkgjs;dlfkgjs;dfklg`),
|
||||
|
|
|
|||
139
Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/authentication.pb.go
generated
vendored
Normal file
139
Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/authentication.pb.go
generated
vendored
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
// Code generated by protoc-gen-gogo.
|
||||
// source: authentication.proto
|
||||
// DO NOT EDIT!
|
||||
|
||||
/*
|
||||
Package mesosproto is a generated protocol buffer package.
|
||||
|
||||
It is generated from these files:
|
||||
authentication.proto
|
||||
containerizer.proto
|
||||
internal.proto
|
||||
log.proto
|
||||
mesos.proto
|
||||
messages.proto
|
||||
registry.proto
|
||||
scheduler.proto
|
||||
state.proto
|
||||
|
||||
It has these top-level messages:
|
||||
AuthenticateMessage
|
||||
AuthenticationMechanismsMessage
|
||||
AuthenticationStartMessage
|
||||
AuthenticationStepMessage
|
||||
AuthenticationCompletedMessage
|
||||
AuthenticationFailedMessage
|
||||
AuthenticationErrorMessage
|
||||
*/
|
||||
package mesosproto
|
||||
|
||||
import proto "github.com/gogo/protobuf/proto"
|
||||
import math "math"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = math.Inf
|
||||
|
||||
type AuthenticateMessage struct {
|
||||
Pid *string `protobuf:"bytes,1,req,name=pid" json:"pid,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *AuthenticateMessage) Reset() { *m = AuthenticateMessage{} }
|
||||
func (m *AuthenticateMessage) String() string { return proto.CompactTextString(m) }
|
||||
func (*AuthenticateMessage) ProtoMessage() {}
|
||||
|
||||
func (m *AuthenticateMessage) GetPid() string {
|
||||
if m != nil && m.Pid != nil {
|
||||
return *m.Pid
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type AuthenticationMechanismsMessage struct {
|
||||
Mechanisms []string `protobuf:"bytes,1,rep,name=mechanisms" json:"mechanisms,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *AuthenticationMechanismsMessage) Reset() { *m = AuthenticationMechanismsMessage{} }
|
||||
func (m *AuthenticationMechanismsMessage) String() string { return proto.CompactTextString(m) }
|
||||
func (*AuthenticationMechanismsMessage) ProtoMessage() {}
|
||||
|
||||
func (m *AuthenticationMechanismsMessage) GetMechanisms() []string {
|
||||
if m != nil {
|
||||
return m.Mechanisms
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AuthenticationStartMessage struct {
|
||||
Mechanism *string `protobuf:"bytes,1,req,name=mechanism" json:"mechanism,omitempty"`
|
||||
Data []byte `protobuf:"bytes,2,opt,name=data" json:"data,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *AuthenticationStartMessage) Reset() { *m = AuthenticationStartMessage{} }
|
||||
func (m *AuthenticationStartMessage) String() string { return proto.CompactTextString(m) }
|
||||
func (*AuthenticationStartMessage) ProtoMessage() {}
|
||||
|
||||
func (m *AuthenticationStartMessage) GetMechanism() string {
|
||||
if m != nil && m.Mechanism != nil {
|
||||
return *m.Mechanism
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *AuthenticationStartMessage) GetData() []byte {
|
||||
if m != nil {
|
||||
return m.Data
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AuthenticationStepMessage struct {
|
||||
Data []byte `protobuf:"bytes,1,req,name=data" json:"data,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *AuthenticationStepMessage) Reset() { *m = AuthenticationStepMessage{} }
|
||||
func (m *AuthenticationStepMessage) String() string { return proto.CompactTextString(m) }
|
||||
func (*AuthenticationStepMessage) ProtoMessage() {}
|
||||
|
||||
func (m *AuthenticationStepMessage) GetData() []byte {
|
||||
if m != nil {
|
||||
return m.Data
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AuthenticationCompletedMessage struct {
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *AuthenticationCompletedMessage) Reset() { *m = AuthenticationCompletedMessage{} }
|
||||
func (m *AuthenticationCompletedMessage) String() string { return proto.CompactTextString(m) }
|
||||
func (*AuthenticationCompletedMessage) ProtoMessage() {}
|
||||
|
||||
type AuthenticationFailedMessage struct {
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *AuthenticationFailedMessage) Reset() { *m = AuthenticationFailedMessage{} }
|
||||
func (m *AuthenticationFailedMessage) String() string { return proto.CompactTextString(m) }
|
||||
func (*AuthenticationFailedMessage) ProtoMessage() {}
|
||||
|
||||
type AuthenticationErrorMessage struct {
|
||||
Error *string `protobuf:"bytes,1,opt,name=error" json:"error,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *AuthenticationErrorMessage) Reset() { *m = AuthenticationErrorMessage{} }
|
||||
func (m *AuthenticationErrorMessage) String() string { return proto.CompactTextString(m) }
|
||||
func (*AuthenticationErrorMessage) ProtoMessage() {}
|
||||
|
||||
func (m *AuthenticationErrorMessage) GetError() string {
|
||||
if m != nil && m.Error != nil {
|
||||
return *m.Error
|
||||
}
|
||||
return ""
|
||||
}
|
||||
53
Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/authentication.proto
generated
vendored
Normal file
53
Godeps/_workspace/src/github.com/mesos/mesos-go/mesosproto/authentication.proto
generated
vendored
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package mesosproto;
|
||||
|
||||
import "mesos.proto";
|
||||
|
||||
|
||||
message AuthenticateMessage {
|
||||
required string pid = 1; // PID that needs to be authenticated.
|
||||
}
|
||||
|
||||
|
||||
message AuthenticationMechanismsMessage {
|
||||
repeated string mechanisms = 1; // List of available SASL mechanisms.
|
||||
}
|
||||
|
||||
|
||||
message AuthenticationStartMessage {
|
||||
required string mechanism = 1;
|
||||
optional bytes data = 2;
|
||||
}
|
||||
|
||||
|
||||
message AuthenticationStepMessage {
|
||||
required bytes data = 1;
|
||||
}
|
||||
|
||||
|
||||
message AuthenticationCompletedMessage {}
|
||||
|
||||
|
||||
message AuthenticationFailedMessage {}
|
||||
|
||||
|
||||
message AuthenticationErrorMessage {
|
||||
optional string error = 1;
|
||||
}
|
||||
|
|
@ -29,7 +29,7 @@ package mesosproto
|
|||
import proto "github.com/gogo/protobuf/proto"
|
||||
import math "math"
|
||||
|
||||
// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto/gogo.pb"
|
||||
// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
|
|
@ -200,6 +200,8 @@ func (m *Usage) GetContainerId() *ContainerID {
|
|||
type Termination struct {
|
||||
// A container may be killed if it exceeds its resources; this will
|
||||
// be indicated by killed=true and described by the message string.
|
||||
// TODO(jaybuff): As part of MESOS-2035 we should remove killed and
|
||||
// replace it with a TaskStatus::Reason.
|
||||
Killed *bool `protobuf:"varint,1,req,name=killed" json:"killed,omitempty"`
|
||||
Message *string `protobuf:"bytes,2,req,name=message" json:"message,omitempty"`
|
||||
// Exit status of the process.
|
||||
|
|
@ -250,6 +252,3 @@ func (m *Containers) GetContainers() []*ContainerID {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,6 +82,8 @@ message Usage {
|
|||
message Termination {
|
||||
// A container may be killed if it exceeds its resources; this will
|
||||
// be indicated by killed=true and described by the message string.
|
||||
// TODO(jaybuff): As part of MESOS-2035 we should remove killed and
|
||||
// replace it with a TaskStatus::Reason.
|
||||
required bool killed = 1;
|
||||
required string message = 2;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ package mesosproto
|
|||
import proto "github.com/gogo/protobuf/proto"
|
||||
import math "math"
|
||||
|
||||
// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto/gogo.pb"
|
||||
// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
|
|
@ -73,6 +73,3 @@ func (m *InternalAuthenticationResult) GetPid() string {
|
|||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func init() {
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -105,52 +105,83 @@ message ContainerID {
|
|||
|
||||
|
||||
/**
|
||||
* Describes a framework. The user field is used to determine the
|
||||
* Unix user that an executor/task should be launched as. If the user
|
||||
* field is set to an empty string Mesos will automagically set it
|
||||
* to the current user. Note that the ID is only available after a
|
||||
* framework has registered, however, it is included here in order to
|
||||
* facilitate scheduler failover (i.e., if it is set then the
|
||||
* MesosSchedulerDriver expects the scheduler is performing failover).
|
||||
* The amount of time that the master will wait for the scheduler to
|
||||
* failover before removing the framework is specified by
|
||||
* failover_timeout. If checkpoint is set, framework pid, executor
|
||||
* pids and status updates are checkpointed to disk by the slaves.
|
||||
* Checkpointing allows a restarted slave to reconnect with old
|
||||
* executors and recover status updates, at the cost of disk I/O.
|
||||
* The role field is used to group frameworks for allocation
|
||||
* decisions, depending on the allocation policy being used.
|
||||
* If the hostname field is set to an empty string Mesos will
|
||||
* automagically set it to the current hostname.
|
||||
* The principal field should match the credential the framework uses
|
||||
* in authentication. This field is used for framework API rate
|
||||
* exporting and limiting and should be set even if authentication is
|
||||
* not enabled if these features are desired.
|
||||
* The webui_url field allows a framework to advertise its web UI, so
|
||||
* that the Mesos web UI can link to it. It is expected to be a full
|
||||
* URL, for example http://my-scheduler.example.com:8080/.
|
||||
* Describes a framework.
|
||||
*/
|
||||
message FrameworkInfo {
|
||||
// Used to determine the Unix user that an executor or task should
|
||||
// be launched as. If the user field is set to an empty string Mesos
|
||||
// will automagically set it to the current user.
|
||||
required string user = 1;
|
||||
|
||||
// Name of the framework that shows up in the Mesos Web UI.
|
||||
required string name = 2;
|
||||
|
||||
// Note that 'id' is only available after a framework has
|
||||
// registered, however, it is included here in order to facilitate
|
||||
// scheduler failover (i.e., if it is set then the
|
||||
// MesosSchedulerDriver expects the scheduler is performing
|
||||
// failover).
|
||||
optional FrameworkID id = 3;
|
||||
|
||||
// The amount of time that the master will wait for the scheduler to
|
||||
// failover before it tears down the framework by killing all its
|
||||
// tasks/executors. This should be non-zero if a framework expects
|
||||
// to reconnect after a failover and not lose its tasks/executors.
|
||||
optional double failover_timeout = 4 [default = 0.0];
|
||||
|
||||
// If set, framework pid, executor pids and status updates are
|
||||
// checkpointed to disk by the slaves. Checkpointing allows a
|
||||
// restarted slave to reconnect with old executors and recover
|
||||
// status updates, at the cost of disk I/O.
|
||||
optional bool checkpoint = 5 [default = false];
|
||||
|
||||
// Used to group frameworks for allocation decisions, depending on
|
||||
// the allocation policy being used.
|
||||
optional string role = 6 [default = "*"];
|
||||
|
||||
// Used to indicate the current host from which the scheduler is
|
||||
// registered in the Mesos Web UI. If set to an empty string Mesos
|
||||
// will automagically set it to the current hostname.
|
||||
optional string hostname = 7;
|
||||
|
||||
// This field should match the credential's principal the framework
|
||||
// uses for authentication. This field is used for framework API
|
||||
// rate limiting and dynamic reservations. It should be set even
|
||||
// if authentication is not enabled if these features are desired.
|
||||
optional string principal = 8;
|
||||
|
||||
// This field allows a framework to advertise its web UI, so that
|
||||
// the Mesos web UI can link to it. It is expected to be a full URL,
|
||||
// for example http://my-scheduler.example.com:8080/.
|
||||
optional string webui_url = 9;
|
||||
|
||||
message Capability {
|
||||
enum Type {
|
||||
// Receive offers with revocable resources. See 'Resource'
|
||||
// message for details.
|
||||
// TODO(vinod): This is currently a no-op.
|
||||
REVOCABLE_RESOURCES = 1;
|
||||
}
|
||||
|
||||
required Type type = 1;
|
||||
}
|
||||
|
||||
// This field allows a framework to advertise its set of
|
||||
// capabilities (e.g., ability to receive offers for revocable
|
||||
// resources).
|
||||
repeated Capability capabilities = 10;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Describes a health check for a task or executor (or any arbitrary
|
||||
* process/command). A "strategy" is picked by specifying one of the
|
||||
* optional fields, currently only 'http' and 'command' are
|
||||
* supported. Specifying more than one strategy is an error.
|
||||
* optional fields; currently only 'command' is supported.
|
||||
* Specifying more than one strategy is an error.
|
||||
*/
|
||||
message HealthCheck {
|
||||
// Describes an HTTP health check.
|
||||
// Describes an HTTP health check. This is not fully implemented and not
|
||||
// recommended for use - see MESOS-2533.
|
||||
message HTTP {
|
||||
// Port to send the HTTP request.
|
||||
required uint32 port = 1;
|
||||
|
|
@ -170,6 +201,7 @@ message HealthCheck {
|
|||
// for specific data in the response.
|
||||
}
|
||||
|
||||
// HTTP health check - not yet recommended for use, see MESOS-2533.
|
||||
optional HTTP http = 1;
|
||||
|
||||
// TODO(benh): Consider adding a URL health check strategy which
|
||||
|
|
@ -177,12 +209,7 @@ message HealthCheck {
|
|||
// encapsulates all the details in a single string field.
|
||||
|
||||
// TODO(benh): Other possible health check strategies could include
|
||||
// one for TCP/UDP or a "command". A "command" could be running a
|
||||
// (shell) command to check the healthiness. We'd need to determine
|
||||
// what arguments (or environment variables) we'd want to set so
|
||||
// that the command could do it's job (i.e., do we want to expose
|
||||
// the stdout/stderr and/or the pid to make checking for healthiness
|
||||
// easier).
|
||||
// one for TCP/UDP.
|
||||
|
||||
// Amount of time to wait until starting the health checks.
|
||||
optional double delay_seconds = 2 [default = 15.0];
|
||||
|
|
@ -218,7 +245,24 @@ message CommandInfo {
|
|||
message URI {
|
||||
required string value = 1;
|
||||
optional bool executable = 2;
|
||||
|
||||
// In case the fetched file is recognized as an archive, extract
|
||||
// its contents into the sandbox. Note that a cached archive is
|
||||
// not copied from the cache to the sandbox in case extraction
|
||||
// originates from an archive in the cache.
|
||||
optional bool extract = 3 [default = true];
|
||||
|
||||
// If this field is "true", the fetcher cache will be used. If not,
|
||||
// fetching bypasses the cache and downloads directly into the
|
||||
// sandbox directory, no matter whether a suitable cache file is
|
||||
// available or not. The former directs the fetcher to download to
|
||||
// the file cache, then copy from there to the sandbox. Subsequent
|
||||
// fetch attempts with the same URI will omit downloading and copy
|
||||
// from the cache as long as the file is resident there. Cache files
|
||||
// may get evicted at any time, which then leads to renewed
|
||||
// downloading. See also "docs/fetcher.md" and
|
||||
// "docs/fetcher-cache-internals.md".
|
||||
optional bool cache = 4;
|
||||
}
|
||||
|
||||
// Describes a container.
|
||||
|
|
@ -293,6 +337,12 @@ message ExecutorInfo {
|
|||
// usage information into a time series database for monitoring.
|
||||
optional string source = 10;
|
||||
optional bytes data = 4;
|
||||
|
||||
// Service discovery information for the executor. It is not
|
||||
// interpreted or acted upon by Mesos. It is up to a service
|
||||
// discovery system to use this information as needed and to handle
|
||||
// executors without service discovery information.
|
||||
optional DiscoveryInfo discovery = 12;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -307,6 +357,7 @@ message MasterInfo {
|
|||
required uint32 port = 3 [default = 5050];
|
||||
optional string pid = 4;
|
||||
optional string hostname = 5;
|
||||
optional string version = 6;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -323,6 +374,8 @@ message SlaveInfo {
|
|||
repeated Resource resources = 3;
|
||||
repeated Attribute attributes = 5;
|
||||
optional SlaveID id = 6;
|
||||
// TODO(joerg84): Remove checkpoint field as with 0.22.0
|
||||
// slave checkpointing is enabled for all slaves (MESOS-2317).
|
||||
optional bool checkpoint = 7 [default = false];
|
||||
}
|
||||
|
||||
|
|
@ -399,15 +452,122 @@ message Resource {
|
|||
optional Value.Ranges ranges = 4;
|
||||
optional Value.Set set = 5;
|
||||
optional string role = 6 [default = "*"];
|
||||
|
||||
message ReservationInfo {
|
||||
// Describes a dynamic reservation. A dynamic reservation is
|
||||
// acquired by an operator via the '/reserve' HTTP endpoint or by
|
||||
// a framework via the offer cycle by sending back an
|
||||
// 'Offer::Operation::Reserve' message.
|
||||
// NOTE: We currently do not allow frameworks with role "*" to
|
||||
// make dynamic reservations.
|
||||
|
||||
// This field indicates the principal of the operator or framework
|
||||
// that reserved this resource. It is used in conjunction with the
|
||||
// "unreserve" ACL to determine whether the entity attempting to
|
||||
// unreserve this resource is permitted to do so.
|
||||
// NOTE: This field should match the FrameworkInfo.principal of
|
||||
// the framework that reserved this resource.
|
||||
required string principal = 1;
|
||||
}
|
||||
|
||||
// If this is set, this resource was dynamically reserved by an
|
||||
// operator or a framework. Otherwise, this resource is either unreserved
|
||||
// or statically reserved by an operator via the --resources flag.
|
||||
optional ReservationInfo reservation = 8;
|
||||
|
||||
message DiskInfo {
|
||||
// Describes a persistent disk volume.
|
||||
// A persistent disk volume will not be automatically garbage
|
||||
// collected if the task/executor/slave terminates, but is
|
||||
// re-offered to the framework(s) belonging to the 'role'.
|
||||
// A framework can set the ID (if it is not set yet) to express
|
||||
// the intention to create a new persistent disk volume from a
|
||||
// regular disk resource. To reuse a previously created volume, a
|
||||
// framework can launch a task/executor when it receives an offer
|
||||
// with a persistent volume, i.e., ID is set.
|
||||
// NOTE: Currently, we do not allow a persistent disk volume
|
||||
// without a reservation (i.e., 'role' should not be '*').
|
||||
message Persistence {
|
||||
// A unique ID for the persistent disk volume.
|
||||
// NOTE: The ID needs to be unique per role on each slave.
|
||||
required string id = 1;
|
||||
}
|
||||
|
||||
optional Persistence persistence = 1;
|
||||
|
||||
// Describes how this disk resource will be mounted in the
|
||||
// container. If not set, the disk resource will be used as the
|
||||
// sandbox. Otherwise, it will be mounted according to the
|
||||
// 'container_path' inside 'volume'. The 'host_path' inside
|
||||
// 'volume' is ignored.
|
||||
// NOTE: If 'volume' is set but 'persistence' is not set, the
|
||||
// volume will be automatically garbage collected after
|
||||
// task/executor terminates. Currently, if 'persistence' is set,
|
||||
// 'volume' must be set.
|
||||
optional Volume volume = 2;
|
||||
}
|
||||
|
||||
optional DiskInfo disk = 7;
|
||||
|
||||
message RevocableInfo {}
|
||||
|
||||
// If this is set, the resources are revocable, i.e., any tasks or
|
||||
// executors launched using these resources could get preempted or
|
||||
// throttled at any time. This could be used by frameworks to run
|
||||
// best effort tasks that do not need strict uptime or performance
|
||||
// guarantees. Note that if this is set, 'disk' or 'reservation'
|
||||
// cannot be set.
|
||||
optional RevocableInfo revocable = 9;
|
||||
}
|
||||
|
||||
/**
|
||||
* When the network bandwidth caps are enabled and the container
|
||||
* is over its limit, outbound packets may be either delayed or
|
||||
* dropped completely either because it exceeds the maximum bandwidth
|
||||
* allocation for a single container (the cap) or because the combined
|
||||
* network traffic of multiple containers on the host exceeds the
|
||||
* transmit capacity of the host (the share). We can report the
|
||||
* following statistics for each of these conditions exported directly
|
||||
* from the Linux Traffic Control Queueing Discipline.
|
||||
*
|
||||
* id : name of the limiter, e.g. 'tx_bw_cap'
|
||||
* backlog : number of packets currently delayed
|
||||
* bytes : total bytes seen
|
||||
* drops : number of packets dropped in total
|
||||
* overlimits : number of packets which exceeded allocation
|
||||
* packets : total packets seen
|
||||
* qlen : number of packets currently queued
|
||||
* rate_bps : throughput in bytes/sec
|
||||
* rate_pps : throughput in packets/sec
|
||||
* requeues : number of times a packet has been delayed due to
|
||||
* locking or device contention issues
|
||||
*
|
||||
* More information on the operation of Linux Traffic Control can be
|
||||
* found at http://www.lartc.org/lartc.html.
|
||||
*/
|
||||
message TrafficControlStatistics {
|
||||
required string id = 1;
|
||||
optional uint64 backlog = 2;
|
||||
optional uint64 bytes = 3;
|
||||
optional uint64 drops = 4;
|
||||
optional uint64 overlimits = 5;
|
||||
optional uint64 packets = 6;
|
||||
optional uint64 qlen = 7;
|
||||
optional uint64 ratebps = 8;
|
||||
optional uint64 ratepps = 9;
|
||||
optional uint64 requeues = 10;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* A snapshot of resource usage statistics.
|
||||
*/
|
||||
message ResourceStatistics {
|
||||
required double timestamp = 1; // Snapshot time, in seconds since the Epoch.
|
||||
|
||||
optional uint32 processes = 30;
|
||||
optional uint32 threads = 31;
|
||||
|
||||
// CPU Usage Information:
|
||||
// Total CPU time spent in user mode, and kernel mode.
|
||||
optional double cpus_user_time_secs = 2;
|
||||
|
|
@ -422,17 +582,55 @@ message ResourceStatistics {
|
|||
optional double cpus_throttled_time_secs = 9;
|
||||
|
||||
// Memory Usage Information:
|
||||
optional uint64 mem_rss_bytes = 5; // Resident Set Size.
|
||||
|
||||
// Amount of memory resources allocated.
|
||||
// mem_total_bytes was added in 0.23.0 to represent the total memory
|
||||
// of a process in RAM (as opposed to in Swap). This was previously
|
||||
// reported as mem_rss_bytes, which was also changed in 0.23.0 to
|
||||
// represent only the anonymous memory usage, to keep in sync with
|
||||
// Linux kernel's (arguably erroneous) use of terminology.
|
||||
optional uint64 mem_total_bytes = 36;
|
||||
|
||||
// Total memory + swap usage. This is set if swap is enabled.
|
||||
optional uint64 mem_total_memsw_bytes = 37;
|
||||
|
||||
// Hard memory limit for a container.
|
||||
optional uint64 mem_limit_bytes = 6;
|
||||
|
||||
// Broken out memory usage information (files, anonymous, and mmaped files)
|
||||
// Soft memory limit for a container.
|
||||
optional uint64 mem_soft_limit_bytes = 38;
|
||||
|
||||
// Broken out memory usage information: pagecache, rss (anonymous),
|
||||
// mmaped files and swap.
|
||||
|
||||
// TODO(chzhcn) mem_file_bytes and mem_anon_bytes are deprecated in
|
||||
// 0.23.0 and will be removed in 0.24.0.
|
||||
optional uint64 mem_file_bytes = 10;
|
||||
optional uint64 mem_anon_bytes = 11;
|
||||
optional uint64 mem_mapped_file_bytes = 12;
|
||||
|
||||
// TODO(bmahler): Add disk usage.
|
||||
// mem_cache_bytes is added in 0.23.0 to represent page cache usage.
|
||||
optional uint64 mem_cache_bytes = 39;
|
||||
|
||||
// Since 0.23.0, mem_rss_bytes is changed to represent only
|
||||
// anonymous memory usage. Note that neither its requiredness, type,
|
||||
// name nor numeric tag has been changed.
|
||||
optional uint64 mem_rss_bytes = 5;
|
||||
|
||||
optional uint64 mem_mapped_file_bytes = 12;
|
||||
// This is only set if swap is enabled.
|
||||
optional uint64 mem_swap_bytes = 40;
|
||||
|
||||
// Number of occurrences of different levels of memory pressure
|
||||
// events reported by memory cgroup. Pressure listening (re)starts
|
||||
// with these values set to 0 when slave (re)starts. See
|
||||
// https://www.kernel.org/doc/Documentation/cgroups/memory.txt for
|
||||
// more details.
|
||||
optional uint64 mem_low_pressure_counter = 32;
|
||||
optional uint64 mem_medium_pressure_counter = 33;
|
||||
optional uint64 mem_critical_pressure_counter = 34;
|
||||
|
||||
// Disk Usage Information for executor working directory.
|
||||
optional uint64 disk_limit_bytes = 26;
|
||||
optional uint64 disk_used_bytes = 27;
|
||||
|
||||
// Perf statistics.
|
||||
optional PerfStatistics perf = 13;
|
||||
|
|
@ -453,34 +651,36 @@ message ResourceStatistics {
|
|||
optional double net_tcp_rtt_microsecs_p90 = 23;
|
||||
optional double net_tcp_rtt_microsecs_p95 = 24;
|
||||
optional double net_tcp_rtt_microsecs_p99 = 25;
|
||||
|
||||
optional double net_tcp_active_connections = 28;
|
||||
optional double net_tcp_time_wait_connections = 29;
|
||||
|
||||
// Network traffic flowing into or out of a container can be delayed
|
||||
// or dropped due to congestion or policy inside and outside the
|
||||
// container.
|
||||
repeated TrafficControlStatistics net_traffic_control_statistics = 35;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Describes a snapshot of the resource usage for an executor.
|
||||
*
|
||||
* TODO(bmahler): Note that we want to be sending this information
|
||||
* to the master, and subsequently to the relevant scheduler. So
|
||||
* this proto is designed to be easy for the scheduler to use, this
|
||||
* is why we provide the slave id, executor info / task info.
|
||||
* Describes a snapshot of the resource usage for executors.
|
||||
*/
|
||||
message ResourceUsage {
|
||||
required SlaveID slave_id = 1;
|
||||
required FrameworkID framework_id = 2;
|
||||
message Executor {
|
||||
required ExecutorInfo executor_info = 1;
|
||||
|
||||
// Resource usage is for an executor. For tasks launched with
|
||||
// an explicit executor, the executor id is provided. For tasks
|
||||
// launched without an executor, our internal executor will be
|
||||
// used. In this case, we provide the task id here instead, in
|
||||
// order to make this message easier for schedulers to work with.
|
||||
// This includes resources used by the executor itself
|
||||
// as well as its active tasks.
|
||||
repeated Resource allocated = 2;
|
||||
|
||||
optional ExecutorID executor_id = 3; // If present, this executor was
|
||||
optional string executor_name = 4; // explicitly specified.
|
||||
// Current resource usage. If absent, the containerizer
|
||||
// cannot provide resource usage.
|
||||
optional ResourceStatistics statistics = 3;
|
||||
}
|
||||
|
||||
optional TaskID task_id = 5; // If present, the task did not have an executor.
|
||||
repeated Executor executors = 1;
|
||||
|
||||
// If missing, the isolation module cannot provide resource usage.
|
||||
optional ResourceStatistics statistics = 6;
|
||||
// TODO(jieyu): Include slave's total resources here.
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -564,6 +764,8 @@ message PerfStatistics {
|
|||
* to proactively influence the allocator. If 'slave_id' is provided
|
||||
* then this request is assumed to only apply to resources on that
|
||||
* slave.
|
||||
*
|
||||
* TODO(vinod): Remove this once the old driver is removed.
|
||||
*/
|
||||
message Request {
|
||||
optional SlaveID slave_id = 1;
|
||||
|
|
@ -583,6 +785,44 @@ message Offer {
|
|||
repeated Resource resources = 5;
|
||||
repeated Attribute attributes = 7;
|
||||
repeated ExecutorID executor_ids = 6;
|
||||
|
||||
// Defines an operation that can be performed against offers.
|
||||
message Operation {
|
||||
enum Type {
|
||||
LAUNCH = 1;
|
||||
RESERVE = 2;
|
||||
UNRESERVE = 3;
|
||||
CREATE = 4;
|
||||
DESTROY = 5;
|
||||
}
|
||||
|
||||
message Launch {
|
||||
repeated TaskInfo task_infos = 1;
|
||||
}
|
||||
|
||||
message Reserve {
|
||||
repeated Resource resources = 1;
|
||||
}
|
||||
|
||||
message Unreserve {
|
||||
repeated Resource resources = 1;
|
||||
}
|
||||
|
||||
message Create {
|
||||
repeated Resource volumes = 1;
|
||||
}
|
||||
|
||||
message Destroy {
|
||||
repeated Resource volumes = 1;
|
||||
}
|
||||
|
||||
required Type type = 1;
|
||||
optional Launch launch = 2;
|
||||
optional Reserve reserve = 3;
|
||||
optional Unreserve unreserve = 4;
|
||||
optional Create create = 5;
|
||||
optional Destroy destroy = 6;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -607,6 +847,19 @@ message TaskInfo {
|
|||
// A health check for the task (currently in *alpha* and initial
|
||||
// support will only be for TaskInfo's that have a CommandInfo).
|
||||
optional HealthCheck health_check = 8;
|
||||
|
||||
// Labels are free-form key value pairs which are exposed through
|
||||
// master and slave endpoints. Labels will not be interpreted or
|
||||
// acted upon by Mesos itself. As opposed to the data field, labels
|
||||
// will be kept in memory on master and slave processes. Therefore,
|
||||
// labels should be used to tag tasks with light-weight meta-data.
|
||||
optional Labels labels = 10;
|
||||
|
||||
// Service discovery information for the task. It is not interpreted
|
||||
// or acted upon by Mesos. It is up to a service discovery system
|
||||
// to use this information as needed and to handle tasks without
|
||||
// service discovery information.
|
||||
optional DiscoveryInfo discovery = 11;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -625,8 +878,6 @@ enum TaskState {
|
|||
TASK_FAILED = 3; // TERMINAL. The task failed to finish successfully.
|
||||
TASK_KILLED = 4; // TERMINAL. The task was killed by the executor.
|
||||
TASK_LOST = 5; // TERMINAL. The task failed but can be rescheduled.
|
||||
// TASK_ERROR is currently unused but will be introduced in 0.22.0.
|
||||
// TODO(dhamon): Start using TASK_ERROR.
|
||||
TASK_ERROR = 7; // TERMINAL. The task description contains an error.
|
||||
}
|
||||
|
||||
|
|
@ -635,16 +886,20 @@ enum TaskState {
|
|||
* Describes the current status of a task.
|
||||
*/
|
||||
message TaskStatus {
|
||||
/** Describes the source of the task status update. */
|
||||
// Describes the source of the task status update.
|
||||
enum Source {
|
||||
SOURCE_MASTER = 0;
|
||||
SOURCE_SLAVE = 1;
|
||||
SOURCE_EXECUTOR = 2;
|
||||
}
|
||||
|
||||
/** Detailed reason for the task status update. */
|
||||
// Detailed reason for the task status update.
|
||||
//
|
||||
// TODO(bmahler): Differentiate between slave removal reasons
|
||||
// (e.g. unhealthy vs. unregistered for maintenance).
|
||||
enum Reason {
|
||||
REASON_COMMAND_EXECUTOR_FAILED = 0;
|
||||
REASON_EXECUTOR_PREEMPTED = 17;
|
||||
REASON_EXECUTOR_TERMINATED = 1;
|
||||
REASON_EXECUTOR_UNREGISTERED = 2;
|
||||
REASON_FRAMEWORK_REMOVED = 3;
|
||||
|
|
@ -654,6 +909,7 @@ message TaskStatus {
|
|||
REASON_MASTER_DISCONNECTED = 7;
|
||||
REASON_MEMORY_LIMIT = 8;
|
||||
REASON_RECONCILIATION = 9;
|
||||
REASON_RESOURCES_UNKNOWN = 18;
|
||||
REASON_SLAVE_DISCONNECTED = 10;
|
||||
REASON_SLAVE_REMOVED = 11;
|
||||
REASON_SLAVE_RESTARTED = 12;
|
||||
|
|
@ -673,6 +929,17 @@ message TaskStatus {
|
|||
optional ExecutorID executor_id = 7; // TODO(benh): Use in master/slave.
|
||||
optional double timestamp = 6;
|
||||
|
||||
// Statuses that are delivered reliably to the scheduler will
|
||||
// include a 'uuid'. The status is considered delivered once
|
||||
// it is acknowledged by the scheduler. Schedulers can choose
|
||||
// to either explicitly acknowledge statuses or let the scheduler
|
||||
// driver implicitly acknowledge (default).
|
||||
//
|
||||
// TODO(bmahler): This is currently overwritten in the scheduler
|
||||
// driver and executor driver, but executors will need to set this
|
||||
// to a valid RFC-4122 UUID if using the HTTP API.
|
||||
optional bytes uuid = 11;
|
||||
|
||||
// Describes whether the task has been determined to be healthy
|
||||
// (true) or unhealthy (false) according to the HealthCheck field in
|
||||
// the command info.
|
||||
|
|
@ -928,10 +1195,15 @@ message ContainerInfo {
|
|||
optional bool privileged = 4 [default = false];
|
||||
|
||||
// Allowing arbitrary parameters to be passed to docker CLI.
|
||||
// Note that anything passed to this field is not guranteed
|
||||
// Note that anything passed to this field is not guaranteed
|
||||
// to be supported moving forward, as we might move away from
|
||||
// the docker CLI.
|
||||
repeated Parameter parameters = 5;
|
||||
|
||||
// With this flag set to true, the docker containerizer will
|
||||
// pull the docker image from the registry even if the image
|
||||
// is already downloaded on the slave.
|
||||
optional bool force_pull_image = 6;
|
||||
}
|
||||
|
||||
required Type type = 1;
|
||||
|
|
@ -940,3 +1212,68 @@ message ContainerInfo {
|
|||
|
||||
optional DockerInfo docker = 3;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Collection of labels.
|
||||
*/
|
||||
message Labels {
|
||||
repeated Label labels = 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Key, value pair used to store free form user-data.
|
||||
*/
|
||||
message Label {
|
||||
required string key = 1;
|
||||
optional string value = 2;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Named port used for service discovery.
|
||||
*/
|
||||
message Port {
|
||||
required uint32 number = 1;
|
||||
optional string name = 2;
|
||||
optional string protocol = 3;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Collection of ports.
|
||||
*/
|
||||
message Ports {
|
||||
repeated Port ports = 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Service discovery information.
|
||||
* The visibility field restricts discovery within a framework
|
||||
* (FRAMEWORK), within a Mesos cluster (CLUSTER), or places no
|
||||
* restrictions (EXTERNAL).
|
||||
* The environment, location, and version fields provide first class
|
||||
* support for common attributes used to differentiate between
|
||||
* similar services. The environment may receive values such as
|
||||
* PROD/QA/DEV, the location field may receive values like
|
||||
* EAST-US/WEST-US/EUROPE/AMEA, and the version field may receive
|
||||
* values like v2.0/v0.9. The exact use of these fields is up to each
|
||||
* service discovery system.
|
||||
*/
|
||||
message DiscoveryInfo {
|
||||
enum Visibility {
|
||||
FRAMEWORK = 0;
|
||||
CLUSTER = 1;
|
||||
EXTERNAL = 2;
|
||||
}
|
||||
|
||||
required Visibility visibility = 1;
|
||||
optional string name = 2;
|
||||
optional string environment = 3;
|
||||
optional string location = 4;
|
||||
optional string version = 5;
|
||||
optional Ports ports = 6;
|
||||
optional Labels labels = 7;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -7,7 +7,7 @@ package mesosproto
|
|||
import proto "github.com/gogo/protobuf/proto"
|
||||
import math "math"
|
||||
|
||||
// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto/gogo.pb"
|
||||
// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
|
|
@ -71,6 +71,12 @@ type Task struct {
|
|||
// NOTE: Either both the fields must be set or both must be unset.
|
||||
StatusUpdateState *TaskState `protobuf:"varint,9,opt,name=status_update_state,enum=mesosproto.TaskState" json:"status_update_state,omitempty"`
|
||||
StatusUpdateUuid []byte `protobuf:"bytes,10,opt,name=status_update_uuid" json:"status_update_uuid,omitempty"`
|
||||
Labels *Labels `protobuf:"bytes,11,opt,name=labels" json:"labels,omitempty"`
|
||||
// Service discovery information for the task. It is not interpreted
|
||||
// or acted upon by Mesos. It is up to a service discovery system
|
||||
// to use this information as needed and to handle tasks without
|
||||
// service discovery information.
|
||||
Discovery *DiscoveryInfo `protobuf:"bytes,12,opt,name=discovery" json:"discovery,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
|
|
@ -148,33 +154,18 @@ func (m *Task) GetStatusUpdateUuid() []byte {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Describes a role, which are used to group frameworks for allocation
|
||||
// decisions, depending on the allocation policy being used.
|
||||
// The weight field can be used to indicate forms of priority.
|
||||
type RoleInfo struct {
|
||||
Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
|
||||
Weight *float64 `protobuf:"fixed64,2,opt,name=weight,def=1" json:"weight,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
func (m *Task) GetLabels() *Labels {
|
||||
if m != nil {
|
||||
return m.Labels
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *RoleInfo) Reset() { *m = RoleInfo{} }
|
||||
func (m *RoleInfo) String() string { return proto.CompactTextString(m) }
|
||||
func (*RoleInfo) ProtoMessage() {}
|
||||
|
||||
const Default_RoleInfo_Weight float64 = 1
|
||||
|
||||
func (m *RoleInfo) GetName() string {
|
||||
if m != nil && m.Name != nil {
|
||||
return *m.Name
|
||||
func (m *Task) GetDiscovery() *DiscoveryInfo {
|
||||
if m != nil {
|
||||
return m.Discovery
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *RoleInfo) GetWeight() float64 {
|
||||
if m != nil && m.Weight != nil {
|
||||
return *m.Weight
|
||||
}
|
||||
return Default_RoleInfo_Weight
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO(vinod): Create a new UUID message type.
|
||||
|
|
@ -184,7 +175,10 @@ type StatusUpdate struct {
|
|||
SlaveId *SlaveID `protobuf:"bytes,3,opt,name=slave_id" json:"slave_id,omitempty"`
|
||||
Status *TaskStatus `protobuf:"bytes,4,req,name=status" json:"status,omitempty"`
|
||||
Timestamp *float64 `protobuf:"fixed64,5,req,name=timestamp" json:"timestamp,omitempty"`
|
||||
Uuid []byte `protobuf:"bytes,6,req,name=uuid" json:"uuid,omitempty"`
|
||||
// This is being deprecated in favor of TaskStatus.uuid. In 0.23.0,
|
||||
// we set the TaskStatus 'uuid' in the executor driver for all
|
||||
// retryable status updates.
|
||||
Uuid []byte `protobuf:"bytes,6,opt,name=uuid" json:"uuid,omitempty"`
|
||||
// This corresponds to the latest state of the task according to the
|
||||
// slave. Note that this state might be different than the state in
|
||||
// 'status' because status update manager queues updates. In other
|
||||
|
|
@ -635,7 +629,8 @@ func (m *ReviveOffersMessage) GetFrameworkId() *FrameworkID {
|
|||
}
|
||||
|
||||
type RunTaskMessage struct {
|
||||
FrameworkId *FrameworkID `protobuf:"bytes,1,req,name=framework_id" json:"framework_id,omitempty"`
|
||||
// TODO(karya): Remove framework_id after MESOS-2559 has shipped.
|
||||
FrameworkId *FrameworkID `protobuf:"bytes,1,opt,name=framework_id" json:"framework_id,omitempty"`
|
||||
Framework *FrameworkInfo `protobuf:"bytes,2,req,name=framework" json:"framework,omitempty"`
|
||||
Pid *string `protobuf:"bytes,3,req,name=pid" json:"pid,omitempty"`
|
||||
Task *TaskInfo `protobuf:"bytes,4,req,name=task" json:"task,omitempty"`
|
||||
|
|
@ -830,6 +825,10 @@ func (m *FrameworkErrorMessage) GetMessage() string {
|
|||
|
||||
type RegisterSlaveMessage struct {
|
||||
Slave *SlaveInfo `protobuf:"bytes,1,req,name=slave" json:"slave,omitempty"`
|
||||
// Resources that are checkpointed by the slave (e.g., persistent
|
||||
// volume or dynamic reservation). Frameworks need to release
|
||||
// checkpointed resources explicitly.
|
||||
CheckpointedResources []*Resource `protobuf:"bytes,3,rep,name=checkpointed_resources" json:"checkpointed_resources,omitempty"`
|
||||
// NOTE: This is a hack for the master to detect the slave's
|
||||
// version. If unset the slave is < 0.21.0.
|
||||
// TODO(bmahler): Do proper versioning: MESOS-986.
|
||||
|
|
@ -848,6 +847,13 @@ func (m *RegisterSlaveMessage) GetSlave() *SlaveInfo {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *RegisterSlaveMessage) GetCheckpointedResources() []*Resource {
|
||||
if m != nil {
|
||||
return m.CheckpointedResources
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *RegisterSlaveMessage) GetVersion() string {
|
||||
if m != nil && m.Version != nil {
|
||||
return *m.Version
|
||||
|
|
@ -856,11 +862,11 @@ func (m *RegisterSlaveMessage) GetVersion() string {
|
|||
}
|
||||
|
||||
type ReregisterSlaveMessage struct {
|
||||
// TODO(bmahler): slave_id is deprecated.
|
||||
// 0.21.0: Now an optional field. Always written, never read.
|
||||
// 0.22.0: Remove this field.
|
||||
SlaveId *SlaveID `protobuf:"bytes,1,opt,name=slave_id" json:"slave_id,omitempty"`
|
||||
Slave *SlaveInfo `protobuf:"bytes,2,req,name=slave" json:"slave,omitempty"`
|
||||
// Resources that are checkpointed by the slave (e.g., persistent
|
||||
// volume or dynamic reservation). Frameworks need to release
|
||||
// checkpointed resources explicitly.
|
||||
CheckpointedResources []*Resource `protobuf:"bytes,7,rep,name=checkpointed_resources" json:"checkpointed_resources,omitempty"`
|
||||
ExecutorInfos []*ExecutorInfo `protobuf:"bytes,4,rep,name=executor_infos" json:"executor_infos,omitempty"`
|
||||
Tasks []*Task `protobuf:"bytes,3,rep,name=tasks" json:"tasks,omitempty"`
|
||||
CompletedFrameworks []*Archive_Framework `protobuf:"bytes,5,rep,name=completed_frameworks" json:"completed_frameworks,omitempty"`
|
||||
|
|
@ -875,16 +881,16 @@ func (m *ReregisterSlaveMessage) Reset() { *m = ReregisterSlaveMessage{}
|
|||
func (m *ReregisterSlaveMessage) String() string { return proto.CompactTextString(m) }
|
||||
func (*ReregisterSlaveMessage) ProtoMessage() {}
|
||||
|
||||
func (m *ReregisterSlaveMessage) GetSlaveId() *SlaveID {
|
||||
func (m *ReregisterSlaveMessage) GetSlave() *SlaveInfo {
|
||||
if m != nil {
|
||||
return m.SlaveId
|
||||
return m.Slave
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ReregisterSlaveMessage) GetSlave() *SlaveInfo {
|
||||
func (m *ReregisterSlaveMessage) GetCheckpointedResources() []*Resource {
|
||||
if m != nil {
|
||||
return m.Slave
|
||||
return m.CheckpointedResources
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -919,6 +925,7 @@ func (m *ReregisterSlaveMessage) GetVersion() string {
|
|||
|
||||
type SlaveRegisteredMessage struct {
|
||||
SlaveId *SlaveID `protobuf:"bytes,1,req,name=slave_id" json:"slave_id,omitempty"`
|
||||
Connection *MasterSlaveConnection `protobuf:"bytes,2,opt,name=connection" json:"connection,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
|
|
@ -933,9 +940,17 @@ func (m *SlaveRegisteredMessage) GetSlaveId() *SlaveID {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *SlaveRegisteredMessage) GetConnection() *MasterSlaveConnection {
|
||||
if m != nil {
|
||||
return m.Connection
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type SlaveReregisteredMessage struct {
|
||||
SlaveId *SlaveID `protobuf:"bytes,1,req,name=slave_id" json:"slave_id,omitempty"`
|
||||
Reconciliations []*ReconcileTasksMessage `protobuf:"bytes,2,rep,name=reconciliations" json:"reconciliations,omitempty"`
|
||||
Connection *MasterSlaveConnection `protobuf:"bytes,3,opt,name=connection" json:"connection,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
|
|
@ -957,6 +972,13 @@ func (m *SlaveReregisteredMessage) GetReconciliations() []*ReconcileTasksMessage
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *SlaveReregisteredMessage) GetConnection() *MasterSlaveConnection {
|
||||
if m != nil {
|
||||
return m.Connection
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type UnregisterSlaveMessage struct {
|
||||
SlaveId *SlaveID `protobuf:"bytes,1,req,name=slave_id" json:"slave_id,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
|
|
@ -973,6 +995,25 @@ func (m *UnregisterSlaveMessage) GetSlaveId() *SlaveID {
|
|||
return nil
|
||||
}
|
||||
|
||||
type MasterSlaveConnection struct {
|
||||
// Product of max_slave_ping_timeouts * slave_ping_timeout.
|
||||
// If no pings are received within the total timeout,
|
||||
// the master will remove the slave.
|
||||
TotalPingTimeoutSeconds *float64 `protobuf:"fixed64,1,opt,name=total_ping_timeout_seconds" json:"total_ping_timeout_seconds,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *MasterSlaveConnection) Reset() { *m = MasterSlaveConnection{} }
|
||||
func (m *MasterSlaveConnection) String() string { return proto.CompactTextString(m) }
|
||||
func (*MasterSlaveConnection) ProtoMessage() {}
|
||||
|
||||
func (m *MasterSlaveConnection) GetTotalPingTimeoutSeconds() float64 {
|
||||
if m != nil && m.TotalPingTimeoutSeconds != nil {
|
||||
return *m.TotalPingTimeoutSeconds
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// This message is periodically sent by the master to the slave.
|
||||
// If the slave is connected to the master, "connected" is true.
|
||||
type PingSlaveMessage struct {
|
||||
|
|
@ -1018,9 +1059,13 @@ func (m *ShutdownFrameworkMessage) GetFrameworkId() *FrameworkID {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Tells the executor to initiate a shut down by invoking
|
||||
// Executor::shutdown.
|
||||
// Tells a slave (and consequently executor) to shutdown an executor.
|
||||
type ShutdownExecutorMessage struct {
|
||||
// TODO(vinod): Make these fields required. These are made optional
|
||||
// for backwards compatibility between 0.23.0 slave and pre 0.23.0
|
||||
// executor driver.
|
||||
ExecutorId *ExecutorID `protobuf:"bytes,1,opt,name=executor_id" json:"executor_id,omitempty"`
|
||||
FrameworkId *FrameworkID `protobuf:"bytes,2,opt,name=framework_id" json:"framework_id,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
|
|
@ -1028,6 +1073,20 @@ func (m *ShutdownExecutorMessage) Reset() { *m = ShutdownExecutorMessage
|
|||
func (m *ShutdownExecutorMessage) String() string { return proto.CompactTextString(m) }
|
||||
func (*ShutdownExecutorMessage) ProtoMessage() {}
|
||||
|
||||
func (m *ShutdownExecutorMessage) GetExecutorId() *ExecutorID {
|
||||
if m != nil {
|
||||
return m.ExecutorId
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ShutdownExecutorMessage) GetFrameworkId() *FrameworkID {
|
||||
if m != nil {
|
||||
return m.FrameworkId
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type UpdateFrameworkMessage struct {
|
||||
FrameworkId *FrameworkID `protobuf:"bytes,1,req,name=framework_id" json:"framework_id,omitempty"`
|
||||
Pid *string `protobuf:"bytes,2,req,name=pid" json:"pid,omitempty"`
|
||||
|
|
@ -1052,6 +1111,52 @@ func (m *UpdateFrameworkMessage) GetPid() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
// This message is sent to the slave whenever there is an update of
|
||||
// the resources that need to be checkpointed (e.g., persistent volume
|
||||
// or dynamic reservation).
|
||||
type CheckpointResourcesMessage struct {
|
||||
Resources []*Resource `protobuf:"bytes,1,rep,name=resources" json:"resources,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *CheckpointResourcesMessage) Reset() { *m = CheckpointResourcesMessage{} }
|
||||
func (m *CheckpointResourcesMessage) String() string { return proto.CompactTextString(m) }
|
||||
func (*CheckpointResourcesMessage) ProtoMessage() {}
|
||||
|
||||
func (m *CheckpointResourcesMessage) GetResources() []*Resource {
|
||||
if m != nil {
|
||||
return m.Resources
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// This message is sent by the slave to the master to inform the
|
||||
// master about the total amount of oversubscribed (allocated and
|
||||
// allocatable) resources.
|
||||
type UpdateSlaveMessage struct {
|
||||
SlaveId *SlaveID `protobuf:"bytes,1,req,name=slave_id" json:"slave_id,omitempty"`
|
||||
OversubscribedResources []*Resource `protobuf:"bytes,2,rep,name=oversubscribed_resources" json:"oversubscribed_resources,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *UpdateSlaveMessage) Reset() { *m = UpdateSlaveMessage{} }
|
||||
func (m *UpdateSlaveMessage) String() string { return proto.CompactTextString(m) }
|
||||
func (*UpdateSlaveMessage) ProtoMessage() {}
|
||||
|
||||
func (m *UpdateSlaveMessage) GetSlaveId() *SlaveID {
|
||||
if m != nil {
|
||||
return m.SlaveId
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *UpdateSlaveMessage) GetOversubscribedResources() []*Resource {
|
||||
if m != nil {
|
||||
return m.OversubscribedResources
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type RegisterExecutorMessage struct {
|
||||
FrameworkId *FrameworkID `protobuf:"bytes,1,req,name=framework_id" json:"framework_id,omitempty"`
|
||||
ExecutorId *ExecutorID `protobuf:"bytes,2,req,name=executor_id" json:"executor_id,omitempty"`
|
||||
|
|
@ -1260,110 +1365,6 @@ func (m *ShutdownMessage) GetMessage() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
type AuthenticateMessage struct {
|
||||
Pid *string `protobuf:"bytes,1,req,name=pid" json:"pid,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *AuthenticateMessage) Reset() { *m = AuthenticateMessage{} }
|
||||
func (m *AuthenticateMessage) String() string { return proto.CompactTextString(m) }
|
||||
func (*AuthenticateMessage) ProtoMessage() {}
|
||||
|
||||
func (m *AuthenticateMessage) GetPid() string {
|
||||
if m != nil && m.Pid != nil {
|
||||
return *m.Pid
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type AuthenticationMechanismsMessage struct {
|
||||
Mechanisms []string `protobuf:"bytes,1,rep,name=mechanisms" json:"mechanisms,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *AuthenticationMechanismsMessage) Reset() { *m = AuthenticationMechanismsMessage{} }
|
||||
func (m *AuthenticationMechanismsMessage) String() string { return proto.CompactTextString(m) }
|
||||
func (*AuthenticationMechanismsMessage) ProtoMessage() {}
|
||||
|
||||
func (m *AuthenticationMechanismsMessage) GetMechanisms() []string {
|
||||
if m != nil {
|
||||
return m.Mechanisms
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AuthenticationStartMessage struct {
|
||||
Mechanism *string `protobuf:"bytes,1,req,name=mechanism" json:"mechanism,omitempty"`
|
||||
Data *string `protobuf:"bytes,2,opt,name=data" json:"data,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *AuthenticationStartMessage) Reset() { *m = AuthenticationStartMessage{} }
|
||||
func (m *AuthenticationStartMessage) String() string { return proto.CompactTextString(m) }
|
||||
func (*AuthenticationStartMessage) ProtoMessage() {}
|
||||
|
||||
func (m *AuthenticationStartMessage) GetMechanism() string {
|
||||
if m != nil && m.Mechanism != nil {
|
||||
return *m.Mechanism
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *AuthenticationStartMessage) GetData() string {
|
||||
if m != nil && m.Data != nil {
|
||||
return *m.Data
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type AuthenticationStepMessage struct {
|
||||
Data []byte `protobuf:"bytes,1,req,name=data" json:"data,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *AuthenticationStepMessage) Reset() { *m = AuthenticationStepMessage{} }
|
||||
func (m *AuthenticationStepMessage) String() string { return proto.CompactTextString(m) }
|
||||
func (*AuthenticationStepMessage) ProtoMessage() {}
|
||||
|
||||
func (m *AuthenticationStepMessage) GetData() []byte {
|
||||
if m != nil {
|
||||
return m.Data
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AuthenticationCompletedMessage struct {
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *AuthenticationCompletedMessage) Reset() { *m = AuthenticationCompletedMessage{} }
|
||||
func (m *AuthenticationCompletedMessage) String() string { return proto.CompactTextString(m) }
|
||||
func (*AuthenticationCompletedMessage) ProtoMessage() {}
|
||||
|
||||
type AuthenticationFailedMessage struct {
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *AuthenticationFailedMessage) Reset() { *m = AuthenticationFailedMessage{} }
|
||||
func (m *AuthenticationFailedMessage) String() string { return proto.CompactTextString(m) }
|
||||
func (*AuthenticationFailedMessage) ProtoMessage() {}
|
||||
|
||||
type AuthenticationErrorMessage struct {
|
||||
Error *string `protobuf:"bytes,1,opt,name=error" json:"error,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *AuthenticationErrorMessage) Reset() { *m = AuthenticationErrorMessage{} }
|
||||
func (m *AuthenticationErrorMessage) String() string { return proto.CompactTextString(m) }
|
||||
func (*AuthenticationErrorMessage) ProtoMessage() {}
|
||||
|
||||
func (m *AuthenticationErrorMessage) GetError() string {
|
||||
if m != nil && m.Error != nil {
|
||||
return *m.Error
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// *
|
||||
// Describes Completed Frameworks, etc. for archival.
|
||||
type Archive struct {
|
||||
|
|
@ -1465,86 +1466,24 @@ func (m *TaskHealthStatus) GetConsecutiveFailures() int32 {
|
|||
return 0
|
||||
}
|
||||
|
||||
// Collection of Modules.
|
||||
type Modules struct {
|
||||
Libraries []*Modules_Library `protobuf:"bytes,1,rep,name=libraries" json:"libraries,omitempty"`
|
||||
// *
|
||||
// Message to signal completion of an event within a module.
|
||||
type HookExecuted struct {
|
||||
Module *string `protobuf:"bytes,1,opt,name=module" json:"module,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Modules) Reset() { *m = Modules{} }
|
||||
func (m *Modules) String() string { return proto.CompactTextString(m) }
|
||||
func (*Modules) ProtoMessage() {}
|
||||
func (m *HookExecuted) Reset() { *m = HookExecuted{} }
|
||||
func (m *HookExecuted) String() string { return proto.CompactTextString(m) }
|
||||
func (*HookExecuted) ProtoMessage() {}
|
||||
|
||||
func (m *Modules) GetLibraries() []*Modules_Library {
|
||||
if m != nil {
|
||||
return m.Libraries
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Modules_Library struct {
|
||||
// If "file" contains a slash ("/"), then it is interpreted as a
|
||||
// (relative or absolute) pathname. Otherwise a standard library
|
||||
// search is performed.
|
||||
File *string `protobuf:"bytes,1,opt,name=file" json:"file,omitempty"`
|
||||
// We will add the proper prefix ("lib") and suffix (".so" for
|
||||
// Linux and ".dylib" for OS X) to the "name".
|
||||
Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
|
||||
Modules []*Modules_Library_Module `protobuf:"bytes,3,rep,name=modules" json:"modules,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Modules_Library) Reset() { *m = Modules_Library{} }
|
||||
func (m *Modules_Library) String() string { return proto.CompactTextString(m) }
|
||||
func (*Modules_Library) ProtoMessage() {}
|
||||
|
||||
func (m *Modules_Library) GetFile() string {
|
||||
if m != nil && m.File != nil {
|
||||
return *m.File
|
||||
func (m *HookExecuted) GetModule() string {
|
||||
if m != nil && m.Module != nil {
|
||||
return *m.Module
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Modules_Library) GetName() string {
|
||||
if m != nil && m.Name != nil {
|
||||
return *m.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Modules_Library) GetModules() []*Modules_Library_Module {
|
||||
if m != nil {
|
||||
return m.Modules
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Modules_Library_Module struct {
|
||||
// Module name.
|
||||
Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
|
||||
// Module-specific parameters.
|
||||
Parameters []*Parameter `protobuf:"bytes,2,rep,name=parameters" json:"parameters,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Modules_Library_Module) Reset() { *m = Modules_Library_Module{} }
|
||||
func (m *Modules_Library_Module) String() string { return proto.CompactTextString(m) }
|
||||
func (*Modules_Library_Module) ProtoMessage() {}
|
||||
|
||||
func (m *Modules_Library_Module) GetName() string {
|
||||
if m != nil && m.Name != nil {
|
||||
return *m.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Modules_Library_Module) GetParameters() []*Parameter {
|
||||
if m != nil {
|
||||
return m.Parameters
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterEnum("mesosproto.StatusUpdateRecord_Type", StatusUpdateRecord_Type_name, StatusUpdateRecord_Type_value)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,15 +54,14 @@ message Task {
|
|||
// NOTE: Either both the fields must be set or both must be unset.
|
||||
optional TaskState status_update_state = 9;
|
||||
optional bytes status_update_uuid = 10;
|
||||
}
|
||||
|
||||
optional Labels labels = 11;
|
||||
|
||||
// Describes a role, which are used to group frameworks for allocation
|
||||
// decisions, depending on the allocation policy being used.
|
||||
// The weight field can be used to indicate forms of priority.
|
||||
message RoleInfo {
|
||||
required string name = 1;
|
||||
optional double weight = 2 [default = 1];
|
||||
// Service discovery information for the task. It is not interpreted
|
||||
// or acted upon by Mesos. It is up to a service discovery system
|
||||
// to use this information as needed and to handle tasks without
|
||||
// service discovery information.
|
||||
optional DiscoveryInfo discovery = 12;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -73,7 +72,11 @@ message StatusUpdate {
|
|||
optional SlaveID slave_id = 3;
|
||||
required TaskStatus status = 4;
|
||||
required double timestamp = 5;
|
||||
required bytes uuid = 6;
|
||||
|
||||
// This is being deprecated in favor of TaskStatus.uuid. In 0.23.0,
|
||||
// we set the TaskStatus 'uuid' in the executor driver for all
|
||||
// retryable status updates.
|
||||
optional bytes uuid = 6;
|
||||
|
||||
// This corresponds to the latest state of the task according to the
|
||||
// slave. Note that this state might be different than the state in
|
||||
|
|
@ -188,7 +191,8 @@ message ReviveOffersMessage {
|
|||
|
||||
|
||||
message RunTaskMessage {
|
||||
required FrameworkID framework_id = 1;
|
||||
// TODO(karya): Remove framework_id after MESOS-2559 has shipped.
|
||||
optional FrameworkID framework_id = 1 [deprecated = true];
|
||||
required FrameworkInfo framework = 2;
|
||||
required string pid = 3;
|
||||
required TaskInfo task = 4;
|
||||
|
|
@ -244,6 +248,11 @@ message FrameworkErrorMessage {
|
|||
message RegisterSlaveMessage {
|
||||
required SlaveInfo slave = 1;
|
||||
|
||||
// Resources that are checkpointed by the slave (e.g., persistent
|
||||
// volume or dynamic reservation). Frameworks need to release
|
||||
// checkpointed resources explicitly.
|
||||
repeated Resource checkpointed_resources = 3;
|
||||
|
||||
// NOTE: This is a hack for the master to detect the slave's
|
||||
// version. If unset the slave is < 0.21.0.
|
||||
// TODO(bmahler): Do proper versioning: MESOS-986.
|
||||
|
|
@ -252,11 +261,13 @@ message RegisterSlaveMessage {
|
|||
|
||||
|
||||
message ReregisterSlaveMessage {
|
||||
// TODO(bmahler): slave_id is deprecated.
|
||||
// 0.21.0: Now an optional field. Always written, never read.
|
||||
// 0.22.0: Remove this field.
|
||||
optional SlaveID slave_id = 1;
|
||||
required SlaveInfo slave = 2;
|
||||
|
||||
// Resources that are checkpointed by the slave (e.g., persistent
|
||||
// volume or dynamic reservation). Frameworks need to release
|
||||
// checkpointed resources explicitly.
|
||||
repeated Resource checkpointed_resources = 7;
|
||||
|
||||
repeated ExecutorInfo executor_infos = 4;
|
||||
repeated Task tasks = 3;
|
||||
repeated Archive.Framework completed_frameworks = 5;
|
||||
|
|
@ -270,6 +281,7 @@ message ReregisterSlaveMessage {
|
|||
|
||||
message SlaveRegisteredMessage {
|
||||
required SlaveID slave_id = 1;
|
||||
optional MasterSlaveConnection connection = 2;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -277,6 +289,7 @@ message SlaveReregisteredMessage {
|
|||
required SlaveID slave_id = 1;
|
||||
|
||||
repeated ReconcileTasksMessage reconciliations = 2;
|
||||
optional MasterSlaveConnection connection = 3;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -285,6 +298,14 @@ message UnregisterSlaveMessage {
|
|||
}
|
||||
|
||||
|
||||
message MasterSlaveConnection {
|
||||
// Product of max_slave_ping_timeouts * slave_ping_timeout.
|
||||
// If no pings are received within the total timeout,
|
||||
// the master will remove the slave.
|
||||
optional double total_ping_timeout_seconds = 1;
|
||||
}
|
||||
|
||||
|
||||
// This message is periodically sent by the master to the slave.
|
||||
// If the slave is connected to the master, "connected" is true.
|
||||
message PingSlaveMessage {
|
||||
|
|
@ -303,9 +324,14 @@ message ShutdownFrameworkMessage {
|
|||
}
|
||||
|
||||
|
||||
// Tells the executor to initiate a shut down by invoking
|
||||
// Executor::shutdown.
|
||||
message ShutdownExecutorMessage {}
|
||||
// Tells a slave (and consequently executor) to shutdown an executor.
|
||||
message ShutdownExecutorMessage {
|
||||
// TODO(vinod): Make these fields required. These are made optional
|
||||
// for backwards compatibility between 0.23.0 slave and pre 0.23.0
|
||||
// executor driver.
|
||||
optional ExecutorID executor_id = 1;
|
||||
optional FrameworkID framework_id = 2;
|
||||
}
|
||||
|
||||
|
||||
message UpdateFrameworkMessage {
|
||||
|
|
@ -314,6 +340,23 @@ message UpdateFrameworkMessage {
|
|||
}
|
||||
|
||||
|
||||
// This message is sent to the slave whenever there is an update of
|
||||
// the resources that need to be checkpointed (e.g., persistent volume
|
||||
// or dynamic reservation).
|
||||
message CheckpointResourcesMessage {
|
||||
repeated Resource resources = 1;
|
||||
}
|
||||
|
||||
|
||||
// This message is sent by the slave to the master to inform the
|
||||
// master about the total amount of oversubscribed (allocated and
|
||||
// allocatable) resources.
|
||||
message UpdateSlaveMessage {
|
||||
required SlaveID slave_id = 1;
|
||||
repeated Resource oversubscribed_resources = 2;
|
||||
}
|
||||
|
||||
|
||||
message RegisterExecutorMessage {
|
||||
required FrameworkID framework_id = 1;
|
||||
required ExecutorID executor_id = 2;
|
||||
|
|
@ -361,38 +404,6 @@ message ShutdownMessage {
|
|||
}
|
||||
|
||||
|
||||
message AuthenticateMessage {
|
||||
required string pid = 1; // PID that needs to be authenticated.
|
||||
}
|
||||
|
||||
|
||||
message AuthenticationMechanismsMessage {
|
||||
repeated string mechanisms = 1; // List of available SASL mechanisms.
|
||||
}
|
||||
|
||||
|
||||
message AuthenticationStartMessage {
|
||||
required string mechanism = 1;
|
||||
optional string data = 2;
|
||||
}
|
||||
|
||||
|
||||
message AuthenticationStepMessage {
|
||||
required bytes data = 1;
|
||||
}
|
||||
|
||||
|
||||
message AuthenticationCompletedMessage {}
|
||||
|
||||
|
||||
message AuthenticationFailedMessage {}
|
||||
|
||||
|
||||
message AuthenticationErrorMessage {
|
||||
optional string error = 1;
|
||||
}
|
||||
|
||||
|
||||
// TODO(adam-mesos): Move this to an 'archive' package.
|
||||
/**
|
||||
* Describes Completed Frameworks, etc. for archival.
|
||||
|
|
@ -426,28 +437,9 @@ message TaskHealthStatus {
|
|||
}
|
||||
|
||||
|
||||
// Collection of Modules.
|
||||
message Modules {
|
||||
message Library {
|
||||
// If "file" contains a slash ("/"), then it is interpreted as a
|
||||
// (relative or absolute) pathname. Otherwise a standard library
|
||||
// search is performed.
|
||||
optional string file = 1;
|
||||
|
||||
// We will add the proper prefix ("lib") and suffix (".so" for
|
||||
// Linux and ".dylib" for OS X) to the "name".
|
||||
optional string name = 2;
|
||||
|
||||
message Module {
|
||||
// Module name.
|
||||
optional string name = 1;
|
||||
|
||||
// Module-specific parameters.
|
||||
repeated Parameter parameters = 2;
|
||||
}
|
||||
|
||||
repeated Module modules = 3;
|
||||
}
|
||||
|
||||
repeated Library libraries = 1;
|
||||
/**
|
||||
* Message to signal completion of an event within a module.
|
||||
*/
|
||||
message HookExecuted {
|
||||
optional string module = 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ package mesosproto
|
|||
import proto "github.com/gogo/protobuf/proto"
|
||||
import math "math"
|
||||
|
||||
// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto/gogo.pb"
|
||||
// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
|
|
@ -86,6 +86,3 @@ func (m *Registry_Slaves) GetSlaves() []*Registry_Slave {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ package mesosproto
|
|||
import proto "github.com/gogo/protobuf/proto"
|
||||
import math "math"
|
||||
|
||||
// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto/gogo.pb"
|
||||
// discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
|
|
@ -18,35 +18,32 @@ var _ = math.Inf
|
|||
type Event_Type int32
|
||||
|
||||
const (
|
||||
Event_REGISTERED Event_Type = 1
|
||||
Event_REREGISTERED Event_Type = 2
|
||||
Event_OFFERS Event_Type = 3
|
||||
Event_RESCIND Event_Type = 4
|
||||
Event_UPDATE Event_Type = 5
|
||||
Event_MESSAGE Event_Type = 6
|
||||
Event_FAILURE Event_Type = 7
|
||||
Event_ERROR Event_Type = 8
|
||||
Event_SUBSCRIBED Event_Type = 1
|
||||
Event_OFFERS Event_Type = 2
|
||||
Event_RESCIND Event_Type = 3
|
||||
Event_UPDATE Event_Type = 4
|
||||
Event_MESSAGE Event_Type = 5
|
||||
Event_FAILURE Event_Type = 6
|
||||
Event_ERROR Event_Type = 7
|
||||
)
|
||||
|
||||
var Event_Type_name = map[int32]string{
|
||||
1: "REGISTERED",
|
||||
2: "REREGISTERED",
|
||||
3: "OFFERS",
|
||||
4: "RESCIND",
|
||||
5: "UPDATE",
|
||||
6: "MESSAGE",
|
||||
7: "FAILURE",
|
||||
8: "ERROR",
|
||||
1: "SUBSCRIBED",
|
||||
2: "OFFERS",
|
||||
3: "RESCIND",
|
||||
4: "UPDATE",
|
||||
5: "MESSAGE",
|
||||
6: "FAILURE",
|
||||
7: "ERROR",
|
||||
}
|
||||
var Event_Type_value = map[string]int32{
|
||||
"REGISTERED": 1,
|
||||
"REREGISTERED": 2,
|
||||
"OFFERS": 3,
|
||||
"RESCIND": 4,
|
||||
"UPDATE": 5,
|
||||
"MESSAGE": 6,
|
||||
"FAILURE": 7,
|
||||
"ERROR": 8,
|
||||
"SUBSCRIBED": 1,
|
||||
"OFFERS": 2,
|
||||
"RESCIND": 3,
|
||||
"UPDATE": 4,
|
||||
"MESSAGE": 5,
|
||||
"FAILURE": 6,
|
||||
"ERROR": 7,
|
||||
}
|
||||
|
||||
func (x Event_Type) Enum() *Event_Type {
|
||||
|
|
@ -71,44 +68,41 @@ func (x *Event_Type) UnmarshalJSON(data []byte) error {
|
|||
type Call_Type int32
|
||||
|
||||
const (
|
||||
Call_REGISTER Call_Type = 1
|
||||
Call_REREGISTER Call_Type = 2
|
||||
Call_UNREGISTER Call_Type = 3
|
||||
Call_REQUEST Call_Type = 4
|
||||
Call_DECLINE Call_Type = 5
|
||||
Call_REVIVE Call_Type = 6
|
||||
Call_LAUNCH Call_Type = 7
|
||||
Call_KILL Call_Type = 8
|
||||
Call_ACKNOWLEDGE Call_Type = 9
|
||||
Call_RECONCILE Call_Type = 10
|
||||
Call_MESSAGE Call_Type = 11
|
||||
Call_SUBSCRIBE Call_Type = 1
|
||||
Call_TEARDOWN Call_Type = 2
|
||||
Call_ACCEPT Call_Type = 3
|
||||
Call_DECLINE Call_Type = 4
|
||||
Call_REVIVE Call_Type = 5
|
||||
Call_KILL Call_Type = 6
|
||||
Call_SHUTDOWN Call_Type = 7
|
||||
Call_ACKNOWLEDGE Call_Type = 8
|
||||
Call_RECONCILE Call_Type = 9
|
||||
Call_MESSAGE Call_Type = 10
|
||||
)
|
||||
|
||||
var Call_Type_name = map[int32]string{
|
||||
1: "REGISTER",
|
||||
2: "REREGISTER",
|
||||
3: "UNREGISTER",
|
||||
4: "REQUEST",
|
||||
5: "DECLINE",
|
||||
6: "REVIVE",
|
||||
7: "LAUNCH",
|
||||
8: "KILL",
|
||||
9: "ACKNOWLEDGE",
|
||||
10: "RECONCILE",
|
||||
11: "MESSAGE",
|
||||
1: "SUBSCRIBE",
|
||||
2: "TEARDOWN",
|
||||
3: "ACCEPT",
|
||||
4: "DECLINE",
|
||||
5: "REVIVE",
|
||||
6: "KILL",
|
||||
7: "SHUTDOWN",
|
||||
8: "ACKNOWLEDGE",
|
||||
9: "RECONCILE",
|
||||
10: "MESSAGE",
|
||||
}
|
||||
var Call_Type_value = map[string]int32{
|
||||
"REGISTER": 1,
|
||||
"REREGISTER": 2,
|
||||
"UNREGISTER": 3,
|
||||
"REQUEST": 4,
|
||||
"DECLINE": 5,
|
||||
"REVIVE": 6,
|
||||
"LAUNCH": 7,
|
||||
"KILL": 8,
|
||||
"ACKNOWLEDGE": 9,
|
||||
"RECONCILE": 10,
|
||||
"MESSAGE": 11,
|
||||
"SUBSCRIBE": 1,
|
||||
"TEARDOWN": 2,
|
||||
"ACCEPT": 3,
|
||||
"DECLINE": 4,
|
||||
"REVIVE": 5,
|
||||
"KILL": 6,
|
||||
"SHUTDOWN": 7,
|
||||
"ACKNOWLEDGE": 8,
|
||||
"RECONCILE": 9,
|
||||
"MESSAGE": 10,
|
||||
}
|
||||
|
||||
func (x Call_Type) Enum() *Call_Type {
|
||||
|
|
@ -129,22 +123,22 @@ func (x *Call_Type) UnmarshalJSON(data []byte) error {
|
|||
}
|
||||
|
||||
// *
|
||||
// Low-level scheduler event API.
|
||||
// Scheduler event API.
|
||||
//
|
||||
// An event is described using the standard protocol buffer "union"
|
||||
// trick, see https://developers.google.com/protocol-buffers/docs/techniques#union.
|
||||
// trick, see:
|
||||
// https://developers.google.com/protocol-buffers/docs/techniques#union.
|
||||
type Event struct {
|
||||
// Type of the event, indicates which optional field below should be
|
||||
// present if that type has a nested message definition.
|
||||
Type *Event_Type `protobuf:"varint,1,req,name=type,enum=mesosproto.Event_Type" json:"type,omitempty"`
|
||||
Registered *Event_Registered `protobuf:"bytes,2,opt,name=registered" json:"registered,omitempty"`
|
||||
Reregistered *Event_Reregistered `protobuf:"bytes,3,opt,name=reregistered" json:"reregistered,omitempty"`
|
||||
Offers *Event_Offers `protobuf:"bytes,4,opt,name=offers" json:"offers,omitempty"`
|
||||
Rescind *Event_Rescind `protobuf:"bytes,5,opt,name=rescind" json:"rescind,omitempty"`
|
||||
Update *Event_Update `protobuf:"bytes,6,opt,name=update" json:"update,omitempty"`
|
||||
Message *Event_Message `protobuf:"bytes,7,opt,name=message" json:"message,omitempty"`
|
||||
Failure *Event_Failure `protobuf:"bytes,8,opt,name=failure" json:"failure,omitempty"`
|
||||
Error *Event_Error `protobuf:"bytes,9,opt,name=error" json:"error,omitempty"`
|
||||
Subscribed *Event_Subscribed `protobuf:"bytes,2,opt,name=subscribed" json:"subscribed,omitempty"`
|
||||
Offers *Event_Offers `protobuf:"bytes,3,opt,name=offers" json:"offers,omitempty"`
|
||||
Rescind *Event_Rescind `protobuf:"bytes,4,opt,name=rescind" json:"rescind,omitempty"`
|
||||
Update *Event_Update `protobuf:"bytes,5,opt,name=update" json:"update,omitempty"`
|
||||
Message *Event_Message `protobuf:"bytes,6,opt,name=message" json:"message,omitempty"`
|
||||
Failure *Event_Failure `protobuf:"bytes,7,opt,name=failure" json:"failure,omitempty"`
|
||||
Error *Event_Error `protobuf:"bytes,8,opt,name=error" json:"error,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
|
|
@ -156,19 +150,12 @@ func (m *Event) GetType() Event_Type {
|
|||
if m != nil && m.Type != nil {
|
||||
return *m.Type
|
||||
}
|
||||
return Event_REGISTERED
|
||||
return Event_SUBSCRIBED
|
||||
}
|
||||
|
||||
func (m *Event) GetRegistered() *Event_Registered {
|
||||
func (m *Event) GetSubscribed() *Event_Subscribed {
|
||||
if m != nil {
|
||||
return m.Registered
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Event) GetReregistered() *Event_Reregistered {
|
||||
if m != nil {
|
||||
return m.Reregistered
|
||||
return m.Subscribed
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -215,54 +202,27 @@ func (m *Event) GetError() *Event_Error {
|
|||
return nil
|
||||
}
|
||||
|
||||
type Event_Registered struct {
|
||||
// First event received when the scheduler subscribes.
|
||||
type Event_Subscribed struct {
|
||||
FrameworkId *FrameworkID `protobuf:"bytes,1,req,name=framework_id" json:"framework_id,omitempty"`
|
||||
MasterInfo *MasterInfo `protobuf:"bytes,2,req,name=master_info" json:"master_info,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Event_Registered) Reset() { *m = Event_Registered{} }
|
||||
func (m *Event_Registered) String() string { return proto.CompactTextString(m) }
|
||||
func (*Event_Registered) ProtoMessage() {}
|
||||
func (m *Event_Subscribed) Reset() { *m = Event_Subscribed{} }
|
||||
func (m *Event_Subscribed) String() string { return proto.CompactTextString(m) }
|
||||
func (*Event_Subscribed) ProtoMessage() {}
|
||||
|
||||
func (m *Event_Registered) GetFrameworkId() *FrameworkID {
|
||||
func (m *Event_Subscribed) GetFrameworkId() *FrameworkID {
|
||||
if m != nil {
|
||||
return m.FrameworkId
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Event_Registered) GetMasterInfo() *MasterInfo {
|
||||
if m != nil {
|
||||
return m.MasterInfo
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Event_Reregistered struct {
|
||||
FrameworkId *FrameworkID `protobuf:"bytes,1,req,name=framework_id" json:"framework_id,omitempty"`
|
||||
MasterInfo *MasterInfo `protobuf:"bytes,2,req,name=master_info" json:"master_info,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Event_Reregistered) Reset() { *m = Event_Reregistered{} }
|
||||
func (m *Event_Reregistered) String() string { return proto.CompactTextString(m) }
|
||||
func (*Event_Reregistered) ProtoMessage() {}
|
||||
|
||||
func (m *Event_Reregistered) GetFrameworkId() *FrameworkID {
|
||||
if m != nil {
|
||||
return m.FrameworkId
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Event_Reregistered) GetMasterInfo() *MasterInfo {
|
||||
if m != nil {
|
||||
return m.MasterInfo
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Received whenever there are new resources that are offered to the
|
||||
// scheduler. Each offer corresponds to a set of resources on a
|
||||
// slave. Until the scheduler accepts or declines an offer the
|
||||
// resources are considered allocated to the scheduler.
|
||||
type Event_Offers struct {
|
||||
Offers []*Offer `protobuf:"bytes,1,rep,name=offers" json:"offers,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
|
|
@ -279,6 +239,10 @@ func (m *Event_Offers) GetOffers() []*Offer {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Received when a particular offer is no longer valid (e.g., the
|
||||
// slave corresponding to the offer has been removed) and hence
|
||||
// needs to be rescinded. Any future calls ('Accept' / 'Decline') made
|
||||
// by the scheduler regarding this offer will be invalid.
|
||||
type Event_Rescind struct {
|
||||
OfferId *OfferID `protobuf:"bytes,1,req,name=offer_id" json:"offer_id,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
|
|
@ -295,9 +259,17 @@ func (m *Event_Rescind) GetOfferId() *OfferID {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Received whenever there is a status update that is generated by
|
||||
// the executor or slave or master. Status updates should be used by
|
||||
// executors to reliably communicate the status of the tasks that
|
||||
// they manage. It is crucial that a terminal update (see TaskState
|
||||
// in mesos.proto) is sent by the executor as soon as the task
|
||||
// terminates, in order for Mesos to release the resources allocated
|
||||
// to the task. It is also the responsibility of the scheduler to
|
||||
// explicitly acknowledge the receipt of a status update. See
|
||||
// 'Acknowledge' in the 'Call' section below for the semantics.
|
||||
type Event_Update struct {
|
||||
Uuid []byte `protobuf:"bytes,1,req,name=uuid" json:"uuid,omitempty"`
|
||||
Status *TaskStatus `protobuf:"bytes,2,req,name=status" json:"status,omitempty"`
|
||||
Status *TaskStatus `protobuf:"bytes,1,req,name=status" json:"status,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
|
|
@ -305,13 +277,6 @@ func (m *Event_Update) Reset() { *m = Event_Update{} }
|
|||
func (m *Event_Update) String() string { return proto.CompactTextString(m) }
|
||||
func (*Event_Update) ProtoMessage() {}
|
||||
|
||||
func (m *Event_Update) GetUuid() []byte {
|
||||
if m != nil {
|
||||
return m.Uuid
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Event_Update) GetStatus() *TaskStatus {
|
||||
if m != nil {
|
||||
return m.Status
|
||||
|
|
@ -319,6 +284,11 @@ func (m *Event_Update) GetStatus() *TaskStatus {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Received when a custom message generated by the executor is
|
||||
// forwarded by the master. Note that this message is not
|
||||
// interpreted by Mesos and is only forwarded (without reliability
|
||||
// guarantees) to the scheduler. It is up to the executor to retry
|
||||
// if the message is dropped for any reason.
|
||||
type Event_Message struct {
|
||||
SlaveId *SlaveID `protobuf:"bytes,1,req,name=slave_id" json:"slave_id,omitempty"`
|
||||
ExecutorId *ExecutorID `protobuf:"bytes,2,req,name=executor_id" json:"executor_id,omitempty"`
|
||||
|
|
@ -351,6 +321,16 @@ func (m *Event_Message) GetData() []byte {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Received when a slave is removed from the cluster (e.g., failed
|
||||
// health checks) or when an executor is terminated. Note that, this
|
||||
// event coincides with receipt of terminal UPDATE events for any
|
||||
// active tasks belonging to the slave or executor and receipt of
|
||||
// 'Rescind' events for any outstanding offers belonging to the
|
||||
// slave. Note that there is no guaranteed order between the
|
||||
// 'Failure', 'Update' and 'Rescind' events when a slave or executor
|
||||
// is removed.
|
||||
// TODO(vinod): Consider splitting the lost slave and terminated
|
||||
// executor into separate events and ensure it's reliably generated.
|
||||
type Event_Failure struct {
|
||||
SlaveId *SlaveID `protobuf:"bytes,1,opt,name=slave_id" json:"slave_id,omitempty"`
|
||||
// If this was just a failure of an executor on a slave then
|
||||
|
|
@ -386,6 +366,13 @@ func (m *Event_Failure) GetStatus() int32 {
|
|||
return 0
|
||||
}
|
||||
|
||||
// Received when an invalid framework (e.g., unauthenticated,
|
||||
// unauthorized) attempts to subscribe with the master. Error can
|
||||
// also be received if scheduler sends invalid Calls (e.g., not
|
||||
// properly initialized).
|
||||
// TODO(vinod): Remove this once the old scheduler driver is no
|
||||
// longer supported. With HTTP API all errors will be signaled via
|
||||
// HTTP response codes.
|
||||
type Event_Error struct {
|
||||
Message *string `protobuf:"bytes,1,req,name=message" json:"message,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
|
|
@ -403,25 +390,29 @@ func (m *Event_Error) GetMessage() string {
|
|||
}
|
||||
|
||||
// *
|
||||
// Low-level scheduler call API.
|
||||
// Scheduler call API.
|
||||
//
|
||||
// Like Event, a Call is described using the standard protocol buffer
|
||||
// "union" trick (see above).
|
||||
type Call struct {
|
||||
// Identifies who generated this call. Always necessary, but the
|
||||
// only thing that needs to be set for certain calls, e.g.,
|
||||
// REGISTER, REREGISTER, and UNREGISTER.
|
||||
FrameworkInfo *FrameworkInfo `protobuf:"bytes,1,req,name=framework_info" json:"framework_info,omitempty"`
|
||||
// Identifies who generated this call. Master assigns a framework id
|
||||
// when a new scheduler subscribes for the first time. Once assigned,
|
||||
// the scheduler must set the 'framework_id' here and within its
|
||||
// FrameworkInfo (in any further 'Subscribe' calls). This allows the
|
||||
// master to identify a scheduler correctly across disconnections,
|
||||
// failovers, etc.
|
||||
FrameworkId *FrameworkID `protobuf:"bytes,1,opt,name=framework_id" json:"framework_id,omitempty"`
|
||||
// Type of the call, indicates which optional field below should be
|
||||
// present if that type has a nested message definition.
|
||||
Type *Call_Type `protobuf:"varint,2,req,name=type,enum=mesosproto.Call_Type" json:"type,omitempty"`
|
||||
Request *Call_Request `protobuf:"bytes,3,opt,name=request" json:"request,omitempty"`
|
||||
Decline *Call_Decline `protobuf:"bytes,4,opt,name=decline" json:"decline,omitempty"`
|
||||
Launch *Call_Launch `protobuf:"bytes,5,opt,name=launch" json:"launch,omitempty"`
|
||||
Subscribe *Call_Subscribe `protobuf:"bytes,3,opt,name=subscribe" json:"subscribe,omitempty"`
|
||||
Accept *Call_Accept `protobuf:"bytes,4,opt,name=accept" json:"accept,omitempty"`
|
||||
Decline *Call_Decline `protobuf:"bytes,5,opt,name=decline" json:"decline,omitempty"`
|
||||
Kill *Call_Kill `protobuf:"bytes,6,opt,name=kill" json:"kill,omitempty"`
|
||||
Acknowledge *Call_Acknowledge `protobuf:"bytes,7,opt,name=acknowledge" json:"acknowledge,omitempty"`
|
||||
Reconcile *Call_Reconcile `protobuf:"bytes,8,opt,name=reconcile" json:"reconcile,omitempty"`
|
||||
Message *Call_Message `protobuf:"bytes,9,opt,name=message" json:"message,omitempty"`
|
||||
Shutdown *Call_Shutdown `protobuf:"bytes,7,opt,name=shutdown" json:"shutdown,omitempty"`
|
||||
Acknowledge *Call_Acknowledge `protobuf:"bytes,8,opt,name=acknowledge" json:"acknowledge,omitempty"`
|
||||
Reconcile *Call_Reconcile `protobuf:"bytes,9,opt,name=reconcile" json:"reconcile,omitempty"`
|
||||
Message *Call_Message `protobuf:"bytes,10,opt,name=message" json:"message,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
|
|
@ -429,9 +420,9 @@ func (m *Call) Reset() { *m = Call{} }
|
|||
func (m *Call) String() string { return proto.CompactTextString(m) }
|
||||
func (*Call) ProtoMessage() {}
|
||||
|
||||
func (m *Call) GetFrameworkInfo() *FrameworkInfo {
|
||||
func (m *Call) GetFrameworkId() *FrameworkID {
|
||||
if m != nil {
|
||||
return m.FrameworkInfo
|
||||
return m.FrameworkId
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -440,12 +431,19 @@ func (m *Call) GetType() Call_Type {
|
|||
if m != nil && m.Type != nil {
|
||||
return *m.Type
|
||||
}
|
||||
return Call_REGISTER
|
||||
return Call_SUBSCRIBE
|
||||
}
|
||||
|
||||
func (m *Call) GetRequest() *Call_Request {
|
||||
func (m *Call) GetSubscribe() *Call_Subscribe {
|
||||
if m != nil {
|
||||
return m.Request
|
||||
return m.Subscribe
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Call) GetAccept() *Call_Accept {
|
||||
if m != nil {
|
||||
return m.Accept
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -457,16 +455,16 @@ func (m *Call) GetDecline() *Call_Decline {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *Call) GetLaunch() *Call_Launch {
|
||||
func (m *Call) GetKill() *Call_Kill {
|
||||
if m != nil {
|
||||
return m.Launch
|
||||
return m.Kill
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Call) GetKill() *Call_Kill {
|
||||
func (m *Call) GetShutdown() *Call_Shutdown {
|
||||
if m != nil {
|
||||
return m.Kill
|
||||
return m.Shutdown
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -492,22 +490,105 @@ func (m *Call) GetMessage() *Call_Message {
|
|||
return nil
|
||||
}
|
||||
|
||||
type Call_Request struct {
|
||||
Requests []*Request `protobuf:"bytes,1,rep,name=requests" json:"requests,omitempty"`
|
||||
// Subscribes the scheduler with the master to receive events. A
|
||||
// scheduler must send other calls only after it has received the
|
||||
// SUBCRIBED event.
|
||||
type Call_Subscribe struct {
|
||||
// See the comments below on 'framework_id' on the semantics for
|
||||
// 'framework_info.id'.
|
||||
FrameworkInfo *FrameworkInfo `protobuf:"bytes,1,req,name=framework_info" json:"framework_info,omitempty"`
|
||||
// 'force' field is only relevant when 'framework_info.id' is set.
|
||||
// It tells the master what to do in case an instance of the
|
||||
// scheduler attempts to subscribe when another instance of it is
|
||||
// already connected (e.g., split brain due to network partition).
|
||||
// If 'force' is true, this scheduler instance is allowed and the
|
||||
// old connected scheduler instance is disconnected. If false,
|
||||
// this scheduler instance is disallowed subscription in favor of
|
||||
// the already connected scheduler instance.
|
||||
//
|
||||
// It is recommended to set this to true only when a newly elected
|
||||
// scheduler instance is attempting to subscribe but not when a
|
||||
// scheduler is retrying subscription (e.g., disconnection or
|
||||
// master failover; see sched/sched.cpp for an example).
|
||||
Force *bool `protobuf:"varint,2,opt,name=force" json:"force,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Call_Request) Reset() { *m = Call_Request{} }
|
||||
func (m *Call_Request) String() string { return proto.CompactTextString(m) }
|
||||
func (*Call_Request) ProtoMessage() {}
|
||||
func (m *Call_Subscribe) Reset() { *m = Call_Subscribe{} }
|
||||
func (m *Call_Subscribe) String() string { return proto.CompactTextString(m) }
|
||||
func (*Call_Subscribe) ProtoMessage() {}
|
||||
|
||||
func (m *Call_Request) GetRequests() []*Request {
|
||||
func (m *Call_Subscribe) GetFrameworkInfo() *FrameworkInfo {
|
||||
if m != nil {
|
||||
return m.Requests
|
||||
return m.FrameworkInfo
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Call_Subscribe) GetForce() bool {
|
||||
if m != nil && m.Force != nil {
|
||||
return *m.Force
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Accepts an offer, performing the specified operations
|
||||
// in a sequential manner.
|
||||
//
|
||||
// E.g. Launch a task with a newly reserved persistent volume:
|
||||
//
|
||||
// Accept {
|
||||
// offer_ids: [ ... ]
|
||||
// operations: [
|
||||
// { type: RESERVE,
|
||||
// reserve: { resources: [ disk(role):2 ] } }
|
||||
// { type: CREATE,
|
||||
// create: { volumes: [ disk(role):1+persistence ] } }
|
||||
// { type: LAUNCH,
|
||||
// launch: { task_infos ... disk(role):1;disk(role):1+persistence } }
|
||||
// ]
|
||||
// }
|
||||
//
|
||||
// Note that any of the offer’s resources not used in the 'Accept'
|
||||
// call (e.g., to launch a task) are considered unused and might be
|
||||
// reoffered to other frameworks. In other words, the same OfferID
|
||||
// cannot be used in more than one 'Accept' call.
|
||||
type Call_Accept struct {
|
||||
OfferIds []*OfferID `protobuf:"bytes,1,rep,name=offer_ids" json:"offer_ids,omitempty"`
|
||||
Operations []*Offer_Operation `protobuf:"bytes,2,rep,name=operations" json:"operations,omitempty"`
|
||||
Filters *Filters `protobuf:"bytes,3,opt,name=filters" json:"filters,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Call_Accept) Reset() { *m = Call_Accept{} }
|
||||
func (m *Call_Accept) String() string { return proto.CompactTextString(m) }
|
||||
func (*Call_Accept) ProtoMessage() {}
|
||||
|
||||
func (m *Call_Accept) GetOfferIds() []*OfferID {
|
||||
if m != nil {
|
||||
return m.OfferIds
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Call_Accept) GetOperations() []*Offer_Operation {
|
||||
if m != nil {
|
||||
return m.Operations
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Call_Accept) GetFilters() *Filters {
|
||||
if m != nil {
|
||||
return m.Filters
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Declines an offer, signaling the master to potentially reoffer
|
||||
// the resources to a different framework. Note that this is same
|
||||
// as sending an Accept call with no operations. See comments on
|
||||
// top of 'Accept' for semantics.
|
||||
type Call_Decline struct {
|
||||
OfferIds []*OfferID `protobuf:"bytes,1,rep,name=offer_ids" json:"offer_ids,omitempty"`
|
||||
Filters *Filters `protobuf:"bytes,2,opt,name=filters" json:"filters,omitempty"`
|
||||
|
|
@ -532,40 +613,16 @@ func (m *Call_Decline) GetFilters() *Filters {
|
|||
return nil
|
||||
}
|
||||
|
||||
type Call_Launch struct {
|
||||
TaskInfos []*TaskInfo `protobuf:"bytes,1,rep,name=task_infos" json:"task_infos,omitempty"`
|
||||
OfferIds []*OfferID `protobuf:"bytes,2,rep,name=offer_ids" json:"offer_ids,omitempty"`
|
||||
Filters *Filters `protobuf:"bytes,3,opt,name=filters" json:"filters,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Call_Launch) Reset() { *m = Call_Launch{} }
|
||||
func (m *Call_Launch) String() string { return proto.CompactTextString(m) }
|
||||
func (*Call_Launch) ProtoMessage() {}
|
||||
|
||||
func (m *Call_Launch) GetTaskInfos() []*TaskInfo {
|
||||
if m != nil {
|
||||
return m.TaskInfos
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Call_Launch) GetOfferIds() []*OfferID {
|
||||
if m != nil {
|
||||
return m.OfferIds
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Call_Launch) GetFilters() *Filters {
|
||||
if m != nil {
|
||||
return m.Filters
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Kills a specific task. If the scheduler has a custom executor,
|
||||
// the kill is forwarded to the executor and it is up to the
|
||||
// executor to kill the task and send a TASK_KILLED (or TASK_FAILED)
|
||||
// update. Note that Mesos releases the resources for a task once it
|
||||
// receives a terminal update (See TaskState in mesos.proto) for it.
|
||||
// If the task is unknown to the master, a TASK_LOST update is
|
||||
// generated.
|
||||
type Call_Kill struct {
|
||||
TaskId *TaskID `protobuf:"bytes,1,req,name=task_id" json:"task_id,omitempty"`
|
||||
SlaveId *SlaveID `protobuf:"bytes,2,opt,name=slave_id" json:"slave_id,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
|
|
@ -580,6 +637,49 @@ func (m *Call_Kill) GetTaskId() *TaskID {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *Call_Kill) GetSlaveId() *SlaveID {
|
||||
if m != nil {
|
||||
return m.SlaveId
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Shuts down a custom executor. When the executor gets a shutdown
|
||||
// event, it is expected to kill all its tasks (and send TASK_KILLED
|
||||
// updates) and terminate. If the executor doesn’t terminate within
|
||||
// a certain timeout (configurable via
|
||||
// '--executor_shutdown_grace_period' slave flag), the slave will
|
||||
// forcefully destroy the container (executor and its tasks) and
|
||||
// transition its active tasks to TASK_LOST.
|
||||
type Call_Shutdown struct {
|
||||
ExecutorId *ExecutorID `protobuf:"bytes,1,req,name=executor_id" json:"executor_id,omitempty"`
|
||||
SlaveId *SlaveID `protobuf:"bytes,2,req,name=slave_id" json:"slave_id,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Call_Shutdown) Reset() { *m = Call_Shutdown{} }
|
||||
func (m *Call_Shutdown) String() string { return proto.CompactTextString(m) }
|
||||
func (*Call_Shutdown) ProtoMessage() {}
|
||||
|
||||
func (m *Call_Shutdown) GetExecutorId() *ExecutorID {
|
||||
if m != nil {
|
||||
return m.ExecutorId
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Call_Shutdown) GetSlaveId() *SlaveID {
|
||||
if m != nil {
|
||||
return m.SlaveId
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Acknowledges the receipt of status update. Schedulers are
|
||||
// responsible for explicitly acknowledging the receipt of status
|
||||
// updates that have 'Update.status().uuid()' field set. Such status
|
||||
// updates are retried by the slave until they are acknowledged by
|
||||
// the scheduler.
|
||||
type Call_Acknowledge struct {
|
||||
SlaveId *SlaveID `protobuf:"bytes,1,req,name=slave_id" json:"slave_id,omitempty"`
|
||||
TaskId *TaskID `protobuf:"bytes,2,req,name=task_id" json:"task_id,omitempty"`
|
||||
|
|
@ -612,16 +712,14 @@ func (m *Call_Acknowledge) GetUuid() []byte {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Allows the framework to query the status for non-terminal tasks.
|
||||
// Allows the scheduler to query the status for non-terminal tasks.
|
||||
// This causes the master to send back the latest task status for
|
||||
// each task in 'statuses', if possible. Tasks that are no longer
|
||||
// known will result in a TASK_LOST update. If statuses is empty,
|
||||
// then the master will send the latest status for each task
|
||||
// currently known.
|
||||
// TODO(bmahler): Add a guiding document for reconciliation or
|
||||
// document reconciliation in-depth here.
|
||||
// each task in 'tasks', if possible. Tasks that are no longer known
|
||||
// will result in a TASK_LOST update. If 'statuses' is empty, then
|
||||
// the master will send the latest status for each task currently
|
||||
// known.
|
||||
type Call_Reconcile struct {
|
||||
Statuses []*TaskStatus `protobuf:"bytes,1,rep,name=statuses" json:"statuses,omitempty"`
|
||||
Tasks []*Call_Reconcile_Task `protobuf:"bytes,1,rep,name=tasks" json:"tasks,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
|
|
@ -629,13 +727,41 @@ func (m *Call_Reconcile) Reset() { *m = Call_Reconcile{} }
|
|||
func (m *Call_Reconcile) String() string { return proto.CompactTextString(m) }
|
||||
func (*Call_Reconcile) ProtoMessage() {}
|
||||
|
||||
func (m *Call_Reconcile) GetStatuses() []*TaskStatus {
|
||||
func (m *Call_Reconcile) GetTasks() []*Call_Reconcile_Task {
|
||||
if m != nil {
|
||||
return m.Statuses
|
||||
return m.Tasks
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO(vinod): Support arbitrary queries than just state of tasks.
|
||||
type Call_Reconcile_Task struct {
|
||||
TaskId *TaskID `protobuf:"bytes,1,req,name=task_id" json:"task_id,omitempty"`
|
||||
SlaveId *SlaveID `protobuf:"bytes,2,opt,name=slave_id" json:"slave_id,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Call_Reconcile_Task) Reset() { *m = Call_Reconcile_Task{} }
|
||||
func (m *Call_Reconcile_Task) String() string { return proto.CompactTextString(m) }
|
||||
func (*Call_Reconcile_Task) ProtoMessage() {}
|
||||
|
||||
func (m *Call_Reconcile_Task) GetTaskId() *TaskID {
|
||||
if m != nil {
|
||||
return m.TaskId
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Call_Reconcile_Task) GetSlaveId() *SlaveID {
|
||||
if m != nil {
|
||||
return m.SlaveId
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Sends arbitrary binary data to the executor. Note that Mesos
|
||||
// neither interprets this data nor makes any guarantees about the
|
||||
// delivery of this message to the executor.
|
||||
type Call_Message struct {
|
||||
SlaveId *SlaveID `protobuf:"bytes,1,req,name=slave_id" json:"slave_id,omitempty"`
|
||||
ExecutorId *ExecutorID `protobuf:"bytes,2,req,name=executor_id" json:"executor_id,omitempty"`
|
||||
|
|
|
|||
|
|
@ -23,54 +23,80 @@ import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
|||
|
||||
|
||||
/**
|
||||
* Low-level scheduler event API.
|
||||
* Scheduler event API.
|
||||
*
|
||||
* An event is described using the standard protocol buffer "union"
|
||||
* trick, see https://developers.google.com/protocol-buffers/docs/techniques#union.
|
||||
* trick, see:
|
||||
* https://developers.google.com/protocol-buffers/docs/techniques#union.
|
||||
*/
|
||||
message Event {
|
||||
// Possible event types, followed by message definitions if
|
||||
// applicable.
|
||||
enum Type {
|
||||
REGISTERED = 1;
|
||||
REREGISTERED = 2;
|
||||
OFFERS = 3;
|
||||
RESCIND = 4;
|
||||
UPDATE = 5;
|
||||
MESSAGE = 6;
|
||||
FAILURE = 7;
|
||||
ERROR = 8;
|
||||
SUBSCRIBED = 1; // See 'Subscribed' below.
|
||||
OFFERS = 2; // See 'Offers' below.
|
||||
RESCIND = 3; // See 'Rescind' below.
|
||||
UPDATE = 4; // See 'Update' below.
|
||||
MESSAGE = 5; // See 'Message' below.
|
||||
FAILURE = 6; // See 'Failure' below.
|
||||
ERROR = 7; // See 'Error' below.
|
||||
}
|
||||
|
||||
message Registered {
|
||||
// First event received when the scheduler subscribes.
|
||||
message Subscribed {
|
||||
required FrameworkID framework_id = 1;
|
||||
required MasterInfo master_info = 2;
|
||||
}
|
||||
|
||||
message Reregistered {
|
||||
required FrameworkID framework_id = 1;
|
||||
required MasterInfo master_info = 2;
|
||||
}
|
||||
|
||||
// Received whenever there are new resources that are offered to the
|
||||
// scheduler. Each offer corresponds to a set of resources on a
|
||||
// slave. Until the scheduler accepts or declines an offer the
|
||||
// resources are considered allocated to the scheduler.
|
||||
message Offers {
|
||||
repeated Offer offers = 1;
|
||||
}
|
||||
|
||||
// Received when a particular offer is no longer valid (e.g., the
|
||||
// slave corresponding to the offer has been removed) and hence
|
||||
// needs to be rescinded. Any future calls ('Accept' / 'Decline') made
|
||||
// by the scheduler regarding this offer will be invalid.
|
||||
message Rescind {
|
||||
required OfferID offer_id = 1;
|
||||
}
|
||||
|
||||
// Received whenever there is a status update that is generated by
|
||||
// the executor or slave or master. Status updates should be used by
|
||||
// executors to reliably communicate the status of the tasks that
|
||||
// they manage. It is crucial that a terminal update (see TaskState
|
||||
// in mesos.proto) is sent by the executor as soon as the task
|
||||
// terminates, in order for Mesos to release the resources allocated
|
||||
// to the task. It is also the responsibility of the scheduler to
|
||||
// explicitly acknowledge the receipt of a status update. See
|
||||
// 'Acknowledge' in the 'Call' section below for the semantics.
|
||||
message Update {
|
||||
required bytes uuid = 1; // TODO(benh): Replace with UpdateID.
|
||||
required TaskStatus status = 2;
|
||||
required TaskStatus status = 1;
|
||||
}
|
||||
|
||||
// Received when a custom message generated by the executor is
|
||||
// forwarded by the master. Note that this message is not
|
||||
// interpreted by Mesos and is only forwarded (without reliability
|
||||
// guarantees) to the scheduler. It is up to the executor to retry
|
||||
// if the message is dropped for any reason.
|
||||
message Message {
|
||||
required SlaveID slave_id = 1;
|
||||
required ExecutorID executor_id = 2;
|
||||
required bytes data = 3;
|
||||
}
|
||||
|
||||
// Received when a slave is removed from the cluster (e.g., failed
|
||||
// health checks) or when an executor is terminated. Note that, this
|
||||
// event coincides with receipt of terminal UPDATE events for any
|
||||
// active tasks belonging to the slave or executor and receipt of
|
||||
// 'Rescind' events for any outstanding offers belonging to the
|
||||
// slave. Note that there is no guaranteed order between the
|
||||
// 'Failure', 'Update' and 'Rescind' events when a slave or executor
|
||||
// is removed.
|
||||
// TODO(vinod): Consider splitting the lost slave and terminated
|
||||
// executor into separate events and ensure it's reliably generated.
|
||||
message Failure {
|
||||
optional SlaveID slave_id = 1;
|
||||
|
||||
|
|
@ -81,29 +107,33 @@ message Event {
|
|||
optional int32 status = 3;
|
||||
}
|
||||
|
||||
// Received when an invalid framework (e.g., unauthenticated,
|
||||
// unauthorized) attempts to subscribe with the master. Error can
|
||||
// also be received if scheduler sends invalid Calls (e.g., not
|
||||
// properly initialized).
|
||||
// TODO(vinod): Remove this once the old scheduler driver is no
|
||||
// longer supported. With HTTP API all errors will be signaled via
|
||||
// HTTP response codes.
|
||||
message Error {
|
||||
required string message = 1;
|
||||
}
|
||||
|
||||
// TODO(benh): Add a 'from' or 'sender'.
|
||||
|
||||
// Type of the event, indicates which optional field below should be
|
||||
// present if that type has a nested message definition.
|
||||
required Type type = 1;
|
||||
|
||||
optional Registered registered = 2;
|
||||
optional Reregistered reregistered = 3;
|
||||
optional Offers offers = 4;
|
||||
optional Rescind rescind = 5;
|
||||
optional Update update = 6;
|
||||
optional Message message = 7;
|
||||
optional Failure failure = 8;
|
||||
optional Error error = 9;
|
||||
optional Subscribed subscribed = 2;
|
||||
optional Offers offers = 3;
|
||||
optional Rescind rescind = 4;
|
||||
optional Update update = 5;
|
||||
optional Message message = 6;
|
||||
optional Failure failure = 7;
|
||||
optional Error error = 8;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Low-level scheduler call API.
|
||||
* Scheduler call API.
|
||||
*
|
||||
* Like Event, a Call is described using the standard protocol buffer
|
||||
* "union" trick (see above).
|
||||
|
|
@ -112,20 +142,19 @@ message Call {
|
|||
// Possible call types, followed by message definitions if
|
||||
// applicable.
|
||||
enum Type {
|
||||
REGISTER = 1;
|
||||
REREGISTER = 2;
|
||||
UNREGISTER = 3;
|
||||
REQUEST = 4;
|
||||
DECLINE = 5;
|
||||
REVIVE = 6;
|
||||
LAUNCH = 7;
|
||||
KILL = 8;
|
||||
ACKNOWLEDGE = 9;
|
||||
RECONCILE = 10;
|
||||
MESSAGE = 11;
|
||||
SUBSCRIBE = 1; // See 'Subscribe' below.
|
||||
TEARDOWN = 2; // Shuts down all tasks/executors and removes framework.
|
||||
ACCEPT = 3; // See 'Accept' below.
|
||||
DECLINE = 4; // See 'Decline' below.
|
||||
REVIVE = 5; // Removes any previous filters set via ACCEPT or DECLINE.
|
||||
KILL = 6; // See 'Kill' below.
|
||||
SHUTDOWN = 7; // See 'Shutdown' below.
|
||||
ACKNOWLEDGE = 8; // See 'Acknowledge' below.
|
||||
RECONCILE = 9; // See 'Reconcile' below.
|
||||
MESSAGE = 10; // See 'Message' below.
|
||||
|
||||
// TODO(benh): Consider adding an 'ACTIVATE' and 'DEACTIVATE' for
|
||||
// already registered frameworks as a way of stopping offers from
|
||||
// already subscribed frameworks as a way of stopping offers from
|
||||
// being generated and other events from being sent by the master.
|
||||
// Note that this functionality existed originally to support
|
||||
// SchedulerDriver::abort which was only necessary to handle
|
||||
|
|
@ -133,63 +162,144 @@ message Call {
|
|||
// something that is not an issue with the Event/Call API.
|
||||
}
|
||||
|
||||
message Request {
|
||||
repeated mesosproto.Request requests = 1;
|
||||
// Subscribes the scheduler with the master to receive events. A
|
||||
// scheduler must send other calls only after it has received the
|
||||
// SUBCRIBED event.
|
||||
message Subscribe {
|
||||
// See the comments below on 'framework_id' on the semantics for
|
||||
// 'framework_info.id'.
|
||||
required FrameworkInfo framework_info = 1;
|
||||
|
||||
// 'force' field is only relevant when 'framework_info.id' is set.
|
||||
// It tells the master what to do in case an instance of the
|
||||
// scheduler attempts to subscribe when another instance of it is
|
||||
// already connected (e.g., split brain due to network partition).
|
||||
// If 'force' is true, this scheduler instance is allowed and the
|
||||
// old connected scheduler instance is disconnected. If false,
|
||||
// this scheduler instance is disallowed subscription in favor of
|
||||
// the already connected scheduler instance.
|
||||
//
|
||||
// It is recommended to set this to true only when a newly elected
|
||||
// scheduler instance is attempting to subscribe but not when a
|
||||
// scheduler is retrying subscription (e.g., disconnection or
|
||||
// master failover; see sched/sched.cpp for an example).
|
||||
optional bool force = 2;
|
||||
}
|
||||
|
||||
// Accepts an offer, performing the specified operations
|
||||
// in a sequential manner.
|
||||
//
|
||||
// E.g. Launch a task with a newly reserved persistent volume:
|
||||
//
|
||||
// Accept {
|
||||
// offer_ids: [ ... ]
|
||||
// operations: [
|
||||
// { type: RESERVE,
|
||||
// reserve: { resources: [ disk(role):2 ] } }
|
||||
// { type: CREATE,
|
||||
// create: { volumes: [ disk(role):1+persistence ] } }
|
||||
// { type: LAUNCH,
|
||||
// launch: { task_infos ... disk(role):1;disk(role):1+persistence } }
|
||||
// ]
|
||||
// }
|
||||
//
|
||||
// Note that any of the offer’s resources not used in the 'Accept'
|
||||
// call (e.g., to launch a task) are considered unused and might be
|
||||
// reoffered to other frameworks. In other words, the same OfferID
|
||||
// cannot be used in more than one 'Accept' call.
|
||||
message Accept {
|
||||
repeated OfferID offer_ids = 1;
|
||||
repeated Offer.Operation operations = 2;
|
||||
optional Filters filters = 3;
|
||||
}
|
||||
|
||||
// Declines an offer, signaling the master to potentially reoffer
|
||||
// the resources to a different framework. Note that this is same
|
||||
// as sending an Accept call with no operations. See comments on
|
||||
// top of 'Accept' for semantics.
|
||||
message Decline {
|
||||
repeated OfferID offer_ids = 1;
|
||||
optional Filters filters = 2;
|
||||
}
|
||||
|
||||
message Launch {
|
||||
repeated TaskInfo task_infos = 1;
|
||||
repeated OfferID offer_ids = 2;
|
||||
optional Filters filters = 3;
|
||||
}
|
||||
|
||||
// Kills a specific task. If the scheduler has a custom executor,
|
||||
// the kill is forwarded to the executor and it is up to the
|
||||
// executor to kill the task and send a TASK_KILLED (or TASK_FAILED)
|
||||
// update. Note that Mesos releases the resources for a task once it
|
||||
// receives a terminal update (See TaskState in mesos.proto) for it.
|
||||
// If the task is unknown to the master, a TASK_LOST update is
|
||||
// generated.
|
||||
message Kill {
|
||||
required TaskID task_id = 1;
|
||||
optional SlaveID slave_id = 2;
|
||||
}
|
||||
|
||||
// Shuts down a custom executor. When the executor gets a shutdown
|
||||
// event, it is expected to kill all its tasks (and send TASK_KILLED
|
||||
// updates) and terminate. If the executor doesn’t terminate within
|
||||
// a certain timeout (configurable via
|
||||
// '--executor_shutdown_grace_period' slave flag), the slave will
|
||||
// forcefully destroy the container (executor and its tasks) and
|
||||
// transition its active tasks to TASK_LOST.
|
||||
message Shutdown {
|
||||
required ExecutorID executor_id = 1;
|
||||
required SlaveID slave_id = 2;
|
||||
}
|
||||
|
||||
// Acknowledges the receipt of status update. Schedulers are
|
||||
// responsible for explicitly acknowledging the receipt of status
|
||||
// updates that have 'Update.status().uuid()' field set. Such status
|
||||
// updates are retried by the slave until they are acknowledged by
|
||||
// the scheduler.
|
||||
message Acknowledge {
|
||||
required SlaveID slave_id = 1;
|
||||
required TaskID task_id = 2;
|
||||
required bytes uuid = 3;
|
||||
}
|
||||
|
||||
// Allows the framework to query the status for non-terminal tasks.
|
||||
// Allows the scheduler to query the status for non-terminal tasks.
|
||||
// This causes the master to send back the latest task status for
|
||||
// each task in 'statuses', if possible. Tasks that are no longer
|
||||
// known will result in a TASK_LOST update. If statuses is empty,
|
||||
// then the master will send the latest status for each task
|
||||
// currently known.
|
||||
// TODO(bmahler): Add a guiding document for reconciliation or
|
||||
// document reconciliation in-depth here.
|
||||
// each task in 'tasks', if possible. Tasks that are no longer known
|
||||
// will result in a TASK_LOST update. If 'statuses' is empty, then
|
||||
// the master will send the latest status for each task currently
|
||||
// known.
|
||||
message Reconcile {
|
||||
repeated TaskStatus statuses = 1; // Should be non-terminal only.
|
||||
// TODO(vinod): Support arbitrary queries than just state of tasks.
|
||||
message Task {
|
||||
required TaskID task_id = 1;
|
||||
optional SlaveID slave_id = 2;
|
||||
}
|
||||
|
||||
repeated Task tasks = 1;
|
||||
}
|
||||
|
||||
// Sends arbitrary binary data to the executor. Note that Mesos
|
||||
// neither interprets this data nor makes any guarantees about the
|
||||
// delivery of this message to the executor.
|
||||
message Message {
|
||||
required SlaveID slave_id = 1;
|
||||
required ExecutorID executor_id = 2;
|
||||
required bytes data = 3;
|
||||
}
|
||||
|
||||
// Identifies who generated this call. Always necessary, but the
|
||||
// only thing that needs to be set for certain calls, e.g.,
|
||||
// REGISTER, REREGISTER, and UNREGISTER.
|
||||
required FrameworkInfo framework_info = 1;
|
||||
// Identifies who generated this call. Master assigns a framework id
|
||||
// when a new scheduler subscribes for the first time. Once assigned,
|
||||
// the scheduler must set the 'framework_id' here and within its
|
||||
// FrameworkInfo (in any further 'Subscribe' calls). This allows the
|
||||
// master to identify a scheduler correctly across disconnections,
|
||||
// failovers, etc.
|
||||
optional FrameworkID framework_id = 1;
|
||||
|
||||
// Type of the call, indicates which optional field below should be
|
||||
// present if that type has a nested message definition.
|
||||
required Type type = 2;
|
||||
|
||||
optional Request request = 3;
|
||||
optional Decline decline = 4;
|
||||
optional Launch launch = 5;
|
||||
optional Subscribe subscribe = 3;
|
||||
optional Accept accept = 4;
|
||||
optional Decline decline = 5;
|
||||
optional Kill kill = 6;
|
||||
optional Acknowledge acknowledge = 7;
|
||||
optional Reconcile reconcile = 8;
|
||||
optional Message message = 9;
|
||||
optional Shutdown shutdown = 7;
|
||||
optional Acknowledge acknowledge = 8;
|
||||
optional Reconcile reconcile = 9;
|
||||
optional Message message = 10;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
6
Godeps/_workspace/src/github.com/mesos/mesos-go/messenger/http_transporter_test.go
generated
vendored
6
Godeps/_workspace/src/github.com/mesos/mesos-go/messenger/http_transporter_test.go
generated
vendored
|
|
@ -274,7 +274,7 @@ func TestMutatedHostUPid(t *testing.T) {
|
|||
serverAddr := serverHost + ":" + strconv.Itoa(serverPort)
|
||||
|
||||
// override the upid.Host with this listener IP
|
||||
addr := net.ParseIP("127.0.0.2")
|
||||
addr := net.ParseIP("0.0.0.0")
|
||||
|
||||
// setup receiver (server) process
|
||||
uPid, err := upid.Parse(fmt.Sprintf("%s@%s", serverId, serverAddr))
|
||||
|
|
@ -308,7 +308,7 @@ func TestEmptyHostPortUPid(t *testing.T) {
|
|||
uPid.Port = ""
|
||||
|
||||
// override the upid.Host with this listener IP
|
||||
addr := net.ParseIP("127.0.0.2")
|
||||
addr := net.ParseIP("0.0.0.0")
|
||||
|
||||
receiver := NewHTTPTransporter(uPid, addr)
|
||||
|
||||
|
|
@ -316,7 +316,7 @@ func TestEmptyHostPortUPid(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
|
||||
// This should be the host that overrides as uPid.Host is empty
|
||||
if receiver.upid.Host != "127.0.0.2" {
|
||||
if receiver.upid.Host != "0.0.0.0" {
|
||||
t.Fatalf("reciever.upid.Host was expected to return %s, got %s\n", serverHost, receiver.upid.Host)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ type MesosMessenger struct {
|
|||
|
||||
// ForHostname creates a new default messenger (HTTP), using UPIDBindingAddress to
|
||||
// determine the binding-address used for both the UPID.Host and Transport binding address.
|
||||
func ForHostname(proc *process.Process, hostname string, bindingAddress net.IP, port uint16) (Messenger, error) {
|
||||
func ForHostname(proc *process.Process, hostname string, bindingAddress net.IP, port uint16, publishedAddress net.IP) (Messenger, error) {
|
||||
upid := &upid.UPID{
|
||||
ID: proc.Label(),
|
||||
Port: strconv.Itoa(int(port)),
|
||||
|
|
@ -87,7 +87,21 @@ func ForHostname(proc *process.Process, hostname string, bindingAddress net.IP,
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var publishedHost string
|
||||
if publishedAddress != nil {
|
||||
publishedHost, err = UPIDBindingAddress(hostname, publishedAddress)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if publishedHost != "" {
|
||||
upid.Host = publishedHost
|
||||
} else {
|
||||
upid.Host = host
|
||||
}
|
||||
|
||||
return NewHttpWithBindingAddress(upid, bindingAddress), nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"code.google.com/p/go-uuid/uuid"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
log "github.com/golang/glog"
|
||||
"github.com/mesos/mesos-go/auth"
|
||||
|
|
@ -38,6 +37,7 @@ import (
|
|||
"github.com/mesos/mesos-go/mesosutil/process"
|
||||
"github.com/mesos/mesos-go/messenger"
|
||||
"github.com/mesos/mesos-go/upid"
|
||||
"github.com/pborman/uuid"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
|
|
@ -86,6 +86,7 @@ type DriverConfig struct {
|
|||
HostnameOverride string // optional
|
||||
BindingAddress net.IP // optional
|
||||
BindingPort uint16 // optional
|
||||
PublishedAddress net.IP // optional
|
||||
NewMessenger func() (messenger.Messenger, error) // optional
|
||||
}
|
||||
|
||||
|
|
@ -196,7 +197,7 @@ func NewMesosSchedulerDriver(config DriverConfig) (initializedDriver *MesosSched
|
|||
if newMessenger == nil {
|
||||
newMessenger = func() (messenger.Messenger, error) {
|
||||
process := process.New("scheduler")
|
||||
return messenger.ForHostname(process, hostname, config.BindingAddress, config.BindingPort)
|
||||
return messenger.ForHostname(process, hostname, config.BindingAddress, config.BindingPort, config.PublishedAddress)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
Paul Borman <borman@google.com>
|
||||
|
|
@ -157,7 +157,7 @@ func newTask(c *Cluster, config *cluster.ContainerConfig, name string) (*task, e
|
|||
|
||||
task.Name = &name
|
||||
task.TaskId = &mesosproto.TaskID{Value: &id}
|
||||
|
||||
task.Labels = &mesosproto.Labels{Labels: []*mesosproto.Label{{Key: proto.String("SWARM_CONTAINER_NAME"), Value: &name}}}
|
||||
return task, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue