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