diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/google/protobuf/compiler/csharp/csharp_helpers.h | 16 | ||||
-rw-r--r-- | src/google/protobuf/compiler/csharp/csharp_message.cc | 22 |
2 files changed, 34 insertions, 4 deletions
diff --git a/src/google/protobuf/compiler/csharp/csharp_helpers.h b/src/google/protobuf/compiler/csharp/csharp_helpers.h index 1563ca7e..c317ad0e 100644 --- a/src/google/protobuf/compiler/csharp/csharp_helpers.h +++ b/src/google/protobuf/compiler/csharp/csharp_helpers.h @@ -120,6 +120,22 @@ inline bool IsDescriptorProto(const FileDescriptor* descriptor) { return descriptor->name() == "google/protobuf/descriptor.proto"; } +// Determines whether the given message is an options message within descriptor.proto. +inline bool IsDescriptorOptionMessage(const Descriptor* descriptor) { + if (!IsDescriptorProto(descriptor->file())) { + return false; + } + const string name = descriptor->full_name(); + return name == "google.protobuf.FileOptions" || + name == "google.protobuf.MessageOptions" || + name == "google.protobuf.FieldOptions" || + name == "google.protobuf.OneofOptions" || + name == "google.protobuf.EnumOptions" || + name == "google.protobuf.EnumValueOptions" || + name == "google.protobuf.ServiceOptions" || + name == "google.protobuf.MethodOptions"; +} + inline bool IsWrapperType(const FieldDescriptor* descriptor) { return descriptor->type() == FieldDescriptor::TYPE_MESSAGE && descriptor->message_type()->file()->name() == "google/protobuf/wrappers.proto"; diff --git a/src/google/protobuf/compiler/csharp/csharp_message.cc b/src/google/protobuf/compiler/csharp/csharp_message.cc index b0cc6694..0f00a438 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message.cc +++ b/src/google/protobuf/compiler/csharp/csharp_message.cc @@ -151,6 +151,12 @@ void MessageGenerator::Generate(io::Printer* printer) { " get { return Descriptor; }\n" "}\n" "\n"); + // CustomOptions property, only for options messages + if (IsDescriptorOptionMessage(descriptor_)) { + printer->Print( + "internal CustomOptions CustomOptions{ get; private set; } = CustomOptions.Empty;\n" + "\n"); + } // Parameterless constructor and partial OnConstruction method. WriteGeneratedCodeAttributes(printer); @@ -475,10 +481,18 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) { " switch(tag) {\n"); printer->Indent(); printer->Indent(); - printer->Print( - "default:\n" - " input.SkipLastField();\n" // We're not storing the data, but we still need to consume it. - " break;\n"); + // Option messages need to store unknown fields so that options can be parsed later. + if (IsDescriptorOptionMessage(descriptor_)) { + printer->Print( + "default:\n" + " CustomOptions = CustomOptions.ReadOrSkipUnknownField(input);\n" + " break;\n"); + } else { + printer->Print( + "default:\n" + " input.SkipLastField();\n" // We're not storing the data, but we still need to consume it. + " break;\n"); + } for (int i = 0; i < fields_by_number().size(); i++) { const FieldDescriptor* field = fields_by_number()[i]; internal::WireFormatLite::WireType wt = |