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 strs provides string manipulation functionality specific to protobuf.
package strs

import (
	
	
	
	

	
	
)
EnforceUTF8 reports whether to enforce strict UTF-8 validation.
func ( protoreflect.FieldDescriptor) bool {
	if flags.ProtoLegacy {
		if ,  := .(interface{ () bool });  {
			return .()
		}
	}
	return .Syntax() == protoreflect.Proto3
}
GoCamelCase camel-cases a protobuf name for use as a Go identifier. If there is an interior underscore followed by a lower case letter, drop the underscore and convert the letter to upper case.
Invariant: if the next letter is lower case, it must be converted to upper case. That is, we process a word at a time, where words are marked by _ or upper case letter. Digits are treated as words.
	var  []byte
	for  := 0;  < len(); ++ {
		 := []
		switch {
Skip over '.' in ".{{lowercase}}".
		case  == '.':
			 = append(, '_') // convert '.' to '_'
Convert initial '_' to ensure we start with a capital letter. Do the same for '_' after '.' to match historic behavior.
			 = append(, 'X') // convert '_' to 'X'
Skip over '_' in "_{{lowercase}}".
		case isASCIIDigit():
			 = append(, )
Assume we have a letter now - if not, it's a bogus identifier. The next word is a sequence of characters that must start upper case.
			if isASCIILower() {
				 -= 'a' - 'A' // convert lowercase to uppercase
			}
			 = append(, )
Accept lower case sequence that follows.
			for ; +1 < len() && isASCIILower([+1]); ++ {
				 = append(, [+1])
			}
		}
	}
	return string()
}
GoSanitized converts a string to a valid Go identifier.
Sanitize the input to the set of valid characters, which must be '_' or be in the Unicode L or N categories.
	 = strings.Map(func( rune) rune {
		if unicode.IsLetter() || unicode.IsDigit() {
			return 
		}
		return '_'
	}, )
Prepend '_' in the event of a Go keyword conflict or if the identifier is invalid (does not start in the Unicode L category).
	,  := utf8.DecodeRuneInString()
	if token.Lookup().IsKeyword() || !unicode.IsLetter() {
		return "_" + 
	}
	return 
}
JSONCamelCase converts a snake_case identifier to a camelCase identifier, according to the protobuf JSON specification.
func ( string) string {
	var  []byte
	var  bool
	for  := 0;  < len(); ++ { // proto identifiers are always ASCII
		 := []
		if  != '_' {
			if  && isASCIILower() {
				 -= 'a' - 'A' // convert to uppercase
			}
			 = append(, )
		}
		 =  == '_'
	}
	return string()
}
JSONSnakeCase converts a camelCase identifier to a snake_case identifier, according to the protobuf JSON specification.
func ( string) string {
	var  []byte
	for  := 0;  < len(); ++ { // proto identifiers are always ASCII
		 := []
		if isASCIIUpper() {
			 = append(, '_')
			 += 'a' - 'A' // convert to lowercase
		}
		 = append(, )
	}
	return string()
}
MapEntryName derives the name of the map entry message given the field name. See protoc v3.8.0: src/google/protobuf/descriptor.cc:254-276,6057
func ( string) string {
	var  []byte
	 := true
	for ,  := range  {
		switch {
		case  == '_':
			 = true
		case :
			 = append(, byte(unicode.ToUpper()))
			 = false
		default:
			 = append(, byte())
		}
	}
	 = append(, "Entry"...)
	return string()
}
EnumValueName derives the camel-cased enum value name. See protoc v3.8.0: src/google/protobuf/descriptor.cc:297-313
func ( string) string {
	var  []byte
	 := true
	for ,  := range  {
		switch {
		case  == '_':
			 = true
		case :
			 = append(, byte(unicode.ToUpper()))
			 = false
		default:
			 = append(, byte(unicode.ToLower()))
			 = false
		}
	}
	return string()
}
TrimEnumPrefix trims the enum name prefix from an enum value name, where the prefix is all lowercase without underscores. See protoc v3.8.0: src/google/protobuf/descriptor.cc:330-375
func (,  string) string {
	 :=  // original input
	for len() > 0 && len() > 0 {
		if [0] == '_' {
			 = [1:]
			continue
		}
		if unicode.ToLower(rune([0])) != rune([0]) {
			return  // no prefix match
		}
		,  = [1:], [1:]
	}
	if len() > 0 {
		return  // no prefix match
	}
	 = strings.TrimLeft(, "_")
	if len() == 0 {
		return  // avoid returning empty string
	}
	return 
}

func ( byte) bool {
	return 'a' <=  &&  <= 'z'
}
func ( byte) bool {
	return 'A' <=  &&  <= 'Z'
}
func ( byte) bool {
	return '0' <=  &&  <= '9'