diff options
Diffstat (limited to 'src/google/protobuf/compiler/javanano/javanano_message.cc')
-rw-r--r-- | src/google/protobuf/compiler/javanano/javanano_message.cc | 676 |
1 files changed, 0 insertions, 676 deletions
diff --git a/src/google/protobuf/compiler/javanano/javanano_message.cc b/src/google/protobuf/compiler/javanano/javanano_message.cc deleted file mode 100644 index e849521b..00000000 --- a/src/google/protobuf/compiler/javanano/javanano_message.cc +++ /dev/null @@ -1,676 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <algorithm> -#include <google/protobuf/stubs/hash.h> -#include <google/protobuf/compiler/javanano/javanano_message.h> -#include <google/protobuf/compiler/javanano/javanano_enum.h> -#include <google/protobuf/compiler/javanano/javanano_extension.h> -#include <google/protobuf/compiler/javanano/javanano_helpers.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/descriptor.pb.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace javanano { - -using internal::WireFormat; -using internal::WireFormatLite; - -namespace { - -struct FieldOrderingByNumber { - inline bool operator()(const FieldDescriptor* a, - const FieldDescriptor* b) const { - return a->number() < b->number(); - } -}; - -// Sort the fields of the given Descriptor by number into a new[]'d array -// and return it. -const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) { - const FieldDescriptor** fields = - new const FieldDescriptor*[descriptor->field_count()]; - for (int i = 0; i < descriptor->field_count(); i++) { - fields[i] = descriptor->field(i); - } - std::sort(fields, fields + descriptor->field_count(), - FieldOrderingByNumber()); - return fields; -} - -} // namespace - -// =================================================================== - -MessageGenerator::MessageGenerator(const Descriptor* descriptor, const Params& params) - : params_(params), - descriptor_(descriptor), - field_generators_(descriptor, params) { -} - -MessageGenerator::~MessageGenerator() {} - -void MessageGenerator::GenerateStaticVariables(io::Printer* printer) { - // Generate static members for all nested types. - for (int i = 0; i < descriptor_->nested_type_count(); i++) { - // TODO(kenton): Reuse MessageGenerator objects? - if (IsMapEntry(descriptor_->nested_type(i))) continue; - MessageGenerator(descriptor_->nested_type(i), params_) - .GenerateStaticVariables(printer); - } -} - -void MessageGenerator::GenerateStaticVariableInitializers( - io::Printer* printer) { - // Generate static member initializers for all nested types. - for (int i = 0; i < descriptor_->nested_type_count(); i++) { - // TODO(kenton): Reuse MessageGenerator objects? - if (IsMapEntry(descriptor_->nested_type(i))) continue; - MessageGenerator(descriptor_->nested_type(i), params_) - .GenerateStaticVariableInitializers(printer); - } -} - -void MessageGenerator::Generate(io::Printer* printer) { - if (!params_.store_unknown_fields() && - (descriptor_->extension_count() != 0 || descriptor_->extension_range_count() != 0)) { - GOOGLE_LOG(FATAL) << "Extensions are only supported in NANO_RUNTIME if the " - "'store_unknown_fields' generator option is 'true'\n"; - } - - const string& file_name = descriptor_->file()->name(); - bool is_own_file = - params_.java_multiple_files(file_name) - && descriptor_->containing_type() == NULL; - - if (is_own_file) { - // Note: constants (from enums and fields requiring stored defaults, emitted in the loop below) - // may have the same names as constants in the nested classes. This causes Java warnings, but - // is not fatal, so we suppress those warnings here in the top-most class declaration. - printer->Print( - "\n" - "@SuppressWarnings(\"hiding\")\n" - "public final class $classname$ extends\n", - "classname", descriptor_->name()); - } else { - printer->Print( - "\n" - "public static final class $classname$ extends\n", - "classname", descriptor_->name()); - } - if (params_.store_unknown_fields() && params_.parcelable_messages()) { - printer->Print( - " com.google.protobuf.nano.android.ParcelableExtendableMessageNano<$classname$>", - "classname", descriptor_->name()); - } else if (params_.store_unknown_fields()) { - printer->Print( - " com.google.protobuf.nano.ExtendableMessageNano<$classname$>", - "classname", descriptor_->name()); - } else if (params_.parcelable_messages()) { - printer->Print( - " com.google.protobuf.nano.android.ParcelableMessageNano"); - } else { - printer->Print( - " com.google.protobuf.nano.MessageNano"); - } - if (params_.generate_clone()) { - printer->Print(" implements java.lang.Cloneable {\n"); - } else { - printer->Print(" {\n"); - } - printer->Indent(); - - if (params_.parcelable_messages()) { - printer->Print( - "\n" - "// Used by Parcelable\n" - "@SuppressWarnings({\"unused\"})\n" - "public static final android.os.Parcelable.Creator<$classname$> CREATOR =\n" - " new com.google.protobuf.nano.android.ParcelableMessageNanoCreator<\n" - " $classname$>($classname$.class);\n", - "classname", descriptor_->name()); - } - - // Nested types and extensions - for (int i = 0; i < descriptor_->extension_count(); i++) { - ExtensionGenerator(descriptor_->extension(i), params_).Generate(printer); - } - - for (int i = 0; i < descriptor_->enum_type_count(); i++) { - EnumGenerator(descriptor_->enum_type(i), params_).Generate(printer); - } - - for (int i = 0; i < descriptor_->nested_type_count(); i++) { - if (IsMapEntry(descriptor_->nested_type(i))) continue; - MessageGenerator(descriptor_->nested_type(i), params_).Generate(printer); - } - - // oneof - std::map<string, string> vars; - vars["message_name"] = descriptor_->name(); - for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { - const OneofDescriptor* oneof_desc = descriptor_->oneof_decl(i); - vars["oneof_name"] = UnderscoresToCamelCase(oneof_desc); - vars["oneof_capitalized_name"] = - UnderscoresToCapitalizedCamelCase(oneof_desc); - vars["oneof_index"] = SimpleItoa(oneof_desc->index()); - // Oneof Constants - for (int j = 0; j < oneof_desc->field_count(); j++) { - const FieldDescriptor* field = oneof_desc->field(j); - vars["number"] = SimpleItoa(field->number()); - vars["cap_field_name"] = ToUpper(field->name()); - printer->Print(vars, - "public static final int $cap_field_name$_FIELD_NUMBER = $number$;\n"); - } - // oneofCase_ and oneof_ - printer->Print(vars, - "private int $oneof_name$Case_ = 0;\n" - "private java.lang.Object $oneof_name$_;\n"); - printer->Print(vars, - "public int get$oneof_capitalized_name$Case() {\n" - " return this.$oneof_name$Case_;\n" - "}\n"); - // Oneof clear - printer->Print(vars, - "public $message_name$ clear$oneof_capitalized_name$() {\n" - " this.$oneof_name$Case_ = 0;\n" - " this.$oneof_name$_ = null;\n" - " return this;\n" - "}\n"); - } - - // Lazy initialization of otherwise static final fields can help prevent the - // class initializer from being generated. We want to prevent it because it - // stops ProGuard from inlining any methods in this class into call sites and - // therefore reducing the method count. However, extensions are best kept as - // public static final fields with initializers, so with their existence we - // won't bother with lazy initialization. - bool lazy_init = descriptor_->extension_count() == 0; - - // Empty array - if (lazy_init) { - printer->Print( - "\n" - "private static volatile $classname$[] _emptyArray;\n" - "public static $classname$[] emptyArray() {\n" - " // Lazily initializes the empty array\n" - " if (_emptyArray == null) {\n" - " synchronized (\n" - " com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) {\n" - " if (_emptyArray == null) {\n" - " _emptyArray = new $classname$[0];\n" - " }\n" - " }\n" - " }\n" - " return _emptyArray;\n" - "}\n", - "classname", descriptor_->name()); - } else { - printer->Print( - "\n" - "private static final $classname$[] EMPTY_ARRAY = {};\n" - "public static $classname$[] emptyArray() {\n" - " return EMPTY_ARRAY;\n" - "}\n", - "classname", descriptor_->name()); - } - - // Integers for bit fields - int totalInts = (field_generators_.total_bits() + 31) / 32; - if (totalInts > 0) { - printer->Print("\n"); - for (int i = 0; i < totalInts; i++) { - printer->Print("private int $bit_field_name$;\n", - "bit_field_name", GetBitFieldName(i)); - } - } - - // Fields and maybe their default values - for (int i = 0; i < descriptor_->field_count(); i++) { - printer->Print("\n"); - PrintFieldComment(printer, descriptor_->field(i)); - field_generators_.get(descriptor_->field(i)).GenerateMembers( - printer, lazy_init); - } - - // Constructor, with lazy init code if needed - if (lazy_init && field_generators_.saved_defaults_needed()) { - printer->Print( - "\n" - "private static volatile boolean _classInitialized;\n" - "\n" - "public $classname$() {\n" - " // Lazily initializes the field defaults\n" - " if (!_classInitialized) {\n" - " synchronized (\n" - " com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) {\n" - " if (!_classInitialized) {\n", - "classname", descriptor_->name()); - printer->Indent(); - printer->Indent(); - printer->Indent(); - printer->Indent(); - for (int i = 0; i < descriptor_->field_count(); i++) { - field_generators_.get(descriptor_->field(i)) - .GenerateInitSavedDefaultCode(printer); - } - printer->Outdent(); - printer->Outdent(); - printer->Outdent(); - printer->Outdent(); - printer->Print( - " _classInitialized = true;\n" - " }\n" - " }\n" - " }\n"); - if (params_.generate_clear()) { - printer->Print(" clear();\n"); - } - printer->Print("}\n"); - } else { - printer->Print( - "\n" - "public $classname$() {\n", - "classname", descriptor_->name()); - if (params_.generate_clear()) { - printer->Print(" clear();\n"); - } else { - printer->Indent(); - GenerateFieldInitializers(printer); - printer->Outdent(); - } - printer->Print("}\n"); - } - - // Other methods in this class - - GenerateClear(printer); - - if (params_.generate_clone()) { - GenerateClone(printer); - } - - if (params_.generate_equals()) { - GenerateEquals(printer); - GenerateHashCode(printer); - } - - GenerateMessageSerializationMethods(printer); - GenerateMergeFromMethods(printer); - GenerateParseFromMethods(printer); - - printer->Outdent(); - printer->Print("}\n"); -} - -// =================================================================== - -void MessageGenerator:: -GenerateMessageSerializationMethods(io::Printer* printer) { - // Rely on the parent implementations of writeTo() and getSerializedSize() - // if there are no fields to serialize in this message. - if (descriptor_->field_count() == 0) { - return; - } - - std::unique_ptr<const FieldDescriptor*[]> sorted_fields( - SortFieldsByNumber(descriptor_)); - - printer->Print( - "\n" - "@Override\n" - "public void writeTo(com.google.protobuf.nano.CodedOutputByteBufferNano output)\n" - " throws java.io.IOException {\n"); - printer->Indent(); - - // Output the fields in sorted order - for (int i = 0; i < descriptor_->field_count(); i++) { - GenerateSerializeOneField(printer, sorted_fields[i]); - } - - // The parent implementation will write any unknown fields if necessary. - printer->Print( - "super.writeTo(output);\n"); - - printer->Outdent(); - printer->Print("}\n"); - - // The parent implementation will get the serialized size for unknown - // fields if necessary. - printer->Print( - "\n" - "@Override\n" - "protected int computeSerializedSize() {\n" - " int size = super.computeSerializedSize();\n"); - printer->Indent(); - - for (int i = 0; i < descriptor_->field_count(); i++) { - field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer); - } - - printer->Outdent(); - printer->Print( - " return size;\n" - "}\n"); -} - -void MessageGenerator::GenerateMergeFromMethods(io::Printer* printer) { - std::unique_ptr<const FieldDescriptor*[]> sorted_fields( - SortFieldsByNumber(descriptor_)); - - printer->Print( - "\n" - "@Override\n" - "public $classname$ mergeFrom(\n" - " com.google.protobuf.nano.CodedInputByteBufferNano input)\n" - " throws java.io.IOException {\n", - "classname", descriptor_->name()); - - printer->Indent(); - if (HasMapField(descriptor_)) { - printer->Print( - "com.google.protobuf.nano.MapFactories.MapFactory mapFactory =\n" - " com.google.protobuf.nano.MapFactories.getMapFactory();\n"); - } - - printer->Print( - "while (true) {\n"); - printer->Indent(); - - printer->Print( - "int tag = input.readTag();\n" - "switch (tag) {\n"); - printer->Indent(); - - printer->Print( - "case 0:\n" // zero signals EOF / limit reached - " return this;\n" - "default: {\n"); - - printer->Indent(); - if (params_.store_unknown_fields()) { - printer->Print( - "if (!storeUnknownField(input, tag)) {\n" - " return this;\n" - "}\n"); - } else { - printer->Print( - "if (!com.google.protobuf.nano.WireFormatNano.parseUnknownField(input, tag)) {\n" - " return this;\n" // it's an endgroup tag - "}\n"); - } - printer->Print("break;\n"); - printer->Outdent(); - printer->Print("}\n"); - - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = sorted_fields[i]; - uint32 tag = WireFormatLite::MakeTag(field->number(), - WireFormat::WireTypeForFieldType(field->type())); - - printer->Print( - "case $tag$: {\n", - "tag", SimpleItoa(tag)); - printer->Indent(); - - field_generators_.get(field).GenerateMergingCode(printer); - - printer->Outdent(); - printer->Print( - " break;\n" - "}\n"); - - if (field->is_packable()) { - // To make packed = true wire compatible, we generate parsing code from a - // packed version of this field regardless of field->options().packed(). - uint32 packed_tag = WireFormatLite::MakeTag(field->number(), - WireFormatLite::WIRETYPE_LENGTH_DELIMITED); - printer->Print( - "case $tag$: {\n", - "tag", SimpleItoa(packed_tag)); - printer->Indent(); - - field_generators_.get(field).GenerateMergingCodeFromPacked(printer); - - printer->Outdent(); - printer->Print( - " break;\n" - "}\n"); - } - } - - printer->Outdent(); - printer->Outdent(); - printer->Outdent(); - printer->Print( - " }\n" // switch (tag) - " }\n" // while (true) - "}\n"); -} - -void MessageGenerator:: -GenerateParseFromMethods(io::Printer* printer) { - // Note: These are separate from GenerateMessageSerializationMethods() - // because they need to be generated even for messages that are optimized - // for code size. - printer->Print( - "\n" - "public static $classname$ parseFrom(byte[] data)\n" - " throws com.google.protobuf.nano.InvalidProtocolBufferNanoException {\n" - " return com.google.protobuf.nano.MessageNano.mergeFrom(new $classname$(), data);\n" - "}\n" - "\n" - "public static $classname$ parseFrom(\n" - " com.google.protobuf.nano.CodedInputByteBufferNano input)\n" - " throws java.io.IOException {\n" - " return new $classname$().mergeFrom(input);\n" - "}\n", - "classname", descriptor_->name()); -} - -void MessageGenerator::GenerateSerializeOneField( - io::Printer* printer, const FieldDescriptor* field) { - field_generators_.get(field).GenerateSerializationCode(printer); -} - -void MessageGenerator::GenerateClear(io::Printer* printer) { - if (!params_.generate_clear()) { - return; - } - printer->Print( - "\n" - "public $classname$ clear() {\n", - "classname", descriptor_->name()); - printer->Indent(); - - GenerateFieldInitializers(printer); - - printer->Outdent(); - printer->Print( - " return this;\n" - "}\n"); -} - -void MessageGenerator::GenerateFieldInitializers(io::Printer* printer) { - // Clear bit fields. - int totalInts = (field_generators_.total_bits() + 31) / 32; - for (int i = 0; i < totalInts; i++) { - printer->Print("$bit_field_name$ = 0;\n", - "bit_field_name", GetBitFieldName(i)); - } - - // Call clear for all of the fields. - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = descriptor_->field(i); - field_generators_.get(field).GenerateClearCode(printer); - } - - // Clear oneofs. - for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { - printer->Print( - "clear$oneof_capitalized_name$();\n", - "oneof_capitalized_name", UnderscoresToCapitalizedCamelCase( - descriptor_->oneof_decl(i))); - } - - // Clear unknown fields. - if (params_.store_unknown_fields()) { - printer->Print("unknownFieldData = null;\n"); - } - printer->Print("cachedSize = -1;\n"); -} - -void MessageGenerator::GenerateClone(io::Printer* printer) { - printer->Print( - "@Override\n" - "public $classname$ clone() {\n", - "classname", descriptor_->name()); - printer->Indent(); - - printer->Print( - "$classname$ cloned;\n" - "try {\n" - " cloned = ($classname$) super.clone();\n" - "} catch (java.lang.CloneNotSupportedException e) {\n" - " throw new java.lang.AssertionError(e);\n" - "}\n", - "classname", descriptor_->name()); - - for (int i = 0; i < descriptor_->field_count(); i++) { - field_generators_.get(descriptor_->field(i)).GenerateFixClonedCode(printer); - } - - printer->Outdent(); - printer->Print( - " return cloned;\n" - "}\n" - "\n"); -} - -void MessageGenerator::GenerateEquals(io::Printer* printer) { - // Don't override if there are no fields. We could generate an - // equals method that compares types, but often empty messages - // are used as namespaces. - if (descriptor_->field_count() == 0 && !params_.store_unknown_fields()) { - return; - } - - printer->Print( - "\n" - "@Override\n" - "public boolean equals(Object o) {\n"); - printer->Indent(); - printer->Print( - "if (o == this) {\n" - " return true;\n" - "}\n" - "if (!(o instanceof $classname$)) {\n" - " return false;\n" - "}\n" - "$classname$ other = ($classname$) o;\n", - "classname", descriptor_->name()); - - // Checking oneof case before checking each oneof field. - for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { - const OneofDescriptor* oneof_desc = descriptor_->oneof_decl(i); - printer->Print( - "if (this.$oneof_name$Case_ != other.$oneof_name$Case_) {\n" - " return false;\n" - "}\n", - "oneof_name", UnderscoresToCamelCase(oneof_desc)); - } - - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = descriptor_->field(i); - field_generators_.get(field).GenerateEqualsCode(printer); - } - - if (params_.store_unknown_fields()) { - printer->Print( - "if (unknownFieldData == null || unknownFieldData.isEmpty()) {\n" - " return other.unknownFieldData == null || other.unknownFieldData.isEmpty();\n" - "} else {\n" - " return unknownFieldData.equals(other.unknownFieldData);\n" - "}"); - } else { - printer->Print( - "return true;\n"); - } - - printer->Outdent(); - printer->Print("}\n"); -} - -void MessageGenerator::GenerateHashCode(io::Printer* printer) { - if (descriptor_->field_count() == 0 && !params_.store_unknown_fields()) { - return; - } - - printer->Print( - "\n" - "@Override\n" - "public int hashCode() {\n"); - printer->Indent(); - - printer->Print("int result = 17;\n"); - printer->Print("result = 31 * result + getClass().getName().hashCode();\n"); - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = descriptor_->field(i); - field_generators_.get(field).GenerateHashCodeCode(printer); - } - - if (params_.store_unknown_fields()) { - printer->Print( - "result = 31 * result + \n" - " (unknownFieldData == null || unknownFieldData.isEmpty() ? 0 : \n" - " unknownFieldData.hashCode());\n"); - } - - printer->Print("return result;\n"); - - printer->Outdent(); - printer->Print("}\n"); -} - -// =================================================================== - -} // namespace javanano -} // namespace compiler -} // namespace protobuf -} // namespace google |