OLD | NEW |
1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
3 // https://developers.google.com/protocol-buffers/ | 3 // https://developers.google.com/protocol-buffers/ |
4 // | 4 // |
5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
7 // met: | 7 // met: |
8 // | 8 // |
9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 return fields_by_number_; | 98 return fields_by_number_; |
99 } | 99 } |
100 | 100 |
101 void MessageGenerator::Generate(io::Printer* printer) { | 101 void MessageGenerator::Generate(io::Printer* printer) { |
102 map<string, string> vars; | 102 map<string, string> vars; |
103 vars["class_name"] = class_name(); | 103 vars["class_name"] = class_name(); |
104 vars["access_level"] = class_access_level(); | 104 vars["access_level"] = class_access_level(); |
105 | 105 |
106 WriteMessageDocComment(printer, descriptor_); | 106 WriteMessageDocComment(printer, descriptor_); |
107 printer->Print( | 107 printer->Print( |
108 "[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n"); | |
109 WriteGeneratedCodeAttributes(printer); | |
110 printer->Print( | |
111 vars, | 108 vars, |
112 "$access_level$ sealed partial class $class_name$ : pb::IMessage<$class_name
$> {\n"); | 109 "$access_level$ sealed partial class $class_name$ : pb::IMessage<$class_name
$> {\n"); |
113 printer->Indent(); | 110 printer->Indent(); |
114 | 111 |
115 // All static fields and properties | 112 // All static fields and properties |
116 printer->Print( | 113 printer->Print( |
117 vars, | 114 » vars, |
118 "private static readonly pb::MessageParser<$class_name$> _parser = new pb:
:MessageParser<$class_name$>(() => new $class_name$());\n" | 115 » "private static readonly pb::MessageParser<$class_name$> _parser = new
pb::MessageParser<$class_name$>(() => new $class_name$());\n"); |
119 "public static pb::MessageParser<$class_name$> Parser { get { return _pars
er; } }\n\n"); | 116 |
| 117 WriteGeneratedCodeAttributes(printer); |
| 118 printer->Print( |
| 119 » vars, |
| 120 » "public static pb::MessageParser<$class_name$> Parser { get { return _
parser; } }\n\n"); |
120 | 121 |
121 // Access the message descriptor via the relevant file descriptor or containin
g message descriptor. | 122 // Access the message descriptor via the relevant file descriptor or containin
g message descriptor. |
122 if (!descriptor_->containing_type()) { | 123 if (!descriptor_->containing_type()) { |
123 vars["descriptor_accessor"] = GetReflectionClassName(descriptor_->file()) | 124 vars["descriptor_accessor"] = GetReflectionClassName(descriptor_->file()) |
124 + ".Descriptor.MessageTypes[" + SimpleItoa(descriptor_->index()) + "]"; | 125 + ".Descriptor.MessageTypes[" + SimpleItoa(descriptor_->index()) + "]"; |
125 } else { | 126 } else { |
126 vars["descriptor_accessor"] = GetClassName(descriptor_->containing_type()) | 127 vars["descriptor_accessor"] = GetClassName(descriptor_->containing_type()) |
127 + ".Descriptor.NestedTypes[" + SimpleItoa(descriptor_->index()) + "]"; | 128 + ".Descriptor.NestedTypes[" + SimpleItoa(descriptor_->index()) + "]"; |
128 } | 129 } |
129 | 130 |
| 131 WriteGeneratedCodeAttributes(printer); |
130 printer->Print( | 132 printer->Print( |
131 vars, | 133 » vars, |
132 "public static pbr::MessageDescriptor Descriptor {\n" | 134 » "public static pbr::MessageDescriptor Descriptor {\n" |
133 " get { return $descriptor_accessor$; }\n" | 135 » " get { return $descriptor_accessor$; }\n" |
134 "}\n" | 136 » "}\n" |
135 "\n" | 137 » "\n"); |
| 138 WriteGeneratedCodeAttributes(printer); |
| 139 printer->Print( |
| 140 » vars, |
136 "pbr::MessageDescriptor pb::IMessage.Descriptor {\n" | 141 "pbr::MessageDescriptor pb::IMessage.Descriptor {\n" |
137 " get { return Descriptor; }\n" | 142 " get { return Descriptor; }\n" |
138 "}\n" | 143 "}\n" |
139 "\n"); | 144 "\n"); |
140 | 145 |
141 // Parameterless constructor and partial OnConstruction method. | 146 // Parameterless constructor and partial OnConstruction method. |
| 147 WriteGeneratedCodeAttributes(printer); |
142 printer->Print( | 148 printer->Print( |
143 vars, | 149 vars, |
144 "public $class_name$() {\n" | 150 "public $class_name$() {\n" |
145 " OnConstruction();\n" | 151 " OnConstruction();\n" |
146 "}\n\n" | 152 "}\n\n" |
147 "partial void OnConstruction();\n\n"); | 153 "partial void OnConstruction();\n\n"); |
148 | 154 |
149 GenerateCloningCode(printer); | 155 GenerateCloningCode(printer); |
150 GenerateFreezingCode(printer); | 156 GenerateFreezingCode(printer); |
151 | 157 |
(...skipping 29 matching lines...) Expand all Loading... |
181 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { | 187 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { |
182 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); | 188 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); |
183 printer->Print("$field_property_name$ = $index$,\n", | 189 printer->Print("$field_property_name$ = $index$,\n", |
184 "field_property_name", GetPropertyName(field), | 190 "field_property_name", GetPropertyName(field), |
185 "index", SimpleItoa(field->number())); | 191 "index", SimpleItoa(field->number())); |
186 } | 192 } |
187 printer->Outdent(); | 193 printer->Outdent(); |
188 printer->Print("}\n"); | 194 printer->Print("}\n"); |
189 // TODO: Should we put the oneof .proto comments here? | 195 // TODO: Should we put the oneof .proto comments here? |
190 // It's unclear exactly where they should go. | 196 // It's unclear exactly where they should go. |
191 printer->Print( | 197 » printer->Print( |
192 vars, | 198 » vars, |
193 "private $property_name$OneofCase $name$Case_ = $property_name$OneofCase.N
one;\n" | 199 » "private $property_name$OneofCase $name$Case_ = $property_name$OneofCa
se.None;\n"); |
194 "public $property_name$OneofCase $property_name$Case {\n" | 200 » WriteGeneratedCodeAttributes(printer); |
195 " get { return $name$Case_; }\n" | 201 » printer->Print( |
196 "}\n\n" | 202 » vars, |
| 203 » "public $property_name$OneofCase $property_name$Case {\n" |
| 204 » " get { return $name$Case_; }\n" |
| 205 » "}\n\n"); |
| 206 » WriteGeneratedCodeAttributes(printer); |
| 207 » printer->Print( |
| 208 » vars, |
197 "public void Clear$property_name$() {\n" | 209 "public void Clear$property_name$() {\n" |
198 " $name$Case_ = $property_name$OneofCase.None;\n" | 210 " $name$Case_ = $property_name$OneofCase.None;\n" |
199 " $name$_ = null;\n" | 211 " $name$_ = null;\n" |
200 "}\n\n"); | 212 "}\n\n"); |
201 } | 213 } |
202 | 214 |
203 // Standard methods | 215 // Standard methods |
204 GenerateFrameworkMethods(printer); | 216 GenerateFrameworkMethods(printer); |
205 GenerateMessageSerializationMethods(printer); | 217 GenerateMessageSerializationMethods(printer); |
206 GenerateMergingMethods(printer); | 218 GenerateMergingMethods(printer); |
207 | 219 |
208 // Nested messages and enums | 220 // Nested messages and enums |
209 if (HasNestedGeneratedTypes()) { | 221 if (HasNestedGeneratedTypes()) { |
210 printer->Print( | 222 printer->Print( |
211 vars, | 223 vars, |
212 "#region Nested types\n" | 224 "#region Nested types\n" |
213 "/// <summary>Container for nested types declared in the $class_name$ mess
age type.</summary>\n" | 225 "/// <summary>Container for nested types declared in the $class_name$ mess
age type.</summary>\n"); |
214 "[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n"); | |
215 WriteGeneratedCodeAttributes(printer); | 226 WriteGeneratedCodeAttributes(printer); |
216 printer->Print("public static partial class Types {\n"); | 227 printer->Print("public static partial class Types {\n"); |
217 printer->Indent(); | 228 printer->Indent(); |
218 for (int i = 0; i < descriptor_->enum_type_count(); i++) { | 229 for (int i = 0; i < descriptor_->enum_type_count(); i++) { |
219 EnumGenerator enumGenerator(descriptor_->enum_type(i), this->options()); | 230 EnumGenerator enumGenerator(descriptor_->enum_type(i), this->options()); |
220 enumGenerator.Generate(printer); | 231 enumGenerator.Generate(printer); |
221 } | 232 } |
222 for (int i = 0; i < descriptor_->nested_type_count(); i++) { | 233 for (int i = 0; i < descriptor_->nested_type_count(); i++) { |
223 // Don't generate nested types for maps... | 234 // Don't generate nested types for maps... |
224 if (!IsMapEntryMessage(descriptor_->nested_type(i))) { | 235 if (!IsMapEntryMessage(descriptor_->nested_type(i))) { |
(...skipping 23 matching lines...) Expand all Loading... |
248 for (int i = 0; i < descriptor_->nested_type_count(); i++) { | 259 for (int i = 0; i < descriptor_->nested_type_count(); i++) { |
249 if (!IsMapEntryMessage(descriptor_->nested_type(i))) { | 260 if (!IsMapEntryMessage(descriptor_->nested_type(i))) { |
250 return true; | 261 return true; |
251 } | 262 } |
252 } | 263 } |
253 return false; | 264 return false; |
254 } | 265 } |
255 | 266 |
256 void MessageGenerator::GenerateCloningCode(io::Printer* printer) { | 267 void MessageGenerator::GenerateCloningCode(io::Printer* printer) { |
257 map<string, string> vars; | 268 map<string, string> vars; |
| 269 WriteGeneratedCodeAttributes(printer); |
258 vars["class_name"] = class_name(); | 270 vars["class_name"] = class_name(); |
259 printer->Print( | 271 printer->Print( |
260 vars, | 272 vars, |
261 "public $class_name$($class_name$ other) : this() {\n"); | 273 "public $class_name$($class_name$ other) : this() {\n"); |
262 printer->Indent(); | 274 printer->Indent(); |
263 // Clone non-oneof fields first | 275 // Clone non-oneof fields first |
264 for (int i = 0; i < descriptor_->field_count(); i++) { | 276 for (int i = 0; i < descriptor_->field_count(); i++) { |
265 if (!descriptor_->field(i)->containing_oneof()) { | 277 if (!descriptor_->field(i)->containing_oneof()) { |
266 scoped_ptr<FieldGeneratorBase> generator( | 278 scoped_ptr<FieldGeneratorBase> generator( |
267 CreateFieldGeneratorInternal(descriptor_->field(i))); | 279 CreateFieldGeneratorInternal(descriptor_->field(i))); |
(...skipping 19 matching lines...) Expand all Loading... |
287 printer->Print("break;\n"); | 299 printer->Print("break;\n"); |
288 printer->Outdent(); | 300 printer->Outdent(); |
289 } | 301 } |
290 printer->Outdent(); | 302 printer->Outdent(); |
291 printer->Print("}\n\n"); | 303 printer->Print("}\n\n"); |
292 } | 304 } |
293 | 305 |
294 printer->Outdent(); | 306 printer->Outdent(); |
295 printer->Print("}\n\n"); | 307 printer->Print("}\n\n"); |
296 | 308 |
| 309 WriteGeneratedCodeAttributes(printer); |
297 printer->Print( | 310 printer->Print( |
298 vars, | 311 vars, |
299 "public $class_name$ Clone() {\n" | 312 "public $class_name$ Clone() {\n" |
300 " return new $class_name$(this);\n" | 313 " return new $class_name$(this);\n" |
301 "}\n\n"); | 314 "}\n\n"); |
302 } | 315 } |
303 | 316 |
304 void MessageGenerator::GenerateFreezingCode(io::Printer* printer) { | 317 void MessageGenerator::GenerateFreezingCode(io::Printer* printer) { |
305 } | 318 } |
306 | 319 |
307 void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) { | 320 void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) { |
308 map<string, string> vars; | 321 map<string, string> vars; |
309 vars["class_name"] = class_name(); | 322 vars["class_name"] = class_name(); |
310 | 323 |
311 // Equality | 324 // Equality |
| 325 WriteGeneratedCodeAttributes(printer); |
312 printer->Print( | 326 printer->Print( |
313 vars, | 327 vars, |
314 "public override bool Equals(object other) {\n" | 328 "public override bool Equals(object other) {\n" |
315 " return Equals(other as $class_name$);\n" | 329 " return Equals(other as $class_name$);\n" |
316 "}\n\n" | 330 "}\n\n"); |
| 331 » WriteGeneratedCodeAttributes(printer); |
| 332 » printer->Print( |
| 333 » vars, |
317 "public bool Equals($class_name$ other) {\n" | 334 "public bool Equals($class_name$ other) {\n" |
318 " if (ReferenceEquals(other, null)) {\n" | 335 " if (ReferenceEquals(other, null)) {\n" |
319 " return false;\n" | 336 " return false;\n" |
320 " }\n" | 337 " }\n" |
321 " if (ReferenceEquals(other, this)) {\n" | 338 " if (ReferenceEquals(other, this)) {\n" |
322 " return true;\n" | 339 " return true;\n" |
323 " }\n"); | 340 " }\n"); |
324 printer->Indent(); | 341 printer->Indent(); |
325 for (int i = 0; i < descriptor_->field_count(); i++) { | 342 for (int i = 0; i < descriptor_->field_count(); i++) { |
326 scoped_ptr<FieldGeneratorBase> generator( | 343 scoped_ptr<FieldGeneratorBase> generator( |
327 CreateFieldGeneratorInternal(descriptor_->field(i))); | 344 CreateFieldGeneratorInternal(descriptor_->field(i))); |
328 generator->WriteEquals(printer); | 345 generator->WriteEquals(printer); |
329 } | 346 } |
330 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { | 347 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { |
331 printer->Print("if ($property_name$Case != other.$property_name$Case) re
turn false;\n", | 348 printer->Print("if ($property_name$Case != other.$property_name$Case) re
turn false;\n", |
332 "property_name", UnderscoresToCamelCase(descriptor_->oneof_decl(i)->
name(), true)); | 349 "property_name", UnderscoresToCamelCase(descriptor_->oneof_decl(i)->
name(), true)); |
333 } | 350 } |
334 printer->Outdent(); | 351 printer->Outdent(); |
335 printer->Print( | 352 printer->Print( |
336 " return true;\n" | 353 " return true;\n" |
337 "}\n\n"); | 354 "}\n\n"); |
338 | 355 |
339 // GetHashCode | 356 // GetHashCode |
340 // Start with a non-zero value to easily distinguish between null and "empty
" messages. | 357 // Start with a non-zero value to easily distinguish between null and "empty
" messages. |
341 printer->Print( | 358 » WriteGeneratedCodeAttributes(printer); |
| 359 » printer->Print( |
342 "public override int GetHashCode() {\n" | 360 "public override int GetHashCode() {\n" |
343 " int hash = 1;\n"); | 361 " int hash = 1;\n"); |
344 printer->Indent(); | 362 printer->Indent(); |
345 for (int i = 0; i < descriptor_->field_count(); i++) { | 363 for (int i = 0; i < descriptor_->field_count(); i++) { |
346 scoped_ptr<FieldGeneratorBase> generator( | 364 scoped_ptr<FieldGeneratorBase> generator( |
347 CreateFieldGeneratorInternal(descriptor_->field(i))); | 365 CreateFieldGeneratorInternal(descriptor_->field(i))); |
348 generator->WriteHash(printer); | 366 generator->WriteHash(printer); |
349 } | 367 } |
350 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { | 368 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { |
351 printer->Print("hash ^= (int) $name$Case_;\n", | 369 printer->Print("hash ^= (int) $name$Case_;\n", |
352 "name", UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), f
alse)); | 370 "name", UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), f
alse)); |
353 } | 371 } |
354 printer->Print("return hash;\n"); | 372 printer->Print("return hash;\n"); |
355 printer->Outdent(); | 373 printer->Outdent(); |
356 printer->Print("}\n\n"); | 374 printer->Print("}\n\n"); |
357 | 375 |
358 printer->Print( | 376 » WriteGeneratedCodeAttributes(printer); |
| 377 » printer->Print( |
359 "public override string ToString() {\n" | 378 "public override string ToString() {\n" |
360 " return pb::JsonFormatter.ToDiagnosticString(this);\n" | 379 " return pb::JsonFormatter.ToDiagnosticString(this);\n" |
361 "}\n\n"); | 380 "}\n\n"); |
362 } | 381 } |
363 | 382 |
364 void MessageGenerator::GenerateMessageSerializationMethods(io::Printer* printer)
{ | 383 void MessageGenerator::GenerateMessageSerializationMethods(io::Printer* printer)
{ |
| 384 WriteGeneratedCodeAttributes(printer); |
365 printer->Print( | 385 printer->Print( |
366 "public void WriteTo(pb::CodedOutputStream output) {\n"); | 386 "public void WriteTo(pb::CodedOutputStream output) {\n"); |
367 printer->Indent(); | 387 printer->Indent(); |
368 | 388 |
369 // Serialize all the fields | 389 // Serialize all the fields |
370 for (int i = 0; i < fields_by_number().size(); i++) { | 390 for (int i = 0; i < fields_by_number().size(); i++) { |
371 scoped_ptr<FieldGeneratorBase> generator( | 391 scoped_ptr<FieldGeneratorBase> generator( |
372 CreateFieldGeneratorInternal(fields_by_number()[i])); | 392 CreateFieldGeneratorInternal(fields_by_number()[i])); |
373 generator->GenerateSerializationCode(printer); | 393 generator->GenerateSerializationCode(printer); |
374 } | 394 } |
375 | 395 |
376 // TODO(jonskeet): Memoize size of frozen messages? | 396 // TODO(jonskeet): Memoize size of frozen messages? |
377 printer->Outdent(); | 397 printer->Outdent(); |
378 printer->Print( | 398 printer->Print( |
379 "}\n" | 399 » "}\n" |
380 "\n" | 400 » "\n"); |
| 401 WriteGeneratedCodeAttributes(printer); |
| 402 printer->Print( |
381 "public int CalculateSize() {\n"); | 403 "public int CalculateSize() {\n"); |
382 printer->Indent(); | 404 printer->Indent(); |
383 printer->Print("int size = 0;\n"); | 405 printer->Print("int size = 0;\n"); |
384 for (int i = 0; i < descriptor_->field_count(); i++) { | 406 for (int i = 0; i < descriptor_->field_count(); i++) { |
385 scoped_ptr<FieldGeneratorBase> generator( | 407 scoped_ptr<FieldGeneratorBase> generator( |
386 CreateFieldGeneratorInternal(descriptor_->field(i))); | 408 CreateFieldGeneratorInternal(descriptor_->field(i))); |
387 generator->GenerateSerializedSizeCode(printer); | 409 generator->GenerateSerializedSizeCode(printer); |
388 } | 410 } |
389 printer->Print("return size;\n"); | 411 printer->Print("return size;\n"); |
390 printer->Outdent(); | 412 printer->Outdent(); |
391 printer->Print("}\n\n"); | 413 printer->Print("}\n\n"); |
392 } | 414 } |
393 | 415 |
394 void MessageGenerator::GenerateMergingMethods(io::Printer* printer) { | 416 void MessageGenerator::GenerateMergingMethods(io::Printer* printer) { |
395 // Note: These are separate from GenerateMessageSerializationMethods() | 417 // Note: These are separate from GenerateMessageSerializationMethods() |
396 // because they need to be generated even for messages that are optimized | 418 // because they need to be generated even for messages that are optimized |
397 // for code size. | 419 // for code size. |
398 map<string, string> vars; | 420 map<string, string> vars; |
399 vars["class_name"] = class_name(); | 421 vars["class_name"] = class_name(); |
400 | 422 |
| 423 WriteGeneratedCodeAttributes(printer); |
401 printer->Print( | 424 printer->Print( |
402 vars, | 425 vars, |
403 "public void MergeFrom($class_name$ other) {\n"); | 426 "public void MergeFrom($class_name$ other) {\n"); |
404 printer->Indent(); | 427 printer->Indent(); |
405 printer->Print( | 428 printer->Print( |
406 "if (other == null) {\n" | 429 "if (other == null) {\n" |
407 " return;\n" | 430 " return;\n" |
408 "}\n"); | 431 "}\n"); |
409 // Merge non-oneof fields | 432 // Merge non-oneof fields |
410 for (int i = 0; i < descriptor_->field_count(); i++) { | 433 for (int i = 0; i < descriptor_->field_count(); i++) { |
(...skipping 16 matching lines...) Expand all Loading... |
427 vars, | 450 vars, |
428 "case $property_name$OneofCase.$field_property_name$:\n" | 451 "case $property_name$OneofCase.$field_property_name$:\n" |
429 " $field_property_name$ = other.$field_property_name$;\n" | 452 " $field_property_name$ = other.$field_property_name$;\n" |
430 " break;\n"); | 453 " break;\n"); |
431 } | 454 } |
432 printer->Outdent(); | 455 printer->Outdent(); |
433 printer->Print("}\n\n"); | 456 printer->Print("}\n\n"); |
434 } | 457 } |
435 printer->Outdent(); | 458 printer->Outdent(); |
436 printer->Print("}\n\n"); | 459 printer->Print("}\n\n"); |
| 460 WriteGeneratedCodeAttributes(printer); |
437 printer->Print("public void MergeFrom(pb::CodedInputStream input) {\n"); | 461 printer->Print("public void MergeFrom(pb::CodedInputStream input) {\n"); |
438 printer->Indent(); | 462 printer->Indent(); |
439 printer->Print( | 463 printer->Print( |
440 "uint tag;\n" | 464 "uint tag;\n" |
441 "while ((tag = input.ReadTag()) != 0) {\n" | 465 "while ((tag = input.ReadTag()) != 0) {\n" |
442 " switch(tag) {\n"); | 466 " switch(tag) {\n"); |
443 printer->Indent(); | 467 printer->Indent(); |
444 printer->Indent(); | 468 printer->Indent(); |
445 printer->Print( | 469 printer->Print( |
446 "default:\n" | 470 "default:\n" |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 | 519 |
496 FieldGeneratorBase* MessageGenerator::CreateFieldGeneratorInternal( | 520 FieldGeneratorBase* MessageGenerator::CreateFieldGeneratorInternal( |
497 const FieldDescriptor* descriptor) { | 521 const FieldDescriptor* descriptor) { |
498 return CreateFieldGenerator(descriptor, GetFieldOrdinal(descriptor), this->opt
ions()); | 522 return CreateFieldGenerator(descriptor, GetFieldOrdinal(descriptor), this->opt
ions()); |
499 } | 523 } |
500 | 524 |
501 } // namespace csharp | 525 } // namespace csharp |
502 } // namespace compiler | 526 } // namespace compiler |
503 } // namespace protobuf | 527 } // namespace protobuf |
504 } // namespace google | 528 } // namespace google |
OLD | NEW |