diff options
author | Jakob Buchgraber <buchgr@google.com> | 2017-04-26 15:37:42 +0200 |
---|---|---|
committer | Jakob Buchgraber <buchgr@google.com> | 2017-05-02 09:51:34 +0200 |
commit | 2b49f678a7dfaf27afc0e44ed7a65b00ec06d413 (patch) | |
tree | c1c46d0f1f66859ff42fd41f0aefb6436c9f4507 /third_party/protobuf/3.2.0/src/google/protobuf/compiler/javanano/javanano_message.cc | |
parent | b712f335a945c81a6b77fd48e96103ff09c8967b (diff) |
Update third_party/protobuf to pre-release 3.2.0
Update protobuf to @laszlocsomor's fork of protobuf. This is essentially
the development version of protobuf 3.2.0 and windows specific fixes
from laszlo. Those fixes will be merged into protobuf soon:
https://github.com/google/protobuf/pull/2969.
Change-Id: Id88cd7e5b2c27ab74f3ecfa1e127e5a863f2deb3
Diffstat (limited to 'third_party/protobuf/3.2.0/src/google/protobuf/compiler/javanano/javanano_message.cc')
-rw-r--r-- | third_party/protobuf/3.2.0/src/google/protobuf/compiler/javanano/javanano_message.cc | 676 |
1 files changed, 676 insertions, 0 deletions
diff --git a/third_party/protobuf/3.2.0/src/google/protobuf/compiler/javanano/javanano_message.cc b/third_party/protobuf/3.2.0/src/google/protobuf/compiler/javanano/javanano_message.cc new file mode 100644 index 0000000000..a41da5ae33 --- /dev/null +++ b/third_party/protobuf/3.2.0/src/google/protobuf/compiler/javanano/javanano_message.cc @@ -0,0 +1,676 @@ +// 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); + } + 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 + 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; + } + + scoped_array<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) { + scoped_array<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 |