164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// Protocol Buffers - Google's data interchange format
264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// Copyright 2008 Google Inc.  All rights reserved.
364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// http://code.google.com/p/protobuf/
464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci//
564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// Redistribution and use in source and binary forms, with or without
664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// modification, are permitted provided that the following conditions are
764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// met:
864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci//
964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci//     * Redistributions of source code must retain the above copyright
1064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// notice, this list of conditions and the following disclaimer.
1164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci//     * Redistributions in binary form must reproduce the above
1264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// copyright notice, this list of conditions and the following disclaimer
1364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// in the documentation and/or other materials provided with the
1464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// distribution.
1564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci//     * Neither the name of Google Inc. nor the names of its
1664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// contributors may be used to endorse or promote products derived from
1764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// this software without specific prior written permission.
1864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci//
1964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
3164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// Author: kenton@google.com (Kenton Varda)
3264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci//  Based on original Protocol Buffers design by
3364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci//  Sanjay Ghemawat, Jeff Dean, and others.
3464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
3564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/compiler/javanano/javanano_field.h>
3664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/compiler/javanano/javanano_helpers.h>
3764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/compiler/javanano/javanano_primitive_field.h>
3864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/compiler/javanano/javanano_enum_field.h>
3964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/compiler/javanano/javanano_message_field.h>
4064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/stubs/common.h>
4164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
4264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcinamespace google {
4364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcinamespace protobuf {
4464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcinamespace compiler {
4564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcinamespace javanano {
4664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
4764d8d8f89050c5ada85341f967af391f4716a7cbUlas KirazciFieldGenerator::~FieldGenerator() {}
4864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
495cc242074f189837b38e7768b57ccfb0bca258dfMax Caibool FieldGenerator::SavedDefaultNeeded() const {
505cc242074f189837b38e7768b57ccfb0bca258dfMax Cai  // No saved default for this field by default.
515cc242074f189837b38e7768b57ccfb0bca258dfMax Cai  // Subclasses whose instances may need saved defaults will override this
525cc242074f189837b38e7768b57ccfb0bca258dfMax Cai  // and return the appropriate value.
535cc242074f189837b38e7768b57ccfb0bca258dfMax Cai  return false;
545cc242074f189837b38e7768b57ccfb0bca258dfMax Cai}
555cc242074f189837b38e7768b57ccfb0bca258dfMax Cai
565cc242074f189837b38e7768b57ccfb0bca258dfMax Caivoid FieldGenerator::GenerateInitSavedDefaultCode(io::Printer* printer) const {
575cc242074f189837b38e7768b57ccfb0bca258dfMax Cai  // No saved default for this field by default.
585cc242074f189837b38e7768b57ccfb0bca258dfMax Cai  // Subclasses whose instances may need saved defaults will override this
595cc242074f189837b38e7768b57ccfb0bca258dfMax Cai  // and generate the appropriate init code to the printer.
605cc242074f189837b38e7768b57ccfb0bca258dfMax Cai}
615cc242074f189837b38e7768b57ccfb0bca258dfMax Cai
62fea3fd5cb6ff88b51da60b1f33004944d93a9fceMax Caivoid FieldGenerator::GenerateMergingCodeFromPacked(io::Printer* printer) const {
63fea3fd5cb6ff88b51da60b1f33004944d93a9fceMax Cai  // Reaching here indicates a bug. Cases are:
64fea3fd5cb6ff88b51da60b1f33004944d93a9fceMax Cai  //   - This FieldGenerator should support packing, but this method should be
65fea3fd5cb6ff88b51da60b1f33004944d93a9fceMax Cai  //     overridden.
66fea3fd5cb6ff88b51da60b1f33004944d93a9fceMax Cai  //   - This FieldGenerator doesn't support packing, and this method should
67fea3fd5cb6ff88b51da60b1f33004944d93a9fceMax Cai  //     never have been called.
68fea3fd5cb6ff88b51da60b1f33004944d93a9fceMax Cai  GOOGLE_LOG(FATAL) << "GenerateParsingCodeFromPacked() "
69fea3fd5cb6ff88b51da60b1f33004944d93a9fceMax Cai             << "called on field generator that does not support packing.";
70fea3fd5cb6ff88b51da60b1f33004944d93a9fceMax Cai}
71fea3fd5cb6ff88b51da60b1f33004944d93a9fceMax Cai
725cc242074f189837b38e7768b57ccfb0bca258dfMax Cai// =============================================
735cc242074f189837b38e7768b57ccfb0bca258dfMax Cai
745cc242074f189837b38e7768b57ccfb0bca258dfMax CaiFieldGeneratorMap::FieldGeneratorMap(
755cc242074f189837b38e7768b57ccfb0bca258dfMax Cai    const Descriptor* descriptor, const Params &params)
7664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  : descriptor_(descriptor),
7764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    field_generators_(
785cc242074f189837b38e7768b57ccfb0bca258dfMax Cai      new scoped_ptr<FieldGenerator>[descriptor->field_count()]) {
7964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
80e74fe623e115237968a3de1143d7cdb4df710858Max Cai  int next_has_bit_index = 0;
815cc242074f189837b38e7768b57ccfb0bca258dfMax Cai  bool saved_defaults_needed = false;
8264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  // Construct all the FieldGenerators.
8364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  for (int i = 0; i < descriptor->field_count(); i++) {
845cc242074f189837b38e7768b57ccfb0bca258dfMax Cai    FieldGenerator* field_generator = MakeGenerator(
855cc242074f189837b38e7768b57ccfb0bca258dfMax Cai        descriptor->field(i), params, &next_has_bit_index);
865cc242074f189837b38e7768b57ccfb0bca258dfMax Cai    saved_defaults_needed = saved_defaults_needed
875cc242074f189837b38e7768b57ccfb0bca258dfMax Cai        || field_generator->SavedDefaultNeeded();
885cc242074f189837b38e7768b57ccfb0bca258dfMax Cai    field_generators_[i].reset(field_generator);
8964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
90e74fe623e115237968a3de1143d7cdb4df710858Max Cai  total_bits_ = next_has_bit_index;
915cc242074f189837b38e7768b57ccfb0bca258dfMax Cai  saved_defaults_needed_ = saved_defaults_needed;
9264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
9364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
94e74fe623e115237968a3de1143d7cdb4df710858Max CaiFieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field,
95e74fe623e115237968a3de1143d7cdb4df710858Max Cai    const Params &params, int* next_has_bit_index) {
96102cfe65b9b9e2b458c3d0ec69d47e8fc40dc726Andrew Flynn  JavaType java_type = GetJavaType(field);
9764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  if (field->is_repeated()) {
98102cfe65b9b9e2b458c3d0ec69d47e8fc40dc726Andrew Flynn    switch (java_type) {
9964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      case JAVATYPE_MESSAGE:
10064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        return new RepeatedMessageFieldGenerator(field, params);
10164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      case JAVATYPE_ENUM:
10264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        return new RepeatedEnumFieldGenerator(field, params);
10364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      default:
10464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        return new RepeatedPrimitiveFieldGenerator(field, params);
10564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    }
106102cfe65b9b9e2b458c3d0ec69d47e8fc40dc726Andrew Flynn  } else if (params.optional_field_accessors() && field->is_optional()
107102cfe65b9b9e2b458c3d0ec69d47e8fc40dc726Andrew Flynn      && java_type != JAVATYPE_MESSAGE) {
108e74fe623e115237968a3de1143d7cdb4df710858Max Cai    // We need a has-bit for each primitive/enum field because their default
109e74fe623e115237968a3de1143d7cdb4df710858Max Cai    // values could be same as explicitly set values. But we don't need it
110e74fe623e115237968a3de1143d7cdb4df710858Max Cai    // for a message field because they have no defaults and Nano uses 'null'
111e74fe623e115237968a3de1143d7cdb4df710858Max Cai    // for unset messages, which cannot be set explicitly.
112102cfe65b9b9e2b458c3d0ec69d47e8fc40dc726Andrew Flynn    switch (java_type) {
113e74fe623e115237968a3de1143d7cdb4df710858Max Cai      case JAVATYPE_ENUM:
114e74fe623e115237968a3de1143d7cdb4df710858Max Cai        return new AccessorEnumFieldGenerator(
115e74fe623e115237968a3de1143d7cdb4df710858Max Cai            field, params, (*next_has_bit_index)++);
116e74fe623e115237968a3de1143d7cdb4df710858Max Cai      default:
117e74fe623e115237968a3de1143d7cdb4df710858Max Cai        return new AccessorPrimitiveFieldGenerator(
118e74fe623e115237968a3de1143d7cdb4df710858Max Cai            field, params, (*next_has_bit_index)++);
119e74fe623e115237968a3de1143d7cdb4df710858Max Cai    }
12064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  } else {
121102cfe65b9b9e2b458c3d0ec69d47e8fc40dc726Andrew Flynn    switch (java_type) {
12264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      case JAVATYPE_MESSAGE:
12364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        return new MessageFieldGenerator(field, params);
12464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      case JAVATYPE_ENUM:
12564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        return new EnumFieldGenerator(field, params);
12664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      default:
12764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        return new PrimitiveFieldGenerator(field, params);
12864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    }
12964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
13064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
13164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
13264d8d8f89050c5ada85341f967af391f4716a7cbUlas KirazciFieldGeneratorMap::~FieldGeneratorMap() {}
13364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
13464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazciconst FieldGenerator& FieldGeneratorMap::get(
13564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    const FieldDescriptor* field) const {
13664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  GOOGLE_CHECK_EQ(field->containing_type(), descriptor_);
13764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return *field_generators_[field->index()];
13864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
13964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
14064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}  // namespace javanano
14164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}  // namespace compiler
14264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}  // namespace protobuf
14364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}  // namespace google
144