diff options
author | David Symonds <dsymonds@golang.org> | 2013-01-30 17:08:05 +1100 |
---|---|---|
committer | David Symonds <dsymonds@golang.org> | 2013-01-30 17:08:05 +1100 |
commit | db7a687c2924df3534aea8ec031e79d40f3a8ba0 (patch) | |
tree | 7774c1ab9011866209778ccbe17cf4ea4f0d2af7 | |
parent | 6e8ab8784338b90a5e515346a6193852f33d397b (diff) | |
download | protobuf-db7a687c2924df3534aea8ec031e79d40f3a8ba0.tar.gz |
goprotobuf: Repeated field getters.
R=adg
CC=golang-dev
https://codereview.appspot.com/7225068
-rw-r--r-- | protoc-gen-go/generator/generator.go | 54 | ||||
-rw-r--r-- | protoc-gen-go/testdata/imp.proto | 4 | ||||
-rw-r--r-- | protoc-gen-go/testdata/my_test/test.pb.go | 21 | ||||
-rw-r--r-- | protoc-gen-go/testdata/my_test/test.pb.go.golden | 21 |
4 files changed, 91 insertions, 9 deletions
diff --git a/protoc-gen-go/generator/generator.go b/protoc-gen-go/generator/generator.go index 58d42bf..ddefabe 100644 --- a/protoc-gen-go/generator/generator.go +++ b/protoc-gen-go/generator/generator.go @@ -298,24 +298,60 @@ func (ms *messageSymbol) GenerateAlias(g *Generator, pkg string) { } } for _, get := range ms.getters { + if get.typeName != "" { + g.RecordTypeUse(get.typeName) + } typ := get.typ val := "(*" + remoteSym + ")(this)." + get.name + "()" if get.genType { // typ will be "*pkg.T" (message/group) or "pkg.T" (enum). + // Either of those might have a "[]" prefix if it is repeated. // Drop the package qualifier since we have hoisted the type into this package. + rep := strings.HasPrefix(typ, "[]") + if rep { + typ = typ[2:] + } star := typ[0] == '*' typ = typ[strings.Index(typ, ".")+1:] if star { typ = "*" + typ } + if rep { + // Go does not permit conversion between slice types where both + // element types are named. That means we need to generate a bit + // of code in this situation. + // typ is the element type. + // val is the expression to get the slice from the imported type. + + ctyp := typ // conversion type expression; "Foo" or "(*Foo)" + if star { + ctyp = "(" + typ + ")" + } + + g.P("func (this *", ms.sym, ") ", get.name, "() []", typ, " {") + g.In() + g.P("o := ", val) + g.P("if o == nil {") + g.In() + g.P("return nil") + g.Out() + g.P("}") + g.P("s := make([]", typ, ", len(o))") + g.P("for i, x := range o {") + g.In() + g.P("s[i] = ", ctyp, "(x)") + g.Out() + g.P("}") + g.P("return s") + g.Out() + g.P("}") + continue + } // Convert imported type into the forwarding type. val = "(" + typ + ")(" + val + ")" } g.P("func (this *", ms.sym, ") ", get.name, "() ", typ, " { return ", val, " }") - if get.typeName != "" { - g.RecordTypeUse(get.typeName) - } } } @@ -1011,8 +1047,8 @@ func (g *Generator) generateImports() { } g.P("// Reference proto, json, and math imports to suppress error if they are not otherwise used.") g.P("var _ = ", g.Pkg["proto"], ".Marshal") - g.P("var _ = &json.SyntaxError{}") - g.P("var _ = math.Inf") + g.P("var _ = &", g.Pkg["json"], ".SyntaxError{}") + g.P("var _ = ", g.Pkg["math"], ".Inf") g.P() } @@ -1452,9 +1488,6 @@ func (g *Generator) generateMessage(message *Descriptor) { // Field getters var getters []getterSymbol for _, field := range message.Field { - if isRepeated(field) { - continue - } fname := fieldNames[field] typename, _ := g.GoType(message, field) mname := "Get" + fname @@ -1504,9 +1537,12 @@ func (g *Generator) generateMessage(message *Descriptor) { case descriptor.FieldDescriptorProto_TYPE_GROUP, descriptor.FieldDescriptorProto_TYPE_MESSAGE: typeDefaultIsNil = true } + if isRepeated(field) { + typeDefaultIsNil = true + } if typeDefaultIsNil { // A bytes field with no explicit default needs less generated code, - // as does a message or group field. + // as does a message or group field, or a repeated field. g.P("if this != nil {") g.In() g.P("return this." + fname) diff --git a/protoc-gen-go/testdata/imp.proto b/protoc-gen-go/testdata/imp.proto index 9767a0d..52d34e2 100644 --- a/protoc-gen-go/testdata/imp.proto +++ b/protoc-gen-go/testdata/imp.proto @@ -42,6 +42,10 @@ message ImportedMessage { optional ForeignImportedMessage foreign_msg = 3; // in imp3.proto optional Owner enum_field = 4; + repeated string name = 5; + repeated Owner boss = 6; + repeated ImportedMessage2 memo = 7; + enum Owner { DAVE = 1; MIKE = 2; diff --git a/protoc-gen-go/testdata/my_test/test.pb.go b/protoc-gen-go/testdata/my_test/test.pb.go index 4a465f7..0e3f4c2 100644 --- a/protoc-gen-go/testdata/my_test/test.pb.go +++ b/protoc-gen-go/testdata/my_test/test.pb.go @@ -183,6 +183,13 @@ const Default_Request_Hat HatType = HatType_FEDORA var Default_Request_Deadline float32 = float32(math.Inf(1)) +func (this *Request) GetKey() []int64 { + if this != nil { + return this.Key + } + return nil +} + func (this *Request) GetHue() Request_Color { if this != nil && this.Hue != nil { return *this.Hue @@ -256,6 +263,20 @@ func (this *Reply) ExtensionMap() map[int32]proto.Extension { return this.XXX_extensions } +func (this *Reply) GetFound() []*Reply_Entry { + if this != nil { + return this.Found + } + return nil +} + +func (this *Reply) GetCompactKeys() []int32 { + if this != nil { + return this.CompactKeys + } + return nil +} + type Reply_Entry struct { KeyThatNeeds_1234Camel_CasIng *int64 `protobuf:"varint,1,req,name=key_that_needs_1234camel_CasIng" json:"key_that_needs_1234camel_CasIng,omitempty"` Value *int64 `protobuf:"varint,2,opt,name=value,def=7" json:"value,omitempty"` diff --git a/protoc-gen-go/testdata/my_test/test.pb.go.golden b/protoc-gen-go/testdata/my_test/test.pb.go.golden index 4a465f7..0e3f4c2 100644 --- a/protoc-gen-go/testdata/my_test/test.pb.go.golden +++ b/protoc-gen-go/testdata/my_test/test.pb.go.golden @@ -183,6 +183,13 @@ const Default_Request_Hat HatType = HatType_FEDORA var Default_Request_Deadline float32 = float32(math.Inf(1)) +func (this *Request) GetKey() []int64 { + if this != nil { + return this.Key + } + return nil +} + func (this *Request) GetHue() Request_Color { if this != nil && this.Hue != nil { return *this.Hue @@ -256,6 +263,20 @@ func (this *Reply) ExtensionMap() map[int32]proto.Extension { return this.XXX_extensions } +func (this *Reply) GetFound() []*Reply_Entry { + if this != nil { + return this.Found + } + return nil +} + +func (this *Reply) GetCompactKeys() []int32 { + if this != nil { + return this.CompactKeys + } + return nil +} + type Reply_Entry struct { KeyThatNeeds_1234Camel_CasIng *int64 `protobuf:"varint,1,req,name=key_that_needs_1234camel_CasIng" json:"key_that_needs_1234camel_CasIng,omitempty"` Value *int64 `protobuf:"varint,2,opt,name=value,def=7" json:"value,omitempty"` |