// isAlpha returns true if the byte is not a digit. // b must be an ASCII letter or digit. func isAlpha(b byte) bool { … } // isAlphaNum returns true if the string contains only ASCII letters or digits. func isAlphaNum(s []byte) bool { … } var ErrSyntax … var ErrDuplicateKey … type ValueError … // NewValueError creates a new ValueError. func NewValueError(tag []byte) ValueError { … } func (e ValueError) tag() []byte { … } // Error implements the error interface. func (e ValueError) Error() string { … } // Subtag returns the subtag for which the error occurred. func (e ValueError) Subtag() string { … } type scanner … func makeScannerString(s string) scanner { … } // makeScanner returns a scanner using b as the input buffer. // b is not copied and may be modified by the scanner routines. func makeScanner(b []byte) scanner { … } func (s *scanner) init() { … } // restToLower converts the string between start and end to lower case. func (s *scanner) toLower(start, end int) { … } func (s *scanner) setError(e error) { … } // resizeRange shrinks or grows the array at position oldStart such that // a new string of size newSize can fit between oldStart and oldEnd. // Sets the scan point to after the resized range. func (s *scanner) resizeRange(oldStart, oldEnd, newSize int) { … } // replace replaces the current token with repl. func (s *scanner) replace(repl string) { … } // gobble removes the current token from the input. // Caller must call scan after calling gobble. func (s *scanner) gobble(e error) { … } // deleteRange removes the given range from s.b before the current token. func (s *scanner) deleteRange(start, end int) { … } // scan parses the next token of a BCP 47 string. Tokens that are larger // than 8 characters or include non-alphanumeric characters result in an error // and are gobbled and removed from the output. // It returns the end position of the last token consumed. func (s *scanner) scan() (end int) { … } // acceptMinSize parses multiple tokens of the given size or greater. // It returns the end position of the last token consumed. func (s *scanner) acceptMinSize(min int) (end int) { … } // Parse parses the given BCP 47 string and returns a valid Tag. If parsing // failed it returns an error and any part of the tag that could be parsed. // If parsing succeeded but an unknown value was found, it returns // ValueError. The Tag returned in this case is just stripped of the unknown // value. All other values are preserved. It accepts tags in the BCP 47 format // and extensions to this standard defined in // https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers. func Parse(s string) (t Tag, err error) { … } func parse(scan *scanner, s string) (t Tag, err error) { … } // parseTag parses language, script, region and variants. // It returns a Tag and the end position in the input that was parsed. // If doNorm is true, then <lang>-<extlang> will be normalized to <extlang>. func parseTag(scan *scanner, doNorm bool) (t Tag, end int) { … } var separator … // parseVariants scans tokens as long as each token is a valid variant string. // Duplicate variants are removed. func parseVariants(scan *scanner, end int, t Tag) int { … } type variantsSort … func (s variantsSort) Len() int { … } func (s variantsSort) Swap(i, j int) { … } func (s variantsSort) Less(i, j int) bool { … } type bytesSort … func (b bytesSort) Len() int { … } func (b bytesSort) Swap(i, j int) { … } func (b bytesSort) Less(i, j int) bool { … } // parseExtensions parses and normalizes the extensions in the buffer. // It returns the last position of scan.b that is part of any extension. // It also trims scan.b to remove excess parts accordingly. func parseExtensions(scan *scanner) int { … } // parseExtension parses a single extension and returns the position of // the extension end. func parseExtension(scan *scanner) int { … } // getExtension returns the name, body and end position of the extension. func getExtension(s string, p int) (end int, ext string) { … } // nextExtension finds the next extension within the string, searching // for the -<char>- pattern from position p. // In the fast majority of cases, language tags will have at most // one extension and extensions tend to be small. func nextExtension(s string, p int) int { … }