1a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson# Protocol Buffers - Google's data interchange format 2a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson# Copyright 2008 Google Inc. All rights reserved. 3afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson# https://developers.google.com/protocol-buffers/ 4a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson# 5a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson# Redistribution and use in source and binary forms, with or without 6a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson# modification, are permitted provided that the following conditions are 7a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson# met: 8a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson# 9a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson# * Redistributions of source code must retain the above copyright 10a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson# notice, this list of conditions and the following disclaimer. 11a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson# * Redistributions in binary form must reproduce the above 12a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson# copyright notice, this list of conditions and the following disclaimer 13a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson# in the documentation and/or other materials provided with the 14a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson# distribution. 15a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson# * Neither the name of Google Inc. nor the names of its 16a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson# contributors may be used to endorse or promote products derived from 17a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson# this software without specific prior written permission. 18a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson# 19a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 31a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson"""Provides a container for DescriptorProtos.""" 32a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 33a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson__author__ = 'matthewtoia@google.com (Matt Toia)' 34a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 35a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 36a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonclass Error(Exception): 37a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson pass 38a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 39a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 40a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonclass DescriptorDatabaseConflictingDefinitionError(Error): 41a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson """Raised when a proto is added with the same name & different descriptor.""" 42a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 43a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 44a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonclass DescriptorDatabase(object): 45a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson """A container accepting FileDescriptorProtos and maps DescriptorProtos.""" 46a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 47a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson def __init__(self): 48a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson self._file_desc_protos_by_file = {} 49a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson self._file_desc_protos_by_symbol = {} 50a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 51a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson def Add(self, file_desc_proto): 52a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson """Adds the FileDescriptorProto and its types to this database. 53a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 54a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson Args: 55a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson file_desc_proto: The FileDescriptorProto to add. 56a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson Raises: 57a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson DescriptorDatabaseException: if an attempt is made to add a proto 58a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson with the same name but different definition than an exisiting 59a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson proto in the database. 60a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson """ 61a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson proto_name = file_desc_proto.name 62a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if proto_name not in self._file_desc_protos_by_file: 63a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson self._file_desc_protos_by_file[proto_name] = file_desc_proto 64a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson elif self._file_desc_protos_by_file[proto_name] != file_desc_proto: 65a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson raise DescriptorDatabaseConflictingDefinitionError( 66a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson '%s already added, but with different descriptor.' % proto_name) 67a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 68a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson package = file_desc_proto.package 69a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for message in file_desc_proto.message_type: 70a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson self._file_desc_protos_by_symbol.update( 71a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson (name, file_desc_proto) for name in _ExtractSymbols(message, package)) 72a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for enum in file_desc_proto.enum_type: 73a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson self._file_desc_protos_by_symbol[ 74a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson '.'.join((package, enum.name))] = file_desc_proto 75a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 76a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson def FindFileByName(self, name): 77a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson """Finds the file descriptor proto by file name. 78a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 79a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson Typically the file name is a relative path ending to a .proto file. The 80a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson proto with the given name will have to have been added to this database 81a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson using the Add method or else an error will be raised. 82a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 83a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson Args: 84a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson name: The file name to find. 85a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 86a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson Returns: 87a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson The file descriptor proto matching the name. 88a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 89a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson Raises: 90a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson KeyError if no file by the given name was added. 91a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson """ 92a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 93a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return self._file_desc_protos_by_file[name] 94a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 95a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson def FindFileContainingSymbol(self, symbol): 96a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson """Finds the file descriptor proto containing the specified symbol. 97a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 98a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson The symbol should be a fully qualified name including the file descriptor's 99a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson package and any containing messages. Some examples: 100a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 101a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 'some.package.name.Message' 102a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 'some.package.name.Message.NestedEnum' 103a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 104a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson The file descriptor proto containing the specified symbol must be added to 105a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson this database using the Add method or else an error will be raised. 106a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 107a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson Args: 108a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson symbol: The fully qualified symbol name. 109a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 110a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson Returns: 111a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson The file descriptor proto containing the symbol. 112a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 113a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson Raises: 114a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson KeyError if no file contains the specified symbol. 115a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson """ 116a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 117a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return self._file_desc_protos_by_symbol[symbol] 118a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 119a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 120a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsondef _ExtractSymbols(desc_proto, package): 121a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson """Pulls out all the symbols from a descriptor proto. 122a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 123a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson Args: 124a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson desc_proto: The proto to extract symbols from. 125a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson package: The package containing the descriptor type. 126a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 127a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson Yields: 128a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson The fully qualified name found in the descriptor. 129a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson """ 130a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 131a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson message_name = '.'.join((package, desc_proto.name)) 132a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson yield message_name 133a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for nested_type in desc_proto.nested_type: 134a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for symbol in _ExtractSymbols(nested_type, message_name): 135a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson yield symbol 136a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for enum_type in desc_proto.enum_type: 137a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson yield '.'.join((message_name, enum_type.name)) 138