blob: c18d0135bd380871ed760b95ff1803be4aff77f9 [file] [log] [blame]
Zack Williams41513bf2018-07-07 20:08:35 -07001# Copyright 2017-present Open Networking Foundation
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
Zsolt Harasztidafefe12016-11-14 21:29:58 -080014"""
15Monkey patched json_format to allow best effort decoding of Any fields.
16Use the additional flag (strict_any_handling=False) to trigger the
17best-effort behavior. Omit the flag, or just use the original json_format
18module fot the strict behavior.
19"""
20
21from google.protobuf import json_format
22
23class _PatchedPrinter(json_format._Printer):
24
25 def __init__(self, including_default_value_fields=False,
26 preserving_proto_field_name=False,
27 strict_any_handling=False):
28 super(_PatchedPrinter, self).__init__(including_default_value_fields,
29 preserving_proto_field_name)
30 self.strict_any_handling = strict_any_handling
31
32 def _BestEffortAnyMessageToJsonObject(self, msg):
33 try:
34 res = self._AnyMessageToJsonObject(msg)
35 except TypeError:
36 res = self._RegularMessageToJsonObject(msg, {})
37 return res
38
39
40def MessageToDict(message,
41 including_default_value_fields=False,
42 preserving_proto_field_name=False,
43 strict_any_handling=False):
44 """Converts protobuf message to a JSON dictionary.
45
46 Args:
47 message: The protocol buffers message instance to serialize.
48 including_default_value_fields: If True, singular primitive fields,
49 repeated fields, and map fields will always be serialized. If
50 False, only serialize non-empty fields. Singular message fields
51 and oneof fields are not affected by this option.
52 preserving_proto_field_name: If True, use the original proto field
53 names as defined in the .proto file. If False, convert the field
54 names to lowerCamelCase.
55 strict_any_handling: If True, converion will error out (like in the
56 original method) if an Any field with value for which the Any type
57 is not loaded is encountered. If False, the conversion will leave
58 the field un-packed, but otherwise will continue.
59
60 Returns:
61 A dict representation of the JSON formatted protocol buffer message.
62 """
63 printer = _PatchedPrinter(including_default_value_fields,
64 preserving_proto_field_name,
65 strict_any_handling=strict_any_handling)
66 # pylint: disable=protected-access
67 return printer._MessageToJsonObject(message)
68
69
70def MessageToJson(message,
71 including_default_value_fields=False,
72 preserving_proto_field_name=False,
73 strict_any_handling=False):
74 """Converts protobuf message to JSON format.
75
76 Args:
77 message: The protocol buffers message instance to serialize.
78 including_default_value_fields: If True, singular primitive fields,
79 repeated fields, and map fields will always be serialized. If
80 False, only serialize non-empty fields. Singular message fields
81 and oneof fields are not affected by this option.
82 preserving_proto_field_name: If True, use the original proto field
83 names as defined in the .proto file. If False, convert the field
84 names to lowerCamelCase.
85 strict_any_handling: If True, converion will error out (like in the
86 original method) if an Any field with value for which the Any type
87 is not loaded is encountered. If False, the conversion will leave
88 the field un-packed, but otherwise will continue.
89
90 Returns:
91 A string containing the JSON formatted protocol buffer message.
92 """
93 printer = _PatchedPrinter(including_default_value_fields,
94 preserving_proto_field_name,
95 strict_any_handling=strict_any_handling)
96 return printer.ToJsonString(message)
97
98
99json_format._WKTJSONMETHODS['google.protobuf.Any'] = [
100 '_BestEffortAnyMessageToJsonObject',
101 '_ConvertAnyMessage'
102]
103
104json_format._Printer._BestEffortAnyMessageToJsonObject = \
105 json_format._Printer._AnyMessageToJsonObject