1// Go support for Protocol Buffers - Google's data interchange format 2// 3// Copyright 2015 The Go Authors. All rights reserved. 4// https://github.com/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/* 33Package jsonpb provides marshaling and unmarshaling between protocol buffers and JSON. 34It follows the specification at https://developers.google.com/protocol-buffers/docs/proto3#json. 35 36This package produces a different output than the standard "encoding/json" package, 37which does not operate correctly on protocol buffers. 38*/ 39package jsonpb 40 41import ( 42 "bytes" 43 "encoding/json" 44 "errors" 45 "fmt" 46 "io" 47 "math" 48 "reflect" 49 "sort" 50 "strconv" 51 "strings" 52 "time" 53 54 "github.com/golang/protobuf/proto" 55 56 stpb "github.com/golang/protobuf/ptypes/struct" 57) 58 59// Marshaler is a configurable object for converting between 60// protocol buffer objects and a JSON representation for them. 61type Marshaler struct { 62 // Whether to render enum values as integers, as opposed to string values. 63 EnumsAsInts bool 64 65 // Whether to render fields with zero values. 66 EmitDefaults bool 67 68 // A string to indent each level by. The presence of this field will 69 // also cause a space to appear between the field separator and 70 // value, and for newlines to be appear between fields and array 71 // elements. 72 Indent string 73 74 // Whether to use the original (.proto) name for fields. 75 OrigName bool 76} 77 78// JSONPBMarshaler is implemented by protobuf messages that customize the 79// way they are marshaled to JSON. Messages that implement this should 80// also implement JSONPBUnmarshaler so that the custom format can be 81// parsed. 82type JSONPBMarshaler interface { 83 MarshalJSONPB(*Marshaler) ([]byte, error) 84} 85 86// JSONPBUnmarshaler is implemented by protobuf messages that customize 87// the way they are unmarshaled from JSON. Messages that implement this 88// should also implement JSONPBMarshaler so that the custom format can be 89// produced. 90type JSONPBUnmarshaler interface { 91 UnmarshalJSONPB(*Unmarshaler, []byte) error 92} 93 94// Marshal marshals a protocol buffer into JSON. 95func (m *Marshaler) Marshal(out io.Writer, pb proto.Message) error { 96 writer := &errWriter{writer: out} 97 return m.marshalObject(writer, pb, "", "") 98} 99 100// MarshalToString converts a protocol buffer object to JSON string. 101func (m *Marshaler) MarshalToString(pb proto.Message) (string, error) { 102 var buf bytes.Buffer 103 if err := m.Marshal(&buf, pb); err != nil { 104 return "", err 105 } 106 return buf.String(), nil 107} 108 109type int32Slice []int32 110 111var nonFinite = map[string]float64{ 112 `"NaN"`: math.NaN(), 113 `"Infinity"`: math.Inf(1), 114 `"-Infinity"`: math.Inf(-1), 115} 116 117// For sorting extensions ids to ensure stable output. 118func (s int32Slice) Len() int { return len(s) } 119func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] } 120func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 121 122type wkt interface { 123 XXX_WellKnownType() string 124} 125 126// marshalObject writes a struct to the Writer. 127func (m *Marshaler) marshalObject(out *errWriter, v proto.Message, indent, typeURL string) error { 128 if jsm, ok := v.(JSONPBMarshaler); ok { 129 b, err := jsm.MarshalJSONPB(m) 130 if err != nil { 131 return err 132 } 133 if typeURL != "" { 134 // we are marshaling this object to an Any type 135 var js map[string]*json.RawMessage 136 if err = json.Unmarshal(b, &js); err != nil { 137 return fmt.Errorf("type %T produced invalid JSON: %v", v, err) 138 } 139 turl, err := json.Marshal(typeURL) 140 if err != nil { 141 return fmt.Errorf("failed to marshal type URL %q to JSON: %v", typeURL, err) 142 } 143 js["@type"] = (*json.RawMessage)(&turl) 144 if b, err = json.Marshal(js); err != nil { 145 return err 146 } 147 } 148 149 out.write(string(b)) 150 return out.err 151 } 152 153 s := reflect.ValueOf(v).Elem() 154 155 // Handle well-known types. 156 if wkt, ok := v.(wkt); ok { 157 switch wkt.XXX_WellKnownType() { 158 case "DoubleValue", "FloatValue", "Int64Value", "UInt64Value", 159 "Int32Value", "UInt32Value", "BoolValue", "StringValue", "BytesValue": 160 // "Wrappers use the same representation in JSON 161 // as the wrapped primitive type, ..." 162 sprop := proto.GetProperties(s.Type()) 163 return m.marshalValue(out, sprop.Prop[0], s.Field(0), indent) 164 case "Any": 165 // Any is a bit more involved. 166 return m.marshalAny(out, v, indent) 167 case "Duration": 168 // "Generated output always contains 3, 6, or 9 fractional digits, 169 // depending on required precision." 170 s, ns := s.Field(0).Int(), s.Field(1).Int() 171 d := time.Duration(s)*time.Second + time.Duration(ns)*time.Nanosecond 172 x := fmt.Sprintf("%.9f", d.Seconds()) 173 x = strings.TrimSuffix(x, "000") 174 x = strings.TrimSuffix(x, "000") 175 out.write(`"`) 176 out.write(x) 177 out.write(`s"`) 178 return out.err 179 case "Struct", "ListValue": 180 // Let marshalValue handle the `Struct.fields` map or the `ListValue.values` slice. 181 // TODO: pass the correct Properties if needed. 182 return m.marshalValue(out, &proto.Properties{}, s.Field(0), indent) 183 case "Timestamp": 184 // "RFC 3339, where generated output will always be Z-normalized 185 // and uses 3, 6 or 9 fractional digits." 186 s, ns := s.Field(0).Int(), s.Field(1).Int() 187 t := time.Unix(s, ns).UTC() 188 // time.RFC3339Nano isn't exactly right (we need to get 3/6/9 fractional digits). 189 x := t.Format("2006-01-02T15:04:05.000000000") 190 x = strings.TrimSuffix(x, "000") 191 x = strings.TrimSuffix(x, "000") 192 out.write(`"`) 193 out.write(x) 194 out.write(`Z"`) 195 return out.err 196 case "Value": 197 // Value has a single oneof. 198 kind := s.Field(0) 199 if kind.IsNil() { 200 // "absence of any variant indicates an error" 201 return errors.New("nil Value") 202 } 203 // oneof -> *T -> T -> T.F 204 x := kind.Elem().Elem().Field(0) 205 // TODO: pass the correct Properties if needed. 206 return m.marshalValue(out, &proto.Properties{}, x, indent) 207 } 208 } 209 210 out.write("{") 211 if m.Indent != "" { 212 out.write("\n") 213 } 214 215 firstField := true 216 217 if typeURL != "" { 218 if err := m.marshalTypeURL(out, indent, typeURL); err != nil { 219 return err 220 } 221 firstField = false 222 } 223 224 for i := 0; i < s.NumField(); i++ { 225 value := s.Field(i) 226 valueField := s.Type().Field(i) 227 if strings.HasPrefix(valueField.Name, "XXX_") { 228 continue 229 } 230 231 // IsNil will panic on most value kinds. 232 switch value.Kind() { 233 case reflect.Chan, reflect.Func, reflect.Interface: 234 if value.IsNil() { 235 continue 236 } 237 } 238 239 if !m.EmitDefaults { 240 switch value.Kind() { 241 case reflect.Bool: 242 if !value.Bool() { 243 continue 244 } 245 case reflect.Int32, reflect.Int64: 246 if value.Int() == 0 { 247 continue 248 } 249 case reflect.Uint32, reflect.Uint64: 250 if value.Uint() == 0 { 251 continue 252 } 253 case reflect.Float32, reflect.Float64: 254 if value.Float() == 0 { 255 continue 256 } 257 case reflect.String: 258 if value.Len() == 0 { 259 continue 260 } 261 case reflect.Map, reflect.Ptr, reflect.Slice: 262 if value.IsNil() { 263 continue 264 } 265 } 266 } 267 268 // Oneof fields need special handling. 269 if valueField.Tag.Get("protobuf_oneof") != "" { 270 // value is an interface containing &T{real_value}. 271 sv := value.Elem().Elem() // interface -> *T -> T 272 value = sv.Field(0) 273 valueField = sv.Type().Field(0) 274 } 275 prop := jsonProperties(valueField, m.OrigName) 276 if !firstField { 277 m.writeSep(out) 278 } 279 if err := m.marshalField(out, prop, value, indent); err != nil { 280 return err 281 } 282 firstField = false 283 } 284 285 // Handle proto2 extensions. 286 if ep, ok := v.(proto.Message); ok { 287 extensions := proto.RegisteredExtensions(v) 288 // Sort extensions for stable output. 289 ids := make([]int32, 0, len(extensions)) 290 for id, desc := range extensions { 291 if !proto.HasExtension(ep, desc) { 292 continue 293 } 294 ids = append(ids, id) 295 } 296 sort.Sort(int32Slice(ids)) 297 for _, id := range ids { 298 desc := extensions[id] 299 if desc == nil { 300 // unknown extension 301 continue 302 } 303 ext, extErr := proto.GetExtension(ep, desc) 304 if extErr != nil { 305 return extErr 306 } 307 value := reflect.ValueOf(ext) 308 var prop proto.Properties 309 prop.Parse(desc.Tag) 310 prop.JSONName = fmt.Sprintf("[%s]", desc.Name) 311 if !firstField { 312 m.writeSep(out) 313 } 314 if err := m.marshalField(out, &prop, value, indent); err != nil { 315 return err 316 } 317 firstField = false 318 } 319 320 } 321 322 if m.Indent != "" { 323 out.write("\n") 324 out.write(indent) 325 } 326 out.write("}") 327 return out.err 328} 329 330func (m *Marshaler) writeSep(out *errWriter) { 331 if m.Indent != "" { 332 out.write(",\n") 333 } else { 334 out.write(",") 335 } 336} 337 338func (m *Marshaler) marshalAny(out *errWriter, any proto.Message, indent string) error { 339 // "If the Any contains a value that has a special JSON mapping, 340 // it will be converted as follows: {"@type": xxx, "value": yyy}. 341 // Otherwise, the value will be converted into a JSON object, 342 // and the "@type" field will be inserted to indicate the actual data type." 343 v := reflect.ValueOf(any).Elem() 344 turl := v.Field(0).String() 345 val := v.Field(1).Bytes() 346 347 // Only the part of type_url after the last slash is relevant. 348 mname := turl 349 if slash := strings.LastIndex(mname, "/"); slash >= 0 { 350 mname = mname[slash+1:] 351 } 352 mt := proto.MessageType(mname) 353 if mt == nil { 354 return fmt.Errorf("unknown message type %q", mname) 355 } 356 msg := reflect.New(mt.Elem()).Interface().(proto.Message) 357 if err := proto.Unmarshal(val, msg); err != nil { 358 return err 359 } 360 361 if _, ok := msg.(wkt); ok { 362 out.write("{") 363 if m.Indent != "" { 364 out.write("\n") 365 } 366 if err := m.marshalTypeURL(out, indent, turl); err != nil { 367 return err 368 } 369 m.writeSep(out) 370 if m.Indent != "" { 371 out.write(indent) 372 out.write(m.Indent) 373 out.write(`"value": `) 374 } else { 375 out.write(`"value":`) 376 } 377 if err := m.marshalObject(out, msg, indent+m.Indent, ""); err != nil { 378 return err 379 } 380 if m.Indent != "" { 381 out.write("\n") 382 out.write(indent) 383 } 384 out.write("}") 385 return out.err 386 } 387 388 return m.marshalObject(out, msg, indent, turl) 389} 390 391func (m *Marshaler) marshalTypeURL(out *errWriter, indent, typeURL string) error { 392 if m.Indent != "" { 393 out.write(indent) 394 out.write(m.Indent) 395 } 396 out.write(`"@type":`) 397 if m.Indent != "" { 398 out.write(" ") 399 } 400 b, err := json.Marshal(typeURL) 401 if err != nil { 402 return err 403 } 404 out.write(string(b)) 405 return out.err 406} 407 408// marshalField writes field description and value to the Writer. 409func (m *Marshaler) marshalField(out *errWriter, prop *proto.Properties, v reflect.Value, indent string) error { 410 if m.Indent != "" { 411 out.write(indent) 412 out.write(m.Indent) 413 } 414 out.write(`"`) 415 out.write(prop.JSONName) 416 out.write(`":`) 417 if m.Indent != "" { 418 out.write(" ") 419 } 420 if err := m.marshalValue(out, prop, v, indent); err != nil { 421 return err 422 } 423 return nil 424} 425 426// marshalValue writes the value to the Writer. 427func (m *Marshaler) marshalValue(out *errWriter, prop *proto.Properties, v reflect.Value, indent string) error { 428 var err error 429 v = reflect.Indirect(v) 430 431 // Handle nil pointer 432 if v.Kind() == reflect.Invalid { 433 out.write("null") 434 return out.err 435 } 436 437 // Handle repeated elements. 438 if v.Kind() == reflect.Slice && v.Type().Elem().Kind() != reflect.Uint8 { 439 out.write("[") 440 comma := "" 441 for i := 0; i < v.Len(); i++ { 442 sliceVal := v.Index(i) 443 out.write(comma) 444 if m.Indent != "" { 445 out.write("\n") 446 out.write(indent) 447 out.write(m.Indent) 448 out.write(m.Indent) 449 } 450 if err := m.marshalValue(out, prop, sliceVal, indent+m.Indent); err != nil { 451 return err 452 } 453 comma = "," 454 } 455 if m.Indent != "" { 456 out.write("\n") 457 out.write(indent) 458 out.write(m.Indent) 459 } 460 out.write("]") 461 return out.err 462 } 463 464 // Handle well-known types. 465 // Most are handled up in marshalObject (because 99% are messages). 466 if wkt, ok := v.Interface().(wkt); ok { 467 switch wkt.XXX_WellKnownType() { 468 case "NullValue": 469 out.write("null") 470 return out.err 471 } 472 } 473 474 // Handle enumerations. 475 if !m.EnumsAsInts && prop.Enum != "" { 476 // Unknown enum values will are stringified by the proto library as their 477 // value. Such values should _not_ be quoted or they will be interpreted 478 // as an enum string instead of their value. 479 enumStr := v.Interface().(fmt.Stringer).String() 480 var valStr string 481 if v.Kind() == reflect.Ptr { 482 valStr = strconv.Itoa(int(v.Elem().Int())) 483 } else { 484 valStr = strconv.Itoa(int(v.Int())) 485 } 486 isKnownEnum := enumStr != valStr 487 if isKnownEnum { 488 out.write(`"`) 489 } 490 out.write(enumStr) 491 if isKnownEnum { 492 out.write(`"`) 493 } 494 return out.err 495 } 496 497 // Handle nested messages. 498 if v.Kind() == reflect.Struct { 499 return m.marshalObject(out, v.Addr().Interface().(proto.Message), indent+m.Indent, "") 500 } 501 502 // Handle maps. 503 // Since Go randomizes map iteration, we sort keys for stable output. 504 if v.Kind() == reflect.Map { 505 out.write(`{`) 506 keys := v.MapKeys() 507 sort.Sort(mapKeys(keys)) 508 for i, k := range keys { 509 if i > 0 { 510 out.write(`,`) 511 } 512 if m.Indent != "" { 513 out.write("\n") 514 out.write(indent) 515 out.write(m.Indent) 516 out.write(m.Indent) 517 } 518 519 b, err := json.Marshal(k.Interface()) 520 if err != nil { 521 return err 522 } 523 s := string(b) 524 525 // If the JSON is not a string value, encode it again to make it one. 526 if !strings.HasPrefix(s, `"`) { 527 b, err := json.Marshal(s) 528 if err != nil { 529 return err 530 } 531 s = string(b) 532 } 533 534 out.write(s) 535 out.write(`:`) 536 if m.Indent != "" { 537 out.write(` `) 538 } 539 540 if err := m.marshalValue(out, prop, v.MapIndex(k), indent+m.Indent); err != nil { 541 return err 542 } 543 } 544 if m.Indent != "" { 545 out.write("\n") 546 out.write(indent) 547 out.write(m.Indent) 548 } 549 out.write(`}`) 550 return out.err 551 } 552 553 // Handle non-finite floats, e.g. NaN, Infinity and -Infinity. 554 if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 { 555 f := v.Float() 556 var sval string 557 switch { 558 case math.IsInf(f, 1): 559 sval = `"Infinity"` 560 case math.IsInf(f, -1): 561 sval = `"-Infinity"` 562 case math.IsNaN(f): 563 sval = `"NaN"` 564 } 565 if sval != "" { 566 out.write(sval) 567 return out.err 568 } 569 } 570 571 // Default handling defers to the encoding/json library. 572 b, err := json.Marshal(v.Interface()) 573 if err != nil { 574 return err 575 } 576 needToQuote := string(b[0]) != `"` && (v.Kind() == reflect.Int64 || v.Kind() == reflect.Uint64) 577 if needToQuote { 578 out.write(`"`) 579 } 580 out.write(string(b)) 581 if needToQuote { 582 out.write(`"`) 583 } 584 return out.err 585} 586 587// Unmarshaler is a configurable object for converting from a JSON 588// representation to a protocol buffer object. 589type Unmarshaler struct { 590 // Whether to allow messages to contain unknown fields, as opposed to 591 // failing to unmarshal. 592 AllowUnknownFields bool 593} 594 595// UnmarshalNext unmarshals the next protocol buffer from a JSON object stream. 596// This function is lenient and will decode any options permutations of the 597// related Marshaler. 598func (u *Unmarshaler) UnmarshalNext(dec *json.Decoder, pb proto.Message) error { 599 inputValue := json.RawMessage{} 600 if err := dec.Decode(&inputValue); err != nil { 601 return err 602 } 603 return u.unmarshalValue(reflect.ValueOf(pb).Elem(), inputValue, nil) 604} 605 606// Unmarshal unmarshals a JSON object stream into a protocol 607// buffer. This function is lenient and will decode any options 608// permutations of the related Marshaler. 609func (u *Unmarshaler) Unmarshal(r io.Reader, pb proto.Message) error { 610 dec := json.NewDecoder(r) 611 return u.UnmarshalNext(dec, pb) 612} 613 614// UnmarshalNext unmarshals the next protocol buffer from a JSON object stream. 615// This function is lenient and will decode any options permutations of the 616// related Marshaler. 617func UnmarshalNext(dec *json.Decoder, pb proto.Message) error { 618 return new(Unmarshaler).UnmarshalNext(dec, pb) 619} 620 621// Unmarshal unmarshals a JSON object stream into a protocol 622// buffer. This function is lenient and will decode any options 623// permutations of the related Marshaler. 624func Unmarshal(r io.Reader, pb proto.Message) error { 625 return new(Unmarshaler).Unmarshal(r, pb) 626} 627 628// UnmarshalString will populate the fields of a protocol buffer based 629// on a JSON string. This function is lenient and will decode any options 630// permutations of the related Marshaler. 631func UnmarshalString(str string, pb proto.Message) error { 632 return new(Unmarshaler).Unmarshal(strings.NewReader(str), pb) 633} 634 635// unmarshalValue converts/copies a value into the target. 636// prop may be nil. 637func (u *Unmarshaler) unmarshalValue(target reflect.Value, inputValue json.RawMessage, prop *proto.Properties) error { 638 targetType := target.Type() 639 640 // Allocate memory for pointer fields. 641 if targetType.Kind() == reflect.Ptr { 642 target.Set(reflect.New(targetType.Elem())) 643 return u.unmarshalValue(target.Elem(), inputValue, prop) 644 } 645 646 if jsu, ok := target.Addr().Interface().(JSONPBUnmarshaler); ok { 647 return jsu.UnmarshalJSONPB(u, []byte(inputValue)) 648 } 649 650 // Handle well-known types. 651 if w, ok := target.Addr().Interface().(wkt); ok { 652 switch w.XXX_WellKnownType() { 653 case "DoubleValue", "FloatValue", "Int64Value", "UInt64Value", 654 "Int32Value", "UInt32Value", "BoolValue", "StringValue", "BytesValue": 655 // "Wrappers use the same representation in JSON 656 // as the wrapped primitive type, except that null is allowed." 657 // encoding/json will turn JSON `null` into Go `nil`, 658 // so we don't have to do any extra work. 659 return u.unmarshalValue(target.Field(0), inputValue, prop) 660 case "Any": 661 // Use json.RawMessage pointer type instead of value to support pre-1.8 version. 662 // 1.8 changed RawMessage.MarshalJSON from pointer type to value type, see 663 // https://github.com/golang/go/issues/14493 664 var jsonFields map[string]*json.RawMessage 665 if err := json.Unmarshal(inputValue, &jsonFields); err != nil { 666 return err 667 } 668 669 val, ok := jsonFields["@type"] 670 if !ok || val == nil { 671 return errors.New("Any JSON doesn't have '@type'") 672 } 673 674 var turl string 675 if err := json.Unmarshal([]byte(*val), &turl); err != nil { 676 return fmt.Errorf("can't unmarshal Any's '@type': %q", *val) 677 } 678 target.Field(0).SetString(turl) 679 680 mname := turl 681 if slash := strings.LastIndex(mname, "/"); slash >= 0 { 682 mname = mname[slash+1:] 683 } 684 mt := proto.MessageType(mname) 685 if mt == nil { 686 return fmt.Errorf("unknown message type %q", mname) 687 } 688 689 m := reflect.New(mt.Elem()).Interface().(proto.Message) 690 if _, ok := m.(wkt); ok { 691 val, ok := jsonFields["value"] 692 if !ok { 693 return errors.New("Any JSON doesn't have 'value'") 694 } 695 696 if err := u.unmarshalValue(reflect.ValueOf(m).Elem(), *val, nil); err != nil { 697 return fmt.Errorf("can't unmarshal Any nested proto %T: %v", m, err) 698 } 699 } else { 700 delete(jsonFields, "@type") 701 nestedProto, err := json.Marshal(jsonFields) 702 if err != nil { 703 return fmt.Errorf("can't generate JSON for Any's nested proto to be unmarshaled: %v", err) 704 } 705 706 if err = u.unmarshalValue(reflect.ValueOf(m).Elem(), nestedProto, nil); err != nil { 707 return fmt.Errorf("can't unmarshal Any nested proto %T: %v", m, err) 708 } 709 } 710 711 b, err := proto.Marshal(m) 712 if err != nil { 713 return fmt.Errorf("can't marshal proto %T into Any.Value: %v", m, err) 714 } 715 target.Field(1).SetBytes(b) 716 717 return nil 718 case "Duration": 719 ivStr := string(inputValue) 720 if ivStr == "null" { 721 target.Field(0).SetInt(0) 722 target.Field(1).SetInt(0) 723 return nil 724 } 725 726 unq, err := strconv.Unquote(ivStr) 727 if err != nil { 728 return err 729 } 730 d, err := time.ParseDuration(unq) 731 if err != nil { 732 return fmt.Errorf("bad Duration: %v", err) 733 } 734 ns := d.Nanoseconds() 735 s := ns / 1e9 736 ns %= 1e9 737 target.Field(0).SetInt(s) 738 target.Field(1).SetInt(ns) 739 return nil 740 case "Timestamp": 741 ivStr := string(inputValue) 742 if ivStr == "null" { 743 target.Field(0).SetInt(0) 744 target.Field(1).SetInt(0) 745 return nil 746 } 747 748 unq, err := strconv.Unquote(ivStr) 749 if err != nil { 750 return err 751 } 752 t, err := time.Parse(time.RFC3339Nano, unq) 753 if err != nil { 754 return fmt.Errorf("bad Timestamp: %v", err) 755 } 756 target.Field(0).SetInt(int64(t.Unix())) 757 target.Field(1).SetInt(int64(t.Nanosecond())) 758 return nil 759 case "Struct": 760 if string(inputValue) == "null" { 761 // Interpret a null struct as empty. 762 return nil 763 } 764 var m map[string]json.RawMessage 765 if err := json.Unmarshal(inputValue, &m); err != nil { 766 return fmt.Errorf("bad StructValue: %v", err) 767 } 768 target.Field(0).Set(reflect.ValueOf(map[string]*stpb.Value{})) 769 for k, jv := range m { 770 pv := &stpb.Value{} 771 if err := u.unmarshalValue(reflect.ValueOf(pv).Elem(), jv, prop); err != nil { 772 return fmt.Errorf("bad value in StructValue for key %q: %v", k, err) 773 } 774 target.Field(0).SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(pv)) 775 } 776 return nil 777 case "ListValue": 778 if string(inputValue) == "null" { 779 // Interpret a null ListValue as empty. 780 return nil 781 } 782 var s []json.RawMessage 783 if err := json.Unmarshal(inputValue, &s); err != nil { 784 return fmt.Errorf("bad ListValue: %v", err) 785 } 786 target.Field(0).Set(reflect.ValueOf(make([]*stpb.Value, len(s), len(s)))) 787 for i, sv := range s { 788 if err := u.unmarshalValue(target.Field(0).Index(i), sv, prop); err != nil { 789 return err 790 } 791 } 792 return nil 793 case "Value": 794 ivStr := string(inputValue) 795 if ivStr == "null" { 796 target.Field(0).Set(reflect.ValueOf(&stpb.Value_NullValue{})) 797 } else if v, err := strconv.ParseFloat(ivStr, 0); err == nil { 798 target.Field(0).Set(reflect.ValueOf(&stpb.Value_NumberValue{v})) 799 } else if v, err := strconv.Unquote(ivStr); err == nil { 800 target.Field(0).Set(reflect.ValueOf(&stpb.Value_StringValue{v})) 801 } else if v, err := strconv.ParseBool(ivStr); err == nil { 802 target.Field(0).Set(reflect.ValueOf(&stpb.Value_BoolValue{v})) 803 } else if err := json.Unmarshal(inputValue, &[]json.RawMessage{}); err == nil { 804 lv := &stpb.ListValue{} 805 target.Field(0).Set(reflect.ValueOf(&stpb.Value_ListValue{lv})) 806 return u.unmarshalValue(reflect.ValueOf(lv).Elem(), inputValue, prop) 807 } else if err := json.Unmarshal(inputValue, &map[string]json.RawMessage{}); err == nil { 808 sv := &stpb.Struct{} 809 target.Field(0).Set(reflect.ValueOf(&stpb.Value_StructValue{sv})) 810 return u.unmarshalValue(reflect.ValueOf(sv).Elem(), inputValue, prop) 811 } else { 812 return fmt.Errorf("unrecognized type for Value %q", ivStr) 813 } 814 return nil 815 } 816 } 817 818 // Handle enums, which have an underlying type of int32, 819 // and may appear as strings. 820 // The case of an enum appearing as a number is handled 821 // at the bottom of this function. 822 if inputValue[0] == '"' && prop != nil && prop.Enum != "" { 823 vmap := proto.EnumValueMap(prop.Enum) 824 // Don't need to do unquoting; valid enum names 825 // are from a limited character set. 826 s := inputValue[1 : len(inputValue)-1] 827 n, ok := vmap[string(s)] 828 if !ok { 829 return fmt.Errorf("unknown value %q for enum %s", s, prop.Enum) 830 } 831 if target.Kind() == reflect.Ptr { // proto2 832 target.Set(reflect.New(targetType.Elem())) 833 target = target.Elem() 834 } 835 target.SetInt(int64(n)) 836 return nil 837 } 838 839 // Handle nested messages. 840 if targetType.Kind() == reflect.Struct { 841 var jsonFields map[string]json.RawMessage 842 if err := json.Unmarshal(inputValue, &jsonFields); err != nil { 843 return err 844 } 845 846 consumeField := func(prop *proto.Properties) (json.RawMessage, bool) { 847 // Be liberal in what names we accept; both orig_name and camelName are okay. 848 fieldNames := acceptedJSONFieldNames(prop) 849 850 vOrig, okOrig := jsonFields[fieldNames.orig] 851 vCamel, okCamel := jsonFields[fieldNames.camel] 852 if !okOrig && !okCamel { 853 return nil, false 854 } 855 // If, for some reason, both are present in the data, favour the camelName. 856 var raw json.RawMessage 857 if okOrig { 858 raw = vOrig 859 delete(jsonFields, fieldNames.orig) 860 } 861 if okCamel { 862 raw = vCamel 863 delete(jsonFields, fieldNames.camel) 864 } 865 return raw, true 866 } 867 868 sprops := proto.GetProperties(targetType) 869 for i := 0; i < target.NumField(); i++ { 870 ft := target.Type().Field(i) 871 if strings.HasPrefix(ft.Name, "XXX_") { 872 continue 873 } 874 875 valueForField, ok := consumeField(sprops.Prop[i]) 876 if !ok { 877 continue 878 } 879 880 if err := u.unmarshalValue(target.Field(i), valueForField, sprops.Prop[i]); err != nil { 881 return err 882 } 883 } 884 // Check for any oneof fields. 885 if len(jsonFields) > 0 { 886 for _, oop := range sprops.OneofTypes { 887 raw, ok := consumeField(oop.Prop) 888 if !ok { 889 continue 890 } 891 nv := reflect.New(oop.Type.Elem()) 892 target.Field(oop.Field).Set(nv) 893 if err := u.unmarshalValue(nv.Elem().Field(0), raw, oop.Prop); err != nil { 894 return err 895 } 896 } 897 } 898 // Handle proto2 extensions. 899 if len(jsonFields) > 0 { 900 if ep, ok := target.Addr().Interface().(proto.Message); ok { 901 for _, ext := range proto.RegisteredExtensions(ep) { 902 name := fmt.Sprintf("[%s]", ext.Name) 903 raw, ok := jsonFields[name] 904 if !ok { 905 continue 906 } 907 delete(jsonFields, name) 908 nv := reflect.New(reflect.TypeOf(ext.ExtensionType).Elem()) 909 if err := u.unmarshalValue(nv.Elem(), raw, nil); err != nil { 910 return err 911 } 912 if err := proto.SetExtension(ep, ext, nv.Interface()); err != nil { 913 return err 914 } 915 } 916 } 917 } 918 if !u.AllowUnknownFields && len(jsonFields) > 0 { 919 // Pick any field to be the scapegoat. 920 var f string 921 for fname := range jsonFields { 922 f = fname 923 break 924 } 925 return fmt.Errorf("unknown field %q in %v", f, targetType) 926 } 927 return nil 928 } 929 930 // Handle arrays (which aren't encoded bytes) 931 if targetType.Kind() == reflect.Slice && targetType.Elem().Kind() != reflect.Uint8 { 932 var slc []json.RawMessage 933 if err := json.Unmarshal(inputValue, &slc); err != nil { 934 return err 935 } 936 len := len(slc) 937 target.Set(reflect.MakeSlice(targetType, len, len)) 938 for i := 0; i < len; i++ { 939 if err := u.unmarshalValue(target.Index(i), slc[i], prop); err != nil { 940 return err 941 } 942 } 943 return nil 944 } 945 946 // Handle maps (whose keys are always strings) 947 if targetType.Kind() == reflect.Map { 948 var mp map[string]json.RawMessage 949 if err := json.Unmarshal(inputValue, &mp); err != nil { 950 return err 951 } 952 target.Set(reflect.MakeMap(targetType)) 953 var keyprop, valprop *proto.Properties 954 if prop != nil { 955 // These could still be nil if the protobuf metadata is broken somehow. 956 // TODO: This won't work because the fields are unexported. 957 // We should probably just reparse them. 958 //keyprop, valprop = prop.mkeyprop, prop.mvalprop 959 } 960 for ks, raw := range mp { 961 // Unmarshal map key. The core json library already decoded the key into a 962 // string, so we handle that specially. Other types were quoted post-serialization. 963 var k reflect.Value 964 if targetType.Key().Kind() == reflect.String { 965 k = reflect.ValueOf(ks) 966 } else { 967 k = reflect.New(targetType.Key()).Elem() 968 if err := u.unmarshalValue(k, json.RawMessage(ks), keyprop); err != nil { 969 return err 970 } 971 } 972 973 // Unmarshal map value. 974 v := reflect.New(targetType.Elem()).Elem() 975 if err := u.unmarshalValue(v, raw, valprop); err != nil { 976 return err 977 } 978 target.SetMapIndex(k, v) 979 } 980 return nil 981 } 982 983 // 64-bit integers can be encoded as strings. In this case we drop 984 // the quotes and proceed as normal. 985 isNum := targetType.Kind() == reflect.Int64 || targetType.Kind() == reflect.Uint64 986 if isNum && strings.HasPrefix(string(inputValue), `"`) { 987 inputValue = inputValue[1 : len(inputValue)-1] 988 } 989 990 // Non-finite numbers can be encoded as strings. 991 isFloat := targetType.Kind() == reflect.Float32 || targetType.Kind() == reflect.Float64 992 if isFloat { 993 if num, ok := nonFinite[string(inputValue)]; ok { 994 target.SetFloat(num) 995 return nil 996 } 997 } 998 999 // Use the encoding/json for parsing other value types. 1000 return json.Unmarshal(inputValue, target.Addr().Interface()) 1001} 1002 1003// jsonProperties returns parsed proto.Properties for the field and corrects JSONName attribute. 1004func jsonProperties(f reflect.StructField, origName bool) *proto.Properties { 1005 var prop proto.Properties 1006 prop.Init(f.Type, f.Name, f.Tag.Get("protobuf"), &f) 1007 if origName || prop.JSONName == "" { 1008 prop.JSONName = prop.OrigName 1009 } 1010 return &prop 1011} 1012 1013type fieldNames struct { 1014 orig, camel string 1015} 1016 1017func acceptedJSONFieldNames(prop *proto.Properties) fieldNames { 1018 opts := fieldNames{orig: prop.OrigName, camel: prop.OrigName} 1019 if prop.JSONName != "" { 1020 opts.camel = prop.JSONName 1021 } 1022 return opts 1023} 1024 1025// Writer wrapper inspired by https://blog.golang.org/errors-are-values 1026type errWriter struct { 1027 writer io.Writer 1028 err error 1029} 1030 1031func (w *errWriter) write(str string) { 1032 if w.err != nil { 1033 return 1034 } 1035 _, w.err = w.writer.Write([]byte(str)) 1036} 1037 1038// Map fields may have key types of non-float scalars, strings and enums. 1039// The easiest way to sort them in some deterministic order is to use fmt. 1040// If this turns out to be inefficient we can always consider other options, 1041// such as doing a Schwartzian transform. 1042// 1043// Numeric keys are sorted in numeric order per 1044// https://developers.google.com/protocol-buffers/docs/proto#maps. 1045type mapKeys []reflect.Value 1046 1047func (s mapKeys) Len() int { return len(s) } 1048func (s mapKeys) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 1049func (s mapKeys) Less(i, j int) bool { 1050 if k := s[i].Kind(); k == s[j].Kind() { 1051 switch k { 1052 case reflect.Int32, reflect.Int64: 1053 return s[i].Int() < s[j].Int() 1054 case reflect.Uint32, reflect.Uint64: 1055 return s[i].Uint() < s[j].Uint() 1056 } 1057 } 1058 return fmt.Sprint(s[i].Interface()) < fmt.Sprint(s[j].Interface()) 1059} 1060