1// Protocol Buffers - Google's data interchange format 2// Copyright 2008 Google Inc. All rights reserved. 3// http://code.google.com/p/protobuf/ 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// Author: kenton@google.com (Kenton Varda) 32// Based on original Protocol Buffers design by 33// Sanjay Ghemawat, Jeff Dean, and others. 34 35#include <google/protobuf/compiler/javanano/javanano_field.h> 36#include <google/protobuf/compiler/javanano/javanano_helpers.h> 37#include <google/protobuf/compiler/javanano/javanano_primitive_field.h> 38#include <google/protobuf/compiler/javanano/javanano_enum_field.h> 39#include <google/protobuf/compiler/javanano/javanano_message_field.h> 40#include <google/protobuf/stubs/common.h> 41 42namespace google { 43namespace protobuf { 44namespace compiler { 45namespace javanano { 46 47FieldGenerator::~FieldGenerator() {} 48 49bool FieldGenerator::SavedDefaultNeeded() const { 50 // No saved default for this field by default. 51 // Subclasses whose instances may need saved defaults will override this 52 // and return the appropriate value. 53 return false; 54} 55 56void FieldGenerator::GenerateInitSavedDefaultCode(io::Printer* printer) const { 57 // No saved default for this field by default. 58 // Subclasses whose instances may need saved defaults will override this 59 // and generate the appropriate init code to the printer. 60} 61 62void FieldGenerator::GenerateMergingCodeFromPacked(io::Printer* printer) const { 63 // Reaching here indicates a bug. Cases are: 64 // - This FieldGenerator should support packing, but this method should be 65 // overridden. 66 // - This FieldGenerator doesn't support packing, and this method should 67 // never have been called. 68 GOOGLE_LOG(FATAL) << "GenerateParsingCodeFromPacked() " 69 << "called on field generator that does not support packing."; 70} 71 72// ============================================= 73 74FieldGeneratorMap::FieldGeneratorMap( 75 const Descriptor* descriptor, const Params ¶ms) 76 : descriptor_(descriptor), 77 field_generators_( 78 new scoped_ptr<FieldGenerator>[descriptor->field_count()]) { 79 80 int next_has_bit_index = 0; 81 bool saved_defaults_needed = false; 82 // Construct all the FieldGenerators. 83 for (int i = 0; i < descriptor->field_count(); i++) { 84 FieldGenerator* field_generator = MakeGenerator( 85 descriptor->field(i), params, &next_has_bit_index); 86 saved_defaults_needed = saved_defaults_needed 87 || field_generator->SavedDefaultNeeded(); 88 field_generators_[i].reset(field_generator); 89 } 90 total_bits_ = next_has_bit_index; 91 saved_defaults_needed_ = saved_defaults_needed; 92} 93 94FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field, 95 const Params ¶ms, int* next_has_bit_index) { 96 JavaType java_type = GetJavaType(field); 97 if (field->is_repeated()) { 98 switch (java_type) { 99 case JAVATYPE_MESSAGE: 100 return new RepeatedMessageFieldGenerator(field, params); 101 case JAVATYPE_ENUM: 102 return new RepeatedEnumFieldGenerator(field, params); 103 default: 104 return new RepeatedPrimitiveFieldGenerator(field, params); 105 } 106 } else if (params.optional_field_accessors() && field->is_optional() 107 && java_type != JAVATYPE_MESSAGE) { 108 // We need a has-bit for each primitive/enum field because their default 109 // values could be same as explicitly set values. But we don't need it 110 // for a message field because they have no defaults and Nano uses 'null' 111 // for unset messages, which cannot be set explicitly. 112 switch (java_type) { 113 case JAVATYPE_ENUM: 114 return new AccessorEnumFieldGenerator( 115 field, params, (*next_has_bit_index)++); 116 default: 117 return new AccessorPrimitiveFieldGenerator( 118 field, params, (*next_has_bit_index)++); 119 } 120 } else { 121 switch (java_type) { 122 case JAVATYPE_MESSAGE: 123 return new MessageFieldGenerator(field, params); 124 case JAVATYPE_ENUM: 125 return new EnumFieldGenerator(field, params); 126 default: 127 return new PrimitiveFieldGenerator(field, params); 128 } 129 } 130} 131 132FieldGeneratorMap::~FieldGeneratorMap() {} 133 134const FieldGenerator& FieldGeneratorMap::get( 135 const FieldDescriptor* field) const { 136 GOOGLE_CHECK_EQ(field->containing_type(), descriptor_); 137 return *field_generators_[field->index()]; 138} 139 140} // namespace javanano 141} // namespace compiler 142} // namespace protobuf 143} // namespace google 144