package runtime

import (
	
	
	
	
	
	
	

	
	
	
	
	
	
	
	field_mask 
	
	
	
)

var valuesKeyRegexp = regexp.MustCompile(`^(.*)\[(.*)\]$`)

var currentQueryParser QueryParameterParser = &DefaultQueryParser{}

// QueryParameterParser defines interface for all query parameter parsers
type QueryParameterParser interface {
	Parse(msg proto.Message, values url.Values, filter *utilities.DoubleArray) error
}

// PopulateQueryParameters parses query parameters
// into "msg" using current query parser
func ( proto.Message,  url.Values,  *utilities.DoubleArray) error {
	return currentQueryParser.Parse(, , )
}

// DefaultQueryParser is a QueryParameterParser which implements the default
// query parameters parsing behavior.
//
// See https://github.com/grpc-ecosystem/grpc-gateway/issues/2632 for more context.
type DefaultQueryParser struct{}

// Parse populates "values" into "msg".
// A value is ignored if its key starts with one of the elements in "filter".
func (*DefaultQueryParser) ( proto.Message,  url.Values,  *utilities.DoubleArray) error {
	for ,  := range  {
		if  := valuesKeyRegexp.FindStringSubmatch(); len() == 3 {
			 = [1]
			 = append([]string{[2]}, ...)
		}

		 := .ProtoReflect()
		 := normalizeFieldPath(, strings.Split(, "."))
		if .HasCommonPrefix() {
			continue
		}
		if  := populateFieldValueFromPath(, , );  != nil {
			return 
		}
	}
	return nil
}

// PopulateFieldFromPath sets a value in a nested Protobuf structure.
func ( proto.Message,  string,  string) error {
	 := strings.Split(, ".")
	return populateFieldValueFromPath(.ProtoReflect(), , []string{})
}

func normalizeFieldPath( protoreflect.Message,  []string) []string {
	 := make([]string, 0, len())
	for ,  := range  {
		 := .Descriptor().Fields()
		 := .ByTextName()
		if  == nil {
			 = .ByJSONName()
		}
		if  == nil {
			// return initial field path values if no matching  message field was found
			return 
		}

		 = append(, string(.Name()))

		// If this is the last element, we're done
		if  == len()-1 {
			break
		}

		// Only singular message fields are allowed
		if .Message() == nil || .Cardinality() == protoreflect.Repeated {
			return 
		}

		// Get the nested message
		 = .Get().Message()
	}

	return 
}

func populateFieldValueFromPath( protoreflect.Message,  []string,  []string) error {
	if len() < 1 {
		return errors.New("no field path")
	}
	if len() < 1 {
		return errors.New("no value provided")
	}

	var  protoreflect.FieldDescriptor
	for ,  := range  {
		 := .Descriptor().Fields()

		// Get field by name
		 = .ByName(protoreflect.Name())
		if  == nil {
			 = .ByJSONName()
			if  == nil {
				// We're not returning an error here because this could just be
				// an extra query parameter that isn't part of the request.
				grpclog.Infof("field not found in %q: %q", .Descriptor().FullName(), strings.Join(, "."))
				return nil
			}
		}

		// Check if oneof already set
		if  := .ContainingOneof();  != nil && !.IsSynthetic() {
			if  := .WhichOneof();  != nil {
				if .Message() == nil || .FullName() != .FullName() {
					return fmt.Errorf("field already set for oneof %q", .FullName().Name())
				}
			}
		}

		// If this is the last element, we're done
		if  == len()-1 {
			break
		}

		// Only singular message fields are allowed
		if .Message() == nil || .Cardinality() == protoreflect.Repeated {
			return fmt.Errorf("invalid path: %q is not a message", )
		}

		// Get the nested message
		 = .Mutable().Message()
	}

	switch {
	case .IsList():
		return populateRepeatedField(, .Mutable().List(), )
	case .IsMap():
		return populateMapField(, .Mutable().Map(), )
	}

	if len() > 1 {
		return fmt.Errorf("too many values for field %q: %s", .FullName().Name(), strings.Join(, ", "))
	}

	return populateField(, , [0])
}

func populateField( protoreflect.FieldDescriptor,  protoreflect.Message,  string) error {
	,  := parseField(, )
	if  != nil {
		return fmt.Errorf("parsing field %q: %w", .FullName().Name(), )
	}

	.Set(, )
	return nil
}

func populateRepeatedField( protoreflect.FieldDescriptor,  protoreflect.List,  []string) error {
	for ,  := range  {
		,  := parseField(, )
		if  != nil {
			return fmt.Errorf("parsing list %q: %w", .FullName().Name(), )
		}
		.Append()
	}

	return nil
}

func populateMapField( protoreflect.FieldDescriptor,  protoreflect.Map,  []string) error {
	if len() != 2 {
		return fmt.Errorf("more than one value provided for key %q in map %q", [0], .FullName())
	}

	,  := parseField(.MapKey(), [0])
	if  != nil {
		return fmt.Errorf("parsing map key %q: %w", .FullName().Name(), )
	}

	,  := parseField(.MapValue(), [1])
	if  != nil {
		return fmt.Errorf("parsing map value %q: %w", .FullName().Name(), )
	}

	.Set(.MapKey(), )

	return nil
}

func parseField( protoreflect.FieldDescriptor,  string) (protoreflect.Value, error) {
	switch .Kind() {
	case protoreflect.BoolKind:
		,  := strconv.ParseBool()
		if  != nil {
			return protoreflect.Value{}, 
		}
		return protoreflect.ValueOfBool(), nil
	case protoreflect.EnumKind:
		,  := protoregistry.GlobalTypes.FindEnumByName(.Enum().FullName())
		if  != nil {
			if errors.Is(, protoregistry.NotFound) {
				return protoreflect.Value{}, fmt.Errorf("enum %q is not registered", .Enum().FullName())
			}
			return protoreflect.Value{}, fmt.Errorf("failed to look up enum: %w", )
		}
		// Look for enum by name
		 := .Descriptor().Values().ByName(protoreflect.Name())
		if  == nil {
			,  := strconv.Atoi()
			if  != nil {
				return protoreflect.Value{}, fmt.Errorf("%q is not a valid value", )
			}
			// Look for enum by number
			if  = .Descriptor().Values().ByNumber(protoreflect.EnumNumber());  == nil {
				return protoreflect.Value{}, fmt.Errorf("%q is not a valid value", )
			}
		}
		return protoreflect.ValueOfEnum(.Number()), nil
	case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
		,  := strconv.ParseInt(, 10, 32)
		if  != nil {
			return protoreflect.Value{}, 
		}
		return protoreflect.ValueOfInt32(int32()), nil
	case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
		,  := strconv.ParseInt(, 10, 64)
		if  != nil {
			return protoreflect.Value{}, 
		}
		return protoreflect.ValueOfInt64(), nil
	case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
		,  := strconv.ParseUint(, 10, 32)
		if  != nil {
			return protoreflect.Value{}, 
		}
		return protoreflect.ValueOfUint32(uint32()), nil
	case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
		,  := strconv.ParseUint(, 10, 64)
		if  != nil {
			return protoreflect.Value{}, 
		}
		return protoreflect.ValueOfUint64(), nil
	case protoreflect.FloatKind:
		,  := strconv.ParseFloat(, 32)
		if  != nil {
			return protoreflect.Value{}, 
		}
		return protoreflect.ValueOfFloat32(float32()), nil
	case protoreflect.DoubleKind:
		,  := strconv.ParseFloat(, 64)
		if  != nil {
			return protoreflect.Value{}, 
		}
		return protoreflect.ValueOfFloat64(), nil
	case protoreflect.StringKind:
		return protoreflect.ValueOfString(), nil
	case protoreflect.BytesKind:
		,  := Bytes()
		if  != nil {
			return protoreflect.Value{}, 
		}
		return protoreflect.ValueOfBytes(), nil
	case protoreflect.MessageKind, protoreflect.GroupKind:
		return parseMessage(.Message(), )
	default:
		panic(fmt.Sprintf("unknown field kind: %v", .Kind()))
	}
}

func parseMessage( protoreflect.MessageDescriptor,  string) (protoreflect.Value, error) {
	var  proto.Message
	switch .FullName() {
	case "google.protobuf.Timestamp":
		,  := time.Parse(time.RFC3339Nano, )
		if  != nil {
			return protoreflect.Value{}, 
		}
		 := timestamppb.New()
		if  := .IsValid(); ! {
			return protoreflect.Value{}, fmt.Errorf("%s before 0001-01-01", )
		}
		 = 
	case "google.protobuf.Duration":
		,  := time.ParseDuration()
		if  != nil {
			return protoreflect.Value{}, 
		}
		 = durationpb.New()
	case "google.protobuf.DoubleValue":
		,  := strconv.ParseFloat(, 64)
		if  != nil {
			return protoreflect.Value{}, 
		}
		 = wrapperspb.Double()
	case "google.protobuf.FloatValue":
		,  := strconv.ParseFloat(, 32)
		if  != nil {
			return protoreflect.Value{}, 
		}
		 = wrapperspb.Float(float32())
	case "google.protobuf.Int64Value":
		,  := strconv.ParseInt(, 10, 64)
		if  != nil {
			return protoreflect.Value{}, 
		}
		 = wrapperspb.Int64()
	case "google.protobuf.Int32Value":
		,  := strconv.ParseInt(, 10, 32)
		if  != nil {
			return protoreflect.Value{}, 
		}
		 = wrapperspb.Int32(int32())
	case "google.protobuf.UInt64Value":
		,  := strconv.ParseUint(, 10, 64)
		if  != nil {
			return protoreflect.Value{}, 
		}
		 = wrapperspb.UInt64()
	case "google.protobuf.UInt32Value":
		,  := strconv.ParseUint(, 10, 32)
		if  != nil {
			return protoreflect.Value{}, 
		}
		 = wrapperspb.UInt32(uint32())
	case "google.protobuf.BoolValue":
		,  := strconv.ParseBool()
		if  != nil {
			return protoreflect.Value{}, 
		}
		 = wrapperspb.Bool()
	case "google.protobuf.StringValue":
		 = wrapperspb.String()
	case "google.protobuf.BytesValue":
		,  := Bytes()
		if  != nil {
			return protoreflect.Value{}, 
		}
		 = wrapperspb.Bytes()
	case "google.protobuf.FieldMask":
		 := &field_mask.FieldMask{}
		.Paths = append(.Paths, strings.Split(, ",")...)
		 = 
	case "google.protobuf.Value":
		var  structpb.Value
		if  := protojson.Unmarshal([]byte(), &);  != nil {
			return protoreflect.Value{}, 
		}
		 = &
	case "google.protobuf.Struct":
		var  structpb.Struct
		if  := protojson.Unmarshal([]byte(), &);  != nil {
			return protoreflect.Value{}, 
		}
		 = &
	default:
		return protoreflect.Value{}, fmt.Errorf("unsupported message type: %q", string(.FullName()))
	}

	return protoreflect.ValueOfMessage(.ProtoReflect()), nil
}