Allow public access to descriptor.proto as a dependency.

With this in place, generating APIs on github.com/google/googleapis works - previously annotations.proto failed.
Currently there's no access to the annotations (stored as extensions) but we could potentially expose those at a later date.
This commit is contained in:
Jon Skeet 2015-08-13 12:01:41 +01:00
parent f818183f9b
commit a39ababb7c
3 changed files with 27 additions and 2 deletions

View File

@ -368,5 +368,20 @@ namespace Google.Protobuf.Reflection
{ {
return "FileDescriptor for " + proto.Name; return "FileDescriptor for " + proto.Name;
} }
/// <summary>
/// Returns the file descriptor for descriptor.proto.
/// </summary>
/// <remarks>
/// This is used for protos which take a direct dependency on <c>descriptor.proto</c>, typically for
/// annotations. While <c>descriptor.proto</c> 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 <c>descriptor.proto</c>.
/// </remarks>
/// <value>
/// The file descriptor for <c>descriptor.proto</c>.
/// </value>
public static FileDescriptor DescriptorProtoFileDescriptor { get { return DescriptorProtoFile.Descriptor; } }
} }
} }

View File

@ -117,7 +117,10 @@ inline bool IsMapEntryMessage(const Descriptor* descriptor) {
inline bool IsDescriptorProto(const FileDescriptor* descriptor) { inline bool IsDescriptorProto(const FileDescriptor* descriptor) {
// TODO: Do this better! (Currently this depends on a hack in generate_protos.sh to rename // TODO: Do this better! (Currently this depends on a hack in generate_protos.sh to rename
// the file...) // the file...)
return descriptor->name() == "google/protobuf/descriptor_proto_file.proto"; // We need to be able to detect the "normal" name as well, for times that we're just
// depending on descriptor.proto instead of generating it.
return descriptor->name() == "google/protobuf/descriptor_proto_file.proto"
|| descriptor->name() == "google/protobuf/descriptor.proto";
} }
inline bool IsWrapperType(const FieldDescriptor* descriptor) { inline bool IsWrapperType(const FieldDescriptor* descriptor) {

View File

@ -180,10 +180,17 @@ void UmbrellaClassGenerator::WriteDescriptor(io::Printer* printer) {
"descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,\n"); "descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,\n");
printer->Print(" new pbr::FileDescriptor[] { "); printer->Print(" new pbr::FileDescriptor[] { ");
for (int i = 0; i < file_->dependency_count(); i++) { for (int i = 0; i < file_->dependency_count(); i++) {
printer->Print( // descriptor.proto is special: we don't allow access to the generated code, but there's
// a separately-exposed property to get at the file descriptor, specifically to allow this
// kind of dependency.
if (IsDescriptorProto(file_->dependency(i))) {
printer->Print("pbr::FileDescriptor.DescriptorProtoFileDescriptor, ");
} else {
printer->Print(
"$full_umbrella_class_name$.Descriptor, ", "$full_umbrella_class_name$.Descriptor, ",
"full_umbrella_class_name", "full_umbrella_class_name",
GetUmbrellaClassName(file_->dependency(i))); GetUmbrellaClassName(file_->dependency(i)));
}
} }
printer->Print("},\n" printer->Print("},\n"
" new pbr::GeneratedCodeInfo("); " new pbr::GeneratedCodeInfo(");