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 DescriptorPool to use as a container for proto2 descriptors.
32a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
33a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff DavidsonThe DescriptorPool is used in conjection with a DescriptorDatabase to maintain
34a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsona collection of protocol buffer descriptors for use when dynamically creating
35a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonmessage types at runtime.
36a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
37a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff DavidsonFor most applications protocol buffers should be used via modules generated by
38a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonthe protocol buffer compiler tool. This should only be used when the type of
39a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonprotocol buffers used in an application or library cannot be predetermined.
40a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
41a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff DavidsonBelow is a straightforward example on how to use this class:
42a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
43a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  pool = DescriptorPool()
44a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  file_descriptor_protos = [ ... ]
45a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for file_descriptor_proto in file_descriptor_protos:
46a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    pool.Add(file_descriptor_proto)
47a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  my_message_descriptor = pool.FindMessageTypeByName('some.package.MessageType')
48a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
49a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff DavidsonThe message descriptor can be used in conjunction with the message_factory
50a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonmodule in order to create a protocol buffer class that can be encoded and
51a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsondecoded.
52a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
53a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff DavidsonIf you want to get a Python class for the specified proto, use the
54a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonhelper functions inside google.protobuf.message_factory
55a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsondirectly instead of this class.
56a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson"""
57a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
58a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson__author__ = 'matthewtoia@google.com (Matt Toia)'
59a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
60a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonimport sys
61a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
62a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonfrom google.protobuf import descriptor
63a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonfrom google.protobuf import descriptor_database
64a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonfrom google.protobuf import text_encoding
65a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
66a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
67a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsondef _NormalizeFullyQualifiedName(name):
68a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  """Remove leading period from fully-qualified type name.
69a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
70a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  Due to b/13860351 in descriptor_database.py, types in the root namespace are
71a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  generated with a leading period. This function removes that prefix.
72a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
73a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  Args:
74a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    name: A str, the fully-qualified symbol name.
75a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
76a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  Returns:
77a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    A str, the normalized fully-qualified symbol name.
78a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  """
79a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  return name.lstrip('.')
80a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
81a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
82a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonclass DescriptorPool(object):
83a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  """A collection of protobufs dynamically constructed by descriptor protos."""
84a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
85a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  def __init__(self, descriptor_db=None):
86a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """Initializes a Pool of proto buffs.
87a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
88a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    The descriptor_db argument to the constructor is provided to allow
89a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    specialized file descriptor proto lookup code to be triggered on demand. An
90a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    example would be an implementation which will read and compile a file
91a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    specified in a call to FindFileByName() and not require the call to Add()
92a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    at all. Results from this database will be cached internally here as well.
93a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
94a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Args:
95a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      descriptor_db: A secondary source of file descriptors.
96a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """
97a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
98a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    self._internal_db = descriptor_database.DescriptorDatabase()
99a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    self._descriptor_db = descriptor_db
100a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    self._descriptors = {}
101a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    self._enum_descriptors = {}
102a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    self._file_descriptors = {}
103a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
104a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  def Add(self, file_desc_proto):
105a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """Adds the FileDescriptorProto and its types to this pool.
106a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
107a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Args:
108a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      file_desc_proto: The FileDescriptorProto to add.
109a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """
110a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
111a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    self._internal_db.Add(file_desc_proto)
112a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
113a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  def AddDescriptor(self, desc):
114a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """Adds a Descriptor to the pool, non-recursively.
115a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
116a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    If the Descriptor contains nested messages or enums, the caller must
117a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    explicitly register them. This method also registers the FileDescriptor
118a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    associated with the message.
119a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
120a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Args:
121a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      desc: A Descriptor.
122a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """
123a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if not isinstance(desc, descriptor.Descriptor):
124a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      raise TypeError('Expected instance of descriptor.Descriptor.')
125a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
126a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    self._descriptors[desc.full_name] = desc
127a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    self.AddFileDescriptor(desc.file)
128a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
129a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  def AddEnumDescriptor(self, enum_desc):
130a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """Adds an EnumDescriptor to the pool.
131a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
132a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    This method also registers the FileDescriptor associated with the message.
133a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
134a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Args:
135a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      enum_desc: An EnumDescriptor.
136a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """
137a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
138a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if not isinstance(enum_desc, descriptor.EnumDescriptor):
139a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      raise TypeError('Expected instance of descriptor.EnumDescriptor.')
140a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
141a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    self._enum_descriptors[enum_desc.full_name] = enum_desc
142a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    self.AddFileDescriptor(enum_desc.file)
143a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
144a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  def AddFileDescriptor(self, file_desc):
145a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """Adds a FileDescriptor to the pool, non-recursively.
146a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
147a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    If the FileDescriptor contains messages or enums, the caller must explicitly
148a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    register them.
149a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
150a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Args:
151a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      file_desc: A FileDescriptor.
152a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """
153a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
154a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if not isinstance(file_desc, descriptor.FileDescriptor):
155a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      raise TypeError('Expected instance of descriptor.FileDescriptor.')
156a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    self._file_descriptors[file_desc.name] = file_desc
157a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
158a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  def FindFileByName(self, file_name):
159a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """Gets a FileDescriptor by file name.
160a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
161a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Args:
162a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      file_name: The path to the file to get a descriptor for.
163a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
164a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Returns:
165a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      A FileDescriptor for the named file.
166a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
167a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Raises:
168a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      KeyError: if the file can not be found in the pool.
169a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """
170a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
171a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    try:
172a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      return self._file_descriptors[file_name]
173a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    except KeyError:
174a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      pass
175a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
176a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    try:
177a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      file_proto = self._internal_db.FindFileByName(file_name)
178a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    except KeyError:
179a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      _, error, _ = sys.exc_info()  #PY25 compatible for GAE.
180a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      if self._descriptor_db:
181a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        file_proto = self._descriptor_db.FindFileByName(file_name)
182a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      else:
183a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        raise error
184a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if not file_proto:
185a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      raise KeyError('Cannot find a file named %s' % file_name)
186a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    return self._ConvertFileProtoToFileDescriptor(file_proto)
187a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
188a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  def FindFileContainingSymbol(self, symbol):
189a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """Gets the FileDescriptor for the file containing the specified symbol.
190a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
191a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Args:
192a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      symbol: The name of the symbol to search for.
193a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
194a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Returns:
195a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      A FileDescriptor that contains the specified symbol.
196a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
197a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Raises:
198a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      KeyError: if the file can not be found in the pool.
199a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """
200a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
201a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    symbol = _NormalizeFullyQualifiedName(symbol)
202a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    try:
203a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      return self._descriptors[symbol].file
204a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    except KeyError:
205a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      pass
206a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
207a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    try:
208a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      return self._enum_descriptors[symbol].file
209a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    except KeyError:
210a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      pass
211a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
212a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    try:
213a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      file_proto = self._internal_db.FindFileContainingSymbol(symbol)
214a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    except KeyError:
215a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      _, error, _ = sys.exc_info()  #PY25 compatible for GAE.
216a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      if self._descriptor_db:
217a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        file_proto = self._descriptor_db.FindFileContainingSymbol(symbol)
218a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      else:
219a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        raise error
220a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if not file_proto:
221a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      raise KeyError('Cannot find a file containing %s' % symbol)
222a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    return self._ConvertFileProtoToFileDescriptor(file_proto)
223a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
224a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  def FindMessageTypeByName(self, full_name):
225a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """Loads the named descriptor from the pool.
226a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
227a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Args:
228a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      full_name: The full name of the descriptor to load.
229a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
230a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Returns:
231a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      The descriptor for the named type.
232a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """
233a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
234a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    full_name = _NormalizeFullyQualifiedName(full_name)
235a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if full_name not in self._descriptors:
236a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      self.FindFileContainingSymbol(full_name)
237a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    return self._descriptors[full_name]
238a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
239a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  def FindEnumTypeByName(self, full_name):
240a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """Loads the named enum descriptor from the pool.
241a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
242a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Args:
243a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      full_name: The full name of the enum descriptor to load.
244a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
245a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Returns:
246a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      The enum descriptor for the named type.
247a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """
248a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
249a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    full_name = _NormalizeFullyQualifiedName(full_name)
250a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if full_name not in self._enum_descriptors:
251a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      self.FindFileContainingSymbol(full_name)
252a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    return self._enum_descriptors[full_name]
253a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
254a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  def _ConvertFileProtoToFileDescriptor(self, file_proto):
255a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """Creates a FileDescriptor from a proto or returns a cached copy.
256a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
257a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    This method also has the side effect of loading all the symbols found in
258a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    the file into the appropriate dictionaries in the pool.
259a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
260a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Args:
261a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      file_proto: The proto to convert.
262a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
263a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Returns:
264a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      A FileDescriptor matching the passed in proto.
265a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """
266a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
267a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if file_proto.name not in self._file_descriptors:
268a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      built_deps = list(self._GetDeps(file_proto.dependency))
269a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      direct_deps = [self.FindFileByName(n) for n in file_proto.dependency]
270a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
271a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      file_descriptor = descriptor.FileDescriptor(
272a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          name=file_proto.name,
273a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          package=file_proto.package,
274a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          options=file_proto.options,
275a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          serialized_pb=file_proto.SerializeToString(),
276a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          dependencies=direct_deps)
277a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      scope = {}
278a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
279a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      # This loop extracts all the message and enum types from all the
280a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      # dependencoes of the file_proto. This is necessary to create the
281a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      # scope of available message types when defining the passed in
282a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      # file proto.
283a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      for dependency in built_deps:
284a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        scope.update(self._ExtractSymbols(
285a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson            dependency.message_types_by_name.values()))
286a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        scope.update((_PrefixWithDot(enum.full_name), enum)
287a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                     for enum in dependency.enum_types_by_name.values())
288a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
289a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      for message_type in file_proto.message_type:
290a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        message_desc = self._ConvertMessageDescriptor(
291a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson            message_type, file_proto.package, file_descriptor, scope)
292a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        file_descriptor.message_types_by_name[message_desc.name] = message_desc
293a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
294a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      for enum_type in file_proto.enum_type:
295a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        file_descriptor.enum_types_by_name[enum_type.name] = (
296a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson            self._ConvertEnumDescriptor(enum_type, file_proto.package,
297a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                                        file_descriptor, None, scope))
298a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
299a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      for index, extension_proto in enumerate(file_proto.extension):
300a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        extension_desc = self.MakeFieldDescriptor(
301a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson            extension_proto, file_proto.package, index, is_extension=True)
302a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        extension_desc.containing_type = self._GetTypeFromScope(
303a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson            file_descriptor.package, extension_proto.extendee, scope)
304a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        self.SetFieldType(extension_proto, extension_desc,
305a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                          file_descriptor.package, scope)
306a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        file_descriptor.extensions_by_name[extension_desc.name] = extension_desc
307a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
308a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      for desc_proto in file_proto.message_type:
309a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        self.SetAllFieldTypes(file_proto.package, desc_proto, scope)
310a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
311a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      if file_proto.package:
312a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        desc_proto_prefix = _PrefixWithDot(file_proto.package)
313a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      else:
314a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        desc_proto_prefix = ''
315a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
316a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      for desc_proto in file_proto.message_type:
317a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        desc = self._GetTypeFromScope(desc_proto_prefix, desc_proto.name, scope)
318a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        file_descriptor.message_types_by_name[desc_proto.name] = desc
319a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      self.Add(file_proto)
320a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      self._file_descriptors[file_proto.name] = file_descriptor
321a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
322a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    return self._file_descriptors[file_proto.name]
323a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
324a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  def _ConvertMessageDescriptor(self, desc_proto, package=None, file_desc=None,
325a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                                scope=None):
326a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """Adds the proto to the pool in the specified package.
327a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
328a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Args:
329a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      desc_proto: The descriptor_pb2.DescriptorProto protobuf message.
330a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      package: The package the proto should be located in.
331a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      file_desc: The file containing this message.
332a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      scope: Dict mapping short and full symbols to message and enum types.
333a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
334a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Returns:
335a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      The added descriptor.
336a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """
337a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
338a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if package:
339a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      desc_name = '.'.join((package, desc_proto.name))
340a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    else:
341a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      desc_name = desc_proto.name
342a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
343a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if file_desc is None:
344a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      file_name = None
345a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    else:
346a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      file_name = file_desc.name
347a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
348a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if scope is None:
349a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      scope = {}
350a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
351a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    nested = [
352a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        self._ConvertMessageDescriptor(nested, desc_name, file_desc, scope)
353a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        for nested in desc_proto.nested_type]
354a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    enums = [
355a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        self._ConvertEnumDescriptor(enum, desc_name, file_desc, None, scope)
356a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        for enum in desc_proto.enum_type]
357a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    fields = [self.MakeFieldDescriptor(field, desc_name, index)
358a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson              for index, field in enumerate(desc_proto.field)]
359a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    extensions = [
360a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        self.MakeFieldDescriptor(extension, desc_name, index, is_extension=True)
361a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        for index, extension in enumerate(desc_proto.extension)]
362a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    oneofs = [
363a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        descriptor.OneofDescriptor(desc.name, '.'.join((desc_name, desc.name)),
364a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                                   index, None, [])
365a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        for index, desc in enumerate(desc_proto.oneof_decl)]
366a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    extension_ranges = [(r.start, r.end) for r in desc_proto.extension_range]
367a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if extension_ranges:
368a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      is_extendable = True
369a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    else:
370a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      is_extendable = False
371a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    desc = descriptor.Descriptor(
372a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        name=desc_proto.name,
373a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        full_name=desc_name,
374a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        filename=file_name,
375a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        containing_type=None,
376a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        fields=fields,
377a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        oneofs=oneofs,
378a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        nested_types=nested,
379a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        enum_types=enums,
380a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        extensions=extensions,
381a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        options=desc_proto.options,
382a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        is_extendable=is_extendable,
383a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        extension_ranges=extension_ranges,
384a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        file=file_desc,
385a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        serialized_start=None,
386a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        serialized_end=None)
387a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    for nested in desc.nested_types:
388a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      nested.containing_type = desc
389a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    for enum in desc.enum_types:
390a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      enum.containing_type = desc
391a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    for field_index, field_desc in enumerate(desc_proto.field):
392a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      if field_desc.HasField('oneof_index'):
393a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        oneof_index = field_desc.oneof_index
394a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        oneofs[oneof_index].fields.append(fields[field_index])
395a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        fields[field_index].containing_oneof = oneofs[oneof_index]
396a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
397a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    scope[_PrefixWithDot(desc_name)] = desc
398a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    self._descriptors[desc_name] = desc
399a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    return desc
400a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
401a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  def _ConvertEnumDescriptor(self, enum_proto, package=None, file_desc=None,
402a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                             containing_type=None, scope=None):
403a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """Make a protobuf EnumDescriptor given an EnumDescriptorProto protobuf.
404a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
405a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Args:
406a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      enum_proto: The descriptor_pb2.EnumDescriptorProto protobuf message.
407a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      package: Optional package name for the new message EnumDescriptor.
408a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      file_desc: The file containing the enum descriptor.
409a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      containing_type: The type containing this enum.
410a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      scope: Scope containing available types.
411a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
412a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Returns:
413a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      The added descriptor
414a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """
415a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
416a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if package:
417a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      enum_name = '.'.join((package, enum_proto.name))
418a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    else:
419a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      enum_name = enum_proto.name
420a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
421a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if file_desc is None:
422a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      file_name = None
423a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    else:
424a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      file_name = file_desc.name
425a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
426a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    values = [self._MakeEnumValueDescriptor(value, index)
427a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson              for index, value in enumerate(enum_proto.value)]
428a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    desc = descriptor.EnumDescriptor(name=enum_proto.name,
429a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                                     full_name=enum_name,
430a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                                     filename=file_name,
431a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                                     file=file_desc,
432a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                                     values=values,
433a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                                     containing_type=containing_type,
434a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                                     options=enum_proto.options)
435a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    scope['.%s' % enum_name] = desc
436a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    self._enum_descriptors[enum_name] = desc
437a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    return desc
438a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
439a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  def MakeFieldDescriptor(self, field_proto, message_name, index,
440a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                          is_extension=False):
441a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """Creates a field descriptor from a FieldDescriptorProto.
442a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
443a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    For message and enum type fields, this method will do a look up
444a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    in the pool for the appropriate descriptor for that type. If it
445a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    is unavailable, it will fall back to the _source function to
446a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    create it. If this type is still unavailable, construction will
447a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    fail.
448a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
449a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Args:
450a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      field_proto: The proto describing the field.
451a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      message_name: The name of the containing message.
452a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      index: Index of the field
453a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      is_extension: Indication that this field is for an extension.
454a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
455a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Returns:
456a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      An initialized FieldDescriptor object
457a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """
458a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
459a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if message_name:
460a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      full_name = '.'.join((message_name, field_proto.name))
461a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    else:
462a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      full_name = field_proto.name
463a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
464a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    return descriptor.FieldDescriptor(
465a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        name=field_proto.name,
466a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        full_name=full_name,
467a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        index=index,
468a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        number=field_proto.number,
469a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        type=field_proto.type,
470a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        cpp_type=None,
471a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        message_type=None,
472a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        enum_type=None,
473a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        containing_type=None,
474a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        label=field_proto.label,
475a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        has_default_value=False,
476a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        default_value=None,
477a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        is_extension=is_extension,
478a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        extension_scope=None,
479a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        options=field_proto.options)
480a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
481a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  def SetAllFieldTypes(self, package, desc_proto, scope):
482a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """Sets all the descriptor's fields's types.
483a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
484a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    This method also sets the containing types on any extensions.
485a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
486a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Args:
487a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      package: The current package of desc_proto.
488a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      desc_proto: The message descriptor to update.
489a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      scope: Enclosing scope of available types.
490a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """
491a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
492a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    package = _PrefixWithDot(package)
493a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
494a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    main_desc = self._GetTypeFromScope(package, desc_proto.name, scope)
495a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
496a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if package == '.':
497a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      nested_package = _PrefixWithDot(desc_proto.name)
498a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    else:
499a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      nested_package = '.'.join([package, desc_proto.name])
500a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
501a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    for field_proto, field_desc in zip(desc_proto.field, main_desc.fields):
502a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      self.SetFieldType(field_proto, field_desc, nested_package, scope)
503a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
504a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    for extension_proto, extension_desc in (
505a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        zip(desc_proto.extension, main_desc.extensions)):
506a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      extension_desc.containing_type = self._GetTypeFromScope(
507a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          nested_package, extension_proto.extendee, scope)
508a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      self.SetFieldType(extension_proto, extension_desc, nested_package, scope)
509a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
510a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    for nested_type in desc_proto.nested_type:
511a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      self.SetAllFieldTypes(nested_package, nested_type, scope)
512a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
513a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  def SetFieldType(self, field_proto, field_desc, package, scope):
514a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """Sets the field's type, cpp_type, message_type and enum_type.
515a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
516a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Args:
517a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      field_proto: Data about the field in proto format.
518a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      field_desc: The descriptor to modiy.
519a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      package: The package the field's container is in.
520a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      scope: Enclosing scope of available types.
521a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """
522a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if field_proto.type_name:
523a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      desc = self._GetTypeFromScope(package, field_proto.type_name, scope)
524a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    else:
525a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      desc = None
526a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
527a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if not field_proto.HasField('type'):
528a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      if isinstance(desc, descriptor.Descriptor):
529a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        field_proto.type = descriptor.FieldDescriptor.TYPE_MESSAGE
530a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      else:
531a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        field_proto.type = descriptor.FieldDescriptor.TYPE_ENUM
532a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
533a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    field_desc.cpp_type = descriptor.FieldDescriptor.ProtoTypeToCppProtoType(
534a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        field_proto.type)
535a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
536a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if (field_proto.type == descriptor.FieldDescriptor.TYPE_MESSAGE
537a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        or field_proto.type == descriptor.FieldDescriptor.TYPE_GROUP):
538a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      field_desc.message_type = desc
539a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
540a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if field_proto.type == descriptor.FieldDescriptor.TYPE_ENUM:
541a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      field_desc.enum_type = desc
542a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
543a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if field_proto.label == descriptor.FieldDescriptor.LABEL_REPEATED:
544a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      field_desc.has_default_value = False
545a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      field_desc.default_value = []
546a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    elif field_proto.HasField('default_value'):
547a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      field_desc.has_default_value = True
548a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      if (field_proto.type == descriptor.FieldDescriptor.TYPE_DOUBLE or
549a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          field_proto.type == descriptor.FieldDescriptor.TYPE_FLOAT):
550a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        field_desc.default_value = float(field_proto.default_value)
551a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      elif field_proto.type == descriptor.FieldDescriptor.TYPE_STRING:
552a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        field_desc.default_value = field_proto.default_value
553a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      elif field_proto.type == descriptor.FieldDescriptor.TYPE_BOOL:
554a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        field_desc.default_value = field_proto.default_value.lower() == 'true'
555a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      elif field_proto.type == descriptor.FieldDescriptor.TYPE_ENUM:
556a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        field_desc.default_value = field_desc.enum_type.values_by_name[
557a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson            field_proto.default_value].index
558a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      elif field_proto.type == descriptor.FieldDescriptor.TYPE_BYTES:
559a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        field_desc.default_value = text_encoding.CUnescape(
560a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson            field_proto.default_value)
561a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      else:
562a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        field_desc.default_value = int(field_proto.default_value)
563a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    else:
564a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      field_desc.has_default_value = False
565a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      field_desc.default_value = None
566a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
567a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    field_desc.type = field_proto.type
568a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
569a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  def _MakeEnumValueDescriptor(self, value_proto, index):
570a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """Creates a enum value descriptor object from a enum value proto.
571a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
572a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Args:
573a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      value_proto: The proto describing the enum value.
574a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      index: The index of the enum value.
575a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
576a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Returns:
577a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      An initialized EnumValueDescriptor object.
578a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """
579a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
580a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    return descriptor.EnumValueDescriptor(
581a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        name=value_proto.name,
582a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        index=index,
583a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        number=value_proto.number,
584a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        options=value_proto.options,
585a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        type=None)
586a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
587a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  def _ExtractSymbols(self, descriptors):
588a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """Pulls out all the symbols from descriptor protos.
589a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
590a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Args:
591a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      descriptors: The messages to extract descriptors from.
592a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Yields:
593a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      A two element tuple of the type name and descriptor object.
594a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """
595a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
596a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    for desc in descriptors:
597a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      yield (_PrefixWithDot(desc.full_name), desc)
598a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      for symbol in self._ExtractSymbols(desc.nested_types):
599a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        yield symbol
600a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      for enum in desc.enum_types:
601a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        yield (_PrefixWithDot(enum.full_name), enum)
602a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
603a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  def _GetDeps(self, dependencies):
604a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """Recursively finds dependencies for file protos.
605a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
606a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Args:
607a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      dependencies: The names of the files being depended on.
608a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
609a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Yields:
610a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      Each direct and indirect dependency.
611a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """
612a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
613a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    for dependency in dependencies:
614a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      dep_desc = self.FindFileByName(dependency)
615a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      yield dep_desc
616a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      for parent_dep in dep_desc.dependencies:
617a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        yield parent_dep
618a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
619a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  def _GetTypeFromScope(self, package, type_name, scope):
620a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """Finds a given type name in the current scope.
621a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
622a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Args:
623a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      package: The package the proto should be located in.
624a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      type_name: The name of the type to be found in the scope.
625a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      scope: Dict mapping short and full symbols to message and enum types.
626a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
627a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    Returns:
628a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      The descriptor for the requested type.
629a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    """
630a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if type_name not in scope:
631a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      components = _PrefixWithDot(package).split('.')
632a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      while components:
633a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        possible_match = '.'.join(components + [type_name])
634a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        if possible_match in scope:
635a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          type_name = possible_match
636a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          break
637a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        else:
638a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          components.pop(-1)
639a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    return scope[type_name]
640a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
641a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
642a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsondef _PrefixWithDot(name):
643a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  return name if name.startswith('.') else '.%s' % name
644