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