Merge pull request #91 from xfxyjwf/android_nano
Merge nano proto into protobuf repository.
This commit is contained in:
commit
aa8ef98a1f
486
Android.mk
Normal file
486
Android.mk
Normal file
@ -0,0 +1,486 @@
|
|||||||
|
# Copyright (C) 2009 The Android Open Source Project
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
LOCAL_PATH := $(call my-dir)
|
||||||
|
|
||||||
|
IGNORED_WARNINGS := -Wno-sign-compare -Wno-unused-parameter -Wno-sign-promo
|
||||||
|
|
||||||
|
CC_LITE_SRC_FILES := \
|
||||||
|
src/google/protobuf/stubs/common.cc \
|
||||||
|
src/google/protobuf/stubs/once.cc \
|
||||||
|
src/google/protobuf/stubs/hash.cc \
|
||||||
|
src/google/protobuf/stubs/hash.h \
|
||||||
|
src/google/protobuf/stubs/map-util.h \
|
||||||
|
src/google/protobuf/stubs/stl_util-inl.h \
|
||||||
|
src/google/protobuf/extension_set.cc \
|
||||||
|
src/google/protobuf/generated_message_util.cc \
|
||||||
|
src/google/protobuf/message_lite.cc \
|
||||||
|
src/google/protobuf/repeated_field.cc \
|
||||||
|
src/google/protobuf/wire_format_lite.cc \
|
||||||
|
src/google/protobuf/io/coded_stream.cc \
|
||||||
|
src/google/protobuf/io/coded_stream_inl.h \
|
||||||
|
src/google/protobuf/io/zero_copy_stream.cc \
|
||||||
|
src/google/protobuf/io/zero_copy_stream_impl_lite.cc
|
||||||
|
|
||||||
|
JAVA_LITE_SRC_FILES := \
|
||||||
|
java/src/main/java/com/google/protobuf/UninitializedMessageException.java \
|
||||||
|
java/src/main/java/com/google/protobuf/MessageLite.java \
|
||||||
|
java/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java \
|
||||||
|
java/src/main/java/com/google/protobuf/CodedOutputStream.java \
|
||||||
|
java/src/main/java/com/google/protobuf/ByteString.java \
|
||||||
|
java/src/main/java/com/google/protobuf/CodedInputStream.java \
|
||||||
|
java/src/main/java/com/google/protobuf/ExtensionRegistryLite.java \
|
||||||
|
java/src/main/java/com/google/protobuf/AbstractMessageLite.java \
|
||||||
|
java/src/main/java/com/google/protobuf/FieldSet.java \
|
||||||
|
java/src/main/java/com/google/protobuf/Internal.java \
|
||||||
|
java/src/main/java/com/google/protobuf/WireFormat.java \
|
||||||
|
java/src/main/java/com/google/protobuf/GeneratedMessageLite.java
|
||||||
|
|
||||||
|
COMPILER_SRC_FILES := \
|
||||||
|
src/google/protobuf/descriptor.cc \
|
||||||
|
src/google/protobuf/descriptor.pb.cc \
|
||||||
|
src/google/protobuf/descriptor_database.cc \
|
||||||
|
src/google/protobuf/dynamic_message.cc \
|
||||||
|
src/google/protobuf/extension_set.cc \
|
||||||
|
src/google/protobuf/extension_set_heavy.cc \
|
||||||
|
src/google/protobuf/generated_message_reflection.cc \
|
||||||
|
src/google/protobuf/generated_message_util.cc \
|
||||||
|
src/google/protobuf/message.cc \
|
||||||
|
src/google/protobuf/message_lite.cc \
|
||||||
|
src/google/protobuf/reflection_ops.cc \
|
||||||
|
src/google/protobuf/repeated_field.cc \
|
||||||
|
src/google/protobuf/service.cc \
|
||||||
|
src/google/protobuf/text_format.cc \
|
||||||
|
src/google/protobuf/unknown_field_set.cc \
|
||||||
|
src/google/protobuf/wire_format.cc \
|
||||||
|
src/google/protobuf/wire_format_lite.cc \
|
||||||
|
src/google/protobuf/compiler/code_generator.cc \
|
||||||
|
src/google/protobuf/compiler/command_line_interface.cc \
|
||||||
|
src/google/protobuf/compiler/importer.cc \
|
||||||
|
src/google/protobuf/compiler/main.cc \
|
||||||
|
src/google/protobuf/compiler/parser.cc \
|
||||||
|
src/google/protobuf/compiler/plugin.cc \
|
||||||
|
src/google/protobuf/compiler/plugin.pb.cc \
|
||||||
|
src/google/protobuf/compiler/subprocess.cc \
|
||||||
|
src/google/protobuf/compiler/zip_writer.cc \
|
||||||
|
src/google/protobuf/compiler/cpp/cpp_enum.cc \
|
||||||
|
src/google/protobuf/compiler/cpp/cpp_enum_field.cc \
|
||||||
|
src/google/protobuf/compiler/cpp/cpp_extension.cc \
|
||||||
|
src/google/protobuf/compiler/cpp/cpp_field.cc \
|
||||||
|
src/google/protobuf/compiler/cpp/cpp_file.cc \
|
||||||
|
src/google/protobuf/compiler/cpp/cpp_generator.cc \
|
||||||
|
src/google/protobuf/compiler/cpp/cpp_helpers.cc \
|
||||||
|
src/google/protobuf/compiler/cpp/cpp_message.cc \
|
||||||
|
src/google/protobuf/compiler/cpp/cpp_message_field.cc \
|
||||||
|
src/google/protobuf/compiler/cpp/cpp_primitive_field.cc \
|
||||||
|
src/google/protobuf/compiler/cpp/cpp_service.cc \
|
||||||
|
src/google/protobuf/compiler/cpp/cpp_string_field.cc \
|
||||||
|
src/google/protobuf/compiler/java/java_enum.cc \
|
||||||
|
src/google/protobuf/compiler/java/java_enum_field.cc \
|
||||||
|
src/google/protobuf/compiler/java/java_extension.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 \
|
||||||
|
src/google/protobuf/compiler/java/java_helpers.cc \
|
||||||
|
src/google/protobuf/compiler/java/java_message.cc \
|
||||||
|
src/google/protobuf/compiler/java/java_message_field.cc \
|
||||||
|
src/google/protobuf/compiler/java/java_primitive_field.cc \
|
||||||
|
src/google/protobuf/compiler/java/java_service.cc \
|
||||||
|
src/google/protobuf/compiler/javamicro/javamicro_enum.cc \
|
||||||
|
src/google/protobuf/compiler/javamicro/javamicro_enum_field.cc \
|
||||||
|
src/google/protobuf/compiler/javamicro/javamicro_field.cc \
|
||||||
|
src/google/protobuf/compiler/javamicro/javamicro_file.cc \
|
||||||
|
src/google/protobuf/compiler/javamicro/javamicro_generator.cc \
|
||||||
|
src/google/protobuf/compiler/javamicro/javamicro_helpers.cc \
|
||||||
|
src/google/protobuf/compiler/javamicro/javamicro_message.cc \
|
||||||
|
src/google/protobuf/compiler/javamicro/javamicro_message_field.cc \
|
||||||
|
src/google/protobuf/compiler/javamicro/javamicro_primitive_field.cc \
|
||||||
|
src/google/protobuf/compiler/javanano/javanano_enum.cc \
|
||||||
|
src/google/protobuf/compiler/javanano/javanano_enum_field.cc \
|
||||||
|
src/google/protobuf/compiler/javanano/javanano_extension.cc \
|
||||||
|
src/google/protobuf/compiler/javanano/javanano_field.cc \
|
||||||
|
src/google/protobuf/compiler/javanano/javanano_file.cc \
|
||||||
|
src/google/protobuf/compiler/javanano/javanano_generator.cc \
|
||||||
|
src/google/protobuf/compiler/javanano/javanano_helpers.cc \
|
||||||
|
src/google/protobuf/compiler/javanano/javanano_message.cc \
|
||||||
|
src/google/protobuf/compiler/javanano/javanano_message_field.cc \
|
||||||
|
src/google/protobuf/compiler/javanano/javanano_primitive_field.cc \
|
||||||
|
src/google/protobuf/compiler/python/python_generator.cc \
|
||||||
|
src/google/protobuf/io/coded_stream.cc \
|
||||||
|
src/google/protobuf/io/gzip_stream.cc \
|
||||||
|
src/google/protobuf/io/printer.cc \
|
||||||
|
src/google/protobuf/io/tokenizer.cc \
|
||||||
|
src/google/protobuf/io/zero_copy_stream.cc \
|
||||||
|
src/google/protobuf/io/zero_copy_stream_impl.cc \
|
||||||
|
src/google/protobuf/io/zero_copy_stream_impl_lite.cc \
|
||||||
|
src/google/protobuf/stubs/common.cc \
|
||||||
|
src/google/protobuf/stubs/hash.cc \
|
||||||
|
src/google/protobuf/stubs/once.cc \
|
||||||
|
src/google/protobuf/stubs/structurally_valid.cc \
|
||||||
|
src/google/protobuf/stubs/strutil.cc \
|
||||||
|
src/google/protobuf/stubs/substitute.cc
|
||||||
|
|
||||||
|
# Java nano library (for device-side users)
|
||||||
|
# =======================================================
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := libprotobuf-java-nano
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
LOCAL_SDK_VERSION := 8
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := $(call all-java-files-under, java/src/main/java/com/google/protobuf/nano)
|
||||||
|
LOCAL_SRC_FILES += $(call all-java-files-under, java/src/device/main/java/com/google/protobuf/nano)
|
||||||
|
|
||||||
|
include $(BUILD_STATIC_JAVA_LIBRARY)
|
||||||
|
|
||||||
|
# Java nano library (for host-side users)
|
||||||
|
# =======================================================
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := host-libprotobuf-java-nano
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := $(call all-java-files-under, java/src/main/java/com/google/protobuf/nano)
|
||||||
|
|
||||||
|
include $(BUILD_HOST_JAVA_LIBRARY)
|
||||||
|
|
||||||
|
# Java micro library (for device-side users)
|
||||||
|
# =======================================================
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := libprotobuf-java-micro
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
LOCAL_SDK_VERSION := 8
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := $(call all-java-files-under, java/src/main/java/com/google/protobuf/micro)
|
||||||
|
|
||||||
|
include $(BUILD_STATIC_JAVA_LIBRARY)
|
||||||
|
|
||||||
|
# Java micro library (for host-side users)
|
||||||
|
# =======================================================
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := host-libprotobuf-java-micro
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := $(call all-java-files-under, java/src/main/java/com/google/protobuf/micro)
|
||||||
|
|
||||||
|
include $(BUILD_HOST_JAVA_LIBRARY)
|
||||||
|
|
||||||
|
# Java lite library (for device-side users)
|
||||||
|
# =======================================================
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := libprotobuf-java-lite
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
LOCAL_SDK_VERSION := 8
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := $(JAVA_LITE_SRC_FILES)
|
||||||
|
|
||||||
|
include $(BUILD_STATIC_JAVA_LIBRARY)
|
||||||
|
|
||||||
|
# Java lite library (for host-side users)
|
||||||
|
# =======================================================
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := host-libprotobuf-java-lite
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := $(JAVA_LITE_SRC_FILES)
|
||||||
|
|
||||||
|
include $(BUILD_HOST_JAVA_LIBRARY)
|
||||||
|
|
||||||
|
# C++ lite library
|
||||||
|
# =======================================================
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := libprotobuf-cpp-lite
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
|
||||||
|
LOCAL_CPP_EXTENSION := .cc
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := $(CC_LITE_SRC_FILES)
|
||||||
|
|
||||||
|
LOCAL_C_INCLUDES := \
|
||||||
|
$(LOCAL_PATH)/android \
|
||||||
|
$(LOCAL_PATH)/src
|
||||||
|
|
||||||
|
# Define the header files to be copied
|
||||||
|
#LOCAL_COPY_HEADERS := \
|
||||||
|
# src/google/protobuf/stubs/once.h \
|
||||||
|
# src/google/protobuf/stubs/common.h \
|
||||||
|
# src/google/protobuf/io/coded_stream.h \
|
||||||
|
# src/google/protobuf/generated_message_util.h \
|
||||||
|
# src/google/protobuf/repeated_field.h \
|
||||||
|
# src/google/protobuf/extension_set.h \
|
||||||
|
# src/google/protobuf/wire_format_lite_inl.h
|
||||||
|
#
|
||||||
|
#LOCAL_COPY_HEADERS_TO := $(LOCAL_MODULE)
|
||||||
|
|
||||||
|
LOCAL_CFLAGS := -DGOOGLE_PROTOBUF_NO_RTTI $(IGNORED_WARNINGS)
|
||||||
|
|
||||||
|
# These are the minimum versions and don't need to be update.
|
||||||
|
ifeq ($(TARGET_ARCH),arm)
|
||||||
|
LOCAL_SDK_VERSION := 8
|
||||||
|
else
|
||||||
|
# x86/mips support only available from API 9.
|
||||||
|
LOCAL_SDK_VERSION := 9
|
||||||
|
endif
|
||||||
|
LOCAL_NDK_STL_VARIANT := stlport_static
|
||||||
|
|
||||||
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
|
|
||||||
|
# C++ lite library (libc++ flavored for the platform)
|
||||||
|
# =======================================================
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := libprotobuf-cpp-lite
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
|
||||||
|
LOCAL_CPP_EXTENSION := .cc
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := $(CC_LITE_SRC_FILES)
|
||||||
|
|
||||||
|
LOCAL_C_INCLUDES := \
|
||||||
|
$(LOCAL_PATH)/android \
|
||||||
|
$(LOCAL_PATH)/src
|
||||||
|
|
||||||
|
LOCAL_CFLAGS := -DGOOGLE_PROTOBUF_NO_RTTI $(IGNORED_WARNINGS)
|
||||||
|
|
||||||
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
|
|
||||||
|
# C++ full library
|
||||||
|
# =======================================================
|
||||||
|
protobuf_cc_full_src_files := \
|
||||||
|
$(CC_LITE_SRC_FILES) \
|
||||||
|
src/google/protobuf/stubs/strutil.cc \
|
||||||
|
src/google/protobuf/stubs/strutil.h \
|
||||||
|
src/google/protobuf/stubs/substitute.cc \
|
||||||
|
src/google/protobuf/stubs/substitute.h \
|
||||||
|
src/google/protobuf/stubs/structurally_valid.cc \
|
||||||
|
src/google/protobuf/descriptor.cc \
|
||||||
|
src/google/protobuf/descriptor.pb.cc \
|
||||||
|
src/google/protobuf/descriptor_database.cc \
|
||||||
|
src/google/protobuf/dynamic_message.cc \
|
||||||
|
src/google/protobuf/extension_set_heavy.cc \
|
||||||
|
src/google/protobuf/generated_message_reflection.cc \
|
||||||
|
src/google/protobuf/message.cc \
|
||||||
|
src/google/protobuf/reflection_ops.cc \
|
||||||
|
src/google/protobuf/service.cc \
|
||||||
|
src/google/protobuf/text_format.cc \
|
||||||
|
src/google/protobuf/unknown_field_set.cc \
|
||||||
|
src/google/protobuf/wire_format.cc \
|
||||||
|
src/google/protobuf/io/gzip_stream.cc \
|
||||||
|
src/google/protobuf/io/printer.cc \
|
||||||
|
src/google/protobuf/io/tokenizer.cc \
|
||||||
|
src/google/protobuf/io/zero_copy_stream_impl.cc \
|
||||||
|
src/google/protobuf/compiler/importer.cc \
|
||||||
|
src/google/protobuf/compiler/parser.cc
|
||||||
|
|
||||||
|
# C++ full library - stlport version
|
||||||
|
# =======================================================
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := libprotobuf-cpp-full
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
LOCAL_CPP_EXTENSION := .cc
|
||||||
|
LOCAL_SRC_FILES := $(protobuf_cc_full_src_files)
|
||||||
|
LOCAL_C_INCLUDES := \
|
||||||
|
$(LOCAL_PATH)/android \
|
||||||
|
external/zlib \
|
||||||
|
$(LOCAL_PATH)/src
|
||||||
|
|
||||||
|
# Define the header files to be copied
|
||||||
|
#LOCAL_COPY_HEADERS := \
|
||||||
|
# src/google/protobuf/stubs/once.h \
|
||||||
|
# src/google/protobuf/stubs/common.h \
|
||||||
|
# src/google/protobuf/io/coded_stream.h \
|
||||||
|
# src/google/protobuf/generated_message_util.h \
|
||||||
|
# src/google/protobuf/repeated_field.h \
|
||||||
|
# src/google/protobuf/extension_set.h \
|
||||||
|
# src/google/protobuf/wire_format_lite_inl.h
|
||||||
|
#
|
||||||
|
#LOCAL_COPY_HEADERS_TO := $(LOCAL_MODULE)
|
||||||
|
|
||||||
|
LOCAL_CFLAGS := -DGOOGLE_PROTOBUF_NO_RTTI $(IGNORED_WARNINGS)
|
||||||
|
|
||||||
|
# These are the minimum versions and don't need to be update.
|
||||||
|
ifeq ($(TARGET_ARCH),arm)
|
||||||
|
LOCAL_SDK_VERSION := 8
|
||||||
|
else
|
||||||
|
# x86/mips support only available from API 9.
|
||||||
|
LOCAL_SDK_VERSION := 9
|
||||||
|
endif
|
||||||
|
LOCAL_NDK_STL_VARIANT := stlport_static
|
||||||
|
|
||||||
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
|
|
||||||
|
# C++ full library - Gnustl+rtti version
|
||||||
|
# =======================================================
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := libprotobuf-cpp-full-gnustl-rtti
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
LOCAL_CPP_EXTENSION := .cc
|
||||||
|
LOCAL_SRC_FILES := $(protobuf_cc_full_src_files)
|
||||||
|
LOCAL_C_INCLUDES := \
|
||||||
|
$(LOCAL_PATH)/android \
|
||||||
|
external/zlib \
|
||||||
|
$(LOCAL_PATH)/src
|
||||||
|
|
||||||
|
LOCAL_CFLAGS := -frtti $(IGNORED_WARNINGS)
|
||||||
|
LOCAL_SDK_VERSION := 14
|
||||||
|
LOCAL_NDK_STL_VARIANT := gnustl_static
|
||||||
|
|
||||||
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
|
|
||||||
|
# C++ full library - libc++ version for the platform
|
||||||
|
# =======================================================
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := libprotobuf-cpp-full
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
LOCAL_CPP_EXTENSION := .cc
|
||||||
|
LOCAL_SRC_FILES := $(protobuf_cc_full_src_files)
|
||||||
|
LOCAL_C_INCLUDES := \
|
||||||
|
$(LOCAL_PATH)/android \
|
||||||
|
external/zlib \
|
||||||
|
$(LOCAL_PATH)/src
|
||||||
|
|
||||||
|
LOCAL_CFLAGS := -DGOOGLE_PROTOBUF_NO_RTTI $(IGNORED_WARNINGS)
|
||||||
|
LOCAL_SHARED_LIBRARIES := libz
|
||||||
|
|
||||||
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
|
|
||||||
|
# Clean temp vars
|
||||||
|
protobuf_cc_full_src_files :=
|
||||||
|
|
||||||
|
|
||||||
|
# Android Protocol buffer compiler, aprotoc (host executable)
|
||||||
|
# used by the build systems as $(PROTOC) defined in
|
||||||
|
# build/core/config.mk
|
||||||
|
# =======================================================
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := aprotoc
|
||||||
|
LOCAL_MODULE_CLASS := EXECUTABLES
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
|
||||||
|
LOCAL_CPP_EXTENSION := .cc
|
||||||
|
LOCAL_SRC_FILES := $(COMPILER_SRC_FILES)
|
||||||
|
|
||||||
|
LOCAL_C_INCLUDES := \
|
||||||
|
$(LOCAL_PATH)/android \
|
||||||
|
external/zlib \
|
||||||
|
$(LOCAL_PATH)/src
|
||||||
|
|
||||||
|
LOCAL_STATIC_LIBRARIES += libz
|
||||||
|
|
||||||
|
ifneq ($(HOST_OS),windows)
|
||||||
|
LOCAL_LDLIBS := -lpthread
|
||||||
|
endif
|
||||||
|
|
||||||
|
LOCAL_CFLAGS := $(IGNORED_WARNINGS)
|
||||||
|
|
||||||
|
include $(BUILD_HOST_EXECUTABLE)
|
||||||
|
|
||||||
|
# To test java proto params build rules.
|
||||||
|
# =======================================================
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := aprotoc-test-nano-params
|
||||||
|
LOCAL_MODULE_TAGS := tests
|
||||||
|
LOCAL_SDK_VERSION := current
|
||||||
|
|
||||||
|
LOCAL_PROTOC_OPTIMIZE_TYPE := nano
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := \
|
||||||
|
src/google/protobuf/unittest_import_nano.proto \
|
||||||
|
src/google/protobuf/unittest_simple_nano.proto \
|
||||||
|
src/google/protobuf/unittest_stringutf8_nano.proto \
|
||||||
|
src/google/protobuf/unittest_recursive_nano.proto
|
||||||
|
|
||||||
|
|
||||||
|
LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/src
|
||||||
|
|
||||||
|
LOCAL_PROTO_JAVA_OUTPUT_PARAMS := \
|
||||||
|
java_package = $(LOCAL_PATH)/src/google/protobuf/unittest_import_nano.proto|com.google.protobuf.nano, \
|
||||||
|
java_outer_classname = $(LOCAL_PATH)/src/google/protobuf/unittest_import_nano.proto|UnittestImportNano
|
||||||
|
|
||||||
|
include $(BUILD_STATIC_JAVA_LIBRARY)
|
||||||
|
|
||||||
|
# To test Android-specific nanoproto features.
|
||||||
|
# =======================================================
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
# Parcelable messages
|
||||||
|
LOCAL_MODULE := android-nano-test-parcelable
|
||||||
|
LOCAL_MODULE_TAGS := tests
|
||||||
|
LOCAL_SDK_VERSION := current
|
||||||
|
|
||||||
|
LOCAL_PROTOC_OPTIMIZE_TYPE := nano
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := src/google/protobuf/unittest_simple_nano.proto
|
||||||
|
|
||||||
|
LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/src
|
||||||
|
|
||||||
|
LOCAL_PROTO_JAVA_OUTPUT_PARAMS := \
|
||||||
|
parcelable_messages = true
|
||||||
|
|
||||||
|
include $(BUILD_STATIC_JAVA_LIBRARY)
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
# Parcelable and extendable messages
|
||||||
|
LOCAL_MODULE := android-nano-test-parcelable-extendable
|
||||||
|
LOCAL_MODULE_TAGS := tests
|
||||||
|
LOCAL_SDK_VERSION := current
|
||||||
|
|
||||||
|
LOCAL_PROTOC_OPTIMIZE_TYPE := nano
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := src/google/protobuf/unittest_extension_nano.proto
|
||||||
|
|
||||||
|
LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/src
|
||||||
|
|
||||||
|
LOCAL_PROTO_JAVA_OUTPUT_PARAMS := \
|
||||||
|
parcelable_messages = true, \
|
||||||
|
store_unknown_fields = true
|
||||||
|
|
||||||
|
include $(BUILD_STATIC_JAVA_LIBRARY)
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
# Test APK
|
||||||
|
LOCAL_PACKAGE_NAME := NanoAndroidTest
|
||||||
|
|
||||||
|
LOCAL_SDK_VERSION := 8
|
||||||
|
|
||||||
|
LOCAL_MODULE_TAGS := tests
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := $(call all-java-files-under, java/src/device/test/java/com/google/protobuf/nano)
|
||||||
|
|
||||||
|
LOCAL_MANIFEST_FILE := java/src/device/test/AndroidManifest.xml
|
||||||
|
|
||||||
|
LOCAL_STATIC_JAVA_LIBRARIES := libprotobuf-java-nano \
|
||||||
|
android-nano-test-parcelable \
|
||||||
|
android-nano-test-parcelable-extendable
|
||||||
|
|
||||||
|
LOCAL_DEX_PREOPT := false
|
||||||
|
|
||||||
|
include $(BUILD_PACKAGE)
|
||||||
|
|
||||||
|
# 2.3.0 prebuilts for backwards compatibility.
|
||||||
|
include $(LOCAL_PATH)/prebuilts/Android.mk
|
354
javanano/README.txt
Normal file
354
javanano/README.txt
Normal file
@ -0,0 +1,354 @@
|
|||||||
|
Protocol Buffers - Google's data interchange format
|
||||||
|
Copyright 2008 Google Inc.
|
||||||
|
|
||||||
|
This directory contains the Java Protocol Buffers Nano runtime library.
|
||||||
|
|
||||||
|
Installation - With Maven
|
||||||
|
=========================
|
||||||
|
|
||||||
|
The Protocol Buffers build is managed using Maven. If you would
|
||||||
|
rather build without Maven, see below.
|
||||||
|
|
||||||
|
1) Install Apache Maven if you don't have it:
|
||||||
|
|
||||||
|
http://maven.apache.org/
|
||||||
|
|
||||||
|
2) Build the C++ code, or obtain a binary distribution of protoc. If
|
||||||
|
you install a binary distribution, make sure that it is the same
|
||||||
|
version as this package. If in doubt, run:
|
||||||
|
|
||||||
|
$ protoc --version
|
||||||
|
|
||||||
|
You will need to place the protoc executable in ../src. (If you
|
||||||
|
built it yourself, it should already be there.)
|
||||||
|
|
||||||
|
3) Run the tests:
|
||||||
|
|
||||||
|
$ mvn test
|
||||||
|
|
||||||
|
If some tests fail, this library may not work correctly on your
|
||||||
|
system. Continue at your own risk.
|
||||||
|
|
||||||
|
4) Install the library into your Maven repository:
|
||||||
|
|
||||||
|
$ mvn install
|
||||||
|
|
||||||
|
5) If you do not use Maven to manage your own build, you can build a
|
||||||
|
.jar file to use:
|
||||||
|
|
||||||
|
$ mvn package
|
||||||
|
|
||||||
|
The .jar will be placed in the "target" directory.
|
||||||
|
|
||||||
|
Installation - Without Maven
|
||||||
|
============================
|
||||||
|
|
||||||
|
If you would rather not install Maven to build the library, you may
|
||||||
|
follow these instructions instead. Note that these instructions skip
|
||||||
|
running unit tests.
|
||||||
|
|
||||||
|
1) Build the C++ code, or obtain a binary distribution of protoc. If
|
||||||
|
you install a binary distribution, make sure that it is the same
|
||||||
|
version as this package. If in doubt, run:
|
||||||
|
|
||||||
|
$ protoc --version
|
||||||
|
|
||||||
|
If you built the C++ code without installing, the compiler binary
|
||||||
|
should be located in ../src.
|
||||||
|
|
||||||
|
2) Invoke protoc to build DescriptorProtos.java:
|
||||||
|
|
||||||
|
$ protoc --java_out=src/main/java -I../src \
|
||||||
|
../src/google/protobuf/descriptor.proto
|
||||||
|
|
||||||
|
3) Compile the code in src/main/java using whatever means you prefer.
|
||||||
|
|
||||||
|
4) Install the classes wherever you prefer.
|
||||||
|
|
||||||
|
Nano version
|
||||||
|
============================
|
||||||
|
|
||||||
|
Nano is a special code generator and runtime library designed specially
|
||||||
|
for Android, and is very resource-friendly in both the amount of code
|
||||||
|
and the runtime overhead. An overview of Nano features:
|
||||||
|
|
||||||
|
- No descriptors or message builders.
|
||||||
|
- All messages are mutable; fields are public Java fields.
|
||||||
|
- For optional fields only, encapsulation behind setter/getter/hazzer/
|
||||||
|
clearer functions is opt-in, which provide proper 'has' state support.
|
||||||
|
- If not opted in, has state is not available. Serialization outputs
|
||||||
|
all fields not equal to their defaults (see important implications
|
||||||
|
below).
|
||||||
|
- Required fields are always serialized.
|
||||||
|
- Enum constants are integers; protection against invalid values only
|
||||||
|
when parsing from the wire.
|
||||||
|
- Enum constants can be generated into container interfaces bearing
|
||||||
|
the enum's name (so the referencing code is in Java style).
|
||||||
|
- CodedInputByteBufferNano can only take byte[] (not InputStream).
|
||||||
|
- Similarly CodedOutputByteBufferNano can only write to byte[].
|
||||||
|
- Repeated fields are in arrays, not ArrayList or Vector. Null array
|
||||||
|
elements are allowed and silently ignored.
|
||||||
|
- Full support of serializing/deserializing repeated packed fields.
|
||||||
|
- Support of extensions.
|
||||||
|
- Unset messages/groups are null, not an immutable empty default
|
||||||
|
instance.
|
||||||
|
- toByteArray(...) and mergeFrom(...) are now static functions of
|
||||||
|
MessageNano.
|
||||||
|
- The 'bytes' type translates to the Java type byte[].
|
||||||
|
|
||||||
|
The generated messages are not thread-safe for writes, but may be
|
||||||
|
used simultaneously from multiple threads in a read-only manner.
|
||||||
|
In other words, an appropriate synchronization mechanism (such as
|
||||||
|
a ReadWriteLock) must be used to ensure that a message, its
|
||||||
|
ancestors, and descendants are not accessed by any other threads
|
||||||
|
while the message is being modified. Field reads, getter methods
|
||||||
|
(but not getExtension(...)), toByteArray(...), writeTo(...),
|
||||||
|
getCachedSize(), and getSerializedSize() are all considered read-only
|
||||||
|
operations.
|
||||||
|
|
||||||
|
IMPORTANT: If you have fields with defaults and opt out of accessors
|
||||||
|
|
||||||
|
How fields with defaults are serialized has changed. Because we don't
|
||||||
|
keep "has" state, any field equal to its default is assumed to be not
|
||||||
|
set and therefore is not serialized. Consider the situation where we
|
||||||
|
change the default value of a field. Senders compiled against an older
|
||||||
|
version of the proto continue to match against the old default, and
|
||||||
|
don't send values to the receiver even though the receiver assumes the
|
||||||
|
new default value. Therefore, think carefully about the implications
|
||||||
|
of changing the default value. Alternatively, turn on accessors and
|
||||||
|
enjoy the benefit of the explicit has() checks.
|
||||||
|
|
||||||
|
IMPORTANT: If you have "bytes" fields with non-empty defaults
|
||||||
|
|
||||||
|
Because the byte buffer is now of mutable type byte[], the default
|
||||||
|
static final cannot be exposed through a public field. Each time a
|
||||||
|
message's constructor or clear() function is called, the default value
|
||||||
|
(kept in a private byte[]) is cloned. This causes a small memory
|
||||||
|
penalty. This is not a problem if the field has no default or is an
|
||||||
|
empty default.
|
||||||
|
|
||||||
|
Nano Generator options
|
||||||
|
|
||||||
|
java_package -> <file-name>|<package-name>
|
||||||
|
java_outer_classname -> <file-name>|<package-name>
|
||||||
|
java_multiple_files -> true or false
|
||||||
|
java_nano_generate_has -> true or false [DEPRECATED]
|
||||||
|
optional_field_style -> default or accessors
|
||||||
|
enum_style -> c or java
|
||||||
|
ignore_services -> true or false
|
||||||
|
parcelable_messages -> true or false
|
||||||
|
|
||||||
|
java_package=<file-name>|<package-name> (no default)
|
||||||
|
This allows overriding the 'java_package' option value
|
||||||
|
for the given file from the command line. Use multiple
|
||||||
|
java_package options to override the option for multiple
|
||||||
|
files. The final Java package for each file is the value
|
||||||
|
of this command line option if present, or the value of
|
||||||
|
the same option defined in the file if present, or the
|
||||||
|
proto package if present, or the default Java package.
|
||||||
|
|
||||||
|
java_outer_classname=<file-name>|<outer-classname> (no default)
|
||||||
|
This allows overriding the 'java_outer_classname' option
|
||||||
|
for the given file from the command line. Use multiple
|
||||||
|
java_outer_classname options to override the option for
|
||||||
|
multiple files. The final Java outer class name for each
|
||||||
|
file is the value of this command line option if present,
|
||||||
|
or the value of the same option defined in the file if
|
||||||
|
present, or the file name converted to CamelCase. This
|
||||||
|
outer class will nest all classes and integer constants
|
||||||
|
generated from file-scope messages and enums.
|
||||||
|
|
||||||
|
java_multiple_files={true,false} (no default)
|
||||||
|
This allows overriding the 'java_multiple_files' option
|
||||||
|
in all source files and their imported files from the
|
||||||
|
command line. The final value of this option for each
|
||||||
|
file is the value defined in this command line option, or
|
||||||
|
the value of the same option defined in the file if
|
||||||
|
present, or false. This specifies whether to generate
|
||||||
|
package-level classes for the file-scope messages in the
|
||||||
|
same Java package as the outer class (instead of nested
|
||||||
|
classes in the outer class). File-scope enum constants
|
||||||
|
are still generated as integer constants in the outer
|
||||||
|
class. This affects the fully qualified references in the
|
||||||
|
Java code. NOTE: because the command line option
|
||||||
|
overrides the value for all files and their imported
|
||||||
|
files, using this option inconsistently may result in
|
||||||
|
incorrect references to the imported messages and enum
|
||||||
|
constants.
|
||||||
|
|
||||||
|
java_nano_generate_has={true,false} (default: false)
|
||||||
|
DEPRECATED. Use optional_field_style=accessors.
|
||||||
|
|
||||||
|
If true, generates a public boolean variable has<fieldname>
|
||||||
|
accompanying each optional or required field (not present for
|
||||||
|
repeated fields, groups or messages). It is set to false initially
|
||||||
|
and upon clear(). If parseFrom(...) reads the field from the wire,
|
||||||
|
it is set to true. This is a way for clients to inspect the "has"
|
||||||
|
value upon parse. If it is set to true, writeTo(...) will ALWAYS
|
||||||
|
output that field (even if field value is equal to its
|
||||||
|
default).
|
||||||
|
|
||||||
|
IMPORTANT: This option costs an extra 4 bytes per primitive field in
|
||||||
|
the message. Think carefully about whether you really need this. In
|
||||||
|
many cases reading the default works and determining whether the
|
||||||
|
field was received over the wire is irrelevant.
|
||||||
|
|
||||||
|
optional_field_style={default,accessors,reftypes} (default: default)
|
||||||
|
Defines the style of the generated code for fields.
|
||||||
|
|
||||||
|
* default *
|
||||||
|
|
||||||
|
In the default style, optional fields translate into public mutable
|
||||||
|
Java fields, and the serialization process is as discussed in the
|
||||||
|
"IMPORTANT" section above.
|
||||||
|
|
||||||
|
* accessors *
|
||||||
|
|
||||||
|
When set to 'accessors', each optional field is encapsulated behind
|
||||||
|
4 accessors, namely get<fieldname>(), set<fieldname>(), has<fieldname>()
|
||||||
|
and clear<fieldname>() methods, with the standard semantics. The hazzer's
|
||||||
|
return value determines whether a field is serialized, so this style is
|
||||||
|
useful when you need to serialize a field with the default value, or check
|
||||||
|
if a field has been explicitly set to its default value from the wire.
|
||||||
|
|
||||||
|
In the 'accessors' style, required and nested message fields are still
|
||||||
|
translated to one public mutable Java field each, repeated fields are still
|
||||||
|
translated to arrays. No accessors are generated for them.
|
||||||
|
|
||||||
|
IMPORTANT: When using the 'accessors' style, ProGuard should always
|
||||||
|
be enabled with optimization (don't use -dontoptimize) and allowing
|
||||||
|
access modification (use -allowaccessmodification). This removes the
|
||||||
|
unused accessors and maybe inline the rest at the call sites,
|
||||||
|
reducing the final code size.
|
||||||
|
TODO(maxtroy): find ProGuard config that would work the best.
|
||||||
|
|
||||||
|
* reftypes *
|
||||||
|
|
||||||
|
When set to 'reftypes', each proto field is generated as a public Java
|
||||||
|
field. For primitive types, these fields use the Java reference types
|
||||||
|
such as java.lang.Integer instead of primitive types such as int.
|
||||||
|
|
||||||
|
In the 'reftypes' style, fields are initialized to null (or empty
|
||||||
|
arrays for repeated fields), and their default values are not available.
|
||||||
|
They are serialized over the wire based on equality to null.
|
||||||
|
|
||||||
|
The 'reftypes' mode has some additional cost due to autoboxing and usage
|
||||||
|
of reference types. In practice, many boxed types are cached, and so don't
|
||||||
|
result in object creation. However, references do take slightly more memory
|
||||||
|
than primitives.
|
||||||
|
|
||||||
|
The 'reftypes' mode is useful when you want to be able to serialize fields
|
||||||
|
with default values, or check if a field has been explicitly set to the
|
||||||
|
default over the wire without paying the extra method cost of the
|
||||||
|
'accessors' mode.
|
||||||
|
|
||||||
|
Note that if you attempt to write null to a required field in the reftypes
|
||||||
|
mode, serialization of the proto will cause a NullPointerException. This is
|
||||||
|
an intentional indicator that you must set required fields.
|
||||||
|
|
||||||
|
NOTE
|
||||||
|
optional_field_style=accessors or reftypes cannot be used together with
|
||||||
|
java_nano_generate_has=true. If you need the 'has' flag for any
|
||||||
|
required field (you have no reason to), you can only use
|
||||||
|
java_nano_generate_has=true.
|
||||||
|
|
||||||
|
enum_style={c,java} (default: c)
|
||||||
|
Defines where to put the int constants generated from enum members.
|
||||||
|
|
||||||
|
* c *
|
||||||
|
|
||||||
|
Use C-style, so the enum constants are available at the scope where
|
||||||
|
the enum is defined. A file-scope enum's members are referenced like
|
||||||
|
'FileOuterClass.ENUM_VALUE'; a message-scope enum's members are
|
||||||
|
referenced as 'Message.ENUM_VALUE'. The enum name is unavailable.
|
||||||
|
This complies with the Micro code generator's behavior.
|
||||||
|
|
||||||
|
* java *
|
||||||
|
|
||||||
|
Use Java-style, so the enum constants are available under the enum
|
||||||
|
name and referenced like 'EnumName.ENUM_VALUE' (they are still int
|
||||||
|
constants). The enum name becomes the name of a public interface, at
|
||||||
|
the scope where the enum is defined. If the enum is file-scope and
|
||||||
|
the java_multiple_files option is on, the interface will be defined
|
||||||
|
in its own file. To reduce code size, this interface should not be
|
||||||
|
implemented and ProGuard shrinking should be used, so after the Java
|
||||||
|
compiler inlines all referenced enum constants into the call sites,
|
||||||
|
the interface remains unused and can be removed by ProGuard.
|
||||||
|
|
||||||
|
ignore_services={true,false} (default: false)
|
||||||
|
Skips services definitions.
|
||||||
|
|
||||||
|
Nano doesn't support services. By default, if a service is defined
|
||||||
|
it will generate a compilation error. If this flag is set to true,
|
||||||
|
services will be silently ignored, instead.
|
||||||
|
|
||||||
|
parcelable_messages={true,false} (default: false)
|
||||||
|
Android-specific option to generate Parcelable messages.
|
||||||
|
|
||||||
|
|
||||||
|
To use nano protobufs within the Android repo:
|
||||||
|
|
||||||
|
- Set 'LOCAL_PROTOC_OPTIMIZE_TYPE := nano' in your local .mk file.
|
||||||
|
When building a Java library or an app (package) target, the build
|
||||||
|
system will add the Java nano runtime library to the
|
||||||
|
LOCAL_STATIC_JAVA_LIBRARIES variable, so you don't need to.
|
||||||
|
- Set 'LOCAL_PROTO_JAVA_OUTPUT_PARAMS := ...' in your local .mk file
|
||||||
|
for any command-line options you need. Use commas to join multiple
|
||||||
|
options. In the nano flavor only, whitespace surrounding the option
|
||||||
|
names and values are ignored, so you can use backslash-newline or
|
||||||
|
'+=' to structure your make files nicely.
|
||||||
|
- The options will be applied to *all* proto files in LOCAL_SRC_FILES
|
||||||
|
when you build a Java library or package. In case different options
|
||||||
|
are needed for different proto files, build separate Java libraries
|
||||||
|
and reference them in your main target. Note: you should make sure
|
||||||
|
that, for each separate target, all proto files imported from any
|
||||||
|
proto file in LOCAL_SRC_FILES are included in LOCAL_SRC_FILES. This
|
||||||
|
is because the generator has to assume that the imported files are
|
||||||
|
built using the same options, and will generate code that reference
|
||||||
|
the fields and enums from the imported files using the same code
|
||||||
|
style.
|
||||||
|
- Hint: 'include $(CLEAR_VARS)' resets all LOCAL_ variables, including
|
||||||
|
the two above.
|
||||||
|
|
||||||
|
To use nano protobufs outside of Android repo:
|
||||||
|
|
||||||
|
- Link with the generated jar file
|
||||||
|
<protobuf-root>java/target/protobuf-java-2.3.0-nano.jar.
|
||||||
|
- Invoke with --javanano_out, e.g.:
|
||||||
|
|
||||||
|
./protoc '--javanano_out=\
|
||||||
|
java_package=src/proto/simple-data.proto|my_package,\
|
||||||
|
java_outer_classname=src/proto/simple-data.proto|OuterName\
|
||||||
|
:.' src/proto/simple-data.proto
|
||||||
|
|
||||||
|
Contributing to nano:
|
||||||
|
|
||||||
|
Please add/edit tests in NanoTest.java.
|
||||||
|
|
||||||
|
Please run the following steps to test:
|
||||||
|
|
||||||
|
- cd external/protobuf
|
||||||
|
- ./configure
|
||||||
|
- Run "make -j12 check" and verify all tests pass.
|
||||||
|
- cd java
|
||||||
|
- Run "mvn test" and verify all tests pass.
|
||||||
|
- cd ../../..
|
||||||
|
- . build/envsetup.sh
|
||||||
|
- lunch 1
|
||||||
|
- "make -j12 aprotoc libprotobuf-java-2.3.0-nano aprotoc-test-nano-params NanoAndroidTest" and
|
||||||
|
check for build errors.
|
||||||
|
- Plug in an Android device or start an emulator.
|
||||||
|
- adb install -r out/target/product/generic/data/app/NanoAndroidTest.apk
|
||||||
|
- Run:
|
||||||
|
"adb shell am instrument -w com.google.protobuf.nano.test/android.test.InstrumentationTestRunner"
|
||||||
|
and verify all tests pass.
|
||||||
|
- repo sync -c -j256
|
||||||
|
- "make -j12" and check for build errors
|
||||||
|
|
||||||
|
Usage
|
||||||
|
=====
|
||||||
|
|
||||||
|
The complete documentation for Protocol Buffers is available via the
|
||||||
|
web at:
|
||||||
|
|
||||||
|
https://developers.google.com/protocol-buffers/
|
164
javanano/pom.xml
Normal file
164
javanano/pom.xml
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.google</groupId>
|
||||||
|
<artifactId>google</artifactId>
|
||||||
|
<version>1</version>
|
||||||
|
</parent>
|
||||||
|
<groupId>com.google.protobuf.nano</groupId>
|
||||||
|
<artifactId>protobuf-javanano</artifactId>
|
||||||
|
<version>2.6.2-pre</version>
|
||||||
|
<packaging>bundle</packaging>
|
||||||
|
<name>Protocol Buffer JavaNano API</name>
|
||||||
|
<description>
|
||||||
|
Protocol Buffers are a way of encoding structured data in an efficient yet
|
||||||
|
extensible format.
|
||||||
|
</description>
|
||||||
|
<inceptionYear>2008</inceptionYear>
|
||||||
|
<url>https://developers.google.com/protocol-buffers/</url>
|
||||||
|
<licenses>
|
||||||
|
<license>
|
||||||
|
<name>New BSD license</name>
|
||||||
|
<url>http://www.opensource.org/licenses/bsd-license.php</url>
|
||||||
|
<distribution>repo</distribution>
|
||||||
|
</license>
|
||||||
|
</licenses>
|
||||||
|
<scm>
|
||||||
|
<url>https://github.com/google/protobuf</url>
|
||||||
|
<connection>
|
||||||
|
scm:git:https://github.com/google/protobuf.git
|
||||||
|
</connection>
|
||||||
|
</scm>
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.4</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.easymock</groupId>
|
||||||
|
<artifactId>easymock</artifactId>
|
||||||
|
<version>2.2</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.easymock</groupId>
|
||||||
|
<artifactId>easymockclassextension</artifactId>
|
||||||
|
<version>2.2.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>1.5</source>
|
||||||
|
<target>1.5</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<includes>
|
||||||
|
<include>**/*Test.java</include>
|
||||||
|
</includes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-antrun-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>generate-test-sources</id>
|
||||||
|
<phase>generate-test-sources</phase>
|
||||||
|
<configuration>
|
||||||
|
<tasks>
|
||||||
|
<mkdir dir="target/generated-test-sources" />
|
||||||
|
<exec executable="../src/protoc">
|
||||||
|
<arg value="--javanano_out=generate_equals=true:target/generated-test-sources" />
|
||||||
|
<arg value="--proto_path=src/test/java/com" />
|
||||||
|
<arg value="src/test/java/com/google/protobuf/nano/unittest_nano.proto" />
|
||||||
|
<arg value="src/test/java/com/google/protobuf/nano/unittest_simple_nano.proto" />
|
||||||
|
<arg value="src/test/java/com/google/protobuf/nano/unittest_stringutf8_nano.proto" />
|
||||||
|
<arg value="src/test/java/com/google/protobuf/nano/unittest_recursive_nano.proto" />
|
||||||
|
<arg value="src/test/java/com/google/protobuf/nano/unittest_import_nano.proto" />
|
||||||
|
<arg value="src/test/java/com/google/protobuf/nano/unittest_single_nano.proto" />
|
||||||
|
<arg value="src/test/java/com/google/protobuf/nano/unittest_multiple_nano.proto" />
|
||||||
|
<arg value="src/test/java/com/google/protobuf/nano/unittest_multiple_nameclash_nano.proto" />
|
||||||
|
<arg value="src/test/java/com/google/protobuf/nano/unittest_enum_class_nano.proto" />
|
||||||
|
<arg value="src/test/java/com/google/protobuf/nano/unittest_repeated_merge_nano.proto" />
|
||||||
|
</exec>
|
||||||
|
<exec executable="../src/protoc">
|
||||||
|
<arg value="--javanano_out=store_unknown_fields=true,generate_equals=true:target/generated-test-sources" />
|
||||||
|
<arg value="--proto_path=src/test/java/com" />
|
||||||
|
<arg value="src/test/java/com/google/protobuf/nano/unittest_extension_nano.proto" />
|
||||||
|
<arg value="src/test/java/com/google/protobuf/nano/unittest_extension_singular_nano.proto" />
|
||||||
|
<arg value="src/test/java/com/google/protobuf/nano/unittest_extension_repeated_nano.proto" />
|
||||||
|
</exec>
|
||||||
|
<exec executable="../src/protoc">
|
||||||
|
<arg value="--javanano_out=store_unknown_fields=true:target/generated-test-sources" />
|
||||||
|
<arg value="--proto_path=src/test/java/com" />
|
||||||
|
<arg value="src/test/java/com/google/protobuf/nano/unittest_extension_packed_nano.proto" />
|
||||||
|
</exec>
|
||||||
|
<exec executable="../src/protoc">
|
||||||
|
<arg value="--javanano_out=java_nano_generate_has=true,generate_equals=true:target/generated-test-sources" />
|
||||||
|
<arg value="--proto_path=src/test/java/com" />
|
||||||
|
<arg value="src/test/java/com/google/protobuf/nano/unittest_has_nano.proto" />
|
||||||
|
</exec>
|
||||||
|
<exec executable="../src/protoc">
|
||||||
|
<arg value="--javanano_out=optional_field_style=accessors,generate_equals=true:target/generated-test-sources" />
|
||||||
|
<arg value="--proto_path=src/test/java/com" />
|
||||||
|
<arg value="src/test/java/com/google/protobuf/nano/unittest_accessors_nano.proto" />
|
||||||
|
</exec>
|
||||||
|
<exec executable="../src/protoc">
|
||||||
|
<arg value="--javanano_out=enum_style=java:target/generated-test-sources" />
|
||||||
|
<arg value="--proto_path=src/test/java/com" />
|
||||||
|
<arg value="src/test/java/com/google/protobuf/nano/unittest_enum_class_nano.proto" />
|
||||||
|
<arg value="src/test/java/com/google/protobuf/nano/unittest_enum_class_multiple_nano.proto" />
|
||||||
|
<arg value="src/test/java/com/google/protobuf/nano/unittest_repeated_packables_nano.proto" />
|
||||||
|
<arg value="src/test/java/com/google/protobuf/nano/unittest_enum_validity_nano.proto" />
|
||||||
|
</exec>
|
||||||
|
<exec executable="../src/protoc">
|
||||||
|
<arg value="--javanano_out=
|
||||||
|
optional_field_style=accessors,
|
||||||
|
java_outer_classname=google/protobuf/nano/unittest_enum_validity_nano.proto|EnumValidityAccessors
|
||||||
|
:target/generated-test-sources" />
|
||||||
|
<arg value="--proto_path=src/test/java/com" />
|
||||||
|
<arg value="src/test/java/com/google/protobuf/nano/unittest_enum_validity_nano.proto" />
|
||||||
|
</exec>
|
||||||
|
<exec executable="../src/protoc">
|
||||||
|
<arg value="--javanano_out=optional_field_style=reftypes,generate_equals=true:target/generated-test-sources" />
|
||||||
|
<arg value="--proto_path=src/test/java/com" />
|
||||||
|
<arg value="src/test/java/com/google/protobuf/nano/unittest_reference_types_nano.proto" />
|
||||||
|
</exec>
|
||||||
|
</tasks>
|
||||||
|
<testSourceRoot>target/generated-test-sources</testSourceRoot>
|
||||||
|
</configuration>
|
||||||
|
<goals>
|
||||||
|
<goal>run</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.felix</groupId>
|
||||||
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
<extensions>true</extensions>
|
||||||
|
<configuration>
|
||||||
|
<instructions>
|
||||||
|
<Bundle-DocURL>https://developers.google.com/protocol-buffers/</Bundle-DocURL>
|
||||||
|
<Bundle-SymbolicName>com.google.protobuf</Bundle-SymbolicName>
|
||||||
|
<Export-Package>com.google.protobuf;version=2.6.2-pre</Export-Package>
|
||||||
|
</instructions>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
@ -0,0 +1,641 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2013 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package com.google.protobuf.nano;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads and decodes protocol message fields.
|
||||||
|
*
|
||||||
|
* This class contains two kinds of methods: methods that read specific
|
||||||
|
* protocol message constructs and field types (e.g. {@link #readTag()} and
|
||||||
|
* {@link #readInt32()}) and methods that read low-level values (e.g.
|
||||||
|
* {@link #readRawVarint32()} and {@link #readRawBytes}). If you are reading
|
||||||
|
* encoded protocol messages, you should use the former methods, but if you are
|
||||||
|
* reading some other format of your own design, use the latter.
|
||||||
|
*
|
||||||
|
* @author kenton@google.com Kenton Varda
|
||||||
|
*/
|
||||||
|
public final class CodedInputByteBufferNano {
|
||||||
|
/**
|
||||||
|
* Create a new CodedInputStream wrapping the given byte array.
|
||||||
|
*/
|
||||||
|
public static CodedInputByteBufferNano newInstance(final byte[] buf) {
|
||||||
|
return newInstance(buf, 0, buf.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new CodedInputStream wrapping the given byte array slice.
|
||||||
|
*/
|
||||||
|
public static CodedInputByteBufferNano newInstance(final byte[] buf, final int off,
|
||||||
|
final int len) {
|
||||||
|
return new CodedInputByteBufferNano(buf, off, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to read a field tag, returning zero if we have reached EOF.
|
||||||
|
* Protocol message parsers use this to read tags, since a protocol message
|
||||||
|
* may legally end wherever a tag occurs, and zero is not a valid tag number.
|
||||||
|
*/
|
||||||
|
public int readTag() throws IOException {
|
||||||
|
if (isAtEnd()) {
|
||||||
|
lastTag = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastTag = readRawVarint32();
|
||||||
|
if (lastTag == 0) {
|
||||||
|
// If we actually read zero, that's not a valid tag.
|
||||||
|
throw InvalidProtocolBufferNanoException.invalidTag();
|
||||||
|
}
|
||||||
|
return lastTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies that the last call to readTag() returned the given tag value.
|
||||||
|
* This is used to verify that a nested group ended with the correct
|
||||||
|
* end tag.
|
||||||
|
*
|
||||||
|
* @throws InvalidProtocolBufferNanoException {@code value} does not match the
|
||||||
|
* last tag.
|
||||||
|
*/
|
||||||
|
public void checkLastTagWas(final int value)
|
||||||
|
throws InvalidProtocolBufferNanoException {
|
||||||
|
if (lastTag != value) {
|
||||||
|
throw InvalidProtocolBufferNanoException.invalidEndTag();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads and discards a single field, given its tag value.
|
||||||
|
*
|
||||||
|
* @return {@code false} if the tag is an endgroup tag, in which case
|
||||||
|
* nothing is skipped. Otherwise, returns {@code true}.
|
||||||
|
*/
|
||||||
|
public boolean skipField(final int tag) throws IOException {
|
||||||
|
switch (WireFormatNano.getTagWireType(tag)) {
|
||||||
|
case WireFormatNano.WIRETYPE_VARINT:
|
||||||
|
readInt32();
|
||||||
|
return true;
|
||||||
|
case WireFormatNano.WIRETYPE_FIXED64:
|
||||||
|
readRawLittleEndian64();
|
||||||
|
return true;
|
||||||
|
case WireFormatNano.WIRETYPE_LENGTH_DELIMITED:
|
||||||
|
skipRawBytes(readRawVarint32());
|
||||||
|
return true;
|
||||||
|
case WireFormatNano.WIRETYPE_START_GROUP:
|
||||||
|
skipMessage();
|
||||||
|
checkLastTagWas(
|
||||||
|
WireFormatNano.makeTag(WireFormatNano.getTagFieldNumber(tag),
|
||||||
|
WireFormatNano.WIRETYPE_END_GROUP));
|
||||||
|
return true;
|
||||||
|
case WireFormatNano.WIRETYPE_END_GROUP:
|
||||||
|
return false;
|
||||||
|
case WireFormatNano.WIRETYPE_FIXED32:
|
||||||
|
readRawLittleEndian32();
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
throw InvalidProtocolBufferNanoException.invalidWireType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads and discards an entire message. This will read either until EOF
|
||||||
|
* or until an endgroup tag, whichever comes first.
|
||||||
|
*/
|
||||||
|
public void skipMessage() throws IOException {
|
||||||
|
while (true) {
|
||||||
|
final int tag = readTag();
|
||||||
|
if (tag == 0 || !skipField(tag)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
|
||||||
|
/** Read a {@code double} field value from the stream. */
|
||||||
|
public double readDouble() throws IOException {
|
||||||
|
return Double.longBitsToDouble(readRawLittleEndian64());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Read a {@code float} field value from the stream. */
|
||||||
|
public float readFloat() throws IOException {
|
||||||
|
return Float.intBitsToFloat(readRawLittleEndian32());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Read a {@code uint64} field value from the stream. */
|
||||||
|
public long readUInt64() throws IOException {
|
||||||
|
return readRawVarint64();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Read an {@code int64} field value from the stream. */
|
||||||
|
public long readInt64() throws IOException {
|
||||||
|
return readRawVarint64();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Read an {@code int32} field value from the stream. */
|
||||||
|
public int readInt32() throws IOException {
|
||||||
|
return readRawVarint32();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Read a {@code fixed64} field value from the stream. */
|
||||||
|
public long readFixed64() throws IOException {
|
||||||
|
return readRawLittleEndian64();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Read a {@code fixed32} field value from the stream. */
|
||||||
|
public int readFixed32() throws IOException {
|
||||||
|
return readRawLittleEndian32();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Read a {@code bool} field value from the stream. */
|
||||||
|
public boolean readBool() throws IOException {
|
||||||
|
return readRawVarint32() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Read a {@code string} field value from the stream. */
|
||||||
|
public String readString() throws IOException {
|
||||||
|
final int size = readRawVarint32();
|
||||||
|
if (size <= (bufferSize - bufferPos) && size > 0) {
|
||||||
|
// Fast path: We already have the bytes in a contiguous buffer, so
|
||||||
|
// just copy directly from it.
|
||||||
|
final String result = new String(buffer, bufferPos, size, "UTF-8");
|
||||||
|
bufferPos += size;
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
// Slow path: Build a byte array first then copy it.
|
||||||
|
return new String(readRawBytes(size), "UTF-8");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Read a {@code group} field value from the stream. */
|
||||||
|
public void readGroup(final MessageNano msg, final int fieldNumber)
|
||||||
|
throws IOException {
|
||||||
|
if (recursionDepth >= recursionLimit) {
|
||||||
|
throw InvalidProtocolBufferNanoException.recursionLimitExceeded();
|
||||||
|
}
|
||||||
|
++recursionDepth;
|
||||||
|
msg.mergeFrom(this);
|
||||||
|
checkLastTagWas(
|
||||||
|
WireFormatNano.makeTag(fieldNumber, WireFormatNano.WIRETYPE_END_GROUP));
|
||||||
|
--recursionDepth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readMessage(final MessageNano msg)
|
||||||
|
throws IOException {
|
||||||
|
final int length = readRawVarint32();
|
||||||
|
if (recursionDepth >= recursionLimit) {
|
||||||
|
throw InvalidProtocolBufferNanoException.recursionLimitExceeded();
|
||||||
|
}
|
||||||
|
final int oldLimit = pushLimit(length);
|
||||||
|
++recursionDepth;
|
||||||
|
msg.mergeFrom(this);
|
||||||
|
checkLastTagWas(0);
|
||||||
|
--recursionDepth;
|
||||||
|
popLimit(oldLimit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Read a {@code bytes} field value from the stream. */
|
||||||
|
public byte[] readBytes() throws IOException {
|
||||||
|
final int size = readRawVarint32();
|
||||||
|
if (size <= (bufferSize - bufferPos) && size > 0) {
|
||||||
|
// Fast path: We already have the bytes in a contiguous buffer, so
|
||||||
|
// just copy directly from it.
|
||||||
|
final byte[] result = new byte[size];
|
||||||
|
System.arraycopy(buffer, bufferPos, result, 0, size);
|
||||||
|
bufferPos += size;
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
// Slow path: Build a byte array first then copy it.
|
||||||
|
return readRawBytes(size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Read a {@code uint32} field value from the stream. */
|
||||||
|
public int readUInt32() throws IOException {
|
||||||
|
return readRawVarint32();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read an enum field value from the stream. Caller is responsible
|
||||||
|
* for converting the numeric value to an actual enum.
|
||||||
|
*/
|
||||||
|
public int readEnum() throws IOException {
|
||||||
|
return readRawVarint32();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Read an {@code sfixed32} field value from the stream. */
|
||||||
|
public int readSFixed32() throws IOException {
|
||||||
|
return readRawLittleEndian32();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Read an {@code sfixed64} field value from the stream. */
|
||||||
|
public long readSFixed64() throws IOException {
|
||||||
|
return readRawLittleEndian64();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Read an {@code sint32} field value from the stream. */
|
||||||
|
public int readSInt32() throws IOException {
|
||||||
|
return decodeZigZag32(readRawVarint32());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Read an {@code sint64} field value from the stream. */
|
||||||
|
public long readSInt64() throws IOException {
|
||||||
|
return decodeZigZag64(readRawVarint64());
|
||||||
|
}
|
||||||
|
|
||||||
|
// =================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a raw Varint from the stream. If larger than 32 bits, discard the
|
||||||
|
* upper bits.
|
||||||
|
*/
|
||||||
|
public int readRawVarint32() throws IOException {
|
||||||
|
byte tmp = readRawByte();
|
||||||
|
if (tmp >= 0) {
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
int result = tmp & 0x7f;
|
||||||
|
if ((tmp = readRawByte()) >= 0) {
|
||||||
|
result |= tmp << 7;
|
||||||
|
} else {
|
||||||
|
result |= (tmp & 0x7f) << 7;
|
||||||
|
if ((tmp = readRawByte()) >= 0) {
|
||||||
|
result |= tmp << 14;
|
||||||
|
} else {
|
||||||
|
result |= (tmp & 0x7f) << 14;
|
||||||
|
if ((tmp = readRawByte()) >= 0) {
|
||||||
|
result |= tmp << 21;
|
||||||
|
} else {
|
||||||
|
result |= (tmp & 0x7f) << 21;
|
||||||
|
result |= (tmp = readRawByte()) << 28;
|
||||||
|
if (tmp < 0) {
|
||||||
|
// Discard upper 32 bits.
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
if (readRawByte() >= 0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw InvalidProtocolBufferNanoException.malformedVarint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Read a raw Varint from the stream. */
|
||||||
|
public long readRawVarint64() throws IOException {
|
||||||
|
int shift = 0;
|
||||||
|
long result = 0;
|
||||||
|
while (shift < 64) {
|
||||||
|
final byte b = readRawByte();
|
||||||
|
result |= (long)(b & 0x7F) << shift;
|
||||||
|
if ((b & 0x80) == 0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
shift += 7;
|
||||||
|
}
|
||||||
|
throw InvalidProtocolBufferNanoException.malformedVarint();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Read a 32-bit little-endian integer from the stream. */
|
||||||
|
public int readRawLittleEndian32() throws IOException {
|
||||||
|
final byte b1 = readRawByte();
|
||||||
|
final byte b2 = readRawByte();
|
||||||
|
final byte b3 = readRawByte();
|
||||||
|
final byte b4 = readRawByte();
|
||||||
|
return ((b1 & 0xff) ) |
|
||||||
|
((b2 & 0xff) << 8) |
|
||||||
|
((b3 & 0xff) << 16) |
|
||||||
|
((b4 & 0xff) << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Read a 64-bit little-endian integer from the stream. */
|
||||||
|
public long readRawLittleEndian64() throws IOException {
|
||||||
|
final byte b1 = readRawByte();
|
||||||
|
final byte b2 = readRawByte();
|
||||||
|
final byte b3 = readRawByte();
|
||||||
|
final byte b4 = readRawByte();
|
||||||
|
final byte b5 = readRawByte();
|
||||||
|
final byte b6 = readRawByte();
|
||||||
|
final byte b7 = readRawByte();
|
||||||
|
final byte b8 = readRawByte();
|
||||||
|
return (((long)b1 & 0xff) ) |
|
||||||
|
(((long)b2 & 0xff) << 8) |
|
||||||
|
(((long)b3 & 0xff) << 16) |
|
||||||
|
(((long)b4 & 0xff) << 24) |
|
||||||
|
(((long)b5 & 0xff) << 32) |
|
||||||
|
(((long)b6 & 0xff) << 40) |
|
||||||
|
(((long)b7 & 0xff) << 48) |
|
||||||
|
(((long)b8 & 0xff) << 56);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers
|
||||||
|
* into values that can be efficiently encoded with varint. (Otherwise,
|
||||||
|
* negative values must be sign-extended to 64 bits to be varint encoded,
|
||||||
|
* thus always taking 10 bytes on the wire.)
|
||||||
|
*
|
||||||
|
* @param n An unsigned 32-bit integer, stored in a signed int because
|
||||||
|
* Java has no explicit unsigned support.
|
||||||
|
* @return A signed 32-bit integer.
|
||||||
|
*/
|
||||||
|
public static int decodeZigZag32(final int n) {
|
||||||
|
return (n >>> 1) ^ -(n & 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers
|
||||||
|
* into values that can be efficiently encoded with varint. (Otherwise,
|
||||||
|
* negative values must be sign-extended to 64 bits to be varint encoded,
|
||||||
|
* thus always taking 10 bytes on the wire.)
|
||||||
|
*
|
||||||
|
* @param n An unsigned 64-bit integer, stored in a signed int because
|
||||||
|
* Java has no explicit unsigned support.
|
||||||
|
* @return A signed 64-bit integer.
|
||||||
|
*/
|
||||||
|
public static long decodeZigZag64(final long n) {
|
||||||
|
return (n >>> 1) ^ -(n & 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
|
||||||
|
private final byte[] buffer;
|
||||||
|
private int bufferStart;
|
||||||
|
private int bufferSize;
|
||||||
|
private int bufferSizeAfterLimit;
|
||||||
|
private int bufferPos;
|
||||||
|
private int lastTag;
|
||||||
|
|
||||||
|
/** The absolute position of the end of the current message. */
|
||||||
|
private int currentLimit = Integer.MAX_VALUE;
|
||||||
|
|
||||||
|
/** See setRecursionLimit() */
|
||||||
|
private int recursionDepth;
|
||||||
|
private int recursionLimit = DEFAULT_RECURSION_LIMIT;
|
||||||
|
|
||||||
|
/** See setSizeLimit() */
|
||||||
|
private int sizeLimit = DEFAULT_SIZE_LIMIT;
|
||||||
|
|
||||||
|
private static final int DEFAULT_RECURSION_LIMIT = 64;
|
||||||
|
private static final int DEFAULT_SIZE_LIMIT = 64 << 20; // 64MB
|
||||||
|
|
||||||
|
private CodedInputByteBufferNano(final byte[] buffer, final int off, final int len) {
|
||||||
|
this.buffer = buffer;
|
||||||
|
bufferStart = off;
|
||||||
|
bufferSize = off + len;
|
||||||
|
bufferPos = off;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the maximum message recursion depth. In order to prevent malicious
|
||||||
|
* messages from causing stack overflows, {@code CodedInputStream} limits
|
||||||
|
* how deeply messages may be nested. The default limit is 64.
|
||||||
|
*
|
||||||
|
* @return the old limit.
|
||||||
|
*/
|
||||||
|
public int setRecursionLimit(final int limit) {
|
||||||
|
if (limit < 0) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Recursion limit cannot be negative: " + limit);
|
||||||
|
}
|
||||||
|
final int oldLimit = recursionLimit;
|
||||||
|
recursionLimit = limit;
|
||||||
|
return oldLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the maximum message size. In order to prevent malicious
|
||||||
|
* messages from exhausting memory or causing integer overflows,
|
||||||
|
* {@code CodedInputStream} limits how large a message may be.
|
||||||
|
* The default limit is 64MB. You should set this limit as small
|
||||||
|
* as you can without harming your app's functionality. Note that
|
||||||
|
* size limits only apply when reading from an {@code InputStream}, not
|
||||||
|
* when constructed around a raw byte array.
|
||||||
|
* <p>
|
||||||
|
* If you want to read several messages from a single CodedInputStream, you
|
||||||
|
* could call {@link #resetSizeCounter()} after each one to avoid hitting the
|
||||||
|
* size limit.
|
||||||
|
*
|
||||||
|
* @return the old limit.
|
||||||
|
*/
|
||||||
|
public int setSizeLimit(final int limit) {
|
||||||
|
if (limit < 0) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Size limit cannot be negative: " + limit);
|
||||||
|
}
|
||||||
|
final int oldLimit = sizeLimit;
|
||||||
|
sizeLimit = limit;
|
||||||
|
return oldLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the current size counter to zero (see {@link #setSizeLimit(int)}).
|
||||||
|
*/
|
||||||
|
public void resetSizeCounter() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets {@code currentLimit} to (current position) + {@code byteLimit}. This
|
||||||
|
* is called when descending into a length-delimited embedded message.
|
||||||
|
*
|
||||||
|
* @return the old limit.
|
||||||
|
*/
|
||||||
|
public int pushLimit(int byteLimit) throws InvalidProtocolBufferNanoException {
|
||||||
|
if (byteLimit < 0) {
|
||||||
|
throw InvalidProtocolBufferNanoException.negativeSize();
|
||||||
|
}
|
||||||
|
byteLimit += bufferPos;
|
||||||
|
final int oldLimit = currentLimit;
|
||||||
|
if (byteLimit > oldLimit) {
|
||||||
|
throw InvalidProtocolBufferNanoException.truncatedMessage();
|
||||||
|
}
|
||||||
|
currentLimit = byteLimit;
|
||||||
|
|
||||||
|
recomputeBufferSizeAfterLimit();
|
||||||
|
|
||||||
|
return oldLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void recomputeBufferSizeAfterLimit() {
|
||||||
|
bufferSize += bufferSizeAfterLimit;
|
||||||
|
final int bufferEnd = bufferSize;
|
||||||
|
if (bufferEnd > currentLimit) {
|
||||||
|
// Limit is in current buffer.
|
||||||
|
bufferSizeAfterLimit = bufferEnd - currentLimit;
|
||||||
|
bufferSize -= bufferSizeAfterLimit;
|
||||||
|
} else {
|
||||||
|
bufferSizeAfterLimit = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Discards the current limit, returning to the previous limit.
|
||||||
|
*
|
||||||
|
* @param oldLimit The old limit, as returned by {@code pushLimit}.
|
||||||
|
*/
|
||||||
|
public void popLimit(final int oldLimit) {
|
||||||
|
currentLimit = oldLimit;
|
||||||
|
recomputeBufferSizeAfterLimit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of bytes to be read before the current limit.
|
||||||
|
* If no limit is set, returns -1.
|
||||||
|
*/
|
||||||
|
public int getBytesUntilLimit() {
|
||||||
|
if (currentLimit == Integer.MAX_VALUE) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int currentAbsolutePosition = bufferPos;
|
||||||
|
return currentLimit - currentAbsolutePosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the stream has reached the end of the input. This is the
|
||||||
|
* case if either the end of the underlying input source has been reached or
|
||||||
|
* if the stream has reached a limit created using {@link #pushLimit(int)}.
|
||||||
|
*/
|
||||||
|
public boolean isAtEnd() {
|
||||||
|
return bufferPos == bufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get current position in buffer relative to beginning offset.
|
||||||
|
*/
|
||||||
|
public int getPosition() {
|
||||||
|
return bufferPos - bufferStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a subset of data in the buffer. The returned array is not backed by the original
|
||||||
|
* buffer array.
|
||||||
|
*
|
||||||
|
* @param offset the position (relative to the buffer start position) to start at.
|
||||||
|
* @param length the number of bytes to retrieve.
|
||||||
|
*/
|
||||||
|
public byte[] getData(int offset, int length) {
|
||||||
|
if (length == 0) {
|
||||||
|
return WireFormatNano.EMPTY_BYTES;
|
||||||
|
}
|
||||||
|
byte[] copy = new byte[length];
|
||||||
|
int start = bufferStart + offset;
|
||||||
|
System.arraycopy(buffer, start, copy, 0, length);
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rewind to previous position. Cannot go forward.
|
||||||
|
*/
|
||||||
|
public void rewindToPosition(int position) {
|
||||||
|
if (position > bufferPos - bufferStart) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Position " + position + " is beyond current " + (bufferPos - bufferStart));
|
||||||
|
}
|
||||||
|
if (position < 0) {
|
||||||
|
throw new IllegalArgumentException("Bad position " + position);
|
||||||
|
}
|
||||||
|
bufferPos = bufferStart + position;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read one byte from the input.
|
||||||
|
*
|
||||||
|
* @throws InvalidProtocolBufferNanoException The end of the stream or the current
|
||||||
|
* limit was reached.
|
||||||
|
*/
|
||||||
|
public byte readRawByte() throws IOException {
|
||||||
|
if (bufferPos == bufferSize) {
|
||||||
|
throw InvalidProtocolBufferNanoException.truncatedMessage();
|
||||||
|
}
|
||||||
|
return buffer[bufferPos++];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a fixed size of bytes from the input.
|
||||||
|
*
|
||||||
|
* @throws InvalidProtocolBufferNanoException The end of the stream or the current
|
||||||
|
* limit was reached.
|
||||||
|
*/
|
||||||
|
public byte[] readRawBytes(final int size) throws IOException {
|
||||||
|
if (size < 0) {
|
||||||
|
throw InvalidProtocolBufferNanoException.negativeSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bufferPos + size > currentLimit) {
|
||||||
|
// Read to the end of the stream anyway.
|
||||||
|
skipRawBytes(currentLimit - bufferPos);
|
||||||
|
// Then fail.
|
||||||
|
throw InvalidProtocolBufferNanoException.truncatedMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size <= bufferSize - bufferPos) {
|
||||||
|
// We have all the bytes we need already.
|
||||||
|
final byte[] bytes = new byte[size];
|
||||||
|
System.arraycopy(buffer, bufferPos, bytes, 0, size);
|
||||||
|
bufferPos += size;
|
||||||
|
return bytes;
|
||||||
|
} else {
|
||||||
|
throw InvalidProtocolBufferNanoException.truncatedMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads and discards {@code size} bytes.
|
||||||
|
*
|
||||||
|
* @throws InvalidProtocolBufferNanoException The end of the stream or the current
|
||||||
|
* limit was reached.
|
||||||
|
*/
|
||||||
|
public void skipRawBytes(final int size) throws IOException {
|
||||||
|
if (size < 0) {
|
||||||
|
throw InvalidProtocolBufferNanoException.negativeSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bufferPos + size > currentLimit) {
|
||||||
|
// Read to the end of the stream anyway.
|
||||||
|
skipRawBytes(currentLimit - bufferPos);
|
||||||
|
// Then fail.
|
||||||
|
throw InvalidProtocolBufferNanoException.truncatedMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size <= bufferSize - bufferPos) {
|
||||||
|
// We have all the bytes we need already.
|
||||||
|
bufferPos += size;
|
||||||
|
} else {
|
||||||
|
throw InvalidProtocolBufferNanoException.truncatedMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,879 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2013 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package com.google.protobuf.nano;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes and writes protocol message fields.
|
||||||
|
*
|
||||||
|
* <p>This class contains two kinds of methods: methods that write specific
|
||||||
|
* protocol message constructs and field types (e.g. {@link #writeTag} and
|
||||||
|
* {@link #writeInt32}) and methods that write low-level values (e.g.
|
||||||
|
* {@link #writeRawVarint32} and {@link #writeRawBytes}). If you are
|
||||||
|
* writing encoded protocol messages, you should use the former methods, but if
|
||||||
|
* you are writing some other format of your own design, use the latter.
|
||||||
|
*
|
||||||
|
* <p>This class is totally unsynchronized.
|
||||||
|
*
|
||||||
|
* @author kneton@google.com Kenton Varda
|
||||||
|
*/
|
||||||
|
public final class CodedOutputByteBufferNano {
|
||||||
|
private final byte[] buffer;
|
||||||
|
private final int limit;
|
||||||
|
private int position;
|
||||||
|
|
||||||
|
private CodedOutputByteBufferNano(final byte[] buffer, final int offset,
|
||||||
|
final int length) {
|
||||||
|
this.buffer = buffer;
|
||||||
|
position = offset;
|
||||||
|
limit = offset + length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@code CodedOutputStream} that writes directly to the given
|
||||||
|
* byte array. If more bytes are written than fit in the array,
|
||||||
|
* {@link OutOfSpaceException} will be thrown. Writing directly to a flat
|
||||||
|
* array is faster than writing to an {@code OutputStream}.
|
||||||
|
*/
|
||||||
|
public static CodedOutputByteBufferNano newInstance(final byte[] flatArray) {
|
||||||
|
return newInstance(flatArray, 0, flatArray.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@code CodedOutputStream} that writes directly to the given
|
||||||
|
* byte array slice. If more bytes are written than fit in the slice,
|
||||||
|
* {@link OutOfSpaceException} will be thrown. Writing directly to a flat
|
||||||
|
* array is faster than writing to an {@code OutputStream}.
|
||||||
|
*/
|
||||||
|
public static CodedOutputByteBufferNano newInstance(final byte[] flatArray,
|
||||||
|
final int offset,
|
||||||
|
final int length) {
|
||||||
|
return new CodedOutputByteBufferNano(flatArray, offset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
|
||||||
|
/** Write a {@code double} field, including tag, to the stream. */
|
||||||
|
public void writeDouble(final int fieldNumber, final double value)
|
||||||
|
throws IOException {
|
||||||
|
writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED64);
|
||||||
|
writeDoubleNoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write a {@code float} field, including tag, to the stream. */
|
||||||
|
public void writeFloat(final int fieldNumber, final float value)
|
||||||
|
throws IOException {
|
||||||
|
writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED32);
|
||||||
|
writeFloatNoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write a {@code uint64} field, including tag, to the stream. */
|
||||||
|
public void writeUInt64(final int fieldNumber, final long value)
|
||||||
|
throws IOException {
|
||||||
|
writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
|
||||||
|
writeUInt64NoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write an {@code int64} field, including tag, to the stream. */
|
||||||
|
public void writeInt64(final int fieldNumber, final long value)
|
||||||
|
throws IOException {
|
||||||
|
writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
|
||||||
|
writeInt64NoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write an {@code int32} field, including tag, to the stream. */
|
||||||
|
public void writeInt32(final int fieldNumber, final int value)
|
||||||
|
throws IOException {
|
||||||
|
writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
|
||||||
|
writeInt32NoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write a {@code fixed64} field, including tag, to the stream. */
|
||||||
|
public void writeFixed64(final int fieldNumber, final long value)
|
||||||
|
throws IOException {
|
||||||
|
writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED64);
|
||||||
|
writeFixed64NoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write a {@code fixed32} field, including tag, to the stream. */
|
||||||
|
public void writeFixed32(final int fieldNumber, final int value)
|
||||||
|
throws IOException {
|
||||||
|
writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED32);
|
||||||
|
writeFixed32NoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write a {@code bool} field, including tag, to the stream. */
|
||||||
|
public void writeBool(final int fieldNumber, final boolean value)
|
||||||
|
throws IOException {
|
||||||
|
writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
|
||||||
|
writeBoolNoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write a {@code string} field, including tag, to the stream. */
|
||||||
|
public void writeString(final int fieldNumber, final String value)
|
||||||
|
throws IOException {
|
||||||
|
writeTag(fieldNumber, WireFormatNano.WIRETYPE_LENGTH_DELIMITED);
|
||||||
|
writeStringNoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write a {@code group} field, including tag, to the stream. */
|
||||||
|
public void writeGroup(final int fieldNumber, final MessageNano value)
|
||||||
|
throws IOException {
|
||||||
|
writeTag(fieldNumber, WireFormatNano.WIRETYPE_START_GROUP);
|
||||||
|
writeGroupNoTag(value);
|
||||||
|
writeTag(fieldNumber, WireFormatNano.WIRETYPE_END_GROUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write an embedded message field, including tag, to the stream. */
|
||||||
|
public void writeMessage(final int fieldNumber, final MessageNano value)
|
||||||
|
throws IOException {
|
||||||
|
writeTag(fieldNumber, WireFormatNano.WIRETYPE_LENGTH_DELIMITED);
|
||||||
|
writeMessageNoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write a {@code bytes} field, including tag, to the stream. */
|
||||||
|
public void writeBytes(final int fieldNumber, final byte[] value)
|
||||||
|
throws IOException {
|
||||||
|
writeTag(fieldNumber, WireFormatNano.WIRETYPE_LENGTH_DELIMITED);
|
||||||
|
writeBytesNoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write a {@code uint32} field, including tag, to the stream. */
|
||||||
|
public void writeUInt32(final int fieldNumber, final int value)
|
||||||
|
throws IOException {
|
||||||
|
writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
|
||||||
|
writeUInt32NoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write an enum field, including tag, to the stream. Caller is responsible
|
||||||
|
* for converting the enum value to its numeric value.
|
||||||
|
*/
|
||||||
|
public void writeEnum(final int fieldNumber, final int value)
|
||||||
|
throws IOException {
|
||||||
|
writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
|
||||||
|
writeEnumNoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write an {@code sfixed32} field, including tag, to the stream. */
|
||||||
|
public void writeSFixed32(final int fieldNumber, final int value)
|
||||||
|
throws IOException {
|
||||||
|
writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED32);
|
||||||
|
writeSFixed32NoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write an {@code sfixed64} field, including tag, to the stream. */
|
||||||
|
public void writeSFixed64(final int fieldNumber, final long value)
|
||||||
|
throws IOException {
|
||||||
|
writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED64);
|
||||||
|
writeSFixed64NoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write an {@code sint32} field, including tag, to the stream. */
|
||||||
|
public void writeSInt32(final int fieldNumber, final int value)
|
||||||
|
throws IOException {
|
||||||
|
writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
|
||||||
|
writeSInt32NoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write an {@code sint64} field, including tag, to the stream. */
|
||||||
|
public void writeSInt64(final int fieldNumber, final long value)
|
||||||
|
throws IOException {
|
||||||
|
writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
|
||||||
|
writeSInt64NoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a MessageSet extension field to the stream. For historical reasons,
|
||||||
|
* the wire format differs from normal fields.
|
||||||
|
*/
|
||||||
|
// public void writeMessageSetExtension(final int fieldNumber,
|
||||||
|
// final MessageMicro value)
|
||||||
|
// throws IOException {
|
||||||
|
// writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_START_GROUP);
|
||||||
|
// writeUInt32(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber);
|
||||||
|
// writeMessage(WireFormatMicro.MESSAGE_SET_MESSAGE, value);
|
||||||
|
// writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_END_GROUP);
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write an unparsed MessageSet extension field to the stream. For
|
||||||
|
* historical reasons, the wire format differs from normal fields.
|
||||||
|
*/
|
||||||
|
// public void writeRawMessageSetExtension(final int fieldNumber,
|
||||||
|
// final ByteStringMicro value)
|
||||||
|
// throws IOException {
|
||||||
|
// writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_START_GROUP);
|
||||||
|
// writeUInt32(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber);
|
||||||
|
// writeBytes(WireFormatMicro.MESSAGE_SET_MESSAGE, value);
|
||||||
|
// writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_END_GROUP);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
|
||||||
|
/** Write a {@code double} field to the stream. */
|
||||||
|
public void writeDoubleNoTag(final double value) throws IOException {
|
||||||
|
writeRawLittleEndian64(Double.doubleToLongBits(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write a {@code float} field to the stream. */
|
||||||
|
public void writeFloatNoTag(final float value) throws IOException {
|
||||||
|
writeRawLittleEndian32(Float.floatToIntBits(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write a {@code uint64} field to the stream. */
|
||||||
|
public void writeUInt64NoTag(final long value) throws IOException {
|
||||||
|
writeRawVarint64(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write an {@code int64} field to the stream. */
|
||||||
|
public void writeInt64NoTag(final long value) throws IOException {
|
||||||
|
writeRawVarint64(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write an {@code int32} field to the stream. */
|
||||||
|
public void writeInt32NoTag(final int value) throws IOException {
|
||||||
|
if (value >= 0) {
|
||||||
|
writeRawVarint32(value);
|
||||||
|
} else {
|
||||||
|
// Must sign-extend.
|
||||||
|
writeRawVarint64(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write a {@code fixed64} field to the stream. */
|
||||||
|
public void writeFixed64NoTag(final long value) throws IOException {
|
||||||
|
writeRawLittleEndian64(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write a {@code fixed32} field to the stream. */
|
||||||
|
public void writeFixed32NoTag(final int value) throws IOException {
|
||||||
|
writeRawLittleEndian32(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write a {@code bool} field to the stream. */
|
||||||
|
public void writeBoolNoTag(final boolean value) throws IOException {
|
||||||
|
writeRawByte(value ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write a {@code string} field to the stream. */
|
||||||
|
public void writeStringNoTag(final String value) throws IOException {
|
||||||
|
// Unfortunately there does not appear to be any way to tell Java to encode
|
||||||
|
// UTF-8 directly into our buffer, so we have to let it create its own byte
|
||||||
|
// array and then copy.
|
||||||
|
final byte[] bytes = value.getBytes("UTF-8");
|
||||||
|
writeRawVarint32(bytes.length);
|
||||||
|
writeRawBytes(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write a {@code group} field to the stream. */
|
||||||
|
public void writeGroupNoTag(final MessageNano value) throws IOException {
|
||||||
|
value.writeTo(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write an embedded message field to the stream. */
|
||||||
|
public void writeMessageNoTag(final MessageNano value) throws IOException {
|
||||||
|
writeRawVarint32(value.getCachedSize());
|
||||||
|
value.writeTo(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write a {@code bytes} field to the stream. */
|
||||||
|
public void writeBytesNoTag(final byte[] value) throws IOException {
|
||||||
|
writeRawVarint32(value.length);
|
||||||
|
writeRawBytes(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write a {@code uint32} field to the stream. */
|
||||||
|
public void writeUInt32NoTag(final int value) throws IOException {
|
||||||
|
writeRawVarint32(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write an enum field to the stream. Caller is responsible
|
||||||
|
* for converting the enum value to its numeric value.
|
||||||
|
*/
|
||||||
|
public void writeEnumNoTag(final int value) throws IOException {
|
||||||
|
writeRawVarint32(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write an {@code sfixed32} field to the stream. */
|
||||||
|
public void writeSFixed32NoTag(final int value) throws IOException {
|
||||||
|
writeRawLittleEndian32(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write an {@code sfixed64} field to the stream. */
|
||||||
|
public void writeSFixed64NoTag(final long value) throws IOException {
|
||||||
|
writeRawLittleEndian64(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write an {@code sint32} field to the stream. */
|
||||||
|
public void writeSInt32NoTag(final int value) throws IOException {
|
||||||
|
writeRawVarint32(encodeZigZag32(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write an {@code sint64} field to the stream. */
|
||||||
|
public void writeSInt64NoTag(final long value) throws IOException {
|
||||||
|
writeRawVarint64(encodeZigZag64(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
// =================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode a
|
||||||
|
* {@code double} field, including tag.
|
||||||
|
*/
|
||||||
|
public static int computeDoubleSize(final int fieldNumber,
|
||||||
|
final double value) {
|
||||||
|
return computeTagSize(fieldNumber) + computeDoubleSizeNoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode a
|
||||||
|
* {@code float} field, including tag.
|
||||||
|
*/
|
||||||
|
public static int computeFloatSize(final int fieldNumber, final float value) {
|
||||||
|
return computeTagSize(fieldNumber) + computeFloatSizeNoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode a
|
||||||
|
* {@code uint64} field, including tag.
|
||||||
|
*/
|
||||||
|
public static int computeUInt64Size(final int fieldNumber, final long value) {
|
||||||
|
return computeTagSize(fieldNumber) + computeUInt64SizeNoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode an
|
||||||
|
* {@code int64} field, including tag.
|
||||||
|
*/
|
||||||
|
public static int computeInt64Size(final int fieldNumber, final long value) {
|
||||||
|
return computeTagSize(fieldNumber) + computeInt64SizeNoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode an
|
||||||
|
* {@code int32} field, including tag.
|
||||||
|
*/
|
||||||
|
public static int computeInt32Size(final int fieldNumber, final int value) {
|
||||||
|
return computeTagSize(fieldNumber) + computeInt32SizeNoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode a
|
||||||
|
* {@code fixed64} field, including tag.
|
||||||
|
*/
|
||||||
|
public static int computeFixed64Size(final int fieldNumber,
|
||||||
|
final long value) {
|
||||||
|
return computeTagSize(fieldNumber) + computeFixed64SizeNoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode a
|
||||||
|
* {@code fixed32} field, including tag.
|
||||||
|
*/
|
||||||
|
public static int computeFixed32Size(final int fieldNumber,
|
||||||
|
final int value) {
|
||||||
|
return computeTagSize(fieldNumber) + computeFixed32SizeNoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode a
|
||||||
|
* {@code bool} field, including tag.
|
||||||
|
*/
|
||||||
|
public static int computeBoolSize(final int fieldNumber,
|
||||||
|
final boolean value) {
|
||||||
|
return computeTagSize(fieldNumber) + computeBoolSizeNoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode a
|
||||||
|
* {@code string} field, including tag.
|
||||||
|
*/
|
||||||
|
public static int computeStringSize(final int fieldNumber,
|
||||||
|
final String value) {
|
||||||
|
return computeTagSize(fieldNumber) + computeStringSizeNoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode a
|
||||||
|
* {@code group} field, including tag.
|
||||||
|
*/
|
||||||
|
public static int computeGroupSize(final int fieldNumber,
|
||||||
|
final MessageNano value) {
|
||||||
|
return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode an
|
||||||
|
* embedded message field, including tag.
|
||||||
|
*/
|
||||||
|
public static int computeMessageSize(final int fieldNumber,
|
||||||
|
final MessageNano value) {
|
||||||
|
return computeTagSize(fieldNumber) + computeMessageSizeNoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode a
|
||||||
|
* {@code bytes} field, including tag.
|
||||||
|
*/
|
||||||
|
public static int computeBytesSize(final int fieldNumber,
|
||||||
|
final byte[] value) {
|
||||||
|
return computeTagSize(fieldNumber) + computeBytesSizeNoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode a
|
||||||
|
* {@code uint32} field, including tag.
|
||||||
|
*/
|
||||||
|
public static int computeUInt32Size(final int fieldNumber, final int value) {
|
||||||
|
return computeTagSize(fieldNumber) + computeUInt32SizeNoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode an
|
||||||
|
* enum field, including tag. Caller is responsible for converting the
|
||||||
|
* enum value to its numeric value.
|
||||||
|
*/
|
||||||
|
public static int computeEnumSize(final int fieldNumber, final int value) {
|
||||||
|
return computeTagSize(fieldNumber) + computeEnumSizeNoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode an
|
||||||
|
* {@code sfixed32} field, including tag.
|
||||||
|
*/
|
||||||
|
public static int computeSFixed32Size(final int fieldNumber,
|
||||||
|
final int value) {
|
||||||
|
return computeTagSize(fieldNumber) + computeSFixed32SizeNoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode an
|
||||||
|
* {@code sfixed64} field, including tag.
|
||||||
|
*/
|
||||||
|
public static int computeSFixed64Size(final int fieldNumber,
|
||||||
|
final long value) {
|
||||||
|
return computeTagSize(fieldNumber) + computeSFixed64SizeNoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode an
|
||||||
|
* {@code sint32} field, including tag.
|
||||||
|
*/
|
||||||
|
public static int computeSInt32Size(final int fieldNumber, final int value) {
|
||||||
|
return computeTagSize(fieldNumber) + computeSInt32SizeNoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode an
|
||||||
|
* {@code sint64} field, including tag.
|
||||||
|
*/
|
||||||
|
public static int computeSInt64Size(final int fieldNumber, final long value) {
|
||||||
|
return computeTagSize(fieldNumber) + computeSInt64SizeNoTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode a
|
||||||
|
* MessageSet extension to the stream. For historical reasons,
|
||||||
|
* the wire format differs from normal fields.
|
||||||
|
*/
|
||||||
|
// public static int computeMessageSetExtensionSize(
|
||||||
|
// final int fieldNumber, final MessageMicro value) {
|
||||||
|
// return computeTagSize(WireFormatMicro.MESSAGE_SET_ITEM) * 2 +
|
||||||
|
// computeUInt32Size(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber) +
|
||||||
|
// computeMessageSize(WireFormatMicro.MESSAGE_SET_MESSAGE, value);
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode an
|
||||||
|
* unparsed MessageSet extension field to the stream. For
|
||||||
|
* historical reasons, the wire format differs from normal fields.
|
||||||
|
*/
|
||||||
|
// public static int computeRawMessageSetExtensionSize(
|
||||||
|
// final int fieldNumber, final ByteStringMicro value) {
|
||||||
|
// return computeTagSize(WireFormatMicro.MESSAGE_SET_ITEM) * 2 +
|
||||||
|
// computeUInt32Size(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber) +
|
||||||
|
// computeBytesSize(WireFormatMicro.MESSAGE_SET_MESSAGE, value);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode a
|
||||||
|
* {@code double} field, including tag.
|
||||||
|
*/
|
||||||
|
public static int computeDoubleSizeNoTag(final double value) {
|
||||||
|
return LITTLE_ENDIAN_64_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode a
|
||||||
|
* {@code float} field, including tag.
|
||||||
|
*/
|
||||||
|
public static int computeFloatSizeNoTag(final float value) {
|
||||||
|
return LITTLE_ENDIAN_32_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode a
|
||||||
|
* {@code uint64} field, including tag.
|
||||||
|
*/
|
||||||
|
public static int computeUInt64SizeNoTag(final long value) {
|
||||||
|
return computeRawVarint64Size(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode an
|
||||||
|
* {@code int64} field, including tag.
|
||||||
|
*/
|
||||||
|
public static int computeInt64SizeNoTag(final long value) {
|
||||||
|
return computeRawVarint64Size(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode an
|
||||||
|
* {@code int32} field, including tag.
|
||||||
|
*/
|
||||||
|
public static int computeInt32SizeNoTag(final int value) {
|
||||||
|
if (value >= 0) {
|
||||||
|
return computeRawVarint32Size(value);
|
||||||
|
} else {
|
||||||
|
// Must sign-extend.
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode a
|
||||||
|
* {@code fixed64} field.
|
||||||
|
*/
|
||||||
|
public static int computeFixed64SizeNoTag(final long value) {
|
||||||
|
return LITTLE_ENDIAN_64_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode a
|
||||||
|
* {@code fixed32} field.
|
||||||
|
*/
|
||||||
|
public static int computeFixed32SizeNoTag(final int value) {
|
||||||
|
return LITTLE_ENDIAN_32_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode a
|
||||||
|
* {@code bool} field.
|
||||||
|
*/
|
||||||
|
public static int computeBoolSizeNoTag(final boolean value) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode a
|
||||||
|
* {@code string} field.
|
||||||
|
*/
|
||||||
|
public static int computeStringSizeNoTag(final String value) {
|
||||||
|
try {
|
||||||
|
final byte[] bytes = value.getBytes("UTF-8");
|
||||||
|
return computeRawVarint32Size(bytes.length) +
|
||||||
|
bytes.length;
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
throw new RuntimeException("UTF-8 not supported.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode a
|
||||||
|
* {@code group} field.
|
||||||
|
*/
|
||||||
|
public static int computeGroupSizeNoTag(final MessageNano value) {
|
||||||
|
return value.getSerializedSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode an embedded
|
||||||
|
* message field.
|
||||||
|
*/
|
||||||
|
public static int computeMessageSizeNoTag(final MessageNano value) {
|
||||||
|
final int size = value.getSerializedSize();
|
||||||
|
return computeRawVarint32Size(size) + size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode a
|
||||||
|
* {@code bytes} field.
|
||||||
|
*/
|
||||||
|
public static int computeBytesSizeNoTag(final byte[] value) {
|
||||||
|
return computeRawVarint32Size(value.length) + value.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode a
|
||||||
|
* {@code uint32} field.
|
||||||
|
*/
|
||||||
|
public static int computeUInt32SizeNoTag(final int value) {
|
||||||
|
return computeRawVarint32Size(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode an enum field.
|
||||||
|
* Caller is responsible for converting the enum value to its numeric value.
|
||||||
|
*/
|
||||||
|
public static int computeEnumSizeNoTag(final int value) {
|
||||||
|
return computeRawVarint32Size(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode an
|
||||||
|
* {@code sfixed32} field.
|
||||||
|
*/
|
||||||
|
public static int computeSFixed32SizeNoTag(final int value) {
|
||||||
|
return LITTLE_ENDIAN_32_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode an
|
||||||
|
* {@code sfixed64} field.
|
||||||
|
*/
|
||||||
|
public static int computeSFixed64SizeNoTag(final long value) {
|
||||||
|
return LITTLE_ENDIAN_64_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode an
|
||||||
|
* {@code sint32} field.
|
||||||
|
*/
|
||||||
|
public static int computeSInt32SizeNoTag(final int value) {
|
||||||
|
return computeRawVarint32Size(encodeZigZag32(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode an
|
||||||
|
* {@code sint64} field.
|
||||||
|
*/
|
||||||
|
public static int computeSInt64SizeNoTag(final long value) {
|
||||||
|
return computeRawVarint64Size(encodeZigZag64(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
// =================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If writing to a flat array, return the space left in the array.
|
||||||
|
* Otherwise, throws {@code UnsupportedOperationException}.
|
||||||
|
*/
|
||||||
|
public int spaceLeft() {
|
||||||
|
return limit - position;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies that {@link #spaceLeft()} returns zero. It's common to create
|
||||||
|
* a byte array that is exactly big enough to hold a message, then write to
|
||||||
|
* it with a {@code CodedOutputStream}. Calling {@code checkNoSpaceLeft()}
|
||||||
|
* after writing verifies that the message was actually as big as expected,
|
||||||
|
* which can help catch bugs.
|
||||||
|
*/
|
||||||
|
public void checkNoSpaceLeft() {
|
||||||
|
if (spaceLeft() != 0) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Did not write as much data as expected.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If you create a CodedOutputStream around a simple flat array, you must
|
||||||
|
* not attempt to write more bytes than the array has space. Otherwise,
|
||||||
|
* this exception will be thrown.
|
||||||
|
*/
|
||||||
|
public static class OutOfSpaceException extends IOException {
|
||||||
|
private static final long serialVersionUID = -6947486886997889499L;
|
||||||
|
|
||||||
|
OutOfSpaceException(int position, int limit) {
|
||||||
|
super("CodedOutputStream was writing to a flat byte array and ran " +
|
||||||
|
"out of space (pos " + position + " limit " + limit + ").");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write a single byte. */
|
||||||
|
public void writeRawByte(final byte value) throws IOException {
|
||||||
|
if (position == limit) {
|
||||||
|
// We're writing to a single buffer.
|
||||||
|
throw new OutOfSpaceException(position, limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[position++] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write a single byte, represented by an integer value. */
|
||||||
|
public void writeRawByte(final int value) throws IOException {
|
||||||
|
writeRawByte((byte) value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write an array of bytes. */
|
||||||
|
public void writeRawBytes(final byte[] value) throws IOException {
|
||||||
|
writeRawBytes(value, 0, value.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write part of an array of bytes. */
|
||||||
|
public void writeRawBytes(final byte[] value, int offset, int length)
|
||||||
|
throws IOException {
|
||||||
|
if (limit - position >= length) {
|
||||||
|
// We have room in the current buffer.
|
||||||
|
System.arraycopy(value, offset, buffer, position, length);
|
||||||
|
position += length;
|
||||||
|
} else {
|
||||||
|
// We're writing to a single buffer.
|
||||||
|
throw new OutOfSpaceException(position, limit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Encode and write a tag. */
|
||||||
|
public void writeTag(final int fieldNumber, final int wireType)
|
||||||
|
throws IOException {
|
||||||
|
writeRawVarint32(WireFormatNano.makeTag(fieldNumber, wireType));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Compute the number of bytes that would be needed to encode a tag. */
|
||||||
|
public static int computeTagSize(final int fieldNumber) {
|
||||||
|
return computeRawVarint32Size(WireFormatNano.makeTag(fieldNumber, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode and write a varint. {@code value} is treated as
|
||||||
|
* unsigned, so it won't be sign-extended if negative.
|
||||||
|
*/
|
||||||
|
public void writeRawVarint32(int value) throws IOException {
|
||||||
|
while (true) {
|
||||||
|
if ((value & ~0x7F) == 0) {
|
||||||
|
writeRawByte(value);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
writeRawByte((value & 0x7F) | 0x80);
|
||||||
|
value >>>= 7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes that would be needed to encode a varint.
|
||||||
|
* {@code value} is treated as unsigned, so it won't be sign-extended if
|
||||||
|
* negative.
|
||||||
|
*/
|
||||||
|
public static int computeRawVarint32Size(final int value) {
|
||||||
|
if ((value & (0xffffffff << 7)) == 0) return 1;
|
||||||
|
if ((value & (0xffffffff << 14)) == 0) return 2;
|
||||||
|
if ((value & (0xffffffff << 21)) == 0) return 3;
|
||||||
|
if ((value & (0xffffffff << 28)) == 0) return 4;
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Encode and write a varint. */
|
||||||
|
public void writeRawVarint64(long value) throws IOException {
|
||||||
|
while (true) {
|
||||||
|
if ((value & ~0x7FL) == 0) {
|
||||||
|
writeRawByte((int)value);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
writeRawByte(((int)value & 0x7F) | 0x80);
|
||||||
|
value >>>= 7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Compute the number of bytes that would be needed to encode a varint. */
|
||||||
|
public static int computeRawVarint64Size(final long value) {
|
||||||
|
if ((value & (0xffffffffffffffffL << 7)) == 0) return 1;
|
||||||
|
if ((value & (0xffffffffffffffffL << 14)) == 0) return 2;
|
||||||
|
if ((value & (0xffffffffffffffffL << 21)) == 0) return 3;
|
||||||
|
if ((value & (0xffffffffffffffffL << 28)) == 0) return 4;
|
||||||
|
if ((value & (0xffffffffffffffffL << 35)) == 0) return 5;
|
||||||
|
if ((value & (0xffffffffffffffffL << 42)) == 0) return 6;
|
||||||
|
if ((value & (0xffffffffffffffffL << 49)) == 0) return 7;
|
||||||
|
if ((value & (0xffffffffffffffffL << 56)) == 0) return 8;
|
||||||
|
if ((value & (0xffffffffffffffffL << 63)) == 0) return 9;
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Write a little-endian 32-bit integer. */
|
||||||
|
public void writeRawLittleEndian32(final int value) throws IOException {
|
||||||
|
writeRawByte((value ) & 0xFF);
|
||||||
|
writeRawByte((value >> 8) & 0xFF);
|
||||||
|
writeRawByte((value >> 16) & 0xFF);
|
||||||
|
writeRawByte((value >> 24) & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final int LITTLE_ENDIAN_32_SIZE = 4;
|
||||||
|
|
||||||
|
/** Write a little-endian 64-bit integer. */
|
||||||
|
public void writeRawLittleEndian64(final long value) throws IOException {
|
||||||
|
writeRawByte((int)(value ) & 0xFF);
|
||||||
|
writeRawByte((int)(value >> 8) & 0xFF);
|
||||||
|
writeRawByte((int)(value >> 16) & 0xFF);
|
||||||
|
writeRawByte((int)(value >> 24) & 0xFF);
|
||||||
|
writeRawByte((int)(value >> 32) & 0xFF);
|
||||||
|
writeRawByte((int)(value >> 40) & 0xFF);
|
||||||
|
writeRawByte((int)(value >> 48) & 0xFF);
|
||||||
|
writeRawByte((int)(value >> 56) & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final int LITTLE_ENDIAN_64_SIZE = 8;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers
|
||||||
|
* into values that can be efficiently encoded with varint. (Otherwise,
|
||||||
|
* negative values must be sign-extended to 64 bits to be varint encoded,
|
||||||
|
* thus always taking 10 bytes on the wire.)
|
||||||
|
*
|
||||||
|
* @param n A signed 32-bit integer.
|
||||||
|
* @return An unsigned 32-bit integer, stored in a signed int because
|
||||||
|
* Java has no explicit unsigned support.
|
||||||
|
*/
|
||||||
|
public static int encodeZigZag32(final int n) {
|
||||||
|
// Note: the right-shift must be arithmetic
|
||||||
|
return (n << 1) ^ (n >> 31);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers
|
||||||
|
* into values that can be efficiently encoded with varint. (Otherwise,
|
||||||
|
* negative values must be sign-extended to 64 bits to be varint encoded,
|
||||||
|
* thus always taking 10 bytes on the wire.)
|
||||||
|
*
|
||||||
|
* @param n A signed 64-bit integer.
|
||||||
|
* @return An unsigned 64-bit integer, stored in a signed int because
|
||||||
|
* Java has no explicit unsigned support.
|
||||||
|
*/
|
||||||
|
public static long encodeZigZag64(final long n) {
|
||||||
|
// Note: the right-shift must be arithmetic
|
||||||
|
return (n << 1) ^ (n >> 63);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,187 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2013 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package com.google.protobuf.nano;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class of those Protocol Buffer messages that need to store unknown fields,
|
||||||
|
* such as extensions.
|
||||||
|
*/
|
||||||
|
public abstract class ExtendableMessageNano<M extends ExtendableMessageNano<M>>
|
||||||
|
extends MessageNano {
|
||||||
|
/**
|
||||||
|
* A container for fields unknown to the message, including extensions. Extension fields can
|
||||||
|
* can be accessed through the {@link #getExtension} and {@link #setExtension} methods.
|
||||||
|
*/
|
||||||
|
protected FieldArray unknownFieldData;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int computeSerializedSize() {
|
||||||
|
int size = 0;
|
||||||
|
if (unknownFieldData != null) {
|
||||||
|
for (int i = 0; i < unknownFieldData.size(); i++) {
|
||||||
|
FieldData field = unknownFieldData.dataAt(i);
|
||||||
|
size += field.computeSerializedSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeTo(CodedOutputByteBufferNano output) throws IOException {
|
||||||
|
if (unknownFieldData == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < unknownFieldData.size(); i++) {
|
||||||
|
FieldData field = unknownFieldData.dataAt(i);
|
||||||
|
field.writeTo(output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if there is a value stored for the specified extension in this
|
||||||
|
* message.
|
||||||
|
*/
|
||||||
|
public final boolean hasExtension(Extension<M, ?> extension) {
|
||||||
|
if (unknownFieldData == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
FieldData field = unknownFieldData.get(WireFormatNano.getTagFieldNumber(extension.tag));
|
||||||
|
return field != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the value stored in the specified extension of this message.
|
||||||
|
*/
|
||||||
|
public final <T> T getExtension(Extension<M, T> extension) {
|
||||||
|
if (unknownFieldData == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
FieldData field = unknownFieldData.get(WireFormatNano.getTagFieldNumber(extension.tag));
|
||||||
|
return field == null ? null : field.getValue(extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value of the specified extension of this message.
|
||||||
|
*/
|
||||||
|
public final <T> M setExtension(Extension<M, T> extension, T value) {
|
||||||
|
int fieldNumber = WireFormatNano.getTagFieldNumber(extension.tag);
|
||||||
|
if (value == null) {
|
||||||
|
if (unknownFieldData != null) {
|
||||||
|
unknownFieldData.remove(fieldNumber);
|
||||||
|
if (unknownFieldData.isEmpty()) {
|
||||||
|
unknownFieldData = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
FieldData field = null;
|
||||||
|
if (unknownFieldData == null) {
|
||||||
|
unknownFieldData = new FieldArray();
|
||||||
|
} else {
|
||||||
|
field = unknownFieldData.get(fieldNumber);
|
||||||
|
}
|
||||||
|
if (field == null) {
|
||||||
|
unknownFieldData.put(fieldNumber, new FieldData(extension, value));
|
||||||
|
} else {
|
||||||
|
field.setValue(extension, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked") // Generated code should guarantee type safety
|
||||||
|
M typedThis = (M) this;
|
||||||
|
return typedThis;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the binary data of an unknown field.
|
||||||
|
*
|
||||||
|
* <p>Generated messages will call this for unknown fields if the store_unknown_fields
|
||||||
|
* option is on.
|
||||||
|
*
|
||||||
|
* <p>Note that the tag might be a end-group tag (rather than the start of an unknown field) in
|
||||||
|
* which case we do not want to add an unknown field entry.
|
||||||
|
*
|
||||||
|
* @param input the input buffer.
|
||||||
|
* @param tag the tag of the field.
|
||||||
|
|
||||||
|
* @return {@literal true} unless the tag is an end-group tag.
|
||||||
|
*/
|
||||||
|
protected final boolean storeUnknownField(CodedInputByteBufferNano input, int tag)
|
||||||
|
throws IOException {
|
||||||
|
int startPos = input.getPosition();
|
||||||
|
if (!input.skipField(tag)) {
|
||||||
|
return false; // This wasn't an unknown field, it's an end-group tag.
|
||||||
|
}
|
||||||
|
int fieldNumber = WireFormatNano.getTagFieldNumber(tag);
|
||||||
|
int endPos = input.getPosition();
|
||||||
|
byte[] bytes = input.getData(startPos, endPos - startPos);
|
||||||
|
UnknownFieldData unknownField = new UnknownFieldData(tag, bytes);
|
||||||
|
|
||||||
|
FieldData field = null;
|
||||||
|
if (unknownFieldData == null) {
|
||||||
|
unknownFieldData = new FieldArray();
|
||||||
|
} else {
|
||||||
|
field = unknownFieldData.get(fieldNumber);
|
||||||
|
}
|
||||||
|
if (field == null) {
|
||||||
|
field = new FieldData();
|
||||||
|
unknownFieldData.put(fieldNumber, field);
|
||||||
|
}
|
||||||
|
field.addUnknownField(unknownField);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the stored unknown field data in this message is equivalent to that in the
|
||||||
|
* other message.
|
||||||
|
*
|
||||||
|
* @param other the other message.
|
||||||
|
* @return whether the two sets of unknown field data are equal.
|
||||||
|
*/
|
||||||
|
protected final boolean unknownFieldDataEquals(M other) {
|
||||||
|
if (unknownFieldData == null || unknownFieldData.isEmpty()) {
|
||||||
|
return other.unknownFieldData == null || other.unknownFieldData.isEmpty();
|
||||||
|
} else {
|
||||||
|
return unknownFieldData.equals(other.unknownFieldData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the hashcode representing the unknown field data stored in this message.
|
||||||
|
*
|
||||||
|
* @return the hashcode for the unknown field data.
|
||||||
|
*/
|
||||||
|
protected final int unknownFieldDataHashCode() {
|
||||||
|
return (unknownFieldData == null || unknownFieldData.isEmpty()
|
||||||
|
? 0 : unknownFieldData.hashCode());
|
||||||
|
}
|
||||||
|
}
|
722
javanano/src/main/java/com/google/protobuf/nano/Extension.java
Normal file
722
javanano/src/main/java/com/google/protobuf/nano/Extension.java
Normal file
@ -0,0 +1,722 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2013 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package com.google.protobuf.nano;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Array;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an extension.
|
||||||
|
*
|
||||||
|
* @author bduff@google.com (Brian Duff)
|
||||||
|
* @author maxtroy@google.com (Max Cai)
|
||||||
|
* @param <M> the type of the extendable message this extension is for.
|
||||||
|
* @param <T> the Java type of the extension; see {@link #clazz}.
|
||||||
|
*/
|
||||||
|
public class Extension<M extends ExtendableMessageNano<M>, T> {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Because we typically only define message-typed extensions, the Extension class hierarchy is
|
||||||
|
* designed as follows, to allow a big amount of code in this file to be removed by ProGuard:
|
||||||
|
*
|
||||||
|
* Extension // ready to use for message/group typed extensions
|
||||||
|
* Δ
|
||||||
|
* |
|
||||||
|
* PrimitiveExtension // for primitive/enum typed extensions
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static final int TYPE_DOUBLE = 1;
|
||||||
|
public static final int TYPE_FLOAT = 2;
|
||||||
|
public static final int TYPE_INT64 = 3;
|
||||||
|
public static final int TYPE_UINT64 = 4;
|
||||||
|
public static final int TYPE_INT32 = 5;
|
||||||
|
public static final int TYPE_FIXED64 = 6;
|
||||||
|
public static final int TYPE_FIXED32 = 7;
|
||||||
|
public static final int TYPE_BOOL = 8;
|
||||||
|
public static final int TYPE_STRING = 9;
|
||||||
|
public static final int TYPE_GROUP = 10;
|
||||||
|
public static final int TYPE_MESSAGE = 11;
|
||||||
|
public static final int TYPE_BYTES = 12;
|
||||||
|
public static final int TYPE_UINT32 = 13;
|
||||||
|
public static final int TYPE_ENUM = 14;
|
||||||
|
public static final int TYPE_SFIXED32 = 15;
|
||||||
|
public static final int TYPE_SFIXED64 = 16;
|
||||||
|
public static final int TYPE_SINT32 = 17;
|
||||||
|
public static final int TYPE_SINT64 = 18;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an {@code Extension} of the given message type and tag number.
|
||||||
|
* Should be used by the generated code only.
|
||||||
|
*
|
||||||
|
* @param type {@link #TYPE_MESSAGE} or {@link #TYPE_GROUP}
|
||||||
|
*/
|
||||||
|
public static <M extends ExtendableMessageNano<M>, T extends MessageNano>
|
||||||
|
Extension<M, T> createMessageTyped(int type, Class<T> clazz, int tag) {
|
||||||
|
return new Extension<M, T>(type, clazz, tag, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a repeated {@code Extension} of the given message type and tag number.
|
||||||
|
* Should be used by the generated code only.
|
||||||
|
*
|
||||||
|
* @param type {@link #TYPE_MESSAGE} or {@link #TYPE_GROUP}
|
||||||
|
*/
|
||||||
|
public static <M extends ExtendableMessageNano<M>, T extends MessageNano>
|
||||||
|
Extension<M, T[]> createRepeatedMessageTyped(int type, Class<T[]> clazz, int tag) {
|
||||||
|
return new Extension<M, T[]>(type, clazz, tag, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an {@code Extension} of the given primitive type and tag number.
|
||||||
|
* Should be used by the generated code only.
|
||||||
|
*
|
||||||
|
* @param type one of {@code TYPE_*}, except {@link #TYPE_MESSAGE} and {@link #TYPE_GROUP}
|
||||||
|
* @param clazz the boxed Java type of this extension
|
||||||
|
*/
|
||||||
|
public static <M extends ExtendableMessageNano<M>, T>
|
||||||
|
Extension<M, T> createPrimitiveTyped(int type, Class<T> clazz, int tag) {
|
||||||
|
return new PrimitiveExtension<M, T>(type, clazz, tag, false, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a repeated {@code Extension} of the given primitive type and tag number.
|
||||||
|
* Should be used by the generated code only.
|
||||||
|
*
|
||||||
|
* @param type one of {@code TYPE_*}, except {@link #TYPE_MESSAGE} and {@link #TYPE_GROUP}
|
||||||
|
* @param clazz the Java array type of this extension, with an unboxed component type
|
||||||
|
*/
|
||||||
|
public static <M extends ExtendableMessageNano<M>, T>
|
||||||
|
Extension<M, T> createRepeatedPrimitiveTyped(
|
||||||
|
int type, Class<T> clazz, int tag, int nonPackedTag, int packedTag) {
|
||||||
|
return new PrimitiveExtension<M, T>(type, clazz, tag, true, nonPackedTag, packedTag);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protocol Buffer type of this extension; one of the {@code TYPE_} constants.
|
||||||
|
*/
|
||||||
|
protected final int type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Java type of this extension. For a singular extension, this is the boxed Java type for the
|
||||||
|
* Protocol Buffer {@link #type}; for a repeated extension, this is an array type whose
|
||||||
|
* component type is the unboxed Java type for {@link #type}. For example, for a singular
|
||||||
|
* {@code int32}/{@link #TYPE_INT32} extension, this equals {@code Integer.class}; for a
|
||||||
|
* repeated {@code int32} extension, this equals {@code int[].class}.
|
||||||
|
*/
|
||||||
|
protected final Class<T> clazz;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tag number of this extension.
|
||||||
|
*/
|
||||||
|
public final int tag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this extension is repeated.
|
||||||
|
*/
|
||||||
|
protected final boolean repeated;
|
||||||
|
|
||||||
|
private Extension(int type, Class<T> clazz, int tag, boolean repeated) {
|
||||||
|
this.type = type;
|
||||||
|
this.clazz = clazz;
|
||||||
|
this.tag = tag;
|
||||||
|
this.repeated = repeated;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of this extension stored in the given list of unknown fields, or
|
||||||
|
* {@code null} if no unknown fields matches this extension.
|
||||||
|
*
|
||||||
|
* @param unknownFields a list of {@link UnknownFieldData}. All of the elements must have a tag
|
||||||
|
* that matches this Extension's tag.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
final T getValueFrom(List<UnknownFieldData> unknownFields) {
|
||||||
|
if (unknownFields == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return repeated ? getRepeatedValueFrom(unknownFields) : getSingularValueFrom(unknownFields);
|
||||||
|
}
|
||||||
|
|
||||||
|
private T getRepeatedValueFrom(List<UnknownFieldData> unknownFields) {
|
||||||
|
// For repeated extensions, read all matching unknown fields in their original order.
|
||||||
|
List<Object> resultList = new ArrayList<Object>();
|
||||||
|
for (int i = 0; i < unknownFields.size(); i++) {
|
||||||
|
UnknownFieldData data = unknownFields.get(i);
|
||||||
|
if (data.bytes.length != 0) {
|
||||||
|
readDataInto(data, resultList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int resultSize = resultList.size();
|
||||||
|
if (resultSize == 0) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
T result = clazz.cast(Array.newInstance(clazz.getComponentType(), resultSize));
|
||||||
|
for (int i = 0; i < resultSize; i++) {
|
||||||
|
Array.set(result, i, resultList.get(i));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private T getSingularValueFrom(List<UnknownFieldData> unknownFields) {
|
||||||
|
// For singular extensions, get the last piece of data stored under this extension.
|
||||||
|
if (unknownFields.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
UnknownFieldData lastData = unknownFields.get(unknownFields.size() - 1);
|
||||||
|
return clazz.cast(readData(CodedInputByteBufferNano.newInstance(lastData.bytes)));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Object readData(CodedInputByteBufferNano input) {
|
||||||
|
// This implementation is for message/group extensions.
|
||||||
|
Class<?> messageType = repeated ? clazz.getComponentType() : clazz;
|
||||||
|
try {
|
||||||
|
switch (type) {
|
||||||
|
case TYPE_GROUP:
|
||||||
|
MessageNano group = (MessageNano) messageType.newInstance();
|
||||||
|
input.readGroup(group, WireFormatNano.getTagFieldNumber(tag));
|
||||||
|
return group;
|
||||||
|
case TYPE_MESSAGE:
|
||||||
|
MessageNano message = (MessageNano) messageType.newInstance();
|
||||||
|
input.readMessage(message);
|
||||||
|
return message;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unknown type " + type);
|
||||||
|
}
|
||||||
|
} catch (InstantiationException e) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Error creating instance of class " + messageType, e);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Error creating instance of class " + messageType, e);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new IllegalArgumentException("Error reading extension field", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void readDataInto(UnknownFieldData data, List<Object> resultList) {
|
||||||
|
// This implementation is for message/group extensions.
|
||||||
|
resultList.add(readData(CodedInputByteBufferNano.newInstance(data.bytes)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeTo(Object value, CodedOutputByteBufferNano output) throws IOException {
|
||||||
|
if (repeated) {
|
||||||
|
writeRepeatedData(value, output);
|
||||||
|
} else {
|
||||||
|
writeSingularData(value, output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void writeSingularData(Object value, CodedOutputByteBufferNano out) {
|
||||||
|
// This implementation is for message/group extensions.
|
||||||
|
try {
|
||||||
|
out.writeRawVarint32(tag);
|
||||||
|
switch (type) {
|
||||||
|
case TYPE_GROUP:
|
||||||
|
MessageNano groupValue = (MessageNano) value;
|
||||||
|
int fieldNumber = WireFormatNano.getTagFieldNumber(tag);
|
||||||
|
out.writeGroupNoTag(groupValue);
|
||||||
|
// The endgroup tag must be included in the data payload.
|
||||||
|
out.writeTag(fieldNumber, WireFormatNano.WIRETYPE_END_GROUP);
|
||||||
|
break;
|
||||||
|
case TYPE_MESSAGE:
|
||||||
|
MessageNano messageValue = (MessageNano) value;
|
||||||
|
out.writeMessageNoTag(messageValue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unknown type " + type);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
// Should not happen
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void writeRepeatedData(Object array, CodedOutputByteBufferNano output) {
|
||||||
|
// This implementation is for non-packed extensions.
|
||||||
|
int arrayLength = Array.getLength(array);
|
||||||
|
for (int i = 0; i < arrayLength; i++) {
|
||||||
|
Object element = Array.get(array, i);
|
||||||
|
if (element != null) {
|
||||||
|
writeSingularData(element, output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int computeSerializedSize(Object value) {
|
||||||
|
if (repeated) {
|
||||||
|
return computeRepeatedSerializedSize(value);
|
||||||
|
} else {
|
||||||
|
return computeSingularSerializedSize(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int computeRepeatedSerializedSize(Object array) {
|
||||||
|
// This implementation is for non-packed extensions.
|
||||||
|
int size = 0;
|
||||||
|
int arrayLength = Array.getLength(array);
|
||||||
|
for (int i = 0; i < arrayLength; i++) {
|
||||||
|
Object element = Array.get(array, i);
|
||||||
|
if (element != null) {
|
||||||
|
size += computeSingularSerializedSize(Array.get(array, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int computeSingularSerializedSize(Object value) {
|
||||||
|
// This implementation is for message/group extensions.
|
||||||
|
int fieldNumber = WireFormatNano.getTagFieldNumber(tag);
|
||||||
|
switch (type) {
|
||||||
|
case TYPE_GROUP:
|
||||||
|
MessageNano groupValue = (MessageNano) value;
|
||||||
|
return CodedOutputByteBufferNano.computeGroupSize(fieldNumber, groupValue);
|
||||||
|
case TYPE_MESSAGE:
|
||||||
|
MessageNano messageValue = (MessageNano) value;
|
||||||
|
return CodedOutputByteBufferNano.computeMessageSize(fieldNumber, messageValue);
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unknown type " + type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an extension of a primitive (including enum) type. If there is no primitive
|
||||||
|
* extensions, this subclass will be removable by ProGuard.
|
||||||
|
*/
|
||||||
|
private static class PrimitiveExtension<M extends ExtendableMessageNano<M>, T>
|
||||||
|
extends Extension<M, T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tag of a piece of non-packed data from the wire compatible with this extension.
|
||||||
|
*/
|
||||||
|
private final int nonPackedTag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tag of a piece of packed data from the wire compatible with this extension.
|
||||||
|
* 0 if the type of this extension is not packable.
|
||||||
|
*/
|
||||||
|
private final int packedTag;
|
||||||
|
|
||||||
|
public PrimitiveExtension(int type, Class<T> clazz, int tag, boolean repeated,
|
||||||
|
int nonPackedTag, int packedTag) {
|
||||||
|
super(type, clazz, tag, repeated);
|
||||||
|
this.nonPackedTag = nonPackedTag;
|
||||||
|
this.packedTag = packedTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Object readData(CodedInputByteBufferNano input) {
|
||||||
|
try {
|
||||||
|
switch (type) {
|
||||||
|
case TYPE_DOUBLE:
|
||||||
|
return input.readDouble();
|
||||||
|
case TYPE_FLOAT:
|
||||||
|
return input.readFloat();
|
||||||
|
case TYPE_INT64:
|
||||||
|
return input.readInt64();
|
||||||
|
case TYPE_UINT64:
|
||||||
|
return input.readUInt64();
|
||||||
|
case TYPE_INT32:
|
||||||
|
return input.readInt32();
|
||||||
|
case TYPE_FIXED64:
|
||||||
|
return input.readFixed64();
|
||||||
|
case TYPE_FIXED32:
|
||||||
|
return input.readFixed32();
|
||||||
|
case TYPE_BOOL:
|
||||||
|
return input.readBool();
|
||||||
|
case TYPE_STRING:
|
||||||
|
return input.readString();
|
||||||
|
case TYPE_BYTES:
|
||||||
|
return input.readBytes();
|
||||||
|
case TYPE_UINT32:
|
||||||
|
return input.readUInt32();
|
||||||
|
case TYPE_ENUM:
|
||||||
|
return input.readEnum();
|
||||||
|
case TYPE_SFIXED32:
|
||||||
|
return input.readSFixed32();
|
||||||
|
case TYPE_SFIXED64:
|
||||||
|
return input.readSFixed64();
|
||||||
|
case TYPE_SINT32:
|
||||||
|
return input.readSInt32();
|
||||||
|
case TYPE_SINT64:
|
||||||
|
return input.readSInt64();
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unknown type " + type);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new IllegalArgumentException("Error reading extension field", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void readDataInto(UnknownFieldData data, List<Object> resultList) {
|
||||||
|
// This implementation is for primitive typed extensions,
|
||||||
|
// which can read both packed and non-packed data.
|
||||||
|
if (data.tag == nonPackedTag) {
|
||||||
|
resultList.add(readData(CodedInputByteBufferNano.newInstance(data.bytes)));
|
||||||
|
} else {
|
||||||
|
CodedInputByteBufferNano buffer =
|
||||||
|
CodedInputByteBufferNano.newInstance(data.bytes);
|
||||||
|
try {
|
||||||
|
buffer.pushLimit(buffer.readRawVarint32()); // length limit
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new IllegalArgumentException("Error reading extension field", e);
|
||||||
|
}
|
||||||
|
while (!buffer.isAtEnd()) {
|
||||||
|
resultList.add(readData(buffer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected final void writeSingularData(Object value, CodedOutputByteBufferNano output) {
|
||||||
|
try {
|
||||||
|
output.writeRawVarint32(tag);
|
||||||
|
switch (type) {
|
||||||
|
case TYPE_DOUBLE:
|
||||||
|
Double doubleValue = (Double) value;
|
||||||
|
output.writeDoubleNoTag(doubleValue);
|
||||||
|
break;
|
||||||
|
case TYPE_FLOAT:
|
||||||
|
Float floatValue = (Float) value;
|
||||||
|
output.writeFloatNoTag(floatValue);
|
||||||
|
break;
|
||||||
|
case TYPE_INT64:
|
||||||
|
Long int64Value = (Long) value;
|
||||||
|
output.writeInt64NoTag(int64Value);
|
||||||
|
break;
|
||||||
|
case TYPE_UINT64:
|
||||||
|
Long uint64Value = (Long) value;
|
||||||
|
output.writeUInt64NoTag(uint64Value);
|
||||||
|
break;
|
||||||
|
case TYPE_INT32:
|
||||||
|
Integer int32Value = (Integer) value;
|
||||||
|
output.writeInt32NoTag(int32Value);
|
||||||
|
break;
|
||||||
|
case TYPE_FIXED64:
|
||||||
|
Long fixed64Value = (Long) value;
|
||||||
|
output.writeFixed64NoTag(fixed64Value);
|
||||||
|
break;
|
||||||
|
case TYPE_FIXED32:
|
||||||
|
Integer fixed32Value = (Integer) value;
|
||||||
|
output.writeFixed32NoTag(fixed32Value);
|
||||||
|
break;
|
||||||
|
case TYPE_BOOL:
|
||||||
|
Boolean boolValue = (Boolean) value;
|
||||||
|
output.writeBoolNoTag(boolValue);
|
||||||
|
break;
|
||||||
|
case TYPE_STRING:
|
||||||
|
String stringValue = (String) value;
|
||||||
|
output.writeStringNoTag(stringValue);
|
||||||
|
break;
|
||||||
|
case TYPE_BYTES:
|
||||||
|
byte[] bytesValue = (byte[]) value;
|
||||||
|
output.writeBytesNoTag(bytesValue);
|
||||||
|
break;
|
||||||
|
case TYPE_UINT32:
|
||||||
|
Integer uint32Value = (Integer) value;
|
||||||
|
output.writeUInt32NoTag(uint32Value);
|
||||||
|
break;
|
||||||
|
case TYPE_ENUM:
|
||||||
|
Integer enumValue = (Integer) value;
|
||||||
|
output.writeEnumNoTag(enumValue);
|
||||||
|
break;
|
||||||
|
case TYPE_SFIXED32:
|
||||||
|
Integer sfixed32Value = (Integer) value;
|
||||||
|
output.writeSFixed32NoTag(sfixed32Value);
|
||||||
|
break;
|
||||||
|
case TYPE_SFIXED64:
|
||||||
|
Long sfixed64Value = (Long) value;
|
||||||
|
output.writeSFixed64NoTag(sfixed64Value);
|
||||||
|
break;
|
||||||
|
case TYPE_SINT32:
|
||||||
|
Integer sint32Value = (Integer) value;
|
||||||
|
output.writeSInt32NoTag(sint32Value);
|
||||||
|
break;
|
||||||
|
case TYPE_SINT64:
|
||||||
|
Long sint64Value = (Long) value;
|
||||||
|
output.writeSInt64NoTag(sint64Value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unknown type " + type);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
// Should not happen
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void writeRepeatedData(Object array, CodedOutputByteBufferNano output) {
|
||||||
|
if (tag == nonPackedTag) {
|
||||||
|
// Use base implementation for non-packed data
|
||||||
|
super.writeRepeatedData(array, output);
|
||||||
|
} else if (tag == packedTag) {
|
||||||
|
// Packed. Note that the array element type is guaranteed to be primitive, so there
|
||||||
|
// won't be any null elements, so no null check in this block.
|
||||||
|
int arrayLength = Array.getLength(array);
|
||||||
|
int dataSize = computePackedDataSize(array);
|
||||||
|
|
||||||
|
try {
|
||||||
|
output.writeRawVarint32(tag);
|
||||||
|
output.writeRawVarint32(dataSize);
|
||||||
|
switch (type) {
|
||||||
|
case TYPE_BOOL:
|
||||||
|
for (int i = 0; i < arrayLength; i++) {
|
||||||
|
output.writeBoolNoTag(Array.getBoolean(array, i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPE_FIXED32:
|
||||||
|
for (int i = 0; i < arrayLength; i++) {
|
||||||
|
output.writeFixed32NoTag(Array.getInt(array, i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPE_SFIXED32:
|
||||||
|
for (int i = 0; i < arrayLength; i++) {
|
||||||
|
output.writeSFixed32NoTag(Array.getInt(array, i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPE_FLOAT:
|
||||||
|
for (int i = 0; i < arrayLength; i++) {
|
||||||
|
output.writeFloatNoTag(Array.getFloat(array, i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPE_FIXED64:
|
||||||
|
for (int i = 0; i < arrayLength; i++) {
|
||||||
|
output.writeFixed64NoTag(Array.getLong(array, i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPE_SFIXED64:
|
||||||
|
for (int i = 0; i < arrayLength; i++) {
|
||||||
|
output.writeSFixed64NoTag(Array.getLong(array, i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPE_DOUBLE:
|
||||||
|
for (int i = 0; i < arrayLength; i++) {
|
||||||
|
output.writeDoubleNoTag(Array.getDouble(array, i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPE_INT32:
|
||||||
|
for (int i = 0; i < arrayLength; i++) {
|
||||||
|
output.writeInt32NoTag(Array.getInt(array, i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPE_SINT32:
|
||||||
|
for (int i = 0; i < arrayLength; i++) {
|
||||||
|
output.writeSInt32NoTag(Array.getInt(array, i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPE_UINT32:
|
||||||
|
for (int i = 0; i < arrayLength; i++) {
|
||||||
|
output.writeUInt32NoTag(Array.getInt(array, i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPE_INT64:
|
||||||
|
for (int i = 0; i < arrayLength; i++) {
|
||||||
|
output.writeInt64NoTag(Array.getLong(array, i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPE_SINT64:
|
||||||
|
for (int i = 0; i < arrayLength; i++) {
|
||||||
|
output.writeSInt64NoTag(Array.getLong(array, i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPE_UINT64:
|
||||||
|
for (int i = 0; i < arrayLength; i++) {
|
||||||
|
output.writeUInt64NoTag(Array.getLong(array, i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPE_ENUM:
|
||||||
|
for (int i = 0; i < arrayLength; i++) {
|
||||||
|
output.writeEnumNoTag(Array.getInt(array, i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unpackable type " + type);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
// Should not happen.
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Unexpected repeated extension tag " + tag
|
||||||
|
+ ", unequal to both non-packed variant " + nonPackedTag
|
||||||
|
+ " and packed variant " + packedTag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int computePackedDataSize(Object array) {
|
||||||
|
int dataSize = 0;
|
||||||
|
int arrayLength = Array.getLength(array);
|
||||||
|
switch (type) {
|
||||||
|
case TYPE_BOOL:
|
||||||
|
// Bools are stored as int32 but just as 0 or 1, so 1 byte each.
|
||||||
|
dataSize = arrayLength;
|
||||||
|
break;
|
||||||
|
case TYPE_FIXED32:
|
||||||
|
case TYPE_SFIXED32:
|
||||||
|
case TYPE_FLOAT:
|
||||||
|
dataSize = arrayLength * CodedOutputByteBufferNano.LITTLE_ENDIAN_32_SIZE;
|
||||||
|
break;
|
||||||
|
case TYPE_FIXED64:
|
||||||
|
case TYPE_SFIXED64:
|
||||||
|
case TYPE_DOUBLE:
|
||||||
|
dataSize = arrayLength * CodedOutputByteBufferNano.LITTLE_ENDIAN_64_SIZE;
|
||||||
|
break;
|
||||||
|
case TYPE_INT32:
|
||||||
|
for (int i = 0; i < arrayLength; i++) {
|
||||||
|
dataSize += CodedOutputByteBufferNano.computeInt32SizeNoTag(
|
||||||
|
Array.getInt(array, i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPE_SINT32:
|
||||||
|
for (int i = 0; i < arrayLength; i++) {
|
||||||
|
dataSize += CodedOutputByteBufferNano.computeSInt32SizeNoTag(
|
||||||
|
Array.getInt(array, i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPE_UINT32:
|
||||||
|
for (int i = 0; i < arrayLength; i++) {
|
||||||
|
dataSize += CodedOutputByteBufferNano.computeUInt32SizeNoTag(
|
||||||
|
Array.getInt(array, i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPE_INT64:
|
||||||
|
for (int i = 0; i < arrayLength; i++) {
|
||||||
|
dataSize += CodedOutputByteBufferNano.computeInt64SizeNoTag(
|
||||||
|
Array.getLong(array, i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPE_SINT64:
|
||||||
|
for (int i = 0; i < arrayLength; i++) {
|
||||||
|
dataSize += CodedOutputByteBufferNano.computeSInt64SizeNoTag(
|
||||||
|
Array.getLong(array, i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPE_UINT64:
|
||||||
|
for (int i = 0; i < arrayLength; i++) {
|
||||||
|
dataSize += CodedOutputByteBufferNano.computeUInt64SizeNoTag(
|
||||||
|
Array.getLong(array, i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPE_ENUM:
|
||||||
|
for (int i = 0; i < arrayLength; i++) {
|
||||||
|
dataSize += CodedOutputByteBufferNano.computeEnumSizeNoTag(
|
||||||
|
Array.getInt(array, i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unexpected non-packable type " + type);
|
||||||
|
}
|
||||||
|
return dataSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int computeRepeatedSerializedSize(Object array) {
|
||||||
|
if (tag == nonPackedTag) {
|
||||||
|
// Use base implementation for non-packed data
|
||||||
|
return super.computeRepeatedSerializedSize(array);
|
||||||
|
} else if (tag == packedTag) {
|
||||||
|
// Packed.
|
||||||
|
int dataSize = computePackedDataSize(array);
|
||||||
|
int payloadSize =
|
||||||
|
dataSize + CodedOutputByteBufferNano.computeRawVarint32Size(dataSize);
|
||||||
|
return payloadSize + CodedOutputByteBufferNano.computeRawVarint32Size(tag);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Unexpected repeated extension tag " + tag
|
||||||
|
+ ", unequal to both non-packed variant " + nonPackedTag
|
||||||
|
+ " and packed variant " + packedTag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected final int computeSingularSerializedSize(Object value) {
|
||||||
|
int fieldNumber = WireFormatNano.getTagFieldNumber(tag);
|
||||||
|
switch (type) {
|
||||||
|
case TYPE_DOUBLE:
|
||||||
|
Double doubleValue = (Double) value;
|
||||||
|
return CodedOutputByteBufferNano.computeDoubleSize(fieldNumber, doubleValue);
|
||||||
|
case TYPE_FLOAT:
|
||||||
|
Float floatValue = (Float) value;
|
||||||
|
return CodedOutputByteBufferNano.computeFloatSize(fieldNumber, floatValue);
|
||||||
|
case TYPE_INT64:
|
||||||
|
Long int64Value = (Long) value;
|
||||||
|
return CodedOutputByteBufferNano.computeInt64Size(fieldNumber, int64Value);
|
||||||
|
case TYPE_UINT64:
|
||||||
|
Long uint64Value = (Long) value;
|
||||||
|
return CodedOutputByteBufferNano.computeUInt64Size(fieldNumber, uint64Value);
|
||||||
|
case TYPE_INT32:
|
||||||
|
Integer int32Value = (Integer) value;
|
||||||
|
return CodedOutputByteBufferNano.computeInt32Size(fieldNumber, int32Value);
|
||||||
|
case TYPE_FIXED64:
|
||||||
|
Long fixed64Value = (Long) value;
|
||||||
|
return CodedOutputByteBufferNano.computeFixed64Size(fieldNumber, fixed64Value);
|
||||||
|
case TYPE_FIXED32:
|
||||||
|
Integer fixed32Value = (Integer) value;
|
||||||
|
return CodedOutputByteBufferNano.computeFixed32Size(fieldNumber, fixed32Value);
|
||||||
|
case TYPE_BOOL:
|
||||||
|
Boolean boolValue = (Boolean) value;
|
||||||
|
return CodedOutputByteBufferNano.computeBoolSize(fieldNumber, boolValue);
|
||||||
|
case TYPE_STRING:
|
||||||
|
String stringValue = (String) value;
|
||||||
|
return CodedOutputByteBufferNano.computeStringSize(fieldNumber, stringValue);
|
||||||
|
case TYPE_BYTES:
|
||||||
|
byte[] bytesValue = (byte[]) value;
|
||||||
|
return CodedOutputByteBufferNano.computeBytesSize(fieldNumber, bytesValue);
|
||||||
|
case TYPE_UINT32:
|
||||||
|
Integer uint32Value = (Integer) value;
|
||||||
|
return CodedOutputByteBufferNano.computeUInt32Size(fieldNumber, uint32Value);
|
||||||
|
case TYPE_ENUM:
|
||||||
|
Integer enumValue = (Integer) value;
|
||||||
|
return CodedOutputByteBufferNano.computeEnumSize(fieldNumber, enumValue);
|
||||||
|
case TYPE_SFIXED32:
|
||||||
|
Integer sfixed32Value = (Integer) value;
|
||||||
|
return CodedOutputByteBufferNano.computeSFixed32Size(fieldNumber,
|
||||||
|
sfixed32Value);
|
||||||
|
case TYPE_SFIXED64:
|
||||||
|
Long sfixed64Value = (Long) value;
|
||||||
|
return CodedOutputByteBufferNano.computeSFixed64Size(fieldNumber,
|
||||||
|
sfixed64Value);
|
||||||
|
case TYPE_SINT32:
|
||||||
|
Integer sint32Value = (Integer) value;
|
||||||
|
return CodedOutputByteBufferNano.computeSInt32Size(fieldNumber, sint32Value);
|
||||||
|
case TYPE_SINT64:
|
||||||
|
Long sint64Value = (Long) value;
|
||||||
|
return CodedOutputByteBufferNano.computeSInt64Size(fieldNumber, sint64Value);
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unknown type " + type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
273
javanano/src/main/java/com/google/protobuf/nano/FieldArray.java
Normal file
273
javanano/src/main/java/com/google/protobuf/nano/FieldArray.java
Normal file
@ -0,0 +1,273 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2014 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package com.google.protobuf.nano;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A custom version of {@link android.util.SparseArray} with the minimal API
|
||||||
|
* for storing {@link FieldData} objects.
|
||||||
|
*
|
||||||
|
* Based on {@link android.support.v4.util.SpareArrayCompat}.
|
||||||
|
*/
|
||||||
|
class FieldArray {
|
||||||
|
private static final FieldData DELETED = new FieldData();
|
||||||
|
private boolean mGarbage = false;
|
||||||
|
|
||||||
|
private int[] mFieldNumbers;
|
||||||
|
private FieldData[] mData;
|
||||||
|
private int mSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new FieldArray containing no fields.
|
||||||
|
*/
|
||||||
|
public FieldArray() {
|
||||||
|
this(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new FieldArray containing no mappings that will not
|
||||||
|
* require any additional memory allocation to store the specified
|
||||||
|
* number of mappings.
|
||||||
|
*/
|
||||||
|
public FieldArray(int initialCapacity) {
|
||||||
|
initialCapacity = idealIntArraySize(initialCapacity);
|
||||||
|
mFieldNumbers = new int[initialCapacity];
|
||||||
|
mData = new FieldData[initialCapacity];
|
||||||
|
mSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the FieldData mapped from the specified fieldNumber, or <code>null</code>
|
||||||
|
* if no such mapping has been made.
|
||||||
|
*/
|
||||||
|
public FieldData get(int fieldNumber) {
|
||||||
|
int i = binarySearch(fieldNumber);
|
||||||
|
|
||||||
|
if (i < 0 || mData[i] == DELETED) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return mData[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the data from the specified fieldNumber, if there was any.
|
||||||
|
*/
|
||||||
|
public void remove(int fieldNumber) {
|
||||||
|
int i = binarySearch(fieldNumber);
|
||||||
|
|
||||||
|
if (i >= 0 && mData[i] != DELETED) {
|
||||||
|
mData[i] = DELETED;
|
||||||
|
mGarbage = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void gc() {
|
||||||
|
int n = mSize;
|
||||||
|
int o = 0;
|
||||||
|
int[] keys = mFieldNumbers;
|
||||||
|
FieldData[] values = mData;
|
||||||
|
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
FieldData val = values[i];
|
||||||
|
|
||||||
|
if (val != DELETED) {
|
||||||
|
if (i != o) {
|
||||||
|
keys[o] = keys[i];
|
||||||
|
values[o] = val;
|
||||||
|
values[i] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
o++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mGarbage = false;
|
||||||
|
mSize = o;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a mapping from the specified fieldNumber to the specified data,
|
||||||
|
* replacing the previous mapping if there was one.
|
||||||
|
*/
|
||||||
|
public void put(int fieldNumber, FieldData data) {
|
||||||
|
int i = binarySearch(fieldNumber);
|
||||||
|
|
||||||
|
if (i >= 0) {
|
||||||
|
mData[i] = data;
|
||||||
|
} else {
|
||||||
|
i = ~i;
|
||||||
|
|
||||||
|
if (i < mSize && mData[i] == DELETED) {
|
||||||
|
mFieldNumbers[i] = fieldNumber;
|
||||||
|
mData[i] = data;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mGarbage && mSize >= mFieldNumbers.length) {
|
||||||
|
gc();
|
||||||
|
|
||||||
|
// Search again because indices may have changed.
|
||||||
|
i = ~ binarySearch(fieldNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mSize >= mFieldNumbers.length) {
|
||||||
|
int n = idealIntArraySize(mSize + 1);
|
||||||
|
|
||||||
|
int[] nkeys = new int[n];
|
||||||
|
FieldData[] nvalues = new FieldData[n];
|
||||||
|
|
||||||
|
System.arraycopy(mFieldNumbers, 0, nkeys, 0, mFieldNumbers.length);
|
||||||
|
System.arraycopy(mData, 0, nvalues, 0, mData.length);
|
||||||
|
|
||||||
|
mFieldNumbers = nkeys;
|
||||||
|
mData = nvalues;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mSize - i != 0) {
|
||||||
|
System.arraycopy(mFieldNumbers, i, mFieldNumbers, i + 1, mSize - i);
|
||||||
|
System.arraycopy(mData, i, mData, i + 1, mSize - i);
|
||||||
|
}
|
||||||
|
|
||||||
|
mFieldNumbers[i] = fieldNumber;
|
||||||
|
mData[i] = data;
|
||||||
|
mSize++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of key-value mappings that this FieldArray
|
||||||
|
* currently stores.
|
||||||
|
*/
|
||||||
|
public int size() {
|
||||||
|
if (mGarbage) {
|
||||||
|
gc();
|
||||||
|
}
|
||||||
|
|
||||||
|
return mSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given an index in the range <code>0...size()-1</code>, returns
|
||||||
|
* the value from the <code>index</code>th key-value mapping that this
|
||||||
|
* FieldArray stores.
|
||||||
|
*/
|
||||||
|
public FieldData dataAt(int index) {
|
||||||
|
if (mGarbage) {
|
||||||
|
gc();
|
||||||
|
}
|
||||||
|
|
||||||
|
return mData[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (o == this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(o instanceof FieldArray)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FieldArray other = (FieldArray) o;
|
||||||
|
if (size() != other.size()) { // size() will call gc() if necessary.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return arrayEquals(mFieldNumbers, other.mFieldNumbers, mSize) &&
|
||||||
|
arrayEquals(mData, other.mData, mSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
if (mGarbage) {
|
||||||
|
gc();
|
||||||
|
}
|
||||||
|
int result = 17;
|
||||||
|
for (int i = 0; i < mSize; i++) {
|
||||||
|
result = 31 * result + mFieldNumbers[i];
|
||||||
|
result = 31 * result + mData[i].hashCode();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int idealIntArraySize(int need) {
|
||||||
|
return idealByteArraySize(need * 4) / 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int idealByteArraySize(int need) {
|
||||||
|
for (int i = 4; i < 32; i++)
|
||||||
|
if (need <= (1 << i) - 12)
|
||||||
|
return (1 << i) - 12;
|
||||||
|
|
||||||
|
return need;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int binarySearch(int value) {
|
||||||
|
int lo = 0;
|
||||||
|
int hi = mSize - 1;
|
||||||
|
|
||||||
|
while (lo <= hi) {
|
||||||
|
int mid = (lo + hi) >>> 1;
|
||||||
|
int midVal = mFieldNumbers[mid];
|
||||||
|
|
||||||
|
if (midVal < value) {
|
||||||
|
lo = mid + 1;
|
||||||
|
} else if (midVal > value) {
|
||||||
|
hi = mid - 1;
|
||||||
|
} else {
|
||||||
|
return mid; // value found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ~lo; // value not present
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean arrayEquals(int[] a, int[] b, int size) {
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
if (a[i] != b[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean arrayEquals(FieldData[] a, FieldData[] b, int size) {
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
if (!a[i].equals(b[i])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
190
javanano/src/main/java/com/google/protobuf/nano/FieldData.java
Normal file
190
javanano/src/main/java/com/google/protobuf/nano/FieldData.java
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2014 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package com.google.protobuf.nano;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores unknown fields. These might be extensions or fields that the generated API doesn't
|
||||||
|
* know about yet.
|
||||||
|
*/
|
||||||
|
class FieldData {
|
||||||
|
private Extension<?, ?> cachedExtension;
|
||||||
|
private Object value;
|
||||||
|
/** The serialised values for this object. Will be cleared if getValue is called */
|
||||||
|
private List<UnknownFieldData> unknownFieldData;
|
||||||
|
|
||||||
|
<T> FieldData(Extension<?, T> extension, T newValue) {
|
||||||
|
cachedExtension = extension;
|
||||||
|
value = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
FieldData() {
|
||||||
|
unknownFieldData = new ArrayList<UnknownFieldData>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void addUnknownField(UnknownFieldData unknownField) {
|
||||||
|
unknownFieldData.add(unknownField);
|
||||||
|
}
|
||||||
|
|
||||||
|
UnknownFieldData getUnknownField(int index) {
|
||||||
|
if (unknownFieldData == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (index < unknownFieldData.size()) {
|
||||||
|
return unknownFieldData.get(index);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getUnknownFieldSize() {
|
||||||
|
if (unknownFieldData == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return unknownFieldData.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
<T> T getValue(Extension<?, T> extension) {
|
||||||
|
if (value != null){
|
||||||
|
if (cachedExtension != extension) { // Extension objects are singletons.
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Tried to getExtension with a differernt Extension.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cachedExtension = extension;
|
||||||
|
value = extension.getValueFrom(unknownFieldData);
|
||||||
|
unknownFieldData = null;
|
||||||
|
}
|
||||||
|
return (T) value;
|
||||||
|
}
|
||||||
|
|
||||||
|
<T> void setValue(Extension<?, T> extension, T newValue) {
|
||||||
|
cachedExtension = extension;
|
||||||
|
value = newValue;
|
||||||
|
unknownFieldData = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int computeSerializedSize() {
|
||||||
|
int size = 0;
|
||||||
|
if (value != null) {
|
||||||
|
size = cachedExtension.computeSerializedSize(value);
|
||||||
|
} else {
|
||||||
|
for (UnknownFieldData unknownField : unknownFieldData) {
|
||||||
|
size += unknownField.computeSerializedSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeTo(CodedOutputByteBufferNano output) throws IOException {
|
||||||
|
if (value != null) {
|
||||||
|
cachedExtension.writeTo(value, output);
|
||||||
|
} else {
|
||||||
|
for (UnknownFieldData unknownField : unknownFieldData) {
|
||||||
|
unknownField.writeTo(output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (o == this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(o instanceof FieldData)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FieldData other = (FieldData) o;
|
||||||
|
if (value != null && other.value != null) {
|
||||||
|
// If both objects have deserialized values, compare those.
|
||||||
|
// Since unknown fields are only compared if messages have generated equals methods
|
||||||
|
// we know this will be a meaningful comparison (not identity) for all values.
|
||||||
|
if (cachedExtension != other.cachedExtension) { // Extension objects are singletons.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!cachedExtension.clazz.isArray()) {
|
||||||
|
// Can't test (!cachedExtension.repeated) due to 'bytes' -> 'byte[]'
|
||||||
|
return value.equals(other.value);
|
||||||
|
}
|
||||||
|
if (value instanceof byte[]) {
|
||||||
|
return Arrays.equals((byte[]) value, (byte[]) other.value);
|
||||||
|
} else if (value instanceof int[]) {
|
||||||
|
return Arrays.equals((int[]) value, (int[]) other.value);
|
||||||
|
} else if (value instanceof long[]) {
|
||||||
|
return Arrays.equals((long[]) value, (long[]) other.value);
|
||||||
|
} else if (value instanceof float[]) {
|
||||||
|
return Arrays.equals((float[]) value, (float[]) other.value);
|
||||||
|
} else if (value instanceof double[]) {
|
||||||
|
return Arrays.equals((double[]) value, (double[]) other.value);
|
||||||
|
} else if (value instanceof boolean[]) {
|
||||||
|
return Arrays.equals((boolean[]) value, (boolean[]) other.value);
|
||||||
|
} else {
|
||||||
|
return Arrays.deepEquals((Object[]) value, (Object[]) other.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (unknownFieldData != null && other.unknownFieldData != null) {
|
||||||
|
// If both objects have byte arrays compare those directly.
|
||||||
|
return unknownFieldData.equals(other.unknownFieldData);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// As a last resort, serialize and compare the resulting byte arrays.
|
||||||
|
return Arrays.equals(toByteArray(), other.toByteArray());
|
||||||
|
} catch (IOException e) {
|
||||||
|
// Should not happen.
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = 17;
|
||||||
|
try {
|
||||||
|
// The only way to generate a consistent hash is to use the serialized form.
|
||||||
|
result = 31 * result + Arrays.hashCode(toByteArray());
|
||||||
|
} catch (IOException e) {
|
||||||
|
// Should not happen.
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] toByteArray() throws IOException {
|
||||||
|
byte[] result = new byte[computeSerializedSize()];
|
||||||
|
CodedOutputByteBufferNano output = CodedOutputByteBufferNano.newInstance(result);
|
||||||
|
writeTo(output);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,333 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package com.google.protobuf.nano;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The classes contained within are used internally by the Protocol Buffer
|
||||||
|
* library and generated message implementations. They are public only because
|
||||||
|
* those generated messages do not reside in the {@code protobuf} package.
|
||||||
|
* Others should not use this class directly.
|
||||||
|
*
|
||||||
|
* @author kenton@google.com (Kenton Varda)
|
||||||
|
*/
|
||||||
|
public final class InternalNano {
|
||||||
|
|
||||||
|
private InternalNano() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An object to provide synchronization when lazily initializing static fields
|
||||||
|
* of {@link MessageNano} subclasses.
|
||||||
|
* <p>
|
||||||
|
* To enable earlier versions of ProGuard to inline short methods from a
|
||||||
|
* generated MessageNano subclass to the call sites, that class must not have
|
||||||
|
* a class initializer, which will be created if there is any static variable
|
||||||
|
* initializers. To lazily initialize the static variables in a thread-safe
|
||||||
|
* manner, the initialization code will synchronize on this object.
|
||||||
|
*/
|
||||||
|
public static final Object LAZY_INIT_LOCK = new Object();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper called by generated code to construct default values for string
|
||||||
|
* fields.
|
||||||
|
* <p>
|
||||||
|
* The protocol compiler does not actually contain a UTF-8 decoder -- it
|
||||||
|
* just pushes UTF-8-encoded text around without touching it. The one place
|
||||||
|
* where this presents a problem is when generating Java string literals.
|
||||||
|
* Unicode characters in the string literal would normally need to be encoded
|
||||||
|
* using a Unicode escape sequence, which would require decoding them.
|
||||||
|
* To get around this, protoc instead embeds the UTF-8 bytes into the
|
||||||
|
* generated code and leaves it to the runtime library to decode them.
|
||||||
|
* <p>
|
||||||
|
* It gets worse, though. If protoc just generated a byte array, like:
|
||||||
|
* new byte[] {0x12, 0x34, 0x56, 0x78}
|
||||||
|
* Java actually generates *code* which allocates an array and then fills
|
||||||
|
* in each value. This is much less efficient than just embedding the bytes
|
||||||
|
* directly into the bytecode. To get around this, we need another
|
||||||
|
* work-around. String literals are embedded directly, so protoc actually
|
||||||
|
* generates a string literal corresponding to the bytes. The easiest way
|
||||||
|
* to do this is to use the ISO-8859-1 character set, which corresponds to
|
||||||
|
* the first 256 characters of the Unicode range. Protoc can then use
|
||||||
|
* good old CEscape to generate the string.
|
||||||
|
* <p>
|
||||||
|
* So we have a string literal which represents a set of bytes which
|
||||||
|
* represents another string. This function -- stringDefaultValue --
|
||||||
|
* converts from the generated string to the string we actually want. The
|
||||||
|
* generated code calls this automatically.
|
||||||
|
*/
|
||||||
|
public static String stringDefaultValue(String bytes) {
|
||||||
|
try {
|
||||||
|
return new String(bytes.getBytes("ISO-8859-1"), "UTF-8");
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
// This should never happen since all JVMs are required to implement
|
||||||
|
// both of the above character sets.
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Java VM does not support a standard character set.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper called by generated code to construct default values for bytes
|
||||||
|
* fields.
|
||||||
|
* <p>
|
||||||
|
* This is a lot like {@link #stringDefaultValue}, but for bytes fields.
|
||||||
|
* In this case we only need the second of the two hacks -- allowing us to
|
||||||
|
* embed raw bytes as a string literal with ISO-8859-1 encoding.
|
||||||
|
*/
|
||||||
|
public static byte[] bytesDefaultValue(String bytes) {
|
||||||
|
try {
|
||||||
|
return bytes.getBytes("ISO-8859-1");
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
// This should never happen since all JVMs are required to implement
|
||||||
|
// ISO-8859-1.
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Java VM does not support a standard character set.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to convert a string into UTF-8 while turning the
|
||||||
|
* UnsupportedEncodingException to a RuntimeException.
|
||||||
|
*/
|
||||||
|
public static byte[] copyFromUtf8(final String text) {
|
||||||
|
try {
|
||||||
|
return text.getBytes("UTF-8");
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
throw new RuntimeException("UTF-8 not supported?");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks repeated int field equality; null-value and 0-length fields are
|
||||||
|
* considered equal.
|
||||||
|
*/
|
||||||
|
public static boolean equals(int[] field1, int[] field2) {
|
||||||
|
if (field1 == null || field1.length == 0) {
|
||||||
|
return field2 == null || field2.length == 0;
|
||||||
|
} else {
|
||||||
|
return Arrays.equals(field1, field2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks repeated long field equality; null-value and 0-length fields are
|
||||||
|
* considered equal.
|
||||||
|
*/
|
||||||
|
public static boolean equals(long[] field1, long[] field2) {
|
||||||
|
if (field1 == null || field1.length == 0) {
|
||||||
|
return field2 == null || field2.length == 0;
|
||||||
|
} else {
|
||||||
|
return Arrays.equals(field1, field2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks repeated float field equality; null-value and 0-length fields are
|
||||||
|
* considered equal.
|
||||||
|
*/
|
||||||
|
public static boolean equals(float[] field1, float[] field2) {
|
||||||
|
if (field1 == null || field1.length == 0) {
|
||||||
|
return field2 == null || field2.length == 0;
|
||||||
|
} else {
|
||||||
|
return Arrays.equals(field1, field2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks repeated double field equality; null-value and 0-length fields are
|
||||||
|
* considered equal.
|
||||||
|
*/
|
||||||
|
public static boolean equals(double[] field1, double[] field2) {
|
||||||
|
if (field1 == null || field1.length == 0) {
|
||||||
|
return field2 == null || field2.length == 0;
|
||||||
|
} else {
|
||||||
|
return Arrays.equals(field1, field2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks repeated boolean field equality; null-value and 0-length fields are
|
||||||
|
* considered equal.
|
||||||
|
*/
|
||||||
|
public static boolean equals(boolean[] field1, boolean[] field2) {
|
||||||
|
if (field1 == null || field1.length == 0) {
|
||||||
|
return field2 == null || field2.length == 0;
|
||||||
|
} else {
|
||||||
|
return Arrays.equals(field1, field2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks repeated bytes field equality. Only non-null elements are tested.
|
||||||
|
* Returns true if the two fields have the same sequence of non-null
|
||||||
|
* elements. Null-value fields and fields of any length with only null
|
||||||
|
* elements are considered equal.
|
||||||
|
*/
|
||||||
|
public static boolean equals(byte[][] field1, byte[][] field2) {
|
||||||
|
int index1 = 0;
|
||||||
|
int length1 = field1 == null ? 0 : field1.length;
|
||||||
|
int index2 = 0;
|
||||||
|
int length2 = field2 == null ? 0 : field2.length;
|
||||||
|
while (true) {
|
||||||
|
while (index1 < length1 && field1[index1] == null) {
|
||||||
|
index1++;
|
||||||
|
}
|
||||||
|
while (index2 < length2 && field2[index2] == null) {
|
||||||
|
index2++;
|
||||||
|
}
|
||||||
|
boolean atEndOf1 = index1 >= length1;
|
||||||
|
boolean atEndOf2 = index2 >= length2;
|
||||||
|
if (atEndOf1 && atEndOf2) {
|
||||||
|
// no more non-null elements to test in both arrays
|
||||||
|
return true;
|
||||||
|
} else if (atEndOf1 != atEndOf2) {
|
||||||
|
// one of the arrays have extra non-null elements
|
||||||
|
return false;
|
||||||
|
} else if (!Arrays.equals(field1[index1], field2[index2])) {
|
||||||
|
// element mismatch
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
index1++;
|
||||||
|
index2++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks repeated string/message field equality. Only non-null elements are
|
||||||
|
* tested. Returns true if the two fields have the same sequence of non-null
|
||||||
|
* elements. Null-value fields and fields of any length with only null
|
||||||
|
* elements are considered equal.
|
||||||
|
*/
|
||||||
|
public static boolean equals(Object[] field1, Object[] field2) {
|
||||||
|
int index1 = 0;
|
||||||
|
int length1 = field1 == null ? 0 : field1.length;
|
||||||
|
int index2 = 0;
|
||||||
|
int length2 = field2 == null ? 0 : field2.length;
|
||||||
|
while (true) {
|
||||||
|
while (index1 < length1 && field1[index1] == null) {
|
||||||
|
index1++;
|
||||||
|
}
|
||||||
|
while (index2 < length2 && field2[index2] == null) {
|
||||||
|
index2++;
|
||||||
|
}
|
||||||
|
boolean atEndOf1 = index1 >= length1;
|
||||||
|
boolean atEndOf2 = index2 >= length2;
|
||||||
|
if (atEndOf1 && atEndOf2) {
|
||||||
|
// no more non-null elements to test in both arrays
|
||||||
|
return true;
|
||||||
|
} else if (atEndOf1 != atEndOf2) {
|
||||||
|
// one of the arrays have extra non-null elements
|
||||||
|
return false;
|
||||||
|
} else if (!field1[index1].equals(field2[index2])) {
|
||||||
|
// element mismatch
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
index1++;
|
||||||
|
index2++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the hash code of a repeated int field. Null-value and 0-length
|
||||||
|
* fields have the same hash code.
|
||||||
|
*/
|
||||||
|
public static int hashCode(int[] field) {
|
||||||
|
return field == null || field.length == 0 ? 0 : Arrays.hashCode(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the hash code of a repeated long field. Null-value and 0-length
|
||||||
|
* fields have the same hash code.
|
||||||
|
*/
|
||||||
|
public static int hashCode(long[] field) {
|
||||||
|
return field == null || field.length == 0 ? 0 : Arrays.hashCode(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the hash code of a repeated float field. Null-value and 0-length
|
||||||
|
* fields have the same hash code.
|
||||||
|
*/
|
||||||
|
public static int hashCode(float[] field) {
|
||||||
|
return field == null || field.length == 0 ? 0 : Arrays.hashCode(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the hash code of a repeated double field. Null-value and 0-length
|
||||||
|
* fields have the same hash code.
|
||||||
|
*/
|
||||||
|
public static int hashCode(double[] field) {
|
||||||
|
return field == null || field.length == 0 ? 0 : Arrays.hashCode(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the hash code of a repeated boolean field. Null-value and 0-length
|
||||||
|
* fields have the same hash code.
|
||||||
|
*/
|
||||||
|
public static int hashCode(boolean[] field) {
|
||||||
|
return field == null || field.length == 0 ? 0 : Arrays.hashCode(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the hash code of a repeated bytes field. Only the sequence of all
|
||||||
|
* non-null elements are used in the computation. Null-value fields and fields
|
||||||
|
* of any length with only null elements have the same hash code.
|
||||||
|
*/
|
||||||
|
public static int hashCode(byte[][] field) {
|
||||||
|
int result = 0;
|
||||||
|
for (int i = 0, size = field == null ? 0 : field.length; i < size; i++) {
|
||||||
|
byte[] element = field[i];
|
||||||
|
if (element != null) {
|
||||||
|
result = 31 * result + Arrays.hashCode(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the hash code of a repeated string/message field. Only the
|
||||||
|
* sequence of all non-null elements are used in the computation. Null-value
|
||||||
|
* fields and fields of any length with only null elements have the same hash
|
||||||
|
* code.
|
||||||
|
*/
|
||||||
|
public static int hashCode(Object[] field) {
|
||||||
|
int result = 0;
|
||||||
|
for (int i = 0, size = field == null ? 0 : field.length; i < size; i++) {
|
||||||
|
Object element = field[i];
|
||||||
|
if (element != null) {
|
||||||
|
result = 31 * result + element.hashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,93 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2013 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package com.google.protobuf.nano;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown when a protocol message being parsed is invalid in some way,
|
||||||
|
* e.g. it contains a malformed varint or a negative byte length.
|
||||||
|
*
|
||||||
|
* @author kenton@google.com Kenton Varda
|
||||||
|
*/
|
||||||
|
public class InvalidProtocolBufferNanoException extends IOException {
|
||||||
|
private static final long serialVersionUID = -1616151763072450476L;
|
||||||
|
|
||||||
|
public InvalidProtocolBufferNanoException(final String description) {
|
||||||
|
super(description);
|
||||||
|
}
|
||||||
|
|
||||||
|
static InvalidProtocolBufferNanoException truncatedMessage() {
|
||||||
|
return new InvalidProtocolBufferNanoException(
|
||||||
|
"While parsing a protocol message, the input ended unexpectedly " +
|
||||||
|
"in the middle of a field. This could mean either than the " +
|
||||||
|
"input has been truncated or that an embedded message " +
|
||||||
|
"misreported its own length.");
|
||||||
|
}
|
||||||
|
|
||||||
|
static InvalidProtocolBufferNanoException negativeSize() {
|
||||||
|
return new InvalidProtocolBufferNanoException(
|
||||||
|
"CodedInputStream encountered an embedded string or message " +
|
||||||
|
"which claimed to have negative size.");
|
||||||
|
}
|
||||||
|
|
||||||
|
static InvalidProtocolBufferNanoException malformedVarint() {
|
||||||
|
return new InvalidProtocolBufferNanoException(
|
||||||
|
"CodedInputStream encountered a malformed varint.");
|
||||||
|
}
|
||||||
|
|
||||||
|
static InvalidProtocolBufferNanoException invalidTag() {
|
||||||
|
return new InvalidProtocolBufferNanoException(
|
||||||
|
"Protocol message contained an invalid tag (zero).");
|
||||||
|
}
|
||||||
|
|
||||||
|
static InvalidProtocolBufferNanoException invalidEndTag() {
|
||||||
|
return new InvalidProtocolBufferNanoException(
|
||||||
|
"Protocol message end-group tag did not match expected tag.");
|
||||||
|
}
|
||||||
|
|
||||||
|
static InvalidProtocolBufferNanoException invalidWireType() {
|
||||||
|
return new InvalidProtocolBufferNanoException(
|
||||||
|
"Protocol message tag had invalid wire type.");
|
||||||
|
}
|
||||||
|
|
||||||
|
static InvalidProtocolBufferNanoException recursionLimitExceeded() {
|
||||||
|
return new InvalidProtocolBufferNanoException(
|
||||||
|
"Protocol message had too many levels of nesting. May be malicious. " +
|
||||||
|
"Use CodedInputStream.setRecursionLimit() to increase the depth limit.");
|
||||||
|
}
|
||||||
|
|
||||||
|
static InvalidProtocolBufferNanoException sizeLimitExceeded() {
|
||||||
|
return new InvalidProtocolBufferNanoException(
|
||||||
|
"Protocol message was too large. May be malicious. " +
|
||||||
|
"Use CodedInputStream.setSizeLimit() to increase the size limit.");
|
||||||
|
}
|
||||||
|
}
|
190
javanano/src/main/java/com/google/protobuf/nano/MessageNano.java
Normal file
190
javanano/src/main/java/com/google/protobuf/nano/MessageNano.java
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2013 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package com.google.protobuf.nano;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract interface implemented by Protocol Message objects.
|
||||||
|
*
|
||||||
|
* @author wink@google.com Wink Saville
|
||||||
|
*/
|
||||||
|
public abstract class MessageNano {
|
||||||
|
protected volatile int cachedSize = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of bytes required to encode this message.
|
||||||
|
* Returns the cached size or calls getSerializedSize which
|
||||||
|
* sets the cached size. This is used internally when serializing
|
||||||
|
* so the size is only computed once. If a member is modified
|
||||||
|
* then this could be stale call getSerializedSize if in doubt.
|
||||||
|
*/
|
||||||
|
public int getCachedSize() {
|
||||||
|
if (cachedSize < 0) {
|
||||||
|
// getSerializedSize sets cachedSize
|
||||||
|
getSerializedSize();
|
||||||
|
}
|
||||||
|
return cachedSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the number of bytes required to encode this message.
|
||||||
|
* The size is cached and the cached result can be retrieved
|
||||||
|
* using getCachedSize().
|
||||||
|
*/
|
||||||
|
public int getSerializedSize() {
|
||||||
|
int size = computeSerializedSize();
|
||||||
|
cachedSize = size;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the number of bytes required to encode this message. This does not update the
|
||||||
|
* cached size.
|
||||||
|
*/
|
||||||
|
protected int computeSerializedSize() {
|
||||||
|
// This is overridden if the generated message has serialized fields.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes the message and writes it to {@code output}.
|
||||||
|
*
|
||||||
|
* @param output the output to receive the serialized form.
|
||||||
|
* @throws IOException if an error occurred writing to {@code output}.
|
||||||
|
*/
|
||||||
|
public void writeTo(CodedOutputByteBufferNano output) throws IOException {
|
||||||
|
// Does nothing by default. Overridden by subclasses which have data to write.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse {@code input} as a message of this type and merge it with the
|
||||||
|
* message being built.
|
||||||
|
*/
|
||||||
|
public abstract MessageNano mergeFrom(CodedInputByteBufferNano input) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialize to a byte array.
|
||||||
|
* @return byte array with the serialized data.
|
||||||
|
*/
|
||||||
|
public static final byte[] toByteArray(MessageNano msg) {
|
||||||
|
final byte[] result = new byte[msg.getSerializedSize()];
|
||||||
|
toByteArray(msg, result, 0, result.length);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialize to a byte array starting at offset through length. The
|
||||||
|
* method getSerializedSize must have been called prior to calling
|
||||||
|
* this method so the proper length is know. If an attempt to
|
||||||
|
* write more than length bytes OutOfSpaceException will be thrown
|
||||||
|
* and if length bytes are not written then IllegalStateException
|
||||||
|
* is thrown.
|
||||||
|
*/
|
||||||
|
public static final void toByteArray(MessageNano msg, byte[] data, int offset, int length) {
|
||||||
|
try {
|
||||||
|
final CodedOutputByteBufferNano output =
|
||||||
|
CodedOutputByteBufferNano.newInstance(data, offset, length);
|
||||||
|
msg.writeTo(output);
|
||||||
|
output.checkNoSpaceLeft();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Serializing to a byte array threw an IOException "
|
||||||
|
+ "(should never happen).", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse {@code data} as a message of this type and merge it with the
|
||||||
|
* message being built.
|
||||||
|
*/
|
||||||
|
public static final <T extends MessageNano> T mergeFrom(T msg, final byte[] data)
|
||||||
|
throws InvalidProtocolBufferNanoException {
|
||||||
|
return mergeFrom(msg, data, 0, data.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse {@code data} as a message of this type and merge it with the
|
||||||
|
* message being built.
|
||||||
|
*/
|
||||||
|
public static final <T extends MessageNano> T mergeFrom(T msg, final byte[] data,
|
||||||
|
final int off, final int len) throws InvalidProtocolBufferNanoException {
|
||||||
|
try {
|
||||||
|
final CodedInputByteBufferNano input =
|
||||||
|
CodedInputByteBufferNano.newInstance(data, off, len);
|
||||||
|
msg.mergeFrom(input);
|
||||||
|
input.checkLastTagWas(0);
|
||||||
|
return msg;
|
||||||
|
} catch (InvalidProtocolBufferNanoException e) {
|
||||||
|
throw e;
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Reading from a byte array threw an IOException (should "
|
||||||
|
+ "never happen).");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares two {@code MessageNano}s and returns true if the message's are the same class and
|
||||||
|
* have serialized form equality (i.e. all of the field values are the same).
|
||||||
|
*/
|
||||||
|
public static final boolean messageNanoEquals(MessageNano a, MessageNano b) {
|
||||||
|
if (a == b) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (a == null || b == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (a.getClass() != b.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final int serializedSize = a.getSerializedSize();
|
||||||
|
if (b.getSerializedSize() != serializedSize) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final byte[] aByteArray = new byte[serializedSize];
|
||||||
|
final byte[] bByteArray = new byte[serializedSize];
|
||||||
|
toByteArray(a, aByteArray, 0, serializedSize);
|
||||||
|
toByteArray(b, bByteArray, 0, serializedSize);
|
||||||
|
return Arrays.equals(aByteArray, bByteArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string that is (mostly) compatible with ProtoBuffer's TextFormat. Note that groups
|
||||||
|
* (which are deprecated) are not serialized with the correct field name.
|
||||||
|
*
|
||||||
|
* <p>This is implemented using reflection, so it is not especially fast nor is it guaranteed
|
||||||
|
* to find all fields if you have method removal turned on for proguard.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MessageNanoPrinter.print(this);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,257 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2013 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package com.google.protobuf.nano;
|
||||||
|
|
||||||
|
import java.lang.reflect.Array;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static helper methods for printing nano protos.
|
||||||
|
*
|
||||||
|
* @author flynn@google.com Andrew Flynn
|
||||||
|
*/
|
||||||
|
public final class MessageNanoPrinter {
|
||||||
|
// Do not allow instantiation
|
||||||
|
private MessageNanoPrinter() {}
|
||||||
|
|
||||||
|
private static final String INDENT = " ";
|
||||||
|
private static final int MAX_STRING_LEN = 200;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an text representation of a MessageNano suitable for debugging. The returned string
|
||||||
|
* is mostly compatible with Protocol Buffer's TextFormat (as provided by non-nano protocol
|
||||||
|
* buffers) -- groups (which are deprecated) are output with an underscore name (e.g. foo_bar
|
||||||
|
* instead of FooBar) and will thus not parse.
|
||||||
|
*
|
||||||
|
* <p>Employs Java reflection on the given object and recursively prints primitive fields,
|
||||||
|
* groups, and messages.</p>
|
||||||
|
*/
|
||||||
|
public static <T extends MessageNano> String print(T message) {
|
||||||
|
if (message == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuffer buf = new StringBuffer();
|
||||||
|
try {
|
||||||
|
print(null, message, new StringBuffer(), buf);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
return "Error printing proto: " + e.getMessage();
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
return "Error printing proto: " + e.getMessage();
|
||||||
|
}
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function that will print the given message/field into the StringBuffer.
|
||||||
|
* Meant to be called recursively.
|
||||||
|
*
|
||||||
|
* @param identifier the identifier to use, or {@code null} if this is the root message to
|
||||||
|
* print.
|
||||||
|
* @param object the value to print. May in fact be a primitive value or byte array and not a
|
||||||
|
* message.
|
||||||
|
* @param indentBuf the indentation each line should begin with.
|
||||||
|
* @param buf the output buffer.
|
||||||
|
*/
|
||||||
|
private static void print(String identifier, Object object,
|
||||||
|
StringBuffer indentBuf, StringBuffer buf) throws IllegalAccessException,
|
||||||
|
InvocationTargetException {
|
||||||
|
if (object == null) {
|
||||||
|
// This can happen if...
|
||||||
|
// - we're about to print a message, String, or byte[], but it not present;
|
||||||
|
// - we're about to print a primitive, but "reftype" optional style is enabled, and
|
||||||
|
// the field is unset.
|
||||||
|
// In both cases the appropriate behavior is to output nothing.
|
||||||
|
} else if (object instanceof MessageNano) { // Nano proto message
|
||||||
|
int origIndentBufLength = indentBuf.length();
|
||||||
|
if (identifier != null) {
|
||||||
|
buf.append(indentBuf).append(deCamelCaseify(identifier)).append(" <\n");
|
||||||
|
indentBuf.append(INDENT);
|
||||||
|
}
|
||||||
|
Class<?> clazz = object.getClass();
|
||||||
|
|
||||||
|
// Proto fields follow one of two formats:
|
||||||
|
//
|
||||||
|
// 1) Public, non-static variables that do not begin or end with '_'
|
||||||
|
// Find and print these using declared public fields
|
||||||
|
for (Field field : clazz.getFields()) {
|
||||||
|
int modifiers = field.getModifiers();
|
||||||
|
String fieldName = field.getName();
|
||||||
|
|
||||||
|
if ((modifiers & Modifier.PUBLIC) == Modifier.PUBLIC
|
||||||
|
&& (modifiers & Modifier.STATIC) != Modifier.STATIC
|
||||||
|
&& !fieldName.startsWith("_")
|
||||||
|
&& !fieldName.endsWith("_")) {
|
||||||
|
Class<?> fieldType = field.getType();
|
||||||
|
Object value = field.get(object);
|
||||||
|
|
||||||
|
if (fieldType.isArray()) {
|
||||||
|
Class<?> arrayType = fieldType.getComponentType();
|
||||||
|
|
||||||
|
// bytes is special since it's not repeated, but is represented by an array
|
||||||
|
if (arrayType == byte.class) {
|
||||||
|
print(fieldName, value, indentBuf, buf);
|
||||||
|
} else {
|
||||||
|
int len = value == null ? 0 : Array.getLength(value);
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
Object elem = Array.get(value, i);
|
||||||
|
print(fieldName, elem, indentBuf, buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print(fieldName, value, indentBuf, buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2) Fields that are accessed via getter methods (when accessors
|
||||||
|
// mode is turned on)
|
||||||
|
// Find and print these using getter methods.
|
||||||
|
for (Method method : clazz.getMethods()) {
|
||||||
|
String name = method.getName();
|
||||||
|
// Check for the setter accessor method since getters and hazzers both have
|
||||||
|
// non-proto-field name collisions (hashCode() and getSerializedSize())
|
||||||
|
if (name.startsWith("set")) {
|
||||||
|
String subfieldName = name.substring(3);
|
||||||
|
|
||||||
|
Method hazzer = null;
|
||||||
|
try {
|
||||||
|
hazzer = clazz.getMethod("has" + subfieldName);
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// If hazzer does't exist or returns false, no need to continue
|
||||||
|
if (!(Boolean) hazzer.invoke(object)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Method getter = null;
|
||||||
|
try {
|
||||||
|
getter = clazz.getMethod("get" + subfieldName);
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
print(subfieldName, getter.invoke(object), indentBuf, buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (identifier != null) {
|
||||||
|
indentBuf.setLength(origIndentBufLength);
|
||||||
|
buf.append(indentBuf).append(">\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Non-null primitive value
|
||||||
|
identifier = deCamelCaseify(identifier);
|
||||||
|
buf.append(indentBuf).append(identifier).append(": ");
|
||||||
|
if (object instanceof String) {
|
||||||
|
String stringMessage = sanitizeString((String) object);
|
||||||
|
buf.append("\"").append(stringMessage).append("\"");
|
||||||
|
} else if (object instanceof byte[]) {
|
||||||
|
appendQuotedBytes((byte[]) object, buf);
|
||||||
|
} else {
|
||||||
|
buf.append(object);
|
||||||
|
}
|
||||||
|
buf.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts an identifier of the format "FieldName" into "field_name".
|
||||||
|
*/
|
||||||
|
private static String deCamelCaseify(String identifier) {
|
||||||
|
StringBuffer out = new StringBuffer();
|
||||||
|
for (int i = 0; i < identifier.length(); i++) {
|
||||||
|
char currentChar = identifier.charAt(i);
|
||||||
|
if (i == 0) {
|
||||||
|
out.append(Character.toLowerCase(currentChar));
|
||||||
|
} else if (Character.isUpperCase(currentChar)) {
|
||||||
|
out.append('_').append(Character.toLowerCase(currentChar));
|
||||||
|
} else {
|
||||||
|
out.append(currentChar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shortens and escapes the given string.
|
||||||
|
*/
|
||||||
|
private static String sanitizeString(String str) {
|
||||||
|
if (!str.startsWith("http") && str.length() > MAX_STRING_LEN) {
|
||||||
|
// Trim non-URL strings.
|
||||||
|
str = str.substring(0, MAX_STRING_LEN) + "[...]";
|
||||||
|
}
|
||||||
|
return escapeString(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escape everything except for low ASCII code points.
|
||||||
|
*/
|
||||||
|
private static String escapeString(String str) {
|
||||||
|
int strLen = str.length();
|
||||||
|
StringBuilder b = new StringBuilder(strLen);
|
||||||
|
for (int i = 0; i < strLen; i++) {
|
||||||
|
char original = str.charAt(i);
|
||||||
|
if (original >= ' ' && original <= '~' && original != '"' && original != '\'') {
|
||||||
|
b.append(original);
|
||||||
|
} else {
|
||||||
|
b.append(String.format("\\u%04x", (int) original));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends a quoted byte array to the provided {@code StringBuffer}.
|
||||||
|
*/
|
||||||
|
private static void appendQuotedBytes(byte[] bytes, StringBuffer builder) {
|
||||||
|
if (bytes == null) {
|
||||||
|
builder.append("\"\"");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.append('"');
|
||||||
|
for (int i = 0; i < bytes.length; ++i) {
|
||||||
|
int ch = bytes[i] & 0xff;
|
||||||
|
if (ch == '\\' || ch == '"') {
|
||||||
|
builder.append('\\').append((char) ch);
|
||||||
|
} else if (ch >= 32 && ch < 127) {
|
||||||
|
builder.append((char) ch);
|
||||||
|
} else {
|
||||||
|
builder.append(String.format("\\%03o", ch));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
builder.append('"');
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,84 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2013 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package com.google.protobuf.nano;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores unknown fields. These might be extensions or fields that the generated
|
||||||
|
* API doesn't know about yet.
|
||||||
|
*
|
||||||
|
* @author bduff@google.com (Brian Duff)
|
||||||
|
*/
|
||||||
|
final class UnknownFieldData {
|
||||||
|
|
||||||
|
final int tag;
|
||||||
|
final byte[] bytes;
|
||||||
|
|
||||||
|
UnknownFieldData(int tag, byte[] bytes) {
|
||||||
|
this.tag = tag;
|
||||||
|
this.bytes = bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
int computeSerializedSize() {
|
||||||
|
int size = 0;
|
||||||
|
size += CodedOutputByteBufferNano.computeRawVarint32Size(tag);
|
||||||
|
size += bytes.length;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeTo(CodedOutputByteBufferNano output) throws IOException {
|
||||||
|
output.writeRawVarint32(tag);
|
||||||
|
output.writeRawBytes(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (o == this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(o instanceof UnknownFieldData)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UnknownFieldData other = (UnknownFieldData) o;
|
||||||
|
return tag == other.tag && Arrays.equals(bytes, other.bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = 17;
|
||||||
|
result = 31 * result + tag;
|
||||||
|
result = 31 * result + Arrays.hashCode(bytes);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,124 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2013 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package com.google.protobuf.nano;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is used internally by the Protocol Buffer library and generated
|
||||||
|
* message implementations. It is public only because those generated messages
|
||||||
|
* do not reside in the {@code protobuf} package. Others should not use this
|
||||||
|
* class directly.
|
||||||
|
*
|
||||||
|
* This class contains constants and helper functions useful for dealing with
|
||||||
|
* the Protocol Buffer wire format.
|
||||||
|
*
|
||||||
|
* @author kenton@google.com Kenton Varda
|
||||||
|
*/
|
||||||
|
public final class WireFormatNano {
|
||||||
|
// Do not allow instantiation.
|
||||||
|
private WireFormatNano() {}
|
||||||
|
|
||||||
|
static final int WIRETYPE_VARINT = 0;
|
||||||
|
static final int WIRETYPE_FIXED64 = 1;
|
||||||
|
static final int WIRETYPE_LENGTH_DELIMITED = 2;
|
||||||
|
static final int WIRETYPE_START_GROUP = 3;
|
||||||
|
static final int WIRETYPE_END_GROUP = 4;
|
||||||
|
static final int WIRETYPE_FIXED32 = 5;
|
||||||
|
|
||||||
|
static final int TAG_TYPE_BITS = 3;
|
||||||
|
static final int TAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1;
|
||||||
|
|
||||||
|
/** Given a tag value, determines the wire type (the lower 3 bits). */
|
||||||
|
static int getTagWireType(final int tag) {
|
||||||
|
return tag & TAG_TYPE_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Given a tag value, determines the field number (the upper 29 bits). */
|
||||||
|
public static int getTagFieldNumber(final int tag) {
|
||||||
|
return tag >>> TAG_TYPE_BITS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Makes a tag value given a field number and wire type. */
|
||||||
|
static int makeTag(final int fieldNumber, final int wireType) {
|
||||||
|
return (fieldNumber << TAG_TYPE_BITS) | wireType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final int EMPTY_INT_ARRAY[] = {};
|
||||||
|
public static final long EMPTY_LONG_ARRAY[] = {};
|
||||||
|
public static final float EMPTY_FLOAT_ARRAY[] = {};
|
||||||
|
public static final double EMPTY_DOUBLE_ARRAY[] = {};
|
||||||
|
public static final boolean EMPTY_BOOLEAN_ARRAY[] = {};
|
||||||
|
public static final String EMPTY_STRING_ARRAY[] = {};
|
||||||
|
public static final byte[] EMPTY_BYTES_ARRAY[] = {};
|
||||||
|
public static final byte[] EMPTY_BYTES = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses an unknown field. This implementation skips the field.
|
||||||
|
*
|
||||||
|
* <p>Generated messages will call this for unknown fields if the store_unknown_fields
|
||||||
|
* option is off.
|
||||||
|
*
|
||||||
|
* @return {@literal true} unless the tag is an end-group tag.
|
||||||
|
*/
|
||||||
|
public static boolean parseUnknownField(
|
||||||
|
final CodedInputByteBufferNano input,
|
||||||
|
final int tag) throws IOException {
|
||||||
|
return input.skipField(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the array length of a repeated field. We assume that in the common case repeated
|
||||||
|
* fields are contiguously serialized but we still correctly handle interspersed values of a
|
||||||
|
* repeated field (but with extra allocations).
|
||||||
|
*
|
||||||
|
* Rewinds to current input position before returning.
|
||||||
|
*
|
||||||
|
* @param input stream input, pointing to the byte after the first tag
|
||||||
|
* @param tag repeated field tag just read
|
||||||
|
* @return length of array
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static final int getRepeatedFieldArrayLength(
|
||||||
|
final CodedInputByteBufferNano input,
|
||||||
|
final int tag) throws IOException {
|
||||||
|
int arrayLength = 1;
|
||||||
|
int startPos = input.getPosition();
|
||||||
|
input.skipField(tag);
|
||||||
|
while (input.readTag() == tag) {
|
||||||
|
input.skipField(tag);
|
||||||
|
arrayLength++;
|
||||||
|
}
|
||||||
|
input.rewindToPosition(startPos);
|
||||||
|
return arrayLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
3797
javanano/src/test/java/com/google/protobuf/nano/NanoTest.java
Normal file
3797
javanano/src/test/java/com/google/protobuf/nano/NanoTest.java
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,118 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: maxtroy@google.com (Max Cai)
|
||||||
|
|
||||||
|
package protobuf_unittest;
|
||||||
|
|
||||||
|
option java_package = "com.google.protobuf.nano";
|
||||||
|
option java_outer_classname = "NanoAccessorsOuterClass";
|
||||||
|
|
||||||
|
message TestNanoAccessors {
|
||||||
|
|
||||||
|
message NestedMessage {
|
||||||
|
optional int32 bb = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum NestedEnum {
|
||||||
|
FOO = 1;
|
||||||
|
BAR = 2;
|
||||||
|
BAZ = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Singular
|
||||||
|
optional int32 optional_int32 = 1;
|
||||||
|
optional float optional_float = 11;
|
||||||
|
optional double optional_double = 12;
|
||||||
|
optional string optional_string = 14;
|
||||||
|
optional bytes optional_bytes = 15;
|
||||||
|
|
||||||
|
optional NestedMessage optional_nested_message = 18;
|
||||||
|
|
||||||
|
optional NestedEnum optional_nested_enum = 21;
|
||||||
|
|
||||||
|
// Repeated
|
||||||
|
repeated int32 repeated_int32 = 31;
|
||||||
|
repeated string repeated_string = 44;
|
||||||
|
repeated bytes repeated_bytes = 45;
|
||||||
|
|
||||||
|
repeated NestedMessage repeated_nested_message = 48;
|
||||||
|
|
||||||
|
repeated NestedEnum repeated_nested_enum = 51;
|
||||||
|
|
||||||
|
// Singular with defaults
|
||||||
|
optional int32 default_int32 = 61 [default = 41 ];
|
||||||
|
optional string default_string = 74 [default = "hello"];
|
||||||
|
optional bytes default_bytes = 75 [default = "world"];
|
||||||
|
|
||||||
|
optional float default_float_nan = 99 [default = nan];
|
||||||
|
|
||||||
|
optional NestedEnum default_nested_enum = 81 [default = BAR];
|
||||||
|
|
||||||
|
// Required
|
||||||
|
required int32 id = 86;
|
||||||
|
|
||||||
|
// Add enough optional fields to make 2 bit fields in total
|
||||||
|
optional int32 filler100 = 100;
|
||||||
|
optional int32 filler101 = 101;
|
||||||
|
optional int32 filler102 = 102;
|
||||||
|
optional int32 filler103 = 103;
|
||||||
|
optional int32 filler104 = 104;
|
||||||
|
optional int32 filler105 = 105;
|
||||||
|
optional int32 filler106 = 106;
|
||||||
|
optional int32 filler107 = 107;
|
||||||
|
optional int32 filler108 = 108;
|
||||||
|
optional int32 filler109 = 109;
|
||||||
|
optional int32 filler110 = 110;
|
||||||
|
optional int32 filler111 = 111;
|
||||||
|
optional int32 filler112 = 112;
|
||||||
|
optional int32 filler113 = 113;
|
||||||
|
optional int32 filler114 = 114;
|
||||||
|
optional int32 filler115 = 115;
|
||||||
|
optional int32 filler116 = 116;
|
||||||
|
optional int32 filler117 = 117;
|
||||||
|
optional int32 filler118 = 118;
|
||||||
|
optional int32 filler119 = 119;
|
||||||
|
optional int32 filler120 = 120;
|
||||||
|
optional int32 filler121 = 121;
|
||||||
|
optional int32 filler122 = 122;
|
||||||
|
optional int32 filler123 = 123;
|
||||||
|
optional int32 filler124 = 124;
|
||||||
|
optional int32 filler125 = 125;
|
||||||
|
optional int32 filler126 = 126;
|
||||||
|
optional int32 filler127 = 127;
|
||||||
|
optional int32 filler128 = 128;
|
||||||
|
optional int32 filler129 = 129;
|
||||||
|
optional int32 filler130 = 130;
|
||||||
|
|
||||||
|
optional int32 before_bit_field_check = 139;
|
||||||
|
optional int32 bit_field_check = 140;
|
||||||
|
optional int32 after_bit_field_check = 141;
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: maxtroy@google.com (Max Cai)
|
||||||
|
|
||||||
|
package protobuf_unittest;
|
||||||
|
|
||||||
|
option java_package = "com.google.protobuf.nano";
|
||||||
|
option java_multiple_files = true;
|
||||||
|
|
||||||
|
enum FileScopeEnumMultiple {
|
||||||
|
THREE = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message EnumClassNanoMultiple {
|
||||||
|
enum MessageScopeEnumMultiple {
|
||||||
|
FOUR = 4;
|
||||||
|
}
|
||||||
|
optional FileScopeEnumMultiple three = 3 [ default = THREE ];
|
||||||
|
optional MessageScopeEnumMultiple four = 4 [ default = FOUR ];
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: maxtroy@google.com (Max Cai)
|
||||||
|
|
||||||
|
package protobuf_unittest;
|
||||||
|
|
||||||
|
option java_package = "com.google.protobuf.nano";
|
||||||
|
option java_outer_classname = "EnumClassNanos";
|
||||||
|
|
||||||
|
enum FileScopeEnum {
|
||||||
|
ONE = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message EnumClassNano {
|
||||||
|
enum MessageScopeEnum {
|
||||||
|
TWO = 2;
|
||||||
|
}
|
||||||
|
optional FileScopeEnum one = 1 [ default = ONE ];
|
||||||
|
optional MessageScopeEnum two = 2 [ default = TWO ];
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package protobuf_unittest;
|
||||||
|
|
||||||
|
option java_package = "com.google.protobuf.nano";
|
||||||
|
option java_outer_classname = "EnumValidity";
|
||||||
|
|
||||||
|
enum E {
|
||||||
|
default = 1; // test java keyword renaming
|
||||||
|
FOO = 2;
|
||||||
|
BAR = 3;
|
||||||
|
BAZ = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message M {
|
||||||
|
optional E optional_e = 1;
|
||||||
|
optional E default_e = 2 [ default = BAZ ];
|
||||||
|
repeated E repeated_e = 3;
|
||||||
|
repeated E packed_e = 4 [ packed = true ];
|
||||||
|
repeated E repeated_e2 = 5;
|
||||||
|
repeated E packed_e2 = 6 [ packed = true ];
|
||||||
|
repeated E repeated_e3 = 7;
|
||||||
|
repeated E packed_e3 = 8 [ packed = true ];
|
||||||
|
}
|
||||||
|
|
||||||
|
message Alt {
|
||||||
|
optional E repeated_e2_as_optional = 5;
|
||||||
|
repeated E packed_e2_as_non_packed = 6;
|
||||||
|
repeated E non_packed_e3_as_packed = 7 [ packed = true ];
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
option java_outer_classname = "Extensions";
|
||||||
|
option java_package = "com.google.protobuf.nano.testext";
|
||||||
|
|
||||||
|
message ExtendableMessage {
|
||||||
|
optional int32 field = 1;
|
||||||
|
extensions 10 to max;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum AnEnum {
|
||||||
|
FIRST_VALUE = 1;
|
||||||
|
SECOND_VALUE = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AnotherMessage {
|
||||||
|
optional string string = 1;
|
||||||
|
optional bool value = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ContainerMessage {
|
||||||
|
extend ExtendableMessage {
|
||||||
|
optional bool another_thing = 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For testNanoOptionalGroupWithUnknownFieldsEnabled;
|
||||||
|
// not part of the extensions tests.
|
||||||
|
message MessageWithGroup {
|
||||||
|
optional group Group = 1 {
|
||||||
|
optional int32 a = 2;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
option java_multiple_files = true;
|
||||||
|
option java_package = "com.google.protobuf.nano";
|
||||||
|
|
||||||
|
import "google/protobuf/nano/unittest_extension_nano.proto";
|
||||||
|
|
||||||
|
// Must be compiled separately due to extension number reuse.
|
||||||
|
// The reuse is deliberate, for testing wire compatibility.
|
||||||
|
|
||||||
|
message PackedExtensions {
|
||||||
|
extend ExtendableMessage {
|
||||||
|
repeated int32 packed_int32 = 10 [ packed = true ];
|
||||||
|
repeated uint32 packed_uint32 = 11 [ packed = true ];
|
||||||
|
repeated sint32 packed_sint32 = 12 [ packed = true ];
|
||||||
|
repeated int64 packed_int64 = 13 [ packed = true ];
|
||||||
|
repeated uint64 packed_uint64 = 14 [ packed = true ];
|
||||||
|
repeated sint64 packed_sint64 = 15 [ packed = true ];
|
||||||
|
repeated fixed32 packed_fixed32 = 16 [ packed = true ];
|
||||||
|
repeated sfixed32 packed_sfixed32 = 17 [ packed = true ];
|
||||||
|
repeated fixed64 packed_fixed64 = 18 [ packed = true ];
|
||||||
|
repeated sfixed64 packed_sfixed64 = 19 [ packed = true ];
|
||||||
|
repeated bool packed_bool = 20 [ packed = true ];
|
||||||
|
repeated float packed_float = 21 [ packed = true ];
|
||||||
|
repeated double packed_double = 22 [ packed = true ];
|
||||||
|
repeated AnEnum packed_enum = 23 [ packed = true ];
|
||||||
|
// Non-packable types omitted.
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
option java_multiple_files = true;
|
||||||
|
option java_package = "com.google.protobuf.nano";
|
||||||
|
|
||||||
|
import "google/protobuf/nano/unittest_extension_nano.proto";
|
||||||
|
|
||||||
|
// Must be compiled separately due to extension number reuse.
|
||||||
|
// The reuse is deliberate, for testing wire compatibility.
|
||||||
|
|
||||||
|
message RepeatedExtensions {
|
||||||
|
extend ExtendableMessage {
|
||||||
|
repeated int32 repeated_int32 = 10;
|
||||||
|
repeated uint32 repeated_uint32 = 11;
|
||||||
|
repeated sint32 repeated_sint32 = 12;
|
||||||
|
repeated int64 repeated_int64 = 13;
|
||||||
|
repeated uint64 repeated_uint64 = 14;
|
||||||
|
repeated sint64 repeated_sint64 = 15;
|
||||||
|
repeated fixed32 repeated_fixed32 = 16;
|
||||||
|
repeated sfixed32 repeated_sfixed32 = 17;
|
||||||
|
repeated fixed64 repeated_fixed64 = 18;
|
||||||
|
repeated sfixed64 repeated_sfixed64 = 19;
|
||||||
|
repeated bool repeated_bool = 20;
|
||||||
|
repeated float repeated_float = 21;
|
||||||
|
repeated double repeated_double = 22;
|
||||||
|
repeated AnEnum repeated_enum = 23;
|
||||||
|
repeated string repeated_string = 24;
|
||||||
|
repeated bytes repeated_bytes = 25;
|
||||||
|
repeated AnotherMessage repeated_message = 26;
|
||||||
|
repeated group RepeatedGroup = 27 {
|
||||||
|
optional int32 a = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
option java_multiple_files = true;
|
||||||
|
option java_package = "com.google.protobuf.nano";
|
||||||
|
|
||||||
|
import "google/protobuf/nano/unittest_extension_nano.proto";
|
||||||
|
|
||||||
|
// Must be compiled separately due to extension number reuse.
|
||||||
|
// The reuse is deliberate, for testing wire compatibility.
|
||||||
|
|
||||||
|
message SingularExtensions {
|
||||||
|
extend ExtendableMessage {
|
||||||
|
optional int32 some_int32 = 10;
|
||||||
|
optional uint32 some_uint32 = 11;
|
||||||
|
optional sint32 some_sint32 = 12;
|
||||||
|
optional int64 some_int64 = 13;
|
||||||
|
optional uint64 some_uint64 = 14;
|
||||||
|
optional sint64 some_sint64 = 15;
|
||||||
|
optional fixed32 some_fixed32 = 16;
|
||||||
|
optional sfixed32 some_sfixed32 = 17;
|
||||||
|
optional fixed64 some_fixed64 = 18;
|
||||||
|
optional sfixed64 some_sfixed64 = 19;
|
||||||
|
optional bool some_bool = 20;
|
||||||
|
optional float some_float = 21;
|
||||||
|
optional double some_double = 22;
|
||||||
|
optional AnEnum some_enum = 23;
|
||||||
|
optional string some_string = 24;
|
||||||
|
optional bytes some_bytes = 25;
|
||||||
|
optional AnotherMessage some_message = 26;
|
||||||
|
optional group SomeGroup = 27 {
|
||||||
|
optional int32 a = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: ulas@google.com (Ulas Kirazci)
|
||||||
|
|
||||||
|
package protobuf_unittest;
|
||||||
|
|
||||||
|
option java_package = "com.google.protobuf.nano";
|
||||||
|
option java_outer_classname = "NanoHasOuterClass";
|
||||||
|
|
||||||
|
message TestAllTypesNanoHas {
|
||||||
|
|
||||||
|
message NestedMessage {
|
||||||
|
optional int32 bb = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum NestedEnum {
|
||||||
|
FOO = 1;
|
||||||
|
BAR = 2;
|
||||||
|
BAZ = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Singular
|
||||||
|
optional int32 optional_int32 = 1;
|
||||||
|
optional float optional_float = 11;
|
||||||
|
optional double optional_double = 12;
|
||||||
|
optional string optional_string = 14;
|
||||||
|
optional bytes optional_bytes = 15;
|
||||||
|
|
||||||
|
optional NestedMessage optional_nested_message = 18;
|
||||||
|
|
||||||
|
optional NestedEnum optional_nested_enum = 21;
|
||||||
|
|
||||||
|
// Repeated
|
||||||
|
repeated int32 repeated_int32 = 31;
|
||||||
|
repeated string repeated_string = 44;
|
||||||
|
repeated bytes repeated_bytes = 45;
|
||||||
|
|
||||||
|
repeated NestedMessage repeated_nested_message = 48;
|
||||||
|
|
||||||
|
repeated NestedEnum repeated_nested_enum = 51;
|
||||||
|
|
||||||
|
// Singular with defaults
|
||||||
|
optional int32 default_int32 = 61 [default = 41 ];
|
||||||
|
optional string default_string = 74 [default = "hello"];
|
||||||
|
optional bytes default_bytes = 75 [default = "world"];
|
||||||
|
|
||||||
|
optional float default_float_nan = 99 [default = nan];
|
||||||
|
|
||||||
|
optional NestedEnum default_nested_enum = 81 [default = BAR];
|
||||||
|
|
||||||
|
required int32 id = 86;
|
||||||
|
required NestedEnum required_enum = 87;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: kenton@google.com (Kenton Varda)
|
||||||
|
//
|
||||||
|
// This is like unittest_import.proto but with optimize_for = NANO_RUNTIME.
|
||||||
|
|
||||||
|
package protobuf_unittest_import;
|
||||||
|
|
||||||
|
option java_package = "com.google.protobuf.nano.testimport";
|
||||||
|
option java_outer_classname = "UnittestImportNano";
|
||||||
|
|
||||||
|
message ImportMessageNano {
|
||||||
|
optional int32 d = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ImportEnumNano {
|
||||||
|
IMPORT_NANO_FOO = 7;
|
||||||
|
IMPORT_NANO_BAR = 8;
|
||||||
|
IMPORT_NANO_BAZ = 9;
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: maxtroy@google.com (Max Cai)
|
||||||
|
|
||||||
|
package protobuf_unittest_import;
|
||||||
|
|
||||||
|
option java_package = "com.google.protobuf.nano";
|
||||||
|
option java_outer_classname = "MultipleNameClashNano";
|
||||||
|
option java_multiple_files = true;
|
||||||
|
|
||||||
|
message MultipleNameClashNano {
|
||||||
|
optional int32 field = 1;
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: maxtroy@google.com (Max Cai)
|
||||||
|
|
||||||
|
package protobuf_unittest_import;
|
||||||
|
|
||||||
|
import "google/protobuf/nano/unittest_import_nano.proto";
|
||||||
|
|
||||||
|
option java_package = "com.google.protobuf.nano";
|
||||||
|
option java_multiple_files = true;
|
||||||
|
|
||||||
|
enum FileScopeEnum {
|
||||||
|
ONE = 1;
|
||||||
|
TWO = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FileScopeEnumRefNano {
|
||||||
|
optional FileScopeEnum enum_field = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message MessageScopeEnumRefNano {
|
||||||
|
enum MessageScopeEnum {
|
||||||
|
ONE = 1;
|
||||||
|
TWO = 2;
|
||||||
|
}
|
||||||
|
optional MessageScopeEnum enum_field = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message MultipleImportingNonMultipleNano1 {
|
||||||
|
optional ImportMessageNano field = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message MultipleImportingNonMultipleNano2 {
|
||||||
|
optional MultipleImportingNonMultipleNano1 nano1 = 1;
|
||||||
|
}
|
@ -0,0 +1,186 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: wink@google.com (Wink Saville)
|
||||||
|
|
||||||
|
package protobuf_unittest;
|
||||||
|
|
||||||
|
import "google/protobuf/nano/unittest_import_nano.proto";
|
||||||
|
|
||||||
|
option java_package = "com.google.protobuf.nano";
|
||||||
|
option java_outer_classname = "NanoOuterClass";
|
||||||
|
|
||||||
|
// Same as TestAllTypes but with the nano runtime.
|
||||||
|
message TestAllTypesNano {
|
||||||
|
|
||||||
|
message NestedMessage {
|
||||||
|
optional int32 bb = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum NestedEnum {
|
||||||
|
FOO = 1;
|
||||||
|
BAR = 2;
|
||||||
|
BAZ = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Singular
|
||||||
|
optional int32 optional_int32 = 1;
|
||||||
|
optional int64 optional_int64 = 2;
|
||||||
|
optional uint32 optional_uint32 = 3;
|
||||||
|
optional uint64 optional_uint64 = 4;
|
||||||
|
optional sint32 optional_sint32 = 5;
|
||||||
|
optional sint64 optional_sint64 = 6;
|
||||||
|
optional fixed32 optional_fixed32 = 7;
|
||||||
|
optional fixed64 optional_fixed64 = 8;
|
||||||
|
optional sfixed32 optional_sfixed32 = 9;
|
||||||
|
optional sfixed64 optional_sfixed64 = 10;
|
||||||
|
optional float optional_float = 11;
|
||||||
|
optional double optional_double = 12;
|
||||||
|
optional bool optional_bool = 13;
|
||||||
|
optional string optional_string = 14;
|
||||||
|
optional bytes optional_bytes = 15;
|
||||||
|
|
||||||
|
optional group OptionalGroup = 16 {
|
||||||
|
optional int32 a = 17;
|
||||||
|
}
|
||||||
|
|
||||||
|
optional NestedMessage optional_nested_message = 18;
|
||||||
|
optional ForeignMessageNano optional_foreign_message = 19;
|
||||||
|
optional protobuf_unittest_import.ImportMessageNano
|
||||||
|
optional_import_message = 20;
|
||||||
|
|
||||||
|
optional NestedEnum optional_nested_enum = 21;
|
||||||
|
optional ForeignEnumNano optional_foreign_enum = 22;
|
||||||
|
optional protobuf_unittest_import.ImportEnumNano optional_import_enum = 23;
|
||||||
|
|
||||||
|
optional string optional_string_piece = 24 [ctype=STRING_PIECE];
|
||||||
|
optional string optional_cord = 25 [ctype=CORD];
|
||||||
|
|
||||||
|
// Repeated
|
||||||
|
repeated int32 repeated_int32 = 31;
|
||||||
|
repeated int64 repeated_int64 = 32;
|
||||||
|
repeated uint32 repeated_uint32 = 33;
|
||||||
|
repeated uint64 repeated_uint64 = 34;
|
||||||
|
repeated sint32 repeated_sint32 = 35;
|
||||||
|
repeated sint64 repeated_sint64 = 36;
|
||||||
|
repeated fixed32 repeated_fixed32 = 37;
|
||||||
|
repeated fixed64 repeated_fixed64 = 38;
|
||||||
|
repeated sfixed32 repeated_sfixed32 = 39;
|
||||||
|
repeated sfixed64 repeated_sfixed64 = 40;
|
||||||
|
repeated float repeated_float = 41;
|
||||||
|
repeated double repeated_double = 42;
|
||||||
|
repeated bool repeated_bool = 43;
|
||||||
|
repeated string repeated_string = 44;
|
||||||
|
repeated bytes repeated_bytes = 45;
|
||||||
|
|
||||||
|
repeated group RepeatedGroup = 46 {
|
||||||
|
optional int32 a = 47;
|
||||||
|
}
|
||||||
|
|
||||||
|
repeated NestedMessage repeated_nested_message = 48;
|
||||||
|
repeated ForeignMessageNano repeated_foreign_message = 49;
|
||||||
|
repeated protobuf_unittest_import.ImportMessageNano
|
||||||
|
repeated_import_message = 50;
|
||||||
|
|
||||||
|
repeated NestedEnum repeated_nested_enum = 51;
|
||||||
|
repeated ForeignEnumNano repeated_foreign_enum = 52;
|
||||||
|
repeated protobuf_unittest_import.ImportEnumNano repeated_import_enum = 53;
|
||||||
|
|
||||||
|
repeated string repeated_string_piece = 54 [ctype=STRING_PIECE];
|
||||||
|
repeated string repeated_cord = 55 [ctype=CORD];
|
||||||
|
|
||||||
|
// Repeated packed
|
||||||
|
repeated int32 repeated_packed_int32 = 87 [packed=true];
|
||||||
|
repeated sfixed64 repeated_packed_sfixed64 = 88 [packed=true];
|
||||||
|
|
||||||
|
repeated NestedEnum repeated_packed_nested_enum = 89 [packed=true];
|
||||||
|
|
||||||
|
// Singular with defaults
|
||||||
|
optional int32 default_int32 = 61 [default = 41 ];
|
||||||
|
optional int64 default_int64 = 62 [default = 42 ];
|
||||||
|
optional uint32 default_uint32 = 63 [default = 43 ];
|
||||||
|
optional uint64 default_uint64 = 64 [default = 44 ];
|
||||||
|
optional sint32 default_sint32 = 65 [default = -45 ];
|
||||||
|
optional sint64 default_sint64 = 66 [default = 46 ];
|
||||||
|
optional fixed32 default_fixed32 = 67 [default = 47 ];
|
||||||
|
optional fixed64 default_fixed64 = 68 [default = 48 ];
|
||||||
|
optional sfixed32 default_sfixed32 = 69 [default = 49 ];
|
||||||
|
optional sfixed64 default_sfixed64 = 70 [default = -50 ];
|
||||||
|
optional float default_float = 71 [default = 51.5 ];
|
||||||
|
optional double default_double = 72 [default = 52e3 ];
|
||||||
|
optional bool default_bool = 73 [default = true ];
|
||||||
|
optional string default_string = 74 [default = "hello"];
|
||||||
|
optional bytes default_bytes = 75 [default = "world"];
|
||||||
|
|
||||||
|
optional string default_string_nonascii = 76 [default = "dünya"];
|
||||||
|
optional bytes default_bytes_nonascii = 77 [default = "dünyab"];
|
||||||
|
|
||||||
|
optional float default_float_inf = 97 [default = inf];
|
||||||
|
optional float default_float_neg_inf = 98 [default = -inf];
|
||||||
|
optional float default_float_nan = 99 [default = nan];
|
||||||
|
optional double default_double_inf = 100 [default = inf];
|
||||||
|
optional double default_double_neg_inf = 101 [default = -inf];
|
||||||
|
optional double default_double_nan = 102 [default = nan];
|
||||||
|
|
||||||
|
optional NestedEnum default_nested_enum = 81 [default = BAR];
|
||||||
|
optional ForeignEnumNano default_foreign_enum = 82
|
||||||
|
[default = FOREIGN_NANO_BAR];
|
||||||
|
optional protobuf_unittest_import.ImportEnumNano
|
||||||
|
default_import_enum = 83 [default = IMPORT_NANO_BAR];
|
||||||
|
|
||||||
|
optional string default_string_piece = 84 [ctype=STRING_PIECE,default="abc"];
|
||||||
|
optional string default_cord = 85 [ctype=CORD,default="123"];
|
||||||
|
|
||||||
|
required int32 id = 86;
|
||||||
|
|
||||||
|
// Try to cause conflicts.
|
||||||
|
optional int32 tag = 93;
|
||||||
|
optional int32 get_serialized_size = 94;
|
||||||
|
optional int32 write_to = 95;
|
||||||
|
|
||||||
|
// Try to fail with java reserved keywords
|
||||||
|
optional int32 synchronized = 96;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ForeignMessageNano {
|
||||||
|
optional int32 c = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ForeignEnumNano {
|
||||||
|
FOREIGN_NANO_FOO = 4;
|
||||||
|
FOREIGN_NANO_BAR = 5;
|
||||||
|
FOREIGN_NANO_BAZ = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that deprecated fields work. We only verify that they compile (at one
|
||||||
|
// point this failed).
|
||||||
|
message TestDeprecatedNano {
|
||||||
|
optional int32 deprecated_field = 1 [deprecated = true];
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: wink@google.com (Wink Saville)
|
||||||
|
//
|
||||||
|
|
||||||
|
package protobuf_unittest_import;
|
||||||
|
|
||||||
|
option java_package = "com.google.protobuf.nano";
|
||||||
|
// Explicit outer classname to suppress legacy info.
|
||||||
|
option java_outer_classname = "UnittestRecursiveNano";
|
||||||
|
|
||||||
|
message RecursiveMessageNano {
|
||||||
|
message NestedMessage {
|
||||||
|
optional RecursiveMessageNano a = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
required int32 id = 1;
|
||||||
|
optional NestedMessage nested_message = 2;
|
||||||
|
optional RecursiveMessageNano optional_recursive_message_nano = 3;
|
||||||
|
repeated RecursiveMessageNano repeated_recursive_message_nano = 4;
|
||||||
|
}
|
@ -0,0 +1,116 @@
|
|||||||
|
package protobuf_unittest;
|
||||||
|
|
||||||
|
option java_package = "com.google.protobuf.nano";
|
||||||
|
option java_outer_classname = "NanoReferenceTypes";
|
||||||
|
|
||||||
|
message TestAllTypesNano {
|
||||||
|
|
||||||
|
enum NestedEnum {
|
||||||
|
FOO = 1;
|
||||||
|
BAR = 2;
|
||||||
|
BAZ = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message NestedMessage {
|
||||||
|
optional int32 foo = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Singular
|
||||||
|
optional int32 optional_int32 = 1;
|
||||||
|
optional int64 optional_int64 = 2;
|
||||||
|
optional uint32 optional_uint32 = 3;
|
||||||
|
optional uint64 optional_uint64 = 4;
|
||||||
|
optional sint32 optional_sint32 = 5;
|
||||||
|
optional sint64 optional_sint64 = 6;
|
||||||
|
optional fixed32 optional_fixed32 = 7;
|
||||||
|
optional fixed64 optional_fixed64 = 8;
|
||||||
|
optional sfixed32 optional_sfixed32 = 9;
|
||||||
|
optional sfixed64 optional_sfixed64 = 10;
|
||||||
|
optional float optional_float = 11;
|
||||||
|
optional double optional_double = 12;
|
||||||
|
optional bool optional_bool = 13;
|
||||||
|
optional string optional_string = 14;
|
||||||
|
optional bytes optional_bytes = 15;
|
||||||
|
|
||||||
|
optional group OptionalGroup = 16 {
|
||||||
|
optional int32 a = 17;
|
||||||
|
}
|
||||||
|
|
||||||
|
optional NestedMessage optional_nested_message = 18;
|
||||||
|
|
||||||
|
optional NestedEnum optional_nested_enum = 21;
|
||||||
|
|
||||||
|
optional string optional_string_piece = 24 [ctype=STRING_PIECE];
|
||||||
|
optional string optional_cord = 25 [ctype=CORD];
|
||||||
|
|
||||||
|
// Repeated
|
||||||
|
repeated int32 repeated_int32 = 31;
|
||||||
|
repeated int64 repeated_int64 = 32;
|
||||||
|
repeated uint32 repeated_uint32 = 33;
|
||||||
|
repeated uint64 repeated_uint64 = 34;
|
||||||
|
repeated sint32 repeated_sint32 = 35;
|
||||||
|
repeated sint64 repeated_sint64 = 36;
|
||||||
|
repeated fixed32 repeated_fixed32 = 37;
|
||||||
|
repeated fixed64 repeated_fixed64 = 38;
|
||||||
|
repeated sfixed32 repeated_sfixed32 = 39;
|
||||||
|
repeated sfixed64 repeated_sfixed64 = 40;
|
||||||
|
repeated float repeated_float = 41;
|
||||||
|
repeated double repeated_double = 42;
|
||||||
|
repeated bool repeated_bool = 43;
|
||||||
|
repeated string repeated_string = 44;
|
||||||
|
repeated bytes repeated_bytes = 45;
|
||||||
|
|
||||||
|
repeated group RepeatedGroup = 46 {
|
||||||
|
optional int32 a = 47;
|
||||||
|
}
|
||||||
|
|
||||||
|
repeated NestedMessage repeated_nested_message = 48;
|
||||||
|
|
||||||
|
repeated NestedEnum repeated_nested_enum = 51;
|
||||||
|
|
||||||
|
repeated string repeated_string_piece = 54 [ctype=STRING_PIECE];
|
||||||
|
repeated string repeated_cord = 55 [ctype=CORD];
|
||||||
|
|
||||||
|
// Repeated packed
|
||||||
|
repeated int32 repeated_packed_int32 = 87 [packed=true];
|
||||||
|
repeated sfixed64 repeated_packed_sfixed64 = 88 [packed=true];
|
||||||
|
|
||||||
|
repeated NestedEnum repeated_packed_nested_enum = 89 [packed=true];
|
||||||
|
|
||||||
|
// Singular with defaults
|
||||||
|
optional int32 default_int32 = 61 [default = 41 ];
|
||||||
|
optional int64 default_int64 = 62 [default = 42 ];
|
||||||
|
optional uint32 default_uint32 = 63 [default = 43 ];
|
||||||
|
optional uint64 default_uint64 = 64 [default = 44 ];
|
||||||
|
optional sint32 default_sint32 = 65 [default = -45 ];
|
||||||
|
optional sint64 default_sint64 = 66 [default = 46 ];
|
||||||
|
optional fixed32 default_fixed32 = 67 [default = 47 ];
|
||||||
|
optional fixed64 default_fixed64 = 68 [default = 48 ];
|
||||||
|
optional sfixed32 default_sfixed32 = 69 [default = 49 ];
|
||||||
|
optional sfixed64 default_sfixed64 = 70 [default = -50 ];
|
||||||
|
optional float default_float = 71 [default = 51.5 ];
|
||||||
|
optional double default_double = 72 [default = 52e3 ];
|
||||||
|
optional bool default_bool = 73 [default = true ];
|
||||||
|
optional string default_string = 74 [default = "hello"];
|
||||||
|
optional bytes default_bytes = 75 [default = "world"];
|
||||||
|
|
||||||
|
|
||||||
|
optional float default_float_inf = 97 [default = inf];
|
||||||
|
optional float default_float_neg_inf = 98 [default = -inf];
|
||||||
|
optional float default_float_nan = 99 [default = nan];
|
||||||
|
optional double default_double_inf = 100 [default = inf];
|
||||||
|
optional double default_double_neg_inf = 101 [default = -inf];
|
||||||
|
optional double default_double_nan = 102 [default = nan];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
message ForeignMessageNano {
|
||||||
|
optional int32 c = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ForeignEnumNano {
|
||||||
|
FOREIGN_NANO_FOO = 4;
|
||||||
|
FOREIGN_NANO_BAR = 5;
|
||||||
|
FOREIGN_NANO_BAZ = 6;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: maxtroy@google.com (Max Cai)
|
||||||
|
|
||||||
|
package protobuf_unittest;
|
||||||
|
|
||||||
|
import "google/protobuf/nano/unittest_nano.proto";
|
||||||
|
|
||||||
|
option java_package = "com.google.protobuf.nano";
|
||||||
|
option java_multiple_files = true;
|
||||||
|
|
||||||
|
// A container message for testing the merging of repeated fields at a
|
||||||
|
// nested level. Other tests will be done using the repeated fields in
|
||||||
|
// TestAllTypesNano.
|
||||||
|
message TestRepeatedMergeNano {
|
||||||
|
|
||||||
|
optional TestAllTypesNano contained = 1;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,95 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: maxtroy@google.com (Max Cai)
|
||||||
|
|
||||||
|
package protobuf_unittest;
|
||||||
|
|
||||||
|
option java_package = "com.google.protobuf.nano";
|
||||||
|
option java_outer_classname = "NanoRepeatedPackables";
|
||||||
|
|
||||||
|
enum Enum {
|
||||||
|
OPTION_ONE = 1;
|
||||||
|
OPTION_TWO = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Two almost identical messages with all packable repeated field types.
|
||||||
|
// One with none marked as packed and the other all packed. For
|
||||||
|
// compatibility, they should be able to parse each other's serialized
|
||||||
|
// forms.
|
||||||
|
|
||||||
|
message NonPacked {
|
||||||
|
|
||||||
|
// All packable types, none marked as packed.
|
||||||
|
|
||||||
|
repeated int32 int32s = 1;
|
||||||
|
repeated int64 int64s = 2;
|
||||||
|
repeated uint32 uint32s = 3;
|
||||||
|
repeated uint64 uint64s = 4;
|
||||||
|
repeated sint32 sint32s = 5;
|
||||||
|
repeated sint64 sint64s = 6;
|
||||||
|
repeated fixed32 fixed32s = 7;
|
||||||
|
repeated fixed64 fixed64s = 8;
|
||||||
|
repeated sfixed32 sfixed32s = 9;
|
||||||
|
repeated sfixed64 sfixed64s = 10;
|
||||||
|
repeated float floats = 11;
|
||||||
|
repeated double doubles = 12;
|
||||||
|
repeated bool bools = 13;
|
||||||
|
repeated Enum enums = 14;
|
||||||
|
|
||||||
|
// Noise for testing merged deserialization.
|
||||||
|
optional int32 noise = 15;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
message Packed {
|
||||||
|
|
||||||
|
// All packable types, all matching the field numbers in NonPacked,
|
||||||
|
// all marked as packed.
|
||||||
|
|
||||||
|
repeated int32 int32s = 1 [ packed = true ];
|
||||||
|
repeated int64 int64s = 2 [ packed = true ];
|
||||||
|
repeated uint32 uint32s = 3 [ packed = true ];
|
||||||
|
repeated uint64 uint64s = 4 [ packed = true ];
|
||||||
|
repeated sint32 sint32s = 5 [ packed = true ];
|
||||||
|
repeated sint64 sint64s = 6 [ packed = true ];
|
||||||
|
repeated fixed32 fixed32s = 7 [ packed = true ];
|
||||||
|
repeated fixed64 fixed64s = 8 [ packed = true ];
|
||||||
|
repeated sfixed32 sfixed32s = 9 [ packed = true ];
|
||||||
|
repeated sfixed64 sfixed64s = 10 [ packed = true ];
|
||||||
|
repeated float floats = 11 [ packed = true ];
|
||||||
|
repeated double doubles = 12 [ packed = true ];
|
||||||
|
repeated bool bools = 13 [ packed = true ];
|
||||||
|
repeated Enum enums = 14 [ packed = true ];
|
||||||
|
|
||||||
|
// Noise for testing merged deserialization.
|
||||||
|
optional int32 noise = 15;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: wink@google.com (Wink Saville)
|
||||||
|
//
|
||||||
|
|
||||||
|
package protobuf_unittest_import;
|
||||||
|
|
||||||
|
option java_package = "com.google.protobuf.nano";
|
||||||
|
// Explicit outer classname to suppress legacy info.
|
||||||
|
option java_outer_classname = "UnittestSimpleNano";
|
||||||
|
|
||||||
|
message SimpleMessageNano {
|
||||||
|
message NestedMessage {
|
||||||
|
optional int32 bb = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum NestedEnum {
|
||||||
|
FOO = 1;
|
||||||
|
BAR = 2;
|
||||||
|
BAZ = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
optional int32 d = 1 [default = 123];
|
||||||
|
optional NestedMessage nested_msg = 2;
|
||||||
|
optional NestedEnum default_nested_enum = 3 [default = BAZ];
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: maxtroy@google.com (Max Cai)
|
||||||
|
|
||||||
|
package protobuf_unittest_import;
|
||||||
|
|
||||||
|
option java_package = "com.google.protobuf.nano";
|
||||||
|
|
||||||
|
message SingleMessageNano {
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: wink@google.com (Wink Saville)
|
||||||
|
//
|
||||||
|
|
||||||
|
package protobuf_unittest_import;
|
||||||
|
|
||||||
|
option java_package = "com.google.protobuf.nano";
|
||||||
|
// Explicit outer classname to suppress legacy info.
|
||||||
|
option java_outer_classname = "UnittestStringutf8Nano";
|
||||||
|
|
||||||
|
message StringUtf8 {
|
||||||
|
optional string id = 1;
|
||||||
|
repeated string rs = 2;
|
||||||
|
}
|
111
src/google/protobuf/compiler/javanano/javanano_enum.cc
Normal file
111
src/google/protobuf/compiler/javanano/javanano_enum.cc
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: kenton@google.com (Kenton Varda)
|
||||||
|
// Based on original Protocol Buffers design by
|
||||||
|
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_params.h>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_enum.h>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_helpers.h>
|
||||||
|
#include <google/protobuf/io/printer.h>
|
||||||
|
#include <google/protobuf/descriptor.pb.h>
|
||||||
|
#include <google/protobuf/stubs/strutil.h>
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
namespace protobuf {
|
||||||
|
namespace compiler {
|
||||||
|
namespace javanano {
|
||||||
|
|
||||||
|
EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor, const Params& params)
|
||||||
|
: params_(params), descriptor_(descriptor) {
|
||||||
|
for (int i = 0; i < descriptor_->value_count(); i++) {
|
||||||
|
const EnumValueDescriptor* value = descriptor_->value(i);
|
||||||
|
const EnumValueDescriptor* canonical_value =
|
||||||
|
descriptor_->FindValueByNumber(value->number());
|
||||||
|
|
||||||
|
if (value == canonical_value) {
|
||||||
|
canonical_values_.push_back(value);
|
||||||
|
} else {
|
||||||
|
Alias alias;
|
||||||
|
alias.value = value;
|
||||||
|
alias.canonical_value = canonical_value;
|
||||||
|
aliases_.push_back(alias);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EnumGenerator::~EnumGenerator() {}
|
||||||
|
|
||||||
|
void EnumGenerator::Generate(io::Printer* printer) {
|
||||||
|
printer->Print(
|
||||||
|
"\n"
|
||||||
|
"// enum $classname$\n",
|
||||||
|
"classname", descriptor_->name());
|
||||||
|
|
||||||
|
// Start of container interface
|
||||||
|
bool use_shell_class = params_.java_enum_style();
|
||||||
|
if (use_shell_class) {
|
||||||
|
printer->Print(
|
||||||
|
"public interface $classname$ {\n",
|
||||||
|
"classname", RenameJavaKeywords(descriptor_->name()));
|
||||||
|
printer->Indent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Canonical values
|
||||||
|
for (int i = 0; i < canonical_values_.size(); i++) {
|
||||||
|
printer->Print(
|
||||||
|
"public static final int $name$ = $canonical_value$;\n",
|
||||||
|
"name", RenameJavaKeywords(canonical_values_[i]->name()),
|
||||||
|
"canonical_value", SimpleItoa(canonical_values_[i]->number()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aliases
|
||||||
|
for (int i = 0; i < aliases_.size(); i++) {
|
||||||
|
printer->Print(
|
||||||
|
"public static final int $name$ = $canonical_name$;\n",
|
||||||
|
"name", RenameJavaKeywords(aliases_[i].value->name()),
|
||||||
|
"canonical_name", RenameJavaKeywords(aliases_[i].canonical_value->name()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// End of container interface
|
||||||
|
if (use_shell_class) {
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("}\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace javanano
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace protobuf
|
||||||
|
} // namespace google
|
87
src/google/protobuf/compiler/javanano/javanano_enum.h
Normal file
87
src/google/protobuf/compiler/javanano/javanano_enum.h
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: kenton@google.com (Kenton Varda)
|
||||||
|
// Based on original Protocol Buffers design by
|
||||||
|
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||||
|
|
||||||
|
#ifndef GOOGLE_PROTOBUF_COMPILER_JAVANANO_ENUM_H__
|
||||||
|
#define GOOGLE_PROTOBUF_COMPILER_JAVANANO_ENUM_H__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_params.h>
|
||||||
|
#include <google/protobuf/descriptor.h>
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
namespace protobuf {
|
||||||
|
namespace io {
|
||||||
|
class Printer; // printer.h
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace protobuf {
|
||||||
|
namespace compiler {
|
||||||
|
namespace javanano {
|
||||||
|
|
||||||
|
class EnumGenerator {
|
||||||
|
public:
|
||||||
|
explicit EnumGenerator(const EnumDescriptor* descriptor, const Params& params);
|
||||||
|
~EnumGenerator();
|
||||||
|
|
||||||
|
void Generate(io::Printer* printer);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Params& params_;
|
||||||
|
const EnumDescriptor* descriptor_;
|
||||||
|
|
||||||
|
// The proto language allows multiple enum constants to have the same numeric
|
||||||
|
// value. Java, however, does not allow multiple enum constants to be
|
||||||
|
// considered equivalent. We treat the first defined constant for any
|
||||||
|
// given numeric value as "canonical" and the rest as aliases of that
|
||||||
|
// canonical value.
|
||||||
|
vector<const EnumValueDescriptor*> canonical_values_;
|
||||||
|
|
||||||
|
struct Alias {
|
||||||
|
const EnumValueDescriptor* value;
|
||||||
|
const EnumValueDescriptor* canonical_value;
|
||||||
|
};
|
||||||
|
vector<Alias> aliases_;
|
||||||
|
|
||||||
|
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace javanano
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace protobuf
|
||||||
|
|
||||||
|
} // namespace google
|
||||||
|
#endif // GOOGLE_PROTOBUF_COMPILER_JAVANANO_ENUM_H__
|
520
src/google/protobuf/compiler/javanano/javanano_enum_field.cc
Normal file
520
src/google/protobuf/compiler/javanano/javanano_enum_field.cc
Normal file
@ -0,0 +1,520 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: kenton@google.com (Kenton Varda)
|
||||||
|
// Based on original Protocol Buffers design by
|
||||||
|
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_enum_field.h>
|
||||||
|
#include <google/protobuf/stubs/common.h>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_helpers.h>
|
||||||
|
#include <google/protobuf/io/printer.h>
|
||||||
|
#include <google/protobuf/wire_format.h>
|
||||||
|
#include <google/protobuf/stubs/strutil.h>
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
namespace protobuf {
|
||||||
|
namespace compiler {
|
||||||
|
namespace javanano {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of
|
||||||
|
// repeat code between this and the other field types.
|
||||||
|
void SetEnumVariables(const Params& params,
|
||||||
|
const FieldDescriptor* descriptor, map<string, string>* variables) {
|
||||||
|
(*variables)["name"] =
|
||||||
|
RenameJavaKeywords(UnderscoresToCamelCase(descriptor));
|
||||||
|
(*variables)["capitalized_name"] =
|
||||||
|
RenameJavaKeywords(UnderscoresToCapitalizedCamelCase(descriptor));
|
||||||
|
(*variables)["number"] = SimpleItoa(descriptor->number());
|
||||||
|
if (params.use_reference_types_for_primitives()
|
||||||
|
&& !params.reftypes_primitive_enums()
|
||||||
|
&& !descriptor->is_repeated()) {
|
||||||
|
(*variables)["type"] = "java.lang.Integer";
|
||||||
|
(*variables)["default"] = "null";
|
||||||
|
} else {
|
||||||
|
(*variables)["type"] = "int";
|
||||||
|
(*variables)["default"] = DefaultValue(params, descriptor);
|
||||||
|
}
|
||||||
|
(*variables)["repeated_default"] =
|
||||||
|
"com.google.protobuf.nano.WireFormatNano.EMPTY_INT_ARRAY";
|
||||||
|
(*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor));
|
||||||
|
(*variables)["tag_size"] = SimpleItoa(
|
||||||
|
internal::WireFormat::TagSize(descriptor->number(), descriptor->type()));
|
||||||
|
(*variables)["non_packed_tag"] = SimpleItoa(
|
||||||
|
internal::WireFormatLite::MakeTag(descriptor->number(),
|
||||||
|
internal::WireFormat::WireTypeForFieldType(descriptor->type())));
|
||||||
|
(*variables)["message_name"] = descriptor->containing_type()->name();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadEnumValues(const Params& params,
|
||||||
|
const EnumDescriptor* enum_descriptor, vector<string>* canonical_values) {
|
||||||
|
string enum_class_name = ClassName(params, enum_descriptor);
|
||||||
|
for (int i = 0; i < enum_descriptor->value_count(); i++) {
|
||||||
|
const EnumValueDescriptor* value = enum_descriptor->value(i);
|
||||||
|
const EnumValueDescriptor* canonical_value =
|
||||||
|
enum_descriptor->FindValueByNumber(value->number());
|
||||||
|
if (value == canonical_value) {
|
||||||
|
canonical_values->push_back(
|
||||||
|
enum_class_name + "." + RenameJavaKeywords(value->name()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintCaseLabels(
|
||||||
|
io::Printer* printer, const vector<string>& canonical_values) {
|
||||||
|
for (int i = 0; i < canonical_values.size(); i++) {
|
||||||
|
printer->Print(
|
||||||
|
" case $value$:\n",
|
||||||
|
"value", canonical_values[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// ===================================================================
|
||||||
|
|
||||||
|
EnumFieldGenerator::
|
||||||
|
EnumFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
|
||||||
|
: FieldGenerator(params), descriptor_(descriptor) {
|
||||||
|
SetEnumVariables(params, descriptor, &variables_);
|
||||||
|
LoadEnumValues(params, descriptor->enum_type(), &canonical_values_);
|
||||||
|
}
|
||||||
|
|
||||||
|
EnumFieldGenerator::~EnumFieldGenerator() {}
|
||||||
|
|
||||||
|
void EnumFieldGenerator::
|
||||||
|
GenerateMembers(io::Printer* printer, bool /* unused lazy_init */) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"public $type$ $name$;\n");
|
||||||
|
|
||||||
|
if (params_.generate_has()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"public boolean has$capitalized_name$;\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnumFieldGenerator::
|
||||||
|
GenerateClearCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"$name$ = $default$;\n");
|
||||||
|
|
||||||
|
if (params_.generate_has()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"has$capitalized_name$ = false;\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnumFieldGenerator::
|
||||||
|
GenerateMergingCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"int value = input.readInt32();\n"
|
||||||
|
"switch (value) {\n");
|
||||||
|
PrintCaseLabels(printer, canonical_values_);
|
||||||
|
printer->Print(variables_,
|
||||||
|
" this.$name$ = value;\n");
|
||||||
|
if (params_.generate_has()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
" has$capitalized_name$ = true;\n");
|
||||||
|
}
|
||||||
|
printer->Print(
|
||||||
|
" break;\n"
|
||||||
|
"}\n");
|
||||||
|
// No default case: in case of invalid value from the wire, preserve old
|
||||||
|
// field value. Also we are not storing the invalid value into the unknown
|
||||||
|
// fields, because there is no way to get the value out.
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnumFieldGenerator::
|
||||||
|
GenerateSerializationCode(io::Printer* printer) const {
|
||||||
|
if (descriptor_->is_required() && !params_.generate_has()) {
|
||||||
|
// Always serialize a required field if we don't have the 'has' signal.
|
||||||
|
printer->Print(variables_,
|
||||||
|
"output.writeInt32($number$, this.$name$);\n");
|
||||||
|
} else {
|
||||||
|
if (params_.generate_has()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (this.$name$ != $default$ || has$capitalized_name$) {\n");
|
||||||
|
} else {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (this.$name$ != $default$) {\n");
|
||||||
|
}
|
||||||
|
printer->Print(variables_,
|
||||||
|
" output.writeInt32($number$, this.$name$);\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnumFieldGenerator::
|
||||||
|
GenerateSerializedSizeCode(io::Printer* printer) const {
|
||||||
|
if (descriptor_->is_required() && !params_.generate_has()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
|
||||||
|
" .computeInt32Size($number$, this.$name$);\n");
|
||||||
|
} else {
|
||||||
|
if (params_.generate_has()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (this.$name$ != $default$ || has$capitalized_name$) {\n");
|
||||||
|
} else {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (this.$name$ != $default$) {\n");
|
||||||
|
}
|
||||||
|
printer->Print(variables_,
|
||||||
|
" size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
|
||||||
|
" .computeInt32Size($number$, this.$name$);\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnumFieldGenerator::GenerateEqualsCode(io::Printer* printer) const {
|
||||||
|
if (params_.use_reference_types_for_primitives()
|
||||||
|
&& !params_.reftypes_primitive_enums()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (this.$name$ == null) {\n"
|
||||||
|
" if (other.$name$ != null) {\n"
|
||||||
|
" return false;\n"
|
||||||
|
" }\n"
|
||||||
|
"} else if (!this.$name$.equals(other.$name$)) {\n"
|
||||||
|
" return false;"
|
||||||
|
"}\n");
|
||||||
|
} else {
|
||||||
|
// We define equality as serialized form equality. If generate_has(),
|
||||||
|
// then if the field value equals the default value in both messages,
|
||||||
|
// but one's 'has' field is set and the other's is not, the serialized
|
||||||
|
// forms are different and we should return false.
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (this.$name$ != other.$name$");
|
||||||
|
if (params_.generate_has()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"\n"
|
||||||
|
" || (this.$name$ == $default$\n"
|
||||||
|
" && this.has$capitalized_name$ != other.has$capitalized_name$)");
|
||||||
|
}
|
||||||
|
printer->Print(") {\n"
|
||||||
|
" return false;\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnumFieldGenerator::GenerateHashCodeCode(io::Printer* printer) const {
|
||||||
|
printer->Print(
|
||||||
|
"result = 31 * result + ");
|
||||||
|
if (params_.use_reference_types_for_primitives()
|
||||||
|
&& !params_.reftypes_primitive_enums()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"(this.$name$ == null ? 0 : this.$name$)");
|
||||||
|
} else {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"this.$name$");
|
||||||
|
}
|
||||||
|
printer->Print(";\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===================================================================
|
||||||
|
|
||||||
|
AccessorEnumFieldGenerator::
|
||||||
|
AccessorEnumFieldGenerator(const FieldDescriptor* descriptor,
|
||||||
|
const Params& params, int has_bit_index)
|
||||||
|
: FieldGenerator(params), descriptor_(descriptor) {
|
||||||
|
SetEnumVariables(params, descriptor, &variables_);
|
||||||
|
LoadEnumValues(params, descriptor->enum_type(), &canonical_values_);
|
||||||
|
SetBitOperationVariables("has", has_bit_index, &variables_);
|
||||||
|
}
|
||||||
|
|
||||||
|
AccessorEnumFieldGenerator::~AccessorEnumFieldGenerator() {}
|
||||||
|
|
||||||
|
void AccessorEnumFieldGenerator::
|
||||||
|
GenerateMembers(io::Printer* printer, bool /* unused lazy_init */) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"private int $name$_;\n"
|
||||||
|
"public int get$capitalized_name$() {\n"
|
||||||
|
" return $name$_;\n"
|
||||||
|
"}\n"
|
||||||
|
"public $message_name$ set$capitalized_name$(int value) {\n"
|
||||||
|
" $name$_ = value;\n"
|
||||||
|
" $set_has$;\n"
|
||||||
|
" return this;\n"
|
||||||
|
"}\n"
|
||||||
|
"public boolean has$capitalized_name$() {\n"
|
||||||
|
" return $get_has$;\n"
|
||||||
|
"}\n"
|
||||||
|
"public $message_name$ clear$capitalized_name$() {\n"
|
||||||
|
" $name$_ = $default$;\n"
|
||||||
|
" $clear_has$;\n"
|
||||||
|
" return this;\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccessorEnumFieldGenerator::
|
||||||
|
GenerateClearCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"$name$_ = $default$;\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccessorEnumFieldGenerator::
|
||||||
|
GenerateMergingCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"int value = input.readInt32();\n"
|
||||||
|
"switch (value) {\n");
|
||||||
|
PrintCaseLabels(printer, canonical_values_);
|
||||||
|
printer->Print(variables_,
|
||||||
|
" $name$_ = value;\n"
|
||||||
|
" $set_has$;\n"
|
||||||
|
" break;\n"
|
||||||
|
"}\n");
|
||||||
|
// No default case: in case of invalid value from the wire, preserve old
|
||||||
|
// field value. Also we are not storing the invalid value into the unknown
|
||||||
|
// fields, because there is no way to get the value out.
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccessorEnumFieldGenerator::
|
||||||
|
GenerateSerializationCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if ($get_has$) {\n"
|
||||||
|
" output.writeInt32($number$, $name$_);\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccessorEnumFieldGenerator::
|
||||||
|
GenerateSerializedSizeCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if ($get_has$) {\n"
|
||||||
|
" size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
|
||||||
|
" .computeInt32Size($number$, $name$_);\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccessorEnumFieldGenerator::
|
||||||
|
GenerateEqualsCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if ($different_has$\n"
|
||||||
|
" || $name$_ != other.$name$_) {\n"
|
||||||
|
" return false;\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccessorEnumFieldGenerator::
|
||||||
|
GenerateHashCodeCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"result = 31 * result + $name$_;\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===================================================================
|
||||||
|
|
||||||
|
RepeatedEnumFieldGenerator::
|
||||||
|
RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
|
||||||
|
: FieldGenerator(params), descriptor_(descriptor) {
|
||||||
|
SetEnumVariables(params, descriptor, &variables_);
|
||||||
|
LoadEnumValues(params, descriptor->enum_type(), &canonical_values_);
|
||||||
|
}
|
||||||
|
|
||||||
|
RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {}
|
||||||
|
|
||||||
|
void RepeatedEnumFieldGenerator::
|
||||||
|
GenerateMembers(io::Printer* printer, bool /* unused lazy_init */) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"public $type$[] $name$;\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RepeatedEnumFieldGenerator::
|
||||||
|
GenerateClearCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"$name$ = $repeated_default$;\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RepeatedEnumFieldGenerator::
|
||||||
|
GenerateMergingCode(io::Printer* printer) const {
|
||||||
|
// First, figure out the maximum length of the array, then parse,
|
||||||
|
// and finally copy the valid values to the field.
|
||||||
|
printer->Print(variables_,
|
||||||
|
"int length = com.google.protobuf.nano.WireFormatNano\n"
|
||||||
|
" .getRepeatedFieldArrayLength(input, $non_packed_tag$);\n"
|
||||||
|
"int[] validValues = new int[length];\n"
|
||||||
|
"int validCount = 0;\n"
|
||||||
|
"for (int i = 0; i < length; i++) {\n"
|
||||||
|
" if (i != 0) { // tag for first value already consumed.\n"
|
||||||
|
" input.readTag();\n"
|
||||||
|
" }\n"
|
||||||
|
" int value = input.readInt32();\n"
|
||||||
|
" switch (value) {\n");
|
||||||
|
printer->Indent();
|
||||||
|
PrintCaseLabels(printer, canonical_values_);
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print(variables_,
|
||||||
|
" validValues[validCount++] = value;\n"
|
||||||
|
" break;\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
"if (validCount != 0) {\n"
|
||||||
|
" int i = this.$name$ == null ? 0 : this.$name$.length;\n"
|
||||||
|
" if (i == 0 && validCount == validValues.length) {\n"
|
||||||
|
" this.$name$ = validValues;\n"
|
||||||
|
" } else {\n"
|
||||||
|
" int[] newArray = new int[i + validCount];\n"
|
||||||
|
" if (i != 0) {\n"
|
||||||
|
" java.lang.System.arraycopy(this.$name$, 0, newArray, 0, i);\n"
|
||||||
|
" }\n"
|
||||||
|
" java.lang.System.arraycopy(validValues, 0, newArray, i, validCount);\n"
|
||||||
|
" this.$name$ = newArray;\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RepeatedEnumFieldGenerator::
|
||||||
|
GenerateMergingCodeFromPacked(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"int bytes = input.readRawVarint32();\n"
|
||||||
|
"int limit = input.pushLimit(bytes);\n"
|
||||||
|
"// First pass to compute array length.\n"
|
||||||
|
"int arrayLength = 0;\n"
|
||||||
|
"int startPos = input.getPosition();\n"
|
||||||
|
"while (input.getBytesUntilLimit() > 0) {\n"
|
||||||
|
" switch (input.readInt32()) {\n");
|
||||||
|
printer->Indent();
|
||||||
|
PrintCaseLabels(printer, canonical_values_);
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print(variables_,
|
||||||
|
" arrayLength++;\n"
|
||||||
|
" break;\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
"if (arrayLength != 0) {\n"
|
||||||
|
" input.rewindToPosition(startPos);\n"
|
||||||
|
" int i = this.$name$ == null ? 0 : this.$name$.length;\n"
|
||||||
|
" int[] newArray = new int[i + arrayLength];\n"
|
||||||
|
" if (i != 0) {\n"
|
||||||
|
" java.lang.System.arraycopy(this.$name$, 0, newArray, 0, i);\n"
|
||||||
|
" }\n"
|
||||||
|
" while (input.getBytesUntilLimit() > 0) {\n"
|
||||||
|
" int value = input.readInt32();\n"
|
||||||
|
" switch (value) {\n");
|
||||||
|
printer->Indent();
|
||||||
|
printer->Indent();
|
||||||
|
PrintCaseLabels(printer, canonical_values_);
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print(variables_,
|
||||||
|
" newArray[i++] = value;\n"
|
||||||
|
" break;\n"
|
||||||
|
" }\n"
|
||||||
|
" }\n"
|
||||||
|
" this.$name$ = newArray;\n"
|
||||||
|
"}\n"
|
||||||
|
"input.popLimit(limit);\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RepeatedEnumFieldGenerator::
|
||||||
|
GenerateRepeatedDataSizeCode(io::Printer* printer) const {
|
||||||
|
// Creates a variable dataSize and puts the serialized size in there.
|
||||||
|
printer->Print(variables_,
|
||||||
|
"int dataSize = 0;\n"
|
||||||
|
"for (int i = 0; i < this.$name$.length; i++) {\n"
|
||||||
|
" int element = this.$name$[i];\n"
|
||||||
|
" dataSize += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
|
||||||
|
" .computeInt32SizeNoTag(element);\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RepeatedEnumFieldGenerator::
|
||||||
|
GenerateSerializationCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (this.$name$ != null && this.$name$.length > 0) {\n");
|
||||||
|
printer->Indent();
|
||||||
|
|
||||||
|
if (descriptor_->options().packed()) {
|
||||||
|
GenerateRepeatedDataSizeCode(printer);
|
||||||
|
printer->Print(variables_,
|
||||||
|
"output.writeRawVarint32($tag$);\n"
|
||||||
|
"output.writeRawVarint32(dataSize);\n"
|
||||||
|
"for (int i = 0; i < this.$name$.length; i++) {\n"
|
||||||
|
" output.writeRawVarint32(this.$name$[i]);\n"
|
||||||
|
"}\n");
|
||||||
|
} else {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"for (int i = 0; i < this.$name$.length; i++) {\n"
|
||||||
|
" output.writeInt32($number$, this.$name$[i]);\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print(variables_,
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RepeatedEnumFieldGenerator::
|
||||||
|
GenerateSerializedSizeCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (this.$name$ != null && this.$name$.length > 0) {\n");
|
||||||
|
printer->Indent();
|
||||||
|
|
||||||
|
GenerateRepeatedDataSizeCode(printer);
|
||||||
|
|
||||||
|
printer->Print(
|
||||||
|
"size += dataSize;\n");
|
||||||
|
if (descriptor_->options().packed()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"size += $tag_size$;\n"
|
||||||
|
"size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
|
||||||
|
" .computeRawVarint32Size(dataSize);\n");
|
||||||
|
} else {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"size += $tag_size$ * this.$name$.length;\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printer->Outdent();
|
||||||
|
|
||||||
|
printer->Print(
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RepeatedEnumFieldGenerator::
|
||||||
|
GenerateEqualsCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (!com.google.protobuf.nano.InternalNano.equals(\n"
|
||||||
|
" this.$name$, other.$name$)) {\n"
|
||||||
|
" return false;\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RepeatedEnumFieldGenerator::
|
||||||
|
GenerateHashCodeCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"result = 31 * result\n"
|
||||||
|
" + com.google.protobuf.nano.InternalNano.hashCode(this.$name$);\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace javanano
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace protobuf
|
||||||
|
} // namespace google
|
125
src/google/protobuf/compiler/javanano/javanano_enum_field.h
Normal file
125
src/google/protobuf/compiler/javanano/javanano_enum_field.h
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: kenton@google.com (Kenton Varda)
|
||||||
|
// Based on original Protocol Buffers design by
|
||||||
|
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||||
|
|
||||||
|
#ifndef GOOGLE_PROTOBUF_COMPILER_JAVANANO_ENUM_FIELD_H__
|
||||||
|
#define GOOGLE_PROTOBUF_COMPILER_JAVANANO_ENUM_FIELD_H__
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_field.h>
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
namespace protobuf {
|
||||||
|
namespace compiler {
|
||||||
|
namespace javanano {
|
||||||
|
|
||||||
|
class EnumFieldGenerator : public FieldGenerator {
|
||||||
|
public:
|
||||||
|
explicit EnumFieldGenerator(
|
||||||
|
const FieldDescriptor* descriptor, const Params& params);
|
||||||
|
~EnumFieldGenerator();
|
||||||
|
|
||||||
|
// implements FieldGenerator ---------------------------------------
|
||||||
|
void GenerateMembers(io::Printer* printer, bool lazy_init) const;
|
||||||
|
void GenerateClearCode(io::Printer* printer) const;
|
||||||
|
void GenerateMergingCode(io::Printer* printer) const;
|
||||||
|
void GenerateSerializationCode(io::Printer* printer) const;
|
||||||
|
void GenerateSerializedSizeCode(io::Printer* printer) const;
|
||||||
|
void GenerateEqualsCode(io::Printer* printer) const;
|
||||||
|
void GenerateHashCodeCode(io::Printer* printer) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const FieldDescriptor* descriptor_;
|
||||||
|
map<string, string> variables_;
|
||||||
|
vector<string> canonical_values_;
|
||||||
|
|
||||||
|
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator);
|
||||||
|
};
|
||||||
|
|
||||||
|
class AccessorEnumFieldGenerator : public FieldGenerator {
|
||||||
|
public:
|
||||||
|
explicit AccessorEnumFieldGenerator(const FieldDescriptor* descriptor,
|
||||||
|
const Params& params, int has_bit_index);
|
||||||
|
~AccessorEnumFieldGenerator();
|
||||||
|
|
||||||
|
// implements FieldGenerator ---------------------------------------
|
||||||
|
void GenerateMembers(io::Printer* printer, bool lazy_init) const;
|
||||||
|
void GenerateClearCode(io::Printer* printer) const;
|
||||||
|
void GenerateMergingCode(io::Printer* printer) const;
|
||||||
|
void GenerateSerializationCode(io::Printer* printer) const;
|
||||||
|
void GenerateSerializedSizeCode(io::Printer* printer) const;
|
||||||
|
void GenerateEqualsCode(io::Printer* printer) const;
|
||||||
|
void GenerateHashCodeCode(io::Printer* printer) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const FieldDescriptor* descriptor_;
|
||||||
|
map<string, string> variables_;
|
||||||
|
vector<string> canonical_values_;
|
||||||
|
|
||||||
|
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(AccessorEnumFieldGenerator);
|
||||||
|
};
|
||||||
|
|
||||||
|
class RepeatedEnumFieldGenerator : public FieldGenerator {
|
||||||
|
public:
|
||||||
|
explicit RepeatedEnumFieldGenerator(
|
||||||
|
const FieldDescriptor* descriptor, const Params& params);
|
||||||
|
~RepeatedEnumFieldGenerator();
|
||||||
|
|
||||||
|
// implements FieldGenerator ---------------------------------------
|
||||||
|
void GenerateMembers(io::Printer* printer, bool lazy_init) const;
|
||||||
|
void GenerateClearCode(io::Printer* printer) const;
|
||||||
|
void GenerateMergingCode(io::Printer* printer) const;
|
||||||
|
void GenerateMergingCodeFromPacked(io::Printer* printer) const;
|
||||||
|
void GenerateSerializationCode(io::Printer* printer) const;
|
||||||
|
void GenerateSerializedSizeCode(io::Printer* printer) const;
|
||||||
|
void GenerateEqualsCode(io::Printer* printer) const;
|
||||||
|
void GenerateHashCodeCode(io::Printer* printer) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void GenerateRepeatedDataSizeCode(io::Printer* printer) const;
|
||||||
|
|
||||||
|
const FieldDescriptor* descriptor_;
|
||||||
|
map<string, string> variables_;
|
||||||
|
vector<string> canonical_values_;
|
||||||
|
|
||||||
|
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace javanano
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace protobuf
|
||||||
|
|
||||||
|
} // namespace google
|
||||||
|
#endif // GOOGLE_PROTOBUF_COMPILER_JAVANANO_ENUM_FIELD_H__
|
150
src/google/protobuf/compiler/javanano/javanano_extension.cc
Normal file
150
src/google/protobuf/compiler/javanano/javanano_extension.cc
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: bduff@google.com (Brian Duff)
|
||||||
|
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_extension.h>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_helpers.h>
|
||||||
|
#include <google/protobuf/io/printer.h>
|
||||||
|
#include <google/protobuf/stubs/strutil.h>
|
||||||
|
#include <google/protobuf/wire_format.h>
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
namespace protobuf {
|
||||||
|
namespace compiler {
|
||||||
|
namespace javanano {
|
||||||
|
|
||||||
|
using internal::WireFormat;
|
||||||
|
using internal::WireFormatLite;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const char* GetTypeConstantName(const FieldDescriptor::Type type) {
|
||||||
|
switch (type) {
|
||||||
|
case FieldDescriptor::TYPE_INT32 : return "TYPE_INT32" ;
|
||||||
|
case FieldDescriptor::TYPE_UINT32 : return "TYPE_UINT32" ;
|
||||||
|
case FieldDescriptor::TYPE_SINT32 : return "TYPE_SINT32" ;
|
||||||
|
case FieldDescriptor::TYPE_FIXED32 : return "TYPE_FIXED32" ;
|
||||||
|
case FieldDescriptor::TYPE_SFIXED32: return "TYPE_SFIXED32";
|
||||||
|
case FieldDescriptor::TYPE_INT64 : return "TYPE_INT64" ;
|
||||||
|
case FieldDescriptor::TYPE_UINT64 : return "TYPE_UINT64" ;
|
||||||
|
case FieldDescriptor::TYPE_SINT64 : return "TYPE_SINT64" ;
|
||||||
|
case FieldDescriptor::TYPE_FIXED64 : return "TYPE_FIXED64" ;
|
||||||
|
case FieldDescriptor::TYPE_SFIXED64: return "TYPE_SFIXED64";
|
||||||
|
case FieldDescriptor::TYPE_FLOAT : return "TYPE_FLOAT" ;
|
||||||
|
case FieldDescriptor::TYPE_DOUBLE : return "TYPE_DOUBLE" ;
|
||||||
|
case FieldDescriptor::TYPE_BOOL : return "TYPE_BOOL" ;
|
||||||
|
case FieldDescriptor::TYPE_STRING : return "TYPE_STRING" ;
|
||||||
|
case FieldDescriptor::TYPE_BYTES : return "TYPE_BYTES" ;
|
||||||
|
case FieldDescriptor::TYPE_ENUM : return "TYPE_ENUM" ;
|
||||||
|
case FieldDescriptor::TYPE_GROUP : return "TYPE_GROUP" ;
|
||||||
|
case FieldDescriptor::TYPE_MESSAGE : return "TYPE_MESSAGE" ;
|
||||||
|
|
||||||
|
// No default because we want the compiler to complain if any new
|
||||||
|
// types are added.
|
||||||
|
}
|
||||||
|
|
||||||
|
GOOGLE_LOG(FATAL) << "Can't get here.";
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void SetVariables(const FieldDescriptor* descriptor, const Params params,
|
||||||
|
map<string, string>* variables) {
|
||||||
|
(*variables)["extends"] = ClassName(params, descriptor->containing_type());
|
||||||
|
(*variables)["name"] = RenameJavaKeywords(UnderscoresToCamelCase(descriptor));
|
||||||
|
bool repeated = descriptor->is_repeated();
|
||||||
|
(*variables)["repeated"] = repeated ? "Repeated" : "";
|
||||||
|
(*variables)["type"] = GetTypeConstantName(descriptor->type());
|
||||||
|
JavaType java_type = GetJavaType(descriptor->type());
|
||||||
|
string tag = SimpleItoa(WireFormat::MakeTag(descriptor));
|
||||||
|
if (java_type == JAVATYPE_MESSAGE) {
|
||||||
|
(*variables)["ext_type"] = "MessageTyped";
|
||||||
|
string message_type = ClassName(params, descriptor->message_type());
|
||||||
|
if (repeated) {
|
||||||
|
message_type += "[]";
|
||||||
|
}
|
||||||
|
(*variables)["class"] = message_type;
|
||||||
|
// For message typed extensions, tags_params contains a single tag
|
||||||
|
// for both singular and repeated cases.
|
||||||
|
(*variables)["tag_params"] = tag;
|
||||||
|
} else {
|
||||||
|
(*variables)["ext_type"] = "PrimitiveTyped";
|
||||||
|
if (!repeated) {
|
||||||
|
(*variables)["class"] = BoxedPrimitiveTypeName(java_type);
|
||||||
|
(*variables)["tag_params"] = tag;
|
||||||
|
} else {
|
||||||
|
(*variables)["class"] = PrimitiveTypeName(java_type) + "[]";
|
||||||
|
if (!descriptor->is_packable()) {
|
||||||
|
// Non-packable: nonPackedTag == tag, packedTag == 0
|
||||||
|
(*variables)["tag_params"] = tag + ", " + tag + ", 0";
|
||||||
|
} else if (descriptor->options().packed()) {
|
||||||
|
// Packable and packed: tag == packedTag
|
||||||
|
string non_packed_tag = SimpleItoa(WireFormatLite::MakeTag(
|
||||||
|
descriptor->number(),
|
||||||
|
WireFormat::WireTypeForFieldType(descriptor->type())));
|
||||||
|
(*variables)["tag_params"] = tag + ", " + non_packed_tag + ", " + tag;
|
||||||
|
} else {
|
||||||
|
// Packable and not packed: tag == nonPackedTag
|
||||||
|
string packed_tag = SimpleItoa(WireFormatLite::MakeTag(
|
||||||
|
descriptor->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
|
||||||
|
(*variables)["tag_params"] = tag + ", " + tag + ", " + packed_tag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtensionGenerator::
|
||||||
|
ExtensionGenerator(const FieldDescriptor* descriptor, const Params& params)
|
||||||
|
: params_(params), descriptor_(descriptor) {
|
||||||
|
SetVariables(descriptor, params, &variables_);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtensionGenerator::~ExtensionGenerator() {}
|
||||||
|
|
||||||
|
void ExtensionGenerator::Generate(io::Printer* printer) const {
|
||||||
|
printer->Print("\n");
|
||||||
|
PrintFieldComment(printer, descriptor_);
|
||||||
|
printer->Print(variables_,
|
||||||
|
"public static final com.google.protobuf.nano.Extension<\n"
|
||||||
|
" $extends$,\n"
|
||||||
|
" $class$> $name$ =\n"
|
||||||
|
" com.google.protobuf.nano.Extension.create$repeated$$ext_type$(\n"
|
||||||
|
" com.google.protobuf.nano.Extension.$type$,\n"
|
||||||
|
" $class$.class,\n"
|
||||||
|
" $tag_params$);\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace javanano
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace protobuf
|
||||||
|
} // namespace google
|
||||||
|
|
74
src/google/protobuf/compiler/javanano/javanano_extension.h
Normal file
74
src/google/protobuf/compiler/javanano/javanano_extension.h
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: bduff@google.com (Brian Duff)
|
||||||
|
// Based on original Protocol Buffers design by
|
||||||
|
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||||
|
|
||||||
|
#ifndef GOOGLE_PROTOBUF_COMPILER_JAVANANO_EXTENSION_H_
|
||||||
|
#define GOOGLE_PROTOBUF_COMPILER_JAVANANO_EXTENSION_H_
|
||||||
|
|
||||||
|
#include <google/protobuf/stubs/common.h>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_params.h>
|
||||||
|
#include <google/protobuf/descriptor.pb.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
namespace protobuf {
|
||||||
|
namespace io {
|
||||||
|
class Printer; // printer.h
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace protobuf {
|
||||||
|
namespace compiler {
|
||||||
|
namespace javanano {
|
||||||
|
|
||||||
|
class ExtensionGenerator {
|
||||||
|
public:
|
||||||
|
explicit ExtensionGenerator(const FieldDescriptor* descriptor, const Params& params);
|
||||||
|
~ExtensionGenerator();
|
||||||
|
|
||||||
|
void Generate(io::Printer* printer) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Params& params_;
|
||||||
|
const FieldDescriptor* descriptor_;
|
||||||
|
map<string, string> variables_;
|
||||||
|
|
||||||
|
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace javanano
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace protobuf
|
||||||
|
} // namespace google
|
||||||
|
|
||||||
|
#endif // GOOGLE_PROTOBUF_COMPILER_JAVANANO_EXTENSION_H_
|
143
src/google/protobuf/compiler/javanano/javanano_field.cc
Normal file
143
src/google/protobuf/compiler/javanano/javanano_field.cc
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: kenton@google.com (Kenton Varda)
|
||||||
|
// Based on original Protocol Buffers design by
|
||||||
|
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||||
|
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_field.h>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_helpers.h>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_primitive_field.h>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_enum_field.h>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_message_field.h>
|
||||||
|
#include <google/protobuf/stubs/common.h>
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
namespace protobuf {
|
||||||
|
namespace compiler {
|
||||||
|
namespace javanano {
|
||||||
|
|
||||||
|
FieldGenerator::~FieldGenerator() {}
|
||||||
|
|
||||||
|
bool FieldGenerator::SavedDefaultNeeded() const {
|
||||||
|
// No saved default for this field by default.
|
||||||
|
// Subclasses whose instances may need saved defaults will override this
|
||||||
|
// and return the appropriate value.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FieldGenerator::GenerateInitSavedDefaultCode(io::Printer* printer) const {
|
||||||
|
// No saved default for this field by default.
|
||||||
|
// Subclasses whose instances may need saved defaults will override this
|
||||||
|
// and generate the appropriate init code to the printer.
|
||||||
|
}
|
||||||
|
|
||||||
|
void FieldGenerator::GenerateMergingCodeFromPacked(io::Printer* printer) const {
|
||||||
|
// Reaching here indicates a bug. Cases are:
|
||||||
|
// - This FieldGenerator should support packing, but this method should be
|
||||||
|
// overridden.
|
||||||
|
// - This FieldGenerator doesn't support packing, and this method should
|
||||||
|
// never have been called.
|
||||||
|
GOOGLE_LOG(FATAL) << "GenerateParsingCodeFromPacked() "
|
||||||
|
<< "called on field generator that does not support packing.";
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================
|
||||||
|
|
||||||
|
FieldGeneratorMap::FieldGeneratorMap(
|
||||||
|
const Descriptor* descriptor, const Params ¶ms)
|
||||||
|
: descriptor_(descriptor),
|
||||||
|
field_generators_(
|
||||||
|
new scoped_ptr<FieldGenerator>[descriptor->field_count()]) {
|
||||||
|
|
||||||
|
int next_has_bit_index = 0;
|
||||||
|
bool saved_defaults_needed = false;
|
||||||
|
// Construct all the FieldGenerators.
|
||||||
|
for (int i = 0; i < descriptor->field_count(); i++) {
|
||||||
|
FieldGenerator* field_generator = MakeGenerator(
|
||||||
|
descriptor->field(i), params, &next_has_bit_index);
|
||||||
|
saved_defaults_needed = saved_defaults_needed
|
||||||
|
|| field_generator->SavedDefaultNeeded();
|
||||||
|
field_generators_[i].reset(field_generator);
|
||||||
|
}
|
||||||
|
total_bits_ = next_has_bit_index;
|
||||||
|
saved_defaults_needed_ = saved_defaults_needed;
|
||||||
|
}
|
||||||
|
|
||||||
|
FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field,
|
||||||
|
const Params ¶ms, int* next_has_bit_index) {
|
||||||
|
JavaType java_type = GetJavaType(field);
|
||||||
|
if (field->is_repeated()) {
|
||||||
|
switch (java_type) {
|
||||||
|
case JAVATYPE_MESSAGE:
|
||||||
|
return new RepeatedMessageFieldGenerator(field, params);
|
||||||
|
case JAVATYPE_ENUM:
|
||||||
|
return new RepeatedEnumFieldGenerator(field, params);
|
||||||
|
default:
|
||||||
|
return new RepeatedPrimitiveFieldGenerator(field, params);
|
||||||
|
}
|
||||||
|
} else if (params.optional_field_accessors() && field->is_optional()
|
||||||
|
&& java_type != JAVATYPE_MESSAGE) {
|
||||||
|
// We need a has-bit for each primitive/enum field because their default
|
||||||
|
// values could be same as explicitly set values. But we don't need it
|
||||||
|
// for a message field because they have no defaults and Nano uses 'null'
|
||||||
|
// for unset messages, which cannot be set explicitly.
|
||||||
|
switch (java_type) {
|
||||||
|
case JAVATYPE_ENUM:
|
||||||
|
return new AccessorEnumFieldGenerator(
|
||||||
|
field, params, (*next_has_bit_index)++);
|
||||||
|
default:
|
||||||
|
return new AccessorPrimitiveFieldGenerator(
|
||||||
|
field, params, (*next_has_bit_index)++);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (java_type) {
|
||||||
|
case JAVATYPE_MESSAGE:
|
||||||
|
return new MessageFieldGenerator(field, params);
|
||||||
|
case JAVATYPE_ENUM:
|
||||||
|
return new EnumFieldGenerator(field, params);
|
||||||
|
default:
|
||||||
|
return new PrimitiveFieldGenerator(field, params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FieldGeneratorMap::~FieldGeneratorMap() {}
|
||||||
|
|
||||||
|
const FieldGenerator& FieldGeneratorMap::get(
|
||||||
|
const FieldDescriptor* field) const {
|
||||||
|
GOOGLE_CHECK_EQ(field->containing_type(), descriptor_);
|
||||||
|
return *field_generators_[field->index()];
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace javanano
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace protobuf
|
||||||
|
} // namespace google
|
119
src/google/protobuf/compiler/javanano/javanano_field.h
Normal file
119
src/google/protobuf/compiler/javanano/javanano_field.h
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: kenton@google.com (Kenton Varda)
|
||||||
|
// Based on original Protocol Buffers design by
|
||||||
|
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||||
|
|
||||||
|
#ifndef GOOGLE_PROTOBUF_COMPILER_JAVANANO_FIELD_H__
|
||||||
|
#define GOOGLE_PROTOBUF_COMPILER_JAVANANO_FIELD_H__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <google/protobuf/stubs/common.h>
|
||||||
|
#include <google/protobuf/descriptor.h>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_params.h>
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
namespace protobuf {
|
||||||
|
namespace io {
|
||||||
|
class Printer; // printer.h
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace protobuf {
|
||||||
|
namespace compiler {
|
||||||
|
namespace javanano {
|
||||||
|
|
||||||
|
class FieldGenerator {
|
||||||
|
public:
|
||||||
|
FieldGenerator(const Params& params) : params_(params) {}
|
||||||
|
virtual ~FieldGenerator();
|
||||||
|
|
||||||
|
virtual bool SavedDefaultNeeded() const;
|
||||||
|
virtual void GenerateInitSavedDefaultCode(io::Printer* printer) const;
|
||||||
|
|
||||||
|
// Generates code for Java fields and methods supporting this field.
|
||||||
|
// If this field needs a saved default (SavedDefaultNeeded() is true),
|
||||||
|
// then @lazy_init controls how the static field for that default value
|
||||||
|
// and its initialization code should be generated. If @lazy_init is
|
||||||
|
// true, the static field is not declared final and the initialization
|
||||||
|
// code is generated only when GenerateInitSavedDefaultCode is called;
|
||||||
|
// otherwise, the static field is declared final and initialized inline.
|
||||||
|
// GenerateInitSavedDefaultCode will not be called in the latter case.
|
||||||
|
virtual void GenerateMembers(
|
||||||
|
io::Printer* printer, bool lazy_init) const = 0;
|
||||||
|
|
||||||
|
virtual void GenerateClearCode(io::Printer* printer) const = 0;
|
||||||
|
virtual void GenerateMergingCode(io::Printer* printer) const = 0;
|
||||||
|
|
||||||
|
// Generates code to merge from packed serialized form. The default
|
||||||
|
// implementation will fail; subclasses which can handle packed serialized
|
||||||
|
// forms will override this and print appropriate code to the printer.
|
||||||
|
virtual void GenerateMergingCodeFromPacked(io::Printer* printer) const;
|
||||||
|
|
||||||
|
virtual void GenerateSerializationCode(io::Printer* printer) const = 0;
|
||||||
|
virtual void GenerateSerializedSizeCode(io::Printer* printer) const = 0;
|
||||||
|
virtual void GenerateEqualsCode(io::Printer* printer) const = 0;
|
||||||
|
virtual void GenerateHashCodeCode(io::Printer* printer) const = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const Params& params_;
|
||||||
|
private:
|
||||||
|
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGenerator);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Convenience class which constructs FieldGenerators for a Descriptor.
|
||||||
|
class FieldGeneratorMap {
|
||||||
|
public:
|
||||||
|
explicit FieldGeneratorMap(const Descriptor* descriptor, const Params ¶ms);
|
||||||
|
~FieldGeneratorMap();
|
||||||
|
|
||||||
|
const FieldGenerator& get(const FieldDescriptor* field) const;
|
||||||
|
int total_bits() const { return total_bits_; }
|
||||||
|
bool saved_defaults_needed() const { return saved_defaults_needed_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Descriptor* descriptor_;
|
||||||
|
scoped_array<scoped_ptr<FieldGenerator> > field_generators_;
|
||||||
|
int total_bits_;
|
||||||
|
bool saved_defaults_needed_;
|
||||||
|
|
||||||
|
static FieldGenerator* MakeGenerator(const FieldDescriptor* field,
|
||||||
|
const Params ¶ms, int* next_has_bit_index);
|
||||||
|
|
||||||
|
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace javanano
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace protobuf
|
||||||
|
|
||||||
|
} // namespace google
|
||||||
|
#endif // GOOGLE_PROTOBUF_COMPILER_JAVANANO_FIELD_H__
|
263
src/google/protobuf/compiler/javanano/javanano_file.cc
Normal file
263
src/google/protobuf/compiler/javanano/javanano_file.cc
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: kenton@google.com (Kenton Varda)
|
||||||
|
// Based on original Protocol Buffers design by
|
||||||
|
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_file.h>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_enum.h>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_extension.h>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_helpers.h>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_message.h>
|
||||||
|
#include <google/protobuf/compiler/code_generator.h>
|
||||||
|
#include <google/protobuf/io/printer.h>
|
||||||
|
#include <google/protobuf/io/zero_copy_stream.h>
|
||||||
|
#include <google/protobuf/descriptor.pb.h>
|
||||||
|
#include <google/protobuf/stubs/strutil.h>
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
namespace protobuf {
|
||||||
|
namespace compiler {
|
||||||
|
namespace javanano {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Recursively searches the given message to see if it contains any extensions.
|
||||||
|
bool UsesExtensions(const Message& message) {
|
||||||
|
const Reflection* reflection = message.GetReflection();
|
||||||
|
|
||||||
|
// We conservatively assume that unknown fields are extensions.
|
||||||
|
if (reflection->GetUnknownFields(message).field_count() > 0) return true;
|
||||||
|
|
||||||
|
vector<const FieldDescriptor*> fields;
|
||||||
|
reflection->ListFields(message, &fields);
|
||||||
|
|
||||||
|
for (int i = 0; i < fields.size(); i++) {
|
||||||
|
if (fields[i]->is_extension()) return true;
|
||||||
|
|
||||||
|
if (fields[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
|
||||||
|
if (fields[i]->is_repeated()) {
|
||||||
|
int size = reflection->FieldSize(message, fields[i]);
|
||||||
|
for (int j = 0; j < size; j++) {
|
||||||
|
const Message& sub_message =
|
||||||
|
reflection->GetRepeatedMessage(message, fields[i], j);
|
||||||
|
if (UsesExtensions(sub_message)) return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const Message& sub_message = reflection->GetMessage(message, fields[i]);
|
||||||
|
if (UsesExtensions(sub_message)) return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
FileGenerator::FileGenerator(const FileDescriptor* file, const Params& params)
|
||||||
|
: file_(file),
|
||||||
|
params_(params),
|
||||||
|
java_package_(FileJavaPackage(params, file)),
|
||||||
|
classname_(FileClassName(params, file)) {}
|
||||||
|
|
||||||
|
FileGenerator::~FileGenerator() {}
|
||||||
|
|
||||||
|
bool FileGenerator::Validate(string* error) {
|
||||||
|
// Check for extensions
|
||||||
|
FileDescriptorProto file_proto;
|
||||||
|
file_->CopyTo(&file_proto);
|
||||||
|
if (UsesExtensions(file_proto) && !params_.store_unknown_fields()) {
|
||||||
|
error->assign(file_->name());
|
||||||
|
error->append(
|
||||||
|
": Java NANO_RUNTIME only supports extensions when the "
|
||||||
|
"'store_unknown_fields' generator option is 'true'.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file_->service_count() != 0 && !params_.ignore_services()) {
|
||||||
|
error->assign(file_->name());
|
||||||
|
error->append(
|
||||||
|
": Java NANO_RUNTIME does not support services\"");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsOuterClassNeeded(params_, file_)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check whether legacy javanano generator would omit the outer class.
|
||||||
|
if (!params_.has_java_outer_classname(file_->name())
|
||||||
|
&& file_->message_type_count() == 1
|
||||||
|
&& file_->enum_type_count() == 0 && file_->extension_count() == 0) {
|
||||||
|
cout << "INFO: " << file_->name() << ":" << endl;
|
||||||
|
cout << "Javanano generator has changed to align with java generator. "
|
||||||
|
"An outer class will be created for this file and the single message "
|
||||||
|
"in the file will become a nested class. Use java_multiple_files to "
|
||||||
|
"skip generating the outer class, or set an explicit "
|
||||||
|
"java_outer_classname to suppress this message." << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that no class name matches the file's class name. This is a common
|
||||||
|
// problem that leads to Java compile errors that can be hard to understand.
|
||||||
|
// It's especially bad when using the java_multiple_files, since we would
|
||||||
|
// end up overwriting the outer class with one of the inner ones.
|
||||||
|
bool found_conflict = false;
|
||||||
|
for (int i = 0; !found_conflict && i < file_->message_type_count(); i++) {
|
||||||
|
if (file_->message_type(i)->name() == classname_) {
|
||||||
|
found_conflict = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (params_.java_enum_style()) {
|
||||||
|
for (int i = 0; !found_conflict && i < file_->enum_type_count(); i++) {
|
||||||
|
if (file_->enum_type(i)->name() == classname_) {
|
||||||
|
found_conflict = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found_conflict) {
|
||||||
|
error->assign(file_->name());
|
||||||
|
error->append(
|
||||||
|
": Cannot generate Java output because the file's outer class name, \"");
|
||||||
|
error->append(classname_);
|
||||||
|
error->append(
|
||||||
|
"\", matches the name of one of the types declared inside it. "
|
||||||
|
"Please either rename the type or use the java_outer_classname "
|
||||||
|
"option to specify a different outer class name for the .proto file.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileGenerator::Generate(io::Printer* printer) {
|
||||||
|
// We don't import anything because we refer to all classes by their
|
||||||
|
// fully-qualified names in the generated source.
|
||||||
|
printer->Print(
|
||||||
|
"// Generated by the protocol buffer compiler. DO NOT EDIT!\n");
|
||||||
|
if (!java_package_.empty()) {
|
||||||
|
printer->Print(
|
||||||
|
"\n"
|
||||||
|
"package $package$;\n",
|
||||||
|
"package", java_package_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: constants (from enums, emitted in the loop below) may have the same names as constants
|
||||||
|
// in the nested classes. This causes Java warnings, but is not fatal, so we suppress those
|
||||||
|
// warnings here in the top-most class declaration.
|
||||||
|
printer->Print(
|
||||||
|
"\n"
|
||||||
|
"@SuppressWarnings(\"hiding\")\n"
|
||||||
|
"public interface $classname$ {\n",
|
||||||
|
"classname", classname_);
|
||||||
|
printer->Indent();
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
|
||||||
|
// Extensions.
|
||||||
|
for (int i = 0; i < file_->extension_count(); i++) {
|
||||||
|
ExtensionGenerator(file_->extension(i), params_).Generate(printer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enums.
|
||||||
|
for (int i = 0; i < file_->enum_type_count(); i++) {
|
||||||
|
EnumGenerator(file_->enum_type(i), params_).Generate(printer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Messages.
|
||||||
|
if (!params_.java_multiple_files(file_->name())) {
|
||||||
|
for (int i = 0; i < file_->message_type_count(); i++) {
|
||||||
|
MessageGenerator(file_->message_type(i), params_).Generate(printer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Static variables.
|
||||||
|
for (int i = 0; i < file_->message_type_count(); i++) {
|
||||||
|
// TODO(kenton): Reuse MessageGenerator objects?
|
||||||
|
MessageGenerator(file_->message_type(i), params_).GenerateStaticVariables(printer);
|
||||||
|
}
|
||||||
|
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print(
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename GeneratorClass, typename DescriptorClass>
|
||||||
|
static void GenerateSibling(const string& package_dir,
|
||||||
|
const string& java_package,
|
||||||
|
const DescriptorClass* descriptor,
|
||||||
|
GeneratorContext* output_directory,
|
||||||
|
vector<string>* file_list,
|
||||||
|
const Params& params) {
|
||||||
|
string filename = package_dir + descriptor->name() + ".java";
|
||||||
|
file_list->push_back(filename);
|
||||||
|
|
||||||
|
scoped_ptr<io::ZeroCopyOutputStream> output(
|
||||||
|
output_directory->Open(filename));
|
||||||
|
io::Printer printer(output.get(), '$');
|
||||||
|
|
||||||
|
printer.Print(
|
||||||
|
"// Generated by the protocol buffer compiler. DO NOT EDIT!\n");
|
||||||
|
if (!java_package.empty()) {
|
||||||
|
printer.Print(
|
||||||
|
"\n"
|
||||||
|
"package $package$;\n",
|
||||||
|
"package", java_package);
|
||||||
|
}
|
||||||
|
|
||||||
|
GeneratorClass(descriptor, params).Generate(&printer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileGenerator::GenerateSiblings(const string& package_dir,
|
||||||
|
GeneratorContext* output_directory,
|
||||||
|
vector<string>* file_list) {
|
||||||
|
if (params_.java_multiple_files(file_->name())) {
|
||||||
|
for (int i = 0; i < file_->message_type_count(); i++) {
|
||||||
|
GenerateSibling<MessageGenerator>(package_dir, java_package_,
|
||||||
|
file_->message_type(i),
|
||||||
|
output_directory, file_list, params_);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params_.java_enum_style()) {
|
||||||
|
for (int i = 0; i < file_->enum_type_count(); i++) {
|
||||||
|
GenerateSibling<EnumGenerator>(package_dir, java_package_,
|
||||||
|
file_->enum_type(i),
|
||||||
|
output_directory, file_list, params_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace javanano
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace protobuf
|
||||||
|
} // namespace google
|
94
src/google/protobuf/compiler/javanano/javanano_file.h
Normal file
94
src/google/protobuf/compiler/javanano/javanano_file.h
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: kenton@google.com (Kenton Varda)
|
||||||
|
// Based on original Protocol Buffers design by
|
||||||
|
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||||
|
|
||||||
|
#ifndef GOOGLE_PROTOBUF_COMPILER_JAVANANO_FILE_H__
|
||||||
|
#define GOOGLE_PROTOBUF_COMPILER_JAVANANO_FILE_H__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <google/protobuf/stubs/common.h>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_params.h>
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
namespace protobuf {
|
||||||
|
class FileDescriptor; // descriptor.h
|
||||||
|
namespace io {
|
||||||
|
class Printer; // printer.h
|
||||||
|
}
|
||||||
|
namespace compiler {
|
||||||
|
class GeneratorContext; // code_generator.h
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace protobuf {
|
||||||
|
namespace compiler {
|
||||||
|
namespace javanano {
|
||||||
|
|
||||||
|
class FileGenerator {
|
||||||
|
public:
|
||||||
|
explicit FileGenerator(const FileDescriptor* file, const Params& params);
|
||||||
|
~FileGenerator();
|
||||||
|
|
||||||
|
// Checks for problems that would otherwise lead to cryptic compile errors.
|
||||||
|
// Returns true if there are no problems, or writes an error description to
|
||||||
|
// the given string and returns false otherwise.
|
||||||
|
bool Validate(string* error);
|
||||||
|
|
||||||
|
void Generate(io::Printer* printer);
|
||||||
|
|
||||||
|
// If we aren't putting everything into one file, this will write all the
|
||||||
|
// files other than the outer file (i.e. one for each message, enum, and
|
||||||
|
// service type).
|
||||||
|
void GenerateSiblings(const string& package_dir,
|
||||||
|
GeneratorContext* output_directory,
|
||||||
|
vector<string>* file_list);
|
||||||
|
|
||||||
|
const string& java_package() { return java_package_; }
|
||||||
|
const string& classname() { return classname_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const FileDescriptor* file_;
|
||||||
|
const Params& params_;
|
||||||
|
string java_package_;
|
||||||
|
string classname_;
|
||||||
|
|
||||||
|
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace javanano
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace protobuf
|
||||||
|
|
||||||
|
} // namespace google
|
||||||
|
#endif // GOOGLE_PROTOBUF_COMPILER_JAVANANO_FILE_H__
|
219
src/google/protobuf/compiler/javanano/javanano_generator.cc
Normal file
219
src/google/protobuf/compiler/javanano/javanano_generator.cc
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: kenton@google.com (Kenton Varda)
|
||||||
|
// Based on original Protocol Buffers design by
|
||||||
|
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||||
|
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_params.h>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_generator.h>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_file.h>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_helpers.h>
|
||||||
|
#include <google/protobuf/io/printer.h>
|
||||||
|
#include <google/protobuf/io/zero_copy_stream.h>
|
||||||
|
#include <google/protobuf/descriptor.pb.h>
|
||||||
|
#include <google/protobuf/stubs/strutil.h>
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
namespace protobuf {
|
||||||
|
namespace compiler {
|
||||||
|
namespace javanano {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
string TrimString(const string& s) {
|
||||||
|
string::size_type start = s.find_first_not_of(" \n\r\t");
|
||||||
|
if (start == string::npos) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
string::size_type end = s.find_last_not_of(" \n\r\t") + 1;
|
||||||
|
return s.substr(start, end - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void UpdateParamsRecursively(Params& params,
|
||||||
|
const FileDescriptor* file) {
|
||||||
|
// Add any parameters for this file
|
||||||
|
if (file->options().has_java_outer_classname()) {
|
||||||
|
params.set_java_outer_classname(
|
||||||
|
file->name(), file->options().java_outer_classname());
|
||||||
|
}
|
||||||
|
if (file->options().has_java_package()) {
|
||||||
|
params.set_java_package(
|
||||||
|
file->name(), file->options().java_package());
|
||||||
|
}
|
||||||
|
if (file->options().has_java_multiple_files()) {
|
||||||
|
params.set_java_multiple_files(
|
||||||
|
file->name(), file->options().java_multiple_files());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop through all dependent files recursively
|
||||||
|
// adding dep
|
||||||
|
for (int i = 0; i < file->dependency_count(); i++) {
|
||||||
|
UpdateParamsRecursively(params, file->dependency(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JavaNanoGenerator::JavaNanoGenerator() {}
|
||||||
|
JavaNanoGenerator::~JavaNanoGenerator() {}
|
||||||
|
|
||||||
|
bool JavaNanoGenerator::Generate(const FileDescriptor* file,
|
||||||
|
const string& parameter,
|
||||||
|
GeneratorContext* output_directory,
|
||||||
|
string* error) const {
|
||||||
|
vector<pair<string, string> > options;
|
||||||
|
|
||||||
|
ParseGeneratorParameter(parameter, &options);
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
// parse generator options
|
||||||
|
|
||||||
|
// Name a file where we will write a list of generated file names, one
|
||||||
|
// per line.
|
||||||
|
string output_list_file;
|
||||||
|
Params params(file->name());
|
||||||
|
|
||||||
|
// Update per file params
|
||||||
|
UpdateParamsRecursively(params, file);
|
||||||
|
|
||||||
|
// Replace any existing options with ones from command line
|
||||||
|
for (int i = 0; i < options.size(); i++) {
|
||||||
|
string option_name = TrimString(options[i].first);
|
||||||
|
string option_value = TrimString(options[i].second);
|
||||||
|
if (option_name == "output_list_file") {
|
||||||
|
output_list_file = option_value;
|
||||||
|
} else if (option_name == "java_package") {
|
||||||
|
vector<string> parts;
|
||||||
|
SplitStringUsing(option_value, "|", &parts);
|
||||||
|
if (parts.size() != 2) {
|
||||||
|
*error = "Bad java_package, expecting filename|PackageName found '"
|
||||||
|
+ option_value + "'";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
params.set_java_package(parts[0], parts[1]);
|
||||||
|
} else if (option_name == "java_outer_classname") {
|
||||||
|
vector<string> parts;
|
||||||
|
SplitStringUsing(option_value, "|", &parts);
|
||||||
|
if (parts.size() != 2) {
|
||||||
|
*error = "Bad java_outer_classname, "
|
||||||
|
"expecting filename|ClassName found '"
|
||||||
|
+ option_value + "'";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
params.set_java_outer_classname(parts[0], parts[1]);
|
||||||
|
} else if (option_name == "store_unknown_fields") {
|
||||||
|
params.set_store_unknown_fields(option_value == "true");
|
||||||
|
} else if (option_name == "java_multiple_files") {
|
||||||
|
params.set_override_java_multiple_files(option_value == "true");
|
||||||
|
} else if (option_name == "java_nano_generate_has") {
|
||||||
|
params.set_generate_has(option_value == "true");
|
||||||
|
} else if (option_name == "enum_style") {
|
||||||
|
params.set_java_enum_style(option_value == "java");
|
||||||
|
} else if (option_name == "optional_field_style") {
|
||||||
|
params.set_optional_field_accessors(option_value == "accessors");
|
||||||
|
params.set_use_reference_types_for_primitives(option_value == "reftypes"
|
||||||
|
|| option_value == "reftypes_compat_mode");
|
||||||
|
params.set_reftypes_primitive_enums(
|
||||||
|
option_value == "reftypes_compat_mode");
|
||||||
|
if (option_value == "reftypes_compat_mode") {
|
||||||
|
params.set_generate_clear(false);
|
||||||
|
}
|
||||||
|
} else if (option_name == "generate_equals") {
|
||||||
|
params.set_generate_equals(option_value == "true");
|
||||||
|
} else if (option_name == "ignore_services") {
|
||||||
|
params.set_ignore_services(option_value == "true");
|
||||||
|
} else if (option_name == "parcelable_messages") {
|
||||||
|
params.set_parcelable_messages(option_value == "true");
|
||||||
|
} else {
|
||||||
|
*error = "Ignore unknown javanano generator option: " + option_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check illegal parameter combinations
|
||||||
|
// Note: the enum-like optional_field_style generator param ensures
|
||||||
|
// that we can never have illegal combinations of field styles
|
||||||
|
// (e.g. reftypes and accessors can't be on at the same time).
|
||||||
|
if (params.generate_has()
|
||||||
|
&& (params.optional_field_accessors()
|
||||||
|
|| params.use_reference_types_for_primitives())) {
|
||||||
|
error->assign("java_nano_generate_has=true cannot be used in conjunction"
|
||||||
|
" with optional_field_style=accessors or optional_field_style=reftypes");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
|
||||||
|
FileGenerator file_generator(file, params);
|
||||||
|
if (!file_generator.Validate(error)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
string package_dir =
|
||||||
|
StringReplace(file_generator.java_package(), ".", "/", true);
|
||||||
|
if (!package_dir.empty()) package_dir += "/";
|
||||||
|
|
||||||
|
vector<string> all_files;
|
||||||
|
|
||||||
|
if (IsOuterClassNeeded(params, file)) {
|
||||||
|
string java_filename = package_dir;
|
||||||
|
java_filename += file_generator.classname();
|
||||||
|
java_filename += ".java";
|
||||||
|
all_files.push_back(java_filename);
|
||||||
|
|
||||||
|
// Generate main java file.
|
||||||
|
scoped_ptr<io::ZeroCopyOutputStream> output(
|
||||||
|
output_directory->Open(java_filename));
|
||||||
|
io::Printer printer(output.get(), '$');
|
||||||
|
file_generator.Generate(&printer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate sibling files.
|
||||||
|
file_generator.GenerateSiblings(package_dir, output_directory, &all_files);
|
||||||
|
|
||||||
|
// Generate output list if requested.
|
||||||
|
if (!output_list_file.empty()) {
|
||||||
|
// Generate output list. This is just a simple text file placed in a
|
||||||
|
// deterministic location which lists the .java files being generated.
|
||||||
|
scoped_ptr<io::ZeroCopyOutputStream> srclist_raw_output(
|
||||||
|
output_directory->Open(output_list_file));
|
||||||
|
io::Printer srclist_printer(srclist_raw_output.get(), '$');
|
||||||
|
for (int i = 0; i < all_files.size(); i++) {
|
||||||
|
srclist_printer.Print("$filename$\n", "filename", all_files[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace java
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace protobuf
|
||||||
|
} // namespace google
|
72
src/google/protobuf/compiler/javanano/javanano_generator.h
Normal file
72
src/google/protobuf/compiler/javanano/javanano_generator.h
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: kenton@google.com (Kenton Varda)
|
||||||
|
// Based on original Protocol Buffers design by
|
||||||
|
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||||
|
//
|
||||||
|
// Generates Java nano code for a given .proto file.
|
||||||
|
|
||||||
|
#ifndef GOOGLE_PROTOBUF_COMPILER_JAVANANO_NANO_GENERATOR_H__
|
||||||
|
#define GOOGLE_PROTOBUF_COMPILER_JAVANANO_NANO_GENERATOR_H__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <google/protobuf/compiler/code_generator.h>
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
namespace protobuf {
|
||||||
|
namespace compiler {
|
||||||
|
namespace javanano {
|
||||||
|
|
||||||
|
// CodeGenerator implementation which generates Java nano code. If you create your
|
||||||
|
// own protocol compiler binary and you want it to support Java output for the
|
||||||
|
// nano runtime, you can do so by registering an instance of this CodeGenerator with
|
||||||
|
// the CommandLineInterface in your main() function.
|
||||||
|
class LIBPROTOC_EXPORT JavaNanoGenerator : public CodeGenerator {
|
||||||
|
public:
|
||||||
|
JavaNanoGenerator();
|
||||||
|
~JavaNanoGenerator();
|
||||||
|
|
||||||
|
// implements CodeGenerator ----------------------------------------
|
||||||
|
bool Generate(const FileDescriptor* file,
|
||||||
|
const string& parameter,
|
||||||
|
GeneratorContext* output_directory,
|
||||||
|
string* error) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(JavaNanoGenerator);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace javanano
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace protobuf
|
||||||
|
|
||||||
|
} // namespace google
|
||||||
|
#endif // GOOGLE_PROTOBUF_COMPILER_JAVANANO_NANO_GENERATOR_H__
|
566
src/google/protobuf/compiler/javanano/javanano_helpers.cc
Normal file
566
src/google/protobuf/compiler/javanano/javanano_helpers.cc
Normal file
@ -0,0 +1,566 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: kenton@google.com (Kenton Varda)
|
||||||
|
// Based on original Protocol Buffers design by
|
||||||
|
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_helpers.h>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_params.h>
|
||||||
|
#include <google/protobuf/descriptor.pb.h>
|
||||||
|
#include <google/protobuf/stubs/hash.h>
|
||||||
|
#include <google/protobuf/stubs/strutil.h>
|
||||||
|
#include <google/protobuf/stubs/substitute.h>
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
namespace protobuf {
|
||||||
|
namespace compiler {
|
||||||
|
namespace javanano {
|
||||||
|
|
||||||
|
const char kThickSeparator[] =
|
||||||
|
"// ===================================================================\n";
|
||||||
|
const char kThinSeparator[] =
|
||||||
|
"// -------------------------------------------------------------------\n";
|
||||||
|
|
||||||
|
class RenameKeywords {
|
||||||
|
private:
|
||||||
|
hash_set<string> java_keywords_set_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RenameKeywords() {
|
||||||
|
static const char* kJavaKeywordsList[] = {
|
||||||
|
// Reserved Java Keywords
|
||||||
|
"abstract", "assert", "boolean", "break", "byte", "case", "catch",
|
||||||
|
"char", "class", "const", "continue", "default", "do", "double", "else",
|
||||||
|
"enum", "extends", "final", "finally", "float", "for", "goto", "if",
|
||||||
|
"implements", "import", "instanceof", "int", "interface", "long",
|
||||||
|
"native", "new", "package", "private", "protected", "public", "return",
|
||||||
|
"short", "static", "strictfp", "super", "switch", "synchronized",
|
||||||
|
"this", "throw", "throws", "transient", "try", "void", "volatile", "while",
|
||||||
|
|
||||||
|
// Reserved Keywords for Literals
|
||||||
|
"false", "null", "true"
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < GOOGLE_ARRAYSIZE(kJavaKeywordsList); i++) {
|
||||||
|
java_keywords_set_.insert(kJavaKeywordsList[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used to rename the a field name if it's a java keyword. Specifically
|
||||||
|
// this is used to rename the ["name"] or ["capitalized_name"] field params.
|
||||||
|
// (http://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html)
|
||||||
|
string RenameJavaKeywordsImpl(const string& input) {
|
||||||
|
string result = input;
|
||||||
|
|
||||||
|
if (java_keywords_set_.find(result) != java_keywords_set_.end()) {
|
||||||
|
result += "_";
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
static RenameKeywords sRenameKeywords;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const char* kDefaultPackage = "";
|
||||||
|
|
||||||
|
const string& FieldName(const FieldDescriptor* field) {
|
||||||
|
// Groups are hacky: The name of the field is just the lower-cased name
|
||||||
|
// of the group type. In Java, though, we would like to retain the original
|
||||||
|
// capitalization of the type name.
|
||||||
|
if (field->type() == FieldDescriptor::TYPE_GROUP) {
|
||||||
|
return field->message_type()->name();
|
||||||
|
} else {
|
||||||
|
return field->name();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string UnderscoresToCamelCaseImpl(const string& input, bool cap_next_letter) {
|
||||||
|
string result;
|
||||||
|
// Note: I distrust ctype.h due to locales.
|
||||||
|
for (int i = 0; i < input.size(); i++) {
|
||||||
|
if ('a' <= input[i] && input[i] <= 'z') {
|
||||||
|
if (cap_next_letter) {
|
||||||
|
result += input[i] + ('A' - 'a');
|
||||||
|
} else {
|
||||||
|
result += input[i];
|
||||||
|
}
|
||||||
|
cap_next_letter = false;
|
||||||
|
} else if ('A' <= input[i] && input[i] <= 'Z') {
|
||||||
|
if (i == 0 && !cap_next_letter) {
|
||||||
|
// Force first letter to lower-case unless explicitly told to
|
||||||
|
// capitalize it.
|
||||||
|
result += input[i] + ('a' - 'A');
|
||||||
|
} else {
|
||||||
|
// Capital letters after the first are left as-is.
|
||||||
|
result += input[i];
|
||||||
|
}
|
||||||
|
cap_next_letter = false;
|
||||||
|
} else if ('0' <= input[i] && input[i] <= '9') {
|
||||||
|
result += input[i];
|
||||||
|
cap_next_letter = true;
|
||||||
|
} else {
|
||||||
|
cap_next_letter = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
string UnderscoresToCamelCase(const FieldDescriptor* field) {
|
||||||
|
return UnderscoresToCamelCaseImpl(FieldName(field), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field) {
|
||||||
|
return UnderscoresToCamelCaseImpl(FieldName(field), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
string UnderscoresToCamelCase(const MethodDescriptor* method) {
|
||||||
|
return UnderscoresToCamelCaseImpl(method->name(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
string RenameJavaKeywords(const string& input) {
|
||||||
|
return sRenameKeywords.RenameJavaKeywordsImpl(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
string StripProto(const string& filename) {
|
||||||
|
if (HasSuffixString(filename, ".protodevel")) {
|
||||||
|
return StripSuffixString(filename, ".protodevel");
|
||||||
|
} else {
|
||||||
|
return StripSuffixString(filename, ".proto");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string FileClassName(const Params& params, const FileDescriptor* file) {
|
||||||
|
if (params.has_java_outer_classname(file->name())) {
|
||||||
|
return params.java_outer_classname(file->name());
|
||||||
|
} else {
|
||||||
|
// Use the filename itself with underscores removed
|
||||||
|
// and a CamelCase style name.
|
||||||
|
string basename;
|
||||||
|
string::size_type last_slash = file->name().find_last_of('/');
|
||||||
|
if (last_slash == string::npos) {
|
||||||
|
basename = file->name();
|
||||||
|
} else {
|
||||||
|
basename = file->name().substr(last_slash + 1);
|
||||||
|
}
|
||||||
|
return UnderscoresToCamelCaseImpl(StripProto(basename), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string FileJavaPackage(const Params& params, const FileDescriptor* file) {
|
||||||
|
if (params.has_java_package(file->name())) {
|
||||||
|
return params.java_package(file->name());
|
||||||
|
} else {
|
||||||
|
string result = kDefaultPackage;
|
||||||
|
if (!file->package().empty()) {
|
||||||
|
if (!result.empty()) result += '.';
|
||||||
|
result += file->package();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsOuterClassNeeded(const Params& params, const FileDescriptor* file) {
|
||||||
|
// If java_multiple_files is false, the outer class is always needed.
|
||||||
|
if (!params.java_multiple_files(file->name())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// File-scope extensions need the outer class as the scope.
|
||||||
|
if (file->extension_count() != 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If container interfaces are not generated, file-scope enums need the
|
||||||
|
// outer class as the scope.
|
||||||
|
if (file->enum_type_count() != 0 && !params.java_enum_style()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
string ToJavaName(const Params& params, const string& name, bool is_class,
|
||||||
|
const Descriptor* parent, const FileDescriptor* file) {
|
||||||
|
string result;
|
||||||
|
if (parent != NULL) {
|
||||||
|
result.append(ClassName(params, parent));
|
||||||
|
} else if (is_class && params.java_multiple_files(file->name())) {
|
||||||
|
result.append(FileJavaPackage(params, file));
|
||||||
|
} else {
|
||||||
|
result.append(ClassName(params, file));
|
||||||
|
}
|
||||||
|
if (!result.empty()) result.append(1, '.');
|
||||||
|
result.append(RenameJavaKeywords(name));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
string ClassName(const Params& params, const FileDescriptor* descriptor) {
|
||||||
|
string result = FileJavaPackage(params, descriptor);
|
||||||
|
if (!result.empty()) result += '.';
|
||||||
|
result += FileClassName(params, descriptor);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
string ClassName(const Params& params, const EnumDescriptor* descriptor) {
|
||||||
|
const Descriptor* parent = descriptor->containing_type();
|
||||||
|
// When using Java enum style, an enum's class name contains the enum name.
|
||||||
|
// Use the standard ToJavaName translation.
|
||||||
|
if (params.java_enum_style()) {
|
||||||
|
return ToJavaName(params, descriptor->name(), true, parent,
|
||||||
|
descriptor->file());
|
||||||
|
}
|
||||||
|
// Otherwise the enum members are accessed from the enclosing class.
|
||||||
|
if (parent != NULL) {
|
||||||
|
return ClassName(params, parent);
|
||||||
|
} else {
|
||||||
|
return ClassName(params, descriptor->file());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string FieldConstantName(const FieldDescriptor *field) {
|
||||||
|
string name = field->name() + "_FIELD_NUMBER";
|
||||||
|
UpperString(&name);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
string FieldDefaultConstantName(const FieldDescriptor *field) {
|
||||||
|
return "_" + RenameJavaKeywords(UnderscoresToCamelCase(field)) + "Default";
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) {
|
||||||
|
// We don't want to print group bodies so we cut off after the first line
|
||||||
|
// (the second line for extensions).
|
||||||
|
string def = field->DebugString();
|
||||||
|
string::size_type first_line_end = def.find_first_of('\n');
|
||||||
|
printer->Print("// $def$\n",
|
||||||
|
"def", def.substr(0, first_line_end));
|
||||||
|
if (field->is_extension()) {
|
||||||
|
string::size_type second_line_start = first_line_end + 1;
|
||||||
|
string::size_type second_line_length =
|
||||||
|
def.find('\n', second_line_start) - second_line_start;
|
||||||
|
printer->Print("// $def$\n",
|
||||||
|
"def", def.substr(second_line_start, second_line_length));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JavaType GetJavaType(FieldDescriptor::Type field_type) {
|
||||||
|
switch (field_type) {
|
||||||
|
case FieldDescriptor::TYPE_INT32:
|
||||||
|
case FieldDescriptor::TYPE_UINT32:
|
||||||
|
case FieldDescriptor::TYPE_SINT32:
|
||||||
|
case FieldDescriptor::TYPE_FIXED32:
|
||||||
|
case FieldDescriptor::TYPE_SFIXED32:
|
||||||
|
return JAVATYPE_INT;
|
||||||
|
|
||||||
|
case FieldDescriptor::TYPE_INT64:
|
||||||
|
case FieldDescriptor::TYPE_UINT64:
|
||||||
|
case FieldDescriptor::TYPE_SINT64:
|
||||||
|
case FieldDescriptor::TYPE_FIXED64:
|
||||||
|
case FieldDescriptor::TYPE_SFIXED64:
|
||||||
|
return JAVATYPE_LONG;
|
||||||
|
|
||||||
|
case FieldDescriptor::TYPE_FLOAT:
|
||||||
|
return JAVATYPE_FLOAT;
|
||||||
|
|
||||||
|
case FieldDescriptor::TYPE_DOUBLE:
|
||||||
|
return JAVATYPE_DOUBLE;
|
||||||
|
|
||||||
|
case FieldDescriptor::TYPE_BOOL:
|
||||||
|
return JAVATYPE_BOOLEAN;
|
||||||
|
|
||||||
|
case FieldDescriptor::TYPE_STRING:
|
||||||
|
return JAVATYPE_STRING;
|
||||||
|
|
||||||
|
case FieldDescriptor::TYPE_BYTES:
|
||||||
|
return JAVATYPE_BYTES;
|
||||||
|
|
||||||
|
case FieldDescriptor::TYPE_ENUM:
|
||||||
|
return JAVATYPE_ENUM;
|
||||||
|
|
||||||
|
case FieldDescriptor::TYPE_GROUP:
|
||||||
|
case FieldDescriptor::TYPE_MESSAGE:
|
||||||
|
return JAVATYPE_MESSAGE;
|
||||||
|
|
||||||
|
// No default because we want the compiler to complain if any new
|
||||||
|
// types are added.
|
||||||
|
}
|
||||||
|
|
||||||
|
GOOGLE_LOG(FATAL) << "Can't get here.";
|
||||||
|
return JAVATYPE_INT;
|
||||||
|
}
|
||||||
|
|
||||||
|
string PrimitiveTypeName(JavaType type) {
|
||||||
|
switch (type) {
|
||||||
|
case JAVATYPE_INT : return "int";
|
||||||
|
case JAVATYPE_LONG : return "long";
|
||||||
|
case JAVATYPE_FLOAT : return "float";
|
||||||
|
case JAVATYPE_DOUBLE : return "double";
|
||||||
|
case JAVATYPE_BOOLEAN: return "boolean";
|
||||||
|
case JAVATYPE_STRING : return "java.lang.String";
|
||||||
|
case JAVATYPE_BYTES : return "byte[]";
|
||||||
|
case JAVATYPE_ENUM : return "int";
|
||||||
|
case JAVATYPE_MESSAGE: return "";
|
||||||
|
|
||||||
|
// No default because we want the compiler to complain if any new
|
||||||
|
// JavaTypes are added.
|
||||||
|
}
|
||||||
|
|
||||||
|
GOOGLE_LOG(FATAL) << "Can't get here.";
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
string BoxedPrimitiveTypeName(JavaType type) {
|
||||||
|
switch (type) {
|
||||||
|
case JAVATYPE_INT : return "java.lang.Integer";
|
||||||
|
case JAVATYPE_LONG : return "java.lang.Long";
|
||||||
|
case JAVATYPE_FLOAT : return "java.lang.Float";
|
||||||
|
case JAVATYPE_DOUBLE : return "java.lang.Double";
|
||||||
|
case JAVATYPE_BOOLEAN: return "java.lang.Boolean";
|
||||||
|
case JAVATYPE_STRING : return "java.lang.String";
|
||||||
|
case JAVATYPE_BYTES : return "byte[]";
|
||||||
|
case JAVATYPE_ENUM : return "java.lang.Integer";
|
||||||
|
case JAVATYPE_MESSAGE: return "";
|
||||||
|
|
||||||
|
// No default because we want the compiler to complain if any new
|
||||||
|
// JavaTypes are added.
|
||||||
|
}
|
||||||
|
|
||||||
|
GOOGLE_LOG(FATAL) << "Can't get here.";
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
string EmptyArrayName(const Params& params, const FieldDescriptor* field) {
|
||||||
|
switch (GetJavaType(field)) {
|
||||||
|
case JAVATYPE_INT : return "com.google.protobuf.nano.WireFormatNano.EMPTY_INT_ARRAY";
|
||||||
|
case JAVATYPE_LONG : return "com.google.protobuf.nano.WireFormatNano.EMPTY_LONG_ARRAY";
|
||||||
|
case JAVATYPE_FLOAT : return "com.google.protobuf.nano.WireFormatNano.EMPTY_FLOAT_ARRAY";
|
||||||
|
case JAVATYPE_DOUBLE : return "com.google.protobuf.nano.WireFormatNano.EMPTY_DOUBLE_ARRAY";
|
||||||
|
case JAVATYPE_BOOLEAN: return "com.google.protobuf.nano.WireFormatNano.EMPTY_BOOLEAN_ARRAY";
|
||||||
|
case JAVATYPE_STRING : return "com.google.protobuf.nano.WireFormatNano.EMPTY_STRING_ARRAY";
|
||||||
|
case JAVATYPE_BYTES : return "com.google.protobuf.nano.WireFormatNano.EMPTY_BYTES_ARRAY";
|
||||||
|
case JAVATYPE_ENUM : return "com.google.protobuf.nano.WireFormatNano.EMPTY_INT_ARRAY";
|
||||||
|
case JAVATYPE_MESSAGE: return ClassName(params, field->message_type()) + ".EMPTY_ARRAY";
|
||||||
|
|
||||||
|
// No default because we want the compiler to complain if any new
|
||||||
|
// JavaTypes are added.
|
||||||
|
}
|
||||||
|
|
||||||
|
GOOGLE_LOG(FATAL) << "Can't get here.";
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
string DefaultValue(const Params& params, const FieldDescriptor* field) {
|
||||||
|
if (field->label() == FieldDescriptor::LABEL_REPEATED) {
|
||||||
|
return EmptyArrayName(params, field);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params.use_reference_types_for_primitives()) {
|
||||||
|
if (params.reftypes_primitive_enums()
|
||||||
|
&& field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
|
||||||
|
return "Integer.MIN_VALUE";
|
||||||
|
}
|
||||||
|
return "null";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Switch on cpp_type since we need to know which default_value_* method
|
||||||
|
// of FieldDescriptor to call.
|
||||||
|
switch (field->cpp_type()) {
|
||||||
|
case FieldDescriptor::CPPTYPE_INT32:
|
||||||
|
return SimpleItoa(field->default_value_int32());
|
||||||
|
case FieldDescriptor::CPPTYPE_UINT32:
|
||||||
|
// Need to print as a signed int since Java has no unsigned.
|
||||||
|
return SimpleItoa(static_cast<int32>(field->default_value_uint32()));
|
||||||
|
case FieldDescriptor::CPPTYPE_INT64:
|
||||||
|
return SimpleItoa(field->default_value_int64()) + "L";
|
||||||
|
case FieldDescriptor::CPPTYPE_UINT64:
|
||||||
|
return SimpleItoa(static_cast<int64>(field->default_value_uint64())) +
|
||||||
|
"L";
|
||||||
|
case FieldDescriptor::CPPTYPE_DOUBLE: {
|
||||||
|
double value = field->default_value_double();
|
||||||
|
if (value == numeric_limits<double>::infinity()) {
|
||||||
|
return "Double.POSITIVE_INFINITY";
|
||||||
|
} else if (value == -numeric_limits<double>::infinity()) {
|
||||||
|
return "Double.NEGATIVE_INFINITY";
|
||||||
|
} else if (value != value) {
|
||||||
|
return "Double.NaN";
|
||||||
|
} else {
|
||||||
|
return SimpleDtoa(value) + "D";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case FieldDescriptor::CPPTYPE_FLOAT: {
|
||||||
|
float value = field->default_value_float();
|
||||||
|
if (value == numeric_limits<float>::infinity()) {
|
||||||
|
return "Float.POSITIVE_INFINITY";
|
||||||
|
} else if (value == -numeric_limits<float>::infinity()) {
|
||||||
|
return "Float.NEGATIVE_INFINITY";
|
||||||
|
} else if (value != value) {
|
||||||
|
return "Float.NaN";
|
||||||
|
} else {
|
||||||
|
return SimpleFtoa(value) + "F";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case FieldDescriptor::CPPTYPE_BOOL:
|
||||||
|
return field->default_value_bool() ? "true" : "false";
|
||||||
|
case FieldDescriptor::CPPTYPE_STRING:
|
||||||
|
if (!field->default_value_string().empty()) {
|
||||||
|
// Point it to the static final in the generated code.
|
||||||
|
return FieldDefaultConstantName(field);
|
||||||
|
} else {
|
||||||
|
if (field->type() == FieldDescriptor::TYPE_BYTES) {
|
||||||
|
return "com.google.protobuf.nano.WireFormatNano.EMPTY_BYTES";
|
||||||
|
} else {
|
||||||
|
return "\"\"";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case FieldDescriptor::CPPTYPE_ENUM:
|
||||||
|
return ClassName(params, field->enum_type()) + "." +
|
||||||
|
RenameJavaKeywords(field->default_value_enum()->name());
|
||||||
|
|
||||||
|
case FieldDescriptor::CPPTYPE_MESSAGE:
|
||||||
|
return "null";
|
||||||
|
|
||||||
|
// No default because we want the compiler to complain if any new
|
||||||
|
// types are added.
|
||||||
|
}
|
||||||
|
|
||||||
|
GOOGLE_LOG(FATAL) << "Can't get here.";
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const char* kBitMasks[] = {
|
||||||
|
"0x00000001",
|
||||||
|
"0x00000002",
|
||||||
|
"0x00000004",
|
||||||
|
"0x00000008",
|
||||||
|
"0x00000010",
|
||||||
|
"0x00000020",
|
||||||
|
"0x00000040",
|
||||||
|
"0x00000080",
|
||||||
|
|
||||||
|
"0x00000100",
|
||||||
|
"0x00000200",
|
||||||
|
"0x00000400",
|
||||||
|
"0x00000800",
|
||||||
|
"0x00001000",
|
||||||
|
"0x00002000",
|
||||||
|
"0x00004000",
|
||||||
|
"0x00008000",
|
||||||
|
|
||||||
|
"0x00010000",
|
||||||
|
"0x00020000",
|
||||||
|
"0x00040000",
|
||||||
|
"0x00080000",
|
||||||
|
"0x00100000",
|
||||||
|
"0x00200000",
|
||||||
|
"0x00400000",
|
||||||
|
"0x00800000",
|
||||||
|
|
||||||
|
"0x01000000",
|
||||||
|
"0x02000000",
|
||||||
|
"0x04000000",
|
||||||
|
"0x08000000",
|
||||||
|
"0x10000000",
|
||||||
|
"0x20000000",
|
||||||
|
"0x40000000",
|
||||||
|
"0x80000000",
|
||||||
|
};
|
||||||
|
|
||||||
|
string GetBitFieldName(int index) {
|
||||||
|
string var_name = "bitField";
|
||||||
|
var_name += SimpleItoa(index);
|
||||||
|
var_name += "_";
|
||||||
|
return var_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
string GetBitFieldNameForBit(int bit_index) {
|
||||||
|
return GetBitFieldName(bit_index / 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
string GenerateGetBit(int bit_index) {
|
||||||
|
string var_name = GetBitFieldNameForBit(bit_index);
|
||||||
|
int bit_in_var_index = bit_index % 32;
|
||||||
|
|
||||||
|
string mask = kBitMasks[bit_in_var_index];
|
||||||
|
string result = "((" + var_name + " & " + mask + ") != 0)";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
string GenerateSetBit(int bit_index) {
|
||||||
|
string var_name = GetBitFieldNameForBit(bit_index);
|
||||||
|
int bit_in_var_index = bit_index % 32;
|
||||||
|
|
||||||
|
string mask = kBitMasks[bit_in_var_index];
|
||||||
|
string result = var_name + " |= " + mask;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
string GenerateClearBit(int bit_index) {
|
||||||
|
string var_name = GetBitFieldNameForBit(bit_index);
|
||||||
|
int bit_in_var_index = bit_index % 32;
|
||||||
|
|
||||||
|
string mask = kBitMasks[bit_in_var_index];
|
||||||
|
string result = var_name + " = (" + var_name + " & ~" + mask + ")";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
string GenerateDifferentBit(int bit_index) {
|
||||||
|
string var_name = GetBitFieldNameForBit(bit_index);
|
||||||
|
int bit_in_var_index = bit_index % 32;
|
||||||
|
|
||||||
|
string mask = kBitMasks[bit_in_var_index];
|
||||||
|
string result = "((" + var_name + " & " + mask
|
||||||
|
+ ") != (other." + var_name + " & " + mask + "))";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetBitOperationVariables(const string name,
|
||||||
|
int bitIndex, map<string, string>* variables) {
|
||||||
|
(*variables)["get_" + name] = GenerateGetBit(bitIndex);
|
||||||
|
(*variables)["set_" + name] = GenerateSetBit(bitIndex);
|
||||||
|
(*variables)["clear_" + name] = GenerateClearBit(bitIndex);
|
||||||
|
(*variables)["different_" + name] = GenerateDifferentBit(bitIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace javanano
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace protobuf
|
||||||
|
} // namespace google
|
189
src/google/protobuf/compiler/javanano/javanano_helpers.h
Normal file
189
src/google/protobuf/compiler/javanano/javanano_helpers.h
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: kenton@google.com (Kenton Varda)
|
||||||
|
// Based on original Protocol Buffers design by
|
||||||
|
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||||
|
|
||||||
|
#ifndef GOOGLE_PROTOBUF_COMPILER_JAVANANO_HELPERS_H__
|
||||||
|
#define GOOGLE_PROTOBUF_COMPILER_JAVANANO_HELPERS_H__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_params.h>
|
||||||
|
#include <google/protobuf/descriptor.pb.h>
|
||||||
|
#include <google/protobuf/descriptor.h>
|
||||||
|
#include <google/protobuf/io/printer.h>
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
namespace protobuf {
|
||||||
|
namespace compiler {
|
||||||
|
namespace javanano {
|
||||||
|
|
||||||
|
// Commonly-used separator comments. Thick is a line of '=', thin is a line
|
||||||
|
// of '-'.
|
||||||
|
extern const char kThickSeparator[];
|
||||||
|
extern const char kThinSeparator[];
|
||||||
|
|
||||||
|
// Converts the field's name to camel-case, e.g. "foo_bar_baz" becomes
|
||||||
|
// "fooBarBaz" or "FooBarBaz", respectively.
|
||||||
|
string UnderscoresToCamelCase(const FieldDescriptor* field);
|
||||||
|
string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field);
|
||||||
|
|
||||||
|
// Appends an "_" to the end of a field where the name is a reserved java
|
||||||
|
// keyword. For example int32 public = 1 will generate int public_.
|
||||||
|
string RenameJavaKeywords(const string& input);
|
||||||
|
|
||||||
|
// Similar, but for method names. (Typically, this merely has the effect
|
||||||
|
// of lower-casing the first letter of the name.)
|
||||||
|
string UnderscoresToCamelCase(const MethodDescriptor* method);
|
||||||
|
|
||||||
|
// Strips ".proto" or ".protodevel" from the end of a filename.
|
||||||
|
string StripProto(const string& filename);
|
||||||
|
|
||||||
|
// Gets the unqualified class name for the file. Each .proto file becomes a
|
||||||
|
// single Java class, with all its contents nested in that class.
|
||||||
|
string FileClassName(const Params& params, const FileDescriptor* file);
|
||||||
|
|
||||||
|
// Returns the file's Java package name.
|
||||||
|
string FileJavaPackage(const Params& params, const FileDescriptor* file);
|
||||||
|
|
||||||
|
// Returns whether the Java outer class is needed, i.e. whether the option
|
||||||
|
// java_multiple_files is false, or the proto file contains any file-scope
|
||||||
|
// enums/extensions.
|
||||||
|
bool IsOuterClassNeeded(const Params& params, const FileDescriptor* file);
|
||||||
|
|
||||||
|
// Converts the given simple name of a proto entity to its fully-qualified name
|
||||||
|
// in the Java namespace, given that it is in the given file enclosed in the
|
||||||
|
// given parent message (or NULL for file-scope entities). Whether the file's
|
||||||
|
// outer class name should be included in the return value depends on factors
|
||||||
|
// inferrable from the given arguments, including is_class which indicates
|
||||||
|
// whether the entity translates to a Java class.
|
||||||
|
string ToJavaName(const Params& params, const string& name, bool is_class,
|
||||||
|
const Descriptor* parent, const FileDescriptor* file);
|
||||||
|
|
||||||
|
// These return the fully-qualified class name corresponding to the given
|
||||||
|
// descriptor.
|
||||||
|
inline string ClassName(const Params& params, const Descriptor* descriptor) {
|
||||||
|
return ToJavaName(params, descriptor->name(), true,
|
||||||
|
descriptor->containing_type(), descriptor->file());
|
||||||
|
}
|
||||||
|
string ClassName(const Params& params, const EnumDescriptor* descriptor);
|
||||||
|
inline string ClassName(const Params& params,
|
||||||
|
const ServiceDescriptor* descriptor) {
|
||||||
|
return ToJavaName(params, descriptor->name(), true, NULL, descriptor->file());
|
||||||
|
}
|
||||||
|
inline string ExtensionIdentifierName(const Params& params,
|
||||||
|
const FieldDescriptor* descriptor) {
|
||||||
|
return ToJavaName(params, descriptor->name(), false,
|
||||||
|
descriptor->extension_scope(), descriptor->file());
|
||||||
|
}
|
||||||
|
string ClassName(const Params& params, const FileDescriptor* descriptor);
|
||||||
|
|
||||||
|
// Get the unqualified name that should be used for a field's field
|
||||||
|
// number constant.
|
||||||
|
string FieldConstantName(const FieldDescriptor *field);
|
||||||
|
|
||||||
|
string FieldDefaultConstantName(const FieldDescriptor *field);
|
||||||
|
|
||||||
|
// Print the field's proto-syntax definition as a comment.
|
||||||
|
void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field);
|
||||||
|
|
||||||
|
enum JavaType {
|
||||||
|
JAVATYPE_INT,
|
||||||
|
JAVATYPE_LONG,
|
||||||
|
JAVATYPE_FLOAT,
|
||||||
|
JAVATYPE_DOUBLE,
|
||||||
|
JAVATYPE_BOOLEAN,
|
||||||
|
JAVATYPE_STRING,
|
||||||
|
JAVATYPE_BYTES,
|
||||||
|
JAVATYPE_ENUM,
|
||||||
|
JAVATYPE_MESSAGE
|
||||||
|
};
|
||||||
|
|
||||||
|
JavaType GetJavaType(FieldDescriptor::Type field_type);
|
||||||
|
|
||||||
|
inline JavaType GetJavaType(const FieldDescriptor* field) {
|
||||||
|
return GetJavaType(field->type());
|
||||||
|
}
|
||||||
|
|
||||||
|
string PrimitiveTypeName(JavaType type);
|
||||||
|
|
||||||
|
// Get the fully-qualified class name for a boxed primitive type, e.g.
|
||||||
|
// "java.lang.Integer" for JAVATYPE_INT. Returns NULL for enum and message
|
||||||
|
// types.
|
||||||
|
string BoxedPrimitiveTypeName(JavaType type);
|
||||||
|
|
||||||
|
string EmptyArrayName(const Params& params, const FieldDescriptor* field);
|
||||||
|
|
||||||
|
string DefaultValue(const Params& params, const FieldDescriptor* field);
|
||||||
|
|
||||||
|
|
||||||
|
// Methods for shared bitfields.
|
||||||
|
|
||||||
|
// Gets the name of the shared bitfield for the given field index.
|
||||||
|
string GetBitFieldName(int index);
|
||||||
|
|
||||||
|
// Gets the name of the shared bitfield for the given bit index.
|
||||||
|
// Effectively, GetBitFieldName(bit_index / 32)
|
||||||
|
string GetBitFieldNameForBit(int bit_index);
|
||||||
|
|
||||||
|
// Generates the java code for the expression that returns whether the bit at
|
||||||
|
// the given bit index is set.
|
||||||
|
// Example: "((bitField1_ & 0x04000000) != 0)"
|
||||||
|
string GenerateGetBit(int bit_index);
|
||||||
|
|
||||||
|
// Generates the java code for the expression that sets the bit at the given
|
||||||
|
// bit index.
|
||||||
|
// Example: "bitField1_ |= 0x04000000"
|
||||||
|
string GenerateSetBit(int bit_index);
|
||||||
|
|
||||||
|
// Generates the java code for the expression that clears the bit at the given
|
||||||
|
// bit index.
|
||||||
|
// Example: "bitField1_ = (bitField1_ & ~0x04000000)"
|
||||||
|
string GenerateClearBit(int bit_index);
|
||||||
|
|
||||||
|
// Generates the java code for the expression that returns whether the bit at
|
||||||
|
// the given bit index contains different values in the current object and
|
||||||
|
// another object accessible via the variable 'other'.
|
||||||
|
// Example: "((bitField1_ & 0x04000000) != (other.bitField1_ & 0x04000000))"
|
||||||
|
string GenerateDifferentBit(int bit_index);
|
||||||
|
|
||||||
|
// Sets the 'get_*', 'set_*', 'clear_*' and 'different_*' variables, where * is
|
||||||
|
// the given name of the bit, to the appropriate Java expressions for the given
|
||||||
|
// bit index.
|
||||||
|
void SetBitOperationVariables(const string name,
|
||||||
|
int bitIndex, map<string, string>* variables);
|
||||||
|
|
||||||
|
} // namespace javanano
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace protobuf
|
||||||
|
|
||||||
|
} // namespace google
|
||||||
|
#endif // GOOGLE_PROTOBUF_COMPILER_JAVANANO_HELPERS_H__
|
555
src/google/protobuf/compiler/javanano/javanano_message.cc
Normal file
555
src/google/protobuf/compiler/javanano/javanano_message.cc
Normal file
@ -0,0 +1,555 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: kenton@google.com (Kenton Varda)
|
||||||
|
// Based on original Protocol Buffers design by
|
||||||
|
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <google/protobuf/stubs/hash.h>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_message.h>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_enum.h>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_extension.h>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_helpers.h>
|
||||||
|
#include <google/protobuf/stubs/strutil.h>
|
||||||
|
#include <google/protobuf/io/printer.h>
|
||||||
|
#include <google/protobuf/io/coded_stream.h>
|
||||||
|
#include <google/protobuf/wire_format.h>
|
||||||
|
#include <google/protobuf/descriptor.pb.h>
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
namespace protobuf {
|
||||||
|
namespace compiler {
|
||||||
|
namespace javanano {
|
||||||
|
|
||||||
|
using internal::WireFormat;
|
||||||
|
using internal::WireFormatLite;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct FieldOrderingByNumber {
|
||||||
|
inline bool operator()(const FieldDescriptor* a,
|
||||||
|
const FieldDescriptor* b) const {
|
||||||
|
return a->number() < b->number();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Sort the fields of the given Descriptor by number into a new[]'d array
|
||||||
|
// and return it.
|
||||||
|
const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
|
||||||
|
const FieldDescriptor** fields =
|
||||||
|
new const FieldDescriptor*[descriptor->field_count()];
|
||||||
|
for (int i = 0; i < descriptor->field_count(); i++) {
|
||||||
|
fields[i] = descriptor->field(i);
|
||||||
|
}
|
||||||
|
sort(fields, fields + descriptor->field_count(),
|
||||||
|
FieldOrderingByNumber());
|
||||||
|
return fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// ===================================================================
|
||||||
|
|
||||||
|
MessageGenerator::MessageGenerator(const Descriptor* descriptor, const Params& params)
|
||||||
|
: params_(params),
|
||||||
|
descriptor_(descriptor),
|
||||||
|
field_generators_(descriptor, params) {
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageGenerator::~MessageGenerator() {}
|
||||||
|
|
||||||
|
void MessageGenerator::GenerateStaticVariables(io::Printer* printer) {
|
||||||
|
// Generate static members for all nested types.
|
||||||
|
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
|
||||||
|
// TODO(kenton): Reuse MessageGenerator objects?
|
||||||
|
MessageGenerator(descriptor_->nested_type(i), params_)
|
||||||
|
.GenerateStaticVariables(printer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageGenerator::GenerateStaticVariableInitializers(
|
||||||
|
io::Printer* printer) {
|
||||||
|
// Generate static member initializers for all nested types.
|
||||||
|
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
|
||||||
|
// TODO(kenton): Reuse MessageGenerator objects?
|
||||||
|
MessageGenerator(descriptor_->nested_type(i), params_)
|
||||||
|
.GenerateStaticVariableInitializers(printer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageGenerator::Generate(io::Printer* printer) {
|
||||||
|
if (!params_.store_unknown_fields() &&
|
||||||
|
(descriptor_->extension_count() != 0 || descriptor_->extension_range_count() != 0)) {
|
||||||
|
GOOGLE_LOG(FATAL) << "Extensions are only supported in NANO_RUNTIME if the "
|
||||||
|
"'store_unknown_fields' generator option is 'true'\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
const string& file_name = descriptor_->file()->name();
|
||||||
|
bool is_own_file =
|
||||||
|
params_.java_multiple_files(file_name)
|
||||||
|
&& descriptor_->containing_type() == NULL;
|
||||||
|
|
||||||
|
if (is_own_file) {
|
||||||
|
// Note: constants (from enums and fields requiring stored defaults, emitted in the loop below)
|
||||||
|
// may have the same names as constants in the nested classes. This causes Java warnings, but
|
||||||
|
// is not fatal, so we suppress those warnings here in the top-most class declaration.
|
||||||
|
printer->Print(
|
||||||
|
"\n"
|
||||||
|
"@SuppressWarnings(\"hiding\")\n"
|
||||||
|
"public final class $classname$ extends\n",
|
||||||
|
"classname", descriptor_->name());
|
||||||
|
} else {
|
||||||
|
printer->Print(
|
||||||
|
"\n"
|
||||||
|
"public static final class $classname$ extends\n",
|
||||||
|
"classname", descriptor_->name());
|
||||||
|
}
|
||||||
|
if (params_.store_unknown_fields() && params_.parcelable_messages()) {
|
||||||
|
printer->Print(
|
||||||
|
" com.google.protobuf.nano.android.ParcelableExtendableMessageNano<$classname$> {\n",
|
||||||
|
"classname", descriptor_->name());
|
||||||
|
} else if (params_.store_unknown_fields()) {
|
||||||
|
printer->Print(
|
||||||
|
" com.google.protobuf.nano.ExtendableMessageNano<$classname$> {\n",
|
||||||
|
"classname", descriptor_->name());
|
||||||
|
} else if (params_.parcelable_messages()) {
|
||||||
|
printer->Print(
|
||||||
|
" com.google.protobuf.nano.android.ParcelableMessageNano {\n");
|
||||||
|
} else {
|
||||||
|
printer->Print(
|
||||||
|
" com.google.protobuf.nano.MessageNano {\n");
|
||||||
|
}
|
||||||
|
printer->Indent();
|
||||||
|
|
||||||
|
// Nested types and extensions
|
||||||
|
for (int i = 0; i < descriptor_->extension_count(); i++) {
|
||||||
|
ExtensionGenerator(descriptor_->extension(i), params_).Generate(printer);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < descriptor_->enum_type_count(); i++) {
|
||||||
|
EnumGenerator(descriptor_->enum_type(i), params_).Generate(printer);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
|
||||||
|
MessageGenerator(descriptor_->nested_type(i), params_).Generate(printer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lazy initialization of otherwise static final fields can help prevent the
|
||||||
|
// class initializer from being generated. We want to prevent it because it
|
||||||
|
// stops ProGuard from inlining any methods in this class into call sites and
|
||||||
|
// therefore reducing the method count. However, extensions are best kept as
|
||||||
|
// public static final fields with initializers, so with their existence we
|
||||||
|
// won't bother with lazy initialization.
|
||||||
|
bool lazy_init = descriptor_->extension_count() == 0;
|
||||||
|
|
||||||
|
// Empty array
|
||||||
|
if (lazy_init) {
|
||||||
|
printer->Print(
|
||||||
|
"\n"
|
||||||
|
"private static volatile $classname$[] _emptyArray;\n"
|
||||||
|
"public static $classname$[] emptyArray() {\n"
|
||||||
|
" // Lazily initializes the empty array\n"
|
||||||
|
" if (_emptyArray == null) {\n"
|
||||||
|
" synchronized (\n"
|
||||||
|
" com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) {\n"
|
||||||
|
" if (_emptyArray == null) {\n"
|
||||||
|
" _emptyArray = new $classname$[0];\n"
|
||||||
|
" }\n"
|
||||||
|
" }\n"
|
||||||
|
" }\n"
|
||||||
|
" return _emptyArray;\n"
|
||||||
|
"}\n",
|
||||||
|
"classname", descriptor_->name());
|
||||||
|
} else {
|
||||||
|
printer->Print(
|
||||||
|
"\n"
|
||||||
|
"private static final $classname$[] EMPTY_ARRAY = {};\n"
|
||||||
|
"public static $classname$[] emptyArray() {\n"
|
||||||
|
" return EMPTY_ARRAY;\n"
|
||||||
|
"}\n",
|
||||||
|
"classname", descriptor_->name());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Integers for bit fields
|
||||||
|
int totalInts = (field_generators_.total_bits() + 31) / 32;
|
||||||
|
if (totalInts > 0) {
|
||||||
|
printer->Print("\n");
|
||||||
|
for (int i = 0; i < totalInts; i++) {
|
||||||
|
printer->Print("private int $bit_field_name$;\n",
|
||||||
|
"bit_field_name", GetBitFieldName(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fields and maybe their default values
|
||||||
|
for (int i = 0; i < descriptor_->field_count(); i++) {
|
||||||
|
printer->Print("\n");
|
||||||
|
PrintFieldComment(printer, descriptor_->field(i));
|
||||||
|
field_generators_.get(descriptor_->field(i)).GenerateMembers(
|
||||||
|
printer, lazy_init);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructor, with lazy init code if needed
|
||||||
|
if (lazy_init && field_generators_.saved_defaults_needed()) {
|
||||||
|
printer->Print(
|
||||||
|
"\n"
|
||||||
|
"private static volatile boolean _classInitialized;\n"
|
||||||
|
"\n"
|
||||||
|
"public $classname$() {\n"
|
||||||
|
" // Lazily initializes the field defaults\n"
|
||||||
|
" if (!_classInitialized) {\n"
|
||||||
|
" synchronized (\n"
|
||||||
|
" com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) {\n"
|
||||||
|
" if (!_classInitialized) {\n",
|
||||||
|
"classname", descriptor_->name());
|
||||||
|
printer->Indent();
|
||||||
|
printer->Indent();
|
||||||
|
printer->Indent();
|
||||||
|
printer->Indent();
|
||||||
|
for (int i = 0; i < descriptor_->field_count(); i++) {
|
||||||
|
field_generators_.get(descriptor_->field(i))
|
||||||
|
.GenerateInitSavedDefaultCode(printer);
|
||||||
|
}
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print(
|
||||||
|
" _classInitialized = true;\n"
|
||||||
|
" }\n"
|
||||||
|
" }\n"
|
||||||
|
" }\n");
|
||||||
|
if (params_.generate_clear()) {
|
||||||
|
printer->Print(" clear();\n");
|
||||||
|
}
|
||||||
|
printer->Print("}\n");
|
||||||
|
} else {
|
||||||
|
if (params_.generate_clear()) {
|
||||||
|
printer->Print(
|
||||||
|
"\n"
|
||||||
|
"public $classname$() {\n"
|
||||||
|
" clear();\n"
|
||||||
|
"}\n",
|
||||||
|
"classname", descriptor_->name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Other methods in this class
|
||||||
|
|
||||||
|
GenerateClear(printer);
|
||||||
|
|
||||||
|
if (params_.generate_equals()) {
|
||||||
|
GenerateEquals(printer);
|
||||||
|
GenerateHashCode(printer);
|
||||||
|
}
|
||||||
|
|
||||||
|
GenerateMessageSerializationMethods(printer);
|
||||||
|
GenerateMergeFromMethods(printer);
|
||||||
|
GenerateParseFromMethods(printer);
|
||||||
|
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===================================================================
|
||||||
|
|
||||||
|
void MessageGenerator::
|
||||||
|
GenerateMessageSerializationMethods(io::Printer* printer) {
|
||||||
|
// Rely on the parent implementations of writeTo() and getSerializedSize()
|
||||||
|
// if there are no fields to serialize in this message.
|
||||||
|
if (descriptor_->field_count() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
scoped_array<const FieldDescriptor*> sorted_fields(
|
||||||
|
SortFieldsByNumber(descriptor_));
|
||||||
|
|
||||||
|
printer->Print(
|
||||||
|
"\n"
|
||||||
|
"@Override\n"
|
||||||
|
"public void writeTo(com.google.protobuf.nano.CodedOutputByteBufferNano output)\n"
|
||||||
|
" throws java.io.IOException {\n");
|
||||||
|
printer->Indent();
|
||||||
|
|
||||||
|
// Output the fields in sorted order
|
||||||
|
for (int i = 0; i < descriptor_->field_count(); i++) {
|
||||||
|
GenerateSerializeOneField(printer, sorted_fields[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The parent implementation will write any unknown fields if necessary.
|
||||||
|
printer->Print(
|
||||||
|
"super.writeTo(output);\n");
|
||||||
|
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("}\n");
|
||||||
|
|
||||||
|
// The parent implementation will get the serialized size for unknown
|
||||||
|
// fields if necessary.
|
||||||
|
printer->Print(
|
||||||
|
"\n"
|
||||||
|
"@Override\n"
|
||||||
|
"protected int computeSerializedSize() {\n"
|
||||||
|
" int size = super.computeSerializedSize();\n");
|
||||||
|
printer->Indent();
|
||||||
|
|
||||||
|
for (int i = 0; i < descriptor_->field_count(); i++) {
|
||||||
|
field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer);
|
||||||
|
}
|
||||||
|
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print(
|
||||||
|
" return size;\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageGenerator::GenerateMergeFromMethods(io::Printer* printer) {
|
||||||
|
scoped_array<const FieldDescriptor*> sorted_fields(
|
||||||
|
SortFieldsByNumber(descriptor_));
|
||||||
|
|
||||||
|
printer->Print(
|
||||||
|
"\n"
|
||||||
|
"@Override\n"
|
||||||
|
"public $classname$ mergeFrom(\n"
|
||||||
|
" com.google.protobuf.nano.CodedInputByteBufferNano input)\n"
|
||||||
|
" throws java.io.IOException {\n",
|
||||||
|
"classname", descriptor_->name());
|
||||||
|
|
||||||
|
printer->Indent();
|
||||||
|
|
||||||
|
printer->Print(
|
||||||
|
"while (true) {\n");
|
||||||
|
printer->Indent();
|
||||||
|
|
||||||
|
printer->Print(
|
||||||
|
"int tag = input.readTag();\n"
|
||||||
|
"switch (tag) {\n");
|
||||||
|
printer->Indent();
|
||||||
|
|
||||||
|
printer->Print(
|
||||||
|
"case 0:\n" // zero signals EOF / limit reached
|
||||||
|
" return this;\n"
|
||||||
|
"default: {\n");
|
||||||
|
|
||||||
|
printer->Indent();
|
||||||
|
if (params_.store_unknown_fields()) {
|
||||||
|
printer->Print(
|
||||||
|
"if (!storeUnknownField(input, tag)) {\n"
|
||||||
|
" return this;\n"
|
||||||
|
"}\n");
|
||||||
|
} else {
|
||||||
|
printer->Print(
|
||||||
|
"if (!com.google.protobuf.nano.WireFormatNano.parseUnknownField(input, tag)) {\n"
|
||||||
|
" return this;\n" // it's an endgroup tag
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
printer->Print("break;\n");
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("}\n");
|
||||||
|
|
||||||
|
for (int i = 0; i < descriptor_->field_count(); i++) {
|
||||||
|
const FieldDescriptor* field = sorted_fields[i];
|
||||||
|
uint32 tag = WireFormatLite::MakeTag(field->number(),
|
||||||
|
WireFormat::WireTypeForFieldType(field->type()));
|
||||||
|
|
||||||
|
printer->Print(
|
||||||
|
"case $tag$: {\n",
|
||||||
|
"tag", SimpleItoa(tag));
|
||||||
|
printer->Indent();
|
||||||
|
|
||||||
|
field_generators_.get(field).GenerateMergingCode(printer);
|
||||||
|
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print(
|
||||||
|
" break;\n"
|
||||||
|
"}\n");
|
||||||
|
|
||||||
|
if (field->is_packable()) {
|
||||||
|
// To make packed = true wire compatible, we generate parsing code from a
|
||||||
|
// packed version of this field regardless of field->options().packed().
|
||||||
|
uint32 packed_tag = WireFormatLite::MakeTag(field->number(),
|
||||||
|
WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
|
||||||
|
printer->Print(
|
||||||
|
"case $tag$: {\n",
|
||||||
|
"tag", SimpleItoa(packed_tag));
|
||||||
|
printer->Indent();
|
||||||
|
|
||||||
|
field_generators_.get(field).GenerateMergingCodeFromPacked(printer);
|
||||||
|
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print(
|
||||||
|
" break;\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print(
|
||||||
|
" }\n" // switch (tag)
|
||||||
|
" }\n" // while (true)
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageGenerator::
|
||||||
|
GenerateParseFromMethods(io::Printer* printer) {
|
||||||
|
// Note: These are separate from GenerateMessageSerializationMethods()
|
||||||
|
// because they need to be generated even for messages that are optimized
|
||||||
|
// for code size.
|
||||||
|
printer->Print(
|
||||||
|
"\n"
|
||||||
|
"public static $classname$ parseFrom(byte[] data)\n"
|
||||||
|
" throws com.google.protobuf.nano.InvalidProtocolBufferNanoException {\n"
|
||||||
|
" return com.google.protobuf.nano.MessageNano.mergeFrom(new $classname$(), data);\n"
|
||||||
|
"}\n"
|
||||||
|
"\n"
|
||||||
|
"public static $classname$ parseFrom(\n"
|
||||||
|
" com.google.protobuf.nano.CodedInputByteBufferNano input)\n"
|
||||||
|
" throws java.io.IOException {\n"
|
||||||
|
" return new $classname$().mergeFrom(input);\n"
|
||||||
|
"}\n",
|
||||||
|
"classname", descriptor_->name());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageGenerator::GenerateSerializeOneField(
|
||||||
|
io::Printer* printer, const FieldDescriptor* field) {
|
||||||
|
field_generators_.get(field).GenerateSerializationCode(printer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageGenerator::GenerateClear(io::Printer* printer) {
|
||||||
|
if (!params_.generate_clear()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printer->Print(
|
||||||
|
"\n"
|
||||||
|
"public $classname$ clear() {\n",
|
||||||
|
"classname", descriptor_->name());
|
||||||
|
printer->Indent();
|
||||||
|
|
||||||
|
// Clear bit fields.
|
||||||
|
int totalInts = (field_generators_.total_bits() + 31) / 32;
|
||||||
|
for (int i = 0; i < totalInts; i++) {
|
||||||
|
printer->Print("$bit_field_name$ = 0;\n",
|
||||||
|
"bit_field_name", GetBitFieldName(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call clear for all of the fields.
|
||||||
|
for (int i = 0; i < descriptor_->field_count(); i++) {
|
||||||
|
const FieldDescriptor* field = descriptor_->field(i);
|
||||||
|
field_generators_.get(field).GenerateClearCode(printer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear unknown fields.
|
||||||
|
if (params_.store_unknown_fields()) {
|
||||||
|
printer->Print("unknownFieldData = null;\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print(
|
||||||
|
" cachedSize = -1;\n"
|
||||||
|
" return this;\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageGenerator::GenerateEquals(io::Printer* printer) {
|
||||||
|
// Don't override if there are no fields. We could generate an
|
||||||
|
// equals method that compares types, but often empty messages
|
||||||
|
// are used as namespaces.
|
||||||
|
if (descriptor_->field_count() == 0 && !params_.store_unknown_fields()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printer->Print(
|
||||||
|
"\n"
|
||||||
|
"@Override\n"
|
||||||
|
"public boolean equals(Object o) {\n");
|
||||||
|
printer->Indent();
|
||||||
|
printer->Print(
|
||||||
|
"if (o == this) {\n"
|
||||||
|
" return true;\n"
|
||||||
|
"}\n"
|
||||||
|
"if (!(o instanceof $classname$)) {\n"
|
||||||
|
" return false;\n"
|
||||||
|
"}\n"
|
||||||
|
"$classname$ other = ($classname$) o;\n",
|
||||||
|
"classname", descriptor_->name());
|
||||||
|
|
||||||
|
for (int i = 0; i < descriptor_->field_count(); i++) {
|
||||||
|
const FieldDescriptor* field = descriptor_->field(i);
|
||||||
|
field_generators_.get(field).GenerateEqualsCode(printer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params_.store_unknown_fields()) {
|
||||||
|
printer->Print(
|
||||||
|
"return unknownFieldDataEquals(other);\n");
|
||||||
|
} else {
|
||||||
|
printer->Print(
|
||||||
|
"return true;\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageGenerator::GenerateHashCode(io::Printer* printer) {
|
||||||
|
if (descriptor_->field_count() == 0 && !params_.store_unknown_fields()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printer->Print(
|
||||||
|
"\n"
|
||||||
|
"@Override\n"
|
||||||
|
"public int hashCode() {\n");
|
||||||
|
printer->Indent();
|
||||||
|
|
||||||
|
printer->Print("int result = 17;\n");
|
||||||
|
printer->Print("result = 31 * result + getClass().getName().hashCode();\n");
|
||||||
|
for (int i = 0; i < descriptor_->field_count(); i++) {
|
||||||
|
const FieldDescriptor* field = descriptor_->field(i);
|
||||||
|
field_generators_.get(field).GenerateHashCodeCode(printer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params_.store_unknown_fields()) {
|
||||||
|
printer->Print(
|
||||||
|
"result = 31 * result + unknownFieldDataHashCode();\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printer->Print("return result;\n");
|
||||||
|
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===================================================================
|
||||||
|
|
||||||
|
} // namespace javanano
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace protobuf
|
||||||
|
} // namespace google
|
95
src/google/protobuf/compiler/javanano/javanano_message.h
Normal file
95
src/google/protobuf/compiler/javanano/javanano_message.h
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: kenton@google.com (Kenton Varda)
|
||||||
|
// Based on original Protocol Buffers design by
|
||||||
|
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||||
|
|
||||||
|
#ifndef GOOGLE_PROTOBUF_COMPILER_JAVANANO_MESSAGE_H__
|
||||||
|
#define GOOGLE_PROTOBUF_COMPILER_JAVANANO_MESSAGE_H__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_helpers.h>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_field.h>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_params.h>
|
||||||
|
#include <google/protobuf/stubs/common.h>
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
namespace protobuf {
|
||||||
|
namespace io {
|
||||||
|
class Printer; // printer.h
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace protobuf {
|
||||||
|
namespace compiler {
|
||||||
|
namespace javanano {
|
||||||
|
|
||||||
|
class MessageGenerator {
|
||||||
|
public:
|
||||||
|
explicit MessageGenerator(const Descriptor* descriptor, const Params& params);
|
||||||
|
~MessageGenerator();
|
||||||
|
|
||||||
|
// All static variables have to be declared at the top-level of the file
|
||||||
|
// so that we can control initialization order, which is important for
|
||||||
|
// DescriptorProto bootstrapping to work.
|
||||||
|
void GenerateStaticVariables(io::Printer* printer);
|
||||||
|
|
||||||
|
// Output code which initializes the static variables generated by
|
||||||
|
// GenerateStaticVariables().
|
||||||
|
void GenerateStaticVariableInitializers(io::Printer* printer);
|
||||||
|
|
||||||
|
// Generate the class itself.
|
||||||
|
void Generate(io::Printer* printer);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void GenerateMessageSerializationMethods(io::Printer* printer);
|
||||||
|
void GenerateMergeFromMethods(io::Printer* printer);
|
||||||
|
void GenerateParseFromMethods(io::Printer* printer);
|
||||||
|
void GenerateSerializeOneField(io::Printer* printer,
|
||||||
|
const FieldDescriptor* field);
|
||||||
|
|
||||||
|
void GenerateClear(io::Printer* printer);
|
||||||
|
void GenerateEquals(io::Printer* printer);
|
||||||
|
void GenerateHashCode(io::Printer* printer);
|
||||||
|
|
||||||
|
const Params& params_;
|
||||||
|
const Descriptor* descriptor_;
|
||||||
|
FieldGeneratorMap field_generators_;
|
||||||
|
|
||||||
|
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace javanano
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace protobuf
|
||||||
|
|
||||||
|
} // namespace google
|
||||||
|
#endif // GOOGLE_PROTOBUF_COMPILER_JAVANANO_MESSAGE_H__
|
259
src/google/protobuf/compiler/javanano/javanano_message_field.cc
Normal file
259
src/google/protobuf/compiler/javanano/javanano_message_field.cc
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: kenton@google.com (Kenton Varda)
|
||||||
|
// Based on original Protocol Buffers design by
|
||||||
|
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_message_field.h>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_helpers.h>
|
||||||
|
#include <google/protobuf/io/printer.h>
|
||||||
|
#include <google/protobuf/wire_format.h>
|
||||||
|
#include <google/protobuf/stubs/strutil.h>
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
namespace protobuf {
|
||||||
|
namespace compiler {
|
||||||
|
namespace javanano {
|
||||||
|
|
||||||
|
using internal::WireFormat;
|
||||||
|
using internal::WireFormatLite;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of
|
||||||
|
// repeat code between this and the other field types.
|
||||||
|
void SetMessageVariables(const Params& params,
|
||||||
|
const FieldDescriptor* descriptor, map<string, string>* variables) {
|
||||||
|
(*variables)["name"] =
|
||||||
|
RenameJavaKeywords(UnderscoresToCamelCase(descriptor));
|
||||||
|
(*variables)["capitalized_name"] =
|
||||||
|
RenameJavaKeywords(UnderscoresToCapitalizedCamelCase(descriptor));
|
||||||
|
(*variables)["number"] = SimpleItoa(descriptor->number());
|
||||||
|
(*variables)["type"] = ClassName(params, descriptor->message_type());
|
||||||
|
(*variables)["group_or_message"] =
|
||||||
|
(descriptor->type() == FieldDescriptor::TYPE_GROUP) ?
|
||||||
|
"Group" : "Message";
|
||||||
|
(*variables)["message_name"] = descriptor->containing_type()->name();
|
||||||
|
//(*variables)["message_type"] = descriptor->message_type()->name();
|
||||||
|
(*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// ===================================================================
|
||||||
|
|
||||||
|
MessageFieldGenerator::
|
||||||
|
MessageFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
|
||||||
|
: FieldGenerator(params), descriptor_(descriptor) {
|
||||||
|
SetMessageVariables(params, descriptor, &variables_);
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageFieldGenerator::~MessageFieldGenerator() {}
|
||||||
|
|
||||||
|
void MessageFieldGenerator::
|
||||||
|
GenerateMembers(io::Printer* printer, bool /* unused lazy_init */) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"public $type$ $name$;\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageFieldGenerator::
|
||||||
|
GenerateClearCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"$name$ = null;\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageFieldGenerator::
|
||||||
|
GenerateMergingCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (this.$name$ == null) {\n"
|
||||||
|
" this.$name$ = new $type$();\n"
|
||||||
|
"}\n");
|
||||||
|
|
||||||
|
if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"input.readGroup(this.$name$, $number$);\n");
|
||||||
|
} else {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"input.readMessage(this.$name$);\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageFieldGenerator::
|
||||||
|
GenerateSerializationCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (this.$name$ != null) {\n"
|
||||||
|
" output.write$group_or_message$($number$, this.$name$);\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageFieldGenerator::
|
||||||
|
GenerateSerializedSizeCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (this.$name$ != null) {\n"
|
||||||
|
" size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
|
||||||
|
" .compute$group_or_message$Size($number$, this.$name$);\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageFieldGenerator::
|
||||||
|
GenerateEqualsCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (this.$name$ == null) { \n"
|
||||||
|
" if (other.$name$ != null) {\n"
|
||||||
|
" return false;\n"
|
||||||
|
" }\n"
|
||||||
|
"} else {\n"
|
||||||
|
" if (!this.$name$.equals(other.$name$)) {\n"
|
||||||
|
" return false;\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageFieldGenerator::
|
||||||
|
GenerateHashCodeCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"result = 31 * result +\n"
|
||||||
|
" (this.$name$ == null ? 0 : this.$name$.hashCode());\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===================================================================
|
||||||
|
|
||||||
|
RepeatedMessageFieldGenerator::
|
||||||
|
RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
|
||||||
|
: FieldGenerator(params), descriptor_(descriptor) {
|
||||||
|
SetMessageVariables(params, descriptor, &variables_);
|
||||||
|
}
|
||||||
|
|
||||||
|
RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
|
||||||
|
|
||||||
|
void RepeatedMessageFieldGenerator::
|
||||||
|
GenerateMembers(io::Printer* printer, bool /* unused lazy_init */) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"public $type$[] $name$;\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RepeatedMessageFieldGenerator::
|
||||||
|
GenerateClearCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"$name$ = $type$.emptyArray();\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RepeatedMessageFieldGenerator::
|
||||||
|
GenerateMergingCode(io::Printer* printer) const {
|
||||||
|
// First, figure out the length of the array, then parse.
|
||||||
|
printer->Print(variables_,
|
||||||
|
"int arrayLength = com.google.protobuf.nano.WireFormatNano\n"
|
||||||
|
" .getRepeatedFieldArrayLength(input, $tag$);\n"
|
||||||
|
"int i = this.$name$ == null ? 0 : this.$name$.length;\n"
|
||||||
|
"$type$[] newArray =\n"
|
||||||
|
" new $type$[i + arrayLength];\n"
|
||||||
|
"if (i != 0) {\n"
|
||||||
|
" java.lang.System.arraycopy(this.$name$, 0, newArray, 0, i);\n"
|
||||||
|
"}\n"
|
||||||
|
"for (; i < newArray.length - 1; i++) {\n"
|
||||||
|
" newArray[i] = new $type$();\n");
|
||||||
|
|
||||||
|
if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
" input.readGroup(newArray[i], $number$);\n");
|
||||||
|
} else {
|
||||||
|
printer->Print(variables_,
|
||||||
|
" input.readMessage(newArray[i]);\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printer->Print(variables_,
|
||||||
|
" input.readTag();\n"
|
||||||
|
"}\n"
|
||||||
|
"// Last one without readTag.\n"
|
||||||
|
"newArray[i] = new $type$();\n");
|
||||||
|
|
||||||
|
if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"input.readGroup(newArray[i], $number$);\n");
|
||||||
|
} else {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"input.readMessage(newArray[i]);\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printer->Print(variables_,
|
||||||
|
"this.$name$ = newArray;\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RepeatedMessageFieldGenerator::
|
||||||
|
GenerateSerializationCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (this.$name$ != null && this.$name$.length > 0) {\n"
|
||||||
|
" for (int i = 0; i < this.$name$.length; i++) {\n"
|
||||||
|
" $type$ element = this.$name$[i];\n"
|
||||||
|
" if (element != null) {\n"
|
||||||
|
" output.write$group_or_message$($number$, element);\n"
|
||||||
|
" }\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RepeatedMessageFieldGenerator::
|
||||||
|
GenerateSerializedSizeCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (this.$name$ != null && this.$name$.length > 0) {\n"
|
||||||
|
" for (int i = 0; i < this.$name$.length; i++) {\n"
|
||||||
|
" $type$ element = this.$name$[i];\n"
|
||||||
|
" if (element != null) {\n"
|
||||||
|
" size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
|
||||||
|
" .compute$group_or_message$Size($number$, element);\n"
|
||||||
|
" }\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RepeatedMessageFieldGenerator::
|
||||||
|
GenerateEqualsCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (!com.google.protobuf.nano.InternalNano.equals(\n"
|
||||||
|
" this.$name$, other.$name$)) {\n"
|
||||||
|
" return false;\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RepeatedMessageFieldGenerator::
|
||||||
|
GenerateHashCodeCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"result = 31 * result\n"
|
||||||
|
" + com.google.protobuf.nano.InternalNano.hashCode(this.$name$);\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace javanano
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace protobuf
|
||||||
|
} // namespace google
|
@ -0,0 +1,96 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: kenton@google.com (Kenton Varda)
|
||||||
|
// Based on original Protocol Buffers design by
|
||||||
|
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||||
|
|
||||||
|
#ifndef GOOGLE_PROTOBUF_COMPILER_JAVANANO_MESSAGE_FIELD_H__
|
||||||
|
#define GOOGLE_PROTOBUF_COMPILER_JAVANANO_MESSAGE_FIELD_H__
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_field.h>
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
namespace protobuf {
|
||||||
|
namespace compiler {
|
||||||
|
namespace javanano {
|
||||||
|
|
||||||
|
class MessageFieldGenerator : public FieldGenerator {
|
||||||
|
public:
|
||||||
|
explicit MessageFieldGenerator(
|
||||||
|
const FieldDescriptor* descriptor, const Params& params);
|
||||||
|
~MessageFieldGenerator();
|
||||||
|
|
||||||
|
// implements FieldGenerator ---------------------------------------
|
||||||
|
void GenerateMembers(io::Printer* printer, bool lazy_init) const;
|
||||||
|
void GenerateClearCode(io::Printer* printer) const;
|
||||||
|
void GenerateMergingCode(io::Printer* printer) const;
|
||||||
|
void GenerateSerializationCode(io::Printer* printer) const;
|
||||||
|
void GenerateSerializedSizeCode(io::Printer* printer) const;
|
||||||
|
void GenerateEqualsCode(io::Printer* printer) const;
|
||||||
|
void GenerateHashCodeCode(io::Printer* printer) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const FieldDescriptor* descriptor_;
|
||||||
|
map<string, string> variables_;
|
||||||
|
|
||||||
|
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator);
|
||||||
|
};
|
||||||
|
|
||||||
|
class RepeatedMessageFieldGenerator : public FieldGenerator {
|
||||||
|
public:
|
||||||
|
explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
|
||||||
|
const Params& params);
|
||||||
|
~RepeatedMessageFieldGenerator();
|
||||||
|
|
||||||
|
// implements FieldGenerator ---------------------------------------
|
||||||
|
void GenerateMembers(io::Printer* printer, bool lazy_init) const;
|
||||||
|
void GenerateClearCode(io::Printer* printer) const;
|
||||||
|
void GenerateMergingCode(io::Printer* printer) const;
|
||||||
|
void GenerateSerializationCode(io::Printer* printer) const;
|
||||||
|
void GenerateSerializedSizeCode(io::Printer* printer) const;
|
||||||
|
void GenerateEqualsCode(io::Printer* printer) const;
|
||||||
|
void GenerateHashCodeCode(io::Printer* printer) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const FieldDescriptor* descriptor_;
|
||||||
|
map<string, string> variables_;
|
||||||
|
|
||||||
|
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace javanano
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace protobuf
|
||||||
|
|
||||||
|
} // namespace google
|
||||||
|
#endif // GOOGLE_PROTOBUF_COMPILER_JAVANANO_MESSAGE_FIELD_H__
|
240
src/google/protobuf/compiler/javanano/javanano_params.h
Normal file
240
src/google/protobuf/compiler/javanano/javanano_params.h
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2010 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: wink@google.com (Wink Saville)
|
||||||
|
|
||||||
|
#ifndef PROTOBUF_COMPILER_JAVANANO_JAVANANO_PARAMS_H_
|
||||||
|
#define PROTOBUF_COMPILER_JAVANANO_JAVANANO_PARAMS_H_
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
#include <google/protobuf/stubs/strutil.h>
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
namespace protobuf {
|
||||||
|
namespace compiler {
|
||||||
|
namespace javanano {
|
||||||
|
|
||||||
|
enum eMultipleFiles { JAVANANO_MUL_UNSET, JAVANANO_MUL_FALSE, JAVANANO_MUL_TRUE };
|
||||||
|
|
||||||
|
// Parameters for used by the generators
|
||||||
|
class Params {
|
||||||
|
public:
|
||||||
|
typedef map<string, string> NameMap;
|
||||||
|
typedef set<string> NameSet;
|
||||||
|
private:
|
||||||
|
string empty_;
|
||||||
|
string base_name_;
|
||||||
|
eMultipleFiles override_java_multiple_files_;
|
||||||
|
bool store_unknown_fields_;
|
||||||
|
NameMap java_packages_;
|
||||||
|
NameMap java_outer_classnames_;
|
||||||
|
NameSet java_multiple_files_;
|
||||||
|
bool generate_has_;
|
||||||
|
bool java_enum_style_;
|
||||||
|
bool optional_field_accessors_;
|
||||||
|
bool use_reference_types_for_primitives_;
|
||||||
|
bool generate_equals_;
|
||||||
|
bool ignore_services_;
|
||||||
|
bool parcelable_messages_;
|
||||||
|
bool reftypes_primitive_enums_;
|
||||||
|
bool generate_clear_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Params(const string & base_name) :
|
||||||
|
empty_(""),
|
||||||
|
base_name_(base_name),
|
||||||
|
override_java_multiple_files_(JAVANANO_MUL_UNSET),
|
||||||
|
store_unknown_fields_(false),
|
||||||
|
generate_has_(false),
|
||||||
|
java_enum_style_(false),
|
||||||
|
optional_field_accessors_(false),
|
||||||
|
use_reference_types_for_primitives_(false),
|
||||||
|
generate_equals_(false),
|
||||||
|
ignore_services_(false),
|
||||||
|
parcelable_messages_(false),
|
||||||
|
reftypes_primitive_enums_(false),
|
||||||
|
generate_clear_(true) {
|
||||||
|
}
|
||||||
|
|
||||||
|
const string& base_name() const {
|
||||||
|
return base_name_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has_java_package(const string& file_name) const {
|
||||||
|
return java_packages_.find(file_name)
|
||||||
|
!= java_packages_.end();
|
||||||
|
}
|
||||||
|
void set_java_package(const string& file_name,
|
||||||
|
const string& java_package) {
|
||||||
|
java_packages_[file_name] = java_package;
|
||||||
|
}
|
||||||
|
const string& java_package(const string& file_name) const {
|
||||||
|
NameMap::const_iterator itr;
|
||||||
|
|
||||||
|
itr = java_packages_.find(file_name);
|
||||||
|
if (itr == java_packages_.end()) {
|
||||||
|
return empty_;
|
||||||
|
} else {
|
||||||
|
return itr->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const NameMap& java_packages() {
|
||||||
|
return java_packages_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has_java_outer_classname(const string& file_name) const {
|
||||||
|
return java_outer_classnames_.find(file_name)
|
||||||
|
!= java_outer_classnames_.end();
|
||||||
|
}
|
||||||
|
void set_java_outer_classname(const string& file_name,
|
||||||
|
const string& java_outer_classname) {
|
||||||
|
java_outer_classnames_[file_name] = java_outer_classname;
|
||||||
|
}
|
||||||
|
const string& java_outer_classname(const string& file_name) const {
|
||||||
|
NameMap::const_iterator itr;
|
||||||
|
|
||||||
|
itr = java_outer_classnames_.find(file_name);
|
||||||
|
if (itr == java_outer_classnames_.end()) {
|
||||||
|
return empty_;
|
||||||
|
} else {
|
||||||
|
return itr->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const NameMap& java_outer_classnames() {
|
||||||
|
return java_outer_classnames_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_override_java_multiple_files(bool java_multiple_files) {
|
||||||
|
if (java_multiple_files) {
|
||||||
|
override_java_multiple_files_ = JAVANANO_MUL_TRUE;
|
||||||
|
} else {
|
||||||
|
override_java_multiple_files_ = JAVANANO_MUL_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void clear_override_java_multiple_files() {
|
||||||
|
override_java_multiple_files_ = JAVANANO_MUL_UNSET;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_java_multiple_files(const string& file_name, bool value) {
|
||||||
|
if (value) {
|
||||||
|
java_multiple_files_.insert(file_name);
|
||||||
|
} else {
|
||||||
|
java_multiple_files_.erase(file_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool java_multiple_files(const string& file_name) const {
|
||||||
|
switch (override_java_multiple_files_) {
|
||||||
|
case JAVANANO_MUL_FALSE:
|
||||||
|
return false;
|
||||||
|
case JAVANANO_MUL_TRUE:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return java_multiple_files_.find(file_name)
|
||||||
|
!= java_multiple_files_.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_store_unknown_fields(bool value) {
|
||||||
|
store_unknown_fields_ = value;
|
||||||
|
}
|
||||||
|
bool store_unknown_fields() const {
|
||||||
|
return store_unknown_fields_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_generate_has(bool value) {
|
||||||
|
generate_has_ = value;
|
||||||
|
}
|
||||||
|
bool generate_has() const {
|
||||||
|
return generate_has_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_java_enum_style(bool value) {
|
||||||
|
java_enum_style_ = value;
|
||||||
|
}
|
||||||
|
bool java_enum_style() const {
|
||||||
|
return java_enum_style_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_optional_field_accessors(bool value) {
|
||||||
|
optional_field_accessors_ = value;
|
||||||
|
}
|
||||||
|
bool optional_field_accessors() const {
|
||||||
|
return optional_field_accessors_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_use_reference_types_for_primitives(bool value) {
|
||||||
|
use_reference_types_for_primitives_ = value;
|
||||||
|
}
|
||||||
|
bool use_reference_types_for_primitives() const {
|
||||||
|
return use_reference_types_for_primitives_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_generate_equals(bool value) {
|
||||||
|
generate_equals_ = value;
|
||||||
|
}
|
||||||
|
bool generate_equals() const {
|
||||||
|
return generate_equals_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_ignore_services(bool value) {
|
||||||
|
ignore_services_ = value;
|
||||||
|
}
|
||||||
|
bool ignore_services() const {
|
||||||
|
return ignore_services_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_parcelable_messages(bool value) {
|
||||||
|
parcelable_messages_ = value;
|
||||||
|
}
|
||||||
|
bool parcelable_messages() const {
|
||||||
|
return parcelable_messages_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_reftypes_primitive_enums(bool value) {
|
||||||
|
reftypes_primitive_enums_ = value;
|
||||||
|
}
|
||||||
|
bool reftypes_primitive_enums() const {
|
||||||
|
return reftypes_primitive_enums_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_generate_clear(bool value) {
|
||||||
|
generate_clear_ = value;
|
||||||
|
}
|
||||||
|
bool generate_clear() const {
|
||||||
|
return generate_clear_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace javanano
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace protobuf
|
||||||
|
} // namespace google
|
||||||
|
#endif // PROTOBUF_COMPILER_JAVANANO_JAVANANO_PARAMS_H_
|
@ -0,0 +1,910 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: kenton@google.com (Kenton Varda)
|
||||||
|
// Based on original Protocol Buffers design by
|
||||||
|
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <math.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_primitive_field.h>
|
||||||
|
#include <google/protobuf/stubs/common.h>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_helpers.h>
|
||||||
|
#include <google/protobuf/io/printer.h>
|
||||||
|
#include <google/protobuf/wire_format.h>
|
||||||
|
#include <google/protobuf/stubs/strutil.h>
|
||||||
|
#include <google/protobuf/stubs/substitute.h>
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
namespace protobuf {
|
||||||
|
namespace compiler {
|
||||||
|
namespace javanano {
|
||||||
|
|
||||||
|
using internal::WireFormat;
|
||||||
|
using internal::WireFormatLite;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
bool IsReferenceType(JavaType type) {
|
||||||
|
switch (type) {
|
||||||
|
case JAVATYPE_INT : return false;
|
||||||
|
case JAVATYPE_LONG : return false;
|
||||||
|
case JAVATYPE_FLOAT : return false;
|
||||||
|
case JAVATYPE_DOUBLE : return false;
|
||||||
|
case JAVATYPE_BOOLEAN: return false;
|
||||||
|
case JAVATYPE_STRING : return true;
|
||||||
|
case JAVATYPE_BYTES : return true;
|
||||||
|
case JAVATYPE_ENUM : return false;
|
||||||
|
case JAVATYPE_MESSAGE: return true;
|
||||||
|
|
||||||
|
// No default because we want the compiler to complain if any new
|
||||||
|
// JavaTypes are added.
|
||||||
|
}
|
||||||
|
|
||||||
|
GOOGLE_LOG(FATAL) << "Can't get here.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsArrayType(JavaType type) {
|
||||||
|
switch (type) {
|
||||||
|
case JAVATYPE_INT : return false;
|
||||||
|
case JAVATYPE_LONG : return false;
|
||||||
|
case JAVATYPE_FLOAT : return false;
|
||||||
|
case JAVATYPE_DOUBLE : return false;
|
||||||
|
case JAVATYPE_BOOLEAN: return false;
|
||||||
|
case JAVATYPE_STRING : return false;
|
||||||
|
case JAVATYPE_BYTES : return true;
|
||||||
|
case JAVATYPE_ENUM : return false;
|
||||||
|
case JAVATYPE_MESSAGE: return false;
|
||||||
|
|
||||||
|
// No default because we want the compiler to complain if any new
|
||||||
|
// JavaTypes are added.
|
||||||
|
}
|
||||||
|
|
||||||
|
GOOGLE_LOG(FATAL) << "Can't get here.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* GetCapitalizedType(const FieldDescriptor* field) {
|
||||||
|
switch (field->type()) {
|
||||||
|
case FieldDescriptor::TYPE_INT32 : return "Int32" ;
|
||||||
|
case FieldDescriptor::TYPE_UINT32 : return "UInt32" ;
|
||||||
|
case FieldDescriptor::TYPE_SINT32 : return "SInt32" ;
|
||||||
|
case FieldDescriptor::TYPE_FIXED32 : return "Fixed32" ;
|
||||||
|
case FieldDescriptor::TYPE_SFIXED32: return "SFixed32";
|
||||||
|
case FieldDescriptor::TYPE_INT64 : return "Int64" ;
|
||||||
|
case FieldDescriptor::TYPE_UINT64 : return "UInt64" ;
|
||||||
|
case FieldDescriptor::TYPE_SINT64 : return "SInt64" ;
|
||||||
|
case FieldDescriptor::TYPE_FIXED64 : return "Fixed64" ;
|
||||||
|
case FieldDescriptor::TYPE_SFIXED64: return "SFixed64";
|
||||||
|
case FieldDescriptor::TYPE_FLOAT : return "Float" ;
|
||||||
|
case FieldDescriptor::TYPE_DOUBLE : return "Double" ;
|
||||||
|
case FieldDescriptor::TYPE_BOOL : return "Bool" ;
|
||||||
|
case FieldDescriptor::TYPE_STRING : return "String" ;
|
||||||
|
case FieldDescriptor::TYPE_BYTES : return "Bytes" ;
|
||||||
|
case FieldDescriptor::TYPE_ENUM : return "Enum" ;
|
||||||
|
case FieldDescriptor::TYPE_GROUP : return "Group" ;
|
||||||
|
case FieldDescriptor::TYPE_MESSAGE : return "Message" ;
|
||||||
|
|
||||||
|
// No default because we want the compiler to complain if any new
|
||||||
|
// types are added.
|
||||||
|
}
|
||||||
|
|
||||||
|
GOOGLE_LOG(FATAL) << "Can't get here.";
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For encodings with fixed sizes, returns that size in bytes. Otherwise
|
||||||
|
// returns -1.
|
||||||
|
int FixedSize(FieldDescriptor::Type type) {
|
||||||
|
switch (type) {
|
||||||
|
case FieldDescriptor::TYPE_INT32 : return -1;
|
||||||
|
case FieldDescriptor::TYPE_INT64 : return -1;
|
||||||
|
case FieldDescriptor::TYPE_UINT32 : return -1;
|
||||||
|
case FieldDescriptor::TYPE_UINT64 : return -1;
|
||||||
|
case FieldDescriptor::TYPE_SINT32 : return -1;
|
||||||
|
case FieldDescriptor::TYPE_SINT64 : return -1;
|
||||||
|
case FieldDescriptor::TYPE_FIXED32 : return WireFormatLite::kFixed32Size;
|
||||||
|
case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size;
|
||||||
|
case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size;
|
||||||
|
case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size;
|
||||||
|
case FieldDescriptor::TYPE_FLOAT : return WireFormatLite::kFloatSize;
|
||||||
|
case FieldDescriptor::TYPE_DOUBLE : return WireFormatLite::kDoubleSize;
|
||||||
|
|
||||||
|
case FieldDescriptor::TYPE_BOOL : return WireFormatLite::kBoolSize;
|
||||||
|
case FieldDescriptor::TYPE_ENUM : return -1;
|
||||||
|
|
||||||
|
case FieldDescriptor::TYPE_STRING : return -1;
|
||||||
|
case FieldDescriptor::TYPE_BYTES : return -1;
|
||||||
|
case FieldDescriptor::TYPE_GROUP : return -1;
|
||||||
|
case FieldDescriptor::TYPE_MESSAGE : return -1;
|
||||||
|
|
||||||
|
// No default because we want the compiler to complain if any new
|
||||||
|
// types are added.
|
||||||
|
}
|
||||||
|
GOOGLE_LOG(FATAL) << "Can't get here.";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return true if the type is a that has variable length
|
||||||
|
// for instance String's.
|
||||||
|
bool IsVariableLenType(JavaType type) {
|
||||||
|
switch (type) {
|
||||||
|
case JAVATYPE_INT : return false;
|
||||||
|
case JAVATYPE_LONG : return false;
|
||||||
|
case JAVATYPE_FLOAT : return false;
|
||||||
|
case JAVATYPE_DOUBLE : return false;
|
||||||
|
case JAVATYPE_BOOLEAN: return false;
|
||||||
|
case JAVATYPE_STRING : return true;
|
||||||
|
case JAVATYPE_BYTES : return true;
|
||||||
|
case JAVATYPE_ENUM : return false;
|
||||||
|
case JAVATYPE_MESSAGE: return true;
|
||||||
|
|
||||||
|
// No default because we want the compiler to complain if any new
|
||||||
|
// JavaTypes are added.
|
||||||
|
}
|
||||||
|
|
||||||
|
GOOGLE_LOG(FATAL) << "Can't get here.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AllAscii(const string& text) {
|
||||||
|
for (int i = 0; i < text.size(); i++) {
|
||||||
|
if ((text[i] & 0x80) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetPrimitiveVariables(const FieldDescriptor* descriptor, const Params params,
|
||||||
|
map<string, string>* variables) {
|
||||||
|
(*variables)["name"] =
|
||||||
|
RenameJavaKeywords(UnderscoresToCamelCase(descriptor));
|
||||||
|
(*variables)["capitalized_name"] =
|
||||||
|
RenameJavaKeywords(UnderscoresToCapitalizedCamelCase(descriptor));
|
||||||
|
(*variables)["number"] = SimpleItoa(descriptor->number());
|
||||||
|
if (params.use_reference_types_for_primitives()
|
||||||
|
&& !descriptor->is_repeated()) {
|
||||||
|
(*variables)["type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor));
|
||||||
|
} else {
|
||||||
|
(*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor));
|
||||||
|
}
|
||||||
|
// Deals with defaults. For C++-string types (string and bytes),
|
||||||
|
// we might need to have the generated code do the unicode decoding
|
||||||
|
// (see comments in InternalNano.java for gory details.). We would
|
||||||
|
// like to do this once into a static field and re-use that from
|
||||||
|
// then on.
|
||||||
|
if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
|
||||||
|
!descriptor->default_value_string().empty() &&
|
||||||
|
!params.use_reference_types_for_primitives()) {
|
||||||
|
if (descriptor->type() == FieldDescriptor::TYPE_BYTES) {
|
||||||
|
(*variables)["default"] = DefaultValue(params, descriptor);
|
||||||
|
(*variables)["default_constant"] = FieldDefaultConstantName(descriptor);
|
||||||
|
(*variables)["default_constant_value"] = strings::Substitute(
|
||||||
|
"com.google.protobuf.nano.InternalNano.bytesDefaultValue(\"$0\")",
|
||||||
|
CEscape(descriptor->default_value_string()));
|
||||||
|
(*variables)["default_copy_if_needed"] =
|
||||||
|
(*variables)["default"] + ".clone()";
|
||||||
|
} else if (AllAscii(descriptor->default_value_string())) {
|
||||||
|
// All chars are ASCII. In this case directly referencing a
|
||||||
|
// CEscape()'d string literal works fine.
|
||||||
|
(*variables)["default"] =
|
||||||
|
"\"" + CEscape(descriptor->default_value_string()) + "\"";
|
||||||
|
(*variables)["default_copy_if_needed"] = (*variables)["default"];
|
||||||
|
} else {
|
||||||
|
// Strings where some chars are non-ASCII. We need to save the
|
||||||
|
// default value.
|
||||||
|
(*variables)["default"] = DefaultValue(params, descriptor);
|
||||||
|
(*variables)["default_constant"] = FieldDefaultConstantName(descriptor);
|
||||||
|
(*variables)["default_constant_value"] = strings::Substitute(
|
||||||
|
"com.google.protobuf.nano.InternalNano.stringDefaultValue(\"$0\")",
|
||||||
|
CEscape(descriptor->default_value_string()));
|
||||||
|
(*variables)["default_copy_if_needed"] = (*variables)["default"];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Non-string, non-bytes field. Defaults are literals.
|
||||||
|
(*variables)["default"] = DefaultValue(params, descriptor);
|
||||||
|
(*variables)["default_copy_if_needed"] = (*variables)["default"];
|
||||||
|
}
|
||||||
|
(*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor));
|
||||||
|
(*variables)["capitalized_type"] = GetCapitalizedType(descriptor);
|
||||||
|
(*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
|
||||||
|
(*variables)["tag_size"] = SimpleItoa(
|
||||||
|
WireFormat::TagSize(descriptor->number(), descriptor->type()));
|
||||||
|
(*variables)["non_packed_tag"] = SimpleItoa(
|
||||||
|
internal::WireFormatLite::MakeTag(descriptor->number(),
|
||||||
|
internal::WireFormat::WireTypeForFieldType(descriptor->type())));
|
||||||
|
int fixed_size = FixedSize(descriptor->type());
|
||||||
|
if (fixed_size != -1) {
|
||||||
|
(*variables)["fixed_size"] = SimpleItoa(fixed_size);
|
||||||
|
}
|
||||||
|
(*variables)["message_name"] = descriptor->containing_type()->name();
|
||||||
|
(*variables)["empty_array_name"] = EmptyArrayName(params, descriptor);
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// ===================================================================
|
||||||
|
|
||||||
|
PrimitiveFieldGenerator::
|
||||||
|
PrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
|
||||||
|
: FieldGenerator(params), descriptor_(descriptor) {
|
||||||
|
SetPrimitiveVariables(descriptor, params, &variables_);
|
||||||
|
}
|
||||||
|
|
||||||
|
PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
|
||||||
|
|
||||||
|
bool PrimitiveFieldGenerator::SavedDefaultNeeded() const {
|
||||||
|
return variables_.find("default_constant") != variables_.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitiveFieldGenerator::GenerateInitSavedDefaultCode(io::Printer* printer) const {
|
||||||
|
if (variables_.find("default_constant") != variables_.end()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"$default_constant$ = $default_constant_value$;\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitiveFieldGenerator::
|
||||||
|
GenerateMembers(io::Printer* printer, bool lazy_init) const {
|
||||||
|
if (variables_.find("default_constant") != variables_.end()) {
|
||||||
|
// Those primitive types that need a saved default.
|
||||||
|
if (lazy_init) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"private static $type$ $default_constant$;\n");
|
||||||
|
} else {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"private static final $type$ $default_constant$ =\n"
|
||||||
|
" $default_constant_value$;\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printer->Print(variables_,
|
||||||
|
"public $type$ $name$;\n");
|
||||||
|
|
||||||
|
if (params_.generate_has()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"public boolean has$capitalized_name$;\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitiveFieldGenerator::
|
||||||
|
GenerateClearCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"$name$ = $default_copy_if_needed$;\n");
|
||||||
|
|
||||||
|
if (params_.generate_has()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"has$capitalized_name$ = false;\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitiveFieldGenerator::
|
||||||
|
GenerateMergingCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"this.$name$ = input.read$capitalized_type$();\n");
|
||||||
|
|
||||||
|
if (params_.generate_has()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"has$capitalized_name$ = true;\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitiveFieldGenerator::
|
||||||
|
GenerateSerializationConditional(io::Printer* printer) const {
|
||||||
|
if (params_.use_reference_types_for_primitives()) {
|
||||||
|
// For reference type mode, serialize based on equality
|
||||||
|
// to null.
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (this.$name$ != null) {\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (params_.generate_has()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (has$capitalized_name$ || ");
|
||||||
|
} else {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (");
|
||||||
|
}
|
||||||
|
JavaType java_type = GetJavaType(descriptor_);
|
||||||
|
if (IsArrayType(java_type)) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"!java.util.Arrays.equals(this.$name$, $default$)) {\n");
|
||||||
|
} else if (IsReferenceType(java_type)) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"!this.$name$.equals($default$)) {\n");
|
||||||
|
} else if (java_type == JAVATYPE_FLOAT) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"java.lang.Float.floatToIntBits(this.$name$)\n"
|
||||||
|
" != java.lang.Float.floatToIntBits($default$)) {\n");
|
||||||
|
} else if (java_type == JAVATYPE_DOUBLE) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"java.lang.Double.doubleToLongBits(this.$name$)\n"
|
||||||
|
" != java.lang.Double.doubleToLongBits($default$)) {\n");
|
||||||
|
} else {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"this.$name$ != $default$) {\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitiveFieldGenerator::
|
||||||
|
GenerateSerializationCode(io::Printer* printer) const {
|
||||||
|
if (descriptor_->is_required() && !params_.generate_has()) {
|
||||||
|
// Always serialize a required field if we don't have the 'has' signal.
|
||||||
|
printer->Print(variables_,
|
||||||
|
"output.write$capitalized_type$($number$, this.$name$);\n");
|
||||||
|
} else {
|
||||||
|
GenerateSerializationConditional(printer);
|
||||||
|
printer->Print(variables_,
|
||||||
|
" output.write$capitalized_type$($number$, this.$name$);\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitiveFieldGenerator::
|
||||||
|
GenerateSerializedSizeCode(io::Printer* printer) const {
|
||||||
|
if (descriptor_->is_required() && !params_.generate_has()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
|
||||||
|
" .compute$capitalized_type$Size($number$, this.$name$);\n");
|
||||||
|
} else {
|
||||||
|
GenerateSerializationConditional(printer);
|
||||||
|
printer->Print(variables_,
|
||||||
|
" size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
|
||||||
|
" .compute$capitalized_type$Size($number$, this.$name$);\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitiveFieldGenerator::
|
||||||
|
GenerateEqualsCode(io::Printer* printer) const {
|
||||||
|
// We define equality as serialized form equality. If generate_has(),
|
||||||
|
// then if the field value equals the default value in both messages,
|
||||||
|
// but one's 'has' field is set and the other's is not, the serialized
|
||||||
|
// forms are different and we should return false.
|
||||||
|
JavaType java_type = GetJavaType(descriptor_);
|
||||||
|
if (java_type == JAVATYPE_BYTES) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (!java.util.Arrays.equals(this.$name$, other.$name$)");
|
||||||
|
if (params_.generate_has()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"\n"
|
||||||
|
" || (java.util.Arrays.equals(this.$name$, $default$)\n"
|
||||||
|
" && this.has$capitalized_name$ != other.has$capitalized_name$)");
|
||||||
|
}
|
||||||
|
printer->Print(") {\n"
|
||||||
|
" return false;\n"
|
||||||
|
"}\n");
|
||||||
|
} else if (java_type == JAVATYPE_STRING
|
||||||
|
|| params_.use_reference_types_for_primitives()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (this.$name$ == null) {\n"
|
||||||
|
" if (other.$name$ != null) {\n"
|
||||||
|
" return false;\n"
|
||||||
|
" }\n"
|
||||||
|
"} else if (!this.$name$.equals(other.$name$)");
|
||||||
|
if (params_.generate_has()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"\n"
|
||||||
|
" || (this.$name$.equals($default$)\n"
|
||||||
|
" && this.has$capitalized_name$ != other.has$capitalized_name$)");
|
||||||
|
}
|
||||||
|
printer->Print(") {\n"
|
||||||
|
" return false;\n"
|
||||||
|
"}\n");
|
||||||
|
} else if (java_type == JAVATYPE_FLOAT) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"{\n"
|
||||||
|
" int bits = java.lang.Float.floatToIntBits(this.$name$);\n"
|
||||||
|
" if (bits != java.lang.Float.floatToIntBits(other.$name$)");
|
||||||
|
if (params_.generate_has()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"\n"
|
||||||
|
" || (bits == java.lang.Float.floatToIntBits($default$)\n"
|
||||||
|
" && this.has$capitalized_name$ != other.has$capitalized_name$)");
|
||||||
|
}
|
||||||
|
printer->Print(") {\n"
|
||||||
|
" return false;\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n");
|
||||||
|
} else if (java_type == JAVATYPE_DOUBLE) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"{\n"
|
||||||
|
" long bits = java.lang.Double.doubleToLongBits(this.$name$);\n"
|
||||||
|
" if (bits != java.lang.Double.doubleToLongBits(other.$name$)");
|
||||||
|
if (params_.generate_has()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"\n"
|
||||||
|
" || (bits == java.lang.Double.doubleToLongBits($default$)\n"
|
||||||
|
" && this.has$capitalized_name$ != other.has$capitalized_name$)");
|
||||||
|
}
|
||||||
|
printer->Print(") {\n"
|
||||||
|
" return false;\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n");
|
||||||
|
} else {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (this.$name$ != other.$name$");
|
||||||
|
if (params_.generate_has()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"\n"
|
||||||
|
" || (this.$name$ == $default$\n"
|
||||||
|
" && this.has$capitalized_name$ != other.has$capitalized_name$)");
|
||||||
|
}
|
||||||
|
printer->Print(") {\n"
|
||||||
|
" return false;\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitiveFieldGenerator::
|
||||||
|
GenerateHashCodeCode(io::Printer* printer) const {
|
||||||
|
JavaType java_type = GetJavaType(descriptor_);
|
||||||
|
if (java_type == JAVATYPE_BYTES) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"result = 31 * result + java.util.Arrays.hashCode(this.$name$);\n");
|
||||||
|
} else if (java_type == JAVATYPE_STRING
|
||||||
|
|| params_.use_reference_types_for_primitives()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"result = 31 * result\n"
|
||||||
|
" + (this.$name$ == null ? 0 : this.$name$.hashCode());\n");
|
||||||
|
} else {
|
||||||
|
switch (java_type) {
|
||||||
|
// For all Java primitive types below, the hash codes match the
|
||||||
|
// results of BoxedType.valueOf(primitiveValue).hashCode().
|
||||||
|
case JAVATYPE_INT:
|
||||||
|
printer->Print(variables_,
|
||||||
|
"result = 31 * result + this.$name$;\n");
|
||||||
|
break;
|
||||||
|
case JAVATYPE_LONG:
|
||||||
|
printer->Print(variables_,
|
||||||
|
"result = 31 * result\n"
|
||||||
|
" + (int) (this.$name$ ^ (this.$name$ >>> 32));\n");
|
||||||
|
break;
|
||||||
|
case JAVATYPE_FLOAT:
|
||||||
|
printer->Print(variables_,
|
||||||
|
"result = 31 * result\n"
|
||||||
|
" + java.lang.Float.floatToIntBits(this.$name$);\n");
|
||||||
|
break;
|
||||||
|
case JAVATYPE_DOUBLE:
|
||||||
|
printer->Print(variables_,
|
||||||
|
"{\n"
|
||||||
|
" long v = java.lang.Double.doubleToLongBits(this.$name$);\n"
|
||||||
|
" result = 31 * result + (int) (v ^ (v >>> 32));\n"
|
||||||
|
"}\n");
|
||||||
|
break;
|
||||||
|
case JAVATYPE_BOOLEAN:
|
||||||
|
printer->Print(variables_,
|
||||||
|
"result = 31 * result + (this.$name$ ? 1231 : 1237);\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
GOOGLE_LOG(ERROR) << "unknown java type for primitive field";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===================================================================
|
||||||
|
|
||||||
|
AccessorPrimitiveFieldGenerator::
|
||||||
|
AccessorPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
|
||||||
|
const Params& params, int has_bit_index)
|
||||||
|
: FieldGenerator(params), descriptor_(descriptor) {
|
||||||
|
SetPrimitiveVariables(descriptor, params, &variables_);
|
||||||
|
SetBitOperationVariables("has", has_bit_index, &variables_);
|
||||||
|
}
|
||||||
|
|
||||||
|
AccessorPrimitiveFieldGenerator::~AccessorPrimitiveFieldGenerator() {}
|
||||||
|
|
||||||
|
bool AccessorPrimitiveFieldGenerator::SavedDefaultNeeded() const {
|
||||||
|
return variables_.find("default_constant") != variables_.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccessorPrimitiveFieldGenerator::
|
||||||
|
GenerateInitSavedDefaultCode(io::Printer* printer) const {
|
||||||
|
if (variables_.find("default_constant") != variables_.end()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"$default_constant$ = $default_constant_value$;\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccessorPrimitiveFieldGenerator::
|
||||||
|
GenerateMembers(io::Printer* printer, bool lazy_init) const {
|
||||||
|
if (variables_.find("default_constant") != variables_.end()) {
|
||||||
|
// Those primitive types that need a saved default.
|
||||||
|
if (lazy_init) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"private static $type$ $default_constant$;\n");
|
||||||
|
} else {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"private static final $type$ $default_constant$ =\n"
|
||||||
|
" $default_constant_value$;\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printer->Print(variables_,
|
||||||
|
"private $type$ $name$_;\n"
|
||||||
|
"public $type$ get$capitalized_name$() {\n"
|
||||||
|
" return $name$_;\n"
|
||||||
|
"}\n"
|
||||||
|
"public $message_name$ set$capitalized_name$($type$ value) {\n");
|
||||||
|
if (IsReferenceType(GetJavaType(descriptor_))) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
" if (value == null) {\n"
|
||||||
|
" throw new java.lang.NullPointerException();\n"
|
||||||
|
" }\n");
|
||||||
|
}
|
||||||
|
printer->Print(variables_,
|
||||||
|
" $name$_ = value;\n"
|
||||||
|
" $set_has$;\n"
|
||||||
|
" return this;\n"
|
||||||
|
"}\n"
|
||||||
|
"public boolean has$capitalized_name$() {\n"
|
||||||
|
" return $get_has$;\n"
|
||||||
|
"}\n"
|
||||||
|
"public $message_name$ clear$capitalized_name$() {\n"
|
||||||
|
" $name$_ = $default_copy_if_needed$;\n"
|
||||||
|
" $clear_has$;\n"
|
||||||
|
" return this;\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccessorPrimitiveFieldGenerator::
|
||||||
|
GenerateClearCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"$name$_ = $default_copy_if_needed$;\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccessorPrimitiveFieldGenerator::
|
||||||
|
GenerateMergingCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"$name$_ = input.read$capitalized_type$();\n"
|
||||||
|
"$set_has$;\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccessorPrimitiveFieldGenerator::
|
||||||
|
GenerateSerializationCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if ($get_has$) {\n"
|
||||||
|
" output.write$capitalized_type$($number$, $name$_);\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccessorPrimitiveFieldGenerator::
|
||||||
|
GenerateSerializedSizeCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if ($get_has$) {\n"
|
||||||
|
" size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
|
||||||
|
" .compute$capitalized_type$Size($number$, $name$_);\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccessorPrimitiveFieldGenerator::
|
||||||
|
GenerateEqualsCode(io::Printer* printer) const {
|
||||||
|
switch (GetJavaType(descriptor_)) {
|
||||||
|
// For all Java primitive types below, the equality checks match the
|
||||||
|
// results of BoxedType.valueOf(primitiveValue).equals(otherValue).
|
||||||
|
case JAVATYPE_FLOAT:
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if ($different_has$\n"
|
||||||
|
" || java.lang.Float.floatToIntBits($name$_)\n"
|
||||||
|
" != java.lang.Float.floatToIntBits(other.$name$_)) {\n"
|
||||||
|
" return false;\n"
|
||||||
|
"}\n");
|
||||||
|
break;
|
||||||
|
case JAVATYPE_DOUBLE:
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if ($different_has$\n"
|
||||||
|
" || java.lang.Double.doubleToLongBits($name$_)\n"
|
||||||
|
" != java.lang.Double.doubleToLongBits(other.$name$_)) {\n"
|
||||||
|
" return false;\n"
|
||||||
|
"}\n");
|
||||||
|
break;
|
||||||
|
case JAVATYPE_INT:
|
||||||
|
case JAVATYPE_LONG:
|
||||||
|
case JAVATYPE_BOOLEAN:
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if ($different_has$\n"
|
||||||
|
" || $name$_ != other.$name$_) {\n"
|
||||||
|
" return false;\n"
|
||||||
|
"}\n");
|
||||||
|
break;
|
||||||
|
case JAVATYPE_STRING:
|
||||||
|
// Accessor style would guarantee $name$_ non-null
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if ($different_has$\n"
|
||||||
|
" || !$name$_.equals(other.$name$_)) {\n"
|
||||||
|
" return false;\n"
|
||||||
|
"}\n");
|
||||||
|
break;
|
||||||
|
case JAVATYPE_BYTES:
|
||||||
|
// Accessor style would guarantee $name$_ non-null
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if ($different_has$\n"
|
||||||
|
" || !java.util.Arrays.equals($name$_, other.$name$_)) {\n"
|
||||||
|
" return false;\n"
|
||||||
|
"}\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
GOOGLE_LOG(ERROR) << "unknown java type for primitive field";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccessorPrimitiveFieldGenerator::
|
||||||
|
GenerateHashCodeCode(io::Printer* printer) const {
|
||||||
|
switch (GetJavaType(descriptor_)) {
|
||||||
|
// For all Java primitive types below, the hash codes match the
|
||||||
|
// results of BoxedType.valueOf(primitiveValue).hashCode().
|
||||||
|
case JAVATYPE_INT:
|
||||||
|
printer->Print(variables_,
|
||||||
|
"result = 31 * result + $name$_;\n");
|
||||||
|
break;
|
||||||
|
case JAVATYPE_LONG:
|
||||||
|
printer->Print(variables_,
|
||||||
|
"result = 31 * result + (int) ($name$_ ^ ($name$_ >>> 32));\n");
|
||||||
|
break;
|
||||||
|
case JAVATYPE_FLOAT:
|
||||||
|
printer->Print(variables_,
|
||||||
|
"result = 31 * result +\n"
|
||||||
|
" java.lang.Float.floatToIntBits($name$_);\n");
|
||||||
|
break;
|
||||||
|
case JAVATYPE_DOUBLE:
|
||||||
|
printer->Print(variables_,
|
||||||
|
"{\n"
|
||||||
|
" long v = java.lang.Double.doubleToLongBits($name$_);\n"
|
||||||
|
" result = 31 * result + (int) (v ^ (v >>> 32));\n"
|
||||||
|
"}\n");
|
||||||
|
break;
|
||||||
|
case JAVATYPE_BOOLEAN:
|
||||||
|
printer->Print(variables_,
|
||||||
|
"result = 31 * result + ($name$_ ? 1231 : 1237);\n");
|
||||||
|
break;
|
||||||
|
case JAVATYPE_STRING:
|
||||||
|
// Accessor style would guarantee $name$_ non-null
|
||||||
|
printer->Print(variables_,
|
||||||
|
"result = 31 * result + $name$_.hashCode();\n");
|
||||||
|
break;
|
||||||
|
case JAVATYPE_BYTES:
|
||||||
|
// Accessor style would guarantee $name$_ non-null
|
||||||
|
printer->Print(variables_,
|
||||||
|
"result = 31 * result + java.util.Arrays.hashCode($name$_);\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
GOOGLE_LOG(ERROR) << "unknown java type for primitive field";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===================================================================
|
||||||
|
|
||||||
|
RepeatedPrimitiveFieldGenerator::
|
||||||
|
RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
|
||||||
|
: FieldGenerator(params), descriptor_(descriptor) {
|
||||||
|
SetPrimitiveVariables(descriptor, params, &variables_);
|
||||||
|
}
|
||||||
|
|
||||||
|
RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
|
||||||
|
|
||||||
|
void RepeatedPrimitiveFieldGenerator::
|
||||||
|
GenerateMembers(io::Printer* printer, bool /*unused init_defaults*/) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"public $type$[] $name$;\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RepeatedPrimitiveFieldGenerator::
|
||||||
|
GenerateClearCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"$name$ = $default$;\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RepeatedPrimitiveFieldGenerator::
|
||||||
|
GenerateMergingCode(io::Printer* printer) const {
|
||||||
|
// First, figure out the length of the array, then parse.
|
||||||
|
printer->Print(variables_,
|
||||||
|
"int arrayLength = com.google.protobuf.nano.WireFormatNano\n"
|
||||||
|
" .getRepeatedFieldArrayLength(input, $non_packed_tag$);\n"
|
||||||
|
"int i = this.$name$ == null ? 0 : this.$name$.length;\n");
|
||||||
|
|
||||||
|
if (GetJavaType(descriptor_) == JAVATYPE_BYTES) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"byte[][] newArray = new byte[i + arrayLength][];\n");
|
||||||
|
} else {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"$type$[] newArray = new $type$[i + arrayLength];\n");
|
||||||
|
}
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (i != 0) {\n"
|
||||||
|
" java.lang.System.arraycopy(this.$name$, 0, newArray, 0, i);\n"
|
||||||
|
"}\n"
|
||||||
|
"for (; i < newArray.length - 1; i++) {\n"
|
||||||
|
" newArray[i] = input.read$capitalized_type$();\n"
|
||||||
|
" input.readTag();\n"
|
||||||
|
"}\n"
|
||||||
|
"// Last one without readTag.\n"
|
||||||
|
"newArray[i] = input.read$capitalized_type$();\n"
|
||||||
|
"this.$name$ = newArray;\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RepeatedPrimitiveFieldGenerator::
|
||||||
|
GenerateMergingCodeFromPacked(io::Printer* printer) const {
|
||||||
|
printer->Print(
|
||||||
|
"int length = input.readRawVarint32();\n"
|
||||||
|
"int limit = input.pushLimit(length);\n");
|
||||||
|
|
||||||
|
// If we know the elements will all be of the same size, the arrayLength
|
||||||
|
// can be calculated much more easily. However, FixedSize() returns 1 for
|
||||||
|
// repeated bool fields, which are guaranteed to have the fixed size of
|
||||||
|
// 1 byte per value only if we control the output. On the wire they can
|
||||||
|
// legally appear as variable-size integers, so we need to use the slow
|
||||||
|
// way for repeated bool fields.
|
||||||
|
if (descriptor_->type() == FieldDescriptor::TYPE_BOOL
|
||||||
|
|| FixedSize(descriptor_->type()) == -1) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"// First pass to compute array length.\n"
|
||||||
|
"int arrayLength = 0;\n"
|
||||||
|
"int startPos = input.getPosition();\n"
|
||||||
|
"while (input.getBytesUntilLimit() > 0) {\n"
|
||||||
|
" input.read$capitalized_type$();\n"
|
||||||
|
" arrayLength++;\n"
|
||||||
|
"}\n"
|
||||||
|
"input.rewindToPosition(startPos);\n");
|
||||||
|
} else {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"int arrayLength = length / $fixed_size$;\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printer->Print(variables_,
|
||||||
|
"int i = this.$name$ == null ? 0 : this.$name$.length;\n"
|
||||||
|
"$type$[] newArray = new $type$[i + arrayLength];\n"
|
||||||
|
"if (i != 0) {\n"
|
||||||
|
" java.lang.System.arraycopy(this.$name$, 0, newArray, 0, i);\n"
|
||||||
|
"}\n"
|
||||||
|
"for (; i < newArray.length; i++) {\n"
|
||||||
|
" newArray[i] = input.read$capitalized_type$();\n"
|
||||||
|
"}\n"
|
||||||
|
"this.$name$ = newArray;\n"
|
||||||
|
"input.popLimit(limit);\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RepeatedPrimitiveFieldGenerator::
|
||||||
|
GenerateRepeatedDataSizeCode(io::Printer* printer) const {
|
||||||
|
// Creates a variable dataSize and puts the serialized size in there.
|
||||||
|
// If the element type is a Java reference type, also generates
|
||||||
|
// dataCount which stores the number of non-null elements in the field.
|
||||||
|
if (IsReferenceType(GetJavaType(descriptor_))) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"int dataCount = 0;\n"
|
||||||
|
"int dataSize = 0;\n"
|
||||||
|
"for (int i = 0; i < this.$name$.length; i++) {\n"
|
||||||
|
" $type$ element = this.$name$[i];\n"
|
||||||
|
" if (element != null) {\n"
|
||||||
|
" dataCount++;\n"
|
||||||
|
" dataSize += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
|
||||||
|
" .compute$capitalized_type$SizeNoTag(element);\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n");
|
||||||
|
} else if (FixedSize(descriptor_->type()) == -1) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"int dataSize = 0;\n"
|
||||||
|
"for (int i = 0; i < this.$name$.length; i++) {\n"
|
||||||
|
" $type$ element = this.$name$[i];\n"
|
||||||
|
" dataSize += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
|
||||||
|
" .compute$capitalized_type$SizeNoTag(element);\n"
|
||||||
|
"}\n");
|
||||||
|
} else {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"int dataSize = $fixed_size$ * this.$name$.length;\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RepeatedPrimitiveFieldGenerator::
|
||||||
|
GenerateSerializationCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (this.$name$ != null && this.$name$.length > 0) {\n");
|
||||||
|
printer->Indent();
|
||||||
|
|
||||||
|
if (descriptor_->is_packable() && descriptor_->options().packed()) {
|
||||||
|
GenerateRepeatedDataSizeCode(printer);
|
||||||
|
printer->Print(variables_,
|
||||||
|
"output.writeRawVarint32($tag$);\n"
|
||||||
|
"output.writeRawVarint32(dataSize);\n"
|
||||||
|
"for (int i = 0; i < this.$name$.length; i++) {\n"
|
||||||
|
" output.write$capitalized_type$NoTag(this.$name$[i]);\n"
|
||||||
|
"}\n");
|
||||||
|
} else if (IsReferenceType(GetJavaType(descriptor_))) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"for (int i = 0; i < this.$name$.length; i++) {\n"
|
||||||
|
" $type$ element = this.$name$[i];\n"
|
||||||
|
" if (element != null) {\n"
|
||||||
|
" output.write$capitalized_type$($number$, element);\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n");
|
||||||
|
} else {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"for (int i = 0; i < this.$name$.length; i++) {\n"
|
||||||
|
" output.write$capitalized_type$($number$, this.$name$[i]);\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printer->Outdent();
|
||||||
|
printer->Print("}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RepeatedPrimitiveFieldGenerator::
|
||||||
|
GenerateSerializedSizeCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (this.$name$ != null && this.$name$.length > 0) {\n");
|
||||||
|
printer->Indent();
|
||||||
|
|
||||||
|
GenerateRepeatedDataSizeCode(printer);
|
||||||
|
|
||||||
|
printer->Print(
|
||||||
|
"size += dataSize;\n");
|
||||||
|
if (descriptor_->is_packable() && descriptor_->options().packed()) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"size += $tag_size$;\n"
|
||||||
|
"size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
|
||||||
|
" .computeRawVarint32Size(dataSize);\n");
|
||||||
|
} else if (IsReferenceType(GetJavaType(descriptor_))) {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"size += $tag_size$ * dataCount;\n");
|
||||||
|
} else {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"size += $tag_size$ * this.$name$.length;\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printer->Outdent();
|
||||||
|
|
||||||
|
printer->Print(
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RepeatedPrimitiveFieldGenerator::
|
||||||
|
GenerateEqualsCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"if (!com.google.protobuf.nano.InternalNano.equals(\n"
|
||||||
|
" this.$name$, other.$name$)) {\n"
|
||||||
|
" return false;\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RepeatedPrimitiveFieldGenerator::
|
||||||
|
GenerateHashCodeCode(io::Printer* printer) const {
|
||||||
|
printer->Print(variables_,
|
||||||
|
"result = 31 * result\n"
|
||||||
|
" + com.google.protobuf.nano.InternalNano.hashCode(this.$name$);\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace javanano
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace protobuf
|
||||||
|
} // namespace google
|
126
src/google/protobuf/compiler/javanano/javanano_primitive_field.h
Normal file
126
src/google/protobuf/compiler/javanano/javanano_primitive_field.h
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Author: kenton@google.com (Kenton Varda)
|
||||||
|
// Based on original Protocol Buffers design by
|
||||||
|
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||||
|
|
||||||
|
#ifndef GOOGLE_PROTOBUF_COMPILER_JAVANANO_PRIMITIVE_FIELD_H__
|
||||||
|
#define GOOGLE_PROTOBUF_COMPILER_JAVANANO_PRIMITIVE_FIELD_H__
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <google/protobuf/compiler/javanano/javanano_field.h>
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
namespace protobuf {
|
||||||
|
namespace compiler {
|
||||||
|
namespace javanano {
|
||||||
|
|
||||||
|
class PrimitiveFieldGenerator : public FieldGenerator {
|
||||||
|
public:
|
||||||
|
explicit PrimitiveFieldGenerator(
|
||||||
|
const FieldDescriptor* descriptor, const Params ¶ms);
|
||||||
|
~PrimitiveFieldGenerator();
|
||||||
|
|
||||||
|
// implements FieldGenerator ---------------------------------------
|
||||||
|
bool SavedDefaultNeeded() const;
|
||||||
|
void GenerateInitSavedDefaultCode(io::Printer* printer) const;
|
||||||
|
void GenerateMembers(io::Printer* printer, bool lazy_init) const;
|
||||||
|
void GenerateClearCode(io::Printer* printer) const;
|
||||||
|
void GenerateMergingCode(io::Printer* printer) const;
|
||||||
|
void GenerateSerializationCode(io::Printer* printer) const;
|
||||||
|
void GenerateSerializedSizeCode(io::Printer* printer) const;
|
||||||
|
void GenerateEqualsCode(io::Printer* printer) const;
|
||||||
|
void GenerateHashCodeCode(io::Printer* printer) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void GenerateSerializationConditional(io::Printer* printer) const;
|
||||||
|
|
||||||
|
const FieldDescriptor* descriptor_;
|
||||||
|
map<string, string> variables_;
|
||||||
|
|
||||||
|
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator);
|
||||||
|
};
|
||||||
|
|
||||||
|
class AccessorPrimitiveFieldGenerator : public FieldGenerator {
|
||||||
|
public:
|
||||||
|
explicit AccessorPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
|
||||||
|
const Params ¶ms, int has_bit_index);
|
||||||
|
~AccessorPrimitiveFieldGenerator();
|
||||||
|
|
||||||
|
// implements FieldGenerator ---------------------------------------
|
||||||
|
bool SavedDefaultNeeded() const;
|
||||||
|
void GenerateInitSavedDefaultCode(io::Printer* printer) const;
|
||||||
|
void GenerateMembers(io::Printer* printer, bool lazy_init) const;
|
||||||
|
void GenerateClearCode(io::Printer* printer) const;
|
||||||
|
void GenerateMergingCode(io::Printer* printer) const;
|
||||||
|
void GenerateSerializationCode(io::Printer* printer) const;
|
||||||
|
void GenerateSerializedSizeCode(io::Printer* printer) const;
|
||||||
|
void GenerateEqualsCode(io::Printer* printer) const;
|
||||||
|
void GenerateHashCodeCode(io::Printer* printer) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const FieldDescriptor* descriptor_;
|
||||||
|
map<string, string> variables_;
|
||||||
|
|
||||||
|
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(AccessorPrimitiveFieldGenerator);
|
||||||
|
};
|
||||||
|
|
||||||
|
class RepeatedPrimitiveFieldGenerator : public FieldGenerator {
|
||||||
|
public:
|
||||||
|
explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params& params);
|
||||||
|
~RepeatedPrimitiveFieldGenerator();
|
||||||
|
|
||||||
|
// implements FieldGenerator ---------------------------------------
|
||||||
|
void GenerateMembers(io::Printer* printer, bool lazy_init) const;
|
||||||
|
void GenerateClearCode(io::Printer* printer) const;
|
||||||
|
void GenerateMergingCode(io::Printer* printer) const;
|
||||||
|
void GenerateMergingCodeFromPacked(io::Printer* printer) const;
|
||||||
|
void GenerateSerializationCode(io::Printer* printer) const;
|
||||||
|
void GenerateSerializedSizeCode(io::Printer* printer) const;
|
||||||
|
void GenerateEqualsCode(io::Printer* printer) const;
|
||||||
|
void GenerateHashCodeCode(io::Printer* printer) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void GenerateRepeatedDataSizeCode(io::Printer* printer) const;
|
||||||
|
|
||||||
|
const FieldDescriptor* descriptor_;
|
||||||
|
map<string, string> variables_;
|
||||||
|
|
||||||
|
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace javanano
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace protobuf
|
||||||
|
|
||||||
|
} // namespace google
|
||||||
|
#endif // GOOGLE_PROTOBUF_COMPILER_JAVANANO_PRIMITIVE_FIELD_H__
|
Loading…
Reference in New Issue
Block a user