// Copyright 2010 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 proto

import (
	
	
	

	
	
	
	
	
	
)

type (
	// ExtensionDesc represents an extension descriptor and
	// is used to interact with an extension field in a message.
	//
	// Variables of this type are generated in code by protoc-gen-go.
	ExtensionDesc = protoimpl.ExtensionInfo

	// ExtensionRange represents a range of message extensions.
	// Used in code generated by protoc-gen-go.
	ExtensionRange = protoiface.ExtensionRangeV1

	// Deprecated: Do not use; this is an internal type.
	Extension = protoimpl.ExtensionFieldV1

	// Deprecated: Do not use; this is an internal type.
	XXX_InternalExtensions = protoimpl.ExtensionFields
)

// ErrMissingExtension reports whether the extension was not present.
var ErrMissingExtension = errors.New("proto: missing extension")

var errNotExtendable = errors.New("proto: not an extendable proto.Message")

// HasExtension reports whether the extension field is present in m
// either as an explicitly populated field or as an unknown field.
func ( Message,  *ExtensionDesc) ( bool) {
	 := MessageReflect()
	if  == nil || !.IsValid() {
		return false
	}

	// Check whether any populated known field matches the field number.
	 := .TypeDescriptor()
	if isValidExtension(.Descriptor(), ) {
		 = .Has()
	} else {
		.Range(func( protoreflect.FieldDescriptor,  protoreflect.Value) bool {
			 = int32(.Number()) == .Field
			return !
		})
	}

	// Check whether any unknown field matches the field number.
	for  := .GetUnknown(); ! && len() > 0; {
		, ,  := protowire.ConsumeField()
		 = int32() == .Field
		 = [:]
	}
	return 
}

// ClearExtension removes the extension field from m
// either as an explicitly populated field or as an unknown field.
func ( Message,  *ExtensionDesc) {
	 := MessageReflect()
	if  == nil || !.IsValid() {
		return
	}

	 := .TypeDescriptor()
	if isValidExtension(.Descriptor(), ) {
		.Clear()
	} else {
		.Range(func( protoreflect.FieldDescriptor,  protoreflect.Value) bool {
			if int32(.Number()) == .Field {
				.Clear()
				return false
			}
			return true
		})
	}
	clearUnknown(, fieldNum(.Field))
}

// ClearAllExtensions clears all extensions from m.
// This includes populated fields and unknown fields in the extension range.
func ( Message) {
	 := MessageReflect()
	if  == nil || !.IsValid() {
		return
	}

	.Range(func( protoreflect.FieldDescriptor,  protoreflect.Value) bool {
		if .IsExtension() {
			.Clear()
		}
		return true
	})
	clearUnknown(, .Descriptor().ExtensionRanges())
}

// GetExtension retrieves a proto2 extended field from m.
//
// If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil),
// then GetExtension parses the encoded field and returns a Go value of the specified type.
// If the field is not present, then the default value is returned (if one is specified),
// otherwise ErrMissingExtension is reported.
//
// If the descriptor is type incomplete (i.e., ExtensionDesc.ExtensionType is nil),
// then GetExtension returns the raw encoded bytes for the extension field.
func ( Message,  *ExtensionDesc) (interface{}, error) {
	 := MessageReflect()
	if  == nil || !.IsValid() || .Descriptor().ExtensionRanges().Len() == 0 {
		return nil, errNotExtendable
	}

	// Retrieve the unknown fields for this extension field.
	var  protoreflect.RawFields
	for  := .GetUnknown(); len() > 0; {
		, ,  := protowire.ConsumeField()
		if int32() == .Field {
			 = append(, [:]...)
		}
		 = [:]
	}

	// For type incomplete descriptors, only retrieve the unknown fields.
	if .ExtensionType == nil {
		return []byte(), nil
	}

	// If the extension field only exists as unknown fields, unmarshal it.
	// This is rarely done since proto.Unmarshal eagerly unmarshals extensions.
	 := .TypeDescriptor()
	if !isValidExtension(.Descriptor(), ) {
		return nil, fmt.Errorf("proto: bad extended type; %T does not extend %T", .ExtendedType, )
	}
	if !.Has() && len() > 0 {
		 := .New()
		if  := (proto.UnmarshalOptions{
			Resolver: extensionResolver{},
		}.Unmarshal(, .Interface()));  != nil {
			return nil, 
		}
		if .Has() {
			.Set(, .Get())
			clearUnknown(, fieldNum(.Field))
		}
	}

	// Check whether the message has the extension field set or a default.
	var  protoreflect.Value
	switch {
	case .Has():
		 = .Get()
	case .HasDefault():
		 = .Default()
	default:
		return nil, ErrMissingExtension
	}

	 := .InterfaceOf()
	 := reflect.ValueOf()
	if isScalarKind(.Kind()) {
		 := reflect.New(.Type())
		.Elem().Set()
		 = .Interface()
	}
	return , nil
}

// extensionResolver is a custom extension resolver that stores a single
// extension type that takes precedence over the global registry.
type extensionResolver struct{ xt protoreflect.ExtensionType }

func ( extensionResolver) ( protoreflect.FullName) (protoreflect.ExtensionType, error) {
	if  := .xt.TypeDescriptor(); .FullName() ==  {
		return .xt, nil
	}
	return protoregistry.GlobalTypes.FindExtensionByName()
}

func ( extensionResolver) ( protoreflect.FullName,  protoreflect.FieldNumber) (protoreflect.ExtensionType, error) {
	if  := .xt.TypeDescriptor(); .ContainingMessage().FullName() ==  && .Number() ==  {
		return .xt, nil
	}
	return protoregistry.GlobalTypes.FindExtensionByNumber(, )
}

// GetExtensions returns a list of the extensions values present in m,
// corresponding with the provided list of extension descriptors, xts.
// If an extension is missing in m, the corresponding value is nil.
func ( Message,  []*ExtensionDesc) ([]interface{}, error) {
	 := MessageReflect()
	if  == nil || !.IsValid() {
		return nil, errNotExtendable
	}

	 := make([]interface{}, len())
	for ,  := range  {
		,  := GetExtension(, )
		if  != nil {
			if  == ErrMissingExtension {
				continue
			}
			return , 
		}
		[] = 
	}
	return , nil
}

// SetExtension sets an extension field in m to the provided value.
func ( Message,  *ExtensionDesc,  interface{}) error {
	 := MessageReflect()
	if  == nil || !.IsValid() || .Descriptor().ExtensionRanges().Len() == 0 {
		return errNotExtendable
	}

	 := reflect.ValueOf()
	if reflect.TypeOf() != reflect.TypeOf(.ExtensionType) {
		return fmt.Errorf("proto: bad extension value type. got: %T, want: %T", , .ExtensionType)
	}
	if .Kind() == reflect.Ptr {
		if .IsNil() {
			return fmt.Errorf("proto: SetExtension called with nil value of type %T", )
		}
		if isScalarKind(.Elem().Kind()) {
			 = .Elem().Interface()
		}
	}

	 := .TypeDescriptor()
	if !isValidExtension(.Descriptor(), ) {
		return fmt.Errorf("proto: bad extended type; %T does not extend %T", .ExtendedType, )
	}
	.Set(, .ValueOf())
	clearUnknown(, fieldNum(.Field))
	return nil
}

// SetRawExtension inserts b into the unknown fields of m.
//
// Deprecated: Use Message.ProtoReflect.SetUnknown instead.
func ( Message,  int32,  []byte) {
	 := MessageReflect()
	if  == nil || !.IsValid() {
		return
	}

	// Verify that the raw field is valid.
	for  := ; len() > 0; {
		, ,  := protowire.ConsumeField()
		if int32() !=  {
			panic(fmt.Sprintf("mismatching field number: got %d, want %d", , ))
		}
		 = [:]
	}

	ClearExtension(, &ExtensionDesc{Field: })
	.SetUnknown(append(.GetUnknown(), ...))
}

// ExtensionDescs returns a list of extension descriptors found in m,
// containing descriptors for both populated extension fields in m and
// also unknown fields of m that are in the extension range.
// For the later case, an type incomplete descriptor is provided where only
// the ExtensionDesc.Field field is populated.
// The order of the extension descriptors is undefined.
func ( Message) ([]*ExtensionDesc, error) {
	 := MessageReflect()
	if  == nil || !.IsValid() || .Descriptor().ExtensionRanges().Len() == 0 {
		return nil, errNotExtendable
	}

	// Collect a set of known extension descriptors.
	 := make(map[protoreflect.FieldNumber]*ExtensionDesc)
	.Range(func( protoreflect.FieldDescriptor,  protoreflect.Value) bool {
		if .IsExtension() {
			 := .(protoreflect.ExtensionTypeDescriptor)
			if ,  := .Type().(*ExtensionDesc);  {
				[.Number()] = 
			}
		}
		return true
	})

	// Collect a set of unknown extension descriptors.
	 := .Descriptor().ExtensionRanges()
	for  := .GetUnknown(); len() > 0; {
		, ,  := protowire.ConsumeField()
		if .Has() && [] == nil {
			[] = nil
		}
		 = [:]
	}

	// Transpose the set of descriptors into a list.
	var  []*ExtensionDesc
	for ,  := range  {
		if  == nil {
			 = &ExtensionDesc{Field: int32()}
		}
		 = append(, )
	}
	return , nil
}

// isValidExtension reports whether xtd is a valid extension descriptor for md.
func ( protoreflect.MessageDescriptor,  protoreflect.ExtensionTypeDescriptor) bool {
	return .ContainingMessage() ==  && .ExtensionRanges().Has(.Number())
}

// isScalarKind reports whether k is a protobuf scalar kind (except bytes).
// This function exists for historical reasons since the representation of
// scalars differs between v1 and v2, where v1 uses *T and v2 uses T.
func ( reflect.Kind) bool {
	switch  {
	case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String:
		return true
	default:
		return false
	}
}

// clearUnknown removes unknown fields from m where remover.Has reports true.
func ( protoreflect.Message,  interface {
	(protoreflect.FieldNumber) bool
}) {
	var  protoreflect.RawFields
	for  := .GetUnknown(); len() > 0; {
		, ,  := protowire.ConsumeField()
		if !.() {
			 = append(, [:]...)
		}
		 = [:]
	}
	if  := .GetUnknown(); len() != len() {
		.SetUnknown()
	}
}

type fieldNum protoreflect.FieldNumber

func ( fieldNum) ( protoreflect.FieldNumber) bool {
	return protoreflect.FieldNumber() == 
}