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 // If input value is "null" and target is a pointer type, then the field should be treated as not set 643 // UNLESS the target is structpb.Value, in which case it should be set to structpb.NullValue. 644 if string(inputValue) == "null" && targetType != reflect.TypeOf(&stpb.Value{}) { 645 return nil 646 } 647 target.Set(reflect.New(targetType.Elem())) 648 649 return u.unmarshalValue(target.Elem(), inputValue, prop) 650 } 651 652 if jsu, ok := target.Addr().Interface().(JSONPBUnmarshaler); ok { 653 return jsu.UnmarshalJSONPB(u, []byte(inputValue)) 654 } 655 656 // Handle well-known types that are not pointers. 657 if w, ok := target.Addr().Interface().(wkt); ok { 658 switch w.XXX_WellKnownType() { 659 case "DoubleValue", "FloatValue", "Int64Value", "UInt64Value", 660 "Int32Value", "UInt32Value", "BoolValue", "StringValue", "BytesValue": 661 return u.unmarshalValue(target.Field(0), inputValue, prop) 662 case "Any": 663 // Use json.RawMessage pointer type instead of value to support pre-1.8 version. 664 // 1.8 changed RawMessage.MarshalJSON from pointer type to value type, see 665 // https://github.com/golang/go/issues/14493 666 var jsonFields map[string]*json.RawMessage 667 if err := json.Unmarshal(inputValue, &jsonFields); err != nil { 668 return err 669 } 670 671 val, ok := jsonFields["@type"] 672 if !ok || val == nil { 673 return errors.New("Any JSON doesn't have '@type'") 674 } 675 676 var turl string 677 if err := json.Unmarshal([]byte(*val), &turl); err != nil { 678 return fmt.Errorf("can't unmarshal Any's '@type': %q", *val) 679 } 680 target.Field(0).SetString(turl) 681 682 mname := turl 683 if slash := strings.LastIndex(mname, "/"); slash >= 0 { 684 mname = mname[slash+1:] 685 } 686 mt := proto.MessageType(mname) 687 if mt == nil { 688 return fmt.Errorf("unknown message type %q", mname) 689 } 690 691 m := reflect.New(mt.Elem()).Interface().(proto.Message) 692 if _, ok := m.(wkt); ok { 693 val, ok := jsonFields["value"] 694 if !ok { 695 return errors.New("Any JSON doesn't have 'value'") 696 } 697 698 if err := u.unmarshalValue(reflect.ValueOf(m).Elem(), *val, nil); err != nil { 699 return fmt.Errorf("can't unmarshal Any nested proto %T: %v", m, err) 700 } 701 } else { 702 delete(jsonFields, "@type") 703 nestedProto, err := json.Marshal(jsonFields) 704 if err != nil { 705 return fmt.Errorf("can't generate JSON for Any's nested proto to be unmarshaled: %v", err) 706 } 707 708 if err = u.unmarshalValue(reflect.ValueOf(m).Elem(), nestedProto, nil); err != nil { 709 return fmt.Errorf("can't unmarshal Any nested proto %T: %v", m, err) 710 } 711 } 712 713 b, err := proto.Marshal(m) 714 if err != nil { 715 return fmt.Errorf("can't marshal proto %T into Any.Value: %v", m, err) 716 } 717 target.Field(1).SetBytes(b) 718 719 return nil 720 case "Duration": 721 unq, err := strconv.Unquote(string(inputValue)) 722 if err != nil { 723 return err 724 } 725 726 d, err := time.ParseDuration(unq) 727 if err != nil { 728 return fmt.Errorf("bad Duration: %v", err) 729 } 730 731 ns := d.Nanoseconds() 732 s := ns / 1e9 733 ns %= 1e9 734 target.Field(0).SetInt(s) 735 target.Field(1).SetInt(ns) 736 return nil 737 case "Timestamp": 738 unq, err := strconv.Unquote(string(inputValue)) 739 if err != nil { 740 return err 741 } 742 743 t, err := time.Parse(time.RFC3339Nano, unq) 744 if err != nil { 745 return fmt.Errorf("bad Timestamp: %v", err) 746 } 747 748 target.Field(0).SetInt(t.Unix()) 749 target.Field(1).SetInt(int64(t.Nanosecond())) 750 return nil 751 case "Struct": 752 var m map[string]json.RawMessage 753 if err := json.Unmarshal(inputValue, &m); err != nil { 754 return fmt.Errorf("bad StructValue: %v", err) 755 } 756 757 target.Field(0).Set(reflect.ValueOf(map[string]*stpb.Value{})) 758 for k, jv := range m { 759 pv := &stpb.Value{} 760 if err := u.unmarshalValue(reflect.ValueOf(pv).Elem(), jv, prop); err != nil { 761 return fmt.Errorf("bad value in StructValue for key %q: %v", k, err) 762 } 763 target.Field(0).SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(pv)) 764 } 765 return nil 766 case "ListValue": 767 var s []json.RawMessage 768 if err := json.Unmarshal(inputValue, &s); err != nil { 769 return fmt.Errorf("bad ListValue: %v", err) 770 } 771 772 target.Field(0).Set(reflect.ValueOf(make([]*stpb.Value, len(s), len(s)))) 773 for i, sv := range s { 774 if err := u.unmarshalValue(target.Field(0).Index(i), sv, prop); err != nil { 775 return err 776 } 777 } 778 return nil 779 case "Value": 780 ivStr := string(inputValue) 781 if ivStr == "null" { 782 target.Field(0).Set(reflect.ValueOf(&stpb.Value_NullValue{})) 783 } else if v, err := strconv.ParseFloat(ivStr, 0); err == nil { 784 target.Field(0).Set(reflect.ValueOf(&stpb.Value_NumberValue{v})) 785 } else if v, err := strconv.Unquote(ivStr); err == nil { 786 target.Field(0).Set(reflect.ValueOf(&stpb.Value_StringValue{v})) 787 } else if v, err := strconv.ParseBool(ivStr); err == nil { 788 target.Field(0).Set(reflect.ValueOf(&stpb.Value_BoolValue{v})) 789 } else if err := json.Unmarshal(inputValue, &[]json.RawMessage{}); err == nil { 790 lv := &stpb.ListValue{} 791 target.Field(0).Set(reflect.ValueOf(&stpb.Value_ListValue{lv})) 792 return u.unmarshalValue(reflect.ValueOf(lv).Elem(), inputValue, prop) 793 } else if err := json.Unmarshal(inputValue, &map[string]json.RawMessage{}); err == nil { 794 sv := &stpb.Struct{} 795 target.Field(0).Set(reflect.ValueOf(&stpb.Value_StructValue{sv})) 796 return u.unmarshalValue(reflect.ValueOf(sv).Elem(), inputValue, prop) 797 } else { 798 return fmt.Errorf("unrecognized type for Value %q", ivStr) 799 } 800 return nil 801 } 802 } 803 804 // Handle enums, which have an underlying type of int32, 805 // and may appear as strings. 806 // The case of an enum appearing as a number is handled 807 // at the bottom of this function. 808 if inputValue[0] == '"' && prop != nil && prop.Enum != "" { 809 vmap := proto.EnumValueMap(prop.Enum) 810 // Don't need to do unquoting; valid enum names 811 // are from a limited character set. 812 s := inputValue[1 : len(inputValue)-1] 813 n, ok := vmap[string(s)] 814 if !ok { 815 return fmt.Errorf("unknown value %q for enum %s", s, prop.Enum) 816 } 817 if target.Kind() == reflect.Ptr { // proto2 818 target.Set(reflect.New(targetType.Elem())) 819 target = target.Elem() 820 } 821 target.SetInt(int64(n)) 822 return nil 823 } 824 825 // Handle nested messages. 826 if targetType.Kind() == reflect.Struct { 827 var jsonFields map[string]json.RawMessage 828 if err := json.Unmarshal(inputValue, &jsonFields); err != nil { 829 return err 830 } 831 832 consumeField := func(prop *proto.Properties) (json.RawMessage, bool) { 833 // Be liberal in what names we accept; both orig_name and camelName are okay. 834 fieldNames := acceptedJSONFieldNames(prop) 835 836 vOrig, okOrig := jsonFields[fieldNames.orig] 837 vCamel, okCamel := jsonFields[fieldNames.camel] 838 if !okOrig && !okCamel { 839 return nil, false 840 } 841 // If, for some reason, both are present in the data, favour the camelName. 842 var raw json.RawMessage 843 if okOrig { 844 raw = vOrig 845 delete(jsonFields, fieldNames.orig) 846 } 847 if okCamel { 848 raw = vCamel 849 delete(jsonFields, fieldNames.camel) 850 } 851 return raw, true 852 } 853 854 sprops := proto.GetProperties(targetType) 855 for i := 0; i < target.NumField(); i++ { 856 ft := target.Type().Field(i) 857 if strings.HasPrefix(ft.Name, "XXX_") { 858 continue 859 } 860 861 valueForField, ok := consumeField(sprops.Prop[i]) 862 if !ok { 863 continue 864 } 865 866 if err := u.unmarshalValue(target.Field(i), valueForField, sprops.Prop[i]); err != nil { 867 return err 868 } 869 } 870 // Check for any oneof fields. 871 if len(jsonFields) > 0 { 872 for _, oop := range sprops.OneofTypes { 873 raw, ok := consumeField(oop.Prop) 874 if !ok { 875 continue 876 } 877 nv := reflect.New(oop.Type.Elem()) 878 target.Field(oop.Field).Set(nv) 879 if err := u.unmarshalValue(nv.Elem().Field(0), raw, oop.Prop); err != nil { 880 return err 881 } 882 } 883 } 884 // Handle proto2 extensions. 885 if len(jsonFields) > 0 { 886 if ep, ok := target.Addr().Interface().(proto.Message); ok { 887 for _, ext := range proto.RegisteredExtensions(ep) { 888 name := fmt.Sprintf("[%s]", ext.Name) 889 raw, ok := jsonFields[name] 890 if !ok { 891 continue 892 } 893 delete(jsonFields, name) 894 nv := reflect.New(reflect.TypeOf(ext.ExtensionType).Elem()) 895 if err := u.unmarshalValue(nv.Elem(), raw, nil); err != nil { 896 return err 897 } 898 if err := proto.SetExtension(ep, ext, nv.Interface()); err != nil { 899 return err 900 } 901 } 902 } 903 } 904 if !u.AllowUnknownFields && len(jsonFields) > 0 { 905 // Pick any field to be the scapegoat. 906 var f string 907 for fname := range jsonFields { 908 f = fname 909 break 910 } 911 return fmt.Errorf("unknown field %q in %v", f, targetType) 912 } 913 return nil 914 } 915 916 // Handle arrays (which aren't encoded bytes) 917 if targetType.Kind() == reflect.Slice && targetType.Elem().Kind() != reflect.Uint8 { 918 var slc []json.RawMessage 919 if err := json.Unmarshal(inputValue, &slc); err != nil { 920 return err 921 } 922 if slc != nil { 923 l := len(slc) 924 target.Set(reflect.MakeSlice(targetType, l, l)) 925 for i := 0; i < l; i++ { 926 if err := u.unmarshalValue(target.Index(i), slc[i], prop); err != nil { 927 return err 928 } 929 } 930 } 931 return nil 932 } 933 934 // Handle maps (whose keys are always strings) 935 if targetType.Kind() == reflect.Map { 936 var mp map[string]json.RawMessage 937 if err := json.Unmarshal(inputValue, &mp); err != nil { 938 return err 939 } 940 if mp != nil { 941 target.Set(reflect.MakeMap(targetType)) 942 var keyprop, valprop *proto.Properties 943 if prop != nil { 944 // These could still be nil if the protobuf metadata is broken somehow. 945 // TODO: This won't work because the fields are unexported. 946 // We should probably just reparse them. 947 //keyprop, valprop = prop.mkeyprop, prop.mvalprop 948 } 949 for ks, raw := range mp { 950 // Unmarshal map key. The core json library already decoded the key into a 951 // string, so we handle that specially. Other types were quoted post-serialization. 952 var k reflect.Value 953 if targetType.Key().Kind() == reflect.String { 954 k = reflect.ValueOf(ks) 955 } else { 956 k = reflect.New(targetType.Key()).Elem() 957 if err := u.unmarshalValue(k, json.RawMessage(ks), keyprop); err != nil { 958 return err 959 } 960 } 961 962 // Unmarshal map value. 963 v := reflect.New(targetType.Elem()).Elem() 964 if err := u.unmarshalValue(v, raw, valprop); err != nil { 965 return err 966 } 967 target.SetMapIndex(k, v) 968 } 969 } 970 return nil 971 } 972 973 // 64-bit integers can be encoded as strings. In this case we drop 974 // the quotes and proceed as normal. 975 isNum := targetType.Kind() == reflect.Int64 || targetType.Kind() == reflect.Uint64 976 if isNum && strings.HasPrefix(string(inputValue), `"`) { 977 inputValue = inputValue[1 : len(inputValue)-1] 978 } 979 980 // Non-finite numbers can be encoded as strings. 981 isFloat := targetType.Kind() == reflect.Float32 || targetType.Kind() == reflect.Float64 982 if isFloat { 983 if num, ok := nonFinite[string(inputValue)]; ok { 984 target.SetFloat(num) 985 return nil 986 } 987 } 988 989 // Use the encoding/json for parsing other value types. 990 return json.Unmarshal(inputValue, target.Addr().Interface()) 991} 992 993// jsonProperties returns parsed proto.Properties for the field and corrects JSONName attribute. 994func jsonProperties(f reflect.StructField, origName bool) *proto.Properties { 995 var prop proto.Properties 996 prop.Init(f.Type, f.Name, f.Tag.Get("protobuf"), &f) 997 if origName || prop.JSONName == "" { 998 prop.JSONName = prop.OrigName 999 } 1000 return &prop 1001} 1002 1003type fieldNames struct { 1004 orig, camel string 1005} 1006 1007func acceptedJSONFieldNames(prop *proto.Properties) fieldNames { 1008 opts := fieldNames{orig: prop.OrigName, camel: prop.OrigName} 1009 if prop.JSONName != "" { 1010 opts.camel = prop.JSONName 1011 } 1012 return opts 1013} 1014 1015// Writer wrapper inspired by https://blog.golang.org/errors-are-values 1016type errWriter struct { 1017 writer io.Writer 1018 err error 1019} 1020 1021func (w *errWriter) write(str string) { 1022 if w.err != nil { 1023 return 1024 } 1025 _, w.err = w.writer.Write([]byte(str)) 1026} 1027 1028// Map fields may have key types of non-float scalars, strings and enums. 1029// The easiest way to sort them in some deterministic order is to use fmt. 1030// If this turns out to be inefficient we can always consider other options, 1031// such as doing a Schwartzian transform. 1032// 1033// Numeric keys are sorted in numeric order per 1034// https://developers.google.com/protocol-buffers/docs/proto#maps. 1035type mapKeys []reflect.Value 1036 1037func (s mapKeys) Len() int { return len(s) } 1038func (s mapKeys) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 1039func (s mapKeys) Less(i, j int) bool { 1040 if k := s[i].Kind(); k == s[j].Kind() { 1041 switch k { 1042 case reflect.Int32, reflect.Int64: 1043 return s[i].Int() < s[j].Int() 1044 case reflect.Uint32, reflect.Uint64: 1045 return s[i].Uint() < s[j].Uint() 1046 } 1047 } 1048 return fmt.Sprint(s[i].Interface()) < fmt.Sprint(s[j].Interface()) 1049} 1050