diff --git a/vendor/google.golang.org/protobuf/internal/filedesc/desc.go b/vendor/google.golang.org/protobuf/internal/filedesc/desc.go
new file mode 100644
index 0000000..98ab142
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/internal/filedesc/desc.go
@@ -0,0 +1,631 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package filedesc
+
+import (
+	"bytes"
+	"fmt"
+	"sync"
+	"sync/atomic"
+
+	"google.golang.org/protobuf/internal/descfmt"
+	"google.golang.org/protobuf/internal/descopts"
+	"google.golang.org/protobuf/internal/encoding/defval"
+	"google.golang.org/protobuf/internal/encoding/messageset"
+	"google.golang.org/protobuf/internal/genid"
+	"google.golang.org/protobuf/internal/pragma"
+	"google.golang.org/protobuf/internal/strs"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/reflect/protoregistry"
+)
+
+// The types in this file may have a suffix:
+//	• L0: Contains fields common to all descriptors (except File) and
+//	must be initialized up front.
+//	• L1: Contains fields specific to a descriptor and
+//	must be initialized up front.
+//	• L2: Contains fields that are lazily initialized when constructing
+//	from the raw file descriptor. When constructing as a literal, the L2
+//	fields must be initialized up front.
+//
+// The types are exported so that packages like reflect/protodesc can
+// directly construct descriptors.
+
+type (
+	File struct {
+		fileRaw
+		L1 FileL1
+
+		once uint32     // atomically set if L2 is valid
+		mu   sync.Mutex // protects L2
+		L2   *FileL2
+	}
+	FileL1 struct {
+		Syntax  pref.Syntax
+		Path    string
+		Package pref.FullName
+
+		Enums      Enums
+		Messages   Messages
+		Extensions Extensions
+		Services   Services
+	}
+	FileL2 struct {
+		Options   func() pref.ProtoMessage
+		Imports   FileImports
+		Locations SourceLocations
+	}
+)
+
+func (fd *File) ParentFile() pref.FileDescriptor { return fd }
+func (fd *File) Parent() pref.Descriptor         { return nil }
+func (fd *File) Index() int                      { return 0 }
+func (fd *File) Syntax() pref.Syntax             { return fd.L1.Syntax }
+func (fd *File) Name() pref.Name                 { return fd.L1.Package.Name() }
+func (fd *File) FullName() pref.FullName         { return fd.L1.Package }
+func (fd *File) IsPlaceholder() bool             { return false }
+func (fd *File) Options() pref.ProtoMessage {
+	if f := fd.lazyInit().Options; f != nil {
+		return f()
+	}
+	return descopts.File
+}
+func (fd *File) Path() string                          { return fd.L1.Path }
+func (fd *File) Package() pref.FullName                { return fd.L1.Package }
+func (fd *File) Imports() pref.FileImports             { return &fd.lazyInit().Imports }
+func (fd *File) Enums() pref.EnumDescriptors           { return &fd.L1.Enums }
+func (fd *File) Messages() pref.MessageDescriptors     { return &fd.L1.Messages }
+func (fd *File) Extensions() pref.ExtensionDescriptors { return &fd.L1.Extensions }
+func (fd *File) Services() pref.ServiceDescriptors     { return &fd.L1.Services }
+func (fd *File) SourceLocations() pref.SourceLocations { return &fd.lazyInit().Locations }
+func (fd *File) Format(s fmt.State, r rune)            { descfmt.FormatDesc(s, r, fd) }
+func (fd *File) ProtoType(pref.FileDescriptor)         {}
+func (fd *File) ProtoInternal(pragma.DoNotImplement)   {}
+
+func (fd *File) lazyInit() *FileL2 {
+	if atomic.LoadUint32(&fd.once) == 0 {
+		fd.lazyInitOnce()
+	}
+	return fd.L2
+}
+
+func (fd *File) lazyInitOnce() {
+	fd.mu.Lock()
+	if fd.L2 == nil {
+		fd.lazyRawInit() // recursively initializes all L2 structures
+	}
+	atomic.StoreUint32(&fd.once, 1)
+	fd.mu.Unlock()
+}
+
+// GoPackagePath is a pseudo-internal API for determining the Go package path
+// that this file descriptor is declared in.
+//
+// WARNING: This method is exempt from the compatibility promise and may be
+// removed in the future without warning.
+func (fd *File) GoPackagePath() string {
+	return fd.builder.GoPackagePath
+}
+
+type (
+	Enum struct {
+		Base
+		L1 EnumL1
+		L2 *EnumL2 // protected by fileDesc.once
+	}
+	EnumL1 struct {
+		eagerValues bool // controls whether EnumL2.Values is already populated
+	}
+	EnumL2 struct {
+		Options        func() pref.ProtoMessage
+		Values         EnumValues
+		ReservedNames  Names
+		ReservedRanges EnumRanges
+	}
+
+	EnumValue struct {
+		Base
+		L1 EnumValueL1
+	}
+	EnumValueL1 struct {
+		Options func() pref.ProtoMessage
+		Number  pref.EnumNumber
+	}
+)
+
+func (ed *Enum) Options() pref.ProtoMessage {
+	if f := ed.lazyInit().Options; f != nil {
+		return f()
+	}
+	return descopts.Enum
+}
+func (ed *Enum) Values() pref.EnumValueDescriptors {
+	if ed.L1.eagerValues {
+		return &ed.L2.Values
+	}
+	return &ed.lazyInit().Values
+}
+func (ed *Enum) ReservedNames() pref.Names       { return &ed.lazyInit().ReservedNames }
+func (ed *Enum) ReservedRanges() pref.EnumRanges { return &ed.lazyInit().ReservedRanges }
+func (ed *Enum) Format(s fmt.State, r rune)      { descfmt.FormatDesc(s, r, ed) }
+func (ed *Enum) ProtoType(pref.EnumDescriptor)   {}
+func (ed *Enum) lazyInit() *EnumL2 {
+	ed.L0.ParentFile.lazyInit() // implicitly initializes L2
+	return ed.L2
+}
+
+func (ed *EnumValue) Options() pref.ProtoMessage {
+	if f := ed.L1.Options; f != nil {
+		return f()
+	}
+	return descopts.EnumValue
+}
+func (ed *EnumValue) Number() pref.EnumNumber            { return ed.L1.Number }
+func (ed *EnumValue) Format(s fmt.State, r rune)         { descfmt.FormatDesc(s, r, ed) }
+func (ed *EnumValue) ProtoType(pref.EnumValueDescriptor) {}
+
+type (
+	Message struct {
+		Base
+		L1 MessageL1
+		L2 *MessageL2 // protected by fileDesc.once
+	}
+	MessageL1 struct {
+		Enums        Enums
+		Messages     Messages
+		Extensions   Extensions
+		IsMapEntry   bool // promoted from google.protobuf.MessageOptions
+		IsMessageSet bool // promoted from google.protobuf.MessageOptions
+	}
+	MessageL2 struct {
+		Options               func() pref.ProtoMessage
+		Fields                Fields
+		Oneofs                Oneofs
+		ReservedNames         Names
+		ReservedRanges        FieldRanges
+		RequiredNumbers       FieldNumbers // must be consistent with Fields.Cardinality
+		ExtensionRanges       FieldRanges
+		ExtensionRangeOptions []func() pref.ProtoMessage // must be same length as ExtensionRanges
+	}
+
+	Field struct {
+		Base
+		L1 FieldL1
+	}
+	FieldL1 struct {
+		Options          func() pref.ProtoMessage
+		Number           pref.FieldNumber
+		Cardinality      pref.Cardinality // must be consistent with Message.RequiredNumbers
+		Kind             pref.Kind
+		StringName       stringName
+		IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto
+		IsWeak           bool // promoted from google.protobuf.FieldOptions
+		HasPacked        bool // promoted from google.protobuf.FieldOptions
+		IsPacked         bool // promoted from google.protobuf.FieldOptions
+		HasEnforceUTF8   bool // promoted from google.protobuf.FieldOptions
+		EnforceUTF8      bool // promoted from google.protobuf.FieldOptions
+		Default          defaultValue
+		ContainingOneof  pref.OneofDescriptor // must be consistent with Message.Oneofs.Fields
+		Enum             pref.EnumDescriptor
+		Message          pref.MessageDescriptor
+	}
+
+	Oneof struct {
+		Base
+		L1 OneofL1
+	}
+	OneofL1 struct {
+		Options func() pref.ProtoMessage
+		Fields  OneofFields // must be consistent with Message.Fields.ContainingOneof
+	}
+)
+
+func (md *Message) Options() pref.ProtoMessage {
+	if f := md.lazyInit().Options; f != nil {
+		return f()
+	}
+	return descopts.Message
+}
+func (md *Message) IsMapEntry() bool                   { return md.L1.IsMapEntry }
+func (md *Message) Fields() pref.FieldDescriptors      { return &md.lazyInit().Fields }
+func (md *Message) Oneofs() pref.OneofDescriptors      { return &md.lazyInit().Oneofs }
+func (md *Message) ReservedNames() pref.Names          { return &md.lazyInit().ReservedNames }
+func (md *Message) ReservedRanges() pref.FieldRanges   { return &md.lazyInit().ReservedRanges }
+func (md *Message) RequiredNumbers() pref.FieldNumbers { return &md.lazyInit().RequiredNumbers }
+func (md *Message) ExtensionRanges() pref.FieldRanges  { return &md.lazyInit().ExtensionRanges }
+func (md *Message) ExtensionRangeOptions(i int) pref.ProtoMessage {
+	if f := md.lazyInit().ExtensionRangeOptions[i]; f != nil {
+		return f()
+	}
+	return descopts.ExtensionRange
+}
+func (md *Message) Enums() pref.EnumDescriptors           { return &md.L1.Enums }
+func (md *Message) Messages() pref.MessageDescriptors     { return &md.L1.Messages }
+func (md *Message) Extensions() pref.ExtensionDescriptors { return &md.L1.Extensions }
+func (md *Message) ProtoType(pref.MessageDescriptor)      {}
+func (md *Message) Format(s fmt.State, r rune)            { descfmt.FormatDesc(s, r, md) }
+func (md *Message) lazyInit() *MessageL2 {
+	md.L0.ParentFile.lazyInit() // implicitly initializes L2
+	return md.L2
+}
+
+// IsMessageSet is a pseudo-internal API for checking whether a message
+// should serialize in the proto1 message format.
+//
+// WARNING: This method is exempt from the compatibility promise and may be
+// removed in the future without warning.
+func (md *Message) IsMessageSet() bool {
+	return md.L1.IsMessageSet
+}
+
+func (fd *Field) Options() pref.ProtoMessage {
+	if f := fd.L1.Options; f != nil {
+		return f()
+	}
+	return descopts.Field
+}
+func (fd *Field) Number() pref.FieldNumber      { return fd.L1.Number }
+func (fd *Field) Cardinality() pref.Cardinality { return fd.L1.Cardinality }
+func (fd *Field) Kind() pref.Kind               { return fd.L1.Kind }
+func (fd *Field) HasJSONName() bool             { return fd.L1.StringName.hasJSON }
+func (fd *Field) JSONName() string              { return fd.L1.StringName.getJSON(fd) }
+func (fd *Field) TextName() string              { return fd.L1.StringName.getText(fd) }
+func (fd *Field) HasPresence() bool {
+	return fd.L1.Cardinality != pref.Repeated && (fd.L0.ParentFile.L1.Syntax == pref.Proto2 || fd.L1.Message != nil || fd.L1.ContainingOneof != nil)
+}
+func (fd *Field) HasOptionalKeyword() bool {
+	return (fd.L0.ParentFile.L1.Syntax == pref.Proto2 && fd.L1.Cardinality == pref.Optional && fd.L1.ContainingOneof == nil) || fd.L1.IsProto3Optional
+}
+func (fd *Field) IsPacked() bool {
+	if !fd.L1.HasPacked && fd.L0.ParentFile.L1.Syntax != pref.Proto2 && fd.L1.Cardinality == pref.Repeated {
+		switch fd.L1.Kind {
+		case pref.StringKind, pref.BytesKind, pref.MessageKind, pref.GroupKind:
+		default:
+			return true
+		}
+	}
+	return fd.L1.IsPacked
+}
+func (fd *Field) IsExtension() bool { return false }
+func (fd *Field) IsWeak() bool      { return fd.L1.IsWeak }
+func (fd *Field) IsList() bool      { return fd.Cardinality() == pref.Repeated && !fd.IsMap() }
+func (fd *Field) IsMap() bool       { return fd.Message() != nil && fd.Message().IsMapEntry() }
+func (fd *Field) MapKey() pref.FieldDescriptor {
+	if !fd.IsMap() {
+		return nil
+	}
+	return fd.Message().Fields().ByNumber(genid.MapEntry_Key_field_number)
+}
+func (fd *Field) MapValue() pref.FieldDescriptor {
+	if !fd.IsMap() {
+		return nil
+	}
+	return fd.Message().Fields().ByNumber(genid.MapEntry_Value_field_number)
+}
+func (fd *Field) HasDefault() bool                           { return fd.L1.Default.has }
+func (fd *Field) Default() pref.Value                        { return fd.L1.Default.get(fd) }
+func (fd *Field) DefaultEnumValue() pref.EnumValueDescriptor { return fd.L1.Default.enum }
+func (fd *Field) ContainingOneof() pref.OneofDescriptor      { return fd.L1.ContainingOneof }
+func (fd *Field) ContainingMessage() pref.MessageDescriptor {
+	return fd.L0.Parent.(pref.MessageDescriptor)
+}
+func (fd *Field) Enum() pref.EnumDescriptor {
+	return fd.L1.Enum
+}
+func (fd *Field) Message() pref.MessageDescriptor {
+	if fd.L1.IsWeak {
+		if d, _ := protoregistry.GlobalFiles.FindDescriptorByName(fd.L1.Message.FullName()); d != nil {
+			return d.(pref.MessageDescriptor)
+		}
+	}
+	return fd.L1.Message
+}
+func (fd *Field) Format(s fmt.State, r rune)     { descfmt.FormatDesc(s, r, fd) }
+func (fd *Field) ProtoType(pref.FieldDescriptor) {}
+
+// EnforceUTF8 is a pseudo-internal API to determine whether to enforce UTF-8
+// validation for the string field. This exists for Google-internal use only
+// since proto3 did not enforce UTF-8 validity prior to the open-source release.
+// If this method does not exist, the default is to enforce valid UTF-8.
+//
+// WARNING: This method is exempt from the compatibility promise and may be
+// removed in the future without warning.
+func (fd *Field) EnforceUTF8() bool {
+	if fd.L1.HasEnforceUTF8 {
+		return fd.L1.EnforceUTF8
+	}
+	return fd.L0.ParentFile.L1.Syntax == pref.Proto3
+}
+
+func (od *Oneof) IsSynthetic() bool {
+	return od.L0.ParentFile.L1.Syntax == pref.Proto3 && len(od.L1.Fields.List) == 1 && od.L1.Fields.List[0].HasOptionalKeyword()
+}
+func (od *Oneof) Options() pref.ProtoMessage {
+	if f := od.L1.Options; f != nil {
+		return f()
+	}
+	return descopts.Oneof
+}
+func (od *Oneof) Fields() pref.FieldDescriptors  { return &od.L1.Fields }
+func (od *Oneof) Format(s fmt.State, r rune)     { descfmt.FormatDesc(s, r, od) }
+func (od *Oneof) ProtoType(pref.OneofDescriptor) {}
+
+type (
+	Extension struct {
+		Base
+		L1 ExtensionL1
+		L2 *ExtensionL2 // protected by fileDesc.once
+	}
+	ExtensionL1 struct {
+		Number      pref.FieldNumber
+		Extendee    pref.MessageDescriptor
+		Cardinality pref.Cardinality
+		Kind        pref.Kind
+	}
+	ExtensionL2 struct {
+		Options          func() pref.ProtoMessage
+		StringName       stringName
+		IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto
+		IsPacked         bool // promoted from google.protobuf.FieldOptions
+		Default          defaultValue
+		Enum             pref.EnumDescriptor
+		Message          pref.MessageDescriptor
+	}
+)
+
+func (xd *Extension) Options() pref.ProtoMessage {
+	if f := xd.lazyInit().Options; f != nil {
+		return f()
+	}
+	return descopts.Field
+}
+func (xd *Extension) Number() pref.FieldNumber      { return xd.L1.Number }
+func (xd *Extension) Cardinality() pref.Cardinality { return xd.L1.Cardinality }
+func (xd *Extension) Kind() pref.Kind               { return xd.L1.Kind }
+func (xd *Extension) HasJSONName() bool             { return xd.lazyInit().StringName.hasJSON }
+func (xd *Extension) JSONName() string              { return xd.lazyInit().StringName.getJSON(xd) }
+func (xd *Extension) TextName() string              { return xd.lazyInit().StringName.getText(xd) }
+func (xd *Extension) HasPresence() bool             { return xd.L1.Cardinality != pref.Repeated }
+func (xd *Extension) HasOptionalKeyword() bool {
+	return (xd.L0.ParentFile.L1.Syntax == pref.Proto2 && xd.L1.Cardinality == pref.Optional) || xd.lazyInit().IsProto3Optional
+}
+func (xd *Extension) IsPacked() bool                             { return xd.lazyInit().IsPacked }
+func (xd *Extension) IsExtension() bool                          { return true }
+func (xd *Extension) IsWeak() bool                               { return false }
+func (xd *Extension) IsList() bool                               { return xd.Cardinality() == pref.Repeated }
+func (xd *Extension) IsMap() bool                                { return false }
+func (xd *Extension) MapKey() pref.FieldDescriptor               { return nil }
+func (xd *Extension) MapValue() pref.FieldDescriptor             { return nil }
+func (xd *Extension) HasDefault() bool                           { return xd.lazyInit().Default.has }
+func (xd *Extension) Default() pref.Value                        { return xd.lazyInit().Default.get(xd) }
+func (xd *Extension) DefaultEnumValue() pref.EnumValueDescriptor { return xd.lazyInit().Default.enum }
+func (xd *Extension) ContainingOneof() pref.OneofDescriptor      { return nil }
+func (xd *Extension) ContainingMessage() pref.MessageDescriptor  { return xd.L1.Extendee }
+func (xd *Extension) Enum() pref.EnumDescriptor                  { return xd.lazyInit().Enum }
+func (xd *Extension) Message() pref.MessageDescriptor            { return xd.lazyInit().Message }
+func (xd *Extension) Format(s fmt.State, r rune)                 { descfmt.FormatDesc(s, r, xd) }
+func (xd *Extension) ProtoType(pref.FieldDescriptor)             {}
+func (xd *Extension) ProtoInternal(pragma.DoNotImplement)        {}
+func (xd *Extension) lazyInit() *ExtensionL2 {
+	xd.L0.ParentFile.lazyInit() // implicitly initializes L2
+	return xd.L2
+}
+
+type (
+	Service struct {
+		Base
+		L1 ServiceL1
+		L2 *ServiceL2 // protected by fileDesc.once
+	}
+	ServiceL1 struct{}
+	ServiceL2 struct {
+		Options func() pref.ProtoMessage
+		Methods Methods
+	}
+
+	Method struct {
+		Base
+		L1 MethodL1
+	}
+	MethodL1 struct {
+		Options           func() pref.ProtoMessage
+		Input             pref.MessageDescriptor
+		Output            pref.MessageDescriptor
+		IsStreamingClient bool
+		IsStreamingServer bool
+	}
+)
+
+func (sd *Service) Options() pref.ProtoMessage {
+	if f := sd.lazyInit().Options; f != nil {
+		return f()
+	}
+	return descopts.Service
+}
+func (sd *Service) Methods() pref.MethodDescriptors     { return &sd.lazyInit().Methods }
+func (sd *Service) Format(s fmt.State, r rune)          { descfmt.FormatDesc(s, r, sd) }
+func (sd *Service) ProtoType(pref.ServiceDescriptor)    {}
+func (sd *Service) ProtoInternal(pragma.DoNotImplement) {}
+func (sd *Service) lazyInit() *ServiceL2 {
+	sd.L0.ParentFile.lazyInit() // implicitly initializes L2
+	return sd.L2
+}
+
+func (md *Method) Options() pref.ProtoMessage {
+	if f := md.L1.Options; f != nil {
+		return f()
+	}
+	return descopts.Method
+}
+func (md *Method) Input() pref.MessageDescriptor       { return md.L1.Input }
+func (md *Method) Output() pref.MessageDescriptor      { return md.L1.Output }
+func (md *Method) IsStreamingClient() bool             { return md.L1.IsStreamingClient }
+func (md *Method) IsStreamingServer() bool             { return md.L1.IsStreamingServer }
+func (md *Method) Format(s fmt.State, r rune)          { descfmt.FormatDesc(s, r, md) }
+func (md *Method) ProtoType(pref.MethodDescriptor)     {}
+func (md *Method) ProtoInternal(pragma.DoNotImplement) {}
+
+// Surrogate files are can be used to create standalone descriptors
+// where the syntax is only information derived from the parent file.
+var (
+	SurrogateProto2 = &File{L1: FileL1{Syntax: pref.Proto2}, L2: &FileL2{}}
+	SurrogateProto3 = &File{L1: FileL1{Syntax: pref.Proto3}, L2: &FileL2{}}
+)
+
+type (
+	Base struct {
+		L0 BaseL0
+	}
+	BaseL0 struct {
+		FullName   pref.FullName // must be populated
+		ParentFile *File         // must be populated
+		Parent     pref.Descriptor
+		Index      int
+	}
+)
+
+func (d *Base) Name() pref.Name         { return d.L0.FullName.Name() }
+func (d *Base) FullName() pref.FullName { return d.L0.FullName }
+func (d *Base) ParentFile() pref.FileDescriptor {
+	if d.L0.ParentFile == SurrogateProto2 || d.L0.ParentFile == SurrogateProto3 {
+		return nil // surrogate files are not real parents
+	}
+	return d.L0.ParentFile
+}
+func (d *Base) Parent() pref.Descriptor             { return d.L0.Parent }
+func (d *Base) Index() int                          { return d.L0.Index }
+func (d *Base) Syntax() pref.Syntax                 { return d.L0.ParentFile.Syntax() }
+func (d *Base) IsPlaceholder() bool                 { return false }
+func (d *Base) ProtoInternal(pragma.DoNotImplement) {}
+
+type stringName struct {
+	hasJSON  bool
+	once     sync.Once
+	nameJSON string
+	nameText string
+}
+
+// InitJSON initializes the name. It is exported for use by other internal packages.
+func (s *stringName) InitJSON(name string) {
+	s.hasJSON = true
+	s.nameJSON = name
+}
+
+func (s *stringName) lazyInit(fd pref.FieldDescriptor) *stringName {
+	s.once.Do(func() {
+		if fd.IsExtension() {
+			// For extensions, JSON and text are formatted the same way.
+			var name string
+			if messageset.IsMessageSetExtension(fd) {
+				name = string("[" + fd.FullName().Parent() + "]")
+			} else {
+				name = string("[" + fd.FullName() + "]")
+			}
+			s.nameJSON = name
+			s.nameText = name
+		} else {
+			// Format the JSON name.
+			if !s.hasJSON {
+				s.nameJSON = strs.JSONCamelCase(string(fd.Name()))
+			}
+
+			// Format the text name.
+			s.nameText = string(fd.Name())
+			if fd.Kind() == pref.GroupKind {
+				s.nameText = string(fd.Message().Name())
+			}
+		}
+	})
+	return s
+}
+
+func (s *stringName) getJSON(fd pref.FieldDescriptor) string { return s.lazyInit(fd).nameJSON }
+func (s *stringName) getText(fd pref.FieldDescriptor) string { return s.lazyInit(fd).nameText }
+
+func DefaultValue(v pref.Value, ev pref.EnumValueDescriptor) defaultValue {
+	dv := defaultValue{has: v.IsValid(), val: v, enum: ev}
+	if b, ok := v.Interface().([]byte); ok {
+		// Store a copy of the default bytes, so that we can detect
+		// accidental mutations of the original value.
+		dv.bytes = append([]byte(nil), b...)
+	}
+	return dv
+}
+
+func unmarshalDefault(b []byte, k pref.Kind, pf *File, ed pref.EnumDescriptor) defaultValue {
+	var evs pref.EnumValueDescriptors
+	if k == pref.EnumKind {
+		// If the enum is declared within the same file, be careful not to
+		// blindly call the Values method, lest we bind ourselves in a deadlock.
+		if e, ok := ed.(*Enum); ok && e.L0.ParentFile == pf {
+			evs = &e.L2.Values
+		} else {
+			evs = ed.Values()
+		}
+
+		// If we are unable to resolve the enum dependency, use a placeholder
+		// enum value since we will not be able to parse the default value.
+		if ed.IsPlaceholder() && pref.Name(b).IsValid() {
+			v := pref.ValueOfEnum(0)
+			ev := PlaceholderEnumValue(ed.FullName().Parent().Append(pref.Name(b)))
+			return DefaultValue(v, ev)
+		}
+	}
+
+	v, ev, err := defval.Unmarshal(string(b), k, evs, defval.Descriptor)
+	if err != nil {
+		panic(err)
+	}
+	return DefaultValue(v, ev)
+}
+
+type defaultValue struct {
+	has   bool
+	val   pref.Value
+	enum  pref.EnumValueDescriptor
+	bytes []byte
+}
+
+func (dv *defaultValue) get(fd pref.FieldDescriptor) pref.Value {
+	// Return the zero value as the default if unpopulated.
+	if !dv.has {
+		if fd.Cardinality() == pref.Repeated {
+			return pref.Value{}
+		}
+		switch fd.Kind() {
+		case pref.BoolKind:
+			return pref.ValueOfBool(false)
+		case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
+			return pref.ValueOfInt32(0)
+		case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
+			return pref.ValueOfInt64(0)
+		case pref.Uint32Kind, pref.Fixed32Kind:
+			return pref.ValueOfUint32(0)
+		case pref.Uint64Kind, pref.Fixed64Kind:
+			return pref.ValueOfUint64(0)
+		case pref.FloatKind:
+			return pref.ValueOfFloat32(0)
+		case pref.DoubleKind:
+			return pref.ValueOfFloat64(0)
+		case pref.StringKind:
+			return pref.ValueOfString("")
+		case pref.BytesKind:
+			return pref.ValueOfBytes(nil)
+		case pref.EnumKind:
+			if evs := fd.Enum().Values(); evs.Len() > 0 {
+				return pref.ValueOfEnum(evs.Get(0).Number())
+			}
+			return pref.ValueOfEnum(0)
+		}
+	}
+
+	if len(dv.bytes) > 0 && !bytes.Equal(dv.bytes, dv.val.Bytes()) {
+		// TODO: Avoid panic if we're running with the race detector
+		// and instead spawn a goroutine that periodically resets
+		// this value back to the original to induce a race.
+		panic(fmt.Sprintf("detected mutation on the default bytes for %v", fd.FullName()))
+	}
+	return dv.val
+}
