Merge "Add an option to inspect "has" state upon parse."
This commit is contained in:
commit
064b60c659
@ -301,6 +301,22 @@ message's constructor or clear() function is called, the default value
|
|||||||
penalty. This is not a problem if the field has no default or is an
|
penalty. This is not a problem if the field has no default or is an
|
||||||
empty default.
|
empty default.
|
||||||
|
|
||||||
|
Nano Generator options
|
||||||
|
|
||||||
|
java_nano_generate_has:
|
||||||
|
If true, generates a public boolean variable has<fieldname>
|
||||||
|
accompanying the optional or required field (not present for
|
||||||
|
repeated fields, groups or messages). It is set to false initially
|
||||||
|
and upon clear(). If parseFrom(...) reads the field from the wire,
|
||||||
|
it is set to true. This is a way for clients to inspect the "has"
|
||||||
|
value upon parse. If it is set to true, writeTo(...) will ALWAYS
|
||||||
|
output that field (even if field value is equal to its
|
||||||
|
default).
|
||||||
|
|
||||||
|
IMPORTANT: This option costs an extra 4 bytes per primitive field in
|
||||||
|
the message. Think carefully about whether you really need this. In
|
||||||
|
many cases reading the default works and determining whether the
|
||||||
|
field was received over the wire is irrelevant.
|
||||||
|
|
||||||
To use nano protobufs:
|
To use nano protobufs:
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ import com.google.protobuf.nano.InternalNano;
|
|||||||
import com.google.protobuf.nano.MessageNano;
|
import com.google.protobuf.nano.MessageNano;
|
||||||
import com.google.protobuf.nano.MultipleImportingNonMultipleNano1;
|
import com.google.protobuf.nano.MultipleImportingNonMultipleNano1;
|
||||||
import com.google.protobuf.nano.MultipleImportingNonMultipleNano2;
|
import com.google.protobuf.nano.MultipleImportingNonMultipleNano2;
|
||||||
|
import com.google.protobuf.nano.NanoHasOuterClass.TestAllTypesNanoHas;
|
||||||
import com.google.protobuf.nano.NanoOuterClass;
|
import com.google.protobuf.nano.NanoOuterClass;
|
||||||
import com.google.protobuf.nano.NanoOuterClass.TestAllTypesNano;
|
import com.google.protobuf.nano.NanoOuterClass.TestAllTypesNano;
|
||||||
import com.google.protobuf.nano.RecursiveMessageNano;
|
import com.google.protobuf.nano.RecursiveMessageNano;
|
||||||
@ -2095,6 +2096,93 @@ public class NanoTest extends TestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testNanoWithHasParseFrom() throws Exception {
|
||||||
|
TestAllTypesNanoHas msg = null;
|
||||||
|
// Test false on creation, after clear and upon empty parse.
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
if (i == 0) {
|
||||||
|
msg = new TestAllTypesNanoHas();
|
||||||
|
} else if (i == 1) {
|
||||||
|
msg.clear();
|
||||||
|
} else if (i == 2) {
|
||||||
|
msg = TestAllTypesNanoHas.parseFrom(new byte[0]);
|
||||||
|
}
|
||||||
|
assertFalse(msg.hasOptionalInt32);
|
||||||
|
assertFalse(msg.hasOptionalString);
|
||||||
|
assertFalse(msg.hasOptionalBytes);
|
||||||
|
assertFalse(msg.hasOptionalNestedEnum);
|
||||||
|
assertFalse(msg.hasDefaultInt32);
|
||||||
|
assertFalse(msg.hasDefaultString);
|
||||||
|
assertFalse(msg.hasDefaultBytes);
|
||||||
|
assertFalse(msg.hasDefaultFloatNan);
|
||||||
|
assertFalse(msg.hasDefaultNestedEnum);
|
||||||
|
assertFalse(msg.hasId);
|
||||||
|
msg.optionalInt32 = 123;
|
||||||
|
msg.optionalNestedMessage = new TestAllTypesNanoHas.NestedMessage();
|
||||||
|
msg.optionalNestedMessage.bb = 2;
|
||||||
|
msg.optionalNestedEnum = TestAllTypesNano.BAZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte [] result = MessageNano.toByteArray(msg);
|
||||||
|
int msgSerializedSize = msg.getSerializedSize();
|
||||||
|
//System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
|
||||||
|
assertTrue(msgSerializedSize == 13);
|
||||||
|
assertEquals(result.length, msgSerializedSize);
|
||||||
|
|
||||||
|
// Has fields true upon parse.
|
||||||
|
TestAllTypesNanoHas newMsg = TestAllTypesNanoHas.parseFrom(result);
|
||||||
|
assertEquals(123, newMsg.optionalInt32);
|
||||||
|
assertTrue(newMsg.hasOptionalInt32);
|
||||||
|
assertEquals(2, newMsg.optionalNestedMessage.bb);
|
||||||
|
assertTrue(newMsg.optionalNestedMessage.hasBb);
|
||||||
|
assertEquals(TestAllTypesNanoHas.BAZ, newMsg.optionalNestedEnum);
|
||||||
|
assertTrue(newMsg.hasOptionalNestedEnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNanoWithHasSerialize() throws Exception {
|
||||||
|
TestAllTypesNanoHas msg = new TestAllTypesNanoHas();
|
||||||
|
msg.hasOptionalInt32 = true;
|
||||||
|
msg.hasOptionalString = true;
|
||||||
|
msg.hasOptionalBytes = true;
|
||||||
|
msg.optionalNestedMessage = new TestAllTypesNanoHas.NestedMessage();
|
||||||
|
msg.optionalNestedMessage.hasBb = true;
|
||||||
|
msg.hasOptionalNestedEnum = true;
|
||||||
|
msg.hasDefaultInt32 = true;
|
||||||
|
msg.hasDefaultString = true;
|
||||||
|
msg.hasDefaultBytes = true;
|
||||||
|
msg.hasDefaultFloatNan = true;
|
||||||
|
msg.hasDefaultNestedEnum = true;
|
||||||
|
|
||||||
|
byte [] result = MessageNano.toByteArray(msg);
|
||||||
|
int msgSerializedSize = msg.getSerializedSize();
|
||||||
|
assertEquals(result.length, msgSerializedSize);
|
||||||
|
|
||||||
|
// Now deserialize and find that all fields are set and equal to their defaults.
|
||||||
|
TestAllTypesNanoHas newMsg = TestAllTypesNanoHas.parseFrom(result);
|
||||||
|
assertTrue(newMsg.hasOptionalInt32);
|
||||||
|
assertTrue(newMsg.hasOptionalString);
|
||||||
|
assertTrue(newMsg.hasOptionalBytes);
|
||||||
|
assertTrue(newMsg.optionalNestedMessage.hasBb);
|
||||||
|
assertTrue(newMsg.hasOptionalNestedEnum);
|
||||||
|
assertTrue(newMsg.hasDefaultInt32);
|
||||||
|
assertTrue(newMsg.hasDefaultString);
|
||||||
|
assertTrue(newMsg.hasDefaultBytes);
|
||||||
|
assertTrue(newMsg.hasDefaultFloatNan);
|
||||||
|
assertTrue(newMsg.hasDefaultNestedEnum);
|
||||||
|
assertTrue(newMsg.hasId);
|
||||||
|
assertEquals(0, newMsg.optionalInt32);
|
||||||
|
assertEquals(0, newMsg.optionalString.length());
|
||||||
|
assertEquals(0, newMsg.optionalBytes.length);
|
||||||
|
assertEquals(0, newMsg.optionalNestedMessage.bb);
|
||||||
|
assertEquals(TestAllTypesNanoHas.FOO, newMsg.optionalNestedEnum);
|
||||||
|
assertEquals(41, newMsg.defaultInt32);
|
||||||
|
assertEquals("hello", newMsg.defaultString);
|
||||||
|
assertEquals("world", new String(newMsg.defaultBytes, "UTF-8"));
|
||||||
|
assertEquals(TestAllTypesNanoHas.BAR, newMsg.defaultNestedEnum);
|
||||||
|
assertEquals(Float.NaN, newMsg.defaultFloatNan);
|
||||||
|
assertEquals(0, newMsg.id);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that fields with a default value of NaN are not serialized when
|
* Tests that fields with a default value of NaN are not serialized when
|
||||||
* set to NaN. This is a special case as NaN != NaN, so normal equality
|
* set to NaN. This is a special case as NaN != NaN, so normal equality
|
||||||
|
@ -82,12 +82,22 @@ void EnumFieldGenerator::
|
|||||||
GenerateMembers(io::Printer* printer) const {
|
GenerateMembers(io::Printer* printer) const {
|
||||||
printer->Print(variables_,
|
printer->Print(variables_,
|
||||||
"public int $name$ = $default$;\n");
|
"public int $name$ = $default$;\n");
|
||||||
|
|
||||||
|
if (params_.generate_has()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"public boolean has$capitalized_name$ = false;\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnumFieldGenerator::
|
void EnumFieldGenerator::
|
||||||
GenerateParsingCode(io::Printer* printer) const {
|
GenerateParsingCode(io::Printer* printer) const {
|
||||||
printer->Print(variables_,
|
printer->Print(variables_,
|
||||||
" this.$name$ = input.readInt32();\n");
|
" this.$name$ = input.readInt32();\n");
|
||||||
|
|
||||||
|
if (params_.generate_has()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
" has$capitalized_name$ = true;\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnumFieldGenerator::
|
void EnumFieldGenerator::
|
||||||
@ -96,8 +106,14 @@ GenerateSerializationCode(io::Printer* printer) const {
|
|||||||
printer->Print(variables_,
|
printer->Print(variables_,
|
||||||
"output.writeInt32($number$, this.$name$);\n");
|
"output.writeInt32($number$, this.$name$);\n");
|
||||||
} else {
|
} else {
|
||||||
|
if (params_.generate_has()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (this.$name$ != $default$ || has$capitalized_name$) {\n");
|
||||||
|
} else {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (this.$name$ != $default$) {\n");
|
||||||
|
}
|
||||||
printer->Print(variables_,
|
printer->Print(variables_,
|
||||||
"if (this.$name$ != $default$) {\n"
|
|
||||||
" output.writeInt32($number$, this.$name$);\n"
|
" output.writeInt32($number$, this.$name$);\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
}
|
}
|
||||||
@ -110,8 +126,14 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
|
|||||||
"size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
|
"size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
|
||||||
" .computeInt32Size($number$, this.$name$);\n");
|
" .computeInt32Size($number$, this.$name$);\n");
|
||||||
} else {
|
} else {
|
||||||
|
if (params_.generate_has()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (this.$name$ != $default$ || has$capitalized_name$) {\n");
|
||||||
|
} else {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (this.$name$ != $default$) {\n");
|
||||||
|
}
|
||||||
printer->Print(variables_,
|
printer->Print(variables_,
|
||||||
"if (this.$name$ != $default$) {\n"
|
|
||||||
" size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
|
" size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
|
||||||
" .computeInt32Size($number$, this.$name$);\n"
|
" .computeInt32Size($number$, this.$name$);\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
|
@ -118,6 +118,8 @@ bool JavaNanoGenerator::Generate(const FileDescriptor* file,
|
|||||||
params.set_store_unknown_fields(options[i].second == "true");
|
params.set_store_unknown_fields(options[i].second == "true");
|
||||||
} else if (options[i].first == "java_multiple_files") {
|
} else if (options[i].first == "java_multiple_files") {
|
||||||
params.set_override_java_multiple_files(options[i].second == "true");
|
params.set_override_java_multiple_files(options[i].second == "true");
|
||||||
|
} else if (options[i].first == "java_nano_generate_has") {
|
||||||
|
params.set_generate_has(options[i].second == "true");
|
||||||
} else {
|
} else {
|
||||||
*error = "Ignore unknown javanano generator option: " + options[i].first;
|
*error = "Ignore unknown javanano generator option: " + options[i].first;
|
||||||
}
|
}
|
||||||
|
@ -406,6 +406,15 @@ void MessageGenerator::GenerateClear(io::Printer* printer) {
|
|||||||
"name", RenameJavaKeywords(UnderscoresToCamelCase(field)),
|
"name", RenameJavaKeywords(UnderscoresToCamelCase(field)),
|
||||||
"default", DefaultValue(params_, field));
|
"default", DefaultValue(params_, field));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (params_.generate_has() &&
|
||||||
|
field->label() != FieldDescriptor::LABEL_REPEATED &&
|
||||||
|
field->type() != FieldDescriptor::TYPE_GROUP &&
|
||||||
|
field->type() != FieldDescriptor::TYPE_MESSAGE) {
|
||||||
|
printer->Print(
|
||||||
|
"has$capitalized_name$ = false;\n",
|
||||||
|
"capitalized_name", UnderscoresToCapitalizedCamelCase(field));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear unknown fields.
|
// Clear unknown fields.
|
||||||
|
@ -57,13 +57,15 @@ class Params {
|
|||||||
NameMap java_packages_;
|
NameMap java_packages_;
|
||||||
NameMap java_outer_classnames_;
|
NameMap java_outer_classnames_;
|
||||||
NameSet java_multiple_files_;
|
NameSet java_multiple_files_;
|
||||||
|
bool generate_has_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Params(const string & base_name) :
|
Params(const string & base_name) :
|
||||||
empty_(""),
|
empty_(""),
|
||||||
base_name_(base_name),
|
base_name_(base_name),
|
||||||
override_java_multiple_files_(JAVANANO_MUL_UNSET),
|
override_java_multiple_files_(JAVANANO_MUL_UNSET),
|
||||||
store_unknown_fields_(false) {
|
store_unknown_fields_(false),
|
||||||
|
generate_has_(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const string& base_name() const {
|
const string& base_name() const {
|
||||||
@ -151,6 +153,13 @@ class Params {
|
|||||||
return store_unknown_fields_;
|
return store_unknown_fields_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_generate_has(bool value) {
|
||||||
|
generate_has_ = value;
|
||||||
|
}
|
||||||
|
bool generate_has() const {
|
||||||
|
return generate_has_;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace javanano
|
} // namespace javanano
|
||||||
|
@ -321,12 +321,46 @@ GenerateMembers(io::Printer* printer) const {
|
|||||||
printer->Print(variables_,
|
printer->Print(variables_,
|
||||||
"public $type$ $name$ = $default$;\n");
|
"public $type$ $name$ = $default$;\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (params_.generate_has()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"public boolean has$capitalized_name$ = false;\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrimitiveFieldGenerator::
|
void PrimitiveFieldGenerator::
|
||||||
GenerateParsingCode(io::Printer* printer) const {
|
GenerateParsingCode(io::Printer* printer) const {
|
||||||
printer->Print(variables_,
|
printer->Print(variables_,
|
||||||
"this.$name$ = input.read$capitalized_type$();\n");
|
"this.$name$ = input.read$capitalized_type$();\n");
|
||||||
|
|
||||||
|
if (params_.generate_has()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"has$capitalized_name$ = true;\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitiveFieldGenerator::
|
||||||
|
GenerateSerializationConditional(io::Printer* printer) const {
|
||||||
|
if (params_.generate_has()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (has$capitalized_name$ || ");
|
||||||
|
} else {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (");
|
||||||
|
}
|
||||||
|
if (IsArrayType(GetJavaType(descriptor_))) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"!java.util.Arrays.equals(this.$name$, $default$)) {\n");
|
||||||
|
} else if (IsReferenceType(GetJavaType(descriptor_))) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"!this.$name$.equals($default$)) {\n");
|
||||||
|
} else if (IsDefaultNaN(descriptor_)) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"!$capitalized_type$.isNaN(this.$name$)) {\n");
|
||||||
|
} else {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"this.$name$ != $default$) {\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrimitiveFieldGenerator::
|
void PrimitiveFieldGenerator::
|
||||||
@ -335,20 +369,7 @@ GenerateSerializationCode(io::Printer* printer) const {
|
|||||||
printer->Print(variables_,
|
printer->Print(variables_,
|
||||||
"output.write$capitalized_type$($number$, this.$name$);\n");
|
"output.write$capitalized_type$($number$, this.$name$);\n");
|
||||||
} else {
|
} else {
|
||||||
if (IsArrayType(GetJavaType(descriptor_))) {
|
GenerateSerializationConditional(printer);
|
||||||
printer->Print(variables_,
|
|
||||||
"if (!java.util.Arrays.equals(this.$name$, $default$)) {\n");
|
|
||||||
} else if (IsReferenceType(GetJavaType(descriptor_))) {
|
|
||||||
printer->Print(variables_,
|
|
||||||
"if (!this.$name$.equals($default$)) {\n");
|
|
||||||
} else if (IsDefaultNaN(descriptor_)) {
|
|
||||||
printer->Print(variables_,
|
|
||||||
"if (!$capitalized_type$.isNaN(this.$name$)) {\n");
|
|
||||||
} else {
|
|
||||||
printer->Print(variables_,
|
|
||||||
"if (this.$name$ != $default$) {\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
printer->Print(variables_,
|
printer->Print(variables_,
|
||||||
" output.write$capitalized_type$($number$, this.$name$);\n"
|
" output.write$capitalized_type$($number$, this.$name$);\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
@ -362,20 +383,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
|
|||||||
"size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
|
"size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
|
||||||
" .compute$capitalized_type$Size($number$, this.$name$);\n");
|
" .compute$capitalized_type$Size($number$, this.$name$);\n");
|
||||||
} else {
|
} else {
|
||||||
if (IsArrayType(GetJavaType(descriptor_))) {
|
GenerateSerializationConditional(printer);
|
||||||
printer->Print(variables_,
|
|
||||||
"if (!java.util.Arrays.equals(this.$name$, $default$)) {\n");
|
|
||||||
} else if (IsReferenceType(GetJavaType(descriptor_))) {
|
|
||||||
printer->Print(variables_,
|
|
||||||
"if (!this.$name$.equals($default$)) {\n");
|
|
||||||
} else if (IsDefaultNaN(descriptor_)) {
|
|
||||||
printer->Print(variables_,
|
|
||||||
"if (!$capitalized_type$.isNaN(this.$name$)) {\n");
|
|
||||||
} else {
|
|
||||||
printer->Print(variables_,
|
|
||||||
"if (this.$name$ != $default$) {\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
printer->Print(variables_,
|
printer->Print(variables_,
|
||||||
" size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
|
" size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
|
||||||
" .compute$capitalized_type$Size($number$, this.$name$);\n"
|
" .compute$capitalized_type$Size($number$, this.$name$);\n"
|
||||||
|
@ -58,6 +58,8 @@ class PrimitiveFieldGenerator : public FieldGenerator {
|
|||||||
string GetBoxedType() const;
|
string GetBoxedType() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void GenerateSerializationConditional(io::Printer* printer) const;
|
||||||
|
|
||||||
const FieldDescriptor* descriptor_;
|
const FieldDescriptor* descriptor_;
|
||||||
map<string, string> variables_;
|
map<string, string> variables_;
|
||||||
|
|
||||||
|
78
src/google/protobuf/unittest_has_nano.proto
Normal file
78
src/google/protobuf/unittest_has_nano.proto
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
// 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: ulas@google.com (Ulas Kirazci)
|
||||||
|
|
||||||
|
package protobuf_unittest;
|
||||||
|
|
||||||
|
option java_package = "com.google.protobuf.nano";
|
||||||
|
option java_outer_classname = "NanoHasOuterClass";
|
||||||
|
|
||||||
|
message TestAllTypesNanoHas {
|
||||||
|
|
||||||
|
message NestedMessage {
|
||||||
|
optional int32 bb = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum NestedEnum {
|
||||||
|
FOO = 1;
|
||||||
|
BAR = 2;
|
||||||
|
BAZ = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Singular
|
||||||
|
optional int32 optional_int32 = 1;
|
||||||
|
optional string optional_string = 14;
|
||||||
|
optional bytes optional_bytes = 15;
|
||||||
|
|
||||||
|
optional NestedMessage optional_nested_message = 18;
|
||||||
|
|
||||||
|
optional NestedEnum optional_nested_enum = 21;
|
||||||
|
|
||||||
|
// Repeated
|
||||||
|
repeated int32 repeated_int32 = 31;
|
||||||
|
repeated string repeated_string = 44;
|
||||||
|
repeated bytes repeated_bytes = 45;
|
||||||
|
|
||||||
|
repeated NestedMessage repeated_nested_message = 48;
|
||||||
|
|
||||||
|
repeated NestedEnum repeated_nested_enum = 51;
|
||||||
|
|
||||||
|
// Singular with defaults
|
||||||
|
optional int32 default_int32 = 61 [default = 41 ];
|
||||||
|
optional string default_string = 74 [default = "hello"];
|
||||||
|
optional bytes default_bytes = 75 [default = "world"];
|
||||||
|
|
||||||
|
optional float default_float_nan = 99 [default = nan];
|
||||||
|
|
||||||
|
optional NestedEnum default_nested_enum = 81 [default = BAR];
|
||||||
|
|
||||||
|
required int32 id = 86;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user