// 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 (
	
	
	
	
	
	
	

	
	protoV2 
	
	
)

const wrapTextUnmarshalV2 = false

// ParseError is returned by UnmarshalText.
type ParseError struct {
	Message string

	// Deprecated: Do not use.
	Line, Offset int
}

func ( *ParseError) () string {
	if wrapTextUnmarshalV2 {
		return .Message
	}
	if .Line == 1 {
		return fmt.Sprintf("line 1.%d: %v", .Offset, .Message)
	}
	return fmt.Sprintf("line %d: %v", .Line, .Message)
}

// UnmarshalText parses a proto text formatted string into m.
func ( string,  Message) error {
	if ,  := .(encoding.TextUnmarshaler);  {
		return .UnmarshalText([]byte())
	}

	.Reset()
	 := MessageV2()

	if wrapTextUnmarshalV2 {
		 := prototext.UnmarshalOptions{
			AllowPartial: true,
		}.Unmarshal([]byte(), )
		if  != nil {
			return &ParseError{Message: .Error()}
		}
		return checkRequiredNotSet()
	} else {
		if  := newTextParser().unmarshalMessage(.ProtoReflect(), "");  != nil {
			return 
		}
		return checkRequiredNotSet()
	}
}

type textParser struct {
	s            string // remaining input
	done         bool   // whether the parsing is finished (success or error)
	backed       bool   // whether back() was called
	offset, line int
	cur          token
}

type token struct {
	value    string
	err      *ParseError
	line     int    // line number
	offset   int    // byte number from start of input, not start of line
	unquoted string // the unquoted version of value, if it was a quoted string
}

func ( string) *textParser {
	 := new(textParser)
	.s = 
	.line = 1
	.cur.line = 1
	return 
}

func ( *textParser) ( protoreflect.Message,  string) ( error) {
	 := .Descriptor()
	 := .Fields()

	// A struct is a sequence of "name: value", terminated by one of
	// '>' or '}', or the end of the input.  A name may also be
	// "[extension]" or "[type/url]".
	//
	// The whole struct can also be an expanded Any message, like:
	// [type/url] < ... struct contents ... >
	 := make(map[protoreflect.FieldNumber]bool)
	for {
		 := .next()
		if .err != nil {
			return .err
		}
		if .value ==  {
			break
		}
		if .value == "[" {
			if  := .unmarshalExtensionOrAny(, );  != nil {
				return 
			}
			continue
		}

		// This is a normal, non-extension field.
		 := protoreflect.Name(.value)
		 := .ByName()
		switch {
		case  == nil:
			 := .ByName(protoreflect.Name(strings.ToLower(string())))
			if  != nil && .Kind() == protoreflect.GroupKind && .Message().Name() ==  {
				 = 
			}
		case .Kind() == protoreflect.GroupKind && .Message().Name() != :
			 = nil
		case .IsWeak() && .Message().IsPlaceholder():
			 = nil
		}
		if  == nil {
			 := string(.FullName())
			if ,  := .Interface().(Message);  {
				 := reflect.TypeOf()
				if .Kind() == reflect.Ptr {
					 = .Elem().String()
				}
			}
			return .errorf("unknown field name %q in %v", , )
		}
		if  := .ContainingOneof();  != nil && .WhichOneof() != nil {
			return .errorf("field '%s' would overwrite already parsed oneof '%s'", , .Name())
		}
		if .Cardinality() != protoreflect.Repeated && [.Number()] {
			return .errorf("non-repeated field %q was repeated", .Name())
		}
		[.Number()] = true

		// Consume any colon.
		if  := .checkForColon();  != nil {
			return 
		}

		// Parse into the field.
		 := .Get()
		if !.Has() && (.IsList() || .IsMap() || .Message() != nil) {
			 = .Mutable()
		}
		if ,  = .unmarshalValue(, );  != nil {
			return 
		}
		.Set(, )

		if  := .consumeOptionalSeparator();  != nil {
			return 
		}
	}
	return nil
}

func ( *textParser) ( protoreflect.Message,  map[protoreflect.FieldNumber]bool) error {
	,  := .consumeExtensionOrAnyName()
	if  != nil {
		return 
	}

	// If it contains a slash, it's an Any type URL.
	if  := strings.LastIndex(, "/");  >= 0 {
		 := .next()
		if .err != nil {
			return .err
		}
		// consume an optional colon
		if .value == ":" {
			 = .next()
			if .err != nil {
				return .err
			}
		}

		var  string
		switch .value {
		case "<":
			 = ">"
		case "{":
			 = "}"
		default:
			return .errorf("expected '{' or '<', found %q", .value)
		}

		,  := protoregistry.GlobalTypes.FindMessageByURL()
		if  != nil {
			return .errorf("unrecognized message %q in google.protobuf.Any", [+len("/"):])
		}
		 := .New()
		if  := .unmarshalMessage(, );  != nil {
			return 
		}
		,  := protoV2.Marshal(.Interface())
		if  != nil {
			return .errorf("failed to marshal message of type %q: %v", [+len("/"):], )
		}

		 := .Descriptor().Fields().ByName("type_url")
		 := .Descriptor().Fields().ByName("value")
		if [.Number()] {
			return .errorf("Any message unpacked multiple times, or %q already set", .Name())
		}
		if [.Number()] {
			return .errorf("Any message unpacked multiple times, or %q already set", .Name())
		}
		.Set(, protoreflect.ValueOfString())
		.Set(, protoreflect.ValueOfBytes())
		[.Number()] = true
		[.Number()] = true
		return nil
	}

	 := protoreflect.FullName()
	,  := protoregistry.GlobalTypes.FindExtensionByName()
	if  == nil && isMessageSet(.Descriptor()) {
		, _ = protoregistry.GlobalTypes.FindExtensionByName(.Append("message_set_extension"))
	}
	if  == nil {
		return .errorf("unrecognized extension %q", )
	}
	 := .TypeDescriptor()
	if .ContainingMessage().FullName() != .Descriptor().FullName() {
		return .errorf("extension field %q does not extend message %q", , .Descriptor().FullName())
	}

	if  := .checkForColon();  != nil {
		return 
	}

	 := .Get()
	if !.Has() && (.IsList() || .IsMap() || .Message() != nil) {
		 = .Mutable()
	}
	,  = .unmarshalValue(, )
	if  != nil {
		return 
	}
	.Set(, )
	return .consumeOptionalSeparator()
}

func ( *textParser) ( protoreflect.Value,  protoreflect.FieldDescriptor) (protoreflect.Value, error) {
	 := .next()
	if .err != nil {
		return , .err
	}
	if .value == "" {
		return , .errorf("unexpected EOF")
	}

	switch {
	case .IsList():
		 := .List()
		var  error
		if .value == "[" {
			// Repeated field with list notation, like [1,2,3].
			for {
				 := .NewElement()
				,  = .unmarshalSingularValue(, )
				if  != nil {
					return , 
				}
				.Append()

				 := .next()
				if .err != nil {
					return , .err
				}
				if .value == "]" {
					break
				}
				if .value != "," {
					return , .errorf("Expected ']' or ',' found %q", .value)
				}
			}
			return , nil
		}

		// One value of the repeated field.
		.back()
		 := .NewElement()
		,  = .unmarshalSingularValue(, )
		if  != nil {
			return , 
		}
		.Append()
		return , nil
	case .IsMap():
		// The map entry should be this sequence of tokens:
		//	< key : KEY value : VALUE >
		// However, implementations may omit key or value, and technically
		// we should support them in any order.
		var  string
		switch .value {
		case "<":
			 = ">"
		case "{":
			 = "}"
		default:
			return , .errorf("expected '{' or '<', found %q", .value)
		}

		 := .MapKey()
		 := .MapValue()

		 := .Map()
		 := .Default()
		 := .NewValue()
		for {
			 := .next()
			if .err != nil {
				return , .err
			}
			if .value ==  {
				break
			}
			var  error
			switch .value {
			case "key":
				if  := .consumeToken(":");  != nil {
					return , 
				}
				if ,  = .unmarshalSingularValue(, );  != nil {
					return , 
				}
				if  := .consumeOptionalSeparator();  != nil {
					return , 
				}
			case "value":
				if  := .checkForColon();  != nil {
					return , 
				}
				if ,  = .unmarshalSingularValue(, );  != nil {
					return , 
				}
				if  := .consumeOptionalSeparator();  != nil {
					return , 
				}
			default:
				.back()
				return , .errorf(`expected "key", "value", or %q, found %q`, , .value)
			}
		}
		.Set(.MapKey(), )
		return , nil
	default:
		.back()
		return .unmarshalSingularValue(, )
	}
}

func ( *textParser) ( protoreflect.Value,  protoreflect.FieldDescriptor) (protoreflect.Value, error) {
	 := .next()
	if .err != nil {
		return , .err
	}
	if .value == "" {
		return , .errorf("unexpected EOF")
	}

	switch .Kind() {
	case protoreflect.BoolKind:
		switch .value {
		case "true", "1", "t", "True":
			return protoreflect.ValueOfBool(true), nil
		case "false", "0", "f", "False":
			return protoreflect.ValueOfBool(false), nil
		}
	case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
		if ,  := strconv.ParseInt(.value, 0, 32);  == nil {
			return protoreflect.ValueOfInt32(int32()), nil
		}

		// The C++ parser accepts large positive hex numbers that uses
		// two's complement arithmetic to represent negative numbers.
		// This feature is here for backwards compatibility with C++.
		if strings.HasPrefix(.value, "0x") {
			if ,  := strconv.ParseUint(.value, 0, 32);  == nil {
				return protoreflect.ValueOfInt32(int32(-(int64(^) + 1))), nil
			}
		}
	case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
		if ,  := strconv.ParseInt(.value, 0, 64);  == nil {
			return protoreflect.ValueOfInt64(int64()), nil
		}

		// The C++ parser accepts large positive hex numbers that uses
		// two's complement arithmetic to represent negative numbers.
		// This feature is here for backwards compatibility with C++.
		if strings.HasPrefix(.value, "0x") {
			if ,  := strconv.ParseUint(.value, 0, 64);  == nil {
				return protoreflect.ValueOfInt64(int64(-(int64(^) + 1))), nil
			}
		}
	case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
		if ,  := strconv.ParseUint(.value, 0, 32);  == nil {
			return protoreflect.ValueOfUint32(uint32()), nil
		}
	case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
		if ,  := strconv.ParseUint(.value, 0, 64);  == nil {
			return protoreflect.ValueOfUint64(uint64()), nil
		}
	case protoreflect.FloatKind:
		// Ignore 'f' for compatibility with output generated by C++,
		// but don't remove 'f' when the value is "-inf" or "inf".
		 := .value
		if strings.HasSuffix(, "f") &&  != "-inf" &&  != "inf" {
			 = [:len()-len("f")]
		}
		if ,  := strconv.ParseFloat(, 32);  == nil {
			return protoreflect.ValueOfFloat32(float32()), nil
		}
	case protoreflect.DoubleKind:
		// Ignore 'f' for compatibility with output generated by C++,
		// but don't remove 'f' when the value is "-inf" or "inf".
		 := .value
		if strings.HasSuffix(, "f") &&  != "-inf" &&  != "inf" {
			 = [:len()-len("f")]
		}
		if ,  := strconv.ParseFloat(, 64);  == nil {
			return protoreflect.ValueOfFloat64(float64()), nil
		}
	case protoreflect.StringKind:
		if isQuote(.value[0]) {
			return protoreflect.ValueOfString(.unquoted), nil
		}
	case protoreflect.BytesKind:
		if isQuote(.value[0]) {
			return protoreflect.ValueOfBytes([]byte(.unquoted)), nil
		}
	case protoreflect.EnumKind:
		if ,  := strconv.ParseInt(.value, 0, 32);  == nil {
			return protoreflect.ValueOfEnum(protoreflect.EnumNumber()), nil
		}
		 := .Enum().Values().ByName(protoreflect.Name(.value))
		if  != nil {
			return protoreflect.ValueOfEnum(.Number()), nil
		}
	case protoreflect.MessageKind, protoreflect.GroupKind:
		var  string
		switch .value {
		case "{":
			 = "}"
		case "<":
			 = ">"
		default:
			return , .errorf("expected '{' or '<', found %q", .value)
		}
		 := .unmarshalMessage(.Message(), )
		return , 
	default:
		panic(fmt.Sprintf("invalid kind %v", .Kind()))
	}
	return , .errorf("invalid %v: %v", .Kind(), .value)
}

// Consume a ':' from the input stream (if the next token is a colon),
// returning an error if a colon is needed but not present.
func ( *textParser) ( protoreflect.FieldDescriptor) *ParseError {
	 := .next()
	if .err != nil {
		return .err
	}
	if .value != ":" {
		if .Message() == nil {
			return .errorf("expected ':', found %q", .value)
		}
		.back()
	}
	return nil
}

// consumeExtensionOrAnyName consumes an extension name or an Any type URL and
// the following ']'. It returns the name or URL consumed.
func ( *textParser) () (string, error) {
	 := .next()
	if .err != nil {
		return "", .err
	}

	// If extension name or type url is quoted, it's a single token.
	if len(.value) > 2 && isQuote(.value[0]) && .value[len(.value)-1] == .value[0] {
		,  := unquoteC(.value[1:len(.value)-1], rune(.value[0]))
		if  != nil {
			return "", 
		}
		return , .consumeToken("]")
	}

	// Consume everything up to "]"
	var  []string
	for .value != "]" {
		 = append(, .value)
		 = .next()
		if .err != nil {
			return "", .errorf("unrecognized type_url or extension name: %s", .err)
		}
		if .done && .value != "]" {
			return "", .errorf("unclosed type_url or extension name")
		}
	}
	return strings.Join(, ""), nil
}

// consumeOptionalSeparator consumes an optional semicolon or comma.
// It is used in unmarshalMessage to provide backward compatibility.
func ( *textParser) () error {
	 := .next()
	if .err != nil {
		return .err
	}
	if .value != ";" && .value != "," {
		.back()
	}
	return nil
}

func ( *textParser) ( string,  ...interface{}) *ParseError {
	 := &ParseError{fmt.Sprintf(, ...), .cur.line, .cur.offset}
	.cur.err = 
	.done = true
	return 
}

func ( *textParser) () {
	 := 0
	for  < len(.s) && (isWhitespace(.s[]) || .s[] == '#') {
		if .s[] == '#' {
			// comment; skip to end of line or input
			for  < len(.s) && .s[] != '\n' {
				++
			}
			if  == len(.s) {
				break
			}
		}
		if .s[] == '\n' {
			.line++
		}
		++
	}
	.offset += 
	.s = .s[:len(.s)]
	if len(.s) == 0 {
		.done = true
	}
}

func ( *textParser) () {
	// Skip whitespace
	.skipWhitespace()
	if .done {
		return
	}

	// Start of non-whitespace
	.cur.err = nil
	.cur.offset, .cur.line = .offset, .line
	.cur.unquoted = ""
	switch .s[0] {
	case '<', '>', '{', '}', ':', '[', ']', ';', ',', '/':
		// Single symbol
		.cur.value, .s = .s[0:1], .s[1:len(.s)]
	case '"', '\'':
		// Quoted string
		 := 1
		for  < len(.s) && .s[] != .s[0] && .s[] != '\n' {
			if .s[] == '\\' && +1 < len(.s) {
				// skip escaped char
				++
			}
			++
		}
		if  >= len(.s) || .s[] != .s[0] {
			.errorf("unmatched quote")
			return
		}
		,  := unquoteC(.s[1:], rune(.s[0]))
		if  != nil {
			.errorf("invalid quoted string %s: %v", .s[0:+1], )
			return
		}
		.cur.value, .s = .s[0:+1], .s[+1:len(.s)]
		.cur.unquoted = 
	default:
		 := 0
		for  < len(.s) && isIdentOrNumberChar(.s[]) {
			++
		}
		if  == 0 {
			.errorf("unexpected byte %#x", .s[0])
			return
		}
		.cur.value, .s = .s[0:], .s[:len(.s)]
	}
	.offset += len(.cur.value)
}

// Back off the parser by one token. Can only be done between calls to next().
// It makes the next advance() a no-op.
func ( *textParser) () { .backed = true }

// Advances the parser and returns the new current token.
func ( *textParser) () *token {
	if .backed || .done {
		.backed = false
		return &.cur
	}
	.advance()
	if .done {
		.cur.value = ""
	} else if len(.cur.value) > 0 && isQuote(.cur.value[0]) {
		// Look for multiple quoted strings separated by whitespace,
		// and concatenate them.
		 := .cur
		for {
			.skipWhitespace()
			if .done || !isQuote(.s[0]) {
				break
			}
			.advance()
			if .cur.err != nil {
				return &.cur
			}
			.value += " " + .cur.value
			.unquoted += .cur.unquoted
		}
		.done = false // parser may have seen EOF, but we want to return cat
		.cur = 
	}
	return &.cur
}

func ( *textParser) ( string) error {
	 := .next()
	if .err != nil {
		return .err
	}
	if .value !=  {
		.back()
		return .errorf("expected %q, found %q", , .value)
	}
	return nil
}

var errBadUTF8 = errors.New("proto: bad UTF-8")

func ( string,  rune) (string, error) {
	// This is based on C++'s tokenizer.cc.
	// Despite its name, this is *not* parsing C syntax.
	// For instance, "\0" is an invalid quoted string.

	// Avoid allocation in trivial cases.
	 := true
	for ,  := range  {
		if  == '\\' ||  ==  {
			 = false
			break
		}
	}
	if  {
		return , nil
	}

	 := make([]byte, 0, 3*len()/2)
	for len() > 0 {
		,  := utf8.DecodeRuneInString()
		if  == utf8.RuneError &&  == 1 {
			return "", errBadUTF8
		}
		 = [:]
		if  != '\\' {
			if  < utf8.RuneSelf {
				 = append(, byte())
			} else {
				 = append(, string()...)
			}
			continue
		}

		, ,  := unescape()
		if  != nil {
			return "", 
		}
		 = append(, ...)
		 = 
	}
	return string(), nil
}

func ( string) ( string,  string,  error) {
	,  := utf8.DecodeRuneInString()
	if  == utf8.RuneError &&  == 1 {
		return "", "", errBadUTF8
	}
	 = [:]
	switch  {
	case 'a':
		return "\a", , nil
	case 'b':
		return "\b", , nil
	case 'f':
		return "\f", , nil
	case 'n':
		return "\n", , nil
	case 'r':
		return "\r", , nil
	case 't':
		return "\t", , nil
	case 'v':
		return "\v", , nil
	case '?':
		return "?", , nil // trigraph workaround
	case '\'', '"', '\\':
		return string(), , nil
	case '0', '1', '2', '3', '4', '5', '6', '7':
		if len() < 2 {
			return "", "", fmt.Errorf(`\%c requires 2 following digits`, )
		}
		 := string() + [:2]
		 = [2:]
		,  := strconv.ParseUint(, 8, 8)
		if  != nil {
			return "", "", fmt.Errorf(`\%s contains non-octal digits`, )
		}
		return string([]byte{byte()}), , nil
	case 'x', 'X', 'u', 'U':
		var  int
		switch  {
		case 'x', 'X':
			 = 2
		case 'u':
			 = 4
		case 'U':
			 = 8
		}
		if len() <  {
			return "", "", fmt.Errorf(`\%c requires %d following digits`, , )
		}
		 := [:]
		 = [:]
		,  := strconv.ParseUint(, 16, 64)
		if  != nil {
			return "", "", fmt.Errorf(`\%c%s contains non-hexadecimal digits`, , )
		}
		if  == 'x' ||  == 'X' {
			return string([]byte{byte()}), , nil
		}
		if  > utf8.MaxRune {
			return "", "", fmt.Errorf(`\%c%s is not a valid Unicode code point`, , )
		}
		return string(rune()), , nil
	}
	return "", "", fmt.Errorf(`unknown escape \%c`, )
}

func ( byte) bool {
	switch {
	case 'A' <=  &&  <= 'Z', 'a' <=  &&  <= 'z':
		return true
	case '0' <=  &&  <= '9':
		return true
	}
	switch  {
	case '-', '+', '.', '_':
		return true
	}
	return false
}

func ( byte) bool {
	switch  {
	case ' ', '\t', '\n', '\r':
		return true
	}
	return false
}

func ( byte) bool {
	switch  {
	case '"', '\'':
		return true
	}
	return false
}