New options now work fine.

pull/288/head
Jon Skeet 16 years ago
parent d6343be707
commit 1d131c98f0
  1. 19
      protos/google/protobuf/csharp_options.proto
  2. 4
      protos/google/protobuf/unittest.proto
  3. 4
      protos/google/protobuf/unittest_custom_options.proto
  4. 4
      protos/google/protobuf/unittest_embed_optimize_for.proto
  5. 4
      protos/google/protobuf/unittest_import.proto
  6. 4
      protos/google/protobuf/unittest_mset.proto
  7. 4
      protos/google/protobuf/unittest_optimize_for.proto
  8. 1
      src/ProtoGen.Test/ProtoGen.Test.csproj
  9. 2
      src/ProtoGen/ExtensionGenerator.cs
  10. 10
      src/ProtoGen/FieldGeneratorBase.cs
  11. 4
      src/ProtoGen/Generator.cs
  12. 29
      src/ProtocolBuffers.Test/CSharpOptionsTest.cs
  13. 1
      src/ProtocolBuffers.Test/ProtocolBuffers.Test.csproj
  14. 0
      src/ProtocolBuffers.Test/TestProtos/___7469.tmp
  15. 25
      src/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs
  16. 43
      src/ProtocolBuffers/Descriptors/FieldDescriptor.cs
  17. 5
      src/ProtocolBuffers/Descriptors/FileDescriptor.cs

@ -10,16 +10,21 @@ message CSharpFileOptions {
optional bool public_classes = 3;
optional bool multiple_files = 4;
optional bool nest_classes = 5;
}
extend FileOptions {
optional CSharpFileOptions csharp_file_options = 1000;
}
extend FileOptions {
optional CSharpFileOptions csharp_options = 1000;
}
extend FieldOptions {
optional CSharpFieldOptions csharp_field_options = 1000;
}
message CSharpFieldOptions {
// Provides the ability to override the name of the property
// generated for this field. This does not currently work with
// messages optimised for reflection, and is only applied to the
// actual property rather than associated methods. (Careful
// consideration needed here...)
optional string property_name = 1;
extend FieldOptions {
optional CSharpFieldOptions csharp_options = 1000;
}
}

@ -2,8 +2,8 @@
// line onwards is as per original distribution.
import "google/protobuf/csharp_options.proto";
import "google/protobuf/descriptor.proto";
option (google.protobuf.CSharpFileOptions.csharp_options).namespace = "Google.ProtocolBuffers.TestProtos";
option (google.protobuf.CSharpFileOptions.csharp_options).umbrella_classname = "UnitTestProtoFile";
option (google.protobuf.csharp_file_options).namespace = "Google.ProtocolBuffers.TestProtos";
option (google.protobuf.csharp_file_options).umbrella_classname = "UnitTestProtoFile";
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.

@ -1,8 +1,8 @@
// Additional options required for C# generation. File from copyright
// line onwards is as per original distribution.
import "google/protobuf/csharp_options.proto";
option (google.protobuf.CSharpFileOptions.csharp_options).namespace = "Google.ProtocolBuffers.TestProtos";
option (google.protobuf.CSharpFileOptions.csharp_options).umbrella_classname = "UnitTestCustomOptionsProtoFile";
option (google.protobuf.csharp_file_options).namespace = "Google.ProtocolBuffers.TestProtos";
option (google.protobuf.csharp_file_options).umbrella_classname = "UnitTestCustomOptionsProtoFile";
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.

@ -2,8 +2,8 @@
// line onwards is as per original distribution.
import "google/protobuf/csharp_options.proto";
import "google/protobuf/descriptor.proto";
option (google.protobuf.CSharpFileOptions.csharp_options).namespace = "Google.ProtocolBuffers.TestProtos";
option (google.protobuf.CSharpFileOptions.csharp_options).umbrella_classname = "UnitTestEmbedOptimizeForProtoFile";
option (google.protobuf.csharp_file_options).namespace = "Google.ProtocolBuffers.TestProtos";
option (google.protobuf.csharp_file_options).umbrella_classname = "UnitTestEmbedOptimizeForProtoFile";
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.

@ -2,8 +2,8 @@
// line onwards is as per original distribution.
import "google/protobuf/csharp_options.proto";
import "google/protobuf/descriptor.proto";
option (google.protobuf.CSharpFileOptions.csharp_options).namespace = "Google.ProtocolBuffers.TestProtos";
option (google.protobuf.CSharpFileOptions.csharp_options).umbrella_classname = "UnitTestImportProtoFile";
option (google.protobuf.csharp_file_options).namespace = "Google.ProtocolBuffers.TestProtos";
option (google.protobuf.csharp_file_options).umbrella_classname = "UnitTestImportProtoFile";
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.

@ -2,8 +2,8 @@
// line onwards is as per original distribution.
import "google/protobuf/csharp_options.proto";
import "google/protobuf/descriptor.proto";
option (google.protobuf.CSharpFileOptions.csharp_options).namespace = "Google.ProtocolBuffers.TestProtos";
option (google.protobuf.CSharpFileOptions.csharp_options).umbrella_classname = "UnitTestMessageSetProtoFile";
option (google.protobuf.csharp_file_options).namespace = "Google.ProtocolBuffers.TestProtos";
option (google.protobuf.csharp_file_options).umbrella_classname = "UnitTestMessageSetProtoFile";
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.

@ -2,8 +2,8 @@
// line onwards is as per original distribution.
import "google/protobuf/csharp_options.proto";
import "google/protobuf/descriptor.proto";
option (google.protobuf.CSharpFileOptions.csharp_options).namespace = "Google.ProtocolBuffers.TestProtos";
option (google.protobuf.CSharpFileOptions.csharp_options).umbrella_classname = "UnitTestOptimizeForProtoFile";
option (google.protobuf.csharp_file_options).namespace = "Google.ProtocolBuffers.TestProtos";
option (google.protobuf.csharp_file_options).umbrella_classname = "UnitTestOptimizeForProtoFile";
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.

@ -45,7 +45,6 @@
</ItemGroup>
<ItemGroup>
<Compile Include="DependencyResolutionTest.cs" />
<Compile Include="DescriptorUtilTest.cs" />
<Compile Include="GeneratorTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>

@ -9,7 +9,7 @@ namespace Google.ProtocolBuffers.ProtoGen {
}
public void Generate(TextGenerator writer) {
string name = NameHelpers.UnderscoresToPascalCase(GetFieldName(Descriptor));
string name = Descriptor.CSharpOptions.PropertyName;
string type;
switch (Descriptor.MappedType) {

@ -73,17 +73,9 @@ namespace Google.ProtocolBuffers.ProtoGen {
}
}
/// <summary>
/// Usually the same as CapitalizedName, except when the enclosing type has the same name,
/// in which case an underscore is appended.
/// </summary>
protected string PropertyName {
get {
string ret = CapitalizedName;
if (ret == Descriptor.ContainingType.Name) {
ret += "_";
}
return ret;
return Descriptor.CSharpOptions.PropertyName;
}
}

@ -30,8 +30,8 @@ namespace Google.ProtocolBuffers.ProtoGen {
foreach (string inputFile in options.InputFiles) {
FileDescriptorSet descriptorProtos;
ExtensionRegistry extensionRegistry = ExtensionRegistry.CreateInstance();
extensionRegistry.Add(CSharpFileOptions.CSharpOptions);
extensionRegistry.Add(CSharpFieldOptions.CSharpOptions);
extensionRegistry.Add(CSharpOptions.CSharpFileOptions);
extensionRegistry.Add(CSharpOptions.CSharpFieldOptions);
using (Stream inputStream = File.OpenRead(inputFile)) {
descriptorProtos = FileDescriptorSet.ParseFrom(inputStream, extensionRegistry);
}

@ -1,69 +1,70 @@
using Google.ProtocolBuffers.DescriptorProtos;
using Google.ProtocolBuffers.DescriptorProtos;
using Google.ProtocolBuffers.Descriptors;
using NUnit.Framework;
namespace Google.ProtocolBuffers.ProtoGen {
namespace Google.ProtocolBuffers {
[TestFixture]
public class DescriptorUtilTest {
/* FIXME: Move these around!
[Test]
public void ExplicitNamespace() {
FileDescriptorProto proto = new FileDescriptorProto.Builder {
Name = "x", Package = "pack", Options = new FileOptions.Builder().SetExtension(CSharpOptions.CSharpNamespace, "Foo.Bar").Build()
Name = "x", Package = "pack", Options = new FileOptions.Builder().SetExtension(CSharpOptions.CSharpFileOptions,
new CSharpFileOptions.Builder { Namespace = "Foo.Bar" }.Build()).Build()
}.Build();
FileDescriptor descriptor = FileDescriptor.BuildFrom(proto, null);
Assert.AreEqual("Foo.Bar", DescriptorUtil.GetNamespace(descriptor));
Assert.AreEqual("Foo.Bar", descriptor.CSharpOptions.Namespace);
}
[Test]
public void NoNamespaceFallsBackToPackage() {
FileDescriptorProto proto = new FileDescriptorProto.Builder { Name = "x", Package = "pack" }.Build();
FileDescriptor descriptor = FileDescriptor.BuildFrom(proto, null);
Assert.AreEqual("pack", DescriptorUtil.GetNamespace(descriptor));
Assert.AreEqual("pack", descriptor.CSharpOptions.Namespace);
}
[Test]
public void NoNamespaceOrPackageFallsBackToEmptyString() {
FileDescriptorProto proto = new FileDescriptorProto.Builder { Name = "x" }.Build();
FileDescriptor descriptor = FileDescriptor.BuildFrom(proto, null);
Assert.AreEqual("", DescriptorUtil.GetNamespace(descriptor));
Assert.AreEqual("", descriptor.CSharpOptions.Namespace);
}
[Test]
public void ExplicitlyNamedFileClass() {
FileDescriptorProto proto = new FileDescriptorProto.Builder {
Name = "x", Options = new FileOptions.Builder().SetExtension(CSharpOptions.CSharpUmbrellaClassname, "Foo").Build()
Name = "x", Options = new FileOptions.Builder().SetExtension(CSharpOptions.CSharpFileOptions,
new CSharpFileOptions.Builder { UmbrellaClassname = "Foo" }.Build()).Build()
}.Build();
FileDescriptor descriptor = FileDescriptor.BuildFrom(proto, null);
Assert.AreEqual("Foo", DescriptorUtil.GetUmbrellaClassName(descriptor));
Assert.AreEqual("Foo", descriptor.CSharpOptions.UmbrellaClassname);
}
[Test]
public void ImplicitFileClassWithProtoSuffix() {
FileDescriptorProto proto = new FileDescriptorProto.Builder { Name = "foo_bar.proto" }.Build();
FileDescriptor descriptor = FileDescriptor.BuildFrom(proto, null);
Assert.AreEqual("FooBar", DescriptorUtil.GetUmbrellaClassName(descriptor));
Assert.AreEqual("FooBar", descriptor.CSharpOptions.UmbrellaClassname);
}
[Test]
public void ImplicitFileClassWithProtoDevelSuffix() {
FileDescriptorProto proto = new FileDescriptorProto.Builder { Name = "foo_bar.protodevel" }.Build();
FileDescriptor descriptor = FileDescriptor.BuildFrom(proto, null);
Assert.AreEqual("FooBar", DescriptorUtil.GetUmbrellaClassName(descriptor));
Assert.AreEqual("FooBar", descriptor.CSharpOptions.UmbrellaClassname);
}
[Test]
public void ImplicitFileClassWithNoSuffix() {
FileDescriptorProto proto = new FileDescriptorProto.Builder { Name = "foo_bar" }.Build();
FileDescriptor descriptor = FileDescriptor.BuildFrom(proto, null);
Assert.AreEqual("FooBar", DescriptorUtil.GetUmbrellaClassName(descriptor));
Assert.AreEqual("FooBar", descriptor.CSharpOptions.UmbrellaClassname);
}
[Test]
public void ImplicitFileClassWithDirectoryStructure() {
FileDescriptorProto proto = new FileDescriptorProto.Builder { Name = "x/y/foo_bar" }.Build();
FileDescriptor descriptor = FileDescriptor.BuildFrom(proto, null);
Assert.AreEqual("FooBar", DescriptorUtil.GetUmbrellaClassName(descriptor));
} */
Assert.AreEqual("FooBar", descriptor.CSharpOptions.UmbrellaClassname);
}
}
}

@ -51,6 +51,7 @@
<Compile Include="CodedInputStreamTest.cs" />
<Compile Include="CodedOutputStreamTest.cs" />
<Compile Include="Collections\PopsicleListTest.cs" />
<Compile Include="CSharpOptionsTest.cs" />
<Compile Include="DescriptorsTest.cs" />
<Compile Include="DynamicMessageTest.cs" />
<Compile Include="GeneratedMessageTest.cs" />

@ -16,20 +16,27 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
global::System.Convert.FromBase64String(
"CiRnb29nbGUvcHJvdG9idWYvY3NoYXJwX29wdGlvbnMucHJvdG8SD2dvb2ds" +
"ZS5wcm90b2J1ZhogZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8i" +
"4wEKEUNTaGFycEZpbGVPcHRpb25zEhEKCW5hbWVzcGFjZRgBIAEoCRIaChJ1" +
"iAEKEUNTaGFycEZpbGVPcHRpb25zEhEKCW5hbWVzcGFjZRgBIAEoCRIaChJ1" +
"bWJyZWxsYV9jbGFzc25hbWUYAiABKAkSFgoOcHVibGljX2NsYXNzZXMYAyAB" +
"KAgSFgoObXVsdGlwbGVfZmlsZXMYBCABKAgSFAoMbmVzdF9jbGFzc2VzGAUg" +
"ASgIMlkKDmNzaGFycF9vcHRpb25zEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVP" +
"cHRpb25zGOgHIAEoCzIiLmdvb2dsZS5wcm90b2J1Zi5DU2hhcnBGaWxlT3B0" +
"aW9ucyKIAQoSQ1NoYXJwRmllbGRPcHRpb25zEhUKDXByb3BlcnR5X25hbWUY" +
"ASABKAkyWwoOY3NoYXJwX29wdGlvbnMSHS5nb29nbGUucHJvdG9idWYuRmll" +
"bGRPcHRpb25zGOgHIAEoCzIjLmdvb2dsZS5wcm90b2J1Zi5DU2hhcnBGaWVs" +
"ZE9wdGlvbnM="),
"ASgIIisKEkNTaGFycEZpZWxkT3B0aW9ucxIVCg1wcm9wZXJ0eV9uYW1lGAEg" +
"ASgJOl4KE2NzaGFycF9maWxlX29wdGlvbnMSHC5nb29nbGUucHJvdG9idWYu" +
"RmlsZU9wdGlvbnMY6AcgASgLMiIuZ29vZ2xlLnByb3RvYnVmLkNTaGFycEZp" +
"bGVPcHRpb25zOmEKFGNzaGFycF9maWVsZF9vcHRpb25zEh0uZ29vZ2xlLnBy" +
"b3RvYnVmLkZpZWxkT3B0aW9ucxjoByABKAsyIy5nb29nbGUucHJvdG9idWYu" +
"Q1NoYXJwRmllbGRPcHRpb25z"),
new pbd::FileDescriptor[] {
global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor,
});
#endregion
#region Extensions
public static readonly pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions> CSharpFileOptions =
pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions>.CreateInstance(Descriptor.Extensions[0]);
public static readonly pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions> CSharpFieldOptions =
pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions>.CreateInstance(Descriptor.Extensions[1]);
#endregion
#region Static variables
internal static readonly pbd::MessageDescriptor internal__static_google_protobuf_CSharpFileOptions__Descriptor
= Descriptor.MessageTypes[0];
@ -66,8 +73,6 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
get { return global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.internal__static_google_protobuf_CSharpFileOptions__FieldAccessorTable; }
}
public static readonly pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions> CSharpOptions =
pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions>.CreateInstance(Descriptor.Extensions[0]);
private bool hasNamespace;
private string namespace_ = "";
public bool HasNamespace {
@ -293,8 +298,6 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
get { return global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.internal__static_google_protobuf_CSharpFieldOptions__FieldAccessorTable; }
}
public static readonly pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions> CSharpOptions =
pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions>.CreateInstance(Descriptor.Extensions[0]);
private bool hasPropertyName;
private string propertyName_ = "";
public bool HasPropertyName {

@ -50,6 +50,9 @@ namespace Google.ProtocolBuffers.Descriptors {
private FieldType fieldType;
private MappedType mappedType;
private CSharpFieldOptions csharpFieldOptions;
private readonly object optionsLock = new object();
internal FieldDescriptor(FieldDescriptorProto proto, FileDescriptor file,
MessageDescriptor parent, int index, bool isExtension)
: base(proto, file, ComputeFullName(file, parent, proto.Name), index) {
@ -87,6 +90,31 @@ namespace Google.ProtocolBuffers.Descriptors {
file.DescriptorPool.AddSymbol(this);
}
private CSharpFieldOptions BuildOrFakeCSharpOptions() {
// TODO(jonskeet): Check if we could use FileDescriptorProto.Descriptor.Name - interesting bootstrap issues
if (File.Proto.Name == "google/protobuf/csharp_options.proto") {
if (Name=="csharp_field_options") {
return new CSharpFieldOptions.Builder { PropertyName = "CSharpFieldOptions" }.Build();
}
if (Name=="csharp_file_options") {
return new CSharpFieldOptions.Builder { PropertyName = "CSharpFileOptions" }.Build();
}
}
CSharpFieldOptions.Builder builder = CSharpFieldOptions.CreateBuilder();
if (Proto.Options.HasExtension(DescriptorProtos.CSharpOptions.CSharpFieldOptions)) {
builder.MergeFrom(Proto.Options.GetExtension(DescriptorProtos.CSharpOptions.CSharpFieldOptions));
}
if (!builder.HasPropertyName) {
string fieldName = FieldType == FieldType.Group ? MessageType.Name : Name;
string propertyName = NameHelpers.UnderscoresToPascalCase(fieldName);
if (propertyName == ContainingType.Name) {
propertyName += "_";
}
builder.PropertyName = propertyName;
}
return builder.Build();
}
/// <summary>
/// Maps a field type as included in the .proto file to a FieldType.
/// </summary>
@ -191,6 +219,21 @@ namespace Google.ProtocolBuffers.Descriptors {
public MessageDescriptor ContainingType {
get { return containingType; }
}
/// <summary>
/// Returns the C#-specific options for this file descriptor. This will always be
/// completely filled in.
/// </summary>
public CSharpFieldOptions CSharpOptions {
get {
lock (optionsLock) {
if (csharpFieldOptions == null) {
csharpFieldOptions = BuildOrFakeCSharpOptions();
}
}
return csharpFieldOptions;
}
}
/// <summary>
/// For extensions defined nested within message types, gets

@ -88,8 +88,8 @@ namespace Google.ProtocolBuffers.Descriptors {
}.Build();
}
CSharpFileOptions.Builder builder = CSharpFileOptions.CreateBuilder();
if (proto.Options.HasExtension(CSharpFileOptions.CSharpOptions)) {
builder.MergeFrom(proto.Options.GetExtension(CSharpFileOptions.CSharpOptions));
if (proto.Options.HasExtension(DescriptorProtos.CSharpOptions.CSharpFileOptions)) {
builder.MergeFrom(proto.Options.GetExtension(DescriptorProtos.CSharpOptions.CSharpFileOptions));
}
if (!builder.HasNamespace) {
builder.Namespace = Package;
@ -128,7 +128,6 @@ namespace Google.ProtocolBuffers.Descriptors {
/// <summary>
/// Returns the C#-specific options for this file descriptor. This will always be
/// completely filled in.
/// FIXME: This isn't thread-safe. Can't do it at construction time due to bootstrapping issues.
/// </summary>
public CSharpFileOptions CSharpOptions {
get {

Loading…
Cancel
Save