aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJon Skeet <skeet@pobox.com>2008-08-14 20:35:21 +0100
committerJon Skeet <skeet@pobox.com>2008-08-14 20:35:21 +0100
commit575083ae9c3ecb17e14ae29aa20b784940fcdfd1 (patch)
treea8b536c9b8e2982e9e904e25b8489404cd727155 /src
parent1353315dede3e22266df73fca8dd421119597e46 (diff)
downloadprotobuf-575083ae9c3ecb17e14ae29aa20b784940fcdfd1.tar.gz
protobuf-575083ae9c3ecb17e14ae29aa20b784940fcdfd1.tar.bz2
protobuf-575083ae9c3ecb17e14ae29aa20b784940fcdfd1.zip
Initial support for services and extensions. Incomplete, but enough to get generated unit test files to compile.
Diffstat (limited to 'src')
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_enum.cc3
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_enum_field.cc16
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_extension.cc22
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_file.cc4
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_helpers.cc16
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_helpers.h1
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_message.cc12
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_service.cc75
-rw-r--r--src/google/protobuf/unittest.proto2
-rw-r--r--src/google/protobuf/unittest_embed_optimize_for.proto3
-rw-r--r--src/google/protobuf/unittest_import.proto5
-rw-r--r--src/google/protobuf/unittest_mset.proto3
-rw-r--r--src/google/protobuf/unittest_optimize_for.proto3
13 files changed, 84 insertions, 81 deletions
diff --git a/src/google/protobuf/compiler/csharp/csharp_enum.cc b/src/google/protobuf/compiler/csharp/csharp_enum.cc
index c801da00..17241663 100644
--- a/src/google/protobuf/compiler/csharp/csharp_enum.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_enum.cc
@@ -69,8 +69,9 @@ void EnumGenerator::Generate(io::Printer* printer) {
vars["number"] = SimpleItoa(canonical_values_[i]->number());
// TODO(jonskeet): Change CONSTANT_CASE into PascalCase
+ // TODO(jonskeet): I don't think we need EnumDescriptorIndex after all
printer->Print(vars,
- "[pbd::EnumDescriptorIndex($index$)]\r\n"
+ //"[pbd::EnumDescriptorIndex($index$)]\r\n"
"$name$ = $number$,\r\n");
}
printer->Outdent();
diff --git a/src/google/protobuf/compiler/csharp/csharp_enum_field.cc b/src/google/protobuf/compiler/csharp/csharp_enum_field.cc
index c55121c1..28a70200 100644
--- a/src/google/protobuf/compiler/csharp/csharp_enum_field.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_enum_field.cc
@@ -178,11 +178,11 @@ GenerateBuilderMembers(io::Printer* printer) const {
// could hold on to the returned list and modify it after the message
// has been built, thus mutating the message which is supposed to be
// immutable.
- "public global::System.Collections.Generic::IList<$type$> $capitalized_name$List {\r\n"
+ "public scg::IList<$type$> $capitalized_name$List {\r\n"
" get { return pbc::Lists.AsReadOnly(result.$name$_); }\r\n"
"}\r\n"
"public int $capitalized_name$Count {\r\n"
- " get { return result.get$capitalized_name$Count; } \r\n"
+ " get { return result.$capitalized_name$Count; } \r\n"
"}\r\n"
"public $type$ Get$capitalized_name$(int index) {\r\n"
" return result.Get$capitalized_name$(index);\r\n"
@@ -191,7 +191,7 @@ GenerateBuilderMembers(io::Printer* printer) const {
" result.$name$_[index] = value;\r\n"
" return this;\r\n"
"}\r\n"
- "public Builder add$capitalized_name$($type$ value) {\r\n"
+ "public Builder Add$capitalized_name$($type$ value) {\r\n"
" if (result.$name$_.Count == 0) {\r\n"
" result.$name$_ = new scg::List<$type$>();\r\n"
" }\r\n"
@@ -232,9 +232,9 @@ void RepeatedEnumFieldGenerator::
GenerateParsingCode(io::Printer* printer) const {
printer->Print(variables_,
"int rawValue = input.ReadEnum();\r\n"
- "$type$ value = $type$.valueOf(rawValue);\r\n"
- "if (value == null) {\r\n"
- " unknownFields.MergeVarintField($number$, rawValue);\r\n"
+ "$type$ value = ($type$) rawValue;\r\n"
+ "if (!global::System.Enum.IsDefined(typeof($type$), value)) {\r\n"
+ " unknownFields.MergeVarintField($number$, (ulong) rawValue);\r\n"
"} else {\r\n"
" Add$capitalized_name$(value);\r\n"
"}\r\n");
@@ -244,7 +244,7 @@ void RepeatedEnumFieldGenerator::
GenerateSerializationCode(io::Printer* printer) const {
printer->Print(variables_,
"foreach ($type$ element in $capitalized_name$List) {\r\n"
- " output.WriteEnum($number$, element.Number);\r\n"
+ " output.WriteEnum($number$, (int) element);\r\n"
"}\r\n");
}
@@ -253,7 +253,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print(variables_,
"foreach ($type$ element in $capitalized_name$List) {\r\n"
" size += pb::CodedOutputStream\r\n"
- " .ComputeEnumSize($number$, element.Number);\r\n"
+ " .ComputeEnumSize($number$, (int) element);\r\n"
"}\r\n");
}
diff --git a/src/google/protobuf/compiler/csharp/csharp_extension.cc b/src/google/protobuf/compiler/csharp/csharp_extension.cc
index 2e4eb0a9..e126cc8b 100644
--- a/src/google/protobuf/compiler/csharp/csharp_extension.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_extension.cc
@@ -36,7 +36,7 @@ ExtensionGenerator::~ExtensionGenerator() {}
void ExtensionGenerator::Generate(io::Printer* printer) {
map<string, string> vars;
- vars["name"] = UnderscoresToCamelCase(descriptor_);
+ vars["name"] = UnderscoresToCapitalizedCamelCase(descriptor_);
vars["containing_type"] = ClassName(descriptor_->containing_type());
vars["index"] = SimpleItoa(descriptor_->index());
@@ -56,23 +56,13 @@ void ExtensionGenerator::Generate(io::Printer* printer) {
if (descriptor_->is_repeated()) {
printer->Print(vars,
- "public static final\r\n"
- " pb::GeneratedMessage.GeneratedExtension<\r\n"
- " $containing_type$,\r\n"
- " java.util.List<$type$>> $name$ =\r\n"
- " pb::GeneratedMessage\r\n"
- " .newRepeatedGeneratedExtension(\r\n"
- " getDescriptor().getExtensions().get($index$),\r\n"
- " typeof ($type$));\r\n");
+ "public static readonly\r\n"
+ " pb::GeneratedExtension<$containing_type$, scg::IList<$type$>> name =\r\n"
+ " pb::GeneratedExtension.CreateRepeatedExtension<$containing_type$, $type$>(Descriptor.Extensions[$index$]);\r\n");
} else {
printer->Print(vars,
- "public static final\r\n"
- " pb::GeneratedMessage.GeneratedExtension<\r\n"
- " $containing_type$,\r\n"
- " $type$> $name$ =\r\n"
- " pb::GeneratedMessage.newGeneratedExtension(\r\n"
- " getDescriptor().getExtensions().get($index$),\r\n"
- " typeof ($type$));\r\n");
+ "public static readonly pb::GeneratedExtension<$containing_type$, $type$> $name$ =\r\n"
+ " pb::GeneratedExtension.CreateExtension<$containing_type$, $type$>(Descriptor.Extensions[$index$]);\r\n");
}
}
diff --git a/src/google/protobuf/compiler/csharp/csharp_file.cc b/src/google/protobuf/compiler/csharp/csharp_file.cc
index 491cf148..e4317b4b 100644
--- a/src/google/protobuf/compiler/csharp/csharp_file.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_file.cc
@@ -148,7 +148,7 @@ void FileGenerator::Generate(io::Printer* printer) {
printer->Print("\r\n}, new pbd::FileDescriptor[] {\r\n");
for (int i = 0; i < file_->dependency_count(); i++) {
printer->Print(
- " $dependency$.getDescriptor(),\r\n",
+ " $dependency$.Descriptor,\r\n",
"dependency", ClassName(file_->dependency(i)));
}
@@ -165,9 +165,11 @@ void FileGenerator::Generate(io::Printer* printer) {
// Extensions must be generated in the outer class since they are values,
// not classes.
printer->Print("#region Extensions\r\n");
+ printer->Print("/*");
for (int i = 0; i < file_->extension_count(); i++) {
ExtensionGenerator(file_->extension(i)).Generate(printer);
}
+ printer->Print("*/\r\n");
printer->Print("#endregion\r\n\r\n");
printer->Print("#region Static variables\r\n");
diff --git a/src/google/protobuf/compiler/csharp/csharp_helpers.cc b/src/google/protobuf/compiler/csharp/csharp_helpers.cc
index 4cd6c9d5..067a7324 100644
--- a/src/google/protobuf/compiler/csharp/csharp_helpers.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_helpers.cc
@@ -91,6 +91,10 @@ string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field) {
return UnderscoresToCamelCaseImpl(FieldName(field), true);
}
+string UnderscoresToCapitalizedCamelCase(const MethodDescriptor* method) {
+ return UnderscoresToCamelCaseImpl(method->name(), true);
+}
+
string UnderscoresToCamelCase(const MethodDescriptor* method) {
return UnderscoresToCamelCaseImpl(method->name(), false);
}
@@ -162,19 +166,23 @@ string ClassName(const FileDescriptor* descriptor) {
MappedType GetMappedType(FieldDescriptor::Type field_type) {
switch (field_type) {
case FieldDescriptor::TYPE_INT32:
- case FieldDescriptor::TYPE_UINT32:
case FieldDescriptor::TYPE_SINT32:
- case FieldDescriptor::TYPE_FIXED32:
case FieldDescriptor::TYPE_SFIXED32:
return MAPPEDTYPE_INT;
case FieldDescriptor::TYPE_INT64:
- case FieldDescriptor::TYPE_UINT64:
case FieldDescriptor::TYPE_SINT64:
- case FieldDescriptor::TYPE_FIXED64:
case FieldDescriptor::TYPE_SFIXED64:
return MAPPEDTYPE_LONG;
+ case FieldDescriptor::TYPE_UINT32:
+ case FieldDescriptor::TYPE_FIXED32:
+ return MAPPEDTYPE_UINT;
+
+ case FieldDescriptor::TYPE_UINT64:
+ case FieldDescriptor::TYPE_FIXED64:
+ return MAPPEDTYPE_ULONG;
+
case FieldDescriptor::TYPE_FLOAT:
return MAPPEDTYPE_FLOAT;
diff --git a/src/google/protobuf/compiler/csharp/csharp_helpers.h b/src/google/protobuf/compiler/csharp/csharp_helpers.h
index 9a0e992b..3f1becf2 100644
--- a/src/google/protobuf/compiler/csharp/csharp_helpers.h
+++ b/src/google/protobuf/compiler/csharp/csharp_helpers.h
@@ -43,6 +43,7 @@ string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field);
// Similar, but for method names. (Typically, this merely has the effect
// of lower-casing the first letter of the name.)
string UnderscoresToCamelCase(const MethodDescriptor* method);
+string UnderscoresToCapitalizedCamelCase(const MethodDescriptor* method);
// Strips ".proto" or ".protodevel" from the end of a filename.
string StripProto(const string& filename);
diff --git a/src/google/protobuf/compiler/csharp/csharp_message.cc b/src/google/protobuf/compiler/csharp/csharp_message.cc
index 3b47a308..1d99f366 100644
--- a/src/google/protobuf/compiler/csharp/csharp_message.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_message.cc
@@ -204,7 +204,7 @@ void MessageGenerator::Generate(io::Printer* printer) {
if (descriptor_->extension_range_count() > 0) {
printer->Print(
- "$access$ sealed partial class $classname$ : pb::GeneratedMessage.ExtendableMessage<$classname$> {\r\n",
+ "$access$ sealed partial class $classname$ : pb::ExtendableMessage<$classname$, $classname$.Builder> {\r\n",
"classname", descriptor_->name(),
"access", ClassAccessLevel(descriptor_->file()));
} else {
@@ -233,7 +233,7 @@ void MessageGenerator::Generate(io::Printer* printer) {
" get { return $fileclass$.internal__$identifier$__Descriptor; }\r\n"
"}\r\n"
"\r\n"
- "protected internal override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors {\r\n"
+ "protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors {\r\n"
" get { return $fileclass$.internal__$identifier$__FieldAccessorTable; }\r\n"
"}\r\n"
"\r\n",
@@ -298,7 +298,8 @@ GenerateMessageSerializationMethods(io::Printer* printer) {
if (descriptor_->extension_range_count() > 0) {
printer->Print(
- "pb::GeneratedMessage.ExtendableMessage.ExtensionWriter extensionWriter = CreateExtensionWriter();\r\n");
+ "pb::ExtendableMessage<$classname$, $classname$.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);\r\n",
+ "classname", descriptor_->name());
}
// Merge the fields and the extension ranges, both sorted by field number.
@@ -434,8 +435,7 @@ void MessageGenerator::GenerateBuilder(io::Printer* printer) {
if (descriptor_->extension_range_count() > 0) {
printer->Print(
- "$access$ sealed partial class Builder : pb::GeneratedMessage.ExtendableBuilder<\r\n"
- " $classname$, Builder> {\r\n",
+ "$access$ sealed partial class Builder : pb::GeneratedBuilder<$classname$, $classname$.Builder>.ExtendableBuilder {\r\n",
"classname", ClassName(descriptor_),
"access", ClassAccessLevel(descriptor_->file()));
} else {
@@ -673,7 +673,7 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) {
if (descriptor_->extension_range_count() > 0) {
printer->Print(
- "if (!extensionsAreInitialized()) return false;\r\n");
+ "if (!ExtensionsAreInitialized) return false;\r\n");
}
printer->Outdent();
diff --git a/src/google/protobuf/compiler/csharp/csharp_service.cc b/src/google/protobuf/compiler/csharp/csharp_service.cc
index 9f1300cb..da73a630 100644
--- a/src/google/protobuf/compiler/csharp/csharp_service.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_service.cc
@@ -36,11 +36,8 @@ ServiceGenerator::ServiceGenerator(const ServiceDescriptor* descriptor)
ServiceGenerator::~ServiceGenerator() {}
void ServiceGenerator::Generate(io::Printer* printer) {
- bool is_own_file = descriptor_->file()->options().csharp_multiple_files();
printer->Print(
- "public $static$ abstract class $classname$\r\n"
- " implements pb::Service {\r\n",
- "static", is_own_file ? "" : "static",
+ "public abstract class $classname$ : pb::IService {\r\n",
"classname", descriptor_->name());
printer->Indent();
@@ -48,27 +45,24 @@ void ServiceGenerator::Generate(io::Printer* printer) {
for (int i = 0; i < descriptor_->method_count(); i++) {
const MethodDescriptor* method = descriptor_->method(i);
map<string, string> vars;
- vars["name"] = UnderscoresToCamelCase(method);
+ vars["name"] = UnderscoresToCapitalizedCamelCase(method);
vars["input"] = ClassName(method->input_type());
vars["output"] = ClassName(method->output_type());
printer->Print(vars,
"public abstract void $name$(\r\n"
- " pb::RpcController controller,\r\n"
+ " pb::IRpcController controller,\r\n"
" $input$ request,\r\n"
- " pb::RpcCallback<$output$> done);\r\n");
+ " global::System.Action<$output$> done);\r\n");
}
- // Generate getDescriptor() and getDescriptorForType().
+ // Generate Descriptor and DescriptorForType.
printer->Print(
"\r\n"
- "public static final\r\n"
- " pbd::ServiceDescriptor\r\n"
- " getDescriptor() {\r\n"
- " return $file$.getDescriptor().getServices().get($index$);\r\n"
+ "public static pbd::ServiceDescriptor Descriptor {\r\n"
+ " get { return $file$.Descriptor.Services[$index$]; }\r\n"
"}\r\n"
- "public final pbd::ServiceDescriptor\r\n"
- " DescriptorForType {\r\n"
- " return getDescriptor();\r\n"
+ "public pbd::ServiceDescriptor DescriptorForType {\r\n"
+ " get { return Descriptor; }\r\n"
"}\r\n",
"file", ClassName(descriptor_->file()),
"index", SimpleItoa(descriptor_->index()));
@@ -86,18 +80,17 @@ void ServiceGenerator::Generate(io::Printer* printer) {
void ServiceGenerator::GenerateCallMethod(io::Printer* printer) {
printer->Print(
"\r\n"
- "public final void callMethod(\r\n"
+ "public void CallMethod(\r\n"
" pbd::MethodDescriptor method,\r\n"
- " pb::RpcController controller,\r\n"
+ " pb::IRpcController controller,\r\n"
" pb::IMessage request,\r\n"
- " pb::RpcCallback<\r\n"
- " pb::Message> done) {\r\n"
- " if (method.getService() != getDescriptor()) {\r\n"
+ " global::System.Action<pb::IMessage> done) {\r\n"
+ " if (method.Service != Descriptor) {\r\n"
" throw new global::System.ArgumentException(\r\n"
" \"Service.CallMethod() given method descriptor for wrong \" +\r\n"
" \"service type.\");\r\n"
" }\r\n"
- " switch(method.getIndex()) {\r\n");
+ " switch(method.Index) {\r\n");
printer->Indent();
printer->Indent();
@@ -105,13 +98,13 @@ void ServiceGenerator::GenerateCallMethod(io::Printer* printer) {
const MethodDescriptor* method = descriptor_->method(i);
map<string, string> vars;
vars["index"] = SimpleItoa(i);
- vars["method"] = UnderscoresToCamelCase(method);
+ vars["method"] = UnderscoresToCapitalizedCamelCase(method);
vars["input"] = ClassName(method->input_type());
vars["output"] = ClassName(method->output_type());
printer->Print(vars,
"case $index$:\r\n"
" this.$method$(controller, ($input$)request,\r\n"
- " pb::RpcUtil.<$output$>specializeCallback(\r\n"
+ " pb::RpcUtil.SpecializeCallback<$output$>(\r\n"
" done));\r\n"
" return;\r\n");
}
@@ -132,10 +125,8 @@ void ServiceGenerator::GenerateCallMethod(io::Printer* printer) {
void ServiceGenerator::GenerateGetPrototype(RequestOrResponse which,
io::Printer* printer) {
printer->Print(
- "public final pb::Message\r\n"
- " Get$request_or_response$Prototype(\r\n"
- " pbd::MethodDescriptor method) {\r\n"
- " if (method.getService() != getDescriptor()) {\r\n"
+ "public pb::IMessage Get$request_or_response$Prototype(pbd::MethodDescriptor method) {\r\n"
+ " if (method.Service != Descriptor) {\r\n"
" throw new global::System.ArgumentException(\r\n"
" \"Service.Get$request_or_response$Prototype() given method \" +\r\n"
" \"descriptor for wrong service type.\");\r\n"
@@ -162,7 +153,6 @@ void ServiceGenerator::GenerateGetPrototype(RequestOrResponse which,
printer->Outdent();
printer->Outdent();
-
printer->Print(
" }\r\n"
"}\r\n"
@@ -171,48 +161,45 @@ void ServiceGenerator::GenerateGetPrototype(RequestOrResponse which,
void ServiceGenerator::GenerateStub(io::Printer* printer) {
printer->Print(
- "public static Stub newStub(\r\n"
- " pb::RpcChannel channel) {\r\n"
+ "public static Stub CreateStub(\r\n"
+ " pb::IRpcChannel channel) {\r\n"
" return new Stub(channel);\r\n"
"}\r\n"
"\r\n"
- "public static final class Stub extends $classname$ {\r\n",
+ "public class Stub : $classname$ {\r\n",
"classname", ClassName(descriptor_));
printer->Indent();
printer->Print(
- "private Stub(pb::RpcChannel channel) {\r\n"
+ "internal Stub(pb::IRpcChannel channel) {\r\n"
" this.channel = channel;\r\n"
"}\r\n"
"\r\n"
- "private final pb::RpcChannel channel;\r\n"
+ "private readonly pb::IRpcChannel channel;\r\n"
"\r\n"
- "public pb::RpcChannel getChannel() {\r\n"
- " return channel;\r\n"
+ "public pb::IRpcChannel Channel {\r\n"
+ " get { return channel; }\r\n"
"}\r\n");
for (int i = 0; i < descriptor_->method_count(); i++) {
const MethodDescriptor* method = descriptor_->method(i);
map<string, string> vars;
vars["index"] = SimpleItoa(i);
- vars["method"] = UnderscoresToCamelCase(method);
+ vars["method"] = UnderscoresToCapitalizedCamelCase(method);
vars["input"] = ClassName(method->input_type());
vars["output"] = ClassName(method->output_type());
printer->Print(vars,
"\r\n"
- "public void $method$(\r\n"
- " pb::RpcController controller,\r\n"
+ "public override void $method$(\r\n"
+ " pb::IRpcController controller,\r\n"
" $input$ request,\r\n"
- " pb::RpcCallback<$output$> done) {\r\n"
- " channel.callMethod(\r\n"
+ " global::System.Action<$output$> done) {\r\n"
+ " channel.CallMethod(\r\n"
" Descriptor.Methods[$index$],\r\n"
" controller,\r\n"
" request,\r\n"
" $output$.DefaultInstance,\r\n"
- " pb::RpcUtil.generalizeCallback(\r\n"
- " done,\r\n"
- " typeof ($output$),\r\n"
- " $output$.DefaultInstance));\r\n"
+ " pb::RpcUtil.GeneralizeCallback(done, $output$.DefaultInstance));\r\n"
"}\r\n");
}
diff --git a/src/google/protobuf/unittest.proto b/src/google/protobuf/unittest.proto
index f65c4318..a37fd402 100644
--- a/src/google/protobuf/unittest.proto
+++ b/src/google/protobuf/unittest.proto
@@ -20,6 +20,8 @@
//
// A proto file we will use for unit testing.
+option csharp_namespace = "Google.ProtocolBuffers.TestProtos";
+option csharp_file_classname = "UnitTestProtoFile";
import "google/protobuf/unittest_import.proto";
diff --git a/src/google/protobuf/unittest_embed_optimize_for.proto b/src/google/protobuf/unittest_embed_optimize_for.proto
index c600d9fc..f2b9d815 100644
--- a/src/google/protobuf/unittest_embed_optimize_for.proto
+++ b/src/google/protobuf/unittest_embed_optimize_for.proto
@@ -24,6 +24,9 @@ import "google/protobuf/unittest_optimize_for.proto";
package protobuf_unittest;
+option csharp_namespace = "Google.ProtocolBuffers.TestProtos";
+option csharp_file_classname = "UnitTestEmbedOptimizeForProtoFile";
+
// We optimize for speed here, but we are importing a proto that is optimized
// for code size.
option optimize_for = SPEED;
diff --git a/src/google/protobuf/unittest_import.proto b/src/google/protobuf/unittest_import.proto
index 58ce42c3..64495c78 100644
--- a/src/google/protobuf/unittest_import.proto
+++ b/src/google/protobuf/unittest_import.proto
@@ -29,9 +29,12 @@ package protobuf_unittest_import;
option optimize_for = SPEED;
-// Excercise the java_package option.
+// Exercise the java_package option.
option java_package = "com.google.protobuf.test";
+option csharp_namespace = "Google.ProtocolBuffers.TestProtos";
+option csharp_file_classname = "UnitTestImportProtoFile";
+
// Do not set a java_outer_classname here to verify that Proto2 works without
// one.
diff --git a/src/google/protobuf/unittest_mset.proto b/src/google/protobuf/unittest_mset.proto
index 455086d2..4d0b3b1e 100644
--- a/src/google/protobuf/unittest_mset.proto
+++ b/src/google/protobuf/unittest_mset.proto
@@ -24,6 +24,9 @@ package protobuf_unittest;
option optimize_for = SPEED;
+option csharp_namespace = "Google.ProtocolBuffers.TestProtos";
+option csharp_file_classname = "UnitTestMessageSetProtoFile";
+
// A message with message_set_wire_format.
message TestMessageSet {
option message_set_wire_format = true;
diff --git a/src/google/protobuf/unittest_optimize_for.proto b/src/google/protobuf/unittest_optimize_for.proto
index 6154e9c5..660eeda8 100644
--- a/src/google/protobuf/unittest_optimize_for.proto
+++ b/src/google/protobuf/unittest_optimize_for.proto
@@ -26,6 +26,9 @@ package protobuf_unittest;
option optimize_for = CODE_SIZE;
+option csharp_namespace = "Google.ProtocolBuffers.TestProtos";
+option csharp_file_classname = "UnitTestOptimizeForProtoFile";
+
message TestOptimizedForSize {
optional int32 i = 1;
optional ForeignMessage msg = 19;