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