package protoparse

import (
	"bytes"
	"fmt"
	"math"

	"github.com/golang/protobuf/proto"
	dpb "github.com/golang/protobuf/protoc-gen-go/descriptor"

	"github.com/jhump/protoreflect/desc"
	"github.com/jhump/protoreflect/desc/internal"
	"github.com/jhump/protoreflect/dynamic"
)

// NB: To process options, we need descriptors, but we may not have rich
// descriptors when trying to interpret options for unlinked parsed files.
// So we define minimal interfaces that can be backed by both rich descriptors
// as well as their poorer cousins, plain ol' descriptor protos.

type descriptorish interface {
	GetFile() fileDescriptorish
	GetFullyQualifiedName() string
	AsProto() proto.Message
}

type fileDescriptorish interface {
	descriptorish
	GetFileOptions() *dpb.FileOptions
	GetPackage() string
	FindSymbol(name string) desc.Descriptor
	GetPublicDependencies() []fileDescriptorish
	GetDependencies() []fileDescriptorish
	GetMessageTypes() []msgDescriptorish
	GetExtensions() []fldDescriptorish
	GetEnumTypes() []enumDescriptorish
	GetServices() []svcDescriptorish
}

type msgDescriptorish interface {
	descriptorish
	GetMessageOptions() *dpb.MessageOptions
	GetFields() []fldDescriptorish
	GetOneOfs() []oneofDescriptorish
	GetExtensionRanges() []extRangeDescriptorish
	GetNestedMessageTypes() []msgDescriptorish
	GetNestedExtensions() []fldDescriptorish
	GetNestedEnumTypes() []enumDescriptorish
}

type fldDescriptorish interface {
	descriptorish
	GetFieldOptions() *dpb.FieldOptions
	GetMessageType() *desc.MessageDescriptor
	GetEnumType() *desc.EnumDescriptor
	AsFieldDescriptorProto() *dpb.FieldDescriptorProto
}

type oneofDescriptorish interface {
	descriptorish
	GetOneOfOptions() *dpb.OneofOptions
}

type enumDescriptorish interface {
	descriptorish
	GetEnumOptions() *dpb.EnumOptions
	GetValues() []enumValDescriptorish
}

type enumValDescriptorish interface {
	descriptorish
	GetEnumValueOptions() *dpb.EnumValueOptions
}

type svcDescriptorish interface {
	descriptorish
	GetServiceOptions() *dpb.ServiceOptions
	GetMethods() []methodDescriptorish
}

type methodDescriptorish interface {
	descriptorish
	GetMethodOptions() *dpb.MethodOptions
}

// The hierarchy of descriptorish implementations backed by
// rich descriptors:

type richFileDescriptorish struct {
	*desc.FileDescriptor
}

func (d richFileDescriptorish) GetFile() fileDescriptorish {
	return d
}

func (d richFileDescriptorish) GetPublicDependencies() []fileDescriptorish {
	deps := d.FileDescriptor.GetPublicDependencies()
	ret := make([]fileDescriptorish, len(deps))
	for i, d := range deps {
		ret[i] = richFileDescriptorish{FileDescriptor: d}
	}
	return ret
}

func (d richFileDescriptorish) GetDependencies() []fileDescriptorish {
	deps := d.FileDescriptor.GetDependencies()
	ret := make([]fileDescriptorish, len(deps))
	for i, d := range deps {
		ret[i] = richFileDescriptorish{FileDescriptor: d}
	}
	return ret
}

func (d richFileDescriptorish) GetMessageTypes() []msgDescriptorish {
	msgs := d.FileDescriptor.GetMessageTypes()
	ret := make([]msgDescriptorish, len(msgs))
	for i, m := range msgs {
		ret[i] = richMsgDescriptorish{MessageDescriptor: m}
	}
	return ret
}

func (d richFileDescriptorish) GetExtensions() []fldDescriptorish {
	flds := d.FileDescriptor.GetExtensions()
	ret := make([]fldDescriptorish, len(flds))
	for i, f := range flds {
		ret[i] = richFldDescriptorish{FieldDescriptor: f}
	}
	return ret
}

func (d richFileDescriptorish) GetEnumTypes() []enumDescriptorish {
	ens := d.FileDescriptor.GetEnumTypes()
	ret := make([]enumDescriptorish, len(ens))
	for i, en := range ens {
		ret[i] = richEnumDescriptorish{EnumDescriptor: en}
	}
	return ret
}

func (d richFileDescriptorish) GetServices() []svcDescriptorish {
	svcs := d.FileDescriptor.GetServices()
	ret := make([]svcDescriptorish, len(svcs))
	for i, s := range svcs {
		ret[i] = richSvcDescriptorish{ServiceDescriptor: s}
	}
	return ret
}

type richMsgDescriptorish struct {
	*desc.MessageDescriptor
}

func (d richMsgDescriptorish) GetFile() fileDescriptorish {
	return richFileDescriptorish{FileDescriptor: d.MessageDescriptor.GetFile()}
}

func (d richMsgDescriptorish) GetFields() []fldDescriptorish {
	flds := d.MessageDescriptor.GetFields()
	ret := make([]fldDescriptorish, len(flds))
	for i, f := range flds {
		ret[i] = richFldDescriptorish{FieldDescriptor: f}
	}
	return ret
}

func (d richMsgDescriptorish) GetOneOfs() []oneofDescriptorish {
	oos := d.MessageDescriptor.GetOneOfs()
	ret := make([]oneofDescriptorish, len(oos))
	for i, oo := range oos {
		ret[i] = richOneOfDescriptorish{OneOfDescriptor: oo}
	}
	return ret
}

func (d richMsgDescriptorish) GetExtensionRanges() []extRangeDescriptorish {
	md := d.MessageDescriptor
	mdFqn := md.GetFullyQualifiedName()
	extrs := md.AsDescriptorProto().GetExtensionRange()
	ret := make([]extRangeDescriptorish, len(extrs))
	for i, extr := range extrs {
		ret[i] = extRangeDescriptorish{
			er:   extr,
			qual: mdFqn,
			file: richFileDescriptorish{FileDescriptor: md.GetFile()},
		}
	}
	return ret
}

func (d richMsgDescriptorish) GetNestedMessageTypes() []msgDescriptorish {
	msgs := d.MessageDescriptor.GetNestedMessageTypes()
	ret := make([]msgDescriptorish, len(msgs))
	for i, m := range msgs {
		ret[i] = richMsgDescriptorish{MessageDescriptor: m}
	}
	return ret
}

func (d richMsgDescriptorish) GetNestedExtensions() []fldDescriptorish {
	flds := d.MessageDescriptor.GetNestedExtensions()
	ret := make([]fldDescriptorish, len(flds))
	for i, f := range flds {
		ret[i] = richFldDescriptorish{FieldDescriptor: f}
	}
	return ret
}

func (d richMsgDescriptorish) GetNestedEnumTypes() []enumDescriptorish {
	ens := d.MessageDescriptor.GetNestedEnumTypes()
	ret := make([]enumDescriptorish, len(ens))
	for i, en := range ens {
		ret[i] = richEnumDescriptorish{EnumDescriptor: en}
	}
	return ret
}

type richFldDescriptorish struct {
	*desc.FieldDescriptor
}

func (d richFldDescriptorish) GetFile() fileDescriptorish {
	return richFileDescriptorish{FileDescriptor: d.FieldDescriptor.GetFile()}
}

func (d richFldDescriptorish) AsFieldDescriptorProto() *dpb.FieldDescriptorProto {
	return d.FieldDescriptor.AsFieldDescriptorProto()
}

type richOneOfDescriptorish struct {
	*desc.OneOfDescriptor
}

func (d richOneOfDescriptorish) GetFile() fileDescriptorish {
	return richFileDescriptorish{FileDescriptor: d.OneOfDescriptor.GetFile()}
}

type richEnumDescriptorish struct {
	*desc.EnumDescriptor
}

func (d richEnumDescriptorish) GetFile() fileDescriptorish {
	return richFileDescriptorish{FileDescriptor: d.EnumDescriptor.GetFile()}
}

func (d richEnumDescriptorish) GetValues() []enumValDescriptorish {
	vals := d.EnumDescriptor.GetValues()
	ret := make([]enumValDescriptorish, len(vals))
	for i, val := range vals {
		ret[i] = richEnumValDescriptorish{EnumValueDescriptor: val}
	}
	return ret
}

type richEnumValDescriptorish struct {
	*desc.EnumValueDescriptor
}

func (d richEnumValDescriptorish) GetFile() fileDescriptorish {
	return richFileDescriptorish{FileDescriptor: d.EnumValueDescriptor.GetFile()}
}

type richSvcDescriptorish struct {
	*desc.ServiceDescriptor
}

func (d richSvcDescriptorish) GetFile() fileDescriptorish {
	return richFileDescriptorish{FileDescriptor: d.ServiceDescriptor.GetFile()}
}

func (d richSvcDescriptorish) GetMethods() []methodDescriptorish {
	mtds := d.ServiceDescriptor.GetMethods()
	ret := make([]methodDescriptorish, len(mtds))
	for i, mtd := range mtds {
		ret[i] = richMethodDescriptorish{MethodDescriptor: mtd}
	}
	return ret
}

type richMethodDescriptorish struct {
	*desc.MethodDescriptor
}

func (d richMethodDescriptorish) GetFile() fileDescriptorish {
	return richFileDescriptorish{FileDescriptor: d.MethodDescriptor.GetFile()}
}

// The hierarchy of descriptorish implementations backed by
// plain descriptor protos:

type poorFileDescriptorish struct {
	*dpb.FileDescriptorProto
}

func (d poorFileDescriptorish) GetFile() fileDescriptorish {
	return d
}

func (d poorFileDescriptorish) GetFullyQualifiedName() string {
	return d.FileDescriptorProto.GetName()
}

func (d poorFileDescriptorish) AsProto() proto.Message {
	return d.FileDescriptorProto
}

func (d poorFileDescriptorish) GetFileOptions() *dpb.FileOptions {
	return d.FileDescriptorProto.GetOptions()
}

func (d poorFileDescriptorish) FindSymbol(name string) desc.Descriptor {
	return nil
}

func (d poorFileDescriptorish) GetPublicDependencies() []fileDescriptorish {
	return nil
}

func (d poorFileDescriptorish) GetDependencies() []fileDescriptorish {
	return nil
}

func (d poorFileDescriptorish) GetMessageTypes() []msgDescriptorish {
	msgs := d.FileDescriptorProto.GetMessageType()
	pkg := d.FileDescriptorProto.GetPackage()
	ret := make([]msgDescriptorish, len(msgs))
	for i, m := range msgs {
		ret[i] = poorMsgDescriptorish{
			DescriptorProto: m,
			qual:            pkg,
			file:            d,
		}
	}
	return ret
}

func (d poorFileDescriptorish) GetExtensions() []fldDescriptorish {
	exts := d.FileDescriptorProto.GetExtension()
	pkg := d.FileDescriptorProto.GetPackage()
	ret := make([]fldDescriptorish, len(exts))
	for i, e := range exts {
		ret[i] = poorFldDescriptorish{
			FieldDescriptorProto: e,
			qual:                 pkg,
			file:                 d,
		}
	}
	return ret
}

func (d poorFileDescriptorish) GetEnumTypes() []enumDescriptorish {
	ens := d.FileDescriptorProto.GetEnumType()
	pkg := d.FileDescriptorProto.GetPackage()
	ret := make([]enumDescriptorish, len(ens))
	for i, e := range ens {
		ret[i] = poorEnumDescriptorish{
			EnumDescriptorProto: e,
			qual:                pkg,
			file:                d,
		}
	}
	return ret
}

func (d poorFileDescriptorish) GetServices() []svcDescriptorish {
	svcs := d.FileDescriptorProto.GetService()
	pkg := d.FileDescriptorProto.GetPackage()
	ret := make([]svcDescriptorish, len(svcs))
	for i, s := range svcs {
		ret[i] = poorSvcDescriptorish{
			ServiceDescriptorProto: s,
			qual:                   pkg,
			file:                   d,
		}
	}
	return ret
}

type poorMsgDescriptorish struct {
	*dpb.DescriptorProto
	qual string
	file fileDescriptorish
}

func (d poorMsgDescriptorish) GetFile() fileDescriptorish {
	return d.file
}

func (d poorMsgDescriptorish) GetFullyQualifiedName() string {
	return qualify(d.qual, d.DescriptorProto.GetName())
}

func qualify(qual, name string) string {
	if qual == "" {
		return name
	} else {
		return fmt.Sprintf("%s.%s", qual, name)
	}
}

func (d poorMsgDescriptorish) AsProto() proto.Message {
	return d.DescriptorProto
}

func (d poorMsgDescriptorish) GetMessageOptions() *dpb.MessageOptions {
	return d.DescriptorProto.GetOptions()
}

func (d poorMsgDescriptorish) GetFields() []fldDescriptorish {
	flds := d.DescriptorProto.GetField()
	ret := make([]fldDescriptorish, len(flds))
	for i, f := range flds {
		ret[i] = poorFldDescriptorish{
			FieldDescriptorProto: f,
			qual:                 d.GetFullyQualifiedName(),
			file:                 d.file,
		}
	}
	return ret
}

func (d poorMsgDescriptorish) GetOneOfs() []oneofDescriptorish {
	oos := d.DescriptorProto.GetOneofDecl()
	ret := make([]oneofDescriptorish, len(oos))
	for i, oo := range oos {
		ret[i] = poorOneOfDescriptorish{
			OneofDescriptorProto: oo,
			qual:                 d.GetFullyQualifiedName(),
			file:                 d.file,
		}
	}
	return ret
}

func (d poorMsgDescriptorish) GetExtensionRanges() []extRangeDescriptorish {
	mdFqn := d.GetFullyQualifiedName()
	extrs := d.DescriptorProto.GetExtensionRange()
	ret := make([]extRangeDescriptorish, len(extrs))
	for i, extr := range extrs {
		ret[i] = extRangeDescriptorish{
			er:   extr,
			qual: mdFqn,
			file: d.file,
		}
	}
	return ret
}

func (d poorMsgDescriptorish) GetNestedMessageTypes() []msgDescriptorish {
	msgs := d.DescriptorProto.GetNestedType()
	ret := make([]msgDescriptorish, len(msgs))
	for i, m := range msgs {
		ret[i] = poorMsgDescriptorish{
			DescriptorProto: m,
			qual:            d.GetFullyQualifiedName(),
			file:            d.file,
		}
	}
	return ret
}

func (d poorMsgDescriptorish) GetNestedExtensions() []fldDescriptorish {
	flds := d.DescriptorProto.GetExtension()
	ret := make([]fldDescriptorish, len(flds))
	for i, f := range flds {
		ret[i] = poorFldDescriptorish{
			FieldDescriptorProto: f,
			qual:                 d.GetFullyQualifiedName(),
			file:                 d.file,
		}
	}
	return ret
}

func (d poorMsgDescriptorish) GetNestedEnumTypes() []enumDescriptorish {
	ens := d.DescriptorProto.GetEnumType()
	ret := make([]enumDescriptorish, len(ens))
	for i, en := range ens {
		ret[i] = poorEnumDescriptorish{
			EnumDescriptorProto: en,
			qual:                d.GetFullyQualifiedName(),
			file:                d.file,
		}
	}
	return ret
}

type poorFldDescriptorish struct {
	*dpb.FieldDescriptorProto
	qual string
	file fileDescriptorish
}

func (d poorFldDescriptorish) GetFile() fileDescriptorish {
	return d.file
}

func (d poorFldDescriptorish) GetFullyQualifiedName() string {
	return qualify(d.qual, d.FieldDescriptorProto.GetName())
}

func (d poorFldDescriptorish) AsProto() proto.Message {
	return d.FieldDescriptorProto
}

func (d poorFldDescriptorish) GetFieldOptions() *dpb.FieldOptions {
	return d.FieldDescriptorProto.GetOptions()
}

func (d poorFldDescriptorish) GetMessageType() *desc.MessageDescriptor {
	return nil
}

func (d poorFldDescriptorish) GetEnumType() *desc.EnumDescriptor {
	return nil
}

type poorOneOfDescriptorish struct {
	*dpb.OneofDescriptorProto
	qual string
	file fileDescriptorish
}

func (d poorOneOfDescriptorish) GetFile() fileDescriptorish {
	return d.file
}

func (d poorOneOfDescriptorish) GetFullyQualifiedName() string {
	return qualify(d.qual, d.OneofDescriptorProto.GetName())
}

func (d poorOneOfDescriptorish) AsProto() proto.Message {
	return d.OneofDescriptorProto
}

func (d poorOneOfDescriptorish) GetOneOfOptions() *dpb.OneofOptions {
	return d.OneofDescriptorProto.GetOptions()
}

func (d poorFldDescriptorish) AsFieldDescriptorProto() *dpb.FieldDescriptorProto {
	return d.FieldDescriptorProto
}

type poorEnumDescriptorish struct {
	*dpb.EnumDescriptorProto
	qual string
	file fileDescriptorish
}

func (d poorEnumDescriptorish) GetFile() fileDescriptorish {
	return d.file
}

func (d poorEnumDescriptorish) GetFullyQualifiedName() string {
	return qualify(d.qual, d.EnumDescriptorProto.GetName())
}

func (d poorEnumDescriptorish) AsProto() proto.Message {
	return d.EnumDescriptorProto
}

func (d poorEnumDescriptorish) GetEnumOptions() *dpb.EnumOptions {
	return d.EnumDescriptorProto.GetOptions()
}

func (d poorEnumDescriptorish) GetValues() []enumValDescriptorish {
	vals := d.EnumDescriptorProto.GetValue()
	ret := make([]enumValDescriptorish, len(vals))
	for i, v := range vals {
		ret[i] = poorEnumValDescriptorish{
			EnumValueDescriptorProto: v,
			qual:                     d.GetFullyQualifiedName(),
			file:                     d.file,
		}
	}
	return ret
}

type poorEnumValDescriptorish struct {
	*dpb.EnumValueDescriptorProto
	qual string
	file fileDescriptorish
}

func (d poorEnumValDescriptorish) GetFile() fileDescriptorish {
	return d.file
}

func (d poorEnumValDescriptorish) GetFullyQualifiedName() string {
	return qualify(d.qual, d.EnumValueDescriptorProto.GetName())
}

func (d poorEnumValDescriptorish) AsProto() proto.Message {
	return d.EnumValueDescriptorProto
}

func (d poorEnumValDescriptorish) GetEnumValueOptions() *dpb.EnumValueOptions {
	return d.EnumValueDescriptorProto.GetOptions()
}

type poorSvcDescriptorish struct {
	*dpb.ServiceDescriptorProto
	qual string
	file fileDescriptorish
}

func (d poorSvcDescriptorish) GetFile() fileDescriptorish {
	return d.file
}

func (d poorSvcDescriptorish) GetFullyQualifiedName() string {
	return qualify(d.qual, d.ServiceDescriptorProto.GetName())
}

func (d poorSvcDescriptorish) AsProto() proto.Message {
	return d.ServiceDescriptorProto
}

func (d poorSvcDescriptorish) GetServiceOptions() *dpb.ServiceOptions {
	return d.ServiceDescriptorProto.GetOptions()
}

func (d poorSvcDescriptorish) GetMethods() []methodDescriptorish {
	mtds := d.ServiceDescriptorProto.GetMethod()
	ret := make([]methodDescriptorish, len(mtds))
	for i, m := range mtds {
		ret[i] = poorMethodDescriptorish{
			MethodDescriptorProto: m,
			qual:                  d.GetFullyQualifiedName(),
			file:                  d.file,
		}
	}
	return ret
}

type poorMethodDescriptorish struct {
	*dpb.MethodDescriptorProto
	qual string
	file fileDescriptorish
}

func (d poorMethodDescriptorish) GetFile() fileDescriptorish {
	return d.file
}

func (d poorMethodDescriptorish) GetFullyQualifiedName() string {
	return qualify(d.qual, d.MethodDescriptorProto.GetName())
}

func (d poorMethodDescriptorish) AsProto() proto.Message {
	return d.MethodDescriptorProto
}

func (d poorMethodDescriptorish) GetMethodOptions() *dpb.MethodOptions {
	return d.MethodDescriptorProto.GetOptions()
}

type extRangeDescriptorish struct {
	er   *dpb.DescriptorProto_ExtensionRange
	qual string
	file fileDescriptorish
}

func (er extRangeDescriptorish) GetFile() fileDescriptorish {
	return er.file
}

func (er extRangeDescriptorish) GetFullyQualifiedName() string {
	return qualify(er.qual, fmt.Sprintf("%d-%d", er.er.GetStart(), er.er.GetEnd()-1))
}

func (er extRangeDescriptorish) AsProto() proto.Message {
	return er.er
}

func (er extRangeDescriptorish) GetExtensionRangeOptions() *dpb.ExtensionRangeOptions {
	return er.er.GetOptions()
}

func interpretFileOptions(r *parseResult, fd fileDescriptorish) error {
	opts := fd.GetFileOptions()
	if opts != nil {
		if len(opts.UninterpretedOption) > 0 {
			if remain, err := interpretOptions(r, fd, opts, opts.UninterpretedOption); err != nil {
				return err
			} else {
				opts.UninterpretedOption = remain
			}
		}
	}
	for _, md := range fd.GetMessageTypes() {
		if err := interpretMessageOptions(r, md); err != nil {
			return err
		}
	}
	for _, fld := range fd.GetExtensions() {
		if err := interpretFieldOptions(r, fld); err != nil {
			return err
		}
	}
	for _, ed := range fd.GetEnumTypes() {
		if err := interpretEnumOptions(r, ed); err != nil {
			return err
		}
	}
	for _, sd := range fd.GetServices() {
		opts := sd.GetServiceOptions()
		if opts != nil {
			if len(opts.UninterpretedOption) > 0 {
				if remain, err := interpretOptions(r, sd, opts, opts.UninterpretedOption); err != nil {
					return err
				} else {
					opts.UninterpretedOption = remain
				}
			}
		}
		for _, mtd := range sd.GetMethods() {
			opts := mtd.GetMethodOptions()
			if opts != nil {
				if len(opts.UninterpretedOption) > 0 {
					if remain, err := interpretOptions(r, mtd, opts, opts.UninterpretedOption); err != nil {
						return err
					} else {
						opts.UninterpretedOption = remain
					}
				}
			}
		}
	}
	return nil
}

func interpretMessageOptions(r *parseResult, md msgDescriptorish) error {
	opts := md.GetMessageOptions()
	if opts != nil {
		if len(opts.UninterpretedOption) > 0 {
			if remain, err := interpretOptions(r, md, opts, opts.UninterpretedOption); err != nil {
				return err
			} else {
				opts.UninterpretedOption = remain
			}
		}
	}
	for _, fld := range md.GetFields() {
		if err := interpretFieldOptions(r, fld); err != nil {
			return err
		}
	}
	for _, ood := range md.GetOneOfs() {
		opts := ood.GetOneOfOptions()
		if opts != nil {
			if len(opts.UninterpretedOption) > 0 {
				if remain, err := interpretOptions(r, ood, opts, opts.UninterpretedOption); err != nil {
					return err
				} else {
					opts.UninterpretedOption = remain
				}
			}
		}
	}
	for _, fld := range md.GetNestedExtensions() {
		if err := interpretFieldOptions(r, fld); err != nil {
			return err
		}
	}
	for _, er := range md.GetExtensionRanges() {
		opts := er.GetExtensionRangeOptions()
		if opts != nil {
			if len(opts.UninterpretedOption) > 0 {
				if remain, err := interpretOptions(r, er, opts, opts.UninterpretedOption); err != nil {
					return err
				} else {
					opts.UninterpretedOption = remain
				}
			}
		}
	}
	for _, nmd := range md.GetNestedMessageTypes() {
		if err := interpretMessageOptions(r, nmd); err != nil {
			return err
		}
	}
	for _, ed := range md.GetNestedEnumTypes() {
		if err := interpretEnumOptions(r, ed); err != nil {
			return err
		}
	}
	return nil
}

func interpretFieldOptions(r *parseResult, fld fldDescriptorish) error {
	opts := fld.GetFieldOptions()
	if opts != nil {
		if len(opts.UninterpretedOption) > 0 {
			uo := opts.UninterpretedOption
			scope := fmt.Sprintf("field %s", fld.GetFullyQualifiedName())

			// process json_name pseudo-option
			if index, err := findOption(r, scope, uo, "json_name"); err != nil && !r.lenient {
				return err
			} else if err == nil && index >= 0 {
				opt := uo[index]
				optNode := r.getOptionNode(opt)

				// attribute source code info
				if on, ok := optNode.(*optionNode); ok {
					r.interpretedOptions[on] = []int32{-1, internal.Field_jsonNameTag}
				}
				uo = removeOption(uo, index)
				if opt.StringValue == nil {
					return ErrorWithSourcePos{Pos: optNode.getValue().start(), Underlying: fmt.Errorf("%s: expecting string value for json_name option", scope)}
				}
				fld.AsFieldDescriptorProto().JsonName = proto.String(string(opt.StringValue))
			}

			// and process default pseudo-option
			if index, err := processDefaultOption(r, scope, fld, uo); err != nil && !r.lenient {
				return err
			} else if err == nil && index >= 0 {
				// attribute source code info
				optNode := r.getOptionNode(uo[index])
				if on, ok := optNode.(*optionNode); ok {
					r.interpretedOptions[on] = []int32{-1, internal.Field_defaultTag}
				}
				uo = removeOption(uo, index)
			}

			if len(uo) == 0 {
				// no real options, only pseudo-options above? clear out options
				fld.AsFieldDescriptorProto().Options = nil
			} else if remain, err := interpretOptions(r, fld, opts, uo); err != nil {
				return err
			} else {
				opts.UninterpretedOption = remain
			}
		}
	}
	return nil
}

func processDefaultOption(res *parseResult, scope string, fld fldDescriptorish, uos []*dpb.UninterpretedOption) (defaultIndex int, err error) {
	found, err := findOption(res, scope, uos, "default")
	if err != nil {
		return -1, err
	} else if found == -1 {
		return -1, nil
	}
	opt := uos[found]
	optNode := res.getOptionNode(opt)
	fdp := fld.AsFieldDescriptorProto()
	if fdp.GetLabel() == dpb.FieldDescriptorProto_LABEL_REPEATED {
		return -1, ErrorWithSourcePos{Pos: optNode.getName().start(), Underlying: fmt.Errorf("%s: default value cannot be set because field is repeated", scope)}
	}
	if fdp.GetType() == dpb.FieldDescriptorProto_TYPE_GROUP || fdp.GetType() == dpb.FieldDescriptorProto_TYPE_MESSAGE {
		return -1, ErrorWithSourcePos{Pos: optNode.getName().start(), Underlying: fmt.Errorf("%s: default value cannot be set because field is a message", scope)}
	}
	val := optNode.getValue()
	if _, ok := val.(*aggregateLiteralNode); ok {
		return -1, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%s: default value cannot be an aggregate", scope)}
	}
	mc := &messageContext{
		res:         res,
		file:        fld.GetFile(),
		elementName: fld.GetFullyQualifiedName(),
		elementType: descriptorType(fld.AsProto()),
		option:      opt,
	}
	v, err := fieldValue(res, mc, fld, val, true)
	if err != nil {
		return -1, err
	}
	if str, ok := v.(string); ok {
		fld.AsFieldDescriptorProto().DefaultValue = proto.String(str)
	} else if b, ok := v.([]byte); ok {
		fld.AsFieldDescriptorProto().DefaultValue = proto.String(encodeDefaultBytes(b))
	} else {
		var flt float64
		var ok bool
		if flt, ok = v.(float64); !ok {
			var flt32 float32
			if flt32, ok = v.(float32); ok {
				flt = float64(flt32)
			}
		}
		if ok {
			if math.IsInf(flt, 1) {
				fld.AsFieldDescriptorProto().DefaultValue = proto.String("inf")
			} else if ok && math.IsInf(flt, -1) {
				fld.AsFieldDescriptorProto().DefaultValue = proto.String("-inf")
			} else if ok && math.IsNaN(flt) {
				fld.AsFieldDescriptorProto().DefaultValue = proto.String("nan")
			} else {
				fld.AsFieldDescriptorProto().DefaultValue = proto.String(fmt.Sprintf("%v", v))
			}
		} else {
			fld.AsFieldDescriptorProto().DefaultValue = proto.String(fmt.Sprintf("%v", v))
		}
	}
	return found, nil
}

func encodeDefaultBytes(b []byte) string {
	var buf bytes.Buffer
	writeEscapedBytes(&buf, b)
	return buf.String()
}

func interpretEnumOptions(r *parseResult, ed enumDescriptorish) error {
	opts := ed.GetEnumOptions()
	if opts != nil {
		if len(opts.UninterpretedOption) > 0 {
			if remain, err := interpretOptions(r, ed, opts, opts.UninterpretedOption); err != nil {
				return err
			} else {
				opts.UninterpretedOption = remain
			}
		}
	}
	for _, evd := range ed.GetValues() {
		opts := evd.GetEnumValueOptions()
		if opts != nil {
			if len(opts.UninterpretedOption) > 0 {
				if remain, err := interpretOptions(r, evd, opts, opts.UninterpretedOption); err != nil {
					return err
				} else {
					opts.UninterpretedOption = remain
				}
			}
		}
	}
	return nil
}

func interpretOptions(res *parseResult, element descriptorish, opts proto.Message, uninterpreted []*dpb.UninterpretedOption) ([]*dpb.UninterpretedOption, error) {
	optsd, err := desc.LoadMessageDescriptorForMessage(opts)
	if err != nil {
		if res.lenient {
			return uninterpreted, nil
		}
		return nil, err
	}
	dm := dynamic.NewMessage(optsd)
	err = dm.ConvertFrom(opts)
	if err != nil {
		if res.lenient {
			return uninterpreted, nil
		}
		node := res.nodes[element.AsProto()]
		return nil, ErrorWithSourcePos{Pos: node.start(), Underlying: err}
	}

	mc := &messageContext{res: res, file: element.GetFile(), elementName: element.GetFullyQualifiedName(), elementType: descriptorType(element.AsProto())}
	var remain []*dpb.UninterpretedOption
	for _, uo := range uninterpreted {
		node := res.getOptionNode(uo)
		if !uo.Name[0].GetIsExtension() && uo.Name[0].GetNamePart() == "uninterpreted_option" {
			if res.lenient {
				remain = append(remain, uo)
				continue
			}
			// uninterpreted_option might be found reflectively, but is not actually valid for use
			return nil, ErrorWithSourcePos{Pos: node.getName().start(), Underlying: fmt.Errorf("%vinvalid option 'uninterpreted_option'", mc)}
		}
		mc.option = uo
		path, err := interpretField(res, mc, element, dm, uo, 0, nil)
		if err != nil {
			if res.lenient {
				remain = append(remain, uo)
				continue
			}
			return nil, err
		}
		if optn, ok := node.(*optionNode); ok {
			res.interpretedOptions[optn] = path
		}
	}

	if err := dm.ValidateRecursive(); err != nil {
		// if lenient, we'll let this pass, but it means that some required field was not set!
		// TODO: do this in a more granular way, so we can validate individual fields
		// and leave them uninterpreted, instead of just having to live with the
		// thing having invalid data in extensions.
		if !res.lenient {
			node := res.nodes[element.AsProto()]
			return nil, ErrorWithSourcePos{Pos: node.start(), Underlying: fmt.Errorf("error in %s options: %v", descriptorType(element.AsProto()), err)}
		}
	}

	if res.lenient {
		// If we're lenient, then we don't want to clobber the passed in message
		// and leave it partially populated. So we convert into a copy first
		optsClone := proto.Clone(opts)
		if err := dm.ConvertTo(optsClone); err != nil {
			// TODO: do this in a more granular way, so we can convert individual
			// fields and leave bad ones uninterpreted instead of skipping all of
			// the work we've done so far.
			return uninterpreted, nil
		}
		// conversion from dynamic message above worked, so now
		// it is safe to overwrite the passed in message
		opts.Reset()
		proto.Merge(opts, optsClone)

	} else {
		// not lenient: try to convert into the passed in message
		// and fail if not successful
		if err := dm.ConvertTo(opts); err != nil {
			node := res.nodes[element.AsProto()]
			return nil, ErrorWithSourcePos{Pos: node.start(), Underlying: err}
		}
	}

	return remain, nil
}

func interpretField(res *parseResult, mc *messageContext, element descriptorish, dm *dynamic.Message, opt *dpb.UninterpretedOption, nameIndex int, pathPrefix []int32) (path []int32, err error) {
	var fld *desc.FieldDescriptor
	nm := opt.GetName()[nameIndex]
	node := res.getOptionNamePartNode(nm)
	if nm.GetIsExtension() {
		extName := nm.GetNamePart()
		if extName[0] == '.' {
			extName = extName[1:] /* skip leading dot */
		}
		fld = findExtension(element.GetFile(), extName, false, map[fileDescriptorish]struct{}{})
		if fld == nil {
			return nil, ErrorWithSourcePos{
				Pos: node.start(),
				Underlying: fmt.Errorf("%vunrecognized extension %s of %s",
					mc, extName, dm.GetMessageDescriptor().GetFullyQualifiedName()),
			}
		}
		if fld.GetOwner().GetFullyQualifiedName() != dm.GetMessageDescriptor().GetFullyQualifiedName() {
			return nil, ErrorWithSourcePos{
				Pos: node.start(),
				Underlying: fmt.Errorf("%vextension %s should extend %s but instead extends %s",
					mc, extName, dm.GetMessageDescriptor().GetFullyQualifiedName(), fld.GetOwner().GetFullyQualifiedName()),
			}
		}
	} else {
		fld = dm.GetMessageDescriptor().FindFieldByName(nm.GetNamePart())
		if fld == nil {
			return nil, ErrorWithSourcePos{
				Pos: node.start(),
				Underlying: fmt.Errorf("%vfield %s of %s does not exist",
					mc, nm.GetNamePart(), dm.GetMessageDescriptor().GetFullyQualifiedName()),
			}
		}
	}

	path = append(pathPrefix, fld.GetNumber())

	if len(opt.GetName()) > nameIndex+1 {
		nextnm := opt.GetName()[nameIndex+1]
		nextnode := res.getOptionNamePartNode(nextnm)
		if fld.GetType() != dpb.FieldDescriptorProto_TYPE_MESSAGE {
			return nil, ErrorWithSourcePos{
				Pos: nextnode.start(),
				Underlying: fmt.Errorf("%vcannot set field %s because %s is not a message",
					mc, nextnm.GetNamePart(), nm.GetNamePart()),
			}
		}
		if fld.IsRepeated() {
			return nil, ErrorWithSourcePos{
				Pos: nextnode.start(),
				Underlying: fmt.Errorf("%vcannot set field %s because %s is repeated (must use an aggregate)",
					mc, nextnm.GetNamePart(), nm.GetNamePart()),
			}
		}
		var fdm *dynamic.Message
		var err error
		if dm.HasField(fld) {
			var v interface{}
			v, err = dm.TryGetField(fld)
			fdm, _ = v.(*dynamic.Message)
		} else {
			fdm = dynamic.NewMessage(fld.GetMessageType())
			err = dm.TrySetField(fld, fdm)
		}
		if err != nil {
			return nil, ErrorWithSourcePos{Pos: node.start(), Underlying: err}
		}
		// recurse to set next part of name
		return interpretField(res, mc, element, fdm, opt, nameIndex+1, path)
	}

	optNode := res.getOptionNode(opt)
	if err := setOptionField(res, mc, dm, fld, node, optNode.getValue()); err != nil {
		return nil, err
	}
	if fld.IsRepeated() {
		path = append(path, int32(dm.FieldLength(fld))-1)
	}
	return path, nil
}

func findExtension(fd fileDescriptorish, name string, public bool, checked map[fileDescriptorish]struct{}) *desc.FieldDescriptor {
	if _, ok := checked[fd]; ok {
		return nil
	}
	checked[fd] = struct{}{}
	d := fd.FindSymbol(name)
	if d != nil {
		if fld, ok := d.(*desc.FieldDescriptor); ok {
			return fld
		}
		return nil
	}

	// When public = false, we are searching only directly imported symbols. But we
	// also need to search transitive public imports due to semantics of public imports.
	if public {
		for _, dep := range fd.GetPublicDependencies() {
			d := findExtension(dep, name, true, checked)
			if d != nil {
				return d
			}
		}
	} else {
		for _, dep := range fd.GetDependencies() {
			d := findExtension(dep, name, true, checked)
			if d != nil {
				return d
			}
		}
	}
	return nil
}

func setOptionField(res *parseResult, mc *messageContext, dm *dynamic.Message, fld *desc.FieldDescriptor, name node, val valueNode) error {
	v := val.value()
	if sl, ok := v.([]valueNode); ok {
		// handle slices a little differently than the others
		if !fld.IsRepeated() {
			return ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vvalue is an array but field is not repeated", mc)}
		}
		origPath := mc.optAggPath
		defer func() {
			mc.optAggPath = origPath
		}()
		for index, item := range sl {
			mc.optAggPath = fmt.Sprintf("%s[%d]", origPath, index)
			if v, err := fieldValue(res, mc, richFldDescriptorish{FieldDescriptor: fld}, item, false); err != nil {
				return err
			} else if err = dm.TryAddRepeatedField(fld, v); err != nil {
				return ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%verror setting value: %s", mc, err)}
			}
		}
		return nil
	}

	v, err := fieldValue(res, mc, richFldDescriptorish{FieldDescriptor: fld}, val, false)
	if err != nil {
		return err
	}
	if fld.IsRepeated() {
		err = dm.TryAddRepeatedField(fld, v)
	} else {
		if dm.HasField(fld) {
			return ErrorWithSourcePos{Pos: name.start(), Underlying: fmt.Errorf("%vnon-repeated option field %s already set", mc, fieldName(fld))}
		}
		err = dm.TrySetField(fld, v)
	}
	if err != nil {
		return ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%verror setting value: %s", mc, err)}
	}

	return nil
}

type messageContext struct {
	res         *parseResult
	file        fileDescriptorish
	elementType string
	elementName string
	option      *dpb.UninterpretedOption
	optAggPath  string
}

func (c *messageContext) String() string {
	var ctx bytes.Buffer
	if c.elementType != "file" {
		fmt.Fprintf(&ctx, "%s %s: ", c.elementType, c.elementName)
	}
	if c.option != nil && c.option.Name != nil {
		ctx.WriteString("option ")
		writeOptionName(&ctx, c.option.Name)
		if c.res.nodes == nil {
			// if we have no source position info, try to provide as much context
			// as possible (if nodes != nil, we don't need this because any errors
			// will actually have file and line numbers)
			if c.optAggPath != "" {
				fmt.Fprintf(&ctx, " at %s", c.optAggPath)
			}
		}
		ctx.WriteString(": ")
	}
	return ctx.String()
}

func writeOptionName(buf *bytes.Buffer, parts []*dpb.UninterpretedOption_NamePart) {
	first := true
	for _, p := range parts {
		if first {
			first = false
		} else {
			buf.WriteByte('.')
		}
		nm := p.GetNamePart()
		if nm[0] == '.' {
			// skip leading dot
			nm = nm[1:]
		}
		if p.GetIsExtension() {
			buf.WriteByte('(')
			buf.WriteString(nm)
			buf.WriteByte(')')
		} else {
			buf.WriteString(nm)
		}
	}
}

func fieldName(fld *desc.FieldDescriptor) string {
	if fld.IsExtension() {
		return fld.GetFullyQualifiedName()
	} else {
		return fld.GetName()
	}
}

func valueKind(val interface{}) string {
	switch val := val.(type) {
	case identifier:
		return "identifier"
	case bool:
		return "bool"
	case int64:
		if val < 0 {
			return "negative integer"
		}
		return "integer"
	case uint64:
		return "integer"
	case float64:
		return "double"
	case string, []byte:
		return "string"
	case []*aggregateEntryNode:
		return "message"
	default:
		return fmt.Sprintf("%T", val)
	}
}

func fieldValue(res *parseResult, mc *messageContext, fld fldDescriptorish, val valueNode, enumAsString bool) (interface{}, error) {
	v := val.value()
	t := fld.AsFieldDescriptorProto().GetType()
	switch t {
	case dpb.FieldDescriptorProto_TYPE_ENUM:
		if id, ok := v.(identifier); ok {
			ev := fld.GetEnumType().FindValueByName(string(id))
			if ev == nil {
				return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%venum %s has no value named %s", mc, fld.GetEnumType().GetFullyQualifiedName(), id)}
			}
			if enumAsString {
				return ev.GetName(), nil
			} else {
				return ev.GetNumber(), nil
			}
		}
		return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vexpecting enum, got %s", mc, valueKind(v))}
	case dpb.FieldDescriptorProto_TYPE_MESSAGE, dpb.FieldDescriptorProto_TYPE_GROUP:
		if aggs, ok := v.([]*aggregateEntryNode); ok {
			fmd := fld.GetMessageType()
			fdm := dynamic.NewMessage(fmd)
			origPath := mc.optAggPath
			defer func() {
				mc.optAggPath = origPath
			}()
			for _, a := range aggs {
				if origPath == "" {
					mc.optAggPath = a.name.value()
				} else {
					mc.optAggPath = origPath + "." + a.name.value()
				}
				var ffld *desc.FieldDescriptor
				if a.name.isExtension {
					n := a.name.name.val
					ffld = findExtension(mc.file, n, false, map[fileDescriptorish]struct{}{})
					if ffld == nil {
						// may need to qualify with package name
						pkg := mc.file.GetPackage()
						if pkg != "" {
							ffld = findExtension(mc.file, pkg+"."+n, false, map[fileDescriptorish]struct{}{})
						}
					}
				} else {
					ffld = fmd.FindFieldByName(a.name.value())
				}
				if ffld == nil {
					return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vfield %s not found", mc, a.name.name.val)}
				}
				if err := setOptionField(res, mc, fdm, ffld, a.name, a.val); err != nil {
					return nil, err
				}
			}
			return fdm, nil
		}
		return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vexpecting message, got %s", mc, valueKind(v))}
	case dpb.FieldDescriptorProto_TYPE_BOOL:
		if b, ok := v.(bool); ok {
			return b, nil
		}
		return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vexpecting bool, got %s", mc, valueKind(v))}
	case dpb.FieldDescriptorProto_TYPE_BYTES:
		if str, ok := v.(string); ok {
			return []byte(str), nil
		}
		return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vexpecting bytes, got %s", mc, valueKind(v))}
	case dpb.FieldDescriptorProto_TYPE_STRING:
		if str, ok := v.(string); ok {
			return str, nil
		}
		return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vexpecting string, got %s", mc, valueKind(v))}
	case dpb.FieldDescriptorProto_TYPE_INT32, dpb.FieldDescriptorProto_TYPE_SINT32, dpb.FieldDescriptorProto_TYPE_SFIXED32:
		if i, ok := v.(int64); ok {
			if i > math.MaxInt32 || i < math.MinInt32 {
				return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vvalue %d is out of range for int32", mc, i)}
			}
			return int32(i), nil
		}
		if ui, ok := v.(uint64); ok {
			if ui > math.MaxInt32 {
				return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vvalue %d is out of range for int32", mc, ui)}
			}
			return int32(ui), nil
		}
		return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vexpecting int32, got %s", mc, valueKind(v))}
	case dpb.FieldDescriptorProto_TYPE_UINT32, dpb.FieldDescriptorProto_TYPE_FIXED32:
		if i, ok := v.(int64); ok {
			if i > math.MaxUint32 || i < 0 {
				return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vvalue %d is out of range for uint32", mc, i)}
			}
			return uint32(i), nil
		}
		if ui, ok := v.(uint64); ok {
			if ui > math.MaxUint32 {
				return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vvalue %d is out of range for uint32", mc, ui)}
			}
			return uint32(ui), nil
		}
		return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vexpecting uint32, got %s", mc, valueKind(v))}
	case dpb.FieldDescriptorProto_TYPE_INT64, dpb.FieldDescriptorProto_TYPE_SINT64, dpb.FieldDescriptorProto_TYPE_SFIXED64:
		if i, ok := v.(int64); ok {
			return i, nil
		}
		if ui, ok := v.(uint64); ok {
			if ui > math.MaxInt64 {
				return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vvalue %d is out of range for int64", mc, ui)}
			}
			return int64(ui), nil
		}
		return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vexpecting int64, got %s", mc, valueKind(v))}
	case dpb.FieldDescriptorProto_TYPE_UINT64, dpb.FieldDescriptorProto_TYPE_FIXED64:
		if i, ok := v.(int64); ok {
			if i < 0 {
				return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vvalue %d is out of range for uint64", mc, i)}
			}
			return uint64(i), nil
		}
		if ui, ok := v.(uint64); ok {
			return ui, nil
		}
		return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vexpecting uint64, got %s", mc, valueKind(v))}
	case dpb.FieldDescriptorProto_TYPE_DOUBLE:
		if d, ok := v.(float64); ok {
			return d, nil
		}
		if i, ok := v.(int64); ok {
			return float64(i), nil
		}
		if u, ok := v.(uint64); ok {
			return float64(u), nil
		}
		return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vexpecting double, got %s", mc, valueKind(v))}
	case dpb.FieldDescriptorProto_TYPE_FLOAT:
		if d, ok := v.(float64); ok {
			if (d > math.MaxFloat32 || d < -math.MaxFloat32) && !math.IsInf(d, 1) && !math.IsInf(d, -1) && !math.IsNaN(d) {
				return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vvalue %f is out of range for float", mc, d)}
			}
			return float32(d), nil
		}
		if i, ok := v.(int64); ok {
			return float32(i), nil
		}
		if u, ok := v.(uint64); ok {
			return float32(u), nil
		}
		return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vexpecting float, got %s", mc, valueKind(v))}
	default:
		return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vunrecognized field type: %s", mc, t)}
	}
}
