1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol Buffers - Google's data interchange format
2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copyright 2008 Google Inc.  All rights reserved.
3fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// http://code.google.com/p/protobuf/
4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Redistribution and use in source and binary forms, with or without
6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// modification, are permitted provided that the following conditions are
7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// met:
8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Redistributions of source code must retain the above copyright
10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// notice, this list of conditions and the following disclaimer.
11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Redistributions in binary form must reproduce the above
12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// copyright notice, this list of conditions and the following disclaimer
13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in the documentation and/or other materials provided with the
14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// distribution.
15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Neither the name of Google Inc. nor the names of its
16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// contributors may be used to endorse or promote products derived from
17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// this software without specific prior written permission.
18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Author: kenton@google.com (Kenton Varda)
32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//  Based on original Protocol Buffers design by
33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//  Sanjay Ghemawat, Jeff Dean, and others.
34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/cpp/cpp_field.h>
36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/cpp/cpp_helpers.h>
37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/cpp/cpp_primitive_field.h>
38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/cpp/cpp_string_field.h>
39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/cpp/cpp_enum_field.h>
40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/cpp/cpp_message_field.h>
41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/descriptor.pb.h>
42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/wire_format.h>
43d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#include <google/protobuf/io/printer.h>
44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/common.h>
45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/strutil.h>
46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace google {
48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace protobuf {
49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace compiler {
50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace cpp {
51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleusing internal::WireFormat;
53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid SetCommonFieldVariables(const FieldDescriptor* descriptor,
55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                             map<string, string>* variables) {
56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  (*variables)["name"] = FieldName(descriptor);
57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  (*variables)["index"] = SimpleItoa(descriptor->index());
58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  (*variables)["number"] = SimpleItoa(descriptor->number());
59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  (*variables)["classname"] = ClassName(FieldScope(descriptor), false);
60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  (*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type());
61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  (*variables)["tag_size"] = SimpleItoa(
63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    WireFormat::TagSize(descriptor->number(), descriptor->type()));
64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  (*variables)["deprecation"] = descriptor->options().deprecated()
65d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      ? " PROTOBUF_DEPRECATED" : "";
66d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleFieldGenerator::~FieldGenerator() {}
70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
71d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillevoid FieldGenerator::
72d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleGenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const {
73d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  // Reaching here indicates a bug. Cases are:
74d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  //   - This FieldGenerator should support packing, but this method should be
75d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  //     overridden.
76d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  //   - This FieldGenerator doesn't support packing, and this method should
77d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  //     never have been called.
78d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  GOOGLE_LOG(FATAL) << "GenerateMergeFromCodedStreamWithPacking() "
79d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville             << "called on field generator that does not support packing.";
80d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
81d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville}
82d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleFieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor)
84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  : descriptor_(descriptor),
85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    field_generators_(
86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      new scoped_ptr<FieldGenerator>[descriptor->field_count()]) {
87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Construct all the FieldGenerators.
88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor->field_count(); i++) {
89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    field_generators_[i].reset(MakeGenerator(descriptor->field(i)));
90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleFieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field) {
94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (field->is_repeated()) {
95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    switch (field->cpp_type()) {
96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      case FieldDescriptor::CPPTYPE_MESSAGE:
97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return new RepeatedMessageFieldGenerator(field);
98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      case FieldDescriptor::CPPTYPE_STRING:
99d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        switch (field->options().ctype()) {
100d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          default:  // RepeatedStringFieldGenerator handles unknown ctypes.
101d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          case FieldOptions::STRING:
102d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville            return new RepeatedStringFieldGenerator(field);
103d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        }
104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      case FieldDescriptor::CPPTYPE_ENUM:
105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return new RepeatedEnumFieldGenerator(field);
106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      default:
107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return new RepeatedPrimitiveFieldGenerator(field);
108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    switch (field->cpp_type()) {
111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      case FieldDescriptor::CPPTYPE_MESSAGE:
112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return new MessageFieldGenerator(field);
113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      case FieldDescriptor::CPPTYPE_STRING:
114d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        switch (field->options().ctype()) {
115d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          default:  // StringFieldGenerator handles unknown ctypes.
116d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          case FieldOptions::STRING:
117d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville            return new StringFieldGenerator(field);
118d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        }
119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      case FieldDescriptor::CPPTYPE_ENUM:
120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return new EnumFieldGenerator(field);
121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      default:
122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return new PrimitiveFieldGenerator(field);
123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleFieldGeneratorMap::~FieldGeneratorMap() {}
128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst FieldGenerator& FieldGeneratorMap::get(
130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* field) const {
131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_CHECK_EQ(field->containing_type(), descriptor_);
132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return *field_generators_[field->index()];
133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
135d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace cpp
137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace compiler
138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace protobuf
139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace google
140