1# Copyright (C) 2020 Google LLC 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. 14 15r"""Utility class for handling protobuf message.""" 16 17from __future__ import absolute_import 18from __future__ import division 19from __future__ import print_function 20from google.protobuf import descriptor 21from six.moves import xrange # pylint:disable=redefined-builtin 22 23 24def NormalizeRepeatedFields(protobuf_message): 25 """Sorts all repeated fields and removes duplicates. 26 27 Modifies pb in place. 28 29 Args: 30 protobuf_message: The Message object to normalize. 31 32 Returns: 33 protobuf_message, modified in place. 34 """ 35 for desc, values in protobuf_message.ListFields(): 36 if desc.label is descriptor.FieldDescriptor.LABEL_REPEATED: 37 # Sort then de-dup 38 values.sort() 39 # De-dupe in place. Can't use set, etc. because messages aren't 40 # hashable. 41 for i in xrange(len(values) - 1, 0, -1): 42 if values[i] == values[i - 1]: 43 del values[i] 44 45 return protobuf_message 46 47 48def Proto2Equals(a, b): 49 """Tests if two proto2 objects are equal. 50 51 Recurses into nested messages. Uses list (not set) semantics for comparing 52 repeated fields, ie duplicates and order matter. 53 54 Returns: 55 boolean 56 """ 57 return (a.SerializeToString(deterministic=True) 58 == b.SerializeToString(deterministic=True)) 59