(m protoreflect.Message, indent, typeURL string)
| 129 | } |
| 130 | |
| 131 | func (w *jsonWriter) marshalMessage(m protoreflect.Message, indent, typeURL string) error { |
| 132 | if jsm, ok := proto.MessageV1(m.Interface()).(JSONPBMarshaler); ok { |
| 133 | b, err := jsm.MarshalJSONPB(w.Marshaler) |
| 134 | if err != nil { |
| 135 | return err |
| 136 | } |
| 137 | if typeURL != "" { |
| 138 | // we are marshaling this object to an Any type |
| 139 | var js map[string]*json.RawMessage |
| 140 | if err = json.Unmarshal(b, &js); err != nil { |
| 141 | return fmt.Errorf("type %T produced invalid JSON: %v", m.Interface(), err) |
| 142 | } |
| 143 | turl, err := json.Marshal(typeURL) |
| 144 | if err != nil { |
| 145 | return fmt.Errorf("failed to marshal type URL %q to JSON: %v", typeURL, err) |
| 146 | } |
| 147 | js["@type"] = (*json.RawMessage)(&turl) |
| 148 | if b, err = json.Marshal(js); err != nil { |
| 149 | return err |
| 150 | } |
| 151 | } |
| 152 | w.write(string(b)) |
| 153 | return nil |
| 154 | } |
| 155 | |
| 156 | md := m.Descriptor() |
| 157 | fds := md.Fields() |
| 158 | |
| 159 | // Handle well-known types. |
| 160 | const secondInNanos = int64(time.Second / time.Nanosecond) |
| 161 | switch wellKnownType(md.FullName()) { |
| 162 | case "Any": |
| 163 | return w.marshalAny(m, indent) |
| 164 | case "BoolValue", "BytesValue", "StringValue", |
| 165 | "Int32Value", "UInt32Value", "FloatValue", |
| 166 | "Int64Value", "UInt64Value", "DoubleValue": |
| 167 | fd := fds.ByNumber(1) |
| 168 | return w.marshalValue(fd, m.Get(fd), indent) |
| 169 | case "Duration": |
| 170 | const maxSecondsInDuration = 315576000000 |
| 171 | // "Generated output always contains 0, 3, 6, or 9 fractional digits, |
| 172 | // depending on required precision." |
| 173 | s := m.Get(fds.ByNumber(1)).Int() |
| 174 | ns := m.Get(fds.ByNumber(2)).Int() |
| 175 | if s < -maxSecondsInDuration || s > maxSecondsInDuration { |
| 176 | return fmt.Errorf("seconds out of range %v", s) |
| 177 | } |
| 178 | if ns <= -secondInNanos || ns >= secondInNanos { |
| 179 | return fmt.Errorf("ns out of range (%v, %v)", -secondInNanos, secondInNanos) |
| 180 | } |
| 181 | if (s > 0 && ns < 0) || (s < 0 && ns > 0) { |
| 182 | return errors.New("signs of seconds and nanos do not match") |
| 183 | } |
| 184 | var sign string |
| 185 | if s < 0 || ns < 0 { |
| 186 | sign, s, ns = "-", -1*s, -1*ns |
| 187 | } |
| 188 | x := fmt.Sprintf("%s%d.%09d", sign, s, ns) |
no test coverage detected