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/google | |
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/google')
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" |