package desc

import (
	"bytes"
	"fmt"
	"sort"
	"strconv"
	"strings"
	"unicode/utf8"

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

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

// Descriptor is the common interface implemented by all descriptor objects.
type Descriptor interface {
	// GetName returns the name of the object described by the descriptor. This will
	// be a base name that does not include enclosing message names or the package name.
	// For file descriptors, this indicates the path and name to the described file.
	GetName() string
	// GetFullyQualifiedName returns the fully-qualified name of the object described by
	// the descriptor. This will include the package name and any enclosing message names.
	// For file descriptors, this returns the path and name to the described file (same as
	// GetName).
	GetFullyQualifiedName() string
	// GetParent returns the enclosing element in a proto source file. If the described
	// object is a top-level object, this returns the file descriptor. Otherwise, it returns
	// the element in which the described object was declared. File descriptors have no
	// parent and return nil.
	GetParent() Descriptor
	// GetFile returns the file descriptor in which this element was declared. File
	// descriptors return themselves.
	GetFile() *FileDescriptor
	// GetOptions returns the options proto containing options for the described element.
	GetOptions() proto.Message
	// GetSourceInfo returns any source code information that was present in the file
	// descriptor. Source code info is optional. If no source code info is available for
	// the element (including if there is none at all in the file descriptor) then this
	// returns nil
	GetSourceInfo() *dpb.SourceCodeInfo_Location
	// AsProto returns the underlying descriptor proto for this descriptor.
	AsProto() proto.Message
}

type sourceInfoRecomputeFunc = internal.SourceInfoComputeFunc

// FileDescriptor describes a proto source file.
type FileDescriptor struct {
	proto      *dpb.FileDescriptorProto
	symbols    map[string]Descriptor
	deps       []*FileDescriptor
	publicDeps []*FileDescriptor
	weakDeps   []*FileDescriptor
	messages   []*MessageDescriptor
	enums      []*EnumDescriptor
	extensions []*FieldDescriptor
	services   []*ServiceDescriptor
	fieldIndex map[string]map[int32]*FieldDescriptor
	isProto3   bool
	sourceInfo internal.SourceInfoMap
	sourceInfoRecomputeFunc
}

func (fd *FileDescriptor) recomputeSourceInfo() {
	internal.PopulateSourceInfoMap(fd.proto, fd.sourceInfo)
}

func (fd *FileDescriptor) registerField(field *FieldDescriptor) {
	fields := fd.fieldIndex[field.owner.GetFullyQualifiedName()]
	if fields == nil {
		fields = map[int32]*FieldDescriptor{}
		fd.fieldIndex[field.owner.GetFullyQualifiedName()] = fields
	}
	fields[field.GetNumber()] = field
}

// GetName returns the name of the file, as it was given to the protoc invocation
// to compile it, possibly including path (relative to a directory in the proto
// import path).
func (fd *FileDescriptor) GetName() string {
	return fd.proto.GetName()
}

// GetFullyQualifiedName returns the name of the file, same as GetName. It is
// present to satisfy the Descriptor interface.
func (fd *FileDescriptor) GetFullyQualifiedName() string {
	return fd.proto.GetName()
}

// GetPackage returns the name of the package declared in the file.
func (fd *FileDescriptor) GetPackage() string {
	return fd.proto.GetPackage()
}

// GetParent always returns nil: files are the root of descriptor hierarchies.
// Is it present to satisfy the Descriptor interface.
func (fd *FileDescriptor) GetParent() Descriptor {
	return nil
}

// GetFile returns the receiver, which is a file descriptor. This is present
// to satisfy the Descriptor interface.
func (fd *FileDescriptor) GetFile() *FileDescriptor {
	return fd
}

// GetOptions returns the file's options. Most usages will be more interested
// in GetFileOptions, which has a concrete return type. This generic version
// is present to satisfy the Descriptor interface.
func (fd *FileDescriptor) GetOptions() proto.Message {
	return fd.proto.GetOptions()
}

// GetFileOptions returns the file's options.
func (fd *FileDescriptor) GetFileOptions() *dpb.FileOptions {
	return fd.proto.GetOptions()
}

// GetSourceInfo returns nil for files. It is present to satisfy the Descriptor
// interface.
func (fd *FileDescriptor) GetSourceInfo() *dpb.SourceCodeInfo_Location {
	return nil
}

// AsProto returns the underlying descriptor proto. Most usages will be more
// interested in AsFileDescriptorProto, which has a concrete return type. This
// generic version is present to satisfy the Descriptor interface.
func (fd *FileDescriptor) AsProto() proto.Message {
	return fd.proto
}

// AsFileDescriptorProto returns the underlying descriptor proto.
func (fd *FileDescriptor) AsFileDescriptorProto() *dpb.FileDescriptorProto {
	return fd.proto
}

// String returns the underlying descriptor proto, in compact text format.
func (fd *FileDescriptor) String() string {
	return fd.proto.String()
}

// IsProto3 returns true if the file declares a syntax of "proto3".
func (fd *FileDescriptor) IsProto3() bool {
	return fd.isProto3
}

// GetDependencies returns all of this file's dependencies. These correspond to
// import statements in the file.
func (fd *FileDescriptor) GetDependencies() []*FileDescriptor {
	return fd.deps
}

// GetPublicDependencies returns all of this file's public dependencies. These
// correspond to public import statements in the file.
func (fd *FileDescriptor) GetPublicDependencies() []*FileDescriptor {
	return fd.publicDeps
}

// GetWeakDependencies returns all of this file's weak dependencies. These
// correspond to weak import statements in the file.
func (fd *FileDescriptor) GetWeakDependencies() []*FileDescriptor {
	return fd.weakDeps
}

// GetMessageTypes returns all top-level messages declared in this file.
func (fd *FileDescriptor) GetMessageTypes() []*MessageDescriptor {
	return fd.messages
}

// GetEnumTypes returns all top-level enums declared in this file.
func (fd *FileDescriptor) GetEnumTypes() []*EnumDescriptor {
	return fd.enums
}

// GetExtensions returns all top-level extensions declared in this file.
func (fd *FileDescriptor) GetExtensions() []*FieldDescriptor {
	return fd.extensions
}

// GetServices returns all services declared in this file.
func (fd *FileDescriptor) GetServices() []*ServiceDescriptor {
	return fd.services
}

// FindSymbol returns the descriptor contained within this file for the
// element with the given fully-qualified symbol name. If no such element
// exists then this method returns nil.
func (fd *FileDescriptor) FindSymbol(symbol string) Descriptor {
	if symbol[0] == '.' {
		symbol = symbol[1:]
	}
	return fd.symbols[symbol]
}

// FindMessage finds the message with the given fully-qualified name. If no
// such element exists in this file then nil is returned.
func (fd *FileDescriptor) FindMessage(msgName string) *MessageDescriptor {
	if md, ok := fd.symbols[msgName].(*MessageDescriptor); ok {
		return md
	} else {
		return nil
	}
}

// FindEnum finds the enum with the given fully-qualified name. If no such
// element exists in this file then nil is returned.
func (fd *FileDescriptor) FindEnum(enumName string) *EnumDescriptor {
	if ed, ok := fd.symbols[enumName].(*EnumDescriptor); ok {
		return ed
	} else {
		return nil
	}
}

// FindService finds the service with the given fully-qualified name. If no
// such element exists in this file then nil is returned.
func (fd *FileDescriptor) FindService(serviceName string) *ServiceDescriptor {
	if sd, ok := fd.symbols[serviceName].(*ServiceDescriptor); ok {
		return sd
	} else {
		return nil
	}
}

// FindExtension finds the extension field for the given extended type name and
// tag number. If no such element exists in this file then nil is returned.
func (fd *FileDescriptor) FindExtension(extendeeName string, tagNumber int32) *FieldDescriptor {
	if exd, ok := fd.fieldIndex[extendeeName][tagNumber]; ok && exd.IsExtension() {
		return exd
	} else {
		return nil
	}
}

// FindExtensionByName finds the extension field with the given fully-qualified
// name. If no such element exists in this file then nil is returned.
func (fd *FileDescriptor) FindExtensionByName(extName string) *FieldDescriptor {
	if exd, ok := fd.symbols[extName].(*FieldDescriptor); ok && exd.IsExtension() {
		return exd
	} else {
		return nil
	}
}

// MessageDescriptor describes a protocol buffer message.
type MessageDescriptor struct {
	proto          *dpb.DescriptorProto
	parent         Descriptor
	file           *FileDescriptor
	fields         []*FieldDescriptor
	nested         []*MessageDescriptor
	enums          []*EnumDescriptor
	extensions     []*FieldDescriptor
	oneOfs         []*OneOfDescriptor
	extRanges      extRanges
	fqn            string
	sourceInfoPath []int32
	jsonNames      jsonNameMap
	isProto3       bool
	isMapEntry     bool
}

func createMessageDescriptor(fd *FileDescriptor, parent Descriptor, enclosing string, md *dpb.DescriptorProto, symbols map[string]Descriptor) (*MessageDescriptor, string) {
	msgName := merge(enclosing, md.GetName())
	ret := &MessageDescriptor{proto: md, parent: parent, file: fd, fqn: msgName}
	for _, f := range md.GetField() {
		fld, n := createFieldDescriptor(fd, ret, msgName, f)
		symbols[n] = fld
		ret.fields = append(ret.fields, fld)
	}
	for _, nm := range md.NestedType {
		nmd, n := createMessageDescriptor(fd, ret, msgName, nm, symbols)
		symbols[n] = nmd
		ret.nested = append(ret.nested, nmd)
	}
	for _, e := range md.EnumType {
		ed, n := createEnumDescriptor(fd, ret, msgName, e, symbols)
		symbols[n] = ed
		ret.enums = append(ret.enums, ed)
	}
	for _, ex := range md.GetExtension() {
		exd, n := createFieldDescriptor(fd, ret, msgName, ex)
		symbols[n] = exd
		ret.extensions = append(ret.extensions, exd)
	}
	for i, o := range md.GetOneofDecl() {
		od, n := createOneOfDescriptor(fd, ret, i, msgName, o)
		symbols[n] = od
		ret.oneOfs = append(ret.oneOfs, od)
	}
	for _, r := range md.GetExtensionRange() {
		// proto.ExtensionRange is inclusive (and that's how extension ranges are defined in code).
		// but protoc converts range to exclusive end in descriptor, so we must convert back
		end := r.GetEnd() - 1
		ret.extRanges = append(ret.extRanges, proto.ExtensionRange{
			Start: r.GetStart(),
			End:   end})
	}
	sort.Sort(ret.extRanges)
	ret.isProto3 = fd.isProto3
	ret.isMapEntry = md.GetOptions().GetMapEntry() &&
		len(ret.fields) == 2 &&
		ret.fields[0].GetNumber() == 1 &&
		ret.fields[1].GetNumber() == 2

	return ret, msgName
}

func (md *MessageDescriptor) resolve(path []int32, scopes []scope) error {
	md.sourceInfoPath = append([]int32(nil), path...) // defensive copy
	path = append(path, internal.Message_nestedMessagesTag)
	scopes = append(scopes, messageScope(md))
	for i, nmd := range md.nested {
		if err := nmd.resolve(append(path, int32(i)), scopes); err != nil {
			return err
		}
	}
	path[len(path)-1] = internal.Message_enumsTag
	for i, ed := range md.enums {
		ed.resolve(append(path, int32(i)))
	}
	path[len(path)-1] = internal.Message_fieldsTag
	for i, fld := range md.fields {
		if err := fld.resolve(append(path, int32(i)), scopes); err != nil {
			return err
		}
	}
	path[len(path)-1] = internal.Message_extensionsTag
	for i, exd := range md.extensions {
		if err := exd.resolve(append(path, int32(i)), scopes); err != nil {
			return err
		}
	}
	path[len(path)-1] = internal.Message_oneOfsTag
	for i, od := range md.oneOfs {
		od.resolve(append(path, int32(i)))
	}
	return nil
}

// GetName returns the simple (unqualified) name of the message.
func (md *MessageDescriptor) GetName() string {
	return md.proto.GetName()
}

// GetFullyQualifiedName returns the fully qualified name of the message. This
// includes the package name (if there is one) as well as the names of any
// enclosing messages.
func (md *MessageDescriptor) GetFullyQualifiedName() string {
	return md.fqn
}

// GetParent returns the message's enclosing descriptor. For top-level messages,
// this will be a file descriptor. Otherwise it will be the descriptor for the
// enclosing message.
func (md *MessageDescriptor) GetParent() Descriptor {
	return md.parent
}

// GetFile returns the descriptor for the file in which this message is defined.
func (md *MessageDescriptor) GetFile() *FileDescriptor {
	return md.file
}

// GetOptions returns the message's options. Most usages will be more interested
// in GetMessageOptions, which has a concrete return type. This generic version
// is present to satisfy the Descriptor interface.
func (md *MessageDescriptor) GetOptions() proto.Message {
	return md.proto.GetOptions()
}

// GetMessageOptions returns the message's options.
func (md *MessageDescriptor) GetMessageOptions() *dpb.MessageOptions {
	return md.proto.GetOptions()
}

// GetSourceInfo returns source info for the message, if present in the
// descriptor. Not all descriptors will contain source info. If non-nil, the
// returned info contains information about the location in the file where the
// message was defined and also contains comments associated with the message
// definition.
func (md *MessageDescriptor) GetSourceInfo() *dpb.SourceCodeInfo_Location {
	return md.file.sourceInfo.Get(md.sourceInfoPath)
}

// AsProto returns the underlying descriptor proto. Most usages will be more
// interested in AsDescriptorProto, which has a concrete return type. This
// generic version is present to satisfy the Descriptor interface.
func (md *MessageDescriptor) AsProto() proto.Message {
	return md.proto
}

// AsDescriptorProto returns the underlying descriptor proto.
func (md *MessageDescriptor) AsDescriptorProto() *dpb.DescriptorProto {
	return md.proto
}

// String returns the underlying descriptor proto, in compact text format.
func (md *MessageDescriptor) String() string {
	return md.proto.String()
}

// IsMapEntry returns true if this is a synthetic message type that represents an entry
// in a map field.
func (md *MessageDescriptor) IsMapEntry() bool {
	return md.isMapEntry
}

// GetFields returns all of the fields for this message.
func (md *MessageDescriptor) GetFields() []*FieldDescriptor {
	return md.fields
}

// GetNestedMessageTypes returns all of the message types declared inside this message.
func (md *MessageDescriptor) GetNestedMessageTypes() []*MessageDescriptor {
	return md.nested
}

// GetNestedEnumTypes returns all of the enums declared inside this message.
func (md *MessageDescriptor) GetNestedEnumTypes() []*EnumDescriptor {
	return md.enums
}

// GetNestedExtensions returns all of the extensions declared inside this message.
func (md *MessageDescriptor) GetNestedExtensions() []*FieldDescriptor {
	return md.extensions
}

// GetOneOfs returns all of the one-of field sets declared inside this message.
func (md *MessageDescriptor) GetOneOfs() []*OneOfDescriptor {
	return md.oneOfs
}

// IsProto3 returns true if the file in which this message is defined declares a syntax of "proto3".
func (md *MessageDescriptor) IsProto3() bool {
	return md.isProto3
}

// GetExtensionRanges returns the ranges of extension field numbers for this message.
func (md *MessageDescriptor) GetExtensionRanges() []proto.ExtensionRange {
	return md.extRanges
}

// IsExtendable returns true if this message has any extension ranges.
func (md *MessageDescriptor) IsExtendable() bool {
	return len(md.extRanges) > 0
}

// IsExtension returns true if the given tag number is within any of this message's
// extension ranges.
func (md *MessageDescriptor) IsExtension(tagNumber int32) bool {
	return md.extRanges.IsExtension(tagNumber)
}

type extRanges []proto.ExtensionRange

func (er extRanges) String() string {
	var buf bytes.Buffer
	first := true
	for _, r := range er {
		if first {
			first = false
		} else {
			buf.WriteString(",")
		}
		fmt.Fprintf(&buf, "%d..%d", r.Start, r.End)
	}
	return buf.String()
}

func (er extRanges) IsExtension(tagNumber int32) bool {
	i := sort.Search(len(er), func(i int) bool { return er[i].End >= tagNumber })
	return i < len(er) && tagNumber >= er[i].Start
}

func (er extRanges) Len() int {
	return len(er)
}

func (er extRanges) Less(i, j int) bool {
	return er[i].Start < er[j].Start
}

func (er extRanges) Swap(i, j int) {
	er[i], er[j] = er[j], er[i]
}

// FindFieldByName finds the field with the given name. If no such field exists
// then nil is returned. Only regular fields are returned, not extensions.
func (md *MessageDescriptor) FindFieldByName(fieldName string) *FieldDescriptor {
	fqn := fmt.Sprintf("%s.%s", md.fqn, fieldName)
	if fd, ok := md.file.symbols[fqn].(*FieldDescriptor); ok && !fd.IsExtension() {
		return fd
	} else {
		return nil
	}
}

// FindFieldByNumber finds the field with the given tag number. If no such field
// exists then nil is returned. Only regular fields are returned, not extensions.
func (md *MessageDescriptor) FindFieldByNumber(tagNumber int32) *FieldDescriptor {
	if fd, ok := md.file.fieldIndex[md.fqn][tagNumber]; ok && !fd.IsExtension() {
		return fd
	} else {
		return nil
	}
}

// FieldDescriptor describes a field of a protocol buffer message.
type FieldDescriptor struct {
	proto          *dpb.FieldDescriptorProto
	parent         Descriptor
	owner          *MessageDescriptor
	file           *FileDescriptor
	oneOf          *OneOfDescriptor
	msgType        *MessageDescriptor
	enumType       *EnumDescriptor
	fqn            string
	sourceInfoPath []int32
	def            memoizedDefault
	isMap          bool
}

func createFieldDescriptor(fd *FileDescriptor, parent Descriptor, enclosing string, fld *dpb.FieldDescriptorProto) (*FieldDescriptor, string) {
	fldName := merge(enclosing, fld.GetName())
	ret := &FieldDescriptor{proto: fld, parent: parent, file: fd, fqn: fldName}
	if fld.GetExtendee() == "" {
		ret.owner = parent.(*MessageDescriptor)
	}
	// owner for extensions, field type (be it message or enum), and one-ofs get resolved later
	return ret, fldName
}

func (fd *FieldDescriptor) resolve(path []int32, scopes []scope) error {
	if fd.proto.OneofIndex != nil && fd.oneOf == nil {
		return fmt.Errorf("could not link field %s to one-of index %d", fd.fqn, *fd.proto.OneofIndex)
	}
	fd.sourceInfoPath = append([]int32(nil), path...) // defensive copy
	if fd.proto.GetType() == dpb.FieldDescriptorProto_TYPE_ENUM {
		if desc, err := resolve(fd.file, fd.proto.GetTypeName(), scopes); err != nil {
			return err
		} else {
			fd.enumType = desc.(*EnumDescriptor)
		}
	}
	if fd.proto.GetType() == dpb.FieldDescriptorProto_TYPE_MESSAGE || fd.proto.GetType() == dpb.FieldDescriptorProto_TYPE_GROUP {
		if desc, err := resolve(fd.file, fd.proto.GetTypeName(), scopes); err != nil {
			return err
		} else {
			fd.msgType = desc.(*MessageDescriptor)
		}
	}
	if fd.proto.GetExtendee() != "" {
		if desc, err := resolve(fd.file, fd.proto.GetExtendee(), scopes); err != nil {
			return err
		} else {
			fd.owner = desc.(*MessageDescriptor)
		}
	}
	fd.file.registerField(fd)
	fd.isMap = fd.proto.GetLabel() == dpb.FieldDescriptorProto_LABEL_REPEATED &&
		fd.proto.GetType() == dpb.FieldDescriptorProto_TYPE_MESSAGE &&
		fd.GetMessageType().IsMapEntry()
	return nil
}

func (fd *FieldDescriptor) determineDefault() interface{} {
	if fd.IsMap() {
		return map[interface{}]interface{}(nil)
	} else if fd.IsRepeated() {
		return []interface{}(nil)
	} else if fd.msgType != nil {
		return nil
	}

	proto3 := fd.file.isProto3
	if !proto3 {
		def := fd.AsFieldDescriptorProto().GetDefaultValue()
		if def != "" {
			ret := parseDefaultValue(fd, def)
			if ret != nil {
				return ret
			}
			// if we can't parse default value, fall-through to return normal default...
		}
	}

	switch fd.GetType() {
	case dpb.FieldDescriptorProto_TYPE_FIXED32,
		dpb.FieldDescriptorProto_TYPE_UINT32:
		return uint32(0)
	case dpb.FieldDescriptorProto_TYPE_SFIXED32,
		dpb.FieldDescriptorProto_TYPE_INT32,
		dpb.FieldDescriptorProto_TYPE_SINT32:
		return int32(0)
	case dpb.FieldDescriptorProto_TYPE_FIXED64,
		dpb.FieldDescriptorProto_TYPE_UINT64:
		return uint64(0)
	case dpb.FieldDescriptorProto_TYPE_SFIXED64,
		dpb.FieldDescriptorProto_TYPE_INT64,
		dpb.FieldDescriptorProto_TYPE_SINT64:
		return int64(0)
	case dpb.FieldDescriptorProto_TYPE_FLOAT:
		return float32(0.0)
	case dpb.FieldDescriptorProto_TYPE_DOUBLE:
		return float64(0.0)
	case dpb.FieldDescriptorProto_TYPE_BOOL:
		return false
	case dpb.FieldDescriptorProto_TYPE_BYTES:
		return []byte(nil)
	case dpb.FieldDescriptorProto_TYPE_STRING:
		return ""
	case dpb.FieldDescriptorProto_TYPE_ENUM:
		if proto3 {
			return int32(0)
		}
		enumVals := fd.GetEnumType().GetValues()
		if len(enumVals) > 0 {
			return enumVals[0].GetNumber()
		} else {
			return int32(0) // WTF?
		}
	default:
		panic(fmt.Sprintf("Unknown field type: %v", fd.GetType()))
	}
}

func parseDefaultValue(fd *FieldDescriptor, val string) interface{} {
	switch fd.GetType() {
	case dpb.FieldDescriptorProto_TYPE_ENUM:
		vd := fd.GetEnumType().FindValueByName(val)
		if vd != nil {
			return vd.GetNumber()
		}
		return nil
	case dpb.FieldDescriptorProto_TYPE_BOOL:
		if val == "true" {
			return true
		} else if val == "false" {
			return false
		}
		return nil
	case dpb.FieldDescriptorProto_TYPE_BYTES:
		return []byte(unescape(val))
	case dpb.FieldDescriptorProto_TYPE_STRING:
		return val
	case dpb.FieldDescriptorProto_TYPE_FLOAT:
		if f, err := strconv.ParseFloat(val, 32); err == nil {
			return float32(f)
		} else {
			return float32(0)
		}
	case dpb.FieldDescriptorProto_TYPE_DOUBLE:
		if f, err := strconv.ParseFloat(val, 64); err == nil {
			return f
		} else {
			return float64(0)
		}
	case dpb.FieldDescriptorProto_TYPE_INT32,
		dpb.FieldDescriptorProto_TYPE_SINT32,
		dpb.FieldDescriptorProto_TYPE_SFIXED32:
		if i, err := strconv.ParseInt(val, 10, 32); err == nil {
			return int32(i)
		} else {
			return int32(0)
		}
	case dpb.FieldDescriptorProto_TYPE_UINT32,
		dpb.FieldDescriptorProto_TYPE_FIXED32:
		if i, err := strconv.ParseUint(val, 10, 32); err == nil {
			return uint32(i)
		} else {
			return uint32(0)
		}
	case dpb.FieldDescriptorProto_TYPE_INT64,
		dpb.FieldDescriptorProto_TYPE_SINT64,
		dpb.FieldDescriptorProto_TYPE_SFIXED64:
		if i, err := strconv.ParseInt(val, 10, 64); err == nil {
			return i
		} else {
			return int64(0)
		}
	case dpb.FieldDescriptorProto_TYPE_UINT64,
		dpb.FieldDescriptorProto_TYPE_FIXED64:
		if i, err := strconv.ParseUint(val, 10, 64); err == nil {
			return i
		} else {
			return uint64(0)
		}
	default:
		return nil
	}
}

func unescape(s string) string {
	// protoc encodes default values for 'bytes' fields using C escaping,
	// so this function reverses that escaping
	out := make([]byte, 0, len(s))
	var buf [4]byte
	for len(s) > 0 {
		if s[0] != '\\' || len(s) < 2 {
			// not escape sequence, or too short to be well-formed escape
			out = append(out, s[0])
			s = s[1:]
		} else if s[1] == 'x' || s[1] == 'X' {
			n := matchPrefix(s[2:], 2, isHex)
			if n == 0 {
				// bad escape
				out = append(out, s[:2]...)
				s = s[2:]
			} else {
				c, err := strconv.ParseUint(s[2:2+n], 16, 8)
				if err != nil {
					// shouldn't really happen...
					out = append(out, s[:2+n]...)
				} else {
					out = append(out, byte(c))
				}
				s = s[2+n:]
			}
		} else if s[1] >= '0' && s[1] <= '7' {
			n := 1 + matchPrefix(s[2:], 2, isOctal)
			c, err := strconv.ParseUint(s[1:1+n], 8, 8)
			if err != nil || c > 0xff {
				out = append(out, s[:1+n]...)
			} else {
				out = append(out, byte(c))
			}
			s = s[1+n:]
		} else if s[1] == 'u' {
			if len(s) < 6 {
				// bad escape
				out = append(out, s...)
				s = s[len(s):]
			} else {
				c, err := strconv.ParseUint(s[2:6], 16, 16)
				if err != nil {
					// bad escape
					out = append(out, s[:6]...)
				} else {
					w := utf8.EncodeRune(buf[:], rune(c))
					out = append(out, buf[:w]...)
				}
				s = s[6:]
			}
		} else if s[1] == 'U' {
			if len(s) < 10 {
				// bad escape
				out = append(out, s...)
				s = s[len(s):]
			} else {
				c, err := strconv.ParseUint(s[2:10], 16, 32)
				if err != nil || c > 0x10ffff {
					// bad escape
					out = append(out, s[:10]...)
				} else {
					w := utf8.EncodeRune(buf[:], rune(c))
					out = append(out, buf[:w]...)
				}
				s = s[10:]
			}
		} else {
			switch s[1] {
			case 'a':
				out = append(out, '\a')
			case 'b':
				out = append(out, '\b')
			case 'f':
				out = append(out, '\f')
			case 'n':
				out = append(out, '\n')
			case 'r':
				out = append(out, '\r')
			case 't':
				out = append(out, '\t')
			case 'v':
				out = append(out, '\v')
			case '\\':
				out = append(out, '\\')
			case '\'':
				out = append(out, '\'')
			case '"':
				out = append(out, '"')
			case '?':
				out = append(out, '?')
			default:
				// invalid escape, just copy it as-is
				out = append(out, s[:2]...)
			}
			s = s[2:]
		}
	}
	return string(out)
}

func isOctal(b byte) bool { return b >= '0' && b <= '7' }
func isHex(b byte) bool {
	return (b >= '0' && b <= '9') || (b >= 'a' && b <= 'f') || (b >= 'A' && b <= 'F')
}
func matchPrefix(s string, limit int, fn func(byte) bool) int {
	l := len(s)
	if l > limit {
		l = limit
	}
	i := 0
	for ; i < l; i++ {
		if !fn(s[i]) {
			return i
		}
	}
	return i
}

// GetName returns the name of the field.
func (fd *FieldDescriptor) GetName() string {
	return fd.proto.GetName()
}

// GetNumber returns the tag number of this field.
func (fd *FieldDescriptor) GetNumber() int32 {
	return fd.proto.GetNumber()
}

// GetFullyQualifiedName returns the fully qualified name of the field. Unlike
// GetName, this includes fully qualified name of the enclosing message for
// regular fields.
//
// For extension fields, this includes the package (if there is one) as well as
// any enclosing messages. The package and/or enclosing messages are for where
// the extension is defined, not the message it extends.
//
// If this field is part of a one-of, the fully qualified name does *not*
// include the name of the one-of, only of the enclosing message.
func (fd *FieldDescriptor) GetFullyQualifiedName() string {
	return fd.fqn
}

// GetParent returns the fields's enclosing descriptor. For normal
// (non-extension) fields, this is the enclosing message. For extensions, this
// is the descriptor in which the extension is defined, not the message that is
// extended. The parent for an extension may be a file descriptor or a message,
// depending on where the extension is defined.
func (fd *FieldDescriptor) GetParent() Descriptor {
	return fd.parent
}

// GetFile returns the descriptor for the file in which this field is defined.
func (fd *FieldDescriptor) GetFile() *FileDescriptor {
	return fd.file
}

// GetOptions returns the field's options. Most usages will be more interested
// in GetFieldOptions, which has a concrete return type. This generic version
// is present to satisfy the Descriptor interface.
func (fd *FieldDescriptor) GetOptions() proto.Message {
	return fd.proto.GetOptions()
}

// GetFieldOptions returns the field's options.
func (fd *FieldDescriptor) GetFieldOptions() *dpb.FieldOptions {
	return fd.proto.GetOptions()
}

// GetSourceInfo returns source info for the field, if present in the
// descriptor. Not all descriptors will contain source info. If non-nil, the
// returned info contains information about the location in the file where the
// field was defined and also contains comments associated with the field
// definition.
func (fd *FieldDescriptor) GetSourceInfo() *dpb.SourceCodeInfo_Location {
	return fd.file.sourceInfo.Get(fd.sourceInfoPath)
}

// AsProto returns the underlying descriptor proto. Most usages will be more
// interested in AsFieldDescriptorProto, which has a concrete return type. This
// generic version is present to satisfy the Descriptor interface.
func (fd *FieldDescriptor) AsProto() proto.Message {
	return fd.proto
}

// AsFieldDescriptorProto returns the underlying descriptor proto.
func (fd *FieldDescriptor) AsFieldDescriptorProto() *dpb.FieldDescriptorProto {
	return fd.proto
}

// String returns the underlying descriptor proto, in compact text format.
func (fd *FieldDescriptor) String() string {
	return fd.proto.String()
}

// GetJSONName returns the name of the field as referenced in the message's JSON
// format.
func (fd *FieldDescriptor) GetJSONName() string {
	if jsonName := fd.proto.GetJsonName(); jsonName != "" {
		return jsonName
	}
	return fd.proto.GetName()
}

// GetFullyQualifiedJSONName returns the JSON format name (same as GetJSONName),
// but includes the fully qualified name of the enclosing message.
//
// If the field is an extension, it will return the package name (if there is
// one) as well as the names of any enclosing messages. The package and/or
// enclosing messages are for where the extension is defined, not the message it
// extends.
func (fd *FieldDescriptor) GetFullyQualifiedJSONName() string {
	parent := fd.GetParent()
	switch parent := parent.(type) {
	case *FileDescriptor:
		pkg := parent.GetPackage()
		if pkg == "" {
			return fd.GetJSONName()
		}
		return fmt.Sprintf("%s.%s", pkg, fd.GetJSONName())
	default:
		return fmt.Sprintf("%s.%s", parent.GetFullyQualifiedName(), fd.GetJSONName())
	}
}

// GetOwner returns the message type that this field belongs to. If this is a normal
// field then this is the same as GetParent. But for extensions, this will be the
// extendee message whereas GetParent refers to where the extension was declared.
func (fd *FieldDescriptor) GetOwner() *MessageDescriptor {
	return fd.owner
}

// IsExtension returns true if this is an extension field.
func (fd *FieldDescriptor) IsExtension() bool {
	return fd.proto.GetExtendee() != ""
}

// GetOneOf returns the one-of field set to which this field belongs. If this field
// is not part of a one-of then this method returns nil.
func (fd *FieldDescriptor) GetOneOf() *OneOfDescriptor {
	return fd.oneOf
}

// GetType returns the type of this field. If the type indicates an enum, the
// enum type can be queried via GetEnumType. If the type indicates a message, the
// message type can be queried via GetMessageType.
func (fd *FieldDescriptor) GetType() dpb.FieldDescriptorProto_Type {
	return fd.proto.GetType()
}

// GetLabel returns the label for this field. The label can be required (proto2-only),
// optional (default for proto3), or required.
func (fd *FieldDescriptor) GetLabel() dpb.FieldDescriptorProto_Label {
	return fd.proto.GetLabel()
}

// IsRequired returns true if this field has the "required" label.
func (fd *FieldDescriptor) IsRequired() bool {
	return fd.proto.GetLabel() == dpb.FieldDescriptorProto_LABEL_REQUIRED
}

// IsRepeated returns true if this field has the "repeated" label.
func (fd *FieldDescriptor) IsRepeated() bool {
	return fd.proto.GetLabel() == dpb.FieldDescriptorProto_LABEL_REPEATED
}

// IsMap returns true if this is a map field. If so, it will have the "repeated"
// label its type will be a message that represents a map entry. The map entry
// message will have exactly two fields: tag #1 is the key and tag #2 is the value.
func (fd *FieldDescriptor) IsMap() bool {
	return fd.isMap
}

// GetMapKeyType returns the type of the key field if this is a map field. If it is
// not a map field, nil is returned.
func (fd *FieldDescriptor) GetMapKeyType() *FieldDescriptor {
	if fd.isMap {
		return fd.msgType.FindFieldByNumber(int32(1))
	}
	return nil
}

// GetMapValueType returns the type of the value field if this is a map field. If it
// is not a map field, nil is returned.
func (fd *FieldDescriptor) GetMapValueType() *FieldDescriptor {
	if fd.isMap {
		return fd.msgType.FindFieldByNumber(int32(2))
	}
	return nil
}

// GetMessageType returns the type of this field if it is a message type. If
// this field is not a message type, it returns nil.
func (fd *FieldDescriptor) GetMessageType() *MessageDescriptor {
	return fd.msgType
}

// GetEnumType returns the type of this field if it is an enum type. If this
// field is not an enum type, it returns nil.
func (fd *FieldDescriptor) GetEnumType() *EnumDescriptor {
	return fd.enumType
}

// GetDefaultValue returns the default value for this field.
//
// If this field represents a message type, this method always returns nil (even though
// for proto2 files, the default value should be a default instance of the message type).
// If the field represents an enum type, this method returns an int32 corresponding to the
// enum value. If this field is a map, it returns a nil map[interface{}]interface{}. If
// this field is repeated (and not a map), it returns a nil []interface{}.
//
// Otherwise, it returns the declared default value for the field or a zero value, if no
// default is declared or if the file is proto3. The type of said return value corresponds
// to the type of the field:
//  +-------------------------+-----------+
//  |       Declared Type     |  Go Type  |
//  +-------------------------+-----------+
//  | int32, sint32, sfixed32 | int32     |
//  | int64, sint64, sfixed64 | int64     |
//  | uint32, fixed32         | uint32    |
//  | uint64, fixed64         | uint64    |
//  | float                   | float32   |
//  | double                  | double32  |
//  | bool                    | bool      |
//  | string                  | string    |
//  | bytes                   | []byte    |
//  +-------------------------+-----------+
func (fd *FieldDescriptor) GetDefaultValue() interface{} {
	return fd.getDefaultValue()
}

// EnumDescriptor describes an enum declared in a proto file.
type EnumDescriptor struct {
	proto          *dpb.EnumDescriptorProto
	parent         Descriptor
	file           *FileDescriptor
	values         []*EnumValueDescriptor
	valuesByNum    sortedValues
	fqn            string
	sourceInfoPath []int32
}

func createEnumDescriptor(fd *FileDescriptor, parent Descriptor, enclosing string, ed *dpb.EnumDescriptorProto, symbols map[string]Descriptor) (*EnumDescriptor, string) {
	enumName := merge(enclosing, ed.GetName())
	ret := &EnumDescriptor{proto: ed, parent: parent, file: fd, fqn: enumName}
	for _, ev := range ed.GetValue() {
		evd, n := createEnumValueDescriptor(fd, ret, enumName, ev)
		symbols[n] = evd
		ret.values = append(ret.values, evd)
	}
	if len(ret.values) > 0 {
		ret.valuesByNum = make(sortedValues, len(ret.values))
		copy(ret.valuesByNum, ret.values)
		sort.Stable(ret.valuesByNum)
	}
	return ret, enumName
}

type sortedValues []*EnumValueDescriptor

func (sv sortedValues) Len() int {
	return len(sv)
}

func (sv sortedValues) Less(i, j int) bool {
	return sv[i].GetNumber() < sv[j].GetNumber()
}

func (sv sortedValues) Swap(i, j int) {
	sv[i], sv[j] = sv[j], sv[i]
}

func (ed *EnumDescriptor) resolve(path []int32) {
	ed.sourceInfoPath = append([]int32(nil), path...) // defensive copy
	path = append(path, internal.Enum_valuesTag)
	for i, evd := range ed.values {
		evd.resolve(append(path, int32(i)))
	}
}

// GetName returns the simple (unqualified) name of the enum type.
func (ed *EnumDescriptor) GetName() string {
	return ed.proto.GetName()
}

// GetFullyQualifiedName returns the fully qualified name of the enum type.
// This includes the package name (if there is one) as well as the names of any
// enclosing messages.
func (ed *EnumDescriptor) GetFullyQualifiedName() string {
	return ed.fqn
}

// GetParent returns the enum type's enclosing descriptor. For top-level enums,
// this will be a file descriptor. Otherwise it will be the descriptor for the
// enclosing message.
func (ed *EnumDescriptor) GetParent() Descriptor {
	return ed.parent
}

// GetFile returns the descriptor for the file in which this enum is defined.
func (ed *EnumDescriptor) GetFile() *FileDescriptor {
	return ed.file
}

// GetOptions returns the enum type's options. Most usages will be more
// interested in GetEnumOptions, which has a concrete return type. This generic
// version is present to satisfy the Descriptor interface.
func (ed *EnumDescriptor) GetOptions() proto.Message {
	return ed.proto.GetOptions()
}

// GetEnumOptions returns the enum type's options.
func (ed *EnumDescriptor) GetEnumOptions() *dpb.EnumOptions {
	return ed.proto.GetOptions()
}

// GetSourceInfo returns source info for the enum type, if present in the
// descriptor. Not all descriptors will contain source info. If non-nil, the
// returned info contains information about the location in the file where the
// enum type was defined and also contains comments associated with the enum
// definition.
func (ed *EnumDescriptor) GetSourceInfo() *dpb.SourceCodeInfo_Location {
	return ed.file.sourceInfo.Get(ed.sourceInfoPath)
}

// AsProto returns the underlying descriptor proto. Most usages will be more
// interested in AsEnumDescriptorProto, which has a concrete return type. This
// generic version is present to satisfy the Descriptor interface.
func (ed *EnumDescriptor) AsProto() proto.Message {
	return ed.proto
}

// AsEnumDescriptorProto returns the underlying descriptor proto.
func (ed *EnumDescriptor) AsEnumDescriptorProto() *dpb.EnumDescriptorProto {
	return ed.proto
}

// String returns the underlying descriptor proto, in compact text format.
func (ed *EnumDescriptor) String() string {
	return ed.proto.String()
}

// GetValues returns all of the allowed values defined for this enum.
func (ed *EnumDescriptor) GetValues() []*EnumValueDescriptor {
	return ed.values
}

// FindValueByName finds the enum value with the given name. If no such value exists
// then nil is returned.
func (ed *EnumDescriptor) FindValueByName(name string) *EnumValueDescriptor {
	fqn := fmt.Sprintf("%s.%s", ed.fqn, name)
	if vd, ok := ed.file.symbols[fqn].(*EnumValueDescriptor); ok {
		return vd
	} else {
		return nil
	}
}

// FindValueByNumber finds the value with the given numeric value. If no such value
// exists then nil is returned. If aliases are allowed and multiple values have the
// given number, the first declared value is returned.
func (ed *EnumDescriptor) FindValueByNumber(num int32) *EnumValueDescriptor {
	index := sort.Search(len(ed.valuesByNum), func(i int) bool { return ed.valuesByNum[i].GetNumber() >= num })
	if index < len(ed.valuesByNum) {
		vd := ed.valuesByNum[index]
		if vd.GetNumber() == num {
			return vd
		}
	}
	return nil
}

// EnumValueDescriptor describes an allowed value of an enum declared in a proto file.
type EnumValueDescriptor struct {
	proto          *dpb.EnumValueDescriptorProto
	parent         *EnumDescriptor
	file           *FileDescriptor
	fqn            string
	sourceInfoPath []int32
}

func createEnumValueDescriptor(fd *FileDescriptor, parent *EnumDescriptor, enclosing string, evd *dpb.EnumValueDescriptorProto) (*EnumValueDescriptor, string) {
	valName := merge(enclosing, evd.GetName())
	return &EnumValueDescriptor{proto: evd, parent: parent, file: fd, fqn: valName}, valName
}

func (vd *EnumValueDescriptor) resolve(path []int32) {
	vd.sourceInfoPath = append([]int32(nil), path...) // defensive copy
}

// GetName returns the name of the enum value.
func (vd *EnumValueDescriptor) GetName() string {
	return vd.proto.GetName()
}

// GetNumber returns the numeric value associated with this enum value.
func (vd *EnumValueDescriptor) GetNumber() int32 {
	return vd.proto.GetNumber()
}

// GetFullyQualifiedName returns the fully qualified name of the enum value.
// Unlike GetName, this includes fully qualified name of the enclosing enum.
func (vd *EnumValueDescriptor) GetFullyQualifiedName() string {
	return vd.fqn
}

// GetParent returns the descriptor for the enum in which this enum value is
// defined. Most usages will prefer to use GetEnum, which has a concrete return
// type. This more generic method is present to satisfy the Descriptor interface.
func (vd *EnumValueDescriptor) GetParent() Descriptor {
	return vd.parent
}

// GetEnum returns the enum in which this enum value is defined.
func (vd *EnumValueDescriptor) GetEnum() *EnumDescriptor {
	return vd.parent
}

// GetFile returns the descriptor for the file in which this enum value is
// defined.
func (vd *EnumValueDescriptor) GetFile() *FileDescriptor {
	return vd.file
}

// GetOptions returns the enum value's options. Most usages will be more
// interested in GetEnumValueOptions, which has a concrete return type. This
// generic version is present to satisfy the Descriptor interface.
func (vd *EnumValueDescriptor) GetOptions() proto.Message {
	return vd.proto.GetOptions()
}

// GetEnumValueOptions returns the enum value's options.
func (vd *EnumValueDescriptor) GetEnumValueOptions() *dpb.EnumValueOptions {
	return vd.proto.GetOptions()
}

// GetSourceInfo returns source info for the enum value, if present in the
// descriptor. Not all descriptors will contain source info. If non-nil, the
// returned info contains information about the location in the file where the
// enum value was defined and also contains comments associated with the enum
// value definition.
func (vd *EnumValueDescriptor) GetSourceInfo() *dpb.SourceCodeInfo_Location {
	return vd.file.sourceInfo.Get(vd.sourceInfoPath)
}

// AsProto returns the underlying descriptor proto. Most usages will be more
// interested in AsEnumValueDescriptorProto, which has a concrete return type.
// This generic version is present to satisfy the Descriptor interface.
func (vd *EnumValueDescriptor) AsProto() proto.Message {
	return vd.proto
}

// AsEnumValueDescriptorProto returns the underlying descriptor proto.
func (vd *EnumValueDescriptor) AsEnumValueDescriptorProto() *dpb.EnumValueDescriptorProto {
	return vd.proto
}

// String returns the underlying descriptor proto, in compact text format.
func (vd *EnumValueDescriptor) String() string {
	return vd.proto.String()
}

// ServiceDescriptor describes an RPC service declared in a proto file.
type ServiceDescriptor struct {
	proto          *dpb.ServiceDescriptorProto
	file           *FileDescriptor
	methods        []*MethodDescriptor
	fqn            string
	sourceInfoPath []int32
}

func createServiceDescriptor(fd *FileDescriptor, enclosing string, sd *dpb.ServiceDescriptorProto, symbols map[string]Descriptor) (*ServiceDescriptor, string) {
	serviceName := merge(enclosing, sd.GetName())
	ret := &ServiceDescriptor{proto: sd, file: fd, fqn: serviceName}
	for _, m := range sd.GetMethod() {
		md, n := createMethodDescriptor(fd, ret, serviceName, m)
		symbols[n] = md
		ret.methods = append(ret.methods, md)
	}
	return ret, serviceName
}

func (sd *ServiceDescriptor) resolve(path []int32, scopes []scope) error {
	sd.sourceInfoPath = append([]int32(nil), path...) // defensive copy
	path = append(path, internal.Service_methodsTag)
	for i, md := range sd.methods {
		if err := md.resolve(append(path, int32(i)), scopes); err != nil {
			return err
		}
	}
	return nil
}

// GetName returns the simple (unqualified) name of the service.
func (sd *ServiceDescriptor) GetName() string {
	return sd.proto.GetName()
}

// GetFullyQualifiedName returns the fully qualified name of the service. This
// includes the package name (if there is one).
func (sd *ServiceDescriptor) GetFullyQualifiedName() string {
	return sd.fqn
}

// GetParent returns the descriptor for the file in which this service is
// defined. Most usages will prefer to use GetFile, which has a concrete return
// type. This more generic method is present to satisfy the Descriptor interface.
func (sd *ServiceDescriptor) GetParent() Descriptor {
	return sd.file
}

// GetFile returns the descriptor for the file in which this service is defined.
func (sd *ServiceDescriptor) GetFile() *FileDescriptor {
	return sd.file
}

// GetOptions returns the service's options. Most usages will be more interested
// in GetServiceOptions, which has a concrete return type. This generic version
// is present to satisfy the Descriptor interface.
func (sd *ServiceDescriptor) GetOptions() proto.Message {
	return sd.proto.GetOptions()
}

// GetServiceOptions returns the service's options.
func (sd *ServiceDescriptor) GetServiceOptions() *dpb.ServiceOptions {
	return sd.proto.GetOptions()
}

// GetSourceInfo returns source info for the service, if present in the
// descriptor. Not all descriptors will contain source info. If non-nil, the
// returned info contains information about the location in the file where the
// service was defined and also contains comments associated with the service
// definition.
func (sd *ServiceDescriptor) GetSourceInfo() *dpb.SourceCodeInfo_Location {
	return sd.file.sourceInfo.Get(sd.sourceInfoPath)
}

// AsProto returns the underlying descriptor proto. Most usages will be more
// interested in AsServiceDescriptorProto, which has a concrete return type.
// This generic version is present to satisfy the Descriptor interface.
func (sd *ServiceDescriptor) AsProto() proto.Message {
	return sd.proto
}

// AsServiceDescriptorProto returns the underlying descriptor proto.
func (sd *ServiceDescriptor) AsServiceDescriptorProto() *dpb.ServiceDescriptorProto {
	return sd.proto
}

// String returns the underlying descriptor proto, in compact text format.
func (sd *ServiceDescriptor) String() string {
	return sd.proto.String()
}

// GetMethods returns all of the RPC methods for this service.
func (sd *ServiceDescriptor) GetMethods() []*MethodDescriptor {
	return sd.methods
}

// FindMethodByName finds the method with the given name. If no such method exists
// then nil is returned.
func (sd *ServiceDescriptor) FindMethodByName(name string) *MethodDescriptor {
	fqn := fmt.Sprintf("%s.%s", sd.fqn, name)
	if md, ok := sd.file.symbols[fqn].(*MethodDescriptor); ok {
		return md
	} else {
		return nil
	}
}

// MethodDescriptor describes an RPC method declared in a proto file.
type MethodDescriptor struct {
	proto          *dpb.MethodDescriptorProto
	parent         *ServiceDescriptor
	file           *FileDescriptor
	inType         *MessageDescriptor
	outType        *MessageDescriptor
	fqn            string
	sourceInfoPath []int32
}

func createMethodDescriptor(fd *FileDescriptor, parent *ServiceDescriptor, enclosing string, md *dpb.MethodDescriptorProto) (*MethodDescriptor, string) {
	// request and response types get resolved later
	methodName := merge(enclosing, md.GetName())
	return &MethodDescriptor{proto: md, parent: parent, file: fd, fqn: methodName}, methodName
}

func (md *MethodDescriptor) resolve(path []int32, scopes []scope) error {
	md.sourceInfoPath = append([]int32(nil), path...) // defensive copy
	if desc, err := resolve(md.file, md.proto.GetInputType(), scopes); err != nil {
		return err
	} else {
		md.inType = desc.(*MessageDescriptor)
	}
	if desc, err := resolve(md.file, md.proto.GetOutputType(), scopes); err != nil {
		return err
	} else {
		md.outType = desc.(*MessageDescriptor)
	}
	return nil
}

// GetName returns the name of the method.
func (md *MethodDescriptor) GetName() string {
	return md.proto.GetName()
}

// GetFullyQualifiedName returns the fully qualified name of the method. Unlike
// GetName, this includes fully qualified name of the enclosing service.
func (md *MethodDescriptor) GetFullyQualifiedName() string {
	return md.fqn
}

// GetParent returns the descriptor for the service in which this method is
// defined. Most usages will prefer to use GetService, which has a concrete
// return type. This more generic method is present to satisfy the Descriptor
// interface.
func (md *MethodDescriptor) GetParent() Descriptor {
	return md.parent
}

// GetService returns the RPC service in which this method is declared.
func (md *MethodDescriptor) GetService() *ServiceDescriptor {
	return md.parent
}

// GetFile returns the descriptor for the file in which this method is defined.
func (md *MethodDescriptor) GetFile() *FileDescriptor {
	return md.file
}

// GetOptions returns the method's options. Most usages will be more interested
// in GetMethodOptions, which has a concrete return type. This generic version
// is present to satisfy the Descriptor interface.
func (md *MethodDescriptor) GetOptions() proto.Message {
	return md.proto.GetOptions()
}

// GetMethodOptions returns the method's options.
func (md *MethodDescriptor) GetMethodOptions() *dpb.MethodOptions {
	return md.proto.GetOptions()
}

// GetSourceInfo returns source info for the method, if present in the
// descriptor. Not all descriptors will contain source info. If non-nil, the
// returned info contains information about the location in the file where the
// method was defined and also contains comments associated with the method
// definition.
func (md *MethodDescriptor) GetSourceInfo() *dpb.SourceCodeInfo_Location {
	return md.file.sourceInfo.Get(md.sourceInfoPath)
}

// AsProto returns the underlying descriptor proto. Most usages will be more
// interested in AsMethodDescriptorProto, which has a concrete return type. This
// generic version is present to satisfy the Descriptor interface.
func (md *MethodDescriptor) AsProto() proto.Message {
	return md.proto
}

// AsMethodDescriptorProto returns the underlying descriptor proto.
func (md *MethodDescriptor) AsMethodDescriptorProto() *dpb.MethodDescriptorProto {
	return md.proto
}

// String returns the underlying descriptor proto, in compact text format.
func (md *MethodDescriptor) String() string {
	return md.proto.String()
}

// IsServerStreaming returns true if this is a server-streaming method.
func (md *MethodDescriptor) IsServerStreaming() bool {
	return md.proto.GetServerStreaming()
}

// IsClientStreaming returns true if this is a client-streaming method.
func (md *MethodDescriptor) IsClientStreaming() bool {
	return md.proto.GetClientStreaming()
}

// GetInputType returns the input type, or request type, of the RPC method.
func (md *MethodDescriptor) GetInputType() *MessageDescriptor {
	return md.inType
}

// GetOutputType returns the output type, or response type, of the RPC method.
func (md *MethodDescriptor) GetOutputType() *MessageDescriptor {
	return md.outType
}

// OneOfDescriptor describes a one-of field set declared in a protocol buffer message.
type OneOfDescriptor struct {
	proto          *dpb.OneofDescriptorProto
	parent         *MessageDescriptor
	file           *FileDescriptor
	choices        []*FieldDescriptor
	fqn            string
	sourceInfoPath []int32
}

func createOneOfDescriptor(fd *FileDescriptor, parent *MessageDescriptor, index int, enclosing string, od *dpb.OneofDescriptorProto) (*OneOfDescriptor, string) {
	oneOfName := merge(enclosing, od.GetName())
	ret := &OneOfDescriptor{proto: od, parent: parent, file: fd, fqn: oneOfName}
	for _, f := range parent.fields {
		oi := f.proto.OneofIndex
		if oi != nil && *oi == int32(index) {
			f.oneOf = ret
			ret.choices = append(ret.choices, f)
		}
	}
	return ret, oneOfName
}

func (od *OneOfDescriptor) resolve(path []int32) {
	od.sourceInfoPath = append([]int32(nil), path...) // defensive copy
}

// GetName returns the name of the one-of.
func (od *OneOfDescriptor) GetName() string {
	return od.proto.GetName()
}

// GetFullyQualifiedName returns the fully qualified name of the one-of. Unlike
// GetName, this includes fully qualified name of the enclosing message.
func (od *OneOfDescriptor) GetFullyQualifiedName() string {
	return od.fqn
}

// GetParent returns the descriptor for the message in which this one-of is
// defined. Most usages will prefer to use GetOwner, which has a concrete
// return type. This more generic method is present to satisfy the Descriptor
// interface.
func (od *OneOfDescriptor) GetParent() Descriptor {
	return od.parent
}

// GetOwner returns the message to which this one-of field set belongs.
func (od *OneOfDescriptor) GetOwner() *MessageDescriptor {
	return od.parent
}

// GetFile returns the descriptor for the file in which this one-fof is defined.
func (od *OneOfDescriptor) GetFile() *FileDescriptor {
	return od.file
}

// GetOptions returns the one-of's options. Most usages will be more interested
// in GetOneOfOptions, which has a concrete return type. This generic version
// is present to satisfy the Descriptor interface.
func (od *OneOfDescriptor) GetOptions() proto.Message {
	return od.proto.GetOptions()
}

// GetOneOfOptions returns the one-of's options.
func (od *OneOfDescriptor) GetOneOfOptions() *dpb.OneofOptions {
	return od.proto.GetOptions()
}

// GetSourceInfo returns source info for the one-of, if present in the
// descriptor. Not all descriptors will contain source info. If non-nil, the
// returned info contains information about the location in the file where the
// one-of was defined and also contains comments associated with the one-of
// definition.
func (od *OneOfDescriptor) GetSourceInfo() *dpb.SourceCodeInfo_Location {
	return od.file.sourceInfo.Get(od.sourceInfoPath)
}

// AsProto returns the underlying descriptor proto. Most usages will be more
// interested in AsOneofDescriptorProto, which has a concrete return type. This
// generic version is present to satisfy the Descriptor interface.
func (od *OneOfDescriptor) AsProto() proto.Message {
	return od.proto
}

// AsOneofDescriptorProto returns the underlying descriptor proto.
func (od *OneOfDescriptor) AsOneofDescriptorProto() *dpb.OneofDescriptorProto {
	return od.proto
}

// String returns the underlying descriptor proto, in compact text format.
func (od *OneOfDescriptor) String() string {
	return od.proto.String()
}

// GetChoices returns the fields that are part of the one-of field set. At most one of
// these fields may be set for a given message.
func (od *OneOfDescriptor) GetChoices() []*FieldDescriptor {
	return od.choices
}

// scope represents a lexical scope in a proto file in which messages and enums
// can be declared.
type scope func(string) Descriptor

func fileScope(fd *FileDescriptor) scope {
	// we search symbols in this file, but also symbols in other files that have
	// the same package as this file or a "parent" package (in protobuf,
	// packages are a hierarchy like C++ namespaces)
	prefixes := internal.CreatePrefixList(fd.proto.GetPackage())
	return func(name string) Descriptor {
		for _, prefix := range prefixes {
			n := merge(prefix, name)
			d := findSymbol(fd, n, false)
			if d != nil {
				return d
			}
		}
		return nil
	}
}

func messageScope(md *MessageDescriptor) scope {
	return func(name string) Descriptor {
		n := merge(md.fqn, name)
		if d, ok := md.file.symbols[n]; ok {
			return d
		}
		return nil
	}
}

func resolve(fd *FileDescriptor, name string, scopes []scope) (Descriptor, error) {
	if strings.HasPrefix(name, ".") {
		// already fully-qualified
		d := findSymbol(fd, name[1:], false)
		if d != nil {
			return d, nil
		}
	} else {
		// unqualified, so we look in the enclosing (last) scope first and move
		// towards outermost (first) scope, trying to resolve the symbol
		for i := len(scopes) - 1; i >= 0; i-- {
			d := scopes[i](name)
			if d != nil {
				return d, nil
			}
		}
	}
	return nil, fmt.Errorf("file %q included an unresolvable reference to %q", fd.proto.GetName(), name)
}

func findSymbol(fd *FileDescriptor, name string, public bool) Descriptor {
	d := fd.symbols[name]
	if d != nil {
		return d
	}

	// 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.
	var deps []*FileDescriptor
	if public {
		deps = fd.publicDeps
	} else {
		deps = fd.deps
	}
	for _, dep := range deps {
		d = findSymbol(dep, name, true)
		if d != nil {
			return d
		}
	}

	return nil
}

func merge(a, b string) string {
	if a == "" {
		return b
	} else {
		return a + "." + b
	}
}
