1// Protocol Buffers - Google's data interchange format 2// Copyright 2008 Google Inc. All rights reserved. 3// https://developers.google.com/protocol-buffers/ 4// 5// Redistribution and use in source and binary forms, with or without 6// modification, are permitted provided that the following conditions are 7// met: 8// 9// * Redistributions of source code must retain the above copyright 10// notice, this list of conditions and the following disclaimer. 11// * Redistributions in binary form must reproduce the above 12// copyright notice, this list of conditions and the following disclaimer 13// in the documentation and/or other materials provided with the 14// distribution. 15// * Neither the name of Google Inc. nor the names of its 16// contributors may be used to endorse or promote products derived from 17// this software without specific prior written permission. 18// 19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31#include <sstream> 32 33#include <google/protobuf/compiler/code_generator.h> 34#include <google/protobuf/compiler/plugin.h> 35#include <google/protobuf/descriptor.h> 36#include <google/protobuf/descriptor.pb.h> 37#include <google/protobuf/io/printer.h> 38#include <google/protobuf/io/zero_copy_stream.h> 39 40#include <google/protobuf/compiler/csharp/csharp_doc_comment.h> 41#include <google/protobuf/compiler/csharp/csharp_helpers.h> 42#include <google/protobuf/compiler/csharp/csharp_repeated_message_field.h> 43#include <google/protobuf/compiler/csharp/csharp_message_field.h> 44#include <google/protobuf/compiler/csharp/csharp_wrapper_field.h> 45 46namespace google { 47namespace protobuf { 48namespace compiler { 49namespace csharp { 50 51RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator( 52 const FieldDescriptor* descriptor, int fieldOrdinal, const Options *options) 53 : FieldGeneratorBase(descriptor, fieldOrdinal, options) { 54} 55 56RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() { 57 58} 59 60void RepeatedMessageFieldGenerator::GenerateMembers(io::Printer* printer) { 61 printer->Print( 62 variables_, 63 "private static readonly pb::FieldCodec<$type_name$> _repeated_$name$_codec\n" 64 " = "); 65 // Don't want to duplicate the codec code here... maybe we should have a 66 // "create single field generator for this repeated field" 67 // function, but it doesn't seem worth it for just this. 68 if (IsWrapperType(descriptor_)) { 69 scoped_ptr<FieldGeneratorBase> single_generator( 70 new WrapperFieldGenerator(descriptor_, fieldOrdinal_, this->options())); 71 single_generator->GenerateCodecCode(printer); 72 } else { 73 scoped_ptr<FieldGeneratorBase> single_generator( 74 new MessageFieldGenerator(descriptor_, fieldOrdinal_, this->options())); 75 single_generator->GenerateCodecCode(printer); 76 } 77 printer->Print(";\n"); 78 printer->Print( 79 variables_, 80 "private readonly pbc::RepeatedField<$type_name$> $name$_ = new pbc::RepeatedField<$type_name$>();\n"); 81 WritePropertyDocComment(printer, descriptor_); 82 AddDeprecatedFlag(printer); 83 printer->Print( 84 variables_, 85 "$access_level$ pbc::RepeatedField<$type_name$> $property_name$ {\n" 86 " get { return $name$_; }\n" 87 "}\n"); 88} 89 90void RepeatedMessageFieldGenerator::GenerateMergingCode(io::Printer* printer) { 91 printer->Print( 92 variables_, 93 "$name$_.Add(other.$name$_);\n"); 94} 95 96void RepeatedMessageFieldGenerator::GenerateParsingCode(io::Printer* printer) { 97 printer->Print( 98 variables_, 99 "$name$_.AddEntriesFrom(input, _repeated_$name$_codec);\n"); 100} 101 102void RepeatedMessageFieldGenerator::GenerateSerializationCode(io::Printer* printer) { 103 printer->Print( 104 variables_, 105 "$name$_.WriteTo(output, _repeated_$name$_codec);\n"); 106} 107 108void RepeatedMessageFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) { 109 printer->Print( 110 variables_, 111 "size += $name$_.CalculateSize(_repeated_$name$_codec);\n"); 112} 113 114void RepeatedMessageFieldGenerator::WriteHash(io::Printer* printer) { 115 printer->Print( 116 variables_, 117 "hash ^= $name$_.GetHashCode();\n"); 118} 119 120void RepeatedMessageFieldGenerator::WriteEquals(io::Printer* printer) { 121 printer->Print( 122 variables_, 123 "if(!$name$_.Equals(other.$name$_)) return false;\n"); 124} 125 126void RepeatedMessageFieldGenerator::WriteToString(io::Printer* printer) { 127 variables_["field_name"] = GetFieldName(descriptor_); 128 printer->Print( 129 variables_, 130 "PrintField(\"$field_name$\", $name$_, writer);\n"); 131} 132 133void RepeatedMessageFieldGenerator::GenerateCloningCode(io::Printer* printer) { 134 printer->Print(variables_, 135 "$name$_ = other.$name$_.Clone();\n"); 136} 137 138void RepeatedMessageFieldGenerator::GenerateFreezingCode(io::Printer* printer) { 139} 140 141} // namespace csharp 142} // namespace compiler 143} // namespace protobuf 144} // namespace google 145