• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2015 Google Inc.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 #include "google/protobuf/compiler/csharp/csharp_map_field.h"
9 
10 #include <sstream>
11 
12 #include "google/protobuf/compiler/code_generator.h"
13 #include "google/protobuf/descriptor.h"
14 #include "google/protobuf/compiler/csharp/csharp_doc_comment.h"
15 #include "google/protobuf/compiler/csharp/csharp_helpers.h"
16 #include "google/protobuf/descriptor.pb.h"
17 #include "google/protobuf/io/printer.h"
18 
19 namespace google {
20 namespace protobuf {
21 namespace compiler {
22 namespace csharp {
23 
MapFieldGenerator(const FieldDescriptor * descriptor,int presenceIndex,const Options * options)24 MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor,
25                                      int presenceIndex,
26                                      const Options* options)
27     : FieldGeneratorBase(descriptor, presenceIndex, options) {
28 }
29 
~MapFieldGenerator()30 MapFieldGenerator::~MapFieldGenerator() {
31 }
32 
GenerateMembers(io::Printer * printer)33 void MapFieldGenerator::GenerateMembers(io::Printer* printer) {
34   const FieldDescriptor* key_descriptor =
35       descriptor_->message_type()->map_key();
36   const FieldDescriptor* value_descriptor =
37       descriptor_->message_type()->map_value();
38   variables_["key_type_name"] = type_name(key_descriptor);
39   variables_["value_type_name"] = type_name(value_descriptor);
40   std::unique_ptr<FieldGeneratorBase> key_generator(
41       CreateFieldGenerator(key_descriptor, 1, this->options()));
42   std::unique_ptr<FieldGeneratorBase> value_generator(
43       CreateFieldGenerator(value_descriptor, 2, this->options()));
44 
45   printer->Print(
46     variables_,
47     "private static readonly pbc::MapField<$key_type_name$, $value_type_name$>.Codec _map_$name$_codec\n"
48     "    = new pbc::MapField<$key_type_name$, $value_type_name$>.Codec(");
49   key_generator->GenerateCodecCode(printer);
50   printer->Print(", ");
51   value_generator->GenerateCodecCode(printer);
52   printer->Print(
53     variables_,
54     ", $tag$);\n"
55     "private readonly pbc::MapField<$key_type_name$, $value_type_name$> $name$_ = new pbc::MapField<$key_type_name$, $value_type_name$>();\n");
56   WritePropertyDocComment(printer, options(), descriptor_);
57   AddPublicMemberAttributes(printer);
58   printer->Print(
59     variables_,
60     "$access_level$ pbc::MapField<$key_type_name$, $value_type_name$> $property_name$ {\n"
61     "  get { return $name$_; }\n"
62     "}\n");
63 }
64 
GenerateMergingCode(io::Printer * printer)65 void MapFieldGenerator::GenerateMergingCode(io::Printer* printer) {
66   printer->Print(variables_,
67                  "$name$_.MergeFrom(other.$name$_);\n");
68 }
69 
GenerateParsingCode(io::Printer * printer)70 void MapFieldGenerator::GenerateParsingCode(io::Printer* printer) {
71   GenerateParsingCode(printer, true);
72 }
73 
GenerateParsingCode(io::Printer * printer,bool use_parse_context)74 void MapFieldGenerator::GenerateParsingCode(io::Printer* printer, bool use_parse_context) {
75   printer->Print(
76     variables_,
77     use_parse_context
78     ? "$name$_.AddEntriesFrom(ref input, _map_$name$_codec);\n"
79     : "$name$_.AddEntriesFrom(input, _map_$name$_codec);\n");
80 }
81 
GenerateSerializationCode(io::Printer * printer)82 void MapFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
83   GenerateSerializationCode(printer, true);
84 }
85 
GenerateSerializationCode(io::Printer * printer,bool use_write_context)86 void MapFieldGenerator::GenerateSerializationCode(io::Printer* printer, bool use_write_context) {
87   printer->Print(
88     variables_,
89     use_write_context
90     ? "$name$_.WriteTo(ref output, _map_$name$_codec);\n"
91     : "$name$_.WriteTo(output, _map_$name$_codec);\n");
92 }
93 
GenerateSerializedSizeCode(io::Printer * printer)94 void MapFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
95   printer->Print(
96     variables_,
97     "size += $name$_.CalculateSize(_map_$name$_codec);\n");
98 }
99 
WriteHash(io::Printer * printer)100 void MapFieldGenerator::WriteHash(io::Printer* printer) {
101   printer->Print(
102     variables_,
103     "hash ^= $property_name$.GetHashCode();\n");
104 }
WriteEquals(io::Printer * printer)105 void MapFieldGenerator::WriteEquals(io::Printer* printer) {
106   printer->Print(
107     variables_,
108     "if (!$property_name$.Equals(other.$property_name$)) return false;\n");
109 }
110 
WriteToString(io::Printer * printer)111 void MapFieldGenerator::WriteToString(io::Printer* printer) {
112     // TODO: If we ever actually use ToString, we'll need to impleme this...
113 }
114 
GenerateCloningCode(io::Printer * printer)115 void MapFieldGenerator::GenerateCloningCode(io::Printer* printer) {
116   printer->Print(variables_,
117     "$name$_ = other.$name$_.Clone();\n");
118 }
119 
GenerateFreezingCode(io::Printer * printer)120 void MapFieldGenerator::GenerateFreezingCode(io::Printer* printer) {
121 }
122 
123 }  // namespace csharp
124 }  // namespace compiler
125 }  // namespace protobuf
126 }  // namespace google
127