diff options
author | Jon Skeet <jonskeet@google.com> | 2015-07-22 11:38:22 +0100 |
---|---|---|
committer | Jon Skeet <jonskeet@google.com> | 2015-07-22 11:38:22 +0100 |
commit | 4668c3dc3921e157b7904e26a1ddd84287b881be (patch) | |
tree | 755b120ba988871c074454bc6b2a829d86fdd1e7 /src | |
parent | 8d115298c7fc6fec135515ff7ddacb7f1524149e (diff) | |
download | protobuf-4668c3dc3921e157b7904e26a1ddd84287b881be.tar.gz protobuf-4668c3dc3921e157b7904e26a1ddd84287b881be.tar.bz2 protobuf-4668c3dc3921e157b7904e26a1ddd84287b881be.zip |
Remove the usage of attributes for field/method discovery.
Instead, introduce GeneratedCodeInfo which passes in what we need, and adjust the codegen to take account of this.
Diffstat (limited to 'src')
12 files changed, 96 insertions, 50 deletions
diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.cc b/src/google/protobuf/compiler/csharp/csharp_field_base.cc index d327e267..2459d457 100644 --- a/src/google/protobuf/compiler/csharp/csharp_field_base.cc +++ b/src/google/protobuf/compiler/csharp/csharp_field_base.cc @@ -74,7 +74,6 @@ void FieldGeneratorBase::SetCommonFieldVariables( (*variables)["property_name"] = property_name(); (*variables)["type_name"] = type_name(); - (*variables)["original_name"] = descriptor_->name(); (*variables)["name"] = name(); (*variables)["descriptor_name"] = descriptor_->name(); (*variables)["default_value"] = default_value(); @@ -431,10 +430,6 @@ std::string FieldGeneratorBase::capitalized_type_name() { } } -std::string FieldGeneratorBase::field_ordinal() { - return SimpleItoa(fieldOrdinal_); -} - } // namespace csharp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.h b/src/google/protobuf/compiler/csharp/csharp_field_base.h index 4761dc49..d83543bd 100644 --- a/src/google/protobuf/compiler/csharp/csharp_field_base.h +++ b/src/google/protobuf/compiler/csharp/csharp_field_base.h @@ -85,7 +85,6 @@ class FieldGeneratorBase : public SourceGeneratorBase { std::string default_value(const FieldDescriptor* descriptor); std::string number(); std::string capitalized_type_name(); - std::string field_ordinal(); private: void SetCommonFieldVariables(map<string, string>* variables); diff --git a/src/google/protobuf/compiler/csharp/csharp_map_field.cc b/src/google/protobuf/compiler/csharp/csharp_map_field.cc index bdbfd92b..cba24a59 100644 --- a/src/google/protobuf/compiler/csharp/csharp_map_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_map_field.cc @@ -79,7 +79,6 @@ void MapFieldGenerator::GenerateMembers(io::Printer* printer) { AddDeprecatedFlag(printer); printer->Print( variables_, - "[pbr::ProtobufField($number$, \"$original_name$\")]\n" "$access_level$ pbc::MapField<$key_type_name$, $value_type_name$> $property_name$ {\n" " get { return $name$_; }\n" "}\n"); diff --git a/src/google/protobuf/compiler/csharp/csharp_message.cc b/src/google/protobuf/compiler/csharp/csharp_message.cc index 42fd5065..6a22a336 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message.cc +++ b/src/google/protobuf/compiler/csharp/csharp_message.cc @@ -115,19 +115,6 @@ void MessageGenerator::Generate(io::Printer* printer) { vars, "private static readonly pb::MessageParser<$class_name$> _parser = new pb::MessageParser<$class_name$>(() => new $class_name$());\n" "public static pb::MessageParser<$class_name$> Parser { get { return _parser; } }\n\n"); - printer->Print( - "private static readonly string[] _fieldNames = " - "new string[] { $slash$$field_names$$slash$ };\n", - "field_names", JoinStrings(field_names(), "\", \""), - "slash", field_names().size() > 0 ? "\"" : ""); - std::vector<std::string> tags; - for (int i = 0; i < field_names().size(); i++) { - uint32 tag = FixedMakeTag(descriptor_->FindFieldByName(field_names()[i])); - tags.push_back(SimpleItoa(tag)); - } - printer->Print( - "private static readonly uint[] _fieldTags = new uint[] { $tags$ };\n", - "tags", JoinStrings(tags, ", ")); // Access the message descriptor via the relevant file descriptor or containing message descriptor. if (!descriptor_->containing_type()) { diff --git a/src/google/protobuf/compiler/csharp/csharp_message_field.cc b/src/google/protobuf/compiler/csharp/csharp_message_field.cc index c2b6ff76..d2c3a88b 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_message_field.cc @@ -64,7 +64,6 @@ void MessageFieldGenerator::GenerateMembers(io::Printer* printer) { AddDeprecatedFlag(printer); printer->Print( variables_, - "[pbr::ProtobufField($number$, \"$original_name$\")]\n" "$access_level$ $type_name$ $property_name$ {\n" " get { return $name$_; }\n" " set {\n" @@ -159,7 +158,6 @@ void MessageOneofFieldGenerator::GenerateMembers(io::Printer* printer) { AddDeprecatedFlag(printer); printer->Print( variables_, - "[pbr::ProtobufField($number$, \"$original_name$\")]\n" "$access_level$ $type_name$ $property_name$ {\n" " get { return $has_property_check$ ? ($type_name$) $oneof_name$_ : null; }\n" " set {\n" diff --git a/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc index 2c9338bd..4454ef02 100644 --- a/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc @@ -71,7 +71,6 @@ void PrimitiveFieldGenerator::GenerateMembers(io::Printer* printer) { AddDeprecatedFlag(printer); printer->Print( variables_, - "[pbr::ProtobufField($number$, \"$original_name$\")]\n" "$access_level$ $type_name$ $property_name$ {\n" " get { return $name$_; }\n" " set {\n" @@ -175,7 +174,6 @@ void PrimitiveOneofFieldGenerator::GenerateMembers(io::Printer* printer) { AddDeprecatedFlag(printer); printer->Print( variables_, - "[pbr::ProtobufField($number$, \"$original_name$\")]\n" "$access_level$ $type_name$ $property_name$ {\n" " get { return $has_property_check$ ? ($type_name$) $oneof_name$_ : $default_value$; }\n" " set {\n" 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 60d06154..c1b29e2b 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc @@ -65,7 +65,6 @@ void RepeatedEnumFieldGenerator::GenerateMembers(io::Printer* printer) { AddDeprecatedFlag(printer); printer->Print( variables_, - "[pbr::ProtobufField($number$, \"$original_name$\")]\n" "$access_level$ pbc::RepeatedField<$type_name$> $property_name$ {\n" " get { return $name$_; }\n" "}\n"); 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 921798b0..d939fc79 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc @@ -78,7 +78,6 @@ void RepeatedMessageFieldGenerator::GenerateMembers(io::Printer* printer) { AddDeprecatedFlag(printer); printer->Print( variables_, - "[pbr::ProtobufField($number$, \"$original_name$\")]\n" "$access_level$ pbc::RepeatedField<$type_name$> $property_name$ {\n" " get { return $name$_; }\n" "}\n"); 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 bcfb9936..5b5d9b3d 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc @@ -65,7 +65,6 @@ void RepeatedPrimitiveFieldGenerator::GenerateMembers(io::Printer* printer) { AddDeprecatedFlag(printer); printer->Print( variables_, - "[pbr::ProtobufField($number$, \"$original_name$\")]\n" "$access_level$ pbc::RepeatedField<$type_name$> $property_name$ {\n" " get { return $name$_; }\n" "}\n"); diff --git a/src/google/protobuf/compiler/csharp/csharp_umbrella_class.cc b/src/google/protobuf/compiler/csharp/csharp_umbrella_class.cc index 3f39250e..6eb1547e 100644 --- a/src/google/protobuf/compiler/csharp/csharp_umbrella_class.cc +++ b/src/google/protobuf/compiler/csharp/csharp_umbrella_class.cc @@ -36,6 +36,7 @@ #include <google/protobuf/descriptor.pb.h> #include <google/protobuf/io/printer.h> #include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/compiler/csharp/csharp_enum.h> @@ -168,10 +169,10 @@ void UmbrellaClassGenerator::WriteDescriptor(io::Printer* printer) { printer->Print("\"$base64$\", \n", "base64", base64.substr(0, 60)); base64 = base64.substr(60); } - printer->Outdent(); printer->Print("\"$base64$\"));\n", "base64", base64); printer->Outdent(); printer->Outdent(); + printer->Outdent(); // ----------------------------------------------------------------- // Invoke InternalBuildGeneratedFileFrom() to build the file. @@ -184,34 +185,108 @@ void UmbrellaClassGenerator::WriteDescriptor(io::Printer* printer) { "full_umbrella_class_name", GetFullUmbrellaClassName(file_->dependency(i))); } - // Specify all the generated types (messages and enums), recursively, as an array. printer->Print("},\n" - " new global::System.Type[] { "); - for (int i = 0; i < file_->message_type_count(); i++) { - WriteTypeLiterals(file_->message_type(i), printer); + " new pbr::GeneratedCodeInfo("); + // Specify all the generated code information, recursively. + if (file_->enum_type_count() > 0) { + printer->Print("new[] {"); + for (int i = 0; i < file_->enum_type_count(); i++) { + printer->Print("typeof($type_name$), ", "type_name", GetClassName(file_->enum_type(i))); + } + printer->Print("}, "); + } + else { + printer->Print("null, "); + } + if (file_->message_type_count() > 0) { + printer->Print("new pbr::GeneratedCodeInfo[] {\n"); + printer->Indent(); + printer->Indent(); + printer->Indent(); + for (int i = 0; i < file_->message_type_count(); i++) { + WriteGeneratedCodeInfo(file_->message_type(i), printer, i == file_->message_type_count() - 1); + } + printer->Outdent(); + printer->Print("\n}));\n"); + printer->Outdent(); + printer->Outdent(); } - for (int i = 0; i < file_->enum_type_count(); i++) { - printer->Print("typeof($type_name$), ", "type_name", GetClassName(file_->enum_type(i))); + else { + printer->Print("null));\n"); } - printer->Print("});\n"); printer->Outdent(); printer->Print("}\n"); printer->Print("#endregion\n\n"); } -void UmbrellaClassGenerator::WriteTypeLiterals(const Descriptor* descriptor, io::Printer* printer) { - if (IsMapEntryMessage(descriptor)) { - printer->Print("null, "); - return; - } - printer->Print("typeof($type_name$), ", "type_name", GetClassName(descriptor)); - for (int i = 0; i < descriptor->nested_type_count(); i++) { - WriteTypeLiterals(descriptor->nested_type(i), printer); - } - for (int i = 0; i < descriptor->enum_type_count(); i++) { - printer->Print("typeof($type_name$), ", "type_name", GetClassName(descriptor->enum_type(i))); - } +// Write out the generated code for a particular message. This consists of the CLR type, property names +// corresponding to fields, names corresponding to oneofs, nested enums, and nested types. Each array part +// can be specified as null if it would be empty, to make the generated code somewhat simpler to read. +// We write a line break at the end of each generated code info, so that in the final file we'll see all +// the types, pre-ordered depth first, one per line. The indentation will be slightly unusual, +// in that it will look like a single array when it's actually constructing a tree, but it'll be easy to +// read even with multiple levels of nesting. +// The "last" parameter indicates whether this message descriptor is the last one being printed in this immediate +// context. It governs whether or not a trailing comma and newline is written after the constructor, effectively +// just controlling the formatting in the generated code. +void UmbrellaClassGenerator::WriteGeneratedCodeInfo(const Descriptor* descriptor, io::Printer* printer, bool last) { + if (IsMapEntryMessage(descriptor)) { + printer->Print("null, "); + return; + } + // Generated message type + printer->Print("new pbr::GeneratedCodeInfo(typeof($type_name$), ", "type_name", GetClassName(descriptor)); + + // Fields + if (descriptor->field_count() > 0) { + std::vector<std::string> fields; + for (int i = 0; i < descriptor->field_count(); i++) { + fields.push_back(GetPropertyName(descriptor->field(i))); + } + printer->Print("new[]{ \"$fields$\" }, ", "fields", JoinStrings(fields, "\", \"")); + } + else { + printer->Print("null, "); + } + + // Oneofs + if (descriptor->oneof_decl_count() > 0) { + std::vector<std::string> oneofs; + for (int i = 0; i < descriptor->oneof_decl_count(); i++) { + oneofs.push_back(UnderscoresToCamelCase(descriptor->oneof_decl(i)->name(), true)); + } + printer->Print("new[]{ \"$oneofs$\" }, ", "oneofs", JoinStrings(oneofs, "\", \"")); + } + else { + printer->Print("null, "); + } + + // Nested enums + if (descriptor->enum_type_count() > 0) { + std::vector<std::string> enums; + for (int i = 0; i < descriptor->enum_type_count(); i++) { + enums.push_back(GetClassName(descriptor->enum_type(i))); + } + printer->Print("new[]{ typeof($enums$) }, ", "enums", JoinStrings(enums, "), typeof(")); + } + else { + printer->Print("null, "); + } + + // Nested types + if (descriptor->nested_type_count() > 0) { + // Need to specify array type explicitly here, as all elements may be null. + printer->Print("new pbr::GeneratedCodeInfo[] { "); + for (int i = 0; i < descriptor->nested_type_count(); i++) { + WriteGeneratedCodeInfo(descriptor->nested_type(i), printer, i == descriptor->nested_type_count() - 1); + } + printer->Print("}"); + } + else { + printer->Print("null"); + } + printer->Print(last ? ")" : "),\n"); } } // namespace csharp diff --git a/src/google/protobuf/compiler/csharp/csharp_umbrella_class.h b/src/google/protobuf/compiler/csharp/csharp_umbrella_class.h index db1092a9..b8bd2133 100644 --- a/src/google/protobuf/compiler/csharp/csharp_umbrella_class.h +++ b/src/google/protobuf/compiler/csharp/csharp_umbrella_class.h @@ -57,7 +57,7 @@ class UmbrellaClassGenerator : public SourceGeneratorBase { void WriteIntroduction(io::Printer* printer); void WriteDescriptor(io::Printer* printer); - void WriteTypeLiterals(const Descriptor* descriptor, io::Printer* printer); + void WriteGeneratedCodeInfo(const Descriptor* descriptor, io::Printer* printer, bool last); GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UmbrellaClassGenerator); }; diff --git a/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc b/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc index d6cd0a10..75ef5e50 100644 --- a/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc @@ -73,7 +73,6 @@ void WrapperFieldGenerator::GenerateMembers(io::Printer* printer) { AddDeprecatedFlag(printer); printer->Print( variables_, - "[pbr::ProtobufField($number$, \"$original_name$\")]\n" "$access_level$ $type_name$ $property_name$ {\n" " get { return $name$_; }\n" " set {\n" @@ -170,7 +169,6 @@ void WrapperOneofFieldGenerator::GenerateMembers(io::Printer* printer) { AddDeprecatedFlag(printer); printer->Print( variables_, - "[pbr::ProtobufField($number$, \"$original_name$\")]\n" "$access_level$ $type_name$ $property_name$ {\n" " get { return $has_property_check$ ? ($type_name$) $oneof_name$_ : ($type_name$) null; }\n" " set {\n" |