Skip to content

Commit

Permalink
merge master
Browse files Browse the repository at this point in the history
  • Loading branch information
awalterschulze committed May 15, 2015
2 parents 3e5d6f8 + b9e369e commit 23f7c73
Show file tree
Hide file tree
Showing 28 changed files with 2,514 additions and 4 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ regenerate:
make -C proto generate-test-pbs
make -C test/importdedup regenerate
make -C test/custombytesnonstruct regenerate
make -C test/required regenerate
make gofmt

tests:
Expand Down Expand Up @@ -104,6 +105,7 @@ tests:
go test -v ./test/issue42order
go test -v ./test/importdedup
go test -v ./test/custombytesnonstruct
go test -v ./test/required
make vet

vet:
Expand Down
11 changes: 9 additions & 2 deletions plugin/marshalto/marshalto.go
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,14 @@ func (p *marshalto) Generate(file *generator.FileDescriptor) {
fieldname := p.GetFieldName(message, field)
nullable := gogoproto.IsNullable(field)
repeated := field.IsRepeated()
if repeated {
required := field.IsRequired()
if required && nullable {
p.P(`if m.`, fieldname, `== nil {`)
p.In()
p.P(`return 0, `, protoPkg.Use(), `.NewRequiredNotSetError("`, field.GetName(), `")`)
p.Out()
p.P(`} else {`)
} else if repeated {
p.P(`if len(m.`, fieldname, `) > 0 {`)
p.In()
} else if (!proto3 && nullable) || (*field.Type == descriptor.FieldDescriptorProto_TYPE_BYTES && !gogoproto.IsCustomType(field)) {
Expand Down Expand Up @@ -1107,7 +1114,7 @@ func (p *marshalto) Generate(file *generator.FileDescriptor) {
default:
panic("not implemented")
}
if (!proto3 && nullable) || repeated || (*field.Type == descriptor.FieldDescriptorProto_TYPE_BYTES && !gogoproto.IsCustomType(field)) {
if (required && nullable) || (!proto3 && nullable) || repeated || (*field.Type == descriptor.FieldDescriptorProto_TYPE_BYTES && !gogoproto.IsCustomType(field)) {
p.Out()
p.P(`}`)
}
Expand Down
42 changes: 40 additions & 2 deletions plugin/unmarshal/unmarshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -813,8 +813,22 @@ func (p *unmarshal) Generate(file *generator.FileDescriptor) {
}
p.atleastOne = true

// build a map required field_id -> bitmask offset
rfMap := make(map[int32]uint)
rfNextId := uint(0)
for _, field := range message.Field {
if field.IsRequired() {
rfMap[field.GetNumber()] = rfNextId
rfNextId++
}
}
rfCount := len(rfMap)

p.P(`func (m *`, ccTypeName, `) Unmarshal(data []byte) error {`)
p.In()
if rfCount > 0 {
p.P(`var hasFields [`, strconv.Itoa(1+(rfCount-1)/64), `]uint64`)
}
p.P(`l := len(data)`)
p.P(`index := 0`)
p.P(`for index < l {`)
Expand Down Expand Up @@ -868,6 +882,14 @@ func (p *unmarshal) Generate(file *generator.FileDescriptor) {
p.P(`}`)
p.field(file.FileDescriptorProto, field, fieldname, proto3)
}

if field.IsRequired() {
fieldBit, ok := rfMap[field.GetNumber()]
if !ok {
panic("field is required, but no bit registered")
}
p.P(`hasFields[`, strconv.Itoa(int(fieldBit/64)), `] |= uint64(`, fmt.Sprintf("0x%08x", 1<<(fieldBit%64)), `)`)
}
}
p.Out()
p.P(`default:`)
Expand Down Expand Up @@ -955,15 +977,31 @@ func (p *unmarshal) Generate(file *generator.FileDescriptor) {
p.P(`}`)
p.Out()
p.P(`}`)

for _, field := range message.Field {
if !field.IsRequired() {
continue
}

fieldBit, ok := rfMap[field.GetNumber()]
if !ok {
panic("field is required, but no bit registered")
}

p.P(`if hasFields[`, strconv.Itoa(int(fieldBit/64)), `] & uint64(`, fmt.Sprintf("0x%08x", 1<<(fieldBit%64)), `) == 0 {`)
p.In()
p.P(`return `, protoPkg.Use(), `.NewRequiredNotSetError("`, field.GetName(), `")`)
p.Out()
p.P(`}`)
}
p.P()
p.P(`return nil`)
p.Out()
p.P(`}`)
}

if !p.atleastOne {
return
}

}

func init() {
Expand Down
4 changes: 4 additions & 0 deletions proto/encode_gogo.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ import (
"reflect"
)

func NewRequiredNotSetError(field string) *RequiredNotSetError {
return &RequiredNotSetError{field}
}

type Sizer interface {
Size() int
}
Expand Down
Loading

0 comments on commit 23f7c73

Please sign in to comment.