func (d *deepCopyGen) genMsgDeepCopy(m *generator.Descriptor) { ccTypeName := generator.CamelCaseSlice(m.TypeName()) // Generate backwards compatible, type-safe Copy() function. d.P("func (m *", ccTypeName, ") Copy() *", ccTypeName, "{") d.In() d.P("if m == nil {") d.In() d.P("return nil") d.Out() d.P("}") d.P("o := &", ccTypeName, "{}") d.P("o.CopyFrom(m)") d.P("return o") d.Out() d.P("}") d.P() if len(m.Field) == 0 { d.P("func (m *", ccTypeName, ") CopyFrom(src interface{})", " {}") return } d.P("func (m *", ccTypeName, ") CopyFrom(src interface{})", " {") d.P() d.P("o := src.(*", ccTypeName, ")") // shallow copy handles all scalars d.P("*m = *o") oneofByIndex := [][]*descriptor.FieldDescriptorProto{} for _, f := range m.Field { fName := generator.CamelCase(*f.Name) if gogoproto.IsCustomName(f) { fName = gogoproto.GetCustomName(f) } // Handle oneof type, we defer them to a loop below if f.OneofIndex != nil { if len(oneofByIndex) <= int(*f.OneofIndex) { oneofByIndex = append(oneofByIndex, []*descriptor.FieldDescriptorProto{}) } oneofByIndex[*f.OneofIndex] = append(oneofByIndex[*f.OneofIndex], f) continue } // Handle all kinds of message type if f.IsMessage() { // Handle map type if d.genMap(m, f) { continue } // Handle any message which is not repeated or part of oneof if !f.IsRepeated() && f.OneofIndex == nil { if !gogoproto.IsNullable(f) { d.genCopyFunc("&m."+fName, "&o."+fName) } else { d.P("if o.", fName, " != nil {") d.In() // allocate dst object d.P("m.", fName, " = &", d.TypeName(d.ObjectNamed(f.GetTypeName())), "{}") // copy into the allocated struct d.genCopyFunc("m."+fName, "o."+fName) d.Out() d.P("}") } continue } } // Handle repeated field if f.IsRepeated() { d.genRepeated(m, f) continue } // skip: field was a scalar handled by shallow copy! } for i, oo := range m.GetOneofDecl() { d.genOneOf(m, oo, oneofByIndex[i]) } d.P("}") d.P() }