blob: d1672e4206c8c4eeab90752ed392b8252189a2ba [file] [log] [blame]
Zsolt Harasztidafefe12016-11-14 21:29:58 -08001"""
2Monkey patched json_format to allow best effort decoding of Any fields.
3Use the additional flag (strict_any_handling=False) to trigger the
4best-effort behavior. Omit the flag, or just use the original json_format
5module fot the strict behavior.
6"""
7
8from google.protobuf import json_format
9
10class _PatchedPrinter(json_format._Printer):
11
12 def __init__(self, including_default_value_fields=False,
13 preserving_proto_field_name=False,
14 strict_any_handling=False):
15 super(_PatchedPrinter, self).__init__(including_default_value_fields,
16 preserving_proto_field_name)
17 self.strict_any_handling = strict_any_handling
18
19 def _BestEffortAnyMessageToJsonObject(self, msg):
20 try:
21 res = self._AnyMessageToJsonObject(msg)
22 except TypeError:
23 res = self._RegularMessageToJsonObject(msg, {})
24 return res
25
26
27def MessageToDict(message,
28 including_default_value_fields=False,
29 preserving_proto_field_name=False,
30 strict_any_handling=False):
31 """Converts protobuf message to a JSON dictionary.
32
33 Args:
34 message: The protocol buffers message instance to serialize.
35 including_default_value_fields: If True, singular primitive fields,
36 repeated fields, and map fields will always be serialized. If
37 False, only serialize non-empty fields. Singular message fields
38 and oneof fields are not affected by this option.
39 preserving_proto_field_name: If True, use the original proto field
40 names as defined in the .proto file. If False, convert the field
41 names to lowerCamelCase.
42 strict_any_handling: If True, converion will error out (like in the
43 original method) if an Any field with value for which the Any type
44 is not loaded is encountered. If False, the conversion will leave
45 the field un-packed, but otherwise will continue.
46
47 Returns:
48 A dict representation of the JSON formatted protocol buffer message.
49 """
50 printer = _PatchedPrinter(including_default_value_fields,
51 preserving_proto_field_name,
52 strict_any_handling=strict_any_handling)
53 # pylint: disable=protected-access
54 return printer._MessageToJsonObject(message)
55
56
57def MessageToJson(message,
58 including_default_value_fields=False,
59 preserving_proto_field_name=False,
60 strict_any_handling=False):
61 """Converts protobuf message to JSON format.
62
63 Args:
64 message: The protocol buffers message instance to serialize.
65 including_default_value_fields: If True, singular primitive fields,
66 repeated fields, and map fields will always be serialized. If
67 False, only serialize non-empty fields. Singular message fields
68 and oneof fields are not affected by this option.
69 preserving_proto_field_name: If True, use the original proto field
70 names as defined in the .proto file. If False, convert the field
71 names to lowerCamelCase.
72 strict_any_handling: If True, converion will error out (like in the
73 original method) if an Any field with value for which the Any type
74 is not loaded is encountered. If False, the conversion will leave
75 the field un-packed, but otherwise will continue.
76
77 Returns:
78 A string containing the JSON formatted protocol buffer message.
79 """
80 printer = _PatchedPrinter(including_default_value_fields,
81 preserving_proto_field_name,
82 strict_any_handling=strict_any_handling)
83 return printer.ToJsonString(message)
84
85
86json_format._WKTJSONMETHODS['google.protobuf.Any'] = [
87 '_BestEffortAnyMessageToJsonObject',
88 '_ConvertAnyMessage'
89]
90
91json_format._Printer._BestEffortAnyMessageToJsonObject = \
92 json_format._Printer._AnyMessageToJsonObject