Merge remote-tracking branch 'refs/remotes/google/master'
This commit is contained in:
commit
2b22b611a8
2
.gitignore
vendored
2
.gitignore
vendored
@ -111,5 +111,7 @@ conformance/conformance.pb.h
|
||||
conformance/Conformance.pbobjc.h
|
||||
conformance/Conformance.pbobjc.m
|
||||
conformance/conformance.rb
|
||||
conformance/google/
|
||||
conformance/javac_middleman
|
||||
conformance/lite/
|
||||
conformance/protoc_middleman
|
||||
|
11
.travis.yml
11
.travis.yml
@ -10,7 +10,7 @@ os:
|
||||
# The Objective C build needs Xcode 7.0 or later.
|
||||
osx_image: xcode7.2
|
||||
script:
|
||||
- ./travis.sh $CONFIG
|
||||
- ./tests.sh $CONFIG
|
||||
env:
|
||||
- CONFIG=cpp
|
||||
- CONFIG=cpp_distcheck
|
||||
@ -71,5 +71,14 @@ matrix:
|
||||
# we moved to an OS X image that is 10.11.
|
||||
- os: osx
|
||||
env: CONFIG=python_cpp
|
||||
# xctool 0.2.8 seems to have a bug where it randomly kills tests saying
|
||||
# they failed.
|
||||
# https://github.com/facebook/xctool/issues/619
|
||||
# https://github.com/google/protobuf/issues/1232
|
||||
# travis updated their images to include 0.2.8:
|
||||
# https://blog.travis-ci.com/2016-03-23-xcode-image-updates
|
||||
# Mark the iOS test as flakey so these failures don't turn things red.
|
||||
- os: osx
|
||||
env: CONFIG=objectivec_ios
|
||||
notifications:
|
||||
email: false
|
||||
|
98
BUILD
98
BUILD
@ -15,16 +15,58 @@ COPTS = [
|
||||
"-Wno-error=unused-function",
|
||||
]
|
||||
|
||||
# Bazel should provide portable link_opts for pthread.
|
||||
LINK_OPTS = ["-lpthread"]
|
||||
config_setting(
|
||||
name = "android",
|
||||
values = {
|
||||
"crosstool_top": "//external:android/crosstool",
|
||||
},
|
||||
)
|
||||
|
||||
# Android builds do not need to link in a separate pthread library.
|
||||
LINK_OPTS = select({
|
||||
":android": [],
|
||||
"//conditions:default": ["-lpthread"],
|
||||
})
|
||||
|
||||
load(
|
||||
"protobuf",
|
||||
"cc_proto_library",
|
||||
"py_proto_library",
|
||||
"internal_gen_well_known_protos_java",
|
||||
"internal_protobuf_py_tests",
|
||||
)
|
||||
|
||||
config_setting(
|
||||
name = "ios_armv7",
|
||||
values = {
|
||||
"ios_cpu": "armv7",
|
||||
},
|
||||
)
|
||||
|
||||
config_setting(
|
||||
name = "ios_armv7s",
|
||||
values = {
|
||||
"ios_cpu": "armv7s",
|
||||
},
|
||||
)
|
||||
|
||||
config_setting(
|
||||
name = "ios_arm64",
|
||||
values = {
|
||||
"ios_cpu": "arm64",
|
||||
},
|
||||
)
|
||||
|
||||
IOS_ARM_COPTS = COPTS + [
|
||||
"-DOS_IOS",
|
||||
"-miphoneos-version-min=7.0",
|
||||
"-arch armv7",
|
||||
"-arch armv7s",
|
||||
"-arch arm64",
|
||||
"-D__thread=",
|
||||
"-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.2.sdk/",
|
||||
]
|
||||
|
||||
cc_library(
|
||||
name = "protobuf_lite",
|
||||
srcs = [
|
||||
@ -54,7 +96,12 @@ cc_library(
|
||||
"src/google/protobuf/wire_format_lite.cc",
|
||||
],
|
||||
hdrs = glob(["src/google/protobuf/**/*.h"]),
|
||||
copts = COPTS,
|
||||
copts = select({
|
||||
":ios_armv7": IOS_ARM_COPTS,
|
||||
":ios_armv7s": IOS_ARM_COPTS,
|
||||
":ios_arm64": IOS_ARM_COPTS,
|
||||
"//conditions:default": COPTS,
|
||||
}),
|
||||
includes = ["src/"],
|
||||
linkopts = LINK_OPTS,
|
||||
visibility = ["//visibility:public"],
|
||||
@ -119,7 +166,12 @@ cc_library(
|
||||
"src/google/protobuf/wrappers.pb.cc",
|
||||
],
|
||||
hdrs = glob(["src/**/*.h"]),
|
||||
copts = COPTS,
|
||||
copts = select({
|
||||
":ios_armv7": IOS_ARM_COPTS,
|
||||
":ios_armv7s": IOS_ARM_COPTS,
|
||||
":ios_arm64": IOS_ARM_COPTS,
|
||||
"//conditions:default": COPTS,
|
||||
}),
|
||||
includes = ["src/"],
|
||||
linkopts = LINK_OPTS,
|
||||
visibility = ["//visibility:public"],
|
||||
@ -152,6 +204,12 @@ RELATIVE_WELL_KNOWN_PROTOS = [
|
||||
|
||||
WELL_KNOWN_PROTOS = ["src/" + s for s in RELATIVE_WELL_KNOWN_PROTOS]
|
||||
|
||||
filegroup(
|
||||
name = "well_known_protos",
|
||||
srcs = WELL_KNOWN_PROTOS,
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
cc_proto_library(
|
||||
name = "cc_wkt_protos",
|
||||
srcs = WELL_KNOWN_PROTOS,
|
||||
@ -208,6 +266,7 @@ cc_library(
|
||||
"src/google/protobuf/compiler/java/java_enum_field_lite.cc",
|
||||
"src/google/protobuf/compiler/java/java_enum_lite.cc",
|
||||
"src/google/protobuf/compiler/java/java_extension.cc",
|
||||
"src/google/protobuf/compiler/java/java_extension_lite.cc",
|
||||
"src/google/protobuf/compiler/java/java_field.cc",
|
||||
"src/google/protobuf/compiler/java/java_file.cc",
|
||||
"src/google/protobuf/compiler/java/java_generator.cc",
|
||||
@ -318,6 +377,8 @@ RELATIVE_TEST_PROTOS = [
|
||||
"google/protobuf/unittest_preserve_unknown_enum.proto",
|
||||
"google/protobuf/unittest_preserve_unknown_enum2.proto",
|
||||
"google/protobuf/unittest_proto3_arena.proto",
|
||||
"google/protobuf/unittest_proto3_arena_lite.proto",
|
||||
"google/protobuf/unittest_proto3_lite.proto",
|
||||
"google/protobuf/unittest_well_known_types.proto",
|
||||
"google/protobuf/util/internal/testdata/anys.proto",
|
||||
"google/protobuf/util/internal/testdata/books.proto",
|
||||
@ -378,6 +439,7 @@ cc_test(
|
||||
"src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc",
|
||||
"src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc",
|
||||
"src/google/protobuf/compiler/cpp/cpp_unittest.cc",
|
||||
"src/google/protobuf/compiler/cpp/metadata_test.cc",
|
||||
"src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc",
|
||||
"src/google/protobuf/compiler/importer_unittest.cc",
|
||||
"src/google/protobuf/compiler/java/java_doc_comment_unittest.cc",
|
||||
@ -402,7 +464,9 @@ cc_test(
|
||||
"src/google/protobuf/message_unittest.cc",
|
||||
"src/google/protobuf/no_field_presence_test.cc",
|
||||
"src/google/protobuf/preserve_unknown_enum_test.cc",
|
||||
"src/google/protobuf/proto3_arena_lite_unittest.cc",
|
||||
"src/google/protobuf/proto3_arena_unittest.cc",
|
||||
"src/google/protobuf/proto3_lite_unittest.cc",
|
||||
"src/google/protobuf/reflection_ops_unittest.cc",
|
||||
"src/google/protobuf/repeated_field_reflection_unittest.cc",
|
||||
"src/google/protobuf/repeated_field_unittest.cc",
|
||||
@ -457,16 +521,8 @@ cc_test(
|
||||
################################################################################
|
||||
# Java support
|
||||
################################################################################
|
||||
genrule(
|
||||
name = "gen_well_known_protos_java",
|
||||
internal_gen_well_known_protos_java(
|
||||
srcs = WELL_KNOWN_PROTOS,
|
||||
outs = [
|
||||
"wellknown.srcjar",
|
||||
],
|
||||
cmd = "$(location :protoc) --java_out=$(@D)/wellknown.jar" +
|
||||
" -Isrc $(SRCS) " +
|
||||
" && mv $(@D)/wellknown.jar $(@D)/wellknown.srcjar",
|
||||
tools = [":protoc"],
|
||||
)
|
||||
|
||||
java_library(
|
||||
@ -479,6 +535,19 @@ java_library(
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
java_library(
|
||||
name = "protobuf_java_util",
|
||||
srcs = glob([
|
||||
"java/util/src/main/java/com/google/protobuf/util/*.java",
|
||||
]),
|
||||
deps = [
|
||||
"protobuf_java",
|
||||
"//external:gson",
|
||||
"//external:guava",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
################################################################################
|
||||
# Python support
|
||||
################################################################################
|
||||
@ -495,6 +564,7 @@ py_library(
|
||||
"python/google/protobuf/internal/test_util.py",
|
||||
],
|
||||
),
|
||||
srcs_version = "PY2AND3",
|
||||
imports = ["python"],
|
||||
)
|
||||
|
||||
@ -579,6 +649,7 @@ py_proto_library(
|
||||
include = "src",
|
||||
default_runtime = "",
|
||||
protoc = ":protoc",
|
||||
srcs_version = "PY2AND3",
|
||||
deps = [":protobuf_python"],
|
||||
)
|
||||
|
||||
@ -591,6 +662,7 @@ py_proto_library(
|
||||
include = "python",
|
||||
default_runtime = ":protobuf_python",
|
||||
protoc = ":protoc",
|
||||
srcs_version = "PY2AND3",
|
||||
deps = [":python_common_test_protos"],
|
||||
)
|
||||
|
||||
|
19
Makefile.am
19
Makefile.am
@ -9,7 +9,7 @@ AUTOMAKE_OPTIONS = foreign
|
||||
SUBDIRS = . src
|
||||
|
||||
# Always include gmock in distributions.
|
||||
DIST_SUBDIRS = $(subdirs) src conformance
|
||||
DIST_SUBDIRS = $(subdirs) src conformance benchmarks
|
||||
|
||||
# Build gmock before we build protobuf tests. We don't add gmock to SUBDIRS
|
||||
# because then "make check" would also build and run all of gmock's own tests,
|
||||
@ -36,6 +36,10 @@ clean-local:
|
||||
echo "Making clean in conformance"; \
|
||||
cd conformance && $(MAKE) $(AM_MAKEFLAGS) clean; \
|
||||
fi; \
|
||||
if test -e benchmarks/Makefile; then \
|
||||
echo "Making clean in benchmarks"; \
|
||||
cd benchmarks && $(MAKE) $(AM_MAKEFLAGS) clean; \
|
||||
fi; \
|
||||
if test -e objectivec/DevTools; then \
|
||||
echo "Cleaning any ObjC pyc files"; \
|
||||
rm -f objectivec/DevTools/*.pyc; \
|
||||
@ -154,6 +158,7 @@ csharp_EXTRA_DIST= \
|
||||
csharp/src/Google.Protobuf/Reflection/MethodDescriptor.cs \
|
||||
csharp/src/Google.Protobuf/Reflection/OneofAccessor.cs \
|
||||
csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs \
|
||||
csharp/src/Google.Protobuf/Reflection/OriginalNameAttribute.cs \
|
||||
csharp/src/Google.Protobuf/Reflection/PackageDescriptor.cs \
|
||||
csharp/src/Google.Protobuf/Reflection/PartialClasses.cs \
|
||||
csharp/src/Google.Protobuf/Reflection/ReflectionUtil.cs \
|
||||
@ -193,6 +198,8 @@ java_EXTRA_DIST=
|
||||
java/core/src/main/java/com/google/protobuf/BlockingRpcChannel.java \
|
||||
java/core/src/main/java/com/google/protobuf/BlockingService.java \
|
||||
java/core/src/main/java/com/google/protobuf/BooleanArrayList.java \
|
||||
java/core/src/main/java/com/google/protobuf/ByteBufferWriter.java \
|
||||
java/core/src/main/java/com/google/protobuf/ByteOutput.java \
|
||||
java/core/src/main/java/com/google/protobuf/ByteString.java \
|
||||
java/core/src/main/java/com/google/protobuf/CodedInputStream.java \
|
||||
java/core/src/main/java/com/google/protobuf/CodedOutputStream.java \
|
||||
@ -243,6 +250,8 @@ java_EXTRA_DIST=
|
||||
java/core/src/main/java/com/google/protobuf/SmallSortedMap.java \
|
||||
java/core/src/main/java/com/google/protobuf/TextFormat.java \
|
||||
java/core/src/main/java/com/google/protobuf/TextFormatEscaper.java \
|
||||
java/core/src/main/java/com/google/protobuf/TextFormatParseInfoTree.java \
|
||||
java/core/src/main/java/com/google/protobuf/TextFormatParseLocation.java \
|
||||
java/core/src/main/java/com/google/protobuf/UninitializedMessageException.java \
|
||||
java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java \
|
||||
java/core/src/main/java/com/google/protobuf/UnknownFieldSetLite.java \
|
||||
@ -254,6 +263,7 @@ java_EXTRA_DIST=
|
||||
java/core/src/test/java/com/google/protobuf/AnyTest.java \
|
||||
java/core/src/test/java/com/google/protobuf/BooleanArrayListTest.java \
|
||||
java/core/src/test/java/com/google/protobuf/BoundedByteStringTest.java \
|
||||
java/core/src/test/java/com/google/protobuf/ByteBufferWriterTest.java \
|
||||
java/core/src/test/java/com/google/protobuf/ByteStringTest.java \
|
||||
java/core/src/test/java/com/google/protobuf/CheckUtf8Test.java \
|
||||
java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java \
|
||||
@ -262,6 +272,7 @@ java_EXTRA_DIST=
|
||||
java/core/src/test/java/com/google/protobuf/DescriptorsTest.java \
|
||||
java/core/src/test/java/com/google/protobuf/DoubleArrayListTest.java \
|
||||
java/core/src/test/java/com/google/protobuf/DynamicMessageTest.java \
|
||||
java/core/src/test/java/com/google/protobuf/EnumTest.java \
|
||||
java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java \
|
||||
java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java \
|
||||
java/core/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java \
|
||||
@ -294,6 +305,8 @@ java_EXTRA_DIST=
|
||||
java/core/src/test/java/com/google/protobuf/SmallSortedMapTest.java \
|
||||
java/core/src/test/java/com/google/protobuf/TestBadIdentifiers.java \
|
||||
java/core/src/test/java/com/google/protobuf/TestUtil.java \
|
||||
java/core/src/test/java/com/google/protobuf/TextFormatParseInfoTreeTest.java \
|
||||
java/core/src/test/java/com/google/protobuf/TextFormatParseLocationTest.java \
|
||||
java/core/src/test/java/com/google/protobuf/TextFormatTest.java \
|
||||
java/core/src/test/java/com/google/protobuf/UnknownEnumValueTest.java \
|
||||
java/core/src/test/java/com/google/protobuf/UnknownFieldSetLiteTest.java \
|
||||
@ -381,13 +394,11 @@ objectivec_EXTRA_DIST= \
|
||||
objectivec/DevTools/full_mac_build.sh \
|
||||
objectivec/DevTools/pddm.py \
|
||||
objectivec/DevTools/pddm_tests.py \
|
||||
objectivec/generate_descriptors_proto.sh \
|
||||
objectivec/generate_well_known_types.sh \
|
||||
objectivec/google/protobuf/Any.pbobjc.h \
|
||||
objectivec/google/protobuf/Any.pbobjc.m \
|
||||
objectivec/google/protobuf/Api.pbobjc.h \
|
||||
objectivec/google/protobuf/Api.pbobjc.m \
|
||||
objectivec/google/protobuf/Descriptor.pbobjc.h \
|
||||
objectivec/google/protobuf/Descriptor.pbobjc.m \
|
||||
objectivec/google/protobuf/Duration.pbobjc.h \
|
||||
objectivec/google/protobuf/Duration.pbobjc.m \
|
||||
objectivec/google/protobuf/Empty.pbobjc.h \
|
||||
|
@ -17,7 +17,6 @@ Pod::Spec.new do |s|
|
||||
s.source_files = 'objectivec/*.{h,m}',
|
||||
'objectivec/google/protobuf/Any.pbobjc.{h,m}',
|
||||
'objectivec/google/protobuf/Api.pbobjc.{h,m}',
|
||||
'objectivec/google/protobuf/Descriptor.pbobjc.{h,m}',
|
||||
'objectivec/google/protobuf/Duration.pbobjc.h',
|
||||
'objectivec/google/protobuf/Empty.pbobjc.{h,m}',
|
||||
'objectivec/google/protobuf/FieldMask.pbobjc.{h,m}',
|
||||
|
20
WORKSPACE
20
WORKSPACE
@ -31,3 +31,23 @@ bind(
|
||||
name = "six",
|
||||
actual = "@six_archive//:six",
|
||||
)
|
||||
|
||||
maven_jar(
|
||||
name = "guava_maven",
|
||||
artifact = "com.google.guava:guava:18.0",
|
||||
)
|
||||
|
||||
bind(
|
||||
name = "guava",
|
||||
actual = "@guava_maven//jar",
|
||||
)
|
||||
|
||||
maven_jar(
|
||||
name = "gson_maven",
|
||||
artifact = "com.google.code.gson:gson:2.3",
|
||||
)
|
||||
|
||||
bind(
|
||||
name = "gson",
|
||||
actual = "@gson_maven//jar",
|
||||
)
|
||||
|
69
benchmarks/Makefile.am
Normal file
69
benchmarks/Makefile.am
Normal file
@ -0,0 +1,69 @@
|
||||
|
||||
benchmarks_protoc_inputs = \
|
||||
benchmarks.proto \
|
||||
benchmark_messages_proto3.proto
|
||||
|
||||
benchmarks_protoc_inputs_proto2 = \
|
||||
benchmark_messages_proto2.proto
|
||||
|
||||
benchmarks_protoc_outputs = \
|
||||
benchmarks.pb.cc \
|
||||
benchmarks.pb.h \
|
||||
benchmark_messages_proto3.pb.cc \
|
||||
benchmark_messages_proto3.pb.h
|
||||
|
||||
benchmarks_protoc_outputs_proto2 = \
|
||||
benchmark_messages_proto2.pb.cc \
|
||||
benchmark_messages_proto2.pb.h
|
||||
|
||||
bin_PROGRAMS = generate-datasets
|
||||
|
||||
generate_datasets_LDADD = $(top_srcdir)/src/libprotobuf.la
|
||||
generate_datasets_SOURCES = generate_datasets.cc
|
||||
generate_datasets_CPPFLAGS = -I$(top_srcdir)/src -I$(srcdir)
|
||||
nodist_generate_datasets_SOURCES = \
|
||||
$(benchmarks_protoc_outputs) \
|
||||
$(benchmarks_protoc_outputs_proto2)
|
||||
|
||||
# Explicit deps because BUILT_SOURCES are only done before a "make all/check"
|
||||
# so a direct "make test_cpp" could fail if parallel enough.
|
||||
# See: https://www.gnu.org/software/automake/manual/html_node/Built-Sources-Example.html#Recording-Dependencies-manually
|
||||
generate_datasets-generate_datasets.$(OBJEXT): benchmarks.pb.h
|
||||
|
||||
$(benchmarks_protoc_outputs): protoc_middleman
|
||||
$(benchmarks_protoc_outputs_proto2): protoc_middleman2
|
||||
|
||||
CLEANFILES = \
|
||||
$(benchmarks_protoc_outputs) \
|
||||
$(benchmarks_protoc_outputs_proto2) \
|
||||
protoc_middleman \
|
||||
protoc_middleman2 \
|
||||
dataset.*
|
||||
|
||||
MAINTAINERCLEANFILES = \
|
||||
Makefile.in
|
||||
|
||||
if USE_EXTERNAL_PROTOC
|
||||
|
||||
protoc_middleman: $(benchmarks_protoc_inputs)
|
||||
$(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. $(benchmarks_protoc_inputs)
|
||||
touch protoc_middleman
|
||||
|
||||
protoc_middleman2: $(benchmarks_protoc_inputs_proto2)
|
||||
$(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. $(benchmarks_protoc_inputs_proto2)
|
||||
touch protoc_middleman2
|
||||
|
||||
else
|
||||
|
||||
# We have to cd to $(srcdir) before executing protoc because $(protoc_inputs) is
|
||||
# relative to srcdir, which may not be the same as the current directory when
|
||||
# building out-of-tree.
|
||||
protoc_middleman: $(top_srcdir)/src/protoc$(EXEEXT) $(benchmarks_protoc_inputs) $(well_known_type_protoc_inputs)
|
||||
oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd $(benchmarks_protoc_inputs) )
|
||||
touch protoc_middleman
|
||||
|
||||
protoc_middleman2: $(top_srcdir)/src/protoc$(EXEEXT) $(benchmarks_protoc_inputs_proto2) $(well_known_type_protoc_inputs)
|
||||
oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd $(benchmarks_protoc_inputs_proto2) )
|
||||
touch protoc_middleman
|
||||
|
||||
endif
|
28
benchmarks/README.md
Normal file
28
benchmarks/README.md
Normal file
@ -0,0 +1,28 @@
|
||||
|
||||
# Protocol Buffers Benchmarks
|
||||
|
||||
This directory contains benchmarking schemas and data sets that you
|
||||
can use to test a variety of performance scenarios against your
|
||||
protobuf language runtime.
|
||||
|
||||
The schema for the datasets is described in `benchmarks.proto`.
|
||||
|
||||
Generate the data sets like so:
|
||||
|
||||
```
|
||||
$ make
|
||||
$ ./generate-datasets
|
||||
Wrote dataset: dataset.google_message1_proto3.pb
|
||||
Wrote dataset: dataset.google_message1_proto2.pb
|
||||
Wrote dataset: dataset.google_message2.pb
|
||||
$
|
||||
```
|
||||
|
||||
Each data set will be written to its own file. Benchmarks will
|
||||
likely want to run several benchmarks against each data set (parse,
|
||||
serialize, possibly JSON, possibly using different APIs, etc).
|
||||
|
||||
We would like to add more data sets. In general we will favor data sets
|
||||
that make the overall suite diverse without being too large or having
|
||||
too many similar tests. Ideally everyone can run through the entire
|
||||
suite without the test run getting too long.
|
@ -1,11 +1,14 @@
|
||||
// Benchmark messages for proto2.
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
package benchmarks;
|
||||
package benchmarks.proto2;
|
||||
option java_package = "com.google.protobuf.benchmarks";
|
||||
|
||||
option java_outer_classname = "GoogleSpeed";
|
||||
// This is the default, but we specify it here explicitly.
|
||||
option optimize_for = SPEED;
|
||||
|
||||
message SpeedMessage1 {
|
||||
message GoogleMessage1 {
|
||||
required string field1 = 1;
|
||||
optional string field9 = 9;
|
||||
optional string field18 = 18;
|
||||
@ -40,7 +43,7 @@ message SpeedMessage1 {
|
||||
optional int32 field23 = 23 [default=0];
|
||||
optional bool field24 = 24 [default=false];
|
||||
optional int32 field25 = 25 [default=0];
|
||||
optional SpeedMessage1SubMessage field15 = 15;
|
||||
optional GoogleMessage1SubMessage field15 = 15;
|
||||
optional bool field78 = 78;
|
||||
optional int32 field67 = 67 [default=0];
|
||||
optional int32 field68 = 68;
|
||||
@ -49,7 +52,7 @@ message SpeedMessage1 {
|
||||
optional int32 field131 = 131 [default=0];
|
||||
}
|
||||
|
||||
message SpeedMessage1SubMessage {
|
||||
message GoogleMessage1SubMessage {
|
||||
optional int32 field1 = 1 [default=0];
|
||||
optional int32 field2 = 2 [default=0];
|
||||
optional int32 field3 = 3 [default=0];
|
||||
@ -72,7 +75,7 @@ message SpeedMessage1SubMessage {
|
||||
optional uint64 field300 = 300;
|
||||
}
|
||||
|
||||
message SpeedMessage2 {
|
||||
message GoogleMessage2 {
|
||||
optional string field1 = 1;
|
||||
optional int64 field3 = 3;
|
||||
optional int64 field4 = 4;
|
||||
@ -112,7 +115,7 @@ message SpeedMessage2 {
|
||||
repeated int32 field73 = 73;
|
||||
optional int32 field20 = 20 [default=0];
|
||||
optional string field24 = 24;
|
||||
optional SpeedMessage2GroupedMessage field31 = 31;
|
||||
optional GoogleMessage2GroupedMessage field31 = 31;
|
||||
}
|
||||
repeated string field128 = 128;
|
||||
optional int64 field131 = 131;
|
||||
@ -123,7 +126,7 @@ message SpeedMessage2 {
|
||||
optional bool field206 = 206 [default=false];
|
||||
}
|
||||
|
||||
message SpeedMessage2GroupedMessage {
|
||||
message GoogleMessage2GroupedMessage {
|
||||
optional float field1 = 1;
|
||||
optional float field2 = 2;
|
||||
optional float field3 = 3 [default=0.0];
|
76
benchmarks/benchmark_messages_proto3.proto
Normal file
76
benchmarks/benchmark_messages_proto3.proto
Normal file
@ -0,0 +1,76 @@
|
||||
// Benchmark messages for proto3.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package benchmarks.proto3;
|
||||
option java_package = "com.google.protobuf.benchmarks";
|
||||
|
||||
// This is the default, but we specify it here explicitly.
|
||||
option optimize_for = SPEED;
|
||||
|
||||
message GoogleMessage1 {
|
||||
string field1 = 1;
|
||||
string field9 = 9;
|
||||
string field18 = 18;
|
||||
bool field80 = 80;
|
||||
bool field81 = 81;
|
||||
int32 field2 = 2;
|
||||
int32 field3 = 3;
|
||||
int32 field280 = 280;
|
||||
int32 field6 = 6;
|
||||
int64 field22 = 22;
|
||||
string field4 = 4;
|
||||
repeated fixed64 field5 = 5;
|
||||
bool field59 = 59;
|
||||
string field7 = 7;
|
||||
int32 field16 = 16;
|
||||
int32 field130 = 130;
|
||||
bool field12 = 12;
|
||||
bool field17 = 17;
|
||||
bool field13 = 13;
|
||||
bool field14 = 14;
|
||||
int32 field104 = 104;
|
||||
int32 field100 = 100;
|
||||
int32 field101 = 101;
|
||||
string field102 = 102;
|
||||
string field103 = 103;
|
||||
int32 field29 = 29;
|
||||
bool field30 = 30;
|
||||
int32 field60 = 60;
|
||||
int32 field271 = 271;
|
||||
int32 field272 = 272;
|
||||
int32 field150 = 150;
|
||||
int32 field23 = 23;
|
||||
bool field24 = 24;
|
||||
int32 field25 = 25;
|
||||
GoogleMessage1SubMessage field15 = 15;
|
||||
bool field78 = 78;
|
||||
int32 field67 = 67;
|
||||
int32 field68 = 68;
|
||||
int32 field128 = 128;
|
||||
string field129 = 129;
|
||||
int32 field131 = 131;
|
||||
}
|
||||
|
||||
message GoogleMessage1SubMessage {
|
||||
int32 field1 = 1;
|
||||
int32 field2 = 2;
|
||||
int32 field3 = 3;
|
||||
string field15 = 15;
|
||||
bool field12 = 12;
|
||||
int64 field13 = 13;
|
||||
int64 field14 = 14;
|
||||
int32 field16 = 16;
|
||||
int32 field19 = 19;
|
||||
bool field20 = 20;
|
||||
bool field28 = 28;
|
||||
fixed64 field21 = 21;
|
||||
int32 field22 = 22;
|
||||
bool field23 = 23;
|
||||
bool field206 = 206;
|
||||
fixed32 field203 = 203;
|
||||
int32 field204 = 204;
|
||||
string field205 = 205;
|
||||
uint64 field207 = 207;
|
||||
uint64 field300 = 300;
|
||||
}
|
63
benchmarks/benchmarks.proto
Normal file
63
benchmarks/benchmarks.proto
Normal file
@ -0,0 +1,63 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// 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.
|
||||
|
||||
syntax = "proto3";
|
||||
package benchmarks;
|
||||
option java_package = "com.google.protobuf.benchmarks";
|
||||
|
||||
message BenchmarkDataset {
|
||||
// Name of the benchmark dataset. This should be unique across all datasets.
|
||||
// Should only contain word characters: [a-zA-Z0-9_]
|
||||
string name = 1;
|
||||
|
||||
// Fully-qualified name of the protobuf message for this dataset.
|
||||
// It will be one of the messages defined benchmark_messages_proto2.proto
|
||||
// or benchmark_messages_proto3.proto.
|
||||
//
|
||||
// Implementations that do not support reflection can implement this with
|
||||
// an explicit "if/else" chain that lists every known message defined
|
||||
// in those files.
|
||||
string message_name = 2;
|
||||
|
||||
// The payload(s) for this dataset. They should be parsed or serialized
|
||||
// in sequence, in a loop, ie.
|
||||
//
|
||||
// while (!benchmarkDone) { // Benchmark runner decides when to exit.
|
||||
// for (i = 0; i < benchmark.payload.length; i++) {
|
||||
// parse(benchmark.payload[i])
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// This is intended to let datasets include a variety of data to provide
|
||||
// potentially more realistic results than just parsing the same message
|
||||
// over and over. A single message parsed repeatedly could yield unusually
|
||||
// good branch prediction performance.
|
||||
repeated bytes payload = 3;
|
||||
}
|
117
benchmarks/generate_datasets.cc
Normal file
117
benchmarks/generate_datasets.cc
Normal file
@ -0,0 +1,117 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include "benchmarks.pb.h"
|
||||
|
||||
using benchmarks::BenchmarkDataset;
|
||||
using google::protobuf::Descriptor;
|
||||
using google::protobuf::DescriptorPool;
|
||||
using google::protobuf::Message;
|
||||
using google::protobuf::MessageFactory;
|
||||
|
||||
std::set<std::string> names;
|
||||
|
||||
const char *file_prefix = "dataset.";
|
||||
const char *file_suffix = ".pb";
|
||||
|
||||
void WriteFileWithPayloads(const std::string& name,
|
||||
const std::string& message_name,
|
||||
const std::vector<std::string>& payload) {
|
||||
if (!names.insert(name).second) {
|
||||
std::cerr << "Duplicate test name: " << name << "\n";
|
||||
abort();
|
||||
}
|
||||
|
||||
// First verify that this message name exists in our set of benchmark messages
|
||||
// and that these payloads are valid for the given message.
|
||||
const Descriptor* d =
|
||||
DescriptorPool::generated_pool()->FindMessageTypeByName(message_name);
|
||||
|
||||
if (!d) {
|
||||
std::cerr << "For dataset " << name << ", no such message: "
|
||||
<< message_name << "\n";
|
||||
abort();
|
||||
}
|
||||
|
||||
Message* m = MessageFactory::generated_factory()->GetPrototype(d)->New();
|
||||
|
||||
for (size_t i = 0; i < payload.size(); i++) {
|
||||
if (!m->ParseFromString(payload[i])) {
|
||||
std::cerr << "For dataset " << name << ", payload[" << i << "] fails "
|
||||
<< "to parse\n";
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
BenchmarkDataset dataset;
|
||||
dataset.set_name(name);
|
||||
dataset.set_message_name(message_name);
|
||||
for (size_t i = 0; i < payload.size(); i++) {
|
||||
dataset.add_payload()->assign(payload[i]);
|
||||
}
|
||||
|
||||
std::ofstream writer;
|
||||
std::string fname = file_prefix + name + file_suffix;
|
||||
writer.open(fname.c_str());
|
||||
dataset.SerializeToOstream(&writer);
|
||||
writer.close();
|
||||
|
||||
std::cerr << "Wrote dataset: " << fname << "\n";
|
||||
}
|
||||
|
||||
void WriteFile(const std::string& name, const std::string& message_name,
|
||||
const std::string& payload) {
|
||||
std::vector<std::string> payloads;
|
||||
payloads.push_back(payload);
|
||||
WriteFileWithPayloads(name, message_name, payloads);
|
||||
}
|
||||
|
||||
std::string ReadFile(const std::string& name) {
|
||||
std::ifstream file(name.c_str());
|
||||
GOOGLE_CHECK(file.is_open()) << "Couldn't find file '" << name <<
|
||||
"', please make sure you are running "
|
||||
"this command from the benchmarks/ "
|
||||
"directory.\n";
|
||||
return std::string((std::istreambuf_iterator<char>(file)),
|
||||
std::istreambuf_iterator<char>());
|
||||
}
|
||||
|
||||
int main() {
|
||||
WriteFile("google_message1_proto3", "benchmarks.proto3.GoogleMessage1",
|
||||
ReadFile("google_message1.dat"));
|
||||
WriteFile("google_message1_proto2", "benchmarks.proto2.GoogleMessage1",
|
||||
ReadFile("google_message1.dat"));
|
||||
|
||||
// Not in proto3 because it has a group, which is not supported.
|
||||
WriteFile("google_message2", "benchmarks.proto2.GoogleMessage2",
|
||||
ReadFile("google_message2.dat"));
|
||||
}
|
@ -118,6 +118,8 @@ if (MSVC)
|
||||
# Build with multiple processes
|
||||
add_definitions(/MP)
|
||||
add_definitions(/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305)
|
||||
# Allow big object
|
||||
add_definitions(/bigobj)
|
||||
string(REPLACE "/" "\\" PROTOBUF_SOURCE_WIN32_PATH ${protobuf_SOURCE_DIR})
|
||||
string(REPLACE "/" "\\" PROTOBUF_BINARY_WIN32_PATH ${protobuf_BINARY_DIR})
|
||||
configure_file(extract_includes.bat.in extract_includes.bat)
|
||||
|
@ -52,6 +52,8 @@ set(tests_protos
|
||||
google/protobuf/unittest_preserve_unknown_enum.proto
|
||||
google/protobuf/unittest_preserve_unknown_enum2.proto
|
||||
google/protobuf/unittest_proto3_arena.proto
|
||||
google/protobuf/unittest_proto3_arena_lite.proto
|
||||
google/protobuf/unittest_proto3_lite.proto
|
||||
google/protobuf/unittest_well_known_types.proto
|
||||
google/protobuf/util/internal/testdata/anys.proto
|
||||
google/protobuf/util/internal/testdata/books.proto
|
||||
@ -116,6 +118,7 @@ set(tests_files
|
||||
${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/compiler/cpp/metadata_test.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/compiler/importer_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/compiler/java/java_doc_comment_unittest.cc
|
||||
@ -140,7 +143,9 @@ set(tests_files
|
||||
${protobuf_source_dir}/src/google/protobuf/message_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/no_field_presence_test.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/preserve_unknown_enum_test.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/proto3_arena_lite_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/proto3_arena_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/proto3_lite_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/reflection_ops_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/repeated_field_reflection_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/repeated_field_unittest.cc
|
||||
|
@ -180,5 +180,5 @@ export CFLAGS
|
||||
export CXXFLAGS
|
||||
AC_CONFIG_SUBDIRS([gmock])
|
||||
|
||||
AC_CONFIG_FILES([Makefile src/Makefile conformance/Makefile protobuf.pc protobuf-lite.pc])
|
||||
AC_CONFIG_FILES([Makefile src/Makefile benchmarks/Makefile conformance/Makefile protobuf.pc protobuf-lite.pc])
|
||||
AC_OUTPUT
|
||||
|
@ -129,7 +129,7 @@ class ConformanceJava {
|
||||
typeRegistry = TypeRegistry.newBuilder().add(
|
||||
Conformance.TestAllTypes.getDescriptor()).build();
|
||||
while (doTestIo()) {
|
||||
// Empty.
|
||||
this.testCount++;
|
||||
}
|
||||
|
||||
System.err.println("ConformanceJava: received EOF from test runner after " +
|
||||
|
125
conformance/ConformanceJavaLite.java
Normal file
125
conformance/ConformanceJavaLite.java
Normal file
@ -0,0 +1,125 @@
|
||||
|
||||
import com.google.protobuf.conformance.Conformance;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
|
||||
class ConformanceJavaLite {
|
||||
private int testCount = 0;
|
||||
|
||||
private boolean readFromStdin(byte[] buf, int len) throws Exception {
|
||||
int ofs = 0;
|
||||
while (len > 0) {
|
||||
int read = System.in.read(buf, ofs, len);
|
||||
if (read == -1) {
|
||||
return false; // EOF
|
||||
}
|
||||
ofs += read;
|
||||
len -= read;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void writeToStdout(byte[] buf) throws Exception {
|
||||
System.out.write(buf);
|
||||
}
|
||||
|
||||
// Returns -1 on EOF (the actual values will always be positive).
|
||||
private int readLittleEndianIntFromStdin() throws Exception {
|
||||
byte[] buf = new byte[4];
|
||||
if (!readFromStdin(buf, 4)) {
|
||||
return -1;
|
||||
}
|
||||
return (buf[0] & 0xff)
|
||||
| ((buf[1] & 0xff) << 8)
|
||||
| ((buf[2] & 0xff) << 16)
|
||||
| ((buf[3] & 0xff) << 24);
|
||||
}
|
||||
|
||||
private void writeLittleEndianIntToStdout(int val) throws Exception {
|
||||
byte[] buf = new byte[4];
|
||||
buf[0] = (byte)val;
|
||||
buf[1] = (byte)(val >> 8);
|
||||
buf[2] = (byte)(val >> 16);
|
||||
buf[3] = (byte)(val >> 24);
|
||||
writeToStdout(buf);
|
||||
}
|
||||
|
||||
private Conformance.ConformanceResponse doTest(Conformance.ConformanceRequest request) {
|
||||
Conformance.TestAllTypes testMessage;
|
||||
|
||||
switch (request.getPayloadCase()) {
|
||||
case PROTOBUF_PAYLOAD: {
|
||||
try {
|
||||
testMessage = Conformance.TestAllTypes.parseFrom(request.getProtobufPayload());
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
return Conformance.ConformanceResponse.newBuilder().setParseError(e.getMessage()).build();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case JSON_PAYLOAD: {
|
||||
return Conformance.ConformanceResponse.newBuilder().setSkipped(
|
||||
"Lite runtime does not suport Json Formant.").build();
|
||||
}
|
||||
case PAYLOAD_NOT_SET: {
|
||||
throw new RuntimeException("Request didn't have payload.");
|
||||
}
|
||||
|
||||
default: {
|
||||
throw new RuntimeException("Unexpected payload case.");
|
||||
}
|
||||
}
|
||||
|
||||
switch (request.getRequestedOutputFormat()) {
|
||||
case UNSPECIFIED:
|
||||
throw new RuntimeException("Unspecified output format.");
|
||||
|
||||
case PROTOBUF:
|
||||
return Conformance.ConformanceResponse.newBuilder().setProtobufPayload(testMessage.toByteString()).build();
|
||||
|
||||
case JSON:
|
||||
return Conformance.ConformanceResponse.newBuilder().setSkipped(
|
||||
"Lite runtime does not suport Json Formant.").build();
|
||||
|
||||
default: {
|
||||
throw new RuntimeException("Unexpected request output.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean doTestIo() throws Exception {
|
||||
int bytes = readLittleEndianIntFromStdin();
|
||||
|
||||
if (bytes == -1) {
|
||||
return false; // EOF
|
||||
}
|
||||
|
||||
byte[] serializedInput = new byte[bytes];
|
||||
|
||||
if (!readFromStdin(serializedInput, bytes)) {
|
||||
throw new RuntimeException("Unexpected EOF from test program.");
|
||||
}
|
||||
|
||||
Conformance.ConformanceRequest request =
|
||||
Conformance.ConformanceRequest.parseFrom(serializedInput);
|
||||
Conformance.ConformanceResponse response = doTest(request);
|
||||
byte[] serializedOutput = response.toByteArray();
|
||||
|
||||
writeLittleEndianIntToStdout(serializedOutput.length);
|
||||
writeToStdout(serializedOutput);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void run() throws Exception {
|
||||
while (doTestIo()) {
|
||||
this.testCount++;
|
||||
}
|
||||
|
||||
System.err.println("ConformanceJavaLite: received EOF from test runner after " +
|
||||
this.testCount + " tests");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new ConformanceJavaLite().run();
|
||||
}
|
||||
}
|
@ -17,11 +17,114 @@ protoc_outputs = \
|
||||
conformance.pb.h
|
||||
|
||||
other_language_protoc_outputs = \
|
||||
conformance.rb \
|
||||
com/google/protobuf/conformance/Conformance.java \
|
||||
conformance_pb2.py \
|
||||
Conformance.pbobjc.h \
|
||||
Conformance.pbobjc.m
|
||||
Conformance.pbobjc.m \
|
||||
conformance.rb \
|
||||
com/google/protobuf/Any.java \
|
||||
com/google/protobuf/AnyOrBuilder.java \
|
||||
com/google/protobuf/AnyProto.java \
|
||||
com/google/protobuf/BoolValue.java \
|
||||
com/google/protobuf/BoolValueOrBuilder.java \
|
||||
com/google/protobuf/BytesValue.java \
|
||||
com/google/protobuf/BytesValueOrBuilder.java \
|
||||
com/google/protobuf/conformance/Conformance.java \
|
||||
com/google/protobuf/DoubleValue.java \
|
||||
com/google/protobuf/DoubleValueOrBuilder.java \
|
||||
com/google/protobuf/Duration.java \
|
||||
com/google/protobuf/DurationOrBuilder.java \
|
||||
com/google/protobuf/DurationProto.java \
|
||||
com/google/protobuf/FieldMask.java \
|
||||
com/google/protobuf/FieldMaskOrBuilder.java \
|
||||
com/google/protobuf/FieldMaskProto.java \
|
||||
com/google/protobuf/FloatValue.java \
|
||||
com/google/protobuf/FloatValueOrBuilder.java \
|
||||
com/google/protobuf/Int32Value.java \
|
||||
com/google/protobuf/Int32ValueOrBuilder.java \
|
||||
com/google/protobuf/Int64Value.java \
|
||||
com/google/protobuf/Int64ValueOrBuilder.java \
|
||||
com/google/protobuf/ListValue.java \
|
||||
com/google/protobuf/ListValueOrBuilder.java \
|
||||
com/google/protobuf/NullValue.java \
|
||||
com/google/protobuf/StringValue.java \
|
||||
com/google/protobuf/StringValueOrBuilder.java \
|
||||
com/google/protobuf/Struct.java \
|
||||
com/google/protobuf/StructOrBuilder.java \
|
||||
com/google/protobuf/StructProto.java \
|
||||
com/google/protobuf/Timestamp.java \
|
||||
com/google/protobuf/TimestampOrBuilder.java \
|
||||
com/google/protobuf/TimestampProto.java \
|
||||
com/google/protobuf/UInt32Value.java \
|
||||
com/google/protobuf/UInt32ValueOrBuilder.java \
|
||||
com/google/protobuf/UInt64Value.java \
|
||||
com/google/protobuf/UInt64ValueOrBuilder.java \
|
||||
com/google/protobuf/Value.java \
|
||||
com/google/protobuf/ValueOrBuilder.java \
|
||||
com/google/protobuf/WrappersProto.java \
|
||||
google/protobuf/any.pb.cc \
|
||||
google/protobuf/any.pb.h \
|
||||
google/protobuf/any.rb \
|
||||
google/protobuf/any_pb2.py \
|
||||
google/protobuf/duration.pb.cc \
|
||||
google/protobuf/duration.pb.h \
|
||||
google/protobuf/duration.rb \
|
||||
google/protobuf/duration_pb2.py \
|
||||
google/protobuf/field_mask.pb.cc \
|
||||
google/protobuf/field_mask.pb.h \
|
||||
google/protobuf/field_mask.rb \
|
||||
google/protobuf/field_mask_pb2.py \
|
||||
google/protobuf/struct.pb.cc \
|
||||
google/protobuf/struct.pb.h \
|
||||
google/protobuf/struct.rb \
|
||||
google/protobuf/struct_pb2.py \
|
||||
google/protobuf/timestamp.pb.cc \
|
||||
google/protobuf/timestamp.pb.h \
|
||||
google/protobuf/timestamp.rb \
|
||||
google/protobuf/timestamp_pb2.py \
|
||||
google/protobuf/wrappers.pb.cc \
|
||||
google/protobuf/wrappers.pb.h \
|
||||
google/protobuf/wrappers.rb \
|
||||
google/protobuf/wrappers_pb2.py \
|
||||
lite/com/google/protobuf/Any.java \
|
||||
lite/com/google/protobuf/AnyOrBuilder.java \
|
||||
lite/com/google/protobuf/AnyProto.java \
|
||||
lite/com/google/protobuf/BoolValue.java \
|
||||
lite/com/google/protobuf/BoolValueOrBuilder.java \
|
||||
lite/com/google/protobuf/BytesValue.java \
|
||||
lite/com/google/protobuf/BytesValueOrBuilder.java \
|
||||
lite/com/google/protobuf/conformance/Conformance.java \
|
||||
lite/com/google/protobuf/DoubleValue.java \
|
||||
lite/com/google/protobuf/DoubleValueOrBuilder.java \
|
||||
lite/com/google/protobuf/Duration.java \
|
||||
lite/com/google/protobuf/DurationOrBuilder.java \
|
||||
lite/com/google/protobuf/DurationProto.java \
|
||||
lite/com/google/protobuf/FieldMask.java \
|
||||
lite/com/google/protobuf/FieldMaskOrBuilder.java \
|
||||
lite/com/google/protobuf/FieldMaskProto.java \
|
||||
lite/com/google/protobuf/FloatValue.java \
|
||||
lite/com/google/protobuf/FloatValueOrBuilder.java \
|
||||
lite/com/google/protobuf/Int32Value.java \
|
||||
lite/com/google/protobuf/Int32ValueOrBuilder.java \
|
||||
lite/com/google/protobuf/Int64Value.java \
|
||||
lite/com/google/protobuf/Int64ValueOrBuilder.java \
|
||||
lite/com/google/protobuf/ListValue.java \
|
||||
lite/com/google/protobuf/ListValueOrBuilder.java \
|
||||
lite/com/google/protobuf/NullValue.java \
|
||||
lite/com/google/protobuf/StringValue.java \
|
||||
lite/com/google/protobuf/StringValueOrBuilder.java \
|
||||
lite/com/google/protobuf/Struct.java \
|
||||
lite/com/google/protobuf/StructOrBuilder.java \
|
||||
lite/com/google/protobuf/StructProto.java \
|
||||
lite/com/google/protobuf/Timestamp.java \
|
||||
lite/com/google/protobuf/TimestampOrBuilder.java \
|
||||
lite/com/google/protobuf/TimestampProto.java \
|
||||
lite/com/google/protobuf/UInt32Value.java \
|
||||
lite/com/google/protobuf/UInt32ValueOrBuilder.java \
|
||||
lite/com/google/protobuf/UInt64Value.java \
|
||||
lite/com/google/protobuf/UInt64ValueOrBuilder.java \
|
||||
lite/com/google/protobuf/Value.java \
|
||||
lite/com/google/protobuf/ValueOrBuilder.java \
|
||||
lite/com/google/protobuf/WrappersProto.java
|
||||
|
||||
bin_PROGRAMS = conformance-test-runner conformance-cpp
|
||||
|
||||
@ -30,6 +133,7 @@ bin_PROGRAMS = conformance-test-runner conformance-cpp
|
||||
# automatically.
|
||||
EXTRA_DIST = \
|
||||
ConformanceJava.java \
|
||||
ConformanceJavaLite.java \
|
||||
README.md \
|
||||
conformance.proto \
|
||||
conformance_python.py \
|
||||
@ -88,6 +192,7 @@ if USE_EXTERNAL_PROTOC
|
||||
protoc_middleman: $(conformance_protoc_inputs) $(well_known_type_protoc_inputs)
|
||||
$(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --objc_out=. --python_out=. $(conformance_protoc_inputs)
|
||||
$(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --python_out=. $(well_known_type_protoc_inputs)
|
||||
$(PROTOC) -I$(srcdir) -I$(top_srcdir) --java_out=lite:lite $(conformance_protoc_inputs) $(well_known_type_protoc_inputs)
|
||||
touch protoc_middleman
|
||||
|
||||
else
|
||||
@ -98,6 +203,8 @@ else
|
||||
protoc_middleman: $(top_srcdir)/src/protoc$(EXEEXT) $(conformance_protoc_inputs) $(well_known_type_protoc_inputs)
|
||||
oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --objc_out=$$oldpwd --python_out=$$oldpwd $(conformance_protoc_inputs) )
|
||||
oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --python_out=$$oldpwd $(well_known_type_protoc_inputs) )
|
||||
@mkdir -p lite
|
||||
oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --java_out=lite:$$oldpwd/lite $(conformance_protoc_inputs) $(well_known_type_protoc_inputs) )
|
||||
touch protoc_middleman
|
||||
|
||||
endif
|
||||
@ -108,7 +215,7 @@ $(other_language_protoc_outputs): protoc_middleman
|
||||
|
||||
BUILT_SOURCES = $(protoc_outputs) $(other_language_protoc_outputs)
|
||||
|
||||
CLEANFILES = $(protoc_outputs) protoc_middleman javac_middleman conformance-java conformance-csharp $(other_language_protoc_outputs)
|
||||
CLEANFILES = $(protoc_outputs) protoc_middleman javac_middleman conformance-java javac_middleman_lite conformance-java-lite conformance-csharp $(other_language_protoc_outputs)
|
||||
|
||||
MAINTAINERCLEANFILES = \
|
||||
Makefile.in
|
||||
@ -123,6 +230,16 @@ conformance-java: javac_middleman
|
||||
@jar=`ls ../java/util/target/*jar-with-dependencies.jar` && echo java -classpath .:../java/target/classes:$$jar ConformanceJava '$$@' >> conformance-java
|
||||
@chmod +x conformance-java
|
||||
|
||||
javac_middleman_lite: ConformanceJavaLite.java protoc_middleman $(other_language_protoc_outputs)
|
||||
javac -classpath ../java/lite/target/classes:lite ConformanceJavaLite.java lite/com/google/protobuf/conformance/Conformance.java
|
||||
@touch javac_middleman_lite
|
||||
|
||||
conformance-java-lite: javac_middleman_lite
|
||||
@echo "Writing shortcut script conformance-java-lite..."
|
||||
@echo '#! /bin/sh' > conformance-java-lite
|
||||
@echo java -classpath .:../java/lite/target/classes:lite ConformanceJavaLite '$$@' >> conformance-java-lite
|
||||
@chmod +x conformance-java-lite
|
||||
|
||||
# Currently the conformance code is alongside the rest of the C#
|
||||
# source, as it's easier to maintain there. We assume we've already
|
||||
# built that, so we just need a script to run it.
|
||||
@ -139,6 +256,9 @@ test_cpp: protoc_middleman conformance-test-runner conformance-cpp
|
||||
test_java: protoc_middleman conformance-test-runner conformance-java
|
||||
./conformance-test-runner --failure_list failure_list_java.txt ./conformance-java
|
||||
|
||||
test_java_lite: protoc_middleman conformance-test-runner conformance-java-lite
|
||||
./conformance-test-runner ./conformance-java-lite
|
||||
|
||||
test_csharp: protoc_middleman conformance-test-runner conformance-csharp
|
||||
./conformance-test-runner --failure_list failure_list_csharp.txt ./conformance-csharp
|
||||
|
||||
|
@ -80,7 +80,6 @@ JsonInput.Int32FieldMaxFloatValue.JsonOutput
|
||||
JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
|
||||
JsonInput.Int32FieldMinFloatValue.JsonOutput
|
||||
JsonInput.Int32FieldMinFloatValue.ProtobufOutput
|
||||
JsonInput.Int32FieldMinValue.JsonOutput
|
||||
JsonInput.Int32FieldStringValue.JsonOutput
|
||||
JsonInput.Int32FieldStringValue.ProtobufOutput
|
||||
JsonInput.Int32FieldStringValueEscaped.JsonOutput
|
||||
@ -125,7 +124,6 @@ JsonInput.OptionalUint64Wrapper.ProtobufOutput
|
||||
JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput
|
||||
JsonInput.OptionalWrapperTypesWithNonDefaultValue.ProtobufOutput
|
||||
JsonInput.OriginalProtoFieldName.JsonOutput
|
||||
JsonInput.OriginalProtoFieldName.ProtobufOutput
|
||||
JsonInput.PrimitiveRepeatedField.JsonOutput
|
||||
JsonInput.PrimitiveRepeatedField.ProtobufOutput
|
||||
JsonInput.RepeatedBoolWrapper.JsonOutput
|
||||
|
37
csharp/Google.Protobuf.Tools.nuspec
Normal file
37
csharp/Google.Protobuf.Tools.nuspec
Normal file
@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package>
|
||||
<metadata>
|
||||
<id>Google.Protobuf.Tools</id>
|
||||
<title>Google Protocol Buffers tools</title>
|
||||
<summary>Tools for Protocol Buffers - Google's data interchange format.</summary>
|
||||
<description>See project site for more info.</description>
|
||||
<version>3.0.0-beta2</version>
|
||||
<authors>Google Inc.</authors>
|
||||
<owners>protobuf-packages</owners>
|
||||
<licenseUrl>https://github.com/google/protobuf/blob/master/LICENSE</licenseUrl>
|
||||
<projectUrl>https://github.com/google/protobuf</projectUrl>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<releaseNotes>Tools for Protocol Buffers</releaseNotes>
|
||||
<copyright>Copyright 2015, Google Inc.</copyright>
|
||||
<tags>Protocol Buffers Binary Serialization Format Google proto proto3</tags>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="protoc\windows_x86\protoc.exe" target="tools\windows_x86\protoc.exe" />
|
||||
<file src="protoc\windows_x64\protoc.exe" target="tools\windows_x64\protoc.exe" />
|
||||
<file src="protoc\linux_x86\protoc" target="tools\linux_x86\protoc" />
|
||||
<file src="protoc\linux_x64\protoc" target="tools\linux_x64\protoc" />
|
||||
<file src="protoc\macosx_x86\protoc" target="tools\macosx_x86\protoc" />
|
||||
<file src="protoc\macosx_x64\protoc" target="tools\macosx_x64\protoc" />
|
||||
<file src="..\src\google\protobuf\any.proto" target="tools\google\protobuf" />
|
||||
<file src="..\src\google\protobuf\api.proto" target="tools\google\protobuf" />
|
||||
<file src="..\src\google\protobuf\descriptor.proto" target="tools\google\protobuf" />
|
||||
<file src="..\src\google\protobuf\duration.proto" target="tools\google\protobuf" />
|
||||
<file src="..\src\google\protobuf\empty.proto" target="tools\google\protobuf" />
|
||||
<file src="..\src\google\protobuf\field_mask.proto" target="tools\google\protobuf" />
|
||||
<file src="..\src\google\protobuf\source_context.proto" target="tools\google\protobuf" />
|
||||
<file src="..\src\google\protobuf\struct.proto" target="tools\google\protobuf" />
|
||||
<file src="..\src\google\protobuf\timestamp.proto" target="tools\google\protobuf" />
|
||||
<file src="..\src\google\protobuf\type.proto" target="tools\google\protobuf" />
|
||||
<file src="..\src\google\protobuf\wrappers.proto" target="tools\google\protobuf" />
|
||||
</files>
|
||||
</package>
|
@ -116,4 +116,11 @@ message TestJsonFieldOrdering {
|
||||
string o2_string = 3;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
message TestJsonName {
|
||||
// Message for testing the effects for of the json_name option
|
||||
string name = 1;
|
||||
string description = 2 [json_name = "desc"];
|
||||
string guid = 3 [json_name = "exid"];
|
||||
}
|
||||
|
@ -73,13 +73,13 @@ namespace Google.Protobuf.Examples.AddressBook
|
||||
switch (type)
|
||||
{
|
||||
case "mobile":
|
||||
phoneNumber.Type = Person.Types.PhoneType.MOBILE;
|
||||
phoneNumber.Type = Person.Types.PhoneType.Mobile;
|
||||
break;
|
||||
case "home":
|
||||
phoneNumber.Type = Person.Types.PhoneType.HOME;
|
||||
phoneNumber.Type = Person.Types.PhoneType.Home;
|
||||
break;
|
||||
case "work":
|
||||
phoneNumber.Type = Person.Types.PhoneType.WORK;
|
||||
phoneNumber.Type = Person.Types.PhoneType.Work;
|
||||
break;
|
||||
default:
|
||||
output.Write("Unknown phone type. Using default.");
|
||||
|
@ -228,9 +228,9 @@ namespace Google.Protobuf.Examples.AddressBook {
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
public static partial class Types {
|
||||
public enum PhoneType {
|
||||
MOBILE = 0,
|
||||
HOME = 1,
|
||||
WORK = 2,
|
||||
[pbr::OriginalName("MOBILE")] Mobile = 0,
|
||||
[pbr::OriginalName("HOME")] Home = 1,
|
||||
[pbr::OriginalName("WORK")] Work = 2,
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
@ -273,7 +273,7 @@ namespace Google.Protobuf.Examples.AddressBook {
|
||||
|
||||
/// <summary>Field number for the "type" field.</summary>
|
||||
public const int TypeFieldNumber = 2;
|
||||
private global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType type_ = global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType.MOBILE;
|
||||
private global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType type_ = 0;
|
||||
public global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType Type {
|
||||
get { return type_; }
|
||||
set {
|
||||
@ -300,7 +300,7 @@ namespace Google.Protobuf.Examples.AddressBook {
|
||||
public override int GetHashCode() {
|
||||
int hash = 1;
|
||||
if (Number.Length != 0) hash ^= Number.GetHashCode();
|
||||
if (Type != global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType.MOBILE) hash ^= Type.GetHashCode();
|
||||
if (Type != 0) hash ^= Type.GetHashCode();
|
||||
return hash;
|
||||
}
|
||||
|
||||
@ -313,7 +313,7 @@ namespace Google.Protobuf.Examples.AddressBook {
|
||||
output.WriteRawTag(10);
|
||||
output.WriteString(Number);
|
||||
}
|
||||
if (Type != global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType.MOBILE) {
|
||||
if (Type != 0) {
|
||||
output.WriteRawTag(16);
|
||||
output.WriteEnum((int) Type);
|
||||
}
|
||||
@ -324,7 +324,7 @@ namespace Google.Protobuf.Examples.AddressBook {
|
||||
if (Number.Length != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeStringSize(Number);
|
||||
}
|
||||
if (Type != global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType.MOBILE) {
|
||||
if (Type != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Type);
|
||||
}
|
||||
return size;
|
||||
@ -337,7 +337,7 @@ namespace Google.Protobuf.Examples.AddressBook {
|
||||
if (other.Number.Length != 0) {
|
||||
Number = other.Number;
|
||||
}
|
||||
if (other.Type != global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType.MOBILE) {
|
||||
if (other.Type != 0) {
|
||||
Type = other.Type;
|
||||
}
|
||||
}
|
||||
|
@ -55,13 +55,13 @@ namespace Google.Protobuf.Examples.AddressBook
|
||||
{
|
||||
switch (phoneNumber.Type)
|
||||
{
|
||||
case Person.Types.PhoneType.MOBILE:
|
||||
case Person.Types.PhoneType.Mobile:
|
||||
Console.Write(" Mobile phone #: ");
|
||||
break;
|
||||
case Person.Types.PhoneType.HOME:
|
||||
case Person.Types.PhoneType.Home:
|
||||
Console.Write(" Home phone #: ");
|
||||
break;
|
||||
case Person.Types.PhoneType.WORK:
|
||||
case Person.Types.PhoneType.Work:
|
||||
Console.Write(" Work phone #: ");
|
||||
break;
|
||||
}
|
||||
|
@ -199,15 +199,15 @@ namespace Conformance {
|
||||
}
|
||||
#region Enums
|
||||
public enum WireFormat {
|
||||
UNSPECIFIED = 0,
|
||||
PROTOBUF = 1,
|
||||
JSON = 2,
|
||||
[pbr::OriginalName("UNSPECIFIED")] Unspecified = 0,
|
||||
[pbr::OriginalName("PROTOBUF")] Protobuf = 1,
|
||||
[pbr::OriginalName("JSON")] Json = 2,
|
||||
}
|
||||
|
||||
public enum ForeignEnum {
|
||||
FOREIGN_FOO = 0,
|
||||
FOREIGN_BAR = 1,
|
||||
FOREIGN_BAZ = 2,
|
||||
[pbr::OriginalName("FOREIGN_FOO")] ForeignFoo = 0,
|
||||
[pbr::OriginalName("FOREIGN_BAR")] ForeignBar = 1,
|
||||
[pbr::OriginalName("FOREIGN_BAZ")] ForeignBaz = 2,
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -278,7 +278,7 @@ namespace Conformance {
|
||||
|
||||
/// <summary>Field number for the "requested_output_format" field.</summary>
|
||||
public const int RequestedOutputFormatFieldNumber = 3;
|
||||
private global::Conformance.WireFormat requestedOutputFormat_ = global::Conformance.WireFormat.UNSPECIFIED;
|
||||
private global::Conformance.WireFormat requestedOutputFormat_ = 0;
|
||||
/// <summary>
|
||||
/// Which format should the testee serialize its message to?
|
||||
/// </summary>
|
||||
@ -328,7 +328,7 @@ namespace Conformance {
|
||||
int hash = 1;
|
||||
if (payloadCase_ == PayloadOneofCase.ProtobufPayload) hash ^= ProtobufPayload.GetHashCode();
|
||||
if (payloadCase_ == PayloadOneofCase.JsonPayload) hash ^= JsonPayload.GetHashCode();
|
||||
if (RequestedOutputFormat != global::Conformance.WireFormat.UNSPECIFIED) hash ^= RequestedOutputFormat.GetHashCode();
|
||||
if (RequestedOutputFormat != 0) hash ^= RequestedOutputFormat.GetHashCode();
|
||||
hash ^= (int) payloadCase_;
|
||||
return hash;
|
||||
}
|
||||
@ -346,7 +346,7 @@ namespace Conformance {
|
||||
output.WriteRawTag(18);
|
||||
output.WriteString(JsonPayload);
|
||||
}
|
||||
if (RequestedOutputFormat != global::Conformance.WireFormat.UNSPECIFIED) {
|
||||
if (RequestedOutputFormat != 0) {
|
||||
output.WriteRawTag(24);
|
||||
output.WriteEnum((int) RequestedOutputFormat);
|
||||
}
|
||||
@ -360,7 +360,7 @@ namespace Conformance {
|
||||
if (payloadCase_ == PayloadOneofCase.JsonPayload) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeStringSize(JsonPayload);
|
||||
}
|
||||
if (RequestedOutputFormat != global::Conformance.WireFormat.UNSPECIFIED) {
|
||||
if (RequestedOutputFormat != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) RequestedOutputFormat);
|
||||
}
|
||||
return size;
|
||||
@ -370,7 +370,7 @@ namespace Conformance {
|
||||
if (other == null) {
|
||||
return;
|
||||
}
|
||||
if (other.RequestedOutputFormat != global::Conformance.WireFormat.UNSPECIFIED) {
|
||||
if (other.RequestedOutputFormat != 0) {
|
||||
RequestedOutputFormat = other.RequestedOutputFormat;
|
||||
}
|
||||
switch (other.PayloadCase) {
|
||||
@ -1044,7 +1044,7 @@ namespace Conformance {
|
||||
|
||||
/// <summary>Field number for the "optional_nested_enum" field.</summary>
|
||||
public const int OptionalNestedEnumFieldNumber = 21;
|
||||
private global::Conformance.TestAllTypes.Types.NestedEnum optionalNestedEnum_ = global::Conformance.TestAllTypes.Types.NestedEnum.FOO;
|
||||
private global::Conformance.TestAllTypes.Types.NestedEnum optionalNestedEnum_ = 0;
|
||||
public global::Conformance.TestAllTypes.Types.NestedEnum OptionalNestedEnum {
|
||||
get { return optionalNestedEnum_; }
|
||||
set {
|
||||
@ -1054,7 +1054,7 @@ namespace Conformance {
|
||||
|
||||
/// <summary>Field number for the "optional_foreign_enum" field.</summary>
|
||||
public const int OptionalForeignEnumFieldNumber = 22;
|
||||
private global::Conformance.ForeignEnum optionalForeignEnum_ = global::Conformance.ForeignEnum.FOREIGN_FOO;
|
||||
private global::Conformance.ForeignEnum optionalForeignEnum_ = 0;
|
||||
public global::Conformance.ForeignEnum OptionalForeignEnum {
|
||||
get { return optionalForeignEnum_; }
|
||||
set {
|
||||
@ -2079,8 +2079,8 @@ namespace Conformance {
|
||||
if (OptionalBytes.Length != 0) hash ^= OptionalBytes.GetHashCode();
|
||||
if (optionalNestedMessage_ != null) hash ^= OptionalNestedMessage.GetHashCode();
|
||||
if (optionalForeignMessage_ != null) hash ^= OptionalForeignMessage.GetHashCode();
|
||||
if (OptionalNestedEnum != global::Conformance.TestAllTypes.Types.NestedEnum.FOO) hash ^= OptionalNestedEnum.GetHashCode();
|
||||
if (OptionalForeignEnum != global::Conformance.ForeignEnum.FOREIGN_FOO) hash ^= OptionalForeignEnum.GetHashCode();
|
||||
if (OptionalNestedEnum != 0) hash ^= OptionalNestedEnum.GetHashCode();
|
||||
if (OptionalForeignEnum != 0) hash ^= OptionalForeignEnum.GetHashCode();
|
||||
if (OptionalStringPiece.Length != 0) hash ^= OptionalStringPiece.GetHashCode();
|
||||
if (OptionalCord.Length != 0) hash ^= OptionalCord.GetHashCode();
|
||||
if (recursiveMessage_ != null) hash ^= RecursiveMessage.GetHashCode();
|
||||
@ -2247,11 +2247,11 @@ namespace Conformance {
|
||||
output.WriteRawTag(154, 1);
|
||||
output.WriteMessage(OptionalForeignMessage);
|
||||
}
|
||||
if (OptionalNestedEnum != global::Conformance.TestAllTypes.Types.NestedEnum.FOO) {
|
||||
if (OptionalNestedEnum != 0) {
|
||||
output.WriteRawTag(168, 1);
|
||||
output.WriteEnum((int) OptionalNestedEnum);
|
||||
}
|
||||
if (OptionalForeignEnum != global::Conformance.ForeignEnum.FOREIGN_FOO) {
|
||||
if (OptionalForeignEnum != 0) {
|
||||
output.WriteRawTag(176, 1);
|
||||
output.WriteEnum((int) OptionalForeignEnum);
|
||||
}
|
||||
@ -2492,10 +2492,10 @@ namespace Conformance {
|
||||
if (optionalForeignMessage_ != null) {
|
||||
size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalForeignMessage);
|
||||
}
|
||||
if (OptionalNestedEnum != global::Conformance.TestAllTypes.Types.NestedEnum.FOO) {
|
||||
if (OptionalNestedEnum != 0) {
|
||||
size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) OptionalNestedEnum);
|
||||
}
|
||||
if (OptionalForeignEnum != global::Conformance.ForeignEnum.FOREIGN_FOO) {
|
||||
if (OptionalForeignEnum != 0) {
|
||||
size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) OptionalForeignEnum);
|
||||
}
|
||||
if (OptionalStringPiece.Length != 0) {
|
||||
@ -2719,10 +2719,10 @@ namespace Conformance {
|
||||
}
|
||||
OptionalForeignMessage.MergeFrom(other.OptionalForeignMessage);
|
||||
}
|
||||
if (other.OptionalNestedEnum != global::Conformance.TestAllTypes.Types.NestedEnum.FOO) {
|
||||
if (other.OptionalNestedEnum != 0) {
|
||||
OptionalNestedEnum = other.OptionalNestedEnum;
|
||||
}
|
||||
if (other.OptionalForeignEnum != global::Conformance.ForeignEnum.FOREIGN_FOO) {
|
||||
if (other.OptionalForeignEnum != 0) {
|
||||
OptionalForeignEnum = other.OptionalForeignEnum;
|
||||
}
|
||||
if (other.OptionalStringPiece.Length != 0) {
|
||||
@ -3448,13 +3448,13 @@ namespace Conformance {
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
public static partial class Types {
|
||||
public enum NestedEnum {
|
||||
FOO = 0,
|
||||
BAR = 1,
|
||||
BAZ = 2,
|
||||
[pbr::OriginalName("FOO")] Foo = 0,
|
||||
[pbr::OriginalName("BAR")] Bar = 1,
|
||||
[pbr::OriginalName("BAZ")] Baz = 2,
|
||||
/// <summary>
|
||||
/// Intentionally negative.
|
||||
/// </summary>
|
||||
NEG = -1,
|
||||
[pbr::OriginalName("NEG")] Neg = -1,
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
|
@ -109,10 +109,10 @@ namespace Google.Protobuf.Conformance
|
||||
{
|
||||
switch (request.RequestedOutputFormat)
|
||||
{
|
||||
case global::Conformance.WireFormat.JSON:
|
||||
case global::Conformance.WireFormat.Json:
|
||||
var formatter = new JsonFormatter(new JsonFormatter.Settings(false, typeRegistry));
|
||||
return new ConformanceResponse { JsonPayload = formatter.Format(message) };
|
||||
case global::Conformance.WireFormat.PROTOBUF:
|
||||
case global::Conformance.WireFormat.Protobuf:
|
||||
return new ConformanceResponse { ProtobufPayload = message.ToByteString() };
|
||||
default:
|
||||
throw new Exception("Unsupported request output format: " + request.PayloadCase);
|
||||
|
@ -58,7 +58,7 @@ namespace Google.Protobuf
|
||||
new FieldCodecTestData<float>(FieldCodec.ForFloat(100), 1234.5f, "Float"),
|
||||
new FieldCodecTestData<double>(FieldCodec.ForDouble(100), 1234567890.5d, "Double"),
|
||||
new FieldCodecTestData<ForeignEnum>(
|
||||
FieldCodec.ForEnum(100, t => (int) t, t => (ForeignEnum) t), ForeignEnum.FOREIGN_BAZ, "Enum"),
|
||||
FieldCodec.ForEnum(100, t => (int) t, t => (ForeignEnum) t), ForeignEnum.ForeignBaz, "Enum"),
|
||||
new FieldCodecTestData<ForeignMessage>(
|
||||
FieldCodec.ForMessage(100, ForeignMessage.Parser), new ForeignMessage { C = 10 }, "Message"),
|
||||
};
|
||||
|
@ -66,13 +66,13 @@ namespace Google.Protobuf
|
||||
Assert.AreEqual(0, message.SingleFixed32);
|
||||
Assert.AreEqual(0L, message.SingleFixed64);
|
||||
Assert.AreEqual(0.0f, message.SingleFloat);
|
||||
Assert.AreEqual(ForeignEnum.FOREIGN_UNSPECIFIED, message.SingleForeignEnum);
|
||||
Assert.AreEqual(ForeignEnum.ForeignUnspecified, message.SingleForeignEnum);
|
||||
Assert.IsNull(message.SingleForeignMessage);
|
||||
Assert.AreEqual(ImportEnum.IMPORT_ENUM_UNSPECIFIED, message.SingleImportEnum);
|
||||
Assert.AreEqual(ImportEnum.Unspecified, message.SingleImportEnum);
|
||||
Assert.IsNull(message.SingleImportMessage);
|
||||
Assert.AreEqual(0, message.SingleInt32);
|
||||
Assert.AreEqual(0L, message.SingleInt64);
|
||||
Assert.AreEqual(TestAllTypes.Types.NestedEnum.NESTED_ENUM_UNSPECIFIED, message.SingleNestedEnum);
|
||||
Assert.AreEqual(TestAllTypes.Types.NestedEnum.Unspecified, message.SingleNestedEnum);
|
||||
Assert.IsNull(message.SingleNestedMessage);
|
||||
Assert.IsNull(message.SinglePublicImportMessage);
|
||||
Assert.AreEqual(0, message.SingleSfixed32);
|
||||
@ -145,13 +145,13 @@ namespace Google.Protobuf
|
||||
SingleFixed32 = 23,
|
||||
SingleFixed64 = 1234567890123,
|
||||
SingleFloat = 12.25f,
|
||||
SingleForeignEnum = ForeignEnum.FOREIGN_BAR,
|
||||
SingleForeignEnum = ForeignEnum.ForeignBar,
|
||||
SingleForeignMessage = new ForeignMessage { C = 10 },
|
||||
SingleImportEnum = ImportEnum.IMPORT_BAZ,
|
||||
SingleImportEnum = ImportEnum.ImportBaz,
|
||||
SingleImportMessage = new ImportMessage { D = 20 },
|
||||
SingleInt32 = 100,
|
||||
SingleInt64 = 3210987654321,
|
||||
SingleNestedEnum = TestAllTypes.Types.NestedEnum.FOO,
|
||||
SingleNestedEnum = TestAllTypes.Types.NestedEnum.Foo,
|
||||
SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 35 },
|
||||
SinglePublicImportMessage = new PublicImportMessage { E = 54 },
|
||||
SingleSfixed32 = -123,
|
||||
@ -179,13 +179,13 @@ namespace Google.Protobuf
|
||||
RepeatedFixed32 = { uint.MaxValue, 23 },
|
||||
RepeatedFixed64 = { ulong.MaxValue, 1234567890123 },
|
||||
RepeatedFloat = { 100f, 12.25f },
|
||||
RepeatedForeignEnum = { ForeignEnum.FOREIGN_FOO, ForeignEnum.FOREIGN_BAR },
|
||||
RepeatedForeignEnum = { ForeignEnum.ForeignFoo, ForeignEnum.ForeignBar },
|
||||
RepeatedForeignMessage = { new ForeignMessage(), new ForeignMessage { C = 10 } },
|
||||
RepeatedImportEnum = { ImportEnum.IMPORT_BAZ, ImportEnum.IMPORT_ENUM_UNSPECIFIED },
|
||||
RepeatedImportEnum = { ImportEnum.ImportBaz, ImportEnum.Unspecified },
|
||||
RepeatedImportMessage = { new ImportMessage { D = 20 }, new ImportMessage { D = 25 } },
|
||||
RepeatedInt32 = { 100, 200 },
|
||||
RepeatedInt64 = { 3210987654321, long.MaxValue },
|
||||
RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.FOO, TestAllTypes.Types.NestedEnum.NEG },
|
||||
RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.Foo, TestAllTypes.Types.NestedEnum.Neg },
|
||||
RepeatedNestedMessage = { new TestAllTypes.Types.NestedMessage { Bb = 35 }, new TestAllTypes.Types.NestedMessage { Bb = 10 } },
|
||||
RepeatedPublicImportMessage = { new PublicImportMessage { E = 54 }, new PublicImportMessage { E = -1 } },
|
||||
RepeatedSfixed32 = { -123, 123 },
|
||||
@ -224,8 +224,8 @@ namespace Google.Protobuf
|
||||
{ 5, new ForeignMessage() },
|
||||
},
|
||||
MapInt32Enum = {
|
||||
{ 1, MapEnum.MAP_ENUM_BAR },
|
||||
{ 2000, MapEnum.MAP_ENUM_FOO }
|
||||
{ 1, MapEnum.Bar },
|
||||
{ 2000, MapEnum.Foo }
|
||||
}
|
||||
};
|
||||
|
||||
@ -249,7 +249,7 @@ namespace Google.Protobuf
|
||||
Assert.AreEqual(1, parsed.MapInt32Bytes.Count);
|
||||
Assert.AreEqual(ByteString.Empty, parsed.MapInt32Bytes[0]);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void MapWithOnlyValue()
|
||||
{
|
||||
@ -449,7 +449,7 @@ namespace Google.Protobuf
|
||||
SingleFloat = 12.25f,
|
||||
SingleInt32 = 100,
|
||||
SingleInt64 = 3210987654321,
|
||||
SingleNestedEnum = TestAllTypes.Types.NestedEnum.FOO,
|
||||
SingleNestedEnum = TestAllTypes.Types.NestedEnum.Foo,
|
||||
SingleSfixed32 = -123,
|
||||
SingleSfixed64 = -12345678901234,
|
||||
SingleSint32 = -456,
|
||||
@ -479,7 +479,7 @@ namespace Google.Protobuf
|
||||
RepeatedFloat = { 100f, 12.25f },
|
||||
RepeatedInt32 = { 100, 200 },
|
||||
RepeatedInt64 = { 3210987654321, long.MaxValue },
|
||||
RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.FOO, TestAllTypes.Types.NestedEnum.NEG },
|
||||
RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.Foo, TestAllTypes.Types.NestedEnum.Neg },
|
||||
RepeatedSfixed32 = { -123, 123 },
|
||||
RepeatedSfixed64 = { -12345678901234, 12345678901234 },
|
||||
RepeatedSint32 = { -456, 100 },
|
||||
@ -670,7 +670,7 @@ namespace Google.Protobuf
|
||||
{
|
||||
// 130, 3 is the message tag
|
||||
// 1 is the data length - but there's no data.
|
||||
var data = new byte[] { 130, 3, 1 };
|
||||
var data = new byte[] { 130, 3, 1 };
|
||||
Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(data));
|
||||
}
|
||||
|
||||
@ -720,4 +720,4 @@ namespace Google.Protobuf
|
||||
Assert.AreEqual("{ \"c\": 31 }", writer.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -59,5 +59,24 @@ namespace Google.Protobuf
|
||||
// Underscores aren't reflected in the JSON.
|
||||
Assert.AreEqual("{ \"types\": 10, \"descriptor\": 20 }", message.ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void JsonNameParseTest()
|
||||
{
|
||||
var settings = new JsonParser.Settings(10, TypeRegistry.FromFiles(UnittestIssuesReflection.Descriptor));
|
||||
var parser = new JsonParser(settings);
|
||||
|
||||
// It is safe to use either original field name or explicitly specified json_name
|
||||
Assert.AreEqual(new TestJsonName { Name = "test", Description = "test2", Guid = "test3" },
|
||||
parser.Parse<TestJsonName>("{ \"name\": \"test\", \"desc\": \"test2\", \"guid\": \"test3\" }"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void JsonNameFormatTest()
|
||||
{
|
||||
var message = new TestJsonName { Name = "test", Description = "test2", Guid = "test3" };
|
||||
Assert.AreEqual("{ \"name\": \"test\", \"desc\": \"test2\", \"exid\": \"test3\" }",
|
||||
JsonFormatter.Default.Format(message));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -75,13 +75,13 @@ namespace Google.Protobuf
|
||||
SingleFixed32 = 23,
|
||||
SingleFixed64 = 1234567890123,
|
||||
SingleFloat = 12.25f,
|
||||
SingleForeignEnum = ForeignEnum.FOREIGN_BAR,
|
||||
SingleForeignEnum = ForeignEnum.ForeignBar,
|
||||
SingleForeignMessage = new ForeignMessage { C = 10 },
|
||||
SingleImportEnum = ImportEnum.IMPORT_BAZ,
|
||||
SingleImportEnum = ImportEnum.ImportBaz,
|
||||
SingleImportMessage = new ImportMessage { D = 20 },
|
||||
SingleInt32 = 100,
|
||||
SingleInt64 = 3210987654321,
|
||||
SingleNestedEnum = TestAllTypes.Types.NestedEnum.FOO,
|
||||
SingleNestedEnum = TestAllTypes.Types.NestedEnum.Foo,
|
||||
SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 35 },
|
||||
SinglePublicImportMessage = new PublicImportMessage { E = 54 },
|
||||
SingleSfixed32 = -123,
|
||||
@ -174,14 +174,14 @@ namespace Google.Protobuf
|
||||
[Test]
|
||||
public void UnknownEnumValueNumeric_RepeatedField()
|
||||
{
|
||||
var message = new TestAllTypes { RepeatedForeignEnum = { ForeignEnum.FOREIGN_BAZ, (ForeignEnum) 100, ForeignEnum.FOREIGN_FOO } };
|
||||
var message = new TestAllTypes { RepeatedForeignEnum = { ForeignEnum.ForeignBaz, (ForeignEnum) 100, ForeignEnum.ForeignFoo } };
|
||||
AssertJson("{ 'repeatedForeignEnum': [ 'FOREIGN_BAZ', 100, 'FOREIGN_FOO' ] }", JsonFormatter.Default.Format(message));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UnknownEnumValueNumeric_MapField()
|
||||
{
|
||||
var message = new TestMap { MapInt32Enum = { { 1, MapEnum.MAP_ENUM_FOO }, { 2, (MapEnum) 100 }, { 3, MapEnum.MAP_ENUM_BAR } } };
|
||||
var message = new TestMap { MapInt32Enum = { { 1, MapEnum.Foo }, { 2, (MapEnum) 100 }, { 3, MapEnum.Bar } } };
|
||||
AssertJson("{ 'mapInt32Enum': { '1': 'MAP_ENUM_FOO', '2': 100, '3': 'MAP_ENUM_BAR' } }", JsonFormatter.Default.Format(message));
|
||||
}
|
||||
|
||||
@ -321,7 +321,6 @@ namespace Google.Protobuf
|
||||
[TestCase("1970-01-01T00:00:00.001Z", 1000000)]
|
||||
[TestCase("1970-01-01T00:00:00.010Z", 10000000)]
|
||||
[TestCase("1970-01-01T00:00:00.100Z", 100000000)]
|
||||
[TestCase("1970-01-01T00:00:00.100Z", 100000000)]
|
||||
[TestCase("1970-01-01T00:00:00.120Z", 120000000)]
|
||||
[TestCase("1970-01-01T00:00:00.123Z", 123000000)]
|
||||
[TestCase("1970-01-01T00:00:00.123400Z", 123400000)]
|
||||
@ -481,6 +480,15 @@ namespace Google.Protobuf
|
||||
AssertJson("{ '@type': 'type.googleapis.com/protobuf_unittest.TestAllTypes', 'singleInt32': 10, 'singleNestedMessage': { 'bb': 20 } }", formatter.Format(any));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AnyMessageType_CustomPrefix()
|
||||
{
|
||||
var formatter = new JsonFormatter(new JsonFormatter.Settings(false, TypeRegistry.FromMessages(TestAllTypes.Descriptor)));
|
||||
var message = new TestAllTypes { SingleInt32 = 10 };
|
||||
var any = Any.Pack(message, "foo.bar/baz");
|
||||
AssertJson("{ '@type': 'foo.bar/baz/protobuf_unittest.TestAllTypes', 'singleInt32': 10 }", formatter.Format(any));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AnyNested()
|
||||
{
|
||||
|
@ -142,8 +142,8 @@ namespace Google.Protobuf
|
||||
[TestCase(typeof(DoubleValue), "1.5", 1.5d)]
|
||||
public void Wrappers_Standalone(System.Type wrapperType, string json, object expectedValue)
|
||||
{
|
||||
IMessage parsed = (IMessage) Activator.CreateInstance(wrapperType);
|
||||
IMessage expected = (IMessage) Activator.CreateInstance(wrapperType);
|
||||
IMessage parsed = (IMessage)Activator.CreateInstance(wrapperType);
|
||||
IMessage expected = (IMessage)Activator.CreateInstance(wrapperType);
|
||||
JsonParser.Default.Merge(parsed, "null");
|
||||
Assert.AreEqual(expected, parsed);
|
||||
|
||||
@ -640,7 +640,7 @@ namespace Google.Protobuf
|
||||
var parsed = Timestamp.Parser.ParseJson(json);
|
||||
Assert.AreEqual(WrapInQuotes(expectedFormatted), parsed.ToString());
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
[TestCase("2015-10-09 14:46:23.123456789Z", Description = "No T between date and time")]
|
||||
[TestCase("2015/10/09T14:46:23.123456789Z", Description = "Wrong date separators")]
|
||||
@ -810,6 +810,17 @@ namespace Google.Protobuf
|
||||
Assert.AreEqual(original, parser.Parse<Any>(valueFirstJson));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Any_CustomPrefix()
|
||||
{
|
||||
var registry = TypeRegistry.FromMessages(TestAllTypes.Descriptor);
|
||||
var message = new TestAllTypes { SingleInt32 = 10 };
|
||||
var original = Any.Pack(message, "custom.prefix/middle-part");
|
||||
var parser = new JsonParser(new JsonParser.Settings(10, registry));
|
||||
string json = "{ \"@type\": \"custom.prefix/middle-part/protobuf_unittest.TestAllTypes\", \"singleInt32\": 10 }";
|
||||
Assert.AreEqual(original, parser.Parse<Any>(json));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Any_UnknownType()
|
||||
{
|
||||
@ -886,9 +897,9 @@ namespace Google.Protobuf
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("\"FOREIGN_BAR\"", ForeignEnum.FOREIGN_BAR)]
|
||||
[TestCase("5", ForeignEnum.FOREIGN_BAR)]
|
||||
[TestCase("100", (ForeignEnum) 100)]
|
||||
[TestCase("\"FOREIGN_BAR\"", ForeignEnum.ForeignBar)]
|
||||
[TestCase("5", ForeignEnum.ForeignBar)]
|
||||
[TestCase("100", (ForeignEnum)100)]
|
||||
public void EnumValid(string value, ForeignEnum expectedValue)
|
||||
{
|
||||
string json = "{ \"singleForeignEnum\": " + value + " }";
|
||||
@ -922,4 +933,4 @@ namespace Google.Protobuf
|
||||
return '"' + text + '"';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -249,7 +249,6 @@ namespace Google.Protobuf
|
||||
[TestCase("[,", 1)]
|
||||
[TestCase("{", 1)]
|
||||
[TestCase("{,", 1)]
|
||||
[TestCase("{", 1)]
|
||||
[TestCase("{[", 1)]
|
||||
[TestCase("{{", 1)]
|
||||
[TestCase("{0", 1)]
|
||||
|
@ -195,7 +195,7 @@ namespace Google.Protobuf.Reflection
|
||||
Assert.AreEqual(value, enumType.Values[1]);
|
||||
Assert.AreEqual("FOREIGN_FOO", value.Name);
|
||||
Assert.AreEqual(4, value.Number);
|
||||
Assert.AreEqual((int) ForeignEnum.FOREIGN_FOO, value.Number);
|
||||
Assert.AreEqual((int) ForeignEnum.ForeignFoo, value.Number);
|
||||
Assert.AreEqual(value, enumType.FindValueByNumber(4));
|
||||
Assert.Null(enumType.FindValueByName("NO_SUCH_VALUE"));
|
||||
for (int i = 0; i < enumType.Values.Count; i++)
|
||||
|
@ -128,7 +128,7 @@ namespace Google.Protobuf.Reflection
|
||||
fields[TestAllTypes.SingleInt32FieldNumber].Accessor.SetValue(message, 500);
|
||||
fields[TestAllTypes.SingleStringFieldNumber].Accessor.SetValue(message, "It's a string");
|
||||
fields[TestAllTypes.SingleBytesFieldNumber].Accessor.SetValue(message, ByteString.CopyFrom(99, 98, 97));
|
||||
fields[TestAllTypes.SingleForeignEnumFieldNumber].Accessor.SetValue(message, ForeignEnum.FOREIGN_FOO);
|
||||
fields[TestAllTypes.SingleForeignEnumFieldNumber].Accessor.SetValue(message, ForeignEnum.ForeignFoo);
|
||||
fields[TestAllTypes.SingleForeignMessageFieldNumber].Accessor.SetValue(message, new ForeignMessage { C = 12345 });
|
||||
fields[TestAllTypes.SingleDoubleFieldNumber].Accessor.SetValue(message, 20150701.5);
|
||||
|
||||
@ -138,7 +138,7 @@ namespace Google.Protobuf.Reflection
|
||||
SingleInt32 = 500,
|
||||
SingleString = "It's a string",
|
||||
SingleBytes = ByteString.CopyFrom(99, 98, 97),
|
||||
SingleForeignEnum = ForeignEnum.FOREIGN_FOO,
|
||||
SingleForeignEnum = ForeignEnum.ForeignFoo,
|
||||
SingleForeignMessage = new ForeignMessage { C = 12345 },
|
||||
SingleDouble = 20150701.5
|
||||
};
|
||||
|
@ -54,13 +54,13 @@ namespace Google.Protobuf
|
||||
SingleFixed32 = 23,
|
||||
SingleFixed64 = 1234567890123,
|
||||
SingleFloat = 12.25f,
|
||||
SingleForeignEnum = ForeignEnum.FOREIGN_BAR,
|
||||
SingleForeignEnum = ForeignEnum.ForeignBar,
|
||||
SingleForeignMessage = new ForeignMessage { C = 10 },
|
||||
SingleImportEnum = ImportEnum.IMPORT_BAZ,
|
||||
SingleImportEnum = ImportEnum.ImportBaz,
|
||||
SingleImportMessage = new ImportMessage { D = 20 },
|
||||
SingleInt32 = 100,
|
||||
SingleInt64 = 3210987654321,
|
||||
SingleNestedEnum = TestAllTypes.Types.NestedEnum.FOO,
|
||||
SingleNestedEnum = TestAllTypes.Types.NestedEnum.Foo,
|
||||
SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 35 },
|
||||
SinglePublicImportMessage = new PublicImportMessage { E = 54 },
|
||||
SingleSfixed32 = -123,
|
||||
@ -76,13 +76,13 @@ namespace Google.Protobuf
|
||||
RepeatedFixed32 = { UInt32.MaxValue, 23 },
|
||||
RepeatedFixed64 = { UInt64.MaxValue, 1234567890123 },
|
||||
RepeatedFloat = { 100f, 12.25f },
|
||||
RepeatedForeignEnum = { ForeignEnum.FOREIGN_FOO, ForeignEnum.FOREIGN_BAR },
|
||||
RepeatedForeignEnum = { ForeignEnum.ForeignFoo, ForeignEnum.ForeignBar },
|
||||
RepeatedForeignMessage = { new ForeignMessage(), new ForeignMessage { C = 10 } },
|
||||
RepeatedImportEnum = { ImportEnum.IMPORT_BAZ, ImportEnum.IMPORT_ENUM_UNSPECIFIED },
|
||||
RepeatedImportEnum = { ImportEnum.ImportBaz, ImportEnum.Unspecified },
|
||||
RepeatedImportMessage = { new ImportMessage { D = 20 }, new ImportMessage { D = 25 } },
|
||||
RepeatedInt32 = { 100, 200 },
|
||||
RepeatedInt64 = { 3210987654321, Int64.MaxValue },
|
||||
RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.FOO, TestAllTypes.Types.NestedEnum.NEG },
|
||||
RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.Foo, TestAllTypes.Types.NestedEnum.Neg },
|
||||
RepeatedNestedMessage = { new TestAllTypes.Types.NestedMessage { Bb = 35 }, new TestAllTypes.Types.NestedMessage { Bb = 10 } },
|
||||
RepeatedPublicImportMessage = { new PublicImportMessage { E = 54 }, new PublicImportMessage { E = -1 } },
|
||||
RepeatedSfixed32 = { -123, 123 },
|
||||
@ -92,8 +92,8 @@ namespace Google.Protobuf
|
||||
RepeatedString = { "foo", "bar" },
|
||||
RepeatedUint32 = { UInt32.MaxValue, UInt32.MinValue },
|
||||
RepeatedUint64 = { UInt64.MaxValue, UInt32.MinValue },
|
||||
OneofString = "Oneof string"
|
||||
OneofString = "Oneof string"
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -43,8 +43,8 @@ namespace Google.Protobuf
|
||||
NegativeEnumMessage msg = new NegativeEnumMessage
|
||||
{
|
||||
Value = NegativeEnum.MinusOne,
|
||||
Values = { NegativeEnum.NEGATIVE_ENUM_ZERO, NegativeEnum.MinusOne, NegativeEnum.FiveBelow },
|
||||
PackedValues = { NegativeEnum.NEGATIVE_ENUM_ZERO, NegativeEnum.MinusOne, NegativeEnum.FiveBelow }
|
||||
Values = { NegativeEnum.Zero, NegativeEnum.MinusOne, NegativeEnum.FiveBelow },
|
||||
PackedValues = { NegativeEnum.Zero, NegativeEnum.MinusOne, NegativeEnum.FiveBelow }
|
||||
};
|
||||
|
||||
Assert.AreEqual(58, msg.CalculateSize());
|
||||
|
@ -164,9 +164,9 @@ namespace Google.Protobuf.TestProtos {
|
||||
}
|
||||
#region Enums
|
||||
public enum MapEnum {
|
||||
MAP_ENUM_FOO = 0,
|
||||
MAP_ENUM_BAR = 1,
|
||||
MAP_ENUM_BAZ = 2,
|
||||
[pbr::OriginalName("MAP_ENUM_FOO")] Foo = 0,
|
||||
[pbr::OriginalName("MAP_ENUM_BAR")] Bar = 1,
|
||||
[pbr::OriginalName("MAP_ENUM_BAZ")] Baz = 2,
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -1358,7 +1358,7 @@ namespace Google.Protobuf.TestProtos {
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
public static partial class Types {
|
||||
public enum Type {
|
||||
TYPE_FOO = 0,
|
||||
[pbr::OriginalName("TYPE_FOO")] Foo = 0,
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -42,10 +42,10 @@ namespace Google.Protobuf.TestProtos {
|
||||
}
|
||||
#region Enums
|
||||
public enum ImportEnum {
|
||||
IMPORT_ENUM_UNSPECIFIED = 0,
|
||||
IMPORT_FOO = 7,
|
||||
IMPORT_BAR = 8,
|
||||
IMPORT_BAZ = 9,
|
||||
[pbr::OriginalName("IMPORT_ENUM_UNSPECIFIED")] Unspecified = 0,
|
||||
[pbr::OriginalName("IMPORT_FOO")] ImportFoo = 7,
|
||||
[pbr::OriginalName("IMPORT_BAR")] ImportBar = 8,
|
||||
[pbr::OriginalName("IMPORT_BAZ")] ImportBaz = 9,
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -42,10 +42,12 @@ namespace UnitTest.Issues.TestProtos {
|
||||
"CgtwbGFpbl9pbnQzMhgEIAEoBRITCglvMV9zdHJpbmcYAiABKAlIABISCghv",
|
||||
"MV9pbnQzMhgFIAEoBUgAEhQKDHBsYWluX3N0cmluZxgBIAEoCRISCghvMl9p",
|
||||
"bnQzMhgGIAEoBUgBEhMKCW8yX3N0cmluZxgDIAEoCUgBQgQKAm8xQgQKAm8y",
|
||||
"KlUKDE5lZ2F0aXZlRW51bRIWChJORUdBVElWRV9FTlVNX1pFUk8QABIWCglG",
|
||||
"aXZlQmVsb3cQ+///////////ARIVCghNaW51c09uZRD///////////8BKi4K",
|
||||
"DkRlcHJlY2F0ZWRFbnVtEhMKD0RFUFJFQ0FURURfWkVSTxAAEgcKA29uZRAB",
|
||||
"Qh9IAaoCGlVuaXRUZXN0Lklzc3Vlcy5UZXN0UHJvdG9zYgZwcm90bzM="));
|
||||
"IksKDFRlc3RKc29uTmFtZRIMCgRuYW1lGAEgASgJEhkKC2Rlc2NyaXB0aW9u",
|
||||
"GAIgASgJUgRkZXNjEhIKBGd1aWQYAyABKAlSBGV4aWQqVQoMTmVnYXRpdmVF",
|
||||
"bnVtEhYKEk5FR0FUSVZFX0VOVU1fWkVSTxAAEhYKCUZpdmVCZWxvdxD7////",
|
||||
"//////8BEhUKCE1pbnVzT25lEP///////////wEqLgoORGVwcmVjYXRlZEVu",
|
||||
"dW0SEwoPREVQUkVDQVRFRF9aRVJPEAASBwoDb25lEAFCH0gBqgIaVW5pdFRl",
|
||||
"c3QuSXNzdWVzLlRlc3RQcm90b3NiBnByb3RvMw=="));
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedClrTypeInfo(new[] {typeof(global::UnitTest.Issues.TestProtos.NegativeEnum), typeof(global::UnitTest.Issues.TestProtos.DeprecatedEnum), }, new pbr::GeneratedClrTypeInfo[] {
|
||||
@ -55,7 +57,8 @@ namespace UnitTest.Issues.TestProtos {
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.DeprecatedFieldsMessage), global::UnitTest.Issues.TestProtos.DeprecatedFieldsMessage.Parser, new[]{ "PrimitiveValue", "PrimitiveArray", "MessageValue", "MessageArray", "EnumValue", "EnumArray" }, null, null, null),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ItemField), global::UnitTest.Issues.TestProtos.ItemField.Parser, new[]{ "Item" }, null, null, null),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ReservedNames), global::UnitTest.Issues.TestProtos.ReservedNames.Parser, new[]{ "Types_", "Descriptor_" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ReservedNames.Types.SomeNestedType), global::UnitTest.Issues.TestProtos.ReservedNames.Types.SomeNestedType.Parser, null, null, null, null)}),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.TestJsonFieldOrdering), global::UnitTest.Issues.TestProtos.TestJsonFieldOrdering.Parser, new[]{ "PlainInt32", "O1String", "O1Int32", "PlainString", "O2Int32", "O2String" }, new[]{ "O1", "O2" }, null, null)
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.TestJsonFieldOrdering), global::UnitTest.Issues.TestProtos.TestJsonFieldOrdering.Parser, new[]{ "PlainInt32", "O1String", "O1Int32", "PlainString", "O2Int32", "O2String" }, new[]{ "O1", "O2" }, null, null),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.TestJsonName), global::UnitTest.Issues.TestProtos.TestJsonName.Parser, new[]{ "Name", "Description", "Guid" }, null, null, null)
|
||||
}));
|
||||
}
|
||||
#endregion
|
||||
@ -63,14 +66,14 @@ namespace UnitTest.Issues.TestProtos {
|
||||
}
|
||||
#region Enums
|
||||
public enum NegativeEnum {
|
||||
NEGATIVE_ENUM_ZERO = 0,
|
||||
FiveBelow = -5,
|
||||
MinusOne = -1,
|
||||
[pbr::OriginalName("NEGATIVE_ENUM_ZERO")] Zero = 0,
|
||||
[pbr::OriginalName("FiveBelow")] FiveBelow = -5,
|
||||
[pbr::OriginalName("MinusOne")] MinusOne = -1,
|
||||
}
|
||||
|
||||
public enum DeprecatedEnum {
|
||||
DEPRECATED_ZERO = 0,
|
||||
one = 1,
|
||||
[pbr::OriginalName("DEPRECATED_ZERO")] DeprecatedZero = 0,
|
||||
[pbr::OriginalName("one")] One = 1,
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -353,7 +356,7 @@ namespace UnitTest.Issues.TestProtos {
|
||||
|
||||
/// <summary>Field number for the "value" field.</summary>
|
||||
public const int ValueFieldNumber = 1;
|
||||
private global::UnitTest.Issues.TestProtos.NegativeEnum value_ = global::UnitTest.Issues.TestProtos.NegativeEnum.NEGATIVE_ENUM_ZERO;
|
||||
private global::UnitTest.Issues.TestProtos.NegativeEnum value_ = 0;
|
||||
public global::UnitTest.Issues.TestProtos.NegativeEnum Value {
|
||||
get { return value_; }
|
||||
set {
|
||||
@ -398,7 +401,7 @@ namespace UnitTest.Issues.TestProtos {
|
||||
|
||||
public override int GetHashCode() {
|
||||
int hash = 1;
|
||||
if (Value != global::UnitTest.Issues.TestProtos.NegativeEnum.NEGATIVE_ENUM_ZERO) hash ^= Value.GetHashCode();
|
||||
if (Value != 0) hash ^= Value.GetHashCode();
|
||||
hash ^= values_.GetHashCode();
|
||||
hash ^= packedValues_.GetHashCode();
|
||||
return hash;
|
||||
@ -409,7 +412,7 @@ namespace UnitTest.Issues.TestProtos {
|
||||
}
|
||||
|
||||
public void WriteTo(pb::CodedOutputStream output) {
|
||||
if (Value != global::UnitTest.Issues.TestProtos.NegativeEnum.NEGATIVE_ENUM_ZERO) {
|
||||
if (Value != 0) {
|
||||
output.WriteRawTag(8);
|
||||
output.WriteEnum((int) Value);
|
||||
}
|
||||
@ -419,7 +422,7 @@ namespace UnitTest.Issues.TestProtos {
|
||||
|
||||
public int CalculateSize() {
|
||||
int size = 0;
|
||||
if (Value != global::UnitTest.Issues.TestProtos.NegativeEnum.NEGATIVE_ENUM_ZERO) {
|
||||
if (Value != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Value);
|
||||
}
|
||||
size += values_.CalculateSize(_repeated_values_codec);
|
||||
@ -431,7 +434,7 @@ namespace UnitTest.Issues.TestProtos {
|
||||
if (other == null) {
|
||||
return;
|
||||
}
|
||||
if (other.Value != global::UnitTest.Issues.TestProtos.NegativeEnum.NEGATIVE_ENUM_ZERO) {
|
||||
if (other.Value != 0) {
|
||||
Value = other.Value;
|
||||
}
|
||||
values_.Add(other.values_);
|
||||
@ -617,7 +620,7 @@ namespace UnitTest.Issues.TestProtos {
|
||||
|
||||
/// <summary>Field number for the "EnumValue" field.</summary>
|
||||
public const int EnumValueFieldNumber = 5;
|
||||
private global::UnitTest.Issues.TestProtos.DeprecatedEnum enumValue_ = global::UnitTest.Issues.TestProtos.DeprecatedEnum.DEPRECATED_ZERO;
|
||||
private global::UnitTest.Issues.TestProtos.DeprecatedEnum enumValue_ = 0;
|
||||
[global::System.ObsoleteAttribute()]
|
||||
public global::UnitTest.Issues.TestProtos.DeprecatedEnum EnumValue {
|
||||
get { return enumValue_; }
|
||||
@ -662,7 +665,7 @@ namespace UnitTest.Issues.TestProtos {
|
||||
hash ^= primitiveArray_.GetHashCode();
|
||||
if (messageValue_ != null) hash ^= MessageValue.GetHashCode();
|
||||
hash ^= messageArray_.GetHashCode();
|
||||
if (EnumValue != global::UnitTest.Issues.TestProtos.DeprecatedEnum.DEPRECATED_ZERO) hash ^= EnumValue.GetHashCode();
|
||||
if (EnumValue != 0) hash ^= EnumValue.GetHashCode();
|
||||
hash ^= enumArray_.GetHashCode();
|
||||
return hash;
|
||||
}
|
||||
@ -682,7 +685,7 @@ namespace UnitTest.Issues.TestProtos {
|
||||
output.WriteMessage(MessageValue);
|
||||
}
|
||||
messageArray_.WriteTo(output, _repeated_messageArray_codec);
|
||||
if (EnumValue != global::UnitTest.Issues.TestProtos.DeprecatedEnum.DEPRECATED_ZERO) {
|
||||
if (EnumValue != 0) {
|
||||
output.WriteRawTag(40);
|
||||
output.WriteEnum((int) EnumValue);
|
||||
}
|
||||
@ -699,7 +702,7 @@ namespace UnitTest.Issues.TestProtos {
|
||||
size += 1 + pb::CodedOutputStream.ComputeMessageSize(MessageValue);
|
||||
}
|
||||
size += messageArray_.CalculateSize(_repeated_messageArray_codec);
|
||||
if (EnumValue != global::UnitTest.Issues.TestProtos.DeprecatedEnum.DEPRECATED_ZERO) {
|
||||
if (EnumValue != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) EnumValue);
|
||||
}
|
||||
size += enumArray_.CalculateSize(_repeated_enumArray_codec);
|
||||
@ -721,7 +724,7 @@ namespace UnitTest.Issues.TestProtos {
|
||||
MessageValue.MergeFrom(other.MessageValue);
|
||||
}
|
||||
messageArray_.Add(other.messageArray_);
|
||||
if (other.EnumValue != global::UnitTest.Issues.TestProtos.DeprecatedEnum.DEPRECATED_ZERO) {
|
||||
if (other.EnumValue != 0) {
|
||||
EnumValue = other.EnumValue;
|
||||
}
|
||||
enumArray_.Add(other.enumArray_);
|
||||
@ -1399,6 +1402,166 @@ namespace UnitTest.Issues.TestProtos {
|
||||
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
public sealed partial class TestJsonName : pb::IMessage<TestJsonName> {
|
||||
private static readonly pb::MessageParser<TestJsonName> _parser = new pb::MessageParser<TestJsonName>(() => new TestJsonName());
|
||||
public static pb::MessageParser<TestJsonName> Parser { get { return _parser; } }
|
||||
|
||||
public static pbr::MessageDescriptor Descriptor {
|
||||
get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[7]; }
|
||||
}
|
||||
|
||||
pbr::MessageDescriptor pb::IMessage.Descriptor {
|
||||
get { return Descriptor; }
|
||||
}
|
||||
|
||||
public TestJsonName() {
|
||||
OnConstruction();
|
||||
}
|
||||
|
||||
partial void OnConstruction();
|
||||
|
||||
public TestJsonName(TestJsonName other) : this() {
|
||||
name_ = other.name_;
|
||||
description_ = other.description_;
|
||||
guid_ = other.guid_;
|
||||
}
|
||||
|
||||
public TestJsonName Clone() {
|
||||
return new TestJsonName(this);
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "name" field.</summary>
|
||||
public const int NameFieldNumber = 1;
|
||||
private string name_ = "";
|
||||
/// <summary>
|
||||
/// Message for testing the effects for of the json_name option
|
||||
/// </summary>
|
||||
public string Name {
|
||||
get { return name_; }
|
||||
set {
|
||||
name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "description" field.</summary>
|
||||
public const int DescriptionFieldNumber = 2;
|
||||
private string description_ = "";
|
||||
public string Description {
|
||||
get { return description_; }
|
||||
set {
|
||||
description_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "guid" field.</summary>
|
||||
public const int GuidFieldNumber = 3;
|
||||
private string guid_ = "";
|
||||
public string Guid {
|
||||
get { return guid_; }
|
||||
set {
|
||||
guid_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Equals(object other) {
|
||||
return Equals(other as TestJsonName);
|
||||
}
|
||||
|
||||
public bool Equals(TestJsonName other) {
|
||||
if (ReferenceEquals(other, null)) {
|
||||
return false;
|
||||
}
|
||||
if (ReferenceEquals(other, this)) {
|
||||
return true;
|
||||
}
|
||||
if (Name != other.Name) return false;
|
||||
if (Description != other.Description) return false;
|
||||
if (Guid != other.Guid) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override int GetHashCode() {
|
||||
int hash = 1;
|
||||
if (Name.Length != 0) hash ^= Name.GetHashCode();
|
||||
if (Description.Length != 0) hash ^= Description.GetHashCode();
|
||||
if (Guid.Length != 0) hash ^= Guid.GetHashCode();
|
||||
return hash;
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return pb::JsonFormatter.ToDiagnosticString(this);
|
||||
}
|
||||
|
||||
public void WriteTo(pb::CodedOutputStream output) {
|
||||
if (Name.Length != 0) {
|
||||
output.WriteRawTag(10);
|
||||
output.WriteString(Name);
|
||||
}
|
||||
if (Description.Length != 0) {
|
||||
output.WriteRawTag(18);
|
||||
output.WriteString(Description);
|
||||
}
|
||||
if (Guid.Length != 0) {
|
||||
output.WriteRawTag(26);
|
||||
output.WriteString(Guid);
|
||||
}
|
||||
}
|
||||
|
||||
public int CalculateSize() {
|
||||
int size = 0;
|
||||
if (Name.Length != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
|
||||
}
|
||||
if (Description.Length != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeStringSize(Description);
|
||||
}
|
||||
if (Guid.Length != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeStringSize(Guid);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
public void MergeFrom(TestJsonName other) {
|
||||
if (other == null) {
|
||||
return;
|
||||
}
|
||||
if (other.Name.Length != 0) {
|
||||
Name = other.Name;
|
||||
}
|
||||
if (other.Description.Length != 0) {
|
||||
Description = other.Description;
|
||||
}
|
||||
if (other.Guid.Length != 0) {
|
||||
Guid = other.Guid;
|
||||
}
|
||||
}
|
||||
|
||||
public void MergeFrom(pb::CodedInputStream input) {
|
||||
uint tag;
|
||||
while ((tag = input.ReadTag()) != 0) {
|
||||
switch(tag) {
|
||||
default:
|
||||
input.SkipLastField();
|
||||
break;
|
||||
case 10: {
|
||||
Name = input.ReadString();
|
||||
break;
|
||||
}
|
||||
case 18: {
|
||||
Description = input.ReadString();
|
||||
break;
|
||||
}
|
||||
case 26: {
|
||||
Guid = input.ReadString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
@ -193,39 +193,39 @@ namespace Google.Protobuf.TestProtos {
|
||||
}
|
||||
#region Enums
|
||||
public enum ForeignEnum {
|
||||
FOREIGN_UNSPECIFIED = 0,
|
||||
FOREIGN_FOO = 4,
|
||||
FOREIGN_BAR = 5,
|
||||
FOREIGN_BAZ = 6,
|
||||
[pbr::OriginalName("FOREIGN_UNSPECIFIED")] ForeignUnspecified = 0,
|
||||
[pbr::OriginalName("FOREIGN_FOO")] ForeignFoo = 4,
|
||||
[pbr::OriginalName("FOREIGN_BAR")] ForeignBar = 5,
|
||||
[pbr::OriginalName("FOREIGN_BAZ")] ForeignBaz = 6,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test an enum that has multiple values with the same number.
|
||||
/// </summary>
|
||||
public enum TestEnumWithDupValue {
|
||||
TEST_ENUM_WITH_DUP_VALUE_UNSPECIFIED = 0,
|
||||
FOO1 = 1,
|
||||
BAR1 = 2,
|
||||
BAZ = 3,
|
||||
FOO2 = 1,
|
||||
BAR2 = 2,
|
||||
[pbr::OriginalName("TEST_ENUM_WITH_DUP_VALUE_UNSPECIFIED")] Unspecified = 0,
|
||||
[pbr::OriginalName("FOO1")] Foo1 = 1,
|
||||
[pbr::OriginalName("BAR1")] Bar1 = 2,
|
||||
[pbr::OriginalName("BAZ")] Baz = 3,
|
||||
[pbr::OriginalName("FOO2")] Foo2 = 1,
|
||||
[pbr::OriginalName("BAR2")] Bar2 = 2,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test an enum with large, unordered values.
|
||||
/// </summary>
|
||||
public enum TestSparseEnum {
|
||||
TEST_SPARSE_ENUM_UNSPECIFIED = 0,
|
||||
SPARSE_A = 123,
|
||||
SPARSE_B = 62374,
|
||||
SPARSE_C = 12589234,
|
||||
SPARSE_D = -15,
|
||||
SPARSE_E = -53452,
|
||||
[pbr::OriginalName("TEST_SPARSE_ENUM_UNSPECIFIED")] Unspecified = 0,
|
||||
[pbr::OriginalName("SPARSE_A")] SparseA = 123,
|
||||
[pbr::OriginalName("SPARSE_B")] SparseB = 62374,
|
||||
[pbr::OriginalName("SPARSE_C")] SparseC = 12589234,
|
||||
[pbr::OriginalName("SPARSE_D")] SparseD = -15,
|
||||
[pbr::OriginalName("SPARSE_E")] SparseE = -53452,
|
||||
/// <summary>
|
||||
/// In proto3, value 0 must be the first one specified
|
||||
/// SPARSE_F = 0;
|
||||
/// </summary>
|
||||
SPARSE_G = 2,
|
||||
[pbr::OriginalName("SPARSE_G")] SparseG = 2,
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -505,7 +505,7 @@ namespace Google.Protobuf.TestProtos {
|
||||
|
||||
/// <summary>Field number for the "single_nested_enum" field.</summary>
|
||||
public const int SingleNestedEnumFieldNumber = 21;
|
||||
private global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum singleNestedEnum_ = global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum.NESTED_ENUM_UNSPECIFIED;
|
||||
private global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum singleNestedEnum_ = 0;
|
||||
public global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum SingleNestedEnum {
|
||||
get { return singleNestedEnum_; }
|
||||
set {
|
||||
@ -515,7 +515,7 @@ namespace Google.Protobuf.TestProtos {
|
||||
|
||||
/// <summary>Field number for the "single_foreign_enum" field.</summary>
|
||||
public const int SingleForeignEnumFieldNumber = 22;
|
||||
private global::Google.Protobuf.TestProtos.ForeignEnum singleForeignEnum_ = global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED;
|
||||
private global::Google.Protobuf.TestProtos.ForeignEnum singleForeignEnum_ = 0;
|
||||
public global::Google.Protobuf.TestProtos.ForeignEnum SingleForeignEnum {
|
||||
get { return singleForeignEnum_; }
|
||||
set {
|
||||
@ -525,7 +525,7 @@ namespace Google.Protobuf.TestProtos {
|
||||
|
||||
/// <summary>Field number for the "single_import_enum" field.</summary>
|
||||
public const int SingleImportEnumFieldNumber = 23;
|
||||
private global::Google.Protobuf.TestProtos.ImportEnum singleImportEnum_ = global::Google.Protobuf.TestProtos.ImportEnum.IMPORT_ENUM_UNSPECIFIED;
|
||||
private global::Google.Protobuf.TestProtos.ImportEnum singleImportEnum_ = 0;
|
||||
public global::Google.Protobuf.TestProtos.ImportEnum SingleImportEnum {
|
||||
get { return singleImportEnum_; }
|
||||
set {
|
||||
@ -892,9 +892,9 @@ namespace Google.Protobuf.TestProtos {
|
||||
if (singleNestedMessage_ != null) hash ^= SingleNestedMessage.GetHashCode();
|
||||
if (singleForeignMessage_ != null) hash ^= SingleForeignMessage.GetHashCode();
|
||||
if (singleImportMessage_ != null) hash ^= SingleImportMessage.GetHashCode();
|
||||
if (SingleNestedEnum != global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum.NESTED_ENUM_UNSPECIFIED) hash ^= SingleNestedEnum.GetHashCode();
|
||||
if (SingleForeignEnum != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) hash ^= SingleForeignEnum.GetHashCode();
|
||||
if (SingleImportEnum != global::Google.Protobuf.TestProtos.ImportEnum.IMPORT_ENUM_UNSPECIFIED) hash ^= SingleImportEnum.GetHashCode();
|
||||
if (SingleNestedEnum != 0) hash ^= SingleNestedEnum.GetHashCode();
|
||||
if (SingleForeignEnum != 0) hash ^= SingleForeignEnum.GetHashCode();
|
||||
if (SingleImportEnum != 0) hash ^= SingleImportEnum.GetHashCode();
|
||||
if (singlePublicImportMessage_ != null) hash ^= SinglePublicImportMessage.GetHashCode();
|
||||
hash ^= repeatedInt32_.GetHashCode();
|
||||
hash ^= repeatedInt64_.GetHashCode();
|
||||
@ -1003,15 +1003,15 @@ namespace Google.Protobuf.TestProtos {
|
||||
output.WriteRawTag(162, 1);
|
||||
output.WriteMessage(SingleImportMessage);
|
||||
}
|
||||
if (SingleNestedEnum != global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum.NESTED_ENUM_UNSPECIFIED) {
|
||||
if (SingleNestedEnum != 0) {
|
||||
output.WriteRawTag(168, 1);
|
||||
output.WriteEnum((int) SingleNestedEnum);
|
||||
}
|
||||
if (SingleForeignEnum != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) {
|
||||
if (SingleForeignEnum != 0) {
|
||||
output.WriteRawTag(176, 1);
|
||||
output.WriteEnum((int) SingleForeignEnum);
|
||||
}
|
||||
if (SingleImportEnum != global::Google.Protobuf.TestProtos.ImportEnum.IMPORT_ENUM_UNSPECIFIED) {
|
||||
if (SingleImportEnum != 0) {
|
||||
output.WriteRawTag(184, 1);
|
||||
output.WriteEnum((int) SingleImportEnum);
|
||||
}
|
||||
@ -1115,13 +1115,13 @@ namespace Google.Protobuf.TestProtos {
|
||||
if (singleImportMessage_ != null) {
|
||||
size += 2 + pb::CodedOutputStream.ComputeMessageSize(SingleImportMessage);
|
||||
}
|
||||
if (SingleNestedEnum != global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum.NESTED_ENUM_UNSPECIFIED) {
|
||||
if (SingleNestedEnum != 0) {
|
||||
size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) SingleNestedEnum);
|
||||
}
|
||||
if (SingleForeignEnum != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) {
|
||||
if (SingleForeignEnum != 0) {
|
||||
size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) SingleForeignEnum);
|
||||
}
|
||||
if (SingleImportEnum != global::Google.Protobuf.TestProtos.ImportEnum.IMPORT_ENUM_UNSPECIFIED) {
|
||||
if (SingleImportEnum != 0) {
|
||||
size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) SingleImportEnum);
|
||||
}
|
||||
if (singlePublicImportMessage_ != null) {
|
||||
@ -1231,13 +1231,13 @@ namespace Google.Protobuf.TestProtos {
|
||||
}
|
||||
SingleImportMessage.MergeFrom(other.SingleImportMessage);
|
||||
}
|
||||
if (other.SingleNestedEnum != global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum.NESTED_ENUM_UNSPECIFIED) {
|
||||
if (other.SingleNestedEnum != 0) {
|
||||
SingleNestedEnum = other.SingleNestedEnum;
|
||||
}
|
||||
if (other.SingleForeignEnum != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) {
|
||||
if (other.SingleForeignEnum != 0) {
|
||||
SingleForeignEnum = other.SingleForeignEnum;
|
||||
}
|
||||
if (other.SingleImportEnum != global::Google.Protobuf.TestProtos.ImportEnum.IMPORT_ENUM_UNSPECIFIED) {
|
||||
if (other.SingleImportEnum != 0) {
|
||||
SingleImportEnum = other.SingleImportEnum;
|
||||
}
|
||||
if (other.singlePublicImportMessage_ != null) {
|
||||
@ -1526,14 +1526,14 @@ namespace Google.Protobuf.TestProtos {
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
public static partial class Types {
|
||||
public enum NestedEnum {
|
||||
NESTED_ENUM_UNSPECIFIED = 0,
|
||||
FOO = 1,
|
||||
BAR = 2,
|
||||
BAZ = 3,
|
||||
[pbr::OriginalName("NESTED_ENUM_UNSPECIFIED")] Unspecified = 0,
|
||||
[pbr::OriginalName("FOO")] Foo = 1,
|
||||
[pbr::OriginalName("BAR")] Bar = 2,
|
||||
[pbr::OriginalName("BAZ")] Baz = 3,
|
||||
/// <summary>
|
||||
/// Intentionally negative.
|
||||
/// </summary>
|
||||
NEG = -1,
|
||||
[pbr::OriginalName("NEG")] Neg = -1,
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
@ -2793,7 +2793,7 @@ namespace Google.Protobuf.TestProtos {
|
||||
|
||||
/// <summary>Field number for the "EnumField" field.</summary>
|
||||
public const int EnumFieldFieldNumber = 3;
|
||||
private global::Google.Protobuf.TestProtos.ForeignEnum enumField_ = global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED;
|
||||
private global::Google.Protobuf.TestProtos.ForeignEnum enumField_ = 0;
|
||||
public global::Google.Protobuf.TestProtos.ForeignEnum EnumField {
|
||||
get { return enumField_; }
|
||||
set {
|
||||
@ -2873,7 +2873,7 @@ namespace Google.Protobuf.TestProtos {
|
||||
int hash = 1;
|
||||
if (PrimitiveField != 0) hash ^= PrimitiveField.GetHashCode();
|
||||
if (StringField.Length != 0) hash ^= StringField.GetHashCode();
|
||||
if (EnumField != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) hash ^= EnumField.GetHashCode();
|
||||
if (EnumField != 0) hash ^= EnumField.GetHashCode();
|
||||
if (messageField_ != null) hash ^= MessageField.GetHashCode();
|
||||
hash ^= repeatedPrimitiveField_.GetHashCode();
|
||||
hash ^= repeatedStringField_.GetHashCode();
|
||||
@ -2895,7 +2895,7 @@ namespace Google.Protobuf.TestProtos {
|
||||
output.WriteRawTag(18);
|
||||
output.WriteString(StringField);
|
||||
}
|
||||
if (EnumField != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) {
|
||||
if (EnumField != 0) {
|
||||
output.WriteRawTag(24);
|
||||
output.WriteEnum((int) EnumField);
|
||||
}
|
||||
@ -2917,7 +2917,7 @@ namespace Google.Protobuf.TestProtos {
|
||||
if (StringField.Length != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeStringSize(StringField);
|
||||
}
|
||||
if (EnumField != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) {
|
||||
if (EnumField != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) EnumField);
|
||||
}
|
||||
if (messageField_ != null) {
|
||||
@ -2940,7 +2940,7 @@ namespace Google.Protobuf.TestProtos {
|
||||
if (other.StringField.Length != 0) {
|
||||
StringField = other.StringField;
|
||||
}
|
||||
if (other.EnumField != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) {
|
||||
if (other.EnumField != 0) {
|
||||
EnumField = other.EnumField;
|
||||
}
|
||||
if (other.messageField_ != null) {
|
||||
@ -3370,7 +3370,7 @@ namespace Google.Protobuf.TestProtos {
|
||||
|
||||
/// <summary>Field number for the "sparse_enum" field.</summary>
|
||||
public const int SparseEnumFieldNumber = 1;
|
||||
private global::Google.Protobuf.TestProtos.TestSparseEnum sparseEnum_ = global::Google.Protobuf.TestProtos.TestSparseEnum.TEST_SPARSE_ENUM_UNSPECIFIED;
|
||||
private global::Google.Protobuf.TestProtos.TestSparseEnum sparseEnum_ = 0;
|
||||
public global::Google.Protobuf.TestProtos.TestSparseEnum SparseEnum {
|
||||
get { return sparseEnum_; }
|
||||
set {
|
||||
@ -3395,7 +3395,7 @@ namespace Google.Protobuf.TestProtos {
|
||||
|
||||
public override int GetHashCode() {
|
||||
int hash = 1;
|
||||
if (SparseEnum != global::Google.Protobuf.TestProtos.TestSparseEnum.TEST_SPARSE_ENUM_UNSPECIFIED) hash ^= SparseEnum.GetHashCode();
|
||||
if (SparseEnum != 0) hash ^= SparseEnum.GetHashCode();
|
||||
return hash;
|
||||
}
|
||||
|
||||
@ -3404,7 +3404,7 @@ namespace Google.Protobuf.TestProtos {
|
||||
}
|
||||
|
||||
public void WriteTo(pb::CodedOutputStream output) {
|
||||
if (SparseEnum != global::Google.Protobuf.TestProtos.TestSparseEnum.TEST_SPARSE_ENUM_UNSPECIFIED) {
|
||||
if (SparseEnum != 0) {
|
||||
output.WriteRawTag(8);
|
||||
output.WriteEnum((int) SparseEnum);
|
||||
}
|
||||
@ -3412,7 +3412,7 @@ namespace Google.Protobuf.TestProtos {
|
||||
|
||||
public int CalculateSize() {
|
||||
int size = 0;
|
||||
if (SparseEnum != global::Google.Protobuf.TestProtos.TestSparseEnum.TEST_SPARSE_ENUM_UNSPECIFIED) {
|
||||
if (SparseEnum != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) SparseEnum);
|
||||
}
|
||||
return size;
|
||||
@ -3422,7 +3422,7 @@ namespace Google.Protobuf.TestProtos {
|
||||
if (other == null) {
|
||||
return;
|
||||
}
|
||||
if (other.SparseEnum != global::Google.Protobuf.TestProtos.TestSparseEnum.TEST_SPARSE_ENUM_UNSPECIFIED) {
|
||||
if (other.SparseEnum != 0) {
|
||||
SparseEnum = other.SparseEnum;
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,24 @@ namespace Google.Protobuf.WellKnownTypes
|
||||
Assert.AreEqual(message.CalculateSize(), any.Value.Length);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Pack_WithCustomPrefix()
|
||||
{
|
||||
var message = SampleMessages.CreateFullTestAllTypes();
|
||||
var any = Any.Pack(message, "foo.bar/baz");
|
||||
Assert.AreEqual("foo.bar/baz/protobuf_unittest.TestAllTypes", any.TypeUrl);
|
||||
Assert.AreEqual(message.CalculateSize(), any.Value.Length);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Pack_WithCustomPrefixTrailingSlash()
|
||||
{
|
||||
var message = SampleMessages.CreateFullTestAllTypes();
|
||||
var any = Any.Pack(message, "foo.bar/baz/");
|
||||
Assert.AreEqual("foo.bar/baz/protobuf_unittest.TestAllTypes", any.TypeUrl);
|
||||
Assert.AreEqual(message.CalculateSize(), any.Value.Length);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Unpack_WrongType()
|
||||
{
|
||||
@ -63,6 +81,15 @@ namespace Google.Protobuf.WellKnownTypes
|
||||
Assert.AreEqual(message, unpacked);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Unpack_CustomPrefix_Success()
|
||||
{
|
||||
var message = SampleMessages.CreateFullTestAllTypes();
|
||||
var any = Any.Pack(message, "foo.bar/baz");
|
||||
var unpacked = any.Unpack<TestAllTypes>();
|
||||
Assert.AreEqual(message, unpacked);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ToString_WithValues()
|
||||
{
|
||||
|
@ -117,6 +117,7 @@
|
||||
<Compile Include="Reflection\MethodDescriptor.cs" />
|
||||
<Compile Include="Reflection\OneofAccessor.cs" />
|
||||
<Compile Include="Reflection\OneofDescriptor.cs" />
|
||||
<Compile Include="Reflection\OriginalNameAttribute.cs" />
|
||||
<Compile Include="Reflection\PackageDescriptor.cs" />
|
||||
<Compile Include="Reflection\PartialClasses.cs" />
|
||||
<Compile Include="Reflection\ReflectionUtil.cs" />
|
||||
|
@ -23,7 +23,6 @@
|
||||
<group targetFramework="xamarin.ios" />
|
||||
<group targetFramework="monotouch" />
|
||||
<group targetFramework="monoandroid" />
|
||||
|
||||
<!-- Dependencies for newer, more granular platforms (.NET Core etc) -->
|
||||
<group targetFramework="dotnet">
|
||||
<dependency id="System.Collections" version="4.0.0" />
|
||||
@ -34,10 +33,12 @@
|
||||
<dependency id="System.Linq.Expressions" version="4.0.0" />
|
||||
<dependency id="System.ObjectModel" version="4.0.0" />
|
||||
<dependency id="System.Reflection" version="4.0.0" />
|
||||
<dependency id="System.Reflection.Extensions" version="4.0.0" />
|
||||
<dependency id="System.Runtime" version="4.0.0" />
|
||||
<dependency id="System.Runtime.Extensions" version="4.0.0" />
|
||||
<dependency id="System.Text.Encoding" version="4.0.0" />
|
||||
<dependency id="System.Text.RegularExpressions" version="4.0.0" />
|
||||
<dependency id="System.Threading" version="4.0.0" />
|
||||
</group>
|
||||
</dependencies>
|
||||
</metadata>
|
||||
@ -49,18 +50,5 @@
|
||||
<file src="bin/ReleaseSigned/Google.Protobuf.pdb" target="lib/dotnet" />
|
||||
<file src="bin/ReleaseSigned/Google.Protobuf.xml" target="lib/dotnet" />
|
||||
<file src="**\*.cs" target="src" />
|
||||
<file src="..\..\..\cmake\Release\protoc.exe" target="tools" />
|
||||
<file src="..\..\..\src\google\protobuf\any.proto" target="tools\google\protobuf" />
|
||||
<file src="..\..\..\src\google\protobuf\api.proto" target="tools\google\protobuf" />
|
||||
<file src="..\..\..\src\google\protobuf\descriptor.proto" target="tools\google\protobuf" />
|
||||
<file src="..\..\..\src\google\protobuf\duration.proto" target="tools\google\protobuf" />
|
||||
<file src="..\..\..\src\google\protobuf\empty.proto" target="tools\google\protobuf" />
|
||||
<file src="..\..\..\src\google\protobuf\field_mask.proto" target="tools\google\protobuf" />
|
||||
<file src="..\..\..\src\google\protobuf\source_context.proto" target="tools\google\protobuf" />
|
||||
<file src="..\..\..\src\google\protobuf\struct.proto" target="tools\google\protobuf" />
|
||||
<file src="..\..\..\src\google\protobuf\timestamp.proto" target="tools\google\protobuf" />
|
||||
<file src="..\..\..\src\google\protobuf\any.proto" target="tools\google\protobuf" />
|
||||
<file src="..\..\..\src\google\protobuf\type.proto" target="tools\google\protobuf" />
|
||||
<file src="..\..\..\src\google\protobuf\wrappers.proto" target="tools\google\protobuf" />
|
||||
</files>
|
||||
</package>
|
@ -39,6 +39,7 @@ using Google.Protobuf.WellKnownTypes;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Google.Protobuf
|
||||
{
|
||||
@ -237,11 +238,13 @@ namespace Google.Protobuf
|
||||
{
|
||||
writer.Write(PropertySeparator);
|
||||
}
|
||||
WriteString(writer, ToCamelCase(accessor.Descriptor.Name));
|
||||
|
||||
WriteString(writer, accessor.Descriptor.JsonName);
|
||||
writer.Write(NameValueSeparator);
|
||||
WriteValue(writer, value);
|
||||
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
return !first;
|
||||
}
|
||||
|
||||
@ -418,9 +421,10 @@ namespace Google.Protobuf
|
||||
}
|
||||
else if (value is System.Enum)
|
||||
{
|
||||
if (System.Enum.IsDefined(value.GetType(), value))
|
||||
string name = OriginalEnumValueHelper.GetOriginalName(value);
|
||||
if (name != null)
|
||||
{
|
||||
WriteString(writer, value.ToString());
|
||||
WriteString(writer, name);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -563,7 +567,7 @@ namespace Google.Protobuf
|
||||
|
||||
string typeUrl = (string) value.Descriptor.Fields[Any.TypeUrlFieldNumber].Accessor.GetValue(value);
|
||||
ByteString data = (ByteString) value.Descriptor.Fields[Any.ValueFieldNumber].Accessor.GetValue(value);
|
||||
string typeName = GetTypeName(typeUrl);
|
||||
string typeName = Any.GetTypeName(typeUrl);
|
||||
MessageDescriptor descriptor = settings.TypeRegistry.Find(typeName);
|
||||
if (descriptor == null)
|
||||
{
|
||||
@ -604,17 +608,7 @@ namespace Google.Protobuf
|
||||
writer.Write(data.ToBase64());
|
||||
writer.Write('"');
|
||||
writer.Write(" }");
|
||||
}
|
||||
|
||||
internal static string GetTypeName(String typeUrl)
|
||||
{
|
||||
string[] parts = typeUrl.Split('/');
|
||||
if (parts.Length != 2 || parts[0] != TypeUrlPrefix)
|
||||
{
|
||||
throw new InvalidProtocolBufferException($"Invalid type url: {typeUrl}");
|
||||
}
|
||||
return parts[1];
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteStruct(TextWriter writer, IMessage message)
|
||||
{
|
||||
@ -875,5 +869,44 @@ namespace Google.Protobuf
|
||||
TypeRegistry = ProtoPreconditions.CheckNotNull(typeRegistry, nameof(typeRegistry));
|
||||
}
|
||||
}
|
||||
|
||||
// Effectively a cache of mapping from enum values to the original name as specified in the proto file,
|
||||
// fetched by reflection.
|
||||
// The need for this is unfortunate, as is its unbounded size, but realistically it shouldn't cause issues.
|
||||
private static class OriginalEnumValueHelper
|
||||
{
|
||||
// TODO: In the future we might want to use ConcurrentDictionary, at the point where all
|
||||
// the platforms we target have it.
|
||||
private static readonly Dictionary<System.Type, Dictionary<object, string>> dictionaries
|
||||
= new Dictionary<System.Type, Dictionary<object, string>>();
|
||||
|
||||
internal static string GetOriginalName(object value)
|
||||
{
|
||||
var enumType = value.GetType();
|
||||
Dictionary<object, string> nameMapping;
|
||||
lock (dictionaries)
|
||||
{
|
||||
if (!dictionaries.TryGetValue(enumType, out nameMapping))
|
||||
{
|
||||
nameMapping = GetNameMapping(enumType);
|
||||
dictionaries[enumType] = nameMapping;
|
||||
}
|
||||
}
|
||||
|
||||
string originalName;
|
||||
// If this returns false, originalName will be null, which is what we want.
|
||||
nameMapping.TryGetValue(value, out originalName);
|
||||
return originalName;
|
||||
}
|
||||
|
||||
private static Dictionary<object, string> GetNameMapping(System.Type enumType) =>
|
||||
enumType.GetTypeInfo().DeclaredFields
|
||||
.Where(f => f.IsStatic)
|
||||
.ToDictionary(f => f.GetValue(null),
|
||||
f => f.GetCustomAttributes<OriginalNameAttribute>()
|
||||
.FirstOrDefault()
|
||||
// If the attribute hasn't been applied, fall back to the name of the field.
|
||||
?.Name ?? f.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -513,7 +513,7 @@ namespace Google.Protobuf
|
||||
throw new InvalidProtocolBufferException("Expected string value for Any.@type");
|
||||
}
|
||||
string typeUrl = token.StringValue;
|
||||
string typeName = JsonFormatter.GetTypeName(typeUrl);
|
||||
string typeName = Any.GetTypeName(typeUrl);
|
||||
|
||||
MessageDescriptor descriptor = settings.TypeRegistry.Find(typeName);
|
||||
if (descriptor == null)
|
||||
|
@ -80,7 +80,7 @@ namespace Google.Protobuf.Reflection {
|
||||
"EhMKC291dHB1dF90eXBlGAMgASgJEi8KB29wdGlvbnMYBCABKAsyHi5nb29n",
|
||||
"bGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucxIfChBjbGllbnRfc3RyZWFtaW5n",
|
||||
"GAUgASgIOgVmYWxzZRIfChBzZXJ2ZXJfc3RyZWFtaW5nGAYgASgIOgVmYWxz",
|
||||
"ZSKuBQoLRmlsZU9wdGlvbnMSFAoMamF2YV9wYWNrYWdlGAEgASgJEhwKFGph",
|
||||
"ZSKHBQoLRmlsZU9wdGlvbnMSFAoMamF2YV9wYWNrYWdlGAEgASgJEhwKFGph",
|
||||
"dmFfb3V0ZXJfY2xhc3NuYW1lGAggASgJEiIKE2phdmFfbXVsdGlwbGVfZmls",
|
||||
"ZXMYCiABKAg6BWZhbHNlEiwKHWphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9o",
|
||||
"YXNoGBQgASgIOgVmYWxzZRIlChZqYXZhX3N0cmluZ19jaGVja191dGY4GBsg",
|
||||
@ -91,54 +91,53 @@ namespace Google.Protobuf.Reflection {
|
||||
"cHlfZ2VuZXJpY19zZXJ2aWNlcxgSIAEoCDoFZmFsc2USGQoKZGVwcmVjYXRl",
|
||||
"ZBgXIAEoCDoFZmFsc2USHwoQY2NfZW5hYmxlX2FyZW5hcxgfIAEoCDoFZmFs",
|
||||
"c2USGQoRb2JqY19jbGFzc19wcmVmaXgYJCABKAkSGAoQY3NoYXJwX25hbWVz",
|
||||
"cGFjZRglIAEoCRIrCh9qYXZhbmFub191c2VfZGVwcmVjYXRlZF9wYWNrYWdl",
|
||||
"GCYgASgIQgIYARJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5n",
|
||||
"cGFjZRglIAEoCRJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5n",
|
||||
"b29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiI6CgxPcHRpbWl6",
|
||||
"ZU1vZGUSCQoFU1BFRUQQARINCglDT0RFX1NJWkUQAhIQCgxMSVRFX1JVTlRJ",
|
||||
"TUUQAyoJCOgHEICAgIACIuYBCg5NZXNzYWdlT3B0aW9ucxImChdtZXNzYWdl",
|
||||
"X3NldF93aXJlX2Zvcm1hdBgBIAEoCDoFZmFsc2USLgofbm9fc3RhbmRhcmRf",
|
||||
"ZGVzY3JpcHRvcl9hY2Nlc3NvchgCIAEoCDoFZmFsc2USGQoKZGVwcmVjYXRl",
|
||||
"ZBgDIAEoCDoFZmFsc2USEQoJbWFwX2VudHJ5GAcgASgIEkMKFHVuaW50ZXJw",
|
||||
"cmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVy",
|
||||
"cHJldGVkT3B0aW9uKgkI6AcQgICAgAIimAMKDEZpZWxkT3B0aW9ucxI6CgVj",
|
||||
"dHlwZRgBIAEoDjIjLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuQ1R5",
|
||||
"cGU6BlNUUklORxIOCgZwYWNrZWQYAiABKAgSPwoGanN0eXBlGAYgASgOMiQu",
|
||||
"Z29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5KU1R5cGU6CUpTX05PUk1B",
|
||||
"TBITCgRsYXp5GAUgASgIOgVmYWxzZRIZCgpkZXByZWNhdGVkGAMgASgIOgVm",
|
||||
"YWxzZRITCgR3ZWFrGAogASgIOgVmYWxzZRJDChR1bmludGVycHJldGVkX29w",
|
||||
"TUUQAyoJCOgHEICAgIACSgQIJhAnIuYBCg5NZXNzYWdlT3B0aW9ucxImChdt",
|
||||
"ZXNzYWdlX3NldF93aXJlX2Zvcm1hdBgBIAEoCDoFZmFsc2USLgofbm9fc3Rh",
|
||||
"bmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvchgCIAEoCDoFZmFsc2USGQoKZGVw",
|
||||
"cmVjYXRlZBgDIAEoCDoFZmFsc2USEQoJbWFwX2VudHJ5GAcgASgIEkMKFHVu",
|
||||
"aW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5V",
|
||||
"bmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIimAMKDEZpZWxkT3B0aW9u",
|
||||
"cxI6CgVjdHlwZRgBIAEoDjIjLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlv",
|
||||
"bnMuQ1R5cGU6BlNUUklORxIOCgZwYWNrZWQYAiABKAgSPwoGanN0eXBlGAYg",
|
||||
"ASgOMiQuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5KU1R5cGU6CUpT",
|
||||
"X05PUk1BTBITCgRsYXp5GAUgASgIOgVmYWxzZRIZCgpkZXByZWNhdGVkGAMg",
|
||||
"ASgIOgVmYWxzZRITCgR3ZWFrGAogASgIOgVmYWxzZRJDChR1bmludGVycHJl",
|
||||
"dGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnBy",
|
||||
"ZXRlZE9wdGlvbiIvCgVDVHlwZRIKCgZTVFJJTkcQABIICgRDT1JEEAESEAoM",
|
||||
"U1RSSU5HX1BJRUNFEAIiNQoGSlNUeXBlEg0KCUpTX05PUk1BTBAAEg0KCUpT",
|
||||
"X1NUUklORxABEg0KCUpTX05VTUJFUhACKgkI6AcQgICAgAIijQEKC0VudW1P",
|
||||
"cHRpb25zEhMKC2FsbG93X2FsaWFzGAIgASgIEhkKCmRlcHJlY2F0ZWQYAyAB",
|
||||
"KAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdv",
|
||||
"b2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIi",
|
||||
"fQoQRW51bVZhbHVlT3B0aW9ucxIZCgpkZXByZWNhdGVkGAEgASgIOgVmYWxz",
|
||||
"ZRJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJv",
|
||||
"dG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACInsKDlNlcnZp",
|
||||
"Y2VPcHRpb25zEhkKCmRlcHJlY2F0ZWQYISABKAg6BWZhbHNlEkMKFHVuaW50",
|
||||
"ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5Vbmlu",
|
||||
"dGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIiegoNTWV0aG9kT3B0aW9ucxIZ",
|
||||
"CgpkZXByZWNhdGVkGCEgASgIOgVmYWxzZRJDChR1bmludGVycHJldGVkX29w",
|
||||
"dGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9w",
|
||||
"dGlvbiIvCgVDVHlwZRIKCgZTVFJJTkcQABIICgRDT1JEEAESEAoMU1RSSU5H",
|
||||
"X1BJRUNFEAIiNQoGSlNUeXBlEg0KCUpTX05PUk1BTBAAEg0KCUpTX1NUUklO",
|
||||
"RxABEg0KCUpTX05VTUJFUhACKgkI6AcQgICAgAIijQEKC0VudW1PcHRpb25z",
|
||||
"EhMKC2FsbG93X2FsaWFzGAIgASgIEhkKCmRlcHJlY2F0ZWQYAyABKAg6BWZh",
|
||||
"bHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5w",
|
||||
"cm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIifQoQRW51",
|
||||
"bVZhbHVlT3B0aW9ucxIZCgpkZXByZWNhdGVkGAEgASgIOgVmYWxzZRJDChR1",
|
||||
"bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYu",
|
||||
"VW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACInsKDlNlcnZpY2VPcHRp",
|
||||
"b25zEhkKCmRlcHJlY2F0ZWQYISABKAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0",
|
||||
"ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJl",
|
||||
"dGVkT3B0aW9uKgkI6AcQgICAgAIiegoNTWV0aG9kT3B0aW9ucxIZCgpkZXBy",
|
||||
"ZWNhdGVkGCEgASgIOgVmYWxzZRJDChR1bmludGVycHJldGVkX29wdGlvbhjn",
|
||||
"ByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbioJ",
|
||||
"COgHEICAgIACIp4CChNVbmludGVycHJldGVkT3B0aW9uEjsKBG5hbWUYAiAD",
|
||||
"KAsyLS5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1l",
|
||||
"UGFydBIYChBpZGVudGlmaWVyX3ZhbHVlGAMgASgJEhoKEnBvc2l0aXZlX2lu",
|
||||
"dF92YWx1ZRgEIAEoBBIaChJuZWdhdGl2ZV9pbnRfdmFsdWUYBSABKAMSFAoM",
|
||||
"ZG91YmxlX3ZhbHVlGAYgASgBEhQKDHN0cmluZ192YWx1ZRgHIAEoDBIXCg9h",
|
||||
"Z2dyZWdhdGVfdmFsdWUYCCABKAkaMwoITmFtZVBhcnQSEQoJbmFtZV9wYXJ0",
|
||||
"GAEgAigJEhQKDGlzX2V4dGVuc2lvbhgCIAIoCCLVAQoOU291cmNlQ29kZUlu",
|
||||
"Zm8SOgoIbG9jYXRpb24YASADKAsyKC5nb29nbGUucHJvdG9idWYuU291cmNl",
|
||||
"Q29kZUluZm8uTG9jYXRpb24ahgEKCExvY2F0aW9uEhAKBHBhdGgYASADKAVC",
|
||||
"AhABEhAKBHNwYW4YAiADKAVCAhABEhgKEGxlYWRpbmdfY29tbWVudHMYAyAB",
|
||||
"KAkSGQoRdHJhaWxpbmdfY29tbWVudHMYBCABKAkSIQoZbGVhZGluZ19kZXRh",
|
||||
"Y2hlZF9jb21tZW50cxgGIAMoCSKnAQoRR2VuZXJhdGVkQ29kZUluZm8SQQoK",
|
||||
"YW5ub3RhdGlvbhgBIAMoCzItLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRD",
|
||||
"b2RlSW5mby5Bbm5vdGF0aW9uGk8KCkFubm90YXRpb24SEAoEcGF0aBgBIAMo",
|
||||
"BUICEAESEwoLc291cmNlX2ZpbGUYAiABKAkSDQoFYmVnaW4YAyABKAUSCwoD",
|
||||
"ZW5kGAQgASgFQlgKE2NvbS5nb29nbGUucHJvdG9idWZCEERlc2NyaXB0b3JQ",
|
||||
"cm90b3NIAVoKZGVzY3JpcHRvcqICA0dQQqoCGkdvb2dsZS5Qcm90b2J1Zi5S",
|
||||
"ZWZsZWN0aW9u"));
|
||||
"dGlvbioJCOgHEICAgIACIp4CChNVbmludGVycHJldGVkT3B0aW9uEjsKBG5h",
|
||||
"bWUYAiADKAsyLS5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlv",
|
||||
"bi5OYW1lUGFydBIYChBpZGVudGlmaWVyX3ZhbHVlGAMgASgJEhoKEnBvc2l0",
|
||||
"aXZlX2ludF92YWx1ZRgEIAEoBBIaChJuZWdhdGl2ZV9pbnRfdmFsdWUYBSAB",
|
||||
"KAMSFAoMZG91YmxlX3ZhbHVlGAYgASgBEhQKDHN0cmluZ192YWx1ZRgHIAEo",
|
||||
"DBIXCg9hZ2dyZWdhdGVfdmFsdWUYCCABKAkaMwoITmFtZVBhcnQSEQoJbmFt",
|
||||
"ZV9wYXJ0GAEgAigJEhQKDGlzX2V4dGVuc2lvbhgCIAIoCCLVAQoOU291cmNl",
|
||||
"Q29kZUluZm8SOgoIbG9jYXRpb24YASADKAsyKC5nb29nbGUucHJvdG9idWYu",
|
||||
"U291cmNlQ29kZUluZm8uTG9jYXRpb24ahgEKCExvY2F0aW9uEhAKBHBhdGgY",
|
||||
"ASADKAVCAhABEhAKBHNwYW4YAiADKAVCAhABEhgKEGxlYWRpbmdfY29tbWVu",
|
||||
"dHMYAyABKAkSGQoRdHJhaWxpbmdfY29tbWVudHMYBCABKAkSIQoZbGVhZGlu",
|
||||
"Z19kZXRhY2hlZF9jb21tZW50cxgGIAMoCSKnAQoRR2VuZXJhdGVkQ29kZUlu",
|
||||
"Zm8SQQoKYW5ub3RhdGlvbhgBIAMoCzItLmdvb2dsZS5wcm90b2J1Zi5HZW5l",
|
||||
"cmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9uGk8KCkFubm90YXRpb24SEAoEcGF0",
|
||||
"aBgBIAMoBUICEAESEwoLc291cmNlX2ZpbGUYAiABKAkSDQoFYmVnaW4YAyAB",
|
||||
"KAUSCwoDZW5kGAQgASgFQlgKE2NvbS5nb29nbGUucHJvdG9idWZCEERlc2Ny",
|
||||
"aXB0b3JQcm90b3NIAVoKZGVzY3JpcHRvcqICA0dQQqoCGkdvb2dsZS5Qcm90",
|
||||
"b2J1Zi5SZWZsZWN0aW9u"));
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
|
||||
@ -152,7 +151,7 @@ namespace Google.Protobuf.Reflection {
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumValueDescriptorProto), global::Google.Protobuf.Reflection.EnumValueDescriptorProto.Parser, new[]{ "Name", "Number", "Options" }, null, null, null),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.ServiceDescriptorProto), global::Google.Protobuf.Reflection.ServiceDescriptorProto.Parser, new[]{ "Name", "Method", "Options" }, null, null, null),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MethodDescriptorProto), global::Google.Protobuf.Reflection.MethodDescriptorProto.Parser, new[]{ "Name", "InputType", "OutputType", "Options", "ClientStreaming", "ServerStreaming" }, null, null, null),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileOptions), global::Google.Protobuf.Reflection.FileOptions.Parser, new[]{ "JavaPackage", "JavaOuterClassname", "JavaMultipleFiles", "JavaGenerateEqualsAndHash", "JavaStringCheckUtf8", "OptimizeFor", "GoPackage", "CcGenericServices", "JavaGenericServices", "PyGenericServices", "Deprecated", "CcEnableArenas", "ObjcClassPrefix", "CsharpNamespace", "JavananoUseDeprecatedPackage", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode) }, null),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileOptions), global::Google.Protobuf.Reflection.FileOptions.Parser, new[]{ "JavaPackage", "JavaOuterClassname", "JavaMultipleFiles", "JavaGenerateEqualsAndHash", "JavaStringCheckUtf8", "OptimizeFor", "GoPackage", "CcGenericServices", "JavaGenericServices", "PyGenericServices", "Deprecated", "CcEnableArenas", "ObjcClassPrefix", "CsharpNamespace", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode) }, null),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MessageOptions), global::Google.Protobuf.Reflection.MessageOptions.Parser, new[]{ "MessageSetWireFormat", "NoStandardDescriptorAccessor", "Deprecated", "MapEntry", "UninterpretedOption" }, null, null, null),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FieldOptions), global::Google.Protobuf.Reflection.FieldOptions.Parser, new[]{ "Ctype", "Packed", "Jstype", "Lazy", "Deprecated", "Weak", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.CType), typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.JSType) }, null),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumOptions), global::Google.Protobuf.Reflection.EnumOptions.Parser, new[]{ "AllowAlias", "Deprecated", "UninterpretedOption" }, null, null, null),
|
||||
@ -1291,7 +1290,7 @@ namespace Google.Protobuf.Reflection {
|
||||
|
||||
/// <summary>Field number for the "label" field.</summary>
|
||||
public const int LabelFieldNumber = 4;
|
||||
private global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label label_ = global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label.LABEL_OPTIONAL;
|
||||
private global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label label_ = 0;
|
||||
public global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label Label {
|
||||
get { return label_; }
|
||||
set {
|
||||
@ -1301,7 +1300,7 @@ namespace Google.Protobuf.Reflection {
|
||||
|
||||
/// <summary>Field number for the "type" field.</summary>
|
||||
public const int TypeFieldNumber = 5;
|
||||
private global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type type_ = global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type.TYPE_DOUBLE;
|
||||
private global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type type_ = 0;
|
||||
/// <summary>
|
||||
/// If type_name is set, this need not be set. If both this and type_name
|
||||
/// are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP.
|
||||
@ -1429,8 +1428,8 @@ namespace Google.Protobuf.Reflection {
|
||||
int hash = 1;
|
||||
if (Name.Length != 0) hash ^= Name.GetHashCode();
|
||||
if (Number != 0) hash ^= Number.GetHashCode();
|
||||
if (Label != global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label.LABEL_OPTIONAL) hash ^= Label.GetHashCode();
|
||||
if (Type != global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type.TYPE_DOUBLE) hash ^= Type.GetHashCode();
|
||||
if (Label != 0) hash ^= Label.GetHashCode();
|
||||
if (Type != 0) hash ^= Type.GetHashCode();
|
||||
if (TypeName.Length != 0) hash ^= TypeName.GetHashCode();
|
||||
if (Extendee.Length != 0) hash ^= Extendee.GetHashCode();
|
||||
if (DefaultValue.Length != 0) hash ^= DefaultValue.GetHashCode();
|
||||
@ -1457,11 +1456,11 @@ namespace Google.Protobuf.Reflection {
|
||||
output.WriteRawTag(24);
|
||||
output.WriteInt32(Number);
|
||||
}
|
||||
if (Label != global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label.LABEL_OPTIONAL) {
|
||||
if (Label != 0) {
|
||||
output.WriteRawTag(32);
|
||||
output.WriteEnum((int) Label);
|
||||
}
|
||||
if (Type != global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type.TYPE_DOUBLE) {
|
||||
if (Type != 0) {
|
||||
output.WriteRawTag(40);
|
||||
output.WriteEnum((int) Type);
|
||||
}
|
||||
@ -1495,10 +1494,10 @@ namespace Google.Protobuf.Reflection {
|
||||
if (Number != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeInt32Size(Number);
|
||||
}
|
||||
if (Label != global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label.LABEL_OPTIONAL) {
|
||||
if (Label != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Label);
|
||||
}
|
||||
if (Type != global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type.TYPE_DOUBLE) {
|
||||
if (Type != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Type);
|
||||
}
|
||||
if (TypeName.Length != 0) {
|
||||
@ -1532,10 +1531,10 @@ namespace Google.Protobuf.Reflection {
|
||||
if (other.Number != 0) {
|
||||
Number = other.Number;
|
||||
}
|
||||
if (other.Label != global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label.LABEL_OPTIONAL) {
|
||||
if (other.Label != 0) {
|
||||
Label = other.Label;
|
||||
}
|
||||
if (other.Type != global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type.TYPE_DOUBLE) {
|
||||
if (other.Type != 0) {
|
||||
Type = other.Type;
|
||||
}
|
||||
if (other.TypeName.Length != 0) {
|
||||
@ -1624,59 +1623,59 @@ namespace Google.Protobuf.Reflection {
|
||||
/// 0 is reserved for errors.
|
||||
/// Order is weird for historical reasons.
|
||||
/// </summary>
|
||||
TYPE_DOUBLE = 1,
|
||||
TYPE_FLOAT = 2,
|
||||
[pbr::OriginalName("TYPE_DOUBLE")] Double = 1,
|
||||
[pbr::OriginalName("TYPE_FLOAT")] Float = 2,
|
||||
/// <summary>
|
||||
/// Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if
|
||||
/// negative values are likely.
|
||||
/// </summary>
|
||||
TYPE_INT64 = 3,
|
||||
TYPE_UINT64 = 4,
|
||||
[pbr::OriginalName("TYPE_INT64")] Int64 = 3,
|
||||
[pbr::OriginalName("TYPE_UINT64")] Uint64 = 4,
|
||||
/// <summary>
|
||||
/// Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if
|
||||
/// negative values are likely.
|
||||
/// </summary>
|
||||
TYPE_INT32 = 5,
|
||||
TYPE_FIXED64 = 6,
|
||||
TYPE_FIXED32 = 7,
|
||||
TYPE_BOOL = 8,
|
||||
TYPE_STRING = 9,
|
||||
[pbr::OriginalName("TYPE_INT32")] Int32 = 5,
|
||||
[pbr::OriginalName("TYPE_FIXED64")] Fixed64 = 6,
|
||||
[pbr::OriginalName("TYPE_FIXED32")] Fixed32 = 7,
|
||||
[pbr::OriginalName("TYPE_BOOL")] Bool = 8,
|
||||
[pbr::OriginalName("TYPE_STRING")] String = 9,
|
||||
/// <summary>
|
||||
/// Tag-delimited aggregate.
|
||||
/// </summary>
|
||||
TYPE_GROUP = 10,
|
||||
[pbr::OriginalName("TYPE_GROUP")] Group = 10,
|
||||
/// <summary>
|
||||
/// Length-delimited aggregate.
|
||||
/// </summary>
|
||||
TYPE_MESSAGE = 11,
|
||||
[pbr::OriginalName("TYPE_MESSAGE")] Message = 11,
|
||||
/// <summary>
|
||||
/// New in version 2.
|
||||
/// </summary>
|
||||
TYPE_BYTES = 12,
|
||||
TYPE_UINT32 = 13,
|
||||
TYPE_ENUM = 14,
|
||||
TYPE_SFIXED32 = 15,
|
||||
TYPE_SFIXED64 = 16,
|
||||
[pbr::OriginalName("TYPE_BYTES")] Bytes = 12,
|
||||
[pbr::OriginalName("TYPE_UINT32")] Uint32 = 13,
|
||||
[pbr::OriginalName("TYPE_ENUM")] Enum = 14,
|
||||
[pbr::OriginalName("TYPE_SFIXED32")] Sfixed32 = 15,
|
||||
[pbr::OriginalName("TYPE_SFIXED64")] Sfixed64 = 16,
|
||||
/// <summary>
|
||||
/// Uses ZigZag encoding.
|
||||
/// </summary>
|
||||
TYPE_SINT32 = 17,
|
||||
[pbr::OriginalName("TYPE_SINT32")] Sint32 = 17,
|
||||
/// <summary>
|
||||
/// Uses ZigZag encoding.
|
||||
/// </summary>
|
||||
TYPE_SINT64 = 18,
|
||||
[pbr::OriginalName("TYPE_SINT64")] Sint64 = 18,
|
||||
}
|
||||
|
||||
internal enum Label {
|
||||
/// <summary>
|
||||
/// 0 is reserved for errors
|
||||
/// </summary>
|
||||
LABEL_OPTIONAL = 1,
|
||||
LABEL_REQUIRED = 2,
|
||||
[pbr::OriginalName("LABEL_OPTIONAL")] Optional = 1,
|
||||
[pbr::OriginalName("LABEL_REQUIRED")] Required = 2,
|
||||
/// <summary>
|
||||
/// TODO(sanjay): Should we add LABEL_MAP?
|
||||
/// </summary>
|
||||
LABEL_REPEATED = 3,
|
||||
[pbr::OriginalName("LABEL_REPEATED")] Repeated = 3,
|
||||
}
|
||||
|
||||
}
|
||||
@ -2563,7 +2562,6 @@ namespace Google.Protobuf.Reflection {
|
||||
ccEnableArenas_ = other.ccEnableArenas_;
|
||||
objcClassPrefix_ = other.objcClassPrefix_;
|
||||
csharpNamespace_ = other.csharpNamespace_;
|
||||
javananoUseDeprecatedPackage_ = other.javananoUseDeprecatedPackage_;
|
||||
uninterpretedOption_ = other.uninterpretedOption_.Clone();
|
||||
}
|
||||
|
||||
@ -2666,7 +2664,7 @@ namespace Google.Protobuf.Reflection {
|
||||
|
||||
/// <summary>Field number for the "optimize_for" field.</summary>
|
||||
public const int OptimizeForFieldNumber = 9;
|
||||
private global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode optimizeFor_ = global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode.SPEED;
|
||||
private global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode optimizeFor_ = 0;
|
||||
public global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode OptimizeFor {
|
||||
get { return optimizeFor_; }
|
||||
set {
|
||||
@ -2790,21 +2788,6 @@ namespace Google.Protobuf.Reflection {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "javanano_use_deprecated_package" field.</summary>
|
||||
public const int JavananoUseDeprecatedPackageFieldNumber = 38;
|
||||
private bool javananoUseDeprecatedPackage_;
|
||||
/// <summary>
|
||||
/// Whether the nano proto compiler should generate in the deprecated non-nano
|
||||
/// suffixed package.
|
||||
/// </summary>
|
||||
[global::System.ObsoleteAttribute()]
|
||||
public bool JavananoUseDeprecatedPackage {
|
||||
get { return javananoUseDeprecatedPackage_; }
|
||||
set {
|
||||
javananoUseDeprecatedPackage_ = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "uninterpreted_option" field.</summary>
|
||||
public const int UninterpretedOptionFieldNumber = 999;
|
||||
private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.UninterpretedOption> _repeated_uninterpretedOption_codec
|
||||
@ -2842,7 +2825,6 @@ namespace Google.Protobuf.Reflection {
|
||||
if (CcEnableArenas != other.CcEnableArenas) return false;
|
||||
if (ObjcClassPrefix != other.ObjcClassPrefix) return false;
|
||||
if (CsharpNamespace != other.CsharpNamespace) return false;
|
||||
if (JavananoUseDeprecatedPackage != other.JavananoUseDeprecatedPackage) return false;
|
||||
if(!uninterpretedOption_.Equals(other.uninterpretedOption_)) return false;
|
||||
return true;
|
||||
}
|
||||
@ -2854,7 +2836,7 @@ namespace Google.Protobuf.Reflection {
|
||||
if (JavaMultipleFiles != false) hash ^= JavaMultipleFiles.GetHashCode();
|
||||
if (JavaGenerateEqualsAndHash != false) hash ^= JavaGenerateEqualsAndHash.GetHashCode();
|
||||
if (JavaStringCheckUtf8 != false) hash ^= JavaStringCheckUtf8.GetHashCode();
|
||||
if (OptimizeFor != global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode.SPEED) hash ^= OptimizeFor.GetHashCode();
|
||||
if (OptimizeFor != 0) hash ^= OptimizeFor.GetHashCode();
|
||||
if (GoPackage.Length != 0) hash ^= GoPackage.GetHashCode();
|
||||
if (CcGenericServices != false) hash ^= CcGenericServices.GetHashCode();
|
||||
if (JavaGenericServices != false) hash ^= JavaGenericServices.GetHashCode();
|
||||
@ -2863,7 +2845,6 @@ namespace Google.Protobuf.Reflection {
|
||||
if (CcEnableArenas != false) hash ^= CcEnableArenas.GetHashCode();
|
||||
if (ObjcClassPrefix.Length != 0) hash ^= ObjcClassPrefix.GetHashCode();
|
||||
if (CsharpNamespace.Length != 0) hash ^= CsharpNamespace.GetHashCode();
|
||||
if (JavananoUseDeprecatedPackage != false) hash ^= JavananoUseDeprecatedPackage.GetHashCode();
|
||||
hash ^= uninterpretedOption_.GetHashCode();
|
||||
return hash;
|
||||
}
|
||||
@ -2881,7 +2862,7 @@ namespace Google.Protobuf.Reflection {
|
||||
output.WriteRawTag(66);
|
||||
output.WriteString(JavaOuterClassname);
|
||||
}
|
||||
if (OptimizeFor != global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode.SPEED) {
|
||||
if (OptimizeFor != 0) {
|
||||
output.WriteRawTag(72);
|
||||
output.WriteEnum((int) OptimizeFor);
|
||||
}
|
||||
@ -2929,10 +2910,6 @@ namespace Google.Protobuf.Reflection {
|
||||
output.WriteRawTag(170, 2);
|
||||
output.WriteString(CsharpNamespace);
|
||||
}
|
||||
if (JavananoUseDeprecatedPackage != false) {
|
||||
output.WriteRawTag(176, 2);
|
||||
output.WriteBool(JavananoUseDeprecatedPackage);
|
||||
}
|
||||
uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
|
||||
}
|
||||
|
||||
@ -2953,7 +2930,7 @@ namespace Google.Protobuf.Reflection {
|
||||
if (JavaStringCheckUtf8 != false) {
|
||||
size += 2 + 1;
|
||||
}
|
||||
if (OptimizeFor != global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode.SPEED) {
|
||||
if (OptimizeFor != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) OptimizeFor);
|
||||
}
|
||||
if (GoPackage.Length != 0) {
|
||||
@ -2980,9 +2957,6 @@ namespace Google.Protobuf.Reflection {
|
||||
if (CsharpNamespace.Length != 0) {
|
||||
size += 2 + pb::CodedOutputStream.ComputeStringSize(CsharpNamespace);
|
||||
}
|
||||
if (JavananoUseDeprecatedPackage != false) {
|
||||
size += 2 + 1;
|
||||
}
|
||||
size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec);
|
||||
return size;
|
||||
}
|
||||
@ -3006,7 +2980,7 @@ namespace Google.Protobuf.Reflection {
|
||||
if (other.JavaStringCheckUtf8 != false) {
|
||||
JavaStringCheckUtf8 = other.JavaStringCheckUtf8;
|
||||
}
|
||||
if (other.OptimizeFor != global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode.SPEED) {
|
||||
if (other.OptimizeFor != 0) {
|
||||
OptimizeFor = other.OptimizeFor;
|
||||
}
|
||||
if (other.GoPackage.Length != 0) {
|
||||
@ -3033,9 +3007,6 @@ namespace Google.Protobuf.Reflection {
|
||||
if (other.CsharpNamespace.Length != 0) {
|
||||
CsharpNamespace = other.CsharpNamespace;
|
||||
}
|
||||
if (other.JavananoUseDeprecatedPackage != false) {
|
||||
JavananoUseDeprecatedPackage = other.JavananoUseDeprecatedPackage;
|
||||
}
|
||||
uninterpretedOption_.Add(other.uninterpretedOption_);
|
||||
}
|
||||
|
||||
@ -3102,10 +3073,6 @@ namespace Google.Protobuf.Reflection {
|
||||
CsharpNamespace = input.ReadString();
|
||||
break;
|
||||
}
|
||||
case 304: {
|
||||
JavananoUseDeprecatedPackage = input.ReadBool();
|
||||
break;
|
||||
}
|
||||
case 7994: {
|
||||
uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
|
||||
break;
|
||||
@ -3125,15 +3092,15 @@ namespace Google.Protobuf.Reflection {
|
||||
/// <summary>
|
||||
/// Generate complete code for parsing, serialization,
|
||||
/// </summary>
|
||||
SPEED = 1,
|
||||
[pbr::OriginalName("SPEED")] Speed = 1,
|
||||
/// <summary>
|
||||
/// etc.
|
||||
/// </summary>
|
||||
CODE_SIZE = 2,
|
||||
[pbr::OriginalName("CODE_SIZE")] CodeSize = 2,
|
||||
/// <summary>
|
||||
/// Generate code using MessageLite and the lite runtime.
|
||||
/// </summary>
|
||||
LITE_RUNTIME = 3,
|
||||
[pbr::OriginalName("LITE_RUNTIME")] LiteRuntime = 3,
|
||||
}
|
||||
|
||||
}
|
||||
@ -3436,7 +3403,7 @@ namespace Google.Protobuf.Reflection {
|
||||
|
||||
/// <summary>Field number for the "ctype" field.</summary>
|
||||
public const int CtypeFieldNumber = 1;
|
||||
private global::Google.Protobuf.Reflection.FieldOptions.Types.CType ctype_ = global::Google.Protobuf.Reflection.FieldOptions.Types.CType.STRING;
|
||||
private global::Google.Protobuf.Reflection.FieldOptions.Types.CType ctype_ = 0;
|
||||
/// <summary>
|
||||
/// The ctype option instructs the C++ code generator to use a different
|
||||
/// representation of the field than it normally would. See the specific
|
||||
@ -3469,7 +3436,7 @@ namespace Google.Protobuf.Reflection {
|
||||
|
||||
/// <summary>Field number for the "jstype" field.</summary>
|
||||
public const int JstypeFieldNumber = 6;
|
||||
private global::Google.Protobuf.Reflection.FieldOptions.Types.JSType jstype_ = global::Google.Protobuf.Reflection.FieldOptions.Types.JSType.JS_NORMAL;
|
||||
private global::Google.Protobuf.Reflection.FieldOptions.Types.JSType jstype_ = 0;
|
||||
/// <summary>
|
||||
/// The jstype option determines the JavaScript type used for values of the
|
||||
/// field. The option is permitted only for 64 bit integral and fixed types
|
||||
@ -3591,9 +3558,9 @@ namespace Google.Protobuf.Reflection {
|
||||
|
||||
public override int GetHashCode() {
|
||||
int hash = 1;
|
||||
if (Ctype != global::Google.Protobuf.Reflection.FieldOptions.Types.CType.STRING) hash ^= Ctype.GetHashCode();
|
||||
if (Ctype != 0) hash ^= Ctype.GetHashCode();
|
||||
if (Packed != false) hash ^= Packed.GetHashCode();
|
||||
if (Jstype != global::Google.Protobuf.Reflection.FieldOptions.Types.JSType.JS_NORMAL) hash ^= Jstype.GetHashCode();
|
||||
if (Jstype != 0) hash ^= Jstype.GetHashCode();
|
||||
if (Lazy != false) hash ^= Lazy.GetHashCode();
|
||||
if (Deprecated != false) hash ^= Deprecated.GetHashCode();
|
||||
if (Weak != false) hash ^= Weak.GetHashCode();
|
||||
@ -3606,7 +3573,7 @@ namespace Google.Protobuf.Reflection {
|
||||
}
|
||||
|
||||
public void WriteTo(pb::CodedOutputStream output) {
|
||||
if (Ctype != global::Google.Protobuf.Reflection.FieldOptions.Types.CType.STRING) {
|
||||
if (Ctype != 0) {
|
||||
output.WriteRawTag(8);
|
||||
output.WriteEnum((int) Ctype);
|
||||
}
|
||||
@ -3622,7 +3589,7 @@ namespace Google.Protobuf.Reflection {
|
||||
output.WriteRawTag(40);
|
||||
output.WriteBool(Lazy);
|
||||
}
|
||||
if (Jstype != global::Google.Protobuf.Reflection.FieldOptions.Types.JSType.JS_NORMAL) {
|
||||
if (Jstype != 0) {
|
||||
output.WriteRawTag(48);
|
||||
output.WriteEnum((int) Jstype);
|
||||
}
|
||||
@ -3635,13 +3602,13 @@ namespace Google.Protobuf.Reflection {
|
||||
|
||||
public int CalculateSize() {
|
||||
int size = 0;
|
||||
if (Ctype != global::Google.Protobuf.Reflection.FieldOptions.Types.CType.STRING) {
|
||||
if (Ctype != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Ctype);
|
||||
}
|
||||
if (Packed != false) {
|
||||
size += 1 + 1;
|
||||
}
|
||||
if (Jstype != global::Google.Protobuf.Reflection.FieldOptions.Types.JSType.JS_NORMAL) {
|
||||
if (Jstype != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Jstype);
|
||||
}
|
||||
if (Lazy != false) {
|
||||
@ -3661,13 +3628,13 @@ namespace Google.Protobuf.Reflection {
|
||||
if (other == null) {
|
||||
return;
|
||||
}
|
||||
if (other.Ctype != global::Google.Protobuf.Reflection.FieldOptions.Types.CType.STRING) {
|
||||
if (other.Ctype != 0) {
|
||||
Ctype = other.Ctype;
|
||||
}
|
||||
if (other.Packed != false) {
|
||||
Packed = other.Packed;
|
||||
}
|
||||
if (other.Jstype != global::Google.Protobuf.Reflection.FieldOptions.Types.JSType.JS_NORMAL) {
|
||||
if (other.Jstype != 0) {
|
||||
Jstype = other.Jstype;
|
||||
}
|
||||
if (other.Lazy != false) {
|
||||
@ -3729,24 +3696,24 @@ namespace Google.Protobuf.Reflection {
|
||||
/// <summary>
|
||||
/// Default mode.
|
||||
/// </summary>
|
||||
STRING = 0,
|
||||
CORD = 1,
|
||||
STRING_PIECE = 2,
|
||||
[pbr::OriginalName("STRING")] String = 0,
|
||||
[pbr::OriginalName("CORD")] Cord = 1,
|
||||
[pbr::OriginalName("STRING_PIECE")] StringPiece = 2,
|
||||
}
|
||||
|
||||
internal enum JSType {
|
||||
/// <summary>
|
||||
/// Use the default type.
|
||||
/// </summary>
|
||||
JS_NORMAL = 0,
|
||||
[pbr::OriginalName("JS_NORMAL")] JsNormal = 0,
|
||||
/// <summary>
|
||||
/// Use JavaScript strings.
|
||||
/// </summary>
|
||||
JS_STRING = 1,
|
||||
[pbr::OriginalName("JS_STRING")] JsString = 1,
|
||||
/// <summary>
|
||||
/// Use JavaScript numbers.
|
||||
/// </summary>
|
||||
JS_NUMBER = 2,
|
||||
[pbr::OriginalName("JS_NUMBER")] JsNumber = 2,
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -30,9 +30,8 @@
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Google.Protobuf.Compatibility;
|
||||
using System;
|
||||
|
||||
namespace Google.Protobuf.Reflection
|
||||
{
|
||||
@ -41,20 +40,35 @@ namespace Google.Protobuf.Reflection
|
||||
/// </summary>
|
||||
public sealed class FieldDescriptor : DescriptorBase, IComparable<FieldDescriptor>
|
||||
{
|
||||
private readonly FieldDescriptorProto proto;
|
||||
private EnumDescriptor enumType;
|
||||
private MessageDescriptor messageType;
|
||||
private readonly MessageDescriptor containingType;
|
||||
private readonly OneofDescriptor containingOneof;
|
||||
private FieldType fieldType;
|
||||
private readonly string propertyName; // Annoyingly, needed in Crosslink.
|
||||
private IFieldAccessor accessor;
|
||||
|
||||
/// <summary>
|
||||
/// Get the field's containing message type.
|
||||
/// </summary>
|
||||
public MessageDescriptor ContainingType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the oneof containing this field, or <c>null</c> if it is not part of a oneof.
|
||||
/// </summary>
|
||||
public OneofDescriptor ContainingOneof { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The effective JSON name for this field. This is usually the lower-camel-cased form of the field name,
|
||||
/// but can be overridden using the <c>json_name</c> option in the .proto file.
|
||||
/// </summary>
|
||||
public string JsonName { get; }
|
||||
|
||||
internal FieldDescriptorProto Proto { get; }
|
||||
|
||||
internal FieldDescriptor(FieldDescriptorProto proto, FileDescriptor file,
|
||||
MessageDescriptor parent, int index, string propertyName)
|
||||
: base(file, file.ComputeFullName(parent, proto.Name), index)
|
||||
{
|
||||
this.proto = proto;
|
||||
Proto = proto;
|
||||
if (proto.Type != 0)
|
||||
{
|
||||
fieldType = GetFieldTypeFromProtoType(proto.Type);
|
||||
@ -64,7 +78,7 @@ namespace Google.Protobuf.Reflection
|
||||
{
|
||||
throw new DescriptorValidationException(this, "Field numbers must be positive integers.");
|
||||
}
|
||||
containingType = parent;
|
||||
ContainingType = parent;
|
||||
// OneofIndex "defaults" to -1 due to a hack in FieldDescriptor.OnConstruction.
|
||||
if (proto.OneofIndex != -1)
|
||||
{
|
||||
@ -73,7 +87,7 @@ namespace Google.Protobuf.Reflection
|
||||
throw new DescriptorValidationException(this,
|
||||
$"FieldDescriptorProto.oneof_index is out of range for type {parent.Name}");
|
||||
}
|
||||
containingOneof = parent.Oneofs[proto.OneofIndex];
|
||||
ContainingOneof = parent.Oneofs[proto.OneofIndex];
|
||||
}
|
||||
|
||||
file.DescriptorPool.AddSymbol(this);
|
||||
@ -83,14 +97,14 @@ namespace Google.Protobuf.Reflection
|
||||
// We could trust the generated code and check whether the type of the property is
|
||||
// a MapField, but that feels a tad nasty.
|
||||
this.propertyName = propertyName;
|
||||
JsonName = Proto.JsonName == "" ? JsonFormatter.ToCamelCase(Proto.Name) : Proto.JsonName;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The brief name of the descriptor's target.
|
||||
/// </summary>
|
||||
public override string Name { get { return proto.Name; } }
|
||||
|
||||
internal FieldDescriptorProto Proto { get { return proto; } }
|
||||
public override string Name => Proto.Name;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the accessor for this field.
|
||||
@ -110,7 +124,7 @@ namespace Google.Protobuf.Reflection
|
||||
/// and this property will return null.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public IFieldAccessor Accessor { get { return accessor; } }
|
||||
public IFieldAccessor Accessor => accessor;
|
||||
|
||||
/// <summary>
|
||||
/// Maps a field type as included in the .proto file to a FieldType.
|
||||
@ -119,41 +133,41 @@ namespace Google.Protobuf.Reflection
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case FieldDescriptorProto.Types.Type.TYPE_DOUBLE:
|
||||
case FieldDescriptorProto.Types.Type.Double:
|
||||
return FieldType.Double;
|
||||
case FieldDescriptorProto.Types.Type.TYPE_FLOAT:
|
||||
case FieldDescriptorProto.Types.Type.Float:
|
||||
return FieldType.Float;
|
||||
case FieldDescriptorProto.Types.Type.TYPE_INT64:
|
||||
case FieldDescriptorProto.Types.Type.Int64:
|
||||
return FieldType.Int64;
|
||||
case FieldDescriptorProto.Types.Type.TYPE_UINT64:
|
||||
case FieldDescriptorProto.Types.Type.Uint64:
|
||||
return FieldType.UInt64;
|
||||
case FieldDescriptorProto.Types.Type.TYPE_INT32:
|
||||
case FieldDescriptorProto.Types.Type.Int32:
|
||||
return FieldType.Int32;
|
||||
case FieldDescriptorProto.Types.Type.TYPE_FIXED64:
|
||||
case FieldDescriptorProto.Types.Type.Fixed64:
|
||||
return FieldType.Fixed64;
|
||||
case FieldDescriptorProto.Types.Type.TYPE_FIXED32:
|
||||
case FieldDescriptorProto.Types.Type.Fixed32:
|
||||
return FieldType.Fixed32;
|
||||
case FieldDescriptorProto.Types.Type.TYPE_BOOL:
|
||||
case FieldDescriptorProto.Types.Type.Bool:
|
||||
return FieldType.Bool;
|
||||
case FieldDescriptorProto.Types.Type.TYPE_STRING:
|
||||
case FieldDescriptorProto.Types.Type.String:
|
||||
return FieldType.String;
|
||||
case FieldDescriptorProto.Types.Type.TYPE_GROUP:
|
||||
case FieldDescriptorProto.Types.Type.Group:
|
||||
return FieldType.Group;
|
||||
case FieldDescriptorProto.Types.Type.TYPE_MESSAGE:
|
||||
case FieldDescriptorProto.Types.Type.Message:
|
||||
return FieldType.Message;
|
||||
case FieldDescriptorProto.Types.Type.TYPE_BYTES:
|
||||
case FieldDescriptorProto.Types.Type.Bytes:
|
||||
return FieldType.Bytes;
|
||||
case FieldDescriptorProto.Types.Type.TYPE_UINT32:
|
||||
case FieldDescriptorProto.Types.Type.Uint32:
|
||||
return FieldType.UInt32;
|
||||
case FieldDescriptorProto.Types.Type.TYPE_ENUM:
|
||||
case FieldDescriptorProto.Types.Type.Enum:
|
||||
return FieldType.Enum;
|
||||
case FieldDescriptorProto.Types.Type.TYPE_SFIXED32:
|
||||
case FieldDescriptorProto.Types.Type.Sfixed32:
|
||||
return FieldType.SFixed32;
|
||||
case FieldDescriptorProto.Types.Type.TYPE_SFIXED64:
|
||||
case FieldDescriptorProto.Types.Type.Sfixed64:
|
||||
return FieldType.SFixed64;
|
||||
case FieldDescriptorProto.Types.Type.TYPE_SINT32:
|
||||
case FieldDescriptorProto.Types.Type.Sint32:
|
||||
return FieldType.SInt32;
|
||||
case FieldDescriptorProto.Types.Type.TYPE_SINT64:
|
||||
case FieldDescriptorProto.Types.Type.Sint64:
|
||||
return FieldType.SInt64;
|
||||
default:
|
||||
throw new ArgumentException("Invalid type specified");
|
||||
@ -163,62 +177,32 @@ namespace Google.Protobuf.Reflection
|
||||
/// <summary>
|
||||
/// Returns <c>true</c> if this field is a repeated field; <c>false</c> otherwise.
|
||||
/// </summary>
|
||||
public bool IsRepeated
|
||||
{
|
||||
get { return Proto.Label == FieldDescriptorProto.Types.Label.LABEL_REPEATED; }
|
||||
}
|
||||
public bool IsRepeated => Proto.Label == FieldDescriptorProto.Types.Label.Repeated;
|
||||
|
||||
/// <summary>
|
||||
/// Returns <c>true</c> if this field is a map field; <c>false</c> otherwise.
|
||||
/// </summary>
|
||||
public bool IsMap
|
||||
{
|
||||
get { return fieldType == FieldType.Message && messageType.Proto.Options != null && messageType.Proto.Options.MapEntry; }
|
||||
}
|
||||
public bool IsMap => fieldType == FieldType.Message && messageType.Proto.Options != null && messageType.Proto.Options.MapEntry;
|
||||
|
||||
/// <summary>
|
||||
/// Returns <c>true</c> if this field is a packed, repeated field; <c>false</c> otherwise.
|
||||
/// </summary>
|
||||
public bool IsPacked
|
||||
{
|
||||
public bool IsPacked =>
|
||||
// Note the || rather than && here - we're effectively defaulting to packed, because that *is*
|
||||
// the default in proto3, which is all we support. We may give the wrong result for the protos
|
||||
// within descriptor.proto, but that's okay, as they're never exposed and we don't use IsPacked
|
||||
// within the runtime.
|
||||
get { return Proto.Options == null || Proto.Options.Packed; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the field's containing message type.
|
||||
/// </summary>
|
||||
public MessageDescriptor ContainingType
|
||||
{
|
||||
get { return containingType; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the oneof containing this field, or <c>null</c> if it is not part of a oneof.
|
||||
/// </summary>
|
||||
public OneofDescriptor ContainingOneof
|
||||
{
|
||||
get { return containingOneof; }
|
||||
}
|
||||
|
||||
Proto.Options == null || Proto.Options.Packed;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the type of the field.
|
||||
/// </summary>
|
||||
public FieldType FieldType
|
||||
{
|
||||
get { return fieldType; }
|
||||
}
|
||||
public FieldType FieldType => fieldType;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the field number declared in the proto file.
|
||||
/// </summary>
|
||||
public int FieldNumber
|
||||
{
|
||||
get { return Proto.Number; }
|
||||
}
|
||||
public int FieldNumber => Proto.Number;
|
||||
|
||||
/// <summary>
|
||||
/// Compares this descriptor with another one, ordering in "canonical" order
|
||||
@ -228,7 +212,7 @@ namespace Google.Protobuf.Reflection
|
||||
/// </summary>
|
||||
public int CompareTo(FieldDescriptor other)
|
||||
{
|
||||
if (other.containingType != containingType)
|
||||
if (other.ContainingType != ContainingType)
|
||||
{
|
||||
throw new ArgumentException("FieldDescriptors can only be compared to other FieldDescriptors " +
|
||||
"for fields of the same message type.");
|
||||
@ -331,14 +315,14 @@ namespace Google.Protobuf.Reflection
|
||||
|
||||
File.DescriptorPool.AddFieldByNumber(this);
|
||||
|
||||
if (containingType != null && containingType.Proto.Options != null && containingType.Proto.Options.MessageSetWireFormat)
|
||||
if (ContainingType != null && ContainingType.Proto.Options != null && ContainingType.Proto.Options.MessageSetWireFormat)
|
||||
{
|
||||
throw new DescriptorValidationException(this, "MessageSet format is not supported.");
|
||||
}
|
||||
accessor = CreateAccessor(propertyName);
|
||||
accessor = CreateAccessor();
|
||||
}
|
||||
|
||||
private IFieldAccessor CreateAccessor(string propertyName)
|
||||
private IFieldAccessor CreateAccessor()
|
||||
{
|
||||
// If we're given no property name, that's because we really don't want an accessor.
|
||||
// (At the moment, that means it's a map entry message...)
|
||||
@ -346,10 +330,10 @@ namespace Google.Protobuf.Reflection
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var property = containingType.ClrType.GetProperty(propertyName);
|
||||
var property = ContainingType.ClrType.GetProperty(propertyName);
|
||||
if (property == null)
|
||||
{
|
||||
throw new DescriptorValidationException(this, $"Property {propertyName} not found in {containingType.ClrType}");
|
||||
throw new DescriptorValidationException(this, $"Property {propertyName} not found in {ContainingType.ClrType}");
|
||||
}
|
||||
return IsMap ? new MapFieldAccessor(property, this)
|
||||
: IsRepeated ? new RepeatedFieldAccessor(property, this)
|
||||
|
@ -102,8 +102,8 @@ namespace Google.Protobuf.Reflection
|
||||
var map = new Dictionary<string, FieldDescriptor>();
|
||||
foreach (var field in fields)
|
||||
{
|
||||
map[JsonFormatter.ToCamelCase(field.Name)] = field;
|
||||
map[field.Name] = field;
|
||||
map[field.JsonName] = field;
|
||||
}
|
||||
return new ReadOnlyDictionary<string, FieldDescriptor>(map);
|
||||
}
|
||||
|
@ -0,0 +1,58 @@
|
||||
#region Copyright notice and license
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// 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.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
|
||||
namespace Google.Protobuf.Reflection
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies the original name (in the .proto file) of a named element,
|
||||
/// such as an enum value.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class OriginalNameAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the element in the .proto file.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new attribute instance for the given name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the element in the .proto file.</param>
|
||||
public OriginalNameAttribute(string name)
|
||||
{
|
||||
Name = ProtoPreconditions.CheckNotNull(name, nameof(name));
|
||||
}
|
||||
}
|
||||
}
|
@ -24,9 +24,10 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
byte[] descriptorData = global::System.Convert.FromBase64String(
|
||||
string.Concat(
|
||||
"Chlnb29nbGUvcHJvdG9idWYvYW55LnByb3RvEg9nb29nbGUucHJvdG9idWYi",
|
||||
"JgoDQW55EhAKCHR5cGVfdXJsGAEgASgJEg0KBXZhbHVlGAIgASgMQksKE2Nv",
|
||||
"bS5nb29nbGUucHJvdG9idWZCCEFueVByb3RvUAGgAQGiAgNHUEKqAh5Hb29n",
|
||||
"bGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNiBnByb3RvMw=="));
|
||||
"JgoDQW55EhAKCHR5cGVfdXJsGAEgASgJEg0KBXZhbHVlGAIgASgMQnIKE2Nv",
|
||||
"bS5nb29nbGUucHJvdG9idWZCCEFueVByb3RvUAFaJWdpdGh1Yi5jb20vZ29s",
|
||||
"YW5nL3Byb3RvYnVmL3B0eXBlcy9hbnmgAQGiAgNHUEKqAh5Hb29nbGUuUHJv",
|
||||
"dG9idWYuV2VsbEtub3duVHlwZXNiBnByb3RvMw=="));
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
|
||||
@ -38,8 +39,36 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
}
|
||||
#region Messages
|
||||
/// <summary>
|
||||
/// `Any` contains an arbitrary serialized message along with a URL
|
||||
/// that describes the type of the serialized message.
|
||||
/// `Any` contains an arbitrary serialized protocol buffer message along with a
|
||||
/// URL that describes the type of the serialized message.
|
||||
///
|
||||
/// Protobuf library provides support to pack/unpack Any values in the form
|
||||
/// of utility functions or additional generated methods of the Any type.
|
||||
///
|
||||
/// Example 1: Pack and unpack a message in C++.
|
||||
///
|
||||
/// Foo foo = ...;
|
||||
/// Any any;
|
||||
/// any.PackFrom(foo);
|
||||
/// ...
|
||||
/// if (any.UnpackTo(&foo)) {
|
||||
/// ...
|
||||
/// }
|
||||
///
|
||||
/// Example 2: Pack and unpack a message in Java.
|
||||
///
|
||||
/// Foo foo = ...;
|
||||
/// Any any = Any.pack(foo);
|
||||
/// ...
|
||||
/// if (any.is(Foo.class)) {
|
||||
/// foo = any.unpack(Foo.class);
|
||||
/// }
|
||||
///
|
||||
/// The pack methods provided by protobuf library will by default use
|
||||
/// 'type.googleapis.com/full.type.name' as the type URL and the unpack
|
||||
/// methods only use the fully qualified type name after the last '/'
|
||||
/// in the type URL, for example "foo.bar.com/x/y.z" will yield type
|
||||
/// name "y.z".
|
||||
///
|
||||
/// JSON
|
||||
/// ====
|
||||
@ -102,7 +131,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
private string typeUrl_ = "";
|
||||
/// <summary>
|
||||
/// A URL/resource name whose content describes the type of the
|
||||
/// serialized message.
|
||||
/// serialized protocol buffer message.
|
||||
///
|
||||
/// For URLs which use the schema `http`, `https`, or no schema, the
|
||||
/// following restrictions and interpretations apply:
|
||||
@ -110,6 +139,8 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
/// * If no schema is provided, `https` is assumed.
|
||||
/// * The last segment of the URL's path must represent the fully
|
||||
/// qualified name of the type (as in `path/google.protobuf.Duration`).
|
||||
/// The name should be in a canonical form (e.g., leading "." is
|
||||
/// not accepted).
|
||||
/// * An HTTP GET on the URL must yield a [google.protobuf.Type][]
|
||||
/// value in binary format, or produce an error.
|
||||
/// * Applications are allowed to cache lookup results based on the
|
||||
@ -132,7 +163,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
public const int ValueFieldNumber = 2;
|
||||
private pb::ByteString value_ = pb::ByteString.Empty;
|
||||
/// <summary>
|
||||
/// Must be valid serialized data of the above specified type.
|
||||
/// Must be a valid serialized protocol buffer of the above specified type.
|
||||
/// </summary>
|
||||
public pb::ByteString Value {
|
||||
get { return value_; }
|
||||
|
@ -36,11 +36,27 @@ namespace Google.Protobuf.WellKnownTypes
|
||||
{
|
||||
public partial class Any
|
||||
{
|
||||
private const string DefaultPrefix = "type.googleapis.com";
|
||||
|
||||
// This could be moved to MessageDescriptor if we wanted to, but keeping it here means
|
||||
// all the Any-specific code is in the same place.
|
||||
private static string GetTypeUrl(MessageDescriptor descriptor)
|
||||
private static string GetTypeUrl(MessageDescriptor descriptor, string prefix) =>
|
||||
prefix.EndsWith("/") ? prefix + descriptor.FullName : prefix + "/" + descriptor.FullName;
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the type name for a type URL. This is always just the last part of the URL,
|
||||
/// after the trailing slash. No validation of anything before the trailing slash is performed.
|
||||
/// If the type URL does not include a slash, an empty string is returned rather than an exception
|
||||
/// being thrown; this won't match any types, and the calling code is probably in a better position
|
||||
/// to give a meaningful error.
|
||||
/// There is no handling of fragments or queries at the moment.
|
||||
/// </summary>
|
||||
/// <param name="typeUrl">The URL to extract the type name from</param>
|
||||
/// <returns>The type name</returns>
|
||||
internal static string GetTypeName(string typeUrl)
|
||||
{
|
||||
return "type.googleapis.com/" + descriptor.FullName;
|
||||
int lastSlash = typeUrl.LastIndexOf('/');
|
||||
return lastSlash == -1 ? "" : typeUrl.Substring(lastSlash + 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -55,25 +71,37 @@ namespace Google.Protobuf.WellKnownTypes
|
||||
// Note: this doesn't perform as well is it might. We could take a MessageParser<T> in an alternative overload,
|
||||
// which would be expected to perform slightly better... although the difference is likely to be negligible.
|
||||
T target = new T();
|
||||
string targetTypeUrl = GetTypeUrl(target.Descriptor);
|
||||
if (TypeUrl != targetTypeUrl)
|
||||
if (GetTypeName(TypeUrl) != target.Descriptor.FullName)
|
||||
{
|
||||
throw new InvalidProtocolBufferException(string.Format("Type url for {0} is {1}; Any message's type url is {2}",
|
||||
target.Descriptor.Name, targetTypeUrl, TypeUrl));
|
||||
throw new InvalidProtocolBufferException(
|
||||
$"Full type name for {target.Descriptor.Name} is {target.Descriptor.FullName}; Any message's type url is {TypeUrl}");
|
||||
}
|
||||
target.MergeFrom(Value);
|
||||
return target;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Packs the specified message into an Any message.
|
||||
/// Packs the specified message into an Any message using a type URL prefix of "type.googleapis.com".
|
||||
/// </summary>
|
||||
/// <param name="message">The message to pack.</param>
|
||||
/// <returns>An Any message with the content and type URL of <paramref name="message"/>.</returns>
|
||||
public static Any Pack(IMessage message)
|
||||
public static Any Pack(IMessage message) => Pack(message, DefaultPrefix);
|
||||
|
||||
/// <summary>
|
||||
/// Packs the specified message into an Any message using the specified type URL prefix.
|
||||
/// </summary>
|
||||
/// <param name="message">The message to pack.</param>
|
||||
/// <param name="typeUrlPrefix">The prefix for the type URL.</param>
|
||||
/// <returns>An Any message with the content and type URL of <paramref name="message"/>.</returns>
|
||||
public static Any Pack(IMessage message, string typeUrlPrefix)
|
||||
{
|
||||
ProtoPreconditions.CheckNotNull(message, "message");
|
||||
return new Any { TypeUrl = GetTypeUrl(message.Descriptor), Value = message.ToByteString() };
|
||||
ProtoPreconditions.CheckNotNull(message, nameof(message));
|
||||
ProtoPreconditions.CheckNotNull(typeUrlPrefix, nameof(typeUrlPrefix));
|
||||
return new Any
|
||||
{
|
||||
TypeUrl = GetTypeUrl(message.Descriptor, typeUrlPrefix),
|
||||
Value = message.ToByteString()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -185,7 +185,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
|
||||
/// <summary>Field number for the "syntax" field.</summary>
|
||||
public const int SyntaxFieldNumber = 7;
|
||||
private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2;
|
||||
private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = 0;
|
||||
/// <summary>
|
||||
/// The source syntax of the service.
|
||||
/// </summary>
|
||||
@ -225,7 +225,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
if (Version.Length != 0) hash ^= Version.GetHashCode();
|
||||
if (sourceContext_ != null) hash ^= SourceContext.GetHashCode();
|
||||
hash ^= mixins_.GetHashCode();
|
||||
if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) hash ^= Syntax.GetHashCode();
|
||||
if (Syntax != 0) hash ^= Syntax.GetHashCode();
|
||||
return hash;
|
||||
}
|
||||
|
||||
@ -249,7 +249,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
output.WriteMessage(SourceContext);
|
||||
}
|
||||
mixins_.WriteTo(output, _repeated_mixins_codec);
|
||||
if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
|
||||
if (Syntax != 0) {
|
||||
output.WriteRawTag(56);
|
||||
output.WriteEnum((int) Syntax);
|
||||
}
|
||||
@ -269,7 +269,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
size += 1 + pb::CodedOutputStream.ComputeMessageSize(SourceContext);
|
||||
}
|
||||
size += mixins_.CalculateSize(_repeated_mixins_codec);
|
||||
if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
|
||||
if (Syntax != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Syntax);
|
||||
}
|
||||
return size;
|
||||
@ -294,7 +294,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
SourceContext.MergeFrom(other.SourceContext);
|
||||
}
|
||||
mixins_.Add(other.mixins_);
|
||||
if (other.Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
|
||||
if (other.Syntax != 0) {
|
||||
Syntax = other.Syntax;
|
||||
}
|
||||
}
|
||||
@ -458,7 +458,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
|
||||
/// <summary>Field number for the "syntax" field.</summary>
|
||||
public const int SyntaxFieldNumber = 7;
|
||||
private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2;
|
||||
private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = 0;
|
||||
/// <summary>
|
||||
/// The source syntax of this method.
|
||||
/// </summary>
|
||||
@ -498,7 +498,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
if (ResponseTypeUrl.Length != 0) hash ^= ResponseTypeUrl.GetHashCode();
|
||||
if (ResponseStreaming != false) hash ^= ResponseStreaming.GetHashCode();
|
||||
hash ^= options_.GetHashCode();
|
||||
if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) hash ^= Syntax.GetHashCode();
|
||||
if (Syntax != 0) hash ^= Syntax.GetHashCode();
|
||||
return hash;
|
||||
}
|
||||
|
||||
@ -528,7 +528,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
output.WriteBool(ResponseStreaming);
|
||||
}
|
||||
options_.WriteTo(output, _repeated_options_codec);
|
||||
if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
|
||||
if (Syntax != 0) {
|
||||
output.WriteRawTag(56);
|
||||
output.WriteEnum((int) Syntax);
|
||||
}
|
||||
@ -552,7 +552,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
size += 1 + 1;
|
||||
}
|
||||
size += options_.CalculateSize(_repeated_options_codec);
|
||||
if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
|
||||
if (Syntax != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Syntax);
|
||||
}
|
||||
return size;
|
||||
@ -578,7 +578,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
ResponseStreaming = other.ResponseStreaming;
|
||||
}
|
||||
options_.Add(other.options_);
|
||||
if (other.Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
|
||||
if (other.Syntax != 0) {
|
||||
Syntax = other.Syntax;
|
||||
}
|
||||
}
|
||||
|
@ -25,9 +25,10 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
string.Concat(
|
||||
"Ch5nb29nbGUvcHJvdG9idWYvZHVyYXRpb24ucHJvdG8SD2dvb2dsZS5wcm90",
|
||||
"b2J1ZiIqCghEdXJhdGlvbhIPCgdzZWNvbmRzGAEgASgDEg0KBW5hbm9zGAIg",
|
||||
"ASgFQlAKE2NvbS5nb29nbGUucHJvdG9idWZCDUR1cmF0aW9uUHJvdG9QAaAB",
|
||||
"AaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IGcHJv",
|
||||
"dG8z"));
|
||||
"ASgFQnwKE2NvbS5nb29nbGUucHJvdG9idWZCDUR1cmF0aW9uUHJvdG9QAVoq",
|
||||
"Z2l0aHViLmNvbS9nb2xhbmcvcHJvdG9idWYvcHR5cGVzL2R1cmF0aW9uoAEB",
|
||||
"ogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxLbm93blR5cGVzYgZwcm90",
|
||||
"bzM="));
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
|
||||
|
@ -24,9 +24,10 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
byte[] descriptorData = global::System.Convert.FromBase64String(
|
||||
string.Concat(
|
||||
"Chtnb29nbGUvcHJvdG9idWYvZW1wdHkucHJvdG8SD2dvb2dsZS5wcm90b2J1",
|
||||
"ZiIHCgVFbXB0eUJQChNjb20uZ29vZ2xlLnByb3RvYnVmQgpFbXB0eVByb3Rv",
|
||||
"UAGgAQH4AQGiAgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlw",
|
||||
"ZXNiBnByb3RvMw=="));
|
||||
"ZiIHCgVFbXB0eUJ5ChNjb20uZ29vZ2xlLnByb3RvYnVmQgpFbXB0eVByb3Rv",
|
||||
"UAFaJ2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3B0eXBlcy9lbXB0eaAB",
|
||||
"AfgBAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IG",
|
||||
"cHJvdG8z"));
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
|
||||
|
@ -86,7 +86,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
/// operation applies to all fields (as if a FieldMask of all fields
|
||||
/// had been specified).
|
||||
///
|
||||
/// Note that a field mask does not necessarily applies to the
|
||||
/// Note that a field mask does not necessarily apply to the
|
||||
/// top-level response message. In case of a REST get operation, the
|
||||
/// field mask applies directly to the response, but in case of a REST
|
||||
/// list operation, the mask instead applies to each individual message
|
||||
@ -159,6 +159,33 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
/// {
|
||||
/// mask: "user.displayName,photo"
|
||||
/// }
|
||||
///
|
||||
/// # Field Masks and Oneof Fields
|
||||
///
|
||||
/// Field masks treat fields in oneofs just as regular fields. Consider the
|
||||
/// following message:
|
||||
///
|
||||
/// message SampleMessage {
|
||||
/// oneof test_oneof {
|
||||
/// string name = 4;
|
||||
/// SubMessage sub_message = 9;
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// The field mask can be:
|
||||
///
|
||||
/// mask {
|
||||
/// paths: "name"
|
||||
/// }
|
||||
///
|
||||
/// Or:
|
||||
///
|
||||
/// mask {
|
||||
/// paths: "sub_message"
|
||||
/// }
|
||||
///
|
||||
/// Note that oneof type names ("test_oneof" in this case) cannot be used in
|
||||
/// paths.
|
||||
/// </summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
public sealed partial class FieldMask : pb::IMessage<FieldMask> {
|
||||
|
@ -34,9 +34,10 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
"ABIwCgpsaXN0X3ZhbHVlGAYgASgLMhouZ29vZ2xlLnByb3RvYnVmLkxpc3RW",
|
||||
"YWx1ZUgAQgYKBGtpbmQiMwoJTGlzdFZhbHVlEiYKBnZhbHVlcxgBIAMoCzIW",
|
||||
"Lmdvb2dsZS5wcm90b2J1Zi5WYWx1ZSobCglOdWxsVmFsdWUSDgoKTlVMTF9W",
|
||||
"QUxVRRAAQk4KE2NvbS5nb29nbGUucHJvdG9idWZCC1N0cnVjdFByb3RvUAGg",
|
||||
"AQGiAgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNiBnBy",
|
||||
"b3RvMw=="));
|
||||
"QUxVRRAAQoEBChNjb20uZ29vZ2xlLnByb3RvYnVmQgtTdHJ1Y3RQcm90b1AB",
|
||||
"WjFnaXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wdHlwZXMvc3RydWN0O3N0",
|
||||
"cnVjdHBioAEBogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxLbm93blR5",
|
||||
"cGVzYgZwcm90bzM="));
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.WellKnownTypes.NullValue), }, new pbr::GeneratedClrTypeInfo[] {
|
||||
@ -59,7 +60,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
/// <summary>
|
||||
/// Null value.
|
||||
/// </summary>
|
||||
NULL_VALUE = 0,
|
||||
[pbr::OriginalName("NULL_VALUE")] NullValue = 0,
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -108,7 +109,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
= new pbc::MapField<string, global::Google.Protobuf.WellKnownTypes.Value>.Codec(pb::FieldCodec.ForString(10), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Value.Parser), 10);
|
||||
private readonly pbc::MapField<string, global::Google.Protobuf.WellKnownTypes.Value> fields_ = new pbc::MapField<string, global::Google.Protobuf.WellKnownTypes.Value>();
|
||||
/// <summary>
|
||||
/// Map of dynamically typed values.
|
||||
/// Unordered map of dynamically typed values.
|
||||
/// </summary>
|
||||
public pbc::MapField<string, global::Google.Protobuf.WellKnownTypes.Value> Fields {
|
||||
get { return fields_; }
|
||||
@ -234,7 +235,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
/// Represents a null value.
|
||||
/// </summary>
|
||||
public global::Google.Protobuf.WellKnownTypes.NullValue NullValue {
|
||||
get { return kindCase_ == KindOneofCase.NullValue ? (global::Google.Protobuf.WellKnownTypes.NullValue) kind_ : global::Google.Protobuf.WellKnownTypes.NullValue.NULL_VALUE; }
|
||||
get { return kindCase_ == KindOneofCase.NullValue ? (global::Google.Protobuf.WellKnownTypes.NullValue) kind_ : 0; }
|
||||
set {
|
||||
kind_ = value;
|
||||
kindCase_ = KindOneofCase.NullValue;
|
||||
|
@ -25,9 +25,10 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
string.Concat(
|
||||
"Ch9nb29nbGUvcHJvdG9idWYvdGltZXN0YW1wLnByb3RvEg9nb29nbGUucHJv",
|
||||
"dG9idWYiKwoJVGltZXN0YW1wEg8KB3NlY29uZHMYASABKAMSDQoFbmFub3MY",
|
||||
"AiABKAVCVAoTY29tLmdvb2dsZS5wcm90b2J1ZkIOVGltZXN0YW1wUHJvdG9Q",
|
||||
"AaABAfgBAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBl",
|
||||
"c2IGcHJvdG8z"));
|
||||
"AiABKAVCgQEKE2NvbS5nb29nbGUucHJvdG9idWZCDlRpbWVzdGFtcFByb3Rv",
|
||||
"UAFaK2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3B0eXBlcy90aW1lc3Rh",
|
||||
"bXCgAQH4AQGiAgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlw",
|
||||
"ZXNiBnByb3RvMw=="));
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
|
||||
|
@ -79,11 +79,11 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
/// <summary>
|
||||
/// Syntax `proto2`.
|
||||
/// </summary>
|
||||
SYNTAX_PROTO2 = 0,
|
||||
[pbr::OriginalName("SYNTAX_PROTO2")] Proto2 = 0,
|
||||
/// <summary>
|
||||
/// Syntax `proto3`.
|
||||
/// </summary>
|
||||
SYNTAX_PROTO3 = 1,
|
||||
[pbr::OriginalName("SYNTAX_PROTO3")] Proto3 = 1,
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -188,7 +188,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
|
||||
/// <summary>Field number for the "syntax" field.</summary>
|
||||
public const int SyntaxFieldNumber = 6;
|
||||
private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2;
|
||||
private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = 0;
|
||||
/// <summary>
|
||||
/// The source syntax.
|
||||
/// </summary>
|
||||
@ -226,7 +226,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
hash ^= oneofs_.GetHashCode();
|
||||
hash ^= options_.GetHashCode();
|
||||
if (sourceContext_ != null) hash ^= SourceContext.GetHashCode();
|
||||
if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) hash ^= Syntax.GetHashCode();
|
||||
if (Syntax != 0) hash ^= Syntax.GetHashCode();
|
||||
return hash;
|
||||
}
|
||||
|
||||
@ -246,7 +246,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
output.WriteRawTag(42);
|
||||
output.WriteMessage(SourceContext);
|
||||
}
|
||||
if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
|
||||
if (Syntax != 0) {
|
||||
output.WriteRawTag(48);
|
||||
output.WriteEnum((int) Syntax);
|
||||
}
|
||||
@ -263,7 +263,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
if (sourceContext_ != null) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeMessageSize(SourceContext);
|
||||
}
|
||||
if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
|
||||
if (Syntax != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Syntax);
|
||||
}
|
||||
return size;
|
||||
@ -285,7 +285,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
}
|
||||
SourceContext.MergeFrom(other.SourceContext);
|
||||
}
|
||||
if (other.Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
|
||||
if (other.Syntax != 0) {
|
||||
Syntax = other.Syntax;
|
||||
}
|
||||
}
|
||||
@ -371,7 +371,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
|
||||
/// <summary>Field number for the "kind" field.</summary>
|
||||
public const int KindFieldNumber = 1;
|
||||
private global::Google.Protobuf.WellKnownTypes.Field.Types.Kind kind_ = global::Google.Protobuf.WellKnownTypes.Field.Types.Kind.TYPE_UNKNOWN;
|
||||
private global::Google.Protobuf.WellKnownTypes.Field.Types.Kind kind_ = 0;
|
||||
/// <summary>
|
||||
/// The field type.
|
||||
/// </summary>
|
||||
@ -384,7 +384,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
|
||||
/// <summary>Field number for the "cardinality" field.</summary>
|
||||
public const int CardinalityFieldNumber = 2;
|
||||
private global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality cardinality_ = global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality.CARDINALITY_UNKNOWN;
|
||||
private global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality cardinality_ = 0;
|
||||
/// <summary>
|
||||
/// The field cardinality.
|
||||
/// </summary>
|
||||
@ -526,8 +526,8 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
|
||||
public override int GetHashCode() {
|
||||
int hash = 1;
|
||||
if (Kind != global::Google.Protobuf.WellKnownTypes.Field.Types.Kind.TYPE_UNKNOWN) hash ^= Kind.GetHashCode();
|
||||
if (Cardinality != global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality.CARDINALITY_UNKNOWN) hash ^= Cardinality.GetHashCode();
|
||||
if (Kind != 0) hash ^= Kind.GetHashCode();
|
||||
if (Cardinality != 0) hash ^= Cardinality.GetHashCode();
|
||||
if (Number != 0) hash ^= Number.GetHashCode();
|
||||
if (Name.Length != 0) hash ^= Name.GetHashCode();
|
||||
if (TypeUrl.Length != 0) hash ^= TypeUrl.GetHashCode();
|
||||
@ -544,11 +544,11 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
}
|
||||
|
||||
public void WriteTo(pb::CodedOutputStream output) {
|
||||
if (Kind != global::Google.Protobuf.WellKnownTypes.Field.Types.Kind.TYPE_UNKNOWN) {
|
||||
if (Kind != 0) {
|
||||
output.WriteRawTag(8);
|
||||
output.WriteEnum((int) Kind);
|
||||
}
|
||||
if (Cardinality != global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality.CARDINALITY_UNKNOWN) {
|
||||
if (Cardinality != 0) {
|
||||
output.WriteRawTag(16);
|
||||
output.WriteEnum((int) Cardinality);
|
||||
}
|
||||
@ -585,10 +585,10 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
|
||||
public int CalculateSize() {
|
||||
int size = 0;
|
||||
if (Kind != global::Google.Protobuf.WellKnownTypes.Field.Types.Kind.TYPE_UNKNOWN) {
|
||||
if (Kind != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Kind);
|
||||
}
|
||||
if (Cardinality != global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality.CARDINALITY_UNKNOWN) {
|
||||
if (Cardinality != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Cardinality);
|
||||
}
|
||||
if (Number != 0) {
|
||||
@ -620,10 +620,10 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
if (other == null) {
|
||||
return;
|
||||
}
|
||||
if (other.Kind != global::Google.Protobuf.WellKnownTypes.Field.Types.Kind.TYPE_UNKNOWN) {
|
||||
if (other.Kind != 0) {
|
||||
Kind = other.Kind;
|
||||
}
|
||||
if (other.Cardinality != global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality.CARDINALITY_UNKNOWN) {
|
||||
if (other.Cardinality != 0) {
|
||||
Cardinality = other.Cardinality;
|
||||
}
|
||||
if (other.Number != 0) {
|
||||
@ -712,79 +712,79 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
/// <summary>
|
||||
/// Field type unknown.
|
||||
/// </summary>
|
||||
TYPE_UNKNOWN = 0,
|
||||
[pbr::OriginalName("TYPE_UNKNOWN")] TypeUnknown = 0,
|
||||
/// <summary>
|
||||
/// Field type double.
|
||||
/// </summary>
|
||||
TYPE_DOUBLE = 1,
|
||||
[pbr::OriginalName("TYPE_DOUBLE")] TypeDouble = 1,
|
||||
/// <summary>
|
||||
/// Field type float.
|
||||
/// </summary>
|
||||
TYPE_FLOAT = 2,
|
||||
[pbr::OriginalName("TYPE_FLOAT")] TypeFloat = 2,
|
||||
/// <summary>
|
||||
/// Field type int64.
|
||||
/// </summary>
|
||||
TYPE_INT64 = 3,
|
||||
[pbr::OriginalName("TYPE_INT64")] TypeInt64 = 3,
|
||||
/// <summary>
|
||||
/// Field type uint64.
|
||||
/// </summary>
|
||||
TYPE_UINT64 = 4,
|
||||
[pbr::OriginalName("TYPE_UINT64")] TypeUint64 = 4,
|
||||
/// <summary>
|
||||
/// Field type int32.
|
||||
/// </summary>
|
||||
TYPE_INT32 = 5,
|
||||
[pbr::OriginalName("TYPE_INT32")] TypeInt32 = 5,
|
||||
/// <summary>
|
||||
/// Field type fixed64.
|
||||
/// </summary>
|
||||
TYPE_FIXED64 = 6,
|
||||
[pbr::OriginalName("TYPE_FIXED64")] TypeFixed64 = 6,
|
||||
/// <summary>
|
||||
/// Field type fixed32.
|
||||
/// </summary>
|
||||
TYPE_FIXED32 = 7,
|
||||
[pbr::OriginalName("TYPE_FIXED32")] TypeFixed32 = 7,
|
||||
/// <summary>
|
||||
/// Field type bool.
|
||||
/// </summary>
|
||||
TYPE_BOOL = 8,
|
||||
[pbr::OriginalName("TYPE_BOOL")] TypeBool = 8,
|
||||
/// <summary>
|
||||
/// Field type string.
|
||||
/// </summary>
|
||||
TYPE_STRING = 9,
|
||||
[pbr::OriginalName("TYPE_STRING")] TypeString = 9,
|
||||
/// <summary>
|
||||
/// Field type group. Proto2 syntax only, and deprecated.
|
||||
/// </summary>
|
||||
TYPE_GROUP = 10,
|
||||
[pbr::OriginalName("TYPE_GROUP")] TypeGroup = 10,
|
||||
/// <summary>
|
||||
/// Field type message.
|
||||
/// </summary>
|
||||
TYPE_MESSAGE = 11,
|
||||
[pbr::OriginalName("TYPE_MESSAGE")] TypeMessage = 11,
|
||||
/// <summary>
|
||||
/// Field type bytes.
|
||||
/// </summary>
|
||||
TYPE_BYTES = 12,
|
||||
[pbr::OriginalName("TYPE_BYTES")] TypeBytes = 12,
|
||||
/// <summary>
|
||||
/// Field type uint32.
|
||||
/// </summary>
|
||||
TYPE_UINT32 = 13,
|
||||
[pbr::OriginalName("TYPE_UINT32")] TypeUint32 = 13,
|
||||
/// <summary>
|
||||
/// Field type enum.
|
||||
/// </summary>
|
||||
TYPE_ENUM = 14,
|
||||
[pbr::OriginalName("TYPE_ENUM")] TypeEnum = 14,
|
||||
/// <summary>
|
||||
/// Field type sfixed32.
|
||||
/// </summary>
|
||||
TYPE_SFIXED32 = 15,
|
||||
[pbr::OriginalName("TYPE_SFIXED32")] TypeSfixed32 = 15,
|
||||
/// <summary>
|
||||
/// Field type sfixed64.
|
||||
/// </summary>
|
||||
TYPE_SFIXED64 = 16,
|
||||
[pbr::OriginalName("TYPE_SFIXED64")] TypeSfixed64 = 16,
|
||||
/// <summary>
|
||||
/// Field type sint32.
|
||||
/// </summary>
|
||||
TYPE_SINT32 = 17,
|
||||
[pbr::OriginalName("TYPE_SINT32")] TypeSint32 = 17,
|
||||
/// <summary>
|
||||
/// Field type sint64.
|
||||
/// </summary>
|
||||
TYPE_SINT64 = 18,
|
||||
[pbr::OriginalName("TYPE_SINT64")] TypeSint64 = 18,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -794,19 +794,19 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
/// <summary>
|
||||
/// For fields with unknown cardinality.
|
||||
/// </summary>
|
||||
CARDINALITY_UNKNOWN = 0,
|
||||
[pbr::OriginalName("CARDINALITY_UNKNOWN")] Unknown = 0,
|
||||
/// <summary>
|
||||
/// For optional fields.
|
||||
/// </summary>
|
||||
CARDINALITY_OPTIONAL = 1,
|
||||
[pbr::OriginalName("CARDINALITY_OPTIONAL")] Optional = 1,
|
||||
/// <summary>
|
||||
/// For required fields. Proto2 syntax only.
|
||||
/// </summary>
|
||||
CARDINALITY_REQUIRED = 2,
|
||||
[pbr::OriginalName("CARDINALITY_REQUIRED")] Required = 2,
|
||||
/// <summary>
|
||||
/// For repeated fields.
|
||||
/// </summary>
|
||||
CARDINALITY_REPEATED = 3,
|
||||
[pbr::OriginalName("CARDINALITY_REPEATED")] Repeated = 3,
|
||||
}
|
||||
|
||||
}
|
||||
@ -900,7 +900,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
|
||||
/// <summary>Field number for the "syntax" field.</summary>
|
||||
public const int SyntaxFieldNumber = 5;
|
||||
private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2;
|
||||
private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = 0;
|
||||
/// <summary>
|
||||
/// The source syntax.
|
||||
/// </summary>
|
||||
@ -936,7 +936,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
hash ^= enumvalue_.GetHashCode();
|
||||
hash ^= options_.GetHashCode();
|
||||
if (sourceContext_ != null) hash ^= SourceContext.GetHashCode();
|
||||
if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) hash ^= Syntax.GetHashCode();
|
||||
if (Syntax != 0) hash ^= Syntax.GetHashCode();
|
||||
return hash;
|
||||
}
|
||||
|
||||
@ -955,7 +955,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
output.WriteRawTag(34);
|
||||
output.WriteMessage(SourceContext);
|
||||
}
|
||||
if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
|
||||
if (Syntax != 0) {
|
||||
output.WriteRawTag(40);
|
||||
output.WriteEnum((int) Syntax);
|
||||
}
|
||||
@ -971,7 +971,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
if (sourceContext_ != null) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeMessageSize(SourceContext);
|
||||
}
|
||||
if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
|
||||
if (Syntax != 0) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Syntax);
|
||||
}
|
||||
return size;
|
||||
@ -992,7 +992,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
}
|
||||
SourceContext.MergeFrom(other.SourceContext);
|
||||
}
|
||||
if (other.Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
|
||||
if (other.Syntax != 0) {
|
||||
Syntax = other.Syntax;
|
||||
}
|
||||
}
|
||||
|
@ -29,10 +29,10 @@ namespace Google.Protobuf.WellKnownTypes {
|
||||
"KAMiHAoLVUludDY0VmFsdWUSDQoFdmFsdWUYASABKAQiGwoKSW50MzJWYWx1",
|
||||
"ZRINCgV2YWx1ZRgBIAEoBSIcCgtVSW50MzJWYWx1ZRINCgV2YWx1ZRgBIAEo",
|
||||
"DSIaCglCb29sVmFsdWUSDQoFdmFsdWUYASABKAgiHAoLU3RyaW5nVmFsdWUS",
|
||||
"DQoFdmFsdWUYASABKAkiGwoKQnl0ZXNWYWx1ZRINCgV2YWx1ZRgBIAEoDEJT",
|
||||
"ChNjb20uZ29vZ2xlLnByb3RvYnVmQg1XcmFwcGVyc1Byb3RvUAGgAQH4AQGi",
|
||||
"AgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNiBnByb3Rv",
|
||||
"Mw=="));
|
||||
"DQoFdmFsdWUYASABKAkiGwoKQnl0ZXNWYWx1ZRINCgV2YWx1ZRgBIAEoDEJ/",
|
||||
"ChNjb20uZ29vZ2xlLnByb3RvYnVmQg1XcmFwcGVyc1Byb3RvUAFaKmdpdGh1",
|
||||
"Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3B0eXBlcy93cmFwcGVyc6ABAfgBAaIC",
|
||||
"A0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IGcHJvdG8z"));
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
|
||||
|
674
docs/swift/DesignDoc.md
Normal file
674
docs/swift/DesignDoc.md
Normal file
@ -0,0 +1,674 @@
|
||||
# Protocol Buffers in Swift
|
||||
|
||||
## Objective
|
||||
|
||||
This document describes the user-facing API and internal implementation of
|
||||
proto2 and proto3 messages in Apple’s Swift programming language.
|
||||
|
||||
One of the key goals of protobufs is to provide idiomatic APIs for each
|
||||
language. In that vein, **interoperability with Objective-C is a non-goal of
|
||||
this proposal.** Protobuf users who need to pass messages between Objective-C
|
||||
and Swift code in the same application should use the existing Objective-C proto
|
||||
library. The goal of the effort described here is to provide an API for protobuf
|
||||
messages that uses features specific to Swift—optional types, algebraic
|
||||
enumerated types, value types, and so forth—in a natural way that will delight,
|
||||
rather than surprise, users of the language.
|
||||
|
||||
## Naming
|
||||
|
||||
* By convention, both typical protobuf message names and Swift structs/classes
|
||||
are `UpperCamelCase`, so for most messages, the name of a message can be the
|
||||
same as the name of its generated type. (However, see the discussion below
|
||||
about prefixes under [Packages](#packages).)
|
||||
|
||||
* Enum cases in protobufs typically are `UPPERCASE_WITH_UNDERSCORES`, whereas
|
||||
in Swift they are `lowerCamelCase` (as of the Swift 3 API design
|
||||
guidelines). We will transform the names to match Swift convention, using
|
||||
a whitelist similar to the Objective-C compiler plugin to handle commonly
|
||||
used acronyms.
|
||||
|
||||
* Typical fields in proto messages are `lowercase_with_underscores`, while in
|
||||
Swift they are `lowerCamelCase`. We will transform the names to match
|
||||
Swift convention by removing the underscores and uppercasing the subsequent
|
||||
letter.
|
||||
|
||||
## Swift reserved words
|
||||
|
||||
Swift has a large set of reserved words—some always reserved and some
|
||||
contextually reserved (that is, they can be used as identifiers in contexts
|
||||
where they would not be confused). As of Swift 2.2, the set of always-reserved
|
||||
words is:
|
||||
|
||||
```
|
||||
_, #available, #column, #else, #elseif, #endif, #file, #function, #if, #line,
|
||||
#selector, as, associatedtype, break, case, catch, class, continue, default,
|
||||
defer, deinit, do, dynamicType, else, enum, extension, fallthrough, false, for,
|
||||
func, guard, if, import, in, init, inout, internal, is, let, nil, operator,
|
||||
private, protocol, public, repeat, rethrows, return, self, Self, static,
|
||||
struct, subscript, super, switch, throw, throws, true, try, typealias, var,
|
||||
where, while
|
||||
```
|
||||
|
||||
The set of contextually reserved words is:
|
||||
|
||||
```
|
||||
associativity, convenience, dynamic, didSet, final, get, infix, indirect,
|
||||
lazy, left, mutating, none, nonmutating, optional, override, postfix,
|
||||
precedence, prefix, Protocol, required, right, set, Type, unowned, weak,
|
||||
willSet
|
||||
```
|
||||
|
||||
It is possible to use any reserved word as an identifier by escaping it with
|
||||
backticks (for example, ``let `class` = 5``). Other name-mangling schemes would
|
||||
require us to transform the names themselves (for example, by appending an
|
||||
underscore), which requires us to then ensure that the new name does not collide
|
||||
with something else in the same namespace.
|
||||
|
||||
While the backtick feature may not be widely known by all Swift developers, a
|
||||
small amount of user education can address this and it seems like the best
|
||||
approach. We can unconditionally surround all property names with backticks to
|
||||
simplify generation.
|
||||
|
||||
Some remapping will still be required, though, to avoid collisions between
|
||||
generated properties and the names of methods and properties defined in the base
|
||||
protocol/implementation of messages.
|
||||
|
||||
# Features of Protocol Buffers
|
||||
|
||||
This section describes how the features of the protocol buffer syntaxes (proto2
|
||||
and proto3) map to features in Swift—what the code generated from a proto will
|
||||
look like, and how it will be implemented in the underlying library.
|
||||
|
||||
## Packages
|
||||
|
||||
Modules are the main form of namespacing in Swift, but they are not declared
|
||||
using syntactic constructs like namespaces in C++ or packages in Java. Instead,
|
||||
they are tied to build targets in Xcode (or, in the future with open-source
|
||||
Swift, declarations in a Swift Package Manager manifest). They also do not
|
||||
easily support nesting submodules (Clang module maps support this, but pure
|
||||
Swift does not yet provide a way to define submodules).
|
||||
|
||||
We will generate types with fully-qualified underscore-delimited names. For
|
||||
example, a message `Baz` in package `foo.bar` would generate a struct named
|
||||
`Foo_Bar_Baz`. For each fully-qualified proto message, there will be exactly one
|
||||
unique type symbol emitted in the generated binary.
|
||||
|
||||
Users are likely to balk at the ugliness of underscore-delimited names for every
|
||||
generated type. To improve upon this situation, we will add a new string file
|
||||
level option, `swift_package_typealias`, that can be added to `.proto` files.
|
||||
When present, this will cause `typealias`es to be added to the generated Swift
|
||||
messages that replace the package name prefix with the provided string. For
|
||||
example, the following `.proto` file:
|
||||
|
||||
```protobuf
|
||||
option swift_package_typealias = "FBP";
|
||||
package foo.bar;
|
||||
|
||||
message Baz {
|
||||
// Message fields
|
||||
}
|
||||
```
|
||||
|
||||
would generate the following Swift source:
|
||||
|
||||
```swift
|
||||
public struct Foo_Bar_Baz {
|
||||
// Message fields and other methods
|
||||
}
|
||||
|
||||
typealias FBPBaz = Foo_Bar_Baz
|
||||
```
|
||||
|
||||
It should be noted that this type alias is recorded in the generated
|
||||
`.swiftmodule` so that code importing the module can refer to it, but it does
|
||||
not cause a new symbol to be generated in the compiled binary (i.e., we do not
|
||||
risk compiled size bloat by adding `typealias`es for every type).
|
||||
|
||||
Other strategies to handle packages that were considered and rejected can be
|
||||
found in [Appendix A](#appendix-a-rejected-strategies-to-handle-packages).
|
||||
|
||||
## Messages
|
||||
|
||||
Proto messages are natural value types and we will generate messages as structs
|
||||
instead of classes. Users will benefit from Swift’s built-in behavior with
|
||||
regard to mutability. We will define a `ProtoMessage` protocol that defines the
|
||||
common methods and properties for all messages (such as serialization) and also
|
||||
lets users treat messages polymorphically. Any shared method implementations
|
||||
that do not differ between individual messages can be implemented in a protocol
|
||||
extension.
|
||||
|
||||
The backing storage itself for fields of a message will be managed by a
|
||||
`ProtoFieldStorage` type that uses an internal dictionary keyed by field number,
|
||||
and whose values are the value of the field with that number (up-cast to Swift’s
|
||||
`Any` type). This class will provide type-safe getters and setters so that
|
||||
generated messages can manipulate this storage, and core serialization logic
|
||||
will live here as well. Furthermore, factoring the storage out into a separate
|
||||
type, rather than inlining the fields as stored properties in the message
|
||||
itself, lets us implement copy-on-write efficiently to support passing around
|
||||
large messages. (Furthermore, because the messages themselves are value types,
|
||||
inlining fields is not possible if the fields are submessages of the same type,
|
||||
or a type that eventually includes a submessage of the same type.)
|
||||
|
||||
### Required fields (proto2 only)
|
||||
|
||||
Required fields in proto2 messages seem like they could be naturally represented
|
||||
by non-optional properties in Swift, but this presents some problems/concerns.
|
||||
|
||||
Serialization APIs permit partial serialization, which allows required fields to
|
||||
remain unset. Furthermore, other language APIs still provide `has*` and `clear*`
|
||||
methods for required fields, and knowing whether a property has a value when the
|
||||
message is in memory is still useful.
|
||||
|
||||
For example, an e-mail draft message may have the “to” address required on the
|
||||
wire, but when the user constructs it in memory, it doesn’t make sense to force
|
||||
a value until they provide one. We only want to force a value to be present when
|
||||
the message is serialized to the wire. Using non-optional properties prevents
|
||||
this use case, and makes client usage awkward because the user would be forced
|
||||
to select a sentinel or placeholder value for any required fields at the time
|
||||
the message was created.
|
||||
|
||||
### Default values
|
||||
|
||||
In proto2, fields can have a default value specified that may be a value other
|
||||
than the default value for its corresponding language type (for example, a
|
||||
default value of 5 instead of 0 for an integer). When reading a field that is
|
||||
not explicitly set, the user expects to get that value. This makes Swift
|
||||
optionals (i.e., `Foo?`) unsuitable for fields in general. Unfortunately, we
|
||||
cannot implement our own “enhanced optional” type without severely complicating
|
||||
usage (Swift’s use of type inference and its lack of implicit conversions would
|
||||
require manual unwrapping of every property value).
|
||||
|
||||
Instead, we can use **implicitly unwrapped optionals.** For example, a property
|
||||
generated for a field of type `int32` would have Swift type `Int32!`. These
|
||||
properties would behave with the following characteristics, which mirror the
|
||||
nil-resettable properties used elsewhere in Apple’s SDKs (for example,
|
||||
`UIView.tintColor`):
|
||||
|
||||
* Assigning a non-nil value to a property sets the field to that value.
|
||||
* Assigning nil to a property clears the field (its internal representation is
|
||||
nilled out).
|
||||
* Reading the value of a property returns its value if it is set, or returns
|
||||
its default value if it is not set. Reading a property never returns nil.
|
||||
|
||||
The final point in the list above implies that the optional cannot be checked to
|
||||
determine if the field is set to a value other than its default: it will never
|
||||
be nil. Instead, we must provide `has*` methods for each field to allow the user
|
||||
to check this. These methods will be public in proto2. In proto3, these methods
|
||||
will be private (if generated at all), since the user can test the returned
|
||||
value against the zero value for that type.
|
||||
|
||||
### Autocreation of nested messages
|
||||
|
||||
For convenience, dotting into an unset field representing a nested message will
|
||||
return an instance of that message with default values. As in the Objective-C
|
||||
implementation, this does not actually cause the field to be set until the
|
||||
returned message is mutated. Fortunately, thanks to the way mutability of value
|
||||
types is implemented in Swift, the language automatically handles the
|
||||
reassignment-on-mutation for us. A static singleton instance containing default
|
||||
values can be associated with each message that can be returned when reading, so
|
||||
copies are only made by the Swift runtime when mutation occurs. For example,
|
||||
given the following proto:
|
||||
|
||||
```protobuf
|
||||
message Node {
|
||||
Node child = 1;
|
||||
string value = 2 [default = "foo"];
|
||||
}
|
||||
```
|
||||
|
||||
The following Swift code would act as commented, where setting deeply nested
|
||||
properties causes the copies and mutations to occur as the assignment statement
|
||||
is unwound:
|
||||
|
||||
```swift
|
||||
var node = Node()
|
||||
|
||||
let s = node.child.child.value
|
||||
// 1. node.child returns the "default Node".
|
||||
// 2. Reading .child on the result of (1) returns the same default Node.
|
||||
// 3. Reading .value on the result of (2) returns the default value "foo".
|
||||
|
||||
node.child.child.value = "bar"
|
||||
// 4. Setting .value on the default Node causes a copy to be made and sets
|
||||
// the property on that copy. Subsequently, the language updates the
|
||||
// value of "node.child.child" to point to that copy.
|
||||
// 5. Updating "node.child.child" in (4) requires another copy, because
|
||||
// "node.child" was also the instance of the default node. The copy is
|
||||
// assigned back to "node.child".
|
||||
// 6. Setting "node.child" in (5) is a simple value reassignment, since
|
||||
// "node" is a mutable var.
|
||||
```
|
||||
|
||||
In other words, the generated messages do not internally have to manage parental
|
||||
relationships to backfill the appropriate properties on mutation. Swift provides
|
||||
this for free.
|
||||
|
||||
## Scalar value fields
|
||||
|
||||
Proto scalar value fields will map to Swift types in the following way:
|
||||
|
||||
.proto Type | Swift Type
|
||||
----------- | -------------------
|
||||
`double` | `Double`
|
||||
`float` | `Float`
|
||||
`int32` | `Int32`
|
||||
`int64` | `Int64`
|
||||
`uint32` | `UInt32`
|
||||
`uint64` | `UInt64`
|
||||
`sint32` | `Int32`
|
||||
`sint64` | `Int64`
|
||||
`fixed32` | `UInt32`
|
||||
`fixed64` | `UInt64`
|
||||
`sfixed32` | `Int32`
|
||||
`sfixed64` | `Int64`
|
||||
`bool` | `Bool`
|
||||
`string` | `String`
|
||||
`bytes` | `Foundation.NSData`
|
||||
|
||||
The proto spec defines a number of integral types that map to the same Swift
|
||||
type; for example, `intXX`, `sintXX`, and `sfixedXX` are all signed integers,
|
||||
and `uintXX` and `fixedXX` are both unsigned integers. No other language
|
||||
implementation distinguishes these further, so we do not do so either. The
|
||||
rationale is that the various types only serve to distinguish how the value is
|
||||
**encoded on the wire**; once loaded in memory, the user is not concerned about
|
||||
these variations.
|
||||
|
||||
Swift’s lack of implicit conversions among types will make it slightly annoying
|
||||
to use these types in a context expecting an `Int`, or vice-versa, but since
|
||||
this is a data-interchange format with explicitly-sized fields, we should not
|
||||
hide that information from the user. Users will have to explicitly write
|
||||
`Int(message.myField)`, for example.
|
||||
|
||||
## Embedded message fields
|
||||
|
||||
Embedded message fields can be represented using an optional variable of the
|
||||
generated message type. Thus, the message
|
||||
|
||||
```protobuf
|
||||
message Foo {
|
||||
Bar bar = 1;
|
||||
}
|
||||
```
|
||||
|
||||
would be represented in Swift as
|
||||
|
||||
```swift
|
||||
public struct Foo: ProtoMessage {
|
||||
public var bar: Bar! {
|
||||
get { ... }
|
||||
set { ... }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If the user explicitly sets `bar` to nil, or if it was never set when read from
|
||||
the wire, retrieving the value of `bar` would return a default, statically
|
||||
allocated instance of `Bar` containing default values for its fields. This
|
||||
achieves the desired behavior for default values in the same way that scalar
|
||||
fields are designed, and also allows users to deep-drill into complex object
|
||||
graphs to get or set fields without checking for nil at each step.
|
||||
|
||||
## Enum fields
|
||||
|
||||
The design and implementation of enum fields will differ somewhat drastically
|
||||
depending on whether the message being generated is a proto2 or proto3 message.
|
||||
|
||||
### proto2 enums
|
||||
|
||||
For proto2, we do not need to be concerned about unknown enum values, so we can
|
||||
use the simple raw-value enum syntax provided by Swift. So the following enum in
|
||||
proto2:
|
||||
|
||||
```protobuf
|
||||
enum ContentType {
|
||||
TEXT = 0;
|
||||
IMAGE = 1;
|
||||
}
|
||||
```
|
||||
|
||||
would become this Swift enum:
|
||||
|
||||
```swift
|
||||
public enum ContentType: Int32, NilLiteralConvertible {
|
||||
case text = 0
|
||||
case image = 1
|
||||
|
||||
public init(nilLiteral: ()) {
|
||||
self = .text
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
See below for the discussion about `NilLiteralConvertible`.
|
||||
|
||||
### proto3 enums
|
||||
|
||||
For proto3, we need to be able to preserve unknown enum values that may come
|
||||
across the wire so that they can be written back if unmodified. We can
|
||||
accomplish this in Swift by using a case with an associated value for unknowns.
|
||||
So the following enum in proto3:
|
||||
|
||||
```protobuf
|
||||
enum ContentType {
|
||||
TEXT = 0;
|
||||
IMAGE = 1;
|
||||
}
|
||||
```
|
||||
|
||||
would become this Swift enum:
|
||||
|
||||
```swift
|
||||
public enum ContentType: RawRepresentable, NilLiteralConvertible {
|
||||
case text
|
||||
case image
|
||||
case UNKNOWN_VALUE(Int32)
|
||||
|
||||
public typealias RawValue = Int32
|
||||
|
||||
public init(nilLiteral: ()) {
|
||||
self = .text
|
||||
}
|
||||
|
||||
public init(rawValue: RawValue) {
|
||||
switch rawValue {
|
||||
case 0: self = .text
|
||||
case 1: self = .image
|
||||
default: self = .UNKNOWN_VALUE(rawValue)
|
||||
}
|
||||
|
||||
public var rawValue: RawValue {
|
||||
switch self {
|
||||
case .text: return 0
|
||||
case .image: return 1
|
||||
case .UNKNOWN_VALUE(let value): return value
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note that the use of a parameterized case prevents us from inheriting from the
|
||||
raw `Int32` type; Swift does not allow an enum with a raw type to have cases
|
||||
with arguments. Instead, we must implement the raw value initializer and
|
||||
computed property manually. The `UNKNOWN_VALUE` case is explicitly chosen to be
|
||||
"ugly" so that it stands out and does not conflict with other possible case
|
||||
names.
|
||||
|
||||
Using this approach, proto3 consumers must always have a default case or handle
|
||||
the `.UNKNOWN_VALUE` case to satisfy case exhaustion in a switch statement; the
|
||||
Swift compiler considers it an error if switch statements are not exhaustive.
|
||||
|
||||
### NilLiteralConvertible conformance
|
||||
|
||||
This is required to clean up the usage of enum-typed properties in switch
|
||||
statements. Unlike other field types, enum properties cannot be
|
||||
implicitly-unwrapped optionals without requiring that uses in switch statements
|
||||
be explicitly unwrapped. For example, if we consider a message with the enum
|
||||
above, this usage will fail to compile:
|
||||
|
||||
```swift
|
||||
// Without NilLiteralConvertible conformance on ContentType
|
||||
public struct SomeMessage: ProtoMessage {
|
||||
public var contentType: ContentType! { ... }
|
||||
}
|
||||
|
||||
// ERROR: no case named text or image
|
||||
switch someMessage.contentType {
|
||||
case .text: { ... }
|
||||
case .image: { ... }
|
||||
}
|
||||
```
|
||||
|
||||
Even though our implementation guarantees that `contentType` will never be nil,
|
||||
if it is an optional type, its cases would be `some` and `none`, not the cases
|
||||
of the underlying enum type. In order to use it in this context, the user must
|
||||
write `someMessage.contentType!` in their switch statement.
|
||||
|
||||
Making the enum itself `NilLiteralConvertible` permits us to make the property
|
||||
non-optional, so the user can still set it to nil to clear it (i.e., reset it to
|
||||
its default value), while eliminating the need to explicitly unwrap it in a
|
||||
switch statement.
|
||||
|
||||
```swift
|
||||
// With NilLiteralConvertible conformance on ContentType
|
||||
public struct SomeMessage: ProtoMessage {
|
||||
// Note that the property type is no longer optional
|
||||
public var contentType: ContentType { ... }
|
||||
}
|
||||
|
||||
// OK: Compiles and runs as expected
|
||||
switch someMessage.contentType {
|
||||
case .text: { ... }
|
||||
case .image: { ... }
|
||||
}
|
||||
|
||||
// The enum can be reset to its default value this way
|
||||
someMessage.contentType = nil
|
||||
```
|
||||
|
||||
One minor oddity with this approach is that nil will be auto-converted to the
|
||||
default value of the enum in any context, not just field assignment. In other
|
||||
words, this is valid:
|
||||
|
||||
```swift
|
||||
func foo(contentType: ContentType) { ... }
|
||||
foo(nil) // Inside foo, contentType == .text
|
||||
```
|
||||
|
||||
That being said, the advantage of being able to simultaneously support
|
||||
nil-resettability and switch-without-unwrapping outweighs this side effect,
|
||||
especially if appropriately documented. It is our hope that a new form of
|
||||
resettable properties will be added to Swift that eliminates this inconsistency.
|
||||
Some community members have already drafted or sent proposals for review that
|
||||
would benefit our designs:
|
||||
|
||||
* [SE-0030: Property Behaviors]
|
||||
(https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md)
|
||||
* [Drafted: Resettable Properties]
|
||||
(https://github.com/patters/swift-evolution/blob/master/proposals/0000-resettable-properties.md)
|
||||
|
||||
### Enum aliases
|
||||
|
||||
The `allow_alias` option in protobuf slightly complicates the use of Swift enums
|
||||
to represent that type, because raw values of cases in an enum must be unique.
|
||||
Swift lets us define static variables in an enum that alias actual cases. For
|
||||
example, the following protobuf enum:
|
||||
|
||||
```protobuf
|
||||
enum Foo {
|
||||
option allow_alias = true;
|
||||
BAR = 0;
|
||||
BAZ = 0;
|
||||
}
|
||||
```
|
||||
|
||||
will be represented in Swift as:
|
||||
|
||||
```swift
|
||||
public enum Foo: Int32, NilLiteralConvertible {
|
||||
case bar = 0
|
||||
static public let baz = bar
|
||||
|
||||
// ... etc.
|
||||
}
|
||||
|
||||
// Can still use .baz shorthand to reference the alias in contexts
|
||||
// where the type is inferred
|
||||
```
|
||||
|
||||
That is, we use the first name as the actual case and use static variables for
|
||||
the other aliases. One drawback to this approach is that the static aliases
|
||||
cannot be used as cases in a switch statement (the compiler emits the error
|
||||
*“Enum case ‘baz’ not found in type ‘Foo’”*). However, in our own code bases,
|
||||
there are only a few places where enum aliases are not mere renamings of an
|
||||
older value, but they also don’t appear to be the type of value that one would
|
||||
expect to switch on (for example, a group of named constants representing
|
||||
metrics rather than a set of options), so this restriction is not significant.
|
||||
|
||||
This strategy also implies that changing the name of an enum and adding the old
|
||||
name as an alias below the new name will be a breaking change in the generated
|
||||
Swift code.
|
||||
|
||||
## Oneof types
|
||||
|
||||
The `oneof` feature represents a “variant/union” data type that maps nicely to
|
||||
Swift enums with associated values (algebraic types). These fields can also be
|
||||
accessed independently though, and, specifically in the case of proto2, it’s
|
||||
reasonable to expect access to default values when accessing a field that is not
|
||||
explicitly set.
|
||||
|
||||
Taking all this into account, we can represent a `oneof` in Swift with two sets
|
||||
of constructs:
|
||||
|
||||
* Properties in the message that correspond to the `oneof` fields.
|
||||
* A nested enum named after the `oneof` and which provides the corresponding
|
||||
field values as case arguments.
|
||||
|
||||
This approach fulfills the needs of proto consumers by providing a
|
||||
Swift-idiomatic way of simultaneously checking which field is set and accessing
|
||||
its value, providing individual properties to access the default values
|
||||
(important for proto2), and safely allows a field to be moved into a `oneof`
|
||||
without breaking clients.
|
||||
|
||||
Consider the following proto:
|
||||
|
||||
```protobuf
|
||||
message MyMessage {
|
||||
oneof record {
|
||||
string name = 1 [default = "unnamed"];
|
||||
int32 id_number = 2 [default = 0];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In Swift, we would generate an enum, a property for that enum, and properties
|
||||
for the fields themselves:
|
||||
|
||||
```swift
|
||||
public struct MyMessage: ProtoMessage {
|
||||
public enum Record: NilLiteralConvertible {
|
||||
case name(String)
|
||||
case idNumber(Int32)
|
||||
case NOT_SET
|
||||
|
||||
public init(nilLiteral: ()) { self = .NOT_SET }
|
||||
}
|
||||
|
||||
// This is the "Swifty" way of accessing the value
|
||||
public var record: Record { ... }
|
||||
|
||||
// Direct access to the underlying fields
|
||||
public var name: String! { ... }
|
||||
public var idNumber: Int32! { ... }
|
||||
}
|
||||
```
|
||||
|
||||
This makes both usage patterns possible:
|
||||
|
||||
```swift
|
||||
// Usage 1: Case-based dispatch
|
||||
switch message.record {
|
||||
case .name(let name):
|
||||
// Do something with name if it was explicitly set
|
||||
case .idNumber(let id):
|
||||
// Do something with id_number if it was explicitly set
|
||||
case .NOT_SET:
|
||||
// Do something if it’s not set
|
||||
}
|
||||
|
||||
// Usage 2: Direct access for default value fallback
|
||||
// Sets the label text to the name if it was explicitly set, or to
|
||||
// "unnamed" (the default value for the field) if id_number was set
|
||||
// instead
|
||||
let myLabel = UILabel()
|
||||
myLabel.text = message.name
|
||||
```
|
||||
|
||||
As with proto enums, the generated `oneof` enum conforms to
|
||||
`NilLiteralConvertible` to avoid switch statement issues. Setting the property
|
||||
to nil will clear it (i.e., reset it to `NOT_SET`).
|
||||
|
||||
## Unknown Fields (proto2 only)
|
||||
|
||||
To be written.
|
||||
|
||||
## Extensions (proto2 only)
|
||||
|
||||
To be written.
|
||||
|
||||
## Reflection and Descriptors
|
||||
|
||||
We will not include reflection or descriptors in the first version of the Swift
|
||||
library. The use cases for reflection on mobile are not as strong and the static
|
||||
data to represent the descriptors would add bloat when we wish to keep the code
|
||||
size small.
|
||||
|
||||
In the future, we will investigate whether they can be included as extensions
|
||||
which might be able to be excluded from a build and/or automatically dead
|
||||
stripped by the compiler if they are not used.
|
||||
|
||||
## Appendix A: Rejected strategies to handle packages
|
||||
|
||||
### Each package is its own Swift module
|
||||
|
||||
Each proto package could be declared as its own Swift module, replacing dots
|
||||
with underscores (e.g., package `foo.bar` becomes module `Foo_Bar`). Then, users
|
||||
would simply import modules containing whatever proto modules they want to use
|
||||
and refer to the generated types by their short names.
|
||||
|
||||
**This solution is simply not possible, however.** Swift modules cannot
|
||||
circularly reference each other, but there is no restriction against proto
|
||||
packages doing so. Circular imports are forbidden (e.g., `foo.proto` importing
|
||||
`bar.proto` importing `foo.proto`), but nothing prevents package `foo` from
|
||||
using a type in package `bar` which uses a different type in package `foo`, as
|
||||
long as there is no import cycle. If these packages were generated as Swift
|
||||
modules, then `Foo` would contain an `import Bar` statement and `Bar` would
|
||||
contain an `import Foo` statement, and there is no way to compile this.
|
||||
|
||||
### Ad hoc namespacing with structs
|
||||
|
||||
We can “fake” namespaces in Swift by declaring empty structs with private
|
||||
initializers. Since modules are constructed based on compiler arguments, not by
|
||||
syntactic constructs, and because there is no pure Swift way to define
|
||||
submodules (even though Clang module maps support this), there is no
|
||||
source-drive way to group generated code into namespaces aside from this
|
||||
approach.
|
||||
|
||||
Types can be added to those intermediate package structs using Swift extensions.
|
||||
For example, a message `Baz` in package `foo.bar` could be represented in Swift
|
||||
as follows:
|
||||
|
||||
```swift
|
||||
public struct Foo {
|
||||
private init() {}
|
||||
}
|
||||
|
||||
public extension Foo {
|
||||
public struct Bar {
|
||||
private init() {}
|
||||
}
|
||||
}
|
||||
|
||||
public extension Foo.Bar {
|
||||
public struct Baz {
|
||||
// Message fields and other methods
|
||||
}
|
||||
}
|
||||
|
||||
let baz = Foo.Bar.Baz()
|
||||
```
|
||||
|
||||
Each of these constructs would actually be defined in a separate file; Swift
|
||||
lets us keep them separate and add multiple structs to a single “namespace”
|
||||
through extensions.
|
||||
|
||||
Unfortunately, these intermediate structs generate symbols of their own
|
||||
(metatype information in the data segment). This becomes problematic if multiple
|
||||
build targets contain Swift sources generated from different messages in the
|
||||
same package. At link time, these symbols would collide, resulting in multiple
|
||||
definition errors.
|
||||
|
||||
This approach also has the disadvantage that there is no automatic “short” way
|
||||
to refer to the generated messages at the deepest nesting levels; since this use
|
||||
of structs is a hack around the lack of namespaces, there is no equivalent to
|
||||
import (Java) or using (C++) to simplify this. Users would have to declare type
|
||||
aliases to make this cleaner, or we would have to generate them for users.
|
147
docs/third_party.md
Normal file
147
docs/third_party.md
Normal file
@ -0,0 +1,147 @@
|
||||
# Third-Party Add-ons for Protocol Buffers
|
||||
|
||||
This page lists code related to Protocol Buffers which is developed and maintained by third parties. You may find this code useful, but note that **these projects are not affiliated with or endorsed by Google (unless explicitly marked)**; try them at your own risk. Also note that many projects here are in the early stages of development and not production-ready.
|
||||
|
||||
If you have a project that should be listed here, please [send us a pull request](https://github.com/google/protobuf/pulls) to update this page.
|
||||
|
||||
## Programming Languages
|
||||
|
||||
These are projects we know about implementing Protocol Buffers for other programming languages:
|
||||
* Action Script: http://code.google.com/p/protobuf-actionscript3/
|
||||
* Action Script: https://code.google.com/p/protoc-gen-as3/
|
||||
* Action Script: https://github.com/matrix3d/JProtoc
|
||||
* C: https://github.com/protobuf-c/protobuf-c
|
||||
* C: http://koti.kapsi.fi/jpa/nanopb/
|
||||
* C: https://github.com/cloudwu/pbc/
|
||||
* C: https://github.com/haberman/upb/wiki
|
||||
* C: https://github.com/squidfunk/protobluff
|
||||
* C++: https://github.com/google/protobuf (Google-official implementation)
|
||||
* C/C++: http://spbc.sf.net/
|
||||
* C#: http://code.google.com/p/protobuf-csharp-port
|
||||
* C#: http://code.google.com/p/protosharp/
|
||||
* C#: https://silentorbit.com/protobuf/
|
||||
* C#/.NET/WCF/VB: http://code.google.com/p/protobuf-net/
|
||||
* Clojure: http://github.com/ninjudd/clojure-protobuf
|
||||
* Common Lisp: http://www.prism.gatech.edu/~ndantam3/docs/s-protobuf/
|
||||
* Common Lisp: http://github.com/brown/protobuf
|
||||
* D: https://github.com/msoucy/dproto
|
||||
* D: http://256.makerslocal.org/wiki/index.php/ProtocolBuffer
|
||||
* D: https://github.com/opticron/ProtocolBuffer
|
||||
* Dart: https://github.com/dart-lang/dart-protobuf (runtime) https://github.com/dart-lang/dart-protoc-plugin (code generator)
|
||||
* Delphi: http://sourceforge.net/projects/protobuf-delphi/
|
||||
* Delphi: http://fundementals.sourceforge.net/dl.html
|
||||
* Elixir: https://github.com/jeremyong/exprotoc
|
||||
* Erlang: http://github.com/ngerakines/erlang_protobuffs/tree/master
|
||||
* Erlang: http://piqi.org/
|
||||
* Erlang: https://code.google.com/p/protoc-gen-erl/
|
||||
* Erlang: https://github.com/basho/erlang_protobuffs
|
||||
* Go: https://github.com/golang/protobuf (Google-official implementation)
|
||||
* Go: http://code.google.com/p/goprotobuf/
|
||||
* Go: https://github.com/akunspy/gopbuf
|
||||
* Haskell: http://hackage.haskell.org/package/hprotoc
|
||||
* Haxe: https://github.com/Atry/protoc-gen-haxe
|
||||
* Java: https://github.com/google/protobuf (Google-official implementation)
|
||||
* Java/Android: https://github.com/square/wire
|
||||
* Java ME: http://code.google.com/p/protobuf-javame/
|
||||
* Java ME: http://swingme.sourceforge.net/encode.shtml
|
||||
* Java ME: http://github.com/ponderingpanda/protobuf-j2me
|
||||
* Java ME: http://code.google.com/p/protobuf-j2me/
|
||||
* Javascript: http://code.google.com/p/protobuf-js/
|
||||
* Javascript: http://github.com/sirikata/protojs
|
||||
* Javascript: https://github.com/dcodeIO/ProtoBuf.js
|
||||
* Javascript: http://code.google.com/p/protobuf-for-node/
|
||||
* Javascript: http://code.google.com/p/protostuff/
|
||||
* Julia: https://github.com/tanmaykm/ProtoBuf.jl
|
||||
* Lua: http://code.google.com/p/protoc-gen-lua/
|
||||
* Lua: http://github.com/indygreg/lua-protobuf
|
||||
* Lua: https://github.com/Neopallium/lua-pb
|
||||
* Matlab: http://code.google.com/p/protobuf-matlab/
|
||||
* Mercury: http://code.google.com/p/protobuf-mercury/
|
||||
* Objective C: http://code.google.com/p/protobuf-objc/
|
||||
* Objective C: https://github.com/alexeyxo/protobuf-objc
|
||||
* OCaml: http://piqi.org/
|
||||
* Perl: http://groups.google.com/group/protobuf-perl
|
||||
* Perl: http://search.cpan.org/perldoc?Google::ProtocolBuffers
|
||||
* Perl/XS: http://code.google.com/p/protobuf-perlxs/
|
||||
* PHP: http://code.google.com/p/pb4php/
|
||||
* PHP: https://github.com/allegro/php-protobuf/
|
||||
* PHP: https://github.com/chobie/php-protocolbuffers
|
||||
* PHP: http://drslump.github.com/Protobuf-PHP
|
||||
* Prolog: http://www.swi-prolog.org/pldoc/package/protobufs.html
|
||||
* Python: https://github.com/google/protobuf (Google-official implementation)
|
||||
* Python: http://eigenein.github.com/protobuf/
|
||||
* R: http://cran.r-project.org/package=RProtoBuf
|
||||
* Ruby: http://code.google.com/p/ruby-protobuf/
|
||||
* Ruby: http://github.com/mozy/ruby-protocol-buffers
|
||||
* Ruby: https://github.com/bmizerany/beefcake/tree/master/lib/beefcake
|
||||
* Ruby: https://github.com/localshred/protobuf
|
||||
* Rust: https://github.com/stepancheg/rust-protobuf/
|
||||
* Scala: http://github.com/jeffplaisance/scala-protobuf
|
||||
* Scala: http://code.google.com/p/protobuf-scala
|
||||
* Scala: https://github.com/SandroGrzicic/ScalaBuff
|
||||
* Scala: http://trueaccord.github.io/ScalaPB/
|
||||
* Swift: https://github.com/alexeyxo/protobuf-swift
|
||||
* Vala: https://launchpad.net/protobuf-vala
|
||||
* Visual Basic: http://code.google.com/p/protobuf-net/
|
||||
|
||||
## RPC Implementations
|
||||
|
||||
GRPC (http://www.grpc.io/) is Google's RPC implementation for Protocol Buffers. There are other third-party RPC implementations as well. Some of these actually work with Protocol Buffers service definitions (defined using the `service` keyword in `.proto` files) while others just use Protocol Buffers message objects.
|
||||
|
||||
* https://github.com/grpc/grpc (C++, Node.js, Python, Ruby, Objective-C, PHP, C#, Google-official implementation)
|
||||
* http://zeroc.com/ice.html (Multiple languages)
|
||||
* http://code.google.com/p/protobuf-net/ (C#/.NET/WCF/VB)
|
||||
* https://launchpad.net/txprotobuf/ (Python)
|
||||
* https://github.com/modeswitch/protobuf-rpc (Python)
|
||||
* http://code.google.com/p/protobuf-socket-rpc/ (Java, Python)
|
||||
* http://code.google.com/p/proto-streamer/ (Java)
|
||||
* http://code.google.com/p/server1/ (C++)
|
||||
* http://deltavsoft.com/RcfUserGuide/Protobufs (C++)
|
||||
* http://code.google.com/p/protobuf-mina-rpc/ (Python client, Java server)
|
||||
* http://code.google.com/p/casocklib/ (C++)
|
||||
* http://code.google.com/p/cxf-protobuf/ (Java)
|
||||
* http://code.google.com/p/protobuf-remote/ (C++/C#)
|
||||
* http://code.google.com/p/protobuf-rpc-pro/ (Java)
|
||||
* https://code.google.com/p/protorpc/ (Go/C++)
|
||||
* https://code.google.com/p/eneter-protobuf-serializer/ (Java/.NET)
|
||||
* http://www.deltavsoft.com/RCFProto.html (C++/Java/Python/C#)
|
||||
* https://github.com/robbinfan/claire-protorpc (C++)
|
||||
* https://github.com/BaiduPS/sofa-pbrpc (C++)
|
||||
* https://github.com/ebencheung/arab (C++)
|
||||
* http://code.google.com/p/protobuf-csharp-rpc/ (C#)
|
||||
* https://github.com/thesamet/rpcz (C++/Python, based on ZeroMQ)
|
||||
* https://github.com/w359405949/libmaid (C++, Python)
|
||||
* https://github.com/madwyn/libpbrpc (C++)
|
||||
|
||||
## Other Utilities
|
||||
|
||||
There are miscellaneous other things you may find useful as a Protocol Buffers developer.
|
||||
|
||||
* [NetBeans IDE plugin](http://code.google.com/p/protobuf-netbeans-plugin/)
|
||||
* [Wireshark/Ethereal packet sniffer plugin](http://code.google.com/p/protobuf-wireshark/)
|
||||
* [Alternate encodings (JSON, XML, HTML) for Java protobufs](http://code.google.com/p/protobuf-java-format/)
|
||||
* [Another JSON encoder/decoder for Java](https://github.com/sijuv/protobuf-codec)
|
||||
* [Editor for serialized protobufs](http://code.google.com/p/protobufeditor/)
|
||||
* [Intellij IDEA plugin](http://github.com/nnmatveev/idea-plugin-protobuf)
|
||||
* [TextMate syntax highlighting](http://github.com/michaeledgar/protobuf-tmbundle)
|
||||
* [Oracle PL SQL plugin](http://code.google.com/p/protocol-buffer-plsql/)
|
||||
* [Eclipse editor for protobuf (from Google)](http://code.google.com/p/protobuf-dt/)
|
||||
* [C++ Builder compatible protobuf](https://github.com/saadware/protobuf-cppbuilder)
|
||||
* Maven Protocol Compiler Plugin
|
||||
* https://github.com/sergei-ivanov/maven-protoc-plugin/
|
||||
* http://igor-petruk.github.com/protobuf-maven-plugin/
|
||||
* http://code.google.com/p/maven-protoc-plugin/
|
||||
* https://github.com/os72/protoc-jar-maven-plugin
|
||||
* [Documentation generator plugin (Markdown/HTML/DocBook/...)](https://github.com/estan/protoc-gen-doc)
|
||||
* [DocBook generator for .proto files](http://code.google.com/p/protoc-gen-docbook/)
|
||||
* [Protobuf for nginx module](https://github.com/dbcode/protobuf-nginx/)
|
||||
* [RSpec matchers and Cucumber step defs for testing Protocol Buffers](https://github.com/connamara/protobuf_spec)
|
||||
* [Sbt plugin for Protocol Buffers](https://github.com/Atry/sbt-cppp)
|
||||
* [Gradle Protobuf Plugin](https://github.com/aantono/gradle-plugin-protobuf)
|
||||
* [Multi-platform executable JAR and Java API for protoc](https://github.com/os72/protoc-jar)
|
||||
* [Python scripts to convert between Protocol Buffers and JSON](https://github.com/NextTuesday/py-pb-converters)
|
||||
* [Visual Studio Language Service support for Protocol Buffers](http://visualstudiogallery.msdn.microsoft.com/4bc0f38c-b058-4e05-ae38-155e053c19c5)
|
||||
* [C++ library for serialization/de-serialization between Protocol Buffers and JSON.](https://github.com/yinqiwen/pbjson)
|
||||
* [ProtoBuf with Java EE7 Expression Language 3.0; pure Java ProtoBuf Parser and Builder.](https://github.com/protobufel/protobuf-el)
|
||||
* [Notepad++ Syntax Highlighting for .proto files](https://github.com/chai2010/notepadplus-protobuf)
|
||||
* [Linter for .proto files](https://github.com/ckaznocha/protoc-gen-lint)
|
@ -10,8 +10,6 @@
|
||||
# to make when building protoc. This is particularly useful for passing
|
||||
# -j4 to run 4 jobs simultaneously.
|
||||
|
||||
set -e
|
||||
|
||||
if test ! -e src/google/protobuf/stubs/common.h; then
|
||||
cat >&2 << __EOF__
|
||||
Could not find source code. Make sure you are running this script from the
|
||||
@ -52,9 +50,14 @@ do
|
||||
echo "Round $PROCESS_ROUND"
|
||||
CORE_PROTO_IS_CORRECT=1
|
||||
|
||||
make $@ protoc &&
|
||||
./protoc --cpp_out=dllexport_decl=LIBPROTOBUF_EXPORT:$TMP ${RUNTIME_PROTO_FILES[@]} && \
|
||||
./protoc --cpp_out=dllexport_decl=LIBPROTOC_EXPORT:$TMP google/protobuf/compiler/plugin.proto
|
||||
make $@ protoc
|
||||
if test $? -ne 0; then
|
||||
echo "Failed to build protoc."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
./protoc --cpp_out=dllexport_decl=LIBPROTOBUF_EXPORT:$TMP ${RUNTIME_PROTO_FILES[@]} && \
|
||||
./protoc --cpp_out=dllexport_decl=LIBPROTOC_EXPORT:$TMP google/protobuf/compiler/plugin.proto
|
||||
|
||||
for PROTO_FILE in ${RUNTIME_PROTO_FILES[@]}; do
|
||||
BASE_NAME=${PROTO_FILE%.*}
|
||||
@ -92,9 +95,9 @@ do
|
||||
done
|
||||
cd ..
|
||||
|
||||
if test -x objectivec/generate_descriptors_proto.sh; then
|
||||
if test -x objectivec/generate_well_known_types.sh; then
|
||||
echo "Generating messages for objc."
|
||||
objectivec/generate_descriptors_proto.sh $@
|
||||
objectivec/generate_well_known_types.sh $@
|
||||
fi
|
||||
|
||||
if test -x csharp/generate_protos.sh; then
|
||||
|
@ -50,17 +50,23 @@ import java.util.Map;
|
||||
*
|
||||
* @author kenton@google.com Kenton Varda
|
||||
*/
|
||||
public abstract class AbstractMessage extends AbstractMessageLite
|
||||
implements Message {
|
||||
public abstract class AbstractMessage
|
||||
// TODO(dweis): Update GeneratedMessage to parameterize with MessageType and BuilderType.
|
||||
extends AbstractMessageLite
|
||||
implements Message {
|
||||
|
||||
@Override
|
||||
public boolean isInitialized() {
|
||||
return MessageReflection.isInitialized(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> findInitializationErrors() {
|
||||
return MessageReflection.findMissingFields(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInitializationErrorString() {
|
||||
return MessageReflection.delimitWithCommas(findInitializationErrors());
|
||||
}
|
||||
@ -83,12 +89,14 @@ public abstract class AbstractMessage extends AbstractMessageLite
|
||||
return TextFormat.printToString(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(final CodedOutputStream output) throws IOException {
|
||||
MessageReflection.writeMessageTo(this, getAllFields(), output, false);
|
||||
}
|
||||
|
||||
protected int memoizedSize = -1;
|
||||
|
||||
@Override
|
||||
public int getSerializedSize() {
|
||||
int size = memoizedSize;
|
||||
if (size != -1) {
|
||||
@ -288,8 +296,8 @@ public abstract class AbstractMessage extends AbstractMessageLite
|
||||
* other methods.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static abstract class Builder<BuilderType extends Builder>
|
||||
extends AbstractMessageLite.Builder<BuilderType>
|
||||
public static abstract class Builder<BuilderType extends Builder<BuilderType>>
|
||||
extends AbstractMessageLite.Builder
|
||||
implements Message.Builder {
|
||||
// The compiler produces an error if this is not declared explicitly.
|
||||
@Override
|
||||
@ -314,6 +322,7 @@ public abstract class AbstractMessage extends AbstractMessageLite
|
||||
throw new UnsupportedOperationException("clearOneof() is not implemented.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BuilderType clear() {
|
||||
for (final Map.Entry<FieldDescriptor, Object> entry :
|
||||
getAllFields().entrySet()) {
|
||||
@ -322,14 +331,22 @@ public abstract class AbstractMessage extends AbstractMessageLite
|
||||
return (BuilderType) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> findInitializationErrors() {
|
||||
return MessageReflection.findMissingFields(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInitializationErrorString() {
|
||||
return MessageReflection.delimitWithCommas(findInitializationErrors());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BuilderType internalMergeFrom(AbstractMessageLite other) {
|
||||
return mergeFrom((Message) other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BuilderType mergeFrom(final Message other) {
|
||||
if (other.getDescriptorForType() != getDescriptorForType()) {
|
||||
throw new IllegalArgumentException(
|
||||
@ -407,6 +424,7 @@ public abstract class AbstractMessage extends AbstractMessageLite
|
||||
return (BuilderType) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BuilderType mergeUnknownFields(final UnknownFieldSet unknownFields) {
|
||||
setUnknownFields(
|
||||
UnknownFieldSet.newBuilder(getUnknownFields())
|
||||
@ -415,17 +433,19 @@ public abstract class AbstractMessage extends AbstractMessageLite
|
||||
return (BuilderType) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message.Builder getFieldBuilder(final FieldDescriptor field) {
|
||||
throw new UnsupportedOperationException(
|
||||
"getFieldBuilder() called on an unsupported message type.");
|
||||
}
|
||||
|
||||
public Message.Builder getRepeatedFieldBuilder(final FieldDescriptor field,
|
||||
int index) {
|
||||
@Override
|
||||
public Message.Builder getRepeatedFieldBuilder(final FieldDescriptor field, int index) {
|
||||
throw new UnsupportedOperationException(
|
||||
"getRepeatedFieldBuilder() called on an unsupported message type.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return TextFormat.printToString(this);
|
||||
}
|
||||
@ -462,7 +482,7 @@ public abstract class AbstractMessage extends AbstractMessageLite
|
||||
@Override
|
||||
public BuilderType mergeFrom(final ByteString data)
|
||||
throws InvalidProtocolBufferException {
|
||||
return super.mergeFrom(data);
|
||||
return (BuilderType) super.mergeFrom(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -470,20 +490,20 @@ public abstract class AbstractMessage extends AbstractMessageLite
|
||||
final ByteString data,
|
||||
final ExtensionRegistryLite extensionRegistry)
|
||||
throws InvalidProtocolBufferException {
|
||||
return super.mergeFrom(data, extensionRegistry);
|
||||
return (BuilderType) super.mergeFrom(data, extensionRegistry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BuilderType mergeFrom(final byte[] data)
|
||||
throws InvalidProtocolBufferException {
|
||||
return super.mergeFrom(data);
|
||||
return (BuilderType) super.mergeFrom(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BuilderType mergeFrom(
|
||||
final byte[] data, final int off, final int len)
|
||||
throws InvalidProtocolBufferException {
|
||||
return super.mergeFrom(data, off, len);
|
||||
return (BuilderType) super.mergeFrom(data, off, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -491,7 +511,7 @@ public abstract class AbstractMessage extends AbstractMessageLite
|
||||
final byte[] data,
|
||||
final ExtensionRegistryLite extensionRegistry)
|
||||
throws InvalidProtocolBufferException {
|
||||
return super.mergeFrom(data, extensionRegistry);
|
||||
return (BuilderType) super.mergeFrom(data, extensionRegistry);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -499,13 +519,13 @@ public abstract class AbstractMessage extends AbstractMessageLite
|
||||
final byte[] data, final int off, final int len,
|
||||
final ExtensionRegistryLite extensionRegistry)
|
||||
throws InvalidProtocolBufferException {
|
||||
return super.mergeFrom(data, off, len, extensionRegistry);
|
||||
return (BuilderType) super.mergeFrom(data, off, len, extensionRegistry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BuilderType mergeFrom(final InputStream input)
|
||||
throws IOException {
|
||||
return super.mergeFrom(input);
|
||||
return (BuilderType) super.mergeFrom(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -513,7 +533,7 @@ public abstract class AbstractMessage extends AbstractMessageLite
|
||||
final InputStream input,
|
||||
final ExtensionRegistryLite extensionRegistry)
|
||||
throws IOException {
|
||||
return super.mergeFrom(input, extensionRegistry);
|
||||
return (BuilderType) super.mergeFrom(input, extensionRegistry);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -43,9 +43,13 @@ import java.util.Collection;
|
||||
*
|
||||
* @author kenton@google.com Kenton Varda
|
||||
*/
|
||||
public abstract class AbstractMessageLite implements MessageLite {
|
||||
public abstract class AbstractMessageLite<
|
||||
MessageType extends AbstractMessageLite<MessageType, BuilderType>,
|
||||
BuilderType extends AbstractMessageLite.Builder<MessageType, BuilderType>>
|
||||
implements MessageLite {
|
||||
protected int memoizedHashCode = 0;
|
||||
|
||||
|
||||
@Override
|
||||
public ByteString toByteString() {
|
||||
try {
|
||||
final ByteString.CodedBuilder out =
|
||||
@ -59,6 +63,7 @@ public abstract class AbstractMessageLite implements MessageLite {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] toByteArray() {
|
||||
try {
|
||||
final byte[] result = new byte[getSerializedSize()];
|
||||
@ -73,6 +78,7 @@ public abstract class AbstractMessageLite implements MessageLite {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(final OutputStream output) throws IOException {
|
||||
final int bufferSize =
|
||||
CodedOutputStream.computePreferredBufferSize(getSerializedSize());
|
||||
@ -82,6 +88,7 @@ public abstract class AbstractMessageLite implements MessageLite {
|
||||
codedOutput.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDelimitedTo(final OutputStream output) throws IOException {
|
||||
final int serialized = getSerializedSize();
|
||||
final int bufferSize = CodedOutputStream.computePreferredBufferSize(
|
||||
@ -120,25 +127,27 @@ public abstract class AbstractMessageLite implements MessageLite {
|
||||
* other methods.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static abstract class Builder<BuilderType extends Builder>
|
||||
public abstract static class Builder<
|
||||
MessageType extends AbstractMessageLite<MessageType, BuilderType>,
|
||||
BuilderType extends Builder<MessageType, BuilderType>>
|
||||
implements MessageLite.Builder {
|
||||
// The compiler produces an error if this is not declared explicitly.
|
||||
@Override
|
||||
public abstract BuilderType clone();
|
||||
|
||||
public BuilderType mergeFrom(final CodedInputStream input)
|
||||
throws IOException {
|
||||
@Override
|
||||
public BuilderType mergeFrom(final CodedInputStream input) throws IOException {
|
||||
return mergeFrom(input, ExtensionRegistryLite.getEmptyRegistry());
|
||||
}
|
||||
|
||||
// Re-defined here for return type covariance.
|
||||
@Override
|
||||
public abstract BuilderType mergeFrom(
|
||||
final CodedInputStream input,
|
||||
final ExtensionRegistryLite extensionRegistry)
|
||||
final CodedInputStream input, final ExtensionRegistryLite extensionRegistry)
|
||||
throws IOException;
|
||||
|
||||
public BuilderType mergeFrom(final ByteString data)
|
||||
throws InvalidProtocolBufferException {
|
||||
@Override
|
||||
public BuilderType mergeFrom(final ByteString data) throws InvalidProtocolBufferException {
|
||||
try {
|
||||
final CodedInputStream input = data.newCodedInput();
|
||||
mergeFrom(input);
|
||||
@ -153,9 +162,9 @@ public abstract class AbstractMessageLite implements MessageLite {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BuilderType mergeFrom(
|
||||
final ByteString data,
|
||||
final ExtensionRegistryLite extensionRegistry)
|
||||
final ByteString data, final ExtensionRegistryLite extensionRegistry)
|
||||
throws InvalidProtocolBufferException {
|
||||
try {
|
||||
final CodedInputStream input = data.newCodedInput();
|
||||
@ -171,14 +180,14 @@ public abstract class AbstractMessageLite implements MessageLite {
|
||||
}
|
||||
}
|
||||
|
||||
public BuilderType mergeFrom(final byte[] data)
|
||||
throws InvalidProtocolBufferException {
|
||||
@Override
|
||||
public BuilderType mergeFrom(final byte[] data) throws InvalidProtocolBufferException {
|
||||
return mergeFrom(data, 0, data.length);
|
||||
}
|
||||
|
||||
public BuilderType mergeFrom(final byte[] data, final int off,
|
||||
final int len)
|
||||
throws InvalidProtocolBufferException {
|
||||
@Override
|
||||
public BuilderType mergeFrom(final byte[] data, final int off, final int len)
|
||||
throws InvalidProtocolBufferException {
|
||||
try {
|
||||
final CodedInputStream input =
|
||||
CodedInputStream.newInstance(data, off, len);
|
||||
@ -194,15 +203,17 @@ public abstract class AbstractMessageLite implements MessageLite {
|
||||
}
|
||||
}
|
||||
|
||||
public BuilderType mergeFrom(
|
||||
final byte[] data,
|
||||
final ExtensionRegistryLite extensionRegistry)
|
||||
@Override
|
||||
public BuilderType mergeFrom(final byte[] data, final ExtensionRegistryLite extensionRegistry)
|
||||
throws InvalidProtocolBufferException {
|
||||
return mergeFrom(data, 0, data.length, extensionRegistry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BuilderType mergeFrom(
|
||||
final byte[] data, final int off, final int len,
|
||||
final byte[] data,
|
||||
final int off,
|
||||
final int len,
|
||||
final ExtensionRegistryLite extensionRegistry)
|
||||
throws InvalidProtocolBufferException {
|
||||
try {
|
||||
@ -220,6 +231,7 @@ public abstract class AbstractMessageLite implements MessageLite {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BuilderType mergeFrom(final InputStream input) throws IOException {
|
||||
final CodedInputStream codedInput = CodedInputStream.newInstance(input);
|
||||
mergeFrom(codedInput);
|
||||
@ -227,10 +239,9 @@ public abstract class AbstractMessageLite implements MessageLite {
|
||||
return (BuilderType) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BuilderType mergeFrom(
|
||||
final InputStream input,
|
||||
final ExtensionRegistryLite extensionRegistry)
|
||||
throws IOException {
|
||||
final InputStream input, final ExtensionRegistryLite extensionRegistry) throws IOException {
|
||||
final CodedInputStream codedInput = CodedInputStream.newInstance(input);
|
||||
mergeFrom(codedInput, extensionRegistry);
|
||||
codedInput.checkLastTagWas(0);
|
||||
@ -292,10 +303,9 @@ public abstract class AbstractMessageLite implements MessageLite {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mergeDelimitedFrom(
|
||||
final InputStream input,
|
||||
final ExtensionRegistryLite extensionRegistry)
|
||||
throws IOException {
|
||||
final InputStream input, final ExtensionRegistryLite extensionRegistry) throws IOException {
|
||||
final int firstByte = input.read();
|
||||
if (firstByte == -1) {
|
||||
return false;
|
||||
@ -306,11 +316,24 @@ public abstract class AbstractMessageLite implements MessageLite {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean mergeDelimitedFrom(final InputStream input)
|
||||
throws IOException {
|
||||
@Override
|
||||
public boolean mergeDelimitedFrom(final InputStream input) throws IOException {
|
||||
return mergeDelimitedFrom(input,
|
||||
ExtensionRegistryLite.getEmptyRegistry());
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked") // isInstance takes care of this
|
||||
public BuilderType mergeFrom(final MessageLite other) {
|
||||
if (!getDefaultInstanceForType().getClass().isInstance(other)) {
|
||||
throw new IllegalArgumentException(
|
||||
"mergeFrom(MessageLite) can only merge messages of the same type.");
|
||||
}
|
||||
|
||||
return internalMergeFrom((MessageType) other);
|
||||
}
|
||||
|
||||
protected abstract BuilderType internalMergeFrom(MessageType message);
|
||||
|
||||
/**
|
||||
* Construct an UninitializedMessageException reporting missing fields in
|
||||
|
@ -78,26 +78,27 @@ public abstract class AbstractParser<MessageType extends MessageLite>
|
||||
private static final ExtensionRegistryLite EMPTY_REGISTRY
|
||||
= ExtensionRegistryLite.getEmptyRegistry();
|
||||
|
||||
@Override
|
||||
public MessageType parsePartialFrom(CodedInputStream input)
|
||||
throws InvalidProtocolBufferException {
|
||||
return parsePartialFrom(input, EMPTY_REGISTRY);
|
||||
}
|
||||
|
||||
public MessageType parseFrom(CodedInputStream input,
|
||||
ExtensionRegistryLite extensionRegistry)
|
||||
@Override
|
||||
public MessageType parseFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry)
|
||||
throws InvalidProtocolBufferException {
|
||||
return checkMessageInitialized(
|
||||
parsePartialFrom(input, extensionRegistry));
|
||||
}
|
||||
|
||||
public MessageType parseFrom(CodedInputStream input)
|
||||
throws InvalidProtocolBufferException {
|
||||
@Override
|
||||
public MessageType parseFrom(CodedInputStream input) throws InvalidProtocolBufferException {
|
||||
return parseFrom(input, EMPTY_REGISTRY);
|
||||
}
|
||||
|
||||
public MessageType parsePartialFrom(ByteString data,
|
||||
ExtensionRegistryLite extensionRegistry)
|
||||
throws InvalidProtocolBufferException {
|
||||
@Override
|
||||
public MessageType parsePartialFrom(ByteString data, ExtensionRegistryLite extensionRegistry)
|
||||
throws InvalidProtocolBufferException {
|
||||
MessageType message;
|
||||
try {
|
||||
CodedInputStream input = data.newCodedInput();
|
||||
@ -113,24 +114,25 @@ public abstract class AbstractParser<MessageType extends MessageLite>
|
||||
}
|
||||
}
|
||||
|
||||
public MessageType parsePartialFrom(ByteString data)
|
||||
throws InvalidProtocolBufferException {
|
||||
@Override
|
||||
public MessageType parsePartialFrom(ByteString data) throws InvalidProtocolBufferException {
|
||||
return parsePartialFrom(data, EMPTY_REGISTRY);
|
||||
}
|
||||
|
||||
public MessageType parseFrom(ByteString data,
|
||||
ExtensionRegistryLite extensionRegistry)
|
||||
@Override
|
||||
public MessageType parseFrom(ByteString data, ExtensionRegistryLite extensionRegistry)
|
||||
throws InvalidProtocolBufferException {
|
||||
return checkMessageInitialized(parsePartialFrom(data, extensionRegistry));
|
||||
}
|
||||
|
||||
public MessageType parseFrom(ByteString data)
|
||||
throws InvalidProtocolBufferException {
|
||||
@Override
|
||||
public MessageType parseFrom(ByteString data) throws InvalidProtocolBufferException {
|
||||
return parseFrom(data, EMPTY_REGISTRY);
|
||||
}
|
||||
|
||||
public MessageType parsePartialFrom(byte[] data, int off, int len,
|
||||
ExtensionRegistryLite extensionRegistry)
|
||||
@Override
|
||||
public MessageType parsePartialFrom(
|
||||
byte[] data, int off, int len, ExtensionRegistryLite extensionRegistry)
|
||||
throws InvalidProtocolBufferException {
|
||||
try {
|
||||
CodedInputStream input = CodedInputStream.newInstance(data, off, len);
|
||||
@ -146,47 +148,50 @@ public abstract class AbstractParser<MessageType extends MessageLite>
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageType parsePartialFrom(byte[] data, int off, int len)
|
||||
throws InvalidProtocolBufferException {
|
||||
return parsePartialFrom(data, off, len, EMPTY_REGISTRY);
|
||||
}
|
||||
|
||||
public MessageType parsePartialFrom(byte[] data,
|
||||
ExtensionRegistryLite extensionRegistry)
|
||||
@Override
|
||||
public MessageType parsePartialFrom(byte[] data, ExtensionRegistryLite extensionRegistry)
|
||||
throws InvalidProtocolBufferException {
|
||||
return parsePartialFrom(data, 0, data.length, extensionRegistry);
|
||||
}
|
||||
|
||||
public MessageType parsePartialFrom(byte[] data)
|
||||
throws InvalidProtocolBufferException {
|
||||
@Override
|
||||
public MessageType parsePartialFrom(byte[] data) throws InvalidProtocolBufferException {
|
||||
return parsePartialFrom(data, 0, data.length, EMPTY_REGISTRY);
|
||||
}
|
||||
|
||||
public MessageType parseFrom(byte[] data, int off, int len,
|
||||
ExtensionRegistryLite extensionRegistry)
|
||||
@Override
|
||||
public MessageType parseFrom(
|
||||
byte[] data, int off, int len, ExtensionRegistryLite extensionRegistry)
|
||||
throws InvalidProtocolBufferException {
|
||||
return checkMessageInitialized(
|
||||
parsePartialFrom(data, off, len, extensionRegistry));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageType parseFrom(byte[] data, int off, int len)
|
||||
throws InvalidProtocolBufferException {
|
||||
return parseFrom(data, off, len, EMPTY_REGISTRY);
|
||||
}
|
||||
|
||||
public MessageType parseFrom(byte[] data,
|
||||
ExtensionRegistryLite extensionRegistry)
|
||||
@Override
|
||||
public MessageType parseFrom(byte[] data, ExtensionRegistryLite extensionRegistry)
|
||||
throws InvalidProtocolBufferException {
|
||||
return parseFrom(data, 0, data.length, extensionRegistry);
|
||||
}
|
||||
|
||||
public MessageType parseFrom(byte[] data)
|
||||
throws InvalidProtocolBufferException {
|
||||
@Override
|
||||
public MessageType parseFrom(byte[] data) throws InvalidProtocolBufferException {
|
||||
return parseFrom(data, EMPTY_REGISTRY);
|
||||
}
|
||||
|
||||
public MessageType parsePartialFrom(InputStream input,
|
||||
ExtensionRegistryLite extensionRegistry)
|
||||
@Override
|
||||
public MessageType parsePartialFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
|
||||
throws InvalidProtocolBufferException {
|
||||
CodedInputStream codedInput = CodedInputStream.newInstance(input);
|
||||
MessageType message = parsePartialFrom(codedInput, extensionRegistry);
|
||||
@ -198,26 +203,26 @@ public abstract class AbstractParser<MessageType extends MessageLite>
|
||||
return message;
|
||||
}
|
||||
|
||||
public MessageType parsePartialFrom(InputStream input)
|
||||
throws InvalidProtocolBufferException {
|
||||
@Override
|
||||
public MessageType parsePartialFrom(InputStream input) throws InvalidProtocolBufferException {
|
||||
return parsePartialFrom(input, EMPTY_REGISTRY);
|
||||
}
|
||||
|
||||
public MessageType parseFrom(InputStream input,
|
||||
ExtensionRegistryLite extensionRegistry)
|
||||
@Override
|
||||
public MessageType parseFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
|
||||
throws InvalidProtocolBufferException {
|
||||
return checkMessageInitialized(
|
||||
parsePartialFrom(input, extensionRegistry));
|
||||
}
|
||||
|
||||
public MessageType parseFrom(InputStream input)
|
||||
throws InvalidProtocolBufferException {
|
||||
@Override
|
||||
public MessageType parseFrom(InputStream input) throws InvalidProtocolBufferException {
|
||||
return parseFrom(input, EMPTY_REGISTRY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageType parsePartialDelimitedFrom(
|
||||
InputStream input,
|
||||
ExtensionRegistryLite extensionRegistry)
|
||||
InputStream input, ExtensionRegistryLite extensionRegistry)
|
||||
throws InvalidProtocolBufferException {
|
||||
int size;
|
||||
try {
|
||||
@ -233,21 +238,21 @@ public abstract class AbstractParser<MessageType extends MessageLite>
|
||||
return parsePartialFrom(limitedInput, extensionRegistry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageType parsePartialDelimitedFrom(InputStream input)
|
||||
throws InvalidProtocolBufferException {
|
||||
return parsePartialDelimitedFrom(input, EMPTY_REGISTRY);
|
||||
}
|
||||
|
||||
public MessageType parseDelimitedFrom(
|
||||
InputStream input,
|
||||
ExtensionRegistryLite extensionRegistry)
|
||||
@Override
|
||||
public MessageType parseDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
|
||||
throws InvalidProtocolBufferException {
|
||||
return checkMessageInitialized(
|
||||
parsePartialDelimitedFrom(input, extensionRegistry));
|
||||
}
|
||||
|
||||
public MessageType parseDelimitedFrom(InputStream input)
|
||||
throws InvalidProtocolBufferException {
|
||||
@Override
|
||||
public MessageType parseDelimitedFrom(InputStream input) throws InvalidProtocolBufferException {
|
||||
return parseDelimitedFrom(input, EMPTY_REGISTRY);
|
||||
}
|
||||
}
|
||||
|
@ -34,19 +34,25 @@ import com.google.protobuf.Internal.ProtobufList;
|
||||
|
||||
import java.util.AbstractList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.RandomAccess;
|
||||
|
||||
/**
|
||||
* An abstract implementation of {@link ProtobufList} which manages mutability semantics. All mutate
|
||||
* methods are check if the list is mutable before proceeding. Subclasses must invoke
|
||||
* methods must check if the list is mutable before proceeding. Subclasses must invoke
|
||||
* {@link #ensureIsMutable()} manually when overriding those methods.
|
||||
* <p>
|
||||
* This implementation assumes all subclasses are array based, supporting random access.
|
||||
*/
|
||||
abstract class AbstractProtobufList<E> extends AbstractList<E> implements ProtobufList<E> {
|
||||
|
||||
protected static final int DEFAULT_CAPACITY = 10;
|
||||
|
||||
/**
|
||||
* Whether or not this list is modifiable.
|
||||
*/
|
||||
private boolean isMutable;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a mutable list by default.
|
||||
*/
|
||||
@ -54,6 +60,44 @@ abstract class AbstractProtobufList<E> extends AbstractList<E> implements Protob
|
||||
isMutable = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof List)) {
|
||||
return false;
|
||||
}
|
||||
// Handle lists that do not support RandomAccess as efficiently as possible by using an iterator
|
||||
// based approach in our super class. Otherwise our index based approach will avoid those
|
||||
// allocations.
|
||||
if (!(o instanceof RandomAccess)) {
|
||||
return super.equals(o);
|
||||
}
|
||||
|
||||
List<?> other = (List<?>) o;
|
||||
final int size = size();
|
||||
if (size != other.size()) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (!get(i).equals(other.get(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int size = size();
|
||||
int hashCode = 1;
|
||||
for (int i = 0; i < size; i++) {
|
||||
hashCode = (31 * hashCode) + get(i).hashCode();
|
||||
}
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(E e) {
|
||||
ensureIsMutable();
|
||||
|
@ -34,7 +34,6 @@ import com.google.protobuf.Internal.BooleanList;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.RandomAccess;
|
||||
|
||||
/**
|
||||
@ -45,8 +44,6 @@ import java.util.RandomAccess;
|
||||
final class BooleanArrayList
|
||||
extends AbstractProtobufList<Boolean> implements BooleanList, RandomAccess {
|
||||
|
||||
private static final int DEFAULT_CAPACITY = 10;
|
||||
|
||||
private static final BooleanArrayList EMPTY_LIST = new BooleanArrayList();
|
||||
static {
|
||||
EMPTY_LIST.makeImmutable();
|
||||
@ -60,7 +57,7 @@ final class BooleanArrayList
|
||||
* The backing store for the list.
|
||||
*/
|
||||
private boolean[] array;
|
||||
|
||||
|
||||
/**
|
||||
* The size of the list distinct from the length of the array. That is, it is the number of
|
||||
* elements set in the list.
|
||||
@ -71,35 +68,57 @@ final class BooleanArrayList
|
||||
* Constructs a new mutable {@code BooleanArrayList} with default capacity.
|
||||
*/
|
||||
BooleanArrayList() {
|
||||
this(DEFAULT_CAPACITY);
|
||||
this(new boolean[DEFAULT_CAPACITY], 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new mutable {@code BooleanArrayList} with the provided capacity.
|
||||
* Constructs a new mutable {@code BooleanArrayList}.
|
||||
*/
|
||||
BooleanArrayList(int capacity) {
|
||||
array = new boolean[capacity];
|
||||
size = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new mutable {@code BooleanArrayList} containing the same elements as
|
||||
* {@code other}.
|
||||
*/
|
||||
BooleanArrayList(List<Boolean> other) {
|
||||
if (other instanceof BooleanArrayList) {
|
||||
BooleanArrayList list = (BooleanArrayList) other;
|
||||
array = list.array.clone();
|
||||
size = list.size;
|
||||
} else {
|
||||
size = other.size();
|
||||
array = new boolean[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
array[i] = other.get(i);
|
||||
}
|
||||
}
|
||||
private BooleanArrayList(boolean[] array, int size) {
|
||||
this.array = array;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof BooleanArrayList)) {
|
||||
return super.equals(o);
|
||||
}
|
||||
BooleanArrayList other = (BooleanArrayList) o;
|
||||
if (size != other.size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final boolean[] arr = other.array;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (array[i] != arr[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
for (int i = 0; i < size; i++) {
|
||||
result = (31 * result) + Internal.hashBoolean(array[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BooleanList mutableCopyWithCapacity(int capacity) {
|
||||
if (capacity < size) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return new BooleanArrayList(Arrays.copyOf(array, capacity), size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean get(int index) {
|
||||
return getBoolean(index);
|
||||
|
@ -0,0 +1,145 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// 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.
|
||||
|
||||
package com.google.protobuf;
|
||||
|
||||
import static java.lang.Math.max;
|
||||
import static java.lang.Math.min;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* Utility class to provide efficient writing of {@link ByteBuffer}s to {@link OutputStream}s.
|
||||
*/
|
||||
final class ByteBufferWriter {
|
||||
private ByteBufferWriter() {}
|
||||
|
||||
/**
|
||||
* Minimum size for a cached buffer. This prevents us from allocating buffers that are too
|
||||
* small to be easily reused.
|
||||
*/
|
||||
// TODO(nathanmittler): tune this property or allow configuration?
|
||||
private static final int MIN_CACHED_BUFFER_SIZE = 1024;
|
||||
|
||||
/**
|
||||
* Maximum size for a cached buffer. If a larger buffer is required, it will be allocated
|
||||
* but not cached.
|
||||
*/
|
||||
// TODO(nathanmittler): tune this property or allow configuration?
|
||||
private static final int MAX_CACHED_BUFFER_SIZE = 16 * 1024;
|
||||
|
||||
/**
|
||||
* The fraction of the requested buffer size under which the buffer will be reallocated.
|
||||
*/
|
||||
// TODO(nathanmittler): tune this property or allow configuration?
|
||||
private static final float BUFFER_REALLOCATION_THRESHOLD = 0.5f;
|
||||
|
||||
/**
|
||||
* Keeping a soft reference to a thread-local buffer. This buffer is used for writing a
|
||||
* {@link ByteBuffer} to an {@link OutputStream} when no zero-copy alternative was available.
|
||||
* Using a "soft" reference since VMs may keep this reference around longer than "weak"
|
||||
* (e.g. HotSpot will maintain soft references until memory pressure warrants collection).
|
||||
*/
|
||||
private static final ThreadLocal<SoftReference<byte[]>> BUFFER =
|
||||
new ThreadLocal<SoftReference<byte[]>>();
|
||||
|
||||
/**
|
||||
* For testing purposes only. Clears the cached buffer to force a new allocation on the next
|
||||
* invocation.
|
||||
*/
|
||||
static void clearCachedBuffer() {
|
||||
BUFFER.set(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the remaining content of the buffer to the given stream. The buffer {@code position}
|
||||
* will remain unchanged by this method.
|
||||
*/
|
||||
static void write(ByteBuffer buffer, OutputStream output) throws IOException {
|
||||
final int initialPos = buffer.position();
|
||||
try {
|
||||
if (buffer.hasArray()) {
|
||||
// Optimized write for array-backed buffers.
|
||||
// Note that we're taking the risk that a malicious OutputStream could modify the array.
|
||||
output.write(buffer.array(), buffer.arrayOffset() + buffer.position(), buffer.remaining());
|
||||
} else if (output instanceof FileOutputStream) {
|
||||
// Use a channel to write out the ByteBuffer. This will automatically empty the buffer.
|
||||
((FileOutputStream) output).getChannel().write(buffer);
|
||||
} else {
|
||||
// Read all of the data from the buffer to an array.
|
||||
// TODO(nathanmittler): Consider performance improvements for other "known" stream types.
|
||||
final byte[] array = getOrCreateBuffer(buffer.remaining());
|
||||
while (buffer.hasRemaining()) {
|
||||
int length = min(buffer.remaining(), array.length);
|
||||
buffer.get(array, 0, length);
|
||||
output.write(array, 0, length);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
// Restore the initial position.
|
||||
buffer.position(initialPos);
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] getOrCreateBuffer(int requestedSize) {
|
||||
requestedSize = max(requestedSize, MIN_CACHED_BUFFER_SIZE);
|
||||
|
||||
byte[] buffer = getBuffer();
|
||||
// Only allocate if we need to.
|
||||
if (buffer == null || needToReallocate(requestedSize, buffer.length)) {
|
||||
buffer = new byte[requestedSize];
|
||||
|
||||
// Only cache the buffer if it's not too big.
|
||||
if (requestedSize <= MAX_CACHED_BUFFER_SIZE) {
|
||||
setBuffer(buffer);
|
||||
}
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
private static boolean needToReallocate(int requestedSize, int bufferLength) {
|
||||
// First check against just the requested length to avoid the multiply.
|
||||
return bufferLength < requestedSize
|
||||
&& bufferLength < requestedSize * BUFFER_REALLOCATION_THRESHOLD;
|
||||
}
|
||||
|
||||
private static byte[] getBuffer() {
|
||||
SoftReference<byte[]> sr = BUFFER.get();
|
||||
return sr == null ? null : sr.get();
|
||||
}
|
||||
|
||||
private static void setBuffer(byte[] value) {
|
||||
BUFFER.set(new SoftReference<byte[]>(value));
|
||||
}
|
||||
}
|
116
java/core/src/main/java/com/google/protobuf/ByteOutput.java
Normal file
116
java/core/src/main/java/com/google/protobuf/ByteOutput.java
Normal file
@ -0,0 +1,116 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// 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.
|
||||
|
||||
package com.google.protobuf;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* An output target for raw bytes. This interface provides semantics that support two types of
|
||||
* writing:
|
||||
*
|
||||
* <p/><b>Traditional write operations:</b>
|
||||
* (as defined by {@link java.io.OutputStream}) where the target method is responsible for either
|
||||
* copying the data or completing the write before returning from the method call.
|
||||
*
|
||||
* <p/><b>Lazy write operations:</b> where the caller guarantees that it will never modify the
|
||||
* provided buffer and it can therefore be considered immutable. The target method is free to
|
||||
* maintain a reference to the buffer beyond the scope of the method call (e.g. until the write
|
||||
* operation completes).
|
||||
*/
|
||||
@ExperimentalApi
|
||||
public abstract class ByteOutput {
|
||||
/**
|
||||
* Writes a single byte.
|
||||
*
|
||||
* @param value the byte to be written
|
||||
* @throws IOException thrown if an error occurred while writing
|
||||
*/
|
||||
public abstract void write(byte value) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes a sequence of bytes. The {@link ByteOutput} must copy {@code value} if it will
|
||||
* not be processed prior to the return of this method call, since {@code value} may be
|
||||
* reused/altered by the caller.
|
||||
*
|
||||
* <p>NOTE: This method <strong>MUST NOT</strong> modify the {@code value}. Doing so is a
|
||||
* programming error and will lead to data corruption which will be difficult to debug.
|
||||
*
|
||||
* @param value the bytes to be written
|
||||
* @param offset the offset of the start of the writable range
|
||||
* @param length the number of bytes to write starting from {@code offset}
|
||||
* @throws IOException thrown if an error occurred while writing
|
||||
*/
|
||||
public abstract void write(byte[] value, int offset, int length) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes a sequence of bytes. The {@link ByteOutput} is free to retain a reference to the value
|
||||
* beyond the scope of this method call (e.g. write later) since it is considered immutable and is
|
||||
* guaranteed not to change by the caller.
|
||||
*
|
||||
* <p>NOTE: This method <strong>MUST NOT</strong> modify the {@code value}. Doing so is a
|
||||
* programming error and will lead to data corruption which will be difficult to debug.
|
||||
*
|
||||
* @param value the bytes to be written
|
||||
* @param offset the offset of the start of the writable range
|
||||
* @param length the number of bytes to write starting from {@code offset}
|
||||
* @throws IOException thrown if an error occurred while writing
|
||||
*/
|
||||
public abstract void writeLazy(byte[] value, int offset, int length) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes a sequence of bytes. The {@link ByteOutput} must copy {@code value} if it will
|
||||
* not be processed prior to the return of this method call, since {@code value} may be
|
||||
* reused/altered by the caller.
|
||||
*
|
||||
* <p>NOTE: This method <strong>MUST NOT</strong> modify the {@code value}. Doing so is a
|
||||
* programming error and will lead to data corruption which will be difficult to debug.
|
||||
*
|
||||
* @param value the bytes to be written. Upon returning from this call, the {@code position} of
|
||||
* this buffer will be set to the {@code limit}
|
||||
* @throws IOException thrown if an error occurred while writing
|
||||
*/
|
||||
public abstract void write(ByteBuffer value) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes a sequence of bytes. The {@link ByteOutput} is free to retain a reference to the value
|
||||
* beyond the scope of this method call (e.g. write later) since it is considered immutable and is
|
||||
* guaranteed not to change by the caller.
|
||||
*
|
||||
* <p>NOTE: This method <strong>MUST NOT</strong> modify the {@code value}. Doing so is a
|
||||
* programming error and will lead to data corruption which will be difficult to debug.
|
||||
*
|
||||
* @param value the bytes to be written. Upon returning from this call, the {@code position} of
|
||||
* this buffer will be set to the {@code limit}
|
||||
* @throws IOException thrown if an error occurred while writing
|
||||
*/
|
||||
public abstract void writeLazy(ByteBuffer value) throws IOException;
|
||||
}
|
@ -1,4 +1,32 @@
|
||||
// Copyright 2007 Google Inc. All rights reserved.
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// 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.
|
||||
|
||||
package com.google.protobuf;
|
||||
|
||||
@ -15,6 +43,7 @@ import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.UnsupportedCharsetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
@ -58,6 +87,54 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
|
||||
* Empty {@code ByteString}.
|
||||
*/
|
||||
public static final ByteString EMPTY = new LiteralByteString(Internal.EMPTY_BYTE_ARRAY);
|
||||
|
||||
/**
|
||||
* An interface to efficiently copy {@code byte[]}.
|
||||
*
|
||||
* <p>One of the noticable costs of copying a byte[] into a new array using
|
||||
* {@code System.arraycopy} is nullification of a new buffer before the copy. It has been shown
|
||||
* the Hotspot VM is capable to intrisicfy {@code Arrays.copyOfRange} operation to avoid this
|
||||
* expensive nullification and provide substantial performance gain. Unfortunately this does not
|
||||
* hold on Android runtimes and could make the copy slightly slower due to additional code in
|
||||
* the {@code Arrays.copyOfRange}. Thus we provide two different implementation for array copier
|
||||
* for Hotspot and Android runtimes.
|
||||
*/
|
||||
private interface ByteArrayCopier {
|
||||
/**
|
||||
* Copies the specified range of the specified array into a new array
|
||||
*/
|
||||
byte[] copyFrom(byte[] bytes, int offset, int size);
|
||||
}
|
||||
|
||||
/** Implementation of {@code ByteArrayCopier} which uses {@link System#arraycopy}. */
|
||||
private static final class SystemByteArrayCopier implements ByteArrayCopier {
|
||||
@Override
|
||||
public byte[] copyFrom(byte[] bytes, int offset, int size) {
|
||||
byte[] copy = new byte[size];
|
||||
System.arraycopy(bytes, offset, copy, 0, size);
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
|
||||
/** Implementation of {@code ByteArrayCopier} which uses {@link Arrays#copyOfRange}. */
|
||||
private static final class ArraysByteArrayCopier implements ByteArrayCopier {
|
||||
@Override
|
||||
public byte[] copyFrom(byte[] bytes, int offset, int size) {
|
||||
return Arrays.copyOfRange(bytes, offset, offset + size);
|
||||
}
|
||||
}
|
||||
|
||||
private static final ByteArrayCopier byteArrayCopier;
|
||||
static {
|
||||
boolean isAndroid = true;
|
||||
try {
|
||||
Class.forName("android.content.Context");
|
||||
} catch (ClassNotFoundException e) {
|
||||
isAndroid = false;
|
||||
}
|
||||
|
||||
byteArrayCopier = isAndroid ? new SystemByteArrayCopier() : new ArraysByteArrayCopier();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cached hash value. Intentionally accessed via a data race, which
|
||||
@ -77,7 +154,7 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
|
||||
*
|
||||
* @param index index of byte
|
||||
* @return the value
|
||||
* @throws ArrayIndexOutOfBoundsException {@code index < 0 or index >= size}
|
||||
* @throws IndexOutOfBoundsException {@code index < 0 or index >= size}
|
||||
*/
|
||||
public abstract byte byteAt(int index);
|
||||
|
||||
@ -109,7 +186,7 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
|
||||
public byte nextByte() {
|
||||
try {
|
||||
return byteAt(position++);
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
throw new NoSuchElementException(e.getMessage());
|
||||
}
|
||||
}
|
||||
@ -220,9 +297,7 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
|
||||
* @return new {@code ByteString}
|
||||
*/
|
||||
public static ByteString copyFrom(byte[] bytes, int offset, int size) {
|
||||
byte[] copy = new byte[size];
|
||||
System.arraycopy(bytes, offset, copy, 0, size);
|
||||
return new LiteralByteString(copy);
|
||||
return new LiteralByteString(byteArrayCopier.copyFrom(bytes, offset, size));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -559,12 +634,7 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the complete contents of this byte string to
|
||||
* the specified output stream argument.
|
||||
*
|
||||
* <p>It is assumed that the {@link OutputStream} will not modify the contents passed it
|
||||
* it. It may be possible for a malicious {@link OutputStream} to corrupt
|
||||
* the data underlying the {@link ByteString}.
|
||||
* Writes a copy of the contents of this byte string to the specified output stream argument.
|
||||
*
|
||||
* @param out the output stream to which to write the data.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
@ -578,8 +648,7 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
|
||||
* @param sourceOffset offset within these bytes
|
||||
* @param numberToWrite number of bytes to write
|
||||
* @throws IOException if an I/O error occurs.
|
||||
* @throws IndexOutOfBoundsException if an offset or size is negative or too
|
||||
* large
|
||||
* @throws IndexOutOfBoundsException if an offset or size is negative or too large
|
||||
*/
|
||||
final void writeTo(OutputStream out, int sourceOffset, int numberToWrite)
|
||||
throws IOException {
|
||||
@ -596,6 +665,20 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
|
||||
abstract void writeToInternal(OutputStream out, int sourceOffset, int numberToWrite)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Writes this {@link ByteString} to the provided {@link ByteOutput}. Calling
|
||||
* this method may result in multiple operations on the target {@link ByteOutput}.
|
||||
*
|
||||
* <p>This method may expose internal backing buffers of the {@link ByteString} to the {@link
|
||||
* ByteOutput} in order to avoid additional copying overhead. It would be possible for a malicious
|
||||
* {@link ByteOutput} to corrupt the {@link ByteString}. Use with caution!
|
||||
*
|
||||
* @param byteOutput the output target to receive the bytes
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @see UnsafeByteOperations#unsafeWriteTo(ByteString, ByteOutput)
|
||||
*/
|
||||
abstract void writeTo(ByteOutput byteOutput) throws IOException;
|
||||
|
||||
/**
|
||||
* Constructs a read-only {@code java.nio.ByteBuffer} whose content
|
||||
* is equal to the contents of this byte string.
|
||||
@ -1102,7 +1185,7 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
|
||||
*
|
||||
* @param index the index position to be tested
|
||||
* @param size the length of the array
|
||||
* @throws ArrayIndexOutOfBoundsException if the index does not fall within the array.
|
||||
* @throws IndexOutOfBoundsException if the index does not fall within the array.
|
||||
*/
|
||||
static void checkIndex(int index, int size) {
|
||||
if ((index | (size - (index + 1))) < 0) {
|
||||
@ -1120,7 +1203,7 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
|
||||
* @param endIndex the end index of the range (exclusive)
|
||||
* @param size the size of the array.
|
||||
* @return the length of the range.
|
||||
* @throws ArrayIndexOutOfBoundsException some or all of the range falls outside of the array.
|
||||
* @throws IndexOutOfBoundsException some or all of the range falls outside of the array.
|
||||
*/
|
||||
static int checkRange(int startIndex, int endIndex, int size) {
|
||||
final int length = endIndex - startIndex;
|
||||
@ -1235,6 +1318,11 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
|
||||
outputStream.write(bytes, getOffsetIntoBytes() + sourceOffset, numberToWrite);
|
||||
}
|
||||
|
||||
@Override
|
||||
final void writeTo(ByteOutput output) throws IOException {
|
||||
output.writeLazy(bytes, getOffsetIntoBytes(), size());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final String toStringInternal(Charset charset) {
|
||||
return new String(bytes, getOffsetIntoBytes(), size(), charset);
|
||||
|
@ -55,7 +55,14 @@ public final class CodedInputStream {
|
||||
* Create a new CodedInputStream wrapping the given InputStream.
|
||||
*/
|
||||
public static CodedInputStream newInstance(final InputStream input) {
|
||||
return new CodedInputStream(input);
|
||||
return new CodedInputStream(input, BUFFER_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new CodedInputStream wrapping the given InputStream.
|
||||
*/
|
||||
static CodedInputStream newInstance(final InputStream input, int bufferSize) {
|
||||
return new CodedInputStream(input, bufferSize);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -70,14 +77,14 @@ public final class CodedInputStream {
|
||||
*/
|
||||
public static CodedInputStream newInstance(final byte[] buf, final int off,
|
||||
final int len) {
|
||||
return newInstance(buf, off, len, false);
|
||||
return newInstance(buf, off, len, false /* bufferIsImmutable */);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new CodedInputStream wrapping the given byte array slice.
|
||||
*/
|
||||
public static CodedInputStream newInstance(final byte[] buf, final int off,
|
||||
final int len, boolean bufferIsImmutable) {
|
||||
static CodedInputStream newInstance(
|
||||
final byte[] buf, final int off, final int len, final boolean bufferIsImmutable) {
|
||||
CodedInputStream result = new CodedInputStream(buf, off, len, bufferIsImmutable);
|
||||
try {
|
||||
// Some uses of CodedInputStream can be more efficient if they know
|
||||
@ -361,6 +368,11 @@ public final class CodedInputStream {
|
||||
return result;
|
||||
} else if (size == 0) {
|
||||
return "";
|
||||
} else if (size <= bufferSize) {
|
||||
refillBuffer(size);
|
||||
String result = new String(buffer, bufferPos, size, Internal.UTF_8);
|
||||
bufferPos += size;
|
||||
return result;
|
||||
} else {
|
||||
// Slow path: Build a byte array first then copy it.
|
||||
return new String(readRawBytesSlowPath(size), Internal.UTF_8);
|
||||
@ -375,14 +387,21 @@ public final class CodedInputStream {
|
||||
public String readStringRequireUtf8() throws IOException {
|
||||
final int size = readRawVarint32();
|
||||
final byte[] bytes;
|
||||
int pos = bufferPos;
|
||||
if (size <= (bufferSize - pos) && size > 0) {
|
||||
final int oldPos = bufferPos;
|
||||
final int pos;
|
||||
if (size <= (bufferSize - oldPos) && size > 0) {
|
||||
// Fast path: We already have the bytes in a contiguous buffer, so
|
||||
// just copy directly from it.
|
||||
bytes = buffer;
|
||||
bufferPos = pos + size;
|
||||
bufferPos = oldPos + size;
|
||||
pos = oldPos;
|
||||
} else if (size == 0) {
|
||||
return "";
|
||||
} else if (size <= bufferSize) {
|
||||
refillBuffer(size);
|
||||
bytes = buffer;
|
||||
pos = 0;
|
||||
bufferPos = pos + size;
|
||||
} else {
|
||||
// Slow path: Build a byte array first then copy it.
|
||||
bytes = readRawBytesSlowPath(size);
|
||||
@ -869,7 +888,8 @@ public final class CodedInputStream {
|
||||
private static final int DEFAULT_SIZE_LIMIT = 64 << 20; // 64MB
|
||||
private static final int BUFFER_SIZE = 4096;
|
||||
|
||||
private CodedInputStream(final byte[] buffer, final int off, final int len, boolean bufferIsImmutable) {
|
||||
private CodedInputStream(
|
||||
final byte[] buffer, final int off, final int len, boolean bufferIsImmutable) {
|
||||
this.buffer = buffer;
|
||||
bufferSize = off + len;
|
||||
bufferPos = off;
|
||||
@ -878,8 +898,8 @@ public final class CodedInputStream {
|
||||
this.bufferIsImmutable = bufferIsImmutable;
|
||||
}
|
||||
|
||||
private CodedInputStream(final InputStream input) {
|
||||
buffer = new byte[BUFFER_SIZE];
|
||||
private CodedInputStream(final InputStream input, int bufferSize) {
|
||||
buffer = new byte[bufferSize];
|
||||
bufferSize = 0;
|
||||
bufferPos = 0;
|
||||
totalBytesRetired = 0;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -74,16 +74,28 @@ public final class Descriptors {
|
||||
*/
|
||||
public static final class FileDescriptor extends GenericDescriptor {
|
||||
/** Convert the descriptor to its protocol message representation. */
|
||||
public FileDescriptorProto toProto() { return proto; }
|
||||
@Override
|
||||
public FileDescriptorProto toProto() {
|
||||
return proto;
|
||||
}
|
||||
|
||||
/** Get the file name. */
|
||||
public String getName() { return proto.getName(); }
|
||||
@Override
|
||||
public String getName() {
|
||||
return proto.getName();
|
||||
}
|
||||
|
||||
/** Returns this object. */
|
||||
public FileDescriptor getFile() { return this; }
|
||||
@Override
|
||||
public FileDescriptor getFile() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Returns the same as getName(). */
|
||||
public String getFullName() { return proto.getName(); }
|
||||
@Override
|
||||
public String getFullName() {
|
||||
return proto.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the proto package name. This is the package name given by the
|
||||
@ -272,7 +284,7 @@ public final class Descriptors {
|
||||
* because a field has an undefined type or because two messages
|
||||
* were defined with the same name.
|
||||
*/
|
||||
private static FileDescriptor buildFrom(
|
||||
public static FileDescriptor buildFrom(
|
||||
final FileDescriptorProto proto, final FileDescriptor[] dependencies,
|
||||
final boolean allowUnknownDependencies)
|
||||
throws DescriptorValidationException {
|
||||
@ -582,10 +594,16 @@ public final class Descriptors {
|
||||
public int getIndex() { return index; }
|
||||
|
||||
/** Convert the descriptor to its protocol message representation. */
|
||||
public DescriptorProto toProto() { return proto; }
|
||||
@Override
|
||||
public DescriptorProto toProto() {
|
||||
return proto;
|
||||
}
|
||||
|
||||
/** Get the type's unqualified name. */
|
||||
public String getName() { return proto.getName(); }
|
||||
@Override
|
||||
public String getName() {
|
||||
return proto.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type's fully-qualified name, within the proto language's
|
||||
@ -598,10 +616,16 @@ public final class Descriptors {
|
||||
* </pre>
|
||||
* {@code Baz}'s full name is "foo.bar.Baz".
|
||||
*/
|
||||
public String getFullName() { return fullName; }
|
||||
@Override
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
/** Get the {@link FileDescriptor} containing this descriptor. */
|
||||
public FileDescriptor getFile() { return file; }
|
||||
@Override
|
||||
public FileDescriptor getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
/** If this is a nested type, get the outer descriptor, otherwise null. */
|
||||
public Descriptor getContainingType() { return containingType; }
|
||||
@ -875,19 +899,31 @@ public final class Descriptors {
|
||||
public int getIndex() { return index; }
|
||||
|
||||
/** Convert the descriptor to its protocol message representation. */
|
||||
public FieldDescriptorProto toProto() { return proto; }
|
||||
@Override
|
||||
public FieldDescriptorProto toProto() {
|
||||
return proto;
|
||||
}
|
||||
|
||||
/** Get the field's unqualified name. */
|
||||
public String getName() { return proto.getName(); }
|
||||
@Override
|
||||
public String getName() {
|
||||
return proto.getName();
|
||||
}
|
||||
|
||||
/** Get the field's number. */
|
||||
public int getNumber() { return proto.getNumber(); }
|
||||
@Override
|
||||
public int getNumber() {
|
||||
return proto.getNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the field's fully-qualified name.
|
||||
* @see Descriptors.Descriptor#getFullName()
|
||||
*/
|
||||
public String getFullName() { return fullName; }
|
||||
@Override
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
/** Get the JSON name of this field. */
|
||||
public String getJsonName() {
|
||||
@ -901,17 +937,22 @@ public final class Descriptors {
|
||||
public JavaType getJavaType() { return type.getJavaType(); }
|
||||
|
||||
/** For internal use only. */
|
||||
@Override
|
||||
public WireFormat.JavaType getLiteJavaType() {
|
||||
return getLiteType().getJavaType();
|
||||
}
|
||||
|
||||
/** Get the {@code FileDescriptor} containing this descriptor. */
|
||||
public FileDescriptor getFile() { return file; }
|
||||
@Override
|
||||
public FileDescriptor getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
/** Get the field's declared type. */
|
||||
public Type getType() { return type; }
|
||||
|
||||
/** For internal use only. */
|
||||
@Override
|
||||
public WireFormat.FieldType getLiteType() {
|
||||
return table[type.ordinal()];
|
||||
}
|
||||
@ -953,6 +994,7 @@ public final class Descriptors {
|
||||
}
|
||||
|
||||
/** Is this field declared repeated? */
|
||||
@Override
|
||||
public boolean isRepeated() {
|
||||
return proto.getLabel() == FieldDescriptorProto.Label.LABEL_REPEATED;
|
||||
}
|
||||
@ -960,6 +1002,7 @@ public final class Descriptors {
|
||||
/** Does this field have the {@code [packed = true]} option or is this field
|
||||
* packable in proto3 and not explicitly setted to unpacked?
|
||||
*/
|
||||
@Override
|
||||
public boolean isPacked() {
|
||||
if (!isPackable()) {
|
||||
return false;
|
||||
@ -1048,6 +1091,7 @@ public final class Descriptors {
|
||||
}
|
||||
|
||||
/** For enum fields, gets the field's type. */
|
||||
@Override
|
||||
public EnumDescriptor getEnumType() {
|
||||
if (getJavaType() != JavaType.ENUM) {
|
||||
throw new UnsupportedOperationException(
|
||||
@ -1066,6 +1110,7 @@ public final class Descriptors {
|
||||
* @return negative, zero, or positive if {@code this} is less than,
|
||||
* equal to, or greater than {@code other}, respectively.
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(final FieldDescriptor other) {
|
||||
if (other.containingType != containingType) {
|
||||
throw new IllegalArgumentException(
|
||||
@ -1123,7 +1168,7 @@ public final class Descriptors {
|
||||
private JavaType javaType;
|
||||
|
||||
public FieldDescriptorProto.Type toProto() {
|
||||
return FieldDescriptorProto.Type.valueOf(ordinal() + 1);
|
||||
return FieldDescriptorProto.Type.forNumber(ordinal() + 1);
|
||||
}
|
||||
public JavaType getJavaType() { return javaType; }
|
||||
|
||||
@ -1466,8 +1511,8 @@ public final class Descriptors {
|
||||
* For internal use only. This is to satisfy the FieldDescriptorLite
|
||||
* interface.
|
||||
*/
|
||||
public MessageLite.Builder internalMergeFrom(
|
||||
MessageLite.Builder to, MessageLite from) {
|
||||
@Override
|
||||
public MessageLite.Builder internalMergeFrom(MessageLite.Builder to, MessageLite from) {
|
||||
// FieldDescriptors are only used with non-lite messages so we can just
|
||||
// down-cast and call mergeFrom directly.
|
||||
return ((Message.Builder) to).mergeFrom((Message) from);
|
||||
@ -1487,19 +1532,31 @@ public final class Descriptors {
|
||||
public int getIndex() { return index; }
|
||||
|
||||
/** Convert the descriptor to its protocol message representation. */
|
||||
public EnumDescriptorProto toProto() { return proto; }
|
||||
@Override
|
||||
public EnumDescriptorProto toProto() {
|
||||
return proto;
|
||||
}
|
||||
|
||||
/** Get the type's unqualified name. */
|
||||
public String getName() { return proto.getName(); }
|
||||
@Override
|
||||
public String getName() {
|
||||
return proto.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type's fully-qualified name.
|
||||
* @see Descriptors.Descriptor#getFullName()
|
||||
*/
|
||||
public String getFullName() { return fullName; }
|
||||
@Override
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
/** Get the {@link FileDescriptor} containing this descriptor. */
|
||||
public FileDescriptor getFile() { return file; }
|
||||
@Override
|
||||
public FileDescriptor getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
/** If this is a nested type, get the outer descriptor, otherwise null. */
|
||||
public Descriptor getContainingType() { return containingType; }
|
||||
@ -1533,6 +1590,7 @@ public final class Descriptors {
|
||||
* @param number The value's number.
|
||||
* @return the value's descriptor, or {@code null} if not found.
|
||||
*/
|
||||
@Override
|
||||
public EnumValueDescriptor findValueByNumber(final int number) {
|
||||
return file.pool.enumValuesByNumber.get(
|
||||
new DescriptorPool.DescriptorIntPair(this, number));
|
||||
@ -1659,13 +1717,22 @@ public final class Descriptors {
|
||||
public int getIndex() { return index; }
|
||||
|
||||
/** Convert the descriptor to its protocol message representation. */
|
||||
public EnumValueDescriptorProto toProto() { return proto; }
|
||||
@Override
|
||||
public EnumValueDescriptorProto toProto() {
|
||||
return proto;
|
||||
}
|
||||
|
||||
/** Get the value's unqualified name. */
|
||||
public String getName() { return proto.getName(); }
|
||||
@Override
|
||||
public String getName() {
|
||||
return proto.getName();
|
||||
}
|
||||
|
||||
/** Get the value's number. */
|
||||
public int getNumber() { return proto.getNumber(); }
|
||||
@Override
|
||||
public int getNumber() {
|
||||
return proto.getNumber();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() { return proto.getName(); }
|
||||
@ -1674,10 +1741,16 @@ public final class Descriptors {
|
||||
* Get the value's fully-qualified name.
|
||||
* @see Descriptors.Descriptor#getFullName()
|
||||
*/
|
||||
public String getFullName() { return fullName; }
|
||||
@Override
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
/** Get the {@link FileDescriptor} containing this descriptor. */
|
||||
public FileDescriptor getFile() { return file; }
|
||||
@Override
|
||||
public FileDescriptor getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
/** Get the value's enum type. */
|
||||
public EnumDescriptor getType() { return type; }
|
||||
@ -1745,19 +1818,31 @@ public final class Descriptors {
|
||||
public int getIndex() { return index; }
|
||||
|
||||
/** Convert the descriptor to its protocol message representation. */
|
||||
public ServiceDescriptorProto toProto() { return proto; }
|
||||
@Override
|
||||
public ServiceDescriptorProto toProto() {
|
||||
return proto;
|
||||
}
|
||||
|
||||
/** Get the type's unqualified name. */
|
||||
public String getName() { return proto.getName(); }
|
||||
@Override
|
||||
public String getName() {
|
||||
return proto.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type's fully-qualified name.
|
||||
* @see Descriptors.Descriptor#getFullName()
|
||||
*/
|
||||
public String getFullName() { return fullName; }
|
||||
@Override
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
/** Get the {@link FileDescriptor} containing this descriptor. */
|
||||
public FileDescriptor getFile() { return file; }
|
||||
@Override
|
||||
public FileDescriptor getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
/** Get the {@code ServiceOptions}, defined in {@code descriptor.proto}. */
|
||||
public ServiceOptions getOptions() { return proto.getOptions(); }
|
||||
@ -1835,19 +1920,31 @@ public final class Descriptors {
|
||||
public int getIndex() { return index; }
|
||||
|
||||
/** Convert the descriptor to its protocol message representation. */
|
||||
public MethodDescriptorProto toProto() { return proto; }
|
||||
@Override
|
||||
public MethodDescriptorProto toProto() {
|
||||
return proto;
|
||||
}
|
||||
|
||||
/** Get the method's unqualified name. */
|
||||
public String getName() { return proto.getName(); }
|
||||
@Override
|
||||
public String getName() {
|
||||
return proto.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the method's fully-qualified name.
|
||||
* @see Descriptors.Descriptor#getFullName()
|
||||
*/
|
||||
public String getFullName() { return fullName; }
|
||||
@Override
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
/** Get the {@link FileDescriptor} containing this descriptor. */
|
||||
public FileDescriptor getFile() { return file; }
|
||||
@Override
|
||||
public FileDescriptor getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
/** Get the method's service type. */
|
||||
public ServiceDescriptor getService() { return service; }
|
||||
@ -2248,10 +2345,22 @@ public final class Descriptors {
|
||||
* that has the same name as an existing package.
|
||||
*/
|
||||
private static final class PackageDescriptor extends GenericDescriptor {
|
||||
public Message toProto() { return file.toProto(); }
|
||||
public String getName() { return name; }
|
||||
public String getFullName() { return fullName; }
|
||||
public FileDescriptor getFile() { return file; }
|
||||
@Override
|
||||
public Message toProto() {
|
||||
return file.toProto();
|
||||
}
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
@Override
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
@Override
|
||||
public FileDescriptor getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
PackageDescriptor(final String name, final String fullName,
|
||||
final FileDescriptor file) {
|
||||
|
@ -34,7 +34,6 @@ import com.google.protobuf.Internal.DoubleList;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.RandomAccess;
|
||||
|
||||
/**
|
||||
@ -45,8 +44,6 @@ import java.util.RandomAccess;
|
||||
final class DoubleArrayList
|
||||
extends AbstractProtobufList<Double> implements DoubleList, RandomAccess {
|
||||
|
||||
private static final int DEFAULT_CAPACITY = 10;
|
||||
|
||||
private static final DoubleArrayList EMPTY_LIST = new DoubleArrayList();
|
||||
static {
|
||||
EMPTY_LIST.makeImmutable();
|
||||
@ -71,32 +68,56 @@ final class DoubleArrayList
|
||||
* Constructs a new mutable {@code DoubleArrayList} with default capacity.
|
||||
*/
|
||||
DoubleArrayList() {
|
||||
this(DEFAULT_CAPACITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new mutable {@code DoubleArrayList} with the provided capacity.
|
||||
*/
|
||||
DoubleArrayList(int capacity) {
|
||||
array = new double[capacity];
|
||||
size = 0;
|
||||
this(new double[DEFAULT_CAPACITY], 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new mutable {@code DoubleArrayList} containing the same elements as {@code other}.
|
||||
*/
|
||||
DoubleArrayList(List<Double> other) {
|
||||
if (other instanceof DoubleArrayList) {
|
||||
DoubleArrayList list = (DoubleArrayList) other;
|
||||
array = list.array.clone();
|
||||
size = list.size;
|
||||
} else {
|
||||
size = other.size();
|
||||
array = new double[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
array[i] = other.get(i);
|
||||
private DoubleArrayList(double[] array, int size) {
|
||||
this.array = array;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof DoubleArrayList)) {
|
||||
return super.equals(o);
|
||||
}
|
||||
DoubleArrayList other = (DoubleArrayList) o;
|
||||
if (size != other.size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final double[] arr = other.array;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (array[i] != arr[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
for (int i = 0; i < size; i++) {
|
||||
long bits = Double.doubleToLongBits(array[i]);
|
||||
result = (31 * result) + Internal.hashLong(bits);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DoubleList mutableCopyWithCapacity(int capacity) {
|
||||
if (capacity < size) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return new DoubleArrayList(Arrays.copyOf(array, capacity), size);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -156,18 +156,22 @@ public final class DynamicMessage extends AbstractMessage {
|
||||
// -----------------------------------------------------------------
|
||||
// Implementation of Message interface.
|
||||
|
||||
@Override
|
||||
public Descriptor getDescriptorForType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DynamicMessage getDefaultInstanceForType() {
|
||||
return getDefaultInstance(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<FieldDescriptor, Object> getAllFields() {
|
||||
return fields.getAllFields();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasOneof(OneofDescriptor oneof) {
|
||||
verifyOneofContainingType(oneof);
|
||||
FieldDescriptor field = oneofCases[oneof.getIndex()];
|
||||
@ -177,16 +181,19 @@ public final class DynamicMessage extends AbstractMessage {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldDescriptor getOneofFieldDescriptor(OneofDescriptor oneof) {
|
||||
verifyOneofContainingType(oneof);
|
||||
return oneofCases[oneof.getIndex()];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasField(FieldDescriptor field) {
|
||||
verifyContainingType(field);
|
||||
return fields.hasField(field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getField(FieldDescriptor field) {
|
||||
verifyContainingType(field);
|
||||
Object result = fields.getField(field);
|
||||
@ -202,16 +209,19 @@ public final class DynamicMessage extends AbstractMessage {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRepeatedFieldCount(FieldDescriptor field) {
|
||||
verifyContainingType(field);
|
||||
return fields.getRepeatedFieldCount(field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getRepeatedField(FieldDescriptor field, int index) {
|
||||
verifyContainingType(field);
|
||||
return fields.getRepeatedField(field, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnknownFieldSet getUnknownFields() {
|
||||
return unknownFields;
|
||||
}
|
||||
@ -264,19 +274,22 @@ public final class DynamicMessage extends AbstractMessage {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder newBuilderForType() {
|
||||
return new Builder(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder toBuilder() {
|
||||
return newBuilderForType().mergeFrom(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Parser<DynamicMessage> getParserForType() {
|
||||
return new AbstractParser<DynamicMessage>() {
|
||||
@Override
|
||||
public DynamicMessage parsePartialFrom(
|
||||
CodedInputStream input,
|
||||
ExtensionRegistryLite extensionRegistry)
|
||||
CodedInputStream input, ExtensionRegistryLite extensionRegistry)
|
||||
throws InvalidProtocolBufferException {
|
||||
Builder builder = newBuilder(type);
|
||||
try {
|
||||
@ -370,6 +383,7 @@ public final class DynamicMessage extends AbstractMessage {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DynamicMessage build() {
|
||||
if (!isInitialized()) {
|
||||
throw newUninitializedMessageException(
|
||||
@ -394,6 +408,7 @@ public final class DynamicMessage extends AbstractMessage {
|
||||
return buildPartial();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DynamicMessage buildPartial() {
|
||||
fields.makeImmutable();
|
||||
DynamicMessage result =
|
||||
@ -411,22 +426,27 @@ public final class DynamicMessage extends AbstractMessage {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInitialized() {
|
||||
return DynamicMessage.isInitialized(type, fields);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Descriptor getDescriptorForType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DynamicMessage getDefaultInstanceForType() {
|
||||
return getDefaultInstance(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<FieldDescriptor, Object> getAllFields() {
|
||||
return fields.getAllFields();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder newBuilderForField(FieldDescriptor field) {
|
||||
verifyContainingType(field);
|
||||
|
||||
@ -438,6 +458,7 @@ public final class DynamicMessage extends AbstractMessage {
|
||||
return new Builder(field.getMessageType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasOneof(OneofDescriptor oneof) {
|
||||
verifyOneofContainingType(oneof);
|
||||
FieldDescriptor field = oneofCases[oneof.getIndex()];
|
||||
@ -447,11 +468,13 @@ public final class DynamicMessage extends AbstractMessage {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldDescriptor getOneofFieldDescriptor(OneofDescriptor oneof) {
|
||||
verifyOneofContainingType(oneof);
|
||||
return oneofCases[oneof.getIndex()];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder clearOneof(OneofDescriptor oneof) {
|
||||
verifyOneofContainingType(oneof);
|
||||
FieldDescriptor field = oneofCases[oneof.getIndex()];
|
||||
@ -461,11 +484,13 @@ public final class DynamicMessage extends AbstractMessage {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasField(FieldDescriptor field) {
|
||||
verifyContainingType(field);
|
||||
return fields.hasField(field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getField(FieldDescriptor field) {
|
||||
verifyContainingType(field);
|
||||
Object result = fields.getField(field);
|
||||
@ -481,6 +506,7 @@ public final class DynamicMessage extends AbstractMessage {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder setField(FieldDescriptor field, Object value) {
|
||||
verifyContainingType(field);
|
||||
ensureIsMutable();
|
||||
@ -505,6 +531,7 @@ public final class DynamicMessage extends AbstractMessage {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder clearField(FieldDescriptor field) {
|
||||
verifyContainingType(field);
|
||||
ensureIsMutable();
|
||||
@ -519,24 +546,27 @@ public final class DynamicMessage extends AbstractMessage {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRepeatedFieldCount(FieldDescriptor field) {
|
||||
verifyContainingType(field);
|
||||
return fields.getRepeatedFieldCount(field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getRepeatedField(FieldDescriptor field, int index) {
|
||||
verifyContainingType(field);
|
||||
return fields.getRepeatedField(field, index);
|
||||
}
|
||||
|
||||
public Builder setRepeatedField(FieldDescriptor field,
|
||||
int index, Object value) {
|
||||
@Override
|
||||
public Builder setRepeatedField(FieldDescriptor field, int index, Object value) {
|
||||
verifyContainingType(field);
|
||||
ensureIsMutable();
|
||||
fields.setRepeatedField(field, index, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder addRepeatedField(FieldDescriptor field, Object value) {
|
||||
verifyContainingType(field);
|
||||
ensureIsMutable();
|
||||
@ -544,10 +574,12 @@ public final class DynamicMessage extends AbstractMessage {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnknownFieldSet getUnknownFields() {
|
||||
return unknownFields;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder setUnknownFields(UnknownFieldSet unknownFields) {
|
||||
if (getDescriptorForType().getFile().getSyntax()
|
||||
== Descriptors.FileDescriptor.Syntax.PROTO3) {
|
||||
|
@ -1,3 +1,33 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// 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.
|
||||
|
||||
package com.google.protobuf;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
|
@ -42,6 +42,7 @@ public abstract class Extension<ContainingType extends MessageLite, Type>
|
||||
public abstract Descriptors.FieldDescriptor getDescriptor();
|
||||
|
||||
/** Returns whether or not this extension is a Lite Extension. */
|
||||
@Override
|
||||
final boolean isLite() {
|
||||
return false;
|
||||
}
|
||||
|
@ -120,6 +120,25 @@ final class FieldSet<FieldDescriptorType extends
|
||||
public boolean isImmutable() {
|
||||
return isImmutable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof FieldSet)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FieldSet<?> other = (FieldSet<?>) o;
|
||||
return other.fields.equals(other.fields);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return fields.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones the FieldSet. The returned FieldSet will be mutable even if the
|
||||
|
@ -34,7 +34,6 @@ import com.google.protobuf.Internal.FloatList;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.RandomAccess;
|
||||
|
||||
/**
|
||||
@ -44,8 +43,6 @@ import java.util.RandomAccess;
|
||||
*/
|
||||
final class FloatArrayList extends AbstractProtobufList<Float> implements FloatList, RandomAccess {
|
||||
|
||||
private static final int DEFAULT_CAPACITY = 10;
|
||||
|
||||
private static final FloatArrayList EMPTY_LIST = new FloatArrayList();
|
||||
static {
|
||||
EMPTY_LIST.makeImmutable();
|
||||
@ -70,32 +67,55 @@ final class FloatArrayList extends AbstractProtobufList<Float> implements FloatL
|
||||
* Constructs a new mutable {@code FloatArrayList} with default capacity.
|
||||
*/
|
||||
FloatArrayList() {
|
||||
this(DEFAULT_CAPACITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new mutable {@code FloatArrayList} with the provided capacity.
|
||||
*/
|
||||
FloatArrayList(int capacity) {
|
||||
array = new float[capacity];
|
||||
size = 0;
|
||||
this(new float[DEFAULT_CAPACITY], 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new mutable {@code FloatArrayList} containing the same elements as {@code other}.
|
||||
*/
|
||||
FloatArrayList(List<Float> other) {
|
||||
if (other instanceof FloatArrayList) {
|
||||
FloatArrayList list = (FloatArrayList) other;
|
||||
array = list.array.clone();
|
||||
size = list.size;
|
||||
} else {
|
||||
size = other.size();
|
||||
array = new float[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
array[i] = other.get(i);
|
||||
private FloatArrayList(float[] array, int size) {
|
||||
this.array = array;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof FloatArrayList)) {
|
||||
return super.equals(o);
|
||||
}
|
||||
FloatArrayList other = (FloatArrayList) o;
|
||||
if (size != other.size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final float[] arr = other.array;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (array[i] != arr[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
for (int i = 0; i < size; i++) {
|
||||
result = (31 * result) + Float.floatToIntBits(array[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FloatList mutableCopyWithCapacity(int capacity) {
|
||||
if (capacity < size) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return new FloatArrayList(Arrays.copyOf(array, capacity), size);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -80,6 +80,7 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
unknownFields = builder.getUnknownFields();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Parser<? extends GeneratedMessage> getParserForType() {
|
||||
throw new UnsupportedOperationException(
|
||||
"This is supposed to be overridden by subclasses.");
|
||||
@ -102,7 +103,7 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
*/
|
||||
protected abstract FieldAccessorTable internalGetFieldAccessorTable();
|
||||
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
public Descriptor getDescriptorForType() {
|
||||
return internalGetFieldAccessorTable().descriptor;
|
||||
}
|
||||
@ -191,7 +192,7 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
return true;
|
||||
}
|
||||
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
public Map<FieldDescriptor, Object> getAllFields() {
|
||||
return Collections.unmodifiableMap(
|
||||
getAllFieldsMutable(/* getBytesForString = */ false));
|
||||
@ -212,22 +213,22 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
getAllFieldsMutable(/* getBytesForString = */ true));
|
||||
}
|
||||
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
public boolean hasOneof(final OneofDescriptor oneof) {
|
||||
return internalGetFieldAccessorTable().getOneof(oneof).has(this);
|
||||
}
|
||||
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
public FieldDescriptor getOneofFieldDescriptor(final OneofDescriptor oneof) {
|
||||
return internalGetFieldAccessorTable().getOneof(oneof).get(this);
|
||||
}
|
||||
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
public boolean hasField(final FieldDescriptor field) {
|
||||
return internalGetFieldAccessorTable().getField(field).has(this);
|
||||
}
|
||||
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
public Object getField(final FieldDescriptor field) {
|
||||
return internalGetFieldAccessorTable().getField(field).get(this);
|
||||
}
|
||||
@ -244,19 +245,19 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
return internalGetFieldAccessorTable().getField(field).getRaw(this);
|
||||
}
|
||||
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
public int getRepeatedFieldCount(final FieldDescriptor field) {
|
||||
return internalGetFieldAccessorTable().getField(field)
|
||||
.getRepeatedCount(this);
|
||||
}
|
||||
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
public Object getRepeatedField(final FieldDescriptor field, final int index) {
|
||||
return internalGetFieldAccessorTable().getField(field)
|
||||
.getRepeated(this, index);
|
||||
}
|
||||
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
public UnknownFieldSet getUnknownFields() {
|
||||
throw new UnsupportedOperationException(
|
||||
"This is supposed to be overridden by subclasses.");
|
||||
@ -380,7 +381,7 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public abstract static class Builder <BuilderType extends Builder>
|
||||
public abstract static class Builder <BuilderType extends Builder<BuilderType>>
|
||||
extends AbstractMessage.Builder<BuilderType> {
|
||||
|
||||
private BuilderParent builderParent;
|
||||
@ -444,6 +445,7 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
* Called by the initialization and clear code paths to allow subclasses to
|
||||
* reset any of their builtin fields back to the initial values.
|
||||
*/
|
||||
@Override
|
||||
public BuilderType clear() {
|
||||
unknownFields = UnknownFieldSet.getDefaultInstance();
|
||||
onChanged();
|
||||
@ -457,12 +459,12 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
*/
|
||||
protected abstract FieldAccessorTable internalGetFieldAccessorTable();
|
||||
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
public Descriptor getDescriptorForType() {
|
||||
return internalGetFieldAccessorTable().descriptor;
|
||||
}
|
||||
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
public Map<FieldDescriptor, Object> getAllFields() {
|
||||
return Collections.unmodifiableMap(getAllFieldsMutable());
|
||||
}
|
||||
@ -510,39 +512,38 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
return result;
|
||||
}
|
||||
|
||||
public Message.Builder newBuilderForField(
|
||||
final FieldDescriptor field) {
|
||||
@Override
|
||||
public Message.Builder newBuilderForField(final FieldDescriptor field) {
|
||||
return internalGetFieldAccessorTable().getField(field).newBuilder();
|
||||
}
|
||||
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
public Message.Builder getFieldBuilder(final FieldDescriptor field) {
|
||||
return internalGetFieldAccessorTable().getField(field).getBuilder(this);
|
||||
}
|
||||
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
public Message.Builder getRepeatedFieldBuilder(final FieldDescriptor field,
|
||||
int index) {
|
||||
@Override
|
||||
public Message.Builder getRepeatedFieldBuilder(final FieldDescriptor field, int index) {
|
||||
return internalGetFieldAccessorTable().getField(field).getRepeatedBuilder(
|
||||
this, index);
|
||||
}
|
||||
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
public boolean hasOneof(final OneofDescriptor oneof) {
|
||||
return internalGetFieldAccessorTable().getOneof(oneof).has(this);
|
||||
}
|
||||
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
public FieldDescriptor getOneofFieldDescriptor(final OneofDescriptor oneof) {
|
||||
return internalGetFieldAccessorTable().getOneof(oneof).get(this);
|
||||
}
|
||||
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
public boolean hasField(final FieldDescriptor field) {
|
||||
return internalGetFieldAccessorTable().getField(field).has(this);
|
||||
}
|
||||
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
public Object getField(final FieldDescriptor field) {
|
||||
Object object = internalGetFieldAccessorTable().getField(field).get(this);
|
||||
if (field.isRepeated()) {
|
||||
@ -554,52 +555,52 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
}
|
||||
}
|
||||
|
||||
public BuilderType setField(final FieldDescriptor field,
|
||||
final Object value) {
|
||||
@Override
|
||||
public BuilderType setField(final FieldDescriptor field, final Object value) {
|
||||
internalGetFieldAccessorTable().getField(field).set(this, value);
|
||||
return (BuilderType) this;
|
||||
}
|
||||
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
public BuilderType clearField(final FieldDescriptor field) {
|
||||
internalGetFieldAccessorTable().getField(field).clear(this);
|
||||
return (BuilderType) this;
|
||||
}
|
||||
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
public BuilderType clearOneof(final OneofDescriptor oneof) {
|
||||
internalGetFieldAccessorTable().getOneof(oneof).clear(this);
|
||||
return (BuilderType) this;
|
||||
}
|
||||
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
public int getRepeatedFieldCount(final FieldDescriptor field) {
|
||||
return internalGetFieldAccessorTable().getField(field)
|
||||
.getRepeatedCount(this);
|
||||
}
|
||||
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
public Object getRepeatedField(final FieldDescriptor field,
|
||||
final int index) {
|
||||
@Override
|
||||
public Object getRepeatedField(final FieldDescriptor field, final int index) {
|
||||
return internalGetFieldAccessorTable().getField(field)
|
||||
.getRepeated(this, index);
|
||||
}
|
||||
|
||||
public BuilderType setRepeatedField(final FieldDescriptor field,
|
||||
final int index, final Object value) {
|
||||
@Override
|
||||
public BuilderType setRepeatedField(
|
||||
final FieldDescriptor field, final int index, final Object value) {
|
||||
internalGetFieldAccessorTable().getField(field)
|
||||
.setRepeated(this, index, value);
|
||||
return (BuilderType) this;
|
||||
}
|
||||
|
||||
public BuilderType addRepeatedField(final FieldDescriptor field,
|
||||
final Object value) {
|
||||
@Override
|
||||
public BuilderType addRepeatedField(final FieldDescriptor field, final Object value) {
|
||||
internalGetFieldAccessorTable().getField(field).addRepeated(this, value);
|
||||
return (BuilderType) this;
|
||||
}
|
||||
|
||||
public BuilderType setUnknownFields(
|
||||
final UnknownFieldSet unknownFields) {
|
||||
@Override
|
||||
public BuilderType setUnknownFields(final UnknownFieldSet unknownFields) {
|
||||
this.unknownFields = unknownFields;
|
||||
onChanged();
|
||||
return (BuilderType) this;
|
||||
@ -616,7 +617,7 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
return (BuilderType) this;
|
||||
}
|
||||
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
public boolean isInitialized() {
|
||||
for (final FieldDescriptor field : getDescriptorForType().getFields()) {
|
||||
// Check that all required fields are present.
|
||||
@ -646,7 +647,7 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
return true;
|
||||
}
|
||||
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
public final UnknownFieldSet getUnknownFields() {
|
||||
return unknownFields;
|
||||
}
|
||||
@ -670,7 +671,7 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
*/
|
||||
private class BuilderParentImpl implements BuilderParent {
|
||||
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
public void markDirty() {
|
||||
onChanged();
|
||||
}
|
||||
@ -735,6 +736,7 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
public interface ExtendableMessageOrBuilder<
|
||||
MessageType extends ExtendableMessage> extends MessageOrBuilder {
|
||||
// Re-define for return type covariance.
|
||||
@Override
|
||||
Message getDefaultInstanceForType();
|
||||
|
||||
/** Check if a singular extension is present. */
|
||||
@ -795,6 +797,8 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
extends GeneratedMessage
|
||||
implements ExtendableMessageOrBuilder<MessageType> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final FieldSet<FieldDescriptor> extensions;
|
||||
|
||||
protected ExtendableMessage() {
|
||||
@ -821,9 +825,8 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
}
|
||||
|
||||
/** Check if a singular extension is present. */
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
public final <Type> boolean hasExtension(
|
||||
final ExtensionLite<MessageType, Type> extensionLite) {
|
||||
@Override
|
||||
public final <Type> boolean hasExtension(final ExtensionLite<MessageType, Type> extensionLite) {
|
||||
Extension<MessageType, Type> extension = checkNotLite(extensionLite);
|
||||
|
||||
verifyExtensionContainingType(extension);
|
||||
@ -831,7 +834,7 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
}
|
||||
|
||||
/** Get the number of elements in a repeated extension. */
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
public final <Type> int getExtensionCount(
|
||||
final ExtensionLite<MessageType, List<Type>> extensionLite) {
|
||||
Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
|
||||
@ -842,10 +845,9 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
}
|
||||
|
||||
/** Get the value of an extension. */
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public final <Type> Type getExtension(
|
||||
final ExtensionLite<MessageType, Type> extensionLite) {
|
||||
public final <Type> Type getExtension(final ExtensionLite<MessageType, Type> extensionLite) {
|
||||
Extension<MessageType, Type> extension = checkNotLite(extensionLite);
|
||||
|
||||
verifyExtensionContainingType(extension);
|
||||
@ -867,11 +869,10 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
}
|
||||
|
||||
/** Get one element of a repeated extension. */
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public final <Type> Type getExtension(
|
||||
final ExtensionLite<MessageType, List<Type>> extensionLite,
|
||||
final int index) {
|
||||
final ExtensionLite<MessageType, List<Type>> extensionLite, final int index) {
|
||||
Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
|
||||
|
||||
verifyExtensionContainingType(extension);
|
||||
@ -1019,7 +1020,9 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
verifyContainingType(field);
|
||||
final Object value = extensions.getField(field);
|
||||
if (value == null) {
|
||||
if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
|
||||
if (field.isRepeated()) {
|
||||
return Collections.emptyList();
|
||||
} else if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
|
||||
// Lacking an ExtensionRegistry, we have no way to determine the
|
||||
// extension's real type, so we return a DynamicMessage.
|
||||
return DynamicMessage.getDefaultInstance(field.getMessageType());
|
||||
@ -1103,7 +1106,7 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
@SuppressWarnings("unchecked")
|
||||
public abstract static class ExtendableBuilder<
|
||||
MessageType extends ExtendableMessage,
|
||||
BuilderType extends ExtendableBuilder>
|
||||
BuilderType extends ExtendableBuilder<MessageType, BuilderType>>
|
||||
extends Builder<BuilderType>
|
||||
implements ExtendableMessageOrBuilder<MessageType> {
|
||||
|
||||
@ -1155,9 +1158,8 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
}
|
||||
|
||||
/** Check if a singular extension is present. */
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
public final <Type> boolean hasExtension(
|
||||
final ExtensionLite<MessageType, Type> extensionLite) {
|
||||
@Override
|
||||
public final <Type> boolean hasExtension(final ExtensionLite<MessageType, Type> extensionLite) {
|
||||
Extension<MessageType, Type> extension = checkNotLite(extensionLite);
|
||||
|
||||
verifyExtensionContainingType(extension);
|
||||
@ -1165,7 +1167,7 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
}
|
||||
|
||||
/** Get the number of elements in a repeated extension. */
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
public final <Type> int getExtensionCount(
|
||||
final ExtensionLite<MessageType, List<Type>> extensionLite) {
|
||||
Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
|
||||
@ -1176,9 +1178,8 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
}
|
||||
|
||||
/** Get the value of an extension. */
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
public final <Type> Type getExtension(
|
||||
final ExtensionLite<MessageType, Type> extensionLite) {
|
||||
@Override
|
||||
public final <Type> Type getExtension(final ExtensionLite<MessageType, Type> extensionLite) {
|
||||
Extension<MessageType, Type> extension = checkNotLite(extensionLite);
|
||||
|
||||
verifyExtensionContainingType(extension);
|
||||
@ -1200,10 +1201,9 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
}
|
||||
|
||||
/** Get one element of a repeated extension. */
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
public final <Type> Type getExtension(
|
||||
final ExtensionLite<MessageType, List<Type>> extensionLite,
|
||||
final int index) {
|
||||
final ExtensionLite<MessageType, List<Type>> extensionLite, final int index) {
|
||||
Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
|
||||
|
||||
verifyExtensionContainingType(extension);
|
||||
@ -1456,10 +1456,9 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
// obtained.
|
||||
return new GeneratedExtension<ContainingType, Type>(
|
||||
new CachedDescriptorRetriever() {
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
public FieldDescriptor loadDescriptor() {
|
||||
return scope.getDescriptorForType().getExtensions()
|
||||
.get(descriptorIndex);
|
||||
return scope.getDescriptorForType().getExtensions().get(descriptorIndex);
|
||||
}
|
||||
},
|
||||
singularType,
|
||||
@ -1487,6 +1486,7 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
private volatile FieldDescriptor descriptor;
|
||||
protected abstract FieldDescriptor loadDescriptor();
|
||||
|
||||
@Override
|
||||
public FieldDescriptor getDescriptor() {
|
||||
if (descriptor == null) {
|
||||
synchronized (this) {
|
||||
@ -1516,6 +1516,7 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
// obtained.
|
||||
return new GeneratedExtension<ContainingType, Type>(
|
||||
new CachedDescriptorRetriever() {
|
||||
@Override
|
||||
protected FieldDescriptor loadDescriptor() {
|
||||
return scope.getDescriptorForType().findFieldByName(name);
|
||||
}
|
||||
@ -1542,17 +1543,18 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
// used to obtain the extension's FieldDescriptor.
|
||||
return new GeneratedExtension<ContainingType, Type>(
|
||||
new CachedDescriptorRetriever() {
|
||||
@Override
|
||||
protected FieldDescriptor loadDescriptor() {
|
||||
try {
|
||||
Class clazz =
|
||||
singularType.getClassLoader().loadClass(descriptorOuterClass);
|
||||
FileDescriptor file =
|
||||
(FileDescriptor) clazz.getField("descriptor").get(null);
|
||||
Class clazz = singularType.getClassLoader().loadClass(descriptorOuterClass);
|
||||
FileDescriptor file = (FileDescriptor) clazz.getField("descriptor").get(null);
|
||||
return file.findExtensionByName(extensionName);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(
|
||||
"Cannot load descriptors: " + descriptorOuterClass +
|
||||
" is not a valid descriptor class name", e);
|
||||
"Cannot load descriptors: "
|
||||
+ descriptorOuterClass
|
||||
+ " is not a valid descriptor class name",
|
||||
e);
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -1634,12 +1636,13 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
if (descriptorRetriever != null) {
|
||||
throw new IllegalStateException("Already initialized.");
|
||||
}
|
||||
descriptorRetriever = new ExtensionDescriptorRetriever() {
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
public FieldDescriptor getDescriptor() {
|
||||
return descriptor;
|
||||
}
|
||||
};
|
||||
descriptorRetriever =
|
||||
new ExtensionDescriptorRetriever() {
|
||||
@Override
|
||||
public FieldDescriptor getDescriptor() {
|
||||
return descriptor;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private ExtensionDescriptorRetriever descriptorRetriever;
|
||||
@ -1649,6 +1652,7 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
private final Method enumGetValueDescriptor;
|
||||
private final ExtensionType extensionType;
|
||||
|
||||
@Override
|
||||
public FieldDescriptor getDescriptor() {
|
||||
if (descriptorRetriever == null) {
|
||||
throw new IllegalStateException(
|
||||
@ -1661,10 +1665,12 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
* If the extension is an embedded message or group, returns the default
|
||||
* instance of the message.
|
||||
*/
|
||||
@Override
|
||||
public Message getMessageDefaultInstance() {
|
||||
return messageDefaultInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ExtensionType getExtensionType() {
|
||||
return extensionType;
|
||||
}
|
||||
@ -1675,7 +1681,7 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
* EnumValueDescriptors but the native accessors use the generated enum
|
||||
* type.
|
||||
*/
|
||||
// @Override
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Object fromReflectionType(final Object value) {
|
||||
FieldDescriptor descriptor = getDescriptor();
|
||||
@ -1700,7 +1706,7 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
* Like {@link #fromReflectionType(Object)}, but if the type is a repeated
|
||||
* type, this converts a single element.
|
||||
*/
|
||||
// @Override
|
||||
@Override
|
||||
protected Object singularFromReflectionType(final Object value) {
|
||||
FieldDescriptor descriptor = getDescriptor();
|
||||
switch (descriptor.getJavaType()) {
|
||||
@ -1724,7 +1730,7 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
* EnumValueDescriptors but the native accessors use the generated enum
|
||||
* type.
|
||||
*/
|
||||
// @Override
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Object toReflectionType(final Object value) {
|
||||
FieldDescriptor descriptor = getDescriptor();
|
||||
@ -1748,7 +1754,7 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
* Like {@link #toReflectionType(Object)}, but if the type is a repeated
|
||||
* type, this converts a single element.
|
||||
*/
|
||||
// @Override
|
||||
@Override
|
||||
protected Object singularToReflectionType(final Object value) {
|
||||
FieldDescriptor descriptor = getDescriptor();
|
||||
switch (descriptor.getJavaType()) {
|
||||
@ -1759,22 +1765,22 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
}
|
||||
}
|
||||
|
||||
// @Override
|
||||
@Override
|
||||
public int getNumber() {
|
||||
return getDescriptor().getNumber();
|
||||
}
|
||||
|
||||
// @Override
|
||||
@Override
|
||||
public WireFormat.FieldType getLiteType() {
|
||||
return getDescriptor().getLiteType();
|
||||
}
|
||||
|
||||
// @Override
|
||||
@Override
|
||||
public boolean isRepeated() {
|
||||
return getDescriptor().isRepeated();
|
||||
}
|
||||
|
||||
// @Override
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Type getDefaultValue() {
|
||||
if (isRepeated()) {
|
||||
@ -2124,49 +2130,57 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
return ((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(final GeneratedMessage message) {
|
||||
return invokeOrDie(getMethod, message);
|
||||
}
|
||||
@Override
|
||||
public Object get(GeneratedMessage.Builder builder) {
|
||||
return invokeOrDie(getMethodBuilder, builder);
|
||||
}
|
||||
@Override
|
||||
public Object getRaw(final GeneratedMessage message) {
|
||||
return get(message);
|
||||
}
|
||||
@Override
|
||||
public Object getRaw(GeneratedMessage.Builder builder) {
|
||||
return get(builder);
|
||||
}
|
||||
@Override
|
||||
public void set(final Builder builder, final Object value) {
|
||||
invokeOrDie(setMethod, builder, value);
|
||||
}
|
||||
public Object getRepeated(final GeneratedMessage message,
|
||||
final int index) {
|
||||
@Override
|
||||
public Object getRepeated(final GeneratedMessage message, final int index) {
|
||||
throw new UnsupportedOperationException(
|
||||
"getRepeatedField() called on a singular field.");
|
||||
}
|
||||
public Object getRepeatedRaw(final GeneratedMessage message,
|
||||
final int index) {
|
||||
@Override
|
||||
public Object getRepeatedRaw(final GeneratedMessage message, final int index) {
|
||||
throw new UnsupportedOperationException(
|
||||
"getRepeatedFieldRaw() called on a singular field.");
|
||||
}
|
||||
@Override
|
||||
public Object getRepeated(GeneratedMessage.Builder builder, int index) {
|
||||
throw new UnsupportedOperationException(
|
||||
"getRepeatedField() called on a singular field.");
|
||||
}
|
||||
public Object getRepeatedRaw(GeneratedMessage.Builder builder,
|
||||
int index) {
|
||||
@Override
|
||||
public Object getRepeatedRaw(GeneratedMessage.Builder builder, int index) {
|
||||
throw new UnsupportedOperationException(
|
||||
"getRepeatedFieldRaw() called on a singular field.");
|
||||
}
|
||||
public void setRepeated(final Builder builder, final int index,
|
||||
final Object value) {
|
||||
@Override
|
||||
public void setRepeated(final Builder builder, final int index, final Object value) {
|
||||
throw new UnsupportedOperationException(
|
||||
"setRepeatedField() called on a singular field.");
|
||||
}
|
||||
@Override
|
||||
public void addRepeated(final Builder builder, final Object value) {
|
||||
throw new UnsupportedOperationException(
|
||||
"addRepeatedField() called on a singular field.");
|
||||
}
|
||||
@Override
|
||||
public boolean has(final GeneratedMessage message) {
|
||||
if (!hasHasMethod) {
|
||||
if (isOneofField) {
|
||||
@ -2176,6 +2190,7 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
}
|
||||
return (Boolean) invokeOrDie(hasMethod, message);
|
||||
}
|
||||
@Override
|
||||
public boolean has(GeneratedMessage.Builder builder) {
|
||||
if (!hasHasMethod) {
|
||||
if (isOneofField) {
|
||||
@ -2185,27 +2200,32 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
}
|
||||
return (Boolean) invokeOrDie(hasMethodBuilder, builder);
|
||||
}
|
||||
@Override
|
||||
public int getRepeatedCount(final GeneratedMessage message) {
|
||||
throw new UnsupportedOperationException(
|
||||
"getRepeatedFieldSize() called on a singular field.");
|
||||
}
|
||||
@Override
|
||||
public int getRepeatedCount(GeneratedMessage.Builder builder) {
|
||||
throw new UnsupportedOperationException(
|
||||
"getRepeatedFieldSize() called on a singular field.");
|
||||
}
|
||||
@Override
|
||||
public void clear(final Builder builder) {
|
||||
invokeOrDie(clearMethod, builder);
|
||||
}
|
||||
@Override
|
||||
public Message.Builder newBuilder() {
|
||||
throw new UnsupportedOperationException(
|
||||
"newBuilderForField() called on a non-Message type.");
|
||||
}
|
||||
@Override
|
||||
public Message.Builder getBuilder(GeneratedMessage.Builder builder) {
|
||||
throw new UnsupportedOperationException(
|
||||
"getFieldBuilder() called on a non-Message type.");
|
||||
}
|
||||
public Message.Builder getRepeatedBuilder(GeneratedMessage.Builder builder,
|
||||
int index) {
|
||||
@Override
|
||||
public Message.Builder getRepeatedBuilder(GeneratedMessage.Builder builder, int index) {
|
||||
throw new UnsupportedOperationException(
|
||||
"getRepeatedFieldBuilder() called on a non-Message type.");
|
||||
}
|
||||
@ -2249,18 +2269,23 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(final GeneratedMessage message) {
|
||||
return invokeOrDie(getMethod, message);
|
||||
}
|
||||
@Override
|
||||
public Object get(GeneratedMessage.Builder builder) {
|
||||
return invokeOrDie(getMethodBuilder, builder);
|
||||
}
|
||||
@Override
|
||||
public Object getRaw(final GeneratedMessage message) {
|
||||
return get(message);
|
||||
}
|
||||
@Override
|
||||
public Object getRaw(GeneratedMessage.Builder builder) {
|
||||
return get(builder);
|
||||
}
|
||||
@Override
|
||||
public void set(final Builder builder, final Object value) {
|
||||
// Add all the elements individually. This serves two purposes:
|
||||
// 1) Verifies that each element has the correct type.
|
||||
@ -2271,54 +2296,64 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
addRepeated(builder, element);
|
||||
}
|
||||
}
|
||||
public Object getRepeated(final GeneratedMessage message,
|
||||
final int index) {
|
||||
@Override
|
||||
public Object getRepeated(final GeneratedMessage message, final int index) {
|
||||
return invokeOrDie(getRepeatedMethod, message, index);
|
||||
}
|
||||
@Override
|
||||
public Object getRepeated(GeneratedMessage.Builder builder, int index) {
|
||||
return invokeOrDie(getRepeatedMethodBuilder, builder, index);
|
||||
}
|
||||
@Override
|
||||
public Object getRepeatedRaw(GeneratedMessage message, int index) {
|
||||
return getRepeated(message, index);
|
||||
}
|
||||
public Object getRepeatedRaw(GeneratedMessage.Builder builder,
|
||||
int index) {
|
||||
@Override
|
||||
public Object getRepeatedRaw(GeneratedMessage.Builder builder, int index) {
|
||||
return getRepeated(builder, index);
|
||||
}
|
||||
public void setRepeated(final Builder builder,
|
||||
final int index, final Object value) {
|
||||
@Override
|
||||
public void setRepeated(final Builder builder, final int index, final Object value) {
|
||||
invokeOrDie(setRepeatedMethod, builder, index, value);
|
||||
}
|
||||
@Override
|
||||
public void addRepeated(final Builder builder, final Object value) {
|
||||
invokeOrDie(addRepeatedMethod, builder, value);
|
||||
}
|
||||
@Override
|
||||
public boolean has(final GeneratedMessage message) {
|
||||
throw new UnsupportedOperationException(
|
||||
"hasField() called on a repeated field.");
|
||||
}
|
||||
@Override
|
||||
public boolean has(GeneratedMessage.Builder builder) {
|
||||
throw new UnsupportedOperationException(
|
||||
"hasField() called on a repeated field.");
|
||||
}
|
||||
@Override
|
||||
public int getRepeatedCount(final GeneratedMessage message) {
|
||||
return (Integer) invokeOrDie(getCountMethod, message);
|
||||
}
|
||||
@Override
|
||||
public int getRepeatedCount(GeneratedMessage.Builder builder) {
|
||||
return (Integer) invokeOrDie(getCountMethodBuilder, builder);
|
||||
}
|
||||
@Override
|
||||
public void clear(final Builder builder) {
|
||||
invokeOrDie(clearMethod, builder);
|
||||
}
|
||||
@Override
|
||||
public Message.Builder newBuilder() {
|
||||
throw new UnsupportedOperationException(
|
||||
"newBuilderForField() called on a non-Message type.");
|
||||
}
|
||||
@Override
|
||||
public Message.Builder getBuilder(GeneratedMessage.Builder builder) {
|
||||
throw new UnsupportedOperationException(
|
||||
"getFieldBuilder() called on a non-Message type.");
|
||||
}
|
||||
public Message.Builder getRepeatedBuilder(GeneratedMessage.Builder builder,
|
||||
int index) {
|
||||
@Override
|
||||
public Message.Builder getRepeatedBuilder(GeneratedMessage.Builder builder, int index) {
|
||||
throw new UnsupportedOperationException(
|
||||
"getRepeatedFieldBuilder() called on a non-Message type.");
|
||||
}
|
||||
@ -2355,6 +2390,7 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
field.getNumber());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(GeneratedMessage message) {
|
||||
List result = new ArrayList();
|
||||
for (int i = 0; i < getRepeatedCount(message); i++) {
|
||||
@ -2363,6 +2399,7 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
return Collections.unmodifiableList(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(Builder builder) {
|
||||
List result = new ArrayList();
|
||||
for (int i = 0; i < getRepeatedCount(builder); i++) {
|
||||
@ -2371,14 +2408,17 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
return Collections.unmodifiableList(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getRaw(GeneratedMessage message) {
|
||||
return get(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getRaw(GeneratedMessage.Builder builder) {
|
||||
return get(builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(Builder builder, Object value) {
|
||||
clear(builder);
|
||||
for (Object entry : (List) value) {
|
||||
@ -2386,63 +2426,76 @@ public abstract class GeneratedMessage extends AbstractMessage
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getRepeated(GeneratedMessage message, int index) {
|
||||
return getMapField(message).getList().get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getRepeated(Builder builder, int index) {
|
||||
return getMapField(builder).getList().get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getRepeatedRaw(GeneratedMessage message, int index) {
|
||||
return getRepeated(message, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getRepeatedRaw(Builder builder, int index) {
|
||||
return getRepeated(builder, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRepeated(Builder builder, int index, Object value) {
|
||||
getMutableMapField(builder).getMutableList().set(index, (Message) value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRepeated(Builder builder, Object value) {
|
||||
getMutableMapField(builder).getMutableList().add((Message) value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(GeneratedMessage message) {
|
||||
throw new UnsupportedOperationException(
|
||||
"hasField() is not supported for repeated fields.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(Builder builder) {
|
||||
throw new UnsupportedOperationException(
|
||||
"hasField() is not supported for repeated fields.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRepeatedCount(GeneratedMessage message) {
|
||||
return getMapField(message).getList().size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRepeatedCount(Builder builder) {
|
||||
return getMapField(builder).getList().size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear(Builder builder) {
|
||||
getMutableMapField(builder).getMutableList().clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.google.protobuf.Message.Builder newBuilder() {
|
||||
return mapEntryMessageDefaultInstance.newBuilderForType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.google.protobuf.Message.Builder getBuilder(Builder builder) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Nested builder not supported for map fields.");
|
||||
}
|
||||
|
||||
public com.google.protobuf.Message.Builder getRepeatedBuilder(
|
||||
Builder builder, int index) {
|
||||
@Override
|
||||
public com.google.protobuf.Message.Builder getRepeatedBuilder(Builder builder, int index) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Nested builder not supported for map fields.");
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -34,7 +34,6 @@ import com.google.protobuf.Internal.IntList;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.RandomAccess;
|
||||
|
||||
/**
|
||||
@ -44,8 +43,6 @@ import java.util.RandomAccess;
|
||||
*/
|
||||
final class IntArrayList extends AbstractProtobufList<Integer> implements IntList, RandomAccess {
|
||||
|
||||
private static final int DEFAULT_CAPACITY = 10;
|
||||
|
||||
private static final IntArrayList EMPTY_LIST = new IntArrayList();
|
||||
static {
|
||||
EMPTY_LIST.makeImmutable();
|
||||
@ -70,32 +67,55 @@ final class IntArrayList extends AbstractProtobufList<Integer> implements IntLis
|
||||
* Constructs a new mutable {@code IntArrayList} with default capacity.
|
||||
*/
|
||||
IntArrayList() {
|
||||
this(DEFAULT_CAPACITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new mutable {@code IntArrayList} with the provided capacity.
|
||||
*/
|
||||
IntArrayList(int capacity) {
|
||||
array = new int[capacity];
|
||||
size = 0;
|
||||
this(new int[DEFAULT_CAPACITY], 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new mutable {@code IntArrayList} containing the same elements as {@code other}.
|
||||
*/
|
||||
IntArrayList(List<Integer> other) {
|
||||
if (other instanceof IntArrayList) {
|
||||
IntArrayList list = (IntArrayList) other;
|
||||
array = list.array.clone();
|
||||
size = list.size;
|
||||
} else {
|
||||
size = other.size();
|
||||
array = new int[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
array[i] = other.get(i);
|
||||
private IntArrayList(int[] array, int size) {
|
||||
this.array = array;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof IntArrayList)) {
|
||||
return super.equals(o);
|
||||
}
|
||||
IntArrayList other = (IntArrayList) o;
|
||||
if (size != other.size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final int[] arr = other.array;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (array[i] != arr[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
for (int i = 0; i < size; i++) {
|
||||
result = (31 * result) + array[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntList mutableCopyWithCapacity(int capacity) {
|
||||
if (capacity < size) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return new IntArrayList(Arrays.copyOf(array, capacity), size);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -41,6 +41,7 @@ import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.RandomAccess;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@ -51,10 +52,12 @@ import java.util.Set;
|
||||
*
|
||||
* @author kenton@google.com (Kenton Varda)
|
||||
*/
|
||||
public class Internal {
|
||||
public final class Internal {
|
||||
|
||||
protected static final Charset UTF_8 = Charset.forName("UTF-8");
|
||||
protected static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
|
||||
private Internal() {}
|
||||
|
||||
static final Charset UTF_8 = Charset.forName("UTF-8");
|
||||
static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
|
||||
|
||||
/**
|
||||
* Helper called by generated code to construct default values for string
|
||||
@ -406,6 +409,7 @@ public class Internal {
|
||||
public static final CodedInputStream EMPTY_CODED_INPUT_STREAM =
|
||||
CodedInputStream.newInstance(EMPTY_BYTE_ARRAY);
|
||||
|
||||
|
||||
/**
|
||||
* Provides an immutable view of {@code List<T>} around a {@code List<F>}.
|
||||
*
|
||||
@ -454,10 +458,13 @@ public class Internal {
|
||||
public static <T extends EnumLite> Converter<Integer, T> newEnumConverter(
|
||||
final EnumLiteMap<T> enumMap, final T unrecognizedValue) {
|
||||
return new Converter<Integer, T>() {
|
||||
@Override
|
||||
public T doForward(Integer value) {
|
||||
T result = enumMap.findValueByNumber(value);
|
||||
return result == null ? unrecognizedValue : result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer doBackward(T value) {
|
||||
return value.getNumber();
|
||||
}
|
||||
@ -570,8 +577,10 @@ public class Internal {
|
||||
/**
|
||||
* Extends {@link List} to add the capability to make the list immutable and inspect if it is
|
||||
* modifiable.
|
||||
* <p>
|
||||
* All implementations must support efficient random access.
|
||||
*/
|
||||
public static interface ProtobufList<E> extends List<E> {
|
||||
public static interface ProtobufList<E> extends List<E>, RandomAccess {
|
||||
|
||||
/**
|
||||
* Makes this list immutable. All subsequent modifications will throw an
|
||||
@ -583,6 +592,11 @@ public class Internal {
|
||||
* Returns whether this list can be modified via the publicly accessible {@link List} methods.
|
||||
*/
|
||||
boolean isModifiable();
|
||||
|
||||
/**
|
||||
* Returns a mutable clone of this list with the specified capacity.
|
||||
*/
|
||||
ProtobufList<E> mutableCopyWithCapacity(int capacity);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -597,14 +611,20 @@ public class Internal {
|
||||
int getInt(int index);
|
||||
|
||||
/**
|
||||
* Like {@link #add(Object)} but more efficient in that it doesn't box the element.
|
||||
* Like {@link #add(Integer)} but more efficient in that it doesn't box the element.
|
||||
*/
|
||||
void addInt(int element);
|
||||
|
||||
/**
|
||||
* Like {@link #set(int, Object)} but more efficient in that it doesn't box the element.
|
||||
* Like {@link #set(int, Integer)} but more efficient in that it doesn't box the element.
|
||||
*/
|
||||
int setInt(int index, int element);
|
||||
|
||||
/**
|
||||
* Returns a mutable clone of this list with the specified capacity.
|
||||
*/
|
||||
@Override
|
||||
IntList mutableCopyWithCapacity(int capacity);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -619,14 +639,20 @@ public class Internal {
|
||||
boolean getBoolean(int index);
|
||||
|
||||
/**
|
||||
* Like {@link #add(Object)} but more efficient in that it doesn't box the element.
|
||||
* Like {@link #add(Boolean)} but more efficient in that it doesn't box the element.
|
||||
*/
|
||||
void addBoolean(boolean element);
|
||||
|
||||
/**
|
||||
* Like {@link #set(int, Object)} but more efficient in that it doesn't box the element.
|
||||
* Like {@link #set(int, Boolean)} but more efficient in that it doesn't box the element.
|
||||
*/
|
||||
boolean setBoolean(int index, boolean element);
|
||||
|
||||
/**
|
||||
* Returns a mutable clone of this list with the specified capacity.
|
||||
*/
|
||||
@Override
|
||||
BooleanList mutableCopyWithCapacity(int capacity);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -641,14 +667,20 @@ public class Internal {
|
||||
long getLong(int index);
|
||||
|
||||
/**
|
||||
* Like {@link #add(Object)} but more efficient in that it doesn't box the element.
|
||||
* Like {@link #add(Long)} but more efficient in that it doesn't box the element.
|
||||
*/
|
||||
void addLong(long element);
|
||||
|
||||
/**
|
||||
* Like {@link #set(int, Object)} but more efficient in that it doesn't box the element.
|
||||
* Like {@link #set(int, Long)} but more efficient in that it doesn't box the element.
|
||||
*/
|
||||
long setLong(int index, long element);
|
||||
|
||||
/**
|
||||
* Returns a mutable clone of this list with the specified capacity.
|
||||
*/
|
||||
@Override
|
||||
LongList mutableCopyWithCapacity(int capacity);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -663,14 +695,20 @@ public class Internal {
|
||||
double getDouble(int index);
|
||||
|
||||
/**
|
||||
* Like {@link #add(Object)} but more efficient in that it doesn't box the element.
|
||||
* Like {@link #add(Double)} but more efficient in that it doesn't box the element.
|
||||
*/
|
||||
void addDouble(double element);
|
||||
|
||||
/**
|
||||
* Like {@link #set(int, Object)} but more efficient in that it doesn't box the element.
|
||||
* Like {@link #set(int, Double)} but more efficient in that it doesn't box the element.
|
||||
*/
|
||||
double setDouble(int index, double element);
|
||||
|
||||
/**
|
||||
* Returns a mutable clone of this list with the specified capacity.
|
||||
*/
|
||||
@Override
|
||||
DoubleList mutableCopyWithCapacity(int capacity);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -685,13 +723,19 @@ public class Internal {
|
||||
float getFloat(int index);
|
||||
|
||||
/**
|
||||
* Like {@link #add(Object)} but more efficient in that it doesn't box the element.
|
||||
* Like {@link #add(Float)} but more efficient in that it doesn't box the element.
|
||||
*/
|
||||
void addFloat(float element);
|
||||
|
||||
/**
|
||||
* Like {@link #set(int, Object)} but more efficient in that it doesn't box the element.
|
||||
* Like {@link #set(int, Float)} but more efficient in that it doesn't box the element.
|
||||
*/
|
||||
float setFloat(int index, float element);
|
||||
|
||||
/**
|
||||
* Returns a mutable clone of this list with the specified capacity.
|
||||
*/
|
||||
@Override
|
||||
FloatList mutableCopyWithCapacity(int capacity);
|
||||
}
|
||||
}
|
||||
|
@ -39,14 +39,14 @@ import java.util.Map.Entry;
|
||||
*
|
||||
* Most of key methods are implemented in {@link LazyFieldLite} but this class
|
||||
* can contain default instance of the message to provide {@code hashCode()},
|
||||
* {@code equals()} and {@code toString()}.
|
||||
* {@code euqals()} and {@code toString()}.
|
||||
*
|
||||
* @author xiangl@google.com (Xiang Li)
|
||||
*/
|
||||
public class LazyField extends LazyFieldLite {
|
||||
|
||||
/**
|
||||
* Carry a message's default instance which is used by {@code hashCode()}, {@code equals()} and
|
||||
* Carry a message's default instance which is used by {@code hashCode()}, {@code euqals()} and
|
||||
* {@code toString()}.
|
||||
*/
|
||||
private final MessageLite defaultInstance;
|
||||
@ -95,12 +95,12 @@ public class LazyField extends LazyFieldLite {
|
||||
this.entry = entry;
|
||||
}
|
||||
|
||||
// @Override
|
||||
@Override
|
||||
public K getKey() {
|
||||
return entry.getKey();
|
||||
}
|
||||
|
||||
// @Override
|
||||
@Override
|
||||
public Object getValue() {
|
||||
LazyField field = entry.getValue();
|
||||
if (field == null) {
|
||||
@ -113,7 +113,7 @@ public class LazyField extends LazyFieldLite {
|
||||
return entry.getValue();
|
||||
}
|
||||
|
||||
// @Override
|
||||
@Override
|
||||
public Object setValue(Object value) {
|
||||
if (!(value instanceof MessageLite)) {
|
||||
throw new IllegalArgumentException(
|
||||
@ -131,13 +131,13 @@ public class LazyField extends LazyFieldLite {
|
||||
this.iterator = iterator;
|
||||
}
|
||||
|
||||
// @Override
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return iterator.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
// @Override
|
||||
public Entry<K, Object> next() {
|
||||
Entry<K, ?> entry = iterator.next();
|
||||
if (entry.getValue() instanceof LazyField) {
|
||||
@ -146,7 +146,7 @@ public class LazyField extends LazyFieldLite {
|
||||
return (Entry<K, Object>) entry;
|
||||
}
|
||||
|
||||
// @Override
|
||||
@Override
|
||||
public void remove() {
|
||||
iterator.remove();
|
||||
}
|
||||
|
@ -30,14 +30,26 @@
|
||||
|
||||
package com.google.protobuf;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* LazyFieldLite encapsulates the logic of lazily parsing message fields. It stores
|
||||
* the message in a ByteString initially and then parse it on-demand.
|
||||
* the message in a ByteString initially and then parses it on-demand.
|
||||
*
|
||||
* LazyField is thread-compatible e.g. concurrent read are safe, however,
|
||||
* synchronizations are needed under read/write situations.
|
||||
* LazyFieldLite is thread-compatible: concurrent reads are safe once the proto that this
|
||||
* LazyFieldLite is a part of is no longer being mutated by its Builder. However, explicit
|
||||
* synchronization is needed under read/write situations.
|
||||
*
|
||||
* This class is internal implementation detail, so you don't need to use it directly.
|
||||
* When a LazyFieldLite is used in the context of a MessageLite object, its behavior is considered
|
||||
* to be immutable and none of the setter methods in its API are expected to be invoked. All of the
|
||||
* getters are expected to be thread-safe. When used in the context of a MessageLite.Builder,
|
||||
* setters can be invoked, but there is no guarantee of thread safety.
|
||||
*
|
||||
* TODO(yatin,dweis): Consider splitting this class's functionality and put the mutable methods
|
||||
* into a separate builder class to allow us to give stronger compile-time guarantees.
|
||||
*
|
||||
* This class is internal implementation detail of the protobuf library, so you don't need to use it
|
||||
* directly.
|
||||
*
|
||||
* @author xiangl@google.com (Xiang Li)
|
||||
*/
|
||||
@ -46,8 +58,34 @@ public class LazyFieldLite {
|
||||
ExtensionRegistryLite.getEmptyRegistry();
|
||||
|
||||
/**
|
||||
* A delayed-parsed version of the bytes. When this is non-null then {@code extensionRegistry } is
|
||||
* also non-null and {@code value} and {@code memoizedBytes} are null.
|
||||
* The value associated with the LazyFieldLite object is stored in one or more of the following
|
||||
* three fields (delayedBytes, value, memoizedBytes). They should together be interpreted as
|
||||
* follows.
|
||||
* 1) delayedBytes can be non-null, while value and memoizedBytes is null. The object will be in
|
||||
* this state while the value for the object has not yet been parsed.
|
||||
* 2) Both delayedBytes and value are non-null. The object transitions to this state as soon as
|
||||
* some caller needs to access the value (by invoking getValue()).
|
||||
* 3) memoizedBytes is merely an optimization for calls to LazyFieldLite.toByteString() to avoid
|
||||
* recomputing the ByteString representation on each call. Instead, when the value is parsed
|
||||
* from delayedBytes, we will also assign the contents of delayedBytes to memoizedBytes (since
|
||||
* that is the ByteString representation of value).
|
||||
* 4) Finally, if the LazyFieldLite was created directly with a parsed MessageLite value, then
|
||||
* delayedBytes will be null, and memoizedBytes will be initialized only upon the first call to
|
||||
* LazyFieldLite.toByteString().
|
||||
*
|
||||
* Given the above conditions, any caller that needs a serialized representation of this object
|
||||
* must first check if the memoizedBytes or delayedBytes ByteString is non-null and use it
|
||||
* directly; if both of those are null, it can look at the parsed value field. Similarly, any
|
||||
* caller that needs a parsed value must first check if the value field is already non-null, if
|
||||
* not it must parse the value from delayedBytes.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A delayed-parsed version of the contents of this field. When this field is non-null, then the
|
||||
* "value" field is allowed to be null until the time that the value needs to be read.
|
||||
*
|
||||
* When delayedBytes is non-null then {@code extensionRegistry} is required to also be non-null.
|
||||
* {@code value} and {@code memoizedBytes} will be initialized lazily.
|
||||
*/
|
||||
private ByteString delayedBytes;
|
||||
|
||||
@ -60,12 +98,15 @@ public class LazyFieldLite {
|
||||
private ExtensionRegistryLite extensionRegistry;
|
||||
|
||||
/**
|
||||
* The parsed value. When this is non-null then {@code delayedBytes} will be null.
|
||||
* The parsed value. When this is null and a caller needs access to the MessageLite value, then
|
||||
* {@code delayedBytes} will be parsed lazily at that time.
|
||||
*/
|
||||
protected volatile MessageLite value;
|
||||
|
||||
/**
|
||||
* The memoized bytes for {@code value}. Will be null when {@code value} is null.
|
||||
* The memoized bytes for {@code value}. This is an optimization for the toByteString() method to
|
||||
* not have to recompute its return-value on each invocation.
|
||||
* TODO(yatin): Figure out whether this optimization is actually necessary.
|
||||
*/
|
||||
private volatile ByteString memoizedBytes;
|
||||
|
||||
@ -94,6 +135,43 @@ public class LazyFieldLite {
|
||||
return lf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof LazyFieldLite)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LazyFieldLite other = (LazyFieldLite) o;
|
||||
|
||||
// Lazy fields do not work well with equals... If both are delayedBytes, we do not have a
|
||||
// mechanism to deserialize them so we rely on bytes equality. Otherwise we coerce into an
|
||||
// actual message (if necessary) and call equals on the message itself. This implies that two
|
||||
// messages can by unequal but then be turned equal simply be invoking a getter on a lazy field.
|
||||
MessageLite value1 = value;
|
||||
MessageLite value2 = other.value;
|
||||
if (value1 == null && value2 == null) {
|
||||
return toByteString().equals(other.toByteString());
|
||||
} else if (value1 != null && value2 != null) {
|
||||
return value1.equals(value2);
|
||||
} else if (value1 != null) {
|
||||
return value1.equals(other.getValue(value1.getDefaultInstanceForType()));
|
||||
} else {
|
||||
return getValue(value2.getDefaultInstanceForType()).equals(value2);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
// We can't provide a memoizable hash code for lazy fields. The byte strings may have different
|
||||
// hash codes but evaluate to equivalent messages. And we have no facility for constructing
|
||||
// a message here if we were not already holding a value.
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether this LazyFieldLite instance represents the default instance of this type.
|
||||
*/
|
||||
@ -230,6 +308,46 @@ public class LazyFieldLite {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges another instance's contents from a stream.
|
||||
*
|
||||
* <p>LazyField is not thread-safe for write access. Synchronizations are needed
|
||||
* under read/write situations.
|
||||
*/
|
||||
public void mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry)
|
||||
throws IOException {
|
||||
if (this.containsDefaultInstance()) {
|
||||
setByteString(input.readBytes(), extensionRegistry);
|
||||
return;
|
||||
}
|
||||
|
||||
// If the other field has an extension registry but this does not, copy over the other extension
|
||||
// registry.
|
||||
if (this.extensionRegistry == null) {
|
||||
this.extensionRegistry = extensionRegistry;
|
||||
}
|
||||
|
||||
// In the case that both of them are not parsed we simply concatenate the bytes to save time. In
|
||||
// the (probably rare) case that they have different extension registries there is a chance that
|
||||
// some of the extensions may be dropped, but the tradeoff of making this operation fast seems
|
||||
// to outway the benefits of combining the extension registries, which is not normally done for
|
||||
// lite protos anyways.
|
||||
if (this.delayedBytes != null) {
|
||||
setByteString(this.delayedBytes.concat(input.readBytes()), this.extensionRegistry);
|
||||
return;
|
||||
}
|
||||
|
||||
// We are parsed and both contain data. We won't drop any extensions here directly, but in the
|
||||
// case that the extension registries are not the same then we might in the future if we
|
||||
// need to serialize and parse a message again.
|
||||
try {
|
||||
setValue(value.toBuilder().mergeFrom(input, extensionRegistry).build());
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
// Nothing is logged and no exceptions are thrown. Clients will be unaware that a proto
|
||||
// was invalid.
|
||||
}
|
||||
}
|
||||
|
||||
private static MessageLite mergeValueAndBytes(
|
||||
MessageLite value, ByteString otherBytes, ExtensionRegistryLite extensionRegistry) {
|
||||
@ -259,10 +377,12 @@ public class LazyFieldLite {
|
||||
* parsed. Be careful when using this method.
|
||||
*/
|
||||
public int getSerializedSize() {
|
||||
if (delayedBytes != null) {
|
||||
return delayedBytes.size();
|
||||
} else if (memoizedBytes != null) {
|
||||
// We *must* return delayed bytes size if it was ever set because the dependent messages may
|
||||
// have memoized serialized size based off of it.
|
||||
if (memoizedBytes != null) {
|
||||
return memoizedBytes.size();
|
||||
} else if (delayedBytes != null) {
|
||||
return delayedBytes.size();
|
||||
} else if (value != null) {
|
||||
return value.getSerializedSize();
|
||||
} else {
|
||||
@ -274,12 +394,14 @@ public class LazyFieldLite {
|
||||
* Returns a BytesString for this field in a thread-safe way.
|
||||
*/
|
||||
public ByteString toByteString() {
|
||||
if (delayedBytes != null) {
|
||||
return delayedBytes;
|
||||
}
|
||||
if (memoizedBytes != null) {
|
||||
return memoizedBytes;
|
||||
}
|
||||
// We *must* return delayed bytes if it was set because the dependent messages may have
|
||||
// memoized serialized size based off of it.
|
||||
if (delayedBytes != null) {
|
||||
return delayedBytes;
|
||||
}
|
||||
synchronized (this) {
|
||||
if (memoizedBytes != null) {
|
||||
return memoizedBytes;
|
||||
@ -311,18 +433,15 @@ public class LazyFieldLite {
|
||||
.parseFrom(delayedBytes, extensionRegistry);
|
||||
this.value = parsedValue;
|
||||
this.memoizedBytes = delayedBytes;
|
||||
this.delayedBytes = null;
|
||||
} else {
|
||||
this.value = defaultInstance;
|
||||
this.memoizedBytes = ByteString.EMPTY;
|
||||
this.delayedBytes = null;
|
||||
}
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
// Nothing is logged and no exceptions are thrown. Clients will be unaware that this proto
|
||||
// was invalid.
|
||||
this.value = defaultInstance;
|
||||
this.memoizedBytes = ByteString.EMPTY;
|
||||
this.delayedBytes = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,12 +30,12 @@
|
||||
|
||||
package com.google.protobuf;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.AbstractList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.RandomAccess;
|
||||
|
||||
/**
|
||||
@ -64,7 +64,7 @@ import java.util.RandomAccess;
|
||||
*/
|
||||
public class LazyStringArrayList extends AbstractProtobufList<String>
|
||||
implements LazyStringList, RandomAccess {
|
||||
|
||||
|
||||
private static final LazyStringArrayList EMPTY_LIST = new LazyStringArrayList();
|
||||
static {
|
||||
EMPTY_LIST.makeImmutable();
|
||||
@ -80,11 +80,11 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
|
||||
private final List<Object> list;
|
||||
|
||||
public LazyStringArrayList() {
|
||||
list = new ArrayList<Object>();
|
||||
this(DEFAULT_CAPACITY);
|
||||
}
|
||||
|
||||
public LazyStringArrayList(int intialCapacity) {
|
||||
list = new ArrayList<Object>(intialCapacity);
|
||||
this(new ArrayList<Object>(intialCapacity));
|
||||
}
|
||||
|
||||
public LazyStringArrayList(LazyStringList from) {
|
||||
@ -93,7 +93,21 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
|
||||
}
|
||||
|
||||
public LazyStringArrayList(List<String> from) {
|
||||
list = new ArrayList<Object>(from);
|
||||
this(new ArrayList<Object>(from));
|
||||
}
|
||||
|
||||
private LazyStringArrayList(ArrayList<Object> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LazyStringArrayList mutableCopyWithCapacity(int capacity) {
|
||||
if (capacity < size()) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
ArrayList<Object> newList = new ArrayList<Object>(capacity);
|
||||
newList.addAll(list);
|
||||
return new LazyStringArrayList(newList);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -170,7 +184,7 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
|
||||
return ret;
|
||||
}
|
||||
|
||||
// @Override
|
||||
@Override
|
||||
public boolean addAllByteString(Collection<? extends ByteString> values) {
|
||||
ensureIsMutable();
|
||||
boolean ret = list.addAll(values);
|
||||
@ -178,7 +192,7 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
|
||||
return ret;
|
||||
}
|
||||
|
||||
// @Override
|
||||
@Override
|
||||
public boolean addAllByteArray(Collection<byte[]> c) {
|
||||
ensureIsMutable();
|
||||
boolean ret = list.addAll(c);
|
||||
@ -201,14 +215,14 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
|
||||
modCount++;
|
||||
}
|
||||
|
||||
// @Override
|
||||
@Override
|
||||
public void add(ByteString element) {
|
||||
ensureIsMutable();
|
||||
list.add(element);
|
||||
modCount++;
|
||||
}
|
||||
|
||||
// @Override
|
||||
@Override
|
||||
public void add(byte[] element) {
|
||||
ensureIsMutable();
|
||||
list.add(element);
|
||||
@ -220,7 +234,7 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
|
||||
return list.get(index);
|
||||
}
|
||||
|
||||
// @Override
|
||||
@Override
|
||||
public ByteString getByteString(int index) {
|
||||
Object o = list.get(index);
|
||||
ByteString b = asByteString(o);
|
||||
@ -230,7 +244,7 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
|
||||
return b;
|
||||
}
|
||||
|
||||
// @Override
|
||||
@Override
|
||||
public byte[] getByteArray(int index) {
|
||||
Object o = list.get(index);
|
||||
byte[] b = asByteArray(o);
|
||||
@ -240,7 +254,7 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
|
||||
return b;
|
||||
}
|
||||
|
||||
// @Override
|
||||
@Override
|
||||
public void set(int index, ByteString s) {
|
||||
setAndReturn(index, s);
|
||||
}
|
||||
@ -250,7 +264,7 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
|
||||
return list.set(index, s);
|
||||
}
|
||||
|
||||
// @Override
|
||||
@Override
|
||||
public void set(int index, byte[] s) {
|
||||
setAndReturn(index, s);
|
||||
}
|
||||
@ -290,12 +304,12 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
|
||||
}
|
||||
}
|
||||
|
||||
// @Override
|
||||
@Override
|
||||
public List<?> getUnderlyingElements() {
|
||||
return Collections.unmodifiableList(list);
|
||||
}
|
||||
|
||||
// @Override
|
||||
@Override
|
||||
public void mergeFrom(LazyStringList other) {
|
||||
ensureIsMutable();
|
||||
for (Object o : other.getUnderlyingElements()) {
|
||||
@ -349,7 +363,7 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
|
||||
}
|
||||
}
|
||||
|
||||
// @Override
|
||||
@Override
|
||||
public List<byte[]> asByteArrayList() {
|
||||
return new ByteArrayListView(this);
|
||||
}
|
||||
@ -393,12 +407,12 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
|
||||
}
|
||||
}
|
||||
|
||||
// @Override
|
||||
@Override
|
||||
public List<ByteString> asByteStringList() {
|
||||
return new ByteStringListView(this);
|
||||
}
|
||||
|
||||
// @Override
|
||||
@Override
|
||||
public LazyStringList getUnmodifiableView() {
|
||||
if (isModifiable()) {
|
||||
return new UnmodifiableLazyStringList(this);
|
||||
|
@ -34,7 +34,6 @@ import com.google.protobuf.Internal.LongList;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.RandomAccess;
|
||||
|
||||
/**
|
||||
@ -44,8 +43,6 @@ import java.util.RandomAccess;
|
||||
*/
|
||||
final class LongArrayList extends AbstractProtobufList<Long> implements LongList, RandomAccess {
|
||||
|
||||
private static final int DEFAULT_CAPACITY = 10;
|
||||
|
||||
private static final LongArrayList EMPTY_LIST = new LongArrayList();
|
||||
static {
|
||||
EMPTY_LIST.makeImmutable();
|
||||
@ -70,32 +67,55 @@ final class LongArrayList extends AbstractProtobufList<Long> implements LongList
|
||||
* Constructs a new mutable {@code LongArrayList} with default capacity.
|
||||
*/
|
||||
LongArrayList() {
|
||||
this(DEFAULT_CAPACITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new mutable {@code LongArrayList} with the provided capacity.
|
||||
*/
|
||||
LongArrayList(int capacity) {
|
||||
array = new long[capacity];
|
||||
size = 0;
|
||||
this(new long[DEFAULT_CAPACITY], 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new mutable {@code LongArrayList} containing the same elements as {@code other}.
|
||||
*/
|
||||
LongArrayList(List<Long> other) {
|
||||
if (other instanceof LongArrayList) {
|
||||
LongArrayList list = (LongArrayList) other;
|
||||
array = list.array.clone();
|
||||
size = list.size;
|
||||
} else {
|
||||
size = other.size();
|
||||
array = new long[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
array[i] = other.get(i);
|
||||
private LongArrayList(long[] array, int size) {
|
||||
this.array = array;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof IntArrayList)) {
|
||||
return super.equals(o);
|
||||
}
|
||||
LongArrayList other = (LongArrayList) o;
|
||||
if (size != other.size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final long[] arr = other.array;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (array[i] != arr[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
for (int i = 0; i < size; i++) {
|
||||
result = (31 * result) + Internal.hashLong(array[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LongList mutableCopyWithCapacity(int capacity) {
|
||||
if (capacity < size) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return new LongArrayList(Arrays.copyOf(array, capacity), size);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -41,7 +41,8 @@ import java.io.IOException;
|
||||
*
|
||||
* Protobuf internal. Users shouldn't use.
|
||||
*/
|
||||
public class MapEntryLite<K, V> extends AbstractMessageLite {
|
||||
public class MapEntryLite<K, V>
|
||||
extends AbstractMessageLite<MapEntryLite<K, V>, MapEntryLite.Builder<K, V>> {
|
||||
private static class Metadata<K, V> {
|
||||
public final MapEntryLite<K, V> defaultInstance;
|
||||
public final WireFormat.FieldType keyType;
|
||||
@ -233,7 +234,7 @@ public class MapEntryLite<K, V> extends AbstractMessageLite {
|
||||
* Builder used to create {@link MapEntryLite} messages.
|
||||
*/
|
||||
public static class Builder<K, V>
|
||||
extends AbstractMessageLite.Builder<Builder<K, V>> {
|
||||
extends AbstractMessageLite.Builder<MapEntryLite<K, V>, Builder<K, V>> {
|
||||
private final Metadata<K, V> metadata;
|
||||
private K key;
|
||||
private V value;
|
||||
@ -327,5 +328,10 @@ public class MapEntryLite<K, V> extends AbstractMessageLite {
|
||||
this.value = entry.value;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Builder<K, V> internalMergeFrom(MapEntryLite<K, V> message) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -93,15 +93,18 @@ public class MapField<K, V> implements MutabilityOracle {
|
||||
this.defaultEntry = defaultEntry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message convertKeyAndValueToMessage(K key, V value) {
|
||||
return defaultEntry.newBuilderForType().setKey(key).setValue(value).buildPartial();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertMessageToKeyAndValue(Message message, Map<K, V> map) {
|
||||
MapEntry<K, V> entry = (MapEntry<K, V>) message;
|
||||
map.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message getMessageDefaultInstance() {
|
||||
return defaultEntry;
|
||||
}
|
||||
|
@ -51,6 +51,7 @@ import java.util.Map;
|
||||
public interface Message extends MessageLite, MessageOrBuilder {
|
||||
|
||||
// (From MessageLite, re-declared here only for return type covariance.)
|
||||
@Override
|
||||
Parser<? extends Message> getParserForType();
|
||||
|
||||
|
||||
@ -97,7 +98,10 @@ public interface Message extends MessageLite, MessageOrBuilder {
|
||||
// Builders
|
||||
|
||||
// (From MessageLite, re-declared here only for return type covariance.)
|
||||
@Override
|
||||
Builder newBuilderForType();
|
||||
|
||||
@Override
|
||||
Builder toBuilder();
|
||||
|
||||
/**
|
||||
@ -106,6 +110,7 @@ public interface Message extends MessageLite, MessageOrBuilder {
|
||||
interface Builder extends MessageLite.Builder, MessageOrBuilder {
|
||||
// (From MessageLite.Builder, re-declared here only for return type
|
||||
// covariance.)
|
||||
@Override
|
||||
Builder clear();
|
||||
|
||||
/**
|
||||
@ -131,18 +136,27 @@ public interface Message extends MessageLite, MessageOrBuilder {
|
||||
|
||||
// (From MessageLite.Builder, re-declared here only for return type
|
||||
// covariance.)
|
||||
@Override
|
||||
Message build();
|
||||
|
||||
@Override
|
||||
Message buildPartial();
|
||||
|
||||
@Override
|
||||
Builder clone();
|
||||
|
||||
@Override
|
||||
Builder mergeFrom(CodedInputStream input) throws IOException;
|
||||
Builder mergeFrom(CodedInputStream input,
|
||||
ExtensionRegistryLite extensionRegistry)
|
||||
throws IOException;
|
||||
|
||||
@Override
|
||||
Builder mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Get the message's type's descriptor.
|
||||
* See {@link Message#getDescriptorForType()}.
|
||||
*/
|
||||
@Override
|
||||
Descriptors.Descriptor getDescriptorForType();
|
||||
|
||||
/**
|
||||
@ -240,27 +254,39 @@ public interface Message extends MessageLite, MessageOrBuilder {
|
||||
|
||||
// (From MessageLite.Builder, re-declared here only for return type
|
||||
// covariance.)
|
||||
@Override
|
||||
Builder mergeFrom(ByteString data) throws InvalidProtocolBufferException;
|
||||
Builder mergeFrom(ByteString data,
|
||||
ExtensionRegistryLite extensionRegistry)
|
||||
throws InvalidProtocolBufferException;
|
||||
|
||||
@Override
|
||||
Builder mergeFrom(ByteString data, ExtensionRegistryLite extensionRegistry)
|
||||
throws InvalidProtocolBufferException;
|
||||
|
||||
@Override
|
||||
Builder mergeFrom(byte[] data) throws InvalidProtocolBufferException;
|
||||
Builder mergeFrom(byte[] data, int off, int len)
|
||||
throws InvalidProtocolBufferException;
|
||||
Builder mergeFrom(byte[] data,
|
||||
ExtensionRegistryLite extensionRegistry)
|
||||
throws InvalidProtocolBufferException;
|
||||
Builder mergeFrom(byte[] data, int off, int len,
|
||||
ExtensionRegistryLite extensionRegistry)
|
||||
throws InvalidProtocolBufferException;
|
||||
|
||||
@Override
|
||||
Builder mergeFrom(byte[] data, int off, int len) throws InvalidProtocolBufferException;
|
||||
|
||||
@Override
|
||||
Builder mergeFrom(byte[] data, ExtensionRegistryLite extensionRegistry)
|
||||
throws InvalidProtocolBufferException;
|
||||
|
||||
@Override
|
||||
Builder mergeFrom(byte[] data, int off, int len, ExtensionRegistryLite extensionRegistry)
|
||||
throws InvalidProtocolBufferException;
|
||||
|
||||
@Override
|
||||
Builder mergeFrom(InputStream input) throws IOException;
|
||||
Builder mergeFrom(InputStream input,
|
||||
ExtensionRegistryLite extensionRegistry)
|
||||
throws IOException;
|
||||
boolean mergeDelimitedFrom(InputStream input)
|
||||
throws IOException;
|
||||
boolean mergeDelimitedFrom(InputStream input,
|
||||
ExtensionRegistryLite extensionRegistry)
|
||||
throws IOException;
|
||||
|
||||
@Override
|
||||
Builder mergeFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
|
||||
throws IOException;
|
||||
|
||||
@Override
|
||||
boolean mergeDelimitedFrom(InputStream input) throws IOException;
|
||||
|
||||
@Override
|
||||
boolean mergeDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
|
||||
throws IOException;
|
||||
}
|
||||
}
|
||||
|
@ -295,6 +295,27 @@ public interface MessageLite extends MessageLiteOrBuilder {
|
||||
Builder mergeFrom(InputStream input,
|
||||
ExtensionRegistryLite extensionRegistry)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Merge {@code other} into the message being built. {@code other} must
|
||||
* have the exact same type as {@code this} (i.e.
|
||||
* {@code getClass().equals(getDefaultInstanceForType().getClass())}).
|
||||
*
|
||||
* Merging occurs as follows. For each field:<br>
|
||||
* * For singular primitive fields, if the field is set in {@code other},
|
||||
* then {@code other}'s value overwrites the value in this message.<br>
|
||||
* * For singular message fields, if the field is set in {@code other},
|
||||
* it is merged into the corresponding sub-message of this message
|
||||
* using the same merging rules.<br>
|
||||
* * For repeated fields, the elements in {@code other} are concatenated
|
||||
* with the elements in this message.
|
||||
* * For oneof groups, if the other message has one of the fields set,
|
||||
* the group of this message is cleared and replaced by the field
|
||||
* of the other message, so that the oneof constraint is preserved.
|
||||
*
|
||||
* This is equivalent to the {@code Message::MergeFrom} method in C++.
|
||||
*/
|
||||
Builder mergeFrom(MessageLite other);
|
||||
|
||||
/**
|
||||
* Like {@link #mergeFrom(InputStream)}, but does not read until EOF.
|
||||
|
@ -0,0 +1,239 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// 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.
|
||||
|
||||
package com.google.protobuf;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* Helps generate {@link String} representations of {@link MessageLite} protos.
|
||||
*/
|
||||
// TODO(dweis): Fix map fields.
|
||||
final class MessageLiteToString {
|
||||
|
||||
private static final String LIST_SUFFIX = "List";
|
||||
private static final String BUILDER_LIST_SUFFIX = "OrBuilderList";
|
||||
private static final String BYTES_SUFFIX = "Bytes";
|
||||
|
||||
/**
|
||||
* Returns a {@link String} representation of the {@link MessageLite} object. The first line of
|
||||
* the {@code String} representation representation includes a comment string to uniquely identify
|
||||
* the objcet instance. This acts as an indicator that this should not be relied on for
|
||||
* comparisons.
|
||||
*
|
||||
* <p>For use by generated code only.
|
||||
*/
|
||||
static String toString(MessageLite messageLite, String commentString) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append("# ").append(commentString);
|
||||
reflectivePrintWithIndent(messageLite, buffer, 0);
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reflectively prints the {@link MessageLite} to the buffer at given {@code indent} level.
|
||||
*
|
||||
* @param buffer the buffer to write to
|
||||
* @param indent the number of spaces to indent the proto by
|
||||
*/
|
||||
private static void reflectivePrintWithIndent(
|
||||
MessageLite messageLite, StringBuilder buffer, int indent) {
|
||||
// Build a map of method name to method. We're looking for methods like getFoo(), hasFoo(), and
|
||||
// getFooList() which might be useful for building an object's string representation.
|
||||
Map<String, Method> nameToNoArgMethod = new HashMap<String, Method>();
|
||||
Map<String, Method> nameToMethod = new HashMap<String, Method>();
|
||||
Set<String> getters = new TreeSet<String>();
|
||||
for (Method method : messageLite.getClass().getDeclaredMethods()) {
|
||||
nameToMethod.put(method.getName(), method);
|
||||
if (method.getParameterTypes().length == 0) {
|
||||
nameToNoArgMethod.put(method.getName(), method);
|
||||
|
||||
if (method.getName().startsWith("get")) {
|
||||
getters.add(method.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (String getter : getters) {
|
||||
String suffix = getter.replaceFirst("get", "");
|
||||
if (suffix.endsWith(LIST_SUFFIX) && !suffix.endsWith(BUILDER_LIST_SUFFIX)) {
|
||||
String camelCase = suffix.substring(0, 1).toLowerCase()
|
||||
+ suffix.substring(1, suffix.length() - LIST_SUFFIX.length());
|
||||
// Try to reflectively get the value and toString() the field as if it were repeated. This
|
||||
// only works if the method names have not be proguarded out or renamed.
|
||||
Method listMethod = nameToNoArgMethod.get("get" + suffix);
|
||||
if (listMethod != null) {
|
||||
printField(
|
||||
buffer,
|
||||
indent,
|
||||
camelCaseToSnakeCase(camelCase),
|
||||
GeneratedMessageLite.invokeOrDie(listMethod, messageLite));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Method setter = nameToMethod.get("set" + suffix);
|
||||
if (setter == null) {
|
||||
continue;
|
||||
}
|
||||
if (suffix.endsWith(BYTES_SUFFIX)
|
||||
&& nameToNoArgMethod.containsKey(
|
||||
"get" + suffix.substring(0, suffix.length() - "Bytes".length()))) {
|
||||
// Heuristic to skip bytes based accessors for string fields.
|
||||
continue;
|
||||
}
|
||||
|
||||
String camelCase = suffix.substring(0, 1).toLowerCase() + suffix.substring(1);
|
||||
|
||||
// Try to reflectively get the value and toString() the field as if it were optional. This
|
||||
// only works if the method names have not be proguarded out or renamed.
|
||||
Method getMethod = nameToNoArgMethod.get("get" + suffix);
|
||||
Method hasMethod = nameToNoArgMethod.get("has" + suffix);
|
||||
// TODO(dweis): Fix proto3 semantics.
|
||||
if (getMethod != null) {
|
||||
Object value = GeneratedMessageLite.invokeOrDie(getMethod, messageLite);
|
||||
final boolean hasValue = hasMethod == null
|
||||
? !isDefaultValue(value)
|
||||
: (Boolean) GeneratedMessageLite.invokeOrDie(hasMethod, messageLite);
|
||||
// TODO(dweis): This doesn't stop printing oneof case twice: value and enum style.
|
||||
if (hasValue) {
|
||||
printField(
|
||||
buffer,
|
||||
indent,
|
||||
camelCaseToSnakeCase(camelCase),
|
||||
value);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (messageLite instanceof GeneratedMessageLite.ExtendableMessage) {
|
||||
Iterator<Map.Entry<GeneratedMessageLite.ExtensionDescriptor, Object>> iter =
|
||||
((GeneratedMessageLite.ExtendableMessage<?, ?>) messageLite).extensions.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Map.Entry<GeneratedMessageLite.ExtensionDescriptor, Object> entry = iter.next();
|
||||
printField(buffer, indent, "[" + entry.getKey().getNumber() + "]", entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
if (((GeneratedMessageLite<?, ?>) messageLite).unknownFields != null) {
|
||||
((GeneratedMessageLite<?, ?>) messageLite).unknownFields.printWithIndent(buffer, indent);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isDefaultValue(Object o) {
|
||||
if (o instanceof Boolean) {
|
||||
return !((Boolean) o);
|
||||
}
|
||||
if (o instanceof Integer) {
|
||||
return ((Integer) o) == 0;
|
||||
}
|
||||
if (o instanceof Float) {
|
||||
return ((Float) o) == 0f;
|
||||
}
|
||||
if (o instanceof Double) {
|
||||
return ((Double) o) == 0d;
|
||||
}
|
||||
if (o instanceof String) {
|
||||
return o.equals("");
|
||||
}
|
||||
if (o instanceof ByteString) {
|
||||
return o.equals(ByteString.EMPTY);
|
||||
}
|
||||
if (o instanceof MessageLite) { // Can happen in oneofs.
|
||||
return o == ((MessageLite) o).getDefaultInstanceForType();
|
||||
}
|
||||
if (o instanceof java.lang.Enum<?>) { // Catches oneof enums.
|
||||
return ((java.lang.Enum<?>) o).ordinal() == 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a text proto field.
|
||||
*
|
||||
* <p>For use by generated code only.
|
||||
*
|
||||
* @param buffer the buffer to write to
|
||||
* @param indent the number of spaces the proto should be indented by
|
||||
* @param name the field name (in lower underscore case)
|
||||
* @param object the object value of the field
|
||||
*/
|
||||
static final void printField(StringBuilder buffer, int indent, String name, Object object) {
|
||||
if (object instanceof List<?>) {
|
||||
List<?> list = (List<?>) object;
|
||||
for (Object entry : list) {
|
||||
printField(buffer, indent, name, entry);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
buffer.append('\n');
|
||||
for (int i = 0; i < indent; i++) {
|
||||
buffer.append(' ');
|
||||
}
|
||||
buffer.append(name);
|
||||
|
||||
if (object instanceof String) {
|
||||
buffer.append(": \"").append(TextFormatEscaper.escapeText((String) object)).append('"');
|
||||
} else if (object instanceof ByteString) {
|
||||
buffer.append(": \"").append(TextFormatEscaper.escapeBytes((ByteString) object)).append('"');
|
||||
} else if (object instanceof GeneratedMessageLite) {
|
||||
buffer.append(" {");
|
||||
reflectivePrintWithIndent((GeneratedMessageLite<?, ?>) object, buffer, indent + 2);
|
||||
buffer.append("\n");
|
||||
for (int i = 0; i < indent; i++) {
|
||||
buffer.append(' ');
|
||||
}
|
||||
buffer.append("}");
|
||||
} else {
|
||||
buffer.append(": ").append(object.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private static final String camelCaseToSnakeCase(String camelCase) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < camelCase.length(); i++) {
|
||||
char ch = camelCase.charAt(i);
|
||||
if (Character.isUpperCase(ch)) {
|
||||
builder.append("_");
|
||||
}
|
||||
builder.append(Character.toLowerCase(ch));
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
@ -42,7 +42,7 @@ import java.util.Map;
|
||||
public interface MessageOrBuilder extends MessageLiteOrBuilder {
|
||||
|
||||
// (From MessageLite, re-declared here only for return type covariance.)
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
Message getDefaultInstanceForType();
|
||||
|
||||
/**
|
||||
|
@ -364,12 +364,14 @@ class MessageReflection {
|
||||
* Finishes the merge and returns the underlying object.
|
||||
*/
|
||||
Object finish();
|
||||
|
||||
}
|
||||
|
||||
static class BuilderAdapter implements MergeTarget {
|
||||
|
||||
private final Message.Builder builder;
|
||||
|
||||
@Override
|
||||
public Descriptors.Descriptor getDescriptorForType() {
|
||||
return builder.getDescriptorForType();
|
||||
}
|
||||
@ -378,6 +380,7 @@ class MessageReflection {
|
||||
this.builder = builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getField(Descriptors.FieldDescriptor field) {
|
||||
return builder.getField(field);
|
||||
}
|
||||
@ -387,25 +390,27 @@ class MessageReflection {
|
||||
return builder.hasField(field);
|
||||
}
|
||||
|
||||
public MergeTarget setField(Descriptors.FieldDescriptor field,
|
||||
Object value) {
|
||||
@Override
|
||||
public MergeTarget setField(Descriptors.FieldDescriptor field, Object value) {
|
||||
builder.setField(field, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MergeTarget clearField(Descriptors.FieldDescriptor field) {
|
||||
builder.clearField(field);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MergeTarget setRepeatedField(
|
||||
Descriptors.FieldDescriptor field, int index, Object value) {
|
||||
builder.setRepeatedField(field, index, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MergeTarget addRepeatedField(
|
||||
Descriptors.FieldDescriptor field, Object value) {
|
||||
@Override
|
||||
public MergeTarget addRepeatedField(Descriptors.FieldDescriptor field, Object value) {
|
||||
builder.addRepeatedField(field, value);
|
||||
return this;
|
||||
}
|
||||
@ -426,25 +431,30 @@ class MessageReflection {
|
||||
return builder.getOneofFieldDescriptor(oneof);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContainerType getContainerType() {
|
||||
return ContainerType.MESSAGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtensionRegistry.ExtensionInfo findExtensionByName(
|
||||
ExtensionRegistry registry, String name) {
|
||||
return registry.findImmutableExtensionByName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
|
||||
ExtensionRegistry registry, Descriptors.Descriptor containingType,
|
||||
int fieldNumber) {
|
||||
ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber) {
|
||||
return registry.findImmutableExtensionByNumber(containingType,
|
||||
fieldNumber);
|
||||
}
|
||||
|
||||
public Object parseGroup(CodedInputStream input,
|
||||
@Override
|
||||
public Object parseGroup(
|
||||
CodedInputStream input,
|
||||
ExtensionRegistryLite extensionRegistry,
|
||||
Descriptors.FieldDescriptor field, Message defaultInstance)
|
||||
Descriptors.FieldDescriptor field,
|
||||
Message defaultInstance)
|
||||
throws IOException {
|
||||
Message.Builder subBuilder;
|
||||
// When default instance is not null. The field is an extension field.
|
||||
@ -463,9 +473,12 @@ class MessageReflection {
|
||||
return subBuilder.buildPartial();
|
||||
}
|
||||
|
||||
public Object parseMessage(CodedInputStream input,
|
||||
@Override
|
||||
public Object parseMessage(
|
||||
CodedInputStream input,
|
||||
ExtensionRegistryLite extensionRegistry,
|
||||
Descriptors.FieldDescriptor field, Message defaultInstance)
|
||||
Descriptors.FieldDescriptor field,
|
||||
Message defaultInstance)
|
||||
throws IOException {
|
||||
Message.Builder subBuilder;
|
||||
// When default instance is not null. The field is an extension field.
|
||||
@ -484,9 +497,12 @@ class MessageReflection {
|
||||
return subBuilder.buildPartial();
|
||||
}
|
||||
|
||||
public Object parseMessageFromBytes(ByteString bytes,
|
||||
@Override
|
||||
public Object parseMessageFromBytes(
|
||||
ByteString bytes,
|
||||
ExtensionRegistryLite extensionRegistry,
|
||||
Descriptors.FieldDescriptor field, Message defaultInstance)
|
||||
Descriptors.FieldDescriptor field,
|
||||
Message defaultInstance)
|
||||
throws IOException {
|
||||
Message.Builder subBuilder;
|
||||
// When default instance is not null. The field is an extension field.
|
||||
@ -505,8 +521,9 @@ class MessageReflection {
|
||||
return subBuilder.buildPartial();
|
||||
}
|
||||
|
||||
public MergeTarget newMergeTargetForField(Descriptors.FieldDescriptor field,
|
||||
Message defaultInstance) {
|
||||
@Override
|
||||
public MergeTarget newMergeTargetForField(
|
||||
Descriptors.FieldDescriptor field, Message defaultInstance) {
|
||||
if (defaultInstance != null) {
|
||||
return new BuilderAdapter(
|
||||
defaultInstance.newBuilderForType());
|
||||
@ -515,8 +532,8 @@ class MessageReflection {
|
||||
}
|
||||
}
|
||||
|
||||
public WireFormat.Utf8Validation
|
||||
getUtf8Validation(Descriptors.FieldDescriptor descriptor) {
|
||||
@Override
|
||||
public WireFormat.Utf8Validation getUtf8Validation(Descriptors.FieldDescriptor descriptor) {
|
||||
if (descriptor.needsUtf8Check()) {
|
||||
return WireFormat.Utf8Validation.STRICT;
|
||||
}
|
||||
@ -528,9 +545,11 @@ class MessageReflection {
|
||||
return WireFormat.Utf8Validation.LOOSE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object finish() {
|
||||
return builder.buildPartial();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -542,38 +561,43 @@ class MessageReflection {
|
||||
this.extensions = extensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Descriptors.Descriptor getDescriptorForType() {
|
||||
throw new UnsupportedOperationException(
|
||||
"getDescriptorForType() called on FieldSet object");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getField(Descriptors.FieldDescriptor field) {
|
||||
return extensions.getField(field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasField(Descriptors.FieldDescriptor field) {
|
||||
return extensions.hasField(field);
|
||||
}
|
||||
|
||||
public MergeTarget setField(Descriptors.FieldDescriptor field,
|
||||
Object value) {
|
||||
@Override
|
||||
public MergeTarget setField(Descriptors.FieldDescriptor field, Object value) {
|
||||
extensions.setField(field, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MergeTarget clearField(Descriptors.FieldDescriptor field) {
|
||||
extensions.clearField(field);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MergeTarget setRepeatedField(
|
||||
Descriptors.FieldDescriptor field, int index, Object value) {
|
||||
extensions.setRepeatedField(field, index, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MergeTarget addRepeatedField(
|
||||
Descriptors.FieldDescriptor field, Object value) {
|
||||
@Override
|
||||
public MergeTarget addRepeatedField(Descriptors.FieldDescriptor field, Object value) {
|
||||
extensions.addRepeatedField(field, value);
|
||||
return this;
|
||||
}
|
||||
@ -594,25 +618,31 @@ class MessageReflection {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContainerType getContainerType() {
|
||||
return ContainerType.EXTENSION_SET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtensionRegistry.ExtensionInfo findExtensionByName(
|
||||
ExtensionRegistry registry, String name) {
|
||||
return registry.findImmutableExtensionByName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
|
||||
ExtensionRegistry registry, Descriptors.Descriptor containingType,
|
||||
int fieldNumber) {
|
||||
ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber) {
|
||||
return registry.findImmutableExtensionByNumber(containingType,
|
||||
fieldNumber);
|
||||
}
|
||||
|
||||
public Object parseGroup(CodedInputStream input,
|
||||
ExtensionRegistryLite registry, Descriptors.FieldDescriptor field,
|
||||
Message defaultInstance) throws IOException {
|
||||
@Override
|
||||
public Object parseGroup(
|
||||
CodedInputStream input,
|
||||
ExtensionRegistryLite registry,
|
||||
Descriptors.FieldDescriptor field,
|
||||
Message defaultInstance)
|
||||
throws IOException {
|
||||
Message.Builder subBuilder =
|
||||
defaultInstance.newBuilderForType();
|
||||
if (!field.isRepeated()) {
|
||||
@ -625,9 +655,13 @@ class MessageReflection {
|
||||
return subBuilder.buildPartial();
|
||||
}
|
||||
|
||||
public Object parseMessage(CodedInputStream input,
|
||||
ExtensionRegistryLite registry, Descriptors.FieldDescriptor field,
|
||||
Message defaultInstance) throws IOException {
|
||||
@Override
|
||||
public Object parseMessage(
|
||||
CodedInputStream input,
|
||||
ExtensionRegistryLite registry,
|
||||
Descriptors.FieldDescriptor field,
|
||||
Message defaultInstance)
|
||||
throws IOException {
|
||||
Message.Builder subBuilder =
|
||||
defaultInstance.newBuilderForType();
|
||||
if (!field.isRepeated()) {
|
||||
@ -640,9 +674,13 @@ class MessageReflection {
|
||||
return subBuilder.buildPartial();
|
||||
}
|
||||
|
||||
public Object parseMessageFromBytes(ByteString bytes,
|
||||
ExtensionRegistryLite registry, Descriptors.FieldDescriptor field,
|
||||
Message defaultInstance) throws IOException {
|
||||
@Override
|
||||
public Object parseMessageFromBytes(
|
||||
ByteString bytes,
|
||||
ExtensionRegistryLite registry,
|
||||
Descriptors.FieldDescriptor field,
|
||||
Message defaultInstance)
|
||||
throws IOException {
|
||||
Message.Builder subBuilder = defaultInstance.newBuilderForType();
|
||||
if (!field.isRepeated()) {
|
||||
Message originalMessage = (Message) getField(field);
|
||||
@ -654,14 +692,15 @@ class MessageReflection {
|
||||
return subBuilder.buildPartial();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MergeTarget newMergeTargetForField(
|
||||
Descriptors.FieldDescriptor descriptor, Message defaultInstance) {
|
||||
throw new UnsupportedOperationException(
|
||||
"newMergeTargetForField() called on FieldSet object");
|
||||
}
|
||||
|
||||
public WireFormat.Utf8Validation
|
||||
getUtf8Validation(Descriptors.FieldDescriptor descriptor) {
|
||||
@Override
|
||||
public WireFormat.Utf8Validation getUtf8Validation(Descriptors.FieldDescriptor descriptor) {
|
||||
if (descriptor.needsUtf8Check()) {
|
||||
return WireFormat.Utf8Validation.STRICT;
|
||||
}
|
||||
@ -669,10 +708,12 @@ class MessageReflection {
|
||||
return WireFormat.Utf8Validation.LOOSE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object finish() {
|
||||
throw new UnsupportedOperationException(
|
||||
"finish() called on FieldSet object");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -30,15 +30,14 @@
|
||||
|
||||
package com.google.protobuf;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.InvalidMarkException;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@ -54,7 +53,7 @@ final class NioByteString extends ByteString.LeafByteString {
|
||||
throw new NullPointerException("buffer");
|
||||
}
|
||||
|
||||
this.buffer = buffer.slice();
|
||||
this.buffer = buffer.slice().order(ByteOrder.nativeOrder());
|
||||
}
|
||||
|
||||
// =================================================================
|
||||
@ -119,7 +118,7 @@ final class NioByteString extends ByteString.LeafByteString {
|
||||
|
||||
@Override
|
||||
public void writeTo(OutputStream out) throws IOException {
|
||||
writeToInternal(out, buffer.position(), buffer.remaining());
|
||||
out.write(toByteArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -137,14 +136,12 @@ final class NioByteString extends ByteString.LeafByteString {
|
||||
return;
|
||||
}
|
||||
|
||||
// Slow path
|
||||
if (out instanceof FileOutputStream || numberToWrite >= 8192) {
|
||||
// Use a channel to write out the ByteBuffer.
|
||||
Channels.newChannel(out).write(slice(sourceOffset, sourceOffset + numberToWrite));
|
||||
} else {
|
||||
// Just copy the data to an array and write it.
|
||||
out.write(toByteArray());
|
||||
}
|
||||
ByteBufferWriter.write(slice(sourceOffset, sourceOffset + numberToWrite), out);
|
||||
}
|
||||
|
||||
@Override
|
||||
void writeTo(ByteOutput output) throws IOException {
|
||||
output.writeLazy(buffer.slice());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -159,46 +156,30 @@ final class NioByteString extends ByteString.LeafByteString {
|
||||
|
||||
@Override
|
||||
protected String toStringInternal(Charset charset) {
|
||||
byte[] bytes;
|
||||
int offset;
|
||||
final byte[] bytes;
|
||||
final int offset;
|
||||
final int length;
|
||||
if (buffer.hasArray()) {
|
||||
bytes = buffer.array();
|
||||
offset = buffer.arrayOffset() + buffer.position();
|
||||
length = buffer.remaining();
|
||||
} else {
|
||||
// TODO(nathanmittler): Can we optimize this?
|
||||
bytes = toByteArray();
|
||||
offset = 0;
|
||||
length = bytes.length;
|
||||
}
|
||||
return new String(bytes, offset, size(), charset);
|
||||
return new String(bytes, offset, length, charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidUtf8() {
|
||||
// TODO(nathanmittler): add a ByteBuffer fork for Utf8.isValidUtf8 to avoid the copy
|
||||
byte[] bytes;
|
||||
int startIndex;
|
||||
if (buffer.hasArray()) {
|
||||
bytes = buffer.array();
|
||||
startIndex = buffer.arrayOffset() + buffer.position();
|
||||
} else {
|
||||
bytes = toByteArray();
|
||||
startIndex = 0;
|
||||
}
|
||||
return Utf8.isValidUtf8(bytes, startIndex, startIndex + size());
|
||||
return Utf8.isValidUtf8(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int partialIsValidUtf8(int state, int offset, int length) {
|
||||
// TODO(nathanmittler): TODO add a ByteBuffer fork for Utf8.partialIsValidUtf8 to avoid the copy
|
||||
byte[] bytes;
|
||||
int startIndex;
|
||||
if (buffer.hasArray()) {
|
||||
bytes = buffer.array();
|
||||
startIndex = buffer.arrayOffset() + buffer.position();
|
||||
} else {
|
||||
bytes = toByteArray();
|
||||
startIndex = 0;
|
||||
}
|
||||
return Utf8.partialIsValidUtf8(state, bytes, startIndex, startIndex + size());
|
||||
return Utf8.partialIsValidUtf8(state, buffer, offset, offset + length);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -30,7 +30,6 @@
|
||||
|
||||
package com.google.protobuf;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
|
@ -38,7 +38,7 @@ import java.util.List;
|
||||
/**
|
||||
* Implements {@link ProtobufList} for non-primitive and {@link String} types.
|
||||
*/
|
||||
class ProtobufArrayList<E> extends AbstractProtobufList<E> {
|
||||
final class ProtobufArrayList<E> extends AbstractProtobufList<E> {
|
||||
|
||||
private static final ProtobufArrayList<Object> EMPTY_LIST = new ProtobufArrayList<Object>();
|
||||
static {
|
||||
@ -51,17 +51,23 @@ class ProtobufArrayList<E> extends AbstractProtobufList<E> {
|
||||
}
|
||||
|
||||
private final List<E> list;
|
||||
|
||||
|
||||
ProtobufArrayList() {
|
||||
list = new ArrayList<E>();
|
||||
this(new ArrayList<E>(DEFAULT_CAPACITY));
|
||||
}
|
||||
|
||||
ProtobufArrayList(List<E> toCopy) {
|
||||
list = new ArrayList<E>(toCopy);
|
||||
private ProtobufArrayList(List<E> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
ProtobufArrayList(int capacity) {
|
||||
list = new ArrayList<E>(capacity);
|
||||
|
||||
@Override
|
||||
public ProtobufArrayList<E> mutableCopyWithCapacity(int capacity) {
|
||||
if (capacity < size()) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
List<E> newList = new ArrayList<E>(capacity);
|
||||
newList.addAll(list);
|
||||
return new ProtobufArrayList<E>(newList);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -42,6 +42,7 @@ public interface ProtocolMessageEnum extends Internal.EnumLite {
|
||||
/**
|
||||
* Return the value's numeric value as defined in the .proto file.
|
||||
*/
|
||||
@Override
|
||||
int getNumber();
|
||||
|
||||
/**
|
||||
|
@ -579,7 +579,7 @@ public class RepeatedFieldBuilder
|
||||
}
|
||||
}
|
||||
|
||||
//@Override (Java 1.6 override semantics, but we must support 1.5)
|
||||
@Override
|
||||
public void markDirty() {
|
||||
onChanged();
|
||||
}
|
||||
@ -621,10 +621,12 @@ public class RepeatedFieldBuilder
|
||||
this.builder = builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return this.builder.getCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MType get(int index) {
|
||||
return builder.getMessage(index);
|
||||
}
|
||||
@ -654,10 +656,12 @@ public class RepeatedFieldBuilder
|
||||
this.builder = builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return this.builder.getCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BType get(int index) {
|
||||
return builder.getBuilder(index);
|
||||
}
|
||||
@ -687,10 +691,12 @@ public class RepeatedFieldBuilder
|
||||
this.builder = builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return this.builder.getCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IType get(int index) {
|
||||
return builder.getMessageOrBuilder(index);
|
||||
}
|
||||
|
@ -48,10 +48,11 @@ import java.util.Stack;
|
||||
/**
|
||||
* Class to represent {@code ByteStrings} formed by concatenation of other
|
||||
* ByteStrings, without copying the data in the pieces. The concatenation is
|
||||
* represented as a tree whose leaf nodes are each a {@link LiteralByteString}.
|
||||
* represented as a tree whose leaf nodes are each a
|
||||
* {@link com.google.protobuf.ByteString.LeafByteString}.
|
||||
*
|
||||
* <p>Most of the operation here is inspired by the now-famous paper <a
|
||||
* href="http://www.cs.ubc.ca/local/reading/proceedings/spe91-95/spe/vol25/issue12/spe986.pdf">
|
||||
* href="https://web.archive.org/web/20060202015456/http://www.cs.ubc.ca/local/reading/proceedings/spe91-95/spe/vol25/issue12/spe986.pdf">
|
||||
* BAP95 </a> Ropes: an Alternative to Strings hans-j. boehm, russ atkinson and
|
||||
* michael plass
|
||||
*
|
||||
@ -139,8 +140,9 @@ final class RopeByteString extends ByteString {
|
||||
/**
|
||||
* Concatenate the given strings while performing various optimizations to
|
||||
* slow the growth rate of tree depth and tree node count. The result is
|
||||
* either a {@link LiteralByteString} or a {@link RopeByteString}
|
||||
* depending on which optimizations, if any, were applied.
|
||||
* either a {@link com.google.protobuf.ByteString.LeafByteString} or a
|
||||
* {@link RopeByteString} depending on which optimizations, if any, were
|
||||
* applied.
|
||||
*
|
||||
* <p>Small pieces of length less than {@link
|
||||
* ByteString#CONCATENATE_BY_COPY_SIZE} may be copied by value here, as in
|
||||
@ -294,8 +296,7 @@ final class RopeByteString extends ByteString {
|
||||
*
|
||||
* <p>Substrings of {@code length < 2} should result in at most a single
|
||||
* recursive call chain, terminating at a leaf node. Thus the result will be a
|
||||
* {@link LiteralByteString}. {@link #RopeByteString(ByteString,
|
||||
* ByteString)}.
|
||||
* {@link com.google.protobuf.ByteString.LeafByteString}.
|
||||
*
|
||||
* @param beginIndex start at this index
|
||||
* @param endIndex the last character is the one before this index
|
||||
@ -368,7 +369,7 @@ final class RopeByteString extends ByteString {
|
||||
|
||||
@Override
|
||||
public List<ByteBuffer> asReadOnlyByteBufferList() {
|
||||
// Walk through the list of LiteralByteString's that make up this
|
||||
// Walk through the list of LeafByteString's that make up this
|
||||
// rope, and add each one as a read-only ByteBuffer.
|
||||
List<ByteBuffer> result = new ArrayList<ByteBuffer>();
|
||||
PieceIterator pieces = new PieceIterator(this);
|
||||
@ -399,6 +400,12 @@ final class RopeByteString extends ByteString {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void writeTo(ByteOutput output) throws IOException {
|
||||
left.writeTo(output);
|
||||
right.writeTo(output);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String toStringInternal(Charset charset) {
|
||||
return new String(toByteArray(), charset);
|
||||
@ -709,9 +716,10 @@ final class RopeByteString extends ByteString {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next item and advances one {@code LiteralByteString}.
|
||||
* Returns the next item and advances one
|
||||
* {@link com.google.protobuf.ByteString.LeafByteString}.
|
||||
*
|
||||
* @return next non-empty LiteralByteString or {@code null}
|
||||
* @return next non-empty LeafByteString or {@code null}
|
||||
*/
|
||||
@Override
|
||||
public LeafByteString next() {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user