Commit df67f148 authored by Jon Skeet's avatar Jon Skeet

Fix custom options behaviour

parent 6ef233d4
......@@ -114,6 +114,7 @@
<arg file="${protos-dir}/google/protobuf/descriptor.proto" />
<arg file="${protos-dir}/google/protobuf/csharp_options.proto" />
<arg file="${protos-dir}/google/protobuf/unittest.proto" />
<arg file="${protos-dir}/google/protobuf/unittest_csharp_options.proto" />
<arg file="${protos-dir}/google/protobuf/unittest_custom_options.proto" />
<arg file="${protos-dir}/google/protobuf/unittest_embed_optimize_for.proto" />
<arg file="${protos-dir}/google/protobuf/unittest_import.proto" />
......@@ -140,6 +141,7 @@
<copy todir="${src}/ProtocolBuffers.Test/TestProtos">
<fileset basedir="${tmp-dir}">
<include name="UnitTestProtoFile.cs" />
<include name="UnitTestCSharpOptionsProtoFile.cs" />
<include name="UnitTestCustomOptionsProtoFile.cs" />
<include name="UnitTestEmbedOptimizeForProtoFile.cs" />
<include name="UnitTestImportProtoFile.cs" />
......
......@@ -250,7 +250,7 @@ message FileOptions {
SPEED = 1; // Generate complete code for parsing, serialization, etc.
CODE_SIZE = 2; // Use ReflectionOps to implement these methods.
}
optional OptimizeMode optimize_for = 9 [default=CODE_SIZE];
optional OptimizeMode optimize_for = 9 [default=SPEED];
......@@ -306,6 +306,12 @@ message FieldOptions {
// a single length-delimited blob.
optional bool packed = 2;
// Is this field deprecated?
// Depending on the target platform, this can emit Deprecated annotations
// for accessors, or it will be completely ignored; in the very least, this
// is a formalization for deprecating fields.
optional bool deprecated = 3 [default=false];
// EXPERIMENTAL. DO NOT USE.
// For "map" fields, the name of the field in the enclosed type that
// is the key for this map. For example, suppose we have:
......
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// 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.
// Author: jonskeet@google.com (Jon Skeet)
//
// A proto file for unit testing the custom C# options
import "google/protobuf/csharp_options.proto";
option (google.protobuf.csharp_file_options).namespace = "Google.ProtocolBuffers.TestProtos";
option (google.protobuf.csharp_file_options).umbrella_classname = "UnitTestCSharpOptionsProtoFile";
//option (google.protobuf.csharp_file_options).nest_classes = true;
package protobuf_unittest;
message OptionsMessage {
// Will be left as Normal
optional string normal = 1;
// Will be converted to OptionsMessage_
optional string options_message = 2;
// Will be converted to CustomName
optional string customized = 3 [(google.protobuf.csharp_field_options).property_name = "CustomName"];
}
......@@ -8,12 +8,26 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
public static partial class AddressBookProtos {
#region Extension registration
public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {
}
#endregion
#region Static variables
internal static pbd::MessageDescriptor internal__static_tutorial_Person__Descriptor;
internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.Examples.AddressBook.Person, global::Google.ProtocolBuffers.Examples.AddressBook.Person.Builder> internal__static_tutorial_Person__FieldAccessorTable;
internal static pbd::MessageDescriptor internal__static_tutorial_Person_PhoneNumber__Descriptor;
internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber, global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber.Builder> internal__static_tutorial_Person_PhoneNumber__FieldAccessorTable;
internal static pbd::MessageDescriptor internal__static_tutorial_AddressBook__Descriptor;
internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.Examples.AddressBook.AddressBook, global::Google.ProtocolBuffers.Examples.AddressBook.AddressBook.Builder> internal__static_tutorial_AddressBook__FieldAccessorTable;
#endregion
#region Descriptor
public static pbd::FileDescriptor Descriptor {
get { return descriptor; }
}
private static readonly pbd::FileDescriptor descriptor = pbd::FileDescriptor.InternalBuildGeneratedFileFrom(
global::System.Convert.FromBase64String(
private static pbd::FileDescriptor descriptor;
static AddressBookProtos() {
byte[] descriptorData = global::System.Convert.FromBase64String(
"Chp0dXRvcmlhbC9hZGRyZXNzYm9vay5wcm90bxIIdHV0b3JpYWwaJGdvb2ds" +
"ZS9wcm90b2J1Zi9jc2hhcnBfb3B0aW9ucy5wcm90byLaAQoGUGVyc29uEgwK" +
"BG5hbWUYASACKAkSCgoCaWQYAiACKAUSDQoFZW1haWwYAyABKAkSKwoFcGhv" +
......@@ -23,29 +37,33 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
"T0JJTEUQABIICgRIT01FEAESCAoEV09SSxACIi8KC0FkZHJlc3NCb29rEiAK" +
"BnBlcnNvbhgBIAMoCzIQLnR1dG9yaWFsLlBlcnNvbkJFSAHCPkAKK0dvb2ds" +
"ZS5Qcm90b2NvbEJ1ZmZlcnMuRXhhbXBsZXMuQWRkcmVzc0Jvb2sSEUFkZHJl" +
"c3NCb29rUHJvdG9z"),
new pbd::FileDescriptor[] {
global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor,
});
#endregion
#region Static variables
internal static readonly pbd::MessageDescriptor internal__static_tutorial_Person__Descriptor
= Descriptor.MessageTypes[0];
internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.Examples.AddressBook.Person, global::Google.ProtocolBuffers.Examples.AddressBook.Person.Builder> internal__static_tutorial_Person__FieldAccessorTable
= new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.Examples.AddressBook.Person, global::Google.ProtocolBuffers.Examples.AddressBook.Person.Builder>(internal__static_tutorial_Person__Descriptor,
"c3NCb29rUHJvdG9z");
pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
descriptor = root;
internal__static_tutorial_Person__Descriptor = Descriptor.MessageTypes[0];
internal__static_tutorial_Person__FieldAccessorTable =
new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.Examples.AddressBook.Person, global::Google.ProtocolBuffers.Examples.AddressBook.Person.Builder>(internal__static_tutorial_Person__Descriptor,
new string[] { "Name", "Id", "Email", "Phone", });
internal static readonly pbd::MessageDescriptor internal__static_tutorial_Person_PhoneNumber__Descriptor
= internal__static_tutorial_Person__Descriptor.NestedTypes[0];
internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber, global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber.Builder> internal__static_tutorial_Person_PhoneNumber__FieldAccessorTable
= new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber, global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber.Builder>(internal__static_tutorial_Person_PhoneNumber__Descriptor,
internal__static_tutorial_Person_PhoneNumber__Descriptor = internal__static_tutorial_Person__Descriptor.NestedTypes[0];
internal__static_tutorial_Person_PhoneNumber__FieldAccessorTable =
new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber, global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber.Builder>(internal__static_tutorial_Person_PhoneNumber__Descriptor,
new string[] { "Number", "Type", });
internal static readonly pbd::MessageDescriptor internal__static_tutorial_AddressBook__Descriptor
= Descriptor.MessageTypes[1];
internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.Examples.AddressBook.AddressBook, global::Google.ProtocolBuffers.Examples.AddressBook.AddressBook.Builder> internal__static_tutorial_AddressBook__FieldAccessorTable
= new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.Examples.AddressBook.AddressBook, global::Google.ProtocolBuffers.Examples.AddressBook.AddressBook.Builder>(internal__static_tutorial_AddressBook__Descriptor,
internal__static_tutorial_AddressBook__Descriptor = Descriptor.MessageTypes[1];
internal__static_tutorial_AddressBook__FieldAccessorTable =
new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.Examples.AddressBook.AddressBook, global::Google.ProtocolBuffers.Examples.AddressBook.AddressBook.Builder>(internal__static_tutorial_AddressBook__Descriptor,
new string[] { "Person", });
pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();
RegisterAllExtensions(registry);
global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.RegisterAllExtensions(registry);
return registry;
};
pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
new pbd::FileDescriptor[] {
global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor,
}, assigner);
}
#endregion
}
#region Messages
public sealed partial class Person : pb::GeneratedMessage<Person, Person.Builder> {
......@@ -338,6 +356,9 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
return this;
}
}
static PhoneNumber() {
pbd::FileDescriptor descriptor = global::Google.ProtocolBuffers.Examples.AddressBook.AddressBookProtos.Descriptor;
}
}
}
......@@ -685,6 +706,9 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
return this;
}
}
static Person() {
pbd::FileDescriptor descriptor = global::Google.ProtocolBuffers.Examples.AddressBook.AddressBookProtos.Descriptor;
}
}
public sealed partial class AddressBook : pb::GeneratedMessage<AddressBook, AddressBook.Builder> {
......@@ -924,6 +948,9 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
return this;
}
}
static AddressBook() {
pbd::FileDescriptor descriptor = global::Google.ProtocolBuffers.Examples.AddressBook.AddressBookProtos.Descriptor;
}
}
#endregion
......
......@@ -5,6 +5,7 @@ namespace Google.ProtocolBuffers.ProtoGen {
internal EnumGenerator(EnumDescriptor descriptor) : base(descriptor) {
}
// TODO(jonskeet): Write out enum descriptors? Can be retrieved from file...
public void Generate(TextGenerator writer) {
writer.WriteLine("{0} enum {1} {{", ClassAccessLevel, Descriptor.Name);
writer.Indent();
......
using System;
using System.Collections.Generic;
using System.Text;
using Google.ProtocolBuffers.Descriptors;
namespace Google.ProtocolBuffers.ProtoGen {
internal class ExtensionGenerator : SourceGeneratorBase<FieldDescriptor>, ISourceGenerator {
internal ExtensionGenerator(FieldDescriptor descriptor) : base(descriptor) {
}
public void Generate(TextGenerator writer) {
string name = Descriptor.CSharpOptions.PropertyName;
private readonly string scope;
private readonly string type;
private readonly string name;
string type;
internal ExtensionGenerator(FieldDescriptor descriptor) : base(descriptor) {
if (Descriptor.ExtensionScope != null) {
scope = GetClassName(Descriptor.ExtensionScope);
} else {
scope = DescriptorUtil.GetFullUmbrellaClassName(Descriptor.File);
}
switch (Descriptor.MappedType) {
case MappedType.Message:
type = GetClassName(Descriptor.MessageType);
......@@ -23,16 +24,28 @@ namespace Google.ProtocolBuffers.ProtoGen {
type = DescriptorUtil.GetMappedTypeName(Descriptor.MappedType);
break;
}
name = Descriptor.CSharpOptions.PropertyName;
}
public void Generate(TextGenerator writer) {
writer.WriteLine ("public const int {0} = {1};", GetFieldConstantName(Descriptor), Descriptor.FieldNumber);
if (Descriptor.IsRepeated) {
writer.WriteLine("{0} static readonly", ClassAccessLevel);
writer.WriteLine(" pb::GeneratedExtensionBase<scg::IList<{0}>> {1} =", type, name);
writer.WriteLine(" pb::GeneratedRepeatExtension<{0}>.CreateInstance(Descriptor.Extensions[{1}]);", type, Descriptor.Index);
writer.WriteLine("{0} static pb::GeneratedExtensionBase<scg::IList<{1}>> {2};", ClassAccessLevel, type, name);
} else {
writer.WriteLine("{0} static readonly pb::GeneratedExtensionBase<{1}> {2} =", ClassAccessLevel, type, name);
writer.WriteLine(" pb::GeneratedSingleExtension<{0}>.CreateInstance(Descriptor.Extensions[{1}]);", type, Descriptor.Index);
writer.WriteLine("{0} static pb::GeneratedExtensionBase<{1}> {2};", ClassAccessLevel, type, name);
}
}
internal void GenerateStaticVariableInitializers(TextGenerator writer) {
if (Descriptor.IsRepeated) {
writer.WriteLine("{0}.{1} = pb::GeneratedRepeatExtension<{2}>.CreateInstance({0}.Descriptor.Extensions[{3}]);", scope, name, type, Descriptor.Index);
} else {
writer.WriteLine("{0}.{1} = pb::GeneratedSingleExtension<{2}>.CreateInstance({0}.Descriptor.Extensions[{3}]);", scope, name, type, Descriptor.Index);
}
}
internal void GenerateExtensionRegistrationCode(TextGenerator writer) {
writer.WriteLine("registry.Add({0}.{1});", scope, name);
}
}
}
......@@ -39,25 +39,42 @@ namespace Google.ProtocolBuffers.ProtoGen {
// The descriptor for this type.
string access = Descriptor.File.CSharpOptions.NestClasses ? "private" : "internal";
writer.WriteLine("{0} static readonly pbd::MessageDescriptor internal__{1}__Descriptor", access, identifier);
writer.WriteLine("{0} static pbd::MessageDescriptor internal__{1}__Descriptor;", access, identifier);
writer.WriteLine("{0} static pb::FieldAccess.FieldAccessorTable<{1}, {1}.Builder> internal__{2}__FieldAccessorTable;",
access, FullClassName, identifier);
// Generate static members for all nested types.
foreach (MessageDescriptor nestedMessage in Descriptor.NestedTypes) {
new MessageGenerator(nestedMessage).GenerateStaticVariables(writer);
}
}
internal void GenerateStaticVariableInitializers(TextGenerator writer) {
string identifier = GetUniqueFileScopeIdentifier(Descriptor);
writer.Write("internal__{0}__Descriptor = ", identifier);
if (Descriptor.ContainingType == null) {
writer.WriteLine(" = Descriptor.MessageTypes[{0}];", Descriptor.Index);
writer.WriteLine("Descriptor.MessageTypes[{0}];", Descriptor.Index);
} else {
writer.WriteLine(" = internal__{0}__Descriptor.NestedTypes[{1}];", GetUniqueFileScopeIdentifier(Descriptor.ContainingType), Descriptor.Index);
writer.WriteLine("internal__{0}__Descriptor.NestedTypes[{1}];", GetUniqueFileScopeIdentifier(Descriptor.ContainingType), Descriptor.Index);
}
writer.WriteLine("{0} static pb::FieldAccess.FieldAccessorTable<{1}, {1}.Builder> internal__{2}__FieldAccessorTable",
access, FullClassName, identifier);
writer.WriteLine(" = new pb::FieldAccess.FieldAccessorTable<{0}, {0}.Builder>(internal__{1}__Descriptor,",
FullClassName, identifier);
writer.WriteLine("internal__{0}__FieldAccessorTable = ", identifier);
writer.WriteLine(" new pb::FieldAccess.FieldAccessorTable<{1}, {1}.Builder>(internal__{0}__Descriptor,",
identifier, FullClassName);
writer.Print(" new string[] { ");
foreach (FieldDescriptor field in Descriptor.Fields) {
writer.Write("\"{0}\", ", field.CSharpOptions.PropertyName);
}
writer.WriteLine("});");
// Generate static members for all nested types.
// Generate static member initializers for all nested types.
foreach (MessageDescriptor nestedMessage in Descriptor.NestedTypes) {
new MessageGenerator(nestedMessage).GenerateStaticVariables(writer);
new MessageGenerator(nestedMessage).GenerateStaticVariableInitializers(writer);
}
foreach (FieldDescriptor extension in Descriptor.Extensions) {
new ExtensionGenerator(extension).GenerateStaticVariableInitializers(writer);
}
}
......@@ -119,6 +136,17 @@ namespace Google.ProtocolBuffers.ProtoGen {
GenerateParseFromMethods(writer);
GenerateBuilder(writer);
// Force the static initialization code for the file to run, since it may
// initialize static variables declared in this class.
writer.WriteLine("static {0}() {{", ClassName);
// Note that the variable is needed just so we can access the property
writer.WriteLine(" pbd::FileDescriptor descriptor = {0}.Descriptor;", DescriptorUtil.GetFullUmbrellaClassName(Descriptor));
writer.WriteLine("}");
writer.Outdent();
writer.WriteLine("}");
writer.WriteLine();
}
private void GenerateMessageSerializationMethods(TextGenerator writer) {
......@@ -297,9 +325,6 @@ namespace Google.ProtocolBuffers.ProtoGen {
}
writer.Outdent();
writer.WriteLine("}");
writer.Outdent();
writer.WriteLine("}");
writer.WriteLine();
}
private void GenerateCommonBuilderMethods(TextGenerator writer) {
......@@ -472,5 +497,14 @@ namespace Google.ProtocolBuffers.ProtoGen {
writer.WriteLine("}");
writer.WriteLine();
}
internal void GenerateExtensionRegistrationCode(TextGenerator writer) {
foreach (FieldDescriptor extension in Descriptor.Extensions) {
new ExtensionGenerator(extension).GenerateExtensionRegistrationCode(writer);
}
foreach (MessageDescriptor nestedMessage in Descriptor.NestedTypes) {
new MessageGenerator(nestedMessage).GenerateExtensionRegistrationCode(writer);
}
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Google.ProtocolBuffers.Descriptors;
namespace Google.ProtocolBuffers.ProtoGen {
/// <summary>
......
......@@ -31,7 +31,7 @@ namespace Google.ProtocolBuffers.ProtoGen {
}
internal static string GetFieldConstantName(FieldDescriptor field) {
return NameHelpers.UnderscoresToPascalCase(GetFieldName(field)) + "FieldNumber";
return field.CSharpOptions.PropertyName + "FieldNumber";
}
private static string ToCSharpName(string name, FileDescriptor file) {
......
using System;
using System.Collections;
using System.Collections.Generic;
using Google.ProtocolBuffers.DescriptorProtos;
using Google.ProtocolBuffers.Descriptors;
......@@ -13,19 +15,49 @@ namespace Google.ProtocolBuffers.ProtoGen {
: base(descriptor) {
}
// Recursively searches the given message to see if it contains any extensions.
private static bool UsesExtensions(IMessage message) {
// We conservatively assume that unknown fields are extensions.
if (message.UnknownFields.FieldDictionary.Count > 0) {
return true;
}
foreach (KeyValuePair<FieldDescriptor, object> keyValue in message.AllFields) {
FieldDescriptor field = keyValue.Key;
if (field.IsExtension) {
return true;
}
if (field.MappedType == MappedType.Message) {
if (field.IsRepeated) {
foreach (IMessage subMessage in (IEnumerable)keyValue.Value) {
if (UsesExtensions(subMessage)) {
return true;
}
}
} else {
if (UsesExtensions((IMessage)keyValue.Value)) {
return true;
}
}
}
}
return false;
}
public string UmbrellaClassName {
get { throw new NotImplementedException(); }
}
public void Generate(TextGenerator writer) {
WriteIntroduction(writer);
WriteDescriptor(writer);
WriteExtensionRegistration(writer);
WriteChildren(writer, "Extensions", Descriptor.Extensions);
writer.WriteLine("#region Static variables");
foreach (MessageDescriptor message in Descriptor.MessageTypes) {
new MessageGenerator(message).GenerateStaticVariables(writer);
}
writer.WriteLine("#endregion");
WriteDescriptor(writer);
// The class declaration either gets closed before or after the children are written.
if (!Descriptor.CSharpOptions.NestClasses) {
writer.Outdent();
......@@ -60,14 +92,32 @@ namespace Google.ProtocolBuffers.ProtoGen {
writer.Indent();
}
private void WriteExtensionRegistration(TextGenerator writer) {
writer.WriteLine("#region Extension registration");
writer.WriteLine("public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {");
writer.Indent();
foreach (FieldDescriptor extension in Descriptor.Extensions) {
new ExtensionGenerator(extension).GenerateExtensionRegistrationCode(writer);
}
foreach (MessageDescriptor message in Descriptor.MessageTypes) {
new MessageGenerator(message).GenerateExtensionRegistrationCode(writer);
}
writer.Outdent();
writer.WriteLine("}");
writer.WriteLine("#endregion");
}
private void WriteDescriptor(TextGenerator writer) {
writer.WriteLine("#region Descriptor");
writer.WriteLine("public static pbd::FileDescriptor Descriptor {");
writer.WriteLine(" get { return descriptor; }");
writer.WriteLine("}");
writer.WriteLine("private static readonly pbd::FileDescriptor descriptor = pbd::FileDescriptor.InternalBuildGeneratedFileFrom(");
writer.WriteLine(" global::System.Convert.FromBase64String(");
writer.WriteLine("private static pbd::FileDescriptor descriptor;");
writer.WriteLine();
writer.WriteLine("static {0}() {{", Descriptor.CSharpOptions.UmbrellaClassname);
writer.Indent();
writer.WriteLine("byte[] descriptorData = global::System.Convert.FromBase64String(");
writer.Indent();
writer.Indent();
......@@ -79,15 +129,44 @@ namespace Google.ProtocolBuffers.ProtoGen {
writer.WriteLine("\"{0}\" + ", base64.Substring(0, 60));
base64 = base64.Substring(60);
}
writer.WriteLine("\"{0}\"),", base64);
writer.WriteLine("\"{0}\");", base64);
writer.Outdent();
writer.Outdent();
writer.WriteLine("pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {");
writer.Indent();
writer.WriteLine("descriptor = root;");
foreach (MessageDescriptor message in Descriptor.MessageTypes) {
new MessageGenerator(message).GenerateStaticVariableInitializers(writer);
}
foreach (FieldDescriptor extension in Descriptor.Extensions) {
new ExtensionGenerator(extension).GenerateStaticVariableInitializers(writer);
}
writer.WriteLine("new pbd::FileDescriptor[] {");
if (UsesExtensions(Descriptor.Proto)) {
// Must construct an ExtensionRegistry containing all possible extensions
// and return it.
writer.WriteLine("pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();");
writer.WriteLine("RegisterAllExtensions(registry);");
foreach (FileDescriptor dependency in Descriptor.Dependencies) {
writer.WriteLine(" {0}.Descriptor, ", DescriptorUtil.GetFullUmbrellaClassName(dependency));
writer.WriteLine("{0}.RegisterAllExtensions(registry);", DescriptorUtil.GetFullUmbrellaClassName(dependency));
}
writer.WriteLine("return registry;");
} else {
writer.WriteLine("return null;");
}
writer.WriteLine("});");
writer.Outdent();
writer.WriteLine("};");
// -----------------------------------------------------------------
// Invoke internalBuildGeneratedFileFrom() to build the file.
writer.WriteLine("pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,");
writer.WriteLine(" new pbd::FileDescriptor[] {");
foreach (FileDescriptor dependency in Descriptor.Dependencies) {
writer.WriteLine(" {0}.Descriptor, ", DescriptorUtil.GetFullUmbrellaClassName(dependency));
}
writer.WriteLine(" }, assigner);");
writer.Outdent();
writer.WriteLine("}");
writer.WriteLine("#endregion");
writer.WriteLine();
}
......
......@@ -397,7 +397,7 @@ namespace Google.ProtocolBuffers {
try {
input.ReadRawByte();
Assert.Fail("Should have thrown an exception!");
} catch (InvalidProtocolBufferException e) {
} catch (InvalidProtocolBufferException) {
// Success.
}
......@@ -407,7 +407,7 @@ namespace Google.ProtocolBuffers {
try {
input.ReadRawBytes(16); // Hits limit again.
Assert.Fail("Should have thrown an exception!");
} catch (InvalidProtocolBufferException e) {
} catch (InvalidProtocolBufferException) {
// Success.
}
}
......
using NUnit.Framework;
using Google.ProtocolBuffers.TestProtos;
namespace Google.ProtocolBuffers.Descriptors {
[TestFixture]
public class MessageDescriptorTest {
[Test]
public void FindPropertyWithDefaultName() {
Assert.AreSame(OptionsMessage.Descriptor.FindFieldByNumber(OptionsMessage.NormalFieldNumber),
OptionsMessage.Descriptor.FindFieldByPropertyName("Normal"));
}
[Test]
public void FindPropertyWithAutoModifiedName() {
Assert.AreSame(OptionsMessage.Descriptor.FindFieldByNumber(OptionsMessage.OptionsMessage_FieldNumber),
OptionsMessage.Descriptor.FindFieldByPropertyName("OptionsMessage_"));
}
[Test]
public void FindPropertyWithCustomizedName() {
Assert.AreSame(OptionsMessage.Descriptor.FindFieldByNumber(OptionsMessage.CustomNameFieldNumber),
OptionsMessage.Descriptor.FindFieldByPropertyName("CustomName"));
}
[Test]
public void FindPropertyWithInvalidName() {
Assert.IsNull(OptionsMessage.Descriptor.FindFieldByPropertyName("Bogus"));
}
}
}
......@@ -286,5 +286,41 @@ namespace Google.ProtocolBuffers {
Assert.AreEqual(i, service.Methods[i].Index);
}
}
[Test]
public void CustomOptions() {
MessageDescriptor descriptor = TestMessageWithCustomOptions.Descriptor;
Assert.IsTrue(descriptor.Options.HasExtension(UnitTestCustomOptionsProtoFile.MessageOpt1));
Assert.AreEqual(-56, descriptor.Options.GetExtension(UnitTestCustomOptionsProtoFile.MessageOpt1));
FieldDescriptor field = descriptor.FindFieldByName("field1");
Assert.IsNotNull(field);
Assert.IsTrue(field.Options.HasExtension(UnitTestCustomOptionsProtoFile.FieldOpt1));
Assert.AreEqual(8765432109L, field.Options.GetExtension(UnitTestCustomOptionsProtoFile.FieldOpt1));
// TODO: Write out enum descriptors
/*
EnumDescriptor enumType = TestMessageWithCustomOptions.Types.
UnittestCustomOptions.TestMessageWithCustomOptions.AnEnum.getDescriptor();
Assert.IsTrue(
enumType.getOptions().hasExtension(UnittestCustomOptions.enumOpt1));
Assert.AreEqual(Integer.valueOf(-789),
enumType.getOptions().getExtension(UnittestCustomOptions.enumOpt1));
*/
ServiceDescriptor service = TestServiceWithCustomOptions.Descriptor;
Assert.IsTrue(service.Options.HasExtension(UnitTestCustomOptionsProtoFile.ServiceOpt1));
Assert.AreEqual(-9876543210L, service.Options.GetExtension(UnitTestCustomOptionsProtoFile.ServiceOpt1));
MethodDescriptor method = service.FindMethodByName("Foo");
Assert.IsNotNull(method);
Assert.IsTrue(method.Options.HasExtension(UnitTestCustomOptionsProtoFile.MethodOpt1));
Assert.AreEqual(MethodOpt1.METHODOPT1_VAL2, method.Options.GetExtension(UnitTestCustomOptionsProtoFile.MethodOpt1));
}
}
}
......@@ -64,7 +64,7 @@ namespace Google.ProtocolBuffers {
try {
builder.Build();
Assert.Fail("Should have thrown exception.");
} catch (InvalidOperationException e) {
} catch (InvalidOperationException) {
// Success.
}
}
......
......@@ -97,7 +97,7 @@ namespace Google.ProtocolBuffers {
try {
builder.Build();
Assert.Fail("Should have thrown exception.");
} catch (InvalidOperationException e) {
} catch (InvalidOperationException) {
// Success.
}
}
......
......@@ -53,6 +53,7 @@
<Compile Include="Collections\PopsicleListTest.cs" />
<Compile Include="CSharpOptionsTest.cs" />
<Compile Include="DescriptorsTest.cs" />
<Compile Include="Descriptors\MessageDescriptorTest.cs" />
<Compile Include="DynamicMessageTest.cs" />
<Compile Include="GeneratedMessageTest.cs" />
<Compile Include="MessageStreamIteratorTest.cs" />
......@@ -63,6 +64,8 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ReflectionTester.cs" />
<Compile Include="ServiceTest.cs" />
<Compile Include="TestProtos\UnitTestCSharpOptionsProtoFile.cs" />
<Compile Include="TestProtos\UnitTestCustomOptionsProtoFile.cs" />
<Compile Include="TestProtos\UnitTestEmbedOptimizeForProtoFile.cs" />
<Compile Include="TestProtos\UnitTestImportProtoFile.cs" />
<Compile Include="TestProtos\UnitTestMessageSetProtoFile.cs" />
......
// Generated by the protocol buffer compiler. DO NOT EDIT!
using pb = global::Google.ProtocolBuffers;
using pbc = global::Google.ProtocolBuffers.Collections;
using pbd = global::Google.ProtocolBuffers.Descriptors;
using scg = global::System.Collections.Generic;
namespace Google.ProtocolBuffers.TestProtos {
public static partial class UnitTestCSharpOptionsProtoFile {
#region Extension registration
public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {
}
#endregion
#region Static variables
internal static pbd::MessageDescriptor internal__static_protobuf_unittest_OptionsMessage__Descriptor;
internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.OptionsMessage, global::Google.ProtocolBuffers.TestProtos.OptionsMessage.Builder> internal__static_protobuf_unittest_OptionsMessage__FieldAccessorTable;
#endregion
#region Descriptor
public static pbd::FileDescriptor Descriptor {
get { return descriptor; }
}
private static pbd::FileDescriptor descriptor;
static UnitTestCSharpOptionsProtoFile() {
byte[] descriptorData = global::System.Convert.FromBase64String(
"Ci1nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfY3NoYXJwX29wdGlvbnMucHJv" +
"dG8SEXByb3RvYnVmX3VuaXR0ZXN0GiRnb29nbGUvcHJvdG9idWYvY3NoYXJw" +
"X29wdGlvbnMucHJvdG8iXgoOT3B0aW9uc01lc3NhZ2USDgoGbm9ybWFsGAEg" +
"ASgJEhcKD29wdGlvbnNfbWVzc2FnZRgCIAEoCRIjCgpjdXN0b21pemVkGAMg" +
"ASgJQg/CPgwKCkN1c3RvbU5hbWVCRsI+QwohR29vZ2xlLlByb3RvY29sQnVm" +
"ZmVycy5UZXN0UHJvdG9zEh5Vbml0VGVzdENTaGFycE9wdGlvbnNQcm90b0Zp" +
"bGU=");
pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
descriptor = root;
internal__static_protobuf_unittest_OptionsMessage__Descriptor = Descriptor.MessageTypes[0];
internal__static_protobuf_unittest_OptionsMessage__FieldAccessorTable =
new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.OptionsMessage, global::Google.ProtocolBuffers.TestProtos.OptionsMessage.Builder>(internal__static_protobuf_unittest_OptionsMessage__Descriptor,
new string[] { "Normal", "OptionsMessage_", "CustomName", });
pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();
RegisterAllExtensions(registry);
global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.RegisterAllExtensions(registry);
return registry;
};
pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
new pbd::FileDescriptor[] {
global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor,
}, assigner);
}
#endregion
}
#region Messages
public sealed partial class OptionsMessage : pb::GeneratedMessage<OptionsMessage, OptionsMessage.Builder> {
private static readonly OptionsMessage defaultInstance = new Builder().BuildPartial();
public static OptionsMessage DefaultInstance {
get { return defaultInstance; }
}
public override OptionsMessage DefaultInstanceForType {
get { return defaultInstance; }
}
protected override OptionsMessage ThisMessage {
get { return this; }
}
public static pbd::MessageDescriptor Descriptor {
get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCSharpOptionsProtoFile.internal__static_protobuf_unittest_OptionsMessage__Descriptor; }
}
protected override pb::FieldAccess.FieldAccessorTable<OptionsMessage, OptionsMessage.Builder> InternalFieldAccessors {
get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCSharpOptionsProtoFile.internal__static_protobuf_unittest_OptionsMessage__FieldAccessorTable; }
}
public const int NormalFieldNumber = 1;
private bool hasNormal;
private string normal_ = "";
public bool HasNormal {
get { return hasNormal; }
}
public string Normal {
get { return normal_; }
}
public const int OptionsMessage_FieldNumber = 2;
private bool hasOptionsMessage_;
private string optionsMessage_ = "";
public bool HasOptionsMessage_ {
get { return hasOptionsMessage_; }
}
public string OptionsMessage_ {
get { return optionsMessage_; }
}
public const int CustomNameFieldNumber = 3;
private bool hasCustomName;
private string customized_ = "";
public bool HasCustomName {
get { return hasCustomName; }
}
public string CustomName {
get { return customized_; }
}
public static OptionsMessage ParseFrom(pb::ByteString data) {
return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
}
public static OptionsMessage ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
}
public static OptionsMessage ParseFrom(byte[] data) {
return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
}
public static OptionsMessage ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
}
public static OptionsMessage ParseFrom(global::System.IO.Stream input) {
return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
}
public static OptionsMessage ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
}
public static OptionsMessage ParseDelimitedFrom(global::System.IO.Stream input) {
return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
}
public static OptionsMessage ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
}
public static OptionsMessage ParseFrom(pb::CodedInputStream input) {
return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
}
public static OptionsMessage ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
}
public static Builder CreateBuilder() { return new Builder(); }
public override Builder ToBuilder() { return CreateBuilder(this); }
public override Builder CreateBuilderForType() { return new Builder(); }
public static Builder CreateBuilder(OptionsMessage prototype) {
return (Builder) new Builder().MergeFrom(prototype);
}
public sealed partial class Builder : pb::GeneratedBuilder<OptionsMessage, Builder> {
protected override Builder ThisBuilder {
get { return this; }
}
public Builder() {}
OptionsMessage result = new OptionsMessage();
protected override OptionsMessage MessageBeingBuilt {
get { return result; }
}
public override Builder Clear() {
result = new OptionsMessage();
return this;
}
public override Builder Clone() {
return new Builder().MergeFrom(result);
}
public override pbd::MessageDescriptor DescriptorForType {
get { return OptionsMessage.Descriptor; }
}
public override OptionsMessage DefaultInstanceForType {
get { return OptionsMessage.DefaultInstance; }
}
public override OptionsMessage BuildPartial() {
if (result == null) {
throw new global::System.InvalidOperationException("build() has already been called on this Builder");
}
OptionsMessage returnMe = result;
result = null;
return returnMe;
}
public bool HasNormal {
get { return result.HasNormal; }
}
public string Normal {
get { return result.Normal; }
set { SetNormal(value); }
}
public Builder SetNormal(string value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
result.hasNormal = true;
result.normal_ = value;
return this;
}
public Builder ClearNormal() {
result.hasNormal = false;
result.normal_ = "";
return this;
}
public bool HasOptionsMessage_ {
get { return result.HasOptionsMessage_; }
}
public string OptionsMessage_ {
get { return result.OptionsMessage_; }
set { SetOptionsMessage_(value); }
}
public Builder SetOptionsMessage_(string value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
result.hasOptionsMessage_ = true;
result.optionsMessage_ = value;
return this;
}
public Builder ClearOptionsMessage_() {
result.hasOptionsMessage_ = false;
result.optionsMessage_ = "";
return this;
}
public bool HasCustomName {
get { return result.HasCustomName; }
}
public string CustomName {
get { return result.CustomName; }
set { SetCustomName(value); }
}
public Builder SetCustomName(string value) {
pb::ThrowHelper.ThrowIfNull(value, "value");
result.hasCustomName = true;
result.customized_ = value;
return this;
}
public Builder ClearCustomName() {
result.hasCustomName = false;
result.customized_ = "";
return this;
}
}
static OptionsMessage() {
pbd::FileDescriptor descriptor = global::Google.ProtocolBuffers.TestProtos.UnitTestCSharpOptionsProtoFile.Descriptor;
}
}
#endregion
}
......@@ -8,12 +8,22 @@ namespace Google.ProtocolBuffers.TestProtos {
public static partial class UnitTestEmbedOptimizeForProtoFile {
#region Extension registration
public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {
}
#endregion
#region Static variables
internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestEmbedOptimizedForSize__Descriptor;
internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestEmbedOptimizedForSize, global::Google.ProtocolBuffers.TestProtos.TestEmbedOptimizedForSize.Builder> internal__static_protobuf_unittest_TestEmbedOptimizedForSize__FieldAccessorTable;
#endregion
#region Descriptor
public static pbd::FileDescriptor Descriptor {
get { return descriptor; }
}
private static readonly pbd::FileDescriptor descriptor = pbd::FileDescriptor.InternalBuildGeneratedFileFrom(
global::System.Convert.FromBase64String(
private static pbd::FileDescriptor descriptor;
static UnitTestEmbedOptimizeForProtoFile() {
byte[] descriptorData = global::System.Convert.FromBase64String(
"CjFnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW1iZWRfb3B0aW1pemVfZm9y" +
"LnByb3RvEhFwcm90b2J1Zl91bml0dGVzdBokZ29vZ2xlL3Byb3RvYnVmL2Nz" +
"aGFycF9vcHRpb25zLnByb3RvGitnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rf" +
......@@ -22,20 +32,27 @@ namespace Google.ProtocolBuffers.TestProtos {
"dGVzdC5UZXN0T3B0aW1pemVkRm9yU2l6ZRJBChByZXBlYXRlZF9tZXNzYWdl" +
"GAIgAygLMicucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9wdGltaXplZEZvclNp" +
"emVCS0gBwj5GCiFHb29nbGUuUHJvdG9jb2xCdWZmZXJzLlRlc3RQcm90b3MS" +
"IVVuaXRUZXN0RW1iZWRPcHRpbWl6ZUZvclByb3RvRmlsZQ=="),
"IVVuaXRUZXN0RW1iZWRPcHRpbWl6ZUZvclByb3RvRmlsZQ==");
pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
descriptor = root;
internal__static_protobuf_unittest_TestEmbedOptimizedForSize__Descriptor = Descriptor.MessageTypes[0];
internal__static_protobuf_unittest_TestEmbedOptimizedForSize__FieldAccessorTable =
new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestEmbedOptimizedForSize, global::Google.ProtocolBuffers.TestProtos.TestEmbedOptimizedForSize.Builder>(internal__static_protobuf_unittest_TestEmbedOptimizedForSize__Descriptor,
new string[] { "OptionalMessage", "RepeatedMessage", });
pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();
RegisterAllExtensions(registry);
global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.RegisterAllExtensions(registry);
global::Google.ProtocolBuffers.TestProtos.UnitTestOptimizeForProtoFile.RegisterAllExtensions(registry);
return registry;
};
pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
new pbd::FileDescriptor[] {
global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor,
global::Google.ProtocolBuffers.TestProtos.UnitTestOptimizeForProtoFile.Descriptor,
});
}, assigner);
}
#endregion
#region Static variables
internal static readonly pbd::MessageDescriptor internal__static_protobuf_unittest_TestEmbedOptimizedForSize__Descriptor
= Descriptor.MessageTypes[0];
internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestEmbedOptimizedForSize, global::Google.ProtocolBuffers.TestProtos.TestEmbedOptimizedForSize.Builder> internal__static_protobuf_unittest_TestEmbedOptimizedForSize__FieldAccessorTable
= new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestEmbedOptimizedForSize, global::Google.ProtocolBuffers.TestProtos.TestEmbedOptimizedForSize.Builder>(internal__static_protobuf_unittest_TestEmbedOptimizedForSize__Descriptor,
new string[] { "OptionalMessage", "RepeatedMessage", });
#endregion
}
#region Messages
public sealed partial class TestEmbedOptimizedForSize : pb::GeneratedMessage<TestEmbedOptimizedForSize, TestEmbedOptimizedForSize.Builder> {
......@@ -342,6 +359,9 @@ namespace Google.ProtocolBuffers.TestProtos {
return this;
}
}
static TestEmbedOptimizedForSize() {
pbd::FileDescriptor descriptor = global::Google.ProtocolBuffers.TestProtos.UnitTestEmbedOptimizeForProtoFile.Descriptor;
}
}
#endregion
......
......@@ -8,31 +8,47 @@ namespace Google.ProtocolBuffers.TestProtos {
public static partial class UnitTestImportProtoFile {
#region Extension registration
public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {
}
#endregion
#region Static variables
internal static pbd::MessageDescriptor internal__static_protobuf_unittest_import_ImportMessage__Descriptor;
internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.ImportMessage, global::Google.ProtocolBuffers.TestProtos.ImportMessage.Builder> internal__static_protobuf_unittest_import_ImportMessage__FieldAccessorTable;
#endregion
#region Descriptor
public static pbd::FileDescriptor Descriptor {
get { return descriptor; }
}
private static readonly pbd::FileDescriptor descriptor = pbd::FileDescriptor.InternalBuildGeneratedFileFrom(
global::System.Convert.FromBase64String(
private static pbd::FileDescriptor descriptor;
static UnitTestImportProtoFile() {
byte[] descriptorData = global::System.Convert.FromBase64String(
"CiVnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0LnByb3RvEhhwcm90" +
"b2J1Zl91bml0dGVzdF9pbXBvcnQaJGdvb2dsZS9wcm90b2J1Zi9jc2hhcnBf" +
"b3B0aW9ucy5wcm90byIaCg1JbXBvcnRNZXNzYWdlEgkKAWQYASABKAUqPAoK" +
"SW1wb3J0RW51bRIOCgpJTVBPUlRfRk9PEAcSDgoKSU1QT1JUX0JBUhAIEg4K" +
"CklNUE9SVF9CQVoQCUJbChhjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RIAcI+" +
"PAohR29vZ2xlLlByb3RvY29sQnVmZmVycy5UZXN0UHJvdG9zEhdVbml0VGVz" +
"dEltcG9ydFByb3RvRmlsZQ=="),
"dEltcG9ydFByb3RvRmlsZQ==");
pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
descriptor = root;
internal__static_protobuf_unittest_import_ImportMessage__Descriptor = Descriptor.MessageTypes[0];
internal__static_protobuf_unittest_import_ImportMessage__FieldAccessorTable =
new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.ImportMessage, global::Google.ProtocolBuffers.TestProtos.ImportMessage.Builder>(internal__static_protobuf_unittest_import_ImportMessage__Descriptor,
new string[] { "D", });
pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();
RegisterAllExtensions(registry);
global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.RegisterAllExtensions(registry);
return registry;
};
pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
new pbd::FileDescriptor[] {
global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor,
});
}, assigner);
}
#endregion
#region Static variables
internal static readonly pbd::MessageDescriptor internal__static_protobuf_unittest_import_ImportMessage__Descriptor
= Descriptor.MessageTypes[0];
internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.ImportMessage, global::Google.ProtocolBuffers.TestProtos.ImportMessage.Builder> internal__static_protobuf_unittest_import_ImportMessage__FieldAccessorTable
= new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.ImportMessage, global::Google.ProtocolBuffers.TestProtos.ImportMessage.Builder>(internal__static_protobuf_unittest_import_ImportMessage__Descriptor,
new string[] { "D", });
#endregion
}
#region Enums
public enum ImportEnum {
......@@ -253,6 +269,9 @@ namespace Google.ProtocolBuffers.TestProtos {
return this;
}
}
static ImportMessage() {
pbd::FileDescriptor descriptor = global::Google.ProtocolBuffers.TestProtos.UnitTestImportProtoFile.Descriptor;
}
}
#endregion
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -8,12 +8,33 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
public static partial class CSharpOptions {
#region Extension registration
public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {
registry.Add(global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.CSharpFileOptions);
registry.Add(global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.CSharpFieldOptions);
}
#endregion
#region Extensions
public const int CSharpFileOptionsFieldNumber = 1000;
public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions> CSharpFileOptions;
public const int CSharpFieldOptionsFieldNumber = 1000;
public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions> CSharpFieldOptions;
#endregion
#region Static variables
internal static pbd::MessageDescriptor internal__static_google_protobuf_CSharpFileOptions__Descriptor;
internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions, global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions.Builder> internal__static_google_protobuf_CSharpFileOptions__FieldAccessorTable;
internal static pbd::MessageDescriptor internal__static_google_protobuf_CSharpFieldOptions__Descriptor;
internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions, global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions.Builder> internal__static_google_protobuf_CSharpFieldOptions__FieldAccessorTable;
#endregion
#region Descriptor
public static pbd::FileDescriptor Descriptor {
get { return descriptor; }
}
private static readonly pbd::FileDescriptor descriptor = pbd::FileDescriptor.InternalBuildGeneratedFileFrom(
global::System.Convert.FromBase64String(
private static pbd::FileDescriptor descriptor;
static CSharpOptions() {
byte[] descriptorData = global::System.Convert.FromBase64String(
"CiRnb29nbGUvcHJvdG9idWYvY3NoYXJwX29wdGlvbnMucHJvdG8SD2dvb2ds" +
"ZS5wcm90b2J1ZhogZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8i" +
"iAEKEUNTaGFycEZpbGVPcHRpb25zEhEKCW5hbWVzcGFjZRgBIAEoCRIaChJ1" +
......@@ -24,33 +45,28 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
"RmlsZU9wdGlvbnMY6AcgASgLMiIuZ29vZ2xlLnByb3RvYnVmLkNTaGFycEZp" +
"bGVPcHRpb25zOmEKFGNzaGFycF9maWVsZF9vcHRpb25zEh0uZ29vZ2xlLnBy" +
"b3RvYnVmLkZpZWxkT3B0aW9ucxjoByABKAsyIy5nb29nbGUucHJvdG9idWYu" +
"Q1NoYXJwRmllbGRPcHRpb25z"),
"Q1NoYXJwRmllbGRPcHRpb25z");
pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
descriptor = root;
internal__static_google_protobuf_CSharpFileOptions__Descriptor = Descriptor.MessageTypes[0];
internal__static_google_protobuf_CSharpFileOptions__FieldAccessorTable =
new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions, global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions.Builder>(internal__static_google_protobuf_CSharpFileOptions__Descriptor,
new string[] { "Namespace", "UmbrellaClassname", "PublicClasses", "MultipleFiles", "NestClasses", });
internal__static_google_protobuf_CSharpFieldOptions__Descriptor = Descriptor.MessageTypes[1];
internal__static_google_protobuf_CSharpFieldOptions__FieldAccessorTable =
new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions, global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions.Builder>(internal__static_google_protobuf_CSharpFieldOptions__Descriptor,
new string[] { "PropertyName", });
global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.CSharpFileOptions = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions>.CreateInstance(global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor.Extensions[0]);
global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.CSharpFieldOptions = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions>.CreateInstance(global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor.Extensions[1]);
return null;
};
pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
new pbd::FileDescriptor[] {
global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor,
});
#endregion
#region Extensions
public const int CsharpFileOptionsFieldNumber = 1000;
public static readonly pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions> CSharpFileOptions =
pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions>.CreateInstance(Descriptor.Extensions[0]);
public const int CsharpFieldOptionsFieldNumber = 1000;
public static readonly pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions> CSharpFieldOptions =
pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions>.CreateInstance(Descriptor.Extensions[1]);
}, assigner);
}
#endregion
#region Static variables
internal static readonly pbd::MessageDescriptor internal__static_google_protobuf_CSharpFileOptions__Descriptor
= Descriptor.MessageTypes[0];
internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions, global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions.Builder> internal__static_google_protobuf_CSharpFileOptions__FieldAccessorTable
= new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions, global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions.Builder>(internal__static_google_protobuf_CSharpFileOptions__Descriptor,
new string[] { "Namespace", "UmbrellaClassname", "PublicClasses", "MultipleFiles", "NestClasses", });
internal static readonly pbd::MessageDescriptor internal__static_google_protobuf_CSharpFieldOptions__Descriptor
= Descriptor.MessageTypes[1];
internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions, global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions.Builder> internal__static_google_protobuf_CSharpFieldOptions__FieldAccessorTable
= new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions, global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions.Builder>(internal__static_google_protobuf_CSharpFieldOptions__Descriptor,
new string[] { "PropertyName", });
#endregion
}
#region Messages
public sealed partial class CSharpFileOptions : pb::GeneratedMessage<CSharpFileOptions, CSharpFileOptions.Builder> {
......@@ -293,6 +309,9 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
return this;
}
}
static CSharpFileOptions() {
pbd::FileDescriptor descriptor = global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor;
}
}
public sealed partial class CSharpFieldOptions : pb::GeneratedMessage<CSharpFieldOptions, CSharpFieldOptions.Builder> {
......@@ -422,6 +441,9 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
return this;
}
}
static CSharpFieldOptions() {
pbd::FileDescriptor descriptor = global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor;
}
}
#endregion
......
......@@ -40,7 +40,7 @@ namespace Google.ProtocolBuffers.Descriptors {
public abstract class DescriptorBase<TProto, TOptions> : IDescriptor<TProto>
where TProto : IMessage, IDescriptorProto<TOptions> {
private readonly TProto proto;
private TProto proto;
private readonly FileDescriptor file;
private readonly string fullName;
......@@ -50,6 +50,10 @@ namespace Google.ProtocolBuffers.Descriptors {
this.fullName = fullName;
}
internal virtual void ReplaceProto(TProto newProto) {
this.proto = newProto;
}
protected static string ComputeFullName(FileDescriptor file, MessageDescriptor parent, string name) {
if (parent != null) {
return parent.FullName + "." + name;
......@@ -65,7 +69,7 @@ namespace Google.ProtocolBuffers.Descriptors {
}
/// <summary>
/// Returns the protocol buffer form of this descriptor
/// Returns the protocol buffer form of this descriptor.
/// </summary>
public TProto Proto {
get { return proto; }
......
......@@ -29,6 +29,7 @@
// 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.
using System;
using System.Collections.Generic;
using Google.ProtocolBuffers.DescriptorProtos;
......@@ -88,5 +89,12 @@ namespace Google.ProtocolBuffers.Descriptors {
internal EnumValueDescriptor FindValueByName(string name) {
return File.DescriptorPool.FindSymbol<EnumValueDescriptor>(FullName + "." + name);
}
internal override void ReplaceProto(EnumDescriptorProto newProto) {
base.ReplaceProto(newProto);
for (int i = 0; i < values.Count; i++) {
values[i].ReplaceProto(newProto.GetValue(i));
}
}
}
}
......@@ -225,7 +225,7 @@ namespace Google.ProtocolBuffers.Descriptors {
}
/// <summary>
/// Returns the C#-specific options for this file descriptor. This will always be
/// Returns the C#-specific options for this field descriptor. This will always be
/// completely filled in.
/// </summary>
public CSharpFieldOptions CSharpOptions {
......
......@@ -43,7 +43,7 @@ namespace Google.ProtocolBuffers.Descriptors {
/// </summary>
public sealed class FileDescriptor : IDescriptor<FileDescriptorProto> {
private readonly FileDescriptorProto proto;
private FileDescriptorProto proto;
private readonly IList<MessageDescriptor> messageTypes;
private readonly IList<EnumDescriptor> enumTypes;
private readonly IList<ServiceDescriptor> services;
......@@ -275,9 +275,9 @@ namespace Google.ProtocolBuffers.Descriptors {
}
for (int i = 0; i < proto.DependencyCount; i++) {
if (dependencies[i].Name != proto.DependencyList[i]) {
/*throw new DescriptorValidationException(result,
throw new DescriptorValidationException(result,
"Dependencies passed to FileDescriptor.BuildFrom() don't match " +
"those listed in the FileDescriptorProto.");*/
"those listed in the FileDescriptorProto.");
}
}
......@@ -306,12 +306,89 @@ namespace Google.ProtocolBuffers.Descriptors {
/// <summary>
/// This method is to be called by generated code only. It is equivalent
/// to BuildFrom except that the FileDescriptorProto is encoded in
/// protocol buffer wire format.
/// protocol buffer wire format. This overload is maintained for backward
/// compatibility with source code generated before the custom options were available
/// (and working).
/// </summary>
public static FileDescriptor InternalBuildGeneratedFileFrom(byte[] descriptorData, FileDescriptor[] dependencies) {
return InternalBuildGeneratedFileFrom(descriptorData, dependencies, x => null);
}
/// <summary>
/// This delegate should be used by generated code only. When calling
/// FileDescriptor.InternalBuildGeneratedFileFrom, the caller can provide
/// a callback which assigns the global variables defined in the generated code
/// which point at parts of the FileDescriptor. The callback returns an
/// Extension Registry which contains any extensions which might be used in
/// the descriptor - that is, extensions of the various "Options" messages defined
/// in descriptor.proto. The callback may also return null to indicate that
/// no extensions are used in the descriptor.
/// </summary>
/// <param name="descriptor"></param>
/// <returns></returns>
public delegate ExtensionRegistry InternalDescriptorAssigner(FileDescriptor descriptor);
public static FileDescriptor InternalBuildGeneratedFileFrom(byte[] descriptorData,
FileDescriptor[] dependencies) {
FileDescriptorProto proto = FileDescriptorProto.ParseFrom(descriptorData);
return BuildFrom(proto, dependencies);
FileDescriptor[] dependencies,InternalDescriptorAssigner descriptorAssigner) {
FileDescriptorProto proto;
try {
proto = FileDescriptorProto.ParseFrom(descriptorData);
} catch (InvalidProtocolBufferException e) {
throw new ArgumentException("Failed to parse protocol buffer descriptor for generated code.", e);
}
FileDescriptor result;
try {
result = BuildFrom(proto, dependencies);
} catch (DescriptorValidationException e) {
throw new ArgumentException("Invalid embedded descriptor for \"" + proto.Name + "\".", e);
}
ExtensionRegistry registry = descriptorAssigner(result);
if (registry != null) {
// We must re-parse the proto using the registry.
try {
proto = FileDescriptorProto.ParseFrom(descriptorData, registry);
} catch (InvalidProtocolBufferException e) {
throw new ArgumentException("Failed to parse protocol buffer descriptor for generated code.", e);
}
result.ReplaceProto(proto);
}
return result;
}
/// <summary>
/// Replace our FileDescriptorProto with the given one, which is
/// identical except that it might contain extensions that weren't present
/// in the original. This method is needed for bootstrapping when a file
/// defines custom options. The options may be defined in the file itself,
/// so we can't actually parse them until we've constructed the descriptors,
/// but to construct the decsriptors we have to have parsed the descriptor
/// protos. So, we have to parse the descriptor protos a second time after
/// constructing the descriptors.
/// </summary>
private void ReplaceProto(FileDescriptorProto newProto) {
proto = newProto;
for (int i = 0; i < messageTypes.Count; i++) {
messageTypes[i].ReplaceProto(proto.GetMessageType(i));
}
for (int i = 0; i < enumTypes.Count; i++) {
enumTypes[i].ReplaceProto(proto.GetEnumType(i));
}
for (int i = 0; i < services.Count; i++) {
services[i].ReplaceProto(proto.GetService(i));
}
for (int i = 0; i < extensions.Count; i++) {
extensions[i].ReplaceProto(proto.GetExtension(i));
}
}
}
}
......@@ -29,6 +29,7 @@
// 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.
using System;
using System.Collections.Generic;
using Google.ProtocolBuffers.DescriptorProtos;
......@@ -122,6 +123,15 @@ namespace Google.ProtocolBuffers.Descriptors {
return false;
}
/// <summary>
/// Finds a field by field name.
/// </summary>
/// <param name="name">The unqualified name of the field (e.g. "foo").</param>
/// <returns>The field's descriptor, or null if not found.</returns>
public FieldDescriptor FindFieldByName(String name) {
return File.DescriptorPool.FindSymbol<FieldDescriptor>(FullName + "." + name);
}
/// <summary>
/// Finds a field by field number.
/// </summary>
......@@ -131,6 +141,22 @@ namespace Google.ProtocolBuffers.Descriptors {
return File.DescriptorPool.FindFieldByNumber(this, number);
}
/// <summary>
/// Finds a field by its property name, as it would be generated by protogen.
/// </summary>
/// <param name="propertyName">The property name within this message type.</param>
/// <returns>The field's descriptor, or null if not found.</returns>
public FieldDescriptor FindFieldByPropertyName(string propertyName) {
// For reasonably short messages, this will be more efficient than a dictionary
// lookup. It also means we don't need to do things lazily with locks etc.
foreach (FieldDescriptor field in Fields) {
if (field.CSharpOptions.PropertyName == propertyName) {
return field;
}
}
return null;
}
/// <summary>
/// Finds a nested descriptor by name. The is valid for fields, nested
/// message types and enums.
......@@ -198,5 +224,28 @@ namespace Google.ProtocolBuffers.Descriptors {
}
return false;
}
/// <summary>
/// See FileDescriptor.ReplaceProto
/// </summary>
internal override void ReplaceProto(DescriptorProto newProto) {
base.ReplaceProto(newProto);
for (int i = 0; i < nestedTypes.Count; i++) {
nestedTypes[i].ReplaceProto(newProto.GetNestedType(i));
}
for (int i = 0; i < enumTypes.Count; i++) {
enumTypes[i].ReplaceProto(newProto.GetEnumType(i));
}
for (int i = 0; i < fields.Count; i++) {
fields[i].ReplaceProto(newProto.GetField(i));
}
for (int i = 0; i < extensions.Count; i++) {
extensions[i].ReplaceProto(newProto.GetExtension(i));
}
}
}
}
......@@ -72,5 +72,12 @@ namespace Google.ProtocolBuffers.Descriptors {
method.CrossLink();
}
}
internal override void ReplaceProto(ServiceDescriptorProto newProto) {
base.ReplaceProto(newProto);
for (int i = 0; i < methods.Count; i++) {
methods[i].ReplaceProto(newProto.GetMethod(i));
}
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment