// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package protodesc

import (
	"google.golang.org/protobuf/internal/errors"
	"google.golang.org/protobuf/internal/filedesc"
	"google.golang.org/protobuf/internal/strs"
	"google.golang.org/protobuf/proto"
	"google.golang.org/protobuf/reflect/protoreflect"

	"google.golang.org/protobuf/types/descriptorpb"
)

type descsByName map[protoreflect.FullName]protoreflect.Descriptor

func (r descsByName) initEnumDeclarations(eds []*descriptorpb.EnumDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (es []filedesc.Enum, err error) {
	es = make([]filedesc.Enum, len(eds)) // allocate up-front to ensure stable pointers
	for i, ed := range eds {
		e := &es[i]
		e.L2 = new(filedesc.EnumL2)
		if e.L0, err = r.makeBase(e, parent, ed.GetName(), i, sb); err != nil {
			return nil, err
		}
		if opts := ed.GetOptions(); opts != nil {
			opts = proto.Clone(opts).(*descriptorpb.EnumOptions)
			e.L2.Options = func() protoreflect.ProtoMessage { return opts }
		}
		e.L1.EditionFeatures = mergeEditionFeatures(parent, ed.GetOptions().GetFeatures())
		for _, s := range ed.GetReservedName() {
			e.L2.ReservedNames.List = append(e.L2.ReservedNames.List, protoreflect.Name(s))
		}
		for _, rr := range ed.GetReservedRange() {
			e.L2.ReservedRanges.List = append(e.L2.ReservedRanges.List, [2]protoreflect.EnumNumber{
				protoreflect.EnumNumber(rr.GetStart()),
				protoreflect.EnumNumber(rr.GetEnd()),
			})
		}
		if e.L2.Values.List, err = r.initEnumValuesFromDescriptorProto(ed.GetValue(), e, sb); err != nil {
			return nil, err
		}
	}
	return es, nil
}

func (r descsByName) initEnumValuesFromDescriptorProto(vds []*descriptorpb.EnumValueDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (vs []filedesc.EnumValue, err error) {
	vs = make([]filedesc.EnumValue, len(vds)) // allocate up-front to ensure stable pointers
	for i, vd := range vds {
		v := &vs[i]
		if v.L0, err = r.makeBase(v, parent, vd.GetName(), i, sb); err != nil {
			return nil, err
		}
		if opts := vd.GetOptions(); opts != nil {
			opts = proto.Clone(opts).(*descriptorpb.EnumValueOptions)
			v.L1.Options = func() protoreflect.ProtoMessage { return opts }
		}
		v.L1.Number = protoreflect.EnumNumber(vd.GetNumber())
	}
	return vs, nil
}

func (r descsByName) initMessagesDeclarations(mds []*descriptorpb.DescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (ms []filedesc.Message, err error) {
	ms = make([]filedesc.Message, len(mds)) // allocate up-front to ensure stable pointers
	for i, md := range mds {
		m := &ms[i]
		m.L2 = new(filedesc.MessageL2)
		if m.L0, err = r.makeBase(m, parent, md.GetName(), i, sb); err != nil {
			return nil, err
		}
		m.L1.EditionFeatures = mergeEditionFeatures(parent, md.GetOptions().GetFeatures())
		if opts := md.GetOptions(); opts != nil {
			opts = proto.Clone(opts).(*descriptorpb.MessageOptions)
			m.L2.Options = func() protoreflect.ProtoMessage { return opts }
			m.L1.IsMapEntry = opts.GetMapEntry()
			m.L1.IsMessageSet = opts.GetMessageSetWireFormat()
		}
		for _, s := range md.GetReservedName() {
			m.L2.ReservedNames.List = append(m.L2.ReservedNames.List, protoreflect.Name(s))
		}
		for _, rr := range md.GetReservedRange() {
			m.L2.ReservedRanges.List = append(m.L2.ReservedRanges.List, [2]protoreflect.FieldNumber{
				protoreflect.FieldNumber(rr.GetStart()),
				protoreflect.FieldNumber(rr.GetEnd()),
			})
		}
		for _, xr := range md.GetExtensionRange() {
			m.L2.ExtensionRanges.List = append(m.L2.ExtensionRanges.List, [2]protoreflect.FieldNumber{
				protoreflect.FieldNumber(xr.GetStart()),
				protoreflect.FieldNumber(xr.GetEnd()),
			})
			var optsFunc func() protoreflect.ProtoMessage
			if opts := xr.GetOptions(); opts != nil {
				opts = proto.Clone(opts).(*descriptorpb.ExtensionRangeOptions)
				optsFunc = func() protoreflect.ProtoMessage { return opts }
			}
			m.L2.ExtensionRangeOptions = append(m.L2.ExtensionRangeOptions, optsFunc)
		}
		if m.L2.Fields.List, err = r.initFieldsFromDescriptorProto(md.GetField(), m, sb); err != nil {
			return nil, err
		}
		if m.L2.Oneofs.List, err = r.initOneofsFromDescriptorProto(md.GetOneofDecl(), m, sb); err != nil {
			return nil, err
		}
		if m.L1.Enums.List, err = r.initEnumDeclarations(md.GetEnumType(), m, sb); err != nil {
			return nil, err
		}
		if m.L1.Messages.List, err = r.initMessagesDeclarations(md.GetNestedType(), m, sb); err != nil {
			return nil, err
		}
		if m.L1.Extensions.List, err = r.initExtensionDeclarations(md.GetExtension(), m, sb); err != nil {
			return nil, err
		}
	}
	return ms, nil
}

// canBePacked returns whether the field can use packed encoding:
// https://protobuf.dev/programming-guides/encoding/#packed
func canBePacked(fd *descriptorpb.FieldDescriptorProto) bool {
	if fd.GetLabel() != descriptorpb.FieldDescriptorProto_LABEL_REPEATED {
		return false // not a repeated field
	}

	switch protoreflect.Kind(fd.GetType()) {
	case protoreflect.MessageKind, protoreflect.GroupKind:
		return false // not a scalar type field

	case protoreflect.StringKind, protoreflect.BytesKind:
		// string and bytes can explicitly not be declared as packed,
		// see https://protobuf.dev/programming-guides/encoding/#packed
		return false

	default:
		return true
	}
}

func (r descsByName) initFieldsFromDescriptorProto(fds []*descriptorpb.FieldDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (fs []filedesc.Field, err error) {
	fs = make([]filedesc.Field, len(fds)) // allocate up-front to ensure stable pointers
	for i, fd := range fds {
		f := &fs[i]
		if f.L0, err = r.makeBase(f, parent, fd.GetName(), i, sb); err != nil {
			return nil, err
		}
		f.L1.EditionFeatures = mergeEditionFeatures(parent, fd.GetOptions().GetFeatures())
		f.L1.IsProto3Optional = fd.GetProto3Optional()
		if opts := fd.GetOptions(); opts != nil {
			opts = proto.Clone(opts).(*descriptorpb.FieldOptions)
			f.L1.Options = func() protoreflect.ProtoMessage { return opts }
			f.L1.IsWeak = opts.GetWeak()
			if opts.Packed != nil {
				f.L1.EditionFeatures.IsPacked = opts.GetPacked()
			}
		}
		f.L1.Number = protoreflect.FieldNumber(fd.GetNumber())
		f.L1.Cardinality = protoreflect.Cardinality(fd.GetLabel())
		if fd.Type != nil {
			f.L1.Kind = protoreflect.Kind(fd.GetType())
		}
		if fd.JsonName != nil {
			f.L1.StringName.InitJSON(fd.GetJsonName())
		}

		if f.L1.EditionFeatures.IsLegacyRequired {
			f.L1.Cardinality = protoreflect.Required
		}

		if f.L1.Kind == protoreflect.MessageKind && f.L1.EditionFeatures.IsDelimitedEncoded {
			f.L1.Kind = protoreflect.GroupKind
		}
	}
	return fs, nil
}

func (r descsByName) initOneofsFromDescriptorProto(ods []*descriptorpb.OneofDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (os []filedesc.Oneof, err error) {
	os = make([]filedesc.Oneof, len(ods)) // allocate up-front to ensure stable pointers
	for i, od := range ods {
		o := &os[i]
		if o.L0, err = r.makeBase(o, parent, od.GetName(), i, sb); err != nil {
			return nil, err
		}
		o.L1.EditionFeatures = mergeEditionFeatures(parent, od.GetOptions().GetFeatures())
		if opts := od.GetOptions(); opts != nil {
			opts = proto.Clone(opts).(*descriptorpb.OneofOptions)
			o.L1.Options = func() protoreflect.ProtoMessage { return opts }
		}
	}
	return os, nil
}

func (r descsByName) initExtensionDeclarations(xds []*descriptorpb.FieldDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (xs []filedesc.Extension, err error) {
	xs = make([]filedesc.Extension, len(xds)) // allocate up-front to ensure stable pointers
	for i, xd := range xds {
		x := &xs[i]
		x.L2 = new(filedesc.ExtensionL2)
		if x.L0, err = r.makeBase(x, parent, xd.GetName(), i, sb); err != nil {
			return nil, err
		}
		x.L1.EditionFeatures = mergeEditionFeatures(parent, xd.GetOptions().GetFeatures())
		if opts := xd.GetOptions(); opts != nil {
			opts = proto.Clone(opts).(*descriptorpb.FieldOptions)
			x.L2.Options = func() protoreflect.ProtoMessage { return opts }
			if opts.Packed != nil {
				x.L1.EditionFeatures.IsPacked = opts.GetPacked()
			}
		}
		x.L1.Number = protoreflect.FieldNumber(xd.GetNumber())
		x.L1.Cardinality = protoreflect.Cardinality(xd.GetLabel())
		if xd.Type != nil {
			x.L1.Kind = protoreflect.Kind(xd.GetType())
		}
		if xd.JsonName != nil {
			x.L2.StringName.InitJSON(xd.GetJsonName())
		}
	}
	return xs, nil
}

func (r descsByName) initServiceDeclarations(sds []*descriptorpb.ServiceDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (ss []filedesc.Service, err error) {
	ss = make([]filedesc.Service, len(sds)) // allocate up-front to ensure stable pointers
	for i, sd := range sds {
		s := &ss[i]
		s.L2 = new(filedesc.ServiceL2)
		if s.L0, err = r.makeBase(s, parent, sd.GetName(), i, sb); err != nil {
			return nil, err
		}
		if opts := sd.GetOptions(); opts != nil {
			opts = proto.Clone(opts).(*descriptorpb.ServiceOptions)
			s.L2.Options = func() protoreflect.ProtoMessage { return opts }
		}
		if s.L2.Methods.List, err = r.initMethodsFromDescriptorProto(sd.GetMethod(), s, sb); err != nil {
			return nil, err
		}
	}
	return ss, nil
}

func (r descsByName) initMethodsFromDescriptorProto(mds []*descriptorpb.MethodDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (ms []filedesc.Method, err error) {
	ms = make([]filedesc.Method, len(mds)) // allocate up-front to ensure stable pointers
	for i, md := range mds {
		m := &ms[i]
		if m.L0, err = r.makeBase(m, parent, md.GetName(), i, sb); err != nil {
			return nil, err
		}
		if opts := md.GetOptions(); opts != nil {
			opts = proto.Clone(opts).(*descriptorpb.MethodOptions)
			m.L1.Options = func() protoreflect.ProtoMessage { return opts }
		}
		m.L1.IsStreamingClient = md.GetClientStreaming()
		m.L1.IsStreamingServer = md.GetServerStreaming()
	}
	return ms, nil
}

func (r descsByName) makeBase(child, parent protoreflect.Descriptor, name string, idx int, sb *strs.Builder) (filedesc.BaseL0, error) {
	if !protoreflect.Name(name).IsValid() {
		return filedesc.BaseL0{}, errors.New("descriptor %q has an invalid nested name: %q", parent.FullName(), name)
	}

	// Derive the full name of the child.
	// Note that enum values are a sibling to the enum parent in the namespace.
	var fullName protoreflect.FullName
	if _, ok := parent.(protoreflect.EnumDescriptor); ok {
		fullName = sb.AppendFullName(parent.FullName().Parent(), protoreflect.Name(name))
	} else {
		fullName = sb.AppendFullName(parent.FullName(), protoreflect.Name(name))
	}
	if _, ok := r[fullName]; ok {
		return filedesc.BaseL0{}, errors.New("descriptor %q already declared", fullName)
	}
	r[fullName] = child

	// TODO: Verify that the full name does not already exist in the resolver?
	// This is not as critical since most usages of NewFile will register
	// the created file back into the registry, which will perform this check.

	return filedesc.BaseL0{
		FullName:   fullName,
		ParentFile: parent.ParentFile().(*filedesc.File),
		Parent:     parent,
		Index:      idx,
	}, nil
}
