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": [
|
"Deps": [
|
||||||
{
|
|
||||||
"ImportPath": "code.google.com/p/go-uuid/uuid",
|
|
||||||
"Comment": "null-15",
|
|
||||||
"Rev": "35bc42037350f0078e3c974c6ea690f1926603ab"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/Sirupsen/logrus",
|
"ImportPath": "github.com/Sirupsen/logrus",
|
||||||
"Comment": "v0.6.4-6-g539d4dc",
|
"Comment": "v0.6.4-6-g539d4dc",
|
||||||
|
|
@ -56,7 +51,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gogo/protobuf/proto",
|
"ImportPath": "github.com/gogo/protobuf/proto",
|
||||||
"Rev": "bc946d07d1016848dfd2507f90f0859c9471681e"
|
"Rev": "8edb24c179ed858a38f18920d9005c2dde05ec17"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/golang/glog",
|
"ImportPath": "github.com/golang/glog",
|
||||||
|
|
@ -77,35 +72,35 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/mesos/mesos-go/auth",
|
"ImportPath": "github.com/mesos/mesos-go/auth",
|
||||||
"Rev": "83b52d7f648d2a2fa91330123d348d4090be2aed"
|
"Rev": "d23a18b51b1ddf4072a223b38cc8d05cffb1ea42"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/mesos/mesos-go/detector",
|
"ImportPath": "github.com/mesos/mesos-go/detector",
|
||||||
"Rev": "83b52d7f648d2a2fa91330123d348d4090be2aed"
|
"Rev": "d23a18b51b1ddf4072a223b38cc8d05cffb1ea42"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/mesos/mesos-go/mesosproto",
|
"ImportPath": "github.com/mesos/mesos-go/mesosproto",
|
||||||
"Rev": "83b52d7f648d2a2fa91330123d348d4090be2aed"
|
"Rev": "d23a18b51b1ddf4072a223b38cc8d05cffb1ea42"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/mesos/mesos-go/mesosutil",
|
"ImportPath": "github.com/mesos/mesos-go/mesosutil",
|
||||||
"Rev": "83b52d7f648d2a2fa91330123d348d4090be2aed"
|
"Rev": "d23a18b51b1ddf4072a223b38cc8d05cffb1ea42"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/mesos/mesos-go/messenger",
|
"ImportPath": "github.com/mesos/mesos-go/messenger",
|
||||||
"Rev": "83b52d7f648d2a2fa91330123d348d4090be2aed"
|
"Rev": "d23a18b51b1ddf4072a223b38cc8d05cffb1ea42"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/mesos/mesos-go/scheduler",
|
"ImportPath": "github.com/mesos/mesos-go/scheduler",
|
||||||
"Rev": "83b52d7f648d2a2fa91330123d348d4090be2aed"
|
"Rev": "d23a18b51b1ddf4072a223b38cc8d05cffb1ea42"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/mesos/mesos-go/upid",
|
"ImportPath": "github.com/mesos/mesos-go/upid",
|
||||||
"Rev": "83b52d7f648d2a2fa91330123d348d4090be2aed"
|
"Rev": "d23a18b51b1ddf4072a223b38cc8d05cffb1ea42"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/skarademir/naturalsort",
|
"ImportPath": "github.com/pborman/uuid",
|
||||||
"Rev": "69a5d87bef620f77ee8508db30c846b3b84b111e"
|
"Rev": "ca53cad383cad2479bbba7f7a1a05797ec1386e4"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/samalba/dockerclient",
|
"ImportPath": "github.com/samalba/dockerclient",
|
||||||
|
|
@ -115,6 +110,10 @@
|
||||||
"ImportPath": "github.com/samuel/go-zookeeper/zk",
|
"ImportPath": "github.com/samuel/go-zookeeper/zk",
|
||||||
"Rev": "fa6674abf3f4580b946a01bf7a1ce4ba8766205b"
|
"Rev": "fa6674abf3f4580b946a01bf7a1ce4ba8766205b"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/skarademir/naturalsort",
|
||||||
|
"Rev": "69a5d87bef620f77ee8508db30c846b3b84b111e"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/stretchr/objx",
|
"ImportPath": "github.com/stretchr/objx",
|
||||||
"Rev": "cbeaeb16a013161a98496fad62933b1d21786672"
|
"Rev": "cbeaeb16a013161a98496fad62933b1d21786672"
|
||||||
|
|
|
||||||
|
|
@ -37,4 +37,7 @@ test: install generate-test-pbs
|
||||||
|
|
||||||
|
|
||||||
generate-test-pbs:
|
generate-test-pbs:
|
||||||
make install && cd testdata && make
|
make install
|
||||||
|
make -C testdata
|
||||||
|
protoc-min-version --version="3.0.0" --proto_path=.:../../../../ --gogo_out=. proto3_proto/proto3.proto
|
||||||
|
make
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,8 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
. "./testdata"
|
|
||||||
. "github.com/gogo/protobuf/proto"
|
. "github.com/gogo/protobuf/proto"
|
||||||
|
. "github.com/gogo/protobuf/proto/testdata"
|
||||||
)
|
)
|
||||||
|
|
||||||
var globalO *Buffer
|
var globalO *Buffer
|
||||||
|
|
@ -1252,7 +1252,8 @@ func TestProto1RepeatedGroup(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
o := old()
|
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)
|
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) {
|
func TestMaximumTagNumber(t *testing.T) {
|
||||||
m := &MaxTag{
|
m := &MaxTag{
|
||||||
LastField: String("natural goat essence"),
|
LastField: String("natural goat essence"),
|
||||||
|
|
@ -1833,6 +1845,98 @@ func fuzzUnmarshal(t *testing.T, data []byte) {
|
||||||
Unmarshal(data, pb)
|
Unmarshal(data, pb)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMapFieldMarshal(t *testing.T) {
|
||||||
|
m := &MessageWithMap{
|
||||||
|
NameMapping: map[int32]string{
|
||||||
|
1: "Rob",
|
||||||
|
4: "Ian",
|
||||||
|
8: "Dave",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
b, err := Marshal(m)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Marshal: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// b should be the concatenation of these three byte sequences in some order.
|
||||||
|
parts := []string{
|
||||||
|
"\n\a\b\x01\x12\x03Rob",
|
||||||
|
"\n\a\b\x04\x12\x03Ian",
|
||||||
|
"\n\b\b\x08\x12\x04Dave",
|
||||||
|
}
|
||||||
|
ok := false
|
||||||
|
for i := range parts {
|
||||||
|
for j := range parts {
|
||||||
|
if j == i {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for k := range parts {
|
||||||
|
if k == i || k == j {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
try := parts[i] + parts[j] + parts[k]
|
||||||
|
if bytes.Equal(b, []byte(try)) {
|
||||||
|
ok = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("Incorrect Marshal output.\n got %q\nwant %q (or a permutation of that)", b, parts[0]+parts[1]+parts[2])
|
||||||
|
}
|
||||||
|
t.Logf("FYI b: %q", b)
|
||||||
|
|
||||||
|
(new(Buffer)).DebugPrint("Dump of b", b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMapFieldRoundTrips(t *testing.T) {
|
||||||
|
m := &MessageWithMap{
|
||||||
|
NameMapping: map[int32]string{
|
||||||
|
1: "Rob",
|
||||||
|
4: "Ian",
|
||||||
|
8: "Dave",
|
||||||
|
},
|
||||||
|
MsgMapping: map[int64]*FloatingPoint{
|
||||||
|
0x7001: {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
|
// Benchmarks
|
||||||
|
|
||||||
func testMsg() *GoTest {
|
func testMsg() *GoTest {
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
// Protocol buffer deep copy.
|
// Protocol buffer deep copy and merge.
|
||||||
// TODO: MessageSet and RawMessage.
|
// TODO: MessageSet and RawMessage.
|
||||||
|
|
||||||
package proto
|
package proto
|
||||||
|
|
@ -75,12 +75,13 @@ func Merge(dst, src Message) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func mergeStruct(out, in reflect.Value) {
|
func mergeStruct(out, in reflect.Value) {
|
||||||
|
sprop := GetProperties(in.Type())
|
||||||
for i := 0; i < in.NumField(); i++ {
|
for i := 0; i < in.NumField(); i++ {
|
||||||
f := in.Type().Field(i)
|
f := in.Type().Field(i)
|
||||||
if strings.HasPrefix(f.Name, "XXX_") {
|
if strings.HasPrefix(f.Name, "XXX_") {
|
||||||
continue
|
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 {
|
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.Type() == protoMessageType {
|
||||||
if !in.IsNil() {
|
if !in.IsNil() {
|
||||||
if out.IsNil() {
|
if out.IsNil() {
|
||||||
|
|
@ -117,7 +121,33 @@ func mergeAny(out, in reflect.Value) {
|
||||||
switch in.Kind() {
|
switch in.Kind() {
|
||||||
case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
|
case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
|
||||||
reflect.String, reflect.Uint32, reflect.Uint64:
|
reflect.String, reflect.Uint32, reflect.Uint64:
|
||||||
|
if !viaPtr && isProto3Zero(in) {
|
||||||
|
return
|
||||||
|
}
|
||||||
out.Set(in)
|
out.Set(in)
|
||||||
|
case reflect.Map:
|
||||||
|
if in.Len() == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if out.IsNil() {
|
||||||
|
out.Set(reflect.MakeMap(in.Type()))
|
||||||
|
}
|
||||||
|
// For maps with value types of *T or []byte we need to deep copy each value.
|
||||||
|
elemKind := in.Type().Elem().Kind()
|
||||||
|
for _, key := range in.MapKeys() {
|
||||||
|
var val reflect.Value
|
||||||
|
switch elemKind {
|
||||||
|
case reflect.Ptr:
|
||||||
|
val = reflect.New(in.Type().Elem().Elem())
|
||||||
|
mergeAny(val, in.MapIndex(key), 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:
|
case reflect.Ptr:
|
||||||
if in.IsNil() {
|
if in.IsNil() {
|
||||||
return
|
return
|
||||||
|
|
@ -125,13 +155,21 @@ func mergeAny(out, in reflect.Value) {
|
||||||
if out.IsNil() {
|
if out.IsNil() {
|
||||||
out.Set(reflect.New(in.Elem().Type()))
|
out.Set(reflect.New(in.Elem().Type()))
|
||||||
}
|
}
|
||||||
mergeAny(out.Elem(), in.Elem())
|
mergeAny(out.Elem(), in.Elem(), true, nil)
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
if in.IsNil() {
|
if in.IsNil() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if in.Type().Elem().Kind() == reflect.Uint8 {
|
if in.Type().Elem().Kind() == reflect.Uint8 {
|
||||||
// []byte is a scalar bytes field, not a repeated field.
|
// []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.
|
// Make a deep copy.
|
||||||
// Append to []byte{} instead of []byte(nil) so that we never end up
|
// Append to []byte{} instead of []byte(nil) so that we never end up
|
||||||
// with a nil result.
|
// with a nil result.
|
||||||
|
|
@ -149,7 +187,7 @@ func mergeAny(out, in reflect.Value) {
|
||||||
default:
|
default:
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
x := reflect.Indirect(reflect.New(in.Type().Elem()))
|
x := reflect.Indirect(reflect.New(in.Type().Elem()))
|
||||||
mergeAny(x, in.Index(i))
|
mergeAny(x, in.Index(i), false, nil)
|
||||||
out.Set(reflect.Append(out, x))
|
out.Set(reflect.Append(out, x))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -166,7 +204,7 @@ func mergeExtension(out, in map[int32]Extension) {
|
||||||
eOut := Extension{desc: eIn.desc}
|
eOut := Extension{desc: eIn.desc}
|
||||||
if eIn.value != nil {
|
if eIn.value != nil {
|
||||||
v := reflect.New(reflect.TypeOf(eIn.value)).Elem()
|
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()
|
eOut.value = v.Interface()
|
||||||
}
|
}
|
||||||
if eIn.enc != nil {
|
if eIn.enc != nil {
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,8 @@ import (
|
||||||
|
|
||||||
"github.com/gogo/protobuf/proto"
|
"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{
|
var cloneTestMessage = &pb.MyMessage{
|
||||||
|
|
@ -189,6 +190,48 @@ var mergeTests = []struct {
|
||||||
dst: &pb.OtherMessage{Value: []byte("bar")},
|
dst: &pb.OtherMessage{Value: []byte("bar")},
|
||||||
want: &pb.OtherMessage{Value: []byte("foo")},
|
want: &pb.OtherMessage{Value: []byte("foo")},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
src: &pb.MessageWithMap{
|
||||||
|
NameMapping: map[int32]string{6: "Nigel"},
|
||||||
|
MsgMapping: map[int64]*pb.FloatingPoint{
|
||||||
|
0x4001: {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) {
|
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) {
|
func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) {
|
||||||
n, err := p.DecodeVarint()
|
n, err := p.DecodeVarint()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
nb := int(n)
|
nb := int(n)
|
||||||
|
|
@ -470,6 +470,15 @@ func (o *Buffer) dec_bool(p *Properties, base structPointer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) dec_proto3_bool(p *Properties, base structPointer) error {
|
||||||
|
u, err := p.valDec(o)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*structPointer_BoolVal(base, p.field) = u != 0
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Decode an int32.
|
// Decode an int32.
|
||||||
func (o *Buffer) dec_int32(p *Properties, base structPointer) error {
|
func (o *Buffer) dec_int32(p *Properties, base structPointer) error {
|
||||||
u, err := p.valDec(o)
|
u, err := p.valDec(o)
|
||||||
|
|
@ -480,6 +489,15 @@ func (o *Buffer) dec_int32(p *Properties, base structPointer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) dec_proto3_int32(p *Properties, base structPointer) error {
|
||||||
|
u, err := p.valDec(o)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
word32Val_Set(structPointer_Word32Val(base, p.field), uint32(u))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Decode an int64.
|
// Decode an int64.
|
||||||
func (o *Buffer) dec_int64(p *Properties, base structPointer) error {
|
func (o *Buffer) dec_int64(p *Properties, base structPointer) error {
|
||||||
u, err := p.valDec(o)
|
u, err := p.valDec(o)
|
||||||
|
|
@ -490,15 +508,31 @@ func (o *Buffer) dec_int64(p *Properties, base structPointer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) dec_proto3_int64(p *Properties, base structPointer) error {
|
||||||
|
u, err := p.valDec(o)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
word64Val_Set(structPointer_Word64Val(base, p.field), o, u)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Decode a string.
|
// Decode a string.
|
||||||
func (o *Buffer) dec_string(p *Properties, base structPointer) error {
|
func (o *Buffer) dec_string(p *Properties, base structPointer) error {
|
||||||
s, err := o.DecodeStringBytes()
|
s, err := o.DecodeStringBytes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
sp := new(string)
|
*structPointer_String(base, p.field) = &s
|
||||||
*sp = s
|
return nil
|
||||||
*structPointer_String(base, p.field) = sp
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) dec_proto3_string(p *Properties, base structPointer) error {
|
||||||
|
s, err := o.DecodeStringBytes()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*structPointer_StringVal(base, p.field) = s
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -637,6 +671,78 @@ func (o *Buffer) dec_slice_slice_byte(p *Properties, base structPointer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Decode a map field.
|
||||||
|
func (o *Buffer) dec_new_map(p *Properties, base structPointer) error {
|
||||||
|
raw, err := o.DecodeRawBytes(false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
oi := o.index // index at the end of this map entry
|
||||||
|
o.index -= len(raw) // move buffer back to start of map entry
|
||||||
|
|
||||||
|
mptr := structPointer_Map(base, p.field, p.mtype) // *map[K]V
|
||||||
|
if mptr.Elem().IsNil() {
|
||||||
|
mptr.Elem().Set(reflect.MakeMap(mptr.Type().Elem()))
|
||||||
|
}
|
||||||
|
v := mptr.Elem() // map[K]V
|
||||||
|
|
||||||
|
// Prepare addressable doubly-indirect placeholders for the key and value types.
|
||||||
|
// See enc_new_map for why.
|
||||||
|
keyptr := reflect.New(reflect.PtrTo(p.mtype.Key())).Elem() // addressable *K
|
||||||
|
keybase := toStructPointer(keyptr.Addr()) // **K
|
||||||
|
|
||||||
|
var valbase structPointer
|
||||||
|
var valptr reflect.Value
|
||||||
|
switch p.mtype.Elem().Kind() {
|
||||||
|
case reflect.Slice:
|
||||||
|
// []byte
|
||||||
|
var dummy []byte
|
||||||
|
valptr = reflect.ValueOf(&dummy) // *[]byte
|
||||||
|
valbase = toStructPointer(valptr) // *[]byte
|
||||||
|
case reflect.Ptr:
|
||||||
|
// message; valptr is **Msg; need to allocate the intermediate pointer
|
||||||
|
valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V
|
||||||
|
valptr.Set(reflect.New(valptr.Type().Elem()))
|
||||||
|
valbase = toStructPointer(valptr)
|
||||||
|
default:
|
||||||
|
// everything else
|
||||||
|
valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V
|
||||||
|
valbase = toStructPointer(valptr.Addr()) // **V
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode.
|
||||||
|
// This parses a restricted wire format, namely the encoding of a message
|
||||||
|
// with two fields. See enc_new_map for the format.
|
||||||
|
for o.index < oi {
|
||||||
|
// tagcode for key and value properties are always a single byte
|
||||||
|
// because they have tags 1 and 2.
|
||||||
|
tagcode := o.buf[o.index]
|
||||||
|
o.index++
|
||||||
|
switch tagcode {
|
||||||
|
case p.mkeyprop.tagcode[0]:
|
||||||
|
if err := p.mkeyprop.dec(o, p.mkeyprop, keybase); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case p.mvalprop.tagcode[0]:
|
||||||
|
if err := p.mvalprop.dec(o, p.mvalprop, valbase); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// TODO: Should we silently skip this instead?
|
||||||
|
return fmt.Errorf("proto: bad map data tag %d", raw[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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.
|
// Decode a group.
|
||||||
func (o *Buffer) dec_struct_group(p *Properties, base structPointer) error {
|
func (o *Buffer) dec_struct_group(p *Properties, base structPointer) error {
|
||||||
bas := structPointer_GetStructPointer(base, p.field)
|
bas := structPointer_GetStructPointer(base, p.field)
|
||||||
|
|
|
||||||
|
|
@ -30,51 +30,6 @@ import (
|
||||||
"reflect"
|
"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.
|
// Decode a reference to a struct pointer.
|
||||||
func (o *Buffer) dec_ref_struct_message(p *Properties, base structPointer) (err error) {
|
func (o *Buffer) dec_ref_struct_message(p *Properties, base structPointer) (err error) {
|
||||||
raw, e := o.DecodeRawBytes(false)
|
raw, e := o.DecodeRawBytes(false)
|
||||||
|
|
|
||||||
|
|
@ -60,9 +60,9 @@ func (e *RequiredNotSetError) Error() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
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.
|
// 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 is the error returned if Marshal is called with nil.
|
||||||
ErrNil = errors.New("proto: Marshal 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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) enc_proto3_bool(p *Properties, base structPointer) error {
|
||||||
|
v := *structPointer_BoolVal(base, p.field)
|
||||||
|
if !v {
|
||||||
|
return ErrNil
|
||||||
|
}
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
p.valEnc(o, 1)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func size_bool(p *Properties, base structPointer) int {
|
func size_bool(p *Properties, base structPointer) int {
|
||||||
v := *structPointer_Bool(base, p.field)
|
v := *structPointer_Bool(base, p.field)
|
||||||
if v == nil {
|
if v == nil {
|
||||||
|
|
@ -306,6 +316,14 @@ func size_bool(p *Properties, base structPointer) int {
|
||||||
return len(p.tagcode) + 1 // each bool takes exactly one byte
|
return len(p.tagcode) + 1 // each bool takes exactly one byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func size_proto3_bool(p *Properties, base structPointer) int {
|
||||||
|
v := *structPointer_BoolVal(base, p.field)
|
||||||
|
if !v {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return len(p.tagcode) + 1 // each bool takes exactly one byte
|
||||||
|
}
|
||||||
|
|
||||||
// Encode an int32.
|
// Encode an int32.
|
||||||
func (o *Buffer) enc_int32(p *Properties, base structPointer) error {
|
func (o *Buffer) enc_int32(p *Properties, base structPointer) error {
|
||||||
v := structPointer_Word32(base, p.field)
|
v := structPointer_Word32(base, p.field)
|
||||||
|
|
@ -318,6 +336,17 @@ func (o *Buffer) enc_int32(p *Properties, base structPointer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) enc_proto3_int32(p *Properties, base structPointer) error {
|
||||||
|
v := structPointer_Word32Val(base, p.field)
|
||||||
|
x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range
|
||||||
|
if x == 0 {
|
||||||
|
return ErrNil
|
||||||
|
}
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
p.valEnc(o, uint64(x))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func size_int32(p *Properties, base structPointer) (n int) {
|
func size_int32(p *Properties, base structPointer) (n int) {
|
||||||
v := structPointer_Word32(base, p.field)
|
v := structPointer_Word32(base, p.field)
|
||||||
if word32_IsNil(v) {
|
if word32_IsNil(v) {
|
||||||
|
|
@ -329,6 +358,17 @@ func size_int32(p *Properties, base structPointer) (n int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func size_proto3_int32(p *Properties, base structPointer) (n int) {
|
||||||
|
v := structPointer_Word32Val(base, p.field)
|
||||||
|
x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range
|
||||||
|
if x == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
n += len(p.tagcode)
|
||||||
|
n += p.valSize(uint64(x))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Encode a uint32.
|
// Encode a uint32.
|
||||||
// Exactly the same as int32, except for no sign extension.
|
// Exactly the same as int32, except for no sign extension.
|
||||||
func (o *Buffer) enc_uint32(p *Properties, base structPointer) error {
|
func (o *Buffer) enc_uint32(p *Properties, base structPointer) error {
|
||||||
|
|
@ -342,6 +382,17 @@ func (o *Buffer) enc_uint32(p *Properties, base structPointer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) enc_proto3_uint32(p *Properties, base structPointer) error {
|
||||||
|
v := structPointer_Word32Val(base, p.field)
|
||||||
|
x := word32Val_Get(v)
|
||||||
|
if x == 0 {
|
||||||
|
return ErrNil
|
||||||
|
}
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
p.valEnc(o, uint64(x))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func size_uint32(p *Properties, base structPointer) (n int) {
|
func size_uint32(p *Properties, base structPointer) (n int) {
|
||||||
v := structPointer_Word32(base, p.field)
|
v := structPointer_Word32(base, p.field)
|
||||||
if word32_IsNil(v) {
|
if word32_IsNil(v) {
|
||||||
|
|
@ -353,6 +404,17 @@ func size_uint32(p *Properties, base structPointer) (n int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func size_proto3_uint32(p *Properties, base structPointer) (n int) {
|
||||||
|
v := structPointer_Word32Val(base, p.field)
|
||||||
|
x := word32Val_Get(v)
|
||||||
|
if x == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
n += len(p.tagcode)
|
||||||
|
n += p.valSize(uint64(x))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Encode an int64.
|
// Encode an int64.
|
||||||
func (o *Buffer) enc_int64(p *Properties, base structPointer) error {
|
func (o *Buffer) enc_int64(p *Properties, base structPointer) error {
|
||||||
v := structPointer_Word64(base, p.field)
|
v := structPointer_Word64(base, p.field)
|
||||||
|
|
@ -365,6 +427,17 @@ func (o *Buffer) enc_int64(p *Properties, base structPointer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) enc_proto3_int64(p *Properties, base structPointer) error {
|
||||||
|
v := structPointer_Word64Val(base, p.field)
|
||||||
|
x := word64Val_Get(v)
|
||||||
|
if x == 0 {
|
||||||
|
return ErrNil
|
||||||
|
}
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
p.valEnc(o, x)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func size_int64(p *Properties, base structPointer) (n int) {
|
func size_int64(p *Properties, base structPointer) (n int) {
|
||||||
v := structPointer_Word64(base, p.field)
|
v := structPointer_Word64(base, p.field)
|
||||||
if word64_IsNil(v) {
|
if word64_IsNil(v) {
|
||||||
|
|
@ -376,6 +449,17 @@ func size_int64(p *Properties, base structPointer) (n int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func size_proto3_int64(p *Properties, base structPointer) (n int) {
|
||||||
|
v := structPointer_Word64Val(base, p.field)
|
||||||
|
x := word64Val_Get(v)
|
||||||
|
if x == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
n += len(p.tagcode)
|
||||||
|
n += p.valSize(x)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Encode a string.
|
// Encode a string.
|
||||||
func (o *Buffer) enc_string(p *Properties, base structPointer) error {
|
func (o *Buffer) enc_string(p *Properties, base structPointer) error {
|
||||||
v := *structPointer_String(base, p.field)
|
v := *structPointer_String(base, p.field)
|
||||||
|
|
@ -388,6 +472,16 @@ func (o *Buffer) enc_string(p *Properties, base structPointer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) enc_proto3_string(p *Properties, base structPointer) error {
|
||||||
|
v := *structPointer_StringVal(base, p.field)
|
||||||
|
if v == "" {
|
||||||
|
return ErrNil
|
||||||
|
}
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
o.EncodeStringBytes(v)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func size_string(p *Properties, base structPointer) (n int) {
|
func size_string(p *Properties, base structPointer) (n int) {
|
||||||
v := *structPointer_String(base, p.field)
|
v := *structPointer_String(base, p.field)
|
||||||
if v == nil {
|
if v == nil {
|
||||||
|
|
@ -399,6 +493,16 @@ func size_string(p *Properties, base structPointer) (n int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func size_proto3_string(p *Properties, base structPointer) (n int) {
|
||||||
|
v := *structPointer_StringVal(base, p.field)
|
||||||
|
if v == "" {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
n += len(p.tagcode)
|
||||||
|
n += sizeStringBytes(v)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// All protocol buffer fields are nillable, but be careful.
|
// All protocol buffer fields are nillable, but be careful.
|
||||||
func isNil(v reflect.Value) bool {
|
func isNil(v reflect.Value) bool {
|
||||||
switch v.Kind() {
|
switch v.Kind() {
|
||||||
|
|
@ -551,6 +655,16 @@ func (o *Buffer) enc_slice_byte(p *Properties, base structPointer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) enc_proto3_slice_byte(p *Properties, base structPointer) error {
|
||||||
|
s := *structPointer_Bytes(base, p.field)
|
||||||
|
if len(s) == 0 {
|
||||||
|
return ErrNil
|
||||||
|
}
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
o.EncodeRawBytes(s)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func size_slice_byte(p *Properties, base structPointer) (n int) {
|
func size_slice_byte(p *Properties, base structPointer) (n int) {
|
||||||
s := *structPointer_Bytes(base, p.field)
|
s := *structPointer_Bytes(base, p.field)
|
||||||
if s == nil {
|
if s == nil {
|
||||||
|
|
@ -561,6 +675,16 @@ func size_slice_byte(p *Properties, base structPointer) (n int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func size_proto3_slice_byte(p *Properties, base structPointer) (n int) {
|
||||||
|
s := *structPointer_Bytes(base, p.field)
|
||||||
|
if len(s) == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
n += len(p.tagcode)
|
||||||
|
n += sizeRawBytes(s)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Encode a slice of int32s ([]int32).
|
// Encode a slice of int32s ([]int32).
|
||||||
func (o *Buffer) enc_slice_int32(p *Properties, base structPointer) error {
|
func (o *Buffer) enc_slice_int32(p *Properties, base structPointer) error {
|
||||||
s := structPointer_Word32Slice(base, p.field)
|
s := structPointer_Word32Slice(base, p.field)
|
||||||
|
|
@ -815,7 +939,7 @@ func (o *Buffer) enc_slice_struct_message(p *Properties, base structPointer) err
|
||||||
for i := 0; i < l; i++ {
|
for i := 0; i < l; i++ {
|
||||||
structp := s.Index(i)
|
structp := s.Index(i)
|
||||||
if structPointer_IsNil(structp) {
|
if structPointer_IsNil(structp) {
|
||||||
return ErrRepeatedHasNil
|
return errRepeatedHasNil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can the object marshal itself?
|
// 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)
|
err := o.enc_len_struct(p.sprop, structp, &state)
|
||||||
if err != nil && !state.shouldContinue(err, nil) {
|
if err != nil && !state.shouldContinue(err, nil) {
|
||||||
if err == ErrNil {
|
if err == ErrNil {
|
||||||
return ErrRepeatedHasNil
|
return errRepeatedHasNil
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -877,7 +1001,7 @@ func (o *Buffer) enc_slice_struct_group(p *Properties, base structPointer) error
|
||||||
for i := 0; i < l; i++ {
|
for i := 0; i < l; i++ {
|
||||||
b := s.Index(i)
|
b := s.Index(i)
|
||||||
if structPointer_IsNil(b) {
|
if structPointer_IsNil(b) {
|
||||||
return ErrRepeatedHasNil
|
return errRepeatedHasNil
|
||||||
}
|
}
|
||||||
|
|
||||||
o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
|
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 != nil && !state.shouldContinue(err, nil) {
|
||||||
if err == ErrNil {
|
if err == ErrNil {
|
||||||
return ErrRepeatedHasNil
|
return errRepeatedHasNil
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -945,6 +1069,113 @@ func size_map(p *Properties, base structPointer) int {
|
||||||
return sizeExtensionMap(v)
|
return sizeExtensionMap(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Encode a map field.
|
||||||
|
func (o *Buffer) enc_new_map(p *Properties, base structPointer) error {
|
||||||
|
var state errorState // XXX: or do we need to plumb this through?
|
||||||
|
|
||||||
|
/*
|
||||||
|
A map defined as
|
||||||
|
map<key_type, value_type> map_field = N;
|
||||||
|
is encoded in the same way as
|
||||||
|
message MapFieldEntry {
|
||||||
|
key_type key = 1;
|
||||||
|
value_type value = 2;
|
||||||
|
}
|
||||||
|
repeated MapFieldEntry map_field = N;
|
||||||
|
*/
|
||||||
|
|
||||||
|
v := structPointer_Map(base, p.field, p.mtype).Elem() // map[K]V
|
||||||
|
if v.Len() == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype)
|
||||||
|
|
||||||
|
enc := func() error {
|
||||||
|
if err := p.mkeyprop.enc(o, p.mkeyprop, keybase); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := p.mvalprop.enc(o, p.mvalprop, valbase); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
keys := v.MapKeys()
|
||||||
|
sort.Sort(mapKeys(keys))
|
||||||
|
for _, key := range keys {
|
||||||
|
val := v.MapIndex(key)
|
||||||
|
|
||||||
|
// 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.
|
// Encode a struct.
|
||||||
func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
|
func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
|
||||||
var state errorState
|
var state errorState
|
||||||
|
|
@ -960,6 +1191,9 @@ func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
|
||||||
if p.Required && state.err == nil {
|
if p.Required && state.err == nil {
|
||||||
state.err = &RequiredNotSetError{p.Name}
|
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) {
|
} else if !state.shouldContinue(err, p) {
|
||||||
return err
|
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).
|
// Encode a struct, preceded by its encoded length (as a varint).
|
||||||
func (o *Buffer) enc_len_struct(prop *StructProperties, base structPointer, state *errorState) error {
|
func (o *Buffer) enc_len_struct(prop *StructProperties, base structPointer, state *errorState) error {
|
||||||
|
return o.enc_len_thing(func() error { return o.enc_struct(prop, base) }, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode something, preceded by its encoded length (as a varint).
|
||||||
|
func (o *Buffer) enc_len_thing(enc func() error, state *errorState) error {
|
||||||
iLen := len(o.buf)
|
iLen := len(o.buf)
|
||||||
o.buf = append(o.buf, 0, 0, 0, 0) // reserve four bytes for length
|
o.buf = append(o.buf, 0, 0, 0, 0) // reserve four bytes for length
|
||||||
iMsg := len(o.buf)
|
iMsg := len(o.buf)
|
||||||
err := o.enc_struct(prop, base)
|
err := enc()
|
||||||
if err != nil && !state.shouldContinue(err, nil) {
|
if err != nil && !state.shouldContinue(err, nil) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,10 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func NewRequiredNotSetError(field string) *RequiredNotSetError {
|
||||||
|
return &RequiredNotSetError{field}
|
||||||
|
}
|
||||||
|
|
||||||
type Sizer interface {
|
type Sizer interface {
|
||||||
Size() int
|
Size() int
|
||||||
}
|
}
|
||||||
|
|
@ -64,12 +68,9 @@ func size_ext_slice_byte(p *Properties, base structPointer) (n int) {
|
||||||
|
|
||||||
// Encode a reference to bool pointer.
|
// Encode a reference to bool pointer.
|
||||||
func (o *Buffer) enc_ref_bool(p *Properties, base structPointer) error {
|
func (o *Buffer) enc_ref_bool(p *Properties, base structPointer) error {
|
||||||
v := structPointer_RefBool(base, p.field)
|
v := *structPointer_BoolVal(base, p.field)
|
||||||
if v == nil {
|
|
||||||
return ErrNil
|
|
||||||
}
|
|
||||||
x := 0
|
x := 0
|
||||||
if *v {
|
if v {
|
||||||
x = 1
|
x = 1
|
||||||
}
|
}
|
||||||
o.buf = append(o.buf, p.tagcode...)
|
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 {
|
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
|
return len(p.tagcode) + 1 // each bool takes exactly one byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode a reference to int32 pointer.
|
// Encode a reference to int32 pointer.
|
||||||
func (o *Buffer) enc_ref_int32(p *Properties, base structPointer) error {
|
func (o *Buffer) enc_ref_int32(p *Properties, base structPointer) error {
|
||||||
v := structPointer_RefWord32(base, p.field)
|
v := structPointer_Word32Val(base, p.field)
|
||||||
if refWord32_IsNil(v) {
|
x := int32(word32Val_Get(v))
|
||||||
return ErrNil
|
|
||||||
}
|
|
||||||
x := int32(refWord32_Get(v))
|
|
||||||
o.buf = append(o.buf, p.tagcode...)
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
p.valEnc(o, uint64(x))
|
p.valEnc(o, uint64(x))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func size_ref_int32(p *Properties, base structPointer) (n int) {
|
func size_ref_int32(p *Properties, base structPointer) (n int) {
|
||||||
v := structPointer_RefWord32(base, p.field)
|
v := structPointer_Word32Val(base, p.field)
|
||||||
if refWord32_IsNil(v) {
|
x := int32(word32Val_Get(v))
|
||||||
return 0
|
|
||||||
}
|
|
||||||
x := int32(refWord32_Get(v))
|
|
||||||
n += len(p.tagcode)
|
n += len(p.tagcode)
|
||||||
n += p.valSize(uint64(x))
|
n += p.valSize(uint64(x))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *Buffer) enc_ref_uint32(p *Properties, base structPointer) error {
|
func (o *Buffer) enc_ref_uint32(p *Properties, base structPointer) error {
|
||||||
v := structPointer_RefWord32(base, p.field)
|
v := structPointer_Word32Val(base, p.field)
|
||||||
if refWord32_IsNil(v) {
|
x := word32Val_Get(v)
|
||||||
return ErrNil
|
|
||||||
}
|
|
||||||
x := refWord32_Get(v)
|
|
||||||
o.buf = append(o.buf, p.tagcode...)
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
p.valEnc(o, uint64(x))
|
p.valEnc(o, uint64(x))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func size_ref_uint32(p *Properties, base structPointer) (n int) {
|
func size_ref_uint32(p *Properties, base structPointer) (n int) {
|
||||||
v := structPointer_RefWord32(base, p.field)
|
v := structPointer_Word32Val(base, p.field)
|
||||||
if refWord32_IsNil(v) {
|
x := word32Val_Get(v)
|
||||||
return 0
|
|
||||||
}
|
|
||||||
x := refWord32_Get(v)
|
|
||||||
n += len(p.tagcode)
|
n += len(p.tagcode)
|
||||||
n += p.valSize(uint64(x))
|
n += p.valSize(uint64(x))
|
||||||
return
|
return
|
||||||
|
|
@ -132,22 +117,16 @@ func size_ref_uint32(p *Properties, base structPointer) (n int) {
|
||||||
|
|
||||||
// Encode a reference to an int64 pointer.
|
// Encode a reference to an int64 pointer.
|
||||||
func (o *Buffer) enc_ref_int64(p *Properties, base structPointer) error {
|
func (o *Buffer) enc_ref_int64(p *Properties, base structPointer) error {
|
||||||
v := structPointer_RefWord64(base, p.field)
|
v := structPointer_Word64Val(base, p.field)
|
||||||
if refWord64_IsNil(v) {
|
x := word64Val_Get(v)
|
||||||
return ErrNil
|
|
||||||
}
|
|
||||||
x := refWord64_Get(v)
|
|
||||||
o.buf = append(o.buf, p.tagcode...)
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
p.valEnc(o, x)
|
p.valEnc(o, x)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func size_ref_int64(p *Properties, base structPointer) (n int) {
|
func size_ref_int64(p *Properties, base structPointer) (n int) {
|
||||||
v := structPointer_RefWord64(base, p.field)
|
v := structPointer_Word64Val(base, p.field)
|
||||||
if refWord64_IsNil(v) {
|
x := word64Val_Get(v)
|
||||||
return 0
|
|
||||||
}
|
|
||||||
x := refWord64_Get(v)
|
|
||||||
n += len(p.tagcode)
|
n += len(p.tagcode)
|
||||||
n += p.valSize(x)
|
n += p.valSize(x)
|
||||||
return
|
return
|
||||||
|
|
@ -155,24 +134,16 @@ func size_ref_int64(p *Properties, base structPointer) (n int) {
|
||||||
|
|
||||||
// Encode a reference to a string pointer.
|
// Encode a reference to a string pointer.
|
||||||
func (o *Buffer) enc_ref_string(p *Properties, base structPointer) error {
|
func (o *Buffer) enc_ref_string(p *Properties, base structPointer) error {
|
||||||
v := structPointer_RefString(base, p.field)
|
v := *structPointer_StringVal(base, p.field)
|
||||||
if v == nil {
|
|
||||||
return ErrNil
|
|
||||||
}
|
|
||||||
x := *v
|
|
||||||
o.buf = append(o.buf, p.tagcode...)
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
o.EncodeStringBytes(x)
|
o.EncodeStringBytes(v)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func size_ref_string(p *Properties, base structPointer) (n int) {
|
func size_ref_string(p *Properties, base structPointer) (n int) {
|
||||||
v := structPointer_RefString(base, p.field)
|
v := *structPointer_StringVal(base, p.field)
|
||||||
if v == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
x := *v
|
|
||||||
n += len(p.tagcode)
|
n += len(p.tagcode)
|
||||||
n += sizeStringBytes(x)
|
n += sizeStringBytes(v)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -232,7 +203,7 @@ func (o *Buffer) enc_slice_ref_struct_message(p *Properties, base structPointer)
|
||||||
for i := 0; i < l; i++ {
|
for i := 0; i < l; i++ {
|
||||||
structp := structPointer_Add(ss1, field(uintptr(i)*size))
|
structp := structPointer_Add(ss1, field(uintptr(i)*size))
|
||||||
if structPointer_IsNil(structp) {
|
if structPointer_IsNil(structp) {
|
||||||
return ErrRepeatedHasNil
|
return errRepeatedHasNil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can the object marshal itself?
|
// 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)
|
err := o.enc_len_struct(p.sprop, structp, &state)
|
||||||
if err != nil && !state.shouldContinue(err, nil) {
|
if err != nil && !state.shouldContinue(err, nil) {
|
||||||
if err == ErrNil {
|
if err == ErrNil {
|
||||||
return ErrRepeatedHasNil
|
return errRepeatedHasNil
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -154,6 +154,21 @@ func equalAny(v1, v2 reflect.Value) bool {
|
||||||
return v1.Float() == v2.Float()
|
return v1.Float() == v2.Float()
|
||||||
case reflect.Int32, reflect.Int64:
|
case reflect.Int32, reflect.Int64:
|
||||||
return v1.Int() == v2.Int()
|
return v1.Int() == v2.Int()
|
||||||
|
case reflect.Map:
|
||||||
|
if v1.Len() != v2.Len() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, key := range v1.MapKeys() {
|
||||||
|
val2 := v2.MapIndex(key)
|
||||||
|
if !val2.IsValid() {
|
||||||
|
// This key was not found in the second map.
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !equalAny(v1.MapIndex(key), val2) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
case reflect.Ptr:
|
case reflect.Ptr:
|
||||||
return equalAny(v1.Elem(), v2.Elem())
|
return equalAny(v1.Elem(), v2.Elem())
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,8 @@ package proto_test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
pb "./testdata"
|
|
||||||
. "github.com/gogo/protobuf/proto"
|
. "github.com/gogo/protobuf/proto"
|
||||||
|
pb "github.com/gogo/protobuf/proto/testdata"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Four identical base messages.
|
// Four identical base messages.
|
||||||
|
|
@ -155,6 +155,31 @@ var EqualTests = []struct {
|
||||||
},
|
},
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"map same",
|
||||||
|
&pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
|
||||||
|
&pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"map different entry",
|
||||||
|
&pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
|
||||||
|
&pb.MessageWithMap{NameMapping: map[int32]string{2: "Rob"}},
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"map different key only",
|
||||||
|
&pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
|
||||||
|
&pb.MessageWithMap{NameMapping: map[int32]string{2: "Ken"}},
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"map different value only",
|
||||||
|
&pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
|
||||||
|
&pb.MessageWithMap{NameMapping: map[int32]string{1: "Rob"}},
|
||||||
|
false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEqual(t *testing.T) {
|
func TestEqual(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ package proto
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
@ -310,7 +311,9 @@ func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, er
|
||||||
emap := epb.ExtensionMap()
|
emap := epb.ExtensionMap()
|
||||||
e, ok := emap[extension.Field]
|
e, ok := emap[extension.Field]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, ErrMissingExtension
|
// defaultExtensionValue returns the default value or
|
||||||
|
// ErrMissingExtension if there is no default.
|
||||||
|
return defaultExtensionValue(extension)
|
||||||
}
|
}
|
||||||
if e.value != nil {
|
if e.value != nil {
|
||||||
// Already decoded. Check the descriptor, though.
|
// Already decoded. Check the descriptor, though.
|
||||||
|
|
@ -355,10 +358,46 @@ func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, er
|
||||||
}
|
}
|
||||||
o += n + l
|
o += n + l
|
||||||
}
|
}
|
||||||
|
return defaultExtensionValue(extension)
|
||||||
}
|
}
|
||||||
panic("unreachable")
|
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.
|
// decodeExtension decodes an extension encoded in b.
|
||||||
func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
|
func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
|
||||||
o := NewBuffer(b)
|
o := NewBuffer(b)
|
||||||
|
|
@ -423,6 +462,14 @@ func SetExtension(pb extendableProto, extension *ExtensionDesc, value interface{
|
||||||
if typ != reflect.TypeOf(value) {
|
if typ != reflect.TypeOf(value) {
|
||||||
return errors.New("proto: bad extension value type")
|
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)
|
return setExtension(pb, extension, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,10 +32,12 @@
|
||||||
package proto_test
|
package proto_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
pb "./testdata"
|
|
||||||
"github.com/gogo/protobuf/proto"
|
"github.com/gogo/protobuf/proto"
|
||||||
|
pb "github.com/gogo/protobuf/proto/testdata"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGetExtensionsWithMissingExtensions(t *testing.T) {
|
func TestGetExtensionsWithMissingExtensions(t *testing.T) {
|
||||||
|
|
@ -92,3 +94,199 @@ func TestGetExtensionStability(t *testing.T) {
|
||||||
t.Errorf("GetExtension() not stable after unmarshaling")
|
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.
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,12 +30,12 @@
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Package proto converts data structures to and from the wire format of
|
Package proto converts data structures to and from the wire format of
|
||||||
protocol buffers. It works in concert with the Go source code generated
|
protocol buffers. It works in concert with the Go source code generated
|
||||||
for .proto files by the protocol compiler.
|
for .proto files by the protocol compiler.
|
||||||
|
|
||||||
A summary of the properties of the protocol buffer interface
|
A summary of the properties of the protocol buffer interface
|
||||||
for a protocol buffer variable v:
|
for a protocol buffer variable v:
|
||||||
|
|
||||||
- Names are turned from camel_case to CamelCase for export.
|
- Names are turned from camel_case to CamelCase for export.
|
||||||
- There are no methods on v to set fields; just treat
|
- There are no methods on v to set fields; just treat
|
||||||
|
|
@ -50,17 +50,16 @@
|
||||||
That is, optional or required field int32 f becomes F *int32.
|
That is, optional or required field int32 f becomes F *int32.
|
||||||
- Repeated fields are slices.
|
- Repeated fields are slices.
|
||||||
- Helper functions are available to aid the setting of fields.
|
- Helper functions are available to aid the setting of fields.
|
||||||
Helpers for getting values are superseded by the
|
|
||||||
GetFoo methods and their use is deprecated.
|
|
||||||
msg.Foo = proto.String("hello") // set field
|
msg.Foo = proto.String("hello") // set field
|
||||||
- Constants are defined to hold the default values of all fields that
|
- Constants are defined to hold the default values of all fields that
|
||||||
have them. They have the form Default_StructName_FieldName.
|
have them. They have the form Default_StructName_FieldName.
|
||||||
Because the getter methods handle defaulted values,
|
Because the getter methods handle defaulted values,
|
||||||
direct use of these constants should be rare.
|
direct use of these constants should be rare.
|
||||||
- Enums are given type names and maps from names to values.
|
- Enums are given type names and maps from names to values.
|
||||||
Enum values are prefixed with the enum's type name. Enum types have
|
Enum values are prefixed by the enclosing message's name, or by the
|
||||||
a String method, and a Enum method to assist in message construction.
|
enum's type name if it is a top-level enum. Enum types have a String
|
||||||
- Nested groups and enums have type names prefixed with the name of
|
method, and a Enum method to assist in message construction.
|
||||||
|
- Nested messages, groups and enums have type names prefixed with the name of
|
||||||
the surrounding message type.
|
the surrounding message type.
|
||||||
- Extensions are given descriptor names that start with E_,
|
- Extensions are given descriptor names that start with E_,
|
||||||
followed by an underscore-delimited list of the nested messages
|
followed by an underscore-delimited list of the nested messages
|
||||||
|
|
@ -69,12 +68,12 @@
|
||||||
and SetExtension are functions for manipulating extensions.
|
and SetExtension are functions for manipulating extensions.
|
||||||
- Marshal and Unmarshal are functions to encode and decode the wire format.
|
- Marshal and Unmarshal are functions to encode and decode the wire format.
|
||||||
|
|
||||||
The simplest way to describe this is to see an example.
|
The simplest way to describe this is to see an example.
|
||||||
Given file test.proto, containing
|
Given file test.proto, containing
|
||||||
|
|
||||||
package example;
|
package example;
|
||||||
|
|
||||||
enum FOO { X = 17; };
|
enum FOO { X = 17; }
|
||||||
|
|
||||||
message Test {
|
message Test {
|
||||||
required string label = 1;
|
required string label = 1;
|
||||||
|
|
@ -85,11 +84,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
The resulting file, test.pb.go, is:
|
The resulting file, test.pb.go, is:
|
||||||
|
|
||||||
package example
|
package example
|
||||||
|
|
||||||
import "github.com/gogo/protobuf/proto"
|
import proto "github.com/gogo/protobuf/proto"
|
||||||
|
import math "math"
|
||||||
|
|
||||||
type FOO int32
|
type FOO int32
|
||||||
const (
|
const (
|
||||||
|
|
@ -110,6 +110,14 @@
|
||||||
func (x FOO) String() string {
|
func (x FOO) String() string {
|
||||||
return proto.EnumName(FOO_name, int32(x))
|
return proto.EnumName(FOO_name, int32(x))
|
||||||
}
|
}
|
||||||
|
func (x *FOO) UnmarshalJSON(data []byte) error {
|
||||||
|
value, err := proto.UnmarshalJSONEnum(FOO_value, data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*x = FOO(value)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type Test struct {
|
type Test struct {
|
||||||
Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"`
|
Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"`
|
||||||
|
|
@ -118,41 +126,41 @@
|
||||||
Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"`
|
Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
}
|
}
|
||||||
func (this *Test) Reset() { *this = Test{} }
|
func (m *Test) Reset() { *m = Test{} }
|
||||||
func (this *Test) String() string { return proto.CompactTextString(this) }
|
func (m *Test) String() string { return proto.CompactTextString(m) }
|
||||||
|
func (*Test) ProtoMessage() {}
|
||||||
const Default_Test_Type int32 = 77
|
const Default_Test_Type int32 = 77
|
||||||
|
|
||||||
func (this *Test) GetLabel() string {
|
func (m *Test) GetLabel() string {
|
||||||
if this != nil && this.Label != nil {
|
if m != nil && m.Label != nil {
|
||||||
return *this.Label
|
return *m.Label
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Test) GetType() int32 {
|
func (m *Test) GetType() int32 {
|
||||||
if this != nil && this.Type != nil {
|
if m != nil && m.Type != nil {
|
||||||
return *this.Type
|
return *m.Type
|
||||||
}
|
}
|
||||||
return Default_Test_Type
|
return Default_Test_Type
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Test) GetOptionalgroup() *Test_OptionalGroup {
|
func (m *Test) GetOptionalgroup() *Test_OptionalGroup {
|
||||||
if this != nil {
|
if m != nil {
|
||||||
return this.Optionalgroup
|
return m.Optionalgroup
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type Test_OptionalGroup struct {
|
type Test_OptionalGroup struct {
|
||||||
RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"`
|
RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
|
||||||
}
|
}
|
||||||
func (this *Test_OptionalGroup) Reset() { *this = Test_OptionalGroup{} }
|
func (m *Test_OptionalGroup) Reset() { *m = Test_OptionalGroup{} }
|
||||||
func (this *Test_OptionalGroup) String() string { return proto.CompactTextString(this) }
|
func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) }
|
||||||
|
|
||||||
func (this *Test_OptionalGroup) GetRequiredField() string {
|
func (m *Test_OptionalGroup) GetRequiredField() string {
|
||||||
if this != nil && this.RequiredField != nil {
|
if m != nil && m.RequiredField != nil {
|
||||||
return *this.RequiredField
|
return *m.RequiredField
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
@ -161,22 +169,22 @@
|
||||||
proto.RegisterEnum("example.FOO", FOO_name, FOO_value)
|
proto.RegisterEnum("example.FOO", FOO_name, FOO_value)
|
||||||
}
|
}
|
||||||
|
|
||||||
To create and play with a Test object:
|
To create and play with a Test object:
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/gogo/protobuf/proto"
|
"github.com/gogo/protobuf/proto"
|
||||||
"./example.pb"
|
pb "./example.pb"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
test := &example.Test{
|
test := &pb.Test{
|
||||||
Label: proto.String("hello"),
|
Label: proto.String("hello"),
|
||||||
Type: proto.Int32(17),
|
Type: proto.Int32(17),
|
||||||
Optionalgroup: &example.Test_OptionalGroup{
|
Optionalgroup: &pb.Test_OptionalGroup{
|
||||||
RequiredField: proto.String("good bye"),
|
RequiredField: proto.String("good bye"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -184,7 +192,7 @@
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("marshaling error: ", err)
|
log.Fatal("marshaling error: ", err)
|
||||||
}
|
}
|
||||||
newTest := new(example.Test)
|
newTest := &pb.Test{}
|
||||||
err = proto.Unmarshal(data, newTest)
|
err = proto.Unmarshal(data, newTest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("unmarshaling error: ", err)
|
log.Fatal("unmarshaling error: ", err)
|
||||||
|
|
@ -323,9 +331,7 @@ func Float64(v float64) *float64 {
|
||||||
// Uint32 is a helper routine that allocates a new uint32 value
|
// Uint32 is a helper routine that allocates a new uint32 value
|
||||||
// to store v and returns a pointer to it.
|
// to store v and returns a pointer to it.
|
||||||
func Uint32(v uint32) *uint32 {
|
func Uint32(v uint32) *uint32 {
|
||||||
p := new(uint32)
|
return &v
|
||||||
*p = v
|
|
||||||
return p
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uint64 is a helper routine that allocates a new uint64 value
|
// Uint64 is a helper routine that allocates a new uint64 value
|
||||||
|
|
@ -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
|
// 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.
|
// 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
|
var u uint64
|
||||||
|
|
||||||
obuf := o.buf
|
obuf := p.buf
|
||||||
index := o.index
|
index := p.index
|
||||||
o.buf = b
|
p.buf = b
|
||||||
o.index = 0
|
p.index = 0
|
||||||
depth := 0
|
depth := 0
|
||||||
|
|
||||||
fmt.Printf("\n--- %s ---\n", s)
|
fmt.Printf("\n--- %s ---\n", s)
|
||||||
|
|
@ -396,12 +402,12 @@ out:
|
||||||
fmt.Print(" ")
|
fmt.Print(" ")
|
||||||
}
|
}
|
||||||
|
|
||||||
index := o.index
|
index := p.index
|
||||||
if index == len(o.buf) {
|
if index == len(p.buf) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
op, err := o.DecodeVarint()
|
op, err := p.DecodeVarint()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("%3d: fetching op err %v\n", index, err)
|
fmt.Printf("%3d: fetching op err %v\n", index, err)
|
||||||
break out
|
break out
|
||||||
|
|
@ -418,7 +424,7 @@ out:
|
||||||
case WireBytes:
|
case WireBytes:
|
||||||
var r []byte
|
var r []byte
|
||||||
|
|
||||||
r, err = o.DecodeRawBytes(false)
|
r, err = p.DecodeRawBytes(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break out
|
break out
|
||||||
}
|
}
|
||||||
|
|
@ -439,7 +445,7 @@ out:
|
||||||
fmt.Printf("\n")
|
fmt.Printf("\n")
|
||||||
|
|
||||||
case WireFixed32:
|
case WireFixed32:
|
||||||
u, err = o.DecodeFixed32()
|
u, err = p.DecodeFixed32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err)
|
fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err)
|
||||||
break out
|
break out
|
||||||
|
|
@ -447,7 +453,7 @@ out:
|
||||||
fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u)
|
fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u)
|
||||||
|
|
||||||
case WireFixed64:
|
case WireFixed64:
|
||||||
u, err = o.DecodeFixed64()
|
u, err = p.DecodeFixed64()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err)
|
fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err)
|
||||||
break out
|
break out
|
||||||
|
|
@ -456,7 +462,7 @@ out:
|
||||||
break
|
break
|
||||||
|
|
||||||
case WireVarint:
|
case WireVarint:
|
||||||
u, err = o.DecodeVarint()
|
u, err = p.DecodeVarint()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err)
|
fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err)
|
||||||
break out
|
break out
|
||||||
|
|
@ -482,12 +488,12 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
if depth != 0 {
|
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")
|
fmt.Printf("\n")
|
||||||
|
|
||||||
o.buf = obuf
|
p.buf = obuf
|
||||||
o.index = index
|
p.index = index
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetDefaults sets unset protocol buffer fields to their default values.
|
// 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 {
|
for _, ni := range dm.nested {
|
||||||
f := v.Field(ni)
|
f := v.Field(ni)
|
||||||
|
// f is *T or []*T or map[T]*T
|
||||||
|
switch f.Kind() {
|
||||||
|
case reflect.Ptr:
|
||||||
if f.IsNil() {
|
if f.IsNil() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// f is *T or []*T
|
|
||||||
if f.Kind() == reflect.Ptr {
|
|
||||||
setDefaults(f, recur, zeros)
|
setDefaults(f, recur, zeros)
|
||||||
} else {
|
|
||||||
|
case reflect.Slice:
|
||||||
for i := 0; i < f.Len(); i++ {
|
for i := 0; i < f.Len(); i++ {
|
||||||
e := f.Index(i)
|
e := f.Index(i)
|
||||||
if e.IsNil() {
|
if e.IsNil() {
|
||||||
|
|
@ -615,6 +623,15 @@ func setDefaults(v reflect.Value, recur, zeros bool) {
|
||||||
}
|
}
|
||||||
setDefaults(e, recur, zeros)
|
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
|
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.
|
// t is a struct type.
|
||||||
func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
|
func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
|
||||||
sprop := GetProperties(t)
|
sprop := GetProperties(t)
|
||||||
|
|
@ -655,21 +668,62 @@ func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
|
||||||
}
|
}
|
||||||
ft := t.Field(fi).Type
|
ft := t.Field(fi).Type
|
||||||
|
|
||||||
// nested messages
|
sf, nested, err := fieldDefault(ft, prop)
|
||||||
if ptrToStruct(ft) || (ft.Kind() == reflect.Slice && ptrToStruct(ft.Elem())) {
|
switch {
|
||||||
|
case err != nil:
|
||||||
|
log.Print(err)
|
||||||
|
case nested:
|
||||||
dm.nested = append(dm.nested, fi)
|
dm.nested = append(dm.nested, fi)
|
||||||
continue
|
case sf != nil:
|
||||||
|
sf.index = fi
|
||||||
|
dm.scalars = append(dm.scalars, *sf)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sf := scalarField{
|
return dm
|
||||||
index: fi,
|
}
|
||||||
kind: ft.Elem().Kind(),
|
|
||||||
|
// 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
|
// scalar fields without defaults
|
||||||
if !prop.HasDefault {
|
if !prop.HasDefault {
|
||||||
dm.scalars = append(dm.scalars, sf)
|
return sf, false, nil
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// a scalar field: either *T or []byte
|
// a scalar field: either *T or []byte
|
||||||
|
|
@ -677,36 +731,31 @@ func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
|
||||||
case reflect.Bool:
|
case reflect.Bool:
|
||||||
x, err := strconv.ParseBool(prop.Default)
|
x, err := strconv.ParseBool(prop.Default)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("proto: bad default bool %q: %v", prop.Default, err)
|
return nil, false, fmt.Errorf("proto: bad default bool %q: %v", prop.Default, err)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
sf.value = x
|
sf.value = x
|
||||||
case reflect.Float32:
|
case reflect.Float32:
|
||||||
x, err := strconv.ParseFloat(prop.Default, 32)
|
x, err := strconv.ParseFloat(prop.Default, 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("proto: bad default float32 %q: %v", prop.Default, err)
|
return nil, false, fmt.Errorf("proto: bad default float32 %q: %v", prop.Default, err)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
sf.value = float32(x)
|
sf.value = float32(x)
|
||||||
case reflect.Float64:
|
case reflect.Float64:
|
||||||
x, err := strconv.ParseFloat(prop.Default, 64)
|
x, err := strconv.ParseFloat(prop.Default, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("proto: bad default float64 %q: %v", prop.Default, err)
|
return nil, false, fmt.Errorf("proto: bad default float64 %q: %v", prop.Default, err)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
sf.value = x
|
sf.value = x
|
||||||
case reflect.Int32:
|
case reflect.Int32:
|
||||||
x, err := strconv.ParseInt(prop.Default, 10, 32)
|
x, err := strconv.ParseInt(prop.Default, 10, 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("proto: bad default int32 %q: %v", prop.Default, err)
|
return nil, false, fmt.Errorf("proto: bad default int32 %q: %v", prop.Default, err)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
sf.value = int32(x)
|
sf.value = int32(x)
|
||||||
case reflect.Int64:
|
case reflect.Int64:
|
||||||
x, err := strconv.ParseInt(prop.Default, 10, 64)
|
x, err := strconv.ParseInt(prop.Default, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("proto: bad default int64 %q: %v", prop.Default, err)
|
return nil, false, fmt.Errorf("proto: bad default int64 %q: %v", prop.Default, err)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
sf.value = x
|
sf.value = x
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
|
|
@ -717,24 +766,48 @@ func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
|
||||||
case reflect.Uint32:
|
case reflect.Uint32:
|
||||||
x, err := strconv.ParseUint(prop.Default, 10, 32)
|
x, err := strconv.ParseUint(prop.Default, 10, 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("proto: bad default uint32 %q: %v", prop.Default, err)
|
return nil, false, fmt.Errorf("proto: bad default uint32 %q: %v", prop.Default, err)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
sf.value = uint32(x)
|
sf.value = uint32(x)
|
||||||
case reflect.Uint64:
|
case reflect.Uint64:
|
||||||
x, err := strconv.ParseUint(prop.Default, 10, 64)
|
x, err := strconv.ParseUint(prop.Default, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("proto: bad default uint64 %q: %v", prop.Default, err)
|
return nil, false, fmt.Errorf("proto: bad default uint64 %q: %v", prop.Default, err)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
sf.value = x
|
sf.value = x
|
||||||
default:
|
default:
|
||||||
log.Printf("proto: unhandled def kind %v", ft.Elem().Kind())
|
return nil, false, fmt.Errorf("proto: unhandled def kind %v", ft.Elem().Kind())
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
// +build appengine,!appenginevm
|
// +build appengine
|
||||||
|
|
||||||
// This file contains an implementation of proto field accesses using package reflect.
|
// This file contains an implementation of proto field accesses using package reflect.
|
||||||
// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can
|
// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can
|
||||||
|
|
@ -114,6 +114,11 @@ func structPointer_Bool(p structPointer, f field) **bool {
|
||||||
return structPointer_ifield(p, f).(**bool)
|
return structPointer_ifield(p, f).(**bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BoolVal returns the address of a bool field in the struct.
|
||||||
|
func structPointer_BoolVal(p structPointer, f field) *bool {
|
||||||
|
return structPointer_ifield(p, f).(*bool)
|
||||||
|
}
|
||||||
|
|
||||||
// BoolSlice returns the address of a []bool field in the struct.
|
// BoolSlice returns the address of a []bool field in the struct.
|
||||||
func structPointer_BoolSlice(p structPointer, f field) *[]bool {
|
func structPointer_BoolSlice(p structPointer, f field) *[]bool {
|
||||||
return structPointer_ifield(p, f).(*[]bool)
|
return structPointer_ifield(p, f).(*[]bool)
|
||||||
|
|
@ -124,6 +129,11 @@ func structPointer_String(p structPointer, f field) **string {
|
||||||
return structPointer_ifield(p, f).(**string)
|
return structPointer_ifield(p, f).(**string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StringVal returns the address of a string field in the struct.
|
||||||
|
func structPointer_StringVal(p structPointer, f field) *string {
|
||||||
|
return structPointer_ifield(p, f).(*string)
|
||||||
|
}
|
||||||
|
|
||||||
// StringSlice returns the address of a []string field in the struct.
|
// StringSlice returns the address of a []string field in the struct.
|
||||||
func structPointer_StringSlice(p structPointer, f field) *[]string {
|
func structPointer_StringSlice(p structPointer, f field) *[]string {
|
||||||
return structPointer_ifield(p, f).(*[]string)
|
return structPointer_ifield(p, f).(*[]string)
|
||||||
|
|
@ -134,6 +144,11 @@ func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
|
||||||
return structPointer_ifield(p, f).(*map[int32]Extension)
|
return structPointer_ifield(p, f).(*map[int32]Extension)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Map returns the reflect.Value for the address of a map field in the struct.
|
||||||
|
func structPointer_Map(p structPointer, f field, typ reflect.Type) reflect.Value {
|
||||||
|
return structPointer_field(p, f).Addr()
|
||||||
|
}
|
||||||
|
|
||||||
// SetStructPointer writes a *struct field in the struct.
|
// SetStructPointer writes a *struct field in the struct.
|
||||||
func structPointer_SetStructPointer(p structPointer, f field, q structPointer) {
|
func structPointer_SetStructPointer(p structPointer, f field, q structPointer) {
|
||||||
structPointer_field(p, f).Set(q.v)
|
structPointer_field(p, f).Set(q.v)
|
||||||
|
|
@ -235,6 +250,49 @@ func structPointer_Word32(p structPointer, f field) word32 {
|
||||||
return word32{structPointer_field(p, f)}
|
return word32{structPointer_field(p, f)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A word32Val represents a field of type int32, uint32, float32, or enum.
|
||||||
|
// That is, v.Type() is int32, uint32, float32, or enum and v is assignable.
|
||||||
|
type word32Val struct {
|
||||||
|
v reflect.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set sets *p to x.
|
||||||
|
func word32Val_Set(p word32Val, x uint32) {
|
||||||
|
switch p.v.Type() {
|
||||||
|
case int32Type:
|
||||||
|
p.v.SetInt(int64(x))
|
||||||
|
return
|
||||||
|
case uint32Type:
|
||||||
|
p.v.SetUint(uint64(x))
|
||||||
|
return
|
||||||
|
case float32Type:
|
||||||
|
p.v.SetFloat(float64(math.Float32frombits(x)))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// must be enum
|
||||||
|
p.v.SetInt(int64(int32(x)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get gets the bits pointed at by p, as a uint32.
|
||||||
|
func word32Val_Get(p word32Val) uint32 {
|
||||||
|
elem := p.v
|
||||||
|
switch elem.Kind() {
|
||||||
|
case reflect.Int32:
|
||||||
|
return uint32(elem.Int())
|
||||||
|
case reflect.Uint32:
|
||||||
|
return uint32(elem.Uint())
|
||||||
|
case reflect.Float32:
|
||||||
|
return math.Float32bits(float32(elem.Float()))
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Word32Val returns a reference to a int32, uint32, float32, or enum field in the struct.
|
||||||
|
func structPointer_Word32Val(p structPointer, f field) word32Val {
|
||||||
|
return word32Val{structPointer_field(p, f)}
|
||||||
|
}
|
||||||
|
|
||||||
// A word32Slice is a slice of 32-bit values.
|
// A word32Slice is a slice of 32-bit values.
|
||||||
// That is, v.Type() is []int32, []uint32, []float32, or []enum.
|
// That is, v.Type() is []int32, []uint32, []float32, or []enum.
|
||||||
type word32Slice struct {
|
type word32Slice struct {
|
||||||
|
|
@ -339,6 +397,43 @@ func structPointer_Word64(p structPointer, f field) word64 {
|
||||||
return word64{structPointer_field(p, f)}
|
return word64{structPointer_field(p, f)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// word64Val is like word32Val but for 64-bit values.
|
||||||
|
type word64Val struct {
|
||||||
|
v reflect.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func word64Val_Set(p word64Val, o *Buffer, x uint64) {
|
||||||
|
switch p.v.Type() {
|
||||||
|
case int64Type:
|
||||||
|
p.v.SetInt(int64(x))
|
||||||
|
return
|
||||||
|
case uint64Type:
|
||||||
|
p.v.SetUint(x)
|
||||||
|
return
|
||||||
|
case float64Type:
|
||||||
|
p.v.SetFloat(math.Float64frombits(x))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
func word64Val_Get(p word64Val) uint64 {
|
||||||
|
elem := p.v
|
||||||
|
switch elem.Kind() {
|
||||||
|
case reflect.Int64:
|
||||||
|
return uint64(elem.Int())
|
||||||
|
case reflect.Uint64:
|
||||||
|
return elem.Uint()
|
||||||
|
case reflect.Float64:
|
||||||
|
return math.Float64bits(elem.Float())
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPointer_Word64Val(p structPointer, f field) word64Val {
|
||||||
|
return word64Val{structPointer_field(p, f)}
|
||||||
|
}
|
||||||
|
|
||||||
type word64Slice struct {
|
type word64Slice struct {
|
||||||
v reflect.Value
|
v reflect.Value
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
// +build !appengine appenginevm
|
// +build !appengine
|
||||||
|
|
||||||
// This file contains the implementation of the proto field accesses using package unsafe.
|
// This file contains the implementation of the proto field accesses using package unsafe.
|
||||||
|
|
||||||
|
|
@ -100,6 +100,11 @@ func structPointer_Bool(p structPointer, f field) **bool {
|
||||||
return (**bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
return (**bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BoolVal returns the address of a bool field in the struct.
|
||||||
|
func structPointer_BoolVal(p structPointer, f field) *bool {
|
||||||
|
return (*bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
|
}
|
||||||
|
|
||||||
// BoolSlice returns the address of a []bool field in the struct.
|
// BoolSlice returns the address of a []bool field in the struct.
|
||||||
func structPointer_BoolSlice(p structPointer, f field) *[]bool {
|
func structPointer_BoolSlice(p structPointer, f field) *[]bool {
|
||||||
return (*[]bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
return (*[]bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
|
|
@ -110,6 +115,11 @@ func structPointer_String(p structPointer, f field) **string {
|
||||||
return (**string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
return (**string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StringVal returns the address of a string field in the struct.
|
||||||
|
func structPointer_StringVal(p structPointer, f field) *string {
|
||||||
|
return (*string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
|
}
|
||||||
|
|
||||||
// StringSlice returns the address of a []string field in the struct.
|
// StringSlice returns the address of a []string field in the struct.
|
||||||
func structPointer_StringSlice(p structPointer, f field) *[]string {
|
func structPointer_StringSlice(p structPointer, f field) *[]string {
|
||||||
return (*[]string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
return (*[]string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
|
|
@ -120,6 +130,11 @@ func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
|
||||||
return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Map returns the reflect.Value for the address of a map field in the struct.
|
||||||
|
func structPointer_Map(p structPointer, f field, typ reflect.Type) reflect.Value {
|
||||||
|
return reflect.NewAt(typ, unsafe.Pointer(uintptr(p)+uintptr(f)))
|
||||||
|
}
|
||||||
|
|
||||||
// SetStructPointer writes a *struct field in the struct.
|
// SetStructPointer writes a *struct field in the struct.
|
||||||
func structPointer_SetStructPointer(p structPointer, f field, q structPointer) {
|
func structPointer_SetStructPointer(p structPointer, f field, q structPointer) {
|
||||||
*(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f))) = q
|
*(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f))) = q
|
||||||
|
|
@ -170,6 +185,24 @@ func structPointer_Word32(p structPointer, f field) word32 {
|
||||||
return word32((**uint32)(unsafe.Pointer(uintptr(p) + uintptr(f))))
|
return word32((**uint32)(unsafe.Pointer(uintptr(p) + uintptr(f))))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A word32Val is the address of a 32-bit value field.
|
||||||
|
type word32Val *uint32
|
||||||
|
|
||||||
|
// Set sets *p to x.
|
||||||
|
func word32Val_Set(p word32Val, x uint32) {
|
||||||
|
*p = x
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get gets the value pointed at by p.
|
||||||
|
func word32Val_Get(p word32Val) uint32 {
|
||||||
|
return *p
|
||||||
|
}
|
||||||
|
|
||||||
|
// Word32Val returns the address of a *int32, *uint32, *float32, or *enum field in the struct.
|
||||||
|
func structPointer_Word32Val(p structPointer, f field) word32Val {
|
||||||
|
return word32Val((*uint32)(unsafe.Pointer(uintptr(p) + uintptr(f))))
|
||||||
|
}
|
||||||
|
|
||||||
// A word32Slice is a slice of 32-bit values.
|
// A word32Slice is a slice of 32-bit values.
|
||||||
type word32Slice []uint32
|
type word32Slice []uint32
|
||||||
|
|
||||||
|
|
@ -206,6 +239,21 @@ func structPointer_Word64(p structPointer, f field) word64 {
|
||||||
return word64((**uint64)(unsafe.Pointer(uintptr(p) + uintptr(f))))
|
return word64((**uint64)(unsafe.Pointer(uintptr(p) + uintptr(f))))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// word64Val is like word32Val but for 64-bit values.
|
||||||
|
type word64Val *uint64
|
||||||
|
|
||||||
|
func word64Val_Set(p word64Val, o *Buffer, x uint64) {
|
||||||
|
*p = x
|
||||||
|
}
|
||||||
|
|
||||||
|
func word64Val_Get(p word64Val) uint64 {
|
||||||
|
return *p
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPointer_Word64Val(p structPointer, f field) word64Val {
|
||||||
|
return word64Val((*uint64)(unsafe.Pointer(uintptr(p) + uintptr(f))))
|
||||||
|
}
|
||||||
|
|
||||||
// word64Slice is like word32Slice but for 64-bit values.
|
// word64Slice is like word32Slice but for 64-bit values.
|
||||||
type word64Slice []uint64
|
type word64Slice []uint64
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)))
|
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 {
|
func structPointer_FieldPointer(p structPointer, f field) structPointer {
|
||||||
return structPointer(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
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 {
|
func structPointer_Len(p structPointer, f field) int {
|
||||||
return len(*(*[]interface{})(unsafe.Pointer(structPointer_GetRefStructPointer(p, f))))
|
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
|
Repeated bool
|
||||||
Packed bool // relevant for repeated primitives only
|
Packed bool // relevant for repeated primitives only
|
||||||
Enum string // set for enum types only
|
Enum string // set for enum types only
|
||||||
|
proto3 bool // whether this is known to be a proto3 field; set for []byte only
|
||||||
|
|
||||||
Default string // default value
|
Default string // default value
|
||||||
HasDefault bool // whether an explicit default was provided
|
HasDefault bool // whether an explicit default was provided
|
||||||
|
|
@ -178,6 +179,10 @@ type Properties struct {
|
||||||
isMarshaler bool
|
isMarshaler bool
|
||||||
isUnmarshaler bool
|
isUnmarshaler bool
|
||||||
|
|
||||||
|
mtype reflect.Type // set for map types only
|
||||||
|
mkeyprop *Properties // set for map types only
|
||||||
|
mvalprop *Properties // set for map types only
|
||||||
|
|
||||||
size sizer
|
size sizer
|
||||||
valSize valueSizer // set for bool and numeric types only
|
valSize valueSizer // set for bool and numeric types only
|
||||||
|
|
||||||
|
|
@ -208,6 +213,9 @@ func (p *Properties) String() string {
|
||||||
if p.OrigName != p.Name {
|
if p.OrigName != p.Name {
|
||||||
s += ",name=" + p.OrigName
|
s += ",name=" + p.OrigName
|
||||||
}
|
}
|
||||||
|
if p.proto3 {
|
||||||
|
s += ",proto3"
|
||||||
|
}
|
||||||
if len(p.Enum) > 0 {
|
if len(p.Enum) > 0 {
|
||||||
s += ",enum=" + p.Enum
|
s += ",enum=" + p.Enum
|
||||||
}
|
}
|
||||||
|
|
@ -282,6 +290,8 @@ func (p *Properties) Parse(s string) {
|
||||||
p.OrigName = f[5:]
|
p.OrigName = f[5:]
|
||||||
case strings.HasPrefix(f, "enum="):
|
case strings.HasPrefix(f, "enum="):
|
||||||
p.Enum = f[5:]
|
p.Enum = f[5:]
|
||||||
|
case f == "proto3":
|
||||||
|
p.proto3 = true
|
||||||
case strings.HasPrefix(f, "def="):
|
case strings.HasPrefix(f, "def="):
|
||||||
p.HasDefault = true
|
p.HasDefault = true
|
||||||
p.Default = f[4:] // rest of string
|
p.Default = f[4:] // rest of string
|
||||||
|
|
@ -305,7 +315,7 @@ func logNoSliceEnc(t1, t2 reflect.Type) {
|
||||||
var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem()
|
var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem()
|
||||||
|
|
||||||
// Initialize the fields for encoding and decoding.
|
// Initialize the fields for encoding and decoding.
|
||||||
func (p *Properties) setEncAndDec(typ reflect.Type, lockGetProp bool) {
|
func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lockGetProp bool) {
|
||||||
p.enc = nil
|
p.enc = nil
|
||||||
p.dec = nil
|
p.dec = nil
|
||||||
p.size = nil
|
p.size = nil
|
||||||
|
|
@ -316,13 +326,96 @@ func (p *Properties) setEncAndDec(typ reflect.Type, lockGetProp bool) {
|
||||||
}
|
}
|
||||||
switch t1 := typ; t1.Kind() {
|
switch t1 := typ; t1.Kind() {
|
||||||
default:
|
default:
|
||||||
if !p.setNonNullableEncAndDec(t1) {
|
|
||||||
fmt.Fprintf(os.Stderr, "proto: no coders for %v\n", 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:
|
case reflect.Ptr:
|
||||||
switch t2 := t1.Elem(); t2.Kind() {
|
switch t2 := t1.Elem(); t2.Kind() {
|
||||||
default:
|
default:
|
||||||
fmt.Fprintf(os.Stderr, "proto: no encoder function for %T -> %T\n", t1, t2)
|
fmt.Fprintf(os.Stderr, "proto: no encoder function for %v -> %v\n", t1, t2)
|
||||||
break
|
break
|
||||||
case reflect.Bool:
|
case reflect.Bool:
|
||||||
p.enc = (*Buffer).enc_bool
|
p.enc = (*Buffer).enc_bool
|
||||||
|
|
@ -416,6 +509,15 @@ func (p *Properties) setEncAndDec(typ reflect.Type, lockGetProp bool) {
|
||||||
p.enc = (*Buffer).enc_slice_byte
|
p.enc = (*Buffer).enc_slice_byte
|
||||||
p.dec = (*Buffer).dec_slice_byte
|
p.dec = (*Buffer).dec_slice_byte
|
||||||
p.size = size_slice_byte
|
p.size = size_slice_byte
|
||||||
|
// 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:
|
case reflect.Float32, reflect.Float64:
|
||||||
switch t2.Bits() {
|
switch t2.Bits() {
|
||||||
case 32:
|
case 32:
|
||||||
|
|
@ -480,6 +582,23 @@ func (p *Properties) setEncAndDec(typ reflect.Type, lockGetProp bool) {
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
p.setSliceOfNonPointerStructs(t1)
|
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)
|
p.setTag(lockGetProp)
|
||||||
}
|
}
|
||||||
|
|
@ -539,11 +658,11 @@ func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructF
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p.Parse(tag)
|
p.Parse(tag)
|
||||||
p.setEncAndDec(typ, lockGetProp)
|
p.setEncAndDec(typ, f, lockGetProp)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
mutex sync.Mutex
|
propertiesMu sync.RWMutex
|
||||||
propertiesMap = make(map[reflect.Type]*StructProperties)
|
propertiesMap = make(map[reflect.Type]*StructProperties)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -553,13 +672,26 @@ func GetProperties(t reflect.Type) *StructProperties {
|
||||||
if t.Kind() != reflect.Struct {
|
if t.Kind() != reflect.Struct {
|
||||||
panic("proto: type must have kind struct")
|
panic("proto: type must have kind struct")
|
||||||
}
|
}
|
||||||
mutex.Lock()
|
|
||||||
sprop := getPropertiesLocked(t)
|
// Most calls to GetProperties in a long-running program will be
|
||||||
mutex.Unlock()
|
// retrieving details for types we have seen before.
|
||||||
|
propertiesMu.RLock()
|
||||||
|
sprop, ok := propertiesMap[t]
|
||||||
|
propertiesMu.RUnlock()
|
||||||
|
if ok {
|
||||||
|
if collectStats {
|
||||||
|
stats.Chit++
|
||||||
|
}
|
||||||
|
return sprop
|
||||||
|
}
|
||||||
|
|
||||||
|
propertiesMu.Lock()
|
||||||
|
sprop = getPropertiesLocked(t)
|
||||||
|
propertiesMu.Unlock()
|
||||||
return sprop
|
return sprop
|
||||||
}
|
}
|
||||||
|
|
||||||
// getPropertiesLocked requires that mutex is held.
|
// getPropertiesLocked requires that propertiesMu is held.
|
||||||
func getPropertiesLocked(t reflect.Type) *StructProperties {
|
func getPropertiesLocked(t reflect.Type) *StructProperties {
|
||||||
if prop, ok := propertiesMap[t]; ok {
|
if prop, ok := propertiesMap[t]; ok {
|
||||||
if collectStats {
|
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) {
|
func (p *Properties) setSliceOfNonPointerStructs(typ reflect.Type) {
|
||||||
t2 := typ.Elem()
|
t2 := typ.Elem()
|
||||||
p.sstype = typ
|
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 (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
pb "./testdata"
|
|
||||||
. "github.com/gogo/protobuf/proto"
|
. "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)}
|
var messageWithExtension1 = &pb.MyMessage{Count: Int32(7)}
|
||||||
|
|
@ -102,6 +104,26 @@ var SizeTests = []struct {
|
||||||
{"unrecognized", &pb.MoreRepeated{XXX_unrecognized: []byte{13<<3 | 0, 4}}},
|
{"unrecognized", &pb.MoreRepeated{XXX_unrecognized: []byte{13<<3 | 0, 4}}},
|
||||||
{"extension (unencoded)", messageWithExtension1},
|
{"extension (unencoded)", messageWithExtension1},
|
||||||
{"extension (encoded)", messageWithExtension3},
|
{"extension (encoded)", messageWithExtension3},
|
||||||
|
// proto3 message
|
||||||
|
{"proto3 empty", &proto3pb.Message{}},
|
||||||
|
{"proto3 bool", &proto3pb.Message{TrueScotsman: true}},
|
||||||
|
{"proto3 int64", &proto3pb.Message{ResultCount: 1}},
|
||||||
|
{"proto3 uint32", &proto3pb.Message{HeightInCm: 123}},
|
||||||
|
{"proto3 float", &proto3pb.Message{Score: 12.6}},
|
||||||
|
{"proto3 string", &proto3pb.Message{Name: "Snezana"}},
|
||||||
|
{"proto3 bytes", &proto3pb.Message{Data: []byte("wowsa")}},
|
||||||
|
{"proto3 bytes, empty", &proto3pb.Message{Data: []byte{}}},
|
||||||
|
{"proto3 enum", &proto3pb.Message{Hilarity: proto3pb.Message_PUNS}},
|
||||||
|
{"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) {
|
func TestSize(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ func Skip(data []byte) (n int, err error) {
|
||||||
return index, nil
|
return index, nil
|
||||||
case 3:
|
case 3:
|
||||||
for {
|
for {
|
||||||
var wire uint64
|
var innerWire uint64
|
||||||
var start int = index
|
var start int = index
|
||||||
for shift := uint(0); ; shift += 7 {
|
for shift := uint(0); ; shift += 7 {
|
||||||
if index >= l {
|
if index >= l {
|
||||||
|
|
@ -88,13 +88,13 @@ func Skip(data []byte) (n int, err error) {
|
||||||
}
|
}
|
||||||
b := data[index]
|
b := data[index]
|
||||||
index++
|
index++
|
||||||
wire |= (uint64(b) & 0x7F) << shift
|
innerWire |= (uint64(b) & 0x7F) << shift
|
||||||
if b < 0x80 {
|
if b < 0x80 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wireType := int(wire & 0x7)
|
innerWireType := int(innerWire & 0x7)
|
||||||
if wireType == 4 {
|
if innerWireType == 4 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
next, err := Skip(data[start:])
|
next, err := Skip(data[start:])
|
||||||
|
|
|
||||||
|
|
@ -32,16 +32,6 @@
|
||||||
all: regenerate
|
all: regenerate
|
||||||
|
|
||||||
regenerate:
|
regenerate:
|
||||||
rm -f test.pb.go
|
go install github.com/gogo/protobuf/protoc-gen-gogo/version/protoc-min-version
|
||||||
protoc --gogo_out=. test.proto
|
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
|
OtherMessage
|
||||||
MyMessage
|
MyMessage
|
||||||
Ext
|
Ext
|
||||||
|
DefaultsMessage
|
||||||
MyMessageSet
|
MyMessageSet
|
||||||
Empty
|
Empty
|
||||||
MessageList
|
MessageList
|
||||||
|
|
@ -33,6 +34,7 @@ It has these top-level messages:
|
||||||
GroupOld
|
GroupOld
|
||||||
GroupNew
|
GroupNew
|
||||||
FloatingPoint
|
FloatingPoint
|
||||||
|
MessageWithMap
|
||||||
*/
|
*/
|
||||||
package testdata
|
package testdata
|
||||||
|
|
||||||
|
|
@ -180,6 +182,42 @@ func (x *MyMessage_Color) UnmarshalJSON(data []byte) error {
|
||||||
return nil
|
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
|
type Defaults_Color int32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -1401,6 +1439,29 @@ var E_Ext_Number = &proto.ExtensionDesc{
|
||||||
Tag: "varint,105,opt,name=number",
|
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 {
|
type MyMessageSet struct {
|
||||||
XXX_extensions map[int32]proto.Extension `json:"-"`
|
XXX_extensions map[int32]proto.Extension `json:"-"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
|
|
@ -1885,6 +1946,46 @@ func (m *FloatingPoint) GetF() float64 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MessageWithMap struct {
|
||||||
|
NameMapping map[int32]string `protobuf:"bytes,1,rep,name=name_mapping" json:"name_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
|
||||||
|
MsgMapping map[int64]*FloatingPoint `protobuf:"bytes,2,rep,name=msg_mapping" json:"msg_mapping,omitempty" protobuf_key:"zigzag64,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
|
||||||
|
ByteMapping map[bool][]byte `protobuf:"bytes,3,rep,name=byte_mapping" json:"byte_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
|
||||||
|
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{
|
var E_Greeting = &proto.ExtensionDesc{
|
||||||
ExtendedType: (*MyMessage)(nil),
|
ExtendedType: (*MyMessage)(nil),
|
||||||
ExtensionType: ([]string)(nil),
|
ExtensionType: ([]string)(nil),
|
||||||
|
|
@ -1893,6 +1994,262 @@ var E_Greeting = &proto.ExtensionDesc{
|
||||||
Tag: "bytes,106,rep,name=greeting",
|
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{
|
var E_X201 = &proto.ExtensionDesc{
|
||||||
ExtendedType: (*MyMessageSet)(nil),
|
ExtendedType: (*MyMessageSet)(nil),
|
||||||
ExtensionType: (*Empty)(nil),
|
ExtensionType: (*Empty)(nil),
|
||||||
|
|
@ -2297,12 +2654,45 @@ func init() {
|
||||||
proto.RegisterEnum("testdata.FOO", FOO_name, FOO_value)
|
proto.RegisterEnum("testdata.FOO", FOO_name, FOO_value)
|
||||||
proto.RegisterEnum("testdata.GoTest_KIND", GoTest_KIND_name, GoTest_KIND_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.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.Defaults_Color", Defaults_Color_name, Defaults_Color_value)
|
||||||
proto.RegisterEnum("testdata.RepeatedEnum_Color", RepeatedEnum_Color_name, RepeatedEnum_Color_value)
|
proto.RegisterEnum("testdata.RepeatedEnum_Color", RepeatedEnum_Color_name, RepeatedEnum_Color_value)
|
||||||
proto.RegisterExtension(E_Ext_More)
|
proto.RegisterExtension(E_Ext_More)
|
||||||
proto.RegisterExtension(E_Ext_Text)
|
proto.RegisterExtension(E_Ext_Text)
|
||||||
proto.RegisterExtension(E_Ext_Number)
|
proto.RegisterExtension(E_Ext_Number)
|
||||||
proto.RegisterExtension(E_Greeting)
|
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_X201)
|
||||||
proto.RegisterExtension(E_X202)
|
proto.RegisterExtension(E_X202)
|
||||||
proto.RegisterExtension(E_X203)
|
proto.RegisterExtension(E_X203)
|
||||||
|
|
|
||||||
|
|
@ -277,6 +277,51 @@ extend MyMessage {
|
||||||
repeated string greeting = 106;
|
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 {
|
message MyMessageSet {
|
||||||
option message_set_wire_format = true;
|
option message_set_wire_format = true;
|
||||||
extensions 100 to max;
|
extensions 100 to max;
|
||||||
|
|
@ -426,3 +471,10 @@ message GroupNew {
|
||||||
message FloatingPoint {
|
message FloatingPoint {
|
||||||
required double f = 1;
|
required double f = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message MessageWithMap {
|
||||||
|
map<int32, string> name_mapping = 1;
|
||||||
|
map<sint64, FloatingPoint> msg_mapping = 2;
|
||||||
|
map<bool, bytes> byte_mapping = 3;
|
||||||
|
map<string, string> str_to_str = 4;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,6 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"math"
|
"math"
|
||||||
"os"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -253,6 +252,84 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if fv.Kind() == reflect.Map {
|
||||||
|
// Map fields are rendered as a repeated struct with key/value fields.
|
||||||
|
keys := fv.MapKeys() // TODO: should we sort these for deterministic output?
|
||||||
|
sort.Sort(mapKeys(keys))
|
||||||
|
for _, key := range keys {
|
||||||
|
val := fv.MapIndex(key)
|
||||||
|
if err := writeName(w, props); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !w.compact {
|
||||||
|
if err := w.WriteByte(' '); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// open struct
|
||||||
|
if err := w.WriteByte('<'); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !w.compact {
|
||||||
|
if err := w.WriteByte('\n'); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
w.indent()
|
||||||
|
// key
|
||||||
|
if _, err := w.WriteString("key:"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !w.compact {
|
||||||
|
if err := w.WriteByte(' '); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := writeAny(w, key, props.mkeyprop); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := w.WriteByte('\n'); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// 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 {
|
if err := writeName(w, props); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -354,7 +431,7 @@ func writeAny(w *textWriter, v reflect.Value, props *Properties) error {
|
||||||
switch v.Kind() {
|
switch v.Kind() {
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
// Should only be a []byte; repeated fields are handled in writeStruct.
|
// 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
|
return err
|
||||||
}
|
}
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
|
|
@ -607,10 +684,7 @@ func writeExtensions(w *textWriter, pv reflect.Value) error {
|
||||||
|
|
||||||
pb, err := GetExtension(ep, desc)
|
pb, err := GetExtension(ep, desc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if _, err := fmt.Fprintln(os.Stderr, "proto: failed getting extension: ", err); err != nil {
|
return fmt.Errorf("failed getting extension: %v", err)
|
||||||
return err
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Repeated extensions will appear as a slice.
|
// 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]))
|
unq, err := unquoteC(p.s[1:i], rune(p.s[0]))
|
||||||
if err != nil {
|
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
|
return
|
||||||
}
|
}
|
||||||
p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)]
|
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
|
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.
|
// Return a RequiredNotSetError indicating which required field was not set.
|
||||||
func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSetError {
|
func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSetError {
|
||||||
st := sv.Type()
|
st := sv.Type()
|
||||||
|
|
@ -414,6 +426,10 @@ func (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseEr
|
||||||
if typ.Elem().Kind() != reflect.Ptr {
|
if typ.Elem().Kind() != reflect.Ptr {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
} else if typ.Kind() == reflect.String {
|
||||||
|
// The proto3 exception is for a string field,
|
||||||
|
// which requires a colon.
|
||||||
|
break
|
||||||
}
|
}
|
||||||
needColon = false
|
needColon = false
|
||||||
}
|
}
|
||||||
|
|
@ -519,6 +535,66 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
|
||||||
|
|
||||||
dst := sv.Field(fi)
|
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.
|
// Check that it's not already set if it's not a repeated field.
|
||||||
if !props.Repeated && fieldSet[name] {
|
if !props.Repeated && fieldSet[name] {
|
||||||
return p.errorf("non-repeated field %q was repeated", 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.
|
if err := p.consumeOptionalSeparator(); err != nil {
|
||||||
tok = p.next()
|
return err
|
||||||
if tok.err != nil {
|
|
||||||
return tok.err
|
|
||||||
}
|
|
||||||
if tok.value != ";" && tok.value != "," {
|
|
||||||
p.back()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if reqCount > 0 {
|
if reqCount > 0 {
|
||||||
|
|
@ -556,6 +628,19 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
|
||||||
return reqFieldErr
|
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 {
|
func (p *textParser) readAny(v reflect.Value, props *Properties) error {
|
||||||
tok := p.next()
|
tok := p.next()
|
||||||
if tok.err != nil {
|
if tok.err != nil {
|
||||||
|
|
|
||||||
|
|
@ -36,8 +36,9 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
. "./testdata"
|
|
||||||
. "github.com/gogo/protobuf/proto"
|
. "github.com/gogo/protobuf/proto"
|
||||||
|
proto3pb "github.com/gogo/protobuf/proto/proto3_proto"
|
||||||
|
. "github.com/gogo/protobuf/proto/testdata"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UnmarshalTextTest struct {
|
type UnmarshalTextTest struct {
|
||||||
|
|
@ -151,7 +152,7 @@ var unMarshalTextTests = []UnmarshalTextTest{
|
||||||
// Bad quoted string
|
// Bad quoted string
|
||||||
{
|
{
|
||||||
in: `inner: < host: "\0" >` + "\n",
|
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
|
// 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
|
var benchInput string
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,8 @@ import (
|
||||||
|
|
||||||
"github.com/gogo/protobuf/proto"
|
"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
|
// 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)
|
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{
|
message := &mesos.AuthenticationStartMessage{
|
||||||
Mechanism: proto.String(selectedMech),
|
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 {
|
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{
|
transport.On("Send", mock.Anything, &server, &mesos.AuthenticationStartMessage{
|
||||||
Mechanism: proto.String(crammd5.Name),
|
Mechanism: proto.String(crammd5.Name),
|
||||||
Data: proto.String(""), // may be nil, depends on init step
|
|
||||||
}).Return(nil).Run(func(_ mock.Arguments) {
|
}).Return(nil).Run(func(_ mock.Arguments) {
|
||||||
transport.Recv(&server, &mesos.AuthenticationStepMessage{
|
transport.Recv(&server, &mesos.AuthenticationStepMessage{
|
||||||
Data: []byte(`lsd;lfkgjs;dlfkgjs;dfklg`),
|
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 proto "github.com/gogo/protobuf/proto"
|
||||||
import math "math"
|
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.
|
// Reference imports to suppress errors if they are not otherwise used.
|
||||||
var _ = proto.Marshal
|
var _ = proto.Marshal
|
||||||
|
|
@ -200,6 +200,8 @@ func (m *Usage) GetContainerId() *ContainerID {
|
||||||
type Termination struct {
|
type Termination struct {
|
||||||
// A container may be killed if it exceeds its resources; this will
|
// A container may be killed if it exceeds its resources; this will
|
||||||
// be indicated by killed=true and described by the message string.
|
// 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"`
|
Killed *bool `protobuf:"varint,1,req,name=killed" json:"killed,omitempty"`
|
||||||
Message *string `protobuf:"bytes,2,req,name=message" json:"message,omitempty"`
|
Message *string `protobuf:"bytes,2,req,name=message" json:"message,omitempty"`
|
||||||
// Exit status of the process.
|
// Exit status of the process.
|
||||||
|
|
@ -250,6 +252,3 @@ func (m *Containers) GetContainers() []*ContainerID {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,8 @@ message Usage {
|
||||||
message Termination {
|
message Termination {
|
||||||
// A container may be killed if it exceeds its resources; this will
|
// A container may be killed if it exceeds its resources; this will
|
||||||
// be indicated by killed=true and described by the message string.
|
// 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 bool killed = 1;
|
||||||
required string message = 2;
|
required string message = 2;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ package mesosproto
|
||||||
import proto "github.com/gogo/protobuf/proto"
|
import proto "github.com/gogo/protobuf/proto"
|
||||||
import math "math"
|
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.
|
// Reference imports to suppress errors if they are not otherwise used.
|
||||||
var _ = proto.Marshal
|
var _ = proto.Marshal
|
||||||
|
|
@ -73,6 +73,3 @@ func (m *InternalAuthenticationResult) GetPid() string {
|
||||||
}
|
}
|
||||||
return ""
|
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
|
* Describes a framework.
|
||||||
* 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/.
|
|
||||||
*/
|
*/
|
||||||
message FrameworkInfo {
|
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;
|
required string user = 1;
|
||||||
|
|
||||||
|
// Name of the framework that shows up in the Mesos Web UI.
|
||||||
required string name = 2;
|
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;
|
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];
|
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];
|
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 = "*"];
|
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;
|
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;
|
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;
|
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
|
* Describes a health check for a task or executor (or any arbitrary
|
||||||
* process/command). A "strategy" is picked by specifying one of the
|
* process/command). A "strategy" is picked by specifying one of the
|
||||||
* optional fields, currently only 'http' and 'command' are
|
* optional fields; currently only 'command' is supported.
|
||||||
* supported. Specifying more than one strategy is an error.
|
* Specifying more than one strategy is an error.
|
||||||
*/
|
*/
|
||||||
message HealthCheck {
|
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 {
|
message HTTP {
|
||||||
// Port to send the HTTP request.
|
// Port to send the HTTP request.
|
||||||
required uint32 port = 1;
|
required uint32 port = 1;
|
||||||
|
|
@ -170,6 +201,7 @@ message HealthCheck {
|
||||||
// for specific data in the response.
|
// for specific data in the response.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HTTP health check - not yet recommended for use, see MESOS-2533.
|
||||||
optional HTTP http = 1;
|
optional HTTP http = 1;
|
||||||
|
|
||||||
// TODO(benh): Consider adding a URL health check strategy which
|
// 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.
|
// encapsulates all the details in a single string field.
|
||||||
|
|
||||||
// TODO(benh): Other possible health check strategies could include
|
// TODO(benh): Other possible health check strategies could include
|
||||||
// one for TCP/UDP or a "command". A "command" could be running a
|
// one for TCP/UDP.
|
||||||
// (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).
|
|
||||||
|
|
||||||
// Amount of time to wait until starting the health checks.
|
// Amount of time to wait until starting the health checks.
|
||||||
optional double delay_seconds = 2 [default = 15.0];
|
optional double delay_seconds = 2 [default = 15.0];
|
||||||
|
|
@ -218,7 +245,24 @@ message CommandInfo {
|
||||||
message URI {
|
message URI {
|
||||||
required string value = 1;
|
required string value = 1;
|
||||||
optional bool executable = 2;
|
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];
|
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.
|
// Describes a container.
|
||||||
|
|
@ -293,6 +337,12 @@ message ExecutorInfo {
|
||||||
// usage information into a time series database for monitoring.
|
// usage information into a time series database for monitoring.
|
||||||
optional string source = 10;
|
optional string source = 10;
|
||||||
optional bytes data = 4;
|
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];
|
required uint32 port = 3 [default = 5050];
|
||||||
optional string pid = 4;
|
optional string pid = 4;
|
||||||
optional string hostname = 5;
|
optional string hostname = 5;
|
||||||
|
optional string version = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -323,6 +374,8 @@ message SlaveInfo {
|
||||||
repeated Resource resources = 3;
|
repeated Resource resources = 3;
|
||||||
repeated Attribute attributes = 5;
|
repeated Attribute attributes = 5;
|
||||||
optional SlaveID id = 6;
|
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];
|
optional bool checkpoint = 7 [default = false];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -399,15 +452,122 @@ message Resource {
|
||||||
optional Value.Ranges ranges = 4;
|
optional Value.Ranges ranges = 4;
|
||||||
optional Value.Set set = 5;
|
optional Value.Set set = 5;
|
||||||
optional string role = 6 [default = "*"];
|
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.
|
* A snapshot of resource usage statistics.
|
||||||
*/
|
*/
|
||||||
message ResourceStatistics {
|
message ResourceStatistics {
|
||||||
required double timestamp = 1; // Snapshot time, in seconds since the Epoch.
|
required double timestamp = 1; // Snapshot time, in seconds since the Epoch.
|
||||||
|
|
||||||
|
optional uint32 processes = 30;
|
||||||
|
optional uint32 threads = 31;
|
||||||
|
|
||||||
// CPU Usage Information:
|
// CPU Usage Information:
|
||||||
// Total CPU time spent in user mode, and kernel mode.
|
// Total CPU time spent in user mode, and kernel mode.
|
||||||
optional double cpus_user_time_secs = 2;
|
optional double cpus_user_time_secs = 2;
|
||||||
|
|
@ -422,17 +582,55 @@ message ResourceStatistics {
|
||||||
optional double cpus_throttled_time_secs = 9;
|
optional double cpus_throttled_time_secs = 9;
|
||||||
|
|
||||||
// Memory Usage Information:
|
// 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;
|
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_file_bytes = 10;
|
||||||
optional uint64 mem_anon_bytes = 11;
|
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.
|
// Perf statistics.
|
||||||
optional PerfStatistics perf = 13;
|
optional PerfStatistics perf = 13;
|
||||||
|
|
@ -453,34 +651,36 @@ message ResourceStatistics {
|
||||||
optional double net_tcp_rtt_microsecs_p90 = 23;
|
optional double net_tcp_rtt_microsecs_p90 = 23;
|
||||||
optional double net_tcp_rtt_microsecs_p95 = 24;
|
optional double net_tcp_rtt_microsecs_p95 = 24;
|
||||||
optional double net_tcp_rtt_microsecs_p99 = 25;
|
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.
|
* Describes a snapshot of the resource usage for executors.
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
message ResourceUsage {
|
message ResourceUsage {
|
||||||
required SlaveID slave_id = 1;
|
message Executor {
|
||||||
required FrameworkID framework_id = 2;
|
required ExecutorInfo executor_info = 1;
|
||||||
|
|
||||||
// Resource usage is for an executor. For tasks launched with
|
// This includes resources used by the executor itself
|
||||||
// an explicit executor, the executor id is provided. For tasks
|
// as well as its active tasks.
|
||||||
// launched without an executor, our internal executor will be
|
repeated Resource allocated = 2;
|
||||||
// used. In this case, we provide the task id here instead, in
|
|
||||||
// order to make this message easier for schedulers to work with.
|
|
||||||
|
|
||||||
optional ExecutorID executor_id = 3; // If present, this executor was
|
// Current resource usage. If absent, the containerizer
|
||||||
optional string executor_name = 4; // explicitly specified.
|
// 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.
|
// TODO(jieyu): Include slave's total resources here.
|
||||||
optional ResourceStatistics statistics = 6;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -564,6 +764,8 @@ message PerfStatistics {
|
||||||
* to proactively influence the allocator. If 'slave_id' is provided
|
* to proactively influence the allocator. If 'slave_id' is provided
|
||||||
* then this request is assumed to only apply to resources on that
|
* then this request is assumed to only apply to resources on that
|
||||||
* slave.
|
* slave.
|
||||||
|
*
|
||||||
|
* TODO(vinod): Remove this once the old driver is removed.
|
||||||
*/
|
*/
|
||||||
message Request {
|
message Request {
|
||||||
optional SlaveID slave_id = 1;
|
optional SlaveID slave_id = 1;
|
||||||
|
|
@ -583,6 +785,44 @@ message Offer {
|
||||||
repeated Resource resources = 5;
|
repeated Resource resources = 5;
|
||||||
repeated Attribute attributes = 7;
|
repeated Attribute attributes = 7;
|
||||||
repeated ExecutorID executor_ids = 6;
|
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
|
// A health check for the task (currently in *alpha* and initial
|
||||||
// support will only be for TaskInfo's that have a CommandInfo).
|
// support will only be for TaskInfo's that have a CommandInfo).
|
||||||
optional HealthCheck health_check = 8;
|
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_FAILED = 3; // TERMINAL. The task failed to finish successfully.
|
||||||
TASK_KILLED = 4; // TERMINAL. The task was killed by the executor.
|
TASK_KILLED = 4; // TERMINAL. The task was killed by the executor.
|
||||||
TASK_LOST = 5; // TERMINAL. The task failed but can be rescheduled.
|
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.
|
TASK_ERROR = 7; // TERMINAL. The task description contains an error.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -635,16 +886,20 @@ enum TaskState {
|
||||||
* Describes the current status of a task.
|
* Describes the current status of a task.
|
||||||
*/
|
*/
|
||||||
message TaskStatus {
|
message TaskStatus {
|
||||||
/** Describes the source of the task status update. */
|
// Describes the source of the task status update.
|
||||||
enum Source {
|
enum Source {
|
||||||
SOURCE_MASTER = 0;
|
SOURCE_MASTER = 0;
|
||||||
SOURCE_SLAVE = 1;
|
SOURCE_SLAVE = 1;
|
||||||
SOURCE_EXECUTOR = 2;
|
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 {
|
enum Reason {
|
||||||
REASON_COMMAND_EXECUTOR_FAILED = 0;
|
REASON_COMMAND_EXECUTOR_FAILED = 0;
|
||||||
|
REASON_EXECUTOR_PREEMPTED = 17;
|
||||||
REASON_EXECUTOR_TERMINATED = 1;
|
REASON_EXECUTOR_TERMINATED = 1;
|
||||||
REASON_EXECUTOR_UNREGISTERED = 2;
|
REASON_EXECUTOR_UNREGISTERED = 2;
|
||||||
REASON_FRAMEWORK_REMOVED = 3;
|
REASON_FRAMEWORK_REMOVED = 3;
|
||||||
|
|
@ -654,6 +909,7 @@ message TaskStatus {
|
||||||
REASON_MASTER_DISCONNECTED = 7;
|
REASON_MASTER_DISCONNECTED = 7;
|
||||||
REASON_MEMORY_LIMIT = 8;
|
REASON_MEMORY_LIMIT = 8;
|
||||||
REASON_RECONCILIATION = 9;
|
REASON_RECONCILIATION = 9;
|
||||||
|
REASON_RESOURCES_UNKNOWN = 18;
|
||||||
REASON_SLAVE_DISCONNECTED = 10;
|
REASON_SLAVE_DISCONNECTED = 10;
|
||||||
REASON_SLAVE_REMOVED = 11;
|
REASON_SLAVE_REMOVED = 11;
|
||||||
REASON_SLAVE_RESTARTED = 12;
|
REASON_SLAVE_RESTARTED = 12;
|
||||||
|
|
@ -673,6 +929,17 @@ message TaskStatus {
|
||||||
optional ExecutorID executor_id = 7; // TODO(benh): Use in master/slave.
|
optional ExecutorID executor_id = 7; // TODO(benh): Use in master/slave.
|
||||||
optional double timestamp = 6;
|
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
|
// Describes whether the task has been determined to be healthy
|
||||||
// (true) or unhealthy (false) according to the HealthCheck field in
|
// (true) or unhealthy (false) according to the HealthCheck field in
|
||||||
// the command info.
|
// the command info.
|
||||||
|
|
@ -928,10 +1195,15 @@ message ContainerInfo {
|
||||||
optional bool privileged = 4 [default = false];
|
optional bool privileged = 4 [default = false];
|
||||||
|
|
||||||
// Allowing arbitrary parameters to be passed to docker CLI.
|
// 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
|
// to be supported moving forward, as we might move away from
|
||||||
// the docker CLI.
|
// the docker CLI.
|
||||||
repeated Parameter parameters = 5;
|
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;
|
required Type type = 1;
|
||||||
|
|
@ -940,3 +1212,68 @@ message ContainerInfo {
|
||||||
|
|
||||||
optional DockerInfo docker = 3;
|
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 proto "github.com/gogo/protobuf/proto"
|
||||||
import math "math"
|
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.
|
// Reference imports to suppress errors if they are not otherwise used.
|
||||||
var _ = proto.Marshal
|
var _ = proto.Marshal
|
||||||
|
|
@ -71,6 +71,12 @@ type Task struct {
|
||||||
// NOTE: Either both the fields must be set or both must be unset.
|
// 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"`
|
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"`
|
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:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -148,33 +154,18 @@ func (m *Task) GetStatusUpdateUuid() []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Describes a role, which are used to group frameworks for allocation
|
func (m *Task) GetLabels() *Labels {
|
||||||
// decisions, depending on the allocation policy being used.
|
if m != nil {
|
||||||
// The weight field can be used to indicate forms of priority.
|
return m.Labels
|
||||||
type RoleInfo struct {
|
}
|
||||||
Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
|
return nil
|
||||||
Weight *float64 `protobuf:"fixed64,2,opt,name=weight,def=1" json:"weight,omitempty"`
|
|
||||||
XXX_unrecognized []byte `json:"-"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *RoleInfo) Reset() { *m = RoleInfo{} }
|
func (m *Task) GetDiscovery() *DiscoveryInfo {
|
||||||
func (m *RoleInfo) String() string { return proto.CompactTextString(m) }
|
if m != nil {
|
||||||
func (*RoleInfo) ProtoMessage() {}
|
return m.Discovery
|
||||||
|
|
||||||
const Default_RoleInfo_Weight float64 = 1
|
|
||||||
|
|
||||||
func (m *RoleInfo) GetName() string {
|
|
||||||
if m != nil && m.Name != nil {
|
|
||||||
return *m.Name
|
|
||||||
}
|
}
|
||||||
return ""
|
return nil
|
||||||
}
|
|
||||||
|
|
||||||
func (m *RoleInfo) GetWeight() float64 {
|
|
||||||
if m != nil && m.Weight != nil {
|
|
||||||
return *m.Weight
|
|
||||||
}
|
|
||||||
return Default_RoleInfo_Weight
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(vinod): Create a new UUID message type.
|
// 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"`
|
SlaveId *SlaveID `protobuf:"bytes,3,opt,name=slave_id" json:"slave_id,omitempty"`
|
||||||
Status *TaskStatus `protobuf:"bytes,4,req,name=status" json:"status,omitempty"`
|
Status *TaskStatus `protobuf:"bytes,4,req,name=status" json:"status,omitempty"`
|
||||||
Timestamp *float64 `protobuf:"fixed64,5,req,name=timestamp" json:"timestamp,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
|
// This corresponds to the latest state of the task according to the
|
||||||
// slave. Note that this state might be different than the state in
|
// slave. Note that this state might be different than the state in
|
||||||
// 'status' because status update manager queues updates. In other
|
// 'status' because status update manager queues updates. In other
|
||||||
|
|
@ -635,7 +629,8 @@ func (m *ReviveOffersMessage) GetFrameworkId() *FrameworkID {
|
||||||
}
|
}
|
||||||
|
|
||||||
type RunTaskMessage struct {
|
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"`
|
Framework *FrameworkInfo `protobuf:"bytes,2,req,name=framework" json:"framework,omitempty"`
|
||||||
Pid *string `protobuf:"bytes,3,req,name=pid" json:"pid,omitempty"`
|
Pid *string `protobuf:"bytes,3,req,name=pid" json:"pid,omitempty"`
|
||||||
Task *TaskInfo `protobuf:"bytes,4,req,name=task" json:"task,omitempty"`
|
Task *TaskInfo `protobuf:"bytes,4,req,name=task" json:"task,omitempty"`
|
||||||
|
|
@ -830,6 +825,10 @@ func (m *FrameworkErrorMessage) GetMessage() string {
|
||||||
|
|
||||||
type RegisterSlaveMessage struct {
|
type RegisterSlaveMessage struct {
|
||||||
Slave *SlaveInfo `protobuf:"bytes,1,req,name=slave" json:"slave,omitempty"`
|
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
|
// NOTE: This is a hack for the master to detect the slave's
|
||||||
// version. If unset the slave is < 0.21.0.
|
// version. If unset the slave is < 0.21.0.
|
||||||
// TODO(bmahler): Do proper versioning: MESOS-986.
|
// TODO(bmahler): Do proper versioning: MESOS-986.
|
||||||
|
|
@ -848,6 +847,13 @@ func (m *RegisterSlaveMessage) GetSlave() *SlaveInfo {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *RegisterSlaveMessage) GetCheckpointedResources() []*Resource {
|
||||||
|
if m != nil {
|
||||||
|
return m.CheckpointedResources
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (m *RegisterSlaveMessage) GetVersion() string {
|
func (m *RegisterSlaveMessage) GetVersion() string {
|
||||||
if m != nil && m.Version != nil {
|
if m != nil && m.Version != nil {
|
||||||
return *m.Version
|
return *m.Version
|
||||||
|
|
@ -856,11 +862,11 @@ func (m *RegisterSlaveMessage) GetVersion() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ReregisterSlaveMessage struct {
|
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"`
|
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"`
|
ExecutorInfos []*ExecutorInfo `protobuf:"bytes,4,rep,name=executor_infos" json:"executor_infos,omitempty"`
|
||||||
Tasks []*Task `protobuf:"bytes,3,rep,name=tasks" json:"tasks,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"`
|
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 (m *ReregisterSlaveMessage) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ReregisterSlaveMessage) ProtoMessage() {}
|
func (*ReregisterSlaveMessage) ProtoMessage() {}
|
||||||
|
|
||||||
func (m *ReregisterSlaveMessage) GetSlaveId() *SlaveID {
|
func (m *ReregisterSlaveMessage) GetSlave() *SlaveInfo {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
return m.SlaveId
|
return m.Slave
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ReregisterSlaveMessage) GetSlave() *SlaveInfo {
|
func (m *ReregisterSlaveMessage) GetCheckpointedResources() []*Resource {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
return m.Slave
|
return m.CheckpointedResources
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -919,6 +925,7 @@ func (m *ReregisterSlaveMessage) GetVersion() string {
|
||||||
|
|
||||||
type SlaveRegisteredMessage struct {
|
type SlaveRegisteredMessage struct {
|
||||||
SlaveId *SlaveID `protobuf:"bytes,1,req,name=slave_id" json:"slave_id,omitempty"`
|
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:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -933,9 +940,17 @@ func (m *SlaveRegisteredMessage) GetSlaveId() *SlaveID {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *SlaveRegisteredMessage) GetConnection() *MasterSlaveConnection {
|
||||||
|
if m != nil {
|
||||||
|
return m.Connection
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type SlaveReregisteredMessage struct {
|
type SlaveReregisteredMessage struct {
|
||||||
SlaveId *SlaveID `protobuf:"bytes,1,req,name=slave_id" json:"slave_id,omitempty"`
|
SlaveId *SlaveID `protobuf:"bytes,1,req,name=slave_id" json:"slave_id,omitempty"`
|
||||||
Reconciliations []*ReconcileTasksMessage `protobuf:"bytes,2,rep,name=reconciliations" json:"reconciliations,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:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -957,6 +972,13 @@ func (m *SlaveReregisteredMessage) GetReconciliations() []*ReconcileTasksMessage
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *SlaveReregisteredMessage) GetConnection() *MasterSlaveConnection {
|
||||||
|
if m != nil {
|
||||||
|
return m.Connection
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type UnregisterSlaveMessage struct {
|
type UnregisterSlaveMessage struct {
|
||||||
SlaveId *SlaveID `protobuf:"bytes,1,req,name=slave_id" json:"slave_id,omitempty"`
|
SlaveId *SlaveID `protobuf:"bytes,1,req,name=slave_id" json:"slave_id,omitempty"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
|
|
@ -973,6 +995,25 @@ func (m *UnregisterSlaveMessage) GetSlaveId() *SlaveID {
|
||||||
return nil
|
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.
|
// This message is periodically sent by the master to the slave.
|
||||||
// If the slave is connected to the master, "connected" is true.
|
// If the slave is connected to the master, "connected" is true.
|
||||||
type PingSlaveMessage struct {
|
type PingSlaveMessage struct {
|
||||||
|
|
@ -1018,9 +1059,13 @@ func (m *ShutdownFrameworkMessage) GetFrameworkId() *FrameworkID {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tells the executor to initiate a shut down by invoking
|
// Tells a slave (and consequently executor) to shutdown an executor.
|
||||||
// Executor::shutdown.
|
|
||||||
type ShutdownExecutorMessage struct {
|
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:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1028,6 +1073,20 @@ func (m *ShutdownExecutorMessage) Reset() { *m = ShutdownExecutorMessage
|
||||||
func (m *ShutdownExecutorMessage) String() string { return proto.CompactTextString(m) }
|
func (m *ShutdownExecutorMessage) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ShutdownExecutorMessage) ProtoMessage() {}
|
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 {
|
type UpdateFrameworkMessage struct {
|
||||||
FrameworkId *FrameworkID `protobuf:"bytes,1,req,name=framework_id" json:"framework_id,omitempty"`
|
FrameworkId *FrameworkID `protobuf:"bytes,1,req,name=framework_id" json:"framework_id,omitempty"`
|
||||||
Pid *string `protobuf:"bytes,2,req,name=pid" json:"pid,omitempty"`
|
Pid *string `protobuf:"bytes,2,req,name=pid" json:"pid,omitempty"`
|
||||||
|
|
@ -1052,6 +1111,52 @@ func (m *UpdateFrameworkMessage) GetPid() string {
|
||||||
return ""
|
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 {
|
type RegisterExecutorMessage struct {
|
||||||
FrameworkId *FrameworkID `protobuf:"bytes,1,req,name=framework_id" json:"framework_id,omitempty"`
|
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"`
|
ExecutorId *ExecutorID `protobuf:"bytes,2,req,name=executor_id" json:"executor_id,omitempty"`
|
||||||
|
|
@ -1260,110 +1365,6 @@ func (m *ShutdownMessage) GetMessage() string {
|
||||||
return ""
|
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.
|
// Describes Completed Frameworks, etc. for archival.
|
||||||
type Archive struct {
|
type Archive struct {
|
||||||
|
|
@ -1465,86 +1466,24 @@ func (m *TaskHealthStatus) GetConsecutiveFailures() int32 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collection of Modules.
|
// *
|
||||||
type Modules struct {
|
// Message to signal completion of an event within a module.
|
||||||
Libraries []*Modules_Library `protobuf:"bytes,1,rep,name=libraries" json:"libraries,omitempty"`
|
type HookExecuted struct {
|
||||||
|
Module *string `protobuf:"bytes,1,opt,name=module" json:"module,omitempty"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Modules) Reset() { *m = Modules{} }
|
func (m *HookExecuted) Reset() { *m = HookExecuted{} }
|
||||||
func (m *Modules) String() string { return proto.CompactTextString(m) }
|
func (m *HookExecuted) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Modules) ProtoMessage() {}
|
func (*HookExecuted) ProtoMessage() {}
|
||||||
|
|
||||||
func (m *Modules) GetLibraries() []*Modules_Library {
|
func (m *HookExecuted) GetModule() string {
|
||||||
if m != nil {
|
if m != nil && m.Module != nil {
|
||||||
return m.Libraries
|
return *m.Module
|
||||||
}
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
return ""
|
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() {
|
func init() {
|
||||||
proto.RegisterEnum("mesosproto.StatusUpdateRecord_Type", StatusUpdateRecord_Type_name, StatusUpdateRecord_Type_value)
|
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.
|
// NOTE: Either both the fields must be set or both must be unset.
|
||||||
optional TaskState status_update_state = 9;
|
optional TaskState status_update_state = 9;
|
||||||
optional bytes status_update_uuid = 10;
|
optional bytes status_update_uuid = 10;
|
||||||
}
|
|
||||||
|
|
||||||
|
optional Labels labels = 11;
|
||||||
|
|
||||||
// Describes a role, which are used to group frameworks for allocation
|
// Service discovery information for the task. It is not interpreted
|
||||||
// decisions, depending on the allocation policy being used.
|
// or acted upon by Mesos. It is up to a service discovery system
|
||||||
// The weight field can be used to indicate forms of priority.
|
// to use this information as needed and to handle tasks without
|
||||||
message RoleInfo {
|
// service discovery information.
|
||||||
required string name = 1;
|
optional DiscoveryInfo discovery = 12;
|
||||||
optional double weight = 2 [default = 1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -73,7 +72,11 @@ message StatusUpdate {
|
||||||
optional SlaveID slave_id = 3;
|
optional SlaveID slave_id = 3;
|
||||||
required TaskStatus status = 4;
|
required TaskStatus status = 4;
|
||||||
required double timestamp = 5;
|
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
|
// This corresponds to the latest state of the task according to the
|
||||||
// slave. Note that this state might be different than the state in
|
// slave. Note that this state might be different than the state in
|
||||||
|
|
@ -188,7 +191,8 @@ message ReviveOffersMessage {
|
||||||
|
|
||||||
|
|
||||||
message RunTaskMessage {
|
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 FrameworkInfo framework = 2;
|
||||||
required string pid = 3;
|
required string pid = 3;
|
||||||
required TaskInfo task = 4;
|
required TaskInfo task = 4;
|
||||||
|
|
@ -244,6 +248,11 @@ message FrameworkErrorMessage {
|
||||||
message RegisterSlaveMessage {
|
message RegisterSlaveMessage {
|
||||||
required SlaveInfo slave = 1;
|
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
|
// NOTE: This is a hack for the master to detect the slave's
|
||||||
// version. If unset the slave is < 0.21.0.
|
// version. If unset the slave is < 0.21.0.
|
||||||
// TODO(bmahler): Do proper versioning: MESOS-986.
|
// TODO(bmahler): Do proper versioning: MESOS-986.
|
||||||
|
|
@ -252,11 +261,13 @@ message RegisterSlaveMessage {
|
||||||
|
|
||||||
|
|
||||||
message ReregisterSlaveMessage {
|
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;
|
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 ExecutorInfo executor_infos = 4;
|
||||||
repeated Task tasks = 3;
|
repeated Task tasks = 3;
|
||||||
repeated Archive.Framework completed_frameworks = 5;
|
repeated Archive.Framework completed_frameworks = 5;
|
||||||
|
|
@ -270,6 +281,7 @@ message ReregisterSlaveMessage {
|
||||||
|
|
||||||
message SlaveRegisteredMessage {
|
message SlaveRegisteredMessage {
|
||||||
required SlaveID slave_id = 1;
|
required SlaveID slave_id = 1;
|
||||||
|
optional MasterSlaveConnection connection = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -277,6 +289,7 @@ message SlaveReregisteredMessage {
|
||||||
required SlaveID slave_id = 1;
|
required SlaveID slave_id = 1;
|
||||||
|
|
||||||
repeated ReconcileTasksMessage reconciliations = 2;
|
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.
|
// This message is periodically sent by the master to the slave.
|
||||||
// If the slave is connected to the master, "connected" is true.
|
// If the slave is connected to the master, "connected" is true.
|
||||||
message PingSlaveMessage {
|
message PingSlaveMessage {
|
||||||
|
|
@ -303,9 +324,14 @@ message ShutdownFrameworkMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Tells the executor to initiate a shut down by invoking
|
// Tells a slave (and consequently executor) to shutdown an executor.
|
||||||
// Executor::shutdown.
|
message ShutdownExecutorMessage {
|
||||||
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 {
|
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 {
|
message RegisterExecutorMessage {
|
||||||
required FrameworkID framework_id = 1;
|
required FrameworkID framework_id = 1;
|
||||||
required ExecutorID executor_id = 2;
|
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.
|
// TODO(adam-mesos): Move this to an 'archive' package.
|
||||||
/**
|
/**
|
||||||
* Describes Completed Frameworks, etc. for archival.
|
* Describes Completed Frameworks, etc. for archival.
|
||||||
|
|
@ -426,28 +437,9 @@ message TaskHealthStatus {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Collection of Modules.
|
/**
|
||||||
message Modules {
|
* Message to signal completion of an event within a module.
|
||||||
message Library {
|
*/
|
||||||
// If "file" contains a slash ("/"), then it is interpreted as a
|
message HookExecuted {
|
||||||
// (relative or absolute) pathname. Otherwise a standard library
|
optional string module = 1;
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ package mesosproto
|
||||||
import proto "github.com/gogo/protobuf/proto"
|
import proto "github.com/gogo/protobuf/proto"
|
||||||
import math "math"
|
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.
|
// Reference imports to suppress errors if they are not otherwise used.
|
||||||
var _ = proto.Marshal
|
var _ = proto.Marshal
|
||||||
|
|
@ -86,6 +86,3 @@ func (m *Registry_Slaves) GetSlaves() []*Registry_Slave {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ package mesosproto
|
||||||
import proto "github.com/gogo/protobuf/proto"
|
import proto "github.com/gogo/protobuf/proto"
|
||||||
import math "math"
|
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.
|
// Reference imports to suppress errors if they are not otherwise used.
|
||||||
var _ = proto.Marshal
|
var _ = proto.Marshal
|
||||||
|
|
@ -18,35 +18,32 @@ var _ = math.Inf
|
||||||
type Event_Type int32
|
type Event_Type int32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Event_REGISTERED Event_Type = 1
|
Event_SUBSCRIBED Event_Type = 1
|
||||||
Event_REREGISTERED Event_Type = 2
|
Event_OFFERS Event_Type = 2
|
||||||
Event_OFFERS Event_Type = 3
|
Event_RESCIND Event_Type = 3
|
||||||
Event_RESCIND Event_Type = 4
|
Event_UPDATE Event_Type = 4
|
||||||
Event_UPDATE Event_Type = 5
|
Event_MESSAGE Event_Type = 5
|
||||||
Event_MESSAGE Event_Type = 6
|
Event_FAILURE Event_Type = 6
|
||||||
Event_FAILURE Event_Type = 7
|
Event_ERROR Event_Type = 7
|
||||||
Event_ERROR Event_Type = 8
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var Event_Type_name = map[int32]string{
|
var Event_Type_name = map[int32]string{
|
||||||
1: "REGISTERED",
|
1: "SUBSCRIBED",
|
||||||
2: "REREGISTERED",
|
2: "OFFERS",
|
||||||
3: "OFFERS",
|
3: "RESCIND",
|
||||||
4: "RESCIND",
|
4: "UPDATE",
|
||||||
5: "UPDATE",
|
5: "MESSAGE",
|
||||||
6: "MESSAGE",
|
6: "FAILURE",
|
||||||
7: "FAILURE",
|
7: "ERROR",
|
||||||
8: "ERROR",
|
|
||||||
}
|
}
|
||||||
var Event_Type_value = map[string]int32{
|
var Event_Type_value = map[string]int32{
|
||||||
"REGISTERED": 1,
|
"SUBSCRIBED": 1,
|
||||||
"REREGISTERED": 2,
|
"OFFERS": 2,
|
||||||
"OFFERS": 3,
|
"RESCIND": 3,
|
||||||
"RESCIND": 4,
|
"UPDATE": 4,
|
||||||
"UPDATE": 5,
|
"MESSAGE": 5,
|
||||||
"MESSAGE": 6,
|
"FAILURE": 6,
|
||||||
"FAILURE": 7,
|
"ERROR": 7,
|
||||||
"ERROR": 8,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x Event_Type) Enum() *Event_Type {
|
func (x Event_Type) Enum() *Event_Type {
|
||||||
|
|
@ -71,44 +68,41 @@ func (x *Event_Type) UnmarshalJSON(data []byte) error {
|
||||||
type Call_Type int32
|
type Call_Type int32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Call_REGISTER Call_Type = 1
|
Call_SUBSCRIBE Call_Type = 1
|
||||||
Call_REREGISTER Call_Type = 2
|
Call_TEARDOWN Call_Type = 2
|
||||||
Call_UNREGISTER Call_Type = 3
|
Call_ACCEPT Call_Type = 3
|
||||||
Call_REQUEST Call_Type = 4
|
Call_DECLINE Call_Type = 4
|
||||||
Call_DECLINE Call_Type = 5
|
Call_REVIVE Call_Type = 5
|
||||||
Call_REVIVE Call_Type = 6
|
Call_KILL Call_Type = 6
|
||||||
Call_LAUNCH Call_Type = 7
|
Call_SHUTDOWN Call_Type = 7
|
||||||
Call_KILL Call_Type = 8
|
Call_ACKNOWLEDGE Call_Type = 8
|
||||||
Call_ACKNOWLEDGE Call_Type = 9
|
Call_RECONCILE Call_Type = 9
|
||||||
Call_RECONCILE Call_Type = 10
|
Call_MESSAGE Call_Type = 10
|
||||||
Call_MESSAGE Call_Type = 11
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var Call_Type_name = map[int32]string{
|
var Call_Type_name = map[int32]string{
|
||||||
1: "REGISTER",
|
1: "SUBSCRIBE",
|
||||||
2: "REREGISTER",
|
2: "TEARDOWN",
|
||||||
3: "UNREGISTER",
|
3: "ACCEPT",
|
||||||
4: "REQUEST",
|
4: "DECLINE",
|
||||||
5: "DECLINE",
|
5: "REVIVE",
|
||||||
6: "REVIVE",
|
6: "KILL",
|
||||||
7: "LAUNCH",
|
7: "SHUTDOWN",
|
||||||
8: "KILL",
|
8: "ACKNOWLEDGE",
|
||||||
9: "ACKNOWLEDGE",
|
9: "RECONCILE",
|
||||||
10: "RECONCILE",
|
10: "MESSAGE",
|
||||||
11: "MESSAGE",
|
|
||||||
}
|
}
|
||||||
var Call_Type_value = map[string]int32{
|
var Call_Type_value = map[string]int32{
|
||||||
"REGISTER": 1,
|
"SUBSCRIBE": 1,
|
||||||
"REREGISTER": 2,
|
"TEARDOWN": 2,
|
||||||
"UNREGISTER": 3,
|
"ACCEPT": 3,
|
||||||
"REQUEST": 4,
|
"DECLINE": 4,
|
||||||
"DECLINE": 5,
|
"REVIVE": 5,
|
||||||
"REVIVE": 6,
|
"KILL": 6,
|
||||||
"LAUNCH": 7,
|
"SHUTDOWN": 7,
|
||||||
"KILL": 8,
|
"ACKNOWLEDGE": 8,
|
||||||
"ACKNOWLEDGE": 9,
|
"RECONCILE": 9,
|
||||||
"RECONCILE": 10,
|
"MESSAGE": 10,
|
||||||
"MESSAGE": 11,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x Call_Type) Enum() *Call_Type {
|
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"
|
// 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 Event struct {
|
||||||
// Type of the event, indicates which optional field below should be
|
// Type of the event, indicates which optional field below should be
|
||||||
// present if that type has a nested message definition.
|
// 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"`
|
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"`
|
Subscribed *Event_Subscribed `protobuf:"bytes,2,opt,name=subscribed" json:"subscribed,omitempty"`
|
||||||
Reregistered *Event_Reregistered `protobuf:"bytes,3,opt,name=reregistered" json:"reregistered,omitempty"`
|
Offers *Event_Offers `protobuf:"bytes,3,opt,name=offers" json:"offers,omitempty"`
|
||||||
Offers *Event_Offers `protobuf:"bytes,4,opt,name=offers" json:"offers,omitempty"`
|
Rescind *Event_Rescind `protobuf:"bytes,4,opt,name=rescind" json:"rescind,omitempty"`
|
||||||
Rescind *Event_Rescind `protobuf:"bytes,5,opt,name=rescind" json:"rescind,omitempty"`
|
Update *Event_Update `protobuf:"bytes,5,opt,name=update" json:"update,omitempty"`
|
||||||
Update *Event_Update `protobuf:"bytes,6,opt,name=update" json:"update,omitempty"`
|
Message *Event_Message `protobuf:"bytes,6,opt,name=message" json:"message,omitempty"`
|
||||||
Message *Event_Message `protobuf:"bytes,7,opt,name=message" json:"message,omitempty"`
|
Failure *Event_Failure `protobuf:"bytes,7,opt,name=failure" json:"failure,omitempty"`
|
||||||
Failure *Event_Failure `protobuf:"bytes,8,opt,name=failure" json:"failure,omitempty"`
|
Error *Event_Error `protobuf:"bytes,8,opt,name=error" json:"error,omitempty"`
|
||||||
Error *Event_Error `protobuf:"bytes,9,opt,name=error" json:"error,omitempty"`
|
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -156,19 +150,12 @@ func (m *Event) GetType() Event_Type {
|
||||||
if m != nil && m.Type != nil {
|
if m != nil && m.Type != nil {
|
||||||
return *m.Type
|
return *m.Type
|
||||||
}
|
}
|
||||||
return Event_REGISTERED
|
return Event_SUBSCRIBED
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Event) GetRegistered() *Event_Registered {
|
func (m *Event) GetSubscribed() *Event_Subscribed {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
return m.Registered
|
return m.Subscribed
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Event) GetReregistered() *Event_Reregistered {
|
|
||||||
if m != nil {
|
|
||||||
return m.Reregistered
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -215,54 +202,27 @@ func (m *Event) GetError() *Event_Error {
|
||||||
return nil
|
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"`
|
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:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Event_Registered) Reset() { *m = Event_Registered{} }
|
func (m *Event_Subscribed) Reset() { *m = Event_Subscribed{} }
|
||||||
func (m *Event_Registered) String() string { return proto.CompactTextString(m) }
|
func (m *Event_Subscribed) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Event_Registered) ProtoMessage() {}
|
func (*Event_Subscribed) ProtoMessage() {}
|
||||||
|
|
||||||
func (m *Event_Registered) GetFrameworkId() *FrameworkID {
|
func (m *Event_Subscribed) GetFrameworkId() *FrameworkID {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
return m.FrameworkId
|
return m.FrameworkId
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Event_Registered) GetMasterInfo() *MasterInfo {
|
// Received whenever there are new resources that are offered to the
|
||||||
if m != nil {
|
// scheduler. Each offer corresponds to a set of resources on a
|
||||||
return m.MasterInfo
|
// slave. Until the scheduler accepts or declines an offer the
|
||||||
}
|
// resources are considered allocated to the scheduler.
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
type Event_Offers struct {
|
type Event_Offers struct {
|
||||||
Offers []*Offer `protobuf:"bytes,1,rep,name=offers" json:"offers,omitempty"`
|
Offers []*Offer `protobuf:"bytes,1,rep,name=offers" json:"offers,omitempty"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
|
|
@ -279,6 +239,10 @@ func (m *Event_Offers) GetOffers() []*Offer {
|
||||||
return nil
|
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 {
|
type Event_Rescind struct {
|
||||||
OfferId *OfferID `protobuf:"bytes,1,req,name=offer_id" json:"offer_id,omitempty"`
|
OfferId *OfferID `protobuf:"bytes,1,req,name=offer_id" json:"offer_id,omitempty"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
|
|
@ -295,9 +259,17 @@ func (m *Event_Rescind) GetOfferId() *OfferID {
|
||||||
return nil
|
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 {
|
type Event_Update struct {
|
||||||
Uuid []byte `protobuf:"bytes,1,req,name=uuid" json:"uuid,omitempty"`
|
Status *TaskStatus `protobuf:"bytes,1,req,name=status" json:"status,omitempty"`
|
||||||
Status *TaskStatus `protobuf:"bytes,2,req,name=status" json:"status,omitempty"`
|
|
||||||
XXX_unrecognized []byte `json:"-"`
|
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 (m *Event_Update) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Event_Update) ProtoMessage() {}
|
func (*Event_Update) ProtoMessage() {}
|
||||||
|
|
||||||
func (m *Event_Update) GetUuid() []byte {
|
|
||||||
if m != nil {
|
|
||||||
return m.Uuid
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Event_Update) GetStatus() *TaskStatus {
|
func (m *Event_Update) GetStatus() *TaskStatus {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
return m.Status
|
return m.Status
|
||||||
|
|
@ -319,6 +284,11 @@ func (m *Event_Update) GetStatus() *TaskStatus {
|
||||||
return nil
|
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 {
|
type Event_Message struct {
|
||||||
SlaveId *SlaveID `protobuf:"bytes,1,req,name=slave_id" json:"slave_id,omitempty"`
|
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"`
|
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
|
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 {
|
type Event_Failure struct {
|
||||||
SlaveId *SlaveID `protobuf:"bytes,1,opt,name=slave_id" json:"slave_id,omitempty"`
|
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
|
// 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
|
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 {
|
type Event_Error struct {
|
||||||
Message *string `protobuf:"bytes,1,req,name=message" json:"message,omitempty"`
|
Message *string `protobuf:"bytes,1,req,name=message" json:"message,omitempty"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
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
|
// Like Event, a Call is described using the standard protocol buffer
|
||||||
// "union" trick (see above).
|
// "union" trick (see above).
|
||||||
type Call struct {
|
type Call struct {
|
||||||
// Identifies who generated this call. Always necessary, but the
|
// Identifies who generated this call. Master assigns a framework id
|
||||||
// only thing that needs to be set for certain calls, e.g.,
|
// when a new scheduler subscribes for the first time. Once assigned,
|
||||||
// REGISTER, REREGISTER, and UNREGISTER.
|
// the scheduler must set the 'framework_id' here and within its
|
||||||
FrameworkInfo *FrameworkInfo `protobuf:"bytes,1,req,name=framework_info" json:"framework_info,omitempty"`
|
// 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
|
// Type of the call, indicates which optional field below should be
|
||||||
// present if that type has a nested message definition.
|
// 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"`
|
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"`
|
Subscribe *Call_Subscribe `protobuf:"bytes,3,opt,name=subscribe" json:"subscribe,omitempty"`
|
||||||
Decline *Call_Decline `protobuf:"bytes,4,opt,name=decline" json:"decline,omitempty"`
|
Accept *Call_Accept `protobuf:"bytes,4,opt,name=accept" json:"accept,omitempty"`
|
||||||
Launch *Call_Launch `protobuf:"bytes,5,opt,name=launch" json:"launch,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"`
|
Kill *Call_Kill `protobuf:"bytes,6,opt,name=kill" json:"kill,omitempty"`
|
||||||
Acknowledge *Call_Acknowledge `protobuf:"bytes,7,opt,name=acknowledge" json:"acknowledge,omitempty"`
|
Shutdown *Call_Shutdown `protobuf:"bytes,7,opt,name=shutdown" json:"shutdown,omitempty"`
|
||||||
Reconcile *Call_Reconcile `protobuf:"bytes,8,opt,name=reconcile" json:"reconcile,omitempty"`
|
Acknowledge *Call_Acknowledge `protobuf:"bytes,8,opt,name=acknowledge" json:"acknowledge,omitempty"`
|
||||||
Message *Call_Message `protobuf:"bytes,9,opt,name=message" json:"message,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:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -429,9 +420,9 @@ func (m *Call) Reset() { *m = Call{} }
|
||||||
func (m *Call) String() string { return proto.CompactTextString(m) }
|
func (m *Call) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Call) ProtoMessage() {}
|
func (*Call) ProtoMessage() {}
|
||||||
|
|
||||||
func (m *Call) GetFrameworkInfo() *FrameworkInfo {
|
func (m *Call) GetFrameworkId() *FrameworkID {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
return m.FrameworkInfo
|
return m.FrameworkId
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -440,12 +431,19 @@ func (m *Call) GetType() Call_Type {
|
||||||
if m != nil && m.Type != nil {
|
if m != nil && m.Type != nil {
|
||||||
return *m.Type
|
return *m.Type
|
||||||
}
|
}
|
||||||
return Call_REGISTER
|
return Call_SUBSCRIBE
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Call) GetRequest() *Call_Request {
|
func (m *Call) GetSubscribe() *Call_Subscribe {
|
||||||
if m != nil {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -457,16 +455,16 @@ func (m *Call) GetDecline() *Call_Decline {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Call) GetLaunch() *Call_Launch {
|
func (m *Call) GetKill() *Call_Kill {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
return m.Launch
|
return m.Kill
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Call) GetKill() *Call_Kill {
|
func (m *Call) GetShutdown() *Call_Shutdown {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
return m.Kill
|
return m.Shutdown
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -492,22 +490,105 @@ func (m *Call) GetMessage() *Call_Message {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type Call_Request struct {
|
// Subscribes the scheduler with the master to receive events. A
|
||||||
Requests []*Request `protobuf:"bytes,1,rep,name=requests" json:"requests,omitempty"`
|
// 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:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Call_Request) Reset() { *m = Call_Request{} }
|
func (m *Call_Subscribe) Reset() { *m = Call_Subscribe{} }
|
||||||
func (m *Call_Request) String() string { return proto.CompactTextString(m) }
|
func (m *Call_Subscribe) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Call_Request) ProtoMessage() {}
|
func (*Call_Subscribe) ProtoMessage() {}
|
||||||
|
|
||||||
func (m *Call_Request) GetRequests() []*Request {
|
func (m *Call_Subscribe) GetFrameworkInfo() *FrameworkInfo {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
return m.Requests
|
return m.FrameworkInfo
|
||||||
}
|
}
|
||||||
return nil
|
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 {
|
type Call_Decline struct {
|
||||||
OfferIds []*OfferID `protobuf:"bytes,1,rep,name=offer_ids" json:"offer_ids,omitempty"`
|
OfferIds []*OfferID `protobuf:"bytes,1,rep,name=offer_ids" json:"offer_ids,omitempty"`
|
||||||
Filters *Filters `protobuf:"bytes,2,opt,name=filters" json:"filters,omitempty"`
|
Filters *Filters `protobuf:"bytes,2,opt,name=filters" json:"filters,omitempty"`
|
||||||
|
|
@ -532,40 +613,16 @@ func (m *Call_Decline) GetFilters() *Filters {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type Call_Launch struct {
|
// Kills a specific task. If the scheduler has a custom executor,
|
||||||
TaskInfos []*TaskInfo `protobuf:"bytes,1,rep,name=task_infos" json:"task_infos,omitempty"`
|
// the kill is forwarded to the executor and it is up to the
|
||||||
OfferIds []*OfferID `protobuf:"bytes,2,rep,name=offer_ids" json:"offer_ids,omitempty"`
|
// executor to kill the task and send a TASK_KILLED (or TASK_FAILED)
|
||||||
Filters *Filters `protobuf:"bytes,3,opt,name=filters" json:"filters,omitempty"`
|
// update. Note that Mesos releases the resources for a task once it
|
||||||
XXX_unrecognized []byte `json:"-"`
|
// 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.
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
type Call_Kill struct {
|
type Call_Kill struct {
|
||||||
TaskId *TaskID `protobuf:"bytes,1,req,name=task_id" json:"task_id,omitempty"`
|
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:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -580,6 +637,49 @@ func (m *Call_Kill) GetTaskId() *TaskID {
|
||||||
return nil
|
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 {
|
type Call_Acknowledge struct {
|
||||||
SlaveId *SlaveID `protobuf:"bytes,1,req,name=slave_id" json:"slave_id,omitempty"`
|
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"`
|
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
|
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
|
// This causes the master to send back the latest task status for
|
||||||
// each task in 'statuses', if possible. Tasks that are no longer
|
// each task in 'tasks', if possible. Tasks that are no longer known
|
||||||
// known will result in a TASK_LOST update. If statuses is empty,
|
// will result in a TASK_LOST update. If 'statuses' is empty, then
|
||||||
// then the master will send the latest status for each task
|
// the master will send the latest status for each task currently
|
||||||
// currently known.
|
// known.
|
||||||
// TODO(bmahler): Add a guiding document for reconciliation or
|
|
||||||
// document reconciliation in-depth here.
|
|
||||||
type Call_Reconcile struct {
|
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:"-"`
|
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 (m *Call_Reconcile) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Call_Reconcile) ProtoMessage() {}
|
func (*Call_Reconcile) ProtoMessage() {}
|
||||||
|
|
||||||
func (m *Call_Reconcile) GetStatuses() []*TaskStatus {
|
func (m *Call_Reconcile) GetTasks() []*Call_Reconcile_Task {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
return m.Statuses
|
return m.Tasks
|
||||||
}
|
}
|
||||||
return nil
|
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 {
|
type Call_Message struct {
|
||||||
SlaveId *SlaveID `protobuf:"bytes,1,req,name=slave_id" json:"slave_id,omitempty"`
|
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"`
|
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"
|
* 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 {
|
message Event {
|
||||||
// Possible event types, followed by message definitions if
|
// Possible event types, followed by message definitions if
|
||||||
// applicable.
|
// applicable.
|
||||||
enum Type {
|
enum Type {
|
||||||
REGISTERED = 1;
|
SUBSCRIBED = 1; // See 'Subscribed' below.
|
||||||
REREGISTERED = 2;
|
OFFERS = 2; // See 'Offers' below.
|
||||||
OFFERS = 3;
|
RESCIND = 3; // See 'Rescind' below.
|
||||||
RESCIND = 4;
|
UPDATE = 4; // See 'Update' below.
|
||||||
UPDATE = 5;
|
MESSAGE = 5; // See 'Message' below.
|
||||||
MESSAGE = 6;
|
FAILURE = 6; // See 'Failure' below.
|
||||||
FAILURE = 7;
|
ERROR = 7; // See 'Error' below.
|
||||||
ERROR = 8;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message Registered {
|
// First event received when the scheduler subscribes.
|
||||||
|
message Subscribed {
|
||||||
required FrameworkID framework_id = 1;
|
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 {
|
message Offers {
|
||||||
repeated Offer offers = 1;
|
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 {
|
message Rescind {
|
||||||
required OfferID offer_id = 1;
|
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 {
|
message Update {
|
||||||
required bytes uuid = 1; // TODO(benh): Replace with UpdateID.
|
required TaskStatus status = 1;
|
||||||
required TaskStatus status = 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 {
|
message Message {
|
||||||
required SlaveID slave_id = 1;
|
required SlaveID slave_id = 1;
|
||||||
required ExecutorID executor_id = 2;
|
required ExecutorID executor_id = 2;
|
||||||
required bytes data = 3;
|
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 {
|
message Failure {
|
||||||
optional SlaveID slave_id = 1;
|
optional SlaveID slave_id = 1;
|
||||||
|
|
||||||
|
|
@ -81,29 +107,33 @@ message Event {
|
||||||
optional int32 status = 3;
|
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 {
|
message Error {
|
||||||
required string message = 1;
|
required string message = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(benh): Add a 'from' or 'sender'.
|
|
||||||
|
|
||||||
// Type of the event, indicates which optional field below should be
|
// Type of the event, indicates which optional field below should be
|
||||||
// present if that type has a nested message definition.
|
// present if that type has a nested message definition.
|
||||||
required Type type = 1;
|
required Type type = 1;
|
||||||
|
|
||||||
optional Registered registered = 2;
|
optional Subscribed subscribed = 2;
|
||||||
optional Reregistered reregistered = 3;
|
optional Offers offers = 3;
|
||||||
optional Offers offers = 4;
|
optional Rescind rescind = 4;
|
||||||
optional Rescind rescind = 5;
|
optional Update update = 5;
|
||||||
optional Update update = 6;
|
optional Message message = 6;
|
||||||
optional Message message = 7;
|
optional Failure failure = 7;
|
||||||
optional Failure failure = 8;
|
optional Error error = 8;
|
||||||
optional Error error = 9;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Low-level scheduler call API.
|
* Scheduler call API.
|
||||||
*
|
*
|
||||||
* Like Event, a Call is described using the standard protocol buffer
|
* Like Event, a Call is described using the standard protocol buffer
|
||||||
* "union" trick (see above).
|
* "union" trick (see above).
|
||||||
|
|
@ -112,20 +142,19 @@ message Call {
|
||||||
// Possible call types, followed by message definitions if
|
// Possible call types, followed by message definitions if
|
||||||
// applicable.
|
// applicable.
|
||||||
enum Type {
|
enum Type {
|
||||||
REGISTER = 1;
|
SUBSCRIBE = 1; // See 'Subscribe' below.
|
||||||
REREGISTER = 2;
|
TEARDOWN = 2; // Shuts down all tasks/executors and removes framework.
|
||||||
UNREGISTER = 3;
|
ACCEPT = 3; // See 'Accept' below.
|
||||||
REQUEST = 4;
|
DECLINE = 4; // See 'Decline' below.
|
||||||
DECLINE = 5;
|
REVIVE = 5; // Removes any previous filters set via ACCEPT or DECLINE.
|
||||||
REVIVE = 6;
|
KILL = 6; // See 'Kill' below.
|
||||||
LAUNCH = 7;
|
SHUTDOWN = 7; // See 'Shutdown' below.
|
||||||
KILL = 8;
|
ACKNOWLEDGE = 8; // See 'Acknowledge' below.
|
||||||
ACKNOWLEDGE = 9;
|
RECONCILE = 9; // See 'Reconcile' below.
|
||||||
RECONCILE = 10;
|
MESSAGE = 10; // See 'Message' below.
|
||||||
MESSAGE = 11;
|
|
||||||
|
|
||||||
// TODO(benh): Consider adding an 'ACTIVATE' and 'DEACTIVATE' for
|
// 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.
|
// being generated and other events from being sent by the master.
|
||||||
// Note that this functionality existed originally to support
|
// Note that this functionality existed originally to support
|
||||||
// SchedulerDriver::abort which was only necessary to handle
|
// 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.
|
// something that is not an issue with the Event/Call API.
|
||||||
}
|
}
|
||||||
|
|
||||||
message Request {
|
// Subscribes the scheduler with the master to receive events. A
|
||||||
repeated mesosproto.Request requests = 1;
|
// 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 {
|
message Decline {
|
||||||
repeated OfferID offer_ids = 1;
|
repeated OfferID offer_ids = 1;
|
||||||
optional Filters filters = 2;
|
optional Filters filters = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Launch {
|
// Kills a specific task. If the scheduler has a custom executor,
|
||||||
repeated TaskInfo task_infos = 1;
|
// the kill is forwarded to the executor and it is up to the
|
||||||
repeated OfferID offer_ids = 2;
|
// executor to kill the task and send a TASK_KILLED (or TASK_FAILED)
|
||||||
optional Filters filters = 3;
|
// 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 {
|
message Kill {
|
||||||
required TaskID task_id = 1;
|
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 {
|
message Acknowledge {
|
||||||
required SlaveID slave_id = 1;
|
required SlaveID slave_id = 1;
|
||||||
required TaskID task_id = 2;
|
required TaskID task_id = 2;
|
||||||
required bytes uuid = 3;
|
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
|
// This causes the master to send back the latest task status for
|
||||||
// each task in 'statuses', if possible. Tasks that are no longer
|
// each task in 'tasks', if possible. Tasks that are no longer known
|
||||||
// known will result in a TASK_LOST update. If statuses is empty,
|
// will result in a TASK_LOST update. If 'statuses' is empty, then
|
||||||
// then the master will send the latest status for each task
|
// the master will send the latest status for each task currently
|
||||||
// currently known.
|
// known.
|
||||||
// TODO(bmahler): Add a guiding document for reconciliation or
|
|
||||||
// document reconciliation in-depth here.
|
|
||||||
message Reconcile {
|
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 {
|
message Message {
|
||||||
required SlaveID slave_id = 1;
|
required SlaveID slave_id = 1;
|
||||||
required ExecutorID executor_id = 2;
|
required ExecutorID executor_id = 2;
|
||||||
required bytes data = 3;
|
required bytes data = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Identifies who generated this call. Always necessary, but the
|
// Identifies who generated this call. Master assigns a framework id
|
||||||
// only thing that needs to be set for certain calls, e.g.,
|
// when a new scheduler subscribes for the first time. Once assigned,
|
||||||
// REGISTER, REREGISTER, and UNREGISTER.
|
// the scheduler must set the 'framework_id' here and within its
|
||||||
required FrameworkInfo framework_info = 1;
|
// 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
|
// Type of the call, indicates which optional field below should be
|
||||||
// present if that type has a nested message definition.
|
// present if that type has a nested message definition.
|
||||||
required Type type = 2;
|
required Type type = 2;
|
||||||
|
|
||||||
optional Request request = 3;
|
optional Subscribe subscribe = 3;
|
||||||
optional Decline decline = 4;
|
optional Accept accept = 4;
|
||||||
optional Launch launch = 5;
|
optional Decline decline = 5;
|
||||||
optional Kill kill = 6;
|
optional Kill kill = 6;
|
||||||
optional Acknowledge acknowledge = 7;
|
optional Shutdown shutdown = 7;
|
||||||
optional Reconcile reconcile = 8;
|
optional Acknowledge acknowledge = 8;
|
||||||
optional Message message = 9;
|
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)
|
serverAddr := serverHost + ":" + strconv.Itoa(serverPort)
|
||||||
|
|
||||||
// override the upid.Host with this listener IP
|
// 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
|
// setup receiver (server) process
|
||||||
uPid, err := upid.Parse(fmt.Sprintf("%s@%s", serverId, serverAddr))
|
uPid, err := upid.Parse(fmt.Sprintf("%s@%s", serverId, serverAddr))
|
||||||
|
|
@ -308,7 +308,7 @@ func TestEmptyHostPortUPid(t *testing.T) {
|
||||||
uPid.Port = ""
|
uPid.Port = ""
|
||||||
|
|
||||||
// override the upid.Host with this listener IP
|
// 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)
|
receiver := NewHTTPTransporter(uPid, addr)
|
||||||
|
|
||||||
|
|
@ -316,7 +316,7 @@ func TestEmptyHostPortUPid(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// This should be the host that overrides as uPid.Host is empty
|
// 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)
|
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
|
// ForHostname creates a new default messenger (HTTP), using UPIDBindingAddress to
|
||||||
// determine the binding-address used for both the UPID.Host and Transport binding address.
|
// 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{
|
upid := &upid.UPID{
|
||||||
ID: proc.Label(),
|
ID: proc.Label(),
|
||||||
Port: strconv.Itoa(int(port)),
|
Port: strconv.Itoa(int(port)),
|
||||||
|
|
@ -87,7 +87,21 @@ func ForHostname(proc *process.Process, hostname string, bindingAddress net.IP,
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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
|
upid.Host = host
|
||||||
|
}
|
||||||
|
|
||||||
return NewHttpWithBindingAddress(upid, bindingAddress), nil
|
return NewHttpWithBindingAddress(upid, bindingAddress), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"code.google.com/p/go-uuid/uuid"
|
|
||||||
"github.com/gogo/protobuf/proto"
|
"github.com/gogo/protobuf/proto"
|
||||||
log "github.com/golang/glog"
|
log "github.com/golang/glog"
|
||||||
"github.com/mesos/mesos-go/auth"
|
"github.com/mesos/mesos-go/auth"
|
||||||
|
|
@ -38,6 +37,7 @@ import (
|
||||||
"github.com/mesos/mesos-go/mesosutil/process"
|
"github.com/mesos/mesos-go/mesosutil/process"
|
||||||
"github.com/mesos/mesos-go/messenger"
|
"github.com/mesos/mesos-go/messenger"
|
||||||
"github.com/mesos/mesos-go/upid"
|
"github.com/mesos/mesos-go/upid"
|
||||||
|
"github.com/pborman/uuid"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -86,6 +86,7 @@ type DriverConfig struct {
|
||||||
HostnameOverride string // optional
|
HostnameOverride string // optional
|
||||||
BindingAddress net.IP // optional
|
BindingAddress net.IP // optional
|
||||||
BindingPort uint16 // optional
|
BindingPort uint16 // optional
|
||||||
|
PublishedAddress net.IP // optional
|
||||||
NewMessenger func() (messenger.Messenger, error) // optional
|
NewMessenger func() (messenger.Messenger, error) // optional
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,7 +197,7 @@ func NewMesosSchedulerDriver(config DriverConfig) (initializedDriver *MesosSched
|
||||||
if newMessenger == nil {
|
if newMessenger == nil {
|
||||||
newMessenger = func() (messenger.Messenger, error) {
|
newMessenger = func() (messenger.Messenger, error) {
|
||||||
process := process.New("scheduler")
|
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.Name = &name
|
||||||
task.TaskId = &mesosproto.TaskID{Value: &id}
|
task.TaskId = &mesosproto.TaskID{Value: &id}
|
||||||
|
task.Labels = &mesosproto.Labels{Labels: []*mesosproto.Label{{Key: proto.String("SWARM_CONTAINER_NAME"), Value: &name}}}
|
||||||
return task, nil
|
return task, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue