Copyright 2018 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 defval marshals and unmarshals textual forms of default values. This package handles both the form historically used in Go struct field tags and also the form used by google.protobuf.FieldDescriptorProto.default_value since they differ in superficial ways.
package defval

import (
	
	
	

	ptext 
	errors 
	pref 
)
Format is the serialization format used to represent the default value.
type Format int

const (
	_ Format = iota
Descriptor uses the serialization format that protoc uses with the google.protobuf.FieldDescriptorProto.default_value field.
GoTag uses the historical serialization format in Go struct field tags.
	GoTag
)
Unmarshal deserializes the default string s according to the given kind k. When k is an enum, a list of enum value descriptors must be provided.
func ( string,  pref.Kind,  pref.EnumValueDescriptors,  Format) (pref.Value, pref.EnumValueDescriptor, error) {
	switch  {
	case pref.BoolKind:
		if  == GoTag {
			switch  {
			case "1":
				return pref.ValueOfBool(true), nil, nil
			case "0":
				return pref.ValueOfBool(false), nil, nil
			}
		} else {
			switch  {
			case "true":
				return pref.ValueOfBool(true), nil, nil
			case "false":
				return pref.ValueOfBool(false), nil, nil
			}
		}
	case pref.EnumKind:
Go tags use the numeric form of the enum value.
			if ,  := strconv.ParseInt(, 10, 32);  == nil {
				if  := .ByNumber(pref.EnumNumber());  != nil {
					return pref.ValueOfEnum(.Number()), , nil
				}
			}
Descriptor default_value use the enum identifier.
			 := .ByName(pref.Name())
			if  != nil {
				return pref.ValueOfEnum(.Number()), , nil
			}
		}
	case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
		if ,  := strconv.ParseInt(, 10, 32);  == nil {
			return pref.ValueOfInt32(int32()), nil, nil
		}
	case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
		if ,  := strconv.ParseInt(, 10, 64);  == nil {
			return pref.ValueOfInt64(int64()), nil, nil
		}
	case pref.Uint32Kind, pref.Fixed32Kind:
		if ,  := strconv.ParseUint(, 10, 32);  == nil {
			return pref.ValueOfUint32(uint32()), nil, nil
		}
	case pref.Uint64Kind, pref.Fixed64Kind:
		if ,  := strconv.ParseUint(, 10, 64);  == nil {
			return pref.ValueOfUint64(uint64()), nil, nil
		}
	case pref.FloatKind, pref.DoubleKind:
		var  float64
		var  error
		switch  {
		case "-inf":
			 = math.Inf(-1)
		case "inf":
			 = math.Inf(+1)
		case "nan":
			 = math.NaN()
		default:
			,  = strconv.ParseFloat(, 64)
		}
		if  == nil {
			if  == pref.FloatKind {
				return pref.ValueOfFloat32(float32()), nil, nil
			} else {
				return pref.ValueOfFloat64(float64()), nil, nil
			}
		}
String values are already unescaped and can be used as is.
		return pref.ValueOfString(), nil, nil
	case pref.BytesKind:
		if ,  := unmarshalBytes();  {
			return pref.ValueOfBytes(), nil, nil
		}
	}
	return pref.Value{}, nil, errors.New("could not parse value for %v: %q", , )
}
Marshal serializes v as the default string according to the given kind k. When specifying the Descriptor format for an enum kind, the associated enum value descriptor must be provided.
func ( pref.Value,  pref.EnumValueDescriptor,  pref.Kind,  Format) (string, error) {
	switch  {
	case pref.BoolKind:
		if  == GoTag {
			if .Bool() {
				return "1", nil
			} else {
				return "0", nil
			}
		} else {
			if .Bool() {
				return "true", nil
			} else {
				return "false", nil
			}
		}
	case pref.EnumKind:
		if  == GoTag {
			return strconv.FormatInt(int64(.Enum()), 10), nil
		} else {
			return string(.Name()), nil
		}
	case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind, pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
		return strconv.FormatInt(.Int(), 10), nil
	case pref.Uint32Kind, pref.Fixed32Kind, pref.Uint64Kind, pref.Fixed64Kind:
		return strconv.FormatUint(.Uint(), 10), nil
	case pref.FloatKind, pref.DoubleKind:
		 := .Float()
		switch {
		case math.IsInf(, -1):
			return "-inf", nil
		case math.IsInf(, +1):
			return "inf", nil
		case math.IsNaN():
			return "nan", nil
		default:
			if  == pref.FloatKind {
				return strconv.FormatFloat(, 'g', -1, 32), nil
			} else {
				return strconv.FormatFloat(, 'g', -1, 64), nil
			}
		}
String values are serialized as is without any escaping.
		return .String(), nil
	case pref.BytesKind:
		if ,  := marshalBytes(.Bytes());  {
			return , nil
		}
	}
	return "", errors.New("could not format value for %v: %v", , )
}
unmarshalBytes deserializes bytes by applying C unescaping.
Bytes values use the same escaping as the text format, however they lack the surrounding double quotes.
	,  := ptext.UnmarshalString(`"` +  + `"`)
	if  != nil {
		return nil, false
	}
	return []byte(), true
}
marshalBytes serializes bytes by using C escaping. To match the exact output of protoc, this is identical to the CEscape function in strutil.cc of the protoc source code.
func ( []byte) (string, bool) {
	var  []byte
	for ,  := range  {
		switch  {
		case '\n':
			 = append(, `\n`...)
		case '\r':
			 = append(, `\r`...)
		case '\t':
			 = append(, `\t`...)
		case '"':
			 = append(, `\"`...)
		case '\'':
			 = append(, `\'`...)
		case '\\':
			 = append(, `\\`...)
		default:
			if  :=  >= 0x20 &&  <= 0x7e;  {
				 = append(, )
			} else {
				 = append(, fmt.Sprintf(`\%03o`, )...)
			}
		}
	}
	return string(), true