diff --git a/csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs b/csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs index 5b6dc0fbd4..e84a072709 100644 --- a/csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs +++ b/csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs @@ -82,6 +82,8 @@ namespace Google.Protobuf.Reflection { Assert.AreEqual(i, file.EnumTypes[i].Index); } + + Assert.AreEqual(10, file.SerializedData[0]); } [Test] diff --git a/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs index 718c47971f..c17c4cc444 100644 --- a/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs @@ -43,6 +43,7 @@ namespace Google.Protobuf.Reflection /// public sealed class FileDescriptor : IDescriptor { + private readonly ByteString descriptorData; private readonly FileDescriptorProto proto; private readonly IList messageTypes; private readonly IList enumTypes; @@ -62,8 +63,9 @@ namespace Google.Protobuf.Reflection get { return proto.Syntax == "proto3" ? ProtoSyntax.Proto3 : ProtoSyntax.Proto2; } } - private FileDescriptor(FileDescriptorProto proto, FileDescriptor[] dependencies, DescriptorPool pool, bool allowUnknownDependencies, GeneratedCodeInfo generatedCodeInfo) + private FileDescriptor(ByteString descriptorData, FileDescriptorProto proto, FileDescriptor[] dependencies, DescriptorPool pool, bool allowUnknownDependencies, GeneratedCodeInfo generatedCodeInfo) { + this.descriptorData = descriptorData; this.pool = pool; this.proto = proto; this.dependencies = new ReadOnlyCollection((FileDescriptor[]) dependencies.Clone()); @@ -203,6 +205,14 @@ namespace Google.Protobuf.Reflection get { return publicDependencies; } } + /// + /// The original serialized binary form of this descriptor. + /// + public ByteString SerializedData + { + get { return descriptorData; } + } + /// /// Implementation of IDescriptor.FullName - just returns the same as Name. /// @@ -257,6 +267,9 @@ namespace Google.Protobuf.Reflection /// /// 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, @@ -266,7 +279,7 @@ namespace Google.Protobuf.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 static FileDescriptor BuildFrom(FileDescriptorProto proto, FileDescriptor[] dependencies, bool allowUnknownDependencies, GeneratedCodeInfo generatedCodeInfo) + private static FileDescriptor BuildFrom(ByteString descriptorData, FileDescriptorProto proto, FileDescriptor[] dependencies, bool allowUnknownDependencies, GeneratedCodeInfo generatedCodeInfo) { // Building descriptors involves two steps: translating and linking. // In the translation step (implemented by FileDescriptor's @@ -283,7 +296,7 @@ namespace Google.Protobuf.Reflection } DescriptorPool pool = new DescriptorPool(dependencies); - FileDescriptor result = new FileDescriptor(proto, dependencies, pool, allowUnknownDependencies, generatedCodeInfo); + FileDescriptor result = new FileDescriptor(descriptorData, proto, dependencies, pool, allowUnknownDependencies, generatedCodeInfo); // TODO(jonskeet): Reinstate these checks, or get rid of them entirely. They aren't in the Java code, // and fail for the CustomOptions test right now. (We get "descriptor.proto" vs "google/protobuf/descriptor.proto".) @@ -342,11 +355,13 @@ namespace Google.Protobuf.Reflection throw new ArgumentException("Failed to parse protocol buffer descriptor for generated code.", e); } + + try { // When building descriptors for generated code, we allow unknown // dependencies by default. - return BuildFrom(proto, dependencies, true, generatedCodeInfo); + return BuildFrom(ByteString.CopyFrom(descriptorData), proto, dependencies, true, generatedCodeInfo); } catch (DescriptorValidationException e) {