github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/golang/protobuf/jsonpb/jsonpb.go (about)

     1  // Go support for Protocol Buffers - Google's data interchange format
     2  //
     3  // Copyright 2015 The Go Authors.  All rights reserved.
     4  // https://yougam/libraries/golang/protobuf
     5  //
     6  // Redistribution and use in source and binary forms, with or without
     7  // modification, are permitted provided that the following conditions are
     8  // met:
     9  //
    10  //     * Redistributions of source code must retain the above copyright
    11  // notice, this list of conditions and the following disclaimer.
    12  //     * Redistributions in binary form must reproduce the above
    13  // copyright notice, this list of conditions and the following disclaimer
    14  // in the documentation and/or other materials provided with the
    15  // distribution.
    16  //     * Neither the name of Google Inc. nor the names of its
    17  // contributors may be used to endorse or promote products derived from
    18  // this software without specific prior written permission.
    19  //
    20  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    21  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    22  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    23  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    24  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    25  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    26  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    27  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    28  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    29  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    30  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    31  
    32  /*
    33  Package jsonpb provides marshaling and unmarshaling between protocol buffers and JSON.
    34  It follows the specification at https://developers.google.com/protocol-buffers/docs/proto3#json.
    35  
    36  This package produces a different output than the standard "encoding/json" package,
    37  which does not operate correctly on protocol buffers.
    38  */
    39  package jsonpb
    40  
    41  import (
    42  	"bytes"
    43  	"encoding/json"
    44  	"errors"
    45  	"fmt"
    46  	"io"
    47  	"reflect"
    48  	"sort"
    49  	"strconv"
    50  	"strings"
    51  	"time"
    52  
    53  	"github.com/insionng/yougam/libraries/golang/protobuf/proto"
    54  )
    55  
    56  var (
    57  	byteArrayType = reflect.TypeOf([]byte{})
    58  )
    59  
    60  // Marshaler is a configurable object for converting between
    61  // protocol buffer objects and a JSON representation for them.
    62  type Marshaler struct {
    63  	// Whether to render enum values as integers, as opposed to string values.
    64  	EnumsAsInts bool
    65  
    66  	// Whether to render fields with zero values.
    67  	EmitDefaults bool
    68  
    69  	// A string to indent each level by. The presence of this field will
    70  	// also cause a space to appear between the field separator and
    71  	// value, and for newlines to be appear between fields and array
    72  	// elements.
    73  	Indent string
    74  
    75  	// Whether to use the original (.proto) name for fields.
    76  	OrigName bool
    77  }
    78  
    79  // Marshal marshals a protocol buffer into JSON.
    80  func (m *Marshaler) Marshal(out io.Writer, pb proto.Message) error {
    81  	writer := &errWriter{writer: out}
    82  	return m.marshalObject(writer, pb, "")
    83  }
    84  
    85  // MarshalToString converts a protocol buffer object to JSON string.
    86  func (m *Marshaler) MarshalToString(pb proto.Message) (string, error) {
    87  	var buf bytes.Buffer
    88  	if err := m.Marshal(&buf, pb); err != nil {
    89  		return "", err
    90  	}
    91  	return buf.String(), nil
    92  }
    93  
    94  type int32Slice []int32
    95  
    96  // For sorting extensions ids to ensure stable output.
    97  func (s int32Slice) Len() int           { return len(s) }
    98  func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] }
    99  func (s int32Slice) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
   100  
   101  // marshalObject writes a struct to the Writer.
   102  func (m *Marshaler) marshalObject(out *errWriter, v proto.Message, indent string) error {
   103  	s := reflect.ValueOf(v).Elem()
   104  
   105  	// Handle well-known types.
   106  	type wkt interface {
   107  		XXX_WellKnownType() string
   108  	}
   109  	if wkt, ok := v.(wkt); ok {
   110  		switch wkt.XXX_WellKnownType() {
   111  		case "DoubleValue", "FloatValue", "Int64Value", "UInt64Value",
   112  			"Int32Value", "UInt32Value", "BoolValue", "StringValue", "BytesValue":
   113  			// "Wrappers use the same representation in JSON
   114  			//  as the wrapped primitive type, ..."
   115  			sprop := proto.GetProperties(s.Type())
   116  			return m.marshalValue(out, sprop.Prop[0], s.Field(0), indent)
   117  		case "Duration":
   118  			// "Generated output always contains 3, 6, or 9 fractional digits,
   119  			//  depending on required precision."
   120  			s, ns := s.Field(0).Int(), s.Field(1).Int()
   121  			d := time.Duration(s)*time.Second + time.Duration(ns)*time.Nanosecond
   122  			x := fmt.Sprintf("%.9f", d.Seconds())
   123  			x = strings.TrimSuffix(x, "000")
   124  			x = strings.TrimSuffix(x, "000")
   125  			out.write(`"`)
   126  			out.write(x)
   127  			out.write(`s"`)
   128  			return out.err
   129  		case "Struct":
   130  			// Let marshalValue handle the `fields` map.
   131  			// TODO: pass the correct Properties if needed.
   132  			return m.marshalValue(out, &proto.Properties{}, s.Field(0), indent)
   133  		case "Timestamp":
   134  			// "RFC 3339, where generated output will always be Z-normalized
   135  			//  and uses 3, 6 or 9 fractional digits."
   136  			s, ns := s.Field(0).Int(), s.Field(1).Int()
   137  			t := time.Unix(s, ns).UTC()
   138  			// time.RFC3339Nano isn't exactly right (we need to get 3/6/9 fractional digits).
   139  			x := t.Format("2006-01-02T15:04:05.000000000")
   140  			x = strings.TrimSuffix(x, "000")
   141  			x = strings.TrimSuffix(x, "000")
   142  			out.write(`"`)
   143  			out.write(x)
   144  			out.write(`Z"`)
   145  			return out.err
   146  		case "Value":
   147  			// Value has a single oneof.
   148  			kind := s.Field(0)
   149  			if kind.IsNil() {
   150  				// "absence of any variant indicates an error"
   151  				return errors.New("nil Value")
   152  			}
   153  			// oneof -> *T -> T -> T.F
   154  			x := kind.Elem().Elem().Field(0)
   155  			// TODO: pass the correct Properties if needed.
   156  			return m.marshalValue(out, &proto.Properties{}, x, indent)
   157  		}
   158  	}
   159  
   160  	out.write("{")
   161  	if m.Indent != "" {
   162  		out.write("\n")
   163  	}
   164  
   165  	firstField := true
   166  	for i := 0; i < s.NumField(); i++ {
   167  		value := s.Field(i)
   168  		valueField := s.Type().Field(i)
   169  		if strings.HasPrefix(valueField.Name, "XXX_") {
   170  			continue
   171  		}
   172  
   173  		// IsNil will panic on most value kinds.
   174  		switch value.Kind() {
   175  		case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
   176  			if value.IsNil() {
   177  				continue
   178  			}
   179  		}
   180  
   181  		if !m.EmitDefaults {
   182  			switch value.Kind() {
   183  			case reflect.Bool:
   184  				if !value.Bool() {
   185  					continue
   186  				}
   187  			case reflect.Int32, reflect.Int64:
   188  				if value.Int() == 0 {
   189  					continue
   190  				}
   191  			case reflect.Uint32, reflect.Uint64:
   192  				if value.Uint() == 0 {
   193  					continue
   194  				}
   195  			case reflect.Float32, reflect.Float64:
   196  				if value.Float() == 0 {
   197  					continue
   198  				}
   199  			case reflect.String:
   200  				if value.Len() == 0 {
   201  					continue
   202  				}
   203  			}
   204  		}
   205  
   206  		// Oneof fields need special handling.
   207  		if valueField.Tag.Get("protobuf_oneof") != "" {
   208  			// value is an interface containing &T{real_value}.
   209  			sv := value.Elem().Elem() // interface -> *T -> T
   210  			value = sv.Field(0)
   211  			valueField = sv.Type().Field(0)
   212  		}
   213  		prop := jsonProperties(valueField, m.OrigName)
   214  		if !firstField {
   215  			m.writeSep(out)
   216  		}
   217  		if err := m.marshalField(out, prop, value, indent); err != nil {
   218  			return err
   219  		}
   220  		firstField = false
   221  	}
   222  
   223  	// Handle proto2 extensions.
   224  	if ep, ok := v.(extendableProto); ok {
   225  		extensions := proto.RegisteredExtensions(v)
   226  		extensionMap := ep.ExtensionMap()
   227  		// Sort extensions for stable output.
   228  		ids := make([]int32, 0, len(extensionMap))
   229  		for id := range extensionMap {
   230  			ids = append(ids, id)
   231  		}
   232  		sort.Sort(int32Slice(ids))
   233  		for _, id := range ids {
   234  			desc := extensions[id]
   235  			if desc == nil {
   236  				// unknown extension
   237  				continue
   238  			}
   239  			ext, extErr := proto.GetExtension(ep, desc)
   240  			if extErr != nil {
   241  				return extErr
   242  			}
   243  			value := reflect.ValueOf(ext)
   244  			var prop proto.Properties
   245  			prop.Parse(desc.Tag)
   246  			prop.JSONName = fmt.Sprintf("[%s]", desc.Name)
   247  			if !firstField {
   248  				m.writeSep(out)
   249  			}
   250  			if err := m.marshalField(out, &prop, value, indent); err != nil {
   251  				return err
   252  			}
   253  			firstField = false
   254  		}
   255  
   256  	}
   257  
   258  	if m.Indent != "" {
   259  		out.write("\n")
   260  		out.write(indent)
   261  	}
   262  	out.write("}")
   263  	return out.err
   264  }
   265  
   266  func (m *Marshaler) writeSep(out *errWriter) {
   267  	if m.Indent != "" {
   268  		out.write(",\n")
   269  	} else {
   270  		out.write(",")
   271  	}
   272  }
   273  
   274  // marshalField writes field description and value to the Writer.
   275  func (m *Marshaler) marshalField(out *errWriter, prop *proto.Properties, v reflect.Value, indent string) error {
   276  	if m.Indent != "" {
   277  		out.write(indent)
   278  		out.write(m.Indent)
   279  	}
   280  	out.write(`"`)
   281  	out.write(prop.JSONName)
   282  	out.write(`":`)
   283  	if m.Indent != "" {
   284  		out.write(" ")
   285  	}
   286  	if err := m.marshalValue(out, prop, v, indent); err != nil {
   287  		return err
   288  	}
   289  	return nil
   290  }
   291  
   292  // marshalValue writes the value to the Writer.
   293  func (m *Marshaler) marshalValue(out *errWriter, prop *proto.Properties, v reflect.Value, indent string) error {
   294  
   295  	var err error
   296  	v = reflect.Indirect(v)
   297  
   298  	// Handle repeated elements.
   299  	if v.Type() != byteArrayType && v.Kind() == reflect.Slice {
   300  		out.write("[")
   301  		comma := ""
   302  		for i := 0; i < v.Len(); i++ {
   303  			sliceVal := v.Index(i)
   304  			out.write(comma)
   305  			if m.Indent != "" {
   306  				out.write("\n")
   307  				out.write(indent)
   308  				out.write(m.Indent)
   309  				out.write(m.Indent)
   310  			}
   311  			m.marshalValue(out, prop, sliceVal, indent+m.Indent)
   312  			comma = ","
   313  		}
   314  		if m.Indent != "" {
   315  			out.write("\n")
   316  			out.write(indent)
   317  			out.write(m.Indent)
   318  		}
   319  		out.write("]")
   320  		return out.err
   321  	}
   322  
   323  	// Handle well-known types.
   324  	// Most are handled up in marshalObject (because 99% are messages).
   325  	type wkt interface {
   326  		XXX_WellKnownType() string
   327  	}
   328  	if wkt, ok := v.Interface().(wkt); ok {
   329  		switch wkt.XXX_WellKnownType() {
   330  		case "NullValue":
   331  			out.write("null")
   332  			return out.err
   333  		}
   334  	}
   335  
   336  	// Handle enumerations.
   337  	if !m.EnumsAsInts && prop.Enum != "" {
   338  		// Unknown enum values will are stringified by the proto library as their
   339  		// value. Such values should _not_ be quoted or they will be interpreted
   340  		// as an enum string instead of their value.
   341  		enumStr := v.Interface().(fmt.Stringer).String()
   342  		var valStr string
   343  		if v.Kind() == reflect.Ptr {
   344  			valStr = strconv.Itoa(int(v.Elem().Int()))
   345  		} else {
   346  			valStr = strconv.Itoa(int(v.Int()))
   347  		}
   348  		isKnownEnum := enumStr != valStr
   349  		if isKnownEnum {
   350  			out.write(`"`)
   351  		}
   352  		out.write(enumStr)
   353  		if isKnownEnum {
   354  			out.write(`"`)
   355  		}
   356  		return out.err
   357  	}
   358  
   359  	// Handle nested messages.
   360  	if v.Kind() == reflect.Struct {
   361  		return m.marshalObject(out, v.Addr().Interface().(proto.Message), indent+m.Indent)
   362  	}
   363  
   364  	// Handle maps.
   365  	// Since Go randomizes map iteration, we sort keys for stable output.
   366  	if v.Kind() == reflect.Map {
   367  		out.write(`{`)
   368  		keys := v.MapKeys()
   369  		sort.Sort(mapKeys(keys))
   370  		for i, k := range keys {
   371  			if i > 0 {
   372  				out.write(`,`)
   373  			}
   374  			if m.Indent != "" {
   375  				out.write("\n")
   376  				out.write(indent)
   377  				out.write(m.Indent)
   378  				out.write(m.Indent)
   379  			}
   380  
   381  			b, err := json.Marshal(k.Interface())
   382  			if err != nil {
   383  				return err
   384  			}
   385  			s := string(b)
   386  
   387  			// If the JSON is not a string value, encode it again to make it one.
   388  			if !strings.HasPrefix(s, `"`) {
   389  				b, err := json.Marshal(s)
   390  				if err != nil {
   391  					return err
   392  				}
   393  				s = string(b)
   394  			}
   395  
   396  			out.write(s)
   397  			out.write(`:`)
   398  			if m.Indent != "" {
   399  				out.write(` `)
   400  			}
   401  
   402  			if err := m.marshalValue(out, prop, v.MapIndex(k), indent+m.Indent); err != nil {
   403  				return err
   404  			}
   405  		}
   406  		if m.Indent != "" {
   407  			out.write("\n")
   408  			out.write(indent)
   409  			out.write(m.Indent)
   410  		}
   411  		out.write(`}`)
   412  		return out.err
   413  	}
   414  
   415  	// Default handling defers to the encoding/json library.
   416  	b, err := json.Marshal(v.Interface())
   417  	if err != nil {
   418  		return err
   419  	}
   420  	needToQuote := string(b[0]) != `"` && (v.Kind() == reflect.Int64 || v.Kind() == reflect.Uint64)
   421  	if needToQuote {
   422  		out.write(`"`)
   423  	}
   424  	out.write(string(b))
   425  	if needToQuote {
   426  		out.write(`"`)
   427  	}
   428  	return out.err
   429  }
   430  
   431  // UnmarshalNext unmarshals the next protocol buffer from a JSON object stream.
   432  // This function is lenient and will decode any options permutations of the
   433  // related Marshaler.
   434  func UnmarshalNext(dec *json.Decoder, pb proto.Message) error {
   435  	inputValue := json.RawMessage{}
   436  	if err := dec.Decode(&inputValue); err != nil {
   437  		return err
   438  	}
   439  	return unmarshalValue(reflect.ValueOf(pb).Elem(), inputValue, nil)
   440  }
   441  
   442  // Unmarshal unmarshals a JSON object stream into a protocol
   443  // buffer. This function is lenient and will decode any options
   444  // permutations of the related Marshaler.
   445  func Unmarshal(r io.Reader, pb proto.Message) error {
   446  	dec := json.NewDecoder(r)
   447  	return UnmarshalNext(dec, pb)
   448  }
   449  
   450  // UnmarshalString will populate the fields of a protocol buffer based
   451  // on a JSON string. This function is lenient and will decode any options
   452  // permutations of the related Marshaler.
   453  func UnmarshalString(str string, pb proto.Message) error {
   454  	return Unmarshal(strings.NewReader(str), pb)
   455  }
   456  
   457  // unmarshalValue converts/copies a value into the target.
   458  // prop may be nil.
   459  func unmarshalValue(target reflect.Value, inputValue json.RawMessage, prop *proto.Properties) error {
   460  	targetType := target.Type()
   461  
   462  	// Allocate memory for pointer fields.
   463  	if targetType.Kind() == reflect.Ptr {
   464  		target.Set(reflect.New(targetType.Elem()))
   465  		return unmarshalValue(target.Elem(), inputValue, prop)
   466  	}
   467  
   468  	// Handle well-known types.
   469  	type wkt interface {
   470  		XXX_WellKnownType() string
   471  	}
   472  	if wkt, ok := target.Addr().Interface().(wkt); ok {
   473  		switch wkt.XXX_WellKnownType() {
   474  		case "DoubleValue", "FloatValue", "Int64Value", "UInt64Value",
   475  			"Int32Value", "UInt32Value", "BoolValue", "StringValue", "BytesValue":
   476  			// "Wrappers use the same representation in JSON
   477  			//  as the wrapped primitive type, except that null is allowed."
   478  			// encoding/json will turn JSON `null` into Go `nil`,
   479  			// so we don't have to do any extra work.
   480  			return unmarshalValue(target.Field(0), inputValue, prop)
   481  		case "Duration":
   482  			unq, err := strconv.Unquote(string(inputValue))
   483  			if err != nil {
   484  				return err
   485  			}
   486  			d, err := time.ParseDuration(unq)
   487  			if err != nil {
   488  				return fmt.Errorf("bad Duration: %v", err)
   489  			}
   490  			ns := d.Nanoseconds()
   491  			s := ns / 1e9
   492  			ns %= 1e9
   493  			target.Field(0).SetInt(s)
   494  			target.Field(1).SetInt(ns)
   495  			return nil
   496  		case "Timestamp":
   497  			unq, err := strconv.Unquote(string(inputValue))
   498  			if err != nil {
   499  				return err
   500  			}
   501  			t, err := time.Parse(time.RFC3339Nano, unq)
   502  			if err != nil {
   503  				return fmt.Errorf("bad Timestamp: %v", err)
   504  			}
   505  			ns := t.UnixNano()
   506  			s := ns / 1e9
   507  			ns %= 1e9
   508  			target.Field(0).SetInt(s)
   509  			target.Field(1).SetInt(ns)
   510  			return nil
   511  		}
   512  	}
   513  
   514  	// Handle enums, which have an underlying type of int32,
   515  	// and may appear as strings.
   516  	// The case of an enum appearing as a number is handled
   517  	// at the bottom of this function.
   518  	if inputValue[0] == '"' && prop != nil && prop.Enum != "" {
   519  		vmap := proto.EnumValueMap(prop.Enum)
   520  		// Don't need to do unquoting; valid enum names
   521  		// are from a limited character set.
   522  		s := inputValue[1 : len(inputValue)-1]
   523  		n, ok := vmap[string(s)]
   524  		if !ok {
   525  			return fmt.Errorf("unknown value %q for enum %s", s, prop.Enum)
   526  		}
   527  		if target.Kind() == reflect.Ptr { // proto2
   528  			target.Set(reflect.New(targetType.Elem()))
   529  			target = target.Elem()
   530  		}
   531  		target.SetInt(int64(n))
   532  		return nil
   533  	}
   534  
   535  	// Handle nested messages.
   536  	if targetType.Kind() == reflect.Struct {
   537  		var jsonFields map[string]json.RawMessage
   538  		if err := json.Unmarshal(inputValue, &jsonFields); err != nil {
   539  			return err
   540  		}
   541  
   542  		consumeField := func(prop *proto.Properties) (json.RawMessage, bool) {
   543  			// Be liberal in what names we accept; both orig_name and camelName are okay.
   544  			fieldNames := acceptedJSONFieldNames(prop)
   545  
   546  			vOrig, okOrig := jsonFields[fieldNames.orig]
   547  			vCamel, okCamel := jsonFields[fieldNames.camel]
   548  			if !okOrig && !okCamel {
   549  				return nil, false
   550  			}
   551  			// If, for some reason, both are present in the data, favour the camelName.
   552  			var raw json.RawMessage
   553  			if okOrig {
   554  				raw = vOrig
   555  				delete(jsonFields, fieldNames.orig)
   556  			}
   557  			if okCamel {
   558  				raw = vCamel
   559  				delete(jsonFields, fieldNames.camel)
   560  			}
   561  			return raw, true
   562  		}
   563  
   564  		sprops := proto.GetProperties(targetType)
   565  		for i := 0; i < target.NumField(); i++ {
   566  			ft := target.Type().Field(i)
   567  			if strings.HasPrefix(ft.Name, "XXX_") {
   568  				continue
   569  			}
   570  
   571  			valueForField, ok := consumeField(sprops.Prop[i])
   572  			if !ok {
   573  				continue
   574  			}
   575  
   576  			if err := unmarshalValue(target.Field(i), valueForField, sprops.Prop[i]); err != nil {
   577  				return err
   578  			}
   579  		}
   580  		// Check for any oneof fields.
   581  		if len(jsonFields) > 0 {
   582  			for _, oop := range sprops.OneofTypes {
   583  				raw, ok := consumeField(oop.Prop)
   584  				if !ok {
   585  					continue
   586  				}
   587  				nv := reflect.New(oop.Type.Elem())
   588  				target.Field(oop.Field).Set(nv)
   589  				if err := unmarshalValue(nv.Elem().Field(0), raw, oop.Prop); err != nil {
   590  					return err
   591  				}
   592  			}
   593  		}
   594  		if len(jsonFields) > 0 {
   595  			// Pick any field to be the scapegoat.
   596  			var f string
   597  			for fname := range jsonFields {
   598  				f = fname
   599  				break
   600  			}
   601  			return fmt.Errorf("unknown field %q in %v", f, targetType)
   602  		}
   603  		return nil
   604  	}
   605  
   606  	// Handle arrays (which aren't encoded bytes)
   607  	if targetType != byteArrayType && targetType.Kind() == reflect.Slice {
   608  		var slc []json.RawMessage
   609  		if err := json.Unmarshal(inputValue, &slc); err != nil {
   610  			return err
   611  		}
   612  		len := len(slc)
   613  		target.Set(reflect.MakeSlice(targetType, len, len))
   614  		for i := 0; i < len; i++ {
   615  			if err := unmarshalValue(target.Index(i), slc[i], prop); err != nil {
   616  				return err
   617  			}
   618  		}
   619  		return nil
   620  	}
   621  
   622  	// Handle maps (whose keys are always strings)
   623  	if targetType.Kind() == reflect.Map {
   624  		var mp map[string]json.RawMessage
   625  		if err := json.Unmarshal(inputValue, &mp); err != nil {
   626  			return err
   627  		}
   628  		target.Set(reflect.MakeMap(targetType))
   629  		var keyprop, valprop *proto.Properties
   630  		if prop != nil {
   631  			// These could still be nil if the protobuf metadata is broken somehow.
   632  			// TODO: This won't work because the fields are unexported.
   633  			// We should probably just reparse them.
   634  			//keyprop, valprop = prop.mkeyprop, prop.mvalprop
   635  		}
   636  		for ks, raw := range mp {
   637  			// Unmarshal map key. The core json library already decoded the key into a
   638  			// string, so we handle that specially. Other types were quoted post-serialization.
   639  			var k reflect.Value
   640  			if targetType.Key().Kind() == reflect.String {
   641  				k = reflect.ValueOf(ks)
   642  			} else {
   643  				k = reflect.New(targetType.Key()).Elem()
   644  				if err := unmarshalValue(k, json.RawMessage(ks), keyprop); err != nil {
   645  					return err
   646  				}
   647  			}
   648  
   649  			// Unmarshal map value.
   650  			v := reflect.New(targetType.Elem()).Elem()
   651  			if err := unmarshalValue(v, raw, valprop); err != nil {
   652  				return err
   653  			}
   654  			target.SetMapIndex(k, v)
   655  		}
   656  		return nil
   657  	}
   658  
   659  	// 64-bit integers can be encoded as strings. In this case we drop
   660  	// the quotes and proceed as normal.
   661  	isNum := targetType.Kind() == reflect.Int64 || targetType.Kind() == reflect.Uint64
   662  	if isNum && strings.HasPrefix(string(inputValue), `"`) {
   663  		inputValue = inputValue[1 : len(inputValue)-1]
   664  	}
   665  
   666  	// Use the encoding/json for parsing other value types.
   667  	return json.Unmarshal(inputValue, target.Addr().Interface())
   668  }
   669  
   670  // jsonProperties returns parsed proto.Properties for the field and corrects JSONName attribute.
   671  func jsonProperties(f reflect.StructField, origName bool) *proto.Properties {
   672  	var prop proto.Properties
   673  	prop.Init(f.Type, f.Name, f.Tag.Get("protobuf"), &f)
   674  	if origName || prop.JSONName == "" {
   675  		prop.JSONName = prop.OrigName
   676  	}
   677  	return &prop
   678  }
   679  
   680  type fieldNames struct {
   681  	orig, camel string
   682  }
   683  
   684  func acceptedJSONFieldNames(prop *proto.Properties) fieldNames {
   685  	opts := fieldNames{orig: prop.OrigName, camel: prop.OrigName}
   686  	if prop.JSONName != "" {
   687  		opts.camel = prop.JSONName
   688  	}
   689  	return opts
   690  }
   691  
   692  // extendableProto is an interface implemented by any protocol buffer that may be extended.
   693  type extendableProto interface {
   694  	proto.Message
   695  	ExtensionRangeArray() []proto.ExtensionRange
   696  	ExtensionMap() map[int32]proto.Extension
   697  }
   698  
   699  // Writer wrapper inspired by https://blog.yougam/libraries/errors-are-values
   700  type errWriter struct {
   701  	writer io.Writer
   702  	err    error
   703  }
   704  
   705  func (w *errWriter) write(str string) {
   706  	if w.err != nil {
   707  		return
   708  	}
   709  	_, w.err = w.writer.Write([]byte(str))
   710  }
   711  
   712  // Map fields may have key types of non-float scalars, strings and enums.
   713  // The easiest way to sort them in some deterministic order is to use fmt.
   714  // If this turns out to be inefficient we can always consider other options,
   715  // such as doing a Schwartzian transform.
   716  type mapKeys []reflect.Value
   717  
   718  func (s mapKeys) Len() int      { return len(s) }
   719  func (s mapKeys) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
   720  func (s mapKeys) Less(i, j int) bool {
   721  	return fmt.Sprint(s[i].Interface()) < fmt.Sprint(s[j].Interface())
   722  }