#Region "Microsoft.VisualBasic::c2efa20f5e1e465d3e3d776518d7b769, Google.Protobuf\Reflection\Descriptor\FileDescriptor.vb" ' Author: ' ' asuka (amethyst.asuka@gcmodeller.org) ' xie (genetics@smrucc.org) ' xieguigang (xie.guigang@live.com) ' ' Copyright (c) 2018 GPL3 Licensed ' ' ' GNU GENERAL PUBLIC LICENSE (GPL3) ' ' ' This program is free software: you can redistribute it and/or modify ' it under the terms of the GNU General Public License as published by ' the Free Software Foundation, either version 3 of the License, or ' (at your option) any later version. ' ' This program is distributed in the hope that it will be useful, ' but WITHOUT ANY WARRANTY; without even the implied warranty of ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ' GNU General Public License for more details. ' ' You should have received a copy of the GNU General Public License ' along with this program. If not, see . ' /********************************************************************************/ ' Summaries: ' Class FileDescriptor ' ' Properties: Dependencies, DescriptorPool, DescriptorProtoFileDescriptor, EnumTypes, File ' FullName, MessageTypes, Name, Package, Proto ' PublicDependencies, SerializedData, Services ' ' Constructor: (+1 Overloads) Sub New ' ' Function: BuildFrom, ComputeFullName, DeterminePublicDependencies, FindTypeByName, FromGeneratedCode ' ToString ' ' Sub: CrossLink ' ' ' /********************************************************************************/ #End Region #Region "Copyright notice and license" ' Protocol Buffers - Google's data interchange format ' Copyright 2008 Google Inc. All rights reserved. ' https://developers.google.com/protocol-buffers/ ' ' Redistribution and use in source and binary forms, with or without ' modification, are permitted provided that the following conditions are ' met: ' ' * Redistributions of source code must retain the above copyright ' notice, this list of conditions and the following disclaimer. ' * Redistributions in binary form must reproduce the above ' copyright notice, this list of conditions and the following disclaimer ' in the documentation and/or other materials provided with the ' distribution. ' * Neither the name of Google Inc. nor the names of its ' contributors may be used to endorse or promote products derived from ' this software without specific prior written permission. ' ' THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ' "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ' LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ' A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ' OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ' SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ' LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ' DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ' THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ' (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ' OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #End Region Imports System Imports System.Collections.Generic Imports System.Collections.ObjectModel Namespace Google.Protobuf.Reflection ''' ''' Describes a .proto file, including everything defined within. ''' IDescriptor is implemented such that the File property returns this descriptor, ''' and the FullName is the same as the Name. ''' Public NotInheritable Class FileDescriptor Implements IDescriptor Private Sub New(descriptorData As ByteString, proto As FileDescriptorProto, dependencies As FileDescriptor(), pool As DescriptorPool, allowUnknownDependencies As Boolean, generatedCodeInfo As GeneratedClrTypeInfo) SerializedData = descriptorData DescriptorPool = pool Me.Proto = proto Me.Dependencies = New ReadOnlyCollection(Of FileDescriptor)(CType(dependencies.Clone(), FileDescriptor())) PublicDependencies = DeterminePublicDependencies(Me, proto, dependencies, allowUnknownDependencies) pool.AddPackage(Package, Me) MessageTypes = DescriptorUtil.ConvertAndMakeReadOnly(proto.MessageType, Function(message, index) New MessageDescriptor(message, Me, Nothing, index, generatedCodeInfo.NestedTypes(index))) EnumTypes = DescriptorUtil.ConvertAndMakeReadOnly(proto.EnumType, Function(enumType, index) New EnumDescriptor(enumType, Me, Nothing, index, generatedCodeInfo.NestedEnums(index))) Services = DescriptorUtil.ConvertAndMakeReadOnly(proto.Service, Function(service, index) New ServiceDescriptor(service, Me, index)) End Sub ''' ''' Computes the full name of a descriptor within this file, with an optional parent message. ''' Friend Function ComputeFullName(parent As MessageDescriptor, name As String) As String If parent IsNot Nothing Then Return parent.FullName & "." & name End If If Package.Length > 0 Then Return Package & "." & name End If Return name End Function ''' ''' Extracts public dependencies from direct dependencies. This is a static method despite its ''' first parameter, as the value we're in the middle of constructing is only used for exceptions. ''' Private Shared Function DeterminePublicDependencies(this As FileDescriptor, proto As FileDescriptorProto, dependencies As FileDescriptor(), allowUnknownDependencies As Boolean) As IList(Of FileDescriptor) Dim nameToFileMap = New Dictionary(Of String, FileDescriptor)() For Each file As FileDescriptor In dependencies nameToFileMap(file.Name) = file Next Dim publicDependencies = New List(Of FileDescriptor)() For i = 0 To proto.PublicDependency.Count - 1 Dim index = proto.PublicDependency(i) If index < 0 OrElse index >= proto.Dependency.Count Then Throw New DescriptorValidationException(this, "Invalid public dependency index.") End If Dim name = proto.Dependency(index) Dim file = nameToFileMap(name) If file Is Nothing Then If Not allowUnknownDependencies Then Throw New DescriptorValidationException(this, "Invalid public dependency: " & name) ' Ignore unknown dependencies. End If Else publicDependencies.Add(file) End If Next Return New ReadOnlyCollection(Of FileDescriptor)(publicDependencies) End Function ''' ''' The descriptor in its protocol message representation. ''' Friend ReadOnly Property Proto As FileDescriptorProto ''' ''' The file name. ''' Public ReadOnly Property Name As String Implements IDescriptor.Name Get Return Proto.Name End Get End Property ''' ''' The package as declared in the .proto file. This may or may not ''' be equivalent to the .NET namespace of the generated classes. ''' Public ReadOnly Property Package As String Get Return Proto.Package End Get End Property ''' ''' Unmodifiable list of top-level message types declared in this file. ''' Public ReadOnly Property MessageTypes As IList(Of MessageDescriptor) ''' ''' Unmodifiable list of top-level enum types declared in this file. ''' Public ReadOnly Property EnumTypes As IList(Of EnumDescriptor) ''' ''' Unmodifiable list of top-level services declared in this file. ''' Public ReadOnly Property Services As IList(Of ServiceDescriptor) ''' ''' Unmodifiable list of this file's dependencies (imports). ''' Public ReadOnly Property Dependencies As IList(Of FileDescriptor) ''' ''' Unmodifiable list of this file's public dependencies (public imports). ''' Public ReadOnly Property PublicDependencies As IList(Of FileDescriptor) ''' ''' The original serialized binary form of this descriptor. ''' Public ReadOnly Property SerializedData As ByteString ''' ''' Implementation of IDescriptor.FullName - just returns the same as Name. ''' Private ReadOnly Property FullName As String Implements IDescriptor.FullName Get Return Name End Get End Property ''' ''' Implementation of IDescriptor.File - just returns this descriptor. ''' Private ReadOnly Property File As FileDescriptor Implements IDescriptor.File Get Return Me End Get End Property ''' ''' Pool containing symbol descriptors. ''' Friend ReadOnly Property DescriptorPool As DescriptorPool ''' ''' Finds a type (message, enum, service or extension) in the file by name. Does not find nested types. ''' ''' The unqualified type name to look for. ''' The type of descriptor to look for ''' The type's descriptor, or null if not found. Public Function FindTypeByName(Of T As {Class, IDescriptor})(name As String) As T ' Don't allow looking up nested types. This will make optimization ' easier later. If name.IndexOf("."c) <> -1 Then Return Nothing End If If Package.Length > 0 Then name = Package & "." & name End If Dim result = DescriptorPool.FindSymbol(Of T)(name) If result IsNot Nothing AndAlso result.File Is Me Then Return result End If Return Nothing End Function ''' ''' Builds a FileDescriptor from its protocol buffer representation. ''' ''' The original serialized descriptor data. ''' We have only limited proto2 support, so serializing FileDescriptorProto ''' would not necessarily give us this. ''' The protocol message form of the FileDescriptor. ''' FileDescriptors corresponding to all of the ''' file's dependencies, in the exact order listed in the .proto file. May be null, ''' in which case it is treated as an empty array. ''' Whether unknown dependencies are ignored (true) or cause an exception to be thrown (false). ''' Details about generated code, for the purposes of reflection. ''' If is not ''' a valid descriptor. This can occur for a number of reasons, such as a field ''' having an undefined type or because two messages were defined with the same name. Private Shared Function BuildFrom(descriptorData As ByteString, proto As FileDescriptorProto, dependencies As FileDescriptor(), allowUnknownDependencies As Boolean, generatedCodeInfo As GeneratedClrTypeInfo) As FileDescriptor ' Building descriptors involves two steps: translating and linking. ' In the translation step (implemented by FileDescriptor's ' constructor), we build an object tree mirroring the ' FileDescriptorProto's tree and put all of the descriptors into the ' DescriptorPool's lookup tables. In the linking step, we look up all ' type references in the DescriptorPool, so that, for example, a ' FieldDescriptor for an embedded message contains a pointer directly ' to the Descriptor for that message's type. We also detect undefined ' types in the linking step. If dependencies Is Nothing Then dependencies = New FileDescriptor(-1) {} End If Dim pool As DescriptorPool = New DescriptorPool(dependencies) Dim result As FileDescriptor = New FileDescriptor(descriptorData, proto, dependencies, pool, allowUnknownDependencies, generatedCodeInfo) ' Validate that the dependencies we've been passed (as FileDescriptors) are actually the ones we ' need. If dependencies.Length <> proto.Dependency.Count Then Throw New DescriptorValidationException(result, "Dependencies passed to FileDescriptor.BuildFrom() don't match " & "those listed in the FileDescriptorProto.") End If For i = 0 To proto.Dependency.Count - 1 If Not Equals(dependencies(i).Name, proto.Dependency(i)) Then Throw New DescriptorValidationException(result, "Dependencies passed to FileDescriptor.BuildFrom() don't match " & "those listed in the FileDescriptorProto. Expected: " & proto.Dependency(i) & " but was: " & dependencies(i).Name) End If Next result.CrossLink() Return result End Function Private Sub CrossLink() For Each message In MessageTypes message.CrossLink() Next For Each service In Services service.CrossLink() Next End Sub ''' ''' Creates a descriptor for generated code. ''' ''' ''' This method is only designed to be used by the results of generating code with protoc, ''' which creates the appropriate dependencies etc. It has to be public because the generated ''' code is "external", but should not be called directly by end users. ''' Public Shared Function FromGeneratedCode(descriptorData As Byte(), dependencies As FileDescriptor(), generatedCodeInfo As GeneratedClrTypeInfo) As FileDescriptor Dim proto As FileDescriptorProto Try proto = FileDescriptorProto.Parser.ParseFrom(descriptorData) Catch e As InvalidProtocolBufferException Throw New ArgumentException("Failed to parse protocol buffer descriptor for generated code.", e) End Try Try ' When building descriptors for generated code, we allow unknown ' dependencies by default. Return BuildFrom(ByteString.CopyFrom(descriptorData), proto, dependencies, True, generatedCodeInfo) Catch e As DescriptorValidationException Throw New ArgumentException($"Invalid embedded descriptor for ""{proto.Name}"".", e) End Try End Function ''' ''' Returns a that represents this instance. ''' ''' ''' A that represents this instance. ''' Public Overrides Function ToString() As String Return $"FileDescriptor for {Name}" End Function ''' ''' Returns the file descriptor for descriptor.proto. ''' ''' ''' This is used for protos which take a direct dependency on descriptor.proto, typically for ''' annotations. While descriptor.proto is a proto2 file, it is built into the Google.Protobuf ''' runtime for reflection purposes. The messages are internal to the runtime as they would require ''' proto2 semantics for full support, but the file descriptor is available via this property. The ''' C# codegen in protoc automatically uses this property when it detects a dependency on descriptor.proto. ''' ''' ''' The file descriptor for descriptor.proto. ''' Public Shared ReadOnly Property DescriptorProtoFileDescriptor As FileDescriptor Get Return Descriptor End Get End Property End Class End Namespace