15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Protocol Buffers - Google's data interchange format
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2008 Google Inc.  All rights reserved.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/protobuf/
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modification, are permitted provided that the following conditions are
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// met:
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Redistributions of source code must retain the above copyright
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notice, this list of conditions and the following disclaimer.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Redistributions in binary form must reproduce the above
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the documentation and/or other materials provided with the
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// distribution.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Neither the name of Google Inc. nor the names of its
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contributors may be used to endorse or promote products derived from
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this software without specific prior written permission.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: kenton@google.com (Kenton Varda)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  Based on original Protocol Buffers design by
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  Sanjay Ghemawat, Jeff Dean, and others.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/compiler/cpp/cpp_field.h>
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/compiler/cpp/cpp_helpers.h>
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/compiler/cpp/cpp_primitive_field.h>
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/compiler/cpp/cpp_string_field.h>
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/compiler/cpp/cpp_enum_field.h>
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/compiler/cpp/cpp_message_field.h>
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/descriptor.pb.h>
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/wire_format.h>
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/printer.h>
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/common.h>
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/strutil.h>
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace google {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protobuf {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace compiler {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace cpp {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using internal::WireFormat;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetCommonFieldVariables(const FieldDescriptor* descriptor,
55ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                             map<string, string>* variables,
56ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                             const Options& options) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (*variables)["name"] = FieldName(descriptor);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (*variables)["index"] = SimpleItoa(descriptor->index());
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (*variables)["number"] = SimpleItoa(descriptor->number());
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (*variables)["classname"] = ClassName(FieldScope(descriptor), false);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type());
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (*variables)["tag_size"] = SimpleItoa(
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WireFormat::TagSize(descriptor->number(), descriptor->type()));
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (*variables)["deprecation"] = descriptor->options().deprecated()
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ? " PROTOBUF_DEPRECATED" : "";
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  (*variables)["cppget"] = "Get";
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FieldGenerator::~FieldGenerator() {}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FieldGenerator::
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reaching here indicates a bug. Cases are:
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   - This FieldGenerator should support packing, but this method should be
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     overridden.
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   - This FieldGenerator doesn't support packing, and this method should
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     never have been called.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_LOG(FATAL) << "GenerateMergeFromCodedStreamWithPacking() "
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             << "called on field generator that does not support packing.";
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochFieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor,
86ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                     const Options& options)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  : descriptor_(descriptor),
88ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    field_generators_(new scoped_ptr<FieldGenerator>[descriptor->field_count()]) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Construct all the FieldGenerators.
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < descriptor->field_count(); i++) {
91ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    field_generators_[i].reset(MakeGenerator(descriptor->field(i), options));
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochFieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field,
96ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                                 const Options& options) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (field->is_repeated()) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (field->cpp_type()) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case FieldDescriptor::CPPTYPE_MESSAGE:
100ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        return new RepeatedMessageFieldGenerator(field, options);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case FieldDescriptor::CPPTYPE_STRING:
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        switch (field->options().ctype()) {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          default:  // RepeatedStringFieldGenerator handles unknown ctypes.
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          case FieldOptions::STRING:
105ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch            return new RepeatedStringFieldGenerator(field, options);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case FieldDescriptor::CPPTYPE_ENUM:
108ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        return new RepeatedEnumFieldGenerator(field, options);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
110ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        return new RepeatedPrimitiveFieldGenerator(field, options);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (field->cpp_type()) {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case FieldDescriptor::CPPTYPE_MESSAGE:
115ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        return new MessageFieldGenerator(field, options);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case FieldDescriptor::CPPTYPE_STRING:
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        switch (field->options().ctype()) {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          default:  // StringFieldGenerator handles unknown ctypes.
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          case FieldOptions::STRING:
120ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch            return new StringFieldGenerator(field, options);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case FieldDescriptor::CPPTYPE_ENUM:
123ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        return new EnumFieldGenerator(field, options);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
125ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        return new PrimitiveFieldGenerator(field, options);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FieldGeneratorMap::~FieldGeneratorMap() {}
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const FieldGenerator& FieldGeneratorMap::get(
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FieldDescriptor* field) const {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_CHECK_EQ(field->containing_type(), descriptor_);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return *field_generators_[field->index()];
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace cpp
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace compiler
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace protobuf
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace google
143