Пример #1
0
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()
}