diff --git a/cmake/libprotoc.cmake b/cmake/libprotoc.cmake index 7aa92ee192..35e5faf20f 100644 --- a/cmake/libprotoc.cmake +++ b/cmake/libprotoc.cmake @@ -14,6 +14,7 @@ set(libprotoc_files ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_service.cc ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_string_field.cc + ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_doc_comment.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_enum.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_enum_field.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_field_base.cc diff --git a/src/Makefile.am b/src/Makefile.am index caae2933e4..2985b5d812 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -434,6 +434,8 @@ libprotoc_la_SOURCES = \ google/protobuf/compiler/objectivec/objectivec_primitive_field.h \ google/protobuf/compiler/python/python_generator.cc \ google/protobuf/compiler/ruby/ruby_generator.cc \ + google/protobuf/compiler/csharp/csharp_doc_comment.cc \ + google/protobuf/compiler/csharp/csharp_doc_comment.h \ google/protobuf/compiler/csharp/csharp_enum.cc \ google/protobuf/compiler/csharp/csharp_enum.h \ google/protobuf/compiler/csharp/csharp_enum_field.cc \ diff --git a/src/google/protobuf/compiler/csharp/csharp_doc_comment.cc b/src/google/protobuf/compiler/csharp/csharp_doc_comment.cc new file mode 100644 index 0000000000..9ad2cbb507 --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_doc_comment.cc @@ -0,0 +1,98 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +// Functions to create C# XML documentation comments. +// Currently this only includes documentation comments containing text specified as comments +// in the .proto file; documentation comments generated just from field/message/enum/proto names +// is inlined in the relevant code. If more control is required, that code can be moved here. + +void WriteDocCommentBodyImpl(io::Printer* printer, SourceLocation location) { + string comments = location.leading_comments.empty() ? + location.trailing_comments : location.leading_comments; + if (comments.empty()) { + return; + } + // XML escaping... no need for apostrophes etc as the whole text is going to be a child + // node of a summary element, not part of an attribute. + comments = StringReplace(comments, "&", "&", true); + comments = StringReplace(comments, "<", "<", true); + vector lines = Split(comments, "\n"); + printer->Print("/// \n"); + for (std::vector::iterator it = lines.begin(); it != lines.end(); ++it) { + printer->Print("/// $line$\n", "line", *it); + } + printer->Print("/// \n"); +} + +template +static void WriteDocCommentBody( + io::Printer* printer, const DescriptorType* descriptor) { + SourceLocation location; + if (descriptor->GetSourceLocation(&location)) { + WriteDocCommentBodyImpl(printer, location); + } +} + +void WriteMessageDocComment(io::Printer* printer, const Descriptor* message) { + WriteDocCommentBody(printer, message); +} + +void WritePropertyDocComment(io::Printer* printer, const FieldDescriptor* field) { + WriteDocCommentBody(printer, field); +} + +void WriteEnumDocComment(io::Printer* printer, const EnumDescriptor* enumDescriptor) { + WriteDocCommentBody(printer, enumDescriptor); +} +void WriteEnumValueDocComment(io::Printer* printer, const EnumValueDescriptor* value) { + WriteDocCommentBody(printer, value); +} + +void WriteMethodDocComment(io::Printer* printer, const MethodDescriptor* method) { + WriteDocCommentBody(printer, method); +} + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_doc_comment.h b/src/google/protobuf/compiler/csharp/csharp_doc_comment.h new file mode 100644 index 0000000000..75eb0ea04d --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_doc_comment.h @@ -0,0 +1,51 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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. + + +#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_DOC_COMMENT_H__ +#define GOOGLE_PROTOBUF_COMPILER_CSHARP_DOC_COMMENT_H__ + +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + void WriteMessageDocComment(io::Printer* printer, const Descriptor* message); + void WritePropertyDocComment(io::Printer* printer, const FieldDescriptor* field); + void WriteEnumDocComment(io::Printer* printer, const EnumDescriptor* enumDescriptor); + void WriteEnumValueDocComment(io::Printer* printer, const EnumValueDescriptor* value); + void WriteMethodDocComment(io::Printer* printer, const MethodDescriptor* method); +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_DOC_COMMENT_H__ diff --git a/src/google/protobuf/compiler/csharp/csharp_enum.cc b/src/google/protobuf/compiler/csharp/csharp_enum.cc index 0e8f983696..566819898b 100644 --- a/src/google/protobuf/compiler/csharp/csharp_enum.cc +++ b/src/google/protobuf/compiler/csharp/csharp_enum.cc @@ -38,6 +38,7 @@ #include #include +#include #include #include @@ -57,13 +58,15 @@ EnumGenerator::~EnumGenerator() { } void EnumGenerator::Generate(io::Printer* printer) { + WriteEnumDocComment(printer, descriptor_); WriteGeneratedCodeAttributes(printer); printer->Print("$access_level$ enum $name$ {\n", "access_level", class_access_level(), "name", descriptor_->name()); printer->Indent(); for (int i = 0; i < descriptor_->value_count(); i++) { - printer->Print("$name$ = $number$,\n", + WriteEnumValueDocComment(printer, descriptor_->value(i)); + printer->Print("$name$ = $number$,\n", "name", descriptor_->value(i)->name(), "number", SimpleItoa(descriptor_->value(i)->number())); } diff --git a/src/google/protobuf/compiler/csharp/csharp_map_field.cc b/src/google/protobuf/compiler/csharp/csharp_map_field.cc index f84ad6f7ac..b493495da7 100644 --- a/src/google/protobuf/compiler/csharp/csharp_map_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_map_field.cc @@ -38,6 +38,7 @@ #include #include +#include #include #include @@ -76,6 +77,7 @@ void MapFieldGenerator::GenerateMembers(io::Printer* printer) { variables_, ", $tag$);\n" "private readonly pbc::MapField<$key_type_name$, $value_type_name$> $name$_ = new pbc::MapField<$key_type_name$, $value_type_name$>($true_for_wrappers$);\n"); + WritePropertyDocComment(printer, descriptor_); AddDeprecatedFlag(printer); printer->Print( variables_, diff --git a/src/google/protobuf/compiler/csharp/csharp_message.cc b/src/google/protobuf/compiler/csharp/csharp_message.cc index 16f7b0af61..21fbf7e3d2 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message.cc +++ b/src/google/protobuf/compiler/csharp/csharp_message.cc @@ -42,6 +42,7 @@ #include #include +#include #include #include #include @@ -101,6 +102,7 @@ void MessageGenerator::Generate(io::Printer* printer) { vars["class_name"] = class_name(); vars["access_level"] = class_access_level(); + WriteMessageDocComment(printer, descriptor_); printer->Print( "[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n"); WriteGeneratedCodeAttributes(printer); @@ -152,7 +154,9 @@ void MessageGenerator::Generate(io::Printer* printer) { // Rats: we lose the debug comment here :( printer->Print( + "/// Field number for the \"$field_name$\" field.\n" "public const int $field_constant_name$ = $index$;\n", + "field_name", fieldDescriptor->name(), "field_constant_name", GetFieldConstantName(fieldDescriptor), "index", SimpleItoa(fieldDescriptor->number())); scoped_ptr generator( @@ -181,6 +185,7 @@ void MessageGenerator::Generate(io::Printer* printer) { } printer->Outdent(); printer->Print("}\n"); + // TODO: Should we put the oneof .proto comments here? It's unclear exactly where they should go. printer->Print( vars, "private $property_name$OneofCase $name$Case_ = $property_name$OneofCase.None;\n" diff --git a/src/google/protobuf/compiler/csharp/csharp_message_field.cc b/src/google/protobuf/compiler/csharp/csharp_message_field.cc index 4f576cd1f6..f81f769b29 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_message_field.cc @@ -38,6 +38,7 @@ #include #include +#include #include #include @@ -61,6 +62,7 @@ void MessageFieldGenerator::GenerateMembers(io::Printer* printer) { printer->Print( variables_, "private $type_name$ $name$_;\n"); + WritePropertyDocComment(printer, descriptor_); AddDeprecatedFlag(printer); printer->Print( variables_, @@ -152,6 +154,7 @@ MessageOneofFieldGenerator::~MessageOneofFieldGenerator() { } void MessageOneofFieldGenerator::GenerateMembers(io::Printer* printer) { + WritePropertyDocComment(printer, descriptor_); AddDeprecatedFlag(printer); printer->Print( variables_, diff --git a/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc index fc043ec06c..76d5b2479b 100644 --- a/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc @@ -38,6 +38,7 @@ #include #include +#include #include #include @@ -68,6 +69,7 @@ void PrimitiveFieldGenerator::GenerateMembers(io::Printer* printer) { printer->Print( variables_, "private $type_name$ $name_def_message$;\n"); + WritePropertyDocComment(printer, descriptor_); AddDeprecatedFlag(printer); printer->Print( variables_, @@ -170,6 +172,7 @@ PrimitiveOneofFieldGenerator::~PrimitiveOneofFieldGenerator() { } void PrimitiveOneofFieldGenerator::GenerateMembers(io::Printer* printer) { + WritePropertyDocComment(printer, descriptor_); AddDeprecatedFlag(printer); printer->Print( variables_, diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc index 625631dfc8..3a11b75d1b 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc @@ -38,6 +38,7 @@ #include #include +#include #include #include @@ -62,6 +63,7 @@ void RepeatedEnumFieldGenerator::GenerateMembers(io::Printer* printer) { " = pb::FieldCodec.ForEnum($tag$, x => (int) x, x => ($type_name$) x);\n"); printer->Print(variables_, "private readonly pbc::RepeatedField<$type_name$> $name$_ = new pbc::RepeatedField<$type_name$>();\n"); + WritePropertyDocComment(printer, descriptor_); AddDeprecatedFlag(printer); printer->Print( variables_, diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc index 7fbab681fb..fc12faed80 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc @@ -37,6 +37,7 @@ #include #include +#include #include #include #include @@ -75,6 +76,7 @@ void RepeatedMessageFieldGenerator::GenerateMembers(io::Printer* printer) { printer->Print( variables_, "private readonly pbc::RepeatedField<$type_name$> $name$_ = new pbc::RepeatedField<$type_name$>();\n"); + WritePropertyDocComment(printer, descriptor_); AddDeprecatedFlag(printer); printer->Print( variables_, diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc index 1163ce73d4..5fe0b203de 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc @@ -38,6 +38,7 @@ #include #include +#include #include #include @@ -62,6 +63,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateMembers(io::Printer* printer) { " = pb::FieldCodec.For$capitalized_type_name$($tag$);\n"); printer->Print(variables_, "private readonly pbc::RepeatedField<$type_name$> $name$_ = new pbc::RepeatedField<$type_name$>();\n"); + WritePropertyDocComment(printer, descriptor_); AddDeprecatedFlag(printer); printer->Print( variables_, diff --git a/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc b/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc index 44f832bfca..6a3750e003 100644 --- a/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc @@ -37,6 +37,7 @@ #include #include +#include #include #include @@ -70,6 +71,7 @@ void WrapperFieldGenerator::GenerateMembers(io::Printer* printer) { variables_, ";\n" "private $type_name$ $name$_;\n"); + WritePropertyDocComment(printer, descriptor_); AddDeprecatedFlag(printer); printer->Print( variables_, @@ -165,6 +167,7 @@ void WrapperOneofFieldGenerator::GenerateMembers(io::Printer* printer) { "private static readonly pb::FieldCodec<$type_name$> _oneof_$name$_codec = "); GenerateCodecCode(printer); printer->Print(";\n"); + WritePropertyDocComment(printer, descriptor_); AddDeprecatedFlag(printer); printer->Print( variables_,